diff --git a/src/main.cpp b/src/main.cpp index 08f9036..27b7533 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,6 +33,7 @@ #include "eventthread.h" #include "debuglogger.h" #include "debugwriter.h" +#include "exception.h" #include "binding.h" @@ -100,6 +101,7 @@ int rgssThreadFun(void *userdata) { rgssThreadError(threadData, "Error initializing glew"); SDL_GL_DeleteContext(glCtx); + return 0; } @@ -114,6 +116,7 @@ int rgssThreadFun(void *userdata) { rgssThreadError(threadData, "At least OpenGL 2.0 is required"); SDL_GL_DeleteContext(glCtx); + return 0; } @@ -125,6 +128,7 @@ int rgssThreadFun(void *userdata) rgssThreadError(threadData, std::string("Required GL extension \"") + reqExt[i] + "\" not present"); SDL_GL_DeleteContext(glCtx); + return 0; } } @@ -140,6 +144,7 @@ int rgssThreadFun(void *userdata) { rgssThreadError(threadData, "Error opening OpenAL device"); SDL_GL_DeleteContext(glCtx); + return 0; } @@ -150,12 +155,25 @@ int rgssThreadFun(void *userdata) rgssThreadError(threadData, "Error creating OpenAL context"); alcCloseDevice(alcDev); SDL_GL_DeleteContext(glCtx); + return 0; } alcMakeContextCurrent(alcCtx); - SharedState::initInstance(threadData); + try + { + SharedState::initInstance(threadData); + } + catch (const Exception &exc) + { + rgssThreadError(threadData, exc.msg); + alcDestroyContext(alcCtx); + alcCloseDevice(alcDev); + SDL_GL_DeleteContext(glCtx); + + return 0; + } /* Start script execution */ scriptBinding->execute(); diff --git a/src/sharedstate.cpp b/src/sharedstate.cpp index 60eb7ae..84d0c24 100644 --- a/src/sharedstate.cpp +++ b/src/sharedstate.cpp @@ -35,6 +35,7 @@ #include "global-ibo.h" #include "quad.h" #include "binding.h" +#include "exception.h" #include #include @@ -93,8 +94,13 @@ struct SharedStatePrivate { if (!config.gameFolder.empty()) { - int unused = chdir(config.gameFolder.c_str()); - (void) unused; + int result = chdir(config.gameFolder.c_str()); + + if (result != 0) + throw Exception(Exception::MKXPError, + "Unable to switch into gameFolder '%s'", + config.gameFolder.c_str()); + fileSystem.addPath("."); } @@ -139,14 +145,31 @@ struct SharedStatePrivate void SharedState::initInstance(RGSSThreadData *threadData) { + /* This section is tricky because of dependencies: + * SharedState depends on GlobalIBO existing, + * Font depends on SharedState existing */ + globalIBO = new GlobalIBO(); globalIBO->ensureSize(1); - SharedState *state = new SharedState(threadData); + SharedState::instance = 0; + Font *defaultFont = 0; - SharedState::instance = state; + try + { + SharedState::instance = new SharedState(threadData); + defaultFont = new Font(); + } + catch (const Exception &exc) + { + delete globalIBO; + delete SharedState::instance; + delete defaultFont; - state->p->defaultFont = new Font(); + throw exc; + } + + SharedState::instance->p->defaultFont = defaultFont; } void SharedState::finiInstance() diff --git a/src/sharedstate.h b/src/sharedstate.h index 89bc716..c389f1f 100644 --- a/src/sharedstate.h +++ b/src/sharedstate.h @@ -106,6 +106,9 @@ struct SharedState void checkShutdown(); static SharedState *instance; + + /* This function will throw an Exception instance + * on initialization error */ static void initInstance(RGSSThreadData *threadData); static void finiInstance();