diff --git a/README.md b/README.md index b43e3e6d..566a4e15 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ To alleviate possible porting of heavily Win32API reliant scripts, certain funct ### Graphics * The `Graphics` module has three additional properties: `fullscreen` represents the current fullscreen mode (`true` = fullscreen, `false` = windowed), `show_cursor` hides the system cursor inside the game window when `false`. `scale` represents the current scale factor of the screen, and can be set from `0.5` to `2`. -* The `Graphics` module has one additional function: `Graphics.screenshot(path)` will save a screenshot to `path` in BMP format. +* The `Graphics` module has two additional functions: `Graphics.screenshot(path)` will save a screenshot to `path` in BMP format. `Graphics.center` will move the window to the center of the screen. Commonly used Win32API routines will eventually have equivalent functions directly bound, like `Graphics.screenshot` for `Win32API.new('rubyscreen.dll,'TakeScreenshot','p','i')`. diff --git a/binding/graphics-binding.cpp b/binding/graphics-binding.cpp index 8ffee11b..235b275b 100644 --- a/binding/graphics-binding.cpp +++ b/binding/graphics-binding.cpp @@ -198,6 +198,14 @@ RB_METHOD(graphicsReset) return Qnil; } +RB_METHOD(graphicsCenter) +{ + RB_UNUSED_PARAM; + + shState->graphics().center(); + return Qnil; +} + RB_METHOD(graphicsPlayMovie) { RB_UNUSED_PARAM; @@ -267,6 +275,7 @@ void graphicsBindingInit() _rb_define_module_function(module, "fadein", graphicsFadein); _rb_define_module_function(module, "snap_to_bitmap", graphicsSnapToBitmap); _rb_define_module_function(module, "resize_screen", graphicsResizeScreen); + _rb_define_module_function(module, "center", graphicsCenter); INIT_GRA_PROP_BIND( Brightness, "brightness" ); diff --git a/src/eventthread.cpp b/src/eventthread.cpp index 100a2a90..53130a8d 100644 --- a/src/eventthread.cpp +++ b/src/eventthread.cpp @@ -84,6 +84,7 @@ enum REQUEST_WINRESIZE, REQUEST_WINREPOSITION, REQUEST_WINRENAME, + REQUEST_WINCENTER, REQUEST_MESSAGEBOX, REQUEST_SETCURSORVISIBLE, @@ -157,7 +158,9 @@ void EventThread::process(RGSSThreadData &rtData) bool resetting = false; int winW, winH; - int i; + int i, rc; + + SDL_DisplayMode dm = {0}; SDL_GetWindowSize(win, &winW, &winH); @@ -416,6 +419,14 @@ void EventThread::process(RGSSThreadData &rtData) SDL_SetWindowPosition(win, event.window.data1, event.window.data2); break; + case REQUEST_WINCENTER : + rc = SDL_GetDesktopDisplayMode(SDL_GetWindowDisplayIndex(win), &dm); + if (!rc) + SDL_SetWindowPosition(win, + (dm.w / 2) - (winW / 2), + (dm.h / 2) - (winH / 2)); + break; + case REQUEST_WINRENAME : rtData.config.windowTitle = (const char*)event.user.data1; SDL_SetWindowTitle(win, rtData.config.windowTitle.c_str()); @@ -607,6 +618,13 @@ void EventThread::requestWindowReposition(int x, int y) SDL_PushEvent(&event); } +void EventThread::requestWindowCenter() +{ + SDL_Event event; + event.type = usrIdStart + REQUEST_WINCENTER; + SDL_PushEvent(&event); +} + void EventThread::requestWindowRename(const char *title) { SDL_Event event; diff --git a/src/eventthread.h b/src/eventthread.h index 74dfbf05..ec745654 100644 --- a/src/eventthread.h +++ b/src/eventthread.h @@ -87,6 +87,7 @@ public: void requestFullscreenMode(bool mode); void requestWindowResize(int width, int height); void requestWindowReposition(int x, int y); + void requestWindowCenter(); void requestWindowRename(const char *title); void requestShowCursor(bool mode); diff --git a/src/graphics.cpp b/src/graphics.cpp index 7b13fccd..5bfc8c04 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -1039,6 +1039,11 @@ void Graphics::reset() setBrightness(255); } +void Graphics::center() +{ + p->threadData->ethread->requestWindowCenter(); +} + bool Graphics::getFullscreen() const { return p->threadData->ethread->getFullscreen(); @@ -1067,9 +1072,21 @@ double Graphics::getScale() const void Graphics::setScale(double factor) { factor = clamp(factor, 0.5, 2.0); + + if (factor == getScale()) return; + int widthpx = p->scRes.x * factor; int heightpx = p->scRes.y * factor; + + int cur_sz = p->scSize.x; shState->eThread().requestWindowResize(widthpx, heightpx); + + // Give things a little time to recalculate before continuing + for (int i = 0; i < p->frameRate; i++) + { + if (cur_sz != p->scSize.x) break; + update(); + } } Scene *Graphics::getScreen() const diff --git a/src/graphics.h b/src/graphics.h index eba250a8..d32035ae 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -58,6 +58,7 @@ public: void screenshot(const char *filename); void reset(); + void center(); /* Non-standard extension */ DECL_ATTR( Fullscreen, bool )