Merge remote-tracking branch 'MKXP/master' into new-mkxp

This commit is contained in:
Vinyl Darkscratch 2018-03-06 18:43:36 -08:00
commit 8921e23ba5
25 changed files with 326 additions and 141 deletions

View file

@ -205,6 +205,11 @@ set(MAIN_SOURCE
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})
## Setup embedded source ##
@ -405,6 +410,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE
)
target_include_directories(${PROJECT_NAME} PRIVATE
src
windows
${SIGCXX_INCLUDE_DIRS}
${PIXMAN_INCLUDE_DIRS}
${PHYSFS_INCLUDE_DIRS}

View file

@ -115,6 +115,15 @@ DEF_PLAY_STOP( se )
DEF_AUD_PROP_I(BGM_Volume)
DEF_AUD_PROP_I(SFX_Volume)
RB_METHOD(audioSetupMidi)
{
RB_UNUSED_PARAM;
shState->audio().setupMidi();
return Qnil;
}
RB_METHOD(audioReset)
{
RB_UNUSED_PARAM;
@ -158,6 +167,8 @@ audioBindingInit()
{
BIND_POS( bgm );
BIND_POS( bgs );
_rb_define_module_function(module, "setup_midi", audioSetupMidi);
}
BIND_PLAY_STOP( se )

View file

@ -85,6 +85,7 @@ RB_METHOD(mriP);
RB_METHOD(mkxpDataDirectory);
RB_METHOD(mkxpPuts);
RB_METHOD(mkxpRawKeyStates);
RB_METHOD(mkxpMouseInWindow);
RB_METHOD(mriRgssMain);
RB_METHOD(mriRgssStop);
@ -140,8 +141,18 @@ static void mriBindingInit()
_rb_define_module_function(mod, "data_directory", mkxpDataDirectory);
_rb_define_module_function(mod, "puts", mkxpPuts);
_rb_define_module_function(mod, "raw_key_states", mkxpRawKeyStates);
_rb_define_module_function(mod, "mouse_in_window", mkxpMouseInWindow);
/* Load global constants */
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
@ -222,6 +233,13 @@ RB_METHOD(mkxpRawKeyStates)
return str;
}
RB_METHOD(mkxpMouseInWindow)
{
RB_UNUSED_PARAM;
return rb_bool_new(EventThread::mouseState.inWindow);
}
static VALUE rgssMainCb(VALUE block)
{
rb_funcall2(block, rb_intern("call"), 0, 0);
@ -455,8 +473,9 @@ static void runRMXPScripts(BacktraceData &btData)
}
/* Execute preloaded scripts */
for (size_t i = 0; i < conf.preloadScripts.size(); ++i)
runCustomScript(conf.preloadScripts[i]);
for (std::set<std::string>::iterator i = conf.preloadScripts.begin();
i != conf.preloadScripts.end(); ++i)
runCustomScript(*i);
VALUE exc = rb_gv_get("$!");
if (exc != Qnil)

View file

@ -67,7 +67,7 @@ raiseRbExc(const Exception &exc);
/* 2.1 has added a new field (flags) to rb_data_type_t */
#include <ruby/version.h>
#if RUBY_API_VERSION_MINOR > 0
#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 1
/* TODO: can mkxp use RUBY_TYPED_FREE_IMMEDIATELY here? */
#define DEF_TYPE_FLAGS 0
#else

View file

@ -51,6 +51,12 @@
# vsync=true
# Override the game window title
# (default: none)
#
# windowTitle=Custom Title
# Enforce a static frame rate
# (0 = disabled)
#
@ -89,6 +95,26 @@
# subImageFix=false
# Enable framebuffer blitting if the driver is
# capable of it. Some drivers carry buggy
# implementations of this functionality, so
# disabling it can be used as a workaround
# (default: enabled)
#
# enableBlitting=true
# Limit the maximum size (width, height) of
# most textures mkxp will create (exceptions are
# rendering backbuffers and similar).
# If set to 0, the hardware maximum is used.
# This is useful for recording traces that can
# be played back on machines with lower specs.
# (default: 0)
#
# maxTextureSize=0
# Set the base path of the game to '/path/to/game'
# (default: executable directory)
#

View file

@ -1,48 +1,40 @@
uniform sampler2D inputTexture;
uniform float hueAdjust;
uniform sampler2D texture;
uniform mediump float hueAdjust;
varying vec2 v_texCoord;
/* Source: gamedev.stackexchange.com/a/59808/24839 */
vec3 rgb2hsv(vec3 c)
{
const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
/* Avoid divide-by-zero situations by adding a very tiny delta.
* Since we always deal with underlying 8-Bit color values, this
* should never mask a real value */
const float eps = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + eps)), d / (q.x + eps), q.x);
}
vec3 hsv2rgb(vec3 c)
{
const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
void main ()
{
const vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);
const vec4 kRGBToI = vec4 (0.596, -0.275, -0.321, 0.0);
const vec4 kRGBToQ = vec4 (0.212, -0.523, 0.311, 0.0);
vec4 color = texture2D (texture, v_texCoord.xy);
vec3 hsv = rgb2hsv(color.rgb);
const vec4 kYIQToR = vec4 (1.0, 0.956, 0.621, 0.0);
const vec4 kYIQToG = vec4 (1.0, -0.272, -0.647, 0.0);
const vec4 kYIQToB = vec4 (1.0, -1.107, 1.704, 0.0);
hsv.x += hueAdjust;
color.rgb = hsv2rgb(hsv);
/* Sample the input pixel */
vec4 color = texture2D (inputTexture, v_texCoord.xy);
/* Convert to YIQ */
float YPrime = dot (color, kRGBToYPrime);
float I = dot (color, kRGBToI);
float Q = dot (color, kRGBToQ);
/* Calculate the hue and chroma */
float hue = atan (Q, I);
float chroma = sqrt (I * I + Q * Q);
/* Make the user's adjustments */
hue += hueAdjust;
/* Remember old I and color */
float IOriginal = I;
vec4 coOriginal = color;
/* Convert back to YIQ */
Q = chroma * sin (hue);
I = chroma * cos (hue);
/* Convert back to RGB */
vec4 yIQ = vec4 (YPrime, I, Q, 0.0);
color.r = dot (yIQ, kYIQToR);
color.g = dot (yIQ, kYIQToG);
color.b = dot (yIQ, kYIQToB);
/* Save the result */
gl_FragColor = (IOriginal == 0.0) ? coOriginal : color;
gl_FragColor = color;
}

View file

@ -221,9 +221,9 @@ struct BitmapPrivate
surf = surfConv;
}
void onModified()
void onModified(bool freeSurface = true)
{
if (surface)
if (surface && freeSurface)
{
SDL_FreeSurface(surface);
surface = 0;
@ -768,6 +768,14 @@ void Bitmap::clear()
p->onModified();
}
static uint32_t &getPixelAt(SDL_Surface *surf, SDL_PixelFormat *form, int x, int y)
{
size_t offset = x*form->BytesPerPixel + y*surf->pitch;
uint8_t *bytes = (uint8_t*) surf->pixels + offset;
return *((uint32_t*) bytes);
}
Color Bitmap::getPixel(int x, int y) const
{
guardDisposed();
@ -790,9 +798,7 @@ Color Bitmap::getPixel(int x, int y) const
glState.viewport.pop();
}
size_t offset = x*p->format->BytesPerPixel + y*p->surface->pitch;
uint8_t *bytes = (uint8_t*) p->surface->pixels + offset;
uint32_t pixel = *((uint32_t*) bytes);
uint32_t pixel = getPixelAt(p->surface, p->format, x, y);
return Color((pixel >> p->format->Rshift) & 0xFF,
(pixel >> p->format->Gshift) & 0xFF,
@ -819,7 +825,16 @@ void Bitmap::setPixel(int x, int y, const Color &color)
p->addTaintedArea(IntRect(x, y, 1, 1));
p->onModified();
/* Setting just a single pixel is no reason to throw away the
* whole cached surface; we can just apply the same change */
if (p->surface)
{
uint32_t &surfPixel = getPixelAt(p->surface, p->format, x, y);
surfPixel = SDL_MapRGBA(p->format, pixel[0], pixel[1], pixel[2], pixel[3]);
}
p->onModified(false);
}
void Bitmap::hueChange(int hue)
@ -839,13 +854,10 @@ void Bitmap::hueChange(int hue)
quad.setTexPosRect(texRect, texRect);
quad.setColor(Vec4(1, 1, 1, 1));
/* Calculate hue parameter */
hue = wrapRange(hue, 0, 359);
float hueAdj = -((M_PI * 2) / 360) * hue;
HueShader &shader = shState->shaders().hue;
shader.bind();
shader.setHueAdjust(hueAdj);
/* Shader expects normalized value */
shader.setHueAdjust(wrapRange(hue, 0, 359) / 360.0f);
FBO::bind(newTex.fbo);
p->pushSetViewport(shader);

View file

@ -48,6 +48,12 @@ static std::string prefPath(const char *org, const char *app)
return str;
}
template<typename T>
std::set<T> setFromVec(const std::vector<T> &vec)
{
return std::set<T>(vec.begin(), vec.end());
}
typedef std::vector<std::string> StringVec;
namespace po = boost::program_options;
@ -66,11 +72,16 @@ void Config::read(int argc, char *argv[])
PO_DESC(fixedAspectRatio, bool, true) \
PO_DESC(smoothScaling, bool, true) \
PO_DESC(vsync, bool, true) \
PO_DESC(defScreenW, int, 0) \
PO_DESC(defScreenH, int, 0) \
PO_DESC(windowTitle, std::string, "") \
PO_DESC(fixedFramerate, int, 0) \
PO_DESC(frameSkip, bool, true) \
PO_DESC(syncToRefreshrate, bool, false) \
PO_DESC(solidFonts, bool, false) \
PO_DESC(subImageFix, bool, false) \
PO_DESC(enableBlitting, bool, true) \
PO_DESC(maxTextureSize, int, 0) \
PO_DESC(gameFolder, std::string, ".") \
PO_DESC(allowSymlinks, bool, false) \
PO_DESC(iconPath, std::string, "") \
@ -80,6 +91,27 @@ void Config::read(int argc, char *argv[])
// Not gonna take your shit boost
#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))
po::options_description podesc;
@ -125,7 +157,7 @@ void Config::read(int argc, char *argv[])
PO_DESC_ALL;
GUARD_ALL( preloadScripts = vm["preloadScript"].as<StringVec>(); );
GUARD_ALL( preloadScripts = setFromVec(vm["preloadScript"].as<StringVec>()); );
GUARD_ALL( fontSubs = vm["fontSub"].as<StringVec>(); );

View file

@ -24,6 +24,7 @@
#include <string>
#include <vector>
#include <set>
struct Config
{
@ -40,6 +41,7 @@ struct Config
int defScreenW;
int defScreenH;
std::string windowTitle;
int fixedFramerate;
bool frameSkip;
@ -48,6 +50,8 @@ struct Config
bool solidFonts;
bool subImageFix;
bool enableBlitting;
int maxTextureSize;
std::string gameFolder;
bool allowSymlinks;
@ -60,12 +64,22 @@ struct Config
int sourceCount;
} SE;
std::vector<std::string> preloadScripts;
bool useScriptNames;
std::string customScript;
std::set<std::string> preloadScripts;
std::vector<std::string> rtps;
std::vector<std::string> fontSubs;
std::vector<std::string> rubyLoadpaths;
/* Editor flags */
struct {
bool debug;
bool battleTest;
} editor;
/* Game INI contents */
struct {
std::string scripts;

View file

@ -28,6 +28,7 @@
#include <SDL_timer.h>
#include <SDL_thread.h>
#include <SDL_touch.h>
#include <SDL_rect.h>
#include <al.h>
#include <alc.h>
@ -90,6 +91,7 @@ enum
REQUEST_SETCURSORVISIBLE,
UPDATE_FPS,
UPDATE_SCREEN_RECT,
EVENT_COUNT
};
@ -137,6 +139,8 @@ void EventThread::process(RGSSThreadData &rtData)
bool displayingFPS = false;
bool cursorInWindow = false;
/* Will be updated eventually */
SDL_Rect gameScreen = { 0, 0, 0, 0 };
/* SDL doesn't send an initial FOCUS_GAINED event */
bool windowFocused = true;
@ -194,7 +198,7 @@ void EventThread::process(RGSSThreadData &rtData)
delete sMenu;
sMenu = 0;
updateCursorState(cursorInWindow && windowFocused);
updateCursorState(cursorInWindow && windowFocused, gameScreen);
}
continue;
@ -237,14 +241,14 @@ void EventThread::process(RGSSThreadData &rtData)
case SDL_WINDOWEVENT_ENTER :
cursorInWindow = true;
mouseState.inWindow = true;
updateCursorState(cursorInWindow && windowFocused && !sMenu);
updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen);
break;
case SDL_WINDOWEVENT_LEAVE :
cursorInWindow = false;
mouseState.inWindow = false;
updateCursorState(cursorInWindow && windowFocused && !sMenu);
updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen);
break;
@ -259,13 +263,13 @@ void EventThread::process(RGSSThreadData &rtData)
case SDL_WINDOWEVENT_FOCUS_GAINED :
windowFocused = true;
updateCursorState(cursorInWindow && windowFocused && !sMenu);
updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen);
break;
case SDL_WINDOWEVENT_FOCUS_LOST :
windowFocused = false;
updateCursorState(cursorInWindow && windowFocused && !sMenu);
updateCursorState(cursorInWindow && windowFocused && !sMenu, gameScreen);
resetInputStates();
break;
@ -292,7 +296,7 @@ void EventThread::process(RGSSThreadData &rtData)
if (!sMenu)
{
sMenu = new SettingsMenu(rtData);
updateCursorState(false);
updateCursorState(false, gameScreen);
}
sMenu->raise();
@ -316,14 +320,14 @@ void EventThread::process(RGSSThreadData &rtData)
if (fullscreen)
{
/* Prevent fullscreen flicker */
strncpy(pendingTitle, rtData.config.game.title.c_str(),
strncpy(pendingTitle, rtData.config.windowTitle.c_str(),
sizeof(pendingTitle));
havePendingTitle = true;
break;
}
SDL_SetWindowTitle(win, rtData.config.game.title.c_str());
SDL_SetWindowTitle(win, rtData.config.windowTitle.c_str());
}
break;
@ -440,6 +444,7 @@ void EventThread::process(RGSSThreadData &rtData)
case SDL_MOUSEMOTION :
mouseState.x = event.motion.x;
mouseState.y = event.motion.y;
updateCursorState(cursorInWindow, gameScreen);
break;
case SDL_FINGERDOWN :
@ -471,7 +476,7 @@ void EventThread::process(RGSSThreadData &rtData)
case REQUEST_MESSAGEBOX :
SDL_ShowSimpleMessageBox(event.user.code,
rtData.config.game.title.c_str(),
rtData.config.windowTitle.c_str(),
(const char*) event.user.data1, win);
free(event.user.data1);
msgBoxDone.set();
@ -479,7 +484,7 @@ void EventThread::process(RGSSThreadData &rtData)
case REQUEST_SETCURSORVISIBLE :
showCursor = event.user.code;
updateCursorState(cursorInWindow);
updateCursorState(cursorInWindow, gameScreen);
break;
case UPDATE_FPS :
@ -490,7 +495,7 @@ void EventThread::process(RGSSThreadData &rtData)
break;
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
* mode seems to cause flickering */
@ -504,6 +509,15 @@ void EventThread::process(RGSSThreadData &rtData)
SDL_SetWindowTitle(win, buffer);
break;
case UPDATE_SCREEN_RECT :
gameScreen.x = event.user.windowID;
gameScreen.y = event.user.code;
gameScreen.w = reinterpret_cast<intptr_t>(event.user.data1);
gameScreen.h = reinterpret_cast<intptr_t>(event.user.data2);
updateCursorState(cursorInWindow, gameScreen);
break;
}
}
@ -614,9 +628,13 @@ void EventThread::setFullscreen(SDL_Window *win, bool mode)
fullscreen = mode;
}
void EventThread::updateCursorState(bool inWindow)
void EventThread::updateCursorState(bool inWindow,
const SDL_Rect &screen)
{
if (inWindow)
SDL_Point pos = { mouseState.x, mouseState.y };
bool inScreen = inWindow && SDL_PointInRect(&pos, &screen);
if (inScreen)
SDL_ShowCursor(showCursor ? SDL_TRUE : SDL_FALSE);
else
SDL_ShowCursor(SDL_TRUE);
@ -722,6 +740,19 @@ void EventThread::notifyFrame()
SDL_PushEvent(&event);
}
void EventThread::notifyGameScreenChange(const SDL_Rect &screen)
{
/* We have to get a bit hacky here to fit the rectangle
* data into the user event struct */
SDL_Event event;
event.type = usrIdStart + UPDATE_SCREEN_RECT;
event.user.windowID = screen.x;
event.user.code = screen.y;
event.user.data1 = reinterpret_cast<void*>(screen.w);
event.user.data2 = reinterpret_cast<void*>(screen.h);
SDL_PushEvent(&event);
}
void SyncPoint::haltThreads()
{
if (mainSync.locked)

View file

@ -106,12 +106,16 @@ public:
/* RGSS thread calls this once per frame */
void notifyFrame();
/* Called on game screen (size / offset) changes */
void notifyGameScreenChange(const SDL_Rect &screen);
private:
static int eventFilter(void *, SDL_Event*);
void resetInputStates();
void setFullscreen(SDL_Window *, bool mode);
void updateCursorState(bool inWindow);
void updateCursorState(bool inWindow,
const SDL_Rect &screen);
bool fullscreen;
bool showCursor;

View file

@ -465,7 +465,7 @@ struct FontSetsCBData
};
static PHYSFS_EnumerateCallbackResult
fontSetEnumCB(void *data, const char *, const char *fname)
fontSetEnumCB (void *data, const char *dir, const char *fname)
{
FontSetsCBData *d = static_cast<FontSetsCBData*>(data);
@ -486,7 +486,7 @@ fontSetEnumCB(void *data, const char *, const char *fname)
return PHYSFS_ENUM_STOP;
char filename[512];
snprintf(filename, sizeof(filename), "Fonts/%s", fname);
snprintf(filename, sizeof(filename), "%s/%s", dir, fname);
PHYSFS_File *handle = PHYSFS_openRead(filename);
@ -503,6 +503,26 @@ fontSetEnumCB(void *data, const char *, const char *fname)
return PHYSFS_ENUM_OK;
}
/* Basically just a case-insensitive search
* for the folder "Fonts"... */
static PHYSFS_EnumerateCallbackResult
findFontsFolderCB(void *data, const char *, const char *fname)
{
size_t i = 0;
char buffer[512];
const char *s = fname;
while (*s && i < sizeof(buffer))
buffer[i++] = tolower(*s++);
buffer[i] = '\0';
if (strcmp(buffer, "fonts") == 0)
PHYSFS_enumerate(fname, fontSetEnumCB, data);
return PHYSFS_ENUM_OK;
}
void FileSystem::initFontSets(SharedFontState &sfs)
{
FontSetsCBData d = { p, &sfs };

View file

@ -23,6 +23,7 @@
#include "shader.h"
#include "etc.h"
#include "gl-fun.h"
#include "config.h"
#include <SDL_rect.h>
@ -111,7 +112,7 @@ GLState::Caps::Caps()
gl.GetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
}
GLState::GLState()
GLState::GLState(const Config &conf)
{
gl.Disable(GL_DEPTH_TEST);
@ -121,4 +122,7 @@ GLState::GLState()
scissorTest.init(false);
scissorBox.init(IntRect(0, 0, 640, 480));
program.init(0);
if (conf.maxTextureSize > 0)
caps.maxTexSize = conf.maxTextureSize;
}

View file

@ -27,6 +27,8 @@
#include <stack>
#include <assert.h>
struct Config;
template<typename T>
struct GLProperty
{
@ -130,7 +132,7 @@ public:
} caps;
GLState();
GLState(const Config &conf);
};
#endif // GLSTATE_H

View file

@ -101,11 +101,9 @@ struct PingPong
{
screenW = width;
screenH = height;
for (int i = 0; i < 2; ++i)
{
TEX::bind(rt[i].tex);
TEX::allocEmpty(width, height);
}
TEXFBO::allocEmpty(rt[i], width, height);
}
void startRender()
@ -486,9 +484,7 @@ struct GraphicsPrivate
bool frozen;
TEXFBO frozenScene;
TEXFBO currentScene;
Quad screenQuad;
TEXFBO transBuffer;
/* Global list of all live Disposables
* (disposed on reset) */
@ -516,17 +512,9 @@ struct GraphicsPrivate
TEXFBO::allocEmpty(frozenScene, scRes.x, scRes.y);
TEXFBO::linkFBO(frozenScene);
TEXFBO::init(currentScene);
TEXFBO::allocEmpty(currentScene, scRes.x, scRes.y);
TEXFBO::linkFBO(currentScene);
FloatRect screenRect(0, 0, scRes.x, scRes.y);
screenQuad.setTexPosRect(screenRect, screenRect);
TEXFBO::init(transBuffer);
TEXFBO::allocEmpty(transBuffer, scRes.x, scRes.y);
TEXFBO::linkFBO(transBuffer);
fpsLimiter.resetFrameAdjust();
obscuredTex = TEX::gen();
@ -539,9 +527,6 @@ struct GraphicsPrivate
~GraphicsPrivate()
{
TEXFBO::fini(frozenScene);
TEXFBO::fini(currentScene);
TEXFBO::fini(transBuffer);
}
void updateScreenResoRatio(RGSSThreadData *rtData)
@ -584,6 +569,9 @@ struct GraphicsPrivate
glState.viewport.refresh();
recalculateScreenSize(threadData);
updateScreenResoRatio(threadData);
SDL_Rect screen = { scOffset.x, scOffset.y, scSize.x, scSize.y };
threadData->ethread->notifyGameScreenChange(screen);
}
}
@ -755,8 +743,15 @@ void Graphics::transition(int duration,
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 */
p->compositeToBuffer(p->currentScene);
p->screen.composite();
/* If no transition bitmap is provided,
* we can use a simplified shader */
@ -769,7 +764,7 @@ void Graphics::transition(int duration,
shader.bind();
shader.applyViewportProj();
shader.setFrozenScene(p->frozenScene.tex);
shader.setCurrentScene(p->currentScene.tex);
shader.setCurrentScene(currentScene.tex);
shader.setTransMap(transMap->getGLTypes().tex);
shader.setVague(vague / 256.0f);
shader.setTexSize(p->scRes);
@ -780,7 +775,7 @@ void Graphics::transition(int duration,
shader.bind();
shader.applyViewportProj();
shader.setFrozenScene(p->frozenScene.tex);
shader.setCurrentScene(p->currentScene.tex);
shader.setCurrentScene(currentScene.tex);
shader.setTexSize(p->scRes);
}
@ -830,7 +825,7 @@ void Graphics::transition(int duration,
/* Draw the composed frame to a buffer first
* (we need this because we're skipping PingPong) */
FBO::bind(p->transBuffer.fbo);
FBO::bind(transBuffer.fbo);
FBO::clear();
p->screenQuad.draw();
@ -841,7 +836,7 @@ void Graphics::transition(int duration,
FBO::clear();
GLMeta::blitBeginScreen(Vec2i(p->winSize));
GLMeta::blitSource(p->transBuffer);
GLMeta::blitSource(transBuffer);
p->metaBlitBufferFlippedScaled();
GLMeta::blitEnd();
@ -984,17 +979,11 @@ void Graphics::resizeScreen(int width, int height)
p->screen.setResolution(width, height);
TEX::bind(p->frozenScene.tex);
TEX::allocEmpty(width, height);
TEX::bind(p->currentScene.tex);
TEX::allocEmpty(width, height);
TEXFBO::allocEmpty(p->frozenScene, width, height);
FloatRect screenRect(0, 0, width, height);
p->screenQuad.setTexPosRect(screenRect, screenRect);
TEX::bind(p->transBuffer.tex);
TEX::allocEmpty(width, height);
shState->eThread().requestWindowResize(width, height);
}

View file

@ -742,9 +742,6 @@ int Input::mouseX()
{
RGSSThreadData &rtData = shState->rtData();
if (!EventThread::mouseState.inWindow)
return -20;
return (EventThread::mouseState.x - rtData.screenOffset.x) * rtData.sizeResoRatio.x;
}
@ -752,9 +749,6 @@ int Input::mouseY()
{
RGSSThreadData &rtData = shState->rtData();
if (!EventThread::mouseState.inWindow)
return -20;
return (EventThread::mouseState.y - rtData.screenOffset.y) * rtData.sizeResoRatio.y;
}

View file

@ -41,6 +41,10 @@
#include "binding.h"
#ifdef __WINDOWS__
#include "resource.h"
#endif
#include "icon.png.xxd"
#ifdef STEAM
@ -106,6 +110,9 @@ int rgssThreadFun(void *userdata)
return 0;
}
if (!conf.enableBlitting)
gl.BlitFramebuffer = 0;
gl.ClearColor(0, 0, 0, 1);
gl.Clear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(win);
@ -165,6 +172,24 @@ static void showInitError(const std::string &msg)
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "OneShot", msg.c_str(), 0);
}
static void setupWindowIcon(const Config &conf, SDL_Window *win)
{
SDL_RWops *iconSrc;
if (conf.iconPath.empty())
iconSrc = SDL_RWFromConstMem(assets_icon_png, assets_icon_png_len);
else
iconSrc = SDL_RWFromFile(conf.iconPath.c_str(), "rb");
SDL_Surface *iconImg = IMG_Load_RW(iconSrc, SDL_TRUE);
if (iconImg)
{
SDL_SetWindowIcon(win, iconImg);
SDL_FreeSurface(iconImg);
}
}
int main(int argc, char *argv[])
{
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
@ -218,7 +243,10 @@ int main(int argc, char *argv[])
if (conf.screenMode)
return screenMain(conf);
int imgFlags = IMG_INIT_PNG;
if (conf.windowTitle.empty())
conf.windowTitle = conf.game.title;
int imgFlags = IMG_INIT_PNG | IMG_INIT_JPG;
if (IMG_Init(imgFlags) != imgFlags)
{
showInitError(std::string("Error initializing SDL_image: ") + SDL_GetError());
@ -246,23 +274,13 @@ int main(int argc, char *argv[])
return 0;
}
/* Setup application icon */
SDL_RWops *iconSrc;
if (conf.iconPath.empty())
iconSrc = SDL_RWFromConstMem(assets_icon_png, assets_icon_png_len);
else
iconSrc = SDL_RWFromFile(conf.iconPath.c_str(), "rb");
SDL_Surface *iconImg = IMG_Load_RW(iconSrc, SDL_TRUE);
SDL_Window *win;
Uint32 winFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_RESIZABLE; //| SDL_WINDOW_ALLOW_HIGHDPI;
if (conf.fullscreen)
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,
conf.defScreenW, conf.defScreenH, winFlags);
@ -272,11 +290,13 @@ int main(int argc, char *argv[])
return 0;
}
if (iconImg)
{
SDL_SetWindowIcon(win, iconImg);
SDL_FreeSurface(iconImg);
}
/* OSX and Windows have their own native ways of
* dealing with icons; don't interfere with them */
#ifdef __LINUX__
setupWindowIcon(conf, win);
#else
(void) setupWindowIcon;
#endif
ALCdevice *alcDev = alcOpenDevice(0);
@ -345,13 +365,13 @@ int main(int argc, char *argv[])
if (rtData.rqTermAck)
SDL_WaitThread(rgssThread, 0);
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);
if (!rtData.rgssErrorMsg.empty())
{
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);
}

View file

@ -297,6 +297,8 @@ processDirectories(RGSS_archiveData *data, BoostSet<std::string> &topLevel,
if (slash)
nameBuf[i] = '/';
break;
}
/* Check for more entries */

View file

@ -551,7 +551,6 @@ HueShader::HueShader()
ShaderBase::init();
GET_U(hueAdjust);
GET_U(inputTexture);
}
void HueShader::setHueAdjust(float value)
@ -559,11 +558,6 @@ void HueShader::setHueAdjust(float value)
gl.Uniform1f(u_hueAdjust, value);
}
void HueShader::setInputTexture(TEX::ID tex)
{
setTexUniform(u_inputTexture, 0, tex);
}
SimpleMatrixShader::SimpleMatrixShader()
{

View file

@ -241,10 +241,9 @@ public:
HueShader();
void setHueAdjust(float value);
void setInputTexture(TEX::ID tex);
private:
GLint u_hueAdjust, u_inputTexture;
GLint u_hueAdjust;
};
class SimpleMatrixShader : public ShaderBase

View file

@ -102,6 +102,7 @@ struct SharedStatePrivate
input(*threadData),
audio(*threadData),
oneshot(*threadData),
_glState(threadData->config),
fontState(threadData->config),
stampCounter(0)
{

View file

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

BIN
windows/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

1
windows/resource.h Normal file
View file

@ -0,0 +1 @@
#define IDI_APPICON 101

4
windows/resource.rc Normal file
View file

@ -0,0 +1,4 @@
#include <windows.h>
#include "resource.h"
IDI_APPICON ICON "icon.ico"