From 7b704b71f9d6d4e47c9fbbba7e4390d89f008be3 Mon Sep 17 00:00:00 2001 From: Matthew Lyons Date: Mon, 15 Aug 2022 08:22:14 -0700 Subject: [PATCH 01/14] Force compiler optimizations --- binding-mri/binding-util.cpp | 470 +++++++++++++++++------------------ linux/Makefile | 2 +- windows/Makefile | 2 +- 3 files changed, 236 insertions(+), 238 deletions(-) diff --git a/binding-mri/binding-util.cpp b/binding-mri/binding-util.cpp index 2936c9b4..30d6962c 100644 --- a/binding-mri/binding-util.cpp +++ b/binding-mri/binding-util.cpp @@ -31,7 +31,7 @@ RbData *getRbData() { - return static_cast(shState->bindingData()); + return static_cast(shState->bindingData()); } struct @@ -39,18 +39,17 @@ struct RbException id; const char *name; } static customExc[] = -{ - { MKXP, "MKXPError" }, - { PHYSFS, "PHYSFSError" }, - { SDL, "SDLError" } -}; + { + {MKXP, "MKXPError"}, + {PHYSFS, "PHYSFSError"}, + {SDL, "SDLError"}}; RbData::RbData() { for (size_t i = 0; i < ARRAY_SIZE(customExc); ++i) exc[customExc[i].id] = rb_define_class(customExc[i].name, rb_eException); - exc[RGSS] = rb_define_class("RGSSError", rb_eStandardError); + exc[RGSS] = rb_define_class("RGSSError", rb_eStandardError); exc[Reset] = rb_define_class(rgssVer >= 3 ? "RGSSReset" : "Reset", rb_eException); exc[ErrnoENOENT] = rb_const_get(rb_const_get(rb_cObject, rb_intern("Errno")), rb_intern("ENOENT")); @@ -61,22 +60,21 @@ RbData::RbData() RbData::~RbData() { - } /* Indexed with Exception::Type */ static const RbException excToRbExc[] = -{ - RGSS, /* RGSSError */ - ErrnoENOENT, /* NoFileError */ - IOError, + { + RGSS, /* RGSSError */ + ErrnoENOENT, /* NoFileError */ + IOError, - TypeError, - ArgumentError, + TypeError, + ArgumentError, - PHYSFS, /* PHYSFSError */ - SDL, /* SDLError */ - MKXP /* MKXPError */ + PHYSFS, /* PHYSFSError */ + SDL, /* SDLError */ + MKXP /* MKXPError */ }; void raiseRbExc(const Exception &exc) @@ -87,8 +85,7 @@ void raiseRbExc(const Exception &exc) rb_raise(excClass, "%s", exc.msg.c_str()); } -void -raiseDisposedAccess(VALUE self) +void raiseDisposedAccess(VALUE self) { const char *klassName = RTYPEDDATA_TYPE(self)->wrap_struct_name; char buf[32]; @@ -99,6 +96,7 @@ raiseDisposedAccess(VALUE self) rb_raise(getRbData()->exc[RGSS], "disposed %s", buf); } +/* int rb_get_args(int argc, VALUE *argv, const char *format, ...) { int arg_count = 0; int opt_count = 0; @@ -198,221 +196,221 @@ int rb_get_args(int argc, VALUE *argv, const char *format, ...) { return arg_count; } +*/ + +int rb_get_args(int argc, VALUE *argv, const char *format, ...) +{ + char c; + VALUE *arg = argv; + va_list ap; + bool opt = false; + int argI = 0; + + va_start(ap, format); + + while ((c = *format++)) + { + switch (c) + { + case '|': + break; + default: + // FIXME print num of needed args vs provided + if (argc <= argI && !opt) + rb_raise(rb_eArgError, "wrong number of arguments"); + + break; + } + + if (argI >= argc) + break; + + switch (c) + { + case 'o': + { + if (argI >= argc) + break; + + VALUE *obj = va_arg(ap, VALUE *); + + *obj = *arg++; + ++argI; + + break; + } + + case 'S': + { + if (argI >= argc) + break; + + VALUE *str = va_arg(ap, VALUE *); + VALUE tmp = *arg; + + tmp = rb_str_to_str(tmp); + + *str = tmp; + ++argI; + + break; + } + + case 's': + { + if (argI >= argc) + break; + + const char **s = va_arg(ap, const char **); + int *len = va_arg(ap, int *); + + VALUE tmp = *arg; + + tmp = rb_str_to_str(tmp); + + *s = RSTRING_PTR(tmp); + *len = RSTRING_LEN(tmp); + ++argI; + + break; + } + + case 'z': + { + if (argI >= argc) + break; + + const char **s = va_arg(ap, const char **); + + VALUE tmp = *arg++; + + tmp = rb_str_to_str(tmp); + + *s = RSTRING_PTR(tmp); + ++argI; + + break; + } + + case 'f': + { + if (argI >= argc) + break; + + double *f = va_arg(ap, double *); + VALUE fVal = *arg++; -//int -//rb_get_args(int argc, VALUE *argv, const char *format, ...) -//{ -// char c; -// VALUE *arg = argv; -// va_list ap; -// bool opt = false; -// int argI = 0; -// -// va_start(ap, format); -// -// while ((c = *format++)) -// { -// switch (c) -// { -// case '|' : -// break; -// default: -// // FIXME print num of needed args vs provided -// if (argc <= argI && !opt) -// rb_raise(rb_eArgError, "wrong number of arguments"); -// -// break; -// } -// -// if (argI >= argc) -// break; -// -// switch (c) -// { -// case 'o' : -// { -// if (argI >= argc) -// break; -// -// VALUE *obj = va_arg(ap, VALUE*); -// -// *obj = *arg++; -// ++argI; -// -// break; -// } -// -// case 'S' : -// { -// if (argI >= argc) -// break; -// -// VALUE *str = va_arg(ap, VALUE*); -// VALUE tmp = *arg; -// -// tmp = rb_str_to_str(tmp); -// -// *str = tmp; -// ++argI; -// -// break; -// } -// -// case 's' : -// { -// if (argI >= argc) -// break; -// -// const char **s = va_arg(ap, const char**); -// int *len = va_arg(ap, int*); -// -// VALUE tmp = *arg; -// -// tmp = rb_str_to_str(tmp); -// -// *s = RSTRING_PTR(tmp); -// *len = RSTRING_LEN(tmp); -// ++argI; -// -// break; -// } -// -// case 'z' : -// { -// if (argI >= argc) -// break; -// -// const char **s = va_arg(ap, const char**); -// -// VALUE tmp = *arg++; -// -// tmp = rb_str_to_str(tmp); -// -// *s = RSTRING_PTR(tmp); -// ++argI; -// -// break; -// } -// -// case 'f' : -// { -// if (argI >= argc) -// break; -// -// double *f = va_arg(ap, double*); -// VALUE fVal = *arg++; -// -// rb_float_arg(fVal, f, argI); -// -// ++argI; -// break; -// } -// -// case 'i' : -// { -// if (argI >= argc) -// break; -// -// int *i = va_arg(ap, int*); -// VALUE iVal = *arg++; -// -// rb_int_arg(iVal, i, argI); -// -// ++argI; -// break; -// } -// -// case 'b' : -// { -// if (argI >= argc) -// break; -// -// bool *b = va_arg(ap, bool*); -// VALUE bVal = *arg++; -// -// rb_bool_arg(bVal, b, argI); -// -// ++argI; -// break; -// } -// -// case 'n' : -// { -// if (argI >= argc) -// break; -// -// ID *sym = va_arg(ap, ID*); -// -// VALUE symVal = *arg++; -// -// if (!SYMBOL_P(symVal)) -// rb_raise(rb_eTypeError, "Argument %d: Expected symbol", argI); -// -// *sym = SYM2ID(symVal); -// ++argI; -// -// break; -// } -// -// case '|' : -// opt = true; -// break; -// -// default: -// rb_raise(rb_eFatal, "invalid argument specifier %c", c); -// } -// } -// -//#ifndef NDEBUG -// -// /* Pop remaining arg pointers off -// * the stack to check for RB_ARG_END */ -// format--; -// -// while ((c = *format++)) -// { -// switch (c) -// { -// case 'o' : -// case 'S' : -// va_arg(ap, VALUE*); -// break; -// -// case 's' : -// va_arg(ap, const char**); -// va_arg(ap, int*); -// break; -// -// case 'z' : -// va_arg(ap, const char**); -// break; -// -// case 'f' : -// va_arg(ap, double*); -// break; -// -// case 'i' : -// va_arg(ap, int*); -// break; -// -// case 'b' : -// va_arg(ap, bool*); -// break; -// } -// } -// -// // FIXME print num of needed args vs provided -// if (!c && argc > argI) -// rb_raise(rb_eArgError, "wrong number of arguments"); -// -// /* Verify correct termination */ -// void *argEnd = va_arg(ap, void*); -// (void) argEnd; -// assert(argEnd == RB_ARG_END_VAL); -// -//#endif -// -// va_end(ap); -// -// return argI; -//} + rb_float_arg(fVal, f, argI); + + ++argI; + break; + } + + case 'i': + { + if (argI >= argc) + break; + + int *i = va_arg(ap, int *); + VALUE iVal = *arg++; + + rb_int_arg(iVal, i, argI); + + ++argI; + break; + } + + case 'b': + { + if (argI >= argc) + break; + + bool *b = va_arg(ap, bool *); + VALUE bVal = *arg++; + + rb_bool_arg(bVal, b, argI); + + ++argI; + break; + } + + case 'n': + { + if (argI >= argc) + break; + + ID *sym = va_arg(ap, ID *); + + VALUE symVal = *arg++; + + if (!SYMBOL_P(symVal)) + rb_raise(rb_eTypeError, "Argument %d: Expected symbol", argI); + + *sym = SYM2ID(symVal); + ++argI; + + break; + } + + case '|': + opt = true; + break; + + default: + rb_raise(rb_eFatal, "invalid argument specifier %c", c); + } + } + +#ifndef NDEBUG + + /* Pop remaining arg pointers off + * the stack to check for RB_ARG_END */ + format--; + + while ((c = *format++)) + { + switch (c) + { + case 'o': + case 'S': + va_arg(ap, VALUE *); + break; + + case 's': + va_arg(ap, const char **); + va_arg(ap, int *); + break; + + case 'z': + va_arg(ap, const char **); + break; + + case 'f': + va_arg(ap, double *); + break; + + case 'i': + va_arg(ap, int *); + break; + + case 'b': + va_arg(ap, bool *); + break; + } + } + + // FIXME print num of needed args vs provided + if (!c && argc > argI) + rb_raise(rb_eArgError, "wrong number of arguments"); + + /* Verify correct termination */ + void *argEnd = va_arg(ap, void *); + (void)argEnd; + assert(argEnd == RB_ARG_END_VAL); + +#endif + + va_end(ap); + + return argI; +} diff --git a/linux/Makefile b/linux/Makefile index bb203768..319b343d 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -9,7 +9,7 @@ LIBDIR := $(BUILD_PREFIX)/lib INCLUDEDIR := $(BUILD_PREFIX)/include DOWNLOADS := ${PWD}/downloads/$(ARCH) NPROC := $(shell nproc) -CFLAGS := -I$(INCLUDEDIR) -flax-vector-conversions +CFLAGS := -I$(INCLUDEDIR) -flax-vector-conversions -O3 LDFLAGS := -L$(LIBDIR) CC := gcc PKG_CONFIG_LIBDIR := $(BUILD_PREFIX)/lib/pkgconfig diff --git a/windows/Makefile b/windows/Makefile index ecd5b719..9c63b09f 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -21,7 +21,7 @@ LIBDIR := $(BUILD_PREFIX)/lib INCLUDEDIR := $(BUILD_PREFIX)/include DOWNLOADS := ${PWD}/downloads/$(ARCH) NPROC := $(shell nproc) -CFLAGS := -I$(INCLUDEDIR) +CFLAGS := -I$(INCLUDEDIR) -O3 LDFLAGS := -L$(LIBDIR) CC := gcc PKG_CONFIG_LIBDIR := $(BUILD_PREFIX)/lib/pkgconfig From 0f8e81671f765f6ccbd0923834becd7902339f8a Mon Sep 17 00:00:00 2001 From: Matthew Lyons Date: Mon, 15 Aug 2022 11:12:04 -0700 Subject: [PATCH 02/14] Ditch some boost stuff --- src/filesystem/headers/rgssad.h | 31 -- src/filesystem/source/filesystem.cpp | 5 - src/filesystem/source/rgssad.cpp | 641 --------------------------- src/meson.build | 1 - src/util/headers/boost-hash.h | 29 +- 5 files changed, 15 insertions(+), 692 deletions(-) delete mode 100644 src/filesystem/headers/rgssad.h delete mode 100644 src/filesystem/source/rgssad.cpp diff --git a/src/filesystem/headers/rgssad.h b/src/filesystem/headers/rgssad.h deleted file mode 100644 index 96f9695b..00000000 --- a/src/filesystem/headers/rgssad.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -** rgssad.h -** -** This file is part of mkxp. -** -** Copyright (C) 2014 Jonas Kulla -** -** mkxp is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** mkxp is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with mkxp. If not, see . -*/ - -#ifndef RGSSAD_H -#define RGSSAD_H - -#include - -extern const PHYSFS_Archiver RGSS1_Archiver; -extern const PHYSFS_Archiver RGSS2_Archiver; -extern const PHYSFS_Archiver RGSS3_Archiver; - -#endif // RGSSAD_H diff --git a/src/filesystem/source/filesystem.cpp b/src/filesystem/source/filesystem.cpp index 87dc3908..99b86e5d 100644 --- a/src/filesystem/source/filesystem.cpp +++ b/src/filesystem/source/filesystem.cpp @@ -21,7 +21,6 @@ #include "filesystem.h" -#include "rgssad.h" #include "font.h" #include "util.h" #include "exception.h" @@ -319,10 +318,6 @@ FileSystem::FileSystem(bool allowSymlinks) p = new FileSystemPrivate; p->havePathCache = false; - PHYSFS_registerArchiver(&RGSS1_Archiver); - PHYSFS_registerArchiver(&RGSS2_Archiver); - PHYSFS_registerArchiver(&RGSS3_Archiver); - if (allowSymlinks) PHYSFS_permitSymbolicLinks(1); } diff --git a/src/filesystem/source/rgssad.cpp b/src/filesystem/source/rgssad.cpp deleted file mode 100644 index ac8772a1..00000000 --- a/src/filesystem/source/rgssad.cpp +++ /dev/null @@ -1,641 +0,0 @@ -/* -** rgssad.cpp -** -** This file is part of mkxp. -** -** Copyright (C) 2014 Jonas Kulla -** -** mkxp is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** mkxp is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with mkxp. If not, see . -*/ - -#include "rgssad.h" -#include "boost-hash.h" - -#include -#include - -struct RGSS_entryData -{ - int64_t offset; - uint64_t size; - uint32_t startMagic; -}; - -struct RGSS_entryHandle -{ - const RGSS_entryData data; - uint32_t currentMagic; - uint64_t currentOffset; - PHYSFS_Io *io; - - RGSS_entryHandle(const RGSS_entryData &data, PHYSFS_Io *archIo) - : data(data), - currentMagic(data.startMagic), - currentOffset(0) - { - io = archIo->duplicate(archIo); - } - - ~RGSS_entryHandle() - { - io->destroy(io); - } -}; - -struct RGSS_archiveData -{ - PHYSFS_Io *archiveIo; - - /* Maps: file path - * to: entry data */ - BoostHash entryHash; - - /* Maps: directory path, - * to: list of contained entries */ - BoostHash > dirHash; -}; - -static bool -readUint32(PHYSFS_Io *io, uint32_t &result) -{ - char buff[4]; - PHYSFS_sint64 count = io->read(io, buff, 4); - - result = ((buff[0] << 0x00) & 0x000000FF) | - ((buff[1] << 0x08) & 0x0000FF00) | - ((buff[2] << 0x10) & 0x00FF0000) | - ((buff[3] << 0x18) & 0xFF000000) ; - - return (count == 4); -} - -#define RGSS_HEADER "RGSSAD" -#define RGSS_MAGIC 0xDEADCAFE - -#define PHYSFS_ALLOC(type) \ - static_cast(PHYSFS_getAllocator()->Malloc(sizeof(type))) - -#define IO_READ(io, dest, size) (io->read(io, dest, size) == size) - -static inline uint32_t -advanceMagic(uint32_t &magic) -{ - uint32_t old = magic; - - magic = magic * 7 + 3; - - return old; -} - -static PHYSFS_sint64 -RGSS_ioRead(PHYSFS_Io *self, void *buffer, PHYSFS_uint64 len) -{ - RGSS_entryHandle *entry = static_cast(self->opaque); - - PHYSFS_Io *io = entry->io; - - uint64_t toRead = std::min(entry->data.size - entry->currentOffset, len); - uint64_t offs = entry->currentOffset; - - io->seek(io, entry->data.offset + offs); - - /* We divide up the bytes to be read in 3 categories: - * - * preAlign: If the current read address is not dword - * aligned, this is the number of bytes to read til - * we reach alignment again (therefore can only be - * 3 or less). - * - * align: The number of aligned dwords we can read - * times 4 (= number of bytes). - * - * postAlign: The number of bytes to read after the - * last aligned dword. Always 3 or less. - * - * Treating the pre- and post aligned reads specially, - * we can read all aligned dwords in one syscall directly - * into the write buffer and then run the xor chain on - * it afterwards. */ - - uint8_t preAlign = 4 - (offs % 4); - - if (preAlign == 4) - preAlign = 0; - else - preAlign = std::min(preAlign, len); - - uint8_t postAlign = (len > preAlign) ? (offs + len) % 4 : 0; - - uint64_t align = len - (preAlign + postAlign); - - /* Byte buffer pointer */ - uint8_t *bBufferP = static_cast(buffer); - - if (preAlign > 0) - { - uint32_t dword; - io->read(io, &dword, preAlign); - - /* Need to align the bytes with the - * magic before xoring */ - dword <<= 8 * (offs % 4); - dword ^= entry->currentMagic; - - /* Shift them back to normal */ - dword >>= 8 * (offs % 4); - memcpy(bBufferP, &dword, preAlign); - - bBufferP += preAlign; - - /* Only advance the magic if we actually - * reached the next alignment */ - if ((offs+preAlign) % 4 == 0) - advanceMagic(entry->currentMagic); - } - - if (align > 0) - { - /* Double word buffer pointer */ - uint32_t *dwBufferP = reinterpret_cast(bBufferP); - - /* Read aligned dwords in one go */ - io->read(io, bBufferP, align); - - /* Then xor them */ - for (uint64_t i = 0; i < (align / 4); ++i) - dwBufferP[i] ^= advanceMagic(entry->currentMagic); - - bBufferP += align; - } - - if (postAlign > 0) - { - uint32_t dword; - io->read(io, &dword, postAlign); - - /* Bytes are already aligned with magic */ - dword ^= entry->currentMagic; - memcpy(bBufferP, &dword, postAlign); - } - - entry->currentOffset += toRead; - - return toRead; -} - -static int -RGSS_ioSeek(PHYSFS_Io *self, PHYSFS_uint64 offset) -{ - RGSS_entryHandle *entry = static_cast(self->opaque); - - if (offset == entry->currentOffset) - return 1; - - if (offset > entry->data.size-1) - return 0; - - /* If rewinding, we need to rewind to begining */ - if (offset < entry->currentOffset) - { - entry->currentOffset = 0; - entry->currentMagic = entry->data.startMagic; - } - - /* For each overstepped alignment, advance magic */ - uint64_t currentDword = entry->currentOffset / 4; - uint64_t targetDword = offset / 4; - uint64_t dwordsSought = targetDword - currentDword; - - for (uint64_t i = 0; i < dwordsSought; ++i) - advanceMagic(entry->currentMagic); - - entry->currentOffset = offset; - entry->io->seek(entry->io, entry->data.offset + entry->currentOffset); - - return 1; -} - -static PHYSFS_sint64 -RGSS_ioTell(PHYSFS_Io *self) -{ - const RGSS_entryHandle *entry = static_cast(self->opaque); - - return entry->currentOffset; -} - -static PHYSFS_sint64 -RGSS_ioLength(PHYSFS_Io *self) -{ - const RGSS_entryHandle *entry = static_cast(self->opaque); - - return entry->data.size; -} - -static PHYSFS_Io* -RGSS_ioDuplicate(PHYSFS_Io *self) -{ - const RGSS_entryHandle *entry = static_cast(self->opaque); - RGSS_entryHandle *entryDup = new RGSS_entryHandle(*entry); - - PHYSFS_Io *dup = PHYSFS_ALLOC(PHYSFS_Io); - *dup = *self; - dup->opaque = entryDup; - - return dup; -} - -static void -RGSS_ioDestroy(PHYSFS_Io *self) -{ - RGSS_entryHandle *entry = static_cast(self->opaque); - - delete entry; - - PHYSFS_getAllocator()->Free(self); -} - -static const PHYSFS_Io RGSS_IoTemplate = -{ - 0, /* version */ - 0, /* opaque */ - RGSS_ioRead, - 0, /* write */ - RGSS_ioSeek, - RGSS_ioTell, - RGSS_ioLength, - RGSS_ioDuplicate, - 0, /* flush */ - RGSS_ioDestroy -}; - -static void -processDirectories(RGSS_archiveData *data, BoostSet &topLevel, - char *nameBuf, uint32_t nameLen) -{ - /* Check for top level entries */ - for (uint32_t i = 0; i < nameLen; ++i) - { - bool slash = nameBuf[i] == '/'; - if (!slash && i+1 < nameLen) - continue; - - if (slash) - nameBuf[i] = '\0'; - - topLevel.insert(nameBuf); - - if (slash) - nameBuf[i] = '/'; - - break; - } - - /* Check for more entries */ - for (uint32_t i = nameLen; i > 0; i--) - if (nameBuf[i] == '/') - { - nameBuf[i] = '\0'; - - const char *dir = nameBuf; - const char *entry = &nameBuf[i+1]; - - BoostSet &entryList = data->dirHash[dir]; - entryList.insert(entry); - } -} - -static bool -verifyHeader(PHYSFS_Io *io, char version) -{ - char header[8]; - - if (!IO_READ(io, header, sizeof(header))) - return false; - - if (strcmp(header, RGSS_HEADER)) - return false; - - if (header[7] != version) - return false; - - return true; -} - -static void* -RGSS_openArchive(PHYSFS_Io *io, const char *, int forWrite, int *claimed) -{ - if (forWrite) - return NULL; - - /* Version 1 */ - if (!verifyHeader(io, 1)) - return NULL; - else - *claimed = 1; - - RGSS_archiveData *data = new RGSS_archiveData; - data->archiveIo = io; - - uint32_t magic = RGSS_MAGIC; - - /* Top level entry list */ - BoostSet &topLevel = data->dirHash[""]; - - while (true) - { - /* Read filename length, - * if nothing was read, no files remain */ - uint32_t nameLen; - - if (!readUint32(io, nameLen)) - break; - - nameLen ^= advanceMagic(magic); - - static char nameBuf[512]; - for (uint32_t i = 0; i < nameLen; ++i) - { - char c; - io->read(io, &c, 1); - nameBuf[i] = c ^ (advanceMagic(magic) & 0xFF); - if (nameBuf[i] == '\\') - nameBuf[i] = '/'; - } - - nameBuf[nameLen] = '\0'; - - uint32_t entrySize; - readUint32(io, entrySize); - entrySize ^= advanceMagic(magic); - - RGSS_entryData entry; - entry.offset = io->tell(io); - entry.size = entrySize; - entry.startMagic = magic; - - data->entryHash.insert(nameBuf, entry); - processDirectories(data, topLevel, nameBuf, nameLen); - - io->seek(io, entry.offset + entry.size); - } - - return data; -} - -static PHYSFS_EnumerateCallbackResult -RGSS_enumerateFiles(void *opaque, const char *dirname, - PHYSFS_EnumerateCallback cb, - const char *origdir, void *callbackdata) -{ - RGSS_archiveData *data = static_cast(opaque); - - std::string _dirname(dirname); - - if (!data->dirHash.contains(_dirname)) - return PHYSFS_ENUM_STOP; - - const BoostSet &entries = data->dirHash[_dirname]; - - BoostSet::const_iterator iter; - for (iter = entries.cbegin(); iter != entries.cend(); ++iter) - cb(callbackdata, origdir, iter->c_str()); - - return PHYSFS_ENUM_OK; -} - -static PHYSFS_Io* -RGSS_openRead(void *opaque, const char *filename) -{ - RGSS_archiveData *data = static_cast(opaque); - - if (!data->entryHash.contains(filename)) - return 0; - - RGSS_entryHandle *entry = - new RGSS_entryHandle(data->entryHash[filename], data->archiveIo); - - PHYSFS_Io *io = PHYSFS_ALLOC(PHYSFS_Io); - - *io = RGSS_IoTemplate; - io->opaque = entry; - - return io; -} - -static int -RGSS_stat(void *opaque, const char *filename, PHYSFS_Stat *stat) -{ - RGSS_archiveData *data = static_cast(opaque); - - bool hasFile = data->entryHash.contains(filename); - bool hasDir = data->dirHash.contains(filename); - - if (!hasFile && !hasDir) - { - PHYSFS_setErrorCode(PHYSFS_ERR_NOT_FOUND); - return 0; - } - - stat->modtime = - stat->createtime = - stat->accesstime = 0; - stat->readonly = 1; - - if (hasFile) - { - const RGSS_entryData &entry = data->entryHash[filename]; - - stat->filesize = entry.size; - stat->filetype = PHYSFS_FILETYPE_REGULAR; - } - else - { - stat->filesize = 0; - stat->filetype = PHYSFS_FILETYPE_DIRECTORY; - } - - return 1; -} - -static void -RGSS_closeArchive(void *opaque) -{ - RGSS_archiveData *data = static_cast(opaque); - - delete data; -} - -static PHYSFS_Io* -RGSS_noop1(void*, const char*) -{ - return 0; -} - -static int -RGSS_noop2(void*, const char*) -{ - return 0; -} - -const PHYSFS_Archiver RGSS1_Archiver = -{ - 0, - { - "RGSSAD", - "RGSS encrypted archive format", - "", /* Author */ - "", /* Website */ - 0 /* symlinks not supported */ - }, - RGSS_openArchive, - RGSS_enumerateFiles, - RGSS_openRead, - RGSS_noop1, /* openWrite */ - RGSS_noop1, /* openAppend */ - RGSS_noop2, /* remove */ - RGSS_noop2, /* mkdir */ - RGSS_stat, - RGSS_closeArchive -}; - -const PHYSFS_Archiver RGSS2_Archiver = -{ - 0, - { - "RGSS2A", - "RGSS2 encrypted archive format", - "", /* Author */ - "", /* Website */ - 0 /* symlinks not supported */ - }, - RGSS_openArchive, - RGSS_enumerateFiles, - RGSS_openRead, - RGSS_noop1, /* openWrite */ - RGSS_noop1, /* openAppend */ - RGSS_noop2, /* remove */ - RGSS_noop2, /* mkdir */ - RGSS_stat, - RGSS_closeArchive -}; - -static bool -readUint32AndXor(PHYSFS_Io *io, uint32_t &result, uint32_t key) -{ - if (!readUint32(io, result)) - return false; - - result ^= key; - - return true; -} - -static void* -RGSS3_openArchive(PHYSFS_Io *io, const char *, int forWrite, int *claimed) -{ - if (forWrite) - return NULL; - - /* Version 3 */ - if (!verifyHeader(io, 3)) - return NULL; - else - *claimed = 1; - - uint32_t baseMagic; - - if (!readUint32(io, baseMagic)) - return NULL; - - baseMagic = (baseMagic * 9) + 3; - - RGSS_archiveData *data = new RGSS_archiveData; - data->archiveIo = io; - - /* Top level entry list */ - BoostSet &topLevel = data->dirHash[""]; - - while (true) - { - uint32_t offset, size, magic, nameLen; - - if (!readUint32AndXor(io, offset, baseMagic)) - goto error; - - /* Zero offset means entry list has ended */ - if (offset == 0) - break; - - if (!readUint32AndXor(io, size, baseMagic)) - goto error; - - if (!readUint32AndXor(io, magic, baseMagic)) - goto error; - - if (!readUint32AndXor(io, nameLen, baseMagic)) - goto error; - - char nameBuf[512]; - - if (!IO_READ(io, nameBuf, nameLen)) - goto error; - - for (uint32_t i = 0; i < nameLen; ++i) - { - nameBuf[i] ^= ((baseMagic >> 8*(i%4)) & 0xFF); - - if (nameBuf[i] == '\\') - nameBuf[i] = '/'; - } - - nameBuf[nameLen] = '\0'; - - RGSS_entryData entry; - entry.offset = offset; - entry.size = size; - entry.startMagic = magic; - - data->entryHash.insert(nameBuf, entry); - processDirectories(data, topLevel, nameBuf, nameLen); - - continue; - - error: - delete data; - return NULL; - } - - return data; -} - -const PHYSFS_Archiver RGSS3_Archiver = -{ - 0, - { - "RGSS3A", - "RGSS3 encrypted archive format", - "", /* Author */ - "", /* Website */ - 0 /* symlinks not supported */ - }, - RGSS3_openArchive, - RGSS_enumerateFiles, - RGSS_openRead, - RGSS_noop1, /* openWrite */ - RGSS_noop1, /* openAppend */ - RGSS_noop2, /* remove */ - RGSS_noop2, /* mkdir */ - RGSS_stat, - RGSS_closeArchive -}; diff --git a/src/meson.build b/src/meson.build index 80793e0c..4ee77ca0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -107,7 +107,6 @@ endif main_source = files( 'filesystem/source/filesystem.cpp', - 'filesystem/source/rgssad.cpp', 'graphics/source/autotiles.cpp', 'graphics/source/bitmap.cpp', 'graphics/source/graphics.cpp', diff --git a/src/util/headers/boost-hash.h b/src/util/headers/boost-hash.h index 3ce746a6..14ba7135 100644 --- a/src/util/headers/boost-hash.h +++ b/src/util/headers/boost-hash.h @@ -22,24 +22,19 @@ #ifndef BOOSTHASH_H #define BOOSTHASH_H -#include -#include +// I would like to use unordered but it doesn't play nice with pair or some of the other things provided :/ +#include +#include #include - -/* Wrappers around the boost unordered template classes, - * exposing an interface similar to Qt's QHash/QSet */ - template class BoostHash { private: - typedef boost::unordered_map BoostType; - typedef std::pair PairType; - BoostType p; + std::map p = {}; public: - typedef typename BoostType::const_iterator const_iterator; + typedef typename std::map::const_iterator const_iterator; inline bool contains(const K &key) const { @@ -50,7 +45,8 @@ class BoostHash inline void insert(const K &key, const V &value) { - p.insert(PairType(key, value)); + p[key] = value; + //p.insert(std::pair(key, value)); } inline void remove(const K &key) @@ -92,17 +88,22 @@ class BoostHash { return p.cend(); } + + inline void clear() + { + p.clear(); + } }; template class BoostSet { private: - typedef boost::unordered_set BoostType; - BoostType p; + //typedef std::unordered_set BoostType; + std::set p; public: - typedef typename BoostType::const_iterator const_iterator; + typedef typename std::set::const_iterator const_iterator; inline bool contains(const K &key) { From dad511298ae888a83b67af85d9bf1946b46fc059 Mon Sep 17 00:00:00 2001 From: Matthew Lyons Date: Mon, 15 Aug 2022 14:06:15 -0700 Subject: [PATCH 03/14] Boost begone --- README.md | 7 +- binding-mri/modshot-binding.cpp | 2 - binding-mri/oneshot-binding.cpp | 12 +- binding-mri/wallpaper-binding.cpp | 752 +++++++++++++++------------ linux/Makefile | 18 +- scripts/rgss/i18n_Language.rb | 5 +- setup.sh | 8 +- src/main.cpp | 2 +- src/meson.build | 3 +- src/modshot/source/crash-handler.cpp | 61 --- src/util/headers/config.h | 125 ++--- src/util/headers/debugwriter.h | 9 - src/util/source/config.cpp | 180 +------ windows/Makefile | 18 +- 14 files changed, 532 insertions(+), 670 deletions(-) diff --git a/README.md b/README.md index e47d4be7..afb5e4cf 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Instead, ModShot now makes use of meson, bash, and make, in a fairly simple setu Because of this, compiling with Visual Studio as was standard before is no longer supported, and instead compiling using the msys2 toolset is required. The main upshot of this, of course, is remaining on par with ruby in terms of gem support. (at least for windows) +With some hacking, you could probably get this setup working with Visual Studio, but it's honestly not worth the effort. Previously, C extensions were very jank with ModShot, **however** now you can use a C extension right from your own Ruby install! (Provided the version is the same, and the msys2 evironment is the same. I'll get back to this later.) @@ -45,7 +46,7 @@ You will then need to pass `-Dfmod=true` as an option. ModShot should handle everything from there, it's up to you to follow the FMOD license. FMOD bindings also do not supply the `Audio` module. You may create wrapper functions for that if you wish. -AL Effect bndings are not supplied as well for obvious reasons. +AL Effect bindings are not supplied as well for obvious reasons. Functions will always return an array of values (usually two) in the order of `[result, values...]`. This means you can do `result, value = FMOD.some_func()`, which is pretty neat, right? If a result is not `FMOD_OK` (0) there will be no return value. Keep that in mind! @@ -148,9 +149,9 @@ This should create a folder called `out` with your build of ModShot all ready to ## Configuration -*ModShot* reads configuration data from the file "oneshot.conf". The format is ini-style. Do *not* use quotes around file paths (spaces won't break). Lines starting with '#' are comments. See 'oneshot.conf.sample' for a list of accepted entries. +*ModShot* reads configuration data from the file "modshot.toml". It's a toml file, because toml is cool. -All option entries can alternatively be specified as command line options. Any options that are not arrays (eg. preloaded scripts) specified as command line options will override entries in oneshot.conf. Note that you will have to wrap values containing spaces in quotes (unlike in oneshot.conf). +All option entries can alternatively be specified as command line options. Any options that are not arrays (eg. preloaded scripts) specified as command line options will override entries in modshot.toml. Note that you will have to wrap values containing spaces in quotes. The syntax is: `--