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) {