Shaving bytes off the lite state

This commit is contained in:
Sergio Martin 2024-01-20 15:45:49 +01:00
parent 5a99f2749a
commit 9eccd5084b
2 changed files with 21 additions and 128 deletions

View File

@ -48,6 +48,13 @@ struct nes_state_t
uint32_t frame_count; // number of frames emulated since power-up
};
struct nes_state_lite_t
{
uint16_t timestamp; // CPU clocks * 15 (for NTSC)
uint8_t frame_count; // number of frames emulated since power-up
};
struct joypad_state_t
{
uint32_t joypad_latches[2]; // joypad 1 & 2 shift registers
@ -408,154 +415,77 @@ class Core : private Cpu
size_t serializeLiteState(uint8_t *buffer) const
{
size_t pos = 0;
std::string headerCode;
const uint32_t headerSize = sizeof(char) * 4;
uint32_t blockSize = 0;
void *dataSource;
headerCode = "NESS"; // NESS Block
blockSize = 0xFFFFFFFF;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
headerCode = "TIME"; // TIME Block
nes_state_t state = nes;
nes_state_lite_t state;
state.timestamp = nes.timestamp;
state.frame_count = (uint8_t)nes.frame_count;
state.timestamp *= 5;
blockSize = sizeof(nes_state_t);
blockSize = sizeof(nes_state_lite_t);
dataSource = (void *)&state;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "CPUR"; // CPUR Block
cpu_state_t s;
memset(&s, 0, sizeof s);
s.pc = r.pc;
s.s = r.sp;
s.a = r.a;
s.x = r.x;
s.y = r.y;
s.p = r.status;
blockSize = sizeof(cpu_state_t);
dataSource = (void *)&s;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
blockSize = sizeof(cpu::registers_t);
dataSource = (void *)&r;
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "PPUR"; // PPUR Block
blockSize = sizeof(ppu_state_t);
dataSource = (void *)&ppu;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "APUR"; // APUR Block
Apu::apu_state_t apuState;
impl->apu.save_state(&apuState);
blockSize = sizeof(Apu::apu_state_t);
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &apuState, blockSize);
pos += blockSize;
headerCode = "CTRL"; // CTRL Block
blockSize = sizeof(joypad_state_t);
dataSource = (void *)&joypad;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "MAPR"; // MAPR Block
blockSize = mapper->state_size;
dataSource = (void *)mapper->state;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "LRAM"; // LRAM Block
blockSize = low_ram_size;
dataSource = (void *)low_mem;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "SPRT"; // SPRT Block
blockSize = Ppu::spr_ram_size;
dataSource = (void *)ppu.spr_ram;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
headerCode = "NTAB"; // NTAB Block
size_t nametable_size = 0x800;
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
blockSize = nametable_size;
dataSource = (void *)ppu.impl->nt_ram;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
if (ppu.chr_is_writable)
{
headerCode = "CHRR"; // CHRR Block
blockSize = ppu.chr_size;
dataSource = (void *)ppu.impl->chr_ram;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
}
if (sram_present)
{
headerCode = "SRAM"; // SRAM Block
blockSize = impl->sram_size;
dataSource = (void *)impl->sram;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
pos += blockSize;
}
headerCode = "gend"; // gend Block
blockSize = 0;
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
pos += headerSize;
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
pos += headerSize;
return pos; // Bytes written
}
@ -566,49 +496,30 @@ size_t serializeLiteState(uint8_t *buffer) const
ppu.burst_phase = 0; // avoids shimmer when seeking to same time over and over
size_t pos = 0;
const uint32_t headerSize = sizeof(char) * 4;
uint32_t blockSize = 0;
// NESS Block
pos += headerSize;
pos += headerSize;
// TIME Block
nes_state_t nesState;
pos += headerSize;
pos += headerSize;
blockSize = sizeof(nes_state_t);
nes_state_lite_t nesState;
blockSize = sizeof(nes_state_lite_t);
memcpy(&nesState, &buffer[pos], blockSize);
pos += blockSize;
nes = nesState;
nes.frame_count = nesState.frame_count;
nes.timestamp = nesState.timestamp;
nes.timestamp /= 5;
// CPUR Block
cpu_state_t s;
blockSize = sizeof(cpu_state_t);
pos += headerSize;
pos += headerSize;
memcpy((void *)&s, &buffer[pos], blockSize);
blockSize = sizeof(cpu::registers_t);
memcpy((void *)&r, &buffer[pos], blockSize);
pos += blockSize;
r.pc = s.pc;
r.sp = s.s;
r.a = s.a;
r.x = s.x;
r.y = s.y;
r.status = s.p;
// PPUR Block
blockSize = sizeof(ppu_state_t);
pos += headerSize;
pos += headerSize;
memcpy((void *)&ppu, &buffer[pos], blockSize);
pos += blockSize;
// APUR Block
Apu::apu_state_t apuState;
blockSize = sizeof(Apu::apu_state_t);
pos += headerSize;
pos += headerSize;
memcpy(&apuState, &buffer[pos], blockSize);
pos += blockSize;
impl->apu.load_state(apuState);
@ -616,31 +527,23 @@ size_t serializeLiteState(uint8_t *buffer) const
// CTRL Block
blockSize = sizeof(joypad_state_t);
pos += headerSize;
pos += headerSize;
memcpy((void *)&joypad, &buffer[pos], blockSize);
pos += blockSize;
// MAPR Block
mapper->default_reset_state();
blockSize = mapper->state_size;
pos += headerSize;
pos += headerSize;
memcpy((void *)mapper->state, &buffer[pos], blockSize);
pos += blockSize;
mapper->apply_mapping();
// LRAM Block
blockSize = low_ram_size;
pos += headerSize;
pos += headerSize;
memcpy((void *)low_mem, &buffer[pos], blockSize);
pos += blockSize;
// SPRT Block
blockSize = Ppu::spr_ram_size;
pos += headerSize;
pos += headerSize;
memcpy((void *)ppu.spr_ram, &buffer[pos], blockSize);
pos += blockSize;
@ -648,8 +551,6 @@ size_t serializeLiteState(uint8_t *buffer) const
size_t nametable_size = 0x800;
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
blockSize = nametable_size;
pos += headerSize;
pos += headerSize;
memcpy((void *)ppu.impl->nt_ram, &buffer[pos], blockSize);
pos += blockSize;
@ -657,8 +558,6 @@ size_t serializeLiteState(uint8_t *buffer) const
{
// CHRR Block
blockSize = ppu.chr_size;
pos += headerSize;
pos += headerSize;
memcpy((void *)ppu.impl->chr_ram, &buffer[pos], blockSize);
pos += blockSize;
}
@ -667,17 +566,11 @@ size_t serializeLiteState(uint8_t *buffer) const
{
// SRAM Block
blockSize = impl->sram_size;
pos += headerSize;
pos += headerSize;
memcpy((void *)impl->sram, &buffer[pos], blockSize);
pos += blockSize;
enable_sram(true);
}
// headerCode = "gend"; // gend Block
pos += headerSize;
pos += headerSize;
return pos; // Bytes read
}

View File

@ -234,8 +234,8 @@ class Emu
virtual const char *init_();
virtual void loading_state(State const &) {}
long timestamp() const { return emu.nes.frame_count; }
void set_timestamp(long t) { emu.nes.frame_count = t; }
long timestamp() const { return 0; }
void set_timestamp(long t) { }
private:
// noncopyable