mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-22 10:52:23 +00:00
Refactor hudlib hooks to hooklib
HUD hooks now meet the standard of hooklib. HUD registry magic numbers are gone. HUD hooks may also be added using addHook. addHook('HUD', fn[, type]) hud.add still exists, but the intention is to remove it eventually.
This commit is contained in:
parent
ae57b6ca86
commit
b4fa98d2fb
8 changed files with 93 additions and 219 deletions
|
@ -41,6 +41,7 @@
|
|||
#include "console.h"
|
||||
|
||||
#include "lua_hud.h"
|
||||
#include "lua_hook.h"
|
||||
|
||||
// Stage of animation:
|
||||
// 0 = text, 1 = art screen
|
||||
|
@ -3423,7 +3424,7 @@ void F_TitleScreenDrawer(void)
|
|||
}
|
||||
|
||||
luahook:
|
||||
LUAh_TitleHUD();
|
||||
LUA_HUDHOOK(title);
|
||||
}
|
||||
|
||||
// separate animation timer for backgrounds, since we also count
|
||||
|
|
|
@ -2104,7 +2104,7 @@ void HU_Drawer(void)
|
|||
}
|
||||
else
|
||||
HU_DrawCoopOverlay();
|
||||
LUAh_ScoresHUD();
|
||||
LUA_HUDHOOK(scores);
|
||||
}
|
||||
|
||||
if (gamestate != GS_LEVEL)
|
||||
|
|
|
@ -78,6 +78,13 @@ automatically.
|
|||
X (LinedefExecute),\
|
||||
X (ShouldJingleContinue),/* should jingle of the given music continue playing */\
|
||||
|
||||
#define HUD_HOOK_LIST(X) \
|
||||
X (game),\
|
||||
X (scores),/* emblems/multiplayer list */\
|
||||
X (title),/* titlescreen */\
|
||||
X (titlecard),\
|
||||
X (intermission),\
|
||||
|
||||
/*
|
||||
I chose to access the hook enums through a macro as well. This could provide
|
||||
a hint to lookup the macro's definition instead of the enum's definition.
|
||||
|
@ -88,22 +95,26 @@ grepped and found in the lists above.
|
|||
|
||||
#define MOBJ_HOOK(name) mobjhook_ ## name
|
||||
#define HOOK(name) hook_ ## name
|
||||
#define HUD_HOOK(name) hudhook_ ## name
|
||||
#define STRING_HOOK(name) stringhook_ ## name
|
||||
|
||||
#define ENUM(X) enum { X ## _LIST (X) X(MAX) }
|
||||
|
||||
ENUM (MOBJ_HOOK);
|
||||
ENUM (HOOK);
|
||||
ENUM (HUD_HOOK);
|
||||
ENUM (STRING_HOOK);
|
||||
|
||||
#undef ENUM
|
||||
|
||||
/* dead simple, LUA_HOOK(GameQuit) */
|
||||
#define LUA_HOOK(type) LUA_HookVoid(HOOK(type))
|
||||
#define LUA_HUDHOOK(type) LUA_HookHUD(HUD_HOOK(type))
|
||||
|
||||
extern boolean hook_cmd_running;
|
||||
|
||||
void LUA_HookVoid(int hook);
|
||||
void LUA_HookHUD(int hook);
|
||||
|
||||
int LUA_HookMobj(mobj_t *, int hook);
|
||||
int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
LIST (mobjHookNames, MOBJ_HOOK_LIST);
|
||||
LIST (hookNames, HOOK_LIST);
|
||||
LIST (hudHookNames, HUD_HOOK_LIST);
|
||||
LIST (stringHookNames, STRING_HOOK_LIST);
|
||||
|
||||
#undef LIST
|
||||
|
@ -51,6 +52,7 @@ typedef struct {
|
|||
} stringhook_t;
|
||||
|
||||
static hook_t hookIds[HOOK(MAX)];
|
||||
static hook_t hudHookIds[HUD_HOOK(MAX)];
|
||||
static hook_t mobjHookIds[NUMMOBJTYPES][MOBJ_HOOK(MAX)];
|
||||
|
||||
// Lua tables are used to lookup string hook ids.
|
||||
|
@ -171,6 +173,12 @@ static void add_mobj_hook(lua_State *L, int hook_type)
|
|||
add_hook(&mobjHookIds[mobj_type][hook_type]);
|
||||
}
|
||||
|
||||
static void add_hud_hook(lua_State *L, int idx)
|
||||
{
|
||||
add_hook(&hudHookIds[luaL_checkoption(L,
|
||||
idx, "game", hudHookNames)]);
|
||||
}
|
||||
|
||||
static void add_hook_ref(lua_State *L, int idx)
|
||||
{
|
||||
if (!(nextid & 7))
|
||||
|
@ -213,6 +221,10 @@ static int lib_addHook(lua_State *L)
|
|||
{
|
||||
add_hook(&hookIds[type]);
|
||||
}
|
||||
else if (strcmp(name, "HUD") == 0)
|
||||
{
|
||||
add_hud_hook(L, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
return luaL_argerror(L, 1, lua_pushfstring(L, "invalid hook " LUA_QS, name));
|
||||
|
@ -233,6 +245,23 @@ int LUA_HookLib(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: remove in next backwards incompatible release */
|
||||
#if MODID == 18
|
||||
int lib_hudadd(lua_State *L);/* yeah compiler */
|
||||
int lib_hudadd(lua_State *L)
|
||||
{
|
||||
if (!lua_lumploading)
|
||||
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
|
||||
|
||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||
|
||||
add_hud_hook(L, 2);
|
||||
add_hook_ref(L, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct Hook_State Hook_State;
|
||||
typedef void (*Hook_Callback)(Hook_State *);
|
||||
|
||||
|
@ -610,6 +639,24 @@ int LUA_HookKey(INT32 keycode, int hook_type)
|
|||
return hook.status;
|
||||
}
|
||||
|
||||
void LUA_HookHUD(int hook_type)
|
||||
{
|
||||
const hook_t * map = &hudHookIds[hook_type];
|
||||
Hook_State hook;
|
||||
if (map->numHooks > 0)
|
||||
{
|
||||
start_hook_stack();
|
||||
begin_hook_values(&hook);
|
||||
|
||||
LUA_SetHudHook(hook_type);
|
||||
|
||||
hud_running = true; // local hook
|
||||
init_hook_call(&hook, 0, res_none);
|
||||
call_mapped(&hook, map);
|
||||
hud_running = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
SPECIALIZED HOOKS
|
||||
========================================================================= */
|
||||
|
|
|
@ -47,8 +47,4 @@ extern boolean hud_running;
|
|||
|
||||
boolean LUA_HudEnabled(enum hud option);
|
||||
|
||||
void LUAh_GameHUD(player_t *stplyr);
|
||||
void LUAh_ScoresHUD(void);
|
||||
void LUAh_TitleHUD(void);
|
||||
void LUAh_TitleCardHUD(player_t *stplayr);
|
||||
void LUAh_IntermissionHUD(boolean failedstage);
|
||||
void LUA_SetHudHook(int hook);
|
||||
|
|
236
src/lua_hudlib.c
236
src/lua_hudlib.c
|
@ -23,18 +23,18 @@
|
|||
#include "v_video.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "y_inter.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h"
|
||||
#include "lua_hook.h"
|
||||
|
||||
#define HUDONLY if (!hud_running) return luaL_error(L, "HUD rendering code should not be called outside of rendering hooks!");
|
||||
|
||||
boolean hud_running = false;
|
||||
static UINT8 hud_enabled[(hud_MAX/8)+1];
|
||||
|
||||
static UINT8 hudAvailable; // hud hooks field
|
||||
|
||||
// must match enum hud in lua_hud.h
|
||||
static const char *const hud_disable_options[] = {
|
||||
"stagetitle",
|
||||
|
@ -95,21 +95,6 @@ static const char *const patch_opt[] = {
|
|||
"topoffset",
|
||||
NULL};
|
||||
|
||||
enum hudhook {
|
||||
hudhook_game = 0,
|
||||
hudhook_scores,
|
||||
hudhook_intermission,
|
||||
hudhook_title,
|
||||
hudhook_titlecard
|
||||
};
|
||||
static const char *const hudhook_opt[] = {
|
||||
"game",
|
||||
"scores",
|
||||
"intermission",
|
||||
"title",
|
||||
"titlecard",
|
||||
NULL};
|
||||
|
||||
// alignment types for v.drawString
|
||||
enum align {
|
||||
align_left = 0,
|
||||
|
@ -1152,6 +1137,8 @@ static luaL_Reg lib_draw[] = {
|
|||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static int lib_draw_ref;
|
||||
|
||||
//
|
||||
// lib_hud
|
||||
//
|
||||
|
@ -1186,28 +1173,7 @@ static int lib_hudenabled(lua_State *L)
|
|||
|
||||
|
||||
// add a HUD element for rendering
|
||||
static int lib_hudadd(lua_State *L)
|
||||
{
|
||||
enum hudhook field;
|
||||
|
||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||
field = luaL_checkoption(L, 2, "game", hudhook_opt);
|
||||
|
||||
if (!lua_lumploading)
|
||||
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_rawgeti(L, -1, field+2); // HUD[2+]
|
||||
I_Assert(lua_istable(L, -1));
|
||||
lua_remove(L, -2);
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
lua_rawseti(L, -2, (int)(lua_objlen(L, -2) + 1));
|
||||
|
||||
hudAvailable |= 1<<field;
|
||||
return 0;
|
||||
}
|
||||
extern int lib_hudadd(lua_State *L);
|
||||
|
||||
static luaL_Reg lib_hud[] = {
|
||||
{"enable", lib_hudenable},
|
||||
|
@ -1225,26 +1191,9 @@ int LUA_HudLib(lua_State *L)
|
|||
{
|
||||
memset(hud_enabled, 0xff, (hud_MAX/8)+1);
|
||||
|
||||
lua_newtable(L); // HUD registry table
|
||||
lua_newtable(L);
|
||||
luaL_register(L, NULL, lib_draw);
|
||||
lua_rawseti(L, -2, 1); // HUD[1] = lib_draw
|
||||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 2); // HUD[2] = game rendering functions array
|
||||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 3); // HUD[3] = scores rendering functions array
|
||||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 4); // HUD[4] = intermission rendering functions array
|
||||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 5); // HUD[5] = title rendering functions array
|
||||
|
||||
lua_newtable(L);
|
||||
lua_rawseti(L, -2, 6); // HUD[6] = title card rendering functions array
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "HUD");
|
||||
lua_newtable(L);
|
||||
luaL_register(L, NULL, lib_draw);
|
||||
lib_draw_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
luaL_newmetatable(L, META_HUDINFO);
|
||||
lua_pushcfunction(L, hudinfo_get);
|
||||
|
@ -1296,160 +1245,29 @@ boolean LUA_HudEnabled(enum hud option)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Hook for HUD rendering
|
||||
void LUAh_GameHUD(player_t *stplayr)
|
||||
void LUA_SetHudHook(int hook)
|
||||
{
|
||||
if (!gL || !(hudAvailable & (1<<hudhook_game)))
|
||||
return;
|
||||
lua_getref(gL, lib_draw_ref);
|
||||
|
||||
hud_running = true;
|
||||
lua_settop(gL, 0);
|
||||
switch (hook)
|
||||
{
|
||||
case HUD_HOOK(game): {
|
||||
camera_t *cam = (splitscreen && stplyr ==
|
||||
&players[secondarydisplayplayer])
|
||||
? &camera2 : &camera;
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
LUA_PushUserdata(gL, stplyr, META_PLAYER);
|
||||
LUA_PushUserdata(gL, cam, META_CAMERA);
|
||||
} break;
|
||||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 2+hudhook_game); // HUD[2] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
case HUD_HOOK(titlecard):
|
||||
LUA_PushUserdata(gL, stplyr, META_PLAYER);
|
||||
lua_pushinteger(gL, lt_ticker);
|
||||
lua_pushinteger(gL, (lt_endtime + TICRATE));
|
||||
break;
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_remove(gL, -3); // pop HUD
|
||||
LUA_PushUserdata(gL, stplayr, META_PLAYER);
|
||||
|
||||
if (splitscreen && stplayr == &players[secondarydisplayplayer])
|
||||
LUA_PushUserdata(gL, &camera2, META_CAMERA);
|
||||
else
|
||||
LUA_PushUserdata(gL, &camera, META_CAMERA);
|
||||
|
||||
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); // camera
|
||||
LUA_Call(gL, 3, 0, 1);
|
||||
case HUD_HOOK(intermission):
|
||||
lua_pushboolean(gL, intertype == int_spec &&
|
||||
stagefailed);
|
||||
}
|
||||
lua_settop(gL, 0);
|
||||
hud_running = false;
|
||||
}
|
||||
|
||||
void LUAh_ScoresHUD(void)
|
||||
{
|
||||
if (!gL || !(hudAvailable & (1<<hudhook_scores)))
|
||||
return;
|
||||
|
||||
hud_running = true;
|
||||
lua_settop(gL, 0);
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 2+hudhook_scores); // HUD[3] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_remove(gL, -3); // pop HUD
|
||||
lua_pushnil(gL);
|
||||
while (lua_next(gL, -3) != 0) {
|
||||
lua_pushvalue(gL, -3); // graphics library (HUD[1])
|
||||
LUA_Call(gL, 1, 0, 1);
|
||||
}
|
||||
lua_settop(gL, 0);
|
||||
hud_running = false;
|
||||
}
|
||||
|
||||
void LUAh_TitleHUD(void)
|
||||
{
|
||||
if (!gL || !(hudAvailable & (1<<hudhook_title)))
|
||||
return;
|
||||
|
||||
hud_running = true;
|
||||
lua_settop(gL, 0);
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 2+hudhook_title); // HUD[5] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_remove(gL, -3); // pop HUD
|
||||
lua_pushnil(gL);
|
||||
while (lua_next(gL, -3) != 0) {
|
||||
lua_pushvalue(gL, -3); // graphics library (HUD[1])
|
||||
LUA_Call(gL, 1, 0, 1);
|
||||
}
|
||||
lua_settop(gL, 0);
|
||||
hud_running = false;
|
||||
}
|
||||
|
||||
void LUAh_TitleCardHUD(player_t *stplayr)
|
||||
{
|
||||
if (!gL || !(hudAvailable & (1<<hudhook_titlecard)))
|
||||
return;
|
||||
|
||||
hud_running = true;
|
||||
lua_settop(gL, 0);
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 2+hudhook_titlecard); // HUD[6] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_remove(gL, -3); // pop HUD
|
||||
|
||||
LUA_PushUserdata(gL, stplayr, META_PLAYER);
|
||||
lua_pushinteger(gL, lt_ticker);
|
||||
lua_pushinteger(gL, (lt_endtime + TICRATE));
|
||||
lua_pushnil(gL);
|
||||
|
||||
while (lua_next(gL, -6) != 0) {
|
||||
lua_pushvalue(gL, -6); // graphics library (HUD[1])
|
||||
lua_pushvalue(gL, -6); // stplayr
|
||||
lua_pushvalue(gL, -6); // lt_ticker
|
||||
lua_pushvalue(gL, -6); // lt_endtime
|
||||
LUA_Call(gL, 4, 0, 1);
|
||||
}
|
||||
|
||||
lua_settop(gL, 0);
|
||||
hud_running = false;
|
||||
}
|
||||
|
||||
void LUAh_IntermissionHUD(boolean failedstage)
|
||||
{
|
||||
if (!gL || !(hudAvailable & (1<<hudhook_intermission)))
|
||||
return;
|
||||
|
||||
hud_running = true;
|
||||
lua_settop(gL, 0);
|
||||
|
||||
lua_pushcfunction(gL, LUA_GetErrorMessage);
|
||||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 2+hudhook_intermission); // HUD[4] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_remove(gL, -3); // pop HUD
|
||||
|
||||
lua_pushboolean(gL, failedstage); // stagefailed
|
||||
lua_pushnil(gL);
|
||||
|
||||
while (lua_next(gL, -4) != 0) {
|
||||
lua_pushvalue(gL, -4); // graphics library (HUD[1])
|
||||
lua_pushvalue(gL, -4); // stagefailed
|
||||
LUA_Call(gL, 2, 0, 1);
|
||||
}
|
||||
lua_settop(gL, 0);
|
||||
hud_running = false;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#endif
|
||||
|
||||
#include "lua_hud.h"
|
||||
#include "lua_hook.h"
|
||||
|
||||
UINT16 objectsdrawn = 0;
|
||||
|
||||
|
@ -1391,7 +1392,7 @@ void ST_drawTitleCard(void)
|
|||
lt_lasttic = lt_ticker;
|
||||
|
||||
luahook:
|
||||
LUAh_TitleCardHUD(stplyr);
|
||||
LUA_HUDHOOK(titlecard);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2732,7 +2733,7 @@ static void ST_overlayDrawer(void)
|
|||
ST_drawPowerupHUD(); // same as it ever was...
|
||||
|
||||
if (!(netgame || multiplayer) || !hu_showscores)
|
||||
LUAh_GameHUD(stplyr);
|
||||
LUA_HUDHOOK(game);
|
||||
|
||||
// draw level title Tails
|
||||
if (stagetitle && (!WipeInAction) && (!WipeStageTitle))
|
||||
|
|
|
@ -430,7 +430,7 @@ void Y_IntermissionDrawer(void)
|
|||
else if (bgtile)
|
||||
V_DrawPatchFill(bgtile);
|
||||
|
||||
LUAh_IntermissionHUD(intertype == int_spec && stagefailed);
|
||||
LUA_HUDHOOK(intermission);
|
||||
if (!LUA_HudEnabled(hud_intermissiontally))
|
||||
goto skiptallydrawer;
|
||||
|
||||
|
|
Loading…
Reference in a new issue