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:
parent
3fe9b1590c
commit
04c557f5e8
18 changed files with 1011 additions and 766 deletions
790
BBGE/Core.cpp
790
BBGE/Core.cpp
File diff suppressed because it is too large
Load diff
39
BBGE/Core.h
39
BBGE/Core.h
|
@ -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
82
BBGE/Window.cpp
Normal 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
53
BBGE/Window.h
Normal 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
110
BBGE/Window_SDL1.cpp
Normal 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
231
BBGE/Window_SDL2.cpp
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue