Merge branch 'master' into qt
Jeffrey Pfau jeffrey@endrift.com
Sun, 19 Oct 2014 00:30:27 -0700
4 files changed,
104 insertions(+),
3 deletions(-)
M
src/gba/gba-audio.c
→
src/gba/gba-audio.c
@@ -116,7 +116,7 @@ CircleBufferWrite32(&audio->right, buffer[i]);
} } - GBASyncUnlockAudio(audio->p->sync); + GBASyncConsumeAudio(audio->p->sync); } int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles) {
M
src/gba/gba-thread.c
→
src/gba/gba-thread.c
@@ -209,6 +209,7 @@ threadContext->gba = 0;
ARMDeinit(&cpu); GBADestroy(&gba); + threadContext->sync.videoFrameOn = false; ConditionWake(&threadContext->sync.videoFrameAvailableCond); ConditionWake(&threadContext->sync.audioRequiredCond);@@ -503,7 +504,7 @@ #ifdef USE_PNG
void GBAThreadTakeScreenshot(struct GBAThread* threadContext) { unsigned stride; void* pixels = 0; - struct VFile* vf = VDirOptionalOpenFile(threadContext->stateDir, threadContext->gba->activeFile, "screenshot", ".png", O_CREAT | O_TRUNC | O_WRONLY); + struct VFile* vf = VDirOptionalOpenIncrementFile(threadContext->stateDir, threadContext->gba->activeFile, "screenshot", "-", ".png", O_CREAT | O_TRUNC | O_WRONLY); threadContext->gba->video.renderer->getPixels(threadContext->gba->video.renderer, &stride, &pixels); png_structp png = PNGWriteOpen(vf); png_infop info = PNGWriteHeader(png, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);@@ -561,7 +562,7 @@ ConditionWake(&sync->videoFrameRequiredCond);
if (!sync->videoFrameOn && !sync->videoFramePending) { return false; } - if (sync->videoFrameOn) { + if (sync->videoFrameOn && !sync->videoFramePending) { ConditionWait(&sync->videoFrameAvailableCond, &sync->videoFrameMutex); } sync->videoFramePending = 0;
M
src/util/vfs.c
→
src/util/vfs.c
@@ -211,6 +211,105 @@ }
return vf; } +struct VFile* VDirOptionalOpenIncrementFile(struct VDir* dir, const char* realPath, const char* prefix, const char* infix, const char* suffix, int mode) { + char path[PATH_MAX]; + path[PATH_MAX - 1] = '\0'; + char realPrefix[PATH_MAX]; + realPrefix[PATH_MAX - 1] = '\0'; + if (!dir) { + if (!realPath) { + return 0; + } + const char* separatorPoint = strrchr(realPath, '/'); + const char* dotPoint; + size_t len; + if (!separatorPoint) { + strcpy(path, "./"); + separatorPoint = realPath; + dotPoint = strrchr(realPath, '.'); + } else { + path[0] = '\0'; + dotPoint = strrchr(separatorPoint, '.'); + + if (separatorPoint - realPath + 1 >= PATH_MAX - 1) { + return 0; + } + + len = separatorPoint - realPath; + strncat(path, realPath, len); + path[len] = '\0'; + ++separatorPoint; + } + + if (dotPoint - realPath + 1 >= PATH_MAX - 1) { + return 0; + } + + if (dotPoint >= separatorPoint) { + len = dotPoint - separatorPoint; + } else { + len = PATH_MAX - 1; + } + + strncpy(realPrefix, separatorPoint, len); + realPrefix[len] = '\0'; + + prefix = realPrefix; + dir = VDirOpen(path); + } + if (!dir) { + // This shouldn't be possible + return 0; + } + dir->rewind(dir); + struct VDirEntry* dirent; + size_t prefixLen = strlen(prefix); + size_t infixLen = strlen(infix); + unsigned next = 0; + while ((dirent = dir->listNext(dir))) { + const char* filename = dirent->name(dirent); + char* dotPoint = strrchr(filename, '.'); + size_t len = strlen(filename); + if (dotPoint) { + len = (dotPoint - filename); + } + const char* separator = 0; + const char* nextSeparator = filename; + size_t strstrlen = len; + while ((nextSeparator = strnstr(nextSeparator, infix, strstrlen))) { + strstrlen -= nextSeparator - separator - 1; + separator = nextSeparator; + ++nextSeparator; + } + if (!separator) { + continue; + } + len = separator - filename; + if (len != prefixLen) { + continue; + } + if (strncmp(filename, prefix, prefixLen) == 0) { + int nlen; + separator += infixLen; + snprintf(path, PATH_MAX - 1, "%%u%s%%n", suffix); + unsigned increment; + if (sscanf(separator, path, &increment, &nlen) < 1) { + continue; + } + len = strlen(separator); + if (nlen < (ssize_t) len) { + continue; + } + if (next <= increment) { + next = increment + 1; + } + } + } + snprintf(path, PATH_MAX - 1, "%s%s%u%s", prefix, infix, next, suffix); + path[PATH_MAX - 1] = '\0'; + return dir->openFile(dir, path, mode); +} + bool _vdClose(struct VDir* vd) { struct VDirDE* vdde = (struct VDirDE*) vd; if (closedir(vdde->de) < 0) {
M
src/util/vfs.h
→
src/util/vfs.h
@@ -40,5 +40,6 @@ struct VDir* VDirOpenZip(const char* path, int flags);
#endif struct VFile* VDirOptionalOpenFile(struct VDir* dir, const char* realPath, const char* prefix, const char* suffix, int mode); +struct VFile* VDirOptionalOpenIncrementFile(struct VDir* dir, const char* realPath, const char* prefix, const char* infix, const char* suffix, int mode); #endif