1#pragma region license_and_help 
  207#pragma region version_history 
  367#pragma region hello_world_example 
  417#pragma region std_includes 
  445#pragma region compiler_config 
  446#define USE_EXPERIMENTAL_FS 
  448#if _MSC_VER >= 1920 && _MSVC_LANG >= 201703L 
  449#undef USE_EXPERIMENTAL_FS 
  452#if defined(__linux__) || defined(__MINGW32__) || defined(__EMSCRIPTEN__) || defined(__FreeBSD__) || defined(__APPLE__) 
  453#if __cplusplus >= 201703L 
  454#undef USE_EXPERIMENTAL_FS 
  458#if !defined(OLC_KEYBOARD_UK) 
  459#define OLC_KEYBOARD_UK 
  463#if defined(USE_EXPERIMENTAL_FS) || defined(FORCE_EXPERIMENTAL_FS) 
  465#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING 
  466#include <experimental/filesystem> 
  467namespace _gfs = std::experimental::filesystem::v1;
 
  471namespace _gfs = std::filesystem;
 
  474#if defined(UNICODE) || defined(_UNICODE) 
  480#define UNUSED(x) (void)(x) 
  486#if defined(OLC_PGE_HEADLESS) 
  487#define OLC_PLATFORM_HEADLESS 
  488#define OLC_GFX_HEADLESS 
  489#if !defined(OLC_IMAGE_STB) && !defined(OLC_IMAGE_GDI) && !defined(OLC_IMAGE_LIBPNG) 
  490#define OLC_IMAGE_HEADLESS 
  495#if !defined(OLC_PLATFORM_WINAPI) && !defined(OLC_PLATFORM_X11) && !defined(OLC_PLATFORM_GLUT) && !defined(OLC_PLATFORM_EMSCRIPTEN) && !defined(OLC_PLATFORM_HEADLESS) 
  496#if !defined(OLC_PLATFORM_CUSTOM_EX) 
  498#define OLC_PLATFORM_WINAPI 
  500#if defined(__linux__) || defined(__FreeBSD__) 
  501#define OLC_PLATFORM_X11 
  503#if defined(__APPLE__) 
  504#define GL_SILENCE_DEPRECATION 
  505#define OLC_PLATFORM_GLUT 
  507#if defined(__EMSCRIPTEN__) 
  508#define OLC_PLATFORM_EMSCRIPTEN 
  514#if defined(OLC_PLATFORM_GLUT) || defined(OLC_PLATFORM_EMSCRIPTEN) 
  515#define PGE_USE_CUSTOM_START 
  521#if !defined(OLC_GFX_OPENGL10) && !defined(OLC_GFX_OPENGL33) && !defined(OLC_GFX_DIRECTX10) && !defined(OLC_GFX_HEADLESS) 
  522#if !defined(OLC_GFX_CUSTOM_EX) 
  523#if defined(OLC_PLATFORM_EMSCRIPTEN) 
  524#define OLC_GFX_OPENGL33 
  526#define OLC_GFX_OPENGL10 
  532#if !defined(OLC_IMAGE_STB) && !defined(OLC_IMAGE_GDI) && !defined(OLC_IMAGE_LIBPNG) && !defined(OLC_IMAGE_HEADLESS) 
  533#if !defined(OLC_IMAGE_CUSTOM_EX) 
  537#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) 
  538#define OLC_IMAGE_LIBPNG 
  544#if defined(__EMSCRIPTEN__) 
  545#include <emscripten.h> 
  546#define FILE_RESOLVE(url, file) emscripten_wget(url, file); emscripten_sleep(0) 
  548#define FILE_RESOLVE(url, file) 
  554#if !defined(OLC_PGE_HEADLESS) 
  555#if defined(OLC_PLATFORM_WINAPI)     
  557#if !defined(VC_EXTRALEAN) 
  560#if !defined(NOMINMAX) 
  565#if !defined(_WIN32_WINNT) 
  567#define _WIN32_WINNT 0x0600  
  569#define _WIN32_WINNT 0x0500  
  577#if defined(OLC_PLATFORM_X11) 
  585#if defined(OLC_PLATFORM_GLUT) 
  586#if defined(__linux__) 
  588#include <GL/freeglut_ext.h> 
  590#if defined(__APPLE__) 
  591#include <GLUT/glut.h> 
  592#include <objc/message.h> 
  593#include <objc/NSObjCRuntime.h> 
  598#if defined(OLC_PGE_HEADLESS) 
  610#if !defined(OLC_VECTOR2D_DEFINED) 
  620        static_assert(std::is_arithmetic<T>::value, 
"olc::v_2d<type> must be numeric");
 
  628        inline constexpr v_2d() = 
default;
 
  641        inline constexpr std::array<T, 2> 
a()
 const 
  643            return std::array<T, 2>{
x, 
y};
 
 
  647        inline constexpr auto area()
 const 
 
  655            return std::sqrt(
x * 
x + 
y * 
y);
 
 
  661            return x * 
x + 
y * 
y;
 
 
  668            return v_2d(
x * r, 
y * r);
 
 
  680            return v_2d(std::floor(
x), std::floor(
y));
 
 
  686            return v_2d(std::ceil(
x), std::ceil(
y));
 
 
  692            return v_2d(std::max(
x, v.
x), std::max(
y, v.
y));
 
 
  698            return v_2d(std::min(
x, v.
x), std::min(
y, v.
y));
 
 
  702        inline constexpr auto dot(
const v_2d& rhs)
 const 
  704            return this->x * rhs.
x + this->y * rhs.
y;
 
 
  710            return this->x * rhs.
y - this->y * rhs.
x;
 
 
  716            return v_2d(std::cos(
y) * 
x, std::sin(
y) * 
x);
 
 
  728            return this->
max(v1).
min(v2);
 
 
  734            return (*
this) * (
T(1.0 - t)) + (v1 * 
T(t));
 
 
  740            return (this->x == rhs.
x && this->y == rhs.
y);
 
 
  746            return (this->x != rhs.
x || this->y != rhs.
y);
 
 
  750        inline std::string 
str()
 const 
  752            return std::string(
"(") + std::to_string(this->x) + 
"," + std::to_string(this->y) + 
")";
 
 
  758            return (*
this) - 2.0 * (this->
dot(n) * n);
 
 
  765            return { 
static_cast<F>(this->
x), 
static_cast<F>(this->y) };
 
 
 
  770    template<
class TL, 
class TR>
 
  773        return v_2d(lhs * rhs.
x, lhs * rhs.
y);
 
 
  776    template<
class TL, 
class TR>
 
  779        return v_2d(lhs.
x * rhs, lhs.
y * rhs);
 
 
  782    template<
class TL, 
class TR>
 
  785        return v_2d(lhs.
x * rhs.
x, lhs.
y * rhs.
y);
 
 
  788    template<
class TL, 
class TR>
 
  796    template<
class TL, 
class TR>
 
  799        return v_2d(lhs / rhs.
x, lhs / rhs.
y);
 
 
  802    template<
class TL, 
class TR>
 
  805        return v_2d(lhs.
x / rhs, lhs.
y / rhs);
 
 
  808    template<
class TL, 
class TR>
 
  811        return v_2d(lhs.
x / rhs.
x, lhs.
y / rhs.
y);
 
 
  814    template<
class TL, 
class TR>
 
  825        return v_2d(+lhs.
x, +lhs.
y);
 
 
  829    template<
class TL, 
class TR>
 
  832        return v_2d(lhs + rhs.
x, lhs + rhs.
y);
 
 
  835    template<
class TL, 
class TR>
 
  838        return v_2d(lhs.
x + rhs, lhs.
y + rhs);
 
 
  841    template<
class TL, 
class TR>
 
  844        return v_2d(lhs.
x + rhs.
x, lhs.
y + rhs.
y);
 
 
  847    template<
class TL, 
class TR>
 
  854    template<
class TL, 
class TR>
 
  865        return v_2d(-lhs.
x, -lhs.
y);
 
 
  869    template<
class TL, 
class TR>
 
  872        return v_2d(lhs - rhs.
x, lhs - rhs.
y);
 
 
  875    template<
class TL, 
class TR>
 
  878        return v_2d(lhs.
x - rhs, lhs.
y - rhs);
 
 
  881    template<
class TL, 
class TR>
 
  884        return v_2d(lhs.
x - rhs.
x, lhs.
y - rhs.
y);
 
 
  887    template<
class TL, 
class TR>
 
  895    template<
class TL, 
class TR>
 
  898        return (lhs.
y < rhs.
y) || (lhs.
y == rhs.
y && lhs.
x < rhs.
x);
 
 
  901    template<
class TL, 
class TR>
 
  904        return (lhs.
y > rhs.
y) || (lhs.
y == rhs.
y && lhs.
x > rhs.
x);
 
 
 
  921#define OLC_VECTOR2D_DEFINED 1 
  929#pragma region pge_declaration 
  932    class PixelGameEngine;
 
  946#if !defined(OLC_IGNORE_PIXEL) 
  952            struct { uint8_t 
r; uint8_t 
g; uint8_t 
b; uint8_t 
a; };
 
 
  976    Pixel PixelF(
float red, 
float green, 
float blue, 
float alpha = 1.0f);
 
  998        A, 
B, 
C, 
D, 
E, 
F, 
G, 
H, 
I, 
J, 
K, 
L, 
M, 
N, 
O, 
P, 
Q, 
R, 
S, 
T, 
U, 
V, 
W, 
X, 
Y, 
Z,
 
  999        K0, 
K1, 
K2, 
K3, 
K4, 
K5, 
K6, 
K7, 
K8, 
K9,
 
 1000        F1, 
F2, 
F3, 
F4, 
F5, 
F6, 
F7, 
F8, 
F9, 
F10, 
F11, 
F12,
 
 1002        SPACE, 
TAB, 
SHIFT, 
CTRL, 
INS, 
DEL, 
HOME, 
END, 
PGUP, 
PGDN,
 
 1004        NP0, 
NP1, 
NP2, 
NP3, 
NP4, 
NP5, 
NP6, 
NP7, 
NP8, 
NP9,
 
 
 1013        static constexpr int32_t LEFT = 0;
 
 1014        static constexpr int32_t RIGHT = 1;
 
 1015        static constexpr int32_t MIDDLE = 2;
 
 
 1044        bool LoadPack(
const std::string& sFile, 
const std::string& sKey);
 
 1045        bool SavePack(
const std::string& sFile, 
const std::string& sKey);
 
 1049        struct sResourceFile { uint32_t nSize; uint32_t nOffset; };
 
 1050        std::map<std::string, sResourceFile> mapFiles;
 
 1051        std::ifstream baseFile;
 
 1052        std::vector<char> scramble(
const std::vector<char>& data, 
const std::string& key);
 
 1053        std::string makeposix(
const std::string& path);
 
 
 1106        static std::unique_ptr<olc::ImageLoader> 
loader;
 
 
 1156        void Create(uint32_t width, uint32_t height, 
bool filter = 
false, 
bool clamp = 
true);
 
 1162        std::unique_ptr<olc::Sprite> pSprite = 
nullptr;
 
 1163        std::unique_ptr<olc::Decal> pDecal = 
nullptr;
 
 
 1175        std::vector<olc::vf2d> 
uv;
 
 1176        std::vector<float> 
w;
 
 1177        std::vector<float> 
z;
 
 
 1201        std::array<float, 16> 
mvp = { {
 
 
 
 1239        virtual uint32_t   
CreateTexture(
const uint32_t width, 
const uint32_t height, 
const bool filtered = 
false, 
const bool clamp = 
true) = 0;
 
 
 1270    static std::unique_ptr<Renderer> renderer;
 
 1271    static std::unique_ptr<Platform> platform;
 
 1284            bool full_screen = 
false, 
bool vsync = 
false, 
bool cohesion = 
false, 
bool realwindow = 
false);
 
 1472        void DrawPolygonDecal(
olc::Decal* decal, 
const std::vector<olc::vf2d>& pos, 
const std::vector<olc::vf2d>& uv, 
const std::vector<olc::Pixel>& tint);
 
 1474        void DrawPolygonDecal(
olc::Decal* decal, 
const std::vector<olc::vf2d>& pos, 
const std::vector<float>& depth, 
const std::vector<olc::vf2d>& uv, 
const std::vector<olc::Pixel>& colours, 
const olc::Pixel tint);
 
 1510        const std::string 
GetKeySymbol(
const olc::Key pgekey, 
const bool modShift = 
false, 
const bool modCtrl = 
false, 
const bool modAlt = 
false) 
const;
 
 1514        void UpdateTextEntry();
 
 1515        void UpdateConsole();
 
 1528            const std::array<float, 16>& matModelView,
 
 1531            const std::vector<std::array<float, 4>>& pos,
 
 1532            const std::vector<std::array<float, 2>>& uv,
 
 1533            const std::vector<olc::Pixel>& col,
 
 1538            const std::array<float, 16>& matModelView,
 
 1539            const std::array<float, 4>& pos1,
 
 1540            const std::array<float, 4>& pos2,
 
 1545            const std::array<float, 16>& matModelView,
 
 1546            const std::array<float, 4>& pos,
 
 1547            const std::array<float, 4>& size,
 
 1556        float       fBlendFactor = 1.0f;
 
 1558        olc::vf2d   vInvScreenSize = { 1.0f / 256.0f, 1.0f / 240.0f };
 
 1562        int32_t     nMouseWheelDelta = 0;
 
 1565        int32_t     nMouseWheelDeltaCache = 0;
 
 1570        bool        bFullScreen = 
false;
 
 1572        bool        bHasInputFocus = 
false;
 
 1573        bool        bHasMouseFocus = 
false;
 
 1574        bool        bEnableVSYNC = 
false;
 
 1575        bool        bRealWindowMode = 
false;
 
 1576        bool        bResizeRequested = 
false;
 
 1578        float       fFrameTimer = 1.0f;
 
 1579        float       fLastElapsed = 0.0f;
 
 1580        int         nFrameCount = 0;
 
 1581        bool bSuspendTextureTransfer = 
false;
 
 1582        Renderable  fontRenderable;
 
 1583        std::vector<LayerDesc> vLayers;
 
 1584        uint8_t     nTargetLayer = 0;
 
 1585        uint32_t    nLastFPS = 0;
 
 1586        bool        bManualRenderEnable = 
false;
 
 1587        bool        bPixelCohesion = 
false;
 
 1591        bool        bHW3DDepthTest = 
true;
 
 1594        std::chrono::time_point<std::chrono::system_clock> m_tp1, m_tp2;
 
 1595        std::vector<olc::vi2d> vFontSpacing;
 
 1597        std::vector<std::string> vDroppedFiles;
 
 1598        std::vector<std::string> vDroppedFilesCache;
 
 1603        bool bConsoleShow = 
false;
 
 1604        bool bConsoleSuspendTime = 
false;
 
 1606        std::stringstream ssConsoleOutput;
 
 1607        std::streambuf* sbufOldCout = 
nullptr;
 
 1610        olc::vf2d vConsoleCharacterScale = { 1.0f, 2.0f };
 
 1611        std::vector<std::string> sConsoleLines;
 
 1612        std::list<std::string> sCommandHistory;
 
 1613        std::list<std::string>::iterator sCommandHistoryIt;
 
 1616        bool bTextEntryEnable = 
false;
 
 1617        std::string sTextEntryString = 
"";
 
 1618        int32_t nTextEntryCursor = 0;
 
 1619        std::unordered_map<olc::Key, std::tuple<std::string, std::string, std::string, std::string>> vKeyboardMap;
 
 1624        bool        pKeyNewState[256] = { 0 };
 
 1625        bool        pKeyOldState[256] = { 0 };
 
 1626        HWButton    pKeyboardState[256] = { 0 };
 
 1633        std::vector<int32_t>    vKeyPressCache[2];
 
 1634        uint32_t                nKeyPressCacheTarget = 0;
 
 1637        void        EngineThread();
 
 1642        static std::atomic<bool> bAtomActive;
 
 1659        void olc_DropFiles(int32_t x, int32_t y, 
const std::vector<std::string>& vFiles);
 
 1676        std::vector<olc::PGEX*> vExtensions;
 
 
 1704#pragma region opengl33_iface 
 1709#if defined(OLC_GFX_OPENGL33) 
 1711#if defined(OLC_PLATFORM_WINAPI) 
 1713#define CALLSTYLE __stdcall 
 1716#if defined(__linux__) || defined(__FreeBSD__) 
 1720#if defined(OLC_PLATFORM_X11) 
 1727#if defined(__APPLE__) 
 1728#define GL_SILENCE_DEPRECATION 
 1729#include <OpenGL/OpenGL.h> 
 1730#include <OpenGL/gl.h> 
 1731#include <OpenGL/glu.h> 
 1734#if defined(OLC_PLATFORM_EMSCRIPTEN) 
 1736#include <GLES2/gl2.h> 
 1737#define GL_GLEXT_PROTOTYPES 
 1738#include <GLES2/gl2ext.h> 
 1739#include <emscripten/emscripten.h> 
 1741#define GL_CLAMP GL_CLAMP_TO_EDGE 
 1746    typedef char GLchar;
 
 1747    typedef ptrdiff_t GLsizeiptr;
 
 1749    typedef GLuint CALLSTYLE locCreateShader_t(GLenum type);
 
 1750    typedef GLuint CALLSTYLE locCreateProgram_t(
void);
 
 1751    typedef void CALLSTYLE locDeleteShader_t(GLuint shader);
 
 1752    typedef void CALLSTYLE locCompileShader_t(GLuint shader);
 
 1753    typedef void CALLSTYLE locLinkProgram_t(GLuint program);
 
 1754    typedef void CALLSTYLE locDeleteProgram_t(GLuint program);
 
 1755    typedef void CALLSTYLE locAttachShader_t(GLuint program, GLuint shader);
 
 1756    typedef void CALLSTYLE locBindBuffer_t(GLenum target, GLuint buffer);
 
 1757    typedef void CALLSTYLE locBufferData_t(GLenum target, GLsizeiptr size, 
const void* data, GLenum usage);
 
 1758    typedef void CALLSTYLE locGenBuffers_t(GLsizei n, GLuint* buffers);
 
 1759    typedef void CALLSTYLE locVertexAttribPointer_t(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, 
const void* pointer);
 
 1760    typedef void CALLSTYLE locEnableVertexAttribArray_t(GLuint index);
 
 1761    typedef void CALLSTYLE locUseProgram_t(GLuint program);
 
 1762    typedef void CALLSTYLE locBindVertexArray_t(GLuint array);
 
 1763    typedef void CALLSTYLE locGenVertexArrays_t(GLsizei n, GLuint* arrays);
 
 1764    typedef void CALLSTYLE locGetShaderInfoLog_t(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
 
 1765    typedef GLint CALLSTYLE locGetUniformLocation_t(GLuint program, 
const GLchar* name);
 
 1766    typedef void CALLSTYLE locUniform1f_t(GLint location, GLfloat v0);
 
 1767    typedef void CALLSTYLE locUniform1i_t(GLint location, GLint v0);
 
 1768    typedef void CALLSTYLE locUniform2fv_t(GLint location, GLsizei count, 
const GLfloat* value);
 
 1769    typedef void CALLSTYLE locUniform4fv_t(GLint location, GLsizei count, 
const GLfloat* value);
 
 1770    typedef void CALLSTYLE locUniformMatrix4fv_t(GLint location, GLsizei count, GLboolean trasnpose, 
const GLfloat* value);
 
 1771    typedef void CALLSTYLE locActiveTexture_t(GLenum texture);
 
 1772    typedef void CALLSTYLE locGenFrameBuffers_t(GLsizei n, GLuint* ids);
 
 1773    typedef void CALLSTYLE locBindFrameBuffer_t(GLenum target, GLuint fb);
 
 1774    typedef GLenum CALLSTYLE locCheckFrameBufferStatus_t(GLenum target);
 
 1775    typedef void CALLSTYLE locDeleteFrameBuffers_t(GLsizei n, 
const GLuint* fbs);
 
 1776    typedef void CALLSTYLE locFrameBufferTexture2D_t(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
 
 1777    typedef void CALLSTYLE locDrawBuffers_t(GLsizei n, 
const GLenum* bufs);
 
 1778    typedef void CALLSTYLE locBlendFuncSeparate_t(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
 
 1780#if defined(OLC_PLATFORM_WINAPI) 
 1781    typedef void __stdcall locSwapInterval_t(GLsizei n);
 
 1784#if defined(OLC_PLATFORM_X11) 
 1785    typedef int(locSwapInterval_t)(X11::Display* dpy, X11::GLXDrawable drawable, 
int interval);
 
 1788#if defined(OLC_PLATFORM_EMSCRIPTEN) 
 1789    typedef void CALLSTYLE locShaderSource_t(GLuint shader, GLsizei count, 
const GLchar* 
const* 
string, 
const GLint* length);
 
 1790    typedef EGLBoolean(locSwapInterval_t)(EGLDisplay display, EGLint interval);
 
 1792    typedef void CALLSTYLE locShaderSource_t(GLuint shader, GLsizei count, 
const GLchar** 
string, 
const GLint* length);
 
 1806#ifdef OLC_PGE_APPLICATION 
 1807#undef OLC_PGE_APPLICATION 
 1813#pragma region pge_implementation 
 1819#if !defined(OLC_IGNORE_PIXEL) 
 1825    Pixel::Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
 
 1827        n = red | (green << 8) | (blue << 16) | (alpha << 24);
 
 1847        float fR = std::min(255.0f, std::max(0.0f, 
float(
r) * i));
 
 1848        float fG = std::min(255.0f, std::max(0.0f, 
float(
g) * i));
 
 1849        float fB = std::min(255.0f, std::max(0.0f, 
float(
b) * i));
 
 1850        return Pixel(uint8_t(fR), uint8_t(fG), uint8_t(fB), 
a);
 
 1855        float fR = std::min(255.0f, std::max(0.0f, 
float(
r) / i));
 
 1856        float fG = std::min(255.0f, std::max(0.0f, 
float(
g) / i));
 
 1857        float fB = std::min(255.0f, std::max(0.0f, 
float(
b) / i));
 
 1858        return Pixel(uint8_t(fR), uint8_t(fG), uint8_t(fB), 
a);
 
 1863        this->
r = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
r) * i)));
 
 1864        this->
g = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
g) * i)));
 
 1865        this->
b = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
b) * i)));
 
 1871        this->
r = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
r) / i)));
 
 1872        this->
g = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
g) / i)));
 
 1873        this->
b = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
b) / i)));
 
 1879        uint8_t nR = uint8_t(std::min(255, std::max(0, 
int(
r) + 
int(p.r))));
 
 1880        uint8_t nG = uint8_t(std::min(255, std::max(0, 
int(
g) + 
int(p.g))));
 
 1881        uint8_t nB = uint8_t(std::min(255, std::max(0, 
int(
b) + 
int(p.b))));
 
 1882        return Pixel(nR, nG, nB, 
a);
 
 1887        uint8_t nR = uint8_t(std::min(255, std::max(0, 
int(
r) - 
int(p.r))));
 
 1888        uint8_t nG = uint8_t(std::min(255, std::max(0, 
int(
g) - 
int(p.g))));
 
 1889        uint8_t nB = uint8_t(std::min(255, std::max(0, 
int(
b) - 
int(p.b))));
 
 1890        return Pixel(nR, nG, nB, 
a);
 
 1895        this->
r = uint8_t(std::min(255, std::max(0, 
int(
r) + 
int(p.r))));
 
 1896        this->
g = uint8_t(std::min(255, std::max(0, 
int(
g) + 
int(p.g))));
 
 1897        this->
b = uint8_t(std::min(255, std::max(0, 
int(
b) + 
int(p.b))));
 
 1903        this->
r = uint8_t(std::min(255, std::max(0, 
int(
r) - 
int(p.r))));
 
 1904        this->
g = uint8_t(std::min(255, std::max(0, 
int(
g) - 
int(p.g))));
 
 1905        this->
b = uint8_t(std::min(255, std::max(0, 
int(
b) - 
int(p.b))));
 
 1911        uint8_t nR = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
r) * 
float(p.r) / 255.0f)));
 
 1912        uint8_t nG = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
g) * 
float(p.g) / 255.0f)));
 
 1913        uint8_t nB = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
b) * 
float(p.b) / 255.0f)));
 
 1914        uint8_t nA = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
a) * 
float(p.a) / 255.0f)));
 
 1915        return Pixel(nR, nG, nB, nA);
 
 1920        this->
r = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
r) * 
float(p.r) / 255.0f)));
 
 1921        this->
g = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
g) * 
float(p.g) / 255.0f)));
 
 1922        this->
b = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
b) * 
float(p.b) / 255.0f)));
 
 1923        this->
a = uint8_t(std::min(255.0f, std::max(0.0f, 
float(
a) * 
float(p.a) / 255.0f)));
 
 1929        uint8_t nR = uint8_t(std::min(255, std::max(0, 255 - 
int(
r))));
 
 1930        uint8_t nG = uint8_t(std::min(255, std::max(0, 255 - 
int(
g))));
 
 1931        uint8_t nB = uint8_t(std::min(255, std::max(0, 255 - 
int(
b))));
 
 1932        return Pixel(nR, nG, nB, 
a);
 
 1935    Pixel 
PixelF(
float red, 
float green, 
float blue, 
float alpha)
 
 1937        return Pixel(uint8_t(red * 255.0f), uint8_t(green * 255.0f), uint8_t(blue * 255.0f), uint8_t(alpha * 255.0f));
 
 1942        return (p2 * t) + p1 * (1.0f - t);
 
 1993            if (x >= 0 && x < width && y >= 0 && y < 
height)
 
 1996                return Pixel(0, 0, 0, 0);
 
 2009        if (x >= 0 && x < width && y >= 0 && y < 
height)
 
 2020        int32_t sx = std::min((int32_t)((x * (
float)
width)), 
width - 1);
 
 2021        int32_t sy = std::min((int32_t)((y * (
float)
height)), 
height - 1);
 
 2032        u = u * 
width - 0.5f;
 
 2034        int x = (int)floor(u); 
 
 2035        int y = (int)floor(v); 
 
 2036        float u_ratio = u - x;
 
 2037        float v_ratio = v - y;
 
 2038        float u_opposite = 1 - u_ratio;
 
 2039        float v_opposite = 1 - v_ratio;
 
 2047            (uint8_t)((p1.
r * u_opposite + p2.
r * u_ratio) * v_opposite + (p3.
r * u_opposite + p4.
r * u_ratio) * v_ratio),
 
 2048            (uint8_t)((p1.
g * u_opposite + p2.
g * u_ratio) * v_opposite + (p3.
g * u_opposite + p4.
g * u_ratio) * v_ratio),
 
 2049            (uint8_t)((p1.
b * u_opposite + p2.
b * u_ratio) * v_opposite + (p3.
b * u_opposite + p4.
b * u_ratio) * v_ratio));
 
 2080        for (
int y = 0; y < vSize.
y; y++)
 
 2081            for (
int x = 0; x < vSize.
x; x++)
 
 2088        return { width, height };
 
 2097        if (spr == 
nullptr) 
return;
 
 2105        if (spr == 
nullptr) 
return;
 
 2106        id = nExistingTextureResource;
 
 2111        if (
sprite == 
nullptr) 
return;
 
 2113        renderer->ApplyTexture(
id);
 
 2114        renderer->UpdateTexture(
id, 
sprite);
 
 2119        if (
sprite == 
nullptr) 
return;
 
 2120        renderer->ApplyTexture(
id);
 
 2121        renderer->ReadTexture(
id, 
sprite);
 
 2128            renderer->DeleteTexture(
id);
 
 2135        pSprite = std::make_unique<olc::Sprite>(width, height);
 
 2136        pDecal = std::make_unique<olc::Decal>(pSprite.get(), filter, clamp);
 
 2141        pSprite = std::make_unique<olc::Sprite>();
 
 2144            pDecal = std::make_unique<olc::Decal>(pSprite.get(), filter, clamp);
 
 2157        return pDecal.get();
 
 2162        return pSprite.get();
 
 2185        const std::string file = makeposix(sFile);
 
 2187        if (_gfs::exists(file))
 
 2190            e.nSize = (uint32_t)_gfs::file_size(file);
 
 2201        baseFile.open(sFile, std::ifstream::binary);
 
 2202        if (!baseFile.is_open()) 
return false;
 
 2205        uint32_t nIndexSize = 0;
 
 2206        baseFile.read((
char*)&nIndexSize, 
sizeof(uint32_t));
 
 2208        std::vector<char> buffer(nIndexSize);
 
 2209        for (uint32_t j = 0; j < nIndexSize; j++)
 
 2210            buffer[j] = baseFile.get();
 
 2212        std::vector<char> decoded = scramble(buffer, sKey);
 
 2214        auto read = [&decoded, &pos](
char* dst, 
size_t size) {
 
 2215            memcpy((
void*)dst, (
const void*)(decoded.data() + pos), size);
 
 2219        auto get = [&read]() -> 
int { 
char c; read(&c, 1); 
return c; };
 
 2222        uint32_t nMapEntries = 0;
 
 2223        read((
char*)&nMapEntries, 
sizeof(uint32_t));
 
 2224        for (uint32_t i = 0; i < nMapEntries; i++)
 
 2226            uint32_t nFilePathSize = 0;
 
 2227            read((
char*)&nFilePathSize, 
sizeof(uint32_t));
 
 2229            std::string sFileName(nFilePathSize, 
' ');
 
 2230            for (uint32_t j = 0; j < nFilePathSize; j++)
 
 2231                sFileName[j] = get();
 
 2234            read((
char*)&e.nSize, 
sizeof(uint32_t));
 
 2235            read((
char*)&e.nOffset, 
sizeof(uint32_t));
 
 2236            mapFiles[sFileName] = e;
 
 2247        std::ofstream ofs(sFile, std::ofstream::binary);
 
 2248        if (!ofs.is_open()) 
return false;
 
 2251        uint32_t nIndexSize = 0; 
 
 2252        ofs.write((
char*)&nIndexSize, 
sizeof(uint32_t));
 
 2253        uint32_t nMapSize = uint32_t(mapFiles.size());
 
 2254        ofs.write((
char*)&nMapSize, 
sizeof(uint32_t));
 
 2255        for (
auto& e : mapFiles)
 
 2258            size_t nPathSize = e.first.size();
 
 2259            ofs.write((
char*)&nPathSize, 
sizeof(uint32_t));
 
 2260            ofs.write(e.first.c_str(), nPathSize);
 
 2263            ofs.write((
char*)&e.second.nSize, 
sizeof(uint32_t));
 
 2264            ofs.write((
char*)&e.second.nOffset, 
sizeof(uint32_t));
 
 2268        std::streampos offset = ofs.tellp();
 
 2269        nIndexSize = (uint32_t)offset;
 
 2270        for (
auto& e : mapFiles)
 
 2273            e.second.nOffset = (uint32_t)offset;
 
 2276            std::vector<uint8_t> vBuffer(e.second.nSize);
 
 2277            std::ifstream i(e.first, std::ifstream::binary);
 
 2278            i.read((
char*)vBuffer.data(), e.second.nSize);
 
 2282            ofs.write((
char*)vBuffer.data(), e.second.nSize);
 
 2283            offset += e.second.nSize;
 
 2287        std::vector<char> stream;
 
 2288        auto write = [&stream](
const char* data, 
size_t size) {
 
 2289            size_t sizeNow = stream.size();
 
 2290            stream.resize(sizeNow + size);
 
 2291            memcpy(stream.data() + sizeNow, data, size);
 
 2295        write((
char*)&nMapSize, 
sizeof(uint32_t));
 
 2296        for (
auto& e : mapFiles)
 
 2299            size_t nPathSize = e.first.size();
 
 2300            write((
char*)&nPathSize, 
sizeof(uint32_t));
 
 2301            write(e.first.c_str(), nPathSize);
 
 2304            write((
char*)&e.second.nSize, 
sizeof(uint32_t));
 
 2305            write((
char*)&e.second.nOffset, 
sizeof(uint32_t));
 
 2307        std::vector<char> sIndexString = scramble(stream, sKey);
 
 2308        uint32_t nIndexStringLen = uint32_t(sIndexString.size());
 
 2311        ofs.seekp(0, std::ios::beg);
 
 2312        ofs.write((
char*)&nIndexStringLen, 
sizeof(uint32_t));
 
 2313        ofs.write(sIndexString.data(), nIndexStringLen);
 
 2320        return ResourceBuffer(baseFile, mapFiles[sFile].nOffset, mapFiles[sFile].nSize);
 
 2325        return baseFile.is_open();
 
 2328    std::vector<char> ResourcePack::scramble(
const std::vector<char>& data, 
const std::string& key)
 
 2330        if (key.empty()) 
return data;
 
 2331        std::vector<char> o;
 
 2333        for (
auto s : data) o.push_back(s ^ key[(c++) % key.size()]);
 
 2337    std::string ResourcePack::makeposix(
const std::string& path)
 
 2340        for (
auto s : path) o += std::string(1, s == 
'\\' ? 
'/' : s);
 
 2363        bPixelCohesion = cohesion;
 
 2364        bRealWindowMode = realwindow;
 
 2365        vScreenSize = { screen_w, screen_h };
 
 2366        vInvScreenSize = { 1.0f / float(screen_w), 1.0f / float(screen_h) };
 
 2367        vPixelSize = { pixel_w, pixel_h };
 
 2368        vWindowSize = vScreenSize * vPixelSize;
 
 2369        bFullScreen = full_screen;
 
 2370        bEnableVSYNC = vsync;
 
 2371        vPixel = 2.0f / vScreenSize;
 
 2373        if (vPixelSize.x <= 0 || vPixelSize.y <= 0 || vScreenSize.
x <= 0 || vScreenSize.
y <= 0)
 
 2381        vScreenSize = { w, h };
 
 2382        vInvScreenSize = { 1.0f / float(w), 1.0f / float(h) };
 
 2383        for (
auto& layer : vLayers)
 
 2385            layer.pDrawTarget.Create(vScreenSize.
x, vScreenSize.
y);
 
 2386            layer.bUpdate = 
true;
 
 2389        if (!bRealWindowMode)
 
 2393            renderer->DisplayFrame();
 
 2396        renderer->UpdateViewport(vViewPos, vViewSize);
 
 2399#if !defined(PGE_USE_CUSTOM_START) 
 2405        if (platform->CreateWindowPane({ 30,30 }, vWindowSize, bFullScreen) != 
olc::OK) 
return olc::FAIL;
 
 2410        std::thread t = std::thread(&PixelGameEngine::EngineThread, 
this);
 
 2413        platform->StartSystemEventLoop();
 
 2428            pDrawTarget = target;
 
 2433            if (!vLayers.empty())
 
 2434                pDrawTarget = vLayers[0].pDrawTarget.Sprite();
 
 2440        if (layer < vLayers.size())
 
 2442            pDrawTarget = vLayers[layer].pDrawTarget.Sprite();
 
 2443            vLayers[layer].bUpdate = bDirty;
 
 2444            nTargetLayer = layer;
 
 2450        if (layer < vLayers.size()) vLayers[layer].bShow = b;
 
 2460        if (layer < vLayers.size()) vLayers[layer].vOffset = { x, y };
 
 2470        if (layer < vLayers.size()) vLayers[layer].vScale = { x, y };
 
 2475        if (layer < vLayers.size()) vLayers[layer].tint = tint;
 
 2480        if (layer < vLayers.size()) vLayers[layer].funcHook = f;
 
 2491        ld.pDrawTarget.Create(vScreenSize.
x, vScreenSize.
y);
 
 2492        vLayers.push_back(std::move(ld));
 
 2493        return uint32_t(vLayers.size()) - 1;
 
 2504            return pDrawTarget->
width;
 
 2512            return pDrawTarget->
height;
 
 2524        return bHasInputFocus;
 
 2529        return pKeyboardState[uint8_t(k)];
 
 2534        return pMouseState[b];
 
 2554        return nMouseWheelDelta;
 
 2559        return vScreenSize.
x;
 
 2564        return vScreenSize.
y;
 
 2569        return fLastElapsed;
 
 2589        return vScreenPixelSize;
 
 2599        return vMouseWindowPos;
 
 2604        return Draw(pos.
x, pos.
y, p);
 
 2610        if (!pDrawTarget) 
return false;
 
 2614            return pDrawTarget->
SetPixel(x, y, p);
 
 2620                return pDrawTarget->
SetPixel(x, y, p);
 
 2625            Pixel d = pDrawTarget->
GetPixel(x, y);
 
 2626            float a = (float)(p.a / 255.0f) * fBlendFactor;
 
 2628            float r = a * (float)p.r + c * (
float)d.r;
 
 2629            float g = a * (float)p.g + c * (
float)d.g;
 
 2630            float b = a * (float)p.b + c * (
float)d.b;
 
 2631            return pDrawTarget->
SetPixel(x, y, Pixel((uint8_t)r, (uint8_t)g, (uint8_t)b));
 
 2636            return pDrawTarget->
SetPixel(x, y, funcPixelMode(x, y, p, pDrawTarget->
GetPixel(x, y)));
 
 2650        int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
 
 2651        dx = x2 - x1; dy = y2 - y1;
 
 2653        auto rol = [&](void) { pattern = (pattern << 1) | (pattern >> 31); 
return pattern & 1; };
 
 2658        x1 = p1.x; y1 = p1.y;
 
 2659        x2 = p2.x; y2 = p2.y;
 
 2664            if (y2 < y1) std::swap(y1, y2);
 
 2665            for (y = y1; y <= y2; y++) 
if (rol()) 
Draw(x1, y, p);
 
 2671            if (x2 < x1) std::swap(x1, x2);
 
 2672            for (x = x1; x <= x2; x++) 
if (rol()) 
Draw(x, y1, p);
 
 2677        dx1 = abs(dx); dy1 = abs(dy);
 
 2678        px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
 
 2683                x = x1; y = y1; xe = x2;
 
 2687                x = x2; y = y2; xe = x1;
 
 2690            if (rol()) 
Draw(x, y, p);
 
 2692            for (i = 0; x < xe; i++)
 
 2699                    if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) y = y + 1; 
else y = y - 1;
 
 2700                    px = px + 2 * (dy1 - dx1);
 
 2702                if (rol()) 
Draw(x, y, p);
 
 2709                x = x1; y = y1; ye = y2;
 
 2713                x = x2; y = y2; ye = y1;
 
 2716            if (rol()) 
Draw(x, y, p);
 
 2718            for (i = 0; y < ye; i++)
 
 2725                    if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) x = x + 1; 
else x = x - 1;
 
 2726                    py = py + 2 * (dx1 - dy1);
 
 2728                if (rol()) 
Draw(x, y, p);
 
 2747            int d = 3 - 2 * radius;
 
 2752                if (mask & 0x01) 
Draw(x + x0, y - y0, p);
 
 2753                if (mask & 0x04) 
Draw(x + y0, y + x0, p);
 
 2754                if (mask & 0x10) 
Draw(x - x0, y + y0, p);
 
 2755                if (mask & 0x40) 
Draw(x - y0, y - x0, p);
 
 2756                if (x0 != 0 && x0 != y0)
 
 2758                    if (mask & 0x02) 
Draw(x + y0, y - x0, p);
 
 2759                    if (mask & 0x08) 
Draw(x + x0, y + y0, p);
 
 2760                    if (mask & 0x20) 
Draw(x - y0, y + x0, p);
 
 2761                    if (mask & 0x80) 
Draw(x - x0, y - y0, p);
 
 2767                    d += 4 * (x0++ - y0--) + 10;
 
 2788            int d = 3 - 2 * radius;
 
 2790            auto drawline = [&](
int sx, 
int ex, 
int y)
 
 2792                    for (
int x = sx; x <= ex; x++)
 
 2798                drawline(x - y0, x + y0, y - x0);
 
 2799                if (x0 > 0) drawline(x - y0, x + y0, y + x0);
 
 2807                        drawline(x - x0, x + x0, y - y0);
 
 2808                        drawline(x - x0, x + x0, y + y0);
 
 2810                    d += 4 * (x0++ - y0--) + 10;
 
 2826        DrawLine(x + w, y, x + w, y + h, p);
 
 2827        DrawLine(x + w, y + h, x, y + h, p);
 
 2835        for (
int i = 0; i < pixels; i++) m[i] = p;
 
 2840        renderer->ClearBuffer(p, bDepth);
 
 2845        return fontRenderable.
Sprite();
 
 2851        static constexpr int SEG_I = 0b0000, SEG_L = 0b0001, SEG_R = 0b0010, SEG_B = 0b0100, SEG_T = 0b1000;
 
 2852        auto Segment = [&vScreenSize = vScreenSize](
const olc::vi2d& v)
 
 2855                if (v.x < 0) i |= SEG_L; 
else if (v.x > vScreenSize.
x) i |= SEG_R;
 
 2856                if (v.y < 0) i |= SEG_B; 
else if (v.y > vScreenSize.
y) i |= SEG_T;
 
 2860        int s1 = Segment(in_p1), s2 = Segment(in_p2);
 
 2864            if (!(s1 | s2))   
return true;
 
 2865            else if (s1 & s2) 
return false;
 
 2868                int s3 = s2 > s1 ? s2 : s1;
 
 2870                if (s3 & SEG_T) { n.
x = in_p1.
x + (in_p2.
x - in_p1.
x) * (vScreenSize.
y - in_p1.
y) / (in_p2.
y - in_p1.
y); n.
y = vScreenSize.
y; }
 
 2871                else if (s3 & SEG_B) { n.
x = in_p1.
x + (in_p2.
x - in_p1.
x) * (0 - in_p1.
y) / (in_p2.
y - in_p1.
y); n.
y = 0; }
 
 2872                else if (s3 & SEG_R) { n.
x = vScreenSize.
x; n.
y = in_p1.
y + (in_p2.
y - in_p1.
y) * (vScreenSize.
x - in_p1.
x) / (in_p2.
x - in_p1.
x); }
 
 2873                else if (s3 & SEG_L) { n.
x = 0; n.
y = in_p1.
y + (in_p2.
y - in_p1.
y) * (0 - in_p1.
x) / (in_p2.
x - in_p1.
x); }
 
 2874                if (s3 == s1) { in_p1 = n; s1 = Segment(in_p1); }
 
 2875                else { in_p2 = n; s2 = Segment(in_p2); }
 
 2883        bSuspendTextureTransfer = !bEnable;
 
 2907        for (
int i = x; i < x2; i++)
 
 2908            for (
int j = y; j < y2; j++)
 
 2932        auto drawline = [&](
int sx, 
int ex, 
int ny) { 
for (
int i = sx; i <= ex; i++) 
Draw(i, ny, p); };
 
 2934        int t1x, t2x, y, minx, maxx, t1xp, t2xp;
 
 2935        bool changed1 = 
false;
 
 2936        bool changed2 = 
false;
 
 2937        int signx1, signx2, dx1, dy1, dx2, dy2;
 
 2940        if (y1 > y2) { std::swap(y1, y2); std::swap(x1, x2); }
 
 2941        if (y1 > y3) { std::swap(y1, y3); std::swap(x1, x3); }
 
 2942        if (y2 > y3) { std::swap(y2, y3); std::swap(x2, x3); }
 
 2944        t1x = t2x = x1; y = y1;   
 
 2945        dx1 = (int)(x2 - x1);
 
 2946        if (dx1 < 0) { dx1 = -dx1; signx1 = -1; }
 
 2948        dy1 = (int)(y2 - y1);
 
 2950        dx2 = (int)(x3 - x1);
 
 2951        if (dx2 < 0) { dx2 = -dx2; signx2 = -1; }
 
 2953        dy2 = (int)(y3 - y1);
 
 2955        if (dy1 > dx1) { std::swap(dx1, dy1); changed1 = 
true; }
 
 2956        if (dy2 > dx2) { std::swap(dy2, dx2); changed2 = 
true; }
 
 2958        e2 = (int)(dx2 >> 1);
 
 2960        if (y1 == y2) 
goto next;
 
 2961        e1 = (int)(dx1 >> 1);
 
 2963        for (
int i = 0; i < dx1;) {
 
 2965            if (t1x < t2x) { minx = t1x; maxx = t2x; }
 
 2966            else { minx = t2x; maxx = t1x; }
 
 2973                    if (changed1) t1xp = signx1;
 
 2976                if (changed1) 
break;
 
 2986                    if (changed2) t2xp = signx2;
 
 2989                if (changed2)     
break;
 
 2993            if (minx > t1x) minx = t1x;
 
 2994            if (minx > t2x) minx = t2x;
 
 2995            if (maxx < t1x) maxx = t1x;
 
 2996            if (maxx < t2x) maxx = t2x;
 
 2997            drawline(minx, maxx, y);    
 
 2999            if (!changed1) t1x += signx1;
 
 3001            if (!changed2) t2x += signx2;
 
 3008        dx1 = (int)(x3 - x2); 
if (dx1 < 0) { dx1 = -dx1; signx1 = -1; }
 
 3010        dy1 = (int)(y3 - y2);
 
 3014            std::swap(dy1, dx1);
 
 3017        else changed1 = 
false;
 
 3019        e1 = (int)(dx1 >> 1);
 
 3021        for (
int i = 0; i <= dx1; i++) {
 
 3023            if (t1x < t2x) { minx = t1x; maxx = t2x; }
 
 3024            else { minx = t2x; maxx = t1x; }
 
 3030                    if (changed1) { t1xp = signx1; 
break; }
 
 3033                if (changed1) 
break;
 
 3043                    if (changed2) t2xp = signx2;
 
 3046                if (changed2)     
break;
 
 3051            if (minx > t1x) minx = t1x;
 
 3052            if (minx > t2x) minx = t2x;
 
 3053            if (maxx < t1x) maxx = t1x;
 
 3054            if (maxx < t2x) maxx = t2x;
 
 3055            drawline(minx, maxx, y);
 
 3056            if (!changed1) t1x += signx1;
 
 3058            if (!changed2) t2x += signx2;
 
 3071        if (p2.
y < p1.
y) { std::swap(p1.
y, p2.
y); std::swap(p1.
x, p2.
x); std::swap(vTex[0].x, vTex[1].x); std::swap(vTex[0].y, vTex[1].y); std::swap(vColour[0], vColour[1]); }
 
 3072        if (p3.
y < p1.
y) { std::swap(p1.
y, p3.
y); std::swap(p1.
x, p3.
x); std::swap(vTex[0].x, vTex[2].x); std::swap(vTex[0].y, vTex[2].y); std::swap(vColour[0], vColour[2]); }
 
 3073        if (p3.
y < p2.
y) { std::swap(p2.
y, p3.
y); std::swap(p2.
x, p3.
x); std::swap(vTex[1].x, vTex[2].x); std::swap(vTex[1].y, vTex[2].y); std::swap(vColour[1], vColour[2]); }
 
 3077        int dcr1 = vColour[1].r - vColour[0].r;
 
 3078        int dcg1 = vColour[1].g - vColour[0].g;
 
 3079        int dcb1 = vColour[1].b - vColour[0].b;
 
 3080        int dca1 = vColour[1].a - vColour[0].a;
 
 3084        int dcr2 = vColour[2].r - vColour[0].r;
 
 3085        int dcg2 = vColour[2].g - vColour[0].g;
 
 3086        int dcb2 = vColour[2].b - vColour[0].b;
 
 3087        int dca2 = vColour[2].a - vColour[0].a;
 
 3089        float dax_step = 0, dbx_step = 0, dcr1_step = 0, dcr2_step = 0, dcg1_step = 0, dcg2_step = 0, dcb1_step = 0, dcb2_step = 0, dca1_step = 0, dca2_step = 0;
 
 3094            dax_step = dPos1.
x / (float)abs(dPos1.
y);
 
 3095            vTex1Step = dTex1 / (float)abs(dPos1.
y);
 
 3096            dcr1_step = dcr1 / (float)abs(dPos1.
y);
 
 3097            dcg1_step = dcg1 / (float)abs(dPos1.
y);
 
 3098            dcb1_step = dcb1 / (float)abs(dPos1.
y);
 
 3099            dca1_step = dca1 / (float)abs(dPos1.
y);
 
 3104            dbx_step = dPos2.
x / (float)abs(dPos2.
y);
 
 3105            vTex2Step = dTex2 / (float)abs(dPos2.
y);
 
 3106            dcr2_step = dcr2 / (float)abs(dPos2.
y);
 
 3107            dcg2_step = dcg2 / (float)abs(dPos2.
y);
 
 3108            dcb2_step = dcb2 / (float)abs(dPos2.
y);
 
 3109            dca2_step = dca2 / (float)abs(dPos2.
y);
 
 3116        for (
int pass = 0; pass < 2; pass++)
 
 3120                vStart = p1; vEnd = p2; vStartIdx = 0;
 
 3125                dTex1 = vTex[2] - vTex[1];
 
 3126                dcr1 = vColour[2].r - vColour[1].r;
 
 3127                dcg1 = vColour[2].g - vColour[1].g;
 
 3128                dcb1 = vColour[2].b - vColour[1].b;
 
 3129                dca1 = vColour[2].a - vColour[1].a;
 
 3130                dcr1_step = 0; dcg1_step = 0; dcb1_step = 0; dca1_step = 0;
 
 3132                if (dPos2.
y) dbx_step = dPos2.
x / (float)abs(dPos2.
y);
 
 3135                    dax_step = dPos1.
x / (float)abs(dPos1.
y);
 
 3136                    vTex1Step = dTex1 / (float)abs(dPos1.
y);
 
 3137                    dcr1_step = dcr1 / (float)abs(dPos1.
y);
 
 3138                    dcg1_step = dcg1 / (float)abs(dPos1.
y);
 
 3139                    dcb1_step = dcb1 / (float)abs(dPos1.
y);
 
 3140                    dca1_step = dca1 / (float)abs(dPos1.
y);
 
 3143                vStart = p2; vEnd = p3; vStartIdx = 1;
 
 3148                for (
int i = vStart.
y; i <= vEnd.
y; i++)
 
 3150                    int ax = int(vStart.
x + (
float)(i - vStart.
y) * dax_step);
 
 3151                    int bx = int(p1.x + (
float)(i - p1.y) * dbx_step);
 
 3153                    olc::vf2d tex_s(vTex[vStartIdx].x + (
float)(i - vStart.
y) * vTex1Step.
x, vTex[vStartIdx].y + (
float)(i - vStart.
y) * vTex1Step.
y);
 
 3154                    olc::vf2d tex_e(vTex[0].x + (
float)(i - p1.y) * vTex2Step.
x, vTex[0].y + (
float)(i - p1.y) * vTex2Step.
y);
 
 3156                    olc::Pixel col_s(vColour[vStartIdx].r + uint8_t((
float)(i - vStart.
y) * dcr1_step), vColour[vStartIdx].g + uint8_t((
float)(i - vStart.
y) * dcg1_step),
 
 3157                        vColour[vStartIdx].b + uint8_t((
float)(i - vStart.
y) * dcb1_step), vColour[vStartIdx].a + uint8_t((
float)(i - vStart.
y) * dca1_step));
 
 3159                    olc::Pixel col_e(vColour[0].r + uint8_t((
float)(i - p1.y) * dcr2_step), vColour[0].g + uint8_t((
float)(i - p1.y) * dcg2_step),
 
 3160                        vColour[0].b + uint8_t((
float)(i - p1.y) * dcb2_step), vColour[0].a + uint8_t((
float)(i - p1.y) * dca2_step));
 
 3162                    if (ax > bx) { std::swap(ax, bx); std::swap(tex_s, tex_e); std::swap(col_s, col_e); }
 
 3164                    float tstep = 1.0f / ((float)(bx - ax));
 
 3167                    for (
int j = ax; j < bx; j++)
 
 3170                        if (sprTex != 
nullptr) pixel *= sprTex->
Sample(tex_s.lerp(tex_e, t));
 
 3186        if (vPoints.size() < 3 || vTex.size() < 3 || vColour.size() < 3)
 
 3191            for (
size_t tri = 0; tri < vPoints.size() / 3; tri++)
 
 3193                std::vector<olc::vf2d> vP = { vPoints[tri * 3 + 0], vPoints[tri * 3 + 1], vPoints[tri * 3 + 2] };
 
 3194                std::vector<olc::vf2d> vT = { vTex[tri * 3 + 0], vTex[tri * 3 + 1], vTex[tri * 3 + 2] };
 
 3195                std::vector<olc::Pixel> vC = { vColour[tri * 3 + 0], vColour[tri * 3 + 1], vColour[tri * 3 + 2] };
 
 3203            for (
size_t tri = 2; tri < vPoints.size(); tri++)
 
 3205                std::vector<olc::vf2d> vP = { vPoints[tri - 2], vPoints[tri - 1], vPoints[tri] };
 
 3206                std::vector<olc::vf2d> vT = { vTex[tri - 2], vTex[tri - 1], vTex[tri] };
 
 3207                std::vector<olc::Pixel> vC = { vColour[tri - 2], vColour[tri - 1], vColour[tri] };
 
 3215            for (
size_t tri = 2; tri < vPoints.size(); tri++)
 
 3217                std::vector<olc::vf2d> vP = { vPoints[0], vPoints[tri - 1], vPoints[tri] };
 
 3218                std::vector<olc::vf2d> vT = { vTex[0], vTex[tri - 1], vTex[tri] };
 
 3219                std::vector<olc::Pixel> vC = { vColour[0], vColour[tri - 1], vColour[tri] };
 
 3234        if (sprite == 
nullptr)
 
 3237        int32_t fxs = 0, fxm = 1, fx = 0;
 
 3238        int32_t fys = 0, fym = 1, fy = 0;
 
 3245            for (int32_t i = 0; i < sprite->width; i++, fx += fxm)
 
 3248                for (int32_t j = 0; j < sprite->height; j++, fy += fym)
 
 3249                    for (uint32_t is = 0; is < scale; is++)
 
 3250                        for (uint32_t js = 0; js < scale; js++)
 
 3251                            Draw(x + (i * scale) + is, y + (j * scale) + js, sprite->GetPixel(fx, fy));
 
 3257            for (int32_t i = 0; i < sprite->width; i++, fx += fxm)
 
 3260                for (int32_t j = 0; j < sprite->height; j++, fy += fym)
 
 3261                    Draw(x + i, y + j, sprite->GetPixel(fx, fy));
 
 3273        if (sprite == 
nullptr)
 
 3276        int32_t fxs = 0, fxm = 1, fx = 0;
 
 3277        int32_t fys = 0, fym = 1, fy = 0;
 
 3284            for (int32_t i = 0; i < w; i++, fx += fxm)
 
 3287                for (int32_t j = 0; j < h; j++, fy += fym)
 
 3288                    for (uint32_t is = 0; is < scale; is++)
 
 3289                        for (uint32_t js = 0; js < scale; js++)
 
 3290                            Draw(x + (i * scale) + is, y + (j * scale) + js, sprite->GetPixel(fx + ox, fy + oy));
 
 3296            for (int32_t i = 0; i < w; i++, fx += fxm)
 
 3299                for (int32_t j = 0; j < h; j++, fy += fym)
 
 3300                    Draw(x + i, y + j, sprite->GetPixel(fx + ox, fy + oy));
 
 3312        nDecalStructure = structure;
 
 3319              (pos.
x * vInvScreenSize.
x) * 2.0f - 1.0f,
 
 3320            -((pos.
y * vInvScreenSize.
y) * 2.0f - 1.0f)
 
 3326              ((pos.
x + source_size.
x * scale.
x) * vInvScreenSize.
x) * 2.0f - 1.0f,
 
 3327            -(((pos.
y + source_size.
y * scale.
y) * vInvScreenSize.
y) * 2.0f - 1.0f)
 
 3331        olc::vf2d vQuantisedPos = ((vScreenSpacePos * vWindow) + 
olc::vf2d(0.5f, 0.5f)).floor() / vWindow;
 
 3332        olc::vf2d vQuantisedDim = ((vScreenSpaceDim * vWindow) + 
olc::vf2d(0.5f, -0.5f)).ceil() / vWindow;
 
 3337        di.tint = { tint, tint, tint, tint };
 
 3338        di.pos = { { vQuantisedPos.
x, vQuantisedPos.
y }, { vQuantisedPos.
x, vQuantisedDim.
y }, { vQuantisedDim.
x, vQuantisedDim.
y }, { vQuantisedDim.
x, vQuantisedPos.
y } };
 
 3341        di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } };
 
 3343        di.mode = nDecalMode;
 
 3344        di.structure = nDecalStructure;
 
 3345        vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3352            (pos.
x * vInvScreenSize.
x) * 2.0f - 1.0f,
 
 3353            ((pos.
y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f
 
 3358            vScreenSpacePos.
x + (2.0f * size.
x * vInvScreenSize.
x),
 
 3359            vScreenSpacePos.
y - (2.0f * size.
y * vInvScreenSize.
y)
 
 3365        di.tint = { tint, tint, tint, tint };
 
 3366        di.pos = { { vScreenSpacePos.
x, vScreenSpacePos.
y }, { vScreenSpacePos.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpacePos.
y } };
 
 3369        di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } };
 
 3371        di.mode = nDecalMode;
 
 3372        di.structure = nDecalStructure;
 
 3373        vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3381            (pos.
x * vInvScreenSize.
x) * 2.0f - 1.0f,
 
 3382            ((pos.
y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f
 
 3387            vScreenSpacePos.
x + (2.0f * (float(decal->
sprite->
width) * vInvScreenSize.
x)) * scale.
x,
 
 3388            vScreenSpacePos.
y - (2.0f * (float(decal->
sprite->
height) * vInvScreenSize.
y)) * scale.
y 
 3394        di.tint = { tint, tint, tint, tint };
 
 3395        di.pos = { { vScreenSpacePos.
x, vScreenSpacePos.
y }, { vScreenSpacePos.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpacePos.
y } };
 
 3396        di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
 
 3397        di.w = { 1, 1, 1, 1 };
 
 3398        di.mode = nDecalMode;
 
 3399        di.structure = nDecalStructure;
 
 3400        vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3407        di.pos.resize(elements);
 
 3408        di.uv.resize(elements);
 
 3409        di.w.resize(elements);
 
 3410        di.tint.resize(elements);
 
 3411        di.points = elements;
 
 3412        for (uint32_t i = 0; i < elements; i++)
 
 3414            di.pos[i] = { (pos[i].
x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
 
 3416            di.tint[i] = col[i];
 
 3419        di.mode = nDecalMode;
 
 3420        di.structure = nDecalStructure;
 
 3421        vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3428        di.points = uint32_t(pos.size());
 
 3429        di.pos.resize(di.points);
 
 3430        di.uv.resize(di.points);
 
 3431        di.w.resize(di.points);
 
 3432        di.tint.resize(di.points);
 
 3433        for (uint32_t i = 0; i < di.points; i++)
 
 3435            di.pos[i] = { (pos[i].x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
 
 3440        di.mode = nDecalMode;
 
 3441        di.structure = nDecalStructure;
 
 3442        vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3449        di.points = uint32_t(pos.size());
 
 3450        di.pos.resize(di.points);
 
 3451        di.uv.resize(di.points);
 
 3452        di.w.resize(di.points);
 
 3453        di.tint.resize(di.points);
 
 3454        for (uint32_t i = 0; i < di.points; i++)
 
 3456            di.pos[i] = { (pos[i].x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
 
 3458            di.tint[i] = tint[i];
 
 3461        di.mode = nDecalMode;
 
 3462        di.structure = nDecalStructure;
 
 3463        vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3468        std::vector<olc::Pixel> newColours(colours.size(), 
olc::WHITE);
 
 3469        std::transform(colours.begin(), colours.end(), newColours.begin(),
 
 3470            [&tint](
const olc::Pixel pin) { return pin * tint; });
 
 3479        di.points = uint32_t(pos.size());
 
 3480        di.pos.resize(di.points);
 
 3481        di.uv.resize(di.points);
 
 3482        di.w.resize(di.points);
 
 3483        di.tint.resize(di.points);
 
 3484        for (uint32_t i = 0; i < di.points; i++)
 
 3486            di.pos[i] = { (pos[i].x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
 
 3491        di.mode = nDecalMode;
 
 3492        di.structure = nDecalStructure;
 
 3493        vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3500        di.points = uint32_t(pos.size());
 
 3501        di.pos.resize(di.points);
 
 3502        di.uv.resize(di.points);
 
 3503        di.w.resize(di.points);
 
 3504        di.tint.resize(di.points);
 
 3505        for (uint32_t i = 0; i < di.points; i++)
 
 3507            di.pos[i] = { (pos[i].x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
 
 3509            di.tint[i] = colours[i] * tint;
 
 3512        di.mode = nDecalMode;
 
 3513        di.structure = nDecalStructure;
 
 3514        vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3519        renderer->Set3DProjection(m);
 
 3524        bHW3DDepthTest = bEnableDepth;
 
 3529        nHW3DCullMode = mode;
 
 3536        task.mode = nDecalMode;
 
 3537        task.structure = layout;
 
 3538        task.depth = bHW3DDepthTest;
 
 3539        task.cull = nHW3DCullMode;
 
 3540        task.mvp = matModelView;
 
 3542        task.vb.resize(pos.size());
 
 3544        for (
size_t i = 0; i < pos.size(); i++)
 
 3545            task.vb[i] = { pos[i][0], pos[i][1], pos[i][2], 1.0f, uv[i][0], uv[i][1], col[i].
n };
 
 3547        vLayers[nTargetLayer].vecGPUTasks.push_back(task);
 
 3550    void PixelGameEngine::HW3D_DrawLine(
const std::array<float, 16>& matModelView, 
const std::array<float, 4>& pos1, 
const std::array<float, 4>& pos2, 
const olc::Pixel col)
 
 3553        task.decal = 
nullptr;
 
 3556        task.depth = bHW3DDepthTest;
 
 3557        task.cull = nHW3DCullMode;
 
 3558        task.mvp = matModelView;
 
 3562            { pos1[0], pos1[1], pos1[2], 1.0f, 0.0f, 0.0f, col.
n},
 
 3563            { pos2[0], pos2[1], pos2[2], 1.0f, 0.0f, 0.0f, col.
n}
 
 3566        vLayers[nTargetLayer].vecGPUTasks.push_back(task);
 
 3569    void PixelGameEngine::HW3D_DrawLineBox(
const std::array<float, 16>& matModelView, 
const std::array<float, 4>& pos, 
const std::array<float, 4>& size, 
const olc::Pixel col)
 
 3572        task.decal = 
nullptr;
 
 3573        task.mode = nDecalMode;
 
 3575        task.depth = bHW3DDepthTest;
 
 3576        task.cull = nHW3DCullMode;
 
 3577        task.mvp = matModelView;
 
 3580        const float ox = pos[0];
 
 3581        const float oy = pos[1];
 
 3582        const float oz = pos[2];
 
 3583        const float sx = size[0];
 
 3584        const float sy = size[1];
 
 3585        const float sz = size[2];
 
 3587        const std::array<float, 3> p0 = { {ox, oy, oz} };
 
 3588        const std::array<float, 3> p1 = { {ox+sx, oy, oz} };
 
 3589        const std::array<float, 3> p2 = { {ox+sx, oy+sy, oz} };
 
 3590        const std::array<float, 3> p3 = { {ox, oy+sy, oz} };
 
 3592        const std::array<float, 3> p4 = { {ox, oy, oz+sz} };
 
 3593        const std::array<float, 3> p5 = { {ox+sx, oy, oz+sz} };
 
 3594        const std::array<float, 3> p6 = { {ox+sx, oy+sy, oz+sz} };
 
 3595        const std::array<float, 3> p7 = { {ox, oy+sy, oz+sz} };
 
 3599            { p0[0], p0[1], p0[2], 1.0f, 0.0f, 0.0f, col.
n }, { p1[0], p1[1], p1[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3600            { p1[0], p1[1], p1[2], 1.0f, 0.0f, 0.0f, col.
n }, { p2[0], p2[1], p2[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3601            { p2[0], p2[1], p2[2], 1.0f, 0.0f, 0.0f, col.
n }, { p3[0], p3[1], p3[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3602            { p3[0], p3[1], p3[2], 1.0f, 0.0f, 0.0f, col.
n }, { p0[0], p0[1], p0[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3603            { p4[0], p4[1], p4[2], 1.0f, 0.0f, 0.0f, col.
n }, { p5[0], p5[1], p5[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3604            { p5[0], p5[1], p5[2], 1.0f, 0.0f, 0.0f, col.
n }, { p6[0], p6[1], p6[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3605            { p6[0], p6[1], p6[2], 1.0f, 0.0f, 0.0f, col.
n }, { p7[0], p7[1], p7[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3606            { p7[0], p7[1], p7[2], 1.0f, 0.0f, 0.0f, col.
n }, { p4[0], p4[1], p4[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3607            { p0[0], p0[1], p0[2], 1.0f, 0.0f, 0.0f, col.
n }, { p4[0], p4[1], p4[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3608            { p1[0], p1[1], p1[2], 1.0f, 0.0f, 0.0f, col.
n }, { p5[0], p5[1], p5[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3609            { p2[0], p2[1], p2[2], 1.0f, 0.0f, 0.0f, col.
n }, { p6[0], p6[1], p6[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3610            { p3[0], p3[1], p3[2], 1.0f, 0.0f, 0.0f, col.
n }, { p7[0], p7[1], p7[2], 1.0f, 0.0f, 0.0f, col.
n },
 
 3613        vLayers[nTargetLayer].vecGPUTasks.push_back(task);
 
 3616    void PixelGameEngine::DrawLineDecal(
const olc::vf2d& pos1, 
const olc::vf2d& pos2, Pixel p)
 
 3618        auto m = nDecalMode;
 
 3620        DrawPolygonDecal(
nullptr, { pos1, pos2 }, { {0, 0}, {0,0} }, p);
 
 3626        auto m = nDecalMode;
 
 3629        std::array<olc::vf2d, 4> points = { { {pos}, {pos.
x, pos.
y + vNewSize.
y}, {pos + vNewSize}, {pos.
x + vNewSize.
x, pos.
y} } };
 
 3630        std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0},{0,0}} };
 
 3631        std::array<olc::Pixel, 4> cols = { {col, col, col, col} };
 
 3632        DrawExplicitDecal(
nullptr, points.data(), uvs.data(), cols.data(), 4);
 
 3640        std::array<olc::vf2d, 4> points = { { {pos}, {pos.
x, pos.
y + vNewSize.
y}, {pos + vNewSize}, {pos.
x + vNewSize.
x, pos.
y} } };
 
 3641        std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0},{0,0}} };
 
 3642        std::array<olc::Pixel, 4> cols = { {col, col, col, col} };
 
 3643        DrawExplicitDecal(
nullptr, points.data(), uvs.data(), cols.data(), 4);
 
 3648        std::array<olc::vf2d, 4> points = { { {pos}, {pos.
x, pos.
y + size.
y}, {pos + size}, {pos.
x + size.
x, pos.
y} } };
 
 3649        std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0},{0,0}} };
 
 3650        std::array<olc::Pixel, 4> cols = { {colTL, colBL, colBR, colTR} };
 
 3651        DrawExplicitDecal(
nullptr, points.data(), uvs.data(), cols.data(), 4);
 
 3656        std::array<olc::vf2d, 4> points = { { p0, p1, p2 } };
 
 3657        std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0}} };
 
 3658        std::array<olc::Pixel, 4> cols = { {col, col, col} };
 
 3659        DrawExplicitDecal(
nullptr, points.data(), uvs.data(), cols.data(), 3);
 
 3664        std::array<olc::vf2d, 4> points = { { p0, p1, p2 } };
 
 3665        std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0}} };
 
 3666        std::array<olc::Pixel, 4> cols = { {c0, c1, c2} };
 
 3667        DrawExplicitDecal(
nullptr, points.data(), uvs.data(), cols.data(), 3);
 
 3675        di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
 
 3676        di.w = { 1, 1, 1, 1 };
 
 3677        di.tint = { tint, tint, tint, tint };
 
 3679        di.pos[0] = (
olc::vf2d(0.0f, 0.0f) - center) * scale;
 
 3683        float c = cos(fAngle), s = sin(fAngle);
 
 3684        for (
int i = 0; i < 4; i++)
 
 3686            di.pos[i] = pos + 
olc::vf2d(di.pos[i].x * c - di.pos[i].y * s, di.pos[i].x * s + di.pos[i].y * c);
 
 3687            di.pos[i] = di.pos[i] * vInvScreenSize * 2.0f - 
olc::vf2d(1.0f, 1.0f);
 
 3688            di.pos[i].y *= -1.0f;
 
 3691        di.mode = nDecalMode;
 
 3692        di.structure = nDecalStructure;
 
 3698        task.mode = nDecalMode;
 
 3699        task.structure = nDecalStructure;
 
 3702            {di.pos[0].x, di.pos[0].y, 0.0f, 1.0f, 0.0f, 0.0f, tint.
n},
 
 3703            {di.pos[1].x, di.pos[1].y, 0.0f, 1.0f, 0.0f, 1.0f, tint.
n},
 
 3704            {di.pos[2].x, di.pos[2].y, 0.0f, 1.0f, 1.0f, 1.0f, tint.
n},
 
 3705            {di.pos[3].x, di.pos[3].y, 0.0f, 1.0f, 1.0f, 0.0f, tint.
n},
 
 3707        vLayers[nTargetLayer].vecGPUTasks.push_back(task);
 
 3716        di.tint = { tint, tint, tint, tint };
 
 3717        di.w = { 1, 1, 1, 1 };
 
 3719        di.pos[0] = (
olc::vf2d(0.0f, 0.0f) - center) * scale;
 
 3720        di.pos[1] = (
olc::vf2d(0.0f, source_size.
y) - center) * scale;
 
 3721        di.pos[2] = (
olc::vf2d(source_size.
x, source_size.
y) - center) * scale;
 
 3722        di.pos[3] = (
olc::vf2d(source_size.
x, 0.0f) - center) * scale;
 
 3723        float c = cos(fAngle), s = sin(fAngle);
 
 3724        for (
int i = 0; i < 4; i++)
 
 3726            di.pos[i] = pos + 
olc::vf2d(di.pos[i].x * c - di.pos[i].y * s, di.pos[i].x * s + di.pos[i].y * c);
 
 3727            di.pos[i] = di.pos[i] * vInvScreenSize * 2.0f - 
olc::vf2d(1.0f, 1.0f);
 
 3728            di.pos[i].y *= -1.0f;
 
 3733        di.uv = { { uvtl.
x, uvtl.
y }, { uvtl.
x, uvbr.
y }, { uvbr.
x, uvbr.
y }, { uvbr.
x, uvtl.
y } };
 
 3734        di.mode = nDecalMode;
 
 3735        di.structure = nDecalStructure;
 
 3736        vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3744        di.tint = { tint, tint, tint, tint };
 
 3745        di.w = { 1, 1, 1, 1 };
 
 3747        di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
 
 3749        float rd = ((pos[2].
x - pos[0].
x) * (pos[3].y - pos[1].y) - (pos[3].
x - pos[1].
x) * (pos[2].y - pos[0].y));
 
 3754            di.uv = { { uvtl.
x, uvtl.
y }, { uvtl.
x, uvbr.
y }, { uvbr.
x, uvbr.
y }, { uvbr.
x, uvtl.
y } };
 
 3757            float rn = ((pos[3].
x - pos[1].
x) * (pos[0].y - pos[1].y) - (pos[3].
y - pos[1].
y) * (pos[0].x - pos[1].x)) * rd;
 
 3758            float sn = ((pos[2].
x - pos[0].
x) * (pos[0].y - pos[1].y) - (pos[2].
y - pos[0].
y) * (pos[0].x - pos[1].x)) * rd;
 
 3759            if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center = pos[0] + rn * (pos[2] - pos[0]);
 
 3760            float d[4]; 
for (
int i = 0; i < 4; i++) d[i] = (pos[i] - center).mag();
 
 3761            for (
int i = 0; i < 4; i++)
 
 3763                float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3];
 
 3764                di.uv[i] *= q; di.w[i] *= q;
 
 3765                di.pos[i] = { (pos[i].
x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f };
 
 3767            di.mode = nDecalMode;
 
 3768            di.structure = nDecalStructure;
 
 3769            vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3780        di.tint = { tint, tint, tint, tint };
 
 3781        di.w = { 1, 1, 1, 1 };
 
 3783        di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
 
 3785        float rd = ((pos[2].
x - pos[0].
x) * (pos[3].y - pos[1].y) - (pos[3].
x - pos[1].
x) * (pos[2].y - pos[0].y));
 
 3789            float rn = ((pos[3].
x - pos[1].
x) * (pos[0].y - pos[1].y) - (pos[3].
y - pos[1].
y) * (pos[0].x - pos[1].x)) * rd;
 
 3790            float sn = ((pos[2].
x - pos[0].
x) * (pos[0].y - pos[1].y) - (pos[2].
y - pos[0].
y) * (pos[0].x - pos[1].x)) * rd;
 
 3791            if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center = pos[0] + rn * (pos[2] - pos[0]);
 
 3792            float d[4]; 
for (
int i = 0; i < 4; i++) d[i] = (pos[i] - center).
mag();
 
 3793            for (
int i = 0; i < 4; i++)
 
 3795                float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3];
 
 3796                di.uv[i] *= q; di.w[i] *= q;
 
 3797                di.pos[i] = { (pos[i].
x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f };
 
 3799            di.mode = nDecalMode;
 
 3800            di.structure = nDecalStructure;
 
 3801            vLayers[nTargetLayer].vecDecalInstance.push_back(di);
 
 3805    void PixelGameEngine::DrawWarpedDecal(
olc::Decal* decal, 
const std::array<olc::vf2d, 4>& pos, 
const olc::Pixel& tint)
 
 3807        DrawWarpedDecal(decal, pos.data(), tint);
 
 3812        DrawWarpedDecal(decal, &pos[0], tint);
 
 3817        DrawPartialWarpedDecal(decal, pos.data(), source_pos, source_size, tint);
 
 3822        DrawPartialWarpedDecal(decal, &pos[0], source_pos, source_size, tint);
 
 3825    void PixelGameEngine::DrawStringDecal(
const olc::vf2d& pos, 
const std::string& sText, 
const Pixel col, 
const olc::vf2d& scale)
 
 3828        for (
auto c : sText)
 
 3832                spos.
x = 0; spos.
y += 8.0f * scale.
y;
 
 3836                spos.
x += 8.0f * float(nTabSizeInSpaces) * scale.
x;
 
 3840                int32_t ox = (c - 32) % 16;
 
 3841                int32_t oy = (c - 32) / 16;
 
 3842                DrawPartialDecal(pos + spos, fontRenderable.Decal(), { float(ox) * 8.0f, float(oy) * 8.0f }, { 8.0f, 8.0f }, scale, col);
 
 3843                spos.
x += 8.0f * scale.
x;
 
 3848    void PixelGameEngine::DrawStringPropDecal(
const olc::vf2d& pos, 
const std::string& sText, 
const Pixel col, 
const olc::vf2d& scale)
 
 3851        for (
auto c : sText)
 
 3855                spos.
x = 0; spos.
y += 8.0f * scale.
y;
 
 3859                spos.
x += 8.0f * float(nTabSizeInSpaces) * scale.
x;
 
 3863                int32_t ox = (c - 32) % 16;
 
 3864                int32_t oy = (c - 32) / 16;
 
 3865                DrawPartialDecal(pos + spos, fontRenderable.Decal(), { float(ox) * 8.0f + float(vFontSpacing[c - 32].x), float(oy) * 8.0f }, { float(vFontSpacing[c - 32].y), 8.0f }, scale, col);
 
 3866                spos.
x += float(vFontSpacing[c - 32].y) * scale.
x;
 
 3871    void PixelGameEngine::DrawRotatedStringDecal(
const olc::vf2d& pos, 
const std::string& sText, 
const float fAngle, 
const olc::vf2d& center, 
const Pixel col, 
const olc::vf2d& scale)
 
 3874        for (
auto c : sText)
 
 3878                spos.
x = center.
x; spos.
y -= 8.0f;
 
 3882                spos.
x += 8.0f * float(nTabSizeInSpaces) * scale.
x;
 
 3886                int32_t ox = (c - 32) % 16;
 
 3887                int32_t oy = (c - 32) / 16;
 
 3888                DrawPartialRotatedDecal(pos, fontRenderable.Decal(), fAngle, spos, { float(ox) * 8.0f, float(oy) * 8.0f }, { 8.0f, 8.0f }, scale, col);
 
 3894    void PixelGameEngine::DrawRotatedStringPropDecal(
const olc::vf2d& pos, 
const std::string& sText, 
const float fAngle, 
const olc::vf2d& center, 
const Pixel col, 
const olc::vf2d& scale)
 
 3897        for (
auto c : sText)
 
 3901                spos.
x = center.
x; spos.
y -= 8.0f;
 
 3905                spos.
x += 8.0f * float(nTabSizeInSpaces) * scale.
x;
 
 3909                int32_t ox = (c - 32) % 16;
 
 3910                int32_t oy = (c - 32) / 16;
 
 3911                DrawPartialRotatedDecal(pos, fontRenderable.Decal(), fAngle, spos, { float(ox) * 8.0f + float(vFontSpacing[c - 32].x), float(oy) * 8.0f }, { float(vFontSpacing[c - 32].y), 8.0f }, scale, col);
 
 3912                spos.
x -= float(vFontSpacing[c - 32].y);
 
 3917    olc::vi2d PixelGameEngine::GetTextSize(
const std::string& s)
 
 3923            if (c == 
'\n') { pos.
y++;  pos.
x = 0; }
 
 3926            size.
x = std::max(size.
x, pos.
x);
 
 3927            size.
y = std::max(size.
y, pos.
y);
 
 3932    void PixelGameEngine::DrawString(
const olc::vi2d& pos, 
const std::string& sText, Pixel col, uint32_t scale)
 
 3934        DrawString(pos.
x, pos.
y, sText, col, scale);
 
 3937    void PixelGameEngine::DrawString(int32_t x, int32_t y, 
const std::string& sText, Pixel col, uint32_t scale)
 
 3941        Pixel::Mode m = nPixelMode;
 
 3943        if (m != Pixel::CUSTOM) 
 
 3945            if (col.a != 255)       SetPixelMode(Pixel::ALPHA);
 
 3946            else                    SetPixelMode(Pixel::MASK);
 
 3948        for (
auto c : sText)
 
 3952                sx = 0; sy += 8 * scale;
 
 3960                int32_t ox = (c - 32) % 16;
 
 3961                int32_t oy = (c - 32) / 16;
 
 3965                    for (uint32_t i = 0; i < 8; i++)
 
 3966                        for (uint32_t j = 0; j < 8; j++)
 
 3967                            if (fontRenderable.Sprite()->GetPixel(i + ox * 8, j + oy * 8).r > 0)
 
 3968                                for (uint32_t is = 0; is < scale; is++)
 
 3969                                    for (uint32_t js = 0; js < scale; js++)
 
 3970                                        Draw(x + sx + (i * scale) + is, y + sy + (j * scale) + js, col);
 
 3974                    for (uint32_t i = 0; i < 8; i++)
 
 3975                        for (uint32_t j = 0; j < 8; j++)
 
 3976                            if (fontRenderable.Sprite()->GetPixel(i + ox * 8, j + oy * 8).r > 0)
 
 3977                                Draw(x + sx + i, y + sy + j, col);
 
 3985    olc::vi2d PixelGameEngine::GetTextSizeProp(
const std::string& s)
 
 3991            if (c == 
'\n') { pos.
y += 1;  pos.
x = 0; }
 
 3993            else pos.
x += vFontSpacing[c - 32].y;
 
 3994            size.
x = std::max(size.
x, pos.
x);
 
 3995            size.
y = std::max(size.
y, pos.
y);
 
 4002    void PixelGameEngine::DrawStringProp(
const olc::vi2d& pos, 
const std::string& sText, Pixel col, uint32_t scale)
 
 4004        DrawStringProp(pos.
x, pos.
y, sText, col, scale);
 
 4007    void PixelGameEngine::DrawStringProp(int32_t x, int32_t y, 
const std::string& sText, Pixel col, uint32_t scale)
 
 4011        Pixel::Mode m = nPixelMode;
 
 4013        if (m != Pixel::CUSTOM)
 
 4015            if (col.a != 255)       SetPixelMode(Pixel::ALPHA);
 
 4016            else                    SetPixelMode(Pixel::MASK);
 
 4018        for (
auto c : sText)
 
 4022                sx = 0; sy += 8 * scale;
 
 4030                int32_t ox = (c - 32) % 16;
 
 4031                int32_t oy = (c - 32) / 16;
 
 4035                    for (int32_t i = 0; i < vFontSpacing[c - 32].y; i++)
 
 4036                        for (int32_t j = 0; j < 8; j++)
 
 4037                            if (fontRenderable.Sprite()->GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).r > 0)
 
 4038                                for (int32_t is = 0; is < int(scale); is++)
 
 4039                                    for (int32_t js = 0; js < int(scale); js++)
 
 4040                                        Draw(x + sx + (i * scale) + is, y + sy + (j * scale) + js, col);
 
 4044                    for (int32_t i = 0; i < vFontSpacing[c - 32].y; i++)
 
 4045                        for (int32_t j = 0; j < 8; j++)
 
 4046                            if (fontRenderable.Sprite()->GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).r > 0)
 
 4047                                Draw(x + sx + i, y + sy + j, col);
 
 4049                sx += vFontSpacing[c - 32].y * scale;
 
 4055    void PixelGameEngine::SetPixelMode(Pixel::Mode m)
 
 4060    Pixel::Mode PixelGameEngine::GetPixelMode()
 
 4067        funcPixelMode = pixelMode;
 
 4068        nPixelMode = Pixel::Mode::CUSTOM;
 
 4071    void PixelGameEngine::SetPixelBlend(
float fBlend)
 
 4073        fBlendFactor = fBlend;
 
 4074        if (fBlendFactor < 0.0f) fBlendFactor = 0.0f;
 
 4075        if (fBlendFactor > 1.0f) fBlendFactor = 1.0f;
 
 4078    std::stringstream& PixelGameEngine::ConsoleOut()
 
 4080        return ssConsoleOutput;
 
 4083    bool PixelGameEngine::IsConsoleShowing()
 const 
 4085        return bConsoleShow;
 
 4088    void PixelGameEngine::ConsoleShow(
const olc::Key& keyExit, 
bool bSuspendTime)
 
 4093        bConsoleShow = 
true;
 
 4094        bConsoleSuspendTime = bSuspendTime;
 
 4095        TextEntryEnable(
true);
 
 4096        keyConsoleExit = keyExit;
 
 4097        pKeyboardState[uint8_t(keyConsoleExit)].bHeld = 
false;
 
 4098        pKeyboardState[uint8_t(keyConsoleExit)].bPressed = 
false;
 
 4099        pKeyboardState[uint8_t(keyConsoleExit)].bReleased = 
true;
 
 4102    void PixelGameEngine::ConsoleClear()
 
 4104        sConsoleLines.clear();
 
 4107    void PixelGameEngine::ConsoleCaptureStdOut(
const bool bCapture)
 
 4110            sbufOldCout = std::cout.rdbuf(ssConsoleOutput.rdbuf());
 
 4112            std::cout.rdbuf(sbufOldCout);
 
 4115    void PixelGameEngine::UpdateConsole()
 
 4117        if (GetKey(keyConsoleExit).bPressed)
 
 4119            TextEntryEnable(
false);
 
 4120            bConsoleSuspendTime = 
false;
 
 4121            bConsoleShow = 
false;
 
 4126        vConsoleCharacterScale = 
olc::vf2d(1.0f, 2.0f) / (
olc::vf2d(vViewSize) * vInvScreenSize);
 
 4130        if (vConsoleSize.y != sConsoleLines.size())
 
 4132            vConsoleCursor = { 0,0 };
 
 4133            sConsoleLines.clear();
 
 4134            sConsoleLines.resize(vConsoleSize.y);
 
 4137        auto TypeCharacter = [&](
const char c)
 
 4139                if (c >= 32 && c < 127)
 
 4141                    sConsoleLines[vConsoleCursor.y].append(1, c);
 
 4145                if (c == 
'\n' || vConsoleCursor.x >= vConsoleSize.x)
 
 4147                    vConsoleCursor.y++; vConsoleCursor.x = 0;
 
 4150                if (vConsoleCursor.y >= vConsoleSize.y)
 
 4152                    vConsoleCursor.y = vConsoleSize.y - 1;
 
 4153                    for (
int i = 1; i < vConsoleSize.y; i++)
 
 4154                        sConsoleLines[i - 1] = sConsoleLines[i];
 
 4155                    sConsoleLines[vConsoleCursor.y].clear();
 
 4160        while (ssConsoleOutput.rdbuf()->sgetc() != -1)
 
 4162            char c = ssConsoleOutput.rdbuf()->sbumpc();
 
 4167        GradientFillRectDecal({ 0,0 }, 
olc::vf2d(vScreenSize), 
olc::PixelF(0, 0, 0.5f, 0.5f), 
olc::PixelF(0, 0, 0.25f, 0.5f), 
olc::PixelF(0, 0, 0.25f, 0.5f), 
olc::PixelF(0, 0, 0.25f, 0.5f));
 
 4171        for (int32_t nLine = 0; nLine < vConsoleSize.y; nLine++)
 
 4172            DrawStringDecal(
olc::vf2d(1, 1 + 
float(nLine)) * vConsoleCharacterScale * 8.0f, sConsoleLines[nLine], 
olc::WHITE, vConsoleCharacterScale);
 
 4175        FillRectDecal(
olc::vf2d(1 + 
float((TextEntryGetCursor() + 1)), 1 + 
float((vConsoleSize.y - 1))) * vConsoleCharacterScale * 8.0f, 
olc::vf2d(8, 8) * vConsoleCharacterScale, 
olc::DARK_CYAN);
 
 4176        DrawStringDecal(
olc::vf2d(1, 1 + 
float((vConsoleSize.y - 1))) * vConsoleCharacterScale * 8.0f, std::string(
">") + TextEntryGetString(), 
olc::YELLOW, vConsoleCharacterScale);
 
 4180    const std::vector<std::string>& PixelGameEngine::GetDroppedFiles()
 const 
 4182        return vDroppedFiles;
 
 4185    const olc::vi2d& PixelGameEngine::GetDroppedFilesPoint()
 const 
 4187        return vDroppedFilesPoint;
 
 4191    void PixelGameEngine::TextEntryEnable(
const bool bEnable, 
const std::string& sText)
 
 4195            nTextEntryCursor = int32_t(sText.size());
 
 4196            sTextEntryString = sText;
 
 4197            bTextEntryEnable = 
true;
 
 4201            bTextEntryEnable = 
false;
 
 4205    std::string PixelGameEngine::TextEntryGetString()
 const 
 4207        return sTextEntryString;
 
 4210    int32_t PixelGameEngine::TextEntryGetCursor()
 const 
 4212        return nTextEntryCursor;
 
 4215    bool PixelGameEngine::IsTextEntryEnabled()
 const 
 4217        return bTextEntryEnable;
 
 4221    void PixelGameEngine::UpdateTextEntry()
 
 4224        for (
const auto& key : GetKeyPressCache())
 
 4232                nTextEntryCursor = std::max(0, nTextEntryCursor - 1);
 
 4233            else if (sym == 
"_R")
 
 4234                nTextEntryCursor = std::min(int32_t(sTextEntryString.size()), nTextEntryCursor + 1);
 
 4235            else if (sym == 
"\b" && nTextEntryCursor > 0)
 
 4237                sTextEntryString.erase(nTextEntryCursor - 1, 1);
 
 4238                nTextEntryCursor = std::max(0, nTextEntryCursor - 1);
 
 4240            else if (sym == 
"_X" && 
size_t(nTextEntryCursor) < sTextEntryString.size())
 
 4241                sTextEntryString.erase(nTextEntryCursor, 1);
 
 4242            else if (sym == 
"_U")
 
 4244                if (!sCommandHistory.empty())
 
 4246                    if (sCommandHistoryIt != sCommandHistory.begin())
 
 4247                        sCommandHistoryIt--;
 
 4249                    nTextEntryCursor = int32_t(sCommandHistoryIt->size());
 
 4250                    sTextEntryString = *sCommandHistoryIt;
 
 4254            else if (sym == 
"_D")
 
 4256                if (!sCommandHistory.empty())
 
 4258                    if (sCommandHistoryIt != sCommandHistory.end())
 
 4260                        sCommandHistoryIt++;
 
 4261                        if (sCommandHistoryIt != sCommandHistory.end())
 
 4263                            nTextEntryCursor = int32_t(sCommandHistoryIt->size());
 
 4264                            sTextEntryString = *sCommandHistoryIt;
 
 4268                            nTextEntryCursor = 0;
 
 4269                            sTextEntryString = 
"";
 
 4275            else if (sym == 
"\n")
 
 4279                    std::cout << 
">" + sTextEntryString + 
"\n";
 
 4280                    if (OnConsoleCommand(sTextEntryString))
 
 4282                        sCommandHistory.push_back(sTextEntryString);
 
 4283                        sCommandHistoryIt = sCommandHistory.end();
 
 4285                    sTextEntryString.clear();
 
 4286                    nTextEntryCursor = 0;
 
 4290                    OnTextEntryComplete(sTextEntryString);
 
 4291                    TextEntryEnable(
false);
 
 4294            else if (sym.size() == 1)
 
 4296                sTextEntryString.insert(nTextEntryCursor, sym);
 
 4306    bool PixelGameEngine::OnUserCreate()
 
 4311    bool PixelGameEngine::OnUserUpdate(
float fElapsedTime)
 
 4313        UNUSED(fElapsedTime);  
return false;
 
 4316    bool PixelGameEngine::OnUserDestroy()
 
 4321    void PixelGameEngine::OnTextEntryComplete(
const std::string& sText) { 
UNUSED(sText); }
 
 4322    bool PixelGameEngine::OnConsoleCommand(
const std::string& sCommand) { 
UNUSED(sCommand); 
return false; }
 
 4328            return platform->SetWindowSize(vPos, vSize);
 
 4333    olc::rcode PixelGameEngine::ShowWindowFrame(
const bool bShowFrame)
 
 4336            return platform->ShowWindowFrame(bShowFrame);
 
 4343    void PixelGameEngine::olc_UpdateViewport()
 
 4345        if (bRealWindowMode)
 
 4347            vPixelSize = { 1,1 };
 
 4348            vViewSize = vScreenSize;
 
 4353        int32_t ww = vScreenSize.x * vPixelSize.x;
 
 4354        int32_t wh = vScreenSize.y * vPixelSize.y;
 
 4355        float wasp = (float)ww / (
float)wh;
 
 4359            vScreenPixelSize = (vWindowSize / vScreenSize);
 
 4360            vViewSize = (vWindowSize / vScreenSize) * vScreenSize;
 
 4364            vViewSize.x = (int32_t)vWindowSize.x;
 
 4365            vViewSize.y = (int32_t)((
float)vViewSize.x / wasp);
 
 4367            if (vViewSize.y > vWindowSize.y)
 
 4369                vViewSize.y = vWindowSize.y;
 
 4370                vViewSize.x = (int32_t)((
float)vViewSize.y * wasp);
 
 4374        vViewPos = (vWindowSize - vViewSize) / 2;
 
 4377    void PixelGameEngine::olc_UpdateWindowPos(int32_t x, int32_t y)
 
 4379        vWindowPos = { x, y };
 
 4380        olc_UpdateViewport();
 
 4383    void PixelGameEngine::olc_UpdateWindowSize(int32_t x, int32_t y)
 
 4385        vWindowSize = { x, y };
 
 4387        if (bRealWindowMode)
 
 4389            vResizeRequested = vWindowSize;
 
 4390            bResizeRequested = 
true;
 
 4393        olc_UpdateViewport();
 
 4396    void PixelGameEngine::olc_UpdateMouseWheel(int32_t delta)
 
 4398        nMouseWheelDeltaCache += delta;
 
 4401    void PixelGameEngine::olc_UpdateMouse(int32_t x, int32_t y)
 
 4405        bHasMouseFocus = 
true;
 
 4406        vMouseWindowPos = { x, y };
 
 4410        vMousePosCache.x = (int32_t)(((
float)x / (
float)(vWindowSize.x - (vViewPos.x * 2)) * (
float)vScreenSize.x));
 
 4411        vMousePosCache.y = (int32_t)(((
float)y / (float)(vWindowSize.y - (vViewPos.y * 2)) * (
float)vScreenSize.y));
 
 4412        if (vMousePosCache.x >= (int32_t)vScreenSize.x) vMousePosCache.x = vScreenSize.x - 1;
 
 4413        if (vMousePosCache.y >= (int32_t)vScreenSize.y) vMousePosCache.y = vScreenSize.y - 1;
 
 4414        if (vMousePosCache.x < 0) vMousePosCache.x = 0;
 
 4415        if (vMousePosCache.y < 0) vMousePosCache.y = 0;
 
 4418    void PixelGameEngine::olc_UpdateMouseState(int32_t button, 
bool state)
 
 4420        pMouseNewState[button] = state;
 
 4423    void PixelGameEngine::olc_UpdateKeyState(int32_t keycode, 
bool state)
 
 4425        pKeyNewState[uint8_t(mapKeys[keycode])] = state;
 
 4426        if (state) vKeyPressCache[nKeyPressCacheTarget].push_back(keycode);
 
 4429    void PixelGameEngine::olc_UpdateMouseFocus(
bool state)
 
 4431        bHasMouseFocus = state;
 
 4434    void PixelGameEngine::olc_UpdateKeyFocus(
bool state)
 
 4436        bHasInputFocus = state;
 
 4439    void PixelGameEngine::olc_DropFiles(int32_t x, int32_t y, 
const std::vector<std::string>& vFiles)
 
 4443        vDroppedFilesPointCache.x = (int32_t)(((
float)x / (
float)(vWindowSize.x - (vViewPos.x * 2)) * (
float)vScreenSize.x));
 
 4444        vDroppedFilesPointCache.y = (int32_t)(((
float)y / (float)(vWindowSize.y - (vViewPos.y * 2)) * (
float)vScreenSize.y));
 
 4445        if (vDroppedFilesPointCache.x >= (int32_t)vScreenSize.x)    vDroppedFilesPointCache.x = vScreenSize.x - 1;
 
 4446        if (vDroppedFilesPointCache.y >= (int32_t)vScreenSize.y)    vDroppedFilesPointCache.y = vScreenSize.y - 1;
 
 4447        if (vDroppedFilesPointCache.x < 0) vDroppedFilesPointCache.x = 0;
 
 4448        if (vDroppedFilesPointCache.y < 0) vDroppedFilesPointCache.y = 0;
 
 4449        vDroppedFilesCache = vFiles;
 
 4452    void PixelGameEngine::olc_Reanimate()
 
 4457    bool PixelGameEngine::olc_IsRunning()
 
 4462    void PixelGameEngine::olc_Terminate()
 
 4464        bAtomActive = 
false;
 
 4467    void PixelGameEngine::EngineThread()
 
 4471        if (platform->ThreadStartUp() == 
olc::FAIL) 
return;
 
 4474        olc_PrepareEngine();
 
 4477        for (
auto& ext : vExtensions) ext->OnBeforeUserCreate();
 
 4478        if (!OnUserCreate()) bAtomActive = 
false;
 
 4479        for (
auto& ext : vExtensions) ext->OnAfterUserCreate();
 
 4484            while (bAtomActive) { olc_CoreUpdate(); }
 
 4487            if (!OnUserDestroy())
 
 4494        platform->ThreadCleanUp();
 
 4497    void PixelGameEngine::olc_PrepareEngine()
 
 4500        if (platform->CreateGraphics(bFullScreen, bEnableVSYNC, vViewPos, vViewSize) == 
olc::FAIL) 
return;
 
 4503        olc_ConstructFontSheet();
 
 4507        vLayers[0].bUpdate = 
true;
 
 4508        vLayers[0].bShow = 
true;
 
 4509        SetDrawTarget(
nullptr);
 
 4511        m_tp1 = std::chrono::system_clock::now();
 
 4512        m_tp2 = std::chrono::system_clock::now();
 
 4516    void PixelGameEngine::adv_ManualRenderEnable(
const bool bEnable)
 
 4518        bManualRenderEnable = bEnable;
 
 4521    void PixelGameEngine::adv_HardwareClip(
const bool bClipAndScale, 
const olc::vi2d& viewPos, 
const olc::vi2d& viewSize, 
const bool bClear)
 
 4525        renderer->UpdateViewport(vViewPos + vNewPos * vViewSize, vNewSize * vViewSize);
 
 4530        SetDecalMode(DecalMode::NORMAL);
 
 4531        renderer->PrepareDrawing();
 
 4534            vInvScreenSize = 1.0f / 
olc::vf2d(viewSize);
 
 4536            vInvScreenSize = 1.0f / 
olc::vf2d(vScreenSize);
 
 4539    void PixelGameEngine::adv_FlushLayer(
const size_t nLayerID)
 
 4541        auto& layer = vLayers[nLayerID];
 
 4545            if (layer.funcHook == 
nullptr)
 
 4547                renderer->ApplyTexture(layer.pDrawTarget.Decal()->id);
 
 4548                if (!bSuspendTextureTransfer)
 
 4550                    layer.pDrawTarget.Decal()->Update();
 
 4551                    layer.bUpdate = 
false;
 
 4560                    (layer.vOffset.x * vInvScreenSize.x) * 2.0f - 1.0f,
 
 4561                    ((layer.vOffset.y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f
 
 4566                    vScreenSpacePos.
x + (2.0f * (float(layer.pDrawTarget.Sprite()->width) * vInvScreenSize.x)) * layer.vScale.x,
 
 4567                    vScreenSpacePos.
y - (2.0f * (float(layer.pDrawTarget.Sprite()->height) * vInvScreenSize.y)) * layer.vScale.y
 
 4571                di.decal = layer.pDrawTarget.Decal();
 
 4574                di.pos = { { vScreenSpacePos.
x, vScreenSpacePos.
y }, { vScreenSpacePos.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpacePos.
y } };
 
 4575                di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
 
 4576                di.w = { 1, 1, 1, 1 };
 
 4577                di.mode = DecalMode::NORMAL;
 
 4578                di.structure = DecalStructure::FAN;
 
 4579                renderer->DrawDecal(di);
 
 4589    void PixelGameEngine::adv_FlushLayerDecals(
const size_t nLayerID)
 
 4592        auto& layer = vLayers[nLayerID];
 
 4593        for (
auto& decal : layer.vecDecalInstance)
 
 4594            renderer->DrawDecal(decal);
 
 4595        layer.vecDecalInstance.clear();
 
 4598    void PixelGameEngine::adv_FlushLayerGPUTasks(
const size_t nLayerID)
 
 4601        auto& layer = vLayers[nLayerID];
 
 4602        for (
auto& decal : layer.vecGPUTasks)
 
 4603            renderer->DoGPUTask(decal);
 
 4604        layer.vecGPUTasks.clear();
 
 4609    void PixelGameEngine::olc_CoreUpdate()
 
 4612        m_tp2 = std::chrono::system_clock::now();
 
 4613        std::chrono::duration<float> elapsedTime = m_tp2 - m_tp1;
 
 4617        float fElapsedTime = elapsedTime.count();
 
 4618        fLastElapsed = fElapsedTime;
 
 4620        if (bConsoleSuspendTime)
 
 4621            fElapsedTime = 0.0f;
 
 4624        platform->HandleSystemEvent();
 
 4627        auto ScanHardware = [&](HWButton* pKeys, 
bool* pStateOld, 
bool* pStateNew, uint32_t nKeyCount)
 
 4629                for (uint32_t i = 0; i < nKeyCount; i++)
 
 4631                    pKeys[i].bPressed = 
false;
 
 4632                    pKeys[i].bReleased = 
false;
 
 4633                    if (pStateNew[i] != pStateOld[i])
 
 4637                            pKeys[i].bPressed = !pKeys[i].bHeld;
 
 4638                            pKeys[i].bHeld = 
true;
 
 4642                            pKeys[i].bReleased = 
true;
 
 4643                            pKeys[i].bHeld = 
false;
 
 4646                    pStateOld[i] = pStateNew[i];
 
 4650        ScanHardware(pKeyboardState, pKeyOldState, pKeyNewState, 256);
 
 4651        ScanHardware(pMouseState, pMouseOldState, pMouseNewState, nMouseButtons);
 
 4654        vMousePos = vMousePosCache;
 
 4655        nMouseWheelDelta = nMouseWheelDeltaCache;
 
 4656        nMouseWheelDeltaCache = 0;
 
 4658        vDroppedFiles = vDroppedFilesCache;
 
 4659        vDroppedFilesPoint = vDroppedFilesPointCache;
 
 4660        vDroppedFilesCache.clear();
 
 4665        nKeyPressCacheTarget ^= 0x01;
 
 4667        if (bTextEntryEnable)
 
 4673        bool bExtensionBlockFrame = 
false;
 
 4674        for (
auto& ext : vExtensions) bExtensionBlockFrame |= ext->OnBeforeUserUpdate(fElapsedTime);
 
 4675        if (!bExtensionBlockFrame)
 
 4677            if (!OnUserUpdate(fElapsedTime)) bAtomActive = 
false;
 
 4680        for (
auto& ext : vExtensions) ext->OnAfterUserUpdate(fElapsedTime);
 
 4683        vKeyPressCache[nKeyPressCacheTarget ^ 0x01].clear();
 
 4685        if (bRealWindowMode)
 
 4687            vPixelSize = { 1,1 };
 
 4688            vViewSize = vScreenSize;
 
 4692        if (!bManualRenderEnable)
 
 4696                SetDrawTarget((uint8_t)0);
 
 4701            renderer->UpdateViewport(vViewPos, vViewSize);
 
 4705            vLayers[0].bUpdate = 
true;
 
 4706            vLayers[0].bShow = 
true;
 
 4707            SetDecalMode(DecalMode::NORMAL);
 
 4708            renderer->PrepareDrawing();
 
 4710            for (
auto layer = vLayers.rbegin(); layer != vLayers.rend(); ++layer)
 
 4714                    if (layer->funcHook == 
nullptr)
 
 4716                        renderer->ApplyTexture(layer->pDrawTarget.Decal()->id);
 
 4717                        if (!bSuspendTextureTransfer && layer->bUpdate)
 
 4719                            layer->pDrawTarget.Decal()->Update();
 
 4720                            layer->bUpdate = 
false;
 
 4723                        renderer->DrawLayerQuad(layer->vOffset, layer->vScale, layer->tint);
 
 4726                        for (
auto& task : layer->vecGPUTasks)
 
 4727                            renderer->DoGPUTask(task);
 
 4728                        layer->vecGPUTasks.clear();
 
 4731                        for (
auto& decal : layer->vecDecalInstance)
 
 4732                            renderer->DrawDecal(decal);
 
 4733                        layer->vecDecalInstance.clear();
 
 4745        renderer->DisplayFrame();
 
 4747        if (bResizeRequested)
 
 4749            bResizeRequested = 
false;
 
 4750            SetScreenSize(vWindowSize.x, vWindowSize.y);
 
 4751            renderer->UpdateViewport({ 0,0 }, vWindowSize);
 
 4755        fFrameTimer += fElapsedTime;
 
 4757        if (fFrameTimer >= 1.0f)
 
 4759            nLastFPS = nFrameCount;
 
 4760            fFrameTimer -= 1.0f;
 
 4761            std::string sTitle = 
"OneLoneCoder.com - Pixel Game Engine - " + sAppName + 
" - FPS: " + std::to_string(nFrameCount);
 
 4762            platform->SetWindowTitle(sTitle);
 
 4767    void PixelGameEngine::olc_ConstructFontSheet()
 
 4770        data += 
"?Q`0001oOch0o01o@F40o0<AGD4090LAGD<090@A7ch0?00O7Q`0600>00000000";
 
 4771        data += 
"O000000nOT0063Qo4d8>?7a14Gno94AA4gno94AaOT0>o3`oO400o7QN00000400";
 
 4772        data += 
"Of80001oOg<7O7moBGT7O7lABET024@aBEd714AiOdl717a_=TH013Q>00000000";
 
 4773        data += 
"720D000V?V5oB3Q_HdUoE7a9@DdDE4A9@DmoE4A;Hg]oM4Aj8S4D84@`00000000";
 
 4774        data += 
"OaPT1000Oa`^13P1@AI[?g`1@A=[OdAoHgljA4Ao?WlBA7l1710007l100000000";
 
 4775        data += 
"ObM6000oOfMV?3QoBDD`O7a0BDDH@5A0BDD<@5A0BGeVO5ao@CQR?5Po00000000";
 
 4776        data += 
"Oc``000?Ogij70PO2D]??0Ph2DUM@7i`2DTg@7lh2GUj?0TO0C1870T?00000000";
 
 4777        data += 
"70<4001o?P<7?1QoHg43O;`h@GT0@:@LB@d0>:@hN@L0@?aoN@<0O7ao0000?000";
 
 4778        data += 
"OcH0001SOglLA7mg24TnK7ln24US>0PL24U140PnOgl0>7QgOcH0K71S0000A000";
 
 4779        data += 
"00H00000@Dm1S007@DUSg00?OdTnH7YhOfTL<7Yh@Cl0700?@Ah0300700000000";
 
 4780        data += 
"<008001QL00ZA41a@6HnI<1i@FHLM81M@@0LG81?O`0nC?Y7?`0ZA7Y300080000";
 
 4781        data += 
"O`082000Oh0827mo6>Hn?Wmo?6HnMb11MP08@C11H`08@FP0@@0004@000000000";
 
 4782        data += 
"00P00001Oab00003OcKP0006@6=PMgl<@440MglH@000000`@000001P00000000";
 
 4783        data += 
"Ob@8@@00Ob@8@Ga13R@8Mga172@8?PAo3R@827QoOb@820@0O`0007`0000007P0";
 
 4784        data += 
"O`000P08Od400g`<3V=P0G`673IP0`@3>1`00P@6O`P00g`<O`000GP800000000";
 
 4785        data += 
"?P9PL020O`<`N3R0@E4HC7b0@ET<ATB0@@l6C4B0O`H3N7b0?P01L3R000000020";
 
 4787        fontRenderable.Create(128, 48);
 
 4790        for (
size_t b = 0; b < 1024; b += 4)
 
 4792            uint32_t sym1 = (uint32_t)data[b + 0] - 48;
 
 4793            uint32_t sym2 = (uint32_t)data[b + 1] - 48;
 
 4794            uint32_t sym3 = (uint32_t)data[b + 2] - 48;
 
 4795            uint32_t sym4 = (uint32_t)data[b + 3] - 48;
 
 4796            uint32_t r = sym1 << 18 | sym2 << 12 | sym3 << 6 | sym4;
 
 4798            for (
int i = 0; i < 24; i++)
 
 4800                int k = r & (1 << i) ? 255 : 0;
 
 4801                fontRenderable.Sprite()->SetPixel(px, py, 
olc::Pixel(k, k, k, k));
 
 4802                if (++py == 48) { px++; py = 0; }
 
 4806        fontRenderable.Decal()->Update();
 
 4808        constexpr std::array<uint8_t, 96> vSpacing = { {
 
 4809            0x03,0x25,0x16,0x08,0x07,0x08,0x08,0x04,0x15,0x15,0x08,0x07,0x15,0x07,0x24,0x08,
 
 4810            0x08,0x17,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x24,0x15,0x06,0x07,0x16,0x17,
 
 4811            0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x17,0x08,0x08,0x17,0x08,0x08,0x08,
 
 4812            0x08,0x08,0x08,0x08,0x17,0x08,0x08,0x08,0x08,0x17,0x08,0x15,0x08,0x15,0x08,0x08,
 
 4813            0x24,0x18,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x33,0x17,0x17,0x33,0x18,0x17,0x17,
 
 4814            0x17,0x17,0x17,0x17,0x07,0x17,0x17,0x18,0x18,0x17,0x17,0x07,0x33,0x07,0x08,0x00, } };
 
 4816        for (
auto c : vSpacing) vFontSpacing.push_back({ c >> 4, c & 15 });
 
 4819#ifdef OLC_KEYBOARD_UK 
 4907    const std::vector<int32_t>& PixelGameEngine::GetKeyPressCache()
 const 
 4910        return vKeyPressCache[nKeyPressCacheTarget ^ 0x01];
 
 4913    olc::Key PixelGameEngine::ConvertKeycode(
const int keycode)
 const 
 4915        if (
mapKeys.count(
size_t(keycode)) > 0)
 
 4923    const std::string PixelGameEngine::GetKeySymbol(
const olc::Key pgekey, 
const bool modShift, 
const bool modCtrl, 
const bool modAlt)
 const 
 4925        if (vKeyboardMap.count(pgekey) > 0)
 
 4927            const auto& [sym, sym_s, sym_c, sym_a] = vKeyboardMap.at(pgekey);
 
 4928            if (modShift) 
return sym_s;
 
 4929            if (modCtrl) 
return sym_c;
 
 4930            if (modAlt) 
return sym_a;
 
 4937    void PixelGameEngine::pgex_Register(
olc::PGEX* pgex)
 
 4939        if (std::find(vExtensions.begin(), vExtensions.end(), pgex) == vExtensions.end())
 
 4940            vExtensions.push_back(pgex);
 
 4944    PGEX::PGEX(
bool bHook) { 
if (bHook) pge->pgex_Register(
this); }
 
 4945    void PGEX::OnBeforeUserCreate() {}
 
 4946    void PGEX::OnAfterUserCreate() {}
 
 4947    bool PGEX::OnBeforeUserUpdate(
float& fElapsedTime) { 
return false; }
 
 4948    void PGEX::OnAfterUserUpdate(
float fElapsedTime) {}
 
 4952    std::atomic<bool> PixelGameEngine::bAtomActive{ 
false };
 
 4961#pragma region platform_headless 
 4964#if defined(OLC_GFX_HEADLESS) 
 4968        virtual void       PrepareDevice() {};
 
 4969        virtual olc::rcode CreateDevice(std::vector<void*> params, 
bool bFullScreen, 
bool bVSYNC) { 
return olc::rcode::OK; }
 
 4971        virtual void       DisplayFrame() {}
 
 4972        virtual void       PrepareDrawing() {}
 
 4976        virtual uint32_t   CreateTexture(
const uint32_t width, 
const uint32_t height, 
const bool filtered = 
false, 
const bool clamp = 
true) { 
return 1; };
 
 4977        virtual void       UpdateTexture(uint32_t 
id, 
olc::Sprite* spr) {}
 
 4978        virtual void       ReadTexture(uint32_t 
id, 
olc::Sprite* spr) {}
 
 4979        virtual uint32_t   DeleteTexture(
const uint32_t 
id) { 
return 1; }
 
 4980        virtual void       ApplyTexture(uint32_t 
id) {}
 
 4982        virtual void       ClearBuffer(
olc::Pixel p, 
bool bDepth) {}
 
 4985#if defined(OLC_PLATFORM_HEADLESS) 
 4994        virtual olc::rcode ShowWindowFrame(
const bool bShowFrame = 
true)
 override 
 5017#pragma region image_stb 
 5029#if defined(OLC_IMAGE_STB) 
 5030#define STB_IMAGE_IMPLEMENTATION 
 5031#include "stb_image.h" 
 5037        ImageLoader_STB() : ImageLoader()
 
 5046            stbi_uc* bytes = 
nullptr;
 
 5047            int w = 0, h = 0, cmp = 0;
 
 5048            if (pack != 
nullptr)
 
 5051                bytes = stbi_load_from_memory((
unsigned char*)rb.vMemory.data(), 
int(rb.vMemory.size()), &w, &h, &cmp, 4);
 
 5057                bytes = stbi_load(sImageFile.c_str(), &w, &h, &cmp, 4);
 
 5082#if !defined(OLC_PGE_HEADLESS) 
 5084#pragma region renderer_ogl10 
 5088#if defined(OLC_GFX_OPENGL10) 
 5090#if defined(OLC_PLATFORM_WINAPI) 
 5093#if !defined(__MINGW32__) 
 5094#pragma comment(lib, "Dwmapi.lib") 
 5096typedef BOOL(WINAPI wglSwapInterval_t) (
int interval);
 
 5097static wglSwapInterval_t* wglSwapInterval = 
nullptr;
 
 5098typedef HDC glDeviceContext_t;
 
 5099typedef HGLRC glRenderContext_t;
 
 5102#if defined(__linux__) || defined(__FreeBSD__) 
 5106#if defined(OLC_PLATFORM_X11) 
 5111typedef int(glSwapInterval_t)(X11::Display* dpy, X11::GLXDrawable drawable, 
int interval);
 
 5112static glSwapInterval_t* glSwapIntervalEXT;
 
 5113typedef X11::GLXContext glDeviceContext_t;
 
 5114typedef X11::GLXContext glRenderContext_t;
 
 5117#if defined(__APPLE__) 
 5118#define GL_SILENCE_DEPRECATION 
 5119#include <OpenGL/OpenGL.h> 
 5120#include <OpenGL/gl.h> 
 5121#include <OpenGL/glu.h> 
 5129#if defined(OLC_PLATFORM_GLUT) 
 5130        bool mFullScreen = 
false;
 
 5132        glDeviceContext_t glDeviceContext = 0;
 
 5133        glRenderContext_t glRenderContext = 0;
 
 5139        std::array<float, 16> matProjection = { {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1} };
 
 5140#if defined(OLC_PLATFORM_X11) 
 5141        X11::Display* olc_Display = 
nullptr;
 
 5142        X11::Window* olc_Window = 
nullptr;
 
 5143        X11::XVisualInfo* olc_VisualInfo = 
nullptr;
 
 5147        void PrepareDevice()
 override 
 5149#if defined(OLC_PLATFORM_GLUT) 
 5152            char* argv[1] = { (
char*)
"" };
 
 5153            glutInit(&argc, argv);
 
 5154            glutInitWindowPosition(0, 0);
 
 5155            glutInitWindowSize(512, 512);
 
 5156            glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
 
 5158            glutCreateWindow(
"OneLoneCoder.com - Pixel Game Engine");
 
 5159            glEnable(GL_TEXTURE_2D); 
 
 5160            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
 
 5164        olc::rcode CreateDevice(std::vector<void*> params, 
bool bFullScreen, 
bool bVSYNC)
 override 
 5166#if defined(OLC_PLATFORM_WINAPI) 
 5168            glDeviceContext = GetDC((HWND)(params[0]));
 
 5169            PIXELFORMATDESCRIPTOR pfd =
 
 5171                sizeof(PIXELFORMATDESCRIPTOR), 1,
 
 5172                PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
 
 5173                PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
 5174                PFD_MAIN_PLANE, 0, 0, 0, 0
 
 5178            if (!(pf = ChoosePixelFormat(glDeviceContext, &pfd))) 
return olc::FAIL;
 
 5179            SetPixelFormat(glDeviceContext, pf, &pfd);
 
 5181            if (!(glRenderContext = wglCreateContext(glDeviceContext))) 
return olc::FAIL;
 
 5182            wglMakeCurrent(glDeviceContext, glRenderContext);
 
 5185            wglSwapInterval = (wglSwapInterval_t*)wglGetProcAddress(
"wglSwapIntervalEXT");
 
 5186            if (wglSwapInterval && !bVSYNC) wglSwapInterval(0);
 
 5190#if defined(OLC_PLATFORM_X11) 
 5191            using namespace X11;
 
 5194            olc_Display = (X11::Display*)(params[0]);
 
 5195            olc_Window = (X11::Window*)(params[1]);
 
 5196            olc_VisualInfo = (X11::XVisualInfo*)(params[2]);
 
 5198            glDeviceContext = glXCreateContext(olc_Display, olc_VisualInfo, 
nullptr, GL_TRUE);
 
 5199            glXMakeCurrent(olc_Display, *olc_Window, glDeviceContext);
 
 5201            XWindowAttributes gwa;
 
 5202            XGetWindowAttributes(olc_Display, *olc_Window, &gwa);
 
 5203            glViewport(0, 0, gwa.width, gwa.height);
 
 5205            glSwapIntervalEXT = 
nullptr;
 
 5206            glSwapIntervalEXT = (glSwapInterval_t*)glXGetProcAddress((
unsigned char*)
"glXSwapIntervalEXT");
 
 5208            if (glSwapIntervalEXT == 
nullptr && !bVSYNC)
 
 5210                printf(
"NOTE: Could not disable VSYNC, glXSwapIntervalEXT() was not found!\n");
 
 5211                printf(
"      Don't worry though, things will still work, it's just the\n");
 
 5212                printf(
"      frame rate will be capped to your monitors refresh rate - javidx9\n");
 
 5215            if (glSwapIntervalEXT != 
nullptr && !bVSYNC)
 
 5216                glSwapIntervalEXT(olc_Display, *olc_Window, 0);
 
 5219#if defined(OLC_PLATFORM_GLUT) 
 5220            mFullScreen = bFullScreen;
 
 5223#if defined(__APPLE__) 
 5225                CGLContextObj ctx = CGLGetCurrentContext();
 
 5226                if (ctx) CGLSetParameter(ctx, kCGLCPSwapInterval, &sync);
 
 5230            glEnable(GL_TEXTURE_2D); 
 
 5231            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
 
 5238#if defined(OLC_PLATFORM_WINAPI) 
 5239            wglDeleteContext(glRenderContext);
 
 5242#if defined(OLC_PLATFORM_X11) 
 5243            glXMakeCurrent(olc_Display, None, NULL);
 
 5244            glXDestroyContext(olc_Display, glDeviceContext);
 
 5247#if defined(OLC_PLATFORM_GLUT) 
 5248            glutDestroyWindow(glutGetWindow());
 
 5253        void DisplayFrame()
 override 
 5255#if defined(OLC_PLATFORM_WINAPI) 
 5256            SwapBuffers(glDeviceContext);
 
 5257            if (bSync) DwmFlush(); 
 
 5260#if defined(OLC_PLATFORM_X11) 
 5261            X11::glXSwapBuffers(olc_Display, *olc_Window);
 
 5264#if defined(OLC_PLATFORM_GLUT) 
 5269        void PrepareDrawing()
 override 
 5274            nDecalMode = DecalMode::NORMAL;
 
 5275            nDecalStructure = DecalStructure::FAN;
 
 5276            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 5277            glDisable(GL_CULL_FACE);
 
 5282            if (mode != nDecalMode)
 
 5287                    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 5290                    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 
 5293                    glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
 
 5296                    glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
 
 5299                    glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
 
 5302                    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 5312            glDisable(GL_CULL_FACE);
 
 5314            glColor4ub(tint.
r, tint.
g, tint.
b, tint.
a);
 
 5315            glTexCoord2f(0.0f * scale.
x + offset.
x, 1.0f * scale.
y + offset.
y);
 
 5316            glVertex3f(-1.0f , -1.0f , 0.0f);
 
 5317            glTexCoord2f(0.0f * scale.
x + offset.
x, 0.0f * scale.
y + offset.
y);
 
 5318            glVertex3f(-1.0f , 1.0f , 0.0f);
 
 5319            glTexCoord2f(1.0f * scale.
x + offset.
x, 0.0f * scale.
y + offset.
y);
 
 5320            glVertex3f(1.0f , 1.0f , 0.0f);
 
 5321            glTexCoord2f(1.0f * scale.
x + offset.
x, 1.0f * scale.
y + offset.
y);
 
 5322            glVertex3f(1.0f , -1.0f , 0.0f);
 
 5328            SetDecalMode(decal.
mode);
 
 5330            if (decal.
decal == 
nullptr)
 
 5331                glBindTexture(GL_TEXTURE_2D, 0);
 
 5333                glBindTexture(GL_TEXTURE_2D, decal.
decal->
id);
 
 5335            glDisable(GL_CULL_FACE);
 
 5339                glEnable(GL_DEPTH_TEST);
 
 5342            if (nDecalMode == DecalMode::WIREFRAME)
 
 5343                glBegin(GL_LINE_LOOP);
 
 5347                    glBegin(GL_TRIANGLE_FAN);
 
 5349                    glBegin(GL_TRIANGLE_STRIP);
 
 5351                    glBegin(GL_TRIANGLES);
 
 5353                    glBegin(GL_LINE_STRIP);
 
 5362                for (uint32_t n = 0; n < decal.
points; n++)
 
 5364                    glColor4ub(decal.
tint[n].r, decal.
tint[n].g, decal.
tint[n].b, decal.
tint[n].a);
 
 5365                    glTexCoord4f(decal.
uv[n].x, decal.
uv[n].y, 0.0f, decal.
w[n]);
 
 5366                    glVertex3f(decal.
pos[n].x, decal.
pos[n].y, decal.
z[n]);
 
 5372                for (uint32_t n = 0; n < decal.
points; n++)
 
 5374                    glColor4ub(decal.
tint[n].r, decal.
tint[n].g, decal.
tint[n].b, decal.
tint[n].a);
 
 5375                    glTexCoord4f(decal.
uv[n].x, decal.
uv[n].y, 0.0f, decal.
w[n]);
 
 5376                    glVertex2f(decal.
pos[n].x, decal.
pos[n].y);
 
 5384                glDisable(GL_DEPTH_TEST);
 
 5389        void Set3DProjection(
const std::array<float, 16>& mat)
 
 5391            matProjection = mat;
 
 5396            SetDecalMode(task.
mode);
 
 5398            if (task.
decal == 
nullptr)
 
 5399                glBindTexture(GL_TEXTURE_2D, 0);
 
 5401                glBindTexture(GL_TEXTURE_2D, task.
decal->
id);
 
 5403            glMatrixMode(GL_PROJECTION);
 
 5406            glMatrixMode(GL_MODELVIEW);
 
 5411                glCullFace(GL_FRONT);
 
 5412                glDisable(GL_CULL_FACE);
 
 5416                glCullFace(GL_FRONT);
 
 5417                glEnable(GL_CULL_FACE);
 
 5421                glCullFace(GL_BACK);
 
 5422                glEnable(GL_CULL_FACE);
 
 5427                glEnable(GL_DEPTH_TEST);
 
 5429                glMatrixMode(GL_PROJECTION);
 
 5430                glLoadMatrixf(matProjection.data());
 
 5432                glMatrixMode(GL_MODELVIEW);
 
 5433                glLoadMatrixf(task.
mvp.data());
 
 5437                glMatrixMode(GL_PROJECTION);
 
 5440                glMatrixMode(GL_MODELVIEW);
 
 5445            if (nDecalMode == DecalMode::WIREFRAME)
 
 5446                glBegin(GL_LINE_LOOP);
 
 5450                    glBegin(GL_TRIANGLE_FAN);
 
 5452                    glBegin(GL_TRIANGLE_STRIP);
 
 5454                    glBegin(GL_TRIANGLES);
 
 5462            float f[4] = { float(task.
tint.
r) / 255.0f, float(task.
tint.
g) / 255.0f, float(task.
tint.
b) / 255.0f, float(task.
tint.
a) / 255.0f };
 
 5466                for (uint32_t n = 0; n < task.
vb.size(); n++)
 
 5469                    glColor4ub(GLubyte(p.
r * f[0]), GLubyte(p.
g * f[1]), GLubyte(p.
b * f[2]), GLubyte(p.
a * f[3]));
 
 5470                    glTexCoord2f(task.
vb[n].p[4], task.
vb[n].p[5]);
 
 5471                    glVertex4f(task.
vb[n].p[0], task.
vb[n].p[1], task.
vb[n].p[2], task.
vb[n].p[3]);
 
 5476                for (uint32_t n = 0; n < task.
vb.size(); n++)
 
 5479                    glColor4ub(GLubyte(p.
r * f[0]), GLubyte(p.
g * f[1]), GLubyte(p.
b * f[2]), GLubyte(p.
a * f[3]));
 
 5480                    glVertex4f(task.
vb[n].p[4], task.
vb[n].p[5], 0.0f, task.
vb[n].p[3]);
 
 5481                    glTexCoord2f(task.
vb[n].p[0], task.
vb[n].p[1]);
 
 5489                glDisable(GL_DEPTH_TEST);
 
 5492            glMatrixMode(GL_PROJECTION);
 
 5495            glMatrixMode(GL_MODELVIEW);
 
 5499        uint32_t CreateTexture(
const uint32_t width, 
const uint32_t height, 
const bool filtered, 
const bool clamp)
 override 
 5504            glGenTextures(1, &
id);
 
 5505            glBindTexture(GL_TEXTURE_2D, 
id);
 
 5508                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
 5509                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
 5513                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
 5514                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
 5519                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
 
 5520                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
 5524                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 
 5525                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
 5528            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
 5532        uint32_t DeleteTexture(
const uint32_t 
id)
 override 
 5534            glDeleteTextures(1, &
id);
 
 5538        void UpdateTexture(uint32_t 
id, 
olc::Sprite* spr)
 override 
 5541            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spr->
width, spr->
height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spr->
GetData());
 
 5544        void ReadTexture(uint32_t 
id, 
olc::Sprite* spr)
 override 
 5546            glReadPixels(0, 0, spr->
width, spr->
height, GL_RGBA, GL_UNSIGNED_BYTE, spr->
GetData());
 
 5549        void ApplyTexture(uint32_t 
id)
 override 
 5551            glBindTexture(GL_TEXTURE_2D, 
id);
 
 5554        void ClearBuffer(
olc::Pixel p, 
bool bDepth)
 override 
 5556            glClearColor(
float(p.
r) / 255.0f, 
float(p.
g) / 255.0f, 
float(p.
b) / 255.0f, 
float(p.
a) / 255.0f);
 
 5557            glClear(GL_COLOR_BUFFER_BIT);
 
 5558            if (bDepth) glClear(GL_DEPTH_BUFFER_BIT);
 
 5563            glViewport(pos.
x, pos.
y, size.
x, size.
y);
 
 5573#pragma region renderer_ogl33 
 5577#if defined(OLC_GFX_OPENGL33) 
 5579#if defined(OLC_PLATFORM_WINAPI) 
 5582#if !defined(__MINGW32__) 
 5583#pragma comment(lib, "Dwmapi.lib") 
 5586typedef HDC glDeviceContext_t;
 
 5587typedef HGLRC glRenderContext_t;
 
 5589#define OGL_LOAD(t, n) (t*)wglGetProcAddress(#n) 
 5596#if defined(OLC_PLATFORM_X11) 
 5602typedef X11::GLXContext glDeviceContext_t;
 
 5603typedef X11::GLXContext glRenderContext_t;
 
 5605#define OGL_LOAD(t, n) (t*)glXGetProcAddress((unsigned char*)#n); 
 5615#if defined(OLC_PLATFORM_EMSCRIPTEN) 
 5617#include <GLES2/gl2.h> 
 5618#define GL_GLEXT_PROTOTYPES 
 5619#include <GLES2/gl2ext.h> 
 5620#include <emscripten/emscripten.h> 
 5622typedef EGLBoolean(locSwapInterval_t)(EGLDisplay display, EGLint interval);
 
 5623#define GL_CLAMP GL_CLAMP_TO_EDGE 
 5624#define OGL_LOAD(t, n) n; 
 5670#if defined(OLC_PLATFORM_EMSCRIPTEN) 
 5671        EGLDisplay olc_Display;
 
 5672        EGLConfig olc_Config;
 
 5673        EGLContext olc_Context;
 
 5674        EGLSurface olc_Surface;
 
 5677#if defined(OLC_PLATFORM_GLUT) 
 5678        bool mFullScreen = 
false;
 
 5680#if !defined(OLC_PLATFORM_EMSCRIPTEN) 
 5681        glDeviceContext_t glDeviceContext = 0;
 
 5682        glRenderContext_t glRenderContext = 0;
 
 5687#if defined(OLC_PLATFORM_X11) 
 5688        X11::Display* olc_Display = 
nullptr;
 
 5689        X11::Window* olc_Window = 
nullptr;
 
 5690        X11::XVisualInfo* olc_VisualInfo = 
nullptr;
 
 5694        locCreateShader_t* locCreateShader = 
nullptr;
 
 5695        locShaderSource_t* locShaderSource = 
nullptr;
 
 5696        locCompileShader_t* locCompileShader = 
nullptr;
 
 5697        locDeleteShader_t* locDeleteShader = 
nullptr;
 
 5698        locCreateProgram_t* locCreateProgram = 
nullptr;
 
 5699        locDeleteProgram_t* locDeleteProgram = 
nullptr;
 
 5700        locLinkProgram_t* locLinkProgram = 
nullptr;
 
 5701        locAttachShader_t* locAttachShader = 
nullptr;
 
 5702        locBindBuffer_t* locBindBuffer = 
nullptr;
 
 5703        locBufferData_t* locBufferData = 
nullptr;
 
 5704        locGenBuffers_t* locGenBuffers = 
nullptr;
 
 5705        locVertexAttribPointer_t* locVertexAttribPointer = 
nullptr;
 
 5706        locEnableVertexAttribArray_t* locEnableVertexAttribArray = 
nullptr;
 
 5707        locUseProgram_t* locUseProgram = 
nullptr;
 
 5708        locBindVertexArray_t* locBindVertexArray = 
nullptr;
 
 5709        locGenVertexArrays_t* locGenVertexArrays = 
nullptr;
 
 5710        locSwapInterval_t* locSwapInterval = 
nullptr;
 
 5711        locGetShaderInfoLog_t* locGetShaderInfoLog = 
nullptr;
 
 5712        locGetUniformLocation_t* locGetUniformLocation = 
nullptr;
 
 5713        locUniformMatrix4fv_t* locUniformMatrix4fv = 
nullptr;
 
 5714        locUniform1i_t* locUniform1i = 
nullptr;
 
 5715        locUniform4fv_t* locUniform4fv = 
nullptr;
 
 5719        uint32_t m_nQuadShader = 0;
 
 5720        uint32_t m_vbQuad = 0;
 
 5721        uint32_t m_vaQuad = 0;
 
 5723        uint32_t m_uniMVP = 0;
 
 5724        uint32_t m_uniIs3D = 0;
 
 5725        uint32_t m_uniTint = 0;
 
 5734        std::array<float, 16> matProjection = { {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1} };
 
 5741        void PrepareDevice()
 override 
 5743#if defined(OLC_PLATFORM_GLUT) 
 5746            char* argv[1] = { (
char*)
"" };
 
 5747            glutInit(&argc, argv);
 
 5748            glutInitWindowPosition(0, 0);
 
 5749            glutInitWindowSize(512, 512);
 
 5750            glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
 
 5752            glutCreateWindow(
"OneLoneCoder.com - Pixel Game Engine");
 
 5753            glEnable(GL_TEXTURE_2D); 
 
 5754            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
 
 5758        olc::rcode CreateDevice(std::vector<void*> params, 
bool bFullScreen, 
bool bVSYNC)
 override 
 5761#if defined(OLC_PLATFORM_WINAPI) 
 5763            glDeviceContext = GetDC((HWND)(params[0]));
 
 5764            PIXELFORMATDESCRIPTOR pfd =
 
 5766                sizeof(PIXELFORMATDESCRIPTOR), 1,
 
 5767                PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
 
 5768                PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
 5769                PFD_MAIN_PLANE, 0, 0, 0, 0
 
 5773            if (!(pf = ChoosePixelFormat(glDeviceContext, &pfd))) 
return olc::FAIL;
 
 5774            SetPixelFormat(glDeviceContext, pf, &pfd);
 
 5776            if (!(glRenderContext = wglCreateContext(glDeviceContext))) 
return olc::FAIL;
 
 5777            wglMakeCurrent(glDeviceContext, glRenderContext);
 
 5780            locSwapInterval = OGL_LOAD(locSwapInterval_t, wglSwapIntervalEXT);
 
 5781            if (locSwapInterval && !bVSYNC) locSwapInterval(0);
 
 5785#if defined(OLC_PLATFORM_X11) 
 5786            using namespace X11;
 
 5789            olc_Display = (X11::Display*)(params[0]);
 
 5790            olc_Window = (X11::Window*)(params[1]);
 
 5791            olc_VisualInfo = (X11::XVisualInfo*)(params[2]);
 
 5793            glDeviceContext = glXCreateContext(olc_Display, olc_VisualInfo, 
nullptr, GL_TRUE);
 
 5794            glXMakeCurrent(olc_Display, *olc_Window, glDeviceContext);
 
 5796            XWindowAttributes gwa;
 
 5797            XGetWindowAttributes(olc_Display, *olc_Window, &gwa);
 
 5798            glViewport(0, 0, gwa.width, gwa.height);
 
 5800            locSwapInterval = OGL_LOAD(locSwapInterval_t, glXSwapIntervalEXT);
 
 5802            if (locSwapInterval == 
nullptr && !bVSYNC)
 
 5804                printf(
"NOTE: Could not disable VSYNC, glXSwapIntervalEXT() was not found!\n");
 
 5805                printf(
"      Don't worry though, things will still work, it's just the\n");
 
 5806                printf(
"      frame rate will be capped to your monitors refresh rate - javidx9\n");
 
 5809            if (locSwapInterval != 
nullptr && !bVSYNC)
 
 5810                locSwapInterval(olc_Display, *olc_Window, 0);
 
 5813#if defined(OLC_PLATFORM_EMSCRIPTEN) 
 5814            EGLint 
const attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_NONE };
 
 5815            EGLint 
const context_config[] = { EGL_CONTEXT_CLIENT_VERSION , 2, EGL_NONE };
 
 5818            olc_Display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
 
 5819            eglInitialize(olc_Display, 
nullptr, 
nullptr);
 
 5820            eglChooseConfig(olc_Display, attribute_list, &olc_Config, 1, &num_config);
 
 5823            olc_Context = eglCreateContext(olc_Display, olc_Config, EGL_NO_CONTEXT, context_config);
 
 5824            olc_Surface = eglCreateWindowSurface(olc_Display, olc_Config, NULL, 
nullptr);
 
 5825            eglMakeCurrent(olc_Display, olc_Surface, olc_Surface, olc_Context);
 
 5827            locSwapInterval = &eglSwapInterval;
 
 5828            locSwapInterval(olc_Display, bVSYNC ? 1 : 0);
 
 5831#if defined(OLC_PLATFORM_GLUT) 
 5832            mFullScreen = bFullScreen;
 
 5835#if defined(__APPLE__) 
 5837                CGLContextObj ctx = CGLGetCurrentContext();
 
 5838                if (ctx) CGLSetParameter(ctx, kCGLCPSwapInterval, &sync);
 
 5842#if !defined(OLC_PLATFORM_EMSCRIPTEN) 
 5843            glEnable(GL_TEXTURE_2D); 
 
 5844            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
 
 5848            locCreateShader = OGL_LOAD(locCreateShader_t, glCreateShader);
 
 5849            locCompileShader = OGL_LOAD(locCompileShader_t, glCompileShader);
 
 5850            locShaderSource = OGL_LOAD(locShaderSource_t, glShaderSource);
 
 5851            locDeleteShader = OGL_LOAD(locDeleteShader_t, glDeleteShader);
 
 5852            locCreateProgram = OGL_LOAD(locCreateProgram_t, glCreateProgram);
 
 5853            locDeleteProgram = OGL_LOAD(locDeleteProgram_t, glDeleteProgram);
 
 5854            locLinkProgram = OGL_LOAD(locLinkProgram_t, glLinkProgram);
 
 5855            locAttachShader = OGL_LOAD(locAttachShader_t, glAttachShader);
 
 5856            locBindBuffer = OGL_LOAD(locBindBuffer_t, glBindBuffer);
 
 5857            locBufferData = OGL_LOAD(locBufferData_t, glBufferData);
 
 5858            locGenBuffers = OGL_LOAD(locGenBuffers_t, glGenBuffers);
 
 5859            locVertexAttribPointer = OGL_LOAD(locVertexAttribPointer_t, glVertexAttribPointer);
 
 5860            locEnableVertexAttribArray = OGL_LOAD(locEnableVertexAttribArray_t, glEnableVertexAttribArray);
 
 5861            locUseProgram = OGL_LOAD(locUseProgram_t, glUseProgram);
 
 5862            locGetShaderInfoLog = OGL_LOAD(locGetShaderInfoLog_t, glGetShaderInfoLog);
 
 5863            locUniform1i = OGL_LOAD(locUniform1i_t, glUniform1i);
 
 5864            locUniform4fv = OGL_LOAD(locUniform4fv_t, glUniform4fv);
 
 5865            locUniformMatrix4fv = OGL_LOAD(locUniformMatrix4fv_t, glUniformMatrix4fv);
 
 5866            locGetUniformLocation = OGL_LOAD(locGetUniformLocation_t, glGetUniformLocation);
 
 5867#if !defined(OLC_PLATFORM_EMSCRIPTEN) 
 5868            locBindVertexArray = OGL_LOAD(locBindVertexArray_t, glBindVertexArray);
 
 5869            locGenVertexArrays = OGL_LOAD(locGenVertexArrays_t, glGenVertexArrays);
 
 5871            locBindVertexArray = glBindVertexArrayOES;
 
 5872            locGenVertexArrays = glGenVertexArraysOES;
 
 5876            m_nFS = locCreateShader(0x8B30);
 
 5877            const GLchar* strFS =
 
 5878#if defined(__arm__) || defined(OLC_PLATFORM_EMSCRIPTEN) 
 5880                "precision mediump float;" 
 5882                "#version 330 core\n" 
 5887                "uniform sampler2D sprTex;\n" 
 5888                "void main(){pixel = texture(sprTex, oTex) * oCol;}";
 
 5889            locShaderSource(m_nFS, 1, &strFS, NULL);
 
 5890            locCompileShader(m_nFS);
 
 5892            m_nVS = locCreateShader(0x8B31);
 
 5893            const GLchar* strVS =
 
 5894#if defined(__arm__) || defined(OLC_PLATFORM_EMSCRIPTEN) 
 5896                "precision mediump float;" 
 5898                "#version 330 core\n" 
 5900                "layout(location = 0) in vec4 aPos;\n" 
 5901                "layout(location = 1) in vec2 aTex;\n" 
 5902                "layout(location = 2) in vec4 aCol;\n" 
 5903                "uniform mat4 mvp;\n" 
 5904                "uniform int is3d;\n" 
 5905                "uniform vec4 tint;\n" 
 5908                "void main(){ if(is3d!=0) {gl_Position = mvp * vec4(aPos.x, aPos.y, aPos.z, 1.0); oTex = aTex;} else {float p = 1.0 / aPos.z; gl_Position = p * vec4(aPos.x, aPos.y, 0.0, 1.0); oTex = p * aTex;} oCol = aCol * tint;}";
 
 5909            locShaderSource(m_nVS, 1, &strVS, NULL);
 
 5910            locCompileShader(m_nVS);
 
 5912            m_nQuadShader = locCreateProgram();
 
 5913            locAttachShader(m_nQuadShader, m_nFS);
 
 5914            locAttachShader(m_nQuadShader, m_nVS);
 
 5915            locLinkProgram(m_nQuadShader);
 
 5917            m_uniMVP = locGetUniformLocation(m_nQuadShader, 
"mvp");
 
 5918            m_uniIs3D = locGetUniformLocation(m_nQuadShader, 
"is3d");
 
 5919            m_uniTint = locGetUniformLocation(m_nQuadShader, 
"tint");
 
 5920            locUniform1i(m_uniIs3D, 0);
 
 5921            locUniformMatrix4fv(m_uniMVP, 16, 
false, matProjection.data());
 
 5922            float f[4] = { 100.0f, 100.0f, 100.0f, 100.0f };
 
 5923            locUniform4fv(m_uniTint, 4, f);
 
 5926            locGenBuffers(1, &m_vbQuad);
 
 5927            locGenVertexArrays(1, &m_vaQuad);
 
 5928            locBindVertexArray(m_vaQuad);
 
 5929            locBindBuffer(0x8892, m_vbQuad);
 
 5932            locBufferData(0x8892, 
sizeof(locVertex) * OLC_MAX_VERTS, verts, 0x88E0);
 
 5933            locVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 
sizeof(locVertex), 0); locEnableVertexAttribArray(0);
 
 5934            locVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 
sizeof(locVertex), (
void*)(4 * 
sizeof(
float))); locEnableVertexAttribArray(1);
 
 5935            locVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, 
sizeof(locVertex), (
void*)(6 * 
sizeof(
float))); locEnableVertexAttribArray(2);
 
 5936            locBindBuffer(0x8892, 0);
 
 5937            locBindVertexArray(0);
 
 5940            rendBlankQuad.
Create(1, 1);
 
 5948#if defined(OLC_PLATFORM_WINAPI) 
 5949            wglDeleteContext(glRenderContext);
 
 5952#if defined(OLC_PLATFORM_X11) 
 5953            glXMakeCurrent(olc_Display, None, NULL);
 
 5954            glXDestroyContext(olc_Display, glDeviceContext);
 
 5957#if defined(OLC_PLATFORM_GLUT) 
 5958            glutDestroyWindow(glutGetWindow());
 
 5961#if defined(OLC_PLATFORM_EMSCRIPTEN) 
 5962            eglMakeCurrent(olc_Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 
 5963            eglDestroyContext(olc_Display, olc_Context);
 
 5964            eglDestroySurface(olc_Display, olc_Surface);
 
 5965            eglTerminate(olc_Display);
 
 5966            olc_Display = EGL_NO_DISPLAY;
 
 5967            olc_Surface = EGL_NO_SURFACE;
 
 5968            olc_Context = EGL_NO_CONTEXT;
 
 5973        void DisplayFrame()
 override 
 5975#if defined(OLC_PLATFORM_WINAPI) 
 5976            SwapBuffers(glDeviceContext);
 
 5977            if (bSync) DwmFlush(); 
 
 5980#if defined(OLC_PLATFORM_X11) 
 5981            X11::glXSwapBuffers(olc_Display, *olc_Window);
 
 5984#if defined(OLC_PLATFORM_GLUT) 
 5988#if defined(OLC_PLATFORM_EMSCRIPTEN) 
 5989            eglSwapBuffers(olc_Display, olc_Surface);
 
 5993        void PrepareDrawing()
 override 
 5996            nDecalMode = DecalMode::NORMAL;
 
 5997            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 5998            locUseProgram(m_nQuadShader);
 
 5999            locBindVertexArray(m_vaQuad);
 
 6000            float f[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
 
 6001            locUniform4fv(m_uniTint, 1, f);
 
 6003#if defined(OLC_PLATFORM_EMSCRIPTEN) 
 6004            locVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 
sizeof(locVertex), 0); locEnableVertexAttribArray(0);
 
 6005            locVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 
sizeof(locVertex), (
void*)(4 * 
sizeof(
float))); locEnableVertexAttribArray(1);
 
 6006            locVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, 
sizeof(locVertex), (
void*)(6 * 
sizeof(
float))); locEnableVertexAttribArray(2);
 
 6009            locUniform1i(m_uniIs3D, 0);
 
 6010            locUniformMatrix4fv(m_uniMVP, 1, 
false, matProjection.data());
 
 6011            glDisable(GL_CULL_FACE);
 
 6012            glDepthFunc(GL_LESS);
 
 6017            if (mode != nDecalMode)
 
 6035            glDisable(GL_CULL_FACE);
 
 6036            locBindBuffer(0x8892, m_vbQuad);
 
 6037            locVertex verts[4] = {
 
 6038                {{-1.0f, -1.0f, 1.0, 0.0}, {0.0f * scale.
x + offset.
x, 1.0f * scale.
y + offset.
y}, tint},
 
 6039                {{+1.0f, -1.0f, 1.0, 0.0}, {1.0f * scale.
x + offset.
x, 1.0f * scale.
y + offset.
y}, tint},
 
 6040                {{-1.0f, +1.0f, 1.0, 0.0}, {0.0f * scale.
x + offset.
x, 0.0f * scale.
y + offset.
y}, tint},
 
 6041                {{+1.0f, +1.0f, 1.0, 0.0}, {1.0f * scale.
x + offset.
x, 0.0f * scale.
y + offset.
y}, tint},
 
 6044            locBufferData(0x8892, 
sizeof(locVertex) * 4, verts, 0x88E0);
 
 6046            locUniform1i(m_uniIs3D, 0);
 
 6047            float f[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
 
 6048            locUniform4fv(m_uniTint, 1, f);
 
 6049            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 
 6054            glDisable(GL_CULL_FACE);
 
 6055            SetDecalMode(decal.
mode);
 
 6056            if (decal.
decal == 
nullptr)
 
 6057                glBindTexture(GL_TEXTURE_2D, rendBlankQuad.
Decal()->
id);
 
 6059                glBindTexture(GL_TEXTURE_2D, decal.
decal->
id);
 
 6061            locBindBuffer(0x8892, m_vbQuad);
 
 6063            for (uint32_t i = 0; i < decal.
points; i++)
 
 6064                pVertexMem[i] = { { decal.
pos[i].x, decal.
pos[i].y, decal.
w[i], 0.0 }, { decal.
uv[i].x, decal.
uv[i].y }, decal.
tint[i] };
 
 6066            locBufferData(0x8892, 
sizeof(locVertex) * decal.
points, pVertexMem, 0x88E0);
 
 6067            locUniform1i(m_uniIs3D, 0);
 
 6069            float f[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
 
 6070            locUniform4fv(m_uniTint, 1, f);
 
 6072            if (nDecalMode == DecalMode::WIREFRAME)
 
 6073                glDrawArrays(GL_LINE_LOOP, 0, decal.
points);
 
 6077                    glDrawArrays(GL_TRIANGLE_FAN, 0, decal.
points);
 
 6079                    glDrawArrays(GL_TRIANGLE_STRIP, 0, decal.
points);
 
 6081                    glDrawArrays(GL_TRIANGLES, 0, decal.
points);
 
 6083                    glDrawArrays(GL_LINES, 0, decal.
points);
 
 6087        uint32_t CreateTexture(
const uint32_t width, 
const uint32_t height, 
const bool filtered, 
const bool clamp)
 override 
 6092            glGenTextures(1, &
id);
 
 6093            glBindTexture(GL_TEXTURE_2D, 
id);
 
 6097                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
 6098                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
 6102                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
 6103                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
 6108                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
 
 6109                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
 6113                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 
 6114                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
 6116#if !defined(OLC_PLATFORM_EMSCRIPTEN) 
 6117            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
 6122        uint32_t DeleteTexture(
const uint32_t 
id)
 override 
 6124            glDeleteTextures(1, &
id);
 
 6128        void UpdateTexture(uint32_t 
id, 
olc::Sprite* spr)
 override 
 6131            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spr->
width, spr->
height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spr->
GetData());
 
 6134        void ReadTexture(uint32_t 
id, 
olc::Sprite* spr)
 override 
 6136            glReadPixels(0, 0, spr->
width, spr->
height, GL_RGBA, GL_UNSIGNED_BYTE, spr->
GetData());
 
 6139        void ApplyTexture(uint32_t 
id)
 override 
 6141            glBindTexture(GL_TEXTURE_2D, 
id);
 
 6144        void ClearBuffer(
olc::Pixel p, 
bool bDepth)
 override 
 6146            glClearColor(
float(p.
r) / 255.0f, 
float(p.
g) / 255.0f, 
float(p.
b) / 255.0f, 
float(p.
a) / 255.0f);
 
 6147            glClear(GL_COLOR_BUFFER_BIT);
 
 6148            if (bDepth) glClear(GL_DEPTH_BUFFER_BIT);
 
 6153            glViewport(pos.
x, pos.
y, size.
x, size.
y);
 
 6156        void Set3DProjection(
const std::array<float, 16>& mat)
 
 6158            matProjection = mat;
 
 6163            SetDecalMode(task.
mode);
 
 6164            if (task.
decal == 
nullptr)
 
 6165                glBindTexture(GL_TEXTURE_2D, rendBlankQuad.
Decal()->
id);
 
 6167                glBindTexture(GL_TEXTURE_2D, task.
decal->
id);
 
 6169            locBindBuffer(0x8892, m_vbQuad);
 
 6175            locBufferData(0x8892, 
sizeof(GPUTask::Vertex) * task.
vb.size(), task.
vb.data(), 0x88E0);
 
 6178            locUniform1i(m_uniIs3D, 1);
 
 6182            std::array<float, 16> matMVP;
 
 6183            for (
size_t c = 0; c < 4; c++)
 
 6184                for (
size_t r = 0; r < 4; r++)
 
 6186                    + matProjection[0 * 4 + r] * task.
mvp[c * 4 + 0] 
 
 6187                    + matProjection[1 * 4 + r] * task.
mvp[c * 4 + 1]
 
 6188                    + matProjection[2 * 4 + r] * task.
mvp[c * 4 + 2]
 
 6189                    + matProjection[3 * 4 + r] * task.
mvp[c * 4 + 3];
 
 6190            locUniformMatrix4fv(m_uniMVP, 1, 
false, matMVP.data());
 
 6192            float f[4] = { float(task.
tint.
r) / 255.0f, float(task.
tint.
g) / 255.0f, float(task.
tint.
b) / 255.0f, float(task.
tint.
a) / 255.0f };
 
 6193            locUniform4fv(m_uniTint, 1, f);
 
 6198                glCullFace(GL_FRONT);
 
 6199                glDisable(GL_CULL_FACE);
 
 6203                glCullFace(GL_FRONT);
 
 6204                glEnable(GL_CULL_FACE);
 
 6208                glCullFace(GL_BACK);
 
 6209                glEnable(GL_CULL_FACE);
 
 6213                glEnable(GL_DEPTH_TEST);
 
 6217            if (nDecalMode == DecalMode::WIREFRAME)
 
 6218                glDrawArrays(GL_LINE_LOOP, 0, (GLsizei)task.
vb.size());
 
 6222                    glDrawArrays(GL_TRIANGLE_FAN, 0, (GLsizei)task.
vb.size());
 
 6224                    glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)task.
vb.size());
 
 6226                    glDrawArrays(GL_TRIANGLES, 0, (GLsizei)task.
vb.size());
 
 6228                    glDrawArrays(GL_LINES, 0, (GLsizei)task.
vb.size());
 
 6232                glDisable(GL_DEPTH_TEST);
 
 6246#pragma region image_gdi 
 6250#if defined(OLC_IMAGE_GDI) 
 6252#define min(a, b) ((a < b) ? a : b) 
 6253#define max(a, b) ((a > b) ? a : b) 
 6256#if defined(__MINGW32__)  
 6257#include <gdiplus/gdiplusinit.h> 
 6259#include <gdiplusinit.h> 
 6265#if !defined(__MINGW32__) 
 6266#pragma comment(lib, "gdiplus.lib") 
 6267#pragma comment(lib, "Shlwapi.lib") 
 6274    static class GDIPlusStartup
 
 6279            Gdiplus::GdiplusStartupInput startupInput;
 
 6280            GdiplusStartup(&token, &startupInput, NULL);
 
 6288            Gdiplus::GdiplusShutdown(token);
 
 6295        std::wstring ConvertS2W(std::string s)
 
 6298            wchar_t* buffer = 
new wchar_t[s.length() + 1];
 
 6299            mbstowcs(buffer, s.c_str(), s.length());
 
 6300            buffer[s.length()] = 
L'\0';
 
 6302            int count = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
 
 6303            wchar_t* buffer = 
new wchar_t[count];
 
 6304            MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer, count);
 
 6306            std::wstring w(buffer);
 
 6312        ImageLoader_GDIPlus() : ImageLoader()
 
 6322            Gdiplus::Bitmap* bmp = 
nullptr;
 
 6323            if (pack != 
nullptr)
 
 6327                bmp = Gdiplus::Bitmap::FromStream(SHCreateMemStream((BYTE*)rb.vMemory.data(), UINT(rb.vMemory.size())));
 
 6335                bmp = Gdiplus::Bitmap::FromFile(ConvertS2W(sImageFile).c_str());
 
 6339            spr->
width = bmp->GetWidth();
 
 6340            spr->
height = bmp->GetHeight();
 
 6344            for (
int y = 0; y < spr->
height; y++)
 
 6345                for (
int x = 0; x < spr->
width; x++)
 
 6348                    bmp->GetPixel(x, y, &c);
 
 6349                    spr->
SetPixel(x, y, 
olc::Pixel(c.GetRed(), c.GetGreen(), c.GetBlue(), c.GetAlpha()));
 
 6367#pragma region image_libpng 
 6371#if defined(OLC_IMAGE_LIBPNG) 
 6375    void pngReadStream(png_structp pngPtr, png_bytep data, png_size_t length)
 
 6377        png_voidp a = png_get_io_ptr(pngPtr);
 
 6378        ((std::istream*)a)->read((
char*)data, length);
 
 6384        ImageLoader_LibPNG() : ImageLoader()
 
 6402            auto loadPNG = [&]()
 
 6404                    png_read_info(png, info);
 
 6405                    png_byte color_type;
 
 6407                    png_bytep* row_pointers;
 
 6408                    spr->
width = png_get_image_width(png, info);
 
 6409                    spr->
height = png_get_image_height(png, info);
 
 6410                    color_type = png_get_color_type(png, info);
 
 6411                    bit_depth = png_get_bit_depth(png, info);
 
 6412                    if (bit_depth == 16) png_set_strip_16(png);
 
 6413                    if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
 
 6414                    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png);
 
 6415                    if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png);
 
 6416                    if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE)
 
 6417                        png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
 
 6418                    if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 
 6419                        png_set_gray_to_rgb(png);
 
 6420                    png_read_update_info(png, info);
 
 6421                    row_pointers = (png_bytep*)malloc(
sizeof(png_bytep) * spr->
height);
 
 6422                    for (
int y = 0; y < spr->
height; y++) {
 
 6423                        row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
 
 6425                    png_read_image(png, row_pointers);
 
 6430                    for (
int y = 0; y < spr->
height; y++)
 
 6432                        png_bytep row = row_pointers[y];
 
 6433                        for (
int x = 0; x < spr->
width; x++)
 
 6435                            png_bytep px = &(row[x * 4]);
 
 6436                            spr->
SetPixel(x, y, Pixel(px[0], px[1], px[2], px[3]));
 
 6440                    for (
int y = 0; y < spr->
height; y++) 
 
 6441                        free(row_pointers[y]);
 
 6443                    png_destroy_read_struct(&png, &info, 
nullptr);
 
 6446            png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 
 6447            if (!png) 
goto fail_load;
 
 6449            info = png_create_info_struct(png);
 
 6450            if (!info) 
goto fail_load;
 
 6452            if (setjmp(png_jmpbuf(png))) 
goto fail_load;
 
 6454            if (pack == 
nullptr)
 
 6456                FILE* f = fopen(sImageFile.c_str(), 
"rb");
 
 6458                png_init_io(png, f);
 
 6465                std::istream is(&rb);
 
 6466                png_set_read_fn(png, (png_voidp)&is, pngReadStream);
 
 6496#pragma region platform_windows 
 6500#if defined(OLC_PLATFORM_WINAPI) 
 6502#if defined(_WIN32) && !defined(__MINGW32__) 
 6503#pragma comment(lib, "user32.lib")       
 6504#pragma comment(lib, "gdi32.lib")        
 6505#pragma comment(lib, "opengl32.lib")     
 6513        HWND olc_hWnd = 
nullptr;
 
 6514        std::wstring wsAppName;
 
 6518        std::wstring ConvertS2W(std::string s)
 
 6521            wchar_t* buffer = 
new wchar_t[s.length() + 1];
 
 6522            mbstowcs(buffer, s.c_str(), s.length());
 
 6523            buffer[s.length()] = 
L'\0';
 
 6525            int count = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
 
 6526            wchar_t* buffer = 
new wchar_t[count];
 
 6527            MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer, count);
 
 6529            std::wstring w(buffer);
 
 6543            renderer->DestroyDevice();
 
 6544            PostMessage(olc_hWnd, WM_DESTROY, 0, 0);
 
 6550            if (renderer->CreateDevice({ olc_hWnd }, bFullScreen, bEnableVSYNC) == 
olc::rcode::OK)
 
 6552                renderer->UpdateViewport(vViewPos, vViewSize);
 
 6562            wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 
 6563            wc.hCursor = LoadCursor(NULL, IDC_ARROW);
 
 6564            wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
 
 6565            wc.hInstance = GetModuleHandle(
nullptr);
 
 6566            wc.lpfnWndProc = olc_WindowEvent;
 
 6569            wc.lpszMenuName = 
nullptr;
 
 6570            wc.hbrBackground = 
nullptr;
 
 6571            wc.lpszClassName = 
olcT(
"OLC_PIXEL_GAME_ENGINE");
 
 6574            vWinPos = vWindowPos;
 
 6575            vWinSize = vWindowSize;
 
 6578            DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
 
 6579            DWORD dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_THICKFRAME;
 
 6587                dwStyle = WS_VISIBLE | WS_POPUP;
 
 6588                HMONITOR hmon = MonitorFromWindow(olc_hWnd, MONITOR_DEFAULTTONEAREST);
 
 6589                MONITORINFO mi = { 
sizeof(mi) };
 
 6591                vWindowSize = { mi.rcMonitor.right, mi.rcMonitor.bottom };
 
 6597            RECT rWndRect = { 0, 0, vWindowSize.
x, vWindowSize.
y };
 
 6598            AdjustWindowRectEx(&rWndRect, dwStyle, FALSE, dwExStyle);
 
 6599            int width = rWndRect.right - rWndRect.left;
 
 6600            int height = rWndRect.bottom - rWndRect.top;
 
 6602            olc_hWnd = CreateWindowEx(dwExStyle, 
olcT(
"OLC_PIXEL_GAME_ENGINE"), 
olcT(
""), dwStyle,
 
 6603                vTopLeft.
x, vTopLeft.
y, width, height, NULL, NULL, GetModuleHandle(
nullptr), 
this);
 
 6605            DragAcceptFiles(olc_hWnd, 
true);
 
 6627            mapKeys[VK_SPACE] = Key::SPACE;
 
 6634            mapKeys[VK_MULTIPLY] = Key::NP_MUL; 
mapKeys[VK_ADD] = Key::NP_ADD; 
mapKeys[VK_DIVIDE] = Key::NP_DIV; 
mapKeys[VK_SUBTRACT] = Key::NP_SUB; 
mapKeys[VK_DECIMAL] = Key::NP_DECIMAL;
 
 6637            mapKeys[VK_OEM_1] = Key::OEM_1;         
 
 6638            mapKeys[VK_OEM_2] = Key::OEM_2;         
 
 6639            mapKeys[VK_OEM_3] = Key::OEM_3;         
 
 6640            mapKeys[VK_OEM_4] = Key::OEM_4;         
 
 6641            mapKeys[VK_OEM_5] = Key::OEM_5;         
 
 6642            mapKeys[VK_OEM_6] = Key::OEM_6;         
 
 6643            mapKeys[VK_OEM_7] = Key::OEM_7;         
 
 6644            mapKeys[VK_OEM_8] = Key::OEM_8;         
 
 6645            mapKeys[VK_OEM_PLUS] = Key::EQUALS;     
 
 6646            mapKeys[VK_OEM_COMMA] = Key::COMMA;     
 
 6647            mapKeys[VK_OEM_MINUS] = Key::MINUS;     
 
 6648            mapKeys[VK_OEM_PERIOD] = Key::PERIOD;   
 
 6649            mapKeys[VK_CAPITAL] = Key::CAPS_LOCK;
 
 6653        virtual olc::rcode SetWindowTitle(
const std::string& s)
 override 
 6656            SetWindowText(olc_hWnd, ConvertS2W(s).c_str());
 
 6658            SetWindowText(olc_hWnd, s.c_str());
 
 6663        olc::rcode ShowWindowFrame(
const bool bShowFrame)
 
 6666            DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
 
 6667            DWORD dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_THICKFRAME;
 
 6669            RECT rWndRect, rWndRectNow;
 
 6670            GetWindowRect(olc_hWnd, &rWndRectNow);
 
 6674                LONG_PTR lp = GetWindowLongPtr(olc_hWnd, GWL_STYLE);
 
 6675                SetWindowLongPtr(olc_hWnd, GWL_STYLE, lp & ~(WS_CAPTION | WS_SYSMENU | WS_POPUPWINDOW | WS_THICKFRAME));
 
 6676                lp = GetWindowLongPtr(olc_hWnd, GWL_EXSTYLE);
 
 6677                SetWindowLongPtr(olc_hWnd, GWL_EXSTYLE, lp & ~(WS_EX_WINDOWEDGE));
 
 6678                dwExStyle = WS_EX_APPWINDOW;
 
 6683                LONG_PTR lp = GetWindowLongPtr(olc_hWnd, GWL_STYLE);
 
 6684                SetWindowLongPtr(olc_hWnd, GWL_STYLE, lp | (WS_CAPTION | WS_SYSMENU | WS_POPUPWINDOW | WS_THICKFRAME));
 
 6685                lp = GetWindowLongPtr(olc_hWnd, GWL_EXSTYLE);
 
 6686                SetWindowLongPtr(olc_hWnd, GWL_EXSTYLE, lp | (WS_EX_WINDOWEDGE));
 
 6690            rWndRectNow.right = rWndRectNow.left + vWinSize.
x;
 
 6691            rWndRectNow.bottom = rWndRectNow.top + vWinSize.
y;
 
 6692            rWndRect = rWndRectNow;
 
 6693            AdjustWindowRectEx(&rWndRect, dwStyle, FALSE, dwExStyle);
 
 6694            int width = rWndRect.right - rWndRect.left;
 
 6695            int height = rWndRect.bottom - rWndRect.top;
 
 6696            vWinPos = { rWndRect.left, rWndRect.top };
 
 6697            vWinSize = { width, height };
 
 6698            SetWindowPos(olc_hWnd, NULL, rWndRectNow.left, rWndRectNow.top, width, height, SWP_SHOWWINDOW);
 
 6706            vWinPos = vWindowPos;
 
 6707            vWinSize = vWindowSize;
 
 6709            rWndRect.left = vWinPos.
x;
 
 6710            rWndRect.top = vWinPos.
y;
 
 6711            rWndRect.right = rWndRect.left + vWinSize.
x;
 
 6712            rWndRect.bottom = rWndRect.top + vWinSize.
y;
 
 6713            rWndRect = rWndRect;
 
 6714            DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
 
 6715            DWORD dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_THICKFRAME;
 
 6716            AdjustWindowRectEx(&rWndRect, dwStyle, FALSE, dwExStyle);
 
 6717            int width = rWndRect.right - rWndRect.left;
 
 6718            int height = rWndRect.bottom - rWndRect.top;
 
 6719            vWinPos = { rWndRect.left, rWndRect.top };
 
 6720            vWinSize = { width, height };
 
 6721            SetWindowPos(olc_hWnd, NULL, vWinPos.
x, vWinPos.
y, width, height, SWP_SHOWWINDOW);
 
 6725        virtual olc::rcode StartSystemEventLoop()
 override 
 6728            while (GetMessage(&msg, NULL, 0, 0) > 0)
 
 6730                TranslateMessage(&msg);
 
 6731                DispatchMessage(&msg);
 
 6739        static LRESULT CALLBACK olc_WindowEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
 6746                uint16_t x = lParam & 0xFFFF; uint16_t y = (lParam >> 16) & 0xFFFF;
 
 6747                int16_t ix = *(int16_t*)&x;   int16_t iy = *(int16_t*)&y;
 
 6748                ptrPGE->olc_UpdateMouse(ix, iy);
 
 6751            case WM_MOVE:       vWinPos = 
olc::vi2d(lParam & 0xFFFF, (lParam >> 16) & 0xFFFF);  ptrPGE->olc_UpdateWindowPos(lParam & 0xFFFF, (lParam >> 16) & 0xFFFF);  
return 0;
 
 6752            case WM_SIZE:       vWinSize = 
olc::vi2d(lParam & 0xFFFF, (lParam >> 16) & 0xFFFF);  ptrPGE->olc_UpdateWindowSize(lParam & 0xFFFF, (lParam >> 16) & 0xFFFF);    
return 0;
 
 6753            case WM_MOUSEWHEEL: ptrPGE->olc_UpdateMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam));           
return 0;
 
 6754            case WM_MOUSELEAVE: ptrPGE->olc_UpdateMouseFocus(
false);                                    
return 0;
 
 6755            case WM_SETFOCUS:   ptrPGE->olc_UpdateKeyFocus(
true);                                       
return 0;
 
 6756            case WM_KILLFOCUS:  ptrPGE->olc_UpdateKeyFocus(
false);                                      
return 0;
 
 6757            case WM_KEYDOWN:    ptrPGE->olc_UpdateKeyState(int32_t(wParam), 
true);                      
return 0;
 
 6758            case WM_KEYUP:      ptrPGE->olc_UpdateKeyState(int32_t(wParam), 
false);                     
return 0;
 
 6759            case WM_SYSKEYDOWN: ptrPGE->olc_UpdateKeyState(int32_t(wParam), 
true);                      
return 0;
 
 6760            case WM_SYSKEYUP:   ptrPGE->olc_UpdateKeyState(int32_t(wParam), 
false);                     
return 0;
 
 6761            case WM_LBUTTONDOWN:ptrPGE->olc_UpdateMouseState(0, 
true);                                  
return 0;
 
 6762            case WM_LBUTTONUP:  ptrPGE->olc_UpdateMouseState(0, 
false);                                 
return 0;
 
 6763            case WM_RBUTTONDOWN:ptrPGE->olc_UpdateMouseState(1, 
true);                                  
return 0;
 
 6764            case WM_RBUTTONUP:  ptrPGE->olc_UpdateMouseState(1, 
false);                                 
return 0;
 
 6765            case WM_MBUTTONDOWN:ptrPGE->olc_UpdateMouseState(2, 
true);                                  
return 0;
 
 6766            case WM_MBUTTONUP:  ptrPGE->olc_UpdateMouseState(2, 
false);                                 
return 0;
 
 6770                HDROP drop = (HDROP)wParam;
 
 6772                uint32_t nFiles = DragQueryFile(drop, 0xFFFFFFFF, 
nullptr, 0);
 
 6773                std::vector<std::string> vFiles;
 
 6774                for (uint32_t i = 0; i < nFiles; i++)
 
 6776                    TCHAR dfbuffer[256]{};
 
 6777                    uint32_t len = DragQueryFile(drop, i, 
nullptr, 0);
 
 6778                    DragQueryFile(drop, i, dfbuffer, 256);
 
 6781                    char* buffer = 
new char[len + 1];
 
 6782                    wcstombs(buffer, dfbuffer, len);
 
 6785                    int count = WideCharToMultiByte(CP_UTF8, 0, dfbuffer, -1, NULL, 0, NULL, NULL);
 
 6786                    char* buffer = 
new char[count];
 
 6787                    WideCharToMultiByte(CP_UTF8, 0, dfbuffer, -1, buffer, count, NULL, NULL);
 
 6789                    vFiles.push_back(std::string(buffer));
 
 6792                    vFiles.push_back(std::string(dfbuffer));
 
 6797                POINT p; DragQueryPoint(drop, &p);
 
 6798                ptrPGE->olc_DropFiles(p.x, p.y, vFiles);
 
 6805            case WM_CLOSE:      ptrPGE->olc_Terminate();                                                
return 0;
 
 6806            case WM_DESTROY:    PostQuitMessage(0); DestroyWindow(hWnd);                                
return 0;
 
 6808            return DefWindowProc(hWnd, uMsg, wParam, lParam);
 
 6818#pragma region platform_linux 
 6822#if defined(OLC_PLATFORM_X11) 
 6828        X11::Display* olc_Display = 
nullptr;
 
 6829        X11::Window                  olc_WindowRoot;
 
 6830        X11::Window                  olc_Window;
 
 6831        X11::XVisualInfo* olc_VisualInfo;
 
 6832        X11::Colormap                olc_ColourMap;
 
 6833        X11::XSetWindowAttributes    olc_SetWindowAttribs;
 
 6836        virtual olc::rcode ApplicationStartUp()
 override 
 6841        virtual olc::rcode ApplicationCleanUp()
 override 
 6843            XDestroyWindow(olc_Display, olc_Window);
 
 6854            renderer->DestroyDevice();
 
 6860            if (renderer->CreateDevice({ olc_Display, &olc_Window, olc_VisualInfo }, bFullScreen, bEnableVSYNC) == 
olc::rcode::OK)
 
 6862                renderer->UpdateViewport(vViewPos, vViewSize);
 
 6871            using namespace X11;
 
 6875            olc_Display = XOpenDisplay(NULL);
 
 6876            olc_WindowRoot = DefaultRootWindow(olc_Display);
 
 6879            GLint olc_GLAttribs[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
 
 6880            olc_VisualInfo = glXChooseVisual(olc_Display, 0, olc_GLAttribs);
 
 6881            olc_ColourMap = XCreateColormap(olc_Display, olc_WindowRoot, olc_VisualInfo->visual, AllocNone);
 
 6882            olc_SetWindowAttribs.colormap = olc_ColourMap;
 
 6885            olc_SetWindowAttribs.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
 
 6886                ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask | StructureNotifyMask;
 
 6889            olc_Window = XCreateWindow(olc_Display, olc_WindowRoot, vWindowPos.
x, vWindowPos.
y,
 
 6890                vWindowSize.
x, vWindowSize.
y,
 
 6891                0, olc_VisualInfo->depth, InputOutput, olc_VisualInfo->visual,
 
 6892                CWColormap | CWEventMask, &olc_SetWindowAttribs);
 
 6894            Atom wmDelete = XInternAtom(olc_Display, 
"WM_DELETE_WINDOW", 
true);
 
 6895            XSetWMProtocols(olc_Display, olc_Window, &wmDelete, 1);
 
 6897            XMapWindow(olc_Display, olc_Window);
 
 6898            XStoreName(olc_Display, olc_Window, 
"OneLoneCoder.com - Pixel Game Engine");
 
 6904                wm_state = XInternAtom(olc_Display, 
"_NET_WM_STATE", False);
 
 6905                fullscreen = XInternAtom(olc_Display, 
"_NET_WM_STATE_FULLSCREEN", False);
 
 6907                xev.type = ClientMessage;
 
 6908                xev.xclient.window = olc_Window;
 
 6909                xev.xclient.message_type = wm_state;
 
 6910                xev.xclient.format = 32;
 
 6911                xev.xclient.data.l[0] = (bFullScreen ? 1 : 0);   
 
 6912                xev.xclient.data.l[1] = fullscreen;             
 
 6913                xev.xclient.data.l[2] = 0;                      
 
 6914                xev.xclient.data.l[3] = 0;                      
 
 6915                XMapWindow(olc_Display, olc_Window);
 
 6916                XSendEvent(olc_Display, DefaultRootWindow(olc_Display), False,
 
 6917                    SubstructureRedirectMask | SubstructureNotifyMask, &xev);
 
 6918                XFlush(olc_Display);
 
 6919                XWindowAttributes gwa;
 
 6920                XGetWindowAttributes(olc_Display, olc_Window, &gwa);
 
 6921                vWindowSize.
x = gwa.width;
 
 6922                vWindowSize.
y = gwa.height;
 
 6926            mapKeys[NoSymbol] = Key::NONE;
 
 6930                int keyTracker = (int)Key::A;
 
 6934                for (key = (
size_t)XK_A, key2 = (size_t)XK_a; key <= (size_t)XK_Z; ++key, ++key2)
 
 6948            mapKeys[XK_KP_Enter] = Key::ENTER; 
mapKeys[XK_Return] = Key::ENTER;
 
 6950            mapKeys[XK_BackSpace] = Key::BACK; 
mapKeys[XK_Escape] = Key::ESCAPE; 
mapKeys[XK_Linefeed] = Key::ENTER; 
mapKeys[XK_Pause] = Key::PAUSE;
 
 6953            mapKeys[XK_Shift_L] = Key::SHIFT; 
mapKeys[XK_Shift_R] = Key::SHIFT; 
mapKeys[XK_Control_L] = Key::CTRL; 
mapKeys[XK_Control_R] = Key::CTRL;
 
 6954            mapKeys[XK_space] = Key::SPACE; 
mapKeys[XK_period] = Key::PERIOD;
 
 6961            mapKeys[XK_KP_Multiply] = Key::NP_MUL; 
mapKeys[XK_KP_Add] = Key::NP_ADD; 
mapKeys[XK_KP_Divide] = Key::NP_DIV; 
mapKeys[XK_KP_Subtract] = Key::NP_SUB; 
mapKeys[XK_KP_Decimal] = Key::NP_DECIMAL;
 
 6965            mapKeys[XK_KP_Down] = Key::DOWN; 
mapKeys[XK_KP_Left] = Key::LEFT; 
mapKeys[XK_KP_Right] = Key::RIGHT;
 
 6966            mapKeys[XK_KP_Page_Up] = Key::PGUP; 
mapKeys[XK_KP_Page_Down] = Key::PGDN; 
mapKeys[XK_KP_Insert] = Key::INS;
 
 6967            mapKeys[XK_KP_Delete] = Key::DEL;
 
 6970            mapKeys[XK_semicolon] = Key::OEM_1;     
 
 6971            mapKeys[XK_slash] = Key::OEM_2;         
 
 6972            mapKeys[XK_asciitilde] = Key::OEM_3;    
 
 6973            mapKeys[XK_grave] = Key::OEM_3; 
 
 6974            mapKeys[XK_bracketleft] = Key::OEM_4;   
 
 6975            mapKeys[XK_backslash] = Key::OEM_5;     
 
 6976            mapKeys[XK_bracketright] = Key::OEM_6;  
 
 6977            mapKeys[XK_apostrophe] = Key::OEM_7;    
 
 6978            mapKeys[XK_numbersign] = Key::OEM_8;    
 
 6979            mapKeys[XK_equal] = Key::EQUALS;        
 
 6980            mapKeys[XK_comma] = Key::COMMA;         
 
 6981            mapKeys[XK_minus] = Key::MINUS;         
 
 6983            mapKeys[XK_Caps_Lock] = Key::CAPS_LOCK;
 
 6988        virtual olc::rcode SetWindowTitle(
const std::string& s)
 override 
 6990            X11::XStoreName(olc_Display, olc_Window, s.c_str());
 
 6999        virtual olc::rcode ShowWindowFrame(
const bool bShowFrame = 
true)
 override 
 7005        virtual olc::rcode StartSystemEventLoop()
 override 
 7010        virtual olc::rcode HandleSystemEvent()
 override 
 7012            using namespace X11;
 
 7017            while (XPending(olc_Display))
 
 7019                XNextEvent(olc_Display, &xev);
 
 7020                if (xev.type == Expose)
 
 7022                    XWindowAttributes gwa;
 
 7023                    XGetWindowAttributes(olc_Display, olc_Window, &gwa);
 
 7024                    ptrPGE->olc_UpdateWindowSize(gwa.width, gwa.height);
 
 7026                else if (xev.type == ConfigureNotify)
 
 7028                    XConfigureEvent xce = xev.xconfigure;
 
 7029                    ptrPGE->olc_UpdateWindowSize(xce.width, xce.height);
 
 7031                else if (xev.type == KeyPress)
 
 7036                    XLookupString(&xev.xkey, NULL, 0, &ks, NULL);
 
 7039                        ptrPGE->olc_UpdateKeyState(ks, 
true);
 
 7041                else if (xev.type == KeyRelease)
 
 7044                    XLookupString(&xev.xkey, NULL, 0, &ks, NULL);
 
 7047                        ptrPGE->olc_UpdateKeyState(ks, 
false);
 
 7049                else if (xev.type == ButtonPress)
 
 7051                    switch (xev.xbutton.button)
 
 7053                    case 1: ptrPGE->olc_UpdateMouseState(0, 
true); 
break;
 
 7054                    case 2: ptrPGE->olc_UpdateMouseState(2, 
true); 
break;
 
 7055                    case 3: ptrPGE->olc_UpdateMouseState(1, 
true); 
break;
 
 7056                    case 4: ptrPGE->olc_UpdateMouseWheel(120); 
break;
 
 7057                    case 5: ptrPGE->olc_UpdateMouseWheel(-120); 
break;
 
 7061                else if (xev.type == ButtonRelease)
 
 7063                    switch (xev.xbutton.button)
 
 7065                    case 1: ptrPGE->olc_UpdateMouseState(0, 
false); 
break;
 
 7066                    case 2: ptrPGE->olc_UpdateMouseState(2, 
false); 
break;
 
 7067                    case 3: ptrPGE->olc_UpdateMouseState(1, 
false); 
break;
 
 7071                else if (xev.type == MotionNotify)
 
 7073                    ptrPGE->olc_UpdateMouse(xev.xmotion.x, xev.xmotion.y);
 
 7075                else if (xev.type == FocusIn)
 
 7077                    ptrPGE->olc_UpdateKeyFocus(
true);
 
 7079                else if (xev.type == FocusOut)
 
 7081                    ptrPGE->olc_UpdateKeyFocus(
false);
 
 7083                else if (xev.type == ClientMessage)
 
 7085                    ptrPGE->olc_Terminate();
 
 7098#pragma region platform_glut 
 7109#if defined(OLC_PLATFORM_GLUT) 
 7115        static std::atomic<bool>* bActiveRef;
 
 7122        virtual olc::rcode ShowWindowFrame(
const bool bShowFrame = 
true)
 override 
 7128        virtual olc::rcode ApplicationStartUp()
 override {
 
 7132        virtual olc::rcode ApplicationCleanUp()
 override 
 7144            renderer->DestroyDevice();
 
 7150            if (renderer->CreateDevice({}, bFullScreen, bEnableVSYNC) == 
olc::rcode::OK)
 
 7152                renderer->UpdateViewport(vViewPos, vViewSize);
 
 7159        static void ExitMainLoop() {
 
 7160            if (!ptrPGE->OnUserDestroy()) {
 
 7164            platform->ThreadCleanUp();
 
 7165            platform->ApplicationCleanUp();
 
 7169#if defined(__APPLE__) 
 7170        static void scrollWheelUpdate(
id selff, 
SEL _sel, 
id theEvent) {
 
 7171            static const SEL deltaYSel = sel_registerName(
"deltaY");
 
 7173#if defined(__aarch64__)  
 7174            double deltaY = ((double (*)(id, SEL))objc_msgSend)(theEvent, deltaYSel);
 
 7176            double deltaY = ((double (*)(id, SEL))objc_msgSend_fpret)(theEvent, deltaYSel);
 
 7179            for (
int i = 0; i < abs(deltaY); i++) {
 
 7181                    ptrPGE->olc_UpdateMouseWheel(-1);
 
 7183                else if (deltaY < 0) {
 
 7184                    ptrPGE->olc_UpdateMouseWheel(1);
 
 7189        static void ThreadFunct() {
 
 7190#if defined(__APPLE__) 
 7191            static bool hasEnabledCocoa = 
false;
 
 7192            if (!hasEnabledCocoa) {
 
 7194                Class NSApplicationClass = objc_getClass(
"NSApplication");
 
 7197                SEL sharedApplicationSel = sel_registerName(
"sharedApplication");
 
 7198                id NSApp = ((id(*)(Class, SEL))objc_msgSend)(NSApplicationClass, sharedApplicationSel);
 
 7200                SEL mainWindowSel = sel_registerName(
"mainWindow");
 
 7201                id window = ((id(*)(id, SEL))objc_msgSend)(NSApp, mainWindowSel);
 
 7204                SEL setStyleMaskSel = sel_registerName(
"setStyleMask:");
 
 7205                ((void (*)(id, SEL, NSUInteger))objc_msgSend)(window, setStyleMaskSel, 7);
 
 7207                hasEnabledCocoa = 
true;
 
 7214            glutPostRedisplay();
 
 7217        static void DrawFunct() {
 
 7218            ptrPGE->olc_CoreUpdate();
 
 7223#if defined(__APPLE__) 
 7224            Class GLUTViewClass = objc_getClass(
"GLUTView");
 
 7226            SEL scrollWheelSel = sel_registerName(
"scrollWheel:");
 
 7227            bool resultAddMethod = class_addMethod(GLUTViewClass, scrollWheelSel, (IMP)scrollWheelUpdate, 
"v@:@");
 
 7228            assert(resultAddMethod);
 
 7231            renderer->PrepareDevice();
 
 7235                vWindowSize.
x = glutGet(GLUT_SCREEN_WIDTH);
 
 7236                vWindowSize.
y = glutGet(GLUT_SCREEN_HEIGHT);
 
 7241                if (vWindowSize.
x > glutGet(GLUT_SCREEN_WIDTH) || vWindowSize.
y > glutGet(GLUT_SCREEN_HEIGHT))
 
 7243                    perror(
"ERROR: The specified window dimensions do not fit on your screen\n");
 
 7246                glutReshapeWindow(vWindowSize.
x, vWindowSize.
y - 1);
 
 7262            mapKeys[GLUT_KEY_DOWN] = Key::DOWN; 
mapKeys[GLUT_KEY_LEFT] = Key::LEFT; 
mapKeys[GLUT_KEY_RIGHT] = Key::RIGHT; 
mapKeys[GLUT_KEY_UP] = Key::UP;
 
 7267            mapKeys[GLUT_KEY_END] = Key::END; 
mapKeys[GLUT_KEY_PAGE_UP] = Key::PGUP; 
mapKeys[GLUT_KEY_PAGE_DOWN] = Key::PGDN;    
mapKeys[GLUT_KEY_INSERT] = Key::INS;
 
 7280            glutKeyboardFunc([](
unsigned char key, 
int x, 
int y) -> 
void {
 
 7281                switch (glutGetModifiers()) {
 
 7283                    if (
'a' <= key && key <= 
'z') key -= 32;
 
 7285                case GLUT_ACTIVE_SHIFT:
 
 7288                case GLUT_ACTIVE_CTRL:
 
 7289                    if (
'a' <= key && key <= 
'z') key -= 32;
 
 7292                case GLUT_ACTIVE_ALT:
 
 7293                    if (
'a' <= key && key <= 
'z') key -= 32;
 
 7298                ptrPGE->olc_UpdateKeyState(key, 
true);
 
 7301            glutKeyboardUpFunc([](
unsigned char key, 
int x, 
int y) -> 
void {
 
 7302                switch (glutGetModifiers()) {
 
 7304                    if (
'a' <= key && key <= 
'z') key -= 32;
 
 7306                case GLUT_ACTIVE_SHIFT:
 
 7309                case GLUT_ACTIVE_CTRL:
 
 7310                    if (
'a' <= key && key <= 
'z') key -= 32;
 
 7313                case GLUT_ACTIVE_ALT:
 
 7314                    if (
'a' <= key && key <= 
'z') key -= 32;
 
 7320                ptrPGE->olc_UpdateKeyState(key, 
false);
 
 7324            glutSpecialFunc([](
int key, 
int x, 
int y) -> 
void {
 
 7326                ptrPGE->olc_UpdateKeyState(key, 
true);
 
 7329            glutSpecialUpFunc([](
int key, 
int x, 
int y) -> 
void {
 
 7331                ptrPGE->olc_UpdateKeyState(key, 
false);
 
 7334            glutMouseFunc([](
int button, 
int state, 
int x, 
int y) -> 
void {
 
 7336                case GLUT_LEFT_BUTTON:
 
 7337                    if (state == GLUT_UP) ptrPGE->olc_UpdateMouseState(0, 
false);
 
 7338                    else if (state == GLUT_DOWN) ptrPGE->olc_UpdateMouseState(0, 
true);
 
 7340                case GLUT_MIDDLE_BUTTON:
 
 7341                    if (state == GLUT_UP) ptrPGE->olc_UpdateMouseState(2, 
false);
 
 7342                    else if (state == GLUT_DOWN) ptrPGE->olc_UpdateMouseState(2, 
true);
 
 7344                case GLUT_RIGHT_BUTTON:
 
 7345                    if (state == GLUT_UP) ptrPGE->olc_UpdateMouseState(1, 
false);
 
 7346                    else if (state == GLUT_DOWN) ptrPGE->olc_UpdateMouseState(1, 
true);
 
 7351            auto mouseMoveCall = [](
int x, 
int y) -> 
void {
 
 7352                ptrPGE->olc_UpdateMouse(x, y);
 
 7355            glutMotionFunc(mouseMoveCall);
 
 7356            glutPassiveMotionFunc(mouseMoveCall);
 
 7358            glutEntryFunc([](
int state) -> 
void {
 
 7359                if (state == GLUT_ENTERED) ptrPGE->olc_UpdateKeyFocus(
true);
 
 7360                else if (state == GLUT_LEFT) ptrPGE->olc_UpdateKeyFocus(
false);
 
 7363            glutDisplayFunc(DrawFunct);
 
 7364            glutIdleFunc(ThreadFunct);
 
 7369        virtual olc::rcode SetWindowTitle(
const std::string& s)
 override 
 7371            glutSetWindowTitle(s.c_str());
 
 7375        virtual olc::rcode StartSystemEventLoop()
 override {
 
 7380        virtual olc::rcode HandleSystemEvent()
 override 
 7386    std::atomic<bool>* Platform_GLUT::bActiveRef{ 
nullptr };
 
 7394        if (platform->CreateWindowPane({ 30,30 }, vWindowSize, bFullScreen) != 
olc::OK) 
return olc::FAIL;
 
 7400        Platform_GLUT::bActiveRef = &bAtomActive;
 
 7401        glutWMCloseFunc(Platform_GLUT::ExitMainLoop);
 
 7403        platform->StartSystemEventLoop();
 
 7422#pragma region platform_emscripten 
 7439#if defined(OLC_PLATFORM_EMSCRIPTEN) 
 7441#include <emscripten/html5.h> 
 7442#include <emscripten/key_codes.h> 
 7446    EMSCRIPTEN_KEEPALIVE 
inline int olc_OnPageUnload()
 
 7448        olc::platform->ApplicationCleanUp(); 
return 0;
 
 7463        virtual olc::rcode ShowWindowFrame(
const bool bShowFrame = 
true)
 override 
 7468        virtual olc::rcode ApplicationStartUp()
 override 
 7473        virtual olc::rcode ApplicationCleanUp()
 override 
 7485            renderer->DestroyDevice(); 
return olc::OK;
 
 7490            if (renderer->CreateDevice({}, bFullScreen, bEnableVSYNC) == 
olc::rcode::OK)
 
 7492                renderer->UpdateViewport(vViewPos, vViewSize);
 
 7501            emscripten_set_canvas_element_size(
"#canvas", vWindowSize.
x, vWindowSize.
y);
 
 7503            mapKeys[DOM_PK_UNKNOWN] = Key::NONE;
 
 7518            mapKeys[DOM_PK_ARROW_UP] = Key::UP; 
mapKeys[DOM_PK_ARROW_DOWN] = Key::DOWN;
 
 7519            mapKeys[DOM_PK_ARROW_LEFT] = Key::LEFT; 
mapKeys[DOM_PK_ARROW_RIGHT] = Key::RIGHT;
 
 7520            mapKeys[DOM_PK_SPACE] = Key::SPACE; 
mapKeys[DOM_PK_TAB] = Key::TAB;
 
 7521            mapKeys[DOM_PK_SHIFT_LEFT] = Key::SHIFT; 
mapKeys[DOM_PK_SHIFT_RIGHT] = Key::SHIFT;
 
 7522            mapKeys[DOM_PK_CONTROL_LEFT] = Key::CTRL; 
mapKeys[DOM_PK_CONTROL_RIGHT] = Key::CTRL;
 
 7523            mapKeys[DOM_PK_INSERT] = Key::INS; 
mapKeys[DOM_PK_DELETE] = Key::DEL; 
mapKeys[DOM_PK_HOME] = Key::HOME;
 
 7524            mapKeys[DOM_PK_END] = Key::END; 
mapKeys[DOM_PK_PAGE_UP] = Key::PGUP; 
mapKeys[DOM_PK_PAGE_DOWN] = Key::PGDN;
 
 7525            mapKeys[DOM_PK_BACKSPACE] = Key::BACK; 
mapKeys[DOM_PK_ESCAPE] = Key::ESCAPE;
 
 7526            mapKeys[DOM_PK_ENTER] = Key::ENTER; 
mapKeys[DOM_PK_NUMPAD_EQUAL] = Key::EQUALS;
 
 7527            mapKeys[DOM_PK_NUMPAD_ENTER] = Key::ENTER; 
mapKeys[DOM_PK_PAUSE] = Key::PAUSE;
 
 7528            mapKeys[DOM_PK_SCROLL_LOCK] = Key::SCROLL;
 
 7529            mapKeys[DOM_PK_NUMPAD_0] = Key::NP0; 
mapKeys[DOM_PK_NUMPAD_1] = Key::NP1; 
mapKeys[DOM_PK_NUMPAD_2] = Key::NP2;
 
 7530            mapKeys[DOM_PK_NUMPAD_3] = Key::NP3; 
mapKeys[DOM_PK_NUMPAD_4] = Key::NP4; 
mapKeys[DOM_PK_NUMPAD_5] = Key::NP5;
 
 7531            mapKeys[DOM_PK_NUMPAD_6] = Key::NP6; 
mapKeys[DOM_PK_NUMPAD_7] = Key::NP7; 
mapKeys[DOM_PK_NUMPAD_8] = Key::NP8;
 
 7532            mapKeys[DOM_PK_NUMPAD_9] = Key::NP9;
 
 7533            mapKeys[DOM_PK_NUMPAD_MULTIPLY] = Key::NP_MUL; 
mapKeys[DOM_PK_NUMPAD_DIVIDE] = Key::NP_DIV;
 
 7534            mapKeys[DOM_PK_NUMPAD_ADD] = Key::NP_ADD; 
mapKeys[DOM_PK_NUMPAD_SUBTRACT] = Key::NP_SUB;
 
 7535            mapKeys[DOM_PK_NUMPAD_DECIMAL] = Key::NP_DECIMAL;
 
 7536            mapKeys[DOM_PK_PERIOD] = Key::PERIOD; 
mapKeys[DOM_PK_EQUAL] = Key::EQUALS;
 
 7537            mapKeys[DOM_PK_COMMA] = Key::COMMA; 
mapKeys[DOM_PK_MINUS] = Key::MINUS;
 
 7538            mapKeys[DOM_PK_CAPS_LOCK] = Key::CAPS_LOCK;
 
 7539            mapKeys[DOM_PK_SEMICOLON] = Key::OEM_1; 
mapKeys[DOM_PK_SLASH] = Key::OEM_2; 
mapKeys[DOM_PK_BACKQUOTE] = Key::OEM_3;
 
 7540            mapKeys[DOM_PK_BRACKET_LEFT] = Key::OEM_4; 
mapKeys[DOM_PK_BACKSLASH] = Key::OEM_5; 
mapKeys[DOM_PK_BRACKET_RIGHT] = Key::OEM_6;
 
 7541            mapKeys[DOM_PK_QUOTE] = Key::OEM_7; 
mapKeys[DOM_PK_BACKSLASH] = Key::OEM_8;
 
 7544            emscripten_set_keydown_callback(
"#canvas", 0, 1, keyboard_callback);
 
 7545            emscripten_set_keyup_callback(
"#canvas", 0, 1, keyboard_callback);
 
 7548            emscripten_set_wheel_callback(
"#canvas", 0, 1, wheel_callback);
 
 7549            emscripten_set_mousedown_callback(
"#canvas", 0, 1, mouse_callback);
 
 7550            emscripten_set_mouseup_callback(
"#canvas", 0, 1, mouse_callback);
 
 7551            emscripten_set_mousemove_callback(
"#canvas", 0, 1, mouse_callback);
 
 7554            emscripten_set_touchstart_callback(
"#canvas", 0, 1, touch_callback);
 
 7555            emscripten_set_touchmove_callback(
"#canvas", 0, 1, touch_callback);
 
 7556            emscripten_set_touchend_callback(
"#canvas", 0, 1, touch_callback);
 
 7559            emscripten_set_blur_callback(
"#canvas", 0, 1, focus_callback);
 
 7560            emscripten_set_focus_callback(
"#canvas", 0, 1, focus_callback);
 
 7562#pragma warning disable format 
 7563            EM_ASM(window.onunload = Module._olc_OnPageUnload; );
 
 7584                Module.olc_AspectRatio = $0 / $1;
 
 7590            Module.olc_AssumeDefaultShells = (document.querySelectorAll(
'.emscripten').length >= 3) ? true : 
false;
 
 7595            var olc_ResizeHandler = function()
 
 7598                let isFullscreen = (document.fullscreenElement != null);
 
 7601                let width = (isFullscreen) ? window.innerWidth : Module.canvas.parentNode.clientWidth;
 
 7602                let height = (isFullscreen) ? window.innerHeight : Module.canvas.parentNode.clientHeight;
 
 7605                let viewWidth = width;
 
 7606                let viewHeight = width / Module.olc_AspectRatio;
 
 7609                if (viewHeight > height)
 
 7611                    viewWidth = height * Module.olc_AspectRatio;
 
 7612                    viewHeight = height;
 
 7616                viewWidth = parseInt(viewWidth);
 
 7617                viewHeight = parseInt(viewHeight);
 
 7619                setTimeout(function()
 
 7622                    if (Module.olc_AssumeDefaultShells)
 
 7623                        Module.canvas.parentNode.setAttribute(
'style', 
'width: 100%; height: 70vh; margin-left: auto; margin-right: auto;');
 
 7626                    Module.canvas.setAttribute(
'width', viewWidth);
 
 7627                    Module.canvas.setAttribute(
'height', viewHeight);
 
 7628                    Module.canvas.setAttribute(
'style', `width: ${viewWidth}px; height: ${viewHeight}px; `);
 
 7631                    Module._olc_PGE_UpdateWindowSize(viewWidth, viewHeight);
 
 7634                    Module.canvas.focus();
 
 7642            var olc_Init = function()
 
 7644                if (Module.olc_AspectRatio == = undefined)
 
 7646                    setTimeout(function() { Module.olc_Init(); }, 50);
 
 7650                let resizeObserver = 
new ResizeObserver(function(entries)
 
 7652                    Module.olc_ResizeHandler();
 
 7653                }).observe(Module.canvas.parentNode);
 
 7655                let mutationObserver = 
new MutationObserver(function(mutationsList, observer)
 
 7657                    setTimeout(function() { Module.olc_ResizeHandler(); },  200);
 
 7658                }).observe(Module.canvas.parentNode, { attributes: false, childList : true, subtree : false });
 
 7660                window.addEventListener(
'fullscreenchange', function(e)
 
 7662                    setTimeout(function() { Module.olc_ResizeHandler(); },  200);
 
 7667            Module.olc_ResizeHandler = (Module.olc_ResizeHandler != undefined) ? Module.olc_ResizeHandler : olc_ResizeHandler;
 
 7668            Module.olc_Init = (Module.olc_Init != undefined) ? Module.olc_Init : olc_Init;
 
 7673                    }, vWindowSize.
x, vWindowSize.
y); 
 
 7674#pragma warning restore format 
 7679        void UpdateWindowSize(
int width, 
int height)
 
 7681            ptrPGE->olc_UpdateWindowSize(width, height);
 
 7685        static EM_BOOL focus_callback(
int eventType, 
const EmscriptenFocusEvent* focusEvent, 
void* userData)
 
 7687            if (eventType == EMSCRIPTEN_EVENT_BLUR)
 
 7689                ptrPGE->olc_UpdateKeyFocus(
false);
 
 7690                ptrPGE->olc_UpdateMouseFocus(
false);
 
 7692            else if (eventType == EMSCRIPTEN_EVENT_FOCUS)
 
 7694                ptrPGE->olc_UpdateKeyFocus(
true);
 
 7695                ptrPGE->olc_UpdateMouseFocus(
true);
 
 7702        static EM_BOOL keyboard_callback(
int eventType, 
const EmscriptenKeyboardEvent* e, 
void* userData)
 
 7704            if (eventType == EMSCRIPTEN_EVENT_KEYDOWN)
 
 7705                ptrPGE->olc_UpdateKeyState(emscripten_compute_dom_pk_code(e->code), 
true);
 
 7708            if (eventType == EMSCRIPTEN_EVENT_KEYUP)
 
 7709                ptrPGE->olc_UpdateKeyState(emscripten_compute_dom_pk_code(e->code), 
false);
 
 7716        static EM_BOOL wheel_callback(
int eventType, 
const EmscriptenWheelEvent* e, 
void* userData)
 
 7718            if (eventType == EMSCRIPTEN_EVENT_WHEEL)
 
 7719                ptrPGE->olc_UpdateMouseWheel(-1 * e->deltaY);
 
 7725        static EM_BOOL touch_callback(
int eventType, 
const EmscriptenTouchEvent* e, 
void* userData)
 
 7728            if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE)
 
 7730                ptrPGE->olc_UpdateMouse(e->touches->targetX, e->touches->targetY);
 
 7734            if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART)
 
 7736                ptrPGE->olc_UpdateMouse(e->touches->targetX, e->touches->targetY);
 
 7737                ptrPGE->olc_UpdateMouseState(0, 
true);
 
 7741            if (eventType == EMSCRIPTEN_EVENT_TOUCHEND)
 
 7743                ptrPGE->olc_UpdateMouseState(0, 
false);
 
 7750        static EM_BOOL mouse_callback(
int eventType, 
const EmscriptenMouseEvent* e, 
void* userData)
 
 7753            if (eventType == EMSCRIPTEN_EVENT_MOUSEMOVE)
 
 7754                ptrPGE->olc_UpdateMouse(e->targetX, e->targetY);
 
 7760                if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN)
 
 7761                    ptrPGE->olc_UpdateMouseState(0, 
true);
 
 7762                else if (eventType == EMSCRIPTEN_EVENT_MOUSEUP)
 
 7763                    ptrPGE->olc_UpdateMouseState(0, 
false);
 
 7768                if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN)
 
 7769                    ptrPGE->olc_UpdateMouseState(1, 
true);
 
 7770                else if (eventType == EMSCRIPTEN_EVENT_MOUSEUP)
 
 7771                    ptrPGE->olc_UpdateMouseState(1, 
false);
 
 7777                if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN)
 
 7778                    ptrPGE->olc_UpdateMouseState(2, 
true);
 
 7779                else if (eventType == EMSCRIPTEN_EVENT_MOUSEUP)
 
 7780                    ptrPGE->olc_UpdateMouseState(2, 
false);
 
 7790        virtual olc::rcode SetWindowTitle(
const std::string& s)
 override 
 7792            emscripten_set_window_title(s.c_str()); 
return olc::OK;
 
 7795        virtual olc::rcode StartSystemEventLoop()
 override 
 7800        virtual olc::rcode HandleSystemEvent()
 override 
 7805        static void MainLoop()
 
 7808            if (!ptrPGE->olc_IsRunning())
 
 7810                if (ptrPGE->OnUserDestroy())
 
 7812                    emscripten_cancel_main_loop();
 
 7813                    platform->ApplicationCleanUp();
 
 7817                    ptrPGE->olc_Reanimate();
 
 7830        if (platform->CreateWindowPane({ 30,30 }, vWindowSize, bFullScreen) != 
olc::OK) 
return olc::FAIL;
 
 7843        for (
auto& ext : vExtensions) ext->OnBeforeUserCreate();
 
 7845        for (
auto& ext : vExtensions) ext->OnAfterUserCreate();
 
 7847        platform->StartSystemEventLoop();
 
 7851        emscripten_set_main_loop(&Platform_Emscripten::MainLoop, 0, 1);
 
 7861    EMSCRIPTEN_KEEPALIVE 
inline void olc_PGE_UpdateWindowSize(
int width, 
int height)
 
 7863        emscripten_set_canvas_element_size(
"#canvas", width, height);
 
 7865        ((olc::Platform_Emscripten*)olc::platform.get())->UpdateWindowSize(width, height);
 
 7881#pragma region pge_config 
 7891#if defined(OLC_IMAGE_GDI) 
 7895#if defined(OLC_IMAGE_LIBPNG) 
 7899#if defined(OLC_IMAGE_STB) 
 7903#if defined(OLC_IMAGE_CUSTOM_EX) 
 7908#if defined(OLC_PLATFORM_HEADLESS) 
 7909        platform = std::make_unique<olc::Platform_Headless>();
 
 7912#if defined(OLC_PLATFORM_WINAPI) 
 7913        platform = std::make_unique<olc::Platform_Windows>();
 
 7916#if defined(OLC_PLATFORM_X11) 
 7917        platform = std::make_unique<olc::Platform_Linux>();
 
 7920#if defined(OLC_PLATFORM_GLUT) 
 7921        platform = std::make_unique<olc::Platform_GLUT>();
 
 7924#if defined(OLC_PLATFORM_EMSCRIPTEN) 
 7925        platform = std::make_unique<olc::Platform_Emscripten>();
 
 7928#if defined(OLC_PLATFORM_CUSTOM_EX) 
 7929        platform = std::make_unique<OLC_PLATFORM_CUSTOM_EX>();
 
 7932#if defined(OLC_GFX_HEADLESS) 
 7933        renderer = std::make_unique<olc::Renderer_Headless>();
 
 7936#if defined(OLC_GFX_OPENGL10) 
 7937        renderer = std::make_unique<olc::Renderer_OGL10>();
 
 7940#if defined(OLC_GFX_OPENGL33) 
 7941        renderer = std::make_unique<olc::Renderer_OGL33>();
 
 7944#if defined(OLC_GFX_OPENGLES2) 
 7945        renderer = std::make_unique<olc::Renderer_OGLES2>();
 
 7948#if defined(OLC_GFX_DIRECTX10) 
 7949        renderer = std::make_unique<olc::Renderer_DX10>();
 
 7952#if defined(OLC_GFX_DIRECTX11) 
 7953        renderer = std::make_unique<olc::Renderer_DX11>();
 
 7956#if defined(OLC_GFX_CUSTOM_EX) 
 7957        renderer = std::make_unique<OLC_RENDERER_CUSTOM_EX>();
 
 7961        platform->ptrPGE = 
this;
 
 7962        renderer->ptrPGE = 
this;
 
Definition olcPixelGameEngine.h:1113
 
Decal(olc::Sprite *spr, bool filter=false, bool clamp=true)
 
int32_t id
Definition olcPixelGameEngine.h:1122
 
olc::Sprite * sprite
Definition olcPixelGameEngine.h:1123
 
Decal(const uint32_t nExistingTextureResource, olc::Sprite *spr)
 
olc::vf2d vUVScale
Definition olcPixelGameEngine.h:1124
 
Definition olcPixelGameEngine.h:1058
 
virtual ~ImageLoader()=default
 
virtual olc::rcode LoadImageResource(olc::Sprite *spr, const std::string &sImageFile, olc::ResourcePack *pack)=0
 
virtual olc::rcode SaveImageResource(olc::Sprite *spr, const std::string &sImageFile)=0
 
Definition olcPixelGameEngine.h:1685
 
static PixelGameEngine * pge
Definition olcPixelGameEngine.h:1697
 
virtual void OnAfterUserCreate()
 
virtual void OnAfterUserUpdate(float fElapsedTime)
 
virtual void OnBeforeUserCreate()
 
virtual bool OnBeforeUserUpdate(float &fElapsedTime)
 
Definition olcPixelGameEngine.h:1278
 
void DrawCircle(const olc::vi2d &pos, int32_t radius, Pixel p=olc::WHITE, uint8_t mask=0xFF)
 
void FillRectDecal(const olc::vf2d &pos, const olc::vf2d &size, const olc::Pixel col=olc::WHITE)
 
std::string sAppName
Definition olcPixelGameEngine.h:1551
 
void HW3D_SetCullMode(const olc::CullMode mode)
 
void FillTriangleDecal(const olc::vf2d &p0, const olc::vf2d &p1, const olc::vf2d &p2, const olc::Pixel col=olc::WHITE)
 
void FillTriangle(const olc::vi2d &pos1, const olc::vi2d &pos2, const olc::vi2d &pos3, Pixel p=olc::WHITE)
 
const olc::vi2d & GetWindowSize() const
 
void SetDecalStructure(const olc::DecalStructure &structure)
 
void DrawPolygonDecal(olc::Decal *decal, const std::vector< olc::vf2d > &pos, const std::vector< olc::vf2d > &uv, const std::vector< olc::Pixel > &tint)
 
void SetLayerOffset(uint8_t layer, const olc::vf2d &offset)
 
void olc_ConstructFontSheet()
 
bool ClipLineToScreen(olc::vi2d &in_p1, olc::vi2d &in_p2)
 
void GradientFillRectDecal(const olc::vf2d &pos, const olc::vf2d &size, const olc::Pixel colTL, const olc::Pixel colBL, const olc::Pixel colBR, const olc::Pixel colTR)
 
void DrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, Pixel p=olc::WHITE, uint32_t pattern=0xFFFFFFFF)
 
void HW3D_DrawObject(const std::array< float, 16 > &matModelView, olc::Decal *decal, const olc::DecalStructure layout, const std::vector< std::array< float, 4 > > &pos, const std::vector< std::array< float, 2 > > &uv, const std::vector< olc::Pixel > &col, const olc::Pixel tint=olc::WHITE)
 
void DrawStringProp(const olc::vi2d &pos, const std::string &sText, Pixel col=olc::WHITE, uint32_t scale=1)
 
void FillCircle(const olc::vi2d &pos, int32_t radius, Pixel p=olc::WHITE)
 
void DrawPolygonDecal(olc::Decal *decal, const std::vector< olc::vf2d > &pos, const std::vector< float > &depth, const std::vector< olc::vf2d > &uv, const std::vector< olc::Pixel > &colours, const olc::Pixel tint)
 
void DrawPartialDecal(const olc::vf2d &pos, const olc::vf2d &size, olc::Decal *decal, const olc::vf2d &source_pos, const olc::vf2d &source_size, const olc::Pixel &tint=olc::WHITE)
 
void DrawStringProp(int32_t x, int32_t y, const std::string &sText, Pixel col=olc::WHITE, uint32_t scale=1)
 
void EnableLayer(uint8_t layer, bool b)
 
void olc_DropFiles(int32_t x, int32_t y, const std::vector< std::string > &vFiles)
 
void DrawRect(int32_t x, int32_t y, int32_t w, int32_t h, Pixel p=olc::WHITE)
 
std::vector< LayerDesc > & GetLayers()
 
void DrawExplicitDecal(olc::Decal *decal, const olc::vf2d *pos, const olc::vf2d *uv, const olc::Pixel *col, uint32_t elements=4)
 
HWButton GetKey(Key k) const
 
void SetDecalMode(const olc::DecalMode &mode)
 
void DrawTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, Pixel p=olc::WHITE)
 
void DrawCircle(int32_t x, int32_t y, int32_t radius, Pixel p=olc::WHITE, uint8_t mask=0xFF)
 
int32_t GetMouseX() const
 
const olc::vi2d & GetDroppedFilesPoint() const
 
int32_t TextEntryGetCursor() const
 
void adv_FlushLayerGPUTasks(const size_t nLayerID)
 
virtual bool OnConsoleCommand(const std::string &sCommand)
 
void SetLayerScale(uint8_t layer, float x, float y)
 
void DrawPolygonDecal(olc::Decal *decal, const std::vector< olc::vf2d > &pos, const std::vector< olc::vf2d > &uv, const olc::Pixel tint=olc::WHITE)
 
void SetLayerCustomRenderFunction(uint8_t layer, std::function< void()> f)
 
virtual ~PixelGameEngine()
 
int32_t GetDrawTargetWidth() const
 
void DrawRectDecal(const olc::vf2d &pos, const olc::vf2d &size, const olc::Pixel col=olc::WHITE)
 
void FillCircle(int32_t x, int32_t y, int32_t radius, Pixel p=olc::WHITE)
 
void pgex_Register(olc::PGEX *pgex)
 
int32_t GetDrawTargetHeight() const
 
void olc_UpdateWindowSize(int32_t x, int32_t y)
 
olc::Sprite * GetDrawTarget() const
 
void DrawWarpedDecal(olc::Decal *decal, const std::array< olc::vf2d, 4 > &pos, const olc::Pixel &tint=olc::WHITE)
 
void TextEntryEnable(const bool bEnable, const std::string &sText="")
 
const std::string GetKeySymbol(const olc::Key pgekey, const bool modShift=false, const bool modCtrl=false, const bool modAlt=false) const
 
void olc_UpdateMouseState(int32_t button, bool state)
 
void DrawPartialWarpedDecal(olc::Decal *decal, const olc::vf2d *pos, const olc::vf2d &source_pos, const olc::vf2d &source_size, const olc::Pixel &tint=olc::WHITE)
 
const olc::vi2d & GetScreenSize() const
 
void DrawDecal(const olc::vf2d &pos, olc::Decal *decal, const olc::vf2d &scale={ 1.0f, 1.0f }, const olc::Pixel &tint=olc::WHITE)
 
void DrawSprite(int32_t x, int32_t y, Sprite *sprite, uint32_t scale=1, uint8_t flip=olc::Sprite::NONE)
 
std::stringstream & ConsoleOut()
 
void DrawWarpedDecal(olc::Decal *decal, const olc::vf2d(&pos)[4], const olc::Pixel &tint=olc::WHITE)
 
void DrawStringDecal(const olc::vf2d &pos, const std::string &sText, const Pixel col=olc::WHITE, const olc::vf2d &scale={ 1.0f, 1.0f })
 
void olc_UpdateKeyState(int32_t keycode, bool state)
 
virtual bool OnUserCreate()
 
void FillRect(int32_t x, int32_t y, int32_t w, int32_t h, Pixel p=olc::WHITE)
 
void olc_UpdateMouse(int32_t x, int32_t y)
 
virtual void OnTextEntryComplete(const std::string &sText)
 
void DrawPolygonDecal(olc::Decal *decal, const std::vector< olc::vf2d > &pos, const std::vector< float > &depth, const std::vector< olc::vf2d > &uv, const olc::Pixel tint=olc::WHITE)
 
void SetDrawTarget(Sprite *target)
 
void olc_UpdateKeyFocus(bool state)
 
olc::rcode SetWindowSize(const olc::vi2d &vPos, const olc::vi2d &vSize)
 
void DrawStringPropDecal(const olc::vf2d &pos, const std::string &sText, const Pixel col=olc::WHITE, const olc::vf2d &scale={ 1.0f, 1.0f })
 
void DrawPartialWarpedDecal(olc::Decal *decal, const olc::vf2d(&pos)[4], const olc::vf2d &source_pos, const olc::vf2d &source_size, const olc::Pixel &tint=olc::WHITE)
 
virtual void olc_ConfigureSystem()
 
void SetLayerTint(uint8_t layer, const olc::Pixel &tint)
 
const olc::vi2d & GetWindowMouse() const
 
void HW3D_Projection(const std::array< float, 16 > &m)
 
void ConsoleShow(const olc::Key &keyExit, bool bSuspendTime=true)
 
const olc::vi2d & GetMousePos() const
 
olc::Key ConvertKeycode(const int keycode) const
 
void DrawPartialDecal(const olc::vf2d &pos, olc::Decal *decal, const olc::vf2d &source_pos, const olc::vf2d &source_size, const olc::vf2d &scale={ 1.0f, 1.0f }, const olc::Pixel &tint=olc::WHITE)
 
int32_t GetMouseY() const
 
const olc::vi2d & GetScreenPixelSize() const
 
const std::vector< std::string > & GetDroppedFiles() const
 
void GradientTriangleDecal(const olc::vf2d &p0, const olc::vf2d &p1, const olc::vf2d &p2, const olc::Pixel c0, const olc::Pixel c1, const olc::Pixel c2)
 
virtual bool Draw(int32_t x, int32_t y, Pixel p=olc::WHITE)
 
int32_t GetMouseWheel() const
 
void SetPixelMode(std::function< olc::Pixel(const int x, const int y, const olc::Pixel &pSource, const olc::Pixel &pDest)> pixelMode)
 
bool IsConsoleShowing() const
 
void SetLayerOffset(uint8_t layer, float x, float y)
 
void DrawLineDecal(const olc::vf2d &pos1, const olc::vf2d &pos2, Pixel p=olc::WHITE)
 
olc::rcode ShowWindowFrame(const bool bShowFrame)
 
void olc_UpdateMouseWheel(int32_t delta)
 
int32_t ScreenWidth() const
 
void DrawRotatedStringDecal(const olc::vf2d &pos, const std::string &sText, const float fAngle, const olc::vf2d ¢er={ 0.0f, 0.0f }, const olc::Pixel col=olc::WHITE, const olc::vf2d &scale={ 1.0f, 1.0f })
 
olc::vi2d GetTextSize(const std::string &s)
 
olc::rcode Construct(int32_t screen_w, int32_t screen_h, int32_t pixel_w, int32_t pixel_h, bool full_screen=false, bool vsync=false, bool cohesion=false, bool realwindow=false)
 
void DrawPartialWarpedDecal(olc::Decal *decal, const std::array< olc::vf2d, 4 > &pos, const olc::vf2d &source_pos, const olc::vf2d &source_size, const olc::Pixel &tint=olc::WHITE)
 
void DrawPartialRotatedDecal(const olc::vf2d &pos, olc::Decal *decal, const float fAngle, const olc::vf2d ¢er, const olc::vf2d &source_pos, const olc::vf2d &source_size, const olc::vf2d &scale={ 1.0f, 1.0f }, const olc::Pixel &tint=olc::WHITE)
 
void DrawTriangle(const olc::vi2d &pos1, const olc::vi2d &pos2, const olc::vi2d &pos3, Pixel p=olc::WHITE)
 
void SetPixelBlend(float fBlend)
 
olc::vi2d GetTextSizeProp(const std::string &s)
 
const std::map< size_t, olc::Key > & GetKeyMap() const
Definition olcPixelGameEngine.h:1319
 
void olc_UpdateMouseFocus(bool state)
 
void HW3D_EnableDepthTest(const bool bEnableDepth)
 
void DrawPartialSprite(int32_t x, int32_t y, Sprite *sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, uint32_t scale=1, uint8_t flip=olc::Sprite::NONE)
 
std::string TextEntryGetString() const
 
void adv_FlushLayer(const size_t nLayerID)
 
void DrawRotatedDecal(const olc::vf2d &pos, olc::Decal *decal, const float fAngle, const olc::vf2d ¢er={ 0.0f, 0.0f }, const olc::vf2d &scale={ 1.0f, 1.0f }, const olc::Pixel &tint=olc::WHITE)
 
void EnablePixelTransfer(const bool bEnable=true)
 
bool IsTextEntryEnabled() const
 
int32_t ScreenHeight() const
 
void SetScreenSize(int w, int h)
 
HWButton GetMouse(uint32_t b) const
 
void DrawLine(const olc::vi2d &pos1, const olc::vi2d &pos2, Pixel p=olc::WHITE, uint32_t pattern=0xFFFFFFFF)
 
void DrawString(int32_t x, int32_t y, const std::string &sText, Pixel col=olc::WHITE, uint32_t scale=1)
 
void DrawPolygonDecal(olc::Decal *decal, const std::vector< olc::vf2d > &pos, const std::vector< olc::vf2d > &uv, const std::vector< olc::Pixel > &colours, const olc::Pixel tint)
 
void DrawRect(const olc::vi2d &pos, const olc::vi2d &size, Pixel p=olc::WHITE)
 
const olc::vi2d & GetWindowPos() const
 
void SetDrawTarget(uint8_t layer, bool bDirty=true)
 
void FillTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, Pixel p=olc::WHITE)
 
Pixel::Mode GetPixelMode()
 
virtual bool OnUserDestroy()
 
bool Draw(const olc::vi2d &pos, Pixel p=olc::WHITE)
 
void adv_FlushLayerDecals(const size_t nLayerID)
 
void adv_ManualRenderEnable(const bool bEnable)
 
void DrawSprite(const olc::vi2d &pos, Sprite *sprite, uint32_t scale=1, uint8_t flip=olc::Sprite::NONE)
 
olc::Sprite * GetFontSprite()
 
void FillTexturedTriangle(std::vector< olc::vf2d > vPoints, std::vector< olc::vf2d > vTex, std::vector< olc::Pixel > vColour, olc::Sprite *sprTex)
 
void DrawString(const olc::vi2d &pos, const std::string &sText, Pixel col=olc::WHITE, uint32_t scale=1)
 
void FillRect(const olc::vi2d &pos, const olc::vi2d &size, Pixel p=olc::WHITE)
 
void SetPixelMode(Pixel::Mode m)
 
void ConsoleCaptureStdOut(const bool bCapture)
 
void FillTexturedPolygon(const std::vector< olc::vf2d > &vPoints, const std::vector< olc::vf2d > &vTex, const std::vector< olc::Pixel > &vColour, olc::Sprite *sprTex, olc::DecalStructure structure=olc::DecalStructure::LIST)
 
void HW3D_DrawLineBox(const std::array< float, 16 > &matModelView, const std::array< float, 4 > &pos, const std::array< float, 4 > &size, const olc::Pixel col=olc::WHITE)
 
void DrawWarpedDecal(olc::Decal *decal, const olc::vf2d *pos, const olc::Pixel &tint=olc::WHITE)
 
const std::vector< int32_t > & GetKeyPressCache() const
 
void DrawPartialSprite(const olc::vi2d &pos, Sprite *sprite, const olc::vi2d &sourcepos, const olc::vi2d &size, uint32_t scale=1, uint8_t flip=olc::Sprite::NONE)
 
void ClearBuffer(Pixel p, bool bDepth=true)
 
void olc_UpdateViewport()
 
void HW3D_DrawLine(const std::array< float, 16 > &matModelView, const std::array< float, 4 > &pos1, const std::array< float, 4 > &pos2, const olc::Pixel col=olc::WHITE)
 
const olc::vi2d & GetPixelSize() const
 
float GetElapsedTime() const
 
void SetLayerScale(uint8_t layer, const olc::vf2d &scale)
 
virtual bool OnUserUpdate(float fElapsedTime)
 
void olc_UpdateWindowPos(int32_t x, int32_t y)
 
void adv_HardwareClip(const bool bScale, const olc::vi2d &viewPos, const olc::vi2d &viewSize, const bool bClear=false)
 
void DrawRotatedStringPropDecal(const olc::vf2d &pos, const std::string &sText, const float fAngle, const olc::vf2d ¢er={ 0.0f, 0.0f }, const olc::Pixel col=olc::WHITE, const olc::vf2d &scale={ 1.0f, 1.0f })
 
Definition olcPixelGameEngine.h:1149
 
Renderable & operator=(Renderable &&r)=default
 
Renderable(const Renderable &)=delete
 
void Create(uint32_t width, uint32_t height, bool filter=false, bool clamp=true)
 
Renderable(Renderable &&r)=default
 
olc::rcode Load(const std::string &sFile, ResourcePack *pack=nullptr, bool filter=false, bool clamp=true)
 
olc::Sprite * Sprite() const
 
olc::Decal * Decal() const
 
Definition olcPixelGameEngine.h:1226
 
virtual void PrepareDrawing()=0
 
virtual void ApplyTexture(uint32_t id)=0
 
virtual void UpdateTexture(uint32_t id, olc::Sprite *spr)=0
 
virtual olc::rcode CreateDevice(std::vector< void * > params, bool bFullScreen, bool bVSYNC)=0
 
virtual olc::rcode DestroyDevice()=0
 
virtual void DrawLayerQuad(const olc::vf2d &offset, const olc::vf2d &scale, const olc::Pixel tint)=0
 
virtual void DoGPUTask(const olc::GPUTask &task)=0
 
virtual void DisplayFrame()=0
 
virtual void PrepareDevice()=0
 
virtual ~Renderer()=default
 
static olc::PixelGameEngine * ptrPGE
Definition olcPixelGameEngine.h:1246
 
virtual void Set3DProjection(const std::array< float, 16 > &mat)=0
 
virtual void ClearBuffer(olc::Pixel p, bool bDepth)=0
 
virtual void ReadTexture(uint32_t id, olc::Sprite *spr)=0
 
virtual void UpdateViewport(const olc::vi2d &pos, const olc::vi2d &size)=0
 
virtual void DrawDecal(const olc::DecalInstance &decal)=0
 
virtual uint32_t CreateTexture(const uint32_t width, const uint32_t height, const bool filtered=false, const bool clamp=true)=0
 
virtual void SetDecalMode(const olc::DecalMode &mode)=0
 
virtual uint32_t DeleteTexture(const uint32_t id)=0
 
Definition olcPixelGameEngine.h:1039
 
bool LoadPack(const std::string &sFile, const std::string &sKey)
 
bool AddFile(const std::string &sFile)
 
ResourceBuffer GetFileBuffer(const std::string &sFile)
 
bool SavePack(const std::string &sFile, const std::string &sKey)
 
Definition olcPixelGameEngine.h:1071
 
static std::unique_ptr< olc::ImageLoader > loader
Definition olcPixelGameEngine.h:1106
 
Pixel SampleBL(const olc::vf2d &uv) const
 
Pixel GetPixel(const olc::vi2d &a) const
 
bool SetPixel(int32_t x, int32_t y, Pixel p)
 
olc::Sprite * Duplicate(const olc::vi2d &vPos, const olc::vi2d &vSize)
 
Sprite(int32_t w, int32_t h)
 
olc::Sprite * Duplicate()
 
void SetSize(int32_t w, int32_t h)
 
Sprite(const olc::Sprite &)=delete
 
Pixel SampleBL(float u, float v) const
 
Mode
Definition olcPixelGameEngine.h:1085
 
@ NORMAL
Definition olcPixelGameEngine.h:1085
 
@ PERIODIC
Definition olcPixelGameEngine.h:1085
 
@ CLAMP
Definition olcPixelGameEngine.h:1085
 
void SetSampleMode(olc::Sprite::Mode mode=olc::Sprite::Mode::NORMAL)
 
Pixel GetPixel(int32_t x, int32_t y) const
 
Pixel Sample(float x, float y) const
 
int32_t height
Definition olcPixelGameEngine.h:1084
 
Pixel Sample(const olc::vf2d &uv) const
 
Mode modeSample
Definition olcPixelGameEngine.h:1104
 
Flip
Definition olcPixelGameEngine.h:1086
 
@ HORIZ
Definition olcPixelGameEngine.h:1086
 
@ NONE
Definition olcPixelGameEngine.h:1086
 
@ VERT
Definition olcPixelGameEngine.h:1086
 
Sprite(const std::string &sImageFile, olc::ResourcePack *pack=nullptr)
 
std::vector< olc::Pixel > pColData
Definition olcPixelGameEngine.h:1103
 
olc::rcode LoadFromFile(const std::string &sImageFile, olc::ResourcePack *pack=nullptr)
 
bool SetPixel(const olc::vi2d &a, Pixel p)
 
int32_t width
Definition olcPixelGameEngine.h:1083
 
Definition olcPixelGameEngine.h:612
 
Pixel PixelF(float red, float green, float blue, float alpha=1.0f)
 
constexpr bool operator<(const v_2d< TL > &lhs, const v_2d< TR > &rhs)
Definition olcPixelGameEngine.h:896
 
v_2d< float > vf2d
Definition olcPixelGameEngine.h:918
 
constexpr uint32_t nDefaultPixel
Definition olcPixelGameEngine.h:938
 
constexpr auto operator/=(v_2d< TL > &lhs, const TR &rhs)
Definition olcPixelGameEngine.h:815
 
static const Pixel VERY_DARK_YELLOW(64, 64, 0)
 
static const Pixel VERY_DARK_MAGENTA(64, 0, 64)
 
static const Pixel BLACK(0, 0, 0)
 
constexpr auto operator/(const TL &lhs, const v_2d< TR > &rhs)
Definition olcPixelGameEngine.h:797
 
DecalStructure
Definition olcPixelGameEngine.h:1138
 
Pixel PixelLerp(const olc::Pixel &p1, const olc::Pixel &p2, float t)
 
static const Pixel VERY_DARK_GREEN(0, 64, 0)
 
constexpr auto operator*(const TL &lhs, const v_2d< TR > &rhs)
Definition olcPixelGameEngine.h:771
 
static const Pixel GREEN(0, 255, 0)
 
static const Pixel DARK_YELLOW(128, 128, 0)
 
std::map< size_t, olc::Key > mapKeys
Definition olcPixelGameEngine.h:1272
 
rcode
Definition olcPixelGameEngine.h:941
 
@ OK
Definition olcPixelGameEngine.h:941
 
@ FAIL
Definition olcPixelGameEngine.h:941
 
@ NO_FILE
Definition olcPixelGameEngine.h:941
 
static const Pixel CYAN(0, 255, 255)
 
static const Pixel VERY_DARK_BLUE(0, 0, 64)
 
constexpr auto operator-=(v_2d< TL > &lhs, const TR &rhs)
Definition olcPixelGameEngine.h:888
 
constexpr std::ostream & operator<<(std::ostream &os, const v_2d< T > &rhs)
Definition olcPixelGameEngine.h:909
 
constexpr auto operator+=(v_2d< TL > &lhs, const TR &rhs)
Definition olcPixelGameEngine.h:848
 
constexpr auto operator+(const v_2d< T > &lhs)
Definition olcPixelGameEngine.h:823
 
v_2d< uint32_t > vu2d
Definition olcPixelGameEngine.h:917
 
constexpr uint8_t nTabSizeInSpaces
Definition olcPixelGameEngine.h:939
 
v_2d< double > vd2d
Definition olcPixelGameEngine.h:919
 
static const Pixel YELLOW(255, 255, 0)
 
static const Pixel DARK_GREY(128, 128, 128)
 
v_2d< int32_t > vi2d
Definition olcPixelGameEngine.h:916
 
static const Pixel DARK_RED(128, 0, 0)
 
static const Pixel VERY_DARK_RED(64, 0, 0)
 
constexpr size_t OLC_MAX_VERTS
Definition olcPixelGameEngine.h:940
 
constexpr auto operator*=(v_2d< TL > &lhs, const TR &rhs)
Definition olcPixelGameEngine.h:789
 
constexpr auto operator-(const v_2d< T > &lhs)
Definition olcPixelGameEngine.h:863
 
static const Pixel VERY_DARK_GREY(64, 64, 64)
 
CullMode
Definition olcPixelGameEngine.h:1186
 
static const Pixel DARK_CYAN(0, 128, 128)
 
static const Pixel DARK_MAGENTA(128, 0, 128)
 
constexpr uint8_t nMouseButtons
Definition olcPixelGameEngine.h:936
 
static const Pixel DARK_GREEN(0, 128, 0)
 
static const Pixel BLUE(0, 0, 255)
 
static const Pixel DARK_BLUE(0, 0, 128)
 
static const Pixel BLANK(0, 0, 0, 0)
 
static const Pixel RED(255, 0, 0)
 
static const Pixel MAGENTA(255, 0, 255)
 
constexpr uint8_t nDefaultAlpha
Definition olcPixelGameEngine.h:937
 
static const Pixel WHITE(255, 255, 255)
 
DecalMode
Definition olcPixelGameEngine.h:1128
 
static const Pixel VERY_DARK_CYAN(0, 64, 64)
 
Key
Definition olcPixelGameEngine.h:996
 
constexpr bool operator>(const v_2d< TL > &lhs, const v_2d< TR > &rhs)
Definition olcPixelGameEngine.h:902
 
#define UNUSED(x)
Definition olcPixelGameEngine.h:480
 
#define olcT(s)
Definition olcPixelGameEngine.h:477
 
Definition olcPixelGameEngine.h:1172
 
olc::DecalStructure structure
Definition olcPixelGameEngine.h:1180
 
std::vector< olc::Pixel > tint
Definition olcPixelGameEngine.h:1178
 
std::vector< float > z
Definition olcPixelGameEngine.h:1177
 
std::vector< float > w
Definition olcPixelGameEngine.h:1176
 
bool depth
Definition olcPixelGameEngine.h:1182
 
olc::DecalMode mode
Definition olcPixelGameEngine.h:1179
 
std::vector< olc::vf2d > uv
Definition olcPixelGameEngine.h:1175
 
std::vector< olc::vf2d > pos
Definition olcPixelGameEngine.h:1174
 
uint32_t points
Definition olcPixelGameEngine.h:1181
 
olc::Decal * decal
Definition olcPixelGameEngine.h:1173
 
Definition olcPixelGameEngine.h:1195
 
uint32_t c
Definition olcPixelGameEngine.h:1195
 
float p[6]
Definition olcPixelGameEngine.h:1195
 
Definition olcPixelGameEngine.h:1193
 
olc::DecalStructure structure
Definition olcPixelGameEngine.h:1198
 
olc::CullMode cull
Definition olcPixelGameEngine.h:1207
 
olc::DecalMode mode
Definition olcPixelGameEngine.h:1199
 
std::vector< Vertex > vb
Definition olcPixelGameEngine.h:1196
 
olc::Decal * decal
Definition olcPixelGameEngine.h:1197
 
olc::Pixel tint
Definition olcPixelGameEngine.h:1208
 
std::array< float, 16 > mvp
Definition olcPixelGameEngine.h:1201
 
bool depth
Definition olcPixelGameEngine.h:1200
 
Definition olcPixelGameEngine.h:1212
 
olc::vf2d vOffset
Definition olcPixelGameEngine.h:1213
 
std::function< void()> funcHook
Definition olcPixelGameEngine.h:1222
 
std::vector< GPUTask > vecGPUTasks
Definition olcPixelGameEngine.h:1220
 
bool bUpdate
Definition olcPixelGameEngine.h:1216
 
olc::Renderable pDrawTarget
Definition olcPixelGameEngine.h:1217
 
uint32_t nResID
Definition olcPixelGameEngine.h:1218
 
olc::vf2d vScale
Definition olcPixelGameEngine.h:1214
 
std::vector< DecalInstance > vecDecalInstance
Definition olcPixelGameEngine.h:1219
 
bool bShow
Definition olcPixelGameEngine.h:1215
 
olc::Pixel tint
Definition olcPixelGameEngine.h:1221
 
Definition olcPixelGameEngine.h:948
 
Pixel & operator-=(const Pixel &p)
 
uint8_t g
Definition olcPixelGameEngine.h:952
 
Pixel operator*(const float i) const
 
Pixel operator-(const Pixel &p) const
 
Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha=nDefaultAlpha)
 
uint8_t a
Definition olcPixelGameEngine.h:952
 
bool operator==(const Pixel &p) const
 
Pixel & operator=(const Pixel &v)=default
 
Pixel operator/(const float i) const
 
uint8_t b
Definition olcPixelGameEngine.h:952
 
uint8_t r
Definition olcPixelGameEngine.h:952
 
uint32_t n
Definition olcPixelGameEngine.h:951
 
Pixel & operator+=(const Pixel &p)
 
Pixel & operator*=(const float i)
 
Pixel operator+(const Pixel &p) const
 
Pixel & operator/=(const float i)
 
Mode
Definition olcPixelGameEngine.h:955
 
@ MASK
Definition olcPixelGameEngine.h:955
 
@ ALPHA
Definition olcPixelGameEngine.h:955
 
@ NORMAL
Definition olcPixelGameEngine.h:955
 
@ CUSTOM
Definition olcPixelGameEngine.h:955
 
bool operator!=(const Pixel &p) const
 
Definition olcPixelGameEngine.h:1033
 
std::vector< char > vMemory
Definition olcPixelGameEngine.h:1035
 
ResourceBuffer(std::ifstream &ifs, uint32_t offset, uint32_t size)
 
Definition olcPixelGameEngine.h:619
 
constexpr v_2d clamp(const v_2d &v1, const v_2d &v2) const
Definition olcPixelGameEngine.h:726
 
T x
Definition olcPixelGameEngine.h:623
 
constexpr auto cross(const v_2d &rhs) const
Definition olcPixelGameEngine.h:708
 
T y
Definition olcPixelGameEngine.h:625
 
constexpr v_2d & operator=(const v_2d &v)=default
 
constexpr v_2d lerp(const v_2d &v1, const double t) const
Definition olcPixelGameEngine.h:732
 
constexpr auto dot(const v_2d &rhs) const
Definition olcPixelGameEngine.h:702
 
constexpr T mag2() const
Definition olcPixelGameEngine.h:659
 
v_2d norm() const
Definition olcPixelGameEngine.h:665
 
constexpr bool operator!=(const v_2d &rhs) const
Definition olcPixelGameEngine.h:744
 
std::string str() const
Definition olcPixelGameEngine.h:750
 
constexpr std::array< T, 2 > a() const
Definition olcPixelGameEngine.h:641
 
constexpr auto area() const
Definition olcPixelGameEngine.h:647
 
constexpr v_2d polar() const
Definition olcPixelGameEngine.h:720
 
constexpr v_2d(T _x, T _y)
Definition olcPixelGameEngine.h:631
 
constexpr v_2d min(const v_2d &v) const
Definition olcPixelGameEngine.h:696
 
constexpr v_2d(const v_2d &v)=default
 
constexpr bool operator==(const v_2d &rhs) const
Definition olcPixelGameEngine.h:738
 
constexpr v_2d max(const v_2d &v) const
Definition olcPixelGameEngine.h:690
 
constexpr v_2d ceil() const
Definition olcPixelGameEngine.h:684
 
constexpr v_2d reflect(const v_2d &n) const
Definition olcPixelGameEngine.h:756
 
constexpr v_2d perp() const
Definition olcPixelGameEngine.h:672
 
constexpr v_2d floor() const
Definition olcPixelGameEngine.h:678
 
constexpr v_2d cart() const
Definition olcPixelGameEngine.h:714
 
auto mag() const
Definition olcPixelGameEngine.h:653