mirror of https://github.com/mgba-emu/mgba.git
Add audio FIFOs to savestates
This commit is contained in:
parent
6bf0e704d2
commit
8c9790bb3b
|
@ -692,6 +692,10 @@ void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState*
|
|||
state->audio.ch4.endTime = audio->ch4.control.endTime;
|
||||
state->audio.ch4.nextEvent = audio->nextCh4;
|
||||
|
||||
CircleBufferDump(&audio->chA.fifo, state->audio.fifoA, sizeof(state->audio.fifoA));
|
||||
CircleBufferDump(&audio->chB.fifo, state->audio.fifoB, sizeof(state->audio.fifoB));
|
||||
state->audio.fifoSize = CircleBufferSize(&audio->chA.fifo);
|
||||
|
||||
state->audio.nextEvent = audio->nextEvent;
|
||||
state->audio.eventDiff = audio->eventDiff;
|
||||
state->audio.nextSample = audio->nextSample;
|
||||
|
@ -726,6 +730,14 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState
|
|||
audio->ch4.control.endTime = state->audio.ch4.endTime;
|
||||
audio->nextCh4 = state->audio.ch4.nextEvent;
|
||||
|
||||
CircleBufferClear(&audio->chA.fifo);
|
||||
CircleBufferClear(&audio->chB.fifo);
|
||||
unsigned i;
|
||||
for (i = 0; i < state->audio.fifoSize / sizeof(uint32_t); ++i) {
|
||||
CircleBufferWrite32(&audio->chA.fifo, state->audio.fifoA[i]);
|
||||
CircleBufferWrite32(&audio->chB.fifo, state->audio.fifoB[i]);
|
||||
}
|
||||
|
||||
audio->nextEvent = state->audio.nextEvent;
|
||||
audio->eventDiff = state->audio.eventDiff;
|
||||
audio->nextSample = state->audio.nextSample;
|
||||
|
|
|
@ -61,9 +61,9 @@ static const int _isSpecialRegister[REG_MAX >> 1] = {
|
|||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 0, 0, 0, 0,
|
||||
// DMA
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Timers
|
||||
|
@ -466,12 +466,19 @@ void GBAIODeserialize(struct GBA* gba, struct GBASerializedState* state) {
|
|||
}
|
||||
}
|
||||
|
||||
gba->timersEnabled = 0;
|
||||
memcpy(gba->timers, state->timers, sizeof(gba->timers));
|
||||
for (i = 0; i < 4; ++i) {
|
||||
gba->memory.dma[i].nextSource = state->dma[i].nextSource;
|
||||
gba->memory.dma[i].nextDest = state->dma[i].nextDest;
|
||||
gba->memory.dma[i].nextCount = state->dma[i].nextCount;
|
||||
gba->memory.dma[i].nextEvent = state->dma[i].nextEvent;
|
||||
}
|
||||
if (gba->memory.dma[i].timing != DMA_TIMING_NOW) {
|
||||
GBAMemoryScheduleDMA(gba, i, &gba->memory.dma[i]);
|
||||
}
|
||||
|
||||
memcpy(state->timers, gba->timers, sizeof(gba->timers));
|
||||
if (gba->timers[i].enable) {
|
||||
gba->timersEnabled |= 1 << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,7 @@ static int _checkIntegrity(struct CircleBuffer* buffer) {
|
|||
void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity) {
|
||||
buffer->data = malloc(capacity);
|
||||
buffer->capacity = capacity;
|
||||
buffer->size = 0;
|
||||
buffer->readPtr = buffer->data;
|
||||
buffer->writePtr = buffer->data;
|
||||
CircleBufferClear(buffer);
|
||||
}
|
||||
|
||||
void CircleBufferDeinit(struct CircleBuffer* buffer) {
|
||||
|
@ -32,6 +30,12 @@ unsigned CircleBufferSize(const struct CircleBuffer* buffer) {
|
|||
return buffer->size;
|
||||
}
|
||||
|
||||
void CircleBufferClear(struct CircleBuffer* buffer) {
|
||||
buffer->size = 0;
|
||||
buffer->readPtr = buffer->data;
|
||||
buffer->writePtr = buffer->data;
|
||||
}
|
||||
|
||||
int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value) {
|
||||
int8_t* data = buffer->writePtr;
|
||||
if (buffer->size + sizeof(int8_t) > buffer->capacity) {
|
||||
|
@ -166,3 +170,22 @@ int CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length) {
|
|||
#endif
|
||||
return length;
|
||||
}
|
||||
|
||||
int CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length) {
|
||||
int8_t* data = buffer->readPtr;
|
||||
if (buffer->size == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (length > buffer->size) {
|
||||
length = buffer->size;
|
||||
}
|
||||
size_t remaining = buffer->capacity - ((int8_t*) data - (int8_t*) buffer->data);
|
||||
if (length <= remaining) {
|
||||
memcpy(output, data, length);
|
||||
} else {
|
||||
memcpy(output, data, remaining);
|
||||
memcpy((int8_t*) output + remaining, buffer->data, length - remaining);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
|
|
@ -14,10 +14,12 @@ struct CircleBuffer {
|
|||
void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity);
|
||||
void CircleBufferDeinit(struct CircleBuffer* buffer);
|
||||
unsigned CircleBufferSize(const struct CircleBuffer* buffer);
|
||||
void CircleBufferClear(struct CircleBuffer* buffer);
|
||||
int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value);
|
||||
int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value);
|
||||
int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value);
|
||||
int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value);
|
||||
int CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length);
|
||||
int CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue