X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fthunder.cpp;fp=src%2Fthunder.cpp;h=cb91ed1a76e2ebb1062a2a5ff06c3777c71797a8;hb=9eb5812230547fd62f2413d84a0dcc9e1336be21;hp=2914a96c5ae80eab26a7347e3e388609e6aa77ca;hpb=a046907b274eb0cfa9c10a4c68fb38255f96714c;p=thunder diff --git a/src/thunder.cpp b/src/thunder.cpp index 2914a96..cb91ed1 100644 --- a/src/thunder.cpp +++ b/src/thunder.cpp @@ -13,16 +13,16 @@ // JLH 04/04/2014 Converted to SDL 2 // JLH 04/17/2014 Removed a metric fuck-tonne of cruft, added YM2151 & MCU // JLH 01/13/2023 Finally fixed the sprite lag problem :-D +// JLH 01/13/2023 Added save states // -#define THUNDER_VERSION "1.2.1" +#define THUNDER_VERSION "1.2.2" #include #include -#include #include -#include #include +#include "fileio.h" #include "gui.h" #include "log.h" #include "psg.h" @@ -79,8 +79,9 @@ uint32_t banksw1, banksw2; // MCU inputs Byte input1, input2, input3, input4, input5; -// Copy sprites flag +// Miscellaneous stuff bool copySprites = false; +const uint8_t stateHeader[20] = "THUNDERSAVESTATE1.0"; // Function prototypes uint8_t MCUReadMemory(uint16_t address); @@ -405,6 +406,104 @@ bool UnpackFonts(void) return true; } +void SaveThunderState(const char * filename) +{ + WriteLog("Main: Saving Thunder state...\n"); + FILE * file = fopen(filename, "wb"); + + if (!file) + { + WriteLog("Could not open file \"%s\" for writing!\n", filename); + return; + } + + // Write out header + size_t ignored = fwrite(stateHeader, 1, 19, file); + + // Write out CPUs' state + ignored = fwrite(&cpu1, 1, sizeof(cpu1), file); + ignored = fwrite(&cpu2, 1, sizeof(cpu2), file); + ignored = fwrite(&mcu, 1, sizeof(mcu), file); + + // Write out main memory + ignored = fwrite(gram1, 1, 0x10000, file); + ignored = fwrite(mcuMem, 1, 0x10000, file); + + // Write out state variables + WriteLong(file, banksw1); + WriteLong(file, banksw2); + fputc((uint8_t)copySprites, file); + fputc(input1.byte, file); + fputc(input2.byte, file); + fputc(input3.byte, file); + fputc(input4.byte, file); + fputc(input5.byte, file); + + PSGSaveState(file); + YMSaveState(file); + + fclose(file); +} + +bool LoadThunderState(const char * filename) +{ + WriteLog("Main: Loading Thunder state...\n"); + FILE * file = fopen(filename, "rb"); + + if (!file) + { + WriteLog("Could not open file \"%s\" for reading!\n", filename); + return false; + } + + uint8_t buffer[19]; + size_t ignored = fread(buffer, 1, 19, file); + + // Sanity check... + if (memcmp(buffer, stateHeader, 19) != 0) + { + fclose(file); + WriteLog("File \"%s\" is not a valid Thunder save state file!\n", filename); + return false; + } + + // Read CPUs' state + ignored = fread(&cpu1, 1, sizeof(cpu1), file); + ignored = fread(&cpu2, 1, sizeof(cpu2), file); + ignored = fread(&mcu, 1, sizeof(mcu), file); + + // Read main memory + ignored = fread(gram1, 1, 0x10000, file); + ignored = fread(mcuMem, 1, 0x10000, file); + + // Read in state variables + banksw1 = ReadLong(file); + banksw2 = ReadLong(file); + copySprites = (bool)fgetc(file); + input1.byte = fgetc(file); + input2.byte = fgetc(file); + input3.byte = fgetc(file); + input4.byte = fgetc(file); + input5.byte = fgetc(file); + + PSGLoadState(file); + YMLoadState(file); + + fclose(file); + + // Make sure things are in a sane state before execution :-P + cpu1.RdMem = MainReadMemory; + cpu1.WrMem = MainWriteMemory; + + cpu2.RdMem = SubReadMemory; + cpu2.WrMem = SubWriteMemory; + + mcu.RdMem = MCUReadMemory; + mcu.WrMem = MCUWriteMemory; + + return true; +} + // // Main loop // @@ -610,6 +709,12 @@ WriteLog("About to enter main loop...\n"); else if (event.key.keysym.sym == SDLK_i) input5.bit.b0 = !input5.bit.b0; + // Quick'n'Dirty save state handling... :-P + else if (event.key.keysym.sym == SDLK_F8) + SaveThunderState("thun0001.state"); + else if (event.key.keysym.sym == SDLK_F9) + LoadThunderState("thun0001.state"); + #else else if (event.key.keysym.sym == SDLK_1) input1.bit.b0 = 0;