mirror of https://github.com/mgba-emu/mgba.git
Core: Video log enhancements
This commit is contained in:
parent
b230b6e0f6
commit
3cce95b287
|
@ -104,6 +104,7 @@ void mVideoLoggerAttachChannel(struct mVideoLogger* logger, struct mVideoLogCont
|
|||
struct mCore;
|
||||
struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core);
|
||||
|
||||
void mVideoLogContextSetCompression(struct mVideoLogContext*, bool enable);
|
||||
void mVideoLogContextSetOutput(struct mVideoLogContext*, struct VFile*);
|
||||
void mVideoLogContextWriteHeader(struct mVideoLogContext*, struct mCore* core);
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ struct mVideoLogContext {
|
|||
struct mVideoLogChannel channels[mVL_MAX_CHANNELS];
|
||||
|
||||
bool write;
|
||||
bool compression;
|
||||
uint32_t activeChannel;
|
||||
struct VFile* backing;
|
||||
};
|
||||
|
@ -465,6 +466,12 @@ struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core) {
|
|||
context->initialStateSize = 0;
|
||||
context->initialState = NULL;
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
context->compression = true;
|
||||
#else
|
||||
context->compression = false;
|
||||
#endif
|
||||
|
||||
if (core) {
|
||||
context->initialStateSize = core->stateSize(core);
|
||||
context->initialState = anonymousMemoryMap(context->initialStateSize);
|
||||
|
@ -482,6 +489,10 @@ void mVideoLogContextSetOutput(struct mVideoLogContext* context, struct VFile* v
|
|||
vf->seek(vf, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
void mVideoLogContextSetCompression(struct mVideoLogContext* context, bool compression) {
|
||||
context->compression = compression;
|
||||
}
|
||||
|
||||
void mVideoLogContextWriteHeader(struct mVideoLogContext* context, struct mCore* core) {
|
||||
struct mVideoLogHeader header = { { 0 } };
|
||||
memcpy(header.magic, mVL_MAGIC, sizeof(header.magic));
|
||||
|
@ -499,21 +510,24 @@ void mVideoLogContextWriteHeader(struct mVideoLogContext* context, struct mCore*
|
|||
struct mVLBlockHeader chheader = { 0 };
|
||||
STORE_32LE(mVL_BLOCK_INITIAL_STATE, 0, &chheader.blockType);
|
||||
#ifdef USE_ZLIB
|
||||
STORE_32LE(mVL_FLAG_BLOCK_COMPRESSED, 0, &chheader.flags);
|
||||
if (context->compression) {
|
||||
STORE_32LE(mVL_FLAG_BLOCK_COMPRESSED, 0, &chheader.flags);
|
||||
|
||||
struct VFile* vfm = VFileMemChunk(NULL, 0);
|
||||
struct VFile* src = VFileFromConstMemory(context->initialState, context->initialStateSize);
|
||||
_compress(vfm, src);
|
||||
src->close(src);
|
||||
STORE_32LE(vfm->size(vfm), 0, &chheader.length);
|
||||
context->backing->write(context->backing, &chheader, sizeof(chheader));
|
||||
_copyVf(context->backing, vfm);
|
||||
vfm->close(vfm);
|
||||
#else
|
||||
STORE_32LE(context->initialStateSize, 0, &chheader.length);
|
||||
context->backing->write(context->backing, &chheader, sizeof(chheader));
|
||||
context->backing->write(context->backing, context->initialState, context->initialStateSize);
|
||||
struct VFile* vfm = VFileMemChunk(NULL, 0);
|
||||
struct VFile* src = VFileFromConstMemory(context->initialState, context->initialStateSize);
|
||||
_compress(vfm, src);
|
||||
src->close(src);
|
||||
STORE_32LE(vfm->size(vfm), 0, &chheader.length);
|
||||
context->backing->write(context->backing, &chheader, sizeof(chheader));
|
||||
_copyVf(context->backing, vfm);
|
||||
vfm->close(vfm);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
STORE_32LE(context->initialStateSize, 0, &chheader.length);
|
||||
context->backing->write(context->backing, &chheader, sizeof(chheader));
|
||||
context->backing->write(context->backing, context->initialState, context->initialStateSize);
|
||||
}
|
||||
}
|
||||
|
||||
size_t i;
|
||||
|
@ -647,9 +661,10 @@ static void _flushBufferCompressed(struct mVideoLogContext* context) {
|
|||
|
||||
static void _flushBuffer(struct mVideoLogContext* context) {
|
||||
#ifdef USE_ZLIB
|
||||
// TODO: Make optional
|
||||
_flushBufferCompressed(context);
|
||||
return;
|
||||
if (context->compression) {
|
||||
_flushBufferCompressed(context);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct CircleBuffer* buffer = &context->channels[context->activeChannel].buffer;
|
||||
|
|
|
@ -879,9 +879,11 @@ static void _GBCoreStartVideoLog(struct mCore* core, struct mVideoLogContext* co
|
|||
static void _GBCoreEndVideoLog(struct mCore* core) {
|
||||
struct GBCore* gbcore = (struct GBCore*) core;
|
||||
struct GB* gb = core->board;
|
||||
GBVideoProxyRendererUnshim(&gb->video, &gbcore->proxyRenderer);
|
||||
free(gbcore->proxyRenderer.logger);
|
||||
gbcore->proxyRenderer.logger = NULL;
|
||||
if (gbcore->proxyRenderer.logger) {
|
||||
GBVideoProxyRendererUnshim(&gb->video, &gbcore->proxyRenderer);
|
||||
free(gbcore->proxyRenderer.logger);
|
||||
gbcore->proxyRenderer.logger = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -990,9 +990,11 @@ static void _GBACoreStartVideoLog(struct mCore* core, struct mVideoLogContext* c
|
|||
static void _GBACoreEndVideoLog(struct mCore* core) {
|
||||
struct GBACore* gbacore = (struct GBACore*) core;
|
||||
struct GBA* gba = core->board;
|
||||
GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer);
|
||||
free(gbacore->proxyRenderer.logger);
|
||||
gbacore->proxyRenderer.logger = NULL;
|
||||
if (gbacore->proxyRenderer.logger) {
|
||||
GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer);
|
||||
free(gbacore->proxyRenderer.logger);
|
||||
gbacore->proxyRenderer.logger = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -809,26 +809,39 @@ void CoreController::clearOverride() {
|
|||
m_override.reset();
|
||||
}
|
||||
|
||||
void CoreController::startVideoLog(const QString& path) {
|
||||
void CoreController::startVideoLog(const QString& path, bool compression) {
|
||||
if (m_vl) {
|
||||
return;
|
||||
}
|
||||
|
||||
VFile* vf = VFileDevice::open(path, O_WRONLY | O_CREAT | O_TRUNC);
|
||||
if (!vf) {
|
||||
return;
|
||||
}
|
||||
startVideoLog(vf);
|
||||
}
|
||||
|
||||
void CoreController::startVideoLog(VFile* vf, bool compression) {
|
||||
if (m_vl || !vf) {
|
||||
return;
|
||||
}
|
||||
|
||||
Interrupter interrupter(this);
|
||||
m_vl = mVideoLogContextCreate(m_threadContext.core);
|
||||
m_vlVf = VFileDevice::open(path, O_WRONLY | O_CREAT | O_TRUNC);
|
||||
m_vlVf = vf;
|
||||
mVideoLogContextSetOutput(m_vl, m_vlVf);
|
||||
mVideoLogContextSetCompression(m_vl, compression);
|
||||
mVideoLogContextWriteHeader(m_vl, m_threadContext.core);
|
||||
}
|
||||
|
||||
void CoreController::endVideoLog() {
|
||||
void CoreController::endVideoLog(bool closeVf) {
|
||||
if (!m_vl) {
|
||||
return;
|
||||
}
|
||||
|
||||
Interrupter interrupter(this);
|
||||
mVideoLogContextDestroy(m_threadContext.core, m_vl);
|
||||
if (m_vlVf) {
|
||||
if (m_vlVf && closeVf) {
|
||||
m_vlVf->close(m_vlVf);
|
||||
m_vlVf = nullptr;
|
||||
}
|
||||
|
|
|
@ -161,8 +161,9 @@ public slots:
|
|||
|
||||
void clearOverride();
|
||||
|
||||
void startVideoLog(const QString& path);
|
||||
void endVideoLog();
|
||||
void startVideoLog(const QString& path, bool compression = true);
|
||||
void startVideoLog(VFile* vf, bool compression = true);
|
||||
void endVideoLog(bool closeVf = true);
|
||||
|
||||
void setFramebufferHandle(int fb);
|
||||
|
||||
|
|
Loading…
Reference in New Issue