bool _loadStream(struct GBAMGMContext* mgm, uint32_t streamId) { if (mgm->movieStream && !mgm->movieStream->close(mgm->movieStream)) { return false; } mgm->movieStream = 0; mgm->streamId = streamId; mgm->currentInput = INVALID_INPUT; char buffer[14]; snprintf(buffer, sizeof(buffer), "%u" BINARY_EXT, streamId); if (mgm->d.isRecording(&mgm->d)) { int flags = O_CREAT | O_RDWR; if (streamId > mgm->maxStreamId) { flags |= O_TRUNC; } mgm->movieStream = mgm->streamDir->openFile(mgm->streamDir, buffer, flags); } else if (mgm->d.isPlaying(&mgm->d)) { mgm->movieStream = mgm->streamDir->openFile(mgm->streamDir, buffer, O_RDONLY); mgm->peekedTag = TAG_INVALID; if (!mgm->movieStream || !_verifyMagic(mgm, mgm->movieStream) || !_seekTag(mgm, mgm->movieStream, TAG_BEGIN)) { mgm->d.stopPlaying(&mgm->d); } } GBALog(0, GBA_LOG_DEBUG, "[RR] Loading segment: %u", streamId); mgm->d.frames = 0; mgm->d.lagFrames = 0; return true; }
bool GBARRLoadStream(struct GBARRContext* rr, uint32_t streamId) { if (rr->movieStream && !rr->movieStream->close(rr->movieStream)) { return false; } rr->movieStream = 0; rr->streamId = streamId; rr->currentInput = INVALID_INPUT; char buffer[14]; snprintf(buffer, sizeof(buffer), "%u" BINARY_EXT, streamId); if (GBARRIsRecording(rr)) { int flags = O_CREAT | O_RDWR; if (streamId > rr->maxStreamId) { flags |= O_TRUNC; } rr->movieStream = rr->streamDir->openFile(rr->streamDir, buffer, flags); } else if (GBARRIsPlaying(rr)) { rr->movieStream = rr->streamDir->openFile(rr->streamDir, buffer, O_RDONLY); rr->peekedTag = TAG_INVALID; if (!rr->movieStream || !_verifyMagic(rr, rr->movieStream) || !_seekTag(rr, rr->movieStream, TAG_BEGIN)) { GBARRStopPlaying(rr); } } GBALog(0, GBA_LOG_DEBUG, "[RR] Loading segment: %u", streamId); rr->frames = 0; rr->lagFrames = 0; return true; }
void GBAMGMNextFrame(struct GBARRContext* rr) { if (!rr->isRecording(rr) && !rr->isPlaying(rr)) { return; } struct GBAMGMContext* mgm = (struct GBAMGMContext*) rr; if (rr->isPlaying(rr)) { while (mgm->peekedTag == TAG_INPUT) { _readTag(mgm, mgm->movieStream); GBALog(0, GBA_LOG_WARN, "[RR] Desync detected!"); } if (mgm->peekedTag == TAG_LAG) { GBALog(0, GBA_LOG_DEBUG, "[RR] Lag frame marked in stream"); if (mgm->inputThisFrame) { GBALog(0, GBA_LOG_WARN, "[RR] Lag frame in stream does not match movie"); } } } ++mgm->d.frames; GBALog(0, GBA_LOG_DEBUG, "[RR] Frame: %u", mgm->d.frames); if (!mgm->inputThisFrame) { ++mgm->d.lagFrames; GBALog(0, GBA_LOG_DEBUG, "[RR] Lag frame: %u", mgm->d.lagFrames); } if (rr->isRecording(rr)) { if (!mgm->inputThisFrame) { _emitTag(mgm, mgm->movieStream, TAG_LAG); } _emitTag(mgm, mgm->movieStream, TAG_FRAME); mgm->inputThisFrame = false; } else { if (!_seekTag(mgm, mgm->movieStream, TAG_FRAME)) { _streamEndReached(mgm); } } }