ref: fda3f90cf516fa5a1172f9c4773f85864ca324e9
parent: aa6b257fd20b9ed3f1a1c2755253249ee510f249
author: Snesrev <snesrev@protonmail.com>
date: Wed Sep 28 08:54:16 EDT 2022
Hold tab for ~16x turbo mode
--- a/README.md
+++ b/README.md
@@ -110,6 +110,7 @@
| Key | Action |
| --- | --------------------- |
+| Tab | Turbo mode |
| W | Fill health/magic |
| Shift+W | Fill rupees/bombs/arrows |
| Ctrl+E | Reset |
@@ -117,7 +118,7 @@
| Shift+P | Pause (without dim) |
| Ctrl+Up | Increase window size |
| Ctrl+Down | Decrease window size |
-| T | Toggle replay turbo |
+| T | Toggle replay turbo mode |
| O | Set dungeon key to 1 |
| K | Clear all input history from the joypad log |
| L | Stop replaying a shapshot |
--- a/config.c
+++ b/config.c
@@ -33,8 +33,8 @@
_(SDLK_1), _(SDLK_2), _(SDLK_3), _(SDLK_4), _(SDLK_5), _(SDLK_6), _(SDLK_7), _(SDLK_8), _(SDLK_9), _(SDLK_0), _(SDLK_MINUS), _(SDLK_EQUALS), _(SDLK_BACKSPACE), N, N, N, N, N, N, N,
// Replay Ref State
C(SDLK_1), C(SDLK_2), C(SDLK_3), C(SDLK_4), C(SDLK_5), C(SDLK_6), C(SDLK_7), C(SDLK_8), C(SDLK_9), C(SDLK_0), C(SDLK_MINUS), C(SDLK_EQUALS), C(SDLK_BACKSPACE), N, N, N, N, N, N, N,
- // CheatLife, CheatKeys, CheatEquipment, ClearKeyLog, StopReplay, Fullscreen, Reset, Pause, PauseDimmed, Turbo, WindowBigger, WindowSmaller, DisplayPerf, ToggleRenderer
- _(SDLK_w), _(SDLK_o), S(SDLK_w), _(SDLK_k), _(SDLK_l), A(SDLK_RETURN), _(SDLK_e), S(SDLK_p), _(SDLK_p), _(SDLK_t), N, N, _(SDLK_f), _(SDLK_r),
+ // CheatLife, CheatKeys, CheatEquipment, ClearKeyLog, StopReplay, Fullscreen, Reset, Pause, PauseDimmed, Turbo, ReplayTurbo, WindowBigger, WindowSmaller, DisplayPerf, ToggleRenderer
+ _(SDLK_w), _(SDLK_o), S(SDLK_w), _(SDLK_k), _(SDLK_l), A(SDLK_RETURN), _(SDLK_e), S(SDLK_p), _(SDLK_p), _(SDLK_TAB), _(SDLK_t), N, N, _(SDLK_f), _(SDLK_r),
};
#undef _
#undef A
@@ -52,7 +52,7 @@
static const KeyNameId kKeyNameId[] = {
M(Controls), M(Load), M(Save), M(Replay), M(LoadRef), M(ReplayRef),
S(CheatLife), S(CheatKeys), S(CheatEquipment), S(ClearKeyLog), S(StopReplay), S(Fullscreen), S(Reset),
- S(Pause), S(PauseDimmed), S(Turbo), S(WindowBigger), S(WindowSmaller), S(DisplayPerf), S(ToggleRenderer),
+ S(Pause), S(PauseDimmed), S(Turbo), S(ReplayTurbo), S(WindowBigger), S(WindowSmaller), S(DisplayPerf), S(ToggleRenderer),
};
#undef S
#undef M
--- a/config.h
+++ b/config.h
@@ -25,6 +25,7 @@
kKeys_Pause,
kKeys_PauseDimmed,
kKeys_Turbo,
+ kKeys_ReplayTurbo,
kKeys_WindowBigger,
kKeys_WindowSmaller,
kKeys_DisplayPerf,
--- a/main.c
+++ b/main.c
@@ -32,7 +32,7 @@
void CopyStateAfterSnapshotRestore(bool is_reset);
void SaveLoadSlot(int cmd, int which);
void PatchCommand(char cmd);
-bool RunOneFrame(Snes *snes, int input_state, bool turbo);
+bool RunOneFrame(Snes *snes, int input_state);
static bool LoadRom(const char *name, Snes *snes);
static void PlayAudio(Snes *snes, SDL_AudioDeviceID device, int channels, int16 *audioBuffer);
@@ -57,7 +57,7 @@
static uint32 g_win_flags = SDL_WINDOW_RESIZABLE;
static SDL_Window *g_window;
static SDL_Renderer *g_renderer;
-static uint8 g_paused, g_turbo = true, g_cursor = true;
+static uint8 g_paused, g_turbo, g_replay_turbo = true, g_cursor = true;
static uint8 g_current_window_scale;
static int g_samples_per_block;
static uint8 g_gamepad_buttons;
@@ -373,9 +373,9 @@
if ((inputs & 0x30) == 0x30) inputs ^= 0x30;
if ((inputs & 0xc0) == 0xc0) inputs ^= 0xc0;
- bool is_turbo = RunOneFrame(snes_run, inputs, (frameCtr++ & 0x7f) != 0 && g_turbo);
+ bool is_replay = RunOneFrame(snes_run, inputs);
- if (is_turbo)
+ if ((g_turbo ^ (is_replay & g_replay_turbo)) && (frameCtr++ & (g_turbo ? 0xf : 0x7f)) != 0)
continue;
@@ -550,6 +550,12 @@
SetButtonState(kKbdRemap[j], pressed);
return;
}
+
+ if (j == kKeys_Turbo) {
+ g_turbo = pressed;
+ return;
+ }
+
if (!pressed)
return;
if (j <= kKeys_Load_Last) {
@@ -590,7 +596,7 @@
SDL_RenderPresent(g_renderer);
}
break;
- case kKeys_Turbo: g_turbo = !g_turbo; break;
+ case kKeys_ReplayTurbo: g_replay_turbo = !g_replay_turbo; break;
case kKeys_WindowBigger: ChangeWindowScale(1); break;
case kKeys_WindowSmaller: ChangeWindowScale(-1); break;
case kKeys_DisplayPerf: g_display_perf ^= 1; break;
--- a/zelda3.ini
+++ b/zelda3.ini
@@ -88,7 +88,8 @@
Reset = Ctrl+e
Pause = Shift+p
PauseDimmed = p
-Turbo = t
+Turbo = Tab
+ReplayTurbo = t
WindowBigger = Ctrl+Up
WindowSmaller = Ctrl+Down
--- a/zelda_cpu_infra.c
+++ b/zelda_cpu_infra.c
@@ -697,16 +697,16 @@
}
#endif
-bool RunOneFrame(Snes *snes, int input_state, bool turbo) {
+bool RunOneFrame(Snes *snes, int input_state) {
+ bool is_replay = state_recorder.replay_mode;
frame_ctr++;
// Either copy state or apply state
- if (state_recorder.replay_mode) {
+ if (is_replay) {
input_state = StateRecorder_ReadNextReplayState(&state_recorder);
} else {
// input_state = InputStateReadFromFile();
StateRecorder_Record(&state_recorder, input_state);
- turbo = false;
// This is whether APUI00 is true or false, this is used by the ancilla code.
uint8 apui00 = ZeldaIsMusicPlaying();
@@ -746,7 +746,7 @@
if (snes == NULL || enhanced_features0 != 0) {
// can't compare against real impl when running with extra features.
ZeldaRunFrame(input_state, run_what);
- return turbo;
+ return is_replay;
}
if (g_fail)
@@ -795,7 +795,7 @@
}
}
- return turbo;
+ return is_replay;
}
void PatchRomBP(uint8_t *rom, uint32_t addr) {