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.endTime = audio->ch4.control.endTime;
|
||||||
state->audio.ch4.nextEvent = audio->nextCh4;
|
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.nextEvent = audio->nextEvent;
|
||||||
state->audio.eventDiff = audio->eventDiff;
|
state->audio.eventDiff = audio->eventDiff;
|
||||||
state->audio.nextSample = audio->nextSample;
|
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->ch4.control.endTime = state->audio.ch4.endTime;
|
||||||
audio->nextCh4 = state->audio.ch4.nextEvent;
|
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->nextEvent = state->audio.nextEvent;
|
||||||
audio->eventDiff = state->audio.eventDiff;
|
audio->eventDiff = state->audio.eventDiff;
|
||||||
audio->nextSample = state->audio.nextSample;
|
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, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 0, 0, 0, 0,
|
1, 1, 1, 1, 0, 0, 0, 0,
|
||||||
// DMA
|
// DMA
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
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
|
// 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) {
|
for (i = 0; i < 4; ++i) {
|
||||||
gba->memory.dma[i].nextSource = state->dma[i].nextSource;
|
gba->memory.dma[i].nextSource = state->dma[i].nextSource;
|
||||||
gba->memory.dma[i].nextDest = state->dma[i].nextDest;
|
gba->memory.dma[i].nextDest = state->dma[i].nextDest;
|
||||||
gba->memory.dma[i].nextCount = state->dma[i].nextCount;
|
gba->memory.dma[i].nextCount = state->dma[i].nextCount;
|
||||||
gba->memory.dma[i].nextEvent = state->dma[i].nextEvent;
|
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) {
|
void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity) {
|
||||||
buffer->data = malloc(capacity);
|
buffer->data = malloc(capacity);
|
||||||
buffer->capacity = capacity;
|
buffer->capacity = capacity;
|
||||||
buffer->size = 0;
|
CircleBufferClear(buffer);
|
||||||
buffer->readPtr = buffer->data;
|
|
||||||
buffer->writePtr = buffer->data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CircleBufferDeinit(struct CircleBuffer* buffer) {
|
void CircleBufferDeinit(struct CircleBuffer* buffer) {
|
||||||
|
@ -32,6 +30,12 @@ unsigned CircleBufferSize(const struct CircleBuffer* buffer) {
|
||||||
return buffer->size;
|
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) {
|
int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value) {
|
||||||
int8_t* data = buffer->writePtr;
|
int8_t* data = buffer->writePtr;
|
||||||
if (buffer->size + sizeof(int8_t) > buffer->capacity) {
|
if (buffer->size + sizeof(int8_t) > buffer->capacity) {
|
||||||
|
@ -166,3 +170,22 @@ int CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length) {
|
||||||
#endif
|
#endif
|
||||||
return length;
|
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 CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity);
|
||||||
void CircleBufferDeinit(struct CircleBuffer* buffer);
|
void CircleBufferDeinit(struct CircleBuffer* buffer);
|
||||||
unsigned CircleBufferSize(const struct CircleBuffer* buffer);
|
unsigned CircleBufferSize(const struct CircleBuffer* buffer);
|
||||||
|
void CircleBufferClear(struct CircleBuffer* buffer);
|
||||||
int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value);
|
int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value);
|
||||||
int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value);
|
int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value);
|
||||||
int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value);
|
int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value);
|
||||||
int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value);
|
int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value);
|
||||||
int CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length);
|
int CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length);
|
||||||
|
int CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue