shithub: zelda3

Download patch

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;