From b1a2569dff9b188934816e6d8527bc821a8394c2 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:24:14 -0500
Subject: [PATCH 01/18] add CMake project for easier building

---
 .gitignore            |   2 +
 CMakeLists.txt        | 366 ++++++++++++++++++++++++++++++++++++++++++
 cmake/PrepUtils.cmake |  38 +++++
 3 files changed, 406 insertions(+)
 create mode 100644 CMakeLists.txt
 create mode 100644 cmake/PrepUtils.cmake

diff --git a/.gitignore b/.gitignore
index bef2449..3ef397e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,5 @@ Makefile
 
 mkxp
 xxd+
+
+/build
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..4f00dab
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,366 @@
+cmake_minimum_required(VERSION 2.8.11)
+Project(mkxp)
+
+## Misc setup ##
+
+include(cmake/PrepUtils.cmake)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+IF("${CMAKE_SYSTEM}" MATCHES "Linux")
+    SET(LINUX ON)
+    SET(LINUX ON PARENT_SCOPE)
+ENDIF()
+
+IF(FORCE32)
+    if(APPLE)
+        SET(CMAKE_OSX_ARCHITECTURES "i386")
+    else()
+        SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
+        SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
+    endif()
+ENDIF()
+
+set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
+
+IF(LINUX)
+    if(CMAKE_SIZEOF_VOID_P MATCHES "8" AND NOT(FORCE32) )
+        set(CMAKE_EXECUTABLE_SUFFIX ".bin.x86_64")
+        set(BIN_RPATH "\$ORIGIN/lib64")
+    else()
+        set(CMAKE_EXECUTABLE_SUFFIX ".bin.x86")
+        set(BIN_RPATH "\$ORIGIN/lib")
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FILE_OFFSET_BITS=64")
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FILE_OFFSET_BITS=64")
+    endif()
+elseif(APPLE)
+    SET(BIN_RPATH "@executable_path/../Frameworks")
+endif()
+
+set(CMAKE_SKIP_BUILD_RPATH TRUE)
+set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+set(CMAKE_INSTALL_RPATH ${BIN_RPATH})
+set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
+
+## Setup options ##
+
+option(RGSS2 "Enable RGSS2" ON)
+set(BINDING "MRI" CACHE STRING "The Binding Type (MRI, MRUBY, NULL)")
+set(EXTERNAL_LIB_PATH "" CACHE PATH "External precompiled lib prefix")
+
+## Locate core libs ##
+
+find_package(PkgConfig REQUIRED)
+
+if (EXTERNAL_LIB_PATH)
+    set(CMAKE_PREFIX_PATH ${EXTERNAL_LIB_PATH})
+    if(EXISTS "${EXTERNAL_LIB_PATH}/lib/pkgconfig/")
+        SET(ENV{PKG_CONFIG_PATH} "${EXTERNAL_LIB_PATH}/lib/pkgconfig/")
+    endif()
+    if(APPLE)
+        set(PLATFORM_SHARED_LIBS 
+            libSDL2.dylib libSDL2_image-2.0.0.dylib libSDL2_ttf-2.0.0.dylib libSDL_sound-1.0.1.dylib
+            libfreetype.6.dylib libsigc-2.0.0.dylib
+            CACHE STRING "List of shared libraries that need to be copied into the OS X bundle")
+        foreach(lib ${PLATFORM_SHARED_LIBS})
+            if(EXISTS ${EXTERNAL_LIB_PATH}/lib/${lib})
+                list(APPEND PLATFORM_COPY_LIBS
+                    ${EXTERNAL_LIB_PATH}/lib/${lib}
+                )
+            endif()
+        endforeach()
+    endif()
+endif()
+
+pkg_check_modules(SIGCXX        REQUIRED sigc++-2.0)
+pkg_check_modules(PIXMAN        REQUIRED pixman-1)
+pkg_check_modules(PHYSFS        REQUIRED physfs>=2.1)
+pkg_check_modules(SDL2          REQUIRED sdl2)
+pkg_check_modules(SDL2_TTF      REQUIRED SDL2_ttf)
+pkg_check_modules(SDL2_IMAGE    REQUIRED SDL2_image)
+pkg_check_modules(SDL_SOUND     REQUIRED SDL_sound)
+
+find_package(GLEW 1.9.0 REQUIRED)
+find_package(Boost 1.49 COMPONENTS program_options REQUIRED)
+find_package(OpenAL REQUIRED)
+find_package(OpenGL REQUIRED)
+find_package(zlib REQUIRED)
+
+## Setup main source ##
+
+set(MAIN_HEADERS
+   	src/quadarray.h
+	src/audio.h
+	src/binding.h
+	src/bitmap.h
+	src/disposable.h
+	src/etc.h
+	src/etc-internal.h
+	src/eventthread.h
+	src/flashable.h
+	src/font.h
+	src/input.h
+	src/plane.h
+	src/scene.h
+	src/sprite.h
+	src/table.h
+	src/texpool.h
+	src/tilequad.h
+	src/transform.h
+	src/viewport.h
+	src/window.h
+	src/serializable.h
+	src/shader.h
+	src/glstate.h
+	src/quad.h
+	src/tilemap.h
+	src/graphics.h
+	src/debuglogger.h
+	src/global-ibo.h
+	src/exception.h
+	src/filesystem.h
+	src/serial-util.h
+	src/intrulist.h
+	src/binding.h
+	src/gl-util.h
+	src/util.h
+	src/config.h
+	src/tileatlas.h
+	src/perftimer.h
+	src/sharedstate.h
+	src/al-util.h
+   	src/boost-hash.h
+	src/debugwriter.h
+)
+
+set(MAIN_SOURCE
+	src/main.cpp
+	src/audio.cpp
+	src/bitmap.cpp
+	src/eventthread.cpp
+	src/filesystem.cpp
+	src/font.cpp
+	src/input.cpp
+	src/plane.cpp
+	src/scene.cpp
+	src/sprite.cpp
+	src/table.cpp
+	src/tilequad.cpp
+	src/viewport.cpp
+	src/window.cpp
+	src/texpool.cpp
+	src/shader.cpp
+	src/glstate.cpp
+	src/tilemap.cpp
+	src/autotiles.cpp
+	src/graphics.cpp
+	src/debuglogger.cpp
+	src/etc.cpp
+	src/config.cpp
+	src/tileatlas.cpp
+	src/perftimer.cpp
+	src/sharedstate.cpp
+)
+
+## Setup embedded source ##
+
+set(EMBEDDED_INPUT
+    shader/transSimple.frag
+    shader/trans.frag
+    shader/hue.frag
+    shader/sprite.frag
+    shader/plane.frag
+    shader/bitmapBlit.frag
+    shader/simple.frag
+    shader/simpleColor.frag
+    shader/simpleAlpha.frag
+    shader/flashMap.frag
+    shader/simple.vert
+    shader/simpleColor.vert
+    shader/sprite.vert
+    assets/liberation.ttf
+)
+
+if (RGSS2)
+    list(APPEND EMBEDDED_INPUT
+        shader/blur.frag
+        shader/blurH.vert
+        shader/blurV.vert
+        shader/simpleMatrix.vert
+    )
+endif()
+
+## Process Embeddeds ##
+
+find_program(XXD_EXE xxd
+    DOC "Location of the xxd executable"
+)
+
+macro(ProcessWithXXD outvar inputfile outdir)
+    get_filename_component(basefile ${inputfile} NAME)
+    set(outputfile ${outdir}/${basefile}.xxd)
+    set_source_files_properties(${outputfile} PROPERTIES HEADER_ONLY TRUE)
+    add_custom_command(
+        OUTPUT ${outputfile}
+        COMMAND ${XXD_EXE} -i ${inputfile} ${outputfile}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        DEPENDS ${inputfile}
+        COMMENT "Generating XXD for ${inputfile}"
+    )
+    list(APPEND ${outvar}
+        ${outputfile}
+    )
+endmacro()
+
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/xxdhack)
+include_directories(
+    ${CMAKE_CURRENT_BINARY_DIR}/xxdhack
+)
+
+foreach(item ${EMBEDDED_INPUT})
+    ProcessWithXXD(EMBEDDED_SOURCE ${item} ${CMAKE_CURRENT_BINARY_DIR})
+endforeach()
+
+## Setup binding source ##
+
+if (BINDING STREQUAL "MRI")
+    set(MRIVERSION "2.0" CACHE STRING "Version of MRI to link with")
+    pkg_check_modules(MRI REQUIRED ruby-${MRIVERSION})
+    list(APPEND DEFINES
+        BINDING_MRI
+    )
+    set(BINDING_HEADERS
+        binding-mri/binding-util.h
+        binding-mri/binding-types.h
+        binding-mri/serializable-binding.h
+        binding-mri/disposable-binding.h
+        binding-mri/sceneelement-binding.h
+        binding-mri/viewportelement-binding.h
+        binding-mri/flashable-binding.h
+    )
+    set(BINDING_SOURCE
+        binding-mri/binding-mri.cpp
+        binding-mri/binding-util.cpp
+        binding-mri/table-binding.cpp
+        binding-mri/etc-binding.cpp
+        binding-mri/bitmap-binding.cpp
+        binding-mri/font-binding.cpp
+        binding-mri/graphics-binding.cpp
+        binding-mri/input-binding.cpp
+        binding-mri/sprite-binding.cpp
+        binding-mri/viewport-binding.cpp
+        binding-mri/plane-binding.cpp
+        binding-mri/window-binding.cpp
+        binding-mri/tilemap-binding.cpp
+        binding-mri/audio-binding.cpp
+        binding-mri/module_rpg.cpp
+        binding-mri/filesystem-binding.cpp
+    )
+elseif(BINDING STREQUAL "MRUBY")
+    list(APPEND DEFINES
+        BINDING_MRUBY
+    )
+    set(BINDING_HEADERS
+        binding-mruby/binding-util.h
+        binding-mruby/disposable-binding.h
+        binding-mruby/flashable-binding.h
+        binding-mruby/binding-types.h
+        binding-mruby/sceneelement-binding.h
+        binding-mruby/viewportelement-binding.h
+        binding-mruby/serializable-binding.h
+        binding-mruby/mrb-ext/file.h
+        binding-mruby/mrb-ext/rwmem.h
+        binding-mruby/mrb-ext/marshal.h
+    )
+    set(BINDING_SOURCE
+        binding-mruby/binding-mruby.cpp
+        binding-mruby/binding-util.cpp
+        binding-mruby/window-binding.cpp
+        binding-mruby/bitmap-binding.cpp
+        binding-mruby/sprite-binding.cpp
+        binding-mruby/font-binding.cpp
+        binding-mruby/viewport-binding.cpp
+        binding-mruby/plane-binding.cpp
+        binding-mruby/audio-binding.cpp
+        binding-mruby/tilemap-binding.cpp
+        binding-mruby/etc-binding.cpp
+        binding-mruby/graphics-binding.cpp
+        binding-mruby/input-binding.cpp
+        binding-mruby/table-binding.cpp
+        binding-mruby/module_rpg.c
+        binding-mruby/mrb-ext/file.cpp
+        binding-mruby/mrb-ext/marshal.cpp
+        binding-mruby/mrb-ext/rwmem.cpp
+        binding-mruby/mrb-ext/kernel.cpp
+        binding-mruby/mrb-ext/time.cpp
+    )
+elseif(BINDING STREQUAL "NULL")
+    set(BINDING_SOURCE
+        binding-null/binding-null.cpp
+    )
+else()
+    message(FATAL_ERROR "Must choose a valid binding type.  MRI, MRUBY, or NULL")
+endif()
+
+## Setup main executable ##
+
+if(APPLE)
+    find_library(CARBON_LIBRARY Carbon)
+    find_library(IOKIT_LIBRARY IOKit)
+    mark_as_advanced(CARBON_LIBRARY IOKIT_LIBRARY)
+    list(APPEND PLATFORM_LIBRARIES
+        ${CARBON_LIBRARY}
+        ${IOKIT_LIBRARY}
+    )
+endif()
+
+link_directories(
+    ${SIGCXX_LIBRARY_DIRS}
+    ${PIXMAN_LIBRARY_DIRS}
+    ${PHYSFS_LIBRARY_DIRS}
+    ${SDL2_LIBRARY_DIRS} # Blindly assume other SDL bits are in same directory
+    ${Boost_LIBRARY_DIR}
+    ${MRI_LIBDIR}
+)
+
+add_executable(${PROJECT_NAME} MACOSX_BUNDLE
+    ${MAIN_HEADERS}
+    ${MAIN_SOURCE}
+    ${BINDING_SOURCE}
+    ${EMBEDDED_SOURCE}
+)
+
+target_compile_definitions(${PROJECT_NAME} PRIVATE
+    ${DEFINES}
+)
+target_include_directories(${PROJECT_NAME} PRIVATE
+    src
+    ${SIGCXX_INCLUDE_DIRS}
+    ${PIXMAN_INCLUDE_DIRS}
+    ${PHYSFS_INCLUDE_DIRS}
+    ${SDL2_INCLUDE_DIRS} # Blindly assume other SDL bits are in same directory
+    ${Boost_INCLUDE_DIR}
+    ${GLEW_INCLUDE_DIR}
+    ${MRI_INCLUDE_DIRS}
+    ${OPENAL_INCLUDE_DIR}
+)
+
+target_link_libraries(${PROJECT_NAME}
+    ${SIGCXX_LIBRARIES}
+    ${SDL2_LIBRARIES}
+    ${SDL2_IMAGE_LIBRARIES}
+    ${SDL2_TTF_LIBRARIES}
+    ${SDL_SOUND_LIBRARIES}
+    ${PHYSFS_LIBRARIES}
+    ${PIXMAN_LIBRARIES}
+    ${Boost_LIBRARIES}
+    ${MRI_LIBRARIES}
+    ${OPENAL_LIBRARY}
+    ${OPENGL_gl_LIBRARY}
+    ${GLEW_LIBRARY}
+    ${ZLIB_LIBRARY}
+
+    ${PLATFORM_LIBRARIES}
+)
+
+PostBuildMacBundle(${PROJECT_NAME} "" "${PLATFORM_COPY_LIBS}")
diff --git a/cmake/PrepUtils.cmake b/cmake/PrepUtils.cmake
new file mode 100644
index 0000000..35bd9f6
--- /dev/null
+++ b/cmake/PrepUtils.cmake
@@ -0,0 +1,38 @@
+if(APPLE)
+    function(PostBuildMacBundle target framework_list lib_list)
+        INCLUDE(BundleUtilities)
+        GET_TARGET_PROPERTY(_BIN_NAME ${target} LOCATION)
+        GET_DOTAPP_DIR(${_BIN_NAME} _BUNDLE_DIR)
+
+        set(_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${target}_prep.cmake")
+        file(WRITE ${_SCRIPT_FILE}
+            "# Generated Script file\n"
+            "include(BundleUtilities)\n"
+            "get_bundle_and_executable(\"\${BUNDLE_APP}\" bundle executable valid)\n"
+            "if(valid)\n"
+            "  set(framework_dest \"\${bundle}/Contents/Frameworks\")\n"
+            "  foreach(framework_path ${framework_list})\n"
+            "    get_filename_component(framework_name \${framework_path} NAME_WE)\n"
+            "    file(MAKE_DIRECTORY \"\${framework_dest}/\${framework_name}.framework/Versions/A/\")\n"
+            "    copy_resolved_framework_into_bundle(\${framework_path}/Versions/A/\${framework_name} \${framework_dest}/\${framework_name}.framework/Versions/A/\${framework_name})\n"
+            "  endforeach()\n"
+            "  foreach(lib ${lib_list})\n"
+            "    get_filename_component(lib_file \${lib} NAME)\n"
+            "    copy_resolved_item_into_bundle(\${lib} \${framework_dest}/\${lib_file})\n"
+            "  endforeach()\n"
+            "else()\n"
+            "  message(ERROR \"App Not found? \${BUNDLE_APP}\")\n"
+            "endif()\n"
+            "#fixup_bundle(\"\${BUNDLE_APP}\" \"\" \"\${DEP_LIB_DIR}\")\n"
+        )
+
+        ADD_CUSTOM_COMMAND(TARGET ${target}
+            POST_BUILD
+            COMMAND ${CMAKE_COMMAND} -DBUNDLE_APP="${_BUNDLE_DIR}" -P "${_SCRIPT_FILE}"
+        )
+    endfunction()
+else()
+    function(PostBuildMacBundle target framework_list lib_list)
+        # noop
+    endfunction()
+endif()
\ No newline at end of file

From 5b4e512dc6d9e9c0039752ba1d8eef260d8c2615 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:24:56 -0500
Subject: [PATCH 02/18] ulong isn't defined anywhere (maybe on linux it is..
 but not standard on OS X)

---
 binding-mri/binding-mri.cpp     | 2 +-
 binding-mruby/binding-mruby.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp
index 1cffac1..130c763 100644
--- a/binding-mri/binding-mri.cpp
+++ b/binding-mri/binding-mri.cpp
@@ -226,7 +226,7 @@ static void runRMXPScripts()
 		VALUE scriptString = rb_ary_entry(script, 2);
 
 		int result = Z_OK;
-		ulong bufferLen;
+		unsigned long bufferLen;
 
 		while (true)
 		{
diff --git a/binding-mruby/binding-mruby.cpp b/binding-mruby/binding-mruby.cpp
index cac342a..e93e752 100644
--- a/binding-mruby/binding-mruby.cpp
+++ b/binding-mruby/binding-mruby.cpp
@@ -303,7 +303,7 @@ runRMXPScripts(mrb_state *mrb, mrbc_context *ctx)
 		(void) scriptChksum;
 
 		int result = Z_OK;
-		ulong bufferLen;
+		unsigned long bufferLen;
 
 		while (true)
 		{

From adfbc5bb6466693957de57a67af5a9ad337e0dec Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:25:07 -0500
Subject: [PATCH 03/18] pull in missing include

---
 binding-mri/binding-util.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/binding-mri/binding-util.h b/binding-mri/binding-util.h
index 3fefcb9..9ccf675 100644
--- a/binding-mri/binding-util.h
+++ b/binding-mri/binding-util.h
@@ -24,6 +24,8 @@
 
 #include <ruby.h>
 
+#include "exception.h"
+
 enum RbException
 {
 	RGSS = 0,

From 2572a05e8b1642c57fa55af71594a30e437502b0 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:25:38 -0500
Subject: [PATCH 04/18] safely print errors by explicitly specifying a format
 string

---
 binding-mri/binding-util.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/binding-mri/binding-util.cpp b/binding-mri/binding-util.cpp
index d2d924a..1a850e7 100644
--- a/binding-mri/binding-util.cpp
+++ b/binding-mri/binding-util.cpp
@@ -94,7 +94,7 @@ void raiseRbExc(const Exception &exc)
 	RbData *data = getRbData();
 	VALUE excClass = data->exc[excToRbExc[exc.type]];
 
-	rb_raise(excClass, exc.msg.c_str());
+	rb_raise(excClass, "%s", exc.msg.c_str());
 }
 
 int

From 4a817f45e57ffa6bd9db1b987d3ebeb5d662d791 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:26:10 -0500
Subject: [PATCH 05/18] wrap not check in parenthesis so the check is done
 correctly.

---
 binding-mri/binding-util.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/binding-mri/binding-util.cpp b/binding-mri/binding-util.cpp
index 1a850e7..3a13e57 100644
--- a/binding-mri/binding-util.cpp
+++ b/binding-mri/binding-util.cpp
@@ -146,7 +146,7 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
 			VALUE *str = va_arg(ap, VALUE*);
 			VALUE tmp = *arg;
 
-			if (!rb_type(tmp) == RUBY_T_STRING)
+			if (!(rb_type(tmp) == RUBY_T_STRING))
 				rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
 
 			*str = tmp;
@@ -164,7 +164,7 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
 
 			VALUE tmp = *arg;
 
-			if (!rb_type(tmp) == RUBY_T_STRING)
+			if (!(rb_type(tmp) == RUBY_T_STRING))
 				rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
 
 			*s = RSTRING_PTR(tmp);
@@ -182,7 +182,7 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
 
 			VALUE tmp = *arg++;
 
-			if (!rb_type(tmp) == RUBY_T_STRING)
+			if (!(rb_type(tmp) == RUBY_T_STRING))
 				rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
 
 			*s = RSTRING_PTR(tmp);

From a3c9f53335cfe591568f9f529d1fe83cdf6e74df Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:26:49 -0500
Subject: [PATCH 06/18] GLSL 100 doesn't do automatic type conversions.. (int
 to float)

---
 shader/sprite.frag | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/shader/sprite.frag b/shader/sprite.frag
index 744c9d4..ab50876 100644
--- a/shader/sprite.frag
+++ b/shader/sprite.frag
@@ -33,7 +33,7 @@ void main()
 
 	/* Apply bush alpha by mathematical if */
 	float underBush = float(v_texCoord.y < bushDepth);
-	frag.a *= clamp(bushOpacity + underBush, 0, 1);
+	frag.a *= clamp(bushOpacity + underBush, 0.0, 1.0);
 	
 	gl_FragColor = frag;
 }

From 27ae261d0e3dc11199bc747bde2c85c66631c819 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:27:28 -0500
Subject: [PATCH 07/18] don't use base name it's destructive to the incoming
 string which you shouldn't modify as c_str() is const.

---
 src/config.cpp | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/config.cpp b/src/config.cpp
index 1775a55..e6f3354 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -101,7 +101,9 @@ void Config::readGameINI()
 {
 	if (!customScript.empty())
 	{
-		game.title = basename(customScript.c_str());
+        size_t pos = customScript.find_last_of("/\\");
+        if (pos == customScript.npos) pos = 0;
+        game.title = customScript.substr(pos);
 
 		return;
 	}
@@ -128,6 +130,9 @@ void Config::readGameINI()
 
 	strReplace(game.scripts, '\\', '/');
 
-	if (game.title.empty())
-		game.title = basename(gameFolder.c_str());
+	if (game.title.empty()) {
+        size_t pos = gameFolder.find_last_of("/\\");
+        if (pos == gameFolder.npos) pos = 0;
+        game.title = gameFolder.substr(pos);
+    }
 }

From eacc143ea0c1938109b02c83bc323b1a5d22285f Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:31:03 -0500
Subject: [PATCH 08/18] update extension usage..

nearly all of the previous required extensions are CORE in OpenGL 2.0
the remaining ones need to have fallback checks for ARB vs EXT vs APPLE
variants..
---
 src/bitmap.cpp    |  6 ++---
 src/gl-util.h     | 28 ++++++++++-----------
 src/glstate.cpp   | 14 +++++------
 src/main.cpp      | 63 ++++++++++++++++++++++++++++++++++++++---------
 src/perftimer.cpp |  2 +-
 5 files changed, 76 insertions(+), 37 deletions(-)

diff --git a/src/bitmap.cpp b/src/bitmap.cpp
index b0d6b94..7ebba37 100644
--- a/src/bitmap.cpp
+++ b/src/bitmap.cpp
@@ -873,7 +873,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
 				}
 
 				TEX::bind(p->gl.tex);
-				TEX::uploadSubImage(posRect.x, posRect.y, posRect.w, posRect.h, txtSurf->pixels, GL_BGRA_EXT);
+				TEX::uploadSubImage(posRect.x, posRect.y, posRect.w, posRect.h, txtSurf->pixels, GL_BGRA);
 
 				PixelStore::reset();
 			}
@@ -884,7 +884,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
 			TEXFBO &gpTF = shState->gpTexFBO(txtSurf->w, txtSurf->h);
 
 			TEX::bind(gpTF.tex);
-			TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_BGRA_EXT);
+			TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_BGRA);
 
 			FBO::bind(gpTF.fbo, FBO::Read);
 			p->bindFBO();
@@ -917,7 +917,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
 		shader.setOpacity(txtAlpha);
 
 		shState->bindTex();
-		TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_BGRA_EXT);
+		TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_BGRA);
 		TEX::setSmooth(true);
 
 		Quad &quad = shState->gpQuad();
diff --git a/src/gl-util.h b/src/gl-util.h
index 4383d49..d760672 100644
--- a/src/gl-util.h
+++ b/src/gl-util.h
@@ -109,19 +109,19 @@ namespace RBO
 	inline ID gen()
 	{
 		ID id;
-		glGenRenderbuffersEXT(1, &id.gl);
+		glGenRenderbuffers(1, &id.gl);
 
 		return id;
 	}
 
 	inline void del(ID id)
 	{
-		glDeleteRenderbuffersEXT(1, &id.gl);
+		glDeleteRenderbuffers(1, &id.gl);
 	}
 
 	inline void bind(ID id)
 	{
-		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, id.gl);
+		glBindRenderbuffer(GL_RENDERBUFFER, id.gl);
 	}
 
 	inline void unbind()
@@ -131,7 +131,7 @@ namespace RBO
 
 	inline void allocEmpty(GLsizei width, GLsizei height)
 	{
-		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, width, height);
+		glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
 	}
 }
 
@@ -155,25 +155,25 @@ namespace FBO
 	inline ID gen()
 	{
 		ID id;
-		glGenFramebuffersEXT(1, &id.gl);
+		glGenFramebuffers(1, &id.gl);
 
 		return id;
 	}
 
 	inline void del(ID id)
 	{
-		glDeleteFramebuffersEXT(1, &id.gl);
+		glDeleteFramebuffers(1, &id.gl);
 	}
 
 	inline void bind(ID id, Mode mode)
 	{
 		static const GLenum modes[] =
 		{
-			GL_DRAW_FRAMEBUFFER_EXT,
-			GL_READ_FRAMEBUFFER_EXT
+			GL_DRAW_FRAMEBUFFER,
+			GL_READ_FRAMEBUFFER
 		};
 
-		glBindFramebufferEXT(modes[mode], id.gl);
+		glBindFramebuffer(modes[mode], id.gl);
 	}
 
 	inline void unbind(Mode mode)
@@ -183,12 +183,12 @@ namespace FBO
 
 	inline void setTarget(TEX::ID target, unsigned colorAttach = 0)
 	{
-		glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorAttach, GL_TEXTURE_2D, target.gl, 0);
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorAttach, GL_TEXTURE_2D, target.gl, 0);
 	}
 
 	inline void setTarget(RBO::ID target, unsigned colorAttach = 0)
 	{
-		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorAttach, GL_RENDERBUFFER, target.gl);
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorAttach, GL_RENDERBUFFER, target.gl);
 	}
 
 	inline void blit(int srcX, int srcY,
@@ -203,9 +203,9 @@ namespace FBO
 			GL_LINEAR
 		};
 
-		glBlitFramebufferEXT(srcX, srcY, srcX+srcW, srcY+srcH,
-		                     dstX, dstY, dstX+dstW, dstY+dstH,
-		                     GL_COLOR_BUFFER_BIT, modes[mode]);
+		glBlitFramebuffer(srcX, srcY, srcX+srcW, srcY+srcH,
+						  dstX, dstY, dstX+dstW, dstY+dstH,
+						  GL_COLOR_BUFFER_BIT, modes[mode]);
 	}
 
 	inline void blit(int srcX, int srcY,
diff --git a/src/glstate.cpp b/src/glstate.cpp
index 677c9b7..f9c3557 100644
--- a/src/glstate.cpp
+++ b/src/glstate.cpp
@@ -71,21 +71,21 @@ void GLBlendMode::apply(const BlendType &value)
 
 	case BlendNormal :
 		glBlendEquation(GL_FUNC_ADD);
-		glBlendFuncSeparateEXT(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
-		                       GL_ONE,       GL_ONE_MINUS_SRC_ALPHA);
+		glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
+		                    GL_ONE,       GL_ONE_MINUS_SRC_ALPHA);
 		break;
 
 	case BlendAddition :
 		glBlendEquation(GL_FUNC_ADD);
-		glBlendFuncSeparateEXT(GL_SRC_ALPHA, GL_ONE,
-		                       GL_ONE,       GL_ONE);
+		glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE,
+		                    GL_ONE,       GL_ONE);
 		break;
 
 	case BlendSubstraction :
 		// FIXME Alpha calculation is untested
-		glBlendEquation(GL_FUNC_REVERSE_SUBTRACT_EXT);
-		glBlendFuncSeparateEXT(GL_SRC_ALPHA, GL_ONE,
-		                       GL_ONE,       GL_ONE);
+		glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
+		glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE,
+		                    GL_ONE,       GL_ONE);
 		break;
 	}
 }
diff --git a/src/main.cpp b/src/main.cpp
index 27b7533..3a251fe 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -39,21 +39,11 @@
 
 static const char *reqExt[] =
 {
-	"GL_ARB_fragment_shader",
-	"GL_ARB_shader_objects",
-	"GL_ARB_vertex_shader",
-	"GL_ARB_shading_language_100",
-	"GL_ARB_texture_non_power_of_two",
-	"GL_ARB_vertex_array_object",
-	"GL_ARB_vertex_buffer_object",
-	"GL_EXT_bgra",
-	"GL_EXT_blend_func_separate",
-	"GL_EXT_blend_subtract",
-	"GL_EXT_framebuffer_object",
-	"GL_EXT_framebuffer_blit",
+	// Everything we are using is CORE in OpenGL 2.0 except FBOs and VAOs which we'll handle in a special function
 	0
 };
 
+
 static void
 rgssThreadError(RGSSThreadData *rtData, const std::string &msg)
 {
@@ -77,6 +67,50 @@ printGLInfo()
 	Debug() << "GLSL Version :" << glGetStringInt(GL_SHADING_LANGUAGE_VERSION);
 }
 
+static bool
+setupOptionalGLExtensions(RGSSThreadData* threadData)
+{
+	if (!GLEW_ARB_framebuffer_object) {
+		if (!GLEW_EXT_framebuffer_object && !GLEW_EXT_framebuffer_blit) {
+			rgssThreadError(threadData, "GL extensions \"GL_ARB_framebuffer_object\" or compatible extensiosns GL_EXT_framebuffer_object and GL_EXT_framebuffer_blit are not present");
+			return false;
+		} else {
+			// setup compat
+			// From EXT_framebuffer_object
+			glGenRenderbuffers      = glGenRenderbuffersEXT;
+			glDeleteRenderbuffers   = glDeleteRenderbuffersEXT;
+			glBindRenderbuffer      = glBindRenderbufferEXT;
+			glRenderbufferStorage   = glRenderbufferStorageEXT;
+
+			glGenFramebuffers       = glGenFramebuffersEXT;
+			glDeleteFramebuffers    = glDeleteFramebuffersEXT;
+			glBindFramebuffer       = glBindFramebufferEXT;
+			glFramebufferTexture2D  = glFramebufferTexture2DEXT;
+			glFramebufferRenderbuffer = glFramebufferRenderbufferEXT;
+
+			// From EXT_framebuffer_blit
+			glBlitFramebuffer       = glBlitFramebufferEXT;
+		}
+	}
+	if (!GLEW_ARB_timer_query && GLEW_EXT_timer_query) {
+		glGetQueryObjecti64v = glGetQueryObjecti64vEXT;
+		glGetQueryObjectui64v = glGetQueryObjectui64vEXT;
+	}
+	if (!GLEW_ARB_vertex_array_object ) {
+		if (!GLEW_APPLE_vertex_array_object) {
+			rgssThreadError(threadData, "GL extensions \"GL_ARB_vertex_array_object\" or compatible extensiosn GL_APPLE_vertex_array_object are not present");
+			return false;
+		} else {
+			// setup compat
+			glBindVertexArray = glBindVertexArrayAPPLE;
+			// the cast is because apple's uses const GLuint* and ARB doesn't
+			glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glGenVertexArraysAPPLE;
+			glDeleteVertexArrays = glDeleteVertexArraysAPPLE;
+		}
+	}
+	return true;
+}
+
 int rgssThreadFun(void *userdata)
 {
 	RGSSThreadData *threadData = static_cast<RGSSThreadData*>(userdata);
@@ -132,6 +166,11 @@ int rgssThreadFun(void *userdata)
 			return 0;
 		}
 	}
+	/* Setup optional GL extensions */
+	if (!setupOptionalGLExtensions(threadData)) {
+		SDL_GL_DeleteContext(glCtx);
+		return 0;
+	}
 
 	SDL_GL_SetSwapInterval(threadData->config.vsync ? 1 : 0);
 
diff --git a/src/perftimer.cpp b/src/perftimer.cpp
index abe61a9..4fb450a 100644
--- a/src/perftimer.cpp
+++ b/src/perftimer.cpp
@@ -193,7 +193,7 @@ PerfTimer *createCPUTimer(int iter)
 
 PerfTimer *createGPUTimer(int iter)
 {
-	if (GLEW_EXT_timer_query)
+	if (GLEW_ARB_timer_query || GLEW_EXT_timer_query)
 	{
 		return new GPUTimerGLQuery(iter);
 	}

From af70e8c1ff3241861061256b9582c5771db87e61 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:31:24 -0500
Subject: [PATCH 09/18] correct ScanRow forward declares

---
 src/scene.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/scene.h b/src/scene.h
index 85a62ed..bcc9ca4 100644
--- a/src/scene.h
+++ b/src/scene.h
@@ -30,7 +30,7 @@
 class SceneElement;
 class Viewport;
 class Window;
-class ScanRow;
+struct ScanRow;
 struct TilemapPrivate;
 
 class Scene
@@ -63,7 +63,7 @@ protected:
 
 	friend class SceneElement;
 	friend class Window;
-	friend class ScanRow;
+	friend struct ScanRow;
 };
 
 class SceneElement

From 02738be4c5609a48d54226d2d8275cd61cfeba7c Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:31:58 -0500
Subject: [PATCH 10/18] CMake's GLEW finds parent dir.. not GL subdir.

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4f00dab..e862ff5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -340,7 +340,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE
     ${PHYSFS_INCLUDE_DIRS}
     ${SDL2_INCLUDE_DIRS} # Blindly assume other SDL bits are in same directory
     ${Boost_INCLUDE_DIR}
-    ${GLEW_INCLUDE_DIR}
+    ${GLEW_INCLUDE_DIR}/GL
     ${MRI_INCLUDE_DIRS}
     ${OPENAL_INCLUDE_DIR}
 )

From 7aa07630e4b2e028803a49a2141d4dcca6446bf6 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:32:12 -0500
Subject: [PATCH 11/18] can't sizeof an iVar in a static function

---
 src/etc-internal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/etc-internal.h b/src/etc-internal.h
index 64a6c74..5c3ab22 100644
--- a/src/etc-internal.h
+++ b/src/etc-internal.h
@@ -125,7 +125,7 @@ struct CVertex
 
 	static const void *colorOffset()
 	{
-		return (const void*) sizeof(pos);
+		return (const void*) sizeof(Vec2);
 	}
 };
 

From f106e31c6f53863cbdba92fbdf8b7096cf796457 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 16:36:00 -0500
Subject: [PATCH 12/18] add missed force32 option

---
 CMakeLists.txt | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e862ff5..d4e0dea 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,13 @@
 cmake_minimum_required(VERSION 2.8.11)
 Project(mkxp)
 
+## Setup options ##
+
+option(RGSS2 "Enable RGSS2" ON)
+option(FORCE32 "Force 32bit compile on 64bit OS" OFF)
+set(BINDING "MRI" CACHE STRING "The Binding Type (MRI, MRUBY, NULL)")
+set(EXTERNAL_LIB_PATH "" CACHE PATH "External precompiled lib prefix")
+
 ## Misc setup ##
 
 include(cmake/PrepUtils.cmake)
@@ -42,12 +49,6 @@ set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
 set(CMAKE_INSTALL_RPATH ${BIN_RPATH})
 set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
 
-## Setup options ##
-
-option(RGSS2 "Enable RGSS2" ON)
-set(BINDING "MRI" CACHE STRING "The Binding Type (MRI, MRUBY, NULL)")
-set(EXTERNAL_LIB_PATH "" CACHE PATH "External precompiled lib prefix")
-
 ## Locate core libs ##
 
 find_package(PkgConfig REQUIRED)

From f2bb0b2e79a8ffe5cffea528481dc1560568be91 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 17:19:05 -0500
Subject: [PATCH 13/18] initialize gameFolder to be SDL_GetBasePath()

---
 src/config.cpp | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/config.cpp b/src/config.cpp
index e6f3354..0d14a61 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -21,6 +21,8 @@
 
 #include "config.h"
 
+#include <SDL2/SDL_filesystem.h>
+
 #include <boost/program_options/options_description.hpp>
 #include <boost/program_options/parsers.hpp>
 #include <boost/program_options/variables_map.hpp>
@@ -46,7 +48,13 @@ Config::Config()
       solidFonts(false),
       gameFolder("."),
       allowSymlinks(false)
-{}
+{
+    char *dataDir = SDL_GetBasePath();
+    if (dataDir) {
+        gameFolder = dataDir;
+        SDL_free(dataDir);
+    }
+}
 
 void Config::read()
 {
@@ -101,9 +109,9 @@ void Config::readGameINI()
 {
 	if (!customScript.empty())
 	{
-        size_t pos = customScript.find_last_of("/\\");
-        if (pos == customScript.npos) pos = 0;
-        game.title = customScript.substr(pos);
+		size_t pos = customScript.find_last_of("/\\");
+		if (pos == customScript.npos) pos = 0;
+		game.title = customScript.substr(pos);
 
 		return;
 	}
@@ -131,8 +139,8 @@ void Config::readGameINI()
 	strReplace(game.scripts, '\\', '/');
 
 	if (game.title.empty()) {
-        size_t pos = gameFolder.find_last_of("/\\");
-        if (pos == gameFolder.npos) pos = 0;
-        game.title = gameFolder.substr(pos);
-    }
+		size_t pos = gameFolder.find_last_of("/\\");
+		if (pos == gameFolder.npos) pos = 0;
+		game.title = gameFolder.substr(pos);
+	}
 }

From f8e8d704b5ebd0025511f776d4acb0209384be6c Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 17:23:15 -0500
Subject: [PATCH 14/18] use copy construction to pass the config along so the
 main constructor gets run once.

---
 src/eventthread.h | 4 +++-
 src/main.cpp      | 3 +--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/eventthread.h b/src/eventthread.h
index 56423bf..490d3df 100644
--- a/src/eventthread.h
+++ b/src/eventthread.h
@@ -179,13 +179,15 @@ struct RGSSThreadData
 
 	RGSSThreadData(EventThread *ethread,
 	                 const char *argv0,
-	                 SDL_Window *window)
+	                 SDL_Window *window,
+				     const Config& newconf)
 	    : rqTerm(false),
 	      rqTermAck(false),
 	      ethread(ethread),
 	      argv0(argv0),
 	      window(window),
 	      sizeResoRatio(1, 1),
+	      config(newconf),
 	      rqScreenshot(false)
 	{}
 };
diff --git a/src/main.cpp b/src/main.cpp
index 3a251fe..049f5df 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -293,8 +293,7 @@ int main(int, char *argv[])
 	}
 
 	EventThread eventThread;
-	RGSSThreadData rtData(&eventThread, argv[0], win);
-	rtData.config = conf;
+	RGSSThreadData rtData(&eventThread, argv[0], win, conf);
 
 	/* Start RGSS thread */
 	SDL_Thread *rgssThread =

From 1120c60cae4e58eb6be4862d9dff402fb3569fa9 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 19:31:14 -0500
Subject: [PATCH 15/18] fix viewport resizing on screen resize.

---
 src/graphics.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/graphics.cpp b/src/graphics.cpp
index 2934073..a1875b1 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -469,8 +469,9 @@ struct GraphicsPrivate
 	{
 		if (threadData->windowSizeMsg.pollChange(&winSize.x, &winSize.y))
 		{
+			glState.viewport.init(IntRect(0, 0, winSize.x, winSize.y));
 			recalculateScreenSize();
-			screen.setScreenSize(scSize.x, scSize.y);
+			screen.setScreenSize(winSize.x, winSize.y);
 			updateScreenResoRatio();
 		}
 	}

From f42539e02bb3856732cb5690544717a2a55ed569 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 19:31:29 -0500
Subject: [PATCH 16/18] accept any alt for fullscreen switch

---
 src/eventthread.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/eventthread.cpp b/src/eventthread.cpp
index 4617cb0..71d8d84 100644
--- a/src/eventthread.cpp
+++ b/src/eventthread.cpp
@@ -145,7 +145,7 @@ void EventThread::process(RGSSThreadData &rtData)
 
 		case SDL_KEYDOWN :
 			if (event.key.keysym.scancode == SDL_SCANCODE_RETURN &&
-			    (event.key.keysym.mod & KMOD_LALT))
+			    (event.key.keysym.mod & KMOD_ALT))
 			{
 				setFullscreen(win, !fullscreen);
 				if (!fullscreen && havePendingTitle)

From e87bdb8a955dd551cd936220fd3dbfa61fec6eb7 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 19:56:20 -0500
Subject: [PATCH 17/18] cleaner approach to handling the viewport bug

---
 src/glstate.h    | 4 ++++
 src/graphics.cpp | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/glstate.h b/src/glstate.h
index bb1566f..9ef66de 100644
--- a/src/glstate.h
+++ b/src/glstate.h
@@ -52,6 +52,10 @@ struct GLProperty
 		set(value);
 	}
 
+	void refresh()
+	{
+		apply(current);
+	}
 private:
 	virtual void apply(const T &value) = 0;
 
diff --git a/src/graphics.cpp b/src/graphics.cpp
index a1875b1..9325c11 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -469,7 +469,8 @@ struct GraphicsPrivate
 	{
 		if (threadData->windowSizeMsg.pollChange(&winSize.x, &winSize.y))
 		{
-			glState.viewport.init(IntRect(0, 0, winSize.x, winSize.y));
+			// some GL drivers change the viewport on window resize
+			glState.viewport.refresh();
 			recalculateScreenSize();
 			screen.setScreenSize(winSize.x, winSize.y);
 			updateScreenResoRatio();

From a18497ca7badad7a14678a861a09ea6991713a00 Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 31 Dec 2013 21:03:53 -0500
Subject: [PATCH 18/18] change to exe dir on startup and add some extra guards
 around boost program option parsing.

---
 src/config.cpp | 25 +++++++++++--------------
 src/main.cpp   | 23 ++++++++++++++++-------
 2 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/src/config.cpp b/src/config.cpp
index 0d14a61..13eeb18 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -21,11 +21,10 @@
 
 #include "config.h"
 
-#include <SDL2/SDL_filesystem.h>
-
 #include <boost/program_options/options_description.hpp>
 #include <boost/program_options/parsers.hpp>
 #include <boost/program_options/variables_map.hpp>
+
 #include <fstream>
 
 #include "debugwriter.h"
@@ -48,13 +47,7 @@ Config::Config()
       solidFonts(false),
       gameFolder("."),
       allowSymlinks(false)
-{
-    char *dataDir = SDL_GetBasePath();
-    if (dataDir) {
-        gameFolder = dataDir;
-        SDL_free(dataDir);
-    }
-}
+{ }
 
 void Config::read()
 {
@@ -74,6 +67,9 @@ void Config::read()
     PO_DESC(allowSymlinks, bool) \
     PO_DESC(customScript, std::string)
 
+// Not gonna take your shit boost
+#define GUARD_ALL( exp ) try { exp } catch(...) {}
+
 #define PO_DESC(key, type) (#key, po::value< type >()->default_value(key))
 
 	po::options_description podesc;
@@ -86,13 +82,14 @@ void Config::read()
 	confFile.open("mkxp.conf");
 
 	po::variables_map vm;
-	po::store(po::parse_config_file(confFile, podesc, true), vm);
-	po::notify(vm);
+
+	if (confFile) {
+		GUARD_ALL( po::store(po::parse_config_file(confFile, podesc, true), vm); )
+		po::notify(vm);
+	}
 
 	confFile.close();
 
-// Not gonna take your shit boost
-#define GUARD_ALL( exp ) try { exp } catch(...) {}
 
 #undef PO_DESC
 #define PO_DESC(key, type) GUARD_ALL( key = vm[#key].as< type >(); )
@@ -128,7 +125,7 @@ void Config::readGameINI()
 	iniFile.open((iniPath).c_str());
 
 	po::variables_map vm;
-	po::store(po::parse_config_file(iniFile, podesc, true), vm);
+	GUARD_ALL( po::store(po::parse_config_file(iniFile, podesc, true), vm); )
 	po::notify(vm);
 
 	iniFile.close();
diff --git a/src/main.cpp b/src/main.cpp
index 049f5df..e6283e8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -232,18 +232,27 @@ int rgssThreadFun(void *userdata)
 
 int main(int, char *argv[])
 {
+	// initialize SDL first
+	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
+	{
+		Debug() << "Error initializing SDL:" << SDL_GetError();
+		
+		return 0;
+	}
+
+	// set working directory
+	char *dataDir = SDL_GetBasePath();
+	if (dataDir) {
+		chdir(dataDir);
+		SDL_free(dataDir);
+	}
+
+	// now we load the config
 	Config conf;
 
 	conf.read();
 	conf.readGameINI();
 
-	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
-	{
-		Debug() << "Error initializing SDL:" << SDL_GetError();
-
-		return 0;
-	}
-
 	int imgFlags = IMG_INIT_PNG | IMG_INIT_JPG;
 	if (IMG_Init(imgFlags) != imgFlags)
 	{