Shaving bytes off the lite state
This commit is contained in:
parent
5a99f2749a
commit
9eccd5084b
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue