From 9442a463d46284bc85cfac927bc1b7dc1ef6d832 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Mon, 1 Apr 2024 21:43:50 +0200 Subject: [PATCH 01/54] Shrink drawlists, take 2 Approximately 2/3rds smaller --- src/lua_hudlib_drawlist.c | 45 ++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index de1f234c3..7ec5398e4 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -37,27 +37,32 @@ typedef struct drawitem_s { enum drawitem_e type; fixed_t x; fixed_t y; - fixed_t w; - fixed_t h; - INT32 c; - fixed_t scale; - fixed_t hscale; - fixed_t vscale; - patch_t *patch; - INT32 flags; - UINT16 basecolor; - UINT16 outlinecolor; + union { + INT32 flags; + INT32 c; + }; + + union { + fixed_t scale; // drawScaled + fixed_t hscale; // drawStretched + fixed_t w; // drawFill + INT32 align; // drawString + INT32 num; // drawNum, drawPaddedNum, drawPingNum + UINT16 color; // fadeScreen + }; + union { + fixed_t vscale; // drawStretched + fixed_t h; // drawFill + INT32 digits; // drawPaddedNum + UINT8 strength; // fadeScreen + }; + + // pointers (and size_t's) last, for potentially better packing + union { + patch_t *patch; + size_t stroffset; // offset into strbuf to get str + }; const UINT8 *colormap; - UINT8 *basecolormap; - UINT8 *outlinecolormap; - fixed_t sx; - fixed_t sy; - INT32 num; - INT32 digits; - size_t stroffset; // offset into strbuf to get str - UINT16 color; - UINT8 strength; - INT32 align; } drawitem_t; // The internal structure of a drawlist. -- 2.54.0 From 5f69bfcf222535b73bae57a7d0c8a702f1298566 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Tue, 2 Apr 2024 03:22:24 +0200 Subject: [PATCH 02/54] Split game drawlist per displayplayer --- src/lua_hud.h | 2 +- src/lua_hudlib.c | 29 +++++------------------------ src/st_stuff.c | 13 ++++++++----- 3 files changed, 14 insertions(+), 30 deletions(-) diff --git a/src/lua_hud.h b/src/lua_hud.h index d0fec7f1e..ce9f6e7a8 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -44,7 +44,7 @@ extern boolean hud_running; boolean LUA_HudEnabled(enum hud option); -void LUAh_GameHUD(player_t *stplyr, huddrawlist_h list); +void LUAh_GameHUD(huddrawlist_h list); void LUAh_ScoresHUD(huddrawlist_h list); void LUAh_IntermissionHUD(huddrawlist_h list); void LUAh_VoteHUD(huddrawlist_h list); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 2f81d98bf..3ec03537b 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -1413,7 +1413,7 @@ boolean LUA_HudEnabled(enum hud option) } // Hook for HUD rendering -void LUAh_GameHUD(player_t *stplayr, huddrawlist_h list) +void LUAh_GameHUD(huddrawlist_h list) { if (!gL || !(hudAvailable & (1< 2 && stplayr == &players[displayplayers[3]]) - { - LUA_PushUserdata(gL, &camera[3], META_CAMERA); - camnum = 4; - } - else if (splitscreen > 1 && stplayr == &players[displayplayers[2]]) - { - LUA_PushUserdata(gL, &camera[2], META_CAMERA); - camnum = 3; - } - else if (splitscreen && stplayr == &players[displayplayers[1]]) - { - LUA_PushUserdata(gL, &camera[1], META_CAMERA); - camnum = 2; - } - else - { - LUA_PushUserdata(gL, &camera[0], META_CAMERA); - camnum = 1; - } + LUA_PushUserdata(gL, stplyr, META_PLAYER); + LUA_PushUserdata(gL, &camera[stplyrnum], META_CAMERA); + camnum = stplyrnum + 1; lua_pushnil(gL); while (lua_next(gL, -5) != 0) { lua_pushvalue(gL, -5); // graphics library (HUD[1]) - lua_pushvalue(gL, -5); // stplayr + lua_pushvalue(gL, -5); // stplyr lua_pushvalue(gL, -5); // camera LUA_Call(gL, 3, 0, 1); } diff --git a/src/st_stuff.c b/src/st_stuff.c index 2ecfd73d5..3e64e6626 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -193,7 +193,7 @@ hudinfo_t hudinfo[NUMHUDITEMS] = { 240, 160}, // HUD_LAP }; -static huddrawlist_h luahuddrawlist_game; +static huddrawlist_h luahuddrawlist_game[MAXSPLITSCREENPLAYERS]; // variable to stop mayonaka static from flickering consvar_t cv_lessflicker = {"lessflicker", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -473,7 +473,8 @@ void ST_Init(void) ST_LoadGraphics(); - luahuddrawlist_game = LUA_HUD_CreateDrawList(); + for (int i = 0; i < MAXSPLITSCREENPLAYERS; i++) + luahuddrawlist_game[i] = LUA_HUD_CreateDrawList(); } // change the status bar too, when pressing F12 while viewing a demo. @@ -846,7 +847,7 @@ static void ST_overlayDrawer(void) { if (renderisnewtic) { - LUAh_GameHUD(stplyr, luahuddrawlist_game); + LUAh_GameHUD(luahuddrawlist_game[stplyrnum]); } } @@ -1024,7 +1025,8 @@ void ST_Drawer(void) { if (renderisnewtic) { - LUA_HUD_ClearDrawList(luahuddrawlist_game); + for (i = 0; i <= splitscreen; i++) + LUA_HUD_ClearDrawList(luahuddrawlist_game[i]); } // No deadview! @@ -1035,7 +1037,8 @@ void ST_Drawer(void) ST_overlayDrawer(); } - LUA_HUD_DrawList(luahuddrawlist_game); + for (i = 0; i <= splitscreen; i++) + LUA_HUD_DrawList(luahuddrawlist_game[i]); // draw Midnight Channel's overlay ontop if (mapheaderinfo[gamemap-1]->typeoflevel & TOL_TV) // Very specific Midnight Channel stuff. -- 2.54.0 From b2f9a29eb0bca107ad4bbe7ce65832d48bcb57f3 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:00:23 +0200 Subject: [PATCH 03/54] Lua HUD interpolation --- src/lua_hud.h | 3 + src/lua_hudlib.c | 31 +++++++++ src/lua_hudlib_drawlist.c | 142 +++++++++++++++++++++++++++++--------- 3 files changed, 144 insertions(+), 32 deletions(-) diff --git a/src/lua_hud.h b/src/lua_hud.h index ce9f6e7a8..8601192b6 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -41,6 +41,9 @@ enum hud { }; extern boolean hud_running; +extern UINT8 hud_interptag; +extern UINT32 hud_interpcounter; +extern boolean hud_interpstring; boolean LUA_HudEnabled(enum hud option); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 3ec03537b..62aa30c37 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -32,6 +32,9 @@ #define HUDONLY if (!hud_running) return luaL_error(L, "HUD rendering code should not be called outside of rendering hooks!"); boolean hud_running = false; +UINT8 hud_interptag = 0; +UINT32 hud_interpcounter = 0; +boolean hud_interpstring = false; static UINT8 hud_enabled[(hud_MAX/8)+1]; static UINT8 hudAvailable; // hud hooks field @@ -1178,6 +1181,20 @@ static int libd_getDrawInfo(lua_State *L) return 3; } +static int libd_interpolate(lua_State *L) +{ + HUDONLY + hud_interptag = luaL_checkinteger(L, 1); + return 0; +} + +static int libd_interpString(lua_State *L) +{ + HUDONLY + hud_interpstring = luaL_checkboolean(L, 1); + return 0; +} + static luaL_Reg lib_draw[] = { {"patchExists", libd_patchExists}, {"cachePatch", libd_cachePatch}, @@ -1205,6 +1222,8 @@ static luaL_Reg lib_draw[] = { {"getDrawInfo", libd_getDrawInfo}, {"getHudColor", libd_getHudColor}, {"useColorHud", libd_useColorHud}, + {"interpolate", libd_interpolate}, + {"interpString", libd_interpString}, {NULL, NULL} }; @@ -1438,8 +1457,11 @@ void LUAh_GameHUD(huddrawlist_h list) LUA_PushUserdata(gL, &camera[stplyrnum], META_CAMERA); camnum = stplyrnum + 1; + hud_interpcounter = 0; lua_pushnil(gL); while (lua_next(gL, -5) != 0) { + hud_interptag = 0; + hud_interpcounter++; lua_pushvalue(gL, -5); // graphics library (HUD[1]) lua_pushvalue(gL, -5); // stplyr lua_pushvalue(gL, -5); // camera @@ -1474,7 +1496,10 @@ void LUAh_ScoresHUD(huddrawlist_h list) I_Assert(lua_istable(gL, -1)); lua_remove(gL, -3); // pop HUD lua_pushnil(gL); + hud_interpcounter = 0; while (lua_next(gL, -3) != 0) { + hud_interptag = 0; + hud_interpcounter++; lua_pushvalue(gL, -3); // graphics library (HUD[1]) LUA_Call(gL, 1, 0, 1); } @@ -1507,7 +1532,10 @@ void LUAh_IntermissionHUD(huddrawlist_h list) I_Assert(lua_istable(gL, -1)); lua_remove(gL, -3); // pop HUD lua_pushnil(gL); + hud_interpcounter = 0; while (lua_next(gL, -3) != 0) { + hud_interptag = 0; + hud_interpcounter++; lua_pushvalue(gL, -3); // graphics library (HUD[1]) LUA_Call(gL, 1, 0, 1); } @@ -1540,7 +1568,10 @@ void LUAh_VoteHUD(huddrawlist_h list) I_Assert(lua_istable(gL, -1)); lua_remove(gL, -3); // pop HUD lua_pushnil(gL); + hud_interpcounter = 0; while (lua_next(gL, -3) != 0) { + hud_interptag = 0; + hud_interpcounter++; lua_pushvalue(gL, -3); // graphics library (HUD[1]) LUA_Call(gL, 1, 0, 1); } diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index 7ec5398e4..14a24d90e 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -11,11 +11,16 @@ /// \brief a data structure for managing cached drawlists for the Lua hud lib #include "lua_hudlib_drawlist.h" +#include "lua_hud.h" +#include "blua/lstate.h" // shhhhhh +#include "lua_libs.h" #include #include "v_video.h" #include "z_zone.h" +#include "r_main.h" +#include "r_fps.h" enum drawitem_e { DI_Draw = 0, @@ -34,6 +39,7 @@ enum drawitem_e { // A single draw item with all possible arguments needed for a draw call. typedef struct drawitem_s { + UINT64 id; enum drawitem_e type; fixed_t x; fixed_t y; @@ -68,8 +74,10 @@ typedef struct drawitem_s { // The internal structure of a drawlist. struct huddrawlist_s { drawitem_t *items; - size_t items_capacity; size_t items_len; + drawitem_t *olditems; + size_t olditems_len; + size_t capacity; char *strbuf; size_t strbuf_capacity; size_t strbuf_len; @@ -93,8 +101,10 @@ huddrawlist_h LUA_HUD_CreateDrawList(void) drawlist = (huddrawlist_h) Z_Calloc(sizeof(struct huddrawlist_s), PU_STATIC, NULL); drawlist->items = NULL; - drawlist->items_capacity = 0; drawlist->items_len = 0; + drawlist->olditems = NULL; + drawlist->olditems_len = 0; + drawlist->capacity = 0; drawlist->strbuf = NULL; drawlist->strbuf_capacity = 0; drawlist->strbuf_len = 0; @@ -104,15 +114,14 @@ huddrawlist_h LUA_HUD_CreateDrawList(void) void LUA_HUD_ClearDrawList(huddrawlist_h list) { + // swap the old and new lists + void *tmp = list->olditems; + list->olditems = list->items; + list->items = tmp; + // rather than deallocate, we'll just save the existing allocation and empty // it out for reuse - - // this memset probably isn't necessary - if (list->items) - { - memset(list->items, 0, sizeof(drawitem_t) * list->items_capacity); - } - + list->olditems_len = list->items_len; list->items_len = 0; if (list->strbuf) @@ -130,6 +139,10 @@ void LUA_HUD_DestroyDrawList(huddrawlist_h list) { Z_Free(list->items); } + if (list->olditems) + { + Z_Free(list->olditems); + } if (list->strbuf) { Z_Free(list->strbuf); @@ -148,11 +161,11 @@ boolean LUA_HUD_IsDrawListValid(huddrawlist_h list) static size_t AllocateDrawItem(huddrawlist_h list) { if (!list) I_Error("can't allocate draw item: invalid list"); - if (list->items_capacity <= list->items_len + 1) + if (list->capacity <= list->items_len) { - if (list->items_capacity == 0) list->items_capacity = 128; - else list->items_capacity *= 2; - list->items = (drawitem_t *) Z_Realloc(list->items, sizeof(struct drawitem_s) * list->items_capacity, PU_STATIC, NULL); + list->capacity = list->capacity == 0 ? 128 : list->capacity * 2; + list->items = Z_Realloc(list->items, sizeof(struct drawitem_s) * list->capacity, PU_STATIC, NULL); + list->olditems = Z_Realloc(list->olditems, sizeof(struct drawitem_s) * list->capacity, PU_STATIC, NULL); } return list->items_len++; @@ -183,6 +196,14 @@ static size_t CopyString(huddrawlist_h list, const char* str) } } +// leave bit 0 free for the string mode +#define INTERP_LATCH 1 + +#define GETITEMID \ + item->id = hud_interptag \ + ? (((UINT64)gL->savedpc << 32) | (hud_interpcounter << 9) | (hud_interptag << 1) | (hud_interpstring ? INTERP_LATCH : 0)) \ + : 0; + void LUA_HUD_AddDraw( huddrawlist_h list, INT32 x, @@ -194,9 +215,10 @@ void LUA_HUD_AddDraw( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + GETITEMID item->type = DI_Draw; - item->x = x; - item->y = y; + item->x = x << FRACBITS; + item->y = y << FRACBITS; item->patch = patch; item->flags = flags; item->colormap = colormap; @@ -214,6 +236,7 @@ void LUA_HUD_AddDrawScaled( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + GETITEMID item->type = DI_DrawScaled; item->x = x; item->y = y; @@ -236,6 +259,7 @@ void LUA_HUD_AddDrawStretched( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + GETITEMID item->type = DI_DrawStretched; item->x = x; item->y = y; @@ -256,6 +280,7 @@ void LUA_HUD_AddDrawNum( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + GETITEMID item->type = DI_DrawNum; item->x = x; item->y = y; @@ -274,6 +299,7 @@ void LUA_HUD_AddDrawPaddedNum( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + GETITEMID item->type = DI_DrawPaddedNum; item->x = x; item->y = y; @@ -293,6 +319,7 @@ void LUA_HUD_AddDrawPingNum( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + GETITEMID item->type = DI_DrawPingNum; item->x = x; item->y = y; @@ -312,6 +339,7 @@ void LUA_HUD_AddDrawFill( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + GETITEMID item->type = DI_DrawFill; item->x = x; item->y = y; @@ -331,6 +359,7 @@ void LUA_HUD_AddDrawString( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + GETITEMID item->type = DI_DrawString; item->x = x; item->y = y; @@ -349,6 +378,7 @@ void LUA_HUD_AddDrawKartString( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + GETITEMID item->type = DI_DrawKartString; item->x = x; item->y = y; @@ -366,6 +396,7 @@ void LUA_HUD_AddDrawLevelTitle( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + GETITEMID item->type = DI_DrawLevelTitle; item->x = x; item->y = y; @@ -389,6 +420,11 @@ void LUA_HUD_AddFadeScreen( void LUA_HUD_DrawList(huddrawlist_h list) { size_t i; + size_t j = 0; + fixed_t frac = R_UsingFrameInterpolation() ? rendertimefrac : FRACUNIT; + fixed_t lerpx = 0, lerpy = 0; + drawitem_t *latchitem = NULL; + drawitem_t *oldlatchitem = NULL; if (!list) I_Error("HUD drawlist invalid"); if (list->items_len <= 0) return; @@ -397,68 +433,110 @@ void LUA_HUD_DrawList(huddrawlist_h list) for (i = 0; i < list->items_len; i++) { drawitem_t *item = &list->items[i]; + drawitem_t *olditem = NULL; const char *itemstr = &list->strbuf[item->stroffset]; + if (item->id) { + // find the old one too + // this is kinda cursed... we need to check every item + // but stop when the first-checked item is reached again + size_t stop = j; + while(true) + { + if (j == list->olditems_len) + { + // wrap around + j = 0; + if (j == stop) // i'm dumb + break; + } + drawitem_t *old = &list->olditems[j++]; + if (old->id == item->id) + { + // gotcha! + olditem = old; + if (item->id & INTERP_LATCH) { + if (!latchitem) { + lerpx = FixedMul(frac, item->x - olditem->x); + lerpy = FixedMul(frac, item->y - olditem->y); + latchitem = item; + oldlatchitem = olditem; + } + } else { + lerpx = FixedMul(frac, item->x - olditem->x); + lerpy = FixedMul(frac, item->y - olditem->y); + latchitem = NULL; + } + break; + } + if (j == stop) + break; + } + } + + #define LERP(it) (olditem ? olditem->it + FixedMul(frac, item->it - olditem->it) : item->it) + #define LERPS(it) (olditem ? (latchitem ? (latchitem->it + (item->it - latchitem->it)) - (latchitem->it - oldlatchitem->it) : olditem->it) + lerp##it : item->it) + switch (item->type) { case DI_Draw: - V_DrawFixedPatch(item->x<y<flags, item->patch, item->colormap); + V_DrawFixedPatch(LERPS(x), LERPS(y), FRACUNIT, item->flags, item->patch, item->colormap); break; case DI_DrawScaled: - V_DrawFixedPatch(item->x, item->y, item->scale, item->flags, item->patch, item->colormap); + V_DrawFixedPatch(LERPS(x), LERPS(y), LERP(scale), item->flags, item->patch, item->colormap); break; case DI_DrawStretched: - V_DrawStretchyFixedPatch(item->x, item->y, item->hscale, item->vscale, item->flags, item->patch, item->colormap); + V_DrawStretchyFixedPatch(LERPS(x), LERPS(y), LERP(hscale), LERP(vscale), item->flags, item->patch, item->colormap); break; case DI_DrawNum: - V_DrawTallNum(item->x, item->y, item->flags, item->num); + V_DrawTallNum(LERPS(x), LERPS(y), item->flags, item->num); break; case DI_DrawPaddedNum: - V_DrawPaddedTallNum(item->x, item->y, item->flags, item->num, item->digits); + V_DrawPaddedTallNum(LERPS(x), LERPS(y), item->flags, item->num, item->digits); break; case DI_DrawPingNum: - V_DrawPingNum(item->x, item->y, item->flags, item->num, item->colormap); + V_DrawPingNum(LERPS(x), LERPS(y), item->flags, item->num, item->colormap); break; case DI_DrawFill: - V_DrawFill(item->x, item->y, item->w, item->h, item->c); + V_DrawFill(LERPS(x), LERPS(y), item->w, item->h, item->c); break; case DI_DrawString: switch(item->align) { // hu_font case align_left: - V_DrawString(item->x, item->y, item->flags, itemstr); + V_DrawString(LERPS(x), LERPS(y), item->flags, itemstr); break; case align_center: - V_DrawCenteredString(item->x, item->y, item->flags, itemstr); + V_DrawCenteredString(LERPS(x), LERPS(y), item->flags, itemstr); break; case align_right: - V_DrawRightAlignedString(item->x, item->y, item->flags, itemstr); + V_DrawRightAlignedString(LERPS(x), LERPS(y), item->flags, itemstr); break; case align_fixed: - V_DrawStringAtFixed(item->x, item->y, item->flags, itemstr); + V_DrawStringAtFixed(LERPS(x), LERPS(y), item->flags, itemstr); break; // hu_font, 0.5x scale case align_small: - V_DrawSmallString(item->x, item->y, item->flags, itemstr); + V_DrawSmallString(LERPS(x), LERPS(y), item->flags, itemstr); break; case align_smallright: - V_DrawRightAlignedSmallString(item->x, item->y, item->flags, itemstr); + V_DrawRightAlignedSmallString(LERPS(x), LERPS(y), item->flags, itemstr); break; // tny_font case align_thin: - V_DrawThinString(item->x, item->y, item->flags, itemstr); + V_DrawThinString(LERPS(x), LERPS(y), item->flags, itemstr); break; case align_thinright: - V_DrawRightAlignedThinString(item->x, item->y, item->flags, itemstr); + V_DrawRightAlignedThinString(LERPS(x), LERPS(y), item->flags, itemstr); break; } break; case DI_DrawKartString: - V_DrawKartString(item->x, item->y, item->flags, itemstr); + V_DrawKartString(LERPS(x), LERPS(y), item->flags, itemstr); break; case DI_DrawLevelTitle: - V_DrawLevelTitle(item->x, item->y, item->flags, itemstr); + V_DrawLevelTitle(LERPS(x), LERPS(y), item->flags, itemstr); break; case DI_FadeScreen: V_DrawFadeScreen(item->color, item->strength); -- 2.54.0 From aeb5ae994ecd92cfea78da5c423af52cc76db854 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Wed, 3 Apr 2024 01:37:24 +0200 Subject: [PATCH 04/54] Subpixel interpolation for strings and drawfill --- src/lua_hudlib_drawlist.c | 119 +++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index 14a24d90e..8aaaa67ff 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -196,6 +196,116 @@ static size_t CopyString(huddrawlist_h list, const char* str) } } +static void CalcCoords(huddrawlist_h list, drawitem_t *item) +{ + if (!(item->flags & V_NOSCALESTART) && cv_uncappedhud.value) + { + INT32 dupx = vid.dupx; + INT32 dupy = vid.dupy; + + item->flags |= V_NOSCALESTART; + + if (item->flags & V_SCALEPATCHMASK) switch ((item->flags & V_SCALEPATCHMASK) >> V_SCALEPATCHSHIFT) + { + case 1: // V_NOSCALEPATCH + dupx = dupy = 1; + break; + case 2: // V_SMALLSCALEPATCH + dupx = vid.smalldupx; + dupy = vid.smalldupy; + break; + case 3: // V_MEDSCALEPATCH + dupx = vid.meddupx; + dupy = vid.meddupy; + break; + default: + break; + } + + // only use one dup, to avoid stretching (har har) + dupx = dupy = (dupx < dupy ? dupx : dupy); + + INT32 x = item->x * dupx; + INT32 y = item->y * dupy; + + if (vid.width != BASEVIDWIDTH * dupx) + { + // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, + // so center this imaginary screen + if ((item->flags & (V_HORZSCREEN|V_SNAPTOLEFT)) == (V_HORZSCREEN|V_SNAPTOLEFT)) + x += (vid.width/2 - (BASEVIDWIDTH/2 * dupx)); + else if (item->flags & V_SNAPTORIGHT) + x += (vid.width - (BASEVIDWIDTH * dupx)); + else if (!(item->flags & V_SNAPTOLEFT)) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if ((item->flags & (V_SPLITSCREEN|V_SNAPTOTOP)) == (V_SPLITSCREEN|V_SNAPTOTOP)) + y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); + else if (item->flags & V_SNAPTOBOTTOM) + y += (vid.height - (BASEVIDHEIGHT * dupy)); + else if (!(item->flags & V_SNAPTOTOP)) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + } + + // need to compensate for dup here + + if (item->align == align_center) + x -= (V_StringWidth(&list->strbuf[item->stroffset], item->flags) * (dupx - 1))/2; + if (item->align == align_right) + x -= V_StringWidth(&list->strbuf[item->stroffset], item->flags) * (dupx - 1); + if (item->align == align_thinright) + x -= V_ThinStringWidth(&list->strbuf[item->stroffset], item->flags) * (dupx - 1); + + item->x = x; + item->y = y; + } +} + +static void CalcFillCoords(drawitem_t *item) +{ + if (!(item->flags & V_NOSCALESTART) && cv_uncappedhud.value) + { + INT32 dupx = vid.dupx; + INT32 dupy = vid.dupy; + INT32 x = item->x * dupx; + INT32 y = item->y * dupy; + INT32 c = item->c; + + item->flags |= V_NOSCALESTART; + item->w *= dupx; + item->h *= dupy; + + // Center it if necessary + if (vid.width != BASEVIDWIDTH * dupx) + { + // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, + // so center this imaginary screen + if (c & V_SNAPTORIGHT) + x += (vid.width - (BASEVIDWIDTH * dupx)); + else if (!(c & V_SNAPTOLEFT)) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (c & V_SNAPTOBOTTOM) + y += (vid.height - (BASEVIDHEIGHT * dupy)); + else if (!(c & V_SNAPTOTOP)) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + } + if (c & V_SPLITSCREEN) + y += (BASEVIDHEIGHT * dupy)/2; + if (c & V_HORZSCREEN) + x += (BASEVIDWIDTH * dupx)/2; + + item->x = x; + item->y = y; + } +} + // leave bit 0 free for the string mode #define INTERP_LATCH 1 @@ -346,6 +456,7 @@ void LUA_HUD_AddDrawFill( item->w = w; item->h = h; item->c = c; + CalcFillCoords(item); } void LUA_HUD_AddDrawString( @@ -366,6 +477,7 @@ void LUA_HUD_AddDrawString( item->stroffset = CopyString(list, str); item->flags = flags; item->align = align; + CalcCoords(list, item); } void LUA_HUD_AddDrawKartString( @@ -436,7 +548,7 @@ void LUA_HUD_DrawList(huddrawlist_h list) drawitem_t *olditem = NULL; const char *itemstr = &list->strbuf[item->stroffset]; - if (item->id) { + if (item->id && cv_uncappedhud.value) { // find the old one too // this is kinda cursed... we need to check every item // but stop when the first-checked item is reached again @@ -475,7 +587,10 @@ void LUA_HUD_DrawList(huddrawlist_h list) } #define LERP(it) (olditem ? olditem->it + FixedMul(frac, item->it - olditem->it) : item->it) - #define LERPS(it) (olditem ? (latchitem ? (latchitem->it + (item->it - latchitem->it)) - (latchitem->it - oldlatchitem->it) : olditem->it) + lerp##it : item->it) + + // half of this could be done when the coordinates are latched... zzzzzz + #define LERPS(it) (latchitem ? ((latchitem->it + (item->it - latchitem->it)) - (latchitem->it - oldlatchitem->it)) + lerp##it : (olditem ? olditem->it + lerp##it : item->it)) + //define LERPS(it) (olditem ? (latchitem ? (latchitem->it + (item->it - latchitem->it)) - (latchitem->it - oldlatchitem->it) : olditem->it) + lerp##it : item->it) switch (item->type) { -- 2.54.0 From 18e0485f399b928ac970814f365c4ebacbf64232 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Thu, 4 Apr 2024 23:21:41 +0200 Subject: [PATCH 05/54] Make this less insufferable * Zero is now a valid tag for v.interpolate * Reset lerp coordinates when v.interpString is called again * Leaving string mode enabled on exit no longer breaks other scripts * Fix fadeScreen having an uninitialized ID --- src/lua_hud.h | 3 ++ src/lua_hudlib.c | 36 ++++++++++++++++++---- src/lua_hudlib_drawlist.c | 63 +++++++++++++++++++++++++-------------- 3 files changed, 73 insertions(+), 29 deletions(-) diff --git a/src/lua_hud.h b/src/lua_hud.h index 8601192b6..ccaed738d 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -41,9 +41,12 @@ enum hud { }; extern boolean hud_running; + +extern boolean hud_interpolate; extern UINT8 hud_interptag; extern UINT32 hud_interpcounter; extern boolean hud_interpstring; +extern boolean hud_interplatch; boolean LUA_HudEnabled(enum hud option); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 62aa30c37..bceb9ebc4 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -32,9 +32,12 @@ #define HUDONLY if (!hud_running) return luaL_error(L, "HUD rendering code should not be called outside of rendering hooks!"); boolean hud_running = false; + +boolean hud_interpolate = false; UINT8 hud_interptag = 0; UINT32 hud_interpcounter = 0; boolean hud_interpstring = false; +boolean hud_interplatch = false; static UINT8 hud_enabled[(hud_MAX/8)+1]; static UINT8 hudAvailable; // hud hooks field @@ -1184,14 +1187,35 @@ static int libd_getDrawInfo(lua_State *L) static int libd_interpolate(lua_State *L) { HUDONLY - hud_interptag = luaL_checkinteger(L, 1); + + // do type checking even if interpolation is disabled + boolean newinterpolate; + UINT8 newtag; + + if (lua_isnumber(L, 1)) + { + newinterpolate = true; + newtag = luaL_checkinteger(L, 1); + } + else + { + newinterpolate = luaL_checkboolean(L, 1); + newtag = 0; + } + + if (!cv_uncappedhud.value) + return 0; + + hud_interpolate = newinterpolate; + hud_interptag = newtag; + return 0; } static int libd_interpString(lua_State *L) { HUDONLY - hud_interpstring = luaL_checkboolean(L, 1); + hud_interpstring = hud_interplatch = luaL_checkboolean(L, 1); return 0; } @@ -1460,7 +1484,7 @@ void LUAh_GameHUD(huddrawlist_h list) hud_interpcounter = 0; lua_pushnil(gL); while (lua_next(gL, -5) != 0) { - hud_interptag = 0; + hud_interpolate = hud_interpstring = hud_interplatch = false; hud_interpcounter++; lua_pushvalue(gL, -5); // graphics library (HUD[1]) lua_pushvalue(gL, -5); // stplyr @@ -1498,7 +1522,7 @@ void LUAh_ScoresHUD(huddrawlist_h list) lua_pushnil(gL); hud_interpcounter = 0; while (lua_next(gL, -3) != 0) { - hud_interptag = 0; + hud_interpolate = hud_interpstring = hud_interplatch = false; hud_interpcounter++; lua_pushvalue(gL, -3); // graphics library (HUD[1]) LUA_Call(gL, 1, 0, 1); @@ -1534,7 +1558,7 @@ void LUAh_IntermissionHUD(huddrawlist_h list) lua_pushnil(gL); hud_interpcounter = 0; while (lua_next(gL, -3) != 0) { - hud_interptag = 0; + hud_interpolate = hud_interpstring = hud_interplatch = false; hud_interpcounter++; lua_pushvalue(gL, -3); // graphics library (HUD[1]) LUA_Call(gL, 1, 0, 1); @@ -1570,7 +1594,7 @@ void LUAh_VoteHUD(huddrawlist_h list) lua_pushnil(gL); hud_interpcounter = 0; while (lua_next(gL, -3) != 0) { - hud_interptag = 0; + hud_interpolate = hud_interpstring = hud_interplatch = false; hud_interpcounter++; lua_pushvalue(gL, -3); // graphics library (HUD[1]) LUA_Call(gL, 1, 0, 1); diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index 8aaaa67ff..65e6cef42 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -306,13 +306,27 @@ static void CalcFillCoords(drawitem_t *item) } } -// leave bit 0 free for the string mode #define INTERP_LATCH 1 +#define INTERP_STRING 2 -#define GETITEMID \ - item->id = hud_interptag \ - ? (((UINT64)gL->savedpc << 32) | (hud_interpcounter << 9) | (hud_interptag << 1) | (hud_interpstring ? INTERP_LATCH : 0)) \ - : 0; +static UINT64 GetItemId(void) +{ + if (!hud_interpolate) + return 0; + + // leave bits 0 and 1 free for the string mode + UINT64 id = ((UINT64)gL->savedpc << 32) | (hud_interpcounter << 10) | (hud_interptag << 2); + + if (hud_interplatch) + { + id |= INTERP_LATCH; + hud_interplatch = false; + } + if (hud_interpstring) + id |= INTERP_STRING; + + return id; +} void LUA_HUD_AddDraw( huddrawlist_h list, @@ -325,7 +339,7 @@ void LUA_HUD_AddDraw( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; - GETITEMID + item->id = GetItemId(); item->type = DI_Draw; item->x = x << FRACBITS; item->y = y << FRACBITS; @@ -346,7 +360,7 @@ void LUA_HUD_AddDrawScaled( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; - GETITEMID + item->id = GetItemId(); item->type = DI_DrawScaled; item->x = x; item->y = y; @@ -369,7 +383,7 @@ void LUA_HUD_AddDrawStretched( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; - GETITEMID + item->id = GetItemId(); item->type = DI_DrawStretched; item->x = x; item->y = y; @@ -390,7 +404,7 @@ void LUA_HUD_AddDrawNum( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; - GETITEMID + item->id = GetItemId(); item->type = DI_DrawNum; item->x = x; item->y = y; @@ -409,7 +423,7 @@ void LUA_HUD_AddDrawPaddedNum( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; - GETITEMID + item->id = GetItemId(); item->type = DI_DrawPaddedNum; item->x = x; item->y = y; @@ -429,7 +443,7 @@ void LUA_HUD_AddDrawPingNum( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; - GETITEMID + item->id = GetItemId(); item->type = DI_DrawPingNum; item->x = x; item->y = y; @@ -449,7 +463,7 @@ void LUA_HUD_AddDrawFill( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; - GETITEMID + item->id = GetItemId(); item->type = DI_DrawFill; item->x = x; item->y = y; @@ -470,7 +484,7 @@ void LUA_HUD_AddDrawString( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; - GETITEMID + item->id = GetItemId(); item->type = DI_DrawString; item->x = x; item->y = y; @@ -490,7 +504,7 @@ void LUA_HUD_AddDrawKartString( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; - GETITEMID + item->id = GetItemId(); item->type = DI_DrawKartString; item->x = x; item->y = y; @@ -508,7 +522,7 @@ void LUA_HUD_AddDrawLevelTitle( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; - GETITEMID + item->id = GetItemId(); item->type = DI_DrawLevelTitle; item->x = x; item->y = y; @@ -524,6 +538,8 @@ void LUA_HUD_AddFadeScreen( { size_t i = AllocateDrawItem(list); drawitem_t *item = &list->items[i]; + // nothing to interpolate here + item->id = 0; item->type = DI_FadeScreen; item->color = color; item->strength = strength; @@ -548,7 +564,7 @@ void LUA_HUD_DrawList(huddrawlist_h list) drawitem_t *olditem = NULL; const char *itemstr = &list->strbuf[item->stroffset]; - if (item->id && cv_uncappedhud.value) { + if (item->id) { // find the old one too // this is kinda cursed... we need to check every item // but stop when the first-checked item is reached again @@ -568,13 +584,11 @@ void LUA_HUD_DrawList(huddrawlist_h list) // gotcha! olditem = old; if (item->id & INTERP_LATCH) { - if (!latchitem) { - lerpx = FixedMul(frac, item->x - olditem->x); - lerpy = FixedMul(frac, item->y - olditem->y); - latchitem = item; - oldlatchitem = olditem; - } - } else { + lerpx = FixedMul(frac, item->x - olditem->x); + lerpy = FixedMul(frac, item->y - olditem->y); + latchitem = item; + oldlatchitem = olditem; + } else if (!(item->id & INTERP_STRING)) { lerpx = FixedMul(frac, item->x - olditem->x); lerpy = FixedMul(frac, item->y - olditem->y); latchitem = NULL; @@ -584,6 +598,9 @@ void LUA_HUD_DrawList(huddrawlist_h list) if (j == stop) break; } + } else { + lerpx = lerpy = 0; + latchitem = NULL; } #define LERP(it) (olditem ? olditem->it + FixedMul(frac, item->it - olditem->it) : item->it) -- 2.54.0 From 60e42472e32679b025615bc8257e2a9bf0f43386 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Fri, 12 Apr 2024 21:00:54 +0200 Subject: [PATCH 06/54] Do string coordinate calcs on all functions (and fix) --- src/lua_hudlib_drawlist.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index 65e6cef42..4a58371c8 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -196,7 +196,7 @@ static size_t CopyString(huddrawlist_h list, const char* str) } } -static void CalcCoords(huddrawlist_h list, drawitem_t *item) +static void CalcStringCoords(drawitem_t *item, const char *string) { if (!(item->flags & V_NOSCALESTART) && cv_uncappedhud.value) { @@ -228,6 +228,12 @@ static void CalcCoords(huddrawlist_h list, drawitem_t *item) INT32 x = item->x * dupx; INT32 y = item->y * dupy; + if (item->flags & V_SPLITSCREEN) + y += (BASEVIDHEIGHT * (dupy - 1))/2; + + if (item->flags & V_HORZSCREEN) + x += (BASEVIDWIDTH * (dupx - 1))/2; + if (vid.width != BASEVIDWIDTH * dupx) { // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, @@ -251,13 +257,17 @@ static void CalcCoords(huddrawlist_h list, drawitem_t *item) } // need to compensate for dup here - - if (item->align == align_center) - x -= (V_StringWidth(&list->strbuf[item->stroffset], item->flags) * (dupx - 1))/2; - if (item->align == align_right) - x -= V_StringWidth(&list->strbuf[item->stroffset], item->flags) * (dupx - 1); - if (item->align == align_thinright) - x -= V_ThinStringWidth(&list->strbuf[item->stroffset], item->flags) * (dupx - 1); + if (item->type == DI_DrawString) + { + if (item->align == align_center) + x -= (V_StringWidth(string, item->flags) * (dupx - 1))/2; + if (item->align == align_right) + x -= V_StringWidth(string, item->flags) * (dupx - 1); + if (item->align == align_smallright) + x -= V_SmallStringWidth(string, item->flags) * (dupx - 1); + if (item->align == align_thinright) + x -= V_ThinStringWidth(string, item->flags) * (dupx - 1); + } item->x = x; item->y = y; @@ -410,6 +420,7 @@ void LUA_HUD_AddDrawNum( item->y = y; item->num = num; item->flags = flags; + CalcStringCoords(item, NULL); } void LUA_HUD_AddDrawPaddedNum( @@ -430,6 +441,7 @@ void LUA_HUD_AddDrawPaddedNum( item->num = num; item->digits = digits; item->flags = flags; + CalcStringCoords(item, NULL); } void LUA_HUD_AddDrawPingNum( @@ -450,6 +462,7 @@ void LUA_HUD_AddDrawPingNum( item->num = num; item->flags = flags; item->colormap = colormap; + CalcStringCoords(item, NULL); } void LUA_HUD_AddDrawFill( @@ -491,7 +504,8 @@ void LUA_HUD_AddDrawString( item->stroffset = CopyString(list, str); item->flags = flags; item->align = align; - CalcCoords(list, item); + if (item->align != align_fixed) + CalcStringCoords(item, str); } void LUA_HUD_AddDrawKartString( @@ -510,6 +524,7 @@ void LUA_HUD_AddDrawKartString( item->y = y; item->stroffset = CopyString(list, str); item->flags = flags; + CalcStringCoords(item, str); } void LUA_HUD_AddDrawLevelTitle( @@ -528,6 +543,7 @@ void LUA_HUD_AddDrawLevelTitle( item->y = y; item->stroffset = CopyString(list, str); item->flags = flags; + CalcStringCoords(item, str); } void LUA_HUD_AddFadeScreen( -- 2.54.0 From 995777c676657f45b0db2b5d158edc63a9b070cd Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Fri, 12 Apr 2024 22:36:23 +0200 Subject: [PATCH 07/54] Exclude string mode flags from olditem search --- src/lua_hudlib_drawlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index 4a58371c8..c621512ba 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -595,7 +595,7 @@ void LUA_HUD_DrawList(huddrawlist_h list) break; } drawitem_t *old = &list->olditems[j++]; - if (old->id == item->id) + if ((old->id & ~3) == (item->id & ~3)) { // gotcha! olditem = old; -- 2.54.0 From 1abf6a4ce1302d46073c28c8b97cecee8e19962a Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:17:06 +0200 Subject: [PATCH 08/54] Add interpolation docs to LUASTUFF --- LUASTUFF.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/LUASTUFF.md b/LUASTUFF.md index 05ca33bd0..96df6b5f8 100644 --- a/LUASTUFF.md +++ b/LUASTUFF.md @@ -52,6 +52,45 @@ Returns the displayplayer's HUD color. Returns true if colorization is enabled, false otherwise. +## v.interpolate(true) + +Enables HUD interpolation. Each call to a drawing function will have its coordinates interpolated +by assigning an unique ID to every call. +For example, three successive calls to `v.draw` will each have their own ID and interpolation offsets. +Pass `true` to enable interpolation, `false` to disable. + +Alternatively, pass a number to enable interpolation with the specified tag. +Tags allow HUD items drawn by the same call to a drawing function to be differentiated. +Valid tags range from 0-255. +For example, when iterating players, use a unique tag for each player to avoid artifacting: +```lua +for p in players.iterate do + -- enable interpolation, using player numbers as the tag + -- every draw will have different interp offsets per player + v.interpolate(#p) + + -- doesn't matter for unconditional draws like this one... + v.draw(...) + + -- but it does matter if there's a condition! + -- without tags, this patch would warp between players + -- whenever their `someVar` changes + if p.someVar then v.draw(...) end +end + +-- don't want interpolation anymore? then disable it +v.interpolate(false) +``` +NOTE: The default tag for `true` is 0. + +## v.interpString(true) + +Enables string interpolation mode. The next call to a drawing function will have its interpolation offsets +latched and reused for all following draw calls. +Disable with `false` when done. + +When using a custom string drawer, enable this mode to avoid interpolation artifacting when the string changes. + ## mobj.spritexscale, mobj.spriteyscale, mobj.spritexoffset, mobj.spriteyoffset, mobj.rollangle, mobj.sloperoll, mobj.rollmodel fields Same fields as in SRB2 2.2 -- 2.54.0 From 9cd1233c3224bf2000180a1ce866348c4bdd268f Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Thu, 23 May 2024 16:36:26 +0200 Subject: [PATCH 09/54] Dust this crap off a bit --- src/lua_hud.h | 10 +++++----- src/lua_hudlib_drawlist.c | 19 +++++++++++++------ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/lua_hud.h b/src/lua_hud.h index ccaed738d..5d1f41c83 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -42,11 +42,11 @@ enum hud { extern boolean hud_running; -extern boolean hud_interpolate; -extern UINT8 hud_interptag; -extern UINT32 hud_interpcounter; -extern boolean hud_interpstring; -extern boolean hud_interplatch; +extern boolean hud_interpolate; // interpolation enabled +extern UINT8 hud_interptag; // current tag +extern UINT32 hud_interpcounter; // number of HUD hooks ran +extern boolean hud_interpstring; // string mode +extern boolean hud_interplatch; // string mode was toggled boolean LUA_HudEnabled(enum hud option); diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index c621512ba..98f0d45e7 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -318,6 +318,7 @@ static void CalcFillCoords(drawitem_t *item) #define INTERP_LATCH 1 #define INTERP_STRING 2 +#define INTERP_FLAGS 3 // all bits combined static UINT64 GetItemId(void) { @@ -325,7 +326,7 @@ static UINT64 GetItemId(void) return 0; // leave bits 0 and 1 free for the string mode - UINT64 id = ((UINT64)gL->savedpc << 32) | (hud_interpcounter << 10) | (hud_interptag << 2); + UINT64 id = ((uintptr_t)gL->savedpc << 32) | (hud_interpcounter << 10) | (hud_interptag << 2); if (hud_interplatch) { @@ -580,7 +581,8 @@ void LUA_HUD_DrawList(huddrawlist_h list) drawitem_t *olditem = NULL; const char *itemstr = &list->strbuf[item->stroffset]; - if (item->id) { + if (item->id) + { // find the old one too // this is kinda cursed... we need to check every item // but stop when the first-checked item is reached again @@ -595,16 +597,19 @@ void LUA_HUD_DrawList(huddrawlist_h list) break; } drawitem_t *old = &list->olditems[j++]; - if ((old->id & ~3) == (item->id & ~3)) + if ((old->id & ~INTERP_FLAGS) == (item->id & ~INTERP_FLAGS)) // don't include flags in search { // gotcha! olditem = old; - if (item->id & INTERP_LATCH) { + if (item->id & INTERP_LATCH) + { lerpx = FixedMul(frac, item->x - olditem->x); lerpy = FixedMul(frac, item->y - olditem->y); latchitem = item; oldlatchitem = olditem; - } else if (!(item->id & INTERP_STRING)) { + } + else if (!(item->id & INTERP_STRING)) + { lerpx = FixedMul(frac, item->x - olditem->x); lerpy = FixedMul(frac, item->y - olditem->y); latchitem = NULL; @@ -614,7 +619,9 @@ void LUA_HUD_DrawList(huddrawlist_h list) if (j == stop) break; } - } else { + } + else + { lerpx = lerpy = 0; latchitem = NULL; } -- 2.54.0 From 8de340edbe374e5bbe121792a563f81b62078891 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 23 May 2024 19:11:11 +0200 Subject: [PATCH 10/54] allow gamepad dpad to hold scroll shit in menu aaa absolute arsepain cant wait to see this breaking kek --- src/d_main.c | 39 +++++++++++++++++++++++++++++++++++++++ src/m_menu.c | 40 +++++++++++++++++++++++++++++++++++++++- src/m_menu.h | 5 +++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 17325e904..f32c825f4 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -617,6 +617,7 @@ static void D_Display(void) // ========================================================================= tic_t rendergametic; +static int menuInputDelayTimer = 0; void D_SRB2Loop(void) { @@ -779,6 +780,44 @@ void D_SRB2Loop(void) } #endif + // this is absolutely awful and i hate it lmao + if (menuactive && (UPKEY || DOWNKEY || LEFTKEY || RIGHTKEY)) + { + event_t myev; + myev.type = ev_keydown; + + if (renderisnewtic) + { + menuInputDelayTimer++; + + if (menuInputDelayTimer >= 19) + { + if (UPKEY) + { + myev.data1 = KEY_UPARROW; + M_Responder(&myev); + } + else if (DOWNKEY) + { + myev.data1 = KEY_DOWNARROW; + M_Responder(&myev); + } + else if (LEFTKEY) + { + myev.data1 = KEY_LEFTARROW; + M_Responder(&myev); + } + else if (RIGHTKEY) + { + myev.data1 = KEY_RIGHTARROW; + M_Responder(&myev); + } + } + } + } + else + menuInputDelayTimer = 0; + // Fully completed frame made. finishprecise = I_GetPreciseTime(); if (!singletics) diff --git a/src/m_menu.c b/src/m_menu.c index cc7d45d33..2dd0a6a38 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3433,6 +3433,11 @@ static void Command_Manual_f(void) itemOn = 0; } +boolean UPKEY = false; +boolean DOWNKEY = false; +boolean LEFTKEY = false; +boolean RIGHTKEY = false; + // // M_Responder // @@ -3464,7 +3469,6 @@ boolean M_Responder(event_t *ev) { ch = ev->data1; - // added 5-2-98 remap virtual keys (mouse & joystick buttons) switch (ch) { case KEY_MOUSE1: @@ -3492,6 +3496,40 @@ boolean M_Responder(event_t *ev) ch = KEY_RIGHTARROW; break; } + + switch (ev->data1) + { + case KEY_HAT1: + UPKEY = true; + break; + case KEY_HAT1 + 1: + DOWNKEY = true; + break; + case KEY_HAT1 + 2: + LEFTKEY = true; + break; + case KEY_HAT1 + 3: + RIGHTKEY = true; + break; + } + } + else if (ev->type == ev_keyup) + { + switch (ev->data1) + { + case KEY_HAT1: + UPKEY = false; + break; + case KEY_HAT1 + 1: + DOWNKEY = false; + break; + case KEY_HAT1 + 2: + LEFTKEY = false; + break; + case KEY_HAT1 + 3: + RIGHTKEY = false; + break; + } } else if (menuactive) { diff --git a/src/m_menu.h b/src/m_menu.h index bba8d3db3..530622ffe 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -74,6 +74,11 @@ typedef enum } menumessagetype_t; void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype); +extern boolean UPKEY; +extern boolean DOWNKEY; +extern boolean LEFTKEY; +extern boolean RIGHTKEY; + typedef enum { M_NOT_WAITING, -- 2.54.0 From 9f692c1f6a9ba1fd8ca5b41f0a2ef214395f7c68 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 23 May 2024 19:25:04 +0200 Subject: [PATCH 11/54] change names to be less basic --- src/d_main.c | 12 ++++++------ src/m_menu.c | 28 ++++++++++++++-------------- src/m_menu.h | 8 ++++---- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index f32c825f4..bdfa7557d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -781,7 +781,7 @@ void D_SRB2Loop(void) #endif // this is absolutely awful and i hate it lmao - if (menuactive && (UPKEY || DOWNKEY || LEFTKEY || RIGHTKEY)) + if (menuactive && (DPADUPSCROLL || DPADDOWNSCROLL || DPADLEFTSCROLL || DPADRIGHTSCROLL)) { event_t myev; myev.type = ev_keydown; @@ -790,24 +790,24 @@ void D_SRB2Loop(void) { menuInputDelayTimer++; - if (menuInputDelayTimer >= 19) + if (menuInputDelayTimer >= 19) // TICRATE * ( (k+2) (1 - [wz + h + j - q]^2 - [(gk + 2g + k + 1)(h + j) + h - z]^2 - [16(k + 1)^3(k + 2)(n + 1)^2 + 1 - f^2]^2 calculated by my butt { - if (UPKEY) + if (DPADUPSCROLL) { myev.data1 = KEY_UPARROW; M_Responder(&myev); } - else if (DOWNKEY) + else if (DPADDOWNSCROLL) { myev.data1 = KEY_DOWNARROW; M_Responder(&myev); } - else if (LEFTKEY) + else if (DPADLEFTSCROLL) { myev.data1 = KEY_LEFTARROW; M_Responder(&myev); } - else if (RIGHTKEY) + else if (DPADRIGHTSCROLL) { myev.data1 = KEY_RIGHTARROW; M_Responder(&myev); diff --git a/src/m_menu.c b/src/m_menu.c index 2dd0a6a38..d7dc233b1 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3433,10 +3433,10 @@ static void Command_Manual_f(void) itemOn = 0; } -boolean UPKEY = false; -boolean DOWNKEY = false; -boolean LEFTKEY = false; -boolean RIGHTKEY = false; +boolean DPADUPSCROLL = false; +boolean DPADDOWNSCROLL = false; +boolean DPADLEFTSCROLL = false; +boolean DPADRIGHTSCROLL = false; // // M_Responder @@ -3497,37 +3497,37 @@ boolean M_Responder(event_t *ev) break; } - switch (ev->data1) + switch (ev->data1) // if you pressed it set those to true { case KEY_HAT1: - UPKEY = true; + DPADUPSCROLL = true; break; case KEY_HAT1 + 1: - DOWNKEY = true; + DPADDOWNSCROLL = true; break; case KEY_HAT1 + 2: - LEFTKEY = true; + DPADLEFTSCROLL = true; break; case KEY_HAT1 + 3: - RIGHTKEY = true; + DPADRIGHTSCROLL = true; break; } } else if (ev->type == ev_keyup) { - switch (ev->data1) + switch (ev->data1) // if you let go of those set those to false { case KEY_HAT1: - UPKEY = false; + DPADUPSCROLL = false; break; case KEY_HAT1 + 1: - DOWNKEY = false; + DPADDOWNSCROLL = false; break; case KEY_HAT1 + 2: - LEFTKEY = false; + DPADLEFTSCROLL = false; break; case KEY_HAT1 + 3: - RIGHTKEY = false; + DPADRIGHTSCROLL = false; break; } } diff --git a/src/m_menu.h b/src/m_menu.h index 530622ffe..a01c2ddef 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -74,10 +74,10 @@ typedef enum } menumessagetype_t; void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype); -extern boolean UPKEY; -extern boolean DOWNKEY; -extern boolean LEFTKEY; -extern boolean RIGHTKEY; +extern boolean DPADUPSCROLL; +extern boolean DPADDOWNSCROLL; +extern boolean DPADLEFTSCROLL; +extern boolean DPADRIGHTSCROLL; typedef enum { -- 2.54.0 From 837746c0a99bf540b18ef36de0b527675456cd21 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 25 May 2024 00:01:58 +0200 Subject: [PATCH 12/54] =?UTF-8?q?declare=20outside=20of=20l=C3=B6=C3=B6p?= =?UTF-8?q?=20also=20add=20const=20in=20r=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hardware/hw_main.c | 9 ++++++--- src/r_bsp.c | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index aedf40f34..afddd9365 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3530,14 +3530,16 @@ static boolean HWR_PortalCheckBBox(const fixed_t *bspcoord) static void HWR_RenderBSPNode(INT32 bspnum) { + const node_t *bsp; + INT32 side; ps_numbspcalls.value.i++; while (!(bspnum & NF_SUBSECTOR)) // Found a subsector? { - const node_t *bsp = &nodes[bspnum]; + bsp = &nodes[bspnum]; // Decide which side the view point is on. - INT32 side = R_PointOnSide(viewx, viewy, bsp); + side = R_PointOnSide(viewx, viewy, bsp); // Recursively divide front space. if (HWR_PortalCheckBBox(bsp->bbox[side])) @@ -3553,7 +3555,8 @@ static void HWR_RenderBSPNode(INT32 bspnum) // PORTAL CULLING if (portalclipline && portalcullsector) { - if (portalcullsector != subsectors[bspnum & ~NF_SUBSECTOR].sector) + sector_t *sect = subsectors[bspnum & ~NF_SUBSECTOR].sector; + if (sect != portalcullsector) return; portalcullsector = NULL; } diff --git a/src/r_bsp.c b/src/r_bsp.c index 83f530f2a..81569186d 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -1311,7 +1311,7 @@ INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside) void R_RenderBSPNode(INT32 bspnum) { - node_t *bsp; + const node_t *bsp; INT32 side; ps_numbspcalls.value.i++; -- 2.54.0 From d794de3e83ac0be660d0832fdc3f1584bd27140f Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 25 May 2024 02:21:04 +0200 Subject: [PATCH 13/54] Cull BSP behind a raised floor or lowered ceiling that covers the entire screen https://git.do.srb2.org/KartKrew/RingRacers/-/commit/7b8a564f69688515319ccd425f2b88ffe8b7b120 --- src/r_bsp.c | 25 +++++++++++++++++++------ src/r_bsp.h | 1 + src/r_segs.c | 25 ++++++++++++++----------- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 81569186d..02f4d8c83 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -39,6 +39,10 @@ drawseg_t *ds_p = NULL; // indicates doors closed wrt automap bugfix: INT32 doorclosed; +// A wall was drawn covering the whole screen, which means we +// can block off the BSP across that seg. +boolean g_walloffscreen; + boolean R_NoEncore(sector_t *sector, boolean ceiling) { boolean invertencore = (GETSECSPECIAL(sector->special, 2) == 15); @@ -163,7 +167,7 @@ crunch: // Clips the given range of columns, but does not include it in the clip list. // Does handle windows, e.g. LineDefs with upper and lower texture. // -static inline void R_ClipPassWallSegment(INT32 first, INT32 last) +static inline void R_ClipPassWallSegment(INT32 first, INT32 last, boolean soliddontrender) { cliprange_t *start; @@ -178,12 +182,14 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last) if (last < start->first - 1) { // Post is entirely visible (above start). - R_StoreWallRange(first, last); + if (!soliddontrender) + R_StoreWallRange(first, last); return; } // There is a fragment above *start. - R_StoreWallRange(first, start->first - 1); + if (!soliddontrender) + R_StoreWallRange(first, start->first - 1); } // Bottom contained in start? @@ -193,7 +199,8 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last) while (last >= (start+1)->first - 1) { // There is a fragment between two posts. - R_StoreWallRange(start->last + 1, (start+1)->first - 1); + if (!soliddontrender) + R_StoreWallRange(start->last + 1, (start+1)->first - 1); start++; if (last <= start->last) @@ -201,7 +208,8 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last) } // There is a fragment after *next. - R_StoreWallRange(start->last + 1, last); + if (!soliddontrender) + R_StoreWallRange(start->last + 1, last); } // @@ -579,10 +587,15 @@ static void R_AddLine(seg_t *line) return; clippass: - R_ClipPassWallSegment(x1, x2 - 1); + g_walloffscreen = false; + if (g_walloffscreen) + R_ClipPassWallSegment(x1, x2 - 1, true); + else + R_ClipPassWallSegment(x1, x2 - 1, false); return; clipsolid: + g_walloffscreen = false; R_ClipSolidWallSegment(x1, x2 - 1); } diff --git a/src/r_bsp.h b/src/r_bsp.h index f0db9066f..2803a90e4 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -32,6 +32,7 @@ extern INT32 checkcoord[12][4]; extern drawseg_t *drawsegs; extern drawseg_t *ds_p; extern INT32 doorclosed; +extern boolean g_walloffscreen; // BSP? void R_ClearClipSegs(void); diff --git a/src/r_segs.c b/src/r_segs.c index 8325e0fa0..6dd66e40f 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2596,23 +2596,26 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (toptexture) { - pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); - pixhighstep = -FixedMul (rw_scalestep,worldhigh); + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - if (backsector->c_slope) { - fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - pixhighstep = (topfracend-pixhigh)/(range); - } + pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); + pixhighstep = (topfracend-pixhigh)/(range); + + // If the lowest part of a ceiling stretching down covers the entire screen + if (min(pixhigh, topfracend)>>HEIGHTBITS >= viewheight-1) + g_walloffscreen = true; } if (bottomtexture) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); + pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); - pixlowstep = -FixedMul (rw_scalestep,worldlow); - if (backsector->f_slope) { - fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); - pixlowstep = (bottomfracend-pixlow)/(range); - } + pixlowstep = (bottomfracend-pixlow)/(range); + + // If the highest part of a floor stretching up covers the entire screen + if ((max(pixlow, bottomfracend)+HEIGHTUNIT-1)>>HEIGHTBITS <= 0) + g_walloffscreen = true; } { -- 2.54.0 From a17a5387ff294d0a0a8916f8f97be508d2f6aec7 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Sat, 25 May 2024 14:08:52 +0200 Subject: [PATCH 14/54] Rename interpString to interpLatch --- src/lua_hudlib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index bceb9ebc4..bc56e6688 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -1212,7 +1212,7 @@ static int libd_interpolate(lua_State *L) return 0; } -static int libd_interpString(lua_State *L) +static int libd_interpLatch(lua_State *L) { HUDONLY hud_interpstring = hud_interplatch = luaL_checkboolean(L, 1); @@ -1247,7 +1247,7 @@ static luaL_Reg lib_draw[] = { {"getHudColor", libd_getHudColor}, {"useColorHud", libd_useColorHud}, {"interpolate", libd_interpolate}, - {"interpString", libd_interpString}, + {"interpLatch", libd_interpLatch}, {NULL, NULL} }; -- 2.54.0 From 142c01f516f839d48e292ff115203b3b8f0677c0 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Sat, 25 May 2024 14:09:20 +0200 Subject: [PATCH 15/54] Update docs for interpLatch --- LUASTUFF.md | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/LUASTUFF.md b/LUASTUFF.md index 96df6b5f8..79e2a2545 100644 --- a/LUASTUFF.md +++ b/LUASTUFF.md @@ -83,12 +83,37 @@ v.interpolate(false) ``` NOTE: The default tag for `true` is 0. -## v.interpString(true) +## v.interpLatch(true) -Enables string interpolation mode. The next call to a drawing function will have its interpolation offsets -latched and reused for all following draw calls. -Disable with `false` when done. +Enables interpolation offset latching. The next call to a drawing function will have its lerp offsets +saved and reused for all following draw calls. Disable with `false` when done. +Interpolation cannot easily "snap" between two points; latching can help overcome this by manually +setting the lerp offsets. +```lua +v.interpolate(true) +-- X coordinate for the HUD item +-- every so often, this will wrap around to zero +local x = (leveltime*4) % 256 + +-- draw an interpolated patch, but... when X rolls back to zero, +-- the patch will slide all the way across the screen! +v.draw(x, 100, ...) + +-- this is where interpLatch comes into play +-- enable latching, then draw an invisible patch, +-- moving at the same speed as the visible patch +-- the exact coordinates don't matter, it just has to move at the right speed +v.interpLatch(true) +v.draw(leveltime*4, 0, v.cachePatch("K_TRNULL")) + +-- now we can draw the patch again, and when X becomes zero, +-- it'll snap right back without sliding across the screen +v.draw(x, 150, ...) + +-- don't forget to turn off latching! +v.interpLatch(false) +``` When using a custom string drawer, enable this mode to avoid interpolation artifacting when the string changes. ## mobj.spritexscale, mobj.spriteyscale, mobj.spritexoffset, mobj.spriteyoffset, mobj.rollangle, mobj.sloperoll, mobj.rollmodel fields -- 2.54.0 From 157c95a785ca006d710b5133e1623ae457ef1f2d Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 25 May 2024 14:37:30 +0200 Subject: [PATCH 16/54] super smol optimization to R_DrawRepeatMaskedColumn only maths once not twice lul --- src/r_segs.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 6dd66e40f..219b142e0 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -634,12 +634,15 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // Loop through R_DrawMaskedColumn calls static void R_DrawRepeatMaskedColumn(column_t *col) { - while (sprtopscreen < sprbotscreen) { + INT64 z; + while (sprtopscreen < sprbotscreen) + { R_DrawMaskedColumn(col); - if (sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow + z = sprtopscreen + (INT64)dc_texheight*spryscale; + if (z > (INT64)INT32_MAX) // prevent overflow sprtopscreen = INT32_MAX; else - sprtopscreen += dc_texheight*spryscale; + sprtopscreen = z; } } -- 2.54.0 From 518ac3ca280d24287a5c613c054efe03ee40d86c Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 25 May 2024 14:43:52 +0200 Subject: [PATCH 17/54] Turn of FBO downsampling when you turn off screen textures fbo downsampling needs those and if theyre disabled youre essentially seeing nothing at all lol --- src/hardware/hw_main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index afddd9365..24dd67a97 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -185,7 +185,12 @@ static void CV_screentextures_ONChange(void) { ONLY_IF_GL_LOADED if (cv_grscreentextures.value != 3) + { +#ifdef USE_FBO_OGL + CV_Set(&cv_grframebuffer, "Off"); +#endif CV_Set(&cv_grpaletterendering, "Off"); + } HWD.pfnSetSpecialState(HWD_SET_SCREEN_TEXTURES, cv_grscreentextures.value); } -- 2.54.0 From 8774b14fdf6645ead740befc08063b8343a8b3ba Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 25 May 2024 14:52:58 +0200 Subject: [PATCH 18/54] move some cvars to be registerrerd latur in ogl --- src/hardware/hw_main.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 24dd67a97..0a922bbf3 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5995,9 +5995,6 @@ void HWR_TogglePaletteRendering(void) //added by Hurdler: console varibale that are saved void HWR_AddCommands(void) { -#ifdef USE_FBO_OGL - CV_RegisterVar(&cv_grframebuffer); -#endif CV_RegisterVar(&cv_grfiltermode); CV_RegisterVar(&cv_granisotropicmode); CV_RegisterVar(&cv_grsolvetjoin); @@ -6007,9 +6004,7 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_fofzfightfix); CV_RegisterVar(&cv_splitwallfix); CV_RegisterVar(&cv_slopepegfix); - - CV_RegisterVar(&cv_grscreentextures); - + CV_RegisterVar(&cv_grrenderdistance); CV_RegisterVar(&cv_grfakecontrast); @@ -6037,6 +6032,12 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grpaletterendering); CV_RegisterVar(&cv_grpalettedepth); CV_RegisterVar(&cv_grflashpal); + +#ifdef USE_FBO_OGL + CV_RegisterVar(&cv_grframebuffer); +#endif + + CV_RegisterVar(&cv_grscreentextures); } // -------------------------------------------------------------------------- -- 2.54.0 From b310168c126c6437ada26ab20ce0061b63827486 Mon Sep 17 00:00:00 2001 From: Indev Date: Sat, 25 May 2024 16:39:16 +0300 Subject: [PATCH 19/54] Store hooks in a table with integer keys instead of registry with string keys --- src/lua_hooklib.c | 423 +++++++++++++++++++++++++++++----------------- 1 file changed, 271 insertions(+), 152 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index a1ea4fdaf..d7f89bffd 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -86,8 +86,6 @@ struct hook_s }; typedef struct hook_s* hook_p; -#define FMT_HOOKID "hook_%d" - // For each mobj type, a linked list to its thinker and collision hooks. // That way, we don't have to iterate through all the hooks. // We could do that with all other mobj hooks, but it would probably just be @@ -237,9 +235,9 @@ static int lib_addHook(lua_State *L) *lastp = hookp; // set the hook function in the registry. - lua_pushfstring(L, FMT_HOOKID, hook.id); + lua_getfield(L, LUA_REGISTRYINDEX, "hooks"); lua_pushvalue(L, 1); - lua_settable(L, LUA_REGISTRYINDEX); + lua_rawseti(L, -2, hook.id); return 0; } @@ -248,6 +246,10 @@ int LUA_HookLib(lua_State *L) memset(hooksAvailable,0,sizeof(UINT8[(hook_MAX/8)+1])); roothook = NULL; lua_register(L, "addHook", lib_addHook); + + lua_newtable(L); + lua_setfield(L, LUA_REGISTRYINDEX, "hooks"); + return 0; } @@ -255,26 +257,30 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) return false; I_Assert(mo->type < NUMMOBJTYPES); - + if (!(mobjhooks[MT_NULL] || mobjhooks[mo->type])) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic mobj hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == which) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -292,10 +298,9 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) if (hookp->type == which) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -317,20 +322,24 @@ boolean LUAh_PlayerHook(player_t *plr, enum hook which) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = playerhooks; hookp; hookp = hookp->next) if (hookp->type == which) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) LUA_PushUserdata(gL, plr, META_PLAYER); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -352,25 +361,30 @@ boolean LUAh_PlayerHook(player_t *plr, enum hook which) void LUAh_MapChange(INT16 mapnumber) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MapChange/8] & (1<<(hook_MapChange%8)))) return; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + lua_pushinteger(gL, mapnumber); for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_MapChange) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } } - + lua_settop(gL, 0); } @@ -378,22 +392,27 @@ void LUAh_MapChange(INT16 mapnumber) void LUAh_MapLoad(void) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MapLoad/8] & (1<<(hook_MapLoad%8)))) return; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + lua_pushinteger(gL, gamemap); for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_MapLoad) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } } lua_settop(gL, 0); @@ -403,25 +422,30 @@ void LUAh_MapLoad(void) void LUAh_PlayerJoin(int playernum) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerJoin/8] & (1<<(hook_PlayerJoin%8)))) return; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + lua_pushinteger(gL, playernum); for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerJoin) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } } - + lua_settop(gL, 0); } @@ -429,22 +453,26 @@ void LUAh_PlayerJoin(int playernum) void LUAh_PreThinkFrame(void) { hook_p hookp; + int HOOKSINDEX; // variables used by perf stats int hook_index = 0; precise_t time_taken = 0; if (!gL || !(hooksAvailable[hook_PreThinkFrame/8] & (1<<(hook_PreThinkFrame%8)))) return; - + lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type == hook_PreThinkFrame) - { + { if (cv_perfstats.value == 4) time_taken = I_GetPreciseTime(); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); @@ -456,22 +484,22 @@ void LUAh_PreThinkFrame(void) lua_Debug ar; time_taken = I_GetPreciseTime() - time_taken; // we need the function, let's just retrieve it again - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_getinfo(gL, ">S", &ar); PS_SetPreThinkFrameHookInfo(hook_index, time_taken, ar.short_src); hook_index++; } } - + } - lua_pop(gL, 1); // Pop error handler + lua_pop(gL, 2); // Pop error handler and hooks table } // Hook for frame (after mobj and player thinkers) void LUAh_ThinkFrame(void) { hook_p hookp; + int HOOKSINDEX; // variables used by perf stats int hook_index = 0; precise_t time_taken = 0; @@ -481,14 +509,17 @@ void LUAh_ThinkFrame(void) lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type == hook_ThinkFrame) { if (cv_perfstats.value == 3) time_taken = I_GetPreciseTime(); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); @@ -500,8 +531,7 @@ void LUAh_ThinkFrame(void) lua_Debug ar; time_taken = I_GetPreciseTime() - time_taken; // we need the function, let's just retrieve it again - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_getinfo(gL, ">S", &ar); PS_SetThinkFrameHookInfo(hook_index, time_taken, ar.short_src); hook_index++; @@ -509,13 +539,14 @@ void LUAh_ThinkFrame(void) } } - lua_pop(gL, 1); // Pop error handler + lua_pop(gL, 2); // Pop error handler and hooks table } // Hook for frame (at end of tick, ie after overlays, precipitation, specials) void LUAh_PostThinkFrame(void) { hook_p hookp; + int HOOKSINDEX; // variables used by perf stats int hook_index = 0; precise_t time_taken = 0; @@ -524,14 +555,17 @@ void LUAh_PostThinkFrame(void) lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type == hook_PostThinkFrame) { if (cv_perfstats.value == 5) time_taken = I_GetPreciseTime(); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); @@ -543,8 +577,7 @@ void LUAh_PostThinkFrame(void) lua_Debug ar; time_taken = I_GetPreciseTime() - time_taken; // we need the function, let's just retrieve it again - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_getinfo(gL, ">S", &ar); PS_SetPostThinkFrameHookInfo(hook_index, time_taken, ar.short_src); hook_index++; @@ -552,25 +585,29 @@ void LUAh_PostThinkFrame(void) } } - lua_pop(gL, 1); // Pop error handler + lua_pop(gL, 2); // Pop error handler and hooks table } // Hook for Y_Ticker void LUAh_IntermissionThinker(void) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_IntermissionThinker/8] & (1<<(hook_IntermissionThinker%8)))) return; - lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_pushcfunction(gL, LUA_GetErrorMessage);; + + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type == hook_IntermissionThinker) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); @@ -580,25 +617,29 @@ void LUAh_IntermissionThinker(void) } } - lua_pop(gL, 1); // Pop error handler + lua_pop(gL, 2); // Pop error handler and hooks table } // Hook for Y_VoteTicker void LUAh_VoteThinker(void) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_VoteThinker/8] & (1<<(hook_VoteThinker%8)))) return; lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type == hook_VoteThinker) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); @@ -608,7 +649,7 @@ void LUAh_VoteThinker(void) } } - lua_pop(gL, 1); // Pop error handler + lua_pop(gL, 2); // Pop error handler and hooks table } @@ -617,29 +658,33 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) { hook_p hookp; UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. + int HOOKSINDEX; if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) return 0; I_Assert(thing1->type < NUMMOBJTYPES); - + if (!(mobjcollidehooks[MT_NULL] || mobjcollidehooks[thing1->type])) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic mobj collision hooks for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == which) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, thing1, META_MOBJ); LUA_PushUserdata(gL, thing2, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -663,13 +708,12 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) if (hookp->type == which) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, thing1, META_MOBJ); LUA_PushUserdata(gL, thing2, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -698,25 +742,29 @@ boolean LUAh_MobjThinker(mobj_t *mo) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MobjThinker/8] & (1<<(hook_MobjThinker%8)))) return false; I_Assert(mo->type < NUMMOBJTYPES); - + if (!(mobjthinkerhooks[MT_NULL] || mobjthinkerhooks[mo->type])) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic mobj thinker hooks for (hookp = mobjthinkerhooks[MT_NULL]; hookp; hookp = hookp->next) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -733,10 +781,9 @@ boolean LUAh_MobjThinker(mobj_t *mo) for (hookp = mobjthinkerhooks[mo->type]; hookp; hookp = hookp->next) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -759,29 +806,33 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_TouchSpecial/8] & (1<<(hook_TouchSpecial%8)))) return false; I_Assert(special->type < NUMMOBJTYPES); - - if (!(mobjhooks[MT_NULL] || mobjhooks[special->type])) + + if (!(mobjhooks[MT_NULL] || mobjhooks[special->type])) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic touch special hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == hook_TouchSpecial) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, special, META_MOBJ); LUA_PushUserdata(gL, toucher, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -800,13 +851,12 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) if (hookp->type == hook_TouchSpecial) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, special, META_MOBJ); LUA_PushUserdata(gL, toucher, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -830,31 +880,35 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_ShouldDamage/8] & (1<<(hook_ShouldDamage%8)))) return 0; I_Assert(target->type < NUMMOBJTYPES); - + if (!(mobjhooks[MT_NULL] || mobjhooks[target->type])) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic should damage hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == hook_ShouldDamage) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); @@ -880,15 +934,14 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 if (hookp->type == hook_ShouldDamage) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); @@ -919,31 +972,35 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MobjDamage/8] & (1<<(hook_MobjDamage%8)))) return false; I_Assert(target->type < NUMMOBJTYPES); - + if (!(mobjhooks[MT_NULL] || mobjhooks[target->type])) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic mobj damage hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == hook_MobjDamage) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); @@ -964,15 +1021,14 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 if (hookp->type == hook_MobjDamage) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); @@ -998,29 +1054,33 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MobjDeath/8] & (1<<(hook_MobjDeath%8)))) return false; I_Assert(target->type < NUMMOBJTYPES); - + if (!(mobjhooks[MT_NULL] || mobjhooks[target->type])) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic mobj death hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == hook_MobjDeath) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1040,14 +1100,13 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) if (hookp->type == hook_MobjDeath) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1072,22 +1131,26 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_BotTiccmd/8] & (1<<(hook_BotTiccmd%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_BotTiccmd) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, bot, META_PLAYER); LUA_PushUserdata(gL, cmd, META_TICCMD); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -1112,23 +1175,27 @@ boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerCmd/8] & (1<<(hook_PlayerCmd%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + hook_cmd_running = true; for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerCmd) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, cmd, META_TICCMD); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -1153,23 +1220,27 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_BotAI && (hookp->s.skinname == NULL || !strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name))) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, sonic, META_MOBJ); LUA_PushUserdata(gL, tails, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 8, 1)) { @@ -1181,10 +1252,10 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) } // This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails. - if (lua_istable(gL, 2+1)) { + if (lua_istable(gL, -8)) { boolean forward=false, backward=false, left=false, right=false, strafeleft=false, straferight=false, jump=false, spin=false; #define CHECKFIELD(field) \ - lua_getfield(gL, 2+1, #field);\ + lua_getfield(gL, -8, #field);\ if (lua_toboolean(gL, -1))\ field = true;\ lua_pop(gL, 1); @@ -1200,7 +1271,7 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) #undef CHECKFIELD B_KeysToTiccmd(tails, cmd, forward, backward, left, right, strafeleft, straferight, jump, spin); } else - B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, 2+1), lua_toboolean(gL, 2+2), lua_toboolean(gL, 2+3), lua_toboolean(gL, 2+4), lua_toboolean(gL, 2+5), lua_toboolean(gL, 2+6), lua_toboolean(gL, 2+7), lua_toboolean(gL, 2+8)); + B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, -8), lua_toboolean(gL, -7), lua_toboolean(gL, -6), lua_toboolean(gL, -5), lua_toboolean(gL, -4), lua_toboolean(gL, -3), lua_toboolean(gL, -2), lua_toboolean(gL, -1)); lua_pop(gL, 8); hooked = true; @@ -1215,30 +1286,34 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_LinedefExecute/8] & (1<<(hook_LinedefExecute%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next) if (!strcmp(hookp->s.funcname, line->text)) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, line, META_LINE); LUA_PushUserdata(gL, mo, META_MOBJ); LUA_PushUserdata(gL, sector, META_SECTOR); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); if (lua_pcall(gL, 3, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } hooked = true; } @@ -1254,16 +1329,21 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerMsg/8] & (1<<(hook_PlayerMsg%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerMsg) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c @@ -1285,8 +1365,7 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute) else lua_pushboolean(gL, false); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); @@ -1313,24 +1392,28 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_HurtMsg/8] & (1<<(hook_HurtMsg%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_HurtMsg && (hookp->s.mt == MT_NULL || (inflictor && hookp->s.mt == inflictor->type))) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1354,61 +1437,69 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc) { hook_p hookp; int errorhandlerindex; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_NetVars/8] & (1<<(hook_NetVars%8)))) return; // stack: tables I_Assert(lua_gettop(gL) > 0); I_Assert(lua_istable(gL, -1)); - + lua_pushcfunction(gL, LUA_GetErrorMessage); errorhandlerindex = lua_gettop(gL); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // tables becomes an upvalue of archFunc - lua_pushvalue(gL, -2); + lua_pushvalue(gL, -3); lua_pushcclosure(gL, archFunc, 1); // stack: tables, archFunc for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_NetVars) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); // archFunc if (lua_pcall(gL, 1, 0, errorhandlerindex)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } } - lua_pop(gL, 2); // Pop archFunc and error handler + lua_pop(gL, 3); // Pop archFunc, error handler and hooks table // stack: tables } void LUAh_PlayerQuit(player_t *plr, int reason) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8)))) return; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerQuit) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit lua_pushinteger(gL, reason); // Reason for quitting } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } } @@ -1421,6 +1512,7 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MusicChange/8] & (1<<(hook_MusicChange%8)))) return false; @@ -1428,11 +1520,14 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_MusicChange) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushstring(gL, oldname); lua_pushstring(gL, newname); lua_pushinteger(gL, *mflags); @@ -1480,26 +1575,30 @@ UINT8 LUAh_ShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_ShouldSpin/8] & (1<<(hook_ShouldSpin%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to check for mobj type because it will always be MT_PLAYER in this case. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_ShouldSpin) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1529,26 +1628,30 @@ UINT8 LUAh_ShouldExplode(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_ShouldExplode/8] & (1<<(hook_ShouldExplode%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to check for mobj type because it will always be MT_PLAYER in this case. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_ShouldExplode) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1578,26 +1681,30 @@ UINT8 LUAh_ShouldSquish(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_ShouldSquish/8] & (1<<(hook_ShouldSquish%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to check for mobj type because it will always be MT_PLAYER in this case. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_ShouldSquish) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1627,26 +1734,30 @@ boolean LUAh_PlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerSpin/8] & (1<<(hook_PlayerSpin%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to look for target->type because it will always be MT_PLAYER. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerSpin) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1670,26 +1781,30 @@ boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerSquish/8] & (1<<(hook_PlayerSquish%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to look for target->type because it will always be MT_PLAYER. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerSquish) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1713,26 +1828,30 @@ boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerExplode/8] & (1<<(hook_PlayerExplode%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to look for target->type because it will always be MT_PLAYER. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerExplode) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1749,4 +1868,4 @@ boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source) } lua_settop(gL, 0); return hooked; -} \ No newline at end of file +} -- 2.54.0 From 05a56512606ce4c1e04b4fea0075aa2dd71bcf41 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy <86008856+GenericHeroGuy@users.noreply.github.com> Date: Sat, 25 May 2024 17:05:08 +0200 Subject: [PATCH 20/54] Finishing touches Some cleanup, also interpolate drawfill size (dunno why it wasn't before) --- src/lua_hudlib_drawlist.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index 98f0d45e7..ff98c6e8b 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -318,7 +318,7 @@ static void CalcFillCoords(drawitem_t *item) #define INTERP_LATCH 1 #define INTERP_STRING 2 -#define INTERP_FLAGS 3 // all bits combined +#define INTERP_FLAGMASK 0x3 static UINT64 GetItemId(void) { @@ -587,17 +587,15 @@ void LUA_HUD_DrawList(huddrawlist_h list) // this is kinda cursed... we need to check every item // but stop when the first-checked item is reached again size_t stop = j; - while(true) + do { if (j == list->olditems_len) { - // wrap around j = 0; - if (j == stop) // i'm dumb - break; + continue; } drawitem_t *old = &list->olditems[j++]; - if ((old->id & ~INTERP_FLAGS) == (item->id & ~INTERP_FLAGS)) // don't include flags in search + if ((old->id & ~INTERP_FLAGMASK) == (item->id & ~INTERP_FLAGMASK)) { // gotcha! olditem = old; @@ -616,9 +614,8 @@ void LUA_HUD_DrawList(huddrawlist_h list) } break; } - if (j == stop) - break; } + while (j != stop); } else { @@ -653,7 +650,7 @@ void LUA_HUD_DrawList(huddrawlist_h list) V_DrawPingNum(LERPS(x), LERPS(y), item->flags, item->num, item->colormap); break; case DI_DrawFill: - V_DrawFill(LERPS(x), LERPS(y), item->w, item->h, item->c); + V_DrawFill(LERPS(x), LERPS(y), LERP(w), LERP(h), item->c); break; case DI_DrawString: switch(item->align) -- 2.54.0 From ddddc7a89804e3c3fe1cf2732ff3d2bacc63a9d5 Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 28 May 2024 00:52:09 +0200 Subject: [PATCH 21/54] draw a black screen instead of "nothing" during wipes on disabled screentextures should resolve the intense flashing that can occur --- src/hardware/hw_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 0a922bbf3..d2a5b8189 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6247,6 +6247,12 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum) lumpnum_t lumpnum; size_t lsize; + if (cv_grscreentextures.value == 0) + { + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // just draw a black screen instead of flashing and crap + return; + } + if (wipenum > 99 || scrnnum > 99) // not a valid wipe number return; // shouldn't end up here really, the loop should've stopped running beforehand -- 2.54.0 From 67aa71170fea7b5a7f006a589b02b5cb4bf8bce2 Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 28 May 2024 00:52:40 +0200 Subject: [PATCH 22/54] when not using screentextures draw kart bg on intermission screen --- src/hardware/hw_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d2a5b8189..fc137c109 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6238,7 +6238,12 @@ void HWR_EndScreenWipe(void) void HWR_DrawIntermissionBG(void) { - HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0); + patch_t *bgpatch = W_CachePatchName("SRB2BACK", PU_CACHE); + + if (cv_grscreentextures.value != 3) + V_DrawPatchFill(bgpatch); // use the neato kart bg for intermission on disabled screen textures + else + HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0); } void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum) -- 2.54.0 From 4847e4e3cb19a60c9b38a0e5bb2ad880e199f4c3 Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 28 May 2024 22:22:48 +0200 Subject: [PATCH 23/54] that should be there lul --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index dfe05dbdf..183b6b93e 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2029,6 +2029,7 @@ void R_AddPrecipitationSprites(void) INT32 xl, xh, yl, yh, bx, by; precipmobj_t *th, *next; + // no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off if (drawdist == 0) { return; @@ -2036,7 +2037,6 @@ void R_AddPrecipitationSprites(void) R_GetRenderBlockMapDimensions(drawdist, &xl, &xh, &yl, &yh); - // no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off for (bx = xl; bx <= xh; bx++) { for (by = yl; by <= yh; by++) -- 2.54.0 From 455bbe47c283620d182e264b24931e814fcc7cc9 Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 28 May 2024 22:38:20 +0200 Subject: [PATCH 24/54] smth smth encore magic numbers idk --- src/hardware/hw_cache.c | 8 +++++--- src/hardware/hw_main.c | 4 ++-- src/r_draw8.c | 4 ++-- src/r_main.h | 3 +++ src/r_plane.c | 4 ++-- src/r_segs.c | 16 ++++++++-------- src/r_things.c | 4 ++-- 7 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 848f8243f..2a5ec4ff5 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -26,6 +26,7 @@ #include "../z_zone.h" #include "../v_video.h" #include "../r_draw.h" +#include "../r_main.h" #include "../r_patch.h" // patch rotation INT32 patchformat = GL_TEXFMT_AP_88; // use alpha for holes @@ -344,7 +345,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe #ifdef GLENCORE if (encoremap && !noencore) - grtex->mipmap.colormap += (256*32); + grtex->mipmap.colormap += COLORMAP_REMAPOFFSET; #endif blockwidth = texture->width; @@ -647,7 +648,7 @@ void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap) #ifdef GLENCORE if (!noencoremap && encoremap) - grmip->colormap += (256*32); + grmip->colormap += COLORMAP_REMAPOFFSET; #endif if (!grmip->downloaded && !grmip->data) @@ -729,7 +730,8 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) { GLMipmap_t *grmip, *newmip; - if (colormap == colormaps || colormap == NULL) + // Blatant hack for encore colormapping aside... + if (colormap == colormaps || colormap == NULL || colormap == (const UINT8*)(COLORMAP_REMAPOFFSET)) { // Load the default (green) color in doom cache (temporary?) AND hardware cache HWR_GetPatch(gpatch); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index fc137c109..4893bd5f3 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5285,7 +5285,7 @@ void HWR_ProjectSprite(mobj_t *thing) vis->colormap = colormaps; #ifdef GLENCORE if (encoremap && !(thing->flags & MF_DONTENCOREMAP)) - vis->colormap += (256*32); + vis->colormap += COLORMAP_REMAPOFFSET; #endif } @@ -5416,7 +5416,7 @@ void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) #ifdef GLENCORE if (encoremap && !(thing->flags & MF_DONTENCOREMAP)) - vis->colormap += (256*32); + vis->colormap += COLORMAP_REMAPOFFSET; #endif // set top/bottom coords diff --git a/src/r_draw8.c b/src/r_draw8.c index 93a0796a3..f3ebf0ff9 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -1696,7 +1696,7 @@ void R_DrawColumnShadowed_8(void) { dc_colormap = dc_lightlist[i].rcolormap; if (encoremap) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; if (solid && dc_yl < bheight) dc_yl = bheight; continue; @@ -1714,7 +1714,7 @@ void R_DrawColumnShadowed_8(void) dc_colormap = dc_lightlist[i].rcolormap; if (encoremap) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; } dc_yh = realyh; if (dc_yl <= realyh) diff --git a/src/r_main.h b/src/r_main.h index 56e351138..7c2249873 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -64,6 +64,9 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // There a 0-31, i.e. 32 LUT in the COLORMAP lump. #define NUMCOLORMAPS 32 +#define COLORMAP_SIZE (256*LIGHTLEVELS) +#define COLORMAP_REMAPOFFSET COLORMAP_SIZE + // Utility functions. INT32 R_PointOnSide(fixed_t x, fixed_t y, const node_t *node); INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line); diff --git a/src/r_plane.c b/src/r_plane.c index f89e10330..6bd6f212d 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -295,7 +295,7 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) ds_colormap = planezlight[pindex]; } if (encoremap && !currentplane->noencore) - ds_colormap += (256*32); + ds_colormap += COLORMAP_REMAPOFFSET; if (currentplane->extra_colormap) ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps); @@ -675,7 +675,7 @@ static void R_DrawSkyPlane(visplane_t *pl) // by INVUL inverse mapping. dc_colormap = colormaps; if (encoremap) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; dc_texturemid = skytexturemid; dc_texheight = textureheight[skytexture] >>FRACBITS; diff --git a/src/r_segs.c b/src/r_segs.c index 219b142e0..4a231938b 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -208,7 +208,7 @@ static void R_DrawWallSplats(void) pindex = MAXLIGHTSCALE - 1; dc_colormap = walllights[pindex]; if (encoremap && !(seg->linedef->flags & ML_TFERLINE)) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; if (frontsector->extra_colormap) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -573,7 +573,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { dc_colormap = rlight->rcolormap; if (encoremap && !(ldef->flags & ML_TFERLINE)) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; continue; } @@ -594,7 +594,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) windowtop = windowbottom + 1; dc_colormap = rlight->rcolormap; if (encoremap && !(ldef->flags & ML_TFERLINE)) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; } windowbottom = realbot; if (windowtop < windowbottom) @@ -612,7 +612,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_colormap = walllights[pindex]; if (encoremap && !(ldef->flags & ML_TFERLINE)) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; if (frontsector->extra_colormap) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -1107,7 +1107,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { dc_colormap = rlight->rcolormap; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; } if (solid && windowtop < bheight) windowtop = bheight; @@ -1139,7 +1139,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { dc_colormap = rlight->rcolormap; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; } } windowbottom = sprbotscreen; @@ -1160,7 +1160,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) dc_colormap = walllights[pindex]; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -1396,7 +1396,7 @@ static void R_RenderSegLoop (void) dc_colormap = walllights[pindex]; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; dc_x = rw_x; dc_iscale = 0xffffffffu / (unsigned)rw_scale; diff --git a/src/r_things.c b/src/r_things.c index 183b6b93e..933181ce7 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -816,7 +816,7 @@ static void R_DrawVisSprite(vissprite_t *vis) dc_colormap = colormaps; if (encoremap && !vis->mobj->color && !(vis->mobj->flags & MF_DONTENCOREMAP)) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; dc_texturemid = vis->texturemid; dc_texheight = 0; @@ -939,7 +939,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) dc_colormap = colormaps; if (encoremap) - dc_colormap += (256*32); + dc_colormap += COLORMAP_REMAPOFFSET; dc_iscale = FixedDiv(FRACUNIT, vis->scale); dc_texturemid = vis->texturemid; -- 2.54.0 From 37d3e2ae1a679f437c6333d7b58074d9e84801d1 Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 28 May 2024 20:02:54 +0200 Subject: [PATCH 25/54] scale sprite draw distance with mapobjscale --- src/hardware/hw_main.c | 8 ++++---- src/r_things.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 4893bd5f3..750b245fc 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4795,12 +4795,12 @@ void HWR_AddSprites(sector_t *sec) { // Use the smaller setting if (cv_drawdist.value) - limit_dist = min(current_bsp_culling_distance, cv_drawdist.value << FRACBITS); + limit_dist = min(current_bsp_culling_distance, (fixed_t)(cv_drawdist.value) * mapobjectscale); else limit_dist = current_bsp_culling_distance; } else - limit_dist = cv_drawdist.value << FRACBITS; + limit_dist = (fixed_t)(cv_drawdist.value) * mapobjectscale; // Handle all things in sector. // If a limit exists, handle things a tiny bit different. @@ -4903,9 +4903,9 @@ static void HWR_AddPrecipitationSprites(void) precipmobj_t *th; if (current_bsp_culling_distance) - drawdist = min(current_bsp_culling_distance, cv_drawdist_precip.value * mapobjectscale); + drawdist = min(current_bsp_culling_distance, (fixed_t)(cv_drawdist_precip.value) * mapobjectscale); else - drawdist = cv_drawdist_precip.value * mapobjectscale; + drawdist = (fixed_t)(cv_drawdist_precip.value) * mapobjectscale; // No to infinite precipitation draw distance. if (drawdist == 0) diff --git a/src/r_things.c b/src/r_things.c index 933181ce7..64468ffa9 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1932,7 +1932,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) // Handle all things in sector. // If a limit exists, handle things a tiny bit different. - if ((limit_dist = (fixed_t)(/*(maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : */cv_drawdist.value) << FRACBITS)) + if ((limit_dist = (fixed_t)(cv_drawdist.value) * mapobjectscale)) { for (thing = sec->thinglist; thing; thing = thing->snext) { @@ -2024,7 +2024,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) // void R_AddPrecipitationSprites(void) { - const fixed_t drawdist = cv_drawdist_precip.value * mapobjectscale; + const fixed_t drawdist = (fixed_t)(cv_drawdist_precip.value) * mapobjectscale; INT32 xl, xh, yl, yh, bx, by; precipmobj_t *th, *next; -- 2.54.0 From faa5dbd0e73057bb19cacfa7daa3a18d86f260ee Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 28 May 2024 20:55:03 +0200 Subject: [PATCH 26/54] split sprite draw loops so crap doesent constantly check for papersprites on all sprites --- src/r_things.c | 61 ++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 64468ffa9..1ea932ac3 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -724,9 +724,7 @@ static void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) static void R_DrawVisSprite(vissprite_t *vis) { column_t *column; -#ifdef RANGECHECK INT32 texturecolumn; -#endif fixed_t frac; patch_t *patch = vis->patch; fixed_t this_scale = vis->thingscale; @@ -874,12 +872,16 @@ static void R_DrawVisSprite(vissprite_t *vis) } #endif - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) +#define CLAMP(x, min_val, max_val) ((x) < (min_val) ? (min_val) : ((x) > (max_val) ? (max_val) : (x))) + + // Split drawing loops for paper and non-paper to reduce conditional checks per sprite + if (vis->scalestep) { fixed_t scalestep = FixedMul(vis->scalestep, vis->spriteyscale); - if (vis->scalestep) // currently papersprites only - { + // Papersprite drawing loop + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) + { #ifndef RANGECHECK if ((frac>>FRACBITS) < 0 || (frac>>FRACBITS) >= SHORT(patch->width)) // if this doesn't work i'm removing papersprites break; @@ -887,22 +889,30 @@ static void R_DrawVisSprite(vissprite_t *vis) sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); dc_iscale = (0xffffffffu / (unsigned)spryscale); spryscale += scalestep; + + texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1); + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + + if (vis->vflip) + R_DrawFlippedMaskedColumn(column, patch->height); + else + R_DrawMaskedColumn(column); } -#ifdef RANGECHECK - texturecolumn = frac>>FRACBITS; - - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - I_Error("R_DrawSpriteRange: bad texturecolumn"); - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); -#else - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); -#endif - if (vis->vflip) - R_DrawFlippedMaskedColumn(column, patch->height); - else - R_DrawMaskedColumn(column); } + else + { + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) + { + texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1); + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + if (vis->vflip) + R_DrawFlippedMaskedColumn(column, patch->height); + else + R_DrawMaskedColumn(column); + } + } +#undef CLAMP colfunc = basecolfunc; dc_hires = 0; @@ -914,9 +924,7 @@ static void R_DrawVisSprite(vissprite_t *vis) static void R_DrawPrecipitationVisSprite(vissprite_t *vis) { column_t *column; -#ifdef RANGECHECK INT32 texturecolumn; -#endif fixed_t frac; patch_t *patch; INT64 overflow_test; @@ -956,20 +964,15 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) if (vis->x2 >= vid.width) vis->x2 = vid.width-1; +#define CLAMP(x, min_val, max_val) ((x) < (min_val) ? (min_val) : ((x) > (max_val) ? (max_val) : (x))) for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { -#ifdef RANGECHECK - texturecolumn = frac>>FRACBITS; - - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - I_Error("R_DrawPrecipitationSpriteRange: bad texturecolumn"); - + texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1); column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); -#else - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); -#endif + R_DrawMaskedColumn(column); } +#undef CLAMP colfunc = basecolfunc; } -- 2.54.0 From 040ddb1f40b17c84427c95a241a102c0e8f633bb Mon Sep 17 00:00:00 2001 From: Indev Date: Thu, 30 May 2024 19:23:14 +0300 Subject: [PATCH 27/54] Revert "Revert "Don't traverse the entire HOME directory to find wads"" This reverts commit 443905ffb3dd8904c395c9c50570ccc17b42dd27. --- src/sdl/i_system.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 9574d6ec5..48e513afc 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -4039,12 +4039,16 @@ static const char *locateWad(void) #endif #ifndef NOHOME // find in $HOME - I_OutputMsg(",HOME"); + I_OutputMsg(",HOME/" DEFAULTDIR); if ((envstr = I_GetEnv("HOME")) != NULL) { + char *tmp = malloc(strlen(envstr) + sizeof(DEFAULTDIR)); + strcpy(tmp, envstr); + strcat(tmp, DEFAULTDIR); WadPath = searchWad(envstr); if (WadPath) return WadPath; + free(tmp); } #endif #ifdef DEFAULTSEARCHPATH1 -- 2.54.0 From 6269c7c827feed85ef1bb246b4bed51c565bc6d5 Mon Sep 17 00:00:00 2001 From: Indev Date: Thu, 30 May 2024 19:32:18 +0300 Subject: [PATCH 28/54] Use tmp variable for searchWad since envstr doesn't get changed --- src/sdl/i_system.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 48e513afc..7a5f79f58 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -4042,13 +4042,14 @@ static const char *locateWad(void) I_OutputMsg(",HOME/" DEFAULTDIR); if ((envstr = I_GetEnv("HOME")) != NULL) { - char *tmp = malloc(strlen(envstr) + sizeof(DEFAULTDIR)); + char *tmp = malloc(strlen(envstr) + sizeof(PATHSEP) + sizeof(DEFAULTDIR)); strcpy(tmp, envstr); + strcat(tmp, PATHSEP); strcat(tmp, DEFAULTDIR); - WadPath = searchWad(envstr); + WadPath = searchWad(tmp); + free(tmp); if (WadPath) return WadPath; - free(tmp); } #endif #ifdef DEFAULTSEARCHPATH1 -- 2.54.0 From dc03359f3a44481338715be809ebf9038bd47e6f Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 30 May 2024 19:59:01 +0200 Subject: [PATCH 29/54] theres no value 3 oops i shouldnt do stuff after waking up at 4 in the morning lol --- src/hardware/hw_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 750b245fc..3cf998d84 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -184,7 +184,7 @@ static void CV_anisotropic_ONChange(void) static void CV_screentextures_ONChange(void) { ONLY_IF_GL_LOADED - if (cv_grscreentextures.value != 3) + if (cv_grscreentextures.value != 2) { #ifdef USE_FBO_OGL CV_Set(&cv_grframebuffer, "Off"); @@ -6240,10 +6240,10 @@ void HWR_DrawIntermissionBG(void) { patch_t *bgpatch = W_CachePatchName("SRB2BACK", PU_CACHE); - if (cv_grscreentextures.value != 3) - V_DrawPatchFill(bgpatch); // use the neato kart bg for intermission on disabled screen textures - else + if (cv_grscreentextures.value == 2) HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0); + else + V_DrawPatchFill(bgpatch); // use the neato kart bg for intermission on disabled screen textures } void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum) -- 2.54.0 From b01a2836ea51bfd8d52b8b1116df8ee93052db3d Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 1 Jun 2024 16:29:40 +0200 Subject: [PATCH 30/54] cleanup some super old stuff that did nothing lul --- src/hardware/hw_glob.h | 2 -- src/r_defs.h | 9 +-------- src/r_patch.c | 4 ++-- src/r_things.c | 42 +++++++++++++++--------------------------- src/r_things.h | 2 -- 5 files changed, 18 insertions(+), 41 deletions(-) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index a5b66a429..542a99b33 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -30,11 +30,9 @@ typedef struct gr_vissprite_s float gz, gzt; float tz, ty; float scale; - //lumpnum_t patchlumpnum; float spritexscale, spriteyscale; float spritexoffset, spriteyoffset; UINT32 renderflags; - UINT8 rotateflags; GLPatch_t *gpatch; boolean flip; UINT8 translucency; //alpha level 0-255 diff --git a/src/r_defs.h b/src/r_defs.h index 81e3f0c3a..40a4db023 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -649,15 +649,8 @@ typedef struct INT16 leftoffset; // pixels to the left of origin INT16 topoffset; // pixels below the origin INT32 columnofs[8]; // only [width] used - UINT8 *columns; // Software column data // the [0] is &columnofs[width] - - void *hardware; // OpenGL patch, allocated whenever necessary - -#ifdef ROTSPRITE - rotsprite_t *rotated; // Rotated patches -#endif -} patch_t; +}ATTRPACK patch_t; #ifdef _MSC_VER #pragma warning(disable : 4200) diff --git a/src/r_patch.c b/src/r_patch.c index 597a1a0de..bf0f28aa9 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -48,8 +48,8 @@ boolean R_CheckIfPatch(lumpnum_t lump) patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC); - width = patch->width; - height = patch->height; + width = SHORT(patch->width); + height = SHORT(patch->height); result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < (INT16)(size / 4)); diff --git a/src/r_things.c b/src/r_things.c index 1ea932ac3..8def2ff83 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -152,7 +152,6 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch } #endif/*ROTSPRITE*/ - if (rotation == 0) { // the lump should be used for all rotations @@ -578,10 +577,8 @@ static vissprite_t *R_GetVisSprite(UINT32 num) static vissprite_t *R_NewVisSprite(void) { - if (visspritecount == MAXVISSPRITES) { - //CONS_Alert(CONS_ERROR, M_GetText("R_NewVisSprite: too many vissprites requested (maximum is %i)\n"), MAXVISSPRITES); + if (visspritecount == MAXVISSPRITES) return &overflowsprite; - } return R_GetVisSprite(visspritecount++); } @@ -656,8 +653,6 @@ void R_DrawMaskedColumn(column_t *column) dc_texturemid = basetexturemid; } -INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height - static void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) { INT32 topscreen; @@ -860,9 +855,6 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->x2 >= vid.width) vis->x2 = vid.width-1; - lengthcol = SHORT(patch->height); - -#if 1 // Something is occasionally setting 1px-wide sprites whose frac is exactly the width of the sprite, causing crashes due to // accessing invalid column info. Until the cause is found, let's try to correct those manually... { @@ -870,7 +862,6 @@ static void R_DrawVisSprite(vissprite_t *vis) if (temp > 0) vis->x2 -= temp; } -#endif #define CLAMP(x, min_val, max_val) ((x) < (min_val) ? (min_val) : ((x) > (max_val) ? (max_val) : (x))) @@ -1177,6 +1168,7 @@ static void R_ProjectSprite(mobj_t *thing) // rotsprite fixed_t spr_width, spr_height; fixed_t spr_offset, spr_topoffset; + #ifdef ROTSPRITE patch_t *rotsprite = NULL; INT32 rollangle = 0; @@ -1482,7 +1474,6 @@ static void R_ProjectSprite(mobj_t *thing) scalestep = (yscale2 - yscale)/(x2 - x1); scalestep = scalestep ? scalestep : 1; - // The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2? // sortscale = max(yscale, yscale2); @@ -1558,16 +1549,13 @@ static void R_ProjectSprite(mobj_t *thing) if (heightsec != -1 && phs != -1) // only clip things which are in special sectors { - fixed_t top = gzt; - fixed_t bottom = interp.z; - if (viewz < sectors[phs].floorheight ? - bottom >= sectors[heightsec].floorheight : - top < sectors[heightsec].floorheight) + interp.z >= sectors[heightsec].floorheight : + gzt < sectors[heightsec].floorheight) return; if (viewz > sectors[phs].ceilingheight ? - top < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight : - bottom >= sectors[heightsec].ceilingheight) + gzt < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight : + interp.z >= sectors[heightsec].ceilingheight) return; } @@ -1594,6 +1582,15 @@ static void R_ProjectSprite(mobj_t *thing) vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; + // PORTAL SEMI-CLIPPING + if (portalrender) + { + if (vis->x1 < portalclipstart) + vis->x1 = portalclipstart; + if (vis->x2 > portalclipend) + vis->x2 = portalclipend; + } + vis->sector = thing->subsector->sector; vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS); vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS); @@ -1604,15 +1601,6 @@ static void R_ProjectSprite(mobj_t *thing) else vis->extra_colormap = thing->subsector->sector->extra_colormap; - // PORTAL SEMI-CLIPPING - if (portalrender) - { - if (vis->x1 < portalclipstart) - vis->x1 = portalclipstart; - if (vis->x2 > portalclipend) - vis->x2 = portalclipend; - } - vis->xscale = FixedMul(spritexscale, xscale); //SoM: 4/17/2000 vis->scale = FixedMul(spriteyscale, yscale); //<thingscale = interp.scale; diff --git a/src/r_things.h b/src/r_things.h index 88e1abdab..da2e90168 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -172,12 +172,10 @@ typedef struct vissprite_s spritecut_e cut; UINT32 renderflags; - UINT8 rotateflags; fixed_t spritexscale, spriteyscale; fixed_t spritexoffset, spriteyoffset; - INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH]; boolean precip; -- 2.54.0 From 37a394ebaa63db043ff11a3526100fcb4938239e Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 31 May 2024 23:04:26 +0200 Subject: [PATCH 31/54] flexible array stuff for columnofs hopefully this fixes some crashes or smth --- src/r_defs.h | 2 +- src/r_patch.c | 28 ++++++++++++---------------- src/r_things.c | 3 +-- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 40a4db023..99a185c7a 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -648,7 +648,7 @@ typedef struct INT16 height; INT16 leftoffset; // pixels to the left of origin INT16 topoffset; // pixels below the origin - INT32 columnofs[8]; // only [width] used + INT32 columnofs[]; // only [width] used // the [0] is &columnofs[width] }ATTRPACK patch_t; diff --git a/src/r_patch.c b/src/r_patch.c index bf0f28aa9..eea97cfbb 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -772,6 +772,17 @@ static UINT16 GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip) return 0xFF00; } +#ifdef HWRENDER +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; +} +#endif + #ifdef ROTSPRITE // // R_GetRollAngle @@ -792,11 +803,7 @@ INT32 R_GetRollAngle(angle_t rollangle) return ra; } -patch_t *Patch_GetRotatedSprite( - spriteframe_t *sprite, - size_t frame, size_t spriteangle, - boolean flip, boolean adjustfeet, - void *info, INT32 rotationangle) +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; @@ -882,17 +889,6 @@ static void RotatedPatch_CalculateDimensions( *newheight = max(height, max(h1, h2)); } -#ifdef HWRENDER -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; -} -#endif - void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle, INT32 xpivot, INT32 ypivot, boolean flip) { UINT32 i; diff --git a/src/r_things.c b/src/r_things.c index 8def2ff83..c0efbf751 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1370,8 +1370,7 @@ static void R_ProjectSprite(mobj_t *thing) rollsum += thing->rollangle; rollangle = R_GetRollAngle(rollsum); - rotsprite = Patch_GetRotatedSprite( - sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); + rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); if (rotsprite != NULL) { -- 2.54.0 From 8052eb1c3a0bf58fe531485ba709b528d75ba0fe Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 1 Jun 2024 16:29:20 +0200 Subject: [PATCH 32/54] fix papersprites in software (hopefully) lul --- src/r_things.c | 178 ++++++++++++++++++++++++++++++++++++------------- src/r_things.h | 3 + 2 files changed, 133 insertions(+), 48 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index c0efbf751..daf589980 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -863,25 +863,27 @@ static void R_DrawVisSprite(vissprite_t *vis) vis->x2 -= temp; } -#define CLAMP(x, min_val, max_val) ((x) < (min_val) ? (min_val) : ((x) > (max_val) ? (max_val) : (x))) - // Split drawing loops for paper and non-paper to reduce conditional checks per sprite if (vis->scalestep) { + fixed_t horzscale = FixedMul(vis->spritexscale, this_scale); fixed_t scalestep = FixedMul(vis->scalestep, vis->spriteyscale); // Papersprite drawing loop - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += scalestep) { -#ifndef RANGECHECK - if ((frac>>FRACBITS) < 0 || (frac>>FRACBITS) >= SHORT(patch->width)) // if this doesn't work i'm removing papersprites - break; -#endif + angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF; + texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / horzscale; + + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + continue; + + if (vis->xiscale < 0) // Flipped sprite + texturecolumn = SHORT(patch->width) - 1 - texturecolumn; + sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); dc_iscale = (0xffffffffu / (unsigned)spryscale); - spryscale += scalestep; - texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1); column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); if (vis->vflip) @@ -892,9 +894,12 @@ static void R_DrawVisSprite(vissprite_t *vis) } else { + // Non-paper drawing loop for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { +#define CLAMP(x, min_val, max_val) ((x) < (min_val) ? (min_val) : ((x) > (max_val) ? (max_val) : (x))) texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1); +#undef CLAMP column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); if (vis->vflip) @@ -903,7 +908,7 @@ static void R_DrawVisSprite(vissprite_t *vis) R_DrawMaskedColumn(column); } } -#undef CLAMP + colfunc = basecolfunc; dc_hires = 0; @@ -1126,12 +1131,14 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) static void R_ProjectSprite(mobj_t *thing) { mobj_t *oldthing = thing; + fixed_t tr_x, tr_y; fixed_t gxt, gyt; fixed_t tx, tz; fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! INT32 x1, x2; + INT32 x1test = 0, x2test = 0; spritedef_t *sprdef; spriteframe_t *sprframe; @@ -1157,6 +1164,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t scalestep; // toast '16 fixed_t offset, offset2; boolean papersprite = (thing->frame & FF_PAPERSPRITE); + fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0; //SoM: 3/17/2000 fixed_t gz, gzt; @@ -1176,8 +1184,6 @@ static void R_ProjectSprite(mobj_t *thing) angle_t pitchnroll = 0; angle_t sliptiderollangle = 0; #endif - - fixed_t ang_scale = FRACUNIT; INT32 dist = -1; @@ -1209,7 +1215,7 @@ static void R_ProjectSprite(mobj_t *thing) tz = gxt-gyt; // thing is behind view plane? - if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later + if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; gxt = -FixedMul(tr_x, viewsin); @@ -1280,14 +1286,9 @@ static void R_ProjectSprite(mobj_t *thing) { ang = R_PointToAngle (interp.x, interp.y) - interp.angle; camang = R_PointToAngle (interp.x, interp.y); - } - - if (sprframe->rotate != SRF_SINGLE || papersprite) - { + if (mirrored) ang = InvAngle(ang); - if (papersprite) - ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); } if (sprframe->rotate == SRF_SINGLE) @@ -1387,10 +1388,11 @@ static void R_ProjectSprite(mobj_t *thing) } #endif + flip = !flip != !hflip; + // calculate edges of the shape spritexscale = interp.spritexscale; spriteyscale = interp.spriteyscale; - if (spritexscale < 1 || spriteyscale < 1) return; @@ -1409,39 +1411,19 @@ static void R_ProjectSprite(mobj_t *thing) spr_offset += interp.spritexoffset * flipoffset; spr_topoffset += interp.spriteyoffset * flipoffset; } - - flip = !flip != !hflip; if (flip) offset = spr_offset - spr_width; else offset = -spr_offset; - //offset = FixedMul(offset, FixedMul(spritexscale, this_scale)); - //offset2 = FixedMul(spr_width, FixedMul(spritexscale, this_scale)); // OH GOD I'M REVOOOOORTINGGGG AHHHHHHH - offset = FixedMul(offset, FixedMul(spritexscale, this_scale)); - tx += FixedMul(offset, ang_scale); - x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; - - // off the right side? - if (x1 > viewwidth) - return; - offset2 = FixedMul(spr_width, FixedMul(spritexscale, this_scale)); - tx += FixedMul(offset2, ang_scale); - x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - 1; - - // off the left side - if (x2 < 0) - return; if (papersprite) { - fixed_t yscale2, cosmul, sinmul, tz2; - - if (x2 <= x1) - return; + fixed_t xscale2, yscale2, cosmul, sinmul, tx2, tz2; + INT32 range; if (ang >= ANGLE_180) { @@ -1458,7 +1440,22 @@ static void R_ProjectSprite(mobj_t *thing) gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale = FixedDiv(projectiony, tz); - if (yscale < 64) return; // Fix some funky visuals + + gxt = -FixedMul(tr_x, viewsin); + gyt = FixedMul(tr_y, viewcos); + tx = -(gyt + gxt); + xscale = FixedDiv(projection, tz); + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + + // Get paperoffset (offset) and paperoffset (distance) + paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); + paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul); + if (paperdistance < 0) + { + paperoffset = -paperoffset; + paperdistance = -paperdistance; + } + centerangle = viewangle - interp.angle; tr_x += FixedMul(offset2, cosmul); tr_y += FixedMul(offset2, sinmul); @@ -1466,13 +1463,72 @@ static void R_ProjectSprite(mobj_t *thing) gyt = -FixedMul(tr_y, viewsin); tz2 = gxt-gyt; yscale2 = FixedDiv(projectiony, tz2); - if (yscale2 < 64) return; // ditto + //if (yscale2 < 64) return; // ditto + + gxt = -FixedMul(tr_x, viewsin); + gyt = FixedMul(tr_y, viewcos); + tx2 = -(gyt + gxt); + xscale2 = FixedDiv(projection, tz2); + x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS); if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; - scalestep = (yscale2 - yscale)/(x2 - x1); - scalestep = scalestep ? scalestep : 1; + // Needs partially clipped + if (tz < FixedMul(MINZ, this_scale)) + { + fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz); + tx += FixedDiv(tx2-tx, div); + tz = FixedMul(MINZ, this_scale); + } + else if (tz2 < FixedMul(MINZ, this_scale)) + { + fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2); + tx2 += FixedDiv(tx-tx2, div); + tz2 = FixedMul(MINZ, this_scale); + } + + if ((tx2 / 4) < -(FixedMul(tz2, fovtan)) || (tx / 4) > FixedMul(tz, fovtan)) // too far off the side? + return; + + yscale = FixedDiv(projectiony, tz); + xscale = FixedDiv(projection, tz); + + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + + // off the right side? + if (x1 > viewwidth) + return; + + yscale2 = FixedDiv(projectiony, tz2); + xscale2 = FixedDiv(projection, tz2); + + x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; + + // off the left side + if (x2 < 0) + return; + + range = x2 - x1; + + if (range < 0) + return; + + range++; // fencepost problem + + if (range > 32767) + { + // If the range happens to be too large for fixed_t, + // abort the draw to avoid xscale becoming negative due to arithmetic overflow. + return; + } + + scalestep = ((yscale2 - yscale)/range) ?: 1; + + if (scalestep == 0) + scalestep = 1; + + xscale = FixedDiv(range<>FRACBITS; + x1 = centerx + (FixedMul(tx,xscale) / FRACUNIT); - xscale = FixedMul(xscale, ang_scale); + x1test = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + + if (x1test > viewwidth) + x1test = 0; + + // off the right side? + if (x1 > viewwidth) + return; + + tx += offset2; + //x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--; + x2 = (centerx + (FixedMul(tx,xscale) / FRACUNIT)) - 1; + + x2test = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS) - 1; + + if (x2test < 0) + x2test = 0; + + // off the left side + if (x2 < 0) + return; + } // PORTAL SPRITE CLIPPING if (portalrender) @@ -1575,6 +1654,9 @@ static void R_ProjectSprite(mobj_t *thing) vis->pzt = vis->pz + vis->thingheight; vis->texturemid = FixedDiv(gzt - viewz, spriteyscale); vis->scalestep = scalestep; + vis->paperoffset = paperoffset; + vis->paperdistance = paperdistance; + vis->centerangle = centerangle; vis->mobj = thing; // Easy access! Tails 06-07-2002 diff --git a/src/r_things.h b/src/r_things.h index da2e90168..5b74eea02 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -149,8 +149,11 @@ typedef struct vissprite_s fixed_t thingscale; // the object's scale fixed_t sortscale; // sortscale only differs from scale for flat sprites fixed_t scalestep; // only for flat sprites, 0 otherwise + fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle fixed_t xiscale; // negative if flipped + angle_t centerangle; // for paper sprites + fixed_t texturemid; patch_t *patch; -- 2.54.0 From 957159d4859b2c73221b55cd9d2444d925bf904f Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 1 Jun 2024 16:31:49 +0200 Subject: [PATCH 33/54] forgor to remove that --- src/r_things.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index daf589980..23208c622 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1138,7 +1138,6 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t xscale, yscale, sortscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! INT32 x1, x2; - INT32 x1test = 0, x2test = 0; spritedef_t *sprdef; spriteframe_t *sprframe; @@ -1149,7 +1148,6 @@ static void R_ProjectSprite(mobj_t *thing) size_t rot; UINT8 flip; - /*boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(thing));*/ boolean mirrored = thing->mirrored; boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored); @@ -1542,11 +1540,6 @@ static void R_ProjectSprite(mobj_t *thing) //x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; x1 = centerx + (FixedMul(tx,xscale) / FRACUNIT); - x1test = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; - - if (x1test > viewwidth) - x1test = 0; - // off the right side? if (x1 > viewwidth) return; @@ -1555,11 +1548,6 @@ static void R_ProjectSprite(mobj_t *thing) //x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--; x2 = (centerx + (FixedMul(tx,xscale) / FRACUNIT)) - 1; - x2test = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS) - 1; - - if (x2test < 0) - x2test = 0; - // off the left side if (x2 < 0) return; -- 2.54.0 From 38633a85168f8577bfedd9899327821980f4dcfc Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 1 Jun 2024 17:03:27 +0200 Subject: [PATCH 34/54] stuffs --- src/r_things.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 23208c622..884da6302 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -744,7 +744,7 @@ static void R_DrawVisSprite(vissprite_t *vis) // TODO This check should not be necessary. But Papersprites near to the camera will sometimes create invalid values // for the vissprite's startfrac. This happens because they are not depth culled like other sprites. // Someone who is more familiar with papersprites pls check and try to fix <3 - if (vis->startfrac < 0 || vis->startfrac > (patch->width << FRACBITS)) + if (vis->startfrac < 0 || vis->startfrac > (SHORT(patch->width) << FRACBITS)) { // never draw vissprites with startfrac out of patch range return; @@ -1554,7 +1554,7 @@ static void R_ProjectSprite(mobj_t *thing) } // PORTAL SPRITE CLIPPING - if (portalrender) + if (portalrender && portalclipline) { if (x2 < portalclipstart || x1 > portalclipend) return; @@ -1652,7 +1652,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; // PORTAL SEMI-CLIPPING - if (portalrender) + if (portalrender && portalclipline) { if (vis->x1 < portalclipstart) vis->x1 = portalclipstart; @@ -1809,7 +1809,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) tx = -(gyt + gxt); // too far off the side? - if (abs(tx) > tz<<2) + if (abs(tx) > FixedMul(tz, fovtan)<<2) return; // aspect ratio stuff : @@ -1857,7 +1857,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) return; // PORTAL SPRITE CLIPPING - if (portalrender) + if (portalrender && portalclipline) { if (x2 < portalclipstart || x1 > portalclipend) return; @@ -1889,12 +1889,13 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; vis->scalestep = 0; + vis->paperdistance = 0; vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; // PORTAL SEMI-CLIPPING - if (portalrender) + if (portalrender && portalclipline) { if (vis->x1 < portalclipstart) vis->x1 = portalclipstart; -- 2.54.0 From bf75644144290de36bca71126294b60e3938cd99 Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 28 May 2024 20:28:27 +0200 Subject: [PATCH 35/54] make r_fps if else hell a bit more bearable to look at lol lmao --- src/r_fps.c | 67 ++++++++++++++++++----------------------------------- 1 file changed, 22 insertions(+), 45 deletions(-) diff --git a/src/r_fps.c b/src/r_fps.c index 91044b42e..52a89098f 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -287,6 +287,11 @@ angle_t R_InterpolateAngle(angle_t from, angle_t to) return (R_LerpAngle(from, to, rendertimefrac)); }*/ +#define IFCHANGED(a, b)\ +if (mobj->a == mobj->b)\ +(out->a = mobj->b);\ +else + void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) { if (frac == FRACUNIT) @@ -308,44 +313,28 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) return; } - if (mobj->x == mobj->old_x) - out->x = mobj->x; - else + IFCHANGED(x, old_x) out->x = R_LerpFixed(mobj->old_x, mobj->x, frac); - if (mobj->y == mobj->old_y) - out->y = mobj->y; - else + IFCHANGED(y, old_y) out->y = R_LerpFixed(mobj->old_y, mobj->y, frac); - if (mobj->z == mobj->old_z) - out->z = mobj->z; - else + IFCHANGED(z, old_z) out->z = R_LerpFixed(mobj->old_z, mobj->z, frac); - if (mobj->spritexscale == mobj->old_spritexscale) - out->spritexscale = mobj->spritexscale; - else + IFCHANGED(spritexscale, old_spritexscale) out->spritexscale = mobj->resetinterp ? mobj->spritexscale : R_LerpFixed(mobj->old_spritexscale, mobj->spritexscale, frac); - if (mobj->spriteyscale == mobj->old_spriteyscale) - out->spriteyscale = mobj->spriteyscale; - else + IFCHANGED(spriteyscale, old_spriteyscale) out->spriteyscale = mobj->resetinterp ? mobj->spriteyscale : R_LerpFixed(mobj->old_spriteyscale, mobj->spriteyscale, frac); - if (mobj->spritexoffset == mobj->old_spritexoffset) - out->spritexoffset = mobj->spritexoffset; - else + IFCHANGED(spritexoffset, old_spritexoffset) out->spritexoffset = mobj->resetinterp ? mobj->spritexoffset : R_LerpFixed(mobj->old_spritexoffset, mobj->spritexoffset, frac); - if (mobj->spriteyoffset == mobj->old_spriteyoffset) - out->spriteyoffset = mobj->spriteyoffset; - else + IFCHANGED(spriteyoffset, old_spriteyoffset) out->spriteyoffset = mobj->resetinterp ? mobj->spriteyoffset : R_LerpFixed(mobj->old_spriteyoffset, mobj->spriteyoffset, frac); - if (mobj->scale == mobj->old_scale) // Tiny optimisation - scale is usually unchanging, so let's skip a lerp, two FixedMuls, and two FixedDivs - out->scale = mobj->scale; - else + IFCHANGED(scale, old_scale) out->scale = mobj->resetinterp ? mobj->scale : R_LerpFixed(mobj->old_scale, mobj->scale, frac); if (cv_mobjssector.value) @@ -355,39 +344,27 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) if (mobj->player) { - if (mobj->angle == mobj->player->old_frameangle) - out->angle = mobj->player->frameangle; - else + IFCHANGED(angle, player->old_frameangle) out->angle = mobj->resetinterp ? mobj->player->frameangle : R_LerpAngle(mobj->player->old_frameangle, mobj->player->frameangle, frac); } else { - if (mobj->angle == mobj->old_angle) - out->angle = mobj->angle; - else + IFCHANGED(angle, old_angle) out->angle = mobj->resetinterp ? mobj->angle : R_LerpAngle(mobj->old_angle, mobj->angle, frac); } // pitch roll stuff - if (mobj->pitch == mobj->old_pitch) - out->pitch = mobj->pitch; - else + IFCHANGED(pitch, old_pitch) out->pitch = mobj->resetinterp ? mobj->pitch : R_LerpAngle(mobj->old_pitch, mobj->pitch, frac); - if (mobj->roll == mobj->old_roll) - out->roll = mobj->roll; - else + IFCHANGED(roll, old_roll) out->roll = mobj->resetinterp ? mobj->roll : R_LerpAngle(mobj->old_roll, mobj->roll, frac); // and the slope stuff - if (mobj->slopepitch == mobj->old_slopepitch) - out->slopepitch = mobj->slopepitch; - else + IFCHANGED(slopepitch, old_slopepitch) out->slopepitch = mobj->resetinterp ? mobj->slopepitch : R_LerpAngle(mobj->old_slopepitch, mobj->slopepitch, frac); - if (mobj->sloperoll == mobj->old_sloperoll) - out->sloperoll = mobj->sloperoll; - else + IFCHANGED(sloperoll, old_sloperoll) out->sloperoll = mobj->resetinterp ? mobj->sloperoll : R_LerpAngle(mobj->old_sloperoll, mobj->sloperoll, frac); } @@ -422,12 +399,12 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst else out->subsector = mobj->subsector; - if (mobj->angle == mobj->old_angle) - out->angle = mobj->angle; - else + IFCHANGED(angle, old_angle) out->angle = R_LerpAngle(mobj->old_angle, mobj->angle, frac); } +#undef IFCHANGED + static void AddInterpolator(levelinterpolator_t* interpolator) { if (levelinterpolators_len >= levelinterpolators_size) -- 2.54.0 From ee2ec01eb9796c41f435cbfa41a7046bff4039c9 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 2 Jun 2024 00:44:48 +0200 Subject: [PATCH 36/54] use shader to prevent sprite floor clipping from durr lul --- src/hardware/hw_main.c | 25 ------------------------- src/hardware/hw_shaders.c | 2 +- src/hardware/hw_shaders.h | 11 +++++++++++ 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3cf998d84..c5be8d185 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3970,18 +3970,6 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) // Let dispoffset work first since this adjust each vertex HWR_RotateSpritePolyToAim(spr, baseWallVerts, false); - // push it toward the camera to mitigate floor-clipping sprites - { - float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->ty - gr_viewz)*(spr->ty - gr_viewz)); - float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist; - for (i = 0; i < 4; i++) - { - baseWallVerts[i].x += (gr_viewx - baseWallVerts[i].x)*distfact; - baseWallVerts[i].z += (gr_viewy - baseWallVerts[i].z)*distfact; - baseWallVerts[i].y += (gr_viewz - baseWallVerts[i].y)*distfact; - } - } - realtop = top = baseWallVerts[3].y; realbot = bot = baseWallVerts[0].y; towtop = baseWallVerts[3].t; @@ -4252,19 +4240,6 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // ...nah HWR_RotateSpritePolyToAim(spr, wallVerts, false); - // push it toward the camera to mitigate floor-clipping sprites - { - float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->ty - gr_viewz)*(spr->ty - gr_viewz)); - float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist; - size_t i; - for (i = 0; i < 4; i++) - { - wallVerts[i].x += (gr_viewx - wallVerts[i].x)*distfact; - wallVerts[i].z += (gr_viewy - wallVerts[i].z)*distfact; - wallVerts[i].y += (gr_viewz - wallVerts[i].y)*distfact; - } - } - // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. // sprite lighting by modulating the RGB components /// \todo coloured diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index 427bd1540..a20375981 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -33,7 +33,7 @@ static struct { {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, // Sprite shader - {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, + {GLSL_SPRITECLIP_HACK_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, // Model shader {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, diff --git a/src/hardware/hw_shaders.h b/src/hardware/hw_shaders.h index eb705c34c..e817419a1 100644 --- a/src/hardware/hw_shaders.h +++ b/src/hardware/hw_shaders.h @@ -31,6 +31,17 @@ "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ "}\0" +// Sprite clipping makes me want to McFucking Die + +#define GLSL_SPRITECLIP_HACK_VERTEX_SHADER \ + "void main(void) {\n" \ + "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ + "gl_FrontColor = gl_Color;\n" \ + "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ + "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ + "gl_Position.z -= 80 / gl_Position.z;\n" \ + "}\0" + // ================== // Fragment shaders // ================== -- 2.54.0 From cae40928ad16d088168bc4ba890de890d9337ee6 Mon Sep 17 00:00:00 2001 From: Indev Date: Mon, 3 Jun 2024 00:17:11 +0300 Subject: [PATCH 37/54] Use Z_Calloc to allocate wadfile_t to avoid having uninitialized fields --- src/w_wad.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index cd2968494..15c7db38c 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -789,7 +789,7 @@ UINT16 W_InitFile(const char *filename, boolean local) // // link wad file to search files // - wadfile = Z_Malloc(sizeof (*wadfile), PU_STATIC, NULL); + wadfile = Z_Calloc(sizeof (*wadfile), PU_STATIC, NULL); wadfile->filename = Z_StrDup(filename); wadfile->handle = handle; wadfile->numlumps = (UINT16)numlumps; @@ -798,7 +798,6 @@ UINT16 W_InitFile(const char *filename, boolean local) fseek(handle, 0, SEEK_END); wadfile->filesize = (unsigned)ftell(handle); wadfile->type = type; - wadfile->majormod = false; // already generated, just copy it over M_Memcpy(&wadfile->md5sum, &md5sum, 16); -- 2.54.0 From f977af6a802ffb4330a21d9c790a0e37c72c8e5b Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 3 Jun 2024 15:13:39 +0200 Subject: [PATCH 38/54] fix le dispoffset --- src/hardware/hw_defs.h | 1 + src/hardware/hw_main.c | 23 ++++++++++++++++++++++- src/hardware/hw_shaders.c | 4 ++++ src/hardware/hw_shaders.h | 2 +- src/r_things.c | 3 +-- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 419549d73..d16b490b7 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -174,6 +174,7 @@ enum SHADER_NONE = -1, SHADER_FLOOR = 0, SHADER_WALL, + SHADER_SPRITECLIPHACK, SHADER_MODEL, SHADER_SPRITE, SHADER_WATER, diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c5be8d185..61d4e85e0 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3967,6 +3967,17 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) baseWallVerts[0].t = baseWallVerts[1].t = gpatch->max_t; } + // if it has a dispoffset, push it a little towards the camera + if (spr->dispoffset) + { + float co = -gr_viewcos*(0.05f*spr->dispoffset); + float si = -gr_viewsin*(0.05f*spr->dispoffset); + baseWallVerts[0].z = baseWallVerts[3].z = baseWallVerts[0].z+si; + baseWallVerts[1].z = baseWallVerts[2].z = baseWallVerts[1].z+si; + baseWallVerts[0].x = baseWallVerts[3].x = baseWallVerts[0].x+co; + baseWallVerts[1].x = baseWallVerts[2].x = baseWallVerts[1].x+co; + } + // Let dispoffset work first since this adjust each vertex HWR_RotateSpritePolyToAim(spr, baseWallVerts, false); @@ -4236,8 +4247,18 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) HWR_DrawSpriteShadow(spr, gpatch, this_scale); } + // if it has a dispoffset, push it a little towards the camera + if (spr->dispoffset) + { + float co = -gr_viewcos*(0.05f*spr->dispoffset); + float si = -gr_viewsin*(0.05f*spr->dispoffset); + wallVerts[0].z = wallVerts[3].z = wallVerts[0].z+si; + wallVerts[1].z = wallVerts[2].z = wallVerts[1].z+si; + wallVerts[0].x = wallVerts[3].x = wallVerts[0].x+co; + wallVerts[1].x = wallVerts[2].x = wallVerts[1].x+co; + } + // Let dispoffset work first since this adjust each vertex - // ...nah HWR_RotateSpritePolyToAim(spr, wallVerts, false); // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index a20375981..fb6b9661c 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -33,6 +33,9 @@ static struct { {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, // Sprite shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, + + // Sprite clipping hack shader (for pulling things out of the floor) {GLSL_SPRITECLIP_HACK_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, // Model shader @@ -424,6 +427,7 @@ customshaderxlat_t shaderxlat[] = {"Flat", SHADER_FLOOR}, {"WallTexture", SHADER_WALL}, {"Sprite", SHADER_SPRITE}, + {"SpriteClipHack", SHADER_SPRITECLIPHACK}, {"Model", SHADER_MODEL}, {"WaterRipple", SHADER_WATER}, {"Fog", SHADER_FOG}, diff --git a/src/hardware/hw_shaders.h b/src/hardware/hw_shaders.h index e817419a1..3840eaef1 100644 --- a/src/hardware/hw_shaders.h +++ b/src/hardware/hw_shaders.h @@ -39,7 +39,7 @@ "gl_FrontColor = gl_Color;\n" \ "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ - "gl_Position.z -= 80 / gl_Position.z;\n" \ + "gl_Position.z -= 80.0 / gl_Position.z;\n" \ "}\0" // ================== diff --git a/src/r_things.c b/src/r_things.c index 884da6302..0fa96a4ce 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -299,8 +299,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, spritecachedinfo[numspritelumps].height = SHORT(patch.height)< Date: Mon, 3 Jun 2024 13:53:59 +0200 Subject: [PATCH 39/54] add toggle for beta intermission screen + smol cleanup --- src/d_netcmd.c | 4 ++++ src/d_netcmd.h | 2 ++ src/hardware/hw_main.c | 7 +------ src/y_inter.c | 29 ++++++++++++++++++----------- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1e46da57f..8701448b4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -577,6 +577,8 @@ static CV_PossibleValue_t skinselectgridsort_t[] ={ }; consvar_t cv_skinselectgridsort ={ "skinselectgridsort", "Real name", CV_SAVE|CV_CALL|CV_NOINIT, skinselectgridsort_t, sortSkinGrid, 0, NULL, NULL, 0, 0, NULL }; +consvar_t cv_betainterscreen = {"betaintermissionscreen", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + INT16 gametype = GT_RACE; // SRB2kart boolean forceresetplayers = false; boolean deferencoremode = false; @@ -822,6 +824,8 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_netdemosyncquality); CV_RegisterVar(&cv_maxdemosize); CV_RegisterVar(&cv_keyboardlayout); + + CV_RegisterVar(&cv_betainterscreen); } // ========================================================================= diff --git a/src/d_netcmd.h b/src/d_netcmd.h index e9934e237..b02b68f00 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -205,6 +205,8 @@ extern consvar_t cv_showtrackaddon; extern consvar_t cv_showspecstuff; +extern consvar_t cv_betainterscreen; + typedef enum { SKINMENUTYPE_SCROLL = 0, diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 61d4e85e0..af7fc8f37 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6234,12 +6234,7 @@ void HWR_EndScreenWipe(void) void HWR_DrawIntermissionBG(void) { - patch_t *bgpatch = W_CachePatchName("SRB2BACK", PU_CACHE); - - if (cv_grscreentextures.value == 2) - HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0); - else - V_DrawPatchFill(bgpatch); // use the neato kart bg for intermission on disabled screen textures + HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0); } void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum) diff --git a/src/y_inter.c b/src/y_inter.c index cc1d7dd9c..58cfdc4e0 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -100,10 +100,10 @@ static y_data data; static patch_t *bgpatch = NULL; // INTERSCR static patch_t *widebgpatch = NULL; // INTERSCW static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK -static patch_t *interpic = NULL; // custom picture defined in map header -static boolean usetile; +//static patch_t *interpic = NULL; // custom picture defined in map header +//static boolean usetile; boolean usebuffer = false; -static boolean useinterpic; +//static boolean useinterpic; static INT32 timer; static INT32 intertic; @@ -392,9 +392,16 @@ void Y_IntermissionDrawer(void) if (!usebuffer) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - if (useinterpic) - V_DrawScaledPatch(0, 0, 0, interpic); - else if (!usetile) + if (cv_betainterscreen.value +#ifdef HWRENDER + || (rendermode == render_opengl && cv_grscreentextures.value != 2) // use the neato kart bg for intermission on disabled screen textures +#endif + ) + V_DrawPatchFill(bgtile); // use the neato kart bg for intermission on disabled screen textures + //else if (useinterpic) + //V_DrawScaledPatch(0, 0, 0, interpic); + //else if (!usetile) + else { if (rendermode == render_soft && usebuffer) VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); @@ -412,8 +419,8 @@ void Y_IntermissionDrawer(void) V_DrawScaledPatch(0, 0, 0, bgpatch); } } - else if (bgtile) - V_DrawPatchFill(bgtile); + //else if (bgtile) + //V_DrawPatchFill(bgtile); if (usebuffer) // Fade everything out V_DrawFadeScreen(0xFF00, 22); @@ -937,8 +944,8 @@ void Y_StartIntermission(void) //if (intertype == int_race || intertype == int_match) { - //bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); - usetile = useinterpic = false; + bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + //usetile = useinterpic = false; usebuffer = true; } @@ -988,7 +995,7 @@ static void Y_UnloadData(void) UNLOAD(bgpatch); UNLOAD(widebgpatch); UNLOAD(bgtile); - UNLOAD(interpic); + //UNLOAD(interpic); } // SRB2Kart: Voting! -- 2.54.0 From 9de3db7c97492486264c7faf378598f5b8d77868 Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 3 Jun 2024 16:52:25 +0200 Subject: [PATCH 40/54] add shader for shadows to also fix sprite shadows in pal render --- src/hardware/hw_defs.h | 1 + src/hardware/hw_main.c | 8 +++++--- src/hardware/hw_shaders.c | 4 ++++ src/hardware/hw_shaders.h | 24 ++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index d16b490b7..9f95f8fcd 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -173,6 +173,7 @@ enum { SHADER_NONE = -1, SHADER_FLOOR = 0, + SHADER_SHADOW, SHADER_WALL, SHADER_SPRITECLIPHACK, SHADER_MODEL, diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index af7fc8f37..6fae23c77 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3647,6 +3647,7 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t { FOutVector swallVerts[4]; FSurfaceInfo sSurf; + FBITFIELD blendmode = 0; fixed_t floorheight, mobjfloor; pslope_t *floorslope; fixed_t slopez; @@ -3802,13 +3803,14 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t if (sSurf.PolyColor.s.alpha > floorheight/4) { sSurf.PolyColor.s.alpha = (UINT8)(sSurf.PolyColor.s.alpha - floorheight/4); - + if (HWR_UseShader()) { - shader = SHADER_FLOOR; // floor shader + shader = SHADER_SHADOW; + blendmode |= PF_ColorMapped; } - HWR_ProcessPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated, shader, false); + HWR_ProcessPolygon(&sSurf, swallVerts, 4, blendmode|PF_Translucent|PF_Modulated, shader, false); } } diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index fb6b9661c..c4109837c 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -29,6 +29,9 @@ static struct { // Floor shader {GLSL_DEFAULT_VERTEX_SHADER, GLSL_FLOOR_FRAGMENT_SHADER}, + // Shadow shader + {GLSL_SPRITECLIP_HACK_VERTEX_SHADER, GLSL_SHADOW_FRAGMENT_SHADER}, + // Wall shader {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, @@ -425,6 +428,7 @@ static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum) customshaderxlat_t shaderxlat[] = { {"Flat", SHADER_FLOOR}, + {"Shadow", SHADER_SHADOW}, {"WallTexture", SHADER_WALL}, {"Sprite", SHADER_SPRITE}, {"SpriteClipHack", SHADER_SPRITECLIPHACK}, diff --git a/src/hardware/hw_shaders.h b/src/hardware/hw_shaders.h index 3840eaef1..6c225b1a8 100644 --- a/src/hardware/hw_shaders.h +++ b/src/hardware/hw_shaders.h @@ -144,6 +144,26 @@ "gl_FragColor = final_color;\n" \ "}\n" \ "#endif\0" + +#define GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL \ + "uniform sampler2D tex;\n" \ + "uniform vec4 poly_color;\n" \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ + "vec4 base_color = texel * poly_color;\n" \ + "vec4 final_color = base_color;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "final_color.a = texel.a * poly_color.a;\n" \ + "gl_FragColor = final_color;\n" \ + "}\n" \ // hand tuned adjustments for light level calculation #define GLSL_FLOOR_FUDGES \ @@ -161,6 +181,10 @@ #define GLSL_WALL_FRAGMENT_SHADER \ GLSL_WALL_FUDGES \ GLSL_SOFTWARE_FRAGMENT_SHADER + +#define GLSL_SHADOW_FRAGMENT_SHADER \ + GLSL_FLOOR_FUDGES \ + GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL // // Water surface shader -- 2.54.0 From ea510f95b899220be4251a8b95729f9b9e874db6 Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 3 Jun 2024 17:15:36 +0200 Subject: [PATCH 41/54] Revert "fix le dispoffset" This reverts commit f977af6a802ffb4330a21d9c790a0e37c72c8e5b. --- src/hardware/hw_defs.h | 1 - src/hardware/hw_main.c | 23 +---------------------- src/hardware/hw_shaders.c | 4 ---- src/hardware/hw_shaders.h | 2 +- src/r_things.c | 3 ++- 5 files changed, 4 insertions(+), 29 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 9f95f8fcd..b19106fff 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -175,7 +175,6 @@ enum SHADER_FLOOR = 0, SHADER_SHADOW, SHADER_WALL, - SHADER_SPRITECLIPHACK, SHADER_MODEL, SHADER_SPRITE, SHADER_WATER, diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6fae23c77..eed9f9232 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3969,17 +3969,6 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) baseWallVerts[0].t = baseWallVerts[1].t = gpatch->max_t; } - // if it has a dispoffset, push it a little towards the camera - if (spr->dispoffset) - { - float co = -gr_viewcos*(0.05f*spr->dispoffset); - float si = -gr_viewsin*(0.05f*spr->dispoffset); - baseWallVerts[0].z = baseWallVerts[3].z = baseWallVerts[0].z+si; - baseWallVerts[1].z = baseWallVerts[2].z = baseWallVerts[1].z+si; - baseWallVerts[0].x = baseWallVerts[3].x = baseWallVerts[0].x+co; - baseWallVerts[1].x = baseWallVerts[2].x = baseWallVerts[1].x+co; - } - // Let dispoffset work first since this adjust each vertex HWR_RotateSpritePolyToAim(spr, baseWallVerts, false); @@ -4249,18 +4238,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) HWR_DrawSpriteShadow(spr, gpatch, this_scale); } - // if it has a dispoffset, push it a little towards the camera - if (spr->dispoffset) - { - float co = -gr_viewcos*(0.05f*spr->dispoffset); - float si = -gr_viewsin*(0.05f*spr->dispoffset); - wallVerts[0].z = wallVerts[3].z = wallVerts[0].z+si; - wallVerts[1].z = wallVerts[2].z = wallVerts[1].z+si; - wallVerts[0].x = wallVerts[3].x = wallVerts[0].x+co; - wallVerts[1].x = wallVerts[2].x = wallVerts[1].x+co; - } - // Let dispoffset work first since this adjust each vertex + // ...nah HWR_RotateSpritePolyToAim(spr, wallVerts, false); // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index c4109837c..17485f1be 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -36,9 +36,6 @@ static struct { {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, // Sprite shader - {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, - - // Sprite clipping hack shader (for pulling things out of the floor) {GLSL_SPRITECLIP_HACK_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, // Model shader @@ -431,7 +428,6 @@ customshaderxlat_t shaderxlat[] = {"Shadow", SHADER_SHADOW}, {"WallTexture", SHADER_WALL}, {"Sprite", SHADER_SPRITE}, - {"SpriteClipHack", SHADER_SPRITECLIPHACK}, {"Model", SHADER_MODEL}, {"WaterRipple", SHADER_WATER}, {"Fog", SHADER_FOG}, diff --git a/src/hardware/hw_shaders.h b/src/hardware/hw_shaders.h index 6c225b1a8..45f3aed9e 100644 --- a/src/hardware/hw_shaders.h +++ b/src/hardware/hw_shaders.h @@ -39,7 +39,7 @@ "gl_FrontColor = gl_Color;\n" \ "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ - "gl_Position.z -= 80.0 / gl_Position.z;\n" \ + "gl_Position.z -= 80 / gl_Position.z;\n" \ "}\0" // ================== diff --git a/src/r_things.c b/src/r_things.c index 0fa96a4ce..884da6302 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -299,7 +299,8 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, spritecachedinfo[numspritelumps].height = SHORT(patch.height)< Date: Mon, 3 Jun 2024 17:15:39 +0200 Subject: [PATCH 42/54] Revert "use shader to prevent sprite floor clipping" This reverts commit ee2ec01eb9796c41f435cbfa41a7046bff4039c9. --- src/hardware/hw_main.c | 25 +++++++++++++++++++++++++ src/hardware/hw_shaders.c | 2 +- src/hardware/hw_shaders.h | 11 ----------- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index eed9f9232..007a05de1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3972,6 +3972,18 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) // Let dispoffset work first since this adjust each vertex HWR_RotateSpritePolyToAim(spr, baseWallVerts, false); + // push it toward the camera to mitigate floor-clipping sprites + { + float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->ty - gr_viewz)*(spr->ty - gr_viewz)); + float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist; + for (i = 0; i < 4; i++) + { + baseWallVerts[i].x += (gr_viewx - baseWallVerts[i].x)*distfact; + baseWallVerts[i].z += (gr_viewy - baseWallVerts[i].z)*distfact; + baseWallVerts[i].y += (gr_viewz - baseWallVerts[i].y)*distfact; + } + } + realtop = top = baseWallVerts[3].y; realbot = bot = baseWallVerts[0].y; towtop = baseWallVerts[3].t; @@ -4242,6 +4254,19 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // ...nah HWR_RotateSpritePolyToAim(spr, wallVerts, false); + // push it toward the camera to mitigate floor-clipping sprites + { + float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->ty - gr_viewz)*(spr->ty - gr_viewz)); + float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist; + size_t i; + for (i = 0; i < 4; i++) + { + wallVerts[i].x += (gr_viewx - wallVerts[i].x)*distfact; + wallVerts[i].z += (gr_viewy - wallVerts[i].z)*distfact; + wallVerts[i].y += (gr_viewz - wallVerts[i].y)*distfact; + } + } + // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. // sprite lighting by modulating the RGB components /// \todo coloured diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index 17485f1be..658de5ef6 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -36,7 +36,7 @@ static struct { {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, // Sprite shader - {GLSL_SPRITECLIP_HACK_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, // Model shader {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, diff --git a/src/hardware/hw_shaders.h b/src/hardware/hw_shaders.h index 45f3aed9e..8f600fa79 100644 --- a/src/hardware/hw_shaders.h +++ b/src/hardware/hw_shaders.h @@ -31,17 +31,6 @@ "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ "}\0" -// Sprite clipping makes me want to McFucking Die - -#define GLSL_SPRITECLIP_HACK_VERTEX_SHADER \ - "void main(void) {\n" \ - "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ - "gl_FrontColor = gl_Color;\n" \ - "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ - "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ - "gl_Position.z -= 80 / gl_Position.z;\n" \ - "}\0" - // ================== // Fragment shaders // ================== -- 2.54.0 From 716685d809e836a8aa920732a52703fae420c0ad Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 3 Jun 2024 17:15:16 +0200 Subject: [PATCH 43/54] zzz... --- src/hardware/hw_shaders.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index 658de5ef6..efebecc18 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -30,7 +30,7 @@ static struct { {GLSL_DEFAULT_VERTEX_SHADER, GLSL_FLOOR_FRAGMENT_SHADER}, // Shadow shader - {GLSL_SPRITECLIP_HACK_VERTEX_SHADER, GLSL_SHADOW_FRAGMENT_SHADER}, + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SHADOW_FRAGMENT_SHADER}, // Wall shader {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, -- 2.54.0 From 9b3eaa6fe85a1c9e9264219124516e9e365f53bb Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 4 Jun 2024 17:10:24 +0200 Subject: [PATCH 44/54] smol optimization to skin loading --- src/r_things.c | 92 +++++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 50 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 884da6302..c37807c73 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -275,58 +275,50 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, for (l = startlump; l < endlump; l++) { - if (memcmp(lumpinfo[l].name,sprname,4)==0) + if (memcmp(lumpinfo[l].name,sprname,4)) + continue; + + frame = R_Char2Frame(lumpinfo[l].name[4]); + rotation = (UINT8)(lumpinfo[l].name[5] - '0'); + + if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-... { - frame = R_Char2Frame(lumpinfo[l].name[4]); - rotation = (UINT8)(lumpinfo[l].name[5] - '0'); - - if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-... - { - CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); - continue; - } - - // skip NULL sprites from very old dmadds pwads - if (W_LumpLengthPwad(wadnum,l)<=8) - continue; - - // store sprite info in lookup tables - //FIXME : numspritelumps do not duplicate sprite replacements - W_ReadLumpHeaderPwad(wadnum, l, &patch, sizeof (patch_t), 0); - spritecachedinfo[numspritelumps].width = SHORT(patch.width)<0 && SHORT(patch.topoffset)= max_spritelumps) - { - max_spritelumps *= 2; - Z_Realloc(spritecachedinfo, max_spritelumps*sizeof(*spritecachedinfo), PU_STATIC, &spritecachedinfo); - } - - ++numadded; + CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); + continue; } + + // skip NULL sprites from very old dmadds pwads + if (W_LumpLengthPwad(wadnum,l)<=8) + continue; + + // store sprite info in lookup tables + //FIXME : numspritelumps do not duplicate sprite replacements + W_ReadLumpHeaderPwad(wadnum, l, &patch, sizeof (patch_t), 0); + spritecachedinfo[numspritelumps].width = SHORT(patch.width)<= max_spritelumps) + { + max_spritelumps *= 2; + Z_Realloc(spritecachedinfo, max_spritelumps*sizeof(*spritecachedinfo), PU_STATIC, &spritecachedinfo); + } + + ++numadded; } // -- 2.54.0 From 4246e429487eb58e3f81aa25bf8c001d3f5a077c Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 5 Jun 2024 02:27:18 +0200 Subject: [PATCH 45/54] minor sprite opitmizations --- src/hardware/hw_main.c | 136 +++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 66 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 007a05de1..3ef71658d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3062,13 +3062,13 @@ void HWR_AddPolyObjectPlanes(void) for (i = 0; i < numpolys; i++) { - polyobjsector = po_ptrs[i]->lines[0]->backsector; // the in-level polyobject sector - if (!(po_ptrs[i]->flags & POF_RENDERPLANES)) // Only render planes when you should continue; if (po_ptrs[i]->translucency >= NUMTRANSMAPS) continue; + + polyobjsector = po_ptrs[i]->lines[0]->backsector; // the in-level polyobject sector if (polyobjsector->floorheight <= gr_frontsector->ceilingheight && polyobjsector->floorheight >= gr_frontsector->floorheight @@ -4739,35 +4739,39 @@ void HWR_DrawSprites(void) for (i = 0; i < gr_visspritecount; i++) { gr_vissprite_t *spr = gr_vsprorder[i]; - if (spr->precip) - HWR_DrawPrecipitationSprite(spr); - else - if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - { - md2_t *md2; - if (spr->mobj->localskin) - { - if (spr->mobj->skinlocal) - md2 = &md2_localplayermodels[(skin_t *)spr->mobj->localskin - localskins]; - else - md2 = &md2_playermodels [(skin_t *)spr->mobj->localskin - skins]; - } - else - md2 = &md2_playermodels[(skin_t *)spr->mobj->skin - skins]; - // 8/1/19: Only don't display player models if no default SPR_PLAY is found. - if (!cv_grmdls.value || ((md2->notfound || md2->scale < 0.0f) && ((!cv_grfallbackplayermodel.value) || md2_models[SPR_PLAY].notfound || md2_models[SPR_PLAY].scale < 0.0f)) || spr->mobj->state == &states[S_PLAY_SIGN]) - HWR_DrawSprite(spr); + if (spr->precip) + { + HWR_DrawPrecipitationSprite(spr); + continue; + } + + if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + { + md2_t *md2; + if (spr->mobj->localskin) + { + if (spr->mobj->skinlocal) + md2 = &md2_localplayermodels[(skin_t *)spr->mobj->localskin - localskins]; else - HWR_DrawMD2(spr); + md2 = &md2_playermodels [(skin_t *)spr->mobj->localskin - skins]; } else + md2 = &md2_playermodels[(skin_t *)spr->mobj->skin - skins]; + + // 8/1/19: Only don't display player models if no default SPR_PLAY is found. + if (!cv_grmdls.value || ((md2->notfound || md2->scale < 0.0f) && ((!cv_grfallbackplayermodel.value) || md2_models[SPR_PLAY].notfound || md2_models[SPR_PLAY].scale < 0.0f)) || spr->mobj->state == &states[S_PLAY_SIGN]) + HWR_DrawSprite(spr); + else + HWR_DrawMD2(spr); + } + else { - if (!cv_grmdls.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) - HWR_DrawSprite(spr); - else - HWR_DrawMD2(spr); - } + if (!cv_grmdls.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + HWR_DrawSprite(spr); + else + HWR_DrawMD2(spr); + } } } @@ -4806,7 +4810,46 @@ void HWR_AddSprites(sector_t *sec) // Handle all things in sector. // If a limit exists, handle things a tiny bit different. - if (limit_dist) + if (limit_dist == 0) + { + // Draw everything in sector, no checks + for (thing = sec->thinglist; thing; thing = thing->snext) + { + split_drawsprite = false; + + if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) + continue; + + splitflags = thing->eflags & (MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4); + + if (splitscreen && splitflags) + { + if (thing->eflags & MFE_DRAWONLYFORP1) + if (viewssnum == 0) + split_drawsprite = true; + + if (thing->eflags & MFE_DRAWONLYFORP2) + if (viewssnum == 1) + split_drawsprite = true; + + if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1) + if (viewssnum == 2) + split_drawsprite = true; + + if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2) + if (viewssnum == 3) + split_drawsprite = true; + } + else + split_drawsprite = true; + + if (!split_drawsprite) + continue; + + HWR_ProjectSprite(thing); + } + } + else { for (thing = sec->thinglist; thing; thing = thing->snext) { @@ -4849,45 +4892,6 @@ void HWR_AddSprites(sector_t *sec) HWR_ProjectSprite(thing); } } - else - { - // Draw everything in sector, no checks - for (thing = sec->thinglist; thing; thing = thing->snext) - { - split_drawsprite = false; - - if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) - continue; - - splitflags = thing->eflags & (MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4); - - if (splitscreen && splitflags) - { - if (thing->eflags & MFE_DRAWONLYFORP1) - if (viewssnum == 0) - split_drawsprite = true; - - if (thing->eflags & MFE_DRAWONLYFORP2) - if (viewssnum == 1) - split_drawsprite = true; - - if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1) - if (viewssnum == 2) - split_drawsprite = true; - - if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2) - if (viewssnum == 3) - split_drawsprite = true; - } - else - split_drawsprite = true; - - if (!split_drawsprite) - continue; - - HWR_ProjectSprite(thing); - } - } } // -------------------------------------------------------------------------- -- 2.54.0 From 1503daf02bb1b4d3a64d119abacf4f59e2ecc0a4 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 5 Jun 2024 14:42:23 +0200 Subject: [PATCH 46/54] more minor loop stuff --- src/hardware/hw_bsp.c | 14 ++-- src/hardware/hw_cache.c | 30 +++++--- src/hardware/hw_main.c | 165 +++++++++++++++++++++------------------- src/r_bsp.c | 32 ++++---- src/r_data.c | 61 ++++++++------- src/r_main.c | 20 ++--- src/r_plane.c | 46 ++++++----- src/r_segs.c | 5 +- src/r_things.c | 1 + 9 files changed, 196 insertions(+), 178 deletions(-) diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index ebf18ed14..91759c819 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -772,9 +772,11 @@ static INT32 SolveTProblem(void) for (l = 0; l < addsubsector; l++) { p = extrasubsectors[l].planepoly; - if (p) - for (i = 0; i < p->numpts; i++) - SearchSegInBSP((INT32)numnodes-1, &p->pts[i], p); + if (!p) + continue; + + for (i = 0; i < p->numpts; i++) + SearchSegInBSP((INT32)numnodes-1, &p->pts[i], p); } //CONS_Debug(DBG_RENDER, "numsplitpoly %d\n", numsplitpoly); return numsplitpoly; @@ -802,8 +804,10 @@ static void AdjustSegs(void) count = subsectors[i].numlines; lseg = &segs[subsectors[i].firstline]; p = extrasubsectors[i].planepoly; - //if (!p) - //continue; + + if (!p) + continue; + for (; count--; lseg++) { float distv1,distv2,tmp; diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 2a5ec4ff5..98034970d 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -381,16 +381,17 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe realpatch); Z_Unlock(realpatch); } + //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( if (format2bpp(grtex->mipmap.format)==4) { for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp { - if (block[i] == 0) - { - grtex->mipmap.flags |= TF_TRANSPARENT; - break; - } + if (block[i] != 0) + continue; + + grtex->mipmap.flags |= TF_TRANSPARENT; + break; } } @@ -629,8 +630,12 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) #ifdef GLENCORE flat = grMipmap->data; for (steppy = 0; steppy < size; steppy++) - if (flat[steppy] != HWR_PATCHES_CHROMAKEY_COLORINDEX) - flat[steppy] = grMipmap->colormap[flat[steppy]]; + { + if (flat[steppy] == HWR_PATCHES_CHROMAKEY_COLORINDEX) + continue; + + flat[steppy] = grMipmap->colormap[flat[steppy]]; + } #endif } @@ -743,11 +748,12 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) for (grmip = gpatch->mipmap; grmip->nextcolormap; ) { grmip = grmip->nextcolormap; - if (grmip->colormap == colormap) - { - HWR_LoadMappedPatch(grmip, gpatch); - return; - } + + if (grmip->colormap != colormap) + continue; + + HWR_LoadMappedPatch(grmip, gpatch); + return; } // not found, create it! // If we are here, the sprite with the current colormap is not already in hardware memory diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3ef71658d..1cba83059 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -882,75 +882,75 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc for (i = 0; i < subsector->numlines; i++, line++) { - if (line->linedef->special == HORIZONSPECIAL && R_PointOnSegSide(viewx, viewy, line) == 0) + if (!(line->linedef->special == HORIZONSPECIAL && R_PointOnSegSide(viewx, viewy, line) == 0)) + continue; + + P_ClosestPointOnLine(viewx, viewy, line->linedef, &v); + dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y)); + + if (line->pv1) { - P_ClosestPointOnLine(viewx, viewy, line->linedef, &v); - dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y)); - - if (line->pv1) - { - x1 = ((polyvertex_t *)line->pv1)->x; - y1 = ((polyvertex_t *)line->pv1)->y; - } - else - { - x1 = FIXED_TO_FLOAT(line->v1->x); - y1 = FIXED_TO_FLOAT(line->v1->x); - } - if (line->pv2) - { - xd = ((polyvertex_t *)line->pv2)->x - x1; - yd = ((polyvertex_t *)line->pv2)->y - y1; - } - else - { - xd = FIXED_TO_FLOAT(line->v2->x) - x1; - yd = FIXED_TO_FLOAT(line->v2->y) - y1; - } + x1 = ((polyvertex_t *)line->pv1)->x; + y1 = ((polyvertex_t *)line->pv1)->y; + } + else + { + x1 = FIXED_TO_FLOAT(line->v1->x); + y1 = FIXED_TO_FLOAT(line->v1->x); + } + if (line->pv2) + { + xd = ((polyvertex_t *)line->pv2)->x - x1; + yd = ((polyvertex_t *)line->pv2)->y - y1; + } + else + { + xd = FIXED_TO_FLOAT(line->v2->x) - x1; + yd = FIXED_TO_FLOAT(line->v2->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; + // 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); + 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); + 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); + // 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); + 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; + // 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); + 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 - HWR_ProcessPolygon(&Surf, horizonpts, 6, PolyFlags, shader, true); - } + // Draw + HWR_ProcessPolygon(&Surf, horizonpts, 6, PolyFlags, shader, true); } } } @@ -3230,11 +3230,11 @@ static void HWR_Subsector(size_t num) { sector_t *controlSec = §ors[rover->secnum]; - if (controlSec->moved == true) - { - anyMoved = true; - break; - } + if (controlSec->moved != true) + continue; + + anyMoved = true; + break; } } @@ -3635,8 +3635,11 @@ static fixed_t HWR_OpaqueFloorAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t hei delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > floorz && abs(delta1) < abs(delta2)) - floorz = *rover->topheight; + + if (!(*rover->topheight > floorz && abs(delta1) < abs(delta2))) + continue; + + floorz = *rover->topheight; } } @@ -4041,13 +4044,13 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) for (i = 1; i < sector->numlights; i++) { fixed_t h = P_GetLightZAt(§or->lightlist[i], spr->mobj->x, spr->mobj->y); - if (h <= temp) - { - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *list[i-1].lightlevel > 255 ? 255 : *list[i-1].lightlevel; - colormap = list[i-1].extra_colormap; - break; - } + if (!(h <= temp)) + continue; + + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *list[i-1].lightlevel > 255 ? 255 : *list[i-1].lightlevel; + colormap = list[i-1].extra_colormap; + break; } for (i = 0; i < sector->numlights; i++) @@ -5578,8 +5581,10 @@ void HWR_SetTransform(float fpov, player_t *player) for (i = 0; i <= splitscreen; i++) { - if (player == &players[displayplayers[i]]) - postprocessor = &postimgtype[i]; + if (player != &players[displayplayers[i]]) + continue; + + postprocessor = &postimgtype[i]; } atransform.flip = false; @@ -6146,11 +6151,11 @@ void HWR_DoPostProcessor(player_t *player) for (i = splitscreen; i > 0; i--) { - if (player == &players[displayplayers[i]]) - { - type = &postimgtype[i]; - break; - } + if (player != &players[displayplayers[i]]) + continue; + + type = &postimgtype[i]; + break; } // Armageddon Blast Flash! diff --git a/src/r_bsp.c b/src/r_bsp.c index 02f4d8c83..dc409feba 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -266,11 +266,11 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, for (i = 0; i <= splitscreen; i++) { - if (viewplayer == &players[displayplayers[i]] && camera[i].chase) - { - heightsec = R_PointInSubsector(camera[i].x, camera[i].y)->sector->heightsec; - break; - } + if (!(viewplayer == &players[displayplayers[i]] && camera[i].chase)) + continue; + + heightsec = R_PointInSubsector(camera[i].x, camera[i].y)->sector->heightsec; + break; } if (i > splitscreen && viewmobj) @@ -907,11 +907,11 @@ static void R_Subsector(size_t num) { sector_t *controlSec = §ors[rover->secnum]; - if (controlSec->moved == true) - { - anyMoved = true; - break; - } + if (controlSec->moved != true) + continue; + + anyMoved = true; + break; } } @@ -1185,13 +1185,13 @@ void R_Prep3DFloors(sector_t *sector) count = 1; for (rover = sector->ffloors; rover; rover = rover->next) { - if ((rover->flags & FF_EXISTS) && (!(rover->flags & FF_NOSHADE) - || (rover->flags & FF_CUTLEVEL) || (rover->flags & FF_CUTSPRITES))) - { + if (!((rover->flags & FF_EXISTS) && (!(rover->flags & FF_NOSHADE) + || (rover->flags & FF_CUTLEVEL) || (rover->flags & FF_CUTSPRITES)))) + continue; + + count++; + if (rover->flags & FF_DOUBLESHADOW) count++; - if (rover->flags & FF_DOUBLESHADOW) - count++; - } } if (count != sector->numlights) diff --git a/src/r_data.c b/src/r_data.c index 69b0ce1ac..ad8b420f3 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -429,22 +429,24 @@ void R_LoadTextures(void) } // Add all the textures between TX_START and TX_END - if (texstart != INT16_MAX && texend != INT16_MAX) + if (!(texstart != INT16_MAX && texend != INT16_MAX)) + continue; + + // PK3s have subfolders, so we can't just make a simple sum + if (W_FileHasFolders(wadfiles[w])) { - // PK3s have subfolders, so we can't just make a simple sum - if (W_FileHasFolders(wadfiles[w])) + for (j = texstart; j < texend; j++) { - for (j = texstart; j < texend; j++) - { - if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it - numtextures++; - } - } - else - { - numtextures += (UINT32)(texend - texstart); + if (W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it + continue; + + numtextures++; } } + else + { + numtextures += (UINT32)(texend - texstart); + } } // If no textures found by this point, bomb out @@ -1003,26 +1005,26 @@ lumpnum_t R_GetFlatNumForName(const char *name) { switch (wadfiles[i]->type) { - case RET_WAD: - if ((start = W_CheckNumForNamePwad("F_START", (UINT16)i, 0)) == INT16_MAX) - { - if ((start = W_CheckNumForNamePwad("FF_START", (UINT16)i, 0)) == INT16_MAX) + case RET_WAD: + if ((start = W_CheckNumForNamePwad("F_START", (UINT16)i, 0)) == INT16_MAX) + { + if ((start = W_CheckNumForNamePwad("FF_START", (UINT16)i, 0)) == INT16_MAX) + continue; + else if ((end = W_CheckNumForNamePwad("FF_END", (UINT16)i, start)) == INT16_MAX) + continue; + } + else + if ((end = W_CheckNumForNamePwad("F_END", (UINT16)i, start)) == INT16_MAX) + continue; + break; + case RET_PK3: + if ((start = W_CheckNumForFolderStartPK3("Flats/", i, 0)) == INT16_MAX) continue; - else if ((end = W_CheckNumForNamePwad("FF_END", (UINT16)i, start)) == INT16_MAX) + if ((end = W_CheckNumForFolderEndPK3("Flats/", i, start)) == INT16_MAX) continue; - } - else - if ((end = W_CheckNumForNamePwad("F_END", (UINT16)i, start)) == INT16_MAX) - continue; - break; - case RET_PK3: - if ((start = W_CheckNumForFolderStartPK3("Flats/", i, 0)) == INT16_MAX) + break; + default: continue; - if ((end = W_CheckNumForFolderEndPK3("Flats/", i, start)) == INT16_MAX) - continue; - break; - default: - continue; } // Now find lump with specified name in that range. @@ -1310,6 +1312,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) { if (foundcolormaps[i] != LUMPERROR) continue; + if (maskcolor == extra_colormaps[i].maskcolor && fadecolor == extra_colormaps[i].fadecolor && fabs(maskamt - extra_colormaps[i].maskamt) < DBL_EPSILON diff --git a/src/r_main.c b/src/r_main.c index a15258c48..f1ffeebce 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1687,11 +1687,11 @@ void R_RenderPlayerView(player_t *player) // load previous saved value of skyVisible for the player for (i = 0; i <= splitscreen; i++) { - if (player == &players[displayplayers[i]]) - { - skyVisible = skyVisiblePerPlayer[i]; - break; - } + if (player != &players[displayplayers[i]]) + continue; + + skyVisible = skyVisiblePerPlayer[i]; + break; } portalrender = 0; @@ -1814,11 +1814,11 @@ void R_RenderPlayerView(player_t *player) // this is so that P1 can't affect whether P2 can see a skybox or not, or vice versa for (i = 0; i <= splitscreen; i++) { - if (player == &players[displayplayers[i]]) - { - skyVisiblePerPlayer[i] = skyVisible; - break; - } + if (player != &players[displayplayers[i]]) + continue; + + skyVisiblePerPlayer[i] = skyVisible; + break; } } diff --git a/src/r_plane.c b/src/r_plane.c index 6bd6f212d..6299edd9e 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -674,25 +674,26 @@ static void R_DrawSkyPlane(visplane_t *pl) // Because of this hack, sky is not affected // by INVUL inverse mapping. dc_colormap = colormaps; + if (encoremap) dc_colormap += COLORMAP_REMAPOFFSET; + dc_texturemid = skytexturemid; - dc_texheight = textureheight[skytexture] - >>FRACBITS; + dc_texheight = textureheight[skytexture] >>FRACBITS; + for (x = pl->minx; x <= pl->maxx; x++) { dc_yl = pl->top[x]; dc_yh = pl->bottom[x]; - if (dc_yl <= dc_yh) - { - angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; - dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT)); - dc_x = x; - dc_source = - R_GetColumn(texturetranslation[skytexture], - angle); - wallcolfunc(); - } + + if (!(dc_yl <= dc_yh)) + continue; + + angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; + dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT)); + dc_x = x; + dc_source = R_GetColumn(texturetranslation[skytexture], angle); + wallcolfunc(); } } @@ -839,18 +840,15 @@ void R_DrawSinglePlane(visplane_t *pl) // Don't draw planes that shouldn't be drawn. for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next) { - if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA)) - { - if (pl->ffloor->flags & FF_EXTRA) - { - // The plane is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE))) - && pl->height < *rover->topheight - && pl->height > *rover->bottomheight) - return; - } - } + if (!((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA))) + continue; + + // The plane is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE))) + && pl->height < *rover->topheight + && pl->height > *rover->bottomheight) + return; } if (pl->ffloor->flags & FF_TRANSLUCENT) diff --git a/src/r_segs.c b/src/r_segs.c index 4a231938b..b70e06ff6 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -496,7 +496,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } } - dc_texheight = textureheight[texnum]>>FRACBITS; // draw the columns @@ -983,7 +982,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { - if (maskedtexturecol[dc_x] != INT16_MAX) + if (maskedtexturecol[dc_x] == INT16_MAX) + continue; + { if (ffloortextureslide) { // skew FOF walls if (oldx != -1) diff --git a/src/r_things.c b/src/r_things.c index c37807c73..87cbc33d6 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -447,6 +447,7 @@ void R_AddSpriteDefs(UINT16 wadnum) for (i = 0; i < numsprites; i++) { spritename = sprnames[i]; + if (spritename[4] && wadnum >= (UINT16)spritename[4]) continue; -- 2.54.0 From 51392590372e0cef59ca7023296c1aedaafdf8b9 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 6 Jun 2024 18:42:32 +0200 Subject: [PATCH 47/54] fix HAVE_CURL --- src/d_clisrv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 471d329a4..69c87a157 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1333,9 +1333,13 @@ static inline void CL_DrawConnectionStatus(void) { strncpy(tempname, filename, sizeof(tempname)-1); } - +#ifdef HAVE_CURL V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-58-30, 0, va(M_GetText("%s downloading"), ((cl_mode == CL_DOWNLOADHTTPFILES) ? "\x82""HTTP" : "\x85""Direct"))); +#else + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-58-30, 0, + va(M_GetText("%s downloading"),("\x85""Direct"))); +#endif V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-58-22, V_YELLOWMAP, va(M_GetText("\"%s\""), tempname)); V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-58, V_20TRANS|V_MONOSPACE, @@ -2170,7 +2174,9 @@ static void M_ConfirmConnect(event_t *ev) static void AbortConnection(void) { +#ifdef HAVE_CURL CURLAbortFile(); +#endif D_QuitNetGame(); CL_Reset(); D_StartTitle(); -- 2.54.0 From cfe6e081689fd65267d10c7c708deaff587cdc68 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 6 Jun 2024 18:47:06 +0200 Subject: [PATCH 48/54] fix masterserver ifdef --- src/mserv.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mserv.h b/src/mserv.h index 5a74771a4..76bd5fd28 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -90,9 +90,11 @@ char *GetMODVersion(int id); #endif char *GetMasterServerRules(void); +#endif void AddMServCommands(void); +#ifdef MASTERSERVER /* HTTP */ void HMS_set_api (char *api); int HMS_register (void); @@ -105,4 +107,4 @@ const char * HMS_fetch_rules (char *buffer, size_t size_of_buffer); #endif -#endif \ No newline at end of file +#endif -- 2.54.0 From f8a8b8ac6e1f02e038e0b17f6f6334cca869fe10 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 6 Jun 2024 18:53:40 +0200 Subject: [PATCH 49/54] disable upx on nix by default --- src/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Makefile b/src/Makefile index 20f33a471..98351a8a2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -106,6 +106,8 @@ ifeq ($(OS),Windows_NT) # all windows are Windows_NT... else # if you on the *nix + NOUPX=1 + system:=$(shell uname -s) ifeq ($(system),Linux) -- 2.54.0 From 4abc2ab5bd32037f7889d055346ea2b28e50a744 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 6 Jun 2024 18:57:04 +0200 Subject: [PATCH 50/54] fix redifinition warning --- src/sdl/IMG_xpm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sdl/IMG_xpm.c b/src/sdl/IMG_xpm.c index 458131620..7a68185fa 100644 --- a/src/sdl/IMG_xpm.c +++ b/src/sdl/IMG_xpm.c @@ -1198,6 +1198,8 @@ SDL_Surface *IMG_ReadXPMFromArray(const char **xpm) return load_xpm(xpm, NULL); } +#undef MAX + #else /* not LOAD_XPM */ /* See if an image is contained in a data source */ -- 2.54.0 From bd7103d109b026df8b737bbea157283c987e8c54 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 9 Jun 2024 18:03:58 +0200 Subject: [PATCH 51/54] add check earlier in p_killmobj --- src/p_inter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 14c712033..68d02cdd9 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1908,8 +1908,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) mobj_t *mo; int ms; - //if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL)) - // P_SetTarget(&target->tracer, inflictor); + if (!target || P_MobjWasRemoved(target)) + return; if (!useNightsSS && G_IsSpecialStage(gamemap) && target->player && sstimer > 6) sstimer = 6; // Just let P_Ticker take care of the rest. -- 2.54.0 From 6ffb50530dff945c4b42b8bd1307186fb468e5f3 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 9 Jun 2024 18:13:17 +0200 Subject: [PATCH 52/54] add mobj check here --- src/p_user.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 4cf785529..8f2f1eaa7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1195,6 +1195,9 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) { mobj_t *ghost; + if (!mobj || P_MobjWasRemoved(mobj)) + return; + ghost = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_GHOST); P_SetScale(ghost, mobj->scale); -- 2.54.0 From 07d631e320e096b5190eb6e70fde329c346cc051 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 9 Jun 2024 18:14:22 +0200 Subject: [PATCH 53/54] e --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 8f2f1eaa7..3bee5abcd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1196,7 +1196,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) mobj_t *ghost; if (!mobj || P_MobjWasRemoved(mobj)) - return; + return NULL; ghost = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_GHOST); -- 2.54.0 From d66e7e660d781b84e4281b4e697c9196e7b63fd4 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 9 Jun 2024 18:49:33 +0200 Subject: [PATCH 54/54] reset those here ig need a better place tbh but those occasionally could get stuck for some reason so just reset them when the menu gets opened --- src/m_menu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index d7dc233b1..8693d6f29 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4160,6 +4160,11 @@ void M_StartControlPanel(void) menuactive = true; + DPADUPSCROLL = false; + DPADDOWNSCROLL = false; + DPADLEFTSCROLL = false; + DPADRIGHTSCROLL = false; + if (demo.playback) { currentMenu = &PlaybackMenuDef; -- 2.54.0