all repos — mgba @ f62ccde49d484c65b212ae86299f4720c9dc836d

mGBA Game Boy Advance Emulator

src/gba/gba-rr.c (view raw)

  1#include "gba-rr.h"
  2
  3#include "gba.h"
  4#include "util/vfs.h"
  5
  6#define FILE_INPUTS "input.log"
  7
  8void GBARRContextCreate(struct GBA* gba) {
  9	if (gba->rr) {
 10		return;
 11	}
 12
 13	gba->rr = calloc(1, sizeof(*gba->rr));
 14}
 15
 16void GBARRContextDestroy(struct GBA* gba) {
 17	if (!gba->rr) {
 18		return;
 19	}
 20
 21	free(gba->rr);
 22	gba->rr = 0;
 23}
 24
 25bool GBARRSetStream(struct GBARRContext* rr, struct VDir* stream) {
 26	if (rr->inputsStream && !rr->inputsStream->close(rr->inputsStream)) {
 27		return false;
 28	}
 29	rr->streamDir = stream;
 30	rr->inputsStream = stream->openFile(stream, FILE_INPUTS, O_CREAT | O_RDWR);
 31	return !!rr->inputsStream;
 32}
 33
 34bool GBARRStartPlaying(struct GBARRContext* rr, bool autorecord) {
 35	if (GBARRIsRecording(rr) || GBARRIsPlaying(rr)) {
 36		return false;
 37	}
 38
 39	rr->autorecord = autorecord;
 40	if (rr->inputsStream->seek(rr->inputsStream, 0, SEEK_SET) < 0) {
 41		return false;
 42	}
 43	if (rr->inputsStream->read(rr->inputsStream, &rr->nextInput, sizeof(rr->nextInput)) != sizeof(rr->nextInput)) {
 44		return false;
 45	}
 46	rr->isPlaying = true;
 47	return true;
 48}
 49
 50void GBARRStopPlaying(struct GBARRContext* rr) {
 51	rr->isPlaying = false;
 52}
 53
 54bool GBARRStartRecording(struct GBARRContext* rr) {
 55	if (GBARRIsRecording(rr) || GBARRIsPlaying(rr)) {
 56		return false;
 57	}
 58
 59	rr->isRecording = true;
 60	return true;
 61}
 62
 63void GBARRStopRecording(struct GBARRContext* rr) {
 64	rr->isRecording = false;
 65}
 66
 67bool GBARRIsPlaying(struct GBARRContext* rr) {
 68	return rr && rr->isPlaying;
 69}
 70
 71bool GBARRIsRecording(struct GBARRContext* rr) {
 72	return rr && rr->isRecording;
 73}
 74
 75void GBARRNextFrame(struct GBARRContext* rr) {
 76	if (!GBARRIsRecording(rr)) {
 77		return;
 78	}
 79
 80	++rr->frames;
 81	if (!rr->inputThisFrame) {
 82		++rr->lagFrames;
 83	}
 84
 85	rr->inputThisFrame = false;
 86}
 87
 88void GBARRLogInput(struct GBARRContext* rr, uint16_t keys) {
 89	if (!GBARRIsRecording(rr)) {
 90		return;
 91	}
 92
 93	rr->inputsStream->write(rr->inputsStream, &keys, sizeof(keys));
 94	rr->inputThisFrame = true;
 95}
 96
 97uint16_t GBARRQueryInput(struct GBARRContext* rr) {
 98	if (!GBARRIsPlaying(rr)) {
 99		return 0;
100	}
101
102	uint16_t keys = rr->nextInput;
103	rr->isPlaying = rr->inputsStream->read(rr->inputsStream, &rr->nextInput, sizeof(rr->nextInput)) == sizeof(rr->nextInput);
104	if (!rr->isPlaying && rr->autorecord) {
105		rr->isRecording = true;
106	}
107	return keys;
108}