PixelGameEngine 1.16

Added Fullscreen mode
Maintains accurate mouse
Maintains aspect ratio of screen on window resize
Added extended numpad support
pull/113/head
Javidx9 6 years ago committed by GitHub
parent 7e72a7804c
commit 570e2cf84b
  1. 130
      olcPixelGameEngine.h

@ -2,7 +2,7 @@
olcPixelGameEngine.h
+-------------------------------------------------------------+
| OneLoneCoder Pixel Game Engine v1.15 |
| OneLoneCoder Pixel Game Engine v1.16 |
| "Like the command prompt console one, but not..." - javidx9 |
+-------------------------------------------------------------+
@ -73,6 +73,7 @@
Links
~~~~~
YouTube: https://www.youtube.com/javidx9
https://www.youtube.com/javidx9extra
Discord: https://discord.gg/WhwHUMV
Twitter: https://www.twitter.com/javidx9
Twitch: https://www.twitch.tv/javidx9
@ -117,9 +118,9 @@
~~~~~~
I'd like to extend thanks to Eremiell, slavka, gurkanctn, Phantim,
JackOJC, KrossX, Huhlig, Dragoneye, Appa, JustinRichardsMusic, SliceNDice
Ralakus, Gorbit99, raoul, joshinils & MagetzUb for advice, ideas and
testing, and I'd like to extend my appreciation to the 36K YouTube followers
and 2.3K Discord server members who give me the motivation to keep
Ralakus, Gorbit99, raoul, joshinils, benedani & MagetzUb for advice, ideas and
testing, and I'd like to extend my appreciation to the 40K YouTube followers,
22 Patreons and 2.6K Discord server members who give me the motivation to keep
going with all this :D
Special thanks to those who bring gifts!
@ -404,7 +405,7 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
PixelGameEngine();
public:
olc::rcode Construct(uint32_t screen_w, uint32_t screen_h, uint32_t pixel_w, uint32_t pixel_h);
olc::rcode Construct(uint32_t screen_w, uint32_t screen_h, uint32_t pixel_w, uint32_t pixel_h, bool full_screen = false);
olc::rcode Start();
public: // Override Interfaces
@ -484,8 +485,6 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
// Clears entire draw target to Pixel
void Clear(Pixel p);
void EnableFullScreen(bool bFullScreen, bool bMaintainAspect = true);
public: // Branding
std::string sAppName;
@ -506,6 +505,11 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
int32_t nMouseWheelDeltaCache = 0;
int32_t nWindowWidth = 0;
int32_t nWindowHeight = 0;
int32_t nViewX = 0;
int32_t nViewY = 0;
int32_t nViewW = 0;
int32_t nViewH = 0;
bool bFullScreen = false;
float fPixelX = 1.0f;
float fPixelY = 1.0f;
float fSubPixelOffsetX = 0.0f;
@ -545,6 +549,7 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
void olc_UpdateMouse(int32_t x, int32_t y);
void olc_UpdateMouseWheel(int32_t delta);
void olc_UpdateWindowSize(int32_t x, int32_t y);
void olc_UpdateViewport();
bool olc_OpenGLCreate();
void olc_ConstructFontSheet();
@ -1049,12 +1054,13 @@ namespace olc
olc::PGEX::pge = this;
}
olc::rcode PixelGameEngine::Construct(uint32_t screen_w, uint32_t screen_h, uint32_t pixel_w, uint32_t pixel_h)
olc::rcode PixelGameEngine::Construct(uint32_t screen_w, uint32_t screen_h, uint32_t pixel_w, uint32_t pixel_h, bool full_screen)
{
nScreenWidth = screen_w;
nScreenHeight = screen_h;
nPixelWidth = pixel_w;
nPixelHeight = pixel_h;
bFullScreen = full_screen;
fPixelX = 2.0f / (float)(nScreenWidth);
fPixelY = 2.0f / (float)(nScreenHeight);
@ -1656,24 +1662,31 @@ namespace olc
{ return true; }
//////////////////////////////////////////////////////////////////
void PixelGameEngine::EnableFullScreen(bool bFullScreen, bool bMaintainAspect)
void PixelGameEngine::olc_UpdateViewport()
{
if(bFullScreen)
{
// Go full Screen
int32_t ww = nScreenWidth * nPixelWidth;
int32_t wh = nScreenHeight * nPixelHeight;
float wasp = (float)ww / (float)wh;
}
else
nViewW = nWindowWidth;
nViewH = (float)nViewW / wasp;
if (nViewH > nWindowHeight)
{
// Go back to window
nViewH = nWindowHeight;
nViewW = (float)nViewH * wasp;
}
nViewX = (nWindowWidth - nViewW) / 2;
nViewY = (nWindowHeight - nViewH) / 2;
}
void PixelGameEngine::olc_UpdateWindowSize(int32_t x, int32_t y)
{
nWindowWidth = x;
nWindowHeight = y;
olc_UpdateViewport();
}
void PixelGameEngine::olc_UpdateMouseWheel(int32_t delta)
@ -1685,8 +1698,16 @@ namespace olc
{
// Mouse coords come in screen space
// But leave in pixel space
nMousePosXcache = (int32_t)(((float)x / (float)nWindowWidth) * (float)nScreenWidth);
nMousePosYcache = (int32_t)(((float)y / (float)nWindowHeight) * (float)nScreenHeight);
//if (bFullScreen)
{
// Full Screen mode may have a weird viewport we must clamp to
x -= nViewX;
y -= nViewY;
}
nMousePosXcache = (int32_t)(((float)x / (float)(nWindowWidth - (nViewX * 2)) * (float)nScreenWidth));
nMousePosYcache = (int32_t)(((float)y / (float)(nWindowHeight - (nViewY * 2)) * (float)nScreenHeight));
if (nMousePosXcache >= (int32_t)nScreenWidth)
nMousePosXcache = nScreenWidth - 1;
@ -1747,7 +1768,10 @@ namespace olc
{
XWindowAttributes gwa;
XGetWindowAttributes(olc_Display, olc_Window, &gwa);
glViewport(0, 0, gwa.width, gwa.height);
nWindowWidth = gwa.width;
nWindowHeight = gwa.height;
olc_UpdateViewport();
glClear(GL_COLOR_BUFFER_BIT); // Thanks Benedani!
}
else if (xev.type == ConfigureNotify)
{
@ -1759,11 +1783,17 @@ namespace olc
{
KeySym sym = XLookupKeysym(&xev.xkey, 0);
pKeyNewState[mapKeys[sym]] = true;
XKeyEvent *e = (XKeyEvent *)&xev; // Because DragonEye loves numpads
XLookupString(e, NULL, 0, &sym, NULL);
pKeyNewState[mapKeys[sym]] = true;
}
else if (xev.type == KeyRelease)
{
KeySym sym = XLookupKeysym(&xev.xkey, 0);
pKeyNewState[mapKeys[sym]] = false;
XKeyEvent *e = (XKeyEvent *)&xev;
XLookupString(e, NULL, 0, &sym, NULL);
pKeyNewState[mapKeys[sym]] = false;
}
else if (xev.type == ButtonPress)
{
@ -1869,6 +1899,7 @@ namespace olc
bAtomActive = false;
// Display Graphics
glViewport(nViewX, nViewY, nViewW, nViewH);
// TODO: This is a bit slow (especially in debug, but 100x faster in release mode???)
// Copy pixel array into texture
@ -2010,23 +2041,46 @@ namespace olc
RegisterClass(&wc);
nWindowWidth = (LONG)nScreenWidth * (LONG)nPixelWidth;
nWindowHeight = (LONG)nScreenHeight * (LONG)nPixelHeight;
// Define window furniture
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
DWORD dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE;
RECT rWndRect = { 0, 0, (LONG)nScreenWidth * (LONG)nPixelWidth, (LONG)nScreenHeight * (LONG)nPixelHeight };
DWORD dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE; // | WS_THICKFRAME;
int nCosmeticOffset = 30;
nViewW = nWindowWidth;
nViewH = nWindowHeight;
// Handle Fullscreen
if (bFullScreen)
{
dwExStyle = 0;
dwStyle = WS_VISIBLE | WS_POPUP;
nCosmeticOffset = 0;
HMONITOR hmon = MonitorFromWindow(olc_hWnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO mi = { sizeof(mi) };
if (!GetMonitorInfo(hmon, &mi)) return NULL;
nWindowWidth = mi.rcMonitor.right;
nWindowHeight = mi.rcMonitor.bottom;
}
olc_UpdateViewport();
// Keep client size as requested
RECT rWndRect = { 0, 0, nWindowWidth, nWindowHeight };
AdjustWindowRectEx(&rWndRect, dwStyle, FALSE, dwExStyle);
int width = rWndRect.right - rWndRect.left;
int height = rWndRect.bottom - rWndRect.top;
#ifdef UNICODE
olc_hWnd = CreateWindowEx(dwExStyle, L"OLC_PIXEL_GAME_ENGINE", L"", dwStyle,
30, 30, width, height, NULL, NULL, GetModuleHandle(nullptr), this);
nCosmeticOffset, nCosmeticOffset, width, height, NULL, NULL, GetModuleHandle(nullptr), this);
#else
olc_hWnd = CreateWindowEx(dwExStyle, "OLC_PIXEL_GAME_ENGINE", "", dwStyle,
30, 30, width, height, NULL, NULL, GetModuleHandle(nullptr), this);
nCosmeticOffset, nCosmeticOffset, width, height, NULL, NULL, GetModuleHandle(nullptr), this);
#endif
// Create Keyboard Mapping
@ -2080,6 +2134,8 @@ namespace olc
if (!(glRenderContext = wglCreateContext(glDeviceContext))) return false;
wglMakeCurrent(glDeviceContext, glRenderContext);
glViewport(nViewX, nViewY, nViewW, nViewH);
// Remove Frame cap
wglSwapInterval = (wglSwapInterval_t*)wglGetProcAddress("wglSwapIntervalEXT");
if (wglSwapInterval) wglSwapInterval(0);
@ -2156,6 +2212,32 @@ namespace olc
XMapWindow(olc_Display, olc_Window);
XStoreName(olc_Display, olc_Window, "OneLoneCoder.com - Pixel Game Engine");
if (bFullScreen) // Thanks DragonEye, again :D
{
Atom wm_state;
Atom fullscreen;
wm_state = XInternAtom(olc_Display, "_NET_WM_STATE", False);
fullscreen = XInternAtom(olc_Display, "_NET_WM_STATE_FULLSCREEN", False);
XEvent xev{ 0 };
xev.type = ClientMessage;
xev.xclient.window = olc_Window;
xev.xclient.message_type = wm_state;
xev.xclient.format = 32;
xev.xclient.data.l[0] = (bFullScreen ? 1 : 0); // the action (0: off, 1: on, 2: toggle)
xev.xclient.data.l[1] = fullscreen; // first property to alter
xev.xclient.data.l[2] = 0; // second property to alter
xev.xclient.data.l[3] = 0; // source indication
XMapWindow(olc_Display, olc_Window);
XSendEvent(olc_Display, DefaultRootWindow(olc_Display), False,
SubstructureRedirectMask | SubstructureNotifyMask, &xev);
XFlush(olc_Display);
XWindowAttributes gwa;
XGetWindowAttributes(olc_Display, olc_Window, &gwa);
nWindowWidth = gwa.width;
nWindowHeight = gwa.height;
olc_UpdateViewport();
}
// Create Keyboard Mapping
mapKeys[0x00] = Key::NONE;
mapKeys[0x61] = Key::A; mapKeys[0x62] = Key::B; mapKeys[0x63] = Key::C; mapKeys[0x64] = Key::D; mapKeys[0x65] = Key::E;

Loading…
Cancel
Save