diff --git a/src/Sourcefile b/src/Sourcefile index ef9fbdc13..fa82f86da 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -96,4 +96,5 @@ lua_taglib.c lua_polyobjlib.c lua_blockmaplib.c lua_hudlib.c +lua_hudlib_drawlist.c lua_inputlib.c diff --git a/src/d_main.c b/src/d_main.c index 850da2f1a..8b4de45e9 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -826,6 +826,8 @@ void D_SRB2Loop(void) doDisplay = true; } + + renderisnewtic = true; } if (interp) diff --git a/src/f_finale.c b/src/f_finale.c index 832c0ecb3..4ddcaff5f 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -227,6 +227,8 @@ static tic_t cutscene_lasttextwrite = 0; // STJR Intro char stjrintro[9] = "STJRI000"; +static huddrawlist_h luahuddrawlist_title; + // // This alters the text string cutscene_disptext. // Use the typical string drawing functions to display it. @@ -2278,6 +2280,9 @@ void F_InitMenuPresValues(void) M_SetMenuCurBackground((gamestate == GS_TIMEATTACK) ? "RECATTBG" : "TITLESKY"); M_SetMenuCurFadeValue(16); M_SetMenuCurTitlePics(); + + LUA_HUD_DestroyDrawList(luahuddrawlist_title); + luahuddrawlist_title = LUA_HUD_CreateDrawList(); } // @@ -3397,7 +3402,12 @@ void F_TitleScreenDrawer(void) } luahook: - LUA_HUDHOOK(title); + if (renderisnewtic) + { + LUA_HUD_ClearDrawList(luahuddrawlist_title); + LUA_HUDHOOK(title, luahuddrawlist_title); + } + LUA_HUD_DrawList(luahuddrawlist_title); } // separate animation timer for backgrounds, since we also count diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 518f28b50..c4067d7d8 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -48,6 +48,7 @@ #endif #include "lua_hud.h" +#include "lua_hudlib_drawlist.h" #include "lua_hook.h" // coords are scaled @@ -166,6 +167,8 @@ static tic_t cechotimer = 0; static tic_t cechoduration = 5*TICRATE; static INT32 cechoflags = 0; +static huddrawlist_h luahuddrawlist_scores; + //====================================================================== // HEADS UP INIT //====================================================================== @@ -334,6 +337,8 @@ void HU_Init(void) // set shift translation table shiftxform = english_shiftxform; + + luahuddrawlist_scores = LUA_HUD_CreateDrawList(); } static inline void HU_Stop(void) @@ -1989,7 +1994,13 @@ void HU_Drawer(void) } else HU_DrawCoopOverlay(); - LUA_HUDHOOK(scores); + + if (renderisnewtic) + { + LUA_HUD_ClearDrawList(luahuddrawlist_scores); + LUA_HUDHOOK(scores, luahuddrawlist_scores); + } + LUA_HUD_DrawList(luahuddrawlist_scores); } if (gamestate != GS_LEVEL) diff --git a/src/lua_hook.h b/src/lua_hook.h index fc6a5f4ee..5a14294c3 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -14,6 +14,7 @@ #include "d_player.h" #include "s_sound.h" #include "d_event.h" +#include "lua_hudlib_drawlist.h" /* Do you know what an 'X Macro' is? Such a macro is called over each element of @@ -110,12 +111,12 @@ ENUM (STRING_HOOK); /* dead simple, LUA_HOOK(GameQuit) */ #define LUA_HOOK(type) LUA_HookVoid(HOOK(type)) -#define LUA_HUDHOOK(type) LUA_HookHUD(HUD_HOOK(type)) +#define LUA_HUDHOOK(type,drawlist) LUA_HookHUD(HUD_HOOK(type),(drawlist)) extern boolean hook_cmd_running; void LUA_HookVoid(int hook); -void LUA_HookHUD(int hook); +void LUA_HookHUD(int hook, huddrawlist_h drawlist); int LUA_HookMobj(mobj_t *, int hook); int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 48980f4a4..0b24b7b53 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -641,7 +641,7 @@ int LUA_HookKey(event_t *event, int hook_type) return hook.status; } -void LUA_HookHUD(int hook_type) +void LUA_HookHUD(int hook_type, huddrawlist_h list) { const hook_t * map = &hudHookIds[hook_type]; Hook_State hook; @@ -650,12 +650,15 @@ void LUA_HookHUD(int hook_type) start_hook_stack(); begin_hook_values(&hook); - LUA_SetHudHook(hook_type); + LUA_SetHudHook(hook_type, list); hud_running = true; // local hook init_hook_call(&hook, 0, res_none); call_mapped(&hook, map); hud_running = false; + + lua_pushnil(gL); + lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST"); } } diff --git a/src/lua_hud.h b/src/lua_hud.h index ad2b51d3e..0d629d233 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -10,6 +10,11 @@ /// \file lua_hud.h /// \brief HUD enable/disable flags for Lua scripting +#ifndef __LUA_HUD_H__ +#define __LUA_HUD_H__ + +#include "lua_hudlib_drawlist.h" + enum hud { hud_stagetitle = 0, hud_textspectator, @@ -47,4 +52,6 @@ extern boolean hud_running; boolean LUA_HudEnabled(enum hud option); -void LUA_SetHudHook(int hook); +void LUA_SetHudHook(int hook, huddrawlist_h list); + +#endif // __LUA_HUD_H__ diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index cffb0b64f..d049bcfe2 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -645,7 +645,8 @@ static int libd_draw(lua_State *L) { INT32 x, y, flags; patch_t *patch; - const UINT8 *colormap = NULL; + UINT8 *colormap = NULL; + huddrawlist_h list; HUDONLY x = luaL_checkinteger(L, 1); @@ -659,7 +660,14 @@ static int libd_draw(lua_State *L) flags &= ~V_PARAMMASK; // Don't let crashes happen. - V_DrawFixedPatch(x< maxstrength) return luaL_error(L, "%s fade strength %d out of range (0 - %d)", ((color & 0xFF00) ? "COLORMAP" : "TRANSMAP"), strength, maxstrength); + lua_getfield(L, LUA_REGISTRYINDEX, "HUD_DRAW_LIST"); + list = (huddrawlist_h) lua_touserdata(L, -1); + lua_pop(L, 1); + if (strength == maxstrength) // Allow as a shortcut for drawfill... { - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color)); + if (LUA_HUD_IsDrawListValid(list)) + LUA_HUD_AddDrawFill(list, 0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color)); + else + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color)); return 0; } - V_DrawFadeScreen(color, strength); + if (LUA_HUD_IsDrawListValid(list)) + LUA_HUD_AddFadeScreen(list, color, strength); + else + V_DrawFadeScreen(color, strength); + return 0; } @@ -1365,10 +1472,13 @@ boolean LUA_HudEnabled(enum hud option) return false; } -void LUA_SetHudHook(int hook) +void LUA_SetHudHook(int hook, huddrawlist_h list) { lua_getref(gL, lib_draw_ref); + lua_pushlightuserdata(gL, list); + lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST"); + switch (hook) { case HUD_HOOK(game): { diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c new file mode 100644 index 000000000..bcf132ec6 --- /dev/null +++ b/src/lua_hudlib_drawlist.c @@ -0,0 +1,572 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2014-2016 by John "JTE" Muniz. +// Copyright (C) 2014-2022 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file lua_hudlib_drawlist.c +/// \brief a data structure for managing cached drawlists for the Lua hud lib + +#include "lua_hudlib_drawlist.h" + +#include + +#include "v_video.h" +#include "z_zone.h" + +enum drawitem_e { + DI_Draw = 0, + DI_DrawScaled, + DI_DrawStretched, + DI_DrawCropped, + DI_DrawNum, + DI_DrawPaddedNum, + DI_DrawFill, + DI_DrawString, + DI_DrawNameTag, + DI_DrawScaledNameTag, + DI_DrawLevelTitle, + DI_FadeScreen, + DI_MAX, +}; + +// A single draw item with all possible arguments needed for a draw call. +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; + UINT8 *colormap; + UINT8 *basecolormap; + UINT8 *outlinecolormap; + fixed_t sx; + fixed_t sy; + INT32 num; + INT32 digits; + const char *str; + UINT16 color; + UINT8 strength; + INT32 align; +} drawitem_t; + +// The internal structure of a drawlist. +struct huddrawlist_s { + drawitem_t *items; + size_t items_capacity; + size_t items_len; + char *strbuf; + size_t strbuf_capacity; + size_t strbuf_len; +}; + +// alignment types for v.drawString +enum align { + align_left = 0, + align_center, + align_right, + align_fixed, + align_fixedcenter, + align_fixedright, + align_small, + align_smallfixed, + align_smallfixedcenter, + align_smallfixedright, + align_smallcenter, + align_smallright, + align_smallthin, + align_smallthincenter, + align_smallthinright, + align_smallthinfixed, + align_smallthinfixedcenter, + align_smallthinfixedright, + align_thin, + align_thinfixed, + align_thinfixedcenter, + align_thinfixedright, + align_thincenter, + align_thinright +}; + +huddrawlist_h LUA_HUD_CreateDrawList(void) +{ + huddrawlist_h drawlist; + + drawlist = (huddrawlist_h) Z_CallocAlign(sizeof(struct huddrawlist_s), PU_STATIC, NULL, 64); + drawlist->items = NULL; + drawlist->items_capacity = 0; + drawlist->items_len = 0; + drawlist->strbuf = NULL; + drawlist->strbuf_capacity = 0; + drawlist->strbuf_len = 0; + + return drawlist; +} + +void LUA_HUD_ClearDrawList(huddrawlist_h list) +{ + // 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->items_len = 0; + + if (list->strbuf) + { + list->strbuf[0] = 0; + } + list->strbuf_len = 0; +} + +void LUA_HUD_DestroyDrawList(huddrawlist_h list) +{ + if (list == NULL) return; + + if (list->items) + { + Z_Free(list->items); + } + Z_Free(list); +} + +boolean LUA_HUD_IsDrawListValid(huddrawlist_h list) +{ + if (!list) return false; + + // that's all we can really do to check the validity of the handle right now + return true; +} + +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->items_capacity == 0) list->items_capacity = 128; + else list->items_capacity *= 2; + list->items = (drawitem_t *) Z_ReallocAlign(list->items, sizeof(struct drawitem_s) * list->items_capacity, PU_STATIC, NULL, 64); + } + + return list->items_len++; +} + +// copy string to list's internal string buffer +// lua can deallocate the string before we get to use it, so it's important to +// keep our own copy +static const char *CopyString(huddrawlist_h list, const char* str) +{ + size_t lenstr; + + if (!list) I_Error("can't allocate string; invalid list"); + lenstr = strlen(str); + if (list->strbuf_capacity <= list->strbuf_len + lenstr + 1) + { + if (list->strbuf_capacity == 0) list->strbuf_capacity = 256; + else list->strbuf_capacity *= 2; + list->strbuf = (char*) Z_ReallocAlign(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL, 8); + } + const char *result = (const char *) &list->strbuf[list->strbuf_len]; + strncpy(&list->strbuf[list->strbuf_len], str, lenstr + 1); + list->strbuf_len += lenstr + 1; + return result; +} + +void LUA_HUD_AddDraw( + huddrawlist_h list, + INT32 x, + INT32 y, + patch_t *patch, + INT32 flags, + UINT8 *colormap +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_Draw; + item->x = x; + item->y = y; + item->patch = patch; + item->flags = flags; + item->colormap = colormap; +} + +void LUA_HUD_AddDrawScaled( + huddrawlist_h list, + fixed_t x, + fixed_t y, + fixed_t scale, + patch_t *patch, + INT32 flags, + UINT8 *colormap +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_DrawScaled; + item->x = x; + item->y = y; + item->scale = scale; + item->patch = patch; + item->flags = flags; + item->colormap = colormap; +} + +void LUA_HUD_AddDrawStretched( + huddrawlist_h list, + fixed_t x, + fixed_t y, + fixed_t hscale, + fixed_t vscale, + patch_t *patch, + INT32 flags, + UINT8 *colormap +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_DrawStretched; + item->x = x; + item->y = y; + item->hscale = hscale; + item->vscale = vscale; + item->patch = patch; + item->flags = flags; + item->colormap = colormap; +} + +void LUA_HUD_AddDrawCropped( + huddrawlist_h list, + fixed_t x, + fixed_t y, + fixed_t hscale, + fixed_t vscale, + patch_t *patch, + INT32 flags, + UINT8 *colormap, + fixed_t sx, + fixed_t sy, + fixed_t w, + fixed_t h +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_DrawCropped; + item->x = x; + item->y = y; + item->hscale = hscale; + item->vscale = vscale; + item->patch = patch; + item->flags = flags; + item->colormap = colormap; + item->sx = sx; + item->sy = sy; + item->w = w; + item->h = h; +} + +void LUA_HUD_AddDrawNum( + huddrawlist_h list, + INT32 x, + INT32 y, + INT32 num, + INT32 flags +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_DrawNum; + item->x = x; + item->y = y; + item->num = num; + item->flags = flags; +} + +void LUA_HUD_AddDrawPaddedNum( + huddrawlist_h list, + INT32 x, + INT32 y, + INT32 num, + INT32 digits, + INT32 flags +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_DrawPaddedNum; + item->x = x; + item->y = y; + item->num = num; + item->digits = digits; + item->flags = flags; +} + +void LUA_HUD_AddDrawFill( + huddrawlist_h list, + INT32 x, + INT32 y, + INT32 w, + INT32 h, + INT32 c +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_DrawFill; + item->x = x; + item->y = y; + item->w = w; + item->h = h; + item->c = c; +} + +void LUA_HUD_AddDrawString( + huddrawlist_h list, + fixed_t x, + fixed_t y, + const char *str, + INT32 flags, + INT32 align +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_DrawString; + item->x = x; + item->y = y; + item->str = CopyString(list, str); + item->flags = flags; + item->align = align; +} + +void LUA_HUD_AddDrawNameTag( + huddrawlist_h list, + INT32 x, + INT32 y, + const char *str, + INT32 flags, + UINT16 basecolor, + UINT16 outlinecolor, + UINT8 *basecolormap, + UINT8 *outlinecolormap +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_DrawNameTag; + item->x = x; + item->y = y; + item->str = CopyString(list, str); + item->flags = flags; + item->basecolor = basecolor; + item->outlinecolor = outlinecolor; + item->basecolormap = basecolormap; + item->outlinecolormap = outlinecolormap; +} + +void LUA_HUD_AddDrawScaledNameTag( + huddrawlist_h list, + fixed_t x, + fixed_t y, + const char *str, + INT32 flags, + fixed_t scale, + UINT16 basecolor, + UINT16 outlinecolor, + UINT8 *basecolormap, + UINT8 *outlinecolormap +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_DrawScaledNameTag; + item->x = x; + item->y = y; + item->str = CopyString(list, str); + item->flags = flags; + item->scale = scale; + item->basecolor = basecolor; + item->outlinecolor = outlinecolor; + item->basecolormap = basecolormap; + item->outlinecolormap = outlinecolormap; +} + +void LUA_HUD_AddDrawLevelTitle( + huddrawlist_h list, + INT32 x, + INT32 y, + const char *str, + INT32 flags +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_DrawLevelTitle; + item->x = x; + item->y = y; + item->str = CopyString(list, str); + item->flags = flags; +} + +void LUA_HUD_AddFadeScreen( + huddrawlist_h list, + UINT16 color, + UINT8 strength +) +{ + size_t i = AllocateDrawItem(list); + drawitem_t *item = &list->items[i]; + item->type = DI_FadeScreen; + item->color = color; + item->strength = strength; +} + +void LUA_HUD_DrawList(huddrawlist_h list) +{ + size_t i; + + if (!list) I_Error("HUD drawlist invalid"); + if (list->items_len <= 0) return; + if (!list->items) I_Error("HUD drawlist->items invalid"); + + for (i = 0; i < list->items_len; i++) + { + drawitem_t *item = &list->items[i]; + + switch (item->type) + { + case DI_Draw: + V_DrawFixedPatch(item->x<y<flags, item->patch, item->colormap); + break; + case DI_DrawScaled: + V_DrawFixedPatch(item->x, item->y, item->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); + break; + case DI_DrawCropped: + V_DrawCroppedPatch(item->x, item->y, item->hscale, item->vscale, item->flags, item->patch, item->colormap, item->sx, item->sy, item->w, item->h); + break; + case DI_DrawNum: + V_DrawTallNum(item->x, item->y, item->flags, item->num); + break; + case DI_DrawPaddedNum: + V_DrawPaddedTallNum(item->x, item->y, item->flags, item->num, item->digits); + break; + case DI_DrawFill: + V_DrawFill(item->x, item->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, item->str); + break; + case align_center: + V_DrawCenteredString(item->x, item->y, item->flags, item->str); + break; + case align_right: + V_DrawRightAlignedString(item->x, item->y, item->flags, item->str); + break; + case align_fixed: + V_DrawStringAtFixed(item->x, item->y, item->flags, item->str); + break; + case align_fixedcenter: + V_DrawCenteredStringAtFixed(item->x, item->y, item->flags, item->str); + break; + case align_fixedright: + V_DrawRightAlignedStringAtFixed(item->x, item->y, item->flags, item->str); + break; + // hu_font, 0.5x scale + case align_small: + V_DrawSmallString(item->x, item->y, item->flags, item->str); + break; + case align_smallfixed: + V_DrawSmallStringAtFixed(item->x, item->y, item->flags, item->str); + break; + case align_smallfixedcenter: + V_DrawCenteredSmallStringAtFixed(item->x, item->y, item->flags, item->str); + break; + case align_smallfixedright: + V_DrawRightAlignedSmallStringAtFixed(item->x, item->y, item->flags, item->str); + break; + case align_smallcenter: + V_DrawCenteredSmallString(item->x, item->y, item->flags, item->str); + break; + case align_smallright: + V_DrawRightAlignedSmallString(item->x, item->y, item->flags, item->str); + break; + case align_smallthin: + V_DrawSmallThinString(item->x, item->y, item->flags, item->str); + break; + case align_smallthincenter: + V_DrawCenteredSmallThinString(item->x, item->y, item->flags, item->str); + break; + case align_smallthinright: + V_DrawRightAlignedSmallThinString(item->x, item->y, item->flags, item->str); + break; + case align_smallthinfixed: + V_DrawSmallThinStringAtFixed(item->x, item->y, item->flags, item->str); + break; + case align_smallthinfixedcenter: + V_DrawCenteredSmallThinStringAtFixed(item->x, item->y, item->flags, item->str); + break; + case align_smallthinfixedright: + V_DrawRightAlignedSmallThinStringAtFixed(item->x, item->y, item->flags, item->str); + break; + // tny_font + case align_thin: + V_DrawThinString(item->x, item->y, item->flags, item->str); + break; + case align_thincenter: + V_DrawCenteredThinString(item->x, item->y, item->flags, item->str); + break; + case align_thinright: + V_DrawRightAlignedThinString(item->x, item->y, item->flags, item->str); + break; + case align_thinfixed: + V_DrawThinStringAtFixed(item->x, item->y, item->flags, item->str); + break; + case align_thinfixedcenter: + V_DrawCenteredThinStringAtFixed(item->x, item->y, item->flags, item->str); + break; + case align_thinfixedright: + V_DrawRightAlignedThinStringAtFixed(item->x, item->y, item->flags, item->str); + break; + } + break; + case DI_DrawNameTag: + V_DrawNameTag(item->x, item->y, item->flags, FRACUNIT, item->basecolormap, item->outlinecolormap, item->str); + break; + case DI_DrawScaledNameTag: + V_DrawNameTag(FixedInt(item->x), FixedInt(item->y), item->flags, item->scale, item->basecolormap, item->outlinecolormap, item->str); + break; + case DI_DrawLevelTitle: + V_DrawLevelTitle(item->x, item->y, item->flags, item->str); + break; + case DI_FadeScreen: + V_DrawFadeScreen(item->color, item->strength); + break; + default: + I_Error("can't draw draw list item: invalid draw list item type"); + continue; + } + } +} diff --git a/src/lua_hudlib_drawlist.h b/src/lua_hudlib_drawlist.h new file mode 100644 index 000000000..5e97b5c26 --- /dev/null +++ b/src/lua_hudlib_drawlist.h @@ -0,0 +1,152 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2022-2022 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file lua_hudlib_drawlist.h +/// \brief a data structure for managing cached drawlists for the Lua hud lib + +// The idea behinds this module is to cache drawcall information into an ordered +// list to repeat the same draw operations in later frames. It's used to ensure +// that the HUD hooks from Lua are called at precisely 35hz to avoid problems +// with variable framerates in existing Lua addons. + +#ifndef __LUA_HUDLIB_DRAWLIST__ +#define __LUA_HUDLIB_DRAWLIST__ + +#include "doomtype.h" +#include "r_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct huddrawlist_s *huddrawlist_h; + +// Create a new drawlist. Returns a handle to it. +huddrawlist_h LUA_HUD_CreateDrawList(void); +// Clears the draw list. +void LUA_HUD_ClearDrawList(huddrawlist_h list); +// Destroys the drawlist, invalidating the given handle +void LUA_HUD_DestroyDrawList(huddrawlist_h list); +boolean LUA_HUD_IsDrawListValid(huddrawlist_h list); + +void LUA_HUD_AddDraw( + huddrawlist_h list, + INT32 x, + INT32 y, + patch_t *patch, + INT32 flags, + UINT8 *colormap +); +void LUA_HUD_AddDrawScaled( + huddrawlist_h list, + fixed_t x, + fixed_t y, + fixed_t scale, + patch_t *patch, + INT32 flags, + UINT8 *colormap +); +void LUA_HUD_AddDrawStretched( + huddrawlist_h list, + fixed_t x, + fixed_t y, + fixed_t hscale, + fixed_t vscale, + patch_t *patch, + INT32 flags, + UINT8 *colormap +); +void LUA_HUD_AddDrawCropped( + huddrawlist_h list, + fixed_t x, + fixed_t y, + fixed_t hscale, + fixed_t vscale, + patch_t *patch, + INT32 flags, + UINT8 *colormap, + fixed_t sx, + fixed_t sy, + fixed_t w, + fixed_t h +); +void LUA_HUD_AddDrawNum( + huddrawlist_h list, + INT32 x, + INT32 y, + INT32 num, + INT32 flags +); +void LUA_HUD_AddDrawPaddedNum( + huddrawlist_h list, + INT32 x, + INT32 y, + INT32 num, + INT32 digits, + INT32 flags +); +void LUA_HUD_AddDrawFill( + huddrawlist_h list, + INT32 x, + INT32 y, + INT32 w, + INT32 h, + INT32 c +); +void LUA_HUD_AddDrawString( + huddrawlist_h list, + fixed_t x, + fixed_t y, + const char *str, + INT32 flags, + INT32 align +); +void LUA_HUD_AddDrawNameTag( + huddrawlist_h list, + INT32 x, + INT32 y, + const char *str, + INT32 flags, + UINT16 basecolor, + UINT16 outlinecolor, + UINT8 *basecolormap, + UINT8 *outlinecolormap +); +void LUA_HUD_AddDrawScaledNameTag( + huddrawlist_h list, + fixed_t x, + fixed_t y, + const char *str, + INT32 flags, + fixed_t scale, + UINT16 basecolor, + UINT16 outlinecolor, + UINT8 *basecolormap, + UINT8 *outlinecolormap +); +void LUA_HUD_AddDrawLevelTitle( + huddrawlist_h list, + INT32 x, + INT32 y, + const char *str, + INT32 flags +); +void LUA_HUD_AddFadeScreen( + huddrawlist_h list, + UINT16 color, + UINT8 strength +); + +// Draws the given draw list +void LUA_HUD_DrawList(huddrawlist_h list); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // __LUA_HUDLIB_DRAWLIST__ diff --git a/src/r_main.c b/src/r_main.c index 896b6a29b..fa2313363 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -78,6 +78,7 @@ mobj_t *r_viewmobj; fixed_t rendertimefrac; fixed_t renderdeltatics; +boolean renderisnewtic; // // precalculated math tables diff --git a/src/r_main.h b/src/r_main.h index ccbc0ad8c..94103ceed 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -38,7 +38,9 @@ extern size_t validcount, linecount, loopcount, framecount; // The fraction of a tic being drawn (for interpolation between two tics) extern fixed_t rendertimefrac; // Evaluated delta tics for this frame (how many tics since the last frame) -extern fixed_t renderdeltatics;; +extern fixed_t renderdeltatics; +// The current render is a new logical tic +extern boolean renderisnewtic; // // Lighting LUT. diff --git a/src/st_stuff.c b/src/st_stuff.c index 6ab310252..fcdde5826 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -43,6 +43,7 @@ #endif #include "lua_hud.h" +#include "lua_hudlib_drawlist.h" #include "lua_hook.h" #include "r_fps.h" @@ -163,6 +164,9 @@ hudinfo_t hudinfo[NUMHUDITEMS] = { 288, 176, V_SNAPTORIGHT|V_SNAPTOBOTTOM}, // HUD_POWERUPS }; +static huddrawlist_h luahuddrawlist_game; +static huddrawlist_h luahuddrawlist_titlecard; + // // STATUS BAR CODE // @@ -422,6 +426,9 @@ void ST_Init(void) return; ST_LoadGraphics(); + + luahuddrawlist_game = LUA_HUD_CreateDrawList(); + luahuddrawlist_titlecard = LUA_HUD_CreateDrawList(); } // change the status bar too, when pressing F12 while viewing a demo. @@ -1404,7 +1411,12 @@ void ST_drawTitleCard(void) lt_lasttic = lt_ticker; luahook: - LUA_HUDHOOK(titlecard); + if (renderisnewtic) + { + LUA_HUD_ClearDrawList(luahuddrawlist_titlecard); + LUA_HUDHOOK(titlecard, luahuddrawlist_titlecard); + } + LUA_HUD_DrawList(luahuddrawlist_titlecard); } // @@ -2744,7 +2756,14 @@ static void ST_overlayDrawer(void) ST_drawPowerupHUD(); // same as it ever was... if (!(netgame || multiplayer) || !hu_showscores) - LUA_HUDHOOK(game); + { + if (renderisnewtic) + { + LUA_HUD_ClearDrawList(luahuddrawlist_game); + LUA_HUDHOOK(game, luahuddrawlist_game); + } + LUA_HUD_DrawList(luahuddrawlist_game); + } // draw level title Tails if (stagetitle && (!WipeInAction) && (!WipeStageTitle)) diff --git a/src/y_inter.c b/src/y_inter.c index 8b5c9efc7..4f7b0499d 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -38,6 +38,7 @@ #include "lua_hook.h" // IntermissionThinker hook #include "lua_hud.h" +#include "lua_hudlib_drawlist.h" #ifdef HWRENDER #include "hardware/hw_main.h" @@ -165,6 +166,8 @@ static INT32 endtic = -1; intertype_t intertype = int_none; intertype_t intermissiontypes[NUMGAMETYPES]; +static huddrawlist_h luahuddrawlist_intermission; + static void Y_RescaleScreenBuffer(void); static void Y_AwardCoopBonuses(void); static void Y_AwardSpecialStageBonus(void); @@ -433,7 +436,13 @@ void Y_IntermissionDrawer(void) else if (bgtile) V_DrawPatchFill(bgtile); - LUA_HUDHOOK(intermission); + if (renderisnewtic) + { + LUA_HUD_ClearDrawList(luahuddrawlist_intermission); + LUA_HUDHOOK(intermission, luahuddrawlist_intermission); + } + LUA_HUD_DrawList(luahuddrawlist_intermission); + if (!LUA_HudEnabled(hud_intermissiontally)) goto skiptallydrawer; @@ -1591,6 +1600,9 @@ void Y_StartIntermission(void) default: break; } + + LUA_HUD_DestroyDrawList(luahuddrawlist_intermission); + luahuddrawlist_intermission = LUA_HUD_CreateDrawList(); } //