diff --git a/th03/cutscene/cutscene.hpp b/th03/cutscene/cutscene.hpp index c8994299..7bc41c41 100644 --- a/th03/cutscene/cutscene.hpp +++ b/th03/cutscene/cutscene.hpp @@ -1,3 +1,13 @@ +extern "C" { +#if (GAME == 5) + #include "th05/hardware/input.h" +#elif (GAME == 4) + #include "th04/hardware/input.h" +#else + #include "th03/hardware/input.h" +#endif +} + static const shiftjis_ank_amount_t NAME_LEN = 6; static const shiftjis_kanji_amount_t NAME_KANJI_LEN = ( NAME_LEN / sizeof(shiftjis_kanji_t) @@ -26,3 +36,27 @@ extern bool fast_forward; extern screen_point_t cursor; extern int text_interval; + +// ZUN quirk: The cutscene system features both +// 1) a top-level input sensing mechanism (for updating the fast-forward flag), +// and +// 2) nested, blocking input loops (during all the interruptable wait commands) +// which are skipped based on the fast-forward flag. +// With this combination, the accurate detection of held keys matters: Since +// this function is only called once on every iteration of the loop before +// evaluating a command, a momentary key release scancode from 1) can cause 2) +// to be entered even if the fast-forward key is still being held. Only TH03's +// and TH05's input functions defend against this possibility – at the cost of +// 614.4 µs for every call to them. TH04's cutscene system does suffer from the +// detection issue, but runs significantly faster in exchange, as it's not +// slowed down on every iteration of the script interpreter loop, i.e., between +// every script command or 2-byte text pair. +inline void cutscene_input_sense(void) { + #if (GAME == 5) + input_reset_sense_held(); + #elif (GAME == 4) + input_reset_sense(); + #elif (GAME == 3) + input_mode_interface(); + #endif +} diff --git a/th04/hardware/input.h b/th04/hardware/input.h index c7e33c9d..f7106a32 100644 --- a/th04/hardware/input.h +++ b/th04/hardware/input.h @@ -7,7 +7,8 @@ void input_reset_sense(); // [shiftkey]. void input_sense(); -// Input sense function used in UIs +// Input sense function used in UIs. Should only be used in places where +// support for held keys does not matter. #define input_reset_sense_interface input_reset_sense // Waits ≥1 frames for all held inputs to be released, then waits the given diff --git a/th05/hardware/input.h b/th05/hardware/input.h index 4598bad5..f8ee3699 100644 --- a/th05/hardware/input.h +++ b/th05/hardware/input.h @@ -3,14 +3,17 @@ // Resets, updates, and returns [key_det]. int16_t input_reset_sense(); -// input_reset_sense() with accurate detection of held keyboard keys. +// input_reset_sense() with accurate detection of held keyboard keys, at the +// cost of 614.4 µs per call. See the HOLDKEY example in the `Research/` +// subdirectory for a more detailed explanation of the delay. int16_t input_reset_sense_held(); // ORs the current keyboard and joystick state into [key_det], sets // [shiftkey], and returns [key_det]. int16_t input_sense(); -// Input sense function used in UIs +// Input sense function used in UIs. Should only be used in places where +// support for held keys does not matter. #define input_reset_sense_interface input_reset_sense_held // Waits for all held inputs to be released, then waits the given number of