From 0d1b323e224d5be9a20df47ad37752bb94843acf Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 15 Oct 2014 04:51:19 -0700 Subject: [PATCH 1/4] Fix edge case with video-frame sync where it may never wake up the display thread --- src/gba/gba-thread.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gba/gba-thread.c b/src/gba/gba-thread.c index 4a957c53a..142d9c580 100644 --- a/src/gba/gba-thread.c +++ b/src/gba/gba-thread.c @@ -520,10 +520,12 @@ void GBASyncPostFrame(struct GBASync* sync) { ++sync->videoFramePending; --sync->videoFrameSkip; if (sync->videoFrameSkip < 0) { - ConditionWake(&sync->videoFrameAvailableCond); - while (sync->videoFrameWait && sync->videoFramePending) { - ConditionWait(&sync->videoFrameRequiredCond, &sync->videoFrameMutex); - } + do { + ConditionWake(&sync->videoFrameAvailableCond); + if (sync->videoFrameWait) { + ConditionWait(&sync->videoFrameRequiredCond, &sync->videoFrameMutex); + } + } while (sync->videoFrameWait && sync->videoFramePending); } MutexUnlock(&sync->videoFrameMutex); From 65ce79c6110df10e26c50083b728944349eed464 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Tue, 14 Oct 2014 01:05:53 -0700 Subject: [PATCH 2/4] Expose GBAGetState --- src/gba/gba-serialize.c | 6 +++--- src/gba/gba-serialize.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gba/gba-serialize.c b/src/gba/gba-serialize.c index b26fd169e..8cfdf1df6 100644 --- a/src/gba/gba-serialize.c +++ b/src/gba/gba-serialize.c @@ -102,7 +102,7 @@ void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) { } } -static struct VFile* _getStateVf(struct GBA* gba, struct VDir* dir, int slot, bool write) { +struct VFile* GBAGetState(struct GBA* gba, struct VDir* dir, int slot, bool write) { char suffix[5] = { '\0' }; snprintf(suffix, sizeof(suffix), ".ss%d", slot); return VDirOptionalOpenFile(dir, gba->activeFile, "savestate", suffix, write ? (O_CREAT | O_TRUNC | O_RDWR) : O_RDONLY); @@ -167,7 +167,7 @@ static bool _loadPNGState(struct GBA* gba, struct VFile* vf) { #endif bool GBASaveState(struct GBA* gba, struct VDir* dir, int slot, bool screenshot) { - struct VFile* vf = _getStateVf(gba, dir, slot, true); + struct VFile* vf = GBAGetState(gba, dir, slot, true); if (!vf) { return false; } @@ -177,7 +177,7 @@ bool GBASaveState(struct GBA* gba, struct VDir* dir, int slot, bool screenshot) } bool GBALoadState(struct GBA* gba, struct VDir* dir, int slot) { - struct VFile* vf = _getStateVf(gba, dir, slot, false); + struct VFile* vf = GBAGetState(gba, dir, slot, false); if (!vf) { return false; } diff --git a/src/gba/gba-serialize.h b/src/gba/gba-serialize.h index 86edf9de5..bf1461beb 100644 --- a/src/gba/gba-serialize.h +++ b/src/gba/gba-serialize.h @@ -271,6 +271,7 @@ void GBADeserialize(struct GBA* gba, struct GBASerializedState* state); bool GBASaveState(struct GBA* gba, struct VDir* dir, int slot, bool screenshot); bool GBALoadState(struct GBA* gba, struct VDir* dir, int slot); +struct VFile* GBAGetState(struct GBA* gba, struct VDir* dir, int slot, bool write); bool GBASaveStateNamed(struct GBA* gba, struct VFile* vf, bool screenshot); bool GBALoadStateNamed(struct GBA* gba, struct VFile* vf); From 18e67378fe24815ab76ed97fd5f1497e0a9d3e6a Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Tue, 14 Oct 2014 01:48:56 -0700 Subject: [PATCH 3/4] C++ build fixes --- src/gba/gba-serialize.h | 2 +- src/gba/gba.h | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/gba/gba-serialize.h b/src/gba/gba-serialize.h index bf1461beb..57ce517cc 100644 --- a/src/gba/gba-serialize.h +++ b/src/gba/gba-serialize.h @@ -5,7 +5,7 @@ #include "gba.h" -const uint32_t GBA_SAVESTATE_MAGIC; +extern const uint32_t GBA_SAVESTATE_MAGIC; /* Savestate format: * 0x00000 - 0x00003: Version Magic (0x01000000) diff --git a/src/gba/gba.h b/src/gba/gba.h index 23eb7f13b..2e2e3d39b 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -66,6 +66,18 @@ struct GBARotationSource; struct Patch; struct VFile; +struct GBATimer { + uint16_t reload; + uint16_t oldReload; + int32_t lastEvent; + int32_t nextEvent; + int32_t overflowInterval; + unsigned prescaleBits : 4; + unsigned countUp : 1; + unsigned doIrq : 1; + unsigned enable : 1; +}; + struct GBA { struct ARMComponent d; @@ -80,17 +92,7 @@ struct GBA { struct ARMDebugger* debugger; int timersEnabled; - struct GBATimer { - uint16_t reload; - uint16_t oldReload; - int32_t lastEvent; - int32_t nextEvent; - int32_t overflowInterval; - unsigned prescaleBits : 4; - unsigned countUp : 1; - unsigned doIrq : 1; - unsigned enable : 1; - } timers[4]; + struct GBATimer timers[4]; int springIRQ; uint32_t biosChecksum; From 69d041d3737dafd0d3e6d637c7f234c1ea914ec9 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Tue, 14 Oct 2014 03:08:39 -0700 Subject: [PATCH 4/4] VFile write should use const void* --- src/util/vfs.c | 4 ++-- src/util/vfs.h | 2 +- src/util/vfs/vfs-zip.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/util/vfs.c b/src/util/vfs.c index ac8fe4c34..7902d55c0 100644 --- a/src/util/vfs.c +++ b/src/util/vfs.c @@ -24,7 +24,7 @@ static bool _vfdClose(struct VFile* vf); static off_t _vfdSeek(struct VFile* vf, off_t offset, int whence); static ssize_t _vfdRead(struct VFile* vf, void* buffer, size_t size); static ssize_t _vfdReadline(struct VFile* vf, char* buffer, size_t size); -static ssize_t _vfdWrite(struct VFile* vf, void* buffer, size_t size); +static ssize_t _vfdWrite(struct VFile* vf, const void* buffer, size_t size); static void* _vfdMap(struct VFile* vf, size_t size, int flags); static void _vfdUnmap(struct VFile* vf, void* memory, size_t size); static void _vfdTruncate(struct VFile* vf, size_t size); @@ -96,7 +96,7 @@ ssize_t _vfdReadline(struct VFile* vf, char* buffer, size_t size) { return buffer[bytesRead] = '\0'; } -ssize_t _vfdWrite(struct VFile* vf, void* buffer, size_t size) { +ssize_t _vfdWrite(struct VFile* vf, const void* buffer, size_t size) { struct VFileFD* vfd = (struct VFileFD*) vf; return write(vfd->fd, buffer, size); } diff --git a/src/util/vfs.h b/src/util/vfs.h index 853de9058..cea38aedf 100644 --- a/src/util/vfs.h +++ b/src/util/vfs.h @@ -13,7 +13,7 @@ struct VFile { off_t (*seek)(struct VFile* vf, off_t offset, int whence); ssize_t (*read)(struct VFile* vf, void* buffer, size_t size); ssize_t (*readline)(struct VFile* vf, char* buffer, size_t size); - ssize_t (*write)(struct VFile* vf, void* buffer, size_t size); + ssize_t (*write)(struct VFile* vf, const void* buffer, size_t size); void* (*map)(struct VFile* vf, size_t size, int flags); void (*unmap)(struct VFile* vf, void* memory, size_t size); void (*truncate)(struct VFile* vf, size_t size); diff --git a/src/util/vfs/vfs-zip.c b/src/util/vfs/vfs-zip.c index 0a5d34406..21f703690 100644 --- a/src/util/vfs/vfs-zip.c +++ b/src/util/vfs/vfs-zip.c @@ -34,7 +34,7 @@ static bool _vfzClose(struct VFile* vf); static off_t _vfzSeek(struct VFile* vf, off_t offset, int whence); static ssize_t _vfzRead(struct VFile* vf, void* buffer, size_t size); static ssize_t _vfzReadline(struct VFile* vf, char* buffer, size_t size); -static ssize_t _vfzWrite(struct VFile* vf, void* buffer, size_t size); +static ssize_t _vfzWrite(struct VFile* vf, const void* buffer, size_t size); static void* _vfzMap(struct VFile* vf, size_t size, int flags); static void _vfzUnmap(struct VFile* vf, void* memory, size_t size); static void _vfzTruncate(struct VFile* vf, size_t size); @@ -194,7 +194,7 @@ ssize_t _vfzReadline(struct VFile* vf, char* buffer, size_t size) { return buffer[bytesRead] = '\0'; } -ssize_t _vfzWrite(struct VFile* vf, void* buffer, size_t size) { +ssize_t _vfzWrite(struct VFile* vf, const void* buffer, size_t size) { // TODO UNUSED(vf); UNUSED(buffer);