1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-10-18 20:39:27 +00:00

Refactor Window functionality out of Core. Minor cleanups.

SDL2 impl seems to work, SDL1 impl finalization pending.
This commit is contained in:
fgenesis 2019-01-29 00:36:48 +01:00
commit 04c557f5e8
18 changed files with 1011 additions and 766 deletions

File diff suppressed because it is too large Load diff

View file

@ -28,12 +28,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "StateManager.h"
#include "Effects.h"
#include "Localization.h"
#include "Window.h"
#include "DarkLayer.h"
#include "GameKeys.h"
class ParticleEffect;
class Joystick;
@ -49,10 +49,9 @@ struct ScreenMode
struct CoreSettings
{
CoreSettings() { renderOn = true; updateOn = true; runInBackground = false; prebufferSounds = false; }
CoreSettings() { renderOn = true; runInBackground = false; prebufferSounds = false; }
bool renderOn;
bool runInBackground;
bool updateOn; // NOT IMPLEMENTED YET
bool prebufferSounds;
};
@ -89,7 +88,7 @@ struct Mouse
{
Mouse()
{
scrollWheel = scrollWheelChange = lastScrollWheel = 0;
scrollWheelChange = 0;
buttonsEnabled = true;
}
Vector position, lastPosition;
@ -99,7 +98,7 @@ struct Mouse
Vector change;
bool buttonsEnabled;
int scrollWheel, scrollWheelChange, lastScrollWheel;
int scrollWheelChange;
};
enum FollowCameraLock
@ -195,8 +194,21 @@ protected:
size_t iter;
};
class CoreWindow : public Window
{
public:
virtual ~CoreWindow();
protected:
virtual void onEvent(const SDL_Event& ev);
virtual void onResize(unsigned w, unsigned h);
virtual void onQuit();
};
class Core : public ActionMapper, public StateManager
{
friend class CoreWindow;
public:
// init
@ -278,7 +290,6 @@ public:
unsigned getTicks();
void initGraphics(int w, int h, int fullscreen=-1, int vsync=-1, int bpp=-1, int display=-1, int hz=-1); // pass 0x0 for desktop resolution
void updateWindowDrawSize(int w, int h);
Vector getGameCursorPosition();
@ -430,9 +441,12 @@ public:
void enumerateScreenModes(int display);
void enumerateScreenModesIfNecessary(int display = -1);
void resizeWindow(int w, int h, int full, int bpp, int vsync, int display, int hz);
std::vector<ScreenMode> screenModes;
void pollEvents(float dt);
void onEvent(const SDL_Event& event);
CoreSettings settings;
@ -448,6 +462,8 @@ public:
protected:
CoreWindow *window;
void updateCullData();
std::string userDataFolder;
@ -465,11 +481,8 @@ protected:
CountedPtr<Texture> doTextureAdd(const std::string &texture, const std::string &name, std::string internalTextureName);
void deleteRenderObjectMemory(RenderObject *r);
bool _hasFocus;
bool lib_graphics, lib_sound, lib_input;
Vector clearColor;
bool updateCursorFromMouse;
virtual void unloadDevice();
virtual void reloadDevice();
@ -486,8 +499,7 @@ protected:
bool initSoundLibrary(const std::string &defaultDevice);
bool initInputLibrary();
void initJoystickLibrary();
bool initGraphicsLibrary(int w, int h, bool fullscreen, bool vsync, int bpp, int display, int hz);
void createWindow(int w, int h, bool resizable, bool fullscreen, int bpp, int display);
void initGraphicsLibrary(int w, int h, bool fullscreen, bool vsync, int bpp, int display, int hz);
void shutdownInputLibrary();
void shutdownJoystickLibrary();
void shutdownGraphicsLibrary();
@ -516,13 +528,8 @@ protected:
int nowTicks, thenTicks;
int _vsync, _bpp, _refreshRate;
bool _fullscreen, _useDesktopResolution;
int winPosX, winPosY; // pre-fullscreen
int _lastEnumeratedDisplayIndex;
CountedPtr<Texture> texError;
virtual void onUpdate(float dt);
virtual void onRender(){}

82
BBGE/Window.cpp Normal file
View file

@ -0,0 +1,82 @@
#include "Window.h"
#include <SDL.h>
#include "Base.h"
Window::Window()
: _backend(_initBackend())
, _w(800), _h(600)
, _display(0)
, _bpp(32)
, _hz(60)
, _full(false)
, _vsync(false)
, _hasFocus(false)
{
}
void Window::handleInput()
{
SDL_Event event;
while ( SDL_PollEvent (&event) ) // This function is the same for SDL1 & 2 ...
{
switch(event.type)
{
case SDL_QUIT:
onQuit();
break;
}
_onEventImpl(event);
onEvent(event);
}
}
void Window::onEvent(const SDL_Event& ev)
{
}
void Window::onResize(unsigned w, unsigned h)
{
}
void Window::onQuit()
{
}
void Window::setFullscreen(bool on)
{
if(_full != on)
open(-1, -1, on, -1, -1, -1, -1);
}
void Window::open(int w, int h, int full, int bpp, int vsync, int display, int hz)
{
_fixOpenParams(w, h, full, bpp, vsync, display, hz);
if(isOpen())
_adjust(w, h, !!full, bpp, !!vsync, display, hz);
else
_open(w, h, !!full, bpp, !!vsync, display, hz);
_w = w;
_h = h;
_display = display;
_bpp = bpp;
}
void Window::_fixOpenParams(int& w, int& h, int& full, int& bpp, int& vsync, int& display, int& hz)
{
if(w < 0)
w = _w;
if(h < 0)
h = _h;
if(full < 0)
full = _full;
if(bpp < 0)
bpp = _bpp;
if(vsync < 0)
vsync = _vsync;
if(display < 0)
display = _display;
if(hz < 0)
hz = _hz;
}

53
BBGE/Window.h Normal file
View file

@ -0,0 +1,53 @@
#ifndef BBGE_WINDOW_H
#define BBGE_WINDOW_H
// SDL2 and 1.2-compatible window class.
// Note: With SDL1.2, only one window can exist.
union SDL_Event;
class Window
{
public:
Window();
virtual ~Window();
void handleInput();
// pass -1 to any to leave unchanged
void open(int w, int h, int full, int bpp, int vsync, int display, int hz);
void setGrabInput(bool on);
void present();
void setFullscreen(bool on);
void setTitle(const char *s);
inline bool hasFocus() const { return _hasFocus; }
int getDisplayIndex() const; // -1 on error/unsupported
int getRefreshRate() const { return _hz; }
void warpMouse(int x, int y);
void initSize();
inline bool isFullscreen() const { return _full; }
bool isOpen() const;
bool isDesktopResolution() const;
bool hasInputFocus() const;
protected:
virtual void onEvent(const SDL_Event& ev);
virtual void onResize(unsigned w, unsigned h);
virtual void onQuit();
static void *_initBackend();
void _ctor();
void _fixOpenParams(int& w, int& h, int& full, int& bpp, int& vsync, int& display, int& hz);
void _open(unsigned w, unsigned h, bool full, unsigned bpp, bool vsync, unsigned display, unsigned hz);
void _adjust(unsigned w, unsigned h, bool full, unsigned bpp, bool vsync, unsigned display, unsigned hz);
void _onEventImpl(const SDL_Event& ev);
void * const _backend; // backend-specific struct
unsigned _w, _h, _display, _bpp, _hz;
bool _full, _vsync;
bool _hasFocus;
};
#endif

110
BBGE/Window_SDL1.cpp Normal file
View file

@ -0,0 +1,110 @@
#include "Window.h"
#include <SDL.h>
#include <assert.h>
#include "OSFunctions.h"
#define SDL2_BACKEND SDL_VERSION_ATLEAST(2,0,0)
#if !SDL2_BACKEND // ... to end of file
static Window *s_theWindow; // since SDL1 can only create a single window, keep it around to make sure only one exists.
struct Backend
{
Backend()
: win(NULL)
{}
SDL_Surface *win;
};
#define BACKEND (static_cast<Backend*>(_backend))
#define WIN (BACKEND->win)
void *Window::_initBackend()
{
return new Backend;
}
void Window::_ctor()
{
assert(!s_theWindow);
s_theWindow = this;
}
Window::~Window()
{
delete BACKEND;
s_theWindow = NULL;
}
bool Window::_open(unsigned w, unsigned h, bool full, unsigned bpp, bool vsync, unsigned display, unsigned hz)
{
// ignored for SDL1
(void)display;
(void)hz;
assert(w && h);
// have to cast away constness, since SDL_putenv() might be #defined to
// putenv(), which takes a (char *), and freaks out newer GCC releases
// when you try to pass a (const!) string literal here... --ryan.
SDL_putenv((char *) "SDL_VIDEO_CENTERED=1");
// SDL 1.2 can't set this on an existing context
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vsync);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
Uint32 flags = SDL_OPENGL;
if(full)
flags |= SDL_FULLSCREEN;
SDL_Surface *surf = SDL_SetVideoMode(w, h, bpp, flags);
if(!surf)
return false;
WIN = surf;
return true;
}
void Window::warpMouse(int x, int y)
{
SDL_WarpMouse(x, y);
}
void Window::setGrabInput(bool on)
{
SDL_WM_GrabInput(on ? SDL_GRAB_ON : SDL_GRAB_OFF);
}
void Window::present()
{
SDL_GL_SwapBuffers();
}
void Window::setTitle(const char *s)
{
SDL_WM_SetCaption(s, s);
}
void Window::initIcon()
{
::initIcon(WIN);
}
int Window::getDisplayIndex() const
{
return -1;
}
bool Window::isDesktopResolution() const
{
return false;
}
bool Window::hasInputFocus() const
{
return ((SDL_GetAppState() & SDL_APPINPUTFOCUS) != 0);
}
#endif // !SDL2_BACKEND

231
BBGE/Window_SDL2.cpp Normal file
View file

@ -0,0 +1,231 @@
#include "Window.h"
#include <SDL.h>
#include <assert.h>
#include "OSFunctions.h"
#include "Base.h"
#define SDL2_BACKEND SDL_VERSION_ATLEAST(2,0,0)
#if SDL2_BACKEND
struct Backend
{
Backend()
: win(NULL)
, glctx(NULL)
{}
SDL_Window *win;
SDL_GLContext glctx;
};
#define BACKEND (static_cast<Backend*>(_backend))
#define WIN (BACKEND->win)
#define GLCTX (BACKEND->glctx)
void Window::_ctor()
{
}
void *Window::_initBackend()
{
return new Backend;
}
Window::~Window()
{
SDL_GL_MakeCurrent(WIN, NULL);
SDL_GL_DeleteContext(GLCTX);
SDL_DestroyWindow(WIN);
delete BACKEND;
}
bool Window::isOpen() const
{
return !!WIN;
}
static void setvsync(bool vsync)
{
if(vsync)
{
if(SDL_GL_SetSwapInterval(-1) != 0)
SDL_GL_SetSwapInterval(1);
}
else
SDL_GL_SetSwapInterval(0);
}
void Window::_open(unsigned w, unsigned h, bool full, unsigned bpp, bool vsync, unsigned display, unsigned hz)
{
assert(!WIN);
assert(!GLCTX);
# ifdef _DEBUG
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
# endif
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
if(full)
{
if(!w && !h)
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
else
flags |= SDL_WINDOW_FULLSCREEN;
}
int pos = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
WIN = SDL_CreateWindow("", pos, pos, w, h, flags);
if(!WIN)
exit_error("Failed to create window");
::initIcon(WIN);
GLCTX = SDL_GL_CreateContext(WIN);
if(!GLCTX)
exit_error("Failed to create GL context");
SDL_GL_MakeCurrent(WIN, GLCTX);
_adjust(w, h, full, bpp, vsync, display, hz);
}
void Window::_adjust(unsigned w, unsigned h, bool full, unsigned bpp, bool vsync, unsigned display, unsigned hz)
{
const bool useDesktop = w == 0 || h == 0;
SDL_DisplayMode displaymode;
if(SDL_GetDesktopDisplayMode(display, &displaymode) != 0)
{
// fail-safe
displaymode.w = 800;
displaymode.h = 600;
displaymode.driverdata = 0;
displaymode.refresh_rate = 0;
displaymode.format = 0;
display = 0;
}
setvsync(vsync);
if(useDesktop)
{
w = 800;
h = 600;
}
if(full)
{
int screenflags = useDesktop ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN;
displaymode.w = w;
displaymode.h = h;
// must not be already in fullscreen here, otherwise new display mode doesn't apply properly
SDL_SetWindowDisplayMode(WIN, &displaymode);
SDL_SetWindowFullscreen(WIN, screenflags);
}
else
{
SDL_SetWindowFullscreen(WIN, 0);
SDL_SetWindowSize(WIN, w, h);
int center = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
SDL_SetWindowPosition(WIN, center, center);
if(useDesktop)
SDL_MaximizeWindow(WIN);
}
}
void Window::initSize()
{
int ww, hh;
SDL_GetWindowSize(WIN, &ww, &hh);
onResize(ww, hh);
}
bool Window::isDesktopResolution() const
{
return !!(SDL_GetWindowFlags(WIN) & (SDL_WINDOW_MAXIMIZED || SDL_WINDOW_FULLSCREEN_DESKTOP));
}
void Window::setGrabInput(bool on)
{
SDL_SetWindowGrab(WIN, (SDL_bool)on);
}
void Window::present()
{
SDL_GL_SwapWindow(WIN);
}
int Window::getDisplayIndex() const
{
return SDL_GetWindowDisplayIndex(WIN);
}
bool Window::hasInputFocus() const
{
return (SDL_GetWindowFlags(WIN) & SDL_WINDOW_INPUT_FOCUS) != 0;
}
void Window::setTitle(const char *s)
{
SDL_SetWindowTitle(WIN, s);
}
void Window::warpMouse(int x, int y)
{
SDL_WarpMouseInWindow(WIN, x, y);
}
#ifndef KMOD_GUI
#define KMOD_GUI KMOD_META
#endif
void Window::_onEventImpl(const SDL_Event& ev)
{
switch(ev.type)
{
#if 0
case SDL_KEYDOWN:
{
#if __APPLE__
#if SDL_VERSION_ATLEAST(2, 0, 0)
if ((ev.key.keysym.sym == SDLK_q) && (ev.key.keysym.mod & KMOD_GUI))
#else
if ((ev.key.keysym.sym == SDLK_q) && (ev.key.keysym.mod & KMOD_META))
#endif
#else
if ((ev.key.keysym.sym == SDLK_F4) && (ev.key.keysym.mod & KMOD_ALT))
#endif
{
onQuit()
}
}
break;
#endif
case SDL_WINDOWEVENT:
{
switch(ev.window.event)
{
case SDL_WINDOWEVENT_FOCUS_GAINED:
_hasFocus = true;
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
_hasFocus = false;
break;
case SDL_WINDOWEVENT_CLOSE:
onQuit();
break;
case SDL_WINDOWEVENT_RESIZED:
onResize(ev.window.data1, ev.window.data2);
break;
}
}
break;
}
}
#endif // SDL2_BACKEND