Skip to content

Commit 7aebef4

Browse files
committed
maddog: Allow a simplified Lua tick() during laserdisc seeks.
This lets the crosshair remain responsive, lets gunflashes only last one frame no matter what, and lets the user fire and reload during the lag time. Other games should at least move coinslot input handling to a similar function, even if that isn't as significant as the maddog changes.
1 parent a73e5d8 commit 7aebef4

File tree

2 files changed

+79
-29
lines changed

2 files changed

+79
-29
lines changed

data/games/maddog/game.lua

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,26 @@ local function draw_available_credits()
441441
end
442442
end
443443

444+
local function draw_ui(inputs)
445+
if (scene_manager ~= nil) and (scene_manager.current_sequence ~= nil) then
446+
if scene_manager.current_sequence.overlay ~= nil then
447+
scene_manager.current_sequence.overlay()
448+
end
449+
if not scene_manager.current_sequence.hud_disabled then
450+
draw_hud()
451+
end
452+
if scene_manager.current_sequence.show_credits then
453+
draw_available_credits()
454+
end
455+
if show_hitboxes then
456+
draw_hitboxes()
457+
end
458+
if not scene_manager.current_sequence.crosshairs_disabled then
459+
draw_crosshair(inputs)
460+
end
461+
end
462+
end
463+
444464
local function setup_scene_manager()
445465
-- save off existing credits value, since we reinit when starting a game and would lose this.
446466
-- (this is part of the serialized state, though, so we need it to be in scene_manager and not a global).
@@ -564,14 +584,19 @@ local function crosshairs_in_area(area)
564584
return (x >= (area[1] / 360.0)) and (y >= (area[2] / 240.0)) and (x < (area[3] / 360.0)) and (y < (area[4] / 240.0))
565585
end
566586

567-
local function check_actions(inputs)
587+
-- called during both tick and seek_tick.
588+
local function check_actions_always(inputs)
568589
-- we don't care about inserting coins, but we'll play the sound if you
569590
-- hit the coinslot button and keep track of "credits"
570591
if inputs.pressed["coinslot"] then
571592
scene_manager.credits = scene_manager.credits + 1
572593
DirkSimple.play_sound("arcadecoin")
573594
end
574595

596+
if (scene_manager == nil) or (scene_manager.current_sequence == nil) then
597+
return
598+
end
599+
575600
if not scene_manager.current_sequence.crosshairs_disabled and not scene_manager.current_sequence.gunfire_disabled and not god_mode then
576601
--DirkSimple.log("x=" .. tostring(inputs.pointerx) .. " y=" .. tostring(inputs.pointery) .. " pressed=" .. tostring(inputs.pressed["action"] or false) .. " held=" .. tostring(inputs.held["action"] or false).. " released=" .. tostring(inputs.held["released"] or false))
577602
if inputs.pressed["action"] then
@@ -617,6 +642,10 @@ local function check_actions(inputs)
617642
end
618643
end
619644
end
645+
end
646+
647+
local function check_actions(inputs)
648+
check_actions_always(inputs)
620649

621650
if accepted_input ~= nil then
622651
return true -- ignore all input until end of sequence.
@@ -707,6 +736,7 @@ local function check_timeout()
707736
end
708737
end
709738

739+
710740
DirkSimple.serialize = function()
711741
if not scene_manager.initialized then
712742
setup_scene_manager() -- just so we can serialize a default state.
@@ -787,6 +817,11 @@ DirkSimple.unserialize = function(state)
787817
return true
788818
end
789819

820+
DirkSimple.seek_tick = function(ticks, inputs)
821+
check_actions_always(inputs)
822+
draw_ui(inputs)
823+
end
824+
790825
DirkSimple.tick = function(ticks, sequenceticks, inputs)
791826
xscale = DirkSimple.video_width / 1440.0
792827
yscale = DirkSimple.video_height / 1080.0
@@ -825,27 +860,11 @@ DirkSimple.tick = function(ticks, sequenceticks, inputs)
825860
start_attract_mode()
826861
end
827862

828-
if scene_manager.current_sequence ~= nil then
829-
if scene_manager.current_sequence.overlay ~= nil then
830-
scene_manager.current_sequence.overlay()
831-
end
832-
if not scene_manager.current_sequence.hud_disabled then
833-
draw_hud()
834-
end
835-
if scene_manager.current_sequence.show_credits then
836-
draw_available_credits()
837-
end
838-
if show_hitboxes then
839-
draw_hitboxes()
840-
end
841-
if not scene_manager.current_sequence.crosshairs_disabled then
842-
draw_crosshair(inputs)
843-
end
844-
end
845-
846863
check_actions(inputs) -- check inputs before timeout, in case an input came through at the last possible moment, even if we're over time.
847864
check_timeout()
848865

866+
draw_ui(inputs)
867+
849868
previous_sequence_ticks = scene_manager.current_sequence_ticks
850869
end
851870

dirksimple.c

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,33 @@ static void call_lua_tick(lua_State *L, uint64_t ticks, uint64_t clipstartticks,
16871687
collect_lua_garbage(L); // we can move this to start_clip if it turns out to be too heavy.
16881688
}
16891689

1690+
static void call_lua_seektick(lua_State *L, uint64_t ticks, uint64_t inputbits, float pointerx, float pointery, int *already_called)
1691+
{
1692+
if (*already_called) {
1693+
return;
1694+
}
1695+
1696+
lua_getglobal(L, DIRKSIMPLE_LUA_NAMESPACE);
1697+
if (!lua_istable(L, -1)) { // namespace is sane?
1698+
DirkSimple_panic("DirkSimple Lua namespace is not a table!");
1699+
}
1700+
lua_getfield(L, -1, "seek_tick");
1701+
if (!lua_isfunction(L, -1)) {
1702+
lua_pop(L, 2); // pop the namespace and not-function object.
1703+
} else {
1704+
*already_called = 1; // function actually exists, count it as the tick for this frame.
1705+
1706+
GNumRenderCommands = 0; // clear rendering commands from previous frame, Lua code will replace them.
1707+
lua_pushnumber(L, (lua_Number) ticks);
1708+
push_inputs_table(L, inputbits, pointerx, pointery);
1709+
lua_call(L, 2, 0); // this will pop the function and args
1710+
lua_pop(L, 1); // pop the namespace
1711+
1712+
// Clean up any Lua tick waste.
1713+
collect_lua_garbage(L); // we can move this to start_clip if it turns out to be too heavy.
1714+
}
1715+
}
1716+
16901717
static const char *pixfmtstr(const THEORAPLAY_VideoFormat pixfmt)
16911718
{
16921719
switch (pixfmt) {
@@ -1885,22 +1912,26 @@ static void DirkSimple_tick_impl(uint64_t monotonic_ms, uint64_t inputbits, floa
18851912

18861913
if (GDiscLagUntilTicks) {
18871914
if (GDiscLagUntilTicks > GTicks) {
1915+
call_lua_seektick(L, GTicks, inputbits, pointerx, pointery, &called_lua_tick);
18881916
return; // we're faking the stall while the laserdisc player seeks to a new position. Done for now.
18891917
}
18901918
GDiscLagUntilTicks = 0;
18911919
}
18921920

1893-
// has seek completed? Sync us back up.
1894-
if (GPendingVideoFrame && (GClipStartTicks == 0)) {
1895-
GClipStartTicks = GTicks;
1896-
GSeekToTicksOffset = ((int64_t) GTicks) - ((int64_t) GClipStartMs);
1897-
if (GShowingSingleFrame) {
1898-
DirkSimple_discvideo(GPendingVideoFrame->pixels);
1899-
THEORAPLAY_freeVideo(GPendingVideoFrame);
1900-
GPendingVideoFrame = NULL;
1921+
if (!GClipStartTicks) { // seek still pending?
1922+
if (!GPendingVideoFrame) { // not ready yet, call Lua seek_tick.
1923+
call_lua_seektick(L, GTicks, inputbits, pointerx, pointery, &called_lua_tick);
1924+
} else { // seek completed? Sync us back up.
1925+
GClipStartTicks = GTicks;
1926+
GSeekToTicksOffset = ((int64_t) GTicks) - ((int64_t) GClipStartMs);
1927+
if (GShowingSingleFrame) {
1928+
DirkSimple_discvideo(GPendingVideoFrame->pixels);
1929+
THEORAPLAY_freeVideo(GPendingVideoFrame);
1930+
GPendingVideoFrame = NULL;
1931+
}
1932+
// we didn't call the tick earlier in this function because we were still waiting; do it now that the seek is resolved.
1933+
call_lua_tick(L, GTicks, (GTicks - GClipStartTicks), inputbits, pointerx, pointery, &called_lua_tick);
19011934
}
1902-
// we didn't call the tick earlier in this function because we were still waiting; do it now that the seek is resolved.
1903-
call_lua_tick(L, GTicks, (GTicks - GClipStartTicks), inputbits, pointerx, pointery, &called_lua_tick);
19041935
}
19051936

19061937
if (!GShowingSingleFrame) {

0 commit comments

Comments
 (0)