From 6e176a454c6001eb727a53034f13b441c7986aae Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Tue, 7 Jul 2015 15:56:21 +0200 Subject: [PATCH 01/23] Constify --- src/graphics.cpp | 10 +++++----- src/scene.h | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/graphics.cpp b/src/graphics.cpp index 4d7eb59..5730cfb 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -169,15 +169,15 @@ public: } } - void requestViewportRender(Vec4 &c, Vec4 &f, Vec4 &t) + void requestViewportRender(const Vec4 &c, const Vec4 &f, const Vec4 &t) { const IntRect &viewpRect = glState.scissorBox.get(); const IntRect &screenRect = geometry.rect; - bool toneRGBEffect = t.xyzHasEffect(); - bool toneGrayEffect = t.w != 0; - bool colorEffect = c.w > 0; - bool flashEffect = f.w > 0; + const bool toneRGBEffect = t.xyzHasEffect(); + const bool toneGrayEffect = t.w != 0; + const bool colorEffect = c.w > 0; + const bool flashEffect = f.w > 0; if (toneGrayEffect) { diff --git a/src/scene.h b/src/scene.h index edee331..7685407 100644 --- a/src/scene.h +++ b/src/scene.h @@ -55,7 +55,9 @@ public: virtual ~Scene(); virtual void composite(); - virtual void requestViewportRender(Vec4& /*color*/, Vec4& /*flash*/, Vec4& /*tone*/) {} + virtual void requestViewportRender(const Vec4& /* color */, + const Vec4& /* flash */, + const Vec4& /* tone */) {} const Geometry &getGeometry() const { return geometry; } From 9acdd206f65a70e590705aceca4b251535aed380 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Tue, 7 Jul 2015 15:59:10 +0200 Subject: [PATCH 02/23] Vec4: Rename 'xyzHasEffect()' to something that makes sense --- src/etc-internal.h | 2 +- src/graphics.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/etc-internal.h b/src/etc-internal.h index c9bd520..9bab3a8 100644 --- a/src/etc-internal.h +++ b/src/etc-internal.h @@ -61,7 +61,7 @@ struct Vec4 return (x == other.x && y == other.y && z == other.z && w == other.w); } - bool xyzHasEffect() const + bool xyzNotNull() const { return (x != 0.0 || y != 0.0 || z != 0.0); } diff --git a/src/graphics.cpp b/src/graphics.cpp index 5730cfb..74e97a3 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -174,7 +174,7 @@ public: const IntRect &viewpRect = glState.scissorBox.get(); const IntRect &screenRect = geometry.rect; - const bool toneRGBEffect = t.xyzHasEffect(); + const bool toneRGBEffect = t.xyzNotNull(); const bool toneGrayEffect = t.w != 0; const bool colorEffect = c.w > 0; const bool flashEffect = f.w > 0; @@ -240,7 +240,7 @@ public: /* Then apply them using hardware blending */ gl.BlendFuncSeparate(GL_ONE, GL_ONE, GL_ZERO, GL_ONE); - if (add.xyzHasEffect()) + if (add.xyzNotNull()) { gl.BlendEquation(GL_FUNC_ADD); shader.setColor(add); @@ -248,7 +248,7 @@ public: screenQuad.draw(); } - if (sub.xyzHasEffect()) + if (sub.xyzNotNull()) { gl.BlendEquation(GL_FUNC_REVERSE_SUBTRACT); shader.setColor(sub); From 1e9e24e45c80af732559cdfd55590e06efe37f26 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 9 Jul 2015 12:33:55 +0200 Subject: [PATCH 03/23] README: Add note about RGSS version support --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index fede712..d9f9c09 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ Matz's Ruby Interpreter, also called CRuby, is the most widely deployed version For a list of differences, see: http://stackoverflow.com/questions/21574/what-is-the-difference-between-ruby-1-8-and-ruby-1-9 +This binding supports RGSS1, RGSS2 and RGSS3. + ### mruby (Lightweight Ruby) Website: https://github.com/mruby/mruby @@ -29,6 +31,8 @@ Due to heavy differences between mruby and MRI as well as lacking modules, runni Some extensions to the standard classes/modules are provided, taking the RPG Maker XP helpfile as a quasi "reference". These include Marshal, File, FileTest and Time. +This binding only supports RGSS1. + **Important:** If you decide to use [mattn's oniguruma regexp gem](https://github.com/mattn/mruby-onig-regexp), don't forget to add `-lonig` to the linker flags to avoid ugly symbol overlaps with libc. ### null From 5382cc11a38d7dead059df3de367c0dcf59df1fa Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 9 Jul 2015 12:38:04 +0200 Subject: [PATCH 04/23] MidiSource: Close source SDL_RWops before throwing error --- src/midisource.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/midisource.cpp b/src/midisource.cpp index fdca2e4..9cd3a44 100644 --- a/src/midisource.cpp +++ b/src/midisource.cpp @@ -626,9 +626,20 @@ struct MidiSource : ALDataSource, MidiReadHandler std::vector data(dataLen); if (SDL_RWread(&ops, &data[0], 1, dataLen) < dataLen) + { + SDL_RWclose(&ops); throw Exception(Exception::MKXPError, "Reading midi data failed"); + } - readMidi(this, data); + try + { + readMidi(this, data); + } + catch (const Exception &) + { + SDL_RWclose(&ops); + throw; + } synth = shState->midiState().allocateSynth(); From e4558c9dfbcf342b2d5591753fc7e1bedff41349 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 9 Jul 2015 12:58:01 +0200 Subject: [PATCH 05/23] Use FS::openReadRaw() where ext supplementing makes no sense Specifically, in places where the full filename is always supplied, eg. when reading .rxdata type files. --- binding-mri/filesystem-binding.cpp | 2 +- binding-mruby/binding-mruby.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/binding-mri/filesystem-binding.cpp b/binding-mri/filesystem-binding.cpp index 17cf50d..4bc5e03 100644 --- a/binding-mri/filesystem-binding.cpp +++ b/binding-mri/filesystem-binding.cpp @@ -46,7 +46,7 @@ fileIntForPath(const char *path, bool rubyExc) try { - shState->fileSystem().openRead(*ops, path); + shState->fileSystem().openReadRaw(*ops, path); } catch (const Exception &e) { diff --git a/binding-mruby/binding-mruby.cpp b/binding-mruby/binding-mruby.cpp index f895de3..867d2d6 100644 --- a/binding-mruby/binding-mruby.cpp +++ b/binding-mruby/binding-mruby.cpp @@ -266,7 +266,7 @@ runRMXPScripts(mrb_state *mrb, mrbc_context *ctx) mrb_state *scriptMrb = mrb_open(); SDL_RWops ops; - shState->fileSystem().openRead(ops, scriptPack.c_str()); + shState->fileSystem().openReadRaw(ops, scriptPack.c_str()); mrb_value scriptArray = mrb_nil_value(); std::string readError; From 533e69275abd9d30674da7f42ab506cc449d7b93 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 9 Jul 2015 14:53:59 +0200 Subject: [PATCH 06/23] Constify --- src/rgssad.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rgssad.cpp b/src/rgssad.cpp index e8606b9..17e8417 100644 --- a/src/rgssad.cpp +++ b/src/rgssad.cpp @@ -34,7 +34,7 @@ struct RGSS_entryData struct RGSS_entryHandle { - RGSS_entryData data; + const RGSS_entryData data; uint32_t currentMagic; uint64_t currentOffset; PHYSFS_Io *io; @@ -229,7 +229,7 @@ RGSS_ioSeek(PHYSFS_Io *self, PHYSFS_uint64 offset) static PHYSFS_sint64 RGSS_ioTell(PHYSFS_Io *self) { - RGSS_entryHandle *entry = static_cast(self->opaque); + const RGSS_entryHandle *entry = static_cast(self->opaque); return entry->currentOffset; } @@ -237,7 +237,7 @@ RGSS_ioTell(PHYSFS_Io *self) static PHYSFS_sint64 RGSS_ioLength(PHYSFS_Io *self) { - RGSS_entryHandle *entry = static_cast(self->opaque); + const RGSS_entryHandle *entry = static_cast(self->opaque); return entry->data.size; } @@ -245,7 +245,7 @@ RGSS_ioLength(PHYSFS_Io *self) static PHYSFS_Io* RGSS_ioDuplicate(PHYSFS_Io *self) { - RGSS_entryHandle *entry = static_cast(self->opaque); + const RGSS_entryHandle *entry = static_cast(self->opaque); RGSS_entryHandle *entryDup = new RGSS_entryHandle(*entry); PHYSFS_Io *dup = PHYSFS_ALLOC(PHYSFS_Io); @@ -448,7 +448,7 @@ RGSS_stat(void *opaque, const char *filename, PHYSFS_Stat *stat) if (hasFile) { - RGSS_entryData &entry = data->entryHash[filename]; + const RGSS_entryData &entry = data->entryHash[filename]; stat->filesize = entry.size; stat->filetype = PHYSFS_FILETYPE_REGULAR; From 54c1107f19c6aecde16bfe4eeb843112cc9a916a Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 9 Jul 2015 13:00:56 +0200 Subject: [PATCH 07/23] FileSystem: Fix file lookup if unrelated files with same name exist Before, even though we did match all possible extensions, we only took the first match and tried opening it. If we were looking for a .png image, but there was an unrelated .txt file with the same name (as it actually happens in RTPs), we would potentially see the .txt first, try opening it, and fail alltogether, even though the image file existed. Now we try opening all matching files until we find one that we can parse. This fixes #101. --- src/alstream.cpp | 92 +++++--- src/bitmap.cpp | 23 +- src/filesystem.cpp | 518 +++++++++++++++++++++---------------------- src/filesystem.h | 21 +- src/soundemitter.cpp | 70 +++--- 5 files changed, 399 insertions(+), 325 deletions(-) diff --git a/src/alstream.cpp b/src/alstream.cpp index 18799ff..2f1e39f 100644 --- a/src/alstream.cpp +++ b/src/alstream.cpp @@ -199,43 +199,73 @@ void ALStream::closeSource() delete source; } +struct ALStreamOpenHandler : FileSystem::OpenHandler +{ + SDL_RWops *srcOps; + bool looped; + ALDataSource *source; + std::string errorMsg; + + ALStreamOpenHandler(SDL_RWops &srcOps, bool looped) + : srcOps(&srcOps), looped(looped), source(0) + {} + + bool tryRead(SDL_RWops &ops, const char *ext) + { + /* Copy this because we need to keep it around, + * as we will continue reading data from it later */ + *srcOps = ops; + + /* Try to read ogg file signature */ + char sig[5] = { 0 }; + SDL_RWread(srcOps, sig, 1, 4); + SDL_RWseek(srcOps, 0, RW_SEEK_SET); + + try + { + if (!strcmp(sig, "OggS")) + { + source = createVorbisSource(*srcOps, looped); + return true; + } + + if (!strcmp(sig, "MThd")) + { + shState->midiState().initIfNeeded(shState->config()); + + if (HAVE_FLUID) + { + source = createMidiSource(*srcOps, looped); + return true; + } + } + + source = createSDLSource(*srcOps, ext, STREAM_BUF_SIZE, looped); + } + catch (const Exception &e) + { + /* All source constructors will close the passed ops + * before throwing errors */ + errorMsg = e.msg; + return false; + } + + return true; + } +}; + void ALStream::openSource(const std::string &filename) { - char ext[8]; - shState->fileSystem().openRead(srcOps, filename.c_str(), false, ext, sizeof(ext)); + ALStreamOpenHandler handler(srcOps, looped); + shState->fileSystem().openRead(handler, filename.c_str()); + source = handler.source; needsRewind.clear(); - /* Try to read ogg file signature */ - char sig[5] = { 0 }; - SDL_RWread(&srcOps, sig, 1, 4); - SDL_RWseek(&srcOps, 0, RW_SEEK_SET); - - try - { - if (!strcmp(sig, "OggS")) - { - source = createVorbisSource(srcOps, looped); - return; - } - - if (!strcmp(sig, "MThd")) - { - shState->midiState().initIfNeeded(shState->config()); - - if (HAVE_FLUID) - { - source = createMidiSource(srcOps, looped); - return; - } - } - - source = createSDLSource(srcOps, ext, STREAM_BUF_SIZE, looped); - } - catch (const Exception &e) + if (!source) { char buf[512]; - snprintf(buf, sizeof(buf), "Unable to decode audio stream: %s.%s: %s", - filename.c_str(), ext, e.msg.c_str()); + snprintf(buf, sizeof(buf), "Unable to decode audio stream: %s: %s", + filename.c_str(), handler.errorMsg.c_str()); Debug() << buf; } diff --git a/src/bitmap.cpp b/src/bitmap.cpp index 2a51d6f..37b1af1 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -233,13 +233,26 @@ struct BitmapPrivate } }; +struct BitmapOpenHandler : FileSystem::OpenHandler +{ + SDL_Surface *surf; + + BitmapOpenHandler() + : surf(0) + {} + + bool tryRead(SDL_RWops &ops, const char *ext) + { + surf = IMG_LoadTyped_RW(&ops, 1, ext); + return surf != 0; + } +}; + Bitmap::Bitmap(const char *filename) { - SDL_RWops ops; - char ext[8]; - - shState->fileSystem().openRead(ops, filename, false, ext, sizeof(ext)); - SDL_Surface *imgSurf = IMG_LoadTyped_RW(&ops, 1, ext); + BitmapOpenHandler handler; + shState->fileSystem().openRead(handler, filename); + SDL_Surface *imgSurf = handler.surf; if (!imgSurf) throw Exception(Exception::SDLError, "Error loading image '%s': %s", diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 6642d3b..fe5d403 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef __APPLE__ #include @@ -249,201 +250,65 @@ strcpySafe(char *dst, const char *src, return cpyMax; } +/* Attempt to locate an extension string in a filename. + * Either a pointer into the input string pointing at the + * extension, or null is returned */ +static const char * +findExt(const char *filename) +{ + size_t len; + + for (len = strlen(filename); len > 0; --len) + { + if (filename[len] == '/') + return 0; + + if (filename[len] == '.') + return &filename[len+1]; + } + + return 0; +} + +static void +initReadOps(PHYSFS_File *handle, + SDL_RWops &ops, + bool freeOnClose) +{ + ops.size = SDL_RWopsSize; + ops.seek = SDL_RWopsSeek; + ops.read = SDL_RWopsRead; + ops.write = SDL_RWopsWrite; + + if (freeOnClose) + ops.close = SDL_RWopsCloseFree; + else + ops.close = SDL_RWopsClose; + + ops.type = SDL_RWOPS_PHYSFS; + ops.hidden.unknown.data1 = handle; +} + +static void strTolower(std::string &str) +{ + for (size_t i = 0; i < str.size(); ++i) + str[i] = tolower(str[i]); +} + const Uint32 SDL_RWOPS_PHYSFS = SDL_RWOPS_UNKNOWN+10; struct FileSystemPrivate { - /* Maps: lower case filepath without extension, - * To: mixed case full filepath - * This is for compatibility with games that take Windows' - * case insensitivity for granted */ + /* Maps: lower case full filepath, + * To: mixed case full filepath */ BoostHash pathCache; + /* Maps: lower case directory path, + * To: list of lower case filenames */ + BoostHash > fileLists; + + /* This is for compatibility with games that take Windows' + * case insensitivity for granted */ bool havePathCache; - - /* Attempt to locate an extension string in a filename. - * Either a pointer into the input string pointing at the - * extension, or null is returned */ - const char *findExt(const char *filename) - { - size_t len; - - for (len = strlen(filename); len > 0; --len) - { - if (filename[len] == '/') - return 0; - - if (filename[len] == '.') - return &filename[len+1]; - } - - return 0; - } - - struct CompleteFilenameData - { - bool found; - /* Contains the incomplete filename we're looking for; - * when found, we write the complete filename into this - * same buffer */ - char *outBuf; - /* Length of incomplete file name */ - size_t filenameLen; - /* Maximum we can write into outBuf */ - size_t outBufN; - }; - - static void completeFilenameRegCB(void *data, const char *, - const char *fname) - { - CompleteFilenameData &d = *static_cast(data); - - if (d.found) - return; - - if (strncmp(d.outBuf, fname, d.filenameLen) != 0) - return; - - /* If fname matches up to a following '.' (meaning the rest is part - * of the extension), or up to a following '\0' (full match), we've - * found our file */ - switch (fname[d.filenameLen]) - { - case '.' : - /* Overwrite the incomplete file name we looked for with - * the full version containing any extensions */ - strcpySafe(d.outBuf, fname, d.outBufN, -1); - case '\0' : - d.found = true; - } - } - - bool completeFilenameReg(const char *filepath, - char *outBuffer, - size_t outN) - { - strcpySafe(outBuffer, filepath, outN, -1); - - size_t len = strlen(outBuffer); - char *delim; - - /* Find the deliminator separating directory and file name */ - for (delim = outBuffer + len; delim > outBuffer; --delim) - if (*delim == '/') - break; - - bool root = (delim == outBuffer); - CompleteFilenameData d; - - if (!root) - { - /* If we have such a deliminator, we set it to '\0' so we - * can pass the first half to PhysFS as the directory name, - * and compare all filenames against the second half */ - d.outBuf = delim+1; - d.filenameLen = len - (delim - outBuffer + 1); - - *delim = '\0'; - } - else - { - /* Otherwise the file is in the root directory */ - d.outBuf = outBuffer; - d.filenameLen = len - (delim - outBuffer); - } - - d.found = false; - d.outBufN = outN - (d.outBuf - outBuffer); - - PHYSFS_enumerateFilesCallback(root ? "" : outBuffer, completeFilenameRegCB, &d); - - if (!d.found) - return false; - - /* Now we put the deliminator back in to form the completed - * file path (if required) */ - if (delim != outBuffer) - *delim = '/'; - - return true; - } - - bool completeFilenamePC(const char *filepath, - char *outBuffer, - size_t outN) - { - std::string lowCase(filepath); - - for (size_t i = 0; i < lowCase.size(); ++i) - lowCase[i] = tolower(lowCase[i]); - - if (!pathCache.contains(lowCase)) - return false; - - const std::string &fullPath = pathCache[lowCase]; - strcpySafe(outBuffer, fullPath.c_str(), outN, fullPath.size()); - - return true; - } - - bool completeFilename(const char *filepath, - char *outBuffer, - size_t outN) - { - if (havePathCache) - return completeFilenamePC(filepath, outBuffer, outN); - else - return completeFilenameReg(filepath, outBuffer, outN); - } - - PHYSFS_File *openReadHandle(const char *filename, - char *extBuf, - size_t extBufN) - { - char found[512]; - - if (!completeFilename(filename, found, sizeof(found))) - throw Exception(Exception::NoFileError, "%s", filename); - - PHYSFS_File *handle = PHYSFS_openRead(found); - - if (!handle) - throw Exception(Exception::PHYSFSError, "PhysFS: %s", PHYSFS_getLastError()); - - if (!extBuf) - return handle; - - for (char *q = found+strlen(found); q > found; --q) - { - if (*q == '/') - break; - - if (*q != '.') - continue; - - strcpySafe(extBuf, q+1, extBufN, -1); - break; - } - - return handle; - } - - void initReadOps(PHYSFS_File *handle, - SDL_RWops &ops, - bool freeOnClose) - { - ops.size = SDL_RWopsSize; - ops.seek = SDL_RWopsSeek; - ops.read = SDL_RWopsRead; - ops.write = SDL_RWopsWrite; - - if (freeOnClose) - ops.close = SDL_RWopsCloseFree; - else - ops.close = SDL_RWopsClose; - - ops.type = SDL_RWOPS_PHYSFS; - ops.hidden.unknown.data1 = handle; - } }; FileSystem::FileSystem(const char *argv0, @@ -484,99 +349,105 @@ void FileSystem::addPath(const char *path) } } -#ifdef __APPLE__ -struct CacheEnumCBData +struct CacheEnumData { FileSystemPrivate *p; + std::stack*> fileLists; + +#ifdef __APPLE__ iconv_t nfd2nfc; + char buf[512]; +#endif - CacheEnumCBData(FileSystemPrivate *fsp) + CacheEnumData(FileSystemPrivate *p) + : p(p) { - p = fsp; +#ifdef __APPLE__ nfd2nfc = iconv_open("utf-8", "utf-8-mac"); +#endif } - ~CacheEnumCBData() + ~CacheEnumData() { +#ifdef __APPLE__ iconv_close(nfd2nfc); +#endif } - void nfcFromNfd(char *dst, const char *src, size_t dstSize) + /* Converts in-place */ + void toNFC(char *inout) { - size_t srcSize = strlen(src); +#ifdef __APPLE__ + size_t srcSize = strlen(inout); + size_t bufSize = sizeof(buf); + char *bufPtr = buf; + char *inoutPtr = inout; + /* Reserve room for null terminator */ - --dstSize; - /* iconv takes a char** instead of a const char**, even though - * the string data isn't written to. */ + --bufSize; + iconv(nfd2nfc, - const_cast(&src), &srcSize, - &dst, &dstSize); + &inoutPtr, &srcSize, + &bufPtr, &bufSize); /* Null-terminate */ - *dst = 0; + *bufPtr = 0; + strcpy(inout, buf); +#else + (void) inout; +#endif } }; -#endif static void cacheEnumCB(void *d, const char *origdir, const char *fname) { -#ifdef __APPLE__ - CacheEnumCBData *data = static_cast(d); - FileSystemPrivate *p = data->p; -#else - FileSystemPrivate *p = static_cast(d); -#endif + CacheEnumData &data = *static_cast(d); + char fullPath[512]; - char buf[512]; - - if (*origdir == '\0') - strncpy(buf, fname, sizeof(buf)); + if (!*origdir) + snprintf(fullPath, sizeof(fullPath), "%s", fname); else - snprintf(buf, sizeof(buf), "%s/%s", origdir, fname); + snprintf(fullPath, sizeof(fullPath), "%s/%s", origdir, fname); -#ifdef __APPLE__ - char bufNfc[sizeof(buf)]; - data->nfcFromNfd(bufNfc, buf, sizeof(bufNfc)); -#else - char *const bufNfc = buf; -#endif + /* Deal with OSX' weird UTF-8 standards */ + data.toNFC(fullPath); - char *ptr = bufNfc; + std::string mixedCase(fullPath); + std::string lowerCase = mixedCase; + strTolower(lowerCase); - /* Trim leading slash */ - if (*ptr == '/') - ++ptr; + PHYSFS_Stat stat; + PHYSFS_stat(fullPath, &stat); - std::string mixedCase(ptr); - - for (char *q = bufNfc; *q; ++q) - *q = tolower(*q); - - p->pathCache.insert(std::string(ptr), mixedCase); - - for (char *q = ptr+strlen(ptr); q > ptr; --q) + if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY) { - if (*q == '/') - break; + /* Create a new list for this directory */ + std::vector &list = data.p->fileLists[lowerCase]; - if (*q != '.') - continue; - - *q = '\0'; - p->pathCache.insert(std::string(ptr), mixedCase); + /* Iterate over its contents */ + data.fileLists.push(&list); + PHYSFS_enumerateFilesCallback(fullPath, cacheEnumCB, d); + data.fileLists.pop(); } + else + { + /* Get the file list for the directory we're currently + * traversing and append this filename to it */ + std::vector &list = *data.fileLists.top(); + std::string lowerFilename(fname); + strTolower(lowerFilename); + list.push_back(lowerFilename); - PHYSFS_enumerateFilesCallback(mixedCase.c_str(), cacheEnumCB, d); + /* Add the lower -> mixed mapping of the file's full path */ + data.p->pathCache.insert(lowerCase, mixedCase); + } } void FileSystem::createPathCache() { -#ifdef __APPLE__ - CacheEnumCBData data(p); + CacheEnumData data(p); + data.fileLists.push(&p->fileLists[""]); PHYSFS_enumerateFilesCallback("", cacheEnumCB, &data); -#else - PHYSFS_enumerateFilesCallback("", cacheEnumCB, p); -#endif p->havePathCache = true; } @@ -591,10 +462,9 @@ static void fontSetEnumCB(void *data, const char *, const char *fname) { FontSetsCBData *d = static_cast(data); - FileSystemPrivate *p = d->p; /* Only consider filenames with font extensions */ - const char *ext = p->findExt(fname); + const char *ext = findExt(fname); if (!ext) return; @@ -618,7 +488,7 @@ static void fontSetEnumCB(void *data, const char *, return; SDL_RWops ops; - p->initReadOps(handle, ops, false); + initReadOps(handle, ops, false); d->sfs->initFontSetCB(ops, filename); @@ -632,15 +502,147 @@ void FileSystem::initFontSets(SharedFontState &sfs) PHYSFS_enumerateFilesCallback("Fonts", fontSetEnumCB, &d); } -void FileSystem::openRead(SDL_RWops &ops, - const char *filename, - bool freeOnClose, - char *extBuf, - size_t extBufN) +struct OpenReadEnumData { - PHYSFS_File *handle = p->openReadHandle(filename, extBuf, extBufN); + FileSystem::OpenHandler &handler; + SDL_RWops ops; - p->initReadOps(handle, ops, freeOnClose); + /* The filename (without directory) we're looking for */ + const char *filename; + size_t filenameN; + + /* Optional hash to translate full filepaths + * (used with path cache) */ + BoostHash *pathTrans; + + /* Number of files we've attempted to read and parse */ + size_t matchCount; + bool stopSearching; + + /* In case of a PhysFS error, save it here so it + * doesn't get changed before we get back into our code */ + const char *physfsError; + + OpenReadEnumData(FileSystem::OpenHandler &handler, + const char *filename, size_t filenameN, + BoostHash *pathTrans) + : handler(handler), filename(filename), filenameN(filenameN), + pathTrans(pathTrans), matchCount(0), stopSearching(false), + physfsError(0) + {} +}; + +static void openReadEnumCB(void *d, const char *dirpath, + const char *filename) +{ + OpenReadEnumData &data = *static_cast(d); + char buffer[512]; + const char *fullPath; + + if (data.stopSearching) + return; + + /* If there's not even a partial match, continue searching */ + if (strncmp(filename, data.filename, data.filenameN) != 0) + return; + + if (!*dirpath) + { + fullPath = filename; + } + else + { + snprintf(buffer, sizeof(buffer), "%s/%s", dirpath, filename); + fullPath = buffer; + } + + char last = filename[data.filenameN]; + + /* If fname matches up to a following '.' (meaning the rest is part + * of the extension), or up to a following '\0' (full match), we've + * found our file */ + if (last != '.' && last != '\0') + return; + + /* If the path cache is active, translate from lower case + * to mixed case path */ + if (data.pathTrans) + fullPath = (*data.pathTrans)[fullPath].c_str(); + + PHYSFS_File *phys = PHYSFS_openRead(fullPath); + + if (!phys) + { + /* Failing to open this file here means there must + * be a deeper rooted problem somewhere within PhysFS. + * Just abort alltogether. */ + data.stopSearching = true; + data.physfsError = PHYSFS_getLastError(); + + return; + } + + initReadOps(phys, data.ops, false); + + const char *ext = findExt(filename); + + if (data.handler.tryRead(data.ops, ext)) + data.stopSearching = true; + + ++data.matchCount; +} + +void FileSystem::openRead(OpenHandler &handler, const char *filename) +{ + char buffer[512]; + size_t len = strcpySafe(buffer, filename, sizeof(buffer), -1); + char *delim; + + if (p->havePathCache) + for (size_t i = 0; i < len; ++i) + buffer[i] = tolower(buffer[i]); + + /* Find the deliminator separating directory and file name */ + for (delim = buffer + len; delim > buffer; --delim) + if (*delim == '/') + break; + + const bool root = (delim == buffer); + + const char *file = buffer; + const char *dir = ""; + + if (!root) + { + /* Cut the buffer in half so we can use it + * for both filename and directory path */ + *delim = '\0'; + file = delim+1; + dir = buffer; + } + + OpenReadEnumData data(handler, file, len + buffer - delim - !root, + p->havePathCache ? &p->pathCache : 0); + + if (p->havePathCache) + { + /* Get the list of files contained in this directory + * and manually iterate over them */ + const std::vector &fileList = p->fileLists[dir]; + + for (size_t i = 0; i < fileList.size(); ++i) + openReadEnumCB(&data, dir, fileList[i].c_str()); + } + else + { + PHYSFS_enumerateFilesCallback(dir, openReadEnumCB, &data); + } + + if (data.physfsError) + throw Exception(Exception::PHYSFSError, "PhysFS: %s", data.physfsError); + + if (data.matchCount == 0) + throw Exception(Exception::NoFileError, "%s", filename); } void FileSystem::openReadRaw(SDL_RWops &ops, @@ -650,12 +652,10 @@ void FileSystem::openReadRaw(SDL_RWops &ops, PHYSFS_File *handle = PHYSFS_openRead(filename); assert(handle); - p->initReadOps(handle, ops, freeOnClose); + initReadOps(handle, ops, freeOnClose); } bool FileSystem::exists(const char *filename) { - char found[512]; - - return p->completeFilename(filename, found, sizeof(found)); + return PHYSFS_exists(filename); } diff --git a/src/filesystem.h b/src/filesystem.h index a98d96d..1f9f79f 100644 --- a/src/filesystem.h +++ b/src/filesystem.h @@ -43,17 +43,28 @@ public: * available font assets */ void initFontSets(SharedFontState &sfs); - void openRead(SDL_RWops &ops, - const char *filename, - bool freeOnClose = false, - char *extBuf = 0, - size_t extBufN = 0); + struct OpenHandler + { + /* Try to read and interpret data provided from ops. + * If data cannot be parsed, return false, otherwise true. + * Can be called multiple times until a parseable file is found. + * It's the handler's responsibility to close every passed + * ops structure, even when data could not be parsed. + * After this function returns, ops becomes invalid, so don't take + * references to it. Instead, copy the structure without closing + * if you need to further read from it later. */ + virtual bool tryRead(SDL_RWops &ops, const char *ext) = 0; + }; + + void openRead(OpenHandler &handler, + const char *filename); /* Circumvents extension supplementing */ void openReadRaw(SDL_RWops &ops, const char *filename, bool freeOnClose = false); + /* Does not perform extension supplementing */ bool exists(const char *filename); private: diff --git a/src/soundemitter.cpp b/src/soundemitter.cpp index 3850c0b..b064fd1 100644 --- a/src/soundemitter.cpp +++ b/src/soundemitter.cpp @@ -184,6 +184,44 @@ void SoundEmitter::stop() AL::Source::stop(alSrcs[i]); } +struct SoundOpenHandler : FileSystem::OpenHandler +{ + SoundBuffer *buffer; + + SoundOpenHandler() + : buffer(0) + {} + + bool tryRead(SDL_RWops &ops, const char *ext) + { + Sound_Sample *sample = Sound_NewSample(&ops, ext, 0, STREAM_BUF_SIZE); + + if (!sample) + { + SDL_RWclose(&ops); + return false; + } + + /* Do all of the decoding in the handler so we don't have + * to keep the source ops around */ + uint32_t decBytes = Sound_DecodeAll(sample); + uint8_t sampleSize = formatSampleSize(sample->actual.format); + uint32_t sampleCount = decBytes / sampleSize; + + buffer = new SoundBuffer; + buffer->bytes = sampleSize * sampleCount; + + ALenum alFormat = chooseALFormat(sampleSize, sample->actual.channels); + + AL::Buffer::uploadData(buffer->alBuffer, alFormat, sample->buffer, + buffer->bytes, sample->actual.rate); + + Sound_FreeSample(sample); + + return true; + } +}; + SoundBuffer *SoundEmitter::allocateBuffer(const std::string &filename) { SoundBuffer *buffer = bufferHash.value(filename, 0); @@ -199,40 +237,22 @@ SoundBuffer *SoundEmitter::allocateBuffer(const std::string &filename) } else { - /* Buffer not in cashe, needs to be loaded */ - SDL_RWops dataSource; - char ext[8]; + /* Buffer not in cache, needs to be loaded */ + SoundOpenHandler handler; + shState->fileSystem().openRead(handler, filename.c_str()); + buffer = handler.buffer; - shState->fileSystem().openRead(dataSource, filename.c_str(), - false, ext, sizeof(ext)); - - Sound_Sample *sampleHandle = Sound_NewSample(&dataSource, ext, 0, STREAM_BUF_SIZE); - - if (!sampleHandle) + if (!buffer) { char buf[512]; - snprintf(buf, sizeof(buf), "Unable to decode sound: %s.%s: %s", - filename.c_str(), ext, Sound_GetError()); + snprintf(buf, sizeof(buf), "Unable to decode sound: %s: %s", + filename.c_str(), Sound_GetError()); Debug() << buf; return 0; } - uint32_t decBytes = Sound_DecodeAll(sampleHandle); - uint8_t sampleSize = formatSampleSize(sampleHandle->actual.format); - uint32_t sampleCount = decBytes / sampleSize; - - buffer = new SoundBuffer; buffer->key = filename; - buffer->bytes = sampleSize * sampleCount; - - ALenum alFormat = chooseALFormat(sampleSize, sampleHandle->actual.channels); - - AL::Buffer::uploadData(buffer->alBuffer, alFormat, sampleHandle->buffer, - buffer->bytes, sampleHandle->actual.rate); - - Sound_FreeSample(sampleHandle); - uint32_t wouldBeBytes = bufferBytes + buffer->bytes; /* If memory limit is reached, delete lowest priority buffer From fe709b6010fe128e3756648e3af14db7ecae5b86 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Fri, 10 Jul 2015 04:51:29 +0200 Subject: [PATCH 08/23] Use vector math --- src/tilemapvx.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tilemapvx.cpp b/src/tilemapvx.cpp index 6291fd9..039bd2c 100644 --- a/src/tilemapvx.cpp +++ b/src/tilemapvx.cpp @@ -181,8 +181,7 @@ struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader void updatePosition() { - dispPos.x = -(offset.x - mapViewp.x * 32) + sceneOffset.x; - dispPos.y = -(offset.y - mapViewp.y * 32) + sceneOffset.y; + dispPos = -(offset - mapViewp.pos() * 32) + sceneOffset; } void updateMapViewport() From fe6799d00bae75c6d2ef9f9a6911f49acd983e0b Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Fri, 10 Jul 2015 04:58:28 +0200 Subject: [PATCH 09/23] TilemapVX: Fix map viewport calculation --- src/tilemapvx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tilemapvx.cpp b/src/tilemapvx.cpp index 039bd2c..57abe26 100644 --- a/src/tilemapvx.cpp +++ b/src/tilemapvx.cpp @@ -188,7 +188,7 @@ struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader { int tileOX, tileOY; - Vec2i offs(offset.x-sceneOffset.x, offset.y-sceneOffset.y); + Vec2i offs = offset + sceneGeo.orig; if (offs.x >= 0) tileOX = offs.x / 32; From 861d261af24540b4280acef4fbdffd47c0ea927e Mon Sep 17 00:00:00 2001 From: cremno Date: Tue, 21 Jul 2015 07:27:53 +0200 Subject: [PATCH 10/23] add Sprite#{bush_opacity,bush_opacity=} --- binding-mri/sprite-binding.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/binding-mri/sprite-binding.cpp b/binding-mri/sprite-binding.cpp index 2404e4a..dc7f902 100644 --- a/binding-mri/sprite-binding.cpp +++ b/binding-mri/sprite-binding.cpp @@ -56,6 +56,7 @@ DEF_PROP_I(Sprite, Y) DEF_PROP_I(Sprite, OX) DEF_PROP_I(Sprite, OY) DEF_PROP_I(Sprite, BushDepth) +DEF_PROP_I(Sprite, BushOpacity) DEF_PROP_I(Sprite, Opacity) DEF_PROP_I(Sprite, BlendType) DEF_PROP_I(Sprite, WaveAmp) @@ -126,6 +127,8 @@ spriteBindingInit() _rb_define_method(klass, "width", spriteWidth); _rb_define_method(klass, "height", spriteHeight); + INIT_PROP_BIND( Sprite, BushOpacity, "bush_opacity" ); + INIT_PROP_BIND( Sprite, WaveAmp, "wave_amp" ); INIT_PROP_BIND( Sprite, WaveLength, "wave_length" ); INIT_PROP_BIND( Sprite, WaveSpeed, "wave_speed" ); From d1ee507ec46cc28597717175cd43d32f98fac577 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sun, 12 Jul 2015 10:30:36 +0200 Subject: [PATCH 11/23] Vec2i, IntRect: Add unequal operator --- src/etc-internal.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/etc-internal.h b/src/etc-internal.h index 9bab3a8..6c66239 100644 --- a/src/etc-internal.h +++ b/src/etc-internal.h @@ -88,6 +88,11 @@ struct Vec2i return x == other.x && y == other.y; } + bool operator!=(const Vec2i &other) const + { + return !(*this == other); + } + Vec2i &operator+=(const Vec2i &value) { x += value.x; @@ -176,6 +181,11 @@ struct IntRect : SDL_Rect w == other.w && h == other.h); } + bool operator!=(const IntRect &other) const + { + return !(*this == other); + } + Vec2i pos() const { return Vec2i(x, y); From 384249c31afd14b7ab83bd846180b65a0240611d Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Tue, 14 Jul 2015 18:20:31 +0200 Subject: [PATCH 12/23] Unify float literals to use f suffix and avoid double promotions I might have missed some. --- src/al-util.h | 2 +- src/alstream.cpp | 8 ++++---- src/audio.cpp | 6 +++--- src/audiostream.cpp | 22 +++++++++++----------- src/bitmap.cpp | 24 ++++++++++++------------ src/etc-internal.h | 6 +++--- src/font.cpp | 2 +- src/graphics.cpp | 12 ++++++------ src/midisource.cpp | 6 +++--- src/plane.cpp | 4 ++-- src/settingsmenu.cpp | 6 +++--- src/sharedmidistate.h | 2 +- src/soundemitter.cpp | 4 ++-- src/sprite.cpp | 8 ++++---- src/tileatlasvx.cpp | 16 ++++++++-------- src/tilemap.cpp | 2 +- src/transform.h | 2 +- src/window.cpp | 4 ++-- src/windowvx.cpp | 6 +++--- 19 files changed, 71 insertions(+), 71 deletions(-) diff --git a/src/al-util.h b/src/al-util.h index 78ae615..51801e7 100644 --- a/src/al-util.h +++ b/src/al-util.h @@ -238,6 +238,6 @@ inline ALenum chooseALFormat(int sampleSize, int channelCount) #define AUDIO_SLEEP 10 #define STREAM_BUF_SIZE 32768 -#define GLOBAL_VOLUME 0.8 +#define GLOBAL_VOLUME 0.8f #endif // ALUTIL_H diff --git a/src/alstream.cpp b/src/alstream.cpp index 2f1e39f..487f09f 100644 --- a/src/alstream.cpp +++ b/src/alstream.cpp @@ -42,12 +42,12 @@ ALStream::ALStream(LoopMode loopMode, source(0), thread(0), preemptPause(false), - pitch(1.0) + pitch(1.0f) { alSrc = AL::Source::gen(); - AL::Source::setVolume(alSrc, 1.0); - AL::Source::setPitch(alSrc, 1.0); + AL::Source::setVolume(alSrc, 1.0f); + AL::Source::setPitch(alSrc, 1.0f); AL::Source::detachBuffer(alSrc); for (int i = 0; i < STREAM_BUFS; ++i) @@ -172,7 +172,7 @@ void ALStream::setPitch(float value) /* If the source supports setting pitch natively, * we don't have to do it via OpenAL */ if (source && source->setPitch(value)) - AL::Source::setPitch(alSrc, 1.0); + AL::Source::setPitch(alSrc, 1.0f); else AL::Source::setPitch(alSrc, value); } diff --git a/src/audio.cpp b/src/audio.cpp index 945aed0..d536c70 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -170,7 +170,7 @@ struct AudioPrivate else { /* BGM is stopped. -> MeNotPlaying */ - bgm.setVolume(AudioStream::External, 1.0); + bgm.setVolume(AudioStream::External, 1.0f); if (!bgm.noResumeStop) bgm.stream.play(); @@ -193,7 +193,7 @@ struct AudioPrivate if (bgm.stream.queryState() == ALStream::Stopped) { /* BGM stopped midway fade in. -> MeNotPlaying */ - bgm.setVolume(AudioStream::External, 1.0); + bgm.setVolume(AudioStream::External, 1.0f); meWatch.state = MeNotPlaying; bgm.unlockStream(); @@ -219,7 +219,7 @@ struct AudioPrivate if (vol >= 1) { /* BGM fully faded in. -> MeNotPlaying */ - vol = 1.0; + vol = 1.0f; meWatch.state = MeNotPlaying; } diff --git a/src/audiostream.cpp b/src/audiostream.cpp index ae572ef..1d96553 100644 --- a/src/audiostream.cpp +++ b/src/audiostream.cpp @@ -34,11 +34,11 @@ AudioStream::AudioStream(ALStream::LoopMode loopMode, noResumeStop(false), stream(loopMode, threadId) { - current.volume = 1.0; - current.pitch = 1.0; + current.volume = 1.0f; + current.pitch = 1.0f; for (size_t i = 0; i < VolumeTypeCount; ++i) - volumes[i] = 1.0; + volumes[i] = 1.0f; fade.thread = 0; fade.threadName = std::string("audio_fadeout (") + threadId + ")"; @@ -82,8 +82,8 @@ void AudioStream::play(const std::string &filename, lockStream(); - float _volume = clamp(volume, 0, 100) / 100.f; - float _pitch = clamp(pitch, 50, 150) / 100.f; + float _volume = clamp(volume, 0, 100) / 100.0f; + float _pitch = clamp(pitch, 50, 150) / 100.0f; ALStream::State sState = stream.queryState(); @@ -211,7 +211,7 @@ void AudioStream::fadeOut(int duration) } fade.active.set(); - fade.msStep = (1.0) / duration; + fade.msStep = 1.0f / duration; fade.reqFini.clear(); fade.reqTerm.clear(); fade.startTicks = SDL_GetTicks(); @@ -302,7 +302,7 @@ void AudioStream::fadeOutThread() lockStream(); uint32_t curDur = SDL_GetTicks() - fade.startTicks; - float resVol = 1.0 - (curDur*fade.msStep); + float resVol = 1.0f - (curDur*fade.msStep); ALStream::State state = stream.queryState(); @@ -313,7 +313,7 @@ void AudioStream::fadeOutThread() if (state != ALStream::Paused) stream.stop(); - setVolume(FadeOut, 1.0); + setVolume(FadeOut, 1.0f); unlockStream(); break; @@ -340,15 +340,15 @@ void AudioStream::fadeInThread() /* Fade in duration is always 1 second */ uint32_t cur = SDL_GetTicks() - fadeIn.startTicks; - float prog = cur / 1000.0; + float prog = cur / 1000.0f; ALStream::State state = stream.queryState(); if (state != ALStream::Playing - || prog >= 1.0 + || prog >= 1.0f || fadeIn.rqFini) { - setVolume(FadeIn, 1.0); + setVolume(FadeIn, 1.0f); unlockStream(); break; diff --git a/src/bitmap.cpp b/src/bitmap.cpp index 37b1af1..24fb70f 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -890,9 +890,9 @@ static void applyShadow(SDL_Surface *&in, const SDL_PixelFormat &fm, const SDL_C SDL_Surface *out = SDL_CreateRGBSurface (0, in->w+1, in->h+1, fm.BitsPerPixel, fm.Rmask, fm.Gmask, fm.Bmask, fm.Amask); - float fr = c.r / 255.0; - float fg = c.g / 255.0; - float fb = c.b / 255.0; + float fr = c.r / 255.0f; + float fg = c.g / 255.0f; + float fb = c.b / 255.0f; /* We allocate an output surface one pixel wider and higher than the input, * (implicitly) blit a copy of the input with RGB values set to black into @@ -946,11 +946,11 @@ static void applyShadow(SDL_Surface *&in, const SDL_PixelFormat &fm, const SDL_C continue; } - float fSrcA = srcA / 255.0; - float fShdA = shdA / 255.0; + float fSrcA = srcA / 255.0f; + float fShdA = shdA / 255.0f; /* Because opacity == 1, co1 == fSrcA */ - float co2 = fShdA * (1.0 - fSrcA); + float co2 = fShdA * (1.0f - fSrcA); /* Result alpha */ float fa = fSrcA + co2; /* Temp value to simplify arithmetic below */ @@ -959,10 +959,10 @@ static void applyShadow(SDL_Surface *&in, const SDL_PixelFormat &fm, const SDL_C /* Result colors */ uint8_t r, g, b, a; - r = clamp(fr * co3, 0, 1) * 255; - g = clamp(fg * co3, 0, 1) * 255; - b = clamp(fb * co3, 0, 1) * 255; - a = clamp(fa, 0, 1) * 255; + r = clamp(fr * co3, 0, 1) * 255.0f; + g = clamp(fg * co3, 0, 1) * 255.0f; + b = clamp(fb * co3, 0, 1) * 255.0f; + a = clamp(fa, 0, 1) * 255.0f; *outP = SDL_MapRGBA(&fm, r, g, b, a); } @@ -1067,11 +1067,11 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align) Vec2i gpTexSize; shState->ensureTexSize(txtSurf->w, txtSurf->h, gpTexSize); - bool fastBlit = !p->touchesTaintedArea(posRect) && txtAlpha == 1.0; + bool fastBlit = !p->touchesTaintedArea(posRect) && txtAlpha == 1.0f; if (fastBlit) { - if (squeeze == 1.0 && !shState->config().subImageFix) + if (squeeze == 1.0f && !shState->config().subImageFix) { /* Even faster: upload directly to bitmap texture. * We have to make sure the posRect lies within the texture diff --git a/src/etc-internal.h b/src/etc-internal.h index 6c66239..6b010b3 100644 --- a/src/etc-internal.h +++ b/src/etc-internal.h @@ -63,7 +63,7 @@ struct Vec4 bool xyzNotNull() const { - return (x != 0.0 || y != 0.0 || z != 0.0); + return (x != 0.0f || y != 0.0f || z != 0.0f); } }; @@ -269,13 +269,13 @@ struct NormValue NormValue(int unNorm) : unNorm(unNorm), - norm(unNorm / 255.0) + norm(unNorm / 255.0f) {} void operator =(int value) { unNorm = clamp(value, 0, 255); - norm = unNorm / 255.0; + norm = unNorm / 255.0f; } bool operator ==(int value) const diff --git a/src/font.cpp b/src/font.cpp index 058dd21..560010c 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -174,7 +174,7 @@ _TTF_Font *SharedFontState::getFont(std::string family, // FIXME 0.9 is guesswork at this point // float gamma = (96.0/45.0)*(5.0/14.0)*(size-5); // font = TTF_OpenFontRW(ops, 1, gamma /** .90*/); - font = TTF_OpenFontRW(ops, 1, size* .90); + font = TTF_OpenFontRW(ops, 1, size* 0.90f); if (!font) throw Exception(Exception::SDLError, "%s", SDL_GetError()); diff --git a/src/graphics.cpp b/src/graphics.cpp index 74e97a3..956c4d9 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -281,9 +281,9 @@ public: void setBrightness(float norm) { - brightnessQuad.setColor(Vec4(0, 0, 0, 1.0 - norm)); + brightnessQuad.setColor(Vec4(0, 0, 0, 1.0f - norm)); - brightEffect = norm < 1.0; + brightEffect = norm < 1.0f; } void updateReso(int width, int height) @@ -736,7 +736,7 @@ void Graphics::transition(int duration, shader.setFrozenScene(p->frozenScene.tex); shader.setCurrentScene(p->currentScene.tex); shader.setTransMap(transMap->getGLTypes().tex); - shader.setVague(vague / 256.0); + shader.setVague(vague / 256.0f); shader.setTexSize(p->scRes); } else @@ -774,7 +774,7 @@ void Graphics::transition(int duration, p->checkSyncLock(); - const float prog = i * (1.0 / duration); + const float prog = i * (1.0f / duration); if (transMap) { @@ -852,7 +852,7 @@ void Graphics::fadeout(int duration) FBO::unbind(); float curr = p->brightness; - float diff = 255.0 - curr; + float diff = 255.0f - curr; for (int i = duration-1; i > -1; --i) { @@ -882,7 +882,7 @@ void Graphics::fadein(int duration) FBO::unbind(); float curr = p->brightness; - float diff = 255.0 - curr; + float diff = 255.0f - curr; for (int i = 1; i <= duration; ++i) { diff --git a/src/midisource.cpp b/src/midisource.cpp index 9cd3a44..3d569a7 100644 --- a/src/midisource.cpp +++ b/src/midisource.cpp @@ -320,7 +320,7 @@ readEvent(MidiReadHandler *handler, MemChunk &chunk, | (data[2] << 0x00); e.type = Tempo; - e.e.tempo.bpm = 60000000.0 / mpqn; + e.e.tempo.bpm = 60000000 / mpqn; } else if (metaType == 0x2F) { @@ -699,7 +699,7 @@ struct MidiSource : ALDataSource, MidiReadHandler void updatePlaybackSpeed(uint32_t bpm) { - float deltaLength = 60.0 / (dpb * bpm); + float deltaLength = 60.0f / (dpb * bpm); playbackSpeed = TICK_FRAMES / (deltaLength * freq); } @@ -910,7 +910,7 @@ struct MidiSource : ALDataSource, MidiReadHandler bool setPitch(float value) { // not completely correct, but close - pitchShift = round((value > 1.0 ? 14 : 24) * (value - 1.0)); + pitchShift = round((value > 1.0f ? 14 : 24) * (value - 1.0f)); return true; } diff --git a/src/plane.cpp b/src/plane.cpp index f275e85..e3de3a0 100644 --- a/src/plane.cpp +++ b/src/plane.cpp @@ -105,8 +105,8 @@ struct PlanePrivate return; /* Scaled (zoomed) bitmap dimensions */ - double sw = bitmap->width() * zoomX; - double sh = bitmap->height() * zoomY; + float sw = bitmap->width() * zoomX; + float sh = bitmap->height() * zoomY; /* Plane offset wrapped by scaled bitmap dims */ float wox = fwrap(ox, sw); diff --git a/src/settingsmenu.cpp b/src/settingsmenu.cpp index a14b488..6518d7f 100644 --- a/src/settingsmenu.cpp +++ b/src/settingsmenu.cpp @@ -764,13 +764,13 @@ void Widget::click(int x, int y, uint8_t button) } /* Ratio of cell area to total widget width */ -#define BW_CELL_R 0.75 +#define BW_CELL_R 0.75f void BindingWidget::drawHandler(SDL_Surface *surf) { const int cellW = (rect.w*BW_CELL_R) / 2; const int cellH = rect.h / 2; - const int cellOffX = (1.0-BW_CELL_R) * rect.w; + const int cellOffX = (1.0f-BW_CELL_R) * rect.w; const int cellOff[] = { @@ -860,7 +860,7 @@ int BindingWidget::cellIndex(int x, int y) const { const int cellW = (rect.w*BW_CELL_R) / 2; const int cellH = rect.h / 2; - const int cellOff = (1.0-BW_CELL_R) * rect.w; + const int cellOff = (1.0f-BW_CELL_R) * rect.w; if (x < cellOff) return -1; diff --git a/src/sharedmidistate.h b/src/sharedmidistate.h index 00de6dc..1692848 100644 --- a/src/sharedmidistate.h +++ b/src/sharedmidistate.h @@ -80,7 +80,7 @@ struct SharedMidiState return; flSettings = fluid.new_settings(); - fluid.settings_setnum(flSettings, "synth.gain", 1.0); + fluid.settings_setnum(flSettings, "synth.gain", 1.0f); fluid.settings_setnum(flSettings, "synth.sample-rate", SYNTH_SAMPLERATE); fluid.settings_setstr(flSettings, "synth.chorus.active", conf.midi.chorus ? "yes" : "no"); fluid.settings_setstr(flSettings, "synth.reverb.active", conf.midi.reverb ? "yes" : "no"); diff --git a/src/soundemitter.cpp b/src/soundemitter.cpp index b064fd1..74eaf03 100644 --- a/src/soundemitter.cpp +++ b/src/soundemitter.cpp @@ -123,8 +123,8 @@ void SoundEmitter::play(const std::string &filename, int volume, int pitch) { - float _volume = clamp(volume, 0, 100) / 100.f; - float _pitch = clamp(pitch, 50, 150) / 100.f; + float _volume = clamp(volume, 0, 100) / 100.0f; + float _pitch = clamp(pitch, 50, 150) / 100.0f; SoundBuffer *buffer = allocateBuffer(filename); diff --git a/src/sprite.cpp b/src/sprite.cpp index 0313444..760bb0b 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -109,7 +109,7 @@ struct SpritePrivate wave.amp = 0; wave.length = 180; wave.speed = 360; - wave.phase = 0.0; + wave.phase = 0.0f; wave.dirty = false; } @@ -129,7 +129,7 @@ struct SpritePrivate (srcRect->y + srcRect->height) + bitmap->height(); - efBushDepth = 1.0 - texBushDepth / bitmap->height(); + efBushDepth = 1.0f - texBushDepth / bitmap->height(); } void onSrcRectChange() @@ -194,7 +194,7 @@ struct SpritePrivate void emitWaveChunk(SVertex *&vert, float phase, int width, float zoomY, int chunkY, int chunkLength) { - float wavePos = phase + (chunkY / (float) wave.length) * M_PI * 2; + float wavePos = phase + (chunkY / (float) wave.length) * (float) (M_PI * 2); float chunkX = sin(wavePos) * wave.amp; FloatRect tex(0, chunkY / zoomY, width, chunkLength / zoomY); @@ -261,7 +261,7 @@ struct SpritePrivate wave.qArray.resize(!!firstLength + chunks + !!lastLength); SVertex *vert = &wave.qArray.vertices[0]; - float phase = (wave.phase * M_PI) / 180.f; + float phase = (wave.phase * (float) M_PI) / 180.0f; if (firstLength > 0) emitWaveChunk(vert, phase, width, zoomY, 0, firstLength); diff --git a/src/tileatlasvx.cpp b/src/tileatlasvx.cpp index 8f3ec47..2e1c176 100644 --- a/src/tileatlasvx.cpp +++ b/src/tileatlasvx.cpp @@ -51,14 +51,14 @@ extern const int autotileVXRectsBN; /* Waterfall (C) autotile patterns */ static const StaticRect autotileVXRectsC[] = { - { 32.5, 0.5, 15, 31 }, - { 16.5, 0.5, 15, 31 }, - { 0.0, 0.5, 15, 31 }, - { 16.5, 0.5, 15, 31 }, - { 32.5, 0.5, 15, 31 }, - { 48.5, 0.5, 15, 31 }, - { 0.0, 0.5, 15, 31 }, - { 48.5, 0.5, 15, 31 } + { 32.5f, 0.5f, 15.0f, 31.0f }, + { 16.5f, 0.5f, 15.0f, 31.0f }, + { 0.0f, 0.5f, 15.0f, 31.0f }, + { 16.5f, 0.5f, 15.0f, 31.0f }, + { 32.5f, 0.5f, 15.0f, 31.0f }, + { 48.5f, 0.5f, 15.0f, 31.0f }, + { 0.0f, 0.5f, 15.0f, 31.0f }, + { 48.5f, 0.5f, 15.0f, 31.0f } }; static elementsN(autotileVXRectsC); diff --git a/src/tilemap.cpp b/src/tilemap.cpp index d3cf437..f721e03 100644 --- a/src/tilemap.cpp +++ b/src/tilemap.cpp @@ -698,7 +698,7 @@ struct TilemapPrivate int tileY = tsInd / 8; Vec2i texPos = TileAtlas::tileToAtlasCoor(tileX, tileY, atlas.efTilesetH, atlas.size.y); - FloatRect texRect((float) texPos.x+.5, (float) texPos.y+.5, 31, 31); + FloatRect texRect((float) texPos.x+0.5f, (float) texPos.y+0.5f, 31, 31); FloatRect posRect(x*32, y*32, 32, 32); SVertex v[4]; diff --git a/src/transform.h b/src/transform.h index cefd09f..7a129f9 100644 --- a/src/transform.h +++ b/src/transform.h @@ -130,7 +130,7 @@ private: if (rotation < 0) rotation += 360; - float angle = rotation * 3.141592654f / 180.f; + float angle = rotation * 3.141592654f / 180.0f; float cosine = (float) cos(angle); float sine = (float) sin(angle); float sxc = scale.x * cosine; diff --git a/src/window.cpp b/src/window.cpp index a32481d..71a8cc9 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -642,7 +642,7 @@ struct WindowPrivate if (active && cursorVert.vert) { - float alpha = cursorAniAlpha[cursorAniAlphaIdx] / 255.0; + float alpha = cursorAniAlpha[cursorAniAlphaIdx] / 255.0f; cursorVert.setAlpha(alpha); @@ -651,7 +651,7 @@ struct WindowPrivate if (pause && pauseAniVert.vert) { - float alpha = pauseAniAlpha[pauseAniAlphaIdx] / 255.0; + float alpha = pauseAniAlpha[pauseAniAlphaIdx] / 255.0f; FloatRect frameRect = pauseAniSrc[pauseAniQuad[pauseAniQuadIdx]]; pauseAniVert.setAlpha(alpha); diff --git a/src/windowvx.cpp b/src/windowvx.cpp index 0bafb5b..02a70d9 100644 --- a/src/windowvx.cpp +++ b/src/windowvx.cpp @@ -482,7 +482,7 @@ struct WindowVXPrivate void updateBaseQuad() { const FloatRect tex(0, 0, geo.w, geo.h); - const FloatRect pos(0, (geo.h / 2.0) * (1 - openness.norm), + const FloatRect pos(0, (geo.h / 2.0f) * (1.0f - openness.norm), geo.w, geo.h * openness.norm); base.quad.setTexPosRect(tex, pos); @@ -633,7 +633,7 @@ struct WindowVXPrivate Quad::setTexRect(pauseVert, pauseSrc[pauseQuad[pauseQuadIdx]]); /* Set opacity */ - Quad::setColor(pauseVert, Vec4(1, 1, 1, pauseAlpha[pauseAlphaIdx] / 255.0)); + Quad::setColor(pauseVert, Vec4(1, 1, 1, pauseAlpha[pauseAlphaIdx] / 255.0f)); ctrlVertArrayDirty = true; } @@ -643,7 +643,7 @@ struct WindowVXPrivate if (cursorVert.count() == 0) return; - Vec4 color(1, 1, 1, cursorAlpha[cursorAlphaIdx] / 255.0); + Vec4 color(1, 1, 1, cursorAlpha[cursorAlphaIdx] / 255.0f); for (size_t i = 0; i < cursorVert.count(); ++i) Quad::setColor(&cursorVert.vertices[i*4], color); From 9a3dd2d554df7255b592bba00d5cfea065af475b Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 16 Jul 2015 18:41:48 +0200 Subject: [PATCH 13/23] Config: Enable smoothScaling by default There's really no reason not to. --- mkxp.conf.sample | 4 ++-- src/config.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mkxp.conf.sample b/mkxp.conf.sample index e128755..b88f216 100644 --- a/mkxp.conf.sample +++ b/mkxp.conf.sample @@ -57,9 +57,9 @@ # Apply linear interpolation when game screen # is upscaled -# (default: disabled) +# (default: enabled) # -# smoothScaling=false +# smoothScaling=true # Sync screen redraws to the monitor refresh rate diff --git a/src/config.cpp b/src/config.cpp index cbbbe99..9173acc 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -151,7 +151,7 @@ void Config::read(int argc, char *argv[]) PO_DESC(winResizable, bool, false) \ PO_DESC(fullscreen, bool, false) \ PO_DESC(fixedAspectRatio, bool, true) \ - PO_DESC(smoothScaling, bool, false) \ + PO_DESC(smoothScaling, bool, true) \ PO_DESC(vsync, bool, false) \ PO_DESC(defScreenW, int, 0) \ PO_DESC(defScreenH, int, 0) \ From 5aaeb0206ce512e0415afc23b6754285ce5726af Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Thu, 16 Jul 2015 18:44:03 +0200 Subject: [PATCH 14/23] Remove some stuff that was accidentally committed --- src/config.h | 43 ------------------------------------------- 1 file changed, 43 deletions(-) diff --git a/src/config.h b/src/config.h index eeaf46b..fc9bbda 100644 --- a/src/config.h +++ b/src/config.h @@ -25,49 +25,6 @@ #include #include -struct TouchOverlay -{ - std::string image; - - struct Button - { - enum Shape - { - Rectangle, - Circle, - Triangle - }; - - std::string id; - std::string target; - Shape shape; - - int x; - int y; - - union - { - struct - { - int width; - int height; - } r; - - struct - { - int radius; - } c; - struct - { - int x1, y1; - int x2, y2; - } t; - } u; - }; - - std::vector