Merge remote-tracking branch 'upstream/master' into ems-mruby

This commit is contained in:
Varun Patil 2018-05-01 14:01:34 +05:30
commit 891896957a
16 changed files with 143 additions and 77 deletions

View File

@ -217,6 +217,11 @@ set(MAIN_SOURCE
src/fluid-fun.cpp src/fluid-fun.cpp
) )
if(WIN32)
list(APPEND MAIN_HEADERS windows/resource.h)
list(APPEND MAIN_SOURCE windows/resource.rc)
endif()
source_group("MKXP Source" FILES ${MAIN_SOURCE} ${MAIN_HEADERS}) source_group("MKXP Source" FILES ${MAIN_SOURCE} ${MAIN_HEADERS})
## Setup embedded source ## ## Setup embedded source ##
@ -417,6 +422,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE
) )
target_include_directories(${PROJECT_NAME} PRIVATE target_include_directories(${PROJECT_NAME} PRIVATE
src src
windows
${SIGCXX_INCLUDE_DIRS} ${SIGCXX_INCLUDE_DIRS}
${PIXMAN_INCLUDE_DIRS} ${PIXMAN_INCLUDE_DIRS}
${PHYSFS_INCLUDE_DIRS} ${PHYSFS_INCLUDE_DIRS}

View File

@ -149,7 +149,16 @@ static void mriBindingInit()
_rb_define_module_function(mod, "raw_key_states", mkxpRawKeyStates); _rb_define_module_function(mod, "raw_key_states", mkxpRawKeyStates);
_rb_define_module_function(mod, "mouse_in_window", mkxpMouseInWindow); _rb_define_module_function(mod, "mouse_in_window", mkxpMouseInWindow);
/* Load global constants */
rb_gv_set("MKXP", Qtrue); rb_gv_set("MKXP", Qtrue);
VALUE debug = rb_bool_new(shState->config().editor.debug);
if (rgssVer == 1)
rb_gv_set("DEBUG", debug);
else if (rgssVer >= 2)
rb_gv_set("TEST", debug);
rb_gv_set("BTEST", rb_bool_new(shState->config().editor.battleTest));
} }
static void static void

View File

@ -188,7 +188,8 @@ raiseRbExc(const Exception &exc);
extern rb_data_type_t Klass##Type extern rb_data_type_t Klass##Type
/* 2.1 has added a new field (flags) to rb_data_type_t */ /* 2.1 has added a new field (flags) to rb_data_type_t */
#if RUBY_API_VERSION_MAJOR > 1 && RUBY_API_VERSION_MINOR > 0 #include <ruby/version.h>
#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 1
/* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */ /* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */
#define DEF_TYPE_FLAGS 0 #define DEF_TYPE_FLAGS 0
#else #else
@ -211,7 +212,12 @@ raiseRbExc(const Exception &exc);
template<rb_data_type_t *rbType> template<rb_data_type_t *rbType>
static VALUE classAllocate(VALUE klass) static VALUE classAllocate(VALUE klass)
{ {
/* 2.3 has changed the name of this function */
#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 3
return rb_data_typed_object_wrap(klass, 0, rbType);
#else
return rb_data_typed_object_alloc(klass, 0, rbType); return rb_data_typed_object_alloc(klass, 0, rbType);
#endif
} }
template<class C> template<class C>

View File

@ -118,8 +118,17 @@ static void mrbBindingInit(mrb_state *mrb)
/* Load RPG module */ /* Load RPG module */
mrb_load_irep(mrb, mrbModuleRPG); mrb_load_irep(mrb, mrbModuleRPG);
/* Load global constants */
mrb_define_global_const(mrb, "MKXP", mrb_true_value()); mrb_define_global_const(mrb, "MKXP", mrb_true_value());
mrb_value debug = rb_bool_new(shState->config().editor.debug);
if (rgssVer == 1)
mrb_define_global_const(mrb, "DEBUG", debug);
else if (rgssVer >= 2)
mrb_define_global_const(mrb, "TEST", debug);
mrb_define_global_const(mrb, "BTEST", mrb_bool_value(shState->config().editor.battleTest));
mrb_gc_arena_restore(mrb, arena); mrb_gc_arena_restore(mrb, arena);
} }

View File

@ -86,6 +86,12 @@
# defScreenH=480 # defScreenH=480
# Override the game window title
# (default: none)
#
# windowTitle=Custom Title
# Enforce a static frame rate # Enforce a static frame rate
# (0 = disabled) # (0 = disabled)
# #

View File

@ -163,6 +163,7 @@ void Config::read(int argc, char *argv[])
PO_DESC(vsync, bool, false) \ PO_DESC(vsync, bool, false) \
PO_DESC(defScreenW, int, 0) \ PO_DESC(defScreenW, int, 0) \
PO_DESC(defScreenH, int, 0) \ PO_DESC(defScreenH, int, 0) \
PO_DESC(windowTitle, std::string, "") \
PO_DESC(fixedFramerate, int, 0) \ PO_DESC(fixedFramerate, int, 0) \
PO_DESC(frameSkip, bool, true) \ PO_DESC(frameSkip, bool, true) \
PO_DESC(syncToRefreshrate, bool, false) \ PO_DESC(syncToRefreshrate, bool, false) \
@ -190,6 +191,27 @@ void Config::read(int argc, char *argv[])
// Not gonna take your shit boost // Not gonna take your shit boost
#define GUARD_ALL( exp ) try { exp } catch(...) {} #define GUARD_ALL( exp ) try { exp } catch(...) {}
editor.debug = false;
editor.battleTest = false;
/* Read arguments sent from the editor */
if (argc > 1)
{
std::string argv1 = argv[1];
/* RGSS1 uses "debug", 2 and 3 use "test" */
if (argv1 == "debug" || argv1 == "test")
editor.debug = true;
else if (argv1 == "btest")
editor.battleTest = true;
/* Fix offset */
if (editor.debug || editor.battleTest)
{
argc--;
argv++;
}
}
#define PO_DESC(key, type, def) (#key, po::value< type >()->default_value(def)) #define PO_DESC(key, type, def) (#key, po::value< type >()->default_value(def))
po::options_description podesc; po::options_description podesc;

View File

@ -41,6 +41,7 @@ struct Config
int defScreenW = 0; int defScreenW = 0;
int defScreenH = 0; int defScreenH = 0;
std::string windowTitle;
int fixedFramerate = 0; int fixedFramerate = 0;
bool frameSkip =false; bool frameSkip =false;
@ -87,6 +88,12 @@ struct Config
std::vector<std::string> rubyLoadpaths; std::vector<std::string> rubyLoadpaths;
/* Editor flags */
struct {
bool debug;
bool battleTest;
} editor;
/* Game INI contents */ /* Game INI contents */
struct { struct {
std::string scripts; std::string scripts;

View File

@ -277,14 +277,14 @@ void EventThread::process(RGSSThreadData &rtData)
if (fullscreen) if (fullscreen)
{ {
/* Prevent fullscreen flicker */ /* Prevent fullscreen flicker */
strncpy(pendingTitle, rtData.config.game.title.c_str(), strncpy(pendingTitle, rtData.config.windowTitle.c_str(),
sizeof(pendingTitle)); sizeof(pendingTitle));
havePendingTitle = true; havePendingTitle = true;
break; break;
} }
SDL_SetWindowTitle(win, rtData.config.game.title.c_str()); SDL_SetWindowTitle(win, rtData.config.windowTitle.c_str());
} }
break; break;
@ -391,7 +391,7 @@ void EventThread::process(RGSSThreadData &rtData)
case REQUEST_MESSAGEBOX : case REQUEST_MESSAGEBOX :
SDL_ShowSimpleMessageBox(event.user.code, SDL_ShowSimpleMessageBox(event.user.code,
rtData.config.game.title.c_str(), rtData.config.windowTitle.c_str(),
(const char*) event.user.data1, win); (const char*) event.user.data1, win);
free(event.user.data1); free(event.user.data1);
msgBoxDone.set(); msgBoxDone.set();
@ -410,7 +410,7 @@ void EventThread::process(RGSSThreadData &rtData)
break; break;
snprintf(buffer, sizeof(buffer), "%s - %d FPS", snprintf(buffer, sizeof(buffer), "%s - %d FPS",
rtData.config.game.title.c_str(), event.user.code); rtData.config.windowTitle.c_str(), event.user.code);
/* Updating the window title in fullscreen /* Updating the window title in fullscreen
* mode seems to cause flickering */ * mode seems to cause flickering */

View File

@ -398,8 +398,8 @@ struct CacheEnumData
} }
}; };
static void cacheEnumCB(void *d, const char *origdir, static PHYSFS_EnumerateCallbackResult
const char *fname) cacheEnumCB(void *d, const char *origdir, const char *fname)
{ {
CacheEnumData &data = *static_cast<CacheEnumData*>(d); CacheEnumData &data = *static_cast<CacheEnumData*>(d);
char fullPath[512]; char fullPath[512];
@ -426,7 +426,7 @@ static void cacheEnumCB(void *d, const char *origdir,
/* Iterate over its contents */ /* Iterate over its contents */
data.fileLists.push(&list); data.fileLists.push(&list);
PHYSFS_enumerateFilesCallback(fullPath, cacheEnumCB, d); PHYSFS_enumerate(fullPath, cacheEnumCB, d);
data.fileLists.pop(); data.fileLists.pop();
} }
else else
@ -441,13 +441,15 @@ static void cacheEnumCB(void *d, const char *origdir,
/* Add the lower -> mixed mapping of the file's full path */ /* Add the lower -> mixed mapping of the file's full path */
data.p->pathCache.insert(lowerCase, mixedCase); data.p->pathCache.insert(lowerCase, mixedCase);
} }
return PHYSFS_ENUM_OK;
} }
void FileSystem::createPathCache() void FileSystem::createPathCache()
{ {
CacheEnumData data(p); CacheEnumData data(p);
data.fileLists.push(&p->fileLists[""]); data.fileLists.push(&p->fileLists[""]);
PHYSFS_enumerateFilesCallback("", cacheEnumCB, &data); PHYSFS_enumerate("", cacheEnumCB, &data);
p->havePathCache = true; p->havePathCache = true;
} }
@ -458,8 +460,8 @@ struct FontSetsCBData
SharedFontState *sfs; SharedFontState *sfs;
}; };
static void fontSetEnumCB(void *data, const char *dir, static PHYSFS_EnumerateCallbackResult
const char *fname) fontSetEnumCB (void *data, const char *dir, const char *fname)
{ {
FontSetsCBData *d = static_cast<FontSetsCBData*>(data); FontSetsCBData *d = static_cast<FontSetsCBData*>(data);
@ -467,7 +469,7 @@ static void fontSetEnumCB(void *data, const char *dir,
const char *ext = findExt(fname); const char *ext = findExt(fname);
if (!ext) if (!ext)
return; return PHYSFS_ENUM_STOP;
char lowExt[8]; char lowExt[8];
size_t i; size_t i;
@ -477,7 +479,7 @@ static void fontSetEnumCB(void *data, const char *dir,
lowExt[i] = '\0'; lowExt[i] = '\0';
if (strcmp(lowExt, "ttf") && strcmp(lowExt, "otf")) if (strcmp(lowExt, "ttf") && strcmp(lowExt, "otf"))
return; return PHYSFS_ENUM_STOP;
char filename[512]; char filename[512];
snprintf(filename, sizeof(filename), "%s/%s", dir, fname); snprintf(filename, sizeof(filename), "%s/%s", dir, fname);
@ -485,7 +487,7 @@ static void fontSetEnumCB(void *data, const char *dir,
PHYSFS_File *handle = PHYSFS_openRead(filename); PHYSFS_File *handle = PHYSFS_openRead(filename);
if (!handle) if (!handle)
return; return PHYSFS_ENUM_ERROR;
SDL_RWops ops; SDL_RWops ops;
initReadOps(handle, ops, false); initReadOps(handle, ops, false);
@ -493,31 +495,35 @@ static void fontSetEnumCB(void *data, const char *dir,
d->sfs->initFontSetCB(ops, filename); d->sfs->initFontSetCB(ops, filename);
SDL_RWclose(&ops); SDL_RWclose(&ops);
return PHYSFS_ENUM_OK;
} }
/* Basically just a case-insensitive search /* Basically just a case-insensitive search
* for the folder "Fonts"... */ * for the folder "Fonts"... */
static void findFontsFolderCB(void *data, const char *, static PHYSFS_EnumerateCallbackResult
const char *fname) findFontsFolderCB(void *data, const char *, const char *fname)
{ {
size_t i = 0; size_t i = 0;
char buffer[512]; char buffer[512];
const char *s = fname; const char *s = fname;
while (s && i < sizeof(buffer)) while (*s && i < sizeof(buffer))
buffer[i++] = tolower(*s++); buffer[i++] = tolower(*s++);
buffer[i] = '\0'; buffer[i] = '\0';
if (strcmp(buffer, "fonts") == 0) if (strcmp(buffer, "fonts") == 0)
PHYSFS_enumerateFilesCallback(fname, fontSetEnumCB, data); PHYSFS_enumerate(fname, fontSetEnumCB, data);
return PHYSFS_ENUM_OK;
} }
void FileSystem::initFontSets(SharedFontState &sfs) void FileSystem::initFontSets(SharedFontState &sfs)
{ {
FontSetsCBData d = { p, &sfs }; FontSetsCBData d = { p, &sfs };
PHYSFS_enumerateFilesCallback(".", findFontsFolderCB, &d); PHYSFS_enumerate("", findFontsFolderCB, &d);
} }
struct OpenReadEnumData struct OpenReadEnumData
@ -550,19 +556,19 @@ struct OpenReadEnumData
{} {}
}; };
static void openReadEnumCB(void *d, const char *dirpath, static PHYSFS_EnumerateCallbackResult
const char *filename) openReadEnumCB(void *d, const char *dirpath, const char *filename)
{ {
OpenReadEnumData &data = *static_cast<OpenReadEnumData*>(d); OpenReadEnumData &data = *static_cast<OpenReadEnumData*>(d);
char buffer[512]; char buffer[512];
const char *fullPath; const char *fullPath;
if (data.stopSearching) if (data.stopSearching)
return; return PHYSFS_ENUM_STOP;
/* If there's not even a partial match, continue searching */ /* If there's not even a partial match, continue searching */
if (strncmp(filename, data.filename, data.filenameN) != 0) if (strncmp(filename, data.filename, data.filenameN) != 0)
return; return PHYSFS_ENUM_OK;
if (!*dirpath) if (!*dirpath)
{ {
@ -580,7 +586,7 @@ static void openReadEnumCB(void *d, const char *dirpath,
* of the extension), or up to a following '\0' (full match), we've * of the extension), or up to a following '\0' (full match), we've
* found our file */ * found our file */
if (last != '.' && last != '\0') if (last != '.' && last != '\0')
return; return PHYSFS_ENUM_STOP;
/* If the path cache is active, translate from lower case /* If the path cache is active, translate from lower case
* to mixed case path */ * to mixed case path */
@ -595,9 +601,9 @@ static void openReadEnumCB(void *d, const char *dirpath,
* be a deeper rooted problem somewhere within PhysFS. * be a deeper rooted problem somewhere within PhysFS.
* Just abort alltogether. */ * Just abort alltogether. */
data.stopSearching = true; data.stopSearching = true;
data.physfsError = PHYSFS_getLastError(); data.physfsError = PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode());
return; return PHYSFS_ENUM_ERROR;
} }
initReadOps(phys, data.ops, false); initReadOps(phys, data.ops, false);
@ -608,6 +614,7 @@ static void openReadEnumCB(void *d, const char *dirpath,
data.stopSearching = true; data.stopSearching = true;
++data.matchCount; ++data.matchCount;
return PHYSFS_ENUM_OK;
} }
void FileSystem::openRead(OpenHandler &handler, const char *filename) void FileSystem::openRead(OpenHandler &handler, const char *filename)
@ -653,7 +660,7 @@ void FileSystem::openRead(OpenHandler &handler, const char *filename)
} }
else else
{ {
PHYSFS_enumerateFilesCallback(dir, openReadEnumCB, &data); PHYSFS_enumerate(dir, openReadEnumCB, &data);
} }
if (data.physfsError) if (data.physfsError)

View File

@ -92,11 +92,9 @@ struct PingPong
{ {
screenW = width; screenW = width;
screenH = height; screenH = height;
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
{ TEXFBO::allocEmpty(rt[i], width, height);
TEX::bind(rt[i].tex);
TEX::allocEmpty(width, height);
}
} }
void startRender() void startRender()
@ -483,9 +481,7 @@ struct GraphicsPrivate
bool frozen; bool frozen;
TEXFBO frozenScene; TEXFBO frozenScene;
TEXFBO currentScene;
Quad screenQuad; Quad screenQuad;
TEXFBO transBuffer;
/* Global list of all live Disposables /* Global list of all live Disposables
* (disposed on reset) */ * (disposed on reset) */
@ -511,26 +507,15 @@ struct GraphicsPrivate
TEXFBO::allocEmpty(frozenScene, scRes.x, scRes.y); TEXFBO::allocEmpty(frozenScene, scRes.x, scRes.y);
TEXFBO::linkFBO(frozenScene); TEXFBO::linkFBO(frozenScene);
TEXFBO::init(currentScene);
TEXFBO::allocEmpty(currentScene, scRes.x, scRes.y);
TEXFBO::linkFBO(currentScene);
FloatRect screenRect(0, 0, scRes.x, scRes.y); FloatRect screenRect(0, 0, scRes.x, scRes.y);
screenQuad.setTexPosRect(screenRect, screenRect); screenQuad.setTexPosRect(screenRect, screenRect);
TEXFBO::init(transBuffer);
TEXFBO::allocEmpty(transBuffer, scRes.x, scRes.y);
TEXFBO::linkFBO(transBuffer);
fpsLimiter.resetFrameAdjust(); fpsLimiter.resetFrameAdjust();
} }
~GraphicsPrivate() ~GraphicsPrivate()
{ {
TEXFBO::fini(frozenScene); TEXFBO::fini(frozenScene);
TEXFBO::fini(currentScene);
TEXFBO::fini(transBuffer);
} }
void updateScreenResoRatio(RGSSThreadData *rtData) void updateScreenResoRatio(RGSSThreadData *rtData)
@ -730,8 +715,15 @@ void Graphics::transition(int duration,
setBrightness(255); setBrightness(255);
/* The PP frontbuffer will hold the current scene after the
* composition step. Since the backbuffer is unused during
* the transition, we can reuse it as the target buffer for
* the final rendered image. */
TEXFBO &currentScene = p->screen.getPP().frontBuffer();
TEXFBO &transBuffer = p->screen.getPP().backBuffer();
/* Capture new scene */ /* Capture new scene */
p->compositeToBuffer(p->currentScene); p->screen.composite();
/* If no transition bitmap is provided, /* If no transition bitmap is provided,
* we can use a simplified shader */ * we can use a simplified shader */
@ -744,7 +736,7 @@ void Graphics::transition(int duration,
shader.bind(); shader.bind();
shader.applyViewportProj(); shader.applyViewportProj();
shader.setFrozenScene(p->frozenScene.tex); shader.setFrozenScene(p->frozenScene.tex);
shader.setCurrentScene(p->currentScene.tex); shader.setCurrentScene(currentScene.tex);
shader.setTransMap(transMap->getGLTypes().tex); shader.setTransMap(transMap->getGLTypes().tex);
shader.setVague(vague / 256.0f); shader.setVague(vague / 256.0f);
shader.setTexSize(p->scRes); shader.setTexSize(p->scRes);
@ -755,7 +747,7 @@ void Graphics::transition(int duration,
shader.bind(); shader.bind();
shader.applyViewportProj(); shader.applyViewportProj();
shader.setFrozenScene(p->frozenScene.tex); shader.setFrozenScene(p->frozenScene.tex);
shader.setCurrentScene(p->currentScene.tex); shader.setCurrentScene(currentScene.tex);
shader.setTexSize(p->scRes); shader.setTexSize(p->scRes);
} }
@ -799,7 +791,7 @@ void Graphics::transition(int duration,
/* Draw the composed frame to a buffer first /* Draw the composed frame to a buffer first
* (we need this because we're skipping PingPong) */ * (we need this because we're skipping PingPong) */
FBO::bind(p->transBuffer.fbo); FBO::bind(transBuffer.fbo);
FBO::clear(); FBO::clear();
p->screenQuad.draw(); p->screenQuad.draw();
@ -810,7 +802,7 @@ void Graphics::transition(int duration,
FBO::clear(); FBO::clear();
GLMeta::blitBeginScreen(Vec2i(p->winSize)); GLMeta::blitBeginScreen(Vec2i(p->winSize));
GLMeta::blitSource(p->transBuffer); GLMeta::blitSource(transBuffer);
p->metaBlitBufferFlippedScaled(); p->metaBlitBufferFlippedScaled();
GLMeta::blitEnd(); GLMeta::blitEnd();
@ -953,17 +945,11 @@ void Graphics::resizeScreen(int width, int height)
p->screen.setResolution(width, height); p->screen.setResolution(width, height);
TEX::bind(p->frozenScene.tex); TEXFBO::allocEmpty(p->frozenScene, width, height);
TEX::allocEmpty(width, height);
TEX::bind(p->currentScene.tex);
TEX::allocEmpty(width, height);
FloatRect screenRect(0, 0, width, height); FloatRect screenRect(0, 0, width, height);
p->screenQuad.setTexPosRect(screenRect, screenRect); p->screenQuad.setTexPosRect(screenRect, screenRect);
TEX::bind(p->transBuffer.tex);
TEX::allocEmpty(width, height);
shState->eThread().requestWindowResize(width, height); shState->eThread().requestWindowResize(width, height);
} }

View File

@ -237,7 +237,10 @@ int main(int argc, char *argv[])
} }
conf.readGameINI(); conf.readGameINI();
printf("%s\n", conf.gameFolder.c_str());
if (conf.windowTitle.empty())
conf.windowTitle = conf.game.title;
assert(conf.rgssVersion >= 1 && conf.rgssVersion <= 3); assert(conf.rgssVersion >= 1 && conf.rgssVersion <= 3);
printRgssVersion(conf.rgssVersion); printRgssVersion(conf.rgssVersion);
@ -277,7 +280,7 @@ int main(int argc, char *argv[])
if (conf.fullscreen) if (conf.fullscreen)
winFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; winFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
win = SDL_CreateWindow(conf.game.title.c_str(), win = SDL_CreateWindow(conf.windowTitle.c_str(),
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
conf.defScreenW, conf.defScreenH, winFlags); conf.defScreenW, conf.defScreenH, winFlags);
@ -360,13 +363,13 @@ int main(int argc, char *argv[])
if (rtData.rqTermAck){} if (rtData.rqTermAck){}
//SDL_WaitThread(rgssThread, 0); //SDL_WaitThread(rgssThread, 0);
else else
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.game.title.c_str(), SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.windowTitle.c_str(),
"The RGSS script seems to be stuck and mkxp will now force quit", win); "The RGSS script seems to be stuck and mkxp will now force quit", win);
if (!rtData.rgssErrorMsg.empty()) if (!rtData.rgssErrorMsg.empty())
{ {
Debug() << rtData.rgssErrorMsg; Debug() << rtData.rgssErrorMsg;
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.game.title.c_str(), SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, conf.windowTitle.c_str(),
rtData.rgssErrorMsg.c_str(), win); rtData.rgssErrorMsg.c_str(), win);
} }

View File

@ -297,6 +297,8 @@ processDirectories(RGSS_archiveData *data, BoostSet<std::string> &topLevel,
if (slash) if (slash)
nameBuf[i] = '/'; nameBuf[i] = '/';
break;
} }
/* Check for more entries */ /* Check for more entries */
@ -331,14 +333,16 @@ verifyHeader(PHYSFS_Io *io, char version)
} }
static void* static void*
RGSS_openArchive(PHYSFS_Io *io, const char *, int forWrite) RGSS_openArchive(PHYSFS_Io *io, const char *, int forWrite, int *claimed)
{ {
if (forWrite) if (forWrite)
return 0; return NULL;
/* Version 1 */ /* Version 1 */
if (!verifyHeader(io, 1)) if (!verifyHeader(io, 1))
return 0; return NULL;
else
*claimed = 1;
RGSS_archiveData *data = new RGSS_archiveData; RGSS_archiveData *data = new RGSS_archiveData;
data->archiveIo = io; data->archiveIo = io;
@ -389,9 +393,9 @@ RGSS_openArchive(PHYSFS_Io *io, const char *, int forWrite)
return data; return data;
} }
static void static PHYSFS_EnumerateCallbackResult
RGSS_enumerateFiles(void *opaque, const char *dirname, RGSS_enumerateFiles(void *opaque, const char *dirname,
PHYSFS_EnumFilesCallback cb, PHYSFS_EnumerateCallback cb,
const char *origdir, void *callbackdata) const char *origdir, void *callbackdata)
{ {
RGSS_archiveData *data = static_cast<RGSS_archiveData*>(opaque); RGSS_archiveData *data = static_cast<RGSS_archiveData*>(opaque);
@ -399,13 +403,15 @@ RGSS_enumerateFiles(void *opaque, const char *dirname,
std::string _dirname(dirname); std::string _dirname(dirname);
if (!data->dirHash.contains(_dirname)) if (!data->dirHash.contains(_dirname))
return; return PHYSFS_ENUM_STOP;
const BoostSet<std::string> &entries = data->dirHash[_dirname]; const BoostSet<std::string> &entries = data->dirHash[_dirname];
BoostSet<std::string>::const_iterator iter; BoostSet<std::string>::const_iterator iter;
for (iter = entries.cbegin(); iter != entries.cend(); ++iter) for (iter = entries.cbegin(); iter != entries.cend(); ++iter)
cb(callbackdata, origdir, iter->c_str()); cb(callbackdata, origdir, iter->c_str());
return PHYSFS_ENUM_OK;
} }
static PHYSFS_Io* static PHYSFS_Io*
@ -536,19 +542,21 @@ readUint32AndXor(PHYSFS_Io *io, uint32_t &result, uint32_t key)
} }
static void* static void*
RGSS3_openArchive(PHYSFS_Io *io, const char *, int forWrite) RGSS3_openArchive(PHYSFS_Io *io, const char *, int forWrite, int *claimed)
{ {
if (forWrite) if (forWrite)
return 0; return NULL;
/* Version 3 */ /* Version 3 */
if (!verifyHeader(io, 3)) if (!verifyHeader(io, 3))
return 0; return NULL;
else
*claimed = 1;
uint32_t baseMagic; uint32_t baseMagic;
if (!readUint32(io, baseMagic)) if (!readUint32(io, baseMagic))
return 0; return NULL;
baseMagic = (baseMagic * 9) + 3; baseMagic = (baseMagic * 9) + 3;
@ -605,7 +613,7 @@ RGSS3_openArchive(PHYSFS_Io *io, const char *, int forWrite)
error: error:
delete data; delete data;
return 0; return NULL;
} }
return data; return data;

View File

@ -121,7 +121,7 @@ struct SpritePrivate
void recomputeBushDepth() void recomputeBushDepth()
{ {
if (!bitmap) if (nullOrDisposed(bitmap))
return; return;
/* Calculate effective (normalized) bush depth */ /* Calculate effective (normalized) bush depth */
@ -137,18 +137,15 @@ struct SpritePrivate
FloatRect rect = srcRect->toFloatRect(); FloatRect rect = srcRect->toFloatRect();
Vec2i bmSize; Vec2i bmSize;
if (bitmap) if (!nullOrDisposed(bitmap))
bmSize = Vec2i(bitmap->width(), bitmap->height()); bmSize = Vec2i(bitmap->width(), bitmap->height());
if (mirrored)
rect = rect.hFlipped();
/* Clamp the rectangle so it doesn't reach outside /* Clamp the rectangle so it doesn't reach outside
* the bitmap bounds */ * the bitmap bounds */
rect.w = clamp<int>(rect.w, 0, bmSize.x-rect.x); rect.w = clamp<int>(rect.w, 0, bmSize.x-rect.x);
rect.h = clamp<int>(rect.h, 0, bmSize.y-rect.y); rect.h = clamp<int>(rect.h, 0, bmSize.y-rect.y);
quad.setTexRect(rect); quad.setTexRect(mirrored ? rect.hFlipped() : rect);
quad.setPosRect(FloatRect(0, 0, rect.w, rect.h)); quad.setPosRect(FloatRect(0, 0, rect.w, rect.h));
recomputeBushDepth(); recomputeBushDepth();

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB