/* Value is memory location of data, num is number of type to save */ void StateSav_SaveUWORD(const UWORD *data, int num) { if (!StateFile || nFileError != Z_OK) return; /* UWORDS are saved as 16bits, regardless of the size on this particular platform. Each byte of the UWORD will be pushed out individually in LSB order. The shifts here and in the read routines will work for both LSB and MSB architectures. */ while (num > 0) { UWORD temp; UBYTE byte; temp = *data++; byte = temp & 0xff; if (GZWRITE(StateFile, &byte, 1) == 0) { GetGZErrorText(); break; } temp >>= 8; byte = temp & 0xff; if (GZWRITE(StateFile, &byte, 1) == 0) { GetGZErrorText(); break; } num--; } }
void StateSav_SaveINT(const int *data, int num) { if (!StateFile || nFileError != Z_OK) return; /* INTs are always saved as 32bits (4 bytes) in the file. They can be any size on the platform however. The sign bit is clobbered into the fourth byte saved for each int; on read it will be extended out to its proper position for the native INT size */ while (num > 0) { UBYTE signbit = 0; unsigned int temp; UBYTE byte; int temp0; temp0 = *data++; if (temp0 < 0) { temp0 = -temp0; signbit = 0x80; } temp = (unsigned int) temp0; byte = temp & 0xff; if (GZWRITE(StateFile, &byte, 1) == 0) { GetGZErrorText(); break; } temp >>= 8; byte = temp & 0xff; if (GZWRITE(StateFile, &byte, 1) == 0) { GetGZErrorText(); break; } temp >>= 8; byte = temp & 0xff; if (GZWRITE(StateFile, &byte, 1) == 0) { GetGZErrorText(); break; } temp >>= 8; byte = (temp & 0x7f) | signbit; if (GZWRITE(StateFile, &byte, 1) == 0) { GetGZErrorText(); break; } num--; } }
static size_t _WriteData(ArchiveHandle *AH, const void *data, size_t dLen) { lclTocEntry *tctx = (lclTocEntry *) AH->currToc->formatData; GZWRITE((void *) data, 1, dLen, tctx->FH); return dLen; }
/* Value is memory location of data, num is number of type to save */ void StateSav_SaveUBYTE(const UBYTE *data, int num) { if (!StateFile || nFileError != Z_OK) return; /* Assumption is that UBYTE = 8bits and the pointer passed in refers directly to the active bits if in a padded location. If not (unlikely) you'll have to redefine this to save appropriately for cross-platform compatibility */ if (GZWRITE(StateFile, data, num) == 0) GetGZErrorText(); }
int StateSav_SaveAtariState(const char *filename, const char *mode, UBYTE SaveVerbose) { UBYTE StateVersion = SAVE_VERSION_NUMBER; if (StateFile != NULL) { GZCLOSE(StateFile); StateFile = NULL; } nFileError = Z_OK; StateFile = GZOPEN(filename, mode); if (StateFile == NULL) { Log_print("Could not open %s for state save.", filename); GetGZErrorText(); return FALSE; } if (GZWRITE(StateFile, "ATARI800", 8) == 0) { GetGZErrorText(); GZCLOSE(StateFile); StateFile = NULL; return FALSE; } StateSav_SaveUBYTE(&StateVersion, 1); StateSav_SaveUBYTE(&SaveVerbose, 1); /* The order here is important. Atari800_StateSave must be first because it saves the machine type, and decisions on what to save/not save are made based off that later in the process */ Atari800_StateSave(); CARTRIDGE_StateSave(); SIO_StateSave(); ANTIC_StateSave(); CPU_StateSave(SaveVerbose); GTIA_StateSave(); PIA_StateSave(); POKEY_StateSave(); #ifdef XEP80_EMULATION XEP80_StateSave(); #else { int local_xep80_enabled = FALSE; StateSav_SaveINT(&local_xep80_enabled, 1); } #endif /* XEP80_EMULATION */ PBI_StateSave(); #ifdef PBI_MIO PBI_MIO_StateSave(); #else { int local_mio_enabled = FALSE; StateSav_SaveINT(&local_mio_enabled, 1); } #endif /* PBI_MIO */ #ifdef PBI_BB PBI_BB_StateSave(); #else { int local_bb_enabled = FALSE; StateSav_SaveINT(&local_bb_enabled, 1); } #endif /* PBI_BB */ #ifdef PBI_XLD PBI_XLD_StateSave(); #else { int local_xld_enabled = FALSE; StateSav_SaveINT(&local_xld_enabled, 1); } #endif /* PBI_XLD */ #ifdef DREAMCAST DCStateSave(); #endif if (GZCLOSE(StateFile) != 0) { StateFile = NULL; return FALSE; } StateFile = NULL; if (nFileError != Z_OK) return FALSE; return TRUE; }