mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-28 15:11:55 +00:00
Merge branch 'hudlib-hook-refactor' into 'next'
Refactor HUD hooks too See merge request STJr/SRB2!1577
This commit is contained in:
commit
952ae51669
8 changed files with 188 additions and 297 deletions
|
@ -41,6 +41,7 @@
|
|||
#include "console.h"
|
||||
|
||||
#include "lua_hud.h"
|
||||
#include "lua_hook.h"
|
||||
|
||||
// Stage of animation:
|
||||
// 0 = text, 1 = art screen
|
||||
|
@ -3421,7 +3422,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)
|
||||
|
|
|
@ -79,6 +79,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.
|
||||
|
@ -89,18 +96,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
|
||||
|
||||
enum { MOBJ_HOOK_LIST (MOBJ_HOOK) MOBJ_HOOK(MAX) };
|
||||
enum { HOOK_LIST (HOOK) HOOK(MAX) };
|
||||
enum { STRING_HOOK_LIST (STRING_HOOK) STRING_HOOK(MAX) };
|
||||
#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);
|
||||
|
|
|
@ -31,12 +31,15 @@
|
|||
ABSTRACTION
|
||||
========================================================================= */
|
||||
|
||||
static const char * const mobjHookNames[] = { MOBJ_HOOK_LIST (TOSTR) NULL };
|
||||
static const char * const hookNames[] = { HOOK_LIST (TOSTR) NULL };
|
||||
#define LIST(id, M) \
|
||||
static const char * const id [] = { M (TOSTR) NULL }
|
||||
|
||||
static const char * const stringHookNames[] = {
|
||||
STRING_HOOK_LIST (TOSTR) NULL
|
||||
};
|
||||
LIST (mobjHookNames, MOBJ_HOOK_LIST);
|
||||
LIST (hookNames, HOOK_LIST);
|
||||
LIST (hudHookNames, HUD_HOOK_LIST);
|
||||
LIST (stringHookNames, STRING_HOOK_LIST);
|
||||
|
||||
#undef LIST
|
||||
|
||||
typedef struct {
|
||||
int numHooks;
|
||||
|
@ -49,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.
|
||||
|
@ -56,6 +60,7 @@ static stringhook_t stringHooks[STRING_HOOK(MAX)];
|
|||
|
||||
// This will be indexed by hook id, the value of which fetches the registry.
|
||||
static int * hookRefs;
|
||||
static int nextid;
|
||||
|
||||
// After a hook errors once, don't print the error again.
|
||||
static UINT8 * hooksErrored;
|
||||
|
@ -104,13 +109,13 @@ static void get_table(lua_State *L)
|
|||
lua_remove(L, -2);
|
||||
}
|
||||
|
||||
static void add_hook_to_table(lua_State *L, int id, int n)
|
||||
static void add_hook_to_table(lua_State *L, int n)
|
||||
{
|
||||
lua_pushnumber(L, id);
|
||||
lua_pushnumber(L, nextid);
|
||||
lua_rawseti(L, -2, n);
|
||||
}
|
||||
|
||||
static void add_string_hook(lua_State *L, int type, int id)
|
||||
static void add_string_hook(lua_State *L, int type)
|
||||
{
|
||||
stringhook_t * hook = &stringHooks[type];
|
||||
|
||||
|
@ -146,33 +151,54 @@ static void add_string_hook(lua_State *L, int type, int id)
|
|||
{
|
||||
lua_pushstring(L, string);
|
||||
get_table(L);
|
||||
add_hook_to_table(L, id, 1 + lua_objlen(L, -1));
|
||||
add_hook_to_table(L, 1 + lua_objlen(L, -1));
|
||||
}
|
||||
else
|
||||
add_hook_to_table(L, id, ++hook->numGeneric);
|
||||
add_hook_to_table(L, ++hook->numGeneric);
|
||||
}
|
||||
|
||||
static void add_hook(hook_t *map, int id)
|
||||
static void add_hook(hook_t *map)
|
||||
{
|
||||
Z_Realloc(map->ids, (map->numHooks + 1) * sizeof *map->ids,
|
||||
PU_STATIC, &map->ids);
|
||||
map->ids[map->numHooks++] = id;
|
||||
map->ids[map->numHooks++] = nextid;
|
||||
}
|
||||
|
||||
static void add_mobj_hook(lua_State *L, int hook_type, int id)
|
||||
static void add_mobj_hook(lua_State *L, int hook_type)
|
||||
{
|
||||
mobjtype_t mobj_type = luaL_optnumber(L, 3, MT_NULL);
|
||||
|
||||
luaL_argcheck(L, mobj_type < NUMMOBJTYPES, 3, "invalid mobjtype_t");
|
||||
|
||||
add_hook(&mobjHookIds[mobj_type][hook_type], id);
|
||||
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))
|
||||
{
|
||||
Z_Realloc(hooksErrored,
|
||||
BIT_ARRAY_SIZE (nextid + 1) * sizeof *hooksErrored,
|
||||
PU_STATIC, &hooksErrored);
|
||||
hooksErrored[nextid >> 3] = 0;
|
||||
}
|
||||
|
||||
Z_Realloc(hookRefs, (nextid + 1) * sizeof *hookRefs, PU_STATIC, &hookRefs);
|
||||
|
||||
// set the hook function in the registry.
|
||||
lua_pushvalue(L, idx);
|
||||
hookRefs[nextid++] = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
// Takes hook, function, and additional arguments (mobj type to act on, etc.)
|
||||
static int lib_addHook(lua_State *L)
|
||||
{
|
||||
static int nextid;
|
||||
|
||||
const char * name;
|
||||
int type;
|
||||
|
||||
|
@ -185,34 +211,26 @@ static int lib_addHook(lua_State *L)
|
|||
/* this is a very special case */
|
||||
if (( type = hook_in_list(name, stringHookNames) ) < STRING_HOOK(MAX))
|
||||
{
|
||||
add_string_hook(L, type, nextid);
|
||||
add_string_hook(L, type);
|
||||
}
|
||||
else if (( type = hook_in_list(name, mobjHookNames) ) < MOBJ_HOOK(MAX))
|
||||
{
|
||||
add_mobj_hook(L, type, nextid);
|
||||
add_mobj_hook(L, type);
|
||||
}
|
||||
else if (( type = hook_in_list(name, hookNames) ) < HOOK(MAX))
|
||||
{
|
||||
add_hook(&hookIds[type], nextid);
|
||||
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));
|
||||
}
|
||||
|
||||
if (!(nextid & 7))
|
||||
{
|
||||
Z_Realloc(hooksErrored,
|
||||
BIT_ARRAY_SIZE (nextid + 1) * sizeof *hooksErrored,
|
||||
PU_STATIC, &hooksErrored);
|
||||
hooksErrored[nextid >> 3] = 0;
|
||||
}
|
||||
|
||||
Z_Realloc(hookRefs, (nextid + 1) * sizeof *hookRefs, PU_STATIC, &hookRefs);
|
||||
|
||||
// set the hook function in the registry.
|
||||
lua_pushvalue(L, 2);/* the function */
|
||||
hookRefs[nextid++] = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
add_hook_ref(L, 2);/* the function */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -227,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 *);
|
||||
|
||||
|
@ -259,11 +294,16 @@ static void push_string(void)
|
|||
lua_pushvalue(gL, SINDEX);
|
||||
}
|
||||
|
||||
static boolean start_hook_stack(void)
|
||||
static boolean begin_hook_values(Hook_State *hook)
|
||||
{
|
||||
hook->top = lua_gettop(gL);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void start_hook_stack(void)
|
||||
{
|
||||
lua_settop(gL, 0);
|
||||
push_error_handler();
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean init_hook_type
|
||||
|
@ -279,10 +319,11 @@ static boolean init_hook_type
|
|||
|
||||
if (nonzero)
|
||||
{
|
||||
start_hook_stack();
|
||||
hook->hook_type = hook_type;
|
||||
hook->mobj_type = mobj_type;
|
||||
hook->string = string;
|
||||
return start_hook_stack();
|
||||
return begin_hook_values(hook);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
@ -323,7 +364,7 @@ static boolean prepare_string_hook
|
|||
stringHooks[hook_type].ref))
|
||||
{
|
||||
lua_pushstring(gL, string);
|
||||
return true;
|
||||
return begin_hook_values(hook);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
@ -332,12 +373,12 @@ static boolean prepare_string_hook
|
|||
static void init_hook_call
|
||||
(
|
||||
Hook_State * hook,
|
||||
int values,
|
||||
int results,
|
||||
Hook_Callback results_handler
|
||||
){
|
||||
hook->top = lua_gettop(gL);
|
||||
hook->values = values;
|
||||
const int top = lua_gettop(gL);
|
||||
hook->values = (top - hook->top);
|
||||
hook->top = top;
|
||||
hook->results = results;
|
||||
hook->results_handler = results_handler;
|
||||
}
|
||||
|
@ -447,13 +488,12 @@ static int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
|
|||
static int call_hooks
|
||||
(
|
||||
Hook_State * hook,
|
||||
int values,
|
||||
int results,
|
||||
Hook_Callback results_handler
|
||||
){
|
||||
int calls = 0;
|
||||
|
||||
init_hook_call(hook, values, results, results_handler);
|
||||
init_hook_call(hook, results, results_handler);
|
||||
|
||||
if (hook->string)
|
||||
{
|
||||
|
@ -514,7 +554,7 @@ int LUA_HookMobj(mobj_t *mobj, int hook_type)
|
|||
if (prepare_mobj_hook(&hook, false, hook_type, mobj->type))
|
||||
{
|
||||
LUA_PushUserdata(gL, mobj, META_MOBJ);
|
||||
call_hooks(&hook, 1, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -526,7 +566,7 @@ int LUA_Hook2Mobj(mobj_t *t1, mobj_t *t2, int hook_type)
|
|||
{
|
||||
LUA_PushUserdata(gL, t1, META_MOBJ);
|
||||
LUA_PushUserdata(gL, t2, META_MOBJ);
|
||||
call_hooks(&hook, 2, 1, res_force);
|
||||
call_hooks(&hook, 1, res_force);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -535,7 +575,7 @@ void LUA_HookVoid(int type)
|
|||
{
|
||||
Hook_State hook;
|
||||
if (prepare_hook(&hook, 0, type))
|
||||
call_hooks(&hook, 0, 0, res_none);
|
||||
call_hooks(&hook, 0, res_none);
|
||||
}
|
||||
|
||||
void LUA_HookInt(INT32 number, int hook_type)
|
||||
|
@ -544,7 +584,7 @@ void LUA_HookInt(INT32 number, int hook_type)
|
|||
if (prepare_hook(&hook, 0, hook_type))
|
||||
{
|
||||
lua_pushinteger(gL, number);
|
||||
call_hooks(&hook, 1, 0, res_none);
|
||||
call_hooks(&hook, 0, res_none);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -554,7 +594,7 @@ void LUA_HookBool(boolean value, int hook_type)
|
|||
if (prepare_hook(&hook, 0, hook_type))
|
||||
{
|
||||
lua_pushboolean(gL, value);
|
||||
call_hooks(&hook, 1, 0, res_none);
|
||||
call_hooks(&hook, 0, res_none);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,7 +604,7 @@ int LUA_HookPlayer(player_t *player, int hook_type)
|
|||
if (prepare_hook(&hook, false, hook_type))
|
||||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
call_hooks(&hook, 1, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -580,7 +620,7 @@ int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type)
|
|||
if (hook_type == HOOK(PlayerCmd))
|
||||
hook_cmd_running = true;
|
||||
|
||||
call_hooks(&hook, 2, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
|
||||
if (hook_type == HOOK(PlayerCmd))
|
||||
hook_cmd_running = false;
|
||||
|
@ -594,11 +634,29 @@ int LUA_HookKey(event_t *event, int hook_type)
|
|||
if (prepare_hook(&hook, false, hook_type))
|
||||
{
|
||||
LUA_PushUserdata(gL, event, META_KEYEVENT);
|
||||
call_hooks(&hook, 1, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
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
|
||||
========================================================================= */
|
||||
|
@ -618,7 +676,7 @@ void LUA_HookThinkFrame(void)
|
|||
|
||||
if (prepare_hook(&hook, 0, type))
|
||||
{
|
||||
init_hook_call(&hook, 0, 0, res_none);
|
||||
init_hook_call(&hook, 0, res_none);
|
||||
|
||||
for (k = 0; k < map->numHooks; ++k)
|
||||
{
|
||||
|
@ -653,7 +711,7 @@ int LUA_HookMobjLineCollide(mobj_t *mobj, line_t *line)
|
|||
{
|
||||
LUA_PushUserdata(gL, mobj, META_MOBJ);
|
||||
LUA_PushUserdata(gL, line, META_LINE);
|
||||
call_hooks(&hook, 2, 1, res_force);
|
||||
call_hooks(&hook, 1, res_force);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -665,7 +723,7 @@ int LUA_HookTouchSpecial(mobj_t *special, mobj_t *toucher)
|
|||
{
|
||||
LUA_PushUserdata(gL, special, META_MOBJ);
|
||||
LUA_PushUserdata(gL, toucher, META_MOBJ);
|
||||
call_hooks(&hook, 2, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -678,7 +736,6 @@ static int damage_hook
|
|||
INT32 damage,
|
||||
UINT8 damagetype,
|
||||
int hook_type,
|
||||
int values,
|
||||
Hook_Callback results_handler
|
||||
){
|
||||
Hook_State hook;
|
||||
|
@ -687,10 +744,10 @@ static int damage_hook
|
|||
LUA_PushUserdata(gL, target, META_MOBJ);
|
||||
LUA_PushUserdata(gL, inflictor, META_MOBJ);
|
||||
LUA_PushUserdata(gL, source, META_MOBJ);
|
||||
if (values == 5)
|
||||
if (hook_type != MOBJ_HOOK(MobjDeath))
|
||||
lua_pushinteger(gL, damage);
|
||||
lua_pushinteger(gL, damagetype);
|
||||
call_hooks(&hook, values, 1, results_handler);
|
||||
call_hooks(&hook, 1, results_handler);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -698,19 +755,19 @@ static int damage_hook
|
|||
int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
||||
{
|
||||
return damage_hook(target, inflictor, source, damage, damagetype,
|
||||
MOBJ_HOOK(ShouldDamage), 5, res_force);
|
||||
MOBJ_HOOK(ShouldDamage), res_force);
|
||||
}
|
||||
|
||||
int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
||||
{
|
||||
return damage_hook(target, inflictor, source, damage, damagetype,
|
||||
MOBJ_HOOK(MobjDamage), 5, res_true);
|
||||
MOBJ_HOOK(MobjDamage), res_true);
|
||||
}
|
||||
|
||||
int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype)
|
||||
{
|
||||
return damage_hook(target, inflictor, source, 0, damagetype,
|
||||
MOBJ_HOOK(MobjDeath), 4, res_true);
|
||||
MOBJ_HOOK(MobjDeath), res_true);
|
||||
}
|
||||
|
||||
int LUA_HookMobjMoveBlocked(mobj_t *t1, mobj_t *t2, line_t *line)
|
||||
|
@ -721,7 +778,7 @@ int LUA_HookMobjMoveBlocked(mobj_t *t1, mobj_t *t2, line_t *line)
|
|||
LUA_PushUserdata(gL, t1, META_MOBJ);
|
||||
LUA_PushUserdata(gL, t2, META_MOBJ);
|
||||
LUA_PushUserdata(gL, line, META_LINE);
|
||||
call_hooks(&hook, 3, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -796,7 +853,7 @@ int LUA_HookBotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
|
|||
|
||||
hook.userdata = &botai;
|
||||
|
||||
call_hooks(&hook, 2, 8, res_botai);
|
||||
call_hooks(&hook, 8, res_botai);
|
||||
}
|
||||
|
||||
return hook.status;
|
||||
|
@ -811,7 +868,7 @@ void LUA_HookLinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
|
|||
LUA_PushUserdata(gL, line, META_LINE);
|
||||
LUA_PushUserdata(gL, mo, META_MOBJ);
|
||||
LUA_PushUserdata(gL, sector, META_SECTOR);
|
||||
ps_lua_mobjhooks += call_hooks(&hook, 3, 0, res_none);
|
||||
ps_lua_mobjhooks += call_hooks(&hook, 0, res_none);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -835,7 +892,7 @@ int LUA_HookPlayerMsg(int source, int target, int flags, char *msg)
|
|||
LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target
|
||||
}
|
||||
lua_pushstring(gL, msg); // msg
|
||||
call_hooks(&hook, 4, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -849,7 +906,7 @@ int LUA_HookHurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 d
|
|||
LUA_PushUserdata(gL, inflictor, META_MOBJ);
|
||||
LUA_PushUserdata(gL, source, META_MOBJ);
|
||||
lua_pushinteger(gL, damagetype);
|
||||
call_hooks(&hook, 4, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -868,12 +925,14 @@ void LUA_HookNetArchive(lua_CFunction archFunc)
|
|||
push_error_handler();
|
||||
lua_insert(gL, EINDEX);
|
||||
|
||||
begin_hook_values(&hook);
|
||||
|
||||
// tables becomes an upvalue of archFunc
|
||||
lua_pushvalue(gL, -1);
|
||||
lua_pushcclosure(gL, archFunc, 1);
|
||||
// stack: tables, archFunc
|
||||
|
||||
init_hook_call(&hook, 1, 0, res_none);
|
||||
init_hook_call(&hook, 0, res_none);
|
||||
call_mapped(&hook, map);
|
||||
|
||||
lua_pop(gL, 1); // pop archFunc
|
||||
|
@ -889,7 +948,7 @@ int LUA_HookMapThingSpawn(mobj_t *mobj, mapthing_t *mthing)
|
|||
{
|
||||
LUA_PushUserdata(gL, mobj, META_MOBJ);
|
||||
LUA_PushUserdata(gL, mthing, META_MAPTHING);
|
||||
call_hooks(&hook, 2, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -901,7 +960,7 @@ int LUA_HookFollowMobj(player_t *player, mobj_t *mobj)
|
|||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
LUA_PushUserdata(gL, mobj, META_MOBJ);
|
||||
call_hooks(&hook, 2, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -913,7 +972,7 @@ int LUA_HookPlayerCanDamage(player_t *player, mobj_t *mobj)
|
|||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
LUA_PushUserdata(gL, mobj, META_MOBJ);
|
||||
call_hooks(&hook, 2, 1, res_force);
|
||||
call_hooks(&hook, 1, res_force);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -925,7 +984,7 @@ void LUA_HookPlayerQuit(player_t *plr, kickreason_t reason)
|
|||
{
|
||||
LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit
|
||||
lua_pushinteger(gL, reason); // Reason for quitting
|
||||
call_hooks(&hook, 2, 0, res_none);
|
||||
call_hooks(&hook, 0, res_none);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -939,7 +998,7 @@ int LUA_HookTeamSwitch(player_t *player, int newteam, boolean fromspectators, bo
|
|||
lua_pushboolean(gL, fromspectators);
|
||||
lua_pushboolean(gL, tryingautobalance);
|
||||
lua_pushboolean(gL, tryingscramble);
|
||||
call_hooks(&hook, 5, 1, res_false);
|
||||
call_hooks(&hook, 1, res_false);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -954,7 +1013,7 @@ int LUA_HookViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolea
|
|||
lua_pushboolean(gL, forced);
|
||||
|
||||
hud_running = true; // local hook
|
||||
call_hooks(&hook, 3, 1, res_force);
|
||||
call_hooks(&hook, 1, res_force);
|
||||
hud_running = false;
|
||||
}
|
||||
return hook.status;
|
||||
|
@ -969,7 +1028,7 @@ int LUA_HookSeenPlayer(player_t *player, player_t *seenfriend)
|
|||
LUA_PushUserdata(gL, seenfriend, META_PLAYER);
|
||||
|
||||
hud_running = true; // local hook
|
||||
call_hooks(&hook, 2, 1, res_false);
|
||||
call_hooks(&hook, 1, res_false);
|
||||
hud_running = false;
|
||||
}
|
||||
return hook.status;
|
||||
|
@ -985,7 +1044,7 @@ int LUA_HookShouldJingleContinue(player_t *player, const char *musname)
|
|||
push_string();
|
||||
|
||||
hud_running = true; // local hook
|
||||
call_hooks(&hook, 2, 1, res_true);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
hud_running = false;
|
||||
}
|
||||
return hook.status;
|
||||
|
@ -1051,7 +1110,8 @@ int LUA_HookMusicChange(const char *oldname, struct MusicChange *param)
|
|||
|
||||
if (prepare_hook(&hook, false, type))
|
||||
{
|
||||
init_hook_call(&hook, 7, 6, res_musicchange);
|
||||
init_hook_call(&hook, 6, res_musicchange);
|
||||
hook.values = 7;/* values pushed later */
|
||||
hook.userdata = param;
|
||||
|
||||
lua_pushstring(gL, oldname);/* the only constant value */
|
||||
|
@ -1097,7 +1157,7 @@ fixed_t LUA_HookPlayerHeight(player_t *player)
|
|||
if (prepare_hook(&hook, -1, HOOK(PlayerHeight)))
|
||||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
call_hooks(&hook, 1, 1, res_playerheight);
|
||||
call_hooks(&hook, 1, res_playerheight);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
@ -1108,7 +1168,7 @@ int LUA_HookPlayerCanEnterSpinGaps(player_t *player)
|
|||
if (prepare_hook(&hook, 0, HOOK(PlayerCanEnterSpinGaps)))
|
||||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
call_hooks(&hook, 1, 1, res_force);
|
||||
call_hooks(&hook, 1, res_force);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
228
src/lua_hudlib.c
228
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,
|
||||
|
@ -1279,6 +1264,8 @@ static luaL_Reg lib_draw[] = {
|
|||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static int lib_draw_ref;
|
||||
|
||||
//
|
||||
// lib_hud
|
||||
//
|
||||
|
@ -1313,28 +1300,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},
|
||||
|
@ -1352,26 +1318,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");
|
||||
lib_draw_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
luaL_newmetatable(L, META_HUDINFO);
|
||||
lua_pushcfunction(L, hudinfo_get);
|
||||
|
@ -1432,160 +1381,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));
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
case HUD_HOOK(titlecard):
|
||||
LUA_PushUserdata(gL, stplyr, META_PLAYER);
|
||||
lua_pushinteger(gL, lt_ticker);
|
||||
lua_pushinteger(gL, (lt_endtime + TICRATE));
|
||||
lua_pushnil(gL);
|
||||
break;
|
||||
|
||||
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);
|
||||
case HUD_HOOK(intermission):
|
||||
lua_pushboolean(gL, intertype == int_spec &&
|
||||
stagefailed);
|
||||
}
|
||||
|
||||
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