ref: 6a7c62c449746dd10d51ab6a189a7db8caaff73c
parent: 2ebb5512f459f576dbe5ee4a857334d0d9b1abed
author: Snesrev <snesrev@protonmail.com>
date: Tue Aug 30 23:17:00 EDT 2022
Persist SRAM
--- a/main.cpp
+++ b/main.cpp
@@ -4,8 +4,10 @@
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
-
#include <SDL.h>
+#ifdef _WIN32
+#include <direct.h>
+#endif
#include "snes/snes.h"
#include "tracing.h"
@@ -45,6 +47,26 @@
}
+void ZeldaReadSram(Snes *snes) {
+ FILE *f = fopen("saves/sram.dat", "rb");
+ if (f) {
+ fread(g_zenv.sram, 1, 8192, f);
+ memcpy(snes->cart->ram, g_zenv.sram, 8192);
+ fclose(f);
+ }
+}
+
+void ZeldaWriteSram() {
+ rename("saves/sram.dat", "saves/sram.bak");
+ FILE *f = fopen("saves/sram.dat", "wb");
+ if (f) {
+ fwrite(g_zenv.sram, 1, 8192, f);
+ fclose(f);
+ } else {
+ fprintf(stderr, "Unable to write saves/sram.dat\n");
+ }
+}
+
#undef main
int main(int argc, char** argv) {
// set up SDL
@@ -96,8 +118,17 @@
} else {
snes_reset(snes, true);
}
+
+#if defined(_WIN32)
+ _mkdir("saves");
+#else
+ mkdir("saves", 755);
+#endif
+
SetSnes(snes);
ZeldaInitialize();
+ ZeldaReadSram(snes);
+
bool hooks = true;
// sdl loop
bool running = true;
--- a/messaging.cpp
+++ b/messaging.cpp
@@ -396,6 +396,7 @@
word_7EF4FE = t;
WORD(g_zenv.sram[offs + 0x4fe]) = t;
WORD(g_zenv.sram[offs + 0x4fe + 0xf00]) = t;
+ ZeldaWriteSram();
}
void TransferMode7Characters() { // 80e399
--- a/select_file.cpp
+++ b/select_file.cpp
@@ -155,6 +155,7 @@
selectfile_arr1[k] = 0;
memset(g_zenv.sram + k * 0x500, 0, 0x500);
memset(g_zenv.sram + k * 0x500 + 0xf00, 0, 0x500);
+ ZeldaWriteSram();
}
ReturnToFileSelect();
subsubmodule_index = 0;
@@ -340,7 +341,7 @@
void FileSelect_Main() { // 8ccebd
static const uint8 kSelectFile_Faerie_Y[5] = {0x4a, 0x6a, 0x8a, 0xaf, 0xbf};
- uint8 *cart = g_zenv.sram;
+ const uint8 *cart = g_zenv.sram;
if (selectfile_R16 < 3)
selectfile_var2 = selectfile_R16;
@@ -473,7 +474,7 @@
for (int k = 0; k != 3; k++) {
if (selectfile_arr1[k] & 1) {
- uint16 *name = (uint16 *)(g_zenv.sram + 0x500 * k + kSrmOffs_Name);
+ const uint16 *name = (uint16 *)(g_zenv.sram + 0x500 * k + kSrmOffs_Name);
uint16 *dst = vram_upload_data + kCopyFile_SelectionAndBlinker_Dst[k] / 2;
for (int i = 0; i != 6; i++) {
uint16 t = *name++ + 0x1800;
@@ -571,7 +572,7 @@
dst[10] = t + 0x10;
dst += 2;
if (selectfile_arr1[k]) {
- uint16 *name = (uint16 *)(g_zenv.sram + 0x500 * k + kSrmOffs_Name);
+ const uint16 *name = (uint16 *)(g_zenv.sram + 0x500 * k + kSrmOffs_Name);
for (int i = 0; i != 6; i++) {
uint16 t = *name++ + 0x1800;
dst[0] = t;
@@ -635,6 +636,7 @@
if (selectfile_R16 == 0) {
memcpy(g_zenv.sram + (selectfile_R18 >> 1) * 0x500, g_zenv.sram + (selectfile_R20 >> 1) * 0x500, 0x500);
selectfile_arr1[(selectfile_R18 >> 1)] = 1;
+ ZeldaWriteSram();
}
ReturnToFileSelect();
selectfile_R16 = 0;
@@ -779,9 +781,10 @@
selectfile_var7 = 0x83;
selectfile_var8 = 0x1f0;
BG3HOFS_copy2 = 0;
- attract_legend_ctr = selectfile_R16 * 0x500;
- memset(g_zenv.sram + attract_legend_ctr, 0, 0x500);
- uint16 *name = (uint16 *)(g_zenv.sram + attract_legend_ctr + kSrmOffs_Name);
+ int offs = selectfile_R16 * 0x500;
+ attract_legend_ctr = offs;
+ memset(g_zenv.sram + offs, 0, 0x500);
+ uint16 *name = (uint16 *)(g_zenv.sram + offs + kSrmOffs_Name);
name[0] = name[1] = name[2] = name[3] = name[4] = name[5] = 0xa9;
}
@@ -909,6 +912,7 @@
};
memcpy(sram + 0x340, kSramInit_Normal, 60);
Intro_FixCksum(sram);
+ ZeldaWriteSram();
ReturnToFileSelect();
irq_flag = 0xff;
sound_effect_1 = 0x2c;
--- a/zelda_rtl.h
+++ b/zelda_rtl.h
@@ -26,14 +26,6 @@
static inline void zelda_snes_dummy_write(uint32_t adr, uint8_t val) {}
-
-
-
-
-
-
-
-
const uint16 kUpperBitmasks[] = { 0x8000, 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1 };
const uint8 kLitTorchesColorPlus[] = {31, 8, 4, 0};
const uint8 kDungeonCrystalPendantBit[13] = {0, 0, 4, 2, 0, 16, 2, 1, 64, 4, 1, 32, 8};
@@ -195,3 +187,4 @@
void ClearOamBuffer();
void Startup_InitializeMemory();
void LoadSongBank(const uint8 *p);
+void ZeldaWriteSram();