ref: cb59f279fe5c2c9ef332bfc82873c9323f2a9ece
parent: 8071c81fb71befcf15d0dbd746acf0c92ca04551
author: Snesrev <snesrev@protonmail.com>
date: Fri Sep 2 20:12:10 EDT 2022
Add some code to be able to read inputs from a text file
--- /dev/null
+++ b/other/extract_snapshot_log.py
@@ -1,0 +1,48 @@
+import struct
+import sys
+
+data = open(sys.argv[1], 'rb').read()
+
+ver, total_frames, log_size, last_inputs = struct.unpack_from('IIII', data)
+
+log = data[32:32+log_size]
+
+KEYS = "AXsSUDLRBY"
+
+keys_memo = {}
+def get_keys(i):
+ if i not in keys_memo:
+ keys_memo[i] = "".join(k for j, k in enumerate(KEYS) if i & (1 << j))
+ return keys_memo[i]
+
+frame_ctr = 0
+bb = iter(log)
+
+try:
+ while True:
+ cmd = bb.__next__()
+ mask = 0xf if cmd < 0xc0 else 1
+ frames = cmd & mask
+ if frames == mask:
+ while True:
+ t = bb.__next__()
+ frames += t
+ if t != 255:
+ break
+ frame_ctr += frames
+ if cmd < 0xc0:
+ last_inputs ^= 1 << (cmd >> 4)
+ print('%d: %s' % (frame_ctr, get_keys(last_inputs)))
+ elif cmd < 0xd0:
+ nb = 1 + ((cmd >> 2) & 3)
+ addr = ((cmd >> 1) & 1) << 16
+ addr |= bb.__next__() << 8
+ addr |= bb.__next__()
+ for i in range(nb):
+ bb.__next__()
+ print('%d: patchbytes(0x%x)' % (frame_ctr, addr))
+ else:
+ assert 0
+except StopIteration:
+ pass
+
\ No newline at end of file
--- a/zelda_cpu_infra.c
+++ b/zelda_cpu_infra.c
@@ -655,6 +655,37 @@
return t >> 8;
}
+#ifdef _DEBUG
+// This can be used to read inputs from a text file for easier debugging
+int InputStateReadFromFile() {
+ static FILE *f;
+ static uint32 next_ts, next_keys, cur_keys;
+ char buf[64];
+ char keys[64];
+
+ while (state_recorder.total_frames == next_ts) {
+ cur_keys = next_keys;
+ if (!f)
+ f = fopen("boss_bug.txt", "r");
+ if (fgets(buf, sizeof(buf), f)) {
+ if (sscanf(buf, "%d: %s", &next_ts, keys) == 1) keys[0] = 0;
+ int i = 0;
+ for (const char *s = keys; *s; s++) {
+ static const char kKeys[] = "AXsSUDLRBY";
+ const char *t = strchr(kKeys, *s);
+ assert(t);
+ i |= 1 << (t - kKeys);
+ }
+ next_keys = i;
+ } else {
+ next_ts = 0xffffffff;
+ }
+ }
+
+ return cur_keys;
+}
+#endif
+
bool RunOneFrame(Snes *snes, int input_state, bool turbo) {
frame_ctr++;
@@ -667,6 +698,7 @@
if (state_recorder.replay_mode) {
input_state = StateRecorder_ReadNextReplayState(&state_recorder);
} else {
+ // input_state = InputStateReadFromFile();
StateRecorder_Record(&state_recorder, input_state);
turbo = false;