1#pragma region license_and_help
204#pragma region version_history
348#pragma region hello_world_example
398#pragma region std_includes
426#pragma region compiler_config
427#define USE_EXPERIMENTAL_FS
429 #if _MSC_VER >= 1920 && _MSVC_LANG >= 201703L
430 #undef USE_EXPERIMENTAL_FS
433#if defined(__linux__) || defined(__MINGW32__) || defined(__EMSCRIPTEN__) || defined(__FreeBSD__) || defined(__APPLE__)
434 #if __cplusplus >= 201703L
435 #undef USE_EXPERIMENTAL_FS
439#if !defined(OLC_KEYBOARD_UK)
440 #define OLC_KEYBOARD_UK
444#if defined(USE_EXPERIMENTAL_FS) || defined(FORCE_EXPERIMENTAL_FS)
446 #define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
447 #include <experimental/filesystem>
448 namespace _gfs = std::experimental::filesystem::v1;
451 #include <filesystem>
452 namespace _gfs = std::filesystem;
455#if defined(UNICODE) || defined(_UNICODE)
461#define UNUSED(x) (void)(x)
467#if defined(OLC_PGE_HEADLESS)
468 #define OLC_PLATFORM_HEADLESS
469 #define OLC_GFX_HEADLESS
470 #if !defined(OLC_IMAGE_STB) && !defined(OLC_IMAGE_GDI) && !defined(OLC_IMAGE_LIBPNG)
471 #define OLC_IMAGE_HEADLESS
476#if !defined(OLC_PLATFORM_WINAPI) && !defined(OLC_PLATFORM_X11) && !defined(OLC_PLATFORM_GLUT) && !defined(OLC_PLATFORM_EMSCRIPTEN) && !defined(OLC_PLATFORM_HEADLESS)
477 #if !defined(OLC_PLATFORM_CUSTOM_EX)
479 #define OLC_PLATFORM_WINAPI
481 #if defined(__linux__) || defined(__FreeBSD__)
482 #define OLC_PLATFORM_X11
484 #if defined(__APPLE__)
485 #define GL_SILENCE_DEPRECATION
486 #define OLC_PLATFORM_GLUT
488 #if defined(__EMSCRIPTEN__)
489 #define OLC_PLATFORM_EMSCRIPTEN
495#if defined(OLC_PLATFORM_GLUT) || defined(OLC_PLATFORM_EMSCRIPTEN)
496 #define PGE_USE_CUSTOM_START
502#if !defined(OLC_GFX_OPENGL10) && !defined(OLC_GFX_OPENGL33) && !defined(OLC_GFX_DIRECTX10) && !defined(OLC_GFX_HEADLESS)
503 #if !defined(OLC_GFX_CUSTOM_EX)
504 #if defined(OLC_PLATFORM_EMSCRIPTEN)
505 #define OLC_GFX_OPENGL33
507 #define OLC_GFX_OPENGL10
513#if !defined(OLC_IMAGE_STB) && !defined(OLC_IMAGE_GDI) && !defined(OLC_IMAGE_LIBPNG) && !defined(OLC_IMAGE_HEADLESS)
514 #if !defined(OLC_IMAGE_CUSTOM_EX)
516 #define OLC_IMAGE_GDI
518 #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__)
519 #define OLC_IMAGE_LIBPNG
525#if defined(__EMSCRIPTEN__)
526#include <emscripten.h>
527#define FILE_RESOLVE(url, file) emscripten_wget(url, file); emscripten_sleep(0)
529#define FILE_RESOLVE(url, file)
535#if !defined(OLC_PGE_HEADLESS)
536#if defined(OLC_PLATFORM_WINAPI)
538 #if !defined(VC_EXTRALEAN)
541 #if !defined(NOMINMAX)
546 #if !defined(_WIN32_WINNT)
548 #define _WIN32_WINNT 0x0600
550 #define _WIN32_WINNT 0x0500
558#if defined(OLC_PLATFORM_X11)
562 #include <X11/Xlib.h>
566#if defined(OLC_PLATFORM_GLUT)
567 #if defined(__linux__)
569 #include <GL/freeglut_ext.h>
571 #if defined(__APPLE__)
572 #include <GLUT/glut.h>
573 #include <objc/message.h>
574 #include <objc/NSObjCRuntime.h>
579#if defined(OLC_PGE_HEADLESS)
591#if !defined(OLC_VECTOR2D_DEFINED)
601 static_assert(std::is_arithmetic<T>::value,
"olc::v_2d<type> must be numeric");
609 inline constexpr v_2d() =
default;
623 inline constexpr auto area()
const
631 return std::sqrt(
x *
x +
y *
y);
637 return x *
x +
y *
y;
644 return v_2d(
x * r,
y * r);
656 return v_2d(std::floor(
x), std::floor(
y));
662 return v_2d(std::ceil(
x), std::ceil(
y));
668 return v_2d(std::max(
x, v.
x), std::max(
y, v.
y));
674 return v_2d(std::min(
x, v.
x), std::min(
y, v.
y));
678 inline constexpr auto dot(
const v_2d& rhs)
const
680 return this->x * rhs.
x + this->y * rhs.
y;
686 return this->x * rhs.
y - this->y * rhs.
x;
692 return v_2d(std::cos(
y) *
x, std::sin(
y) *
x);
704 return this->
max(v1).
min(v2);
710 return (*
this) * (
T(1.0 - t)) + (v1 *
T(t));
716 return (this->x == rhs.
x && this->y == rhs.
y);
722 return (this->x != rhs.
x || this->y != rhs.
y);
726 inline std::string
str()
const
728 return std::string(
"(") + std::to_string(this->x) +
"," + std::to_string(this->y) +
")";
734 return (*
this) - 2.0 * (this->
dot(n) * n);
741 return {
static_cast<F>(this->
x),
static_cast<F>(this->y) };
746 template<
class TL,
class TR>
749 return v_2d(lhs * rhs.
x, lhs * rhs.
y);
752 template<
class TL,
class TR>
755 return v_2d(lhs.
x * rhs, lhs.
y * rhs);
758 template<
class TL,
class TR>
761 return v_2d(lhs.
x * rhs.
x, lhs.
y * rhs.
y);
764 template<
class TL,
class TR>
772 template<
class TL,
class TR>
775 return v_2d(lhs / rhs.
x, lhs / rhs.
y);
778 template<
class TL,
class TR>
781 return v_2d(lhs.
x / rhs, lhs.
y / rhs);
784 template<
class TL,
class TR>
787 return v_2d(lhs.
x / rhs.
x, lhs.
y / rhs.
y);
790 template<
class TL,
class TR>
801 return v_2d(+lhs.
x, +lhs.
y);
805 template<
class TL,
class TR>
808 return v_2d(lhs + rhs.
x, lhs + rhs.
y);
811 template<
class TL,
class TR>
814 return v_2d(lhs.
x + rhs, lhs.
y + rhs);
817 template<
class TL,
class TR>
820 return v_2d(lhs.
x + rhs.
x, lhs.
y + rhs.
y);
823 template<
class TL,
class TR>
830 template<
class TL,
class TR>
841 return v_2d(-lhs.
x, -lhs.
y);
845 template<
class TL,
class TR>
848 return v_2d(lhs - rhs.
x, lhs - rhs.
y);
851 template<
class TL,
class TR>
854 return v_2d(lhs.
x - rhs, lhs.
y - rhs);
857 template<
class TL,
class TR>
860 return v_2d(lhs.
x - rhs.
x, lhs.
y - rhs.
y);
863 template<
class TL,
class TR>
871 template<
class TL,
class TR>
874 return (lhs.
y < rhs.
y) || (lhs.
y == rhs.
y && lhs.
x < rhs.
x);
877 template<
class TL,
class TR>
880 return (lhs.
y > rhs.
y) || (lhs.
y == rhs.
y && lhs.
x > rhs.
x);
897#define OLC_VECTOR2D_DEFINED 1
905#pragma region pge_declaration
908 class PixelGameEngine;
922#if !defined(OLC_IGNORE_PIXEL)
928 struct { uint8_t
r; uint8_t
g; uint8_t
b; uint8_t
a; };
952 Pixel PixelF(
float red,
float green,
float blue,
float alpha = 1.0f);
974 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,
975 K0,
K1,
K2,
K3,
K4,
K5,
K6,
K7,
K8,
K9,
976 F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
978 SPACE,
TAB,
SHIFT,
CTRL,
INS,
DEL,
HOME,
END,
PGUP,
PGDN,
980 NP0,
NP1,
NP2,
NP3,
NP4,
NP5,
NP6,
NP7,
NP8,
NP9,
989 static constexpr int32_t LEFT = 0;
990 static constexpr int32_t RIGHT = 1;
991 static constexpr int32_t MIDDLE = 2;
1020 bool LoadPack(
const std::string& sFile,
const std::string& sKey);
1021 bool SavePack(
const std::string& sFile,
const std::string& sKey);
1025 struct sResourceFile { uint32_t nSize; uint32_t nOffset; };
1026 std::map<std::string, sResourceFile> mapFiles;
1027 std::ifstream baseFile;
1028 std::vector<char> scramble(
const std::vector<char>& data,
const std::string& key);
1029 std::string makeposix(
const std::string& path);
1082 static std::unique_ptr<olc::ImageLoader>
loader;
1132 void Create(uint32_t width, uint32_t height,
bool filter =
false,
bool clamp =
true);
1138 std::unique_ptr<olc::Sprite> pSprite =
nullptr;
1139 std::unique_ptr<olc::Decal> pDecal =
nullptr;
1151 std::vector<olc::vf2d>
uv;
1152 std::vector<float>
w;
1153 std::vector<float>
z;
1186 virtual uint32_t
CreateTexture(
const uint32_t width,
const uint32_t height,
const bool filtered =
false,
const bool clamp =
true) = 0;
1217 static std::unique_ptr<Renderer> renderer;
1218 static std::unique_ptr<Platform> platform;
1219 static std::map<size_t, uint8_t> mapKeys;
1231 bool full_screen =
false,
bool vsync =
false,
bool cohesion =
false,
bool realwindow =
false);
1266 static const std::map<size_t, uint8_t>&
GetKeyMap() {
return mapKeys; }
1418 void DrawPolygonDecal(
olc::Decal* decal,
const std::vector<olc::vf2d>& pos,
const std::vector<olc::vf2d>& uv,
const std::vector<olc::Pixel>& tint);
1420 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);
1455 void UpdateTextEntry();
1456 void UpdateConsole();
1461#ifdef OLC_ENABLE_EXPERIMENTAL
1463 void LW3D_View(
const std::array<float, 16>& m);
1465 void LW3D_World(
const std::array<float, 16>& m);
1467 void LW3D_Projection(
const std::array<float, 16>& m);
1470 void LW3D_DrawTriangles(
olc::Decal* decal,
const std::vector<std::array<float,3>>& pos,
const std::vector<olc::vf2d>& tex,
const std::vector<olc::Pixel>& col);
1471 void LW3D_DrawWarpedDecal(
olc::Decal* decal,
const std::vector<std::array<float, 3>>& pos,
const olc::Pixel& tint);
1473 void LW3D_ModelTranslate(
const float x,
const float y,
const float z);
1476 void LW3D_SetCameraAtTarget(
const float fEyeX,
const float fEyeY,
const float fEyeZ,
1477 const float fTargetX,
const float fTargetY,
const float fTargetZ,
1478 const float fUpX = 0.0f,
const float fUpY = 1.0f,
const float fUpZ = 0.0f);
1479 void LW3D_SetCameraAlongDirection(
const float fEyeX,
const float fEyeY,
const float fEyeZ,
1480 const float fDirX,
const float fDirY,
const float fDirZ,
1481 const float fUpX = 0.0f,
const float fUpY = 1.0f,
const float fUpZ = 0.0f);
1484 void LW3D_EnableDepthTest(
const bool bEnableDepth);
1485 void LW3D_EnableBackfaceCulling(
const bool bEnableCull);
1493 float fBlendFactor = 1.0f;
1495 olc::vf2d vInvScreenSize = { 1.0f / 256.0f, 1.0f / 240.0f };
1499 int32_t nMouseWheelDelta = 0;
1502 int32_t nMouseWheelDeltaCache = 0;
1507 bool bFullScreen =
false;
1509 bool bHasInputFocus =
false;
1510 bool bHasMouseFocus =
false;
1511 bool bEnableVSYNC =
false;
1512 bool bRealWindowMode =
false;
1513 bool bResizeRequested =
false;
1515 float fFrameTimer = 1.0f;
1516 float fLastElapsed = 0.0f;
1517 int nFrameCount = 0;
1518 bool bSuspendTextureTransfer =
false;
1519 Renderable fontRenderable;
1520 std::vector<LayerDesc> vLayers;
1521 uint8_t nTargetLayer = 0;
1522 uint32_t nLastFPS = 0;
1523 bool bManualRenderEnable =
false;
1524 bool bPixelCohesion =
false;
1528 std::chrono::time_point<std::chrono::system_clock> m_tp1, m_tp2;
1529 std::vector<olc::vi2d> vFontSpacing;
1530 std::vector<std::string> vDroppedFiles;
1531 std::vector<std::string> vDroppedFilesCache;
1536 bool bConsoleShow =
false;
1537 bool bConsoleSuspendTime =
false;
1539 std::stringstream ssConsoleOutput;
1540 std::streambuf* sbufOldCout =
nullptr;
1543 olc::vf2d vConsoleCharacterScale = { 1.0f, 2.0f };
1544 std::vector<std::string> sConsoleLines;
1545 std::list<std::string> sCommandHistory;
1546 std::list<std::string>::iterator sCommandHistoryIt;
1549 bool bTextEntryEnable =
false;
1550 std::string sTextEntryString =
"";
1551 int32_t nTextEntryCursor = 0;
1552 std::vector<std::tuple<olc::Key, std::string, std::string>> vKeyboardMap;
1557 bool pKeyNewState[256] = { 0 };
1558 bool pKeyOldState[256] = { 0 };
1559 HWButton pKeyboardState[256] = { 0 };
1567 void EngineThread();
1572 static std::atomic<bool> bAtomActive;
1589 void olc_DropFiles(int32_t x, int32_t y,
const std::vector<std::string>& vFiles);
1606 std::vector<olc::PGEX*> vExtensions;
1634#pragma region opengl33_iface
1639#if defined(OLC_GFX_OPENGL33)
1641 #if defined(OLC_PLATFORM_WINAPI)
1643 #define CALLSTYLE __stdcall
1646 #if defined(__linux__) || defined(__FreeBSD__)
1650 #if defined(OLC_PLATFORM_X11)
1657 #if defined(__APPLE__)
1658 #define GL_SILENCE_DEPRECATION
1659 #include <OpenGL/OpenGL.h>
1660 #include <OpenGL/gl.h>
1661 #include <OpenGL/glu.h>
1664 #if defined(OLC_PLATFORM_EMSCRIPTEN)
1665 #include <EGL/egl.h>
1666 #include <GLES2/gl2.h>
1667 #define GL_GLEXT_PROTOTYPES
1668 #include <GLES2/gl2ext.h>
1669 #include <emscripten/emscripten.h>
1671 #define GL_CLAMP GL_CLAMP_TO_EDGE
1676 typedef char GLchar;
1677 typedef ptrdiff_t GLsizeiptr;
1679 typedef GLuint CALLSTYLE locCreateShader_t(GLenum type);
1680 typedef GLuint CALLSTYLE locCreateProgram_t(
void);
1681 typedef void CALLSTYLE locDeleteShader_t(GLuint shader);
1682 typedef void CALLSTYLE locCompileShader_t(GLuint shader);
1683 typedef void CALLSTYLE locLinkProgram_t(GLuint program);
1684 typedef void CALLSTYLE locDeleteProgram_t(GLuint program);
1685 typedef void CALLSTYLE locAttachShader_t(GLuint program, GLuint shader);
1686 typedef void CALLSTYLE locBindBuffer_t(GLenum target, GLuint buffer);
1687 typedef void CALLSTYLE locBufferData_t(GLenum target, GLsizeiptr size,
const void* data, GLenum usage);
1688 typedef void CALLSTYLE locGenBuffers_t(GLsizei n, GLuint* buffers);
1689 typedef void CALLSTYLE locVertexAttribPointer_t(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
const void* pointer);
1690 typedef void CALLSTYLE locEnableVertexAttribArray_t(GLuint index);
1691 typedef void CALLSTYLE locUseProgram_t(GLuint program);
1692 typedef void CALLSTYLE locBindVertexArray_t(GLuint array);
1693 typedef void CALLSTYLE locGenVertexArrays_t(GLsizei n, GLuint* arrays);
1694 typedef void CALLSTYLE locGetShaderInfoLog_t(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
1695 typedef GLint CALLSTYLE locGetUniformLocation_t(GLuint program,
const GLchar* name);
1696 typedef void CALLSTYLE locUniform1f_t(GLint location, GLfloat v0);
1697 typedef void CALLSTYLE locUniform1i_t(GLint location, GLint v0);
1698 typedef void CALLSTYLE locUniform2fv_t(GLint location, GLsizei count,
const GLfloat* value);
1699 typedef void CALLSTYLE locActiveTexture_t(GLenum texture);
1700 typedef void CALLSTYLE locGenFrameBuffers_t(GLsizei n, GLuint* ids);
1701 typedef void CALLSTYLE locBindFrameBuffer_t(GLenum target, GLuint fb);
1702 typedef GLenum CALLSTYLE locCheckFrameBufferStatus_t(GLenum target);
1703 typedef void CALLSTYLE locDeleteFrameBuffers_t(GLsizei n,
const GLuint* fbs);
1704 typedef void CALLSTYLE locFrameBufferTexture2D_t(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
1705 typedef void CALLSTYLE locDrawBuffers_t(GLsizei n,
const GLenum* bufs);
1706 typedef void CALLSTYLE locBlendFuncSeparate_t(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
1708#if defined(OLC_PLATFORM_WINAPI)
1709 typedef void __stdcall locSwapInterval_t(GLsizei n);
1712#if defined(OLC_PLATFORM_X11)
1713 typedef int(locSwapInterval_t)(X11::Display* dpy, X11::GLXDrawable drawable,
int interval);
1716#if defined(OLC_PLATFORM_EMSCRIPTEN)
1717 typedef void CALLSTYLE locShaderSource_t(GLuint shader, GLsizei count,
const GLchar*
const*
string,
const GLint* length);
1718 typedef EGLBoolean(locSwapInterval_t)(EGLDisplay display, EGLint interval);
1720 typedef void CALLSTYLE locShaderSource_t(GLuint shader, GLsizei count,
const GLchar**
string,
const GLint* length);
1734#ifdef OLC_PGE_APPLICATION
1735#undef OLC_PGE_APPLICATION
1741#pragma region pge_implementation
1747#if !defined(OLC_IGNORE_PIXEL)
1751 Pixel::Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
1752 {
n = red | (green << 8) | (blue << 16) | (alpha << 24); }
1758 {
return n == p.n; }
1761 {
return n != p.n; }
1765 float fR = std::min(255.0f, std::max(0.0f,
float(
r) * i));
1766 float fG = std::min(255.0f, std::max(0.0f,
float(
g) * i));
1767 float fB = std::min(255.0f, std::max(0.0f,
float(
b) * i));
1768 return Pixel(uint8_t(fR), uint8_t(fG), uint8_t(fB),
a);
1773 float fR = std::min(255.0f, std::max(0.0f,
float(
r) / i));
1774 float fG = std::min(255.0f, std::max(0.0f,
float(
g) / i));
1775 float fB = std::min(255.0f, std::max(0.0f,
float(
b) / i));
1776 return Pixel(uint8_t(fR), uint8_t(fG), uint8_t(fB),
a);
1781 this->
r = uint8_t(std::min(255.0f, std::max(0.0f,
float(
r) * i)));
1782 this->
g = uint8_t(std::min(255.0f, std::max(0.0f,
float(
g) * i)));
1783 this->
b = uint8_t(std::min(255.0f, std::max(0.0f,
float(
b) * i)));
1789 this->
r = uint8_t(std::min(255.0f, std::max(0.0f,
float(
r) / i)));
1790 this->
g = uint8_t(std::min(255.0f, std::max(0.0f,
float(
g) / i)));
1791 this->
b = uint8_t(std::min(255.0f, std::max(0.0f,
float(
b) / i)));
1797 uint8_t nR = uint8_t(std::min(255, std::max(0,
int(
r) +
int(p.r))));
1798 uint8_t nG = uint8_t(std::min(255, std::max(0,
int(
g) +
int(p.g))));
1799 uint8_t nB = uint8_t(std::min(255, std::max(0,
int(
b) +
int(p.b))));
1800 return Pixel(nR, nG, nB,
a);
1805 uint8_t nR = uint8_t(std::min(255, std::max(0,
int(
r) -
int(p.r))));
1806 uint8_t nG = uint8_t(std::min(255, std::max(0,
int(
g) -
int(p.g))));
1807 uint8_t nB = uint8_t(std::min(255, std::max(0,
int(
b) -
int(p.b))));
1808 return Pixel(nR, nG, nB,
a);
1813 this->
r = uint8_t(std::min(255, std::max(0,
int(
r) +
int(p.r))));
1814 this->
g = uint8_t(std::min(255, std::max(0,
int(
g) +
int(p.g))));
1815 this->
b = uint8_t(std::min(255, std::max(0,
int(
b) +
int(p.b))));
1821 this->
r = uint8_t(std::min(255, std::max(0,
int(
r) -
int(p.r))));
1822 this->
g = uint8_t(std::min(255, std::max(0,
int(
g) -
int(p.g))));
1823 this->
b = uint8_t(std::min(255, std::max(0,
int(
b) -
int(p.b))));
1829 uint8_t nR = uint8_t(std::min(255.0f, std::max(0.0f,
float(
r) *
float(p.r) / 255.0f)));
1830 uint8_t nG = uint8_t(std::min(255.0f, std::max(0.0f,
float(
g) *
float(p.g) / 255.0f)));
1831 uint8_t nB = uint8_t(std::min(255.0f, std::max(0.0f,
float(
b) *
float(p.b) / 255.0f)));
1832 uint8_t nA = uint8_t(std::min(255.0f, std::max(0.0f,
float(
a) *
float(p.a) / 255.0f)));
1833 return Pixel(nR, nG, nB, nA);
1838 this->
r = uint8_t(std::min(255.0f, std::max(0.0f,
float(
r) *
float(p.r) / 255.0f)));
1839 this->
g = uint8_t(std::min(255.0f, std::max(0.0f,
float(
g) *
float(p.g) / 255.0f)));
1840 this->
b = uint8_t(std::min(255.0f, std::max(0.0f,
float(
b) *
float(p.b) / 255.0f)));
1841 this->
a = uint8_t(std::min(255.0f, std::max(0.0f,
float(
a) *
float(p.a) / 255.0f)));
1847 uint8_t nR = uint8_t(std::min(255, std::max(0, 255 -
int(
r))));
1848 uint8_t nG = uint8_t(std::min(255, std::max(0, 255 -
int(
g))));
1849 uint8_t nB = uint8_t(std::min(255, std::max(0, 255 -
int(
b))));
1850 return Pixel(nR, nG, nB,
a);
1853 Pixel
PixelF(
float red,
float green,
float blue,
float alpha)
1854 {
return Pixel(uint8_t(red * 255.0f), uint8_t(green * 255.0f), uint8_t(blue * 255.0f), uint8_t(alpha * 255.0f)); }
1857 {
return (p2 * t) + p1 * (1.0f - t); }
1895 if (x >= 0 && x < width && y >= 0 && y <
height)
1898 return Pixel(0, 0, 0, 0);
1911 if (x >= 0 && x < width && y >= 0 && y <
height)
1922 int32_t sx = std::min((int32_t)((x * (
float)
width)),
width - 1);
1923 int32_t sy = std::min((int32_t)((y * (
float)
height)),
height - 1);
1934 u = u *
width - 0.5f;
1936 int x = (int)floor(u);
1937 int y = (int)floor(v);
1938 float u_ratio = u - x;
1939 float v_ratio = v - y;
1940 float u_opposite = 1 - u_ratio;
1941 float v_opposite = 1 - v_ratio;
1949 (uint8_t)((p1.
r * u_opposite + p2.
r * u_ratio) * v_opposite + (p3.
r * u_opposite + p4.
r * u_ratio) * v_ratio),
1950 (uint8_t)((p1.
g * u_opposite + p2.
g * u_ratio) * v_opposite + (p3.
g * u_opposite + p4.
g * u_ratio) * v_ratio),
1951 (uint8_t)((p1.
b * u_opposite + p2.
b * u_ratio) * v_opposite + (p3.
b * u_opposite + p4.
b * u_ratio) * v_ratio));
1980 for (
int y = 0; y < vSize.
y; y++)
1981 for (
int x = 0; x < vSize.
x; x++)
1988 return { width, height };
1997 if (spr ==
nullptr)
return;
2005 if (spr ==
nullptr)
return;
2006 id = nExistingTextureResource;
2011 if (
sprite ==
nullptr)
return;
2013 renderer->ApplyTexture(
id);
2014 renderer->UpdateTexture(
id,
sprite);
2019 if (
sprite ==
nullptr)
return;
2020 renderer->ApplyTexture(
id);
2021 renderer->ReadTexture(
id,
sprite);
2028 renderer->DeleteTexture(
id);
2035 pSprite = std::make_unique<olc::Sprite>(width, height);
2036 pDecal = std::make_unique<olc::Decal>(pSprite.get(), filter, clamp);
2041 pSprite = std::make_unique<olc::Sprite>();
2044 pDecal = std::make_unique<olc::Decal>(pSprite.get(), filter, clamp);
2056 {
return pDecal.get(); }
2059 {
return pSprite.get(); }
2081 const std::string file = makeposix(sFile);
2083 if (_gfs::exists(file))
2086 e.nSize = (uint32_t)_gfs::file_size(file);
2097 baseFile.open(sFile, std::ifstream::binary);
2098 if (!baseFile.is_open())
return false;
2101 uint32_t nIndexSize = 0;
2102 baseFile.read((
char*)&nIndexSize,
sizeof(uint32_t));
2104 std::vector<char> buffer(nIndexSize);
2105 for (uint32_t j = 0; j < nIndexSize; j++)
2106 buffer[j] = baseFile.get();
2108 std::vector<char> decoded = scramble(buffer, sKey);
2110 auto read = [&decoded, &pos](
char* dst,
size_t size) {
2111 memcpy((
void*)dst, (
const void*)(decoded.data() + pos), size);
2115 auto get = [&read]() ->
int {
char c; read(&c, 1);
return c; };
2118 uint32_t nMapEntries = 0;
2119 read((
char*)&nMapEntries,
sizeof(uint32_t));
2120 for (uint32_t i = 0; i < nMapEntries; i++)
2122 uint32_t nFilePathSize = 0;
2123 read((
char*)&nFilePathSize,
sizeof(uint32_t));
2125 std::string sFileName(nFilePathSize,
' ');
2126 for (uint32_t j = 0; j < nFilePathSize; j++)
2127 sFileName[j] = get();
2130 read((
char*)&e.nSize,
sizeof(uint32_t));
2131 read((
char*)&e.nOffset,
sizeof(uint32_t));
2132 mapFiles[sFileName] = e;
2143 std::ofstream ofs(sFile, std::ofstream::binary);
2144 if (!ofs.is_open())
return false;
2147 uint32_t nIndexSize = 0;
2148 ofs.write((
char*)&nIndexSize,
sizeof(uint32_t));
2149 uint32_t nMapSize = uint32_t(mapFiles.size());
2150 ofs.write((
char*)&nMapSize,
sizeof(uint32_t));
2151 for (
auto& e : mapFiles)
2154 size_t nPathSize = e.first.size();
2155 ofs.write((
char*)&nPathSize,
sizeof(uint32_t));
2156 ofs.write(e.first.c_str(), nPathSize);
2159 ofs.write((
char*)&e.second.nSize,
sizeof(uint32_t));
2160 ofs.write((
char*)&e.second.nOffset,
sizeof(uint32_t));
2164 std::streampos offset = ofs.tellp();
2165 nIndexSize = (uint32_t)offset;
2166 for (
auto& e : mapFiles)
2169 e.second.nOffset = (uint32_t)offset;
2172 std::vector<uint8_t> vBuffer(e.second.nSize);
2173 std::ifstream i(e.first, std::ifstream::binary);
2174 i.read((
char*)vBuffer.data(), e.second.nSize);
2178 ofs.write((
char*)vBuffer.data(), e.second.nSize);
2179 offset += e.second.nSize;
2183 std::vector<char> stream;
2184 auto write = [&stream](
const char* data,
size_t size) {
2185 size_t sizeNow = stream.size();
2186 stream.resize(sizeNow + size);
2187 memcpy(stream.data() + sizeNow, data, size);
2191 write((
char*)&nMapSize,
sizeof(uint32_t));
2192 for (
auto& e : mapFiles)
2195 size_t nPathSize = e.first.size();
2196 write((
char*)&nPathSize,
sizeof(uint32_t));
2197 write(e.first.c_str(), nPathSize);
2200 write((
char*)&e.second.nSize,
sizeof(uint32_t));
2201 write((
char*)&e.second.nOffset,
sizeof(uint32_t));
2203 std::vector<char> sIndexString = scramble(stream, sKey);
2204 uint32_t nIndexStringLen = uint32_t(sIndexString.size());
2207 ofs.seekp(0, std::ios::beg);
2208 ofs.write((
char*)&nIndexStringLen,
sizeof(uint32_t));
2209 ofs.write(sIndexString.data(), nIndexStringLen);
2215 {
return ResourceBuffer(baseFile, mapFiles[sFile].nOffset, mapFiles[sFile].nSize); }
2218 {
return baseFile.is_open(); }
2220 std::vector<char> ResourcePack::scramble(
const std::vector<char>& data,
const std::string& key)
2222 if (key.empty())
return data;
2223 std::vector<char> o;
2225 for (
auto s : data) o.push_back(s ^ key[(c++) % key.size()]);
2229 std::string ResourcePack::makeposix(
const std::string& path)
2232 for (
auto s : path) o += std::string(1, s ==
'\\' ?
'/' : s);
2255 bPixelCohesion = cohesion;
2256 bRealWindowMode = realwindow;
2257 vScreenSize = { screen_w, screen_h };
2258 vInvScreenSize = { 1.0f / float(screen_w), 1.0f / float(screen_h) };
2259 vPixelSize = { pixel_w, pixel_h };
2260 vWindowSize = vScreenSize * vPixelSize;
2261 bFullScreen = full_screen;
2262 bEnableVSYNC = vsync;
2263 vPixel = 2.0f / vScreenSize;
2265 if (vPixelSize.x <= 0 || vPixelSize.y <= 0 || vScreenSize.
x <= 0 || vScreenSize.
y <= 0)
2273 vScreenSize = { w, h };
2274 vInvScreenSize = { 1.0f / float(w), 1.0f / float(h) };
2275 for (
auto& layer : vLayers)
2277 layer.pDrawTarget.Create(vScreenSize.
x, vScreenSize.
y);
2278 layer.bUpdate =
true;
2281 if (!bRealWindowMode)
2285 renderer->DisplayFrame();
2288 renderer->UpdateViewport(vViewPos, vViewSize);
2291#if !defined(PGE_USE_CUSTOM_START)
2297 if (platform->CreateWindowPane({ 30,30 }, vWindowSize, bFullScreen) !=
olc::OK)
return olc::FAIL;
2302 std::thread t = std::thread(&PixelGameEngine::EngineThread,
this);
2305 platform->StartSystemEventLoop();
2320 pDrawTarget = target;
2325 if(!vLayers.empty())
2326 pDrawTarget = vLayers[0].pDrawTarget.Sprite();
2332 if (layer < vLayers.size())
2334 pDrawTarget = vLayers[layer].pDrawTarget.Sprite();
2335 vLayers[layer].bUpdate = bDirty;
2336 nTargetLayer = layer;
2341 {
if (layer < vLayers.size()) vLayers[layer].bShow = b; }
2347 {
if (layer < vLayers.size()) vLayers[layer].vOffset = { x, y }; }
2353 {
if (layer < vLayers.size()) vLayers[layer].vScale = { x, y }; }
2356 {
if (layer < vLayers.size()) vLayers[layer].tint = tint; }
2359 {
if (layer < vLayers.size()) vLayers[layer].funcHook = f; }
2367 ld.pDrawTarget.Create(vScreenSize.
x, vScreenSize.
y);
2368 vLayers.push_back(std::move(ld));
2369 return uint32_t(vLayers.size()) - 1;
2373 {
return pDrawTarget; }
2378 return pDrawTarget->
width;
2386 return pDrawTarget->
height;
2392 {
return nLastFPS; }
2395 {
return bHasInputFocus; }
2398 {
return pKeyboardState[k]; }
2401 {
return pMouseState[b]; }
2404 {
return vMousePos.
x; }
2407 {
return vMousePos.
y; }
2410 {
return vMousePos; }
2413 {
return nMouseWheelDelta; }
2416 {
return vScreenSize.
x; }
2419 {
return vScreenSize.
y; }
2422 {
return fLastElapsed; }
2425 {
return vWindowSize; }
2428 {
return vWindowPos; }
2431 {
return vPixelSize; }
2434 {
return vScreenPixelSize; }
2437 {
return vScreenSize; }
2440 {
return vMouseWindowPos; }
2443 {
return Draw(pos.
x, pos.
y, p); }
2448 if (!pDrawTarget)
return false;
2452 return pDrawTarget->
SetPixel(x, y, p);
2458 return pDrawTarget->
SetPixel(x, y, p);
2463 Pixel d = pDrawTarget->
GetPixel(x, y);
2464 float a = (float)(p.a / 255.0f) * fBlendFactor;
2466 float r = a * (float)p.r + c * (
float)d.r;
2467 float g = a * (float)p.g + c * (
float)d.g;
2468 float b = a * (float)p.b + c * (
float)d.b;
2469 return pDrawTarget->
SetPixel(x, y, Pixel((uint8_t)r, (uint8_t)g, (uint8_t)b));
2474 return pDrawTarget->
SetPixel(x, y, funcPixelMode(x, y, p, pDrawTarget->
GetPixel(x, y)));
2482 {
DrawLine(pos1.
x, pos1.
y, pos2.
x, pos2.
y, p, pattern); }
2486 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
2487 dx = x2 - x1; dy = y2 - y1;
2489 auto rol = [&](void) { pattern = (pattern << 1) | (pattern >> 31);
return pattern & 1; };
2494 x1 = p1.x; y1 = p1.y;
2495 x2 = p2.x; y2 = p2.y;
2500 if (y2 < y1) std::swap(y1, y2);
2501 for (y = y1; y <= y2; y++)
if (rol())
Draw(x1, y, p);
2507 if (x2 < x1) std::swap(x1, x2);
2508 for (x = x1; x <= x2; x++)
if (rol())
Draw(x, y1, p);
2513 dx1 = abs(dx); dy1 = abs(dy);
2514 px = 2 * dy1 - dx1; py = 2 * dx1 - dy1;
2519 x = x1; y = y1; xe = x2;
2523 x = x2; y = y2; xe = x1;
2526 if (rol())
Draw(x, y, p);
2528 for (i = 0; x < xe; i++)
2535 if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) y = y + 1;
else y = y - 1;
2536 px = px + 2 * (dy1 - dx1);
2538 if (rol())
Draw(x, y, p);
2545 x = x1; y = y1; ye = y2;
2549 x = x2; y = y2; ye = y1;
2552 if (rol())
Draw(x, y, p);
2554 for (i = 0; y < ye; i++)
2561 if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) x = x + 1;
else x = x - 1;
2562 py = py + 2 * (dx1 - dy1);
2564 if (rol())
Draw(x, y, p);
2581 int d = 3 - 2 * radius;
2586 if (mask & 0x01)
Draw(x + x0, y - y0, p);
2587 if (mask & 0x04)
Draw(x + y0, y + x0, p);
2588 if (mask & 0x10)
Draw(x - x0, y + y0, p);
2589 if (mask & 0x40)
Draw(x - y0, y - x0, p);
2590 if (x0 != 0 && x0 != y0)
2592 if (mask & 0x02)
Draw(x + y0, y - x0, p);
2593 if (mask & 0x08)
Draw(x + x0, y + y0, p);
2594 if (mask & 0x20)
Draw(x - y0, y + x0, p);
2595 if (mask & 0x80)
Draw(x - x0, y - y0, p);
2601 d += 4 * (x0++ - y0--) + 10;
2620 int d = 3 - 2 * radius;
2622 auto drawline = [&](
int sx,
int ex,
int y)
2624 for (
int x = sx; x <= ex; x++)
2630 drawline(x - y0, x + y0, y - x0);
2631 if (x0 > 0) drawline(x - y0, x + y0, y + x0);
2639 drawline(x - x0, x + x0, y - y0);
2640 drawline(x - x0, x + x0, y + y0);
2642 d += 4 * (x0++ - y0--) + 10;
2656 DrawLine(x + w, y, x + w, y + h, p);
2657 DrawLine(x + w, y + h, x, y + h, p);
2665 for (
int i = 0; i < pixels; i++) m[i] = p;
2669 { renderer->ClearBuffer(p, bDepth); }
2672 {
return fontRenderable.
Sprite(); }
2677 static constexpr int SEG_I = 0b0000, SEG_L = 0b0001, SEG_R = 0b0010, SEG_B = 0b0100, SEG_T = 0b1000;
2678 auto Segment = [&vScreenSize = vScreenSize](
const olc::vi2d& v)
2681 if (v.x < 0) i |= SEG_L;
else if (v.x > vScreenSize.
x) i |= SEG_R;
2682 if (v.y < 0) i |= SEG_B;
else if (v.y > vScreenSize.
y) i |= SEG_T;
2686 int s1 = Segment(in_p1), s2 = Segment(in_p2);
2690 if (!(s1 | s2))
return true;
2691 else if (s1 & s2)
return false;
2694 int s3 = s2 > s1 ? s2 : s1;
2696 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; }
2697 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; }
2698 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); }
2699 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); }
2700 if (s3 == s1) { in_p1 = n; s1 = Segment(in_p1); }
2701 else { in_p2 = n; s2 = Segment(in_p2); }
2709 bSuspendTextureTransfer = !bEnable;
2731 for (
int i = x; i < x2; i++)
2732 for (
int j = y; j < y2; j++)
2752 auto drawline = [&](
int sx,
int ex,
int ny) {
for (
int i = sx; i <= ex; i++)
Draw(i, ny, p); };
2754 int t1x, t2x, y, minx, maxx, t1xp, t2xp;
2755 bool changed1 =
false;
2756 bool changed2 =
false;
2757 int signx1, signx2, dx1, dy1, dx2, dy2;
2760 if (y1 > y2) { std::swap(y1, y2); std::swap(x1, x2); }
2761 if (y1 > y3) { std::swap(y1, y3); std::swap(x1, x3); }
2762 if (y2 > y3) { std::swap(y2, y3); std::swap(x2, x3); }
2764 t1x = t2x = x1; y = y1;
2765 dx1 = (int)(x2 - x1);
2766 if (dx1 < 0) { dx1 = -dx1; signx1 = -1; }
2768 dy1 = (int)(y2 - y1);
2770 dx2 = (int)(x3 - x1);
2771 if (dx2 < 0) { dx2 = -dx2; signx2 = -1; }
2773 dy2 = (int)(y3 - y1);
2775 if (dy1 > dx1) { std::swap(dx1, dy1); changed1 =
true; }
2776 if (dy2 > dx2) { std::swap(dy2, dx2); changed2 =
true; }
2778 e2 = (int)(dx2 >> 1);
2780 if (y1 == y2)
goto next;
2781 e1 = (int)(dx1 >> 1);
2783 for (
int i = 0; i < dx1;) {
2785 if (t1x < t2x) { minx = t1x; maxx = t2x; }
2786 else { minx = t2x; maxx = t1x; }
2793 if (changed1) t1xp = signx1;
2796 if (changed1)
break;
2806 if (changed2) t2xp = signx2;
2809 if (changed2)
break;
2813 if (minx > t1x) minx = t1x;
2814 if (minx > t2x) minx = t2x;
2815 if (maxx < t1x) maxx = t1x;
2816 if (maxx < t2x) maxx = t2x;
2817 drawline(minx, maxx, y);
2819 if (!changed1) t1x += signx1;
2821 if (!changed2) t2x += signx2;
2828 dx1 = (int)(x3 - x2);
if (dx1 < 0) { dx1 = -dx1; signx1 = -1; }
2830 dy1 = (int)(y3 - y2);
2834 std::swap(dy1, dx1);
2837 else changed1 =
false;
2839 e1 = (int)(dx1 >> 1);
2841 for (
int i = 0; i <= dx1; i++) {
2843 if (t1x < t2x) { minx = t1x; maxx = t2x; }
2844 else { minx = t2x; maxx = t1x; }
2850 if (changed1) { t1xp = signx1;
break; }
2853 if (changed1)
break;
2863 if (changed2) t2xp = signx2;
2866 if (changed2)
break;
2871 if (minx > t1x) minx = t1x;
2872 if (minx > t2x) minx = t2x;
2873 if (maxx < t1x) maxx = t1x;
2874 if (maxx < t2x) maxx = t2x;
2875 drawline(minx, maxx, y);
2876 if (!changed1) t1x += signx1;
2878 if (!changed2) t2x += signx2;
2891 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]);}
2892 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]);}
2893 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]);}
2897 int dcr1 = vColour[1].r - vColour[0].r;
2898 int dcg1 = vColour[1].g - vColour[0].g;
2899 int dcb1 = vColour[1].b - vColour[0].b;
2900 int dca1 = vColour[1].a - vColour[0].a;
2904 int dcr2 = vColour[2].r - vColour[0].r;
2905 int dcg2 = vColour[2].g - vColour[0].g;
2906 int dcb2 = vColour[2].b - vColour[0].b;
2907 int dca2 = vColour[2].a - vColour[0].a;
2909 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;
2914 dax_step = dPos1.
x / (float)abs(dPos1.
y);
2915 vTex1Step = dTex1 / (float)abs(dPos1.
y);
2916 dcr1_step = dcr1 / (float)abs(dPos1.
y);
2917 dcg1_step = dcg1 / (float)abs(dPos1.
y);
2918 dcb1_step = dcb1 / (float)abs(dPos1.
y);
2919 dca1_step = dca1 / (float)abs(dPos1.
y);
2924 dbx_step = dPos2.
x / (float)abs(dPos2.
y);
2925 vTex2Step = dTex2 / (float)abs(dPos2.
y);
2926 dcr2_step = dcr2 / (float)abs(dPos2.
y);
2927 dcg2_step = dcg2 / (float)abs(dPos2.
y);
2928 dcb2_step = dcb2 / (float)abs(dPos2.
y);
2929 dca2_step = dca2 / (float)abs(dPos2.
y);
2936 for (
int pass = 0; pass < 2; pass++)
2940 vStart = p1; vEnd = p2; vStartIdx = 0;
2945 dTex1 = vTex[2] - vTex[1];
2946 dcr1 = vColour[2].r - vColour[1].r;
2947 dcg1 = vColour[2].g - vColour[1].g;
2948 dcb1 = vColour[2].b - vColour[1].b;
2949 dca1 = vColour[2].a - vColour[1].a;
2950 dcr1_step = 0; dcg1_step = 0; dcb1_step = 0; dca1_step = 0;
2952 if (dPos2.
y) dbx_step = dPos2.
x / (float)abs(dPos2.
y);
2955 dax_step = dPos1.
x / (float)abs(dPos1.
y);
2956 vTex1Step = dTex1 / (float)abs(dPos1.
y);
2957 dcr1_step = dcr1 / (float)abs(dPos1.
y);
2958 dcg1_step = dcg1 / (float)abs(dPos1.
y);
2959 dcb1_step = dcb1 / (float)abs(dPos1.
y);
2960 dca1_step = dca1 / (float)abs(dPos1.
y);
2963 vStart = p2; vEnd = p3; vStartIdx = 1;
2968 for (
int i = vStart.
y; i <= vEnd.
y; i++)
2970 int ax = int(vStart.
x + (
float)(i - vStart.
y) * dax_step);
2971 int bx = int(p1.x + (
float)(i - p1.y) * dbx_step);
2973 olc::vf2d tex_s(vTex[vStartIdx].x + (
float)(i - vStart.
y) * vTex1Step.
x, vTex[vStartIdx].y + (
float)(i - vStart.
y) * vTex1Step.
y);
2974 olc::vf2d tex_e(vTex[0].x + (
float)(i - p1.y) * vTex2Step.
x, vTex[0].y + (
float)(i - p1.y) * vTex2Step.
y);
2976 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),
2977 vColour[vStartIdx].b + uint8_t((
float)(i - vStart.
y) * dcb1_step), vColour[vStartIdx].a + uint8_t((
float)(i - vStart.
y) * dca1_step));
2979 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),
2980 vColour[0].b + uint8_t((
float)(i - p1.y) * dcb2_step), vColour[0].a + uint8_t((
float)(i - p1.y) * dca2_step));
2982 if (ax > bx) { std::swap(ax, bx); std::swap(tex_s, tex_e); std::swap(col_s, col_e); }
2984 float tstep = 1.0f / ((float)(bx - ax));
2987 for (
int j = ax; j < bx; j++)
2990 if (sprTex !=
nullptr) pixel *= sprTex->
Sample(tex_s.lerp(tex_e, t));
3006 if (vPoints.size() < 3 || vTex.size() < 3 || vColour.size() < 3)
3011 for (
size_t tri = 0; tri < vPoints.size() / 3; tri++)
3013 std::vector<olc::vf2d> vP = { vPoints[tri * 3 + 0], vPoints[tri * 3 + 1], vPoints[tri * 3 + 2] };
3014 std::vector<olc::vf2d> vT = { vTex[tri * 3 + 0], vTex[tri * 3 + 1], vTex[tri * 3 + 2] };
3015 std::vector<olc::Pixel> vC = { vColour[tri * 3 + 0], vColour[tri * 3 + 1], vColour[tri * 3 + 2] };
3023 for (
size_t tri = 2; tri < vPoints.size(); tri++)
3025 std::vector<olc::vf2d> vP = { vPoints[tri - 2], vPoints[tri-1], vPoints[tri] };
3026 std::vector<olc::vf2d> vT = { vTex[tri - 2], vTex[tri - 1], vTex[tri] };
3027 std::vector<olc::Pixel> vC = { vColour[tri - 2], vColour[tri - 1], vColour[tri] };
3035 for (
size_t tri = 2; tri < vPoints.size(); tri++)
3037 std::vector<olc::vf2d> vP = { vPoints[0], vPoints[tri - 1], vPoints[tri] };
3038 std::vector<olc::vf2d> vT = { vTex[0], vTex[tri - 1], vTex[tri] };
3039 std::vector<olc::Pixel> vC = { vColour[0], vColour[tri - 1], vColour[tri] };
3052 if (sprite ==
nullptr)
3055 int32_t fxs = 0, fxm = 1, fx = 0;
3056 int32_t fys = 0, fym = 1, fy = 0;
3063 for (int32_t i = 0; i < sprite->width; i++, fx += fxm)
3066 for (int32_t j = 0; j < sprite->height; j++, fy += fym)
3067 for (uint32_t is = 0; is < scale; is++)
3068 for (uint32_t js = 0; js < scale; js++)
3069 Draw(x + (i * scale) + is, y + (j * scale) + js, sprite->GetPixel(fx, fy));
3075 for (int32_t i = 0; i < sprite->width; i++, fx += fxm)
3078 for (int32_t j = 0; j < sprite->height; j++, fy += fym)
3079 Draw(x + i, y + j, sprite->GetPixel(fx, fy));
3089 if (sprite ==
nullptr)
3092 int32_t fxs = 0, fxm = 1, fx = 0;
3093 int32_t fys = 0, fym = 1, fy = 0;
3100 for (int32_t i = 0; i < w; i++, fx += fxm)
3103 for (int32_t j = 0; j < h; j++, fy += fym)
3104 for (uint32_t is = 0; is < scale; is++)
3105 for (uint32_t js = 0; js < scale; js++)
3106 Draw(x + (i * scale) + is, y + (j * scale) + js, sprite->GetPixel(fx + ox, fy + oy));
3112 for (int32_t i = 0; i < w; i++, fx += fxm)
3115 for (int32_t j = 0; j < h; j++, fy += fym)
3116 Draw(x + i, y + j, sprite->GetPixel(fx + ox, fy + oy));
3122 { nDecalMode = mode; }
3125 { nDecalStructure = structure; }
3131 (pos.
x * vInvScreenSize.
x) * 2.0f - 1.0f,
3132 -((pos.
y * vInvScreenSize.
y) * 2.0f - 1.0f)
3138 ((pos.
x + source_size.
x * scale.
x) * vInvScreenSize.
x) * 2.0f - 1.0f,
3139 -(((pos.
y + source_size.
y * scale.
y) * vInvScreenSize.
y) * 2.0f - 1.0f)
3143 olc::vf2d vQuantisedPos = ((vScreenSpacePos * vWindow) +
olc::vf2d(0.5f, 0.5f)).floor() / vWindow;
3144 olc::vf2d vQuantisedDim = ((vScreenSpaceDim * vWindow) +
olc::vf2d(0.5f, -0.5f)).ceil() / vWindow;
3149 di.tint = { tint, tint, tint, tint };
3150 di.pos = { { vQuantisedPos.
x, vQuantisedPos.
y }, { vQuantisedPos.
x, vQuantisedDim.
y }, { vQuantisedDim.
x, vQuantisedDim.
y }, { vQuantisedDim.
x, vQuantisedPos.
y } };
3153 di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } };
3155 di.mode = nDecalMode;
3156 di.structure = nDecalStructure;
3157 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3164 (pos.
x * vInvScreenSize.
x) * 2.0f - 1.0f,
3165 ((pos.
y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f
3170 vScreenSpacePos.
x + (2.0f * size.
x * vInvScreenSize.
x),
3171 vScreenSpacePos.
y - (2.0f * size.
y * vInvScreenSize.
y)
3177 di.tint = { tint, tint, tint, tint };
3178 di.pos = { { vScreenSpacePos.
x, vScreenSpacePos.
y }, { vScreenSpacePos.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpacePos.
y } };
3181 di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } };
3183 di.mode = nDecalMode;
3184 di.structure = nDecalStructure;
3185 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3193 (pos.
x * vInvScreenSize.
x) * 2.0f - 1.0f,
3194 ((pos.
y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f
3199 vScreenSpacePos.
x + (2.0f * (float(decal->
sprite->
width) * vInvScreenSize.
x)) * scale.
x,
3200 vScreenSpacePos.
y - (2.0f * (float(decal->
sprite->
height) * vInvScreenSize.
y)) * scale.
y
3206 di.tint = { tint, tint, tint, tint };
3207 di.pos = { { vScreenSpacePos.
x, vScreenSpacePos.
y }, { vScreenSpacePos.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpacePos.
y } };
3208 di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
3209 di.w = { 1, 1, 1, 1 };
3210 di.mode = nDecalMode;
3211 di.structure = nDecalStructure;
3212 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3219 di.pos.resize(elements);
3220 di.uv.resize(elements);
3221 di.w.resize(elements);
3222 di.tint.resize(elements);
3223 di.points = elements;
3224 for (uint32_t i = 0; i < elements; i++)
3226 di.pos[i] = { (pos[i].
x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
3228 di.tint[i] = col[i];
3231 di.mode = nDecalMode;
3232 di.structure = nDecalStructure;
3233 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3240 di.points = uint32_t(pos.size());
3241 di.pos.resize(di.points);
3242 di.uv.resize(di.points);
3243 di.w.resize(di.points);
3244 di.tint.resize(di.points);
3245 for (uint32_t i = 0; i < di.points; i++)
3247 di.pos[i] = { (pos[i].x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
3252 di.mode = nDecalMode;
3253 di.structure = nDecalStructure;
3254 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3261 di.points = uint32_t(pos.size());
3262 di.pos.resize(di.points);
3263 di.uv.resize(di.points);
3264 di.w.resize(di.points);
3265 di.tint.resize(di.points);
3266 for (uint32_t i = 0; i < di.points; i++)
3268 di.pos[i] = { (pos[i].x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
3270 di.tint[i] = tint[i];
3273 di.mode = nDecalMode;
3274 di.structure = nDecalStructure;
3275 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3280 std::vector<olc::Pixel> newColours(colours.size(),
olc::WHITE);
3281 std::transform(colours.begin(), colours.end(), newColours.begin(),
3282 [&tint](
const olc::Pixel pin) { return pin * tint; });
3291 di.points = uint32_t(pos.size());
3292 di.pos.resize(di.points);
3293 di.uv.resize(di.points);
3294 di.w.resize(di.points);
3295 di.tint.resize(di.points);
3296 for (uint32_t i = 0; i < di.points; i++)
3298 di.pos[i] = { (pos[i].x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
3303 di.mode = nDecalMode;
3304 di.structure = nDecalStructure;
3305 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3312 di.points = uint32_t(pos.size());
3313 di.pos.resize(di.points);
3314 di.uv.resize(di.points);
3315 di.w.resize(di.points);
3316 di.tint.resize(di.points);
3317 for (uint32_t i = 0; i < di.points; i++)
3319 di.pos[i] = { (pos[i].x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
3321 di.tint[i] = colours[i] * tint;
3324 di.mode = nDecalMode;
3325 di.structure = nDecalStructure;
3326 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3329#ifdef OLC_ENABLE_EXPERIMENTAL
3331 void PixelGameEngine::LW3D_DrawTriangles(
olc::Decal* decal,
const std::vector<std::array<float, 3>>& pos,
const std::vector<olc::vf2d>& tex,
const std::vector<olc::Pixel>& col)
3335 di.points = uint32_t(pos.size());
3336 di.pos.resize(di.points);
3337 di.uv.resize(di.points);
3338 di.w.resize(di.points);
3339 di.z.resize(di.points);
3340 di.tint.resize(di.points);
3341 for (uint32_t i = 0; i < di.points; i++)
3343 di.pos[i] = { pos[i][0], pos[i][1] };
3344 di.w[i] = pos[i][2];
3345 di.z[i] = pos[i][2];
3347 di.tint[i] = col[i];
3349 di.mode = nDecalMode;
3352 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3355 void PixelGameEngine::LW3D_DrawWarpedDecal(
olc::Decal* decal,
const std::vector<std::array<float, 3>>& pos,
const olc::Pixel& tint)
3362 di.tint = { tint, tint, tint, tint };
3363 di.w = { 1, 1, 1, 1 };
3364 di.z = { 1, 1, 1, 1 };
3366 di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
3368 float rd = ((pos[2][0] - pos[0][0]) * (pos[3][1] - pos[1][1]) - (pos[3][0] - pos[1][0]) * (pos[2][1] - pos[0][1]));
3372 float rn = ((pos[3][0] - pos[1][0]) * (pos[0][1] - pos[1][1]) - (pos[3][1] - pos[1][1]) * (pos[0][0] - pos[1][0])) * rd;
3373 float sn = ((pos[2][0] - pos[0][0]) * (pos[0][1] - pos[1][1]) - (pos[2][1] - pos[0][1]) * (pos[0][0] - pos[1][0])) * rd;
3374 if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f))
3376 center.
x = pos[0][0] + rn * (pos[2][0] - pos[0][0]);
3377 center.
y = pos[0][1] + rn * (pos[2][1] - pos[0][1]);
3380 for (
int i = 0; i < 4; i++)
3381 d[i] = std::sqrt((pos[i][0] - center.
x) * (pos[i][0] - center.
x) + (pos[i][1] - center.
y) * (pos[i][1] - center.
y));
3383 for (
int i = 0; i < 4; i++)
3385 float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3];
3388 di.z[i] = pos[i][2];
3389 di.pos[i] = { (pos[i][0] * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i][1] * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
3391 di.mode = nDecalMode;
3392 di.structure = nDecalStructure;
3394 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3401 auto m = nDecalMode;
3428 auto m = nDecalMode;
3431 std::array<olc::vf2d, 4> points = { { {pos}, {pos.
x, pos.
y + vNewSize.
y}, {pos + vNewSize}, {pos.
x + vNewSize.
x, pos.
y} } };
3432 std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0},{0,0}} };
3433 std::array<olc::Pixel, 4> cols = { {col, col, col, col} };
3442 std::array<olc::vf2d, 4> points = { { {pos}, {pos.
x, pos.
y + vNewSize.
y}, {pos + vNewSize}, {pos.
x + vNewSize.
x, pos.
y} } };
3443 std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0},{0,0}} };
3444 std::array<olc::Pixel, 4> cols = { {col, col, col, col} };
3450 std::array<olc::vf2d, 4> points = { { {pos}, {pos.
x, pos.
y + size.
y}, {pos + size}, {pos.
x + size.
x, pos.
y} } };
3451 std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0},{0,0}} };
3452 std::array<olc::Pixel, 4> cols = { {colTL, colBL, colBR, colTR} };
3458 std::array<olc::vf2d, 4> points = { { p0, p1, p2 } };
3459 std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0}} };
3460 std::array<olc::Pixel, 4> cols = { {col, col, col} };
3466 std::array<olc::vf2d, 4> points = { { p0, p1, p2 } };
3467 std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0}} };
3468 std::array<olc::Pixel, 4> cols = { {c0, c1, c2} };
3477 di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
3478 di.w = { 1, 1, 1, 1 };
3479 di.tint = { tint, tint, tint, tint };
3481 di.pos[0] = (
olc::vf2d(0.0f, 0.0f) - center) * scale;
3485 float c = cos(fAngle), s = sin(fAngle);
3486 for (
int i = 0; i < 4; i++)
3488 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);
3489 di.pos[i] = di.pos[i] * vInvScreenSize * 2.0f -
olc::vf2d(1.0f, 1.0f);
3490 di.pos[i].y *= -1.0f;
3493 di.mode = nDecalMode;
3494 di.structure = nDecalStructure;
3495 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3504 di.tint = { tint, tint, tint, tint };
3505 di.w = { 1, 1, 1, 1 };
3507 di.pos[0] = (
olc::vf2d(0.0f, 0.0f) - center) * scale;
3508 di.pos[1] = (
olc::vf2d(0.0f, source_size.
y) - center) * scale;
3509 di.pos[2] = (
olc::vf2d(source_size.
x, source_size.
y) - center) * scale;
3510 di.pos[3] = (
olc::vf2d(source_size.
x, 0.0f) - center) * scale;
3511 float c = cos(fAngle), s = sin(fAngle);
3512 for (
int i = 0; i < 4; i++)
3514 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);
3515 di.pos[i] = di.pos[i] * vInvScreenSize * 2.0f -
olc::vf2d(1.0f, 1.0f);
3516 di.pos[i].y *= -1.0f;
3521 di.uv = { { uvtl.
x, uvtl.
y }, { uvtl.
x, uvbr.
y }, { uvbr.
x, uvbr.
y }, { uvbr.
x, uvtl.
y } };
3522 di.mode = nDecalMode;
3523 di.structure = nDecalStructure;
3524 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3532 di.tint = { tint, tint, tint, tint };
3533 di.w = { 1, 1, 1, 1 };
3535 di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
3537 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));
3542 di.uv = { { uvtl.
x, uvtl.
y }, { uvtl.
x, uvbr.
y }, { uvbr.
x, uvbr.
y }, { uvbr.
x, uvtl.
y } };
3545 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;
3546 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;
3547 if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center = pos[0] + rn * (pos[2] - pos[0]);
3548 float d[4];
for (
int i = 0; i < 4; i++) d[i] = (pos[i] - center).mag();
3549 for (
int i = 0; i < 4; i++)
3551 float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3];
3552 di.uv[i] *= q; di.w[i] *= q;
3553 di.pos[i] = { (pos[i].
x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
3555 di.mode = nDecalMode;
3556 di.structure = nDecalStructure;
3557 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3568 di.tint = { tint, tint, tint, tint };
3569 di.w = { 1, 1, 1, 1 };
3571 di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
3573 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));
3577 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;
3578 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;
3579 if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center = pos[0] + rn * (pos[2] - pos[0]);
3580 float d[4];
for (
int i = 0; i < 4; i++) d[i] = (pos[i] - center).
mag();
3581 for (
int i = 0; i < 4; i++)
3583 float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3];
3584 di.uv[i] *= q; di.w[i] *= q;
3585 di.pos[i] = { (pos[i].
x * vInvScreenSize.
x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f };
3587 di.mode = nDecalMode;
3588 di.structure = nDecalStructure;
3589 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
3608 for (
auto c : sText)
3612 spos.
x = 0; spos.
y += 8.0f * scale.
y;
3620 int32_t ox = (c - 32) % 16;
3621 int32_t oy = (c - 32) / 16;
3622 DrawPartialDecal(pos + spos, fontRenderable.
Decal(), {float(ox) * 8.0f, float(oy) * 8.0f}, {8.0f, 8.0f}, scale, col);
3623 spos.
x += 8.0f * scale.
x;
3631 for (
auto c : sText)
3635 spos.
x = 0; spos.
y += 8.0f * scale.
y;
3643 int32_t ox = (c - 32) % 16;
3644 int32_t oy = (c - 32) / 16;
3645 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);
3646 spos.
x += float(vFontSpacing[c - 32].y) * scale.
x;
3654 for (
auto c : sText)
3658 spos.
x = center.
x; spos.
y -= 8.0f;
3666 int32_t ox = (c - 32) % 16;
3667 int32_t oy = (c - 32) / 16;
3668 DrawPartialRotatedDecal(pos, fontRenderable.
Decal(), fAngle, spos, { float(ox) * 8.0f, float(oy) * 8.0f }, { 8.0f, 8.0f }, scale, col);
3677 for (
auto c : sText)
3681 spos.
x = center.
x; spos.
y -= 8.0f;
3689 int32_t ox = (c - 32) % 16;
3690 int32_t oy = (c - 32) / 16;
3691 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);
3692 spos.
x -= float(vFontSpacing[c - 32].y);
3703 if (c ==
'\n') { pos.
y++; pos.
x = 0; }
3706 size.
x = std::max(size.
x, pos.
x);
3707 size.
y = std::max(size.
y, pos.
y);
3726 for (
auto c : sText)
3730 sx = 0; sy += 8 * scale;
3738 int32_t ox = (c - 32) % 16;
3739 int32_t oy = (c - 32) / 16;
3743 for (uint32_t i = 0; i < 8; i++)
3744 for (uint32_t j = 0; j < 8; j++)
3746 for (uint32_t is = 0; is < scale; is++)
3747 for (uint32_t js = 0; js < scale; js++)
3748 Draw(x + sx + (i * scale) + is, y + sy + (j * scale) + js, col);
3752 for (uint32_t i = 0; i < 8; i++)
3753 for (uint32_t j = 0; j < 8; j++)
3755 Draw(x + sx + i, y + sy + j, col);
3769 if (c ==
'\n') { pos.
y += 1; pos.
x = 0; }
3771 else pos.
x += vFontSpacing[c - 32].y;
3772 size.
x = std::max(size.
x, pos.
x);
3773 size.
y = std::max(size.
y, pos.
y);
3794 for (
auto c : sText)
3798 sx = 0; sy += 8 * scale;
3806 int32_t ox = (c - 32) % 16;
3807 int32_t oy = (c - 32) / 16;
3811 for (int32_t i = 0; i < vFontSpacing[c - 32].y; i++)
3812 for (int32_t j = 0; j < 8; j++)
3813 if (fontRenderable.
Sprite()->
GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).
r > 0)
3814 for (int32_t is = 0; is < int(scale); is++)
3815 for (int32_t js = 0; js < int(scale); js++)
3816 Draw(x + sx + (i * scale) + is, y + sy + (j * scale) + js, col);
3820 for (int32_t i = 0; i < vFontSpacing[c - 32].y; i++)
3821 for (int32_t j = 0; j < 8; j++)
3822 if (fontRenderable.
Sprite()->
GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).
r > 0)
3823 Draw(x + sx + i, y + sy + j, col);
3825 sx += vFontSpacing[c - 32].y * scale;
3835 {
return nPixelMode; }
3839 funcPixelMode = pixelMode;
3845 fBlendFactor = fBlend;
3846 if (fBlendFactor < 0.0f) fBlendFactor = 0.0f;
3847 if (fBlendFactor > 1.0f) fBlendFactor = 1.0f;
3851 {
return ssConsoleOutput; }
3854 {
return bConsoleShow; }
3861 bConsoleShow =
true;
3862 bConsoleSuspendTime = bSuspendTime;
3864 keyConsoleExit = keyExit;
3865 pKeyboardState[keyConsoleExit].
bHeld =
false;
3866 pKeyboardState[keyConsoleExit].
bPressed =
false;
3867 pKeyboardState[keyConsoleExit].
bReleased =
true;
3871 { sConsoleLines.clear(); }
3876 sbufOldCout = std::cout.rdbuf(ssConsoleOutput.rdbuf());
3878 std::cout.rdbuf(sbufOldCout);
3881 void PixelGameEngine::UpdateConsole()
3883 if (
GetKey(keyConsoleExit).bPressed)
3886 bConsoleSuspendTime =
false;
3887 bConsoleShow =
false;
3892 vConsoleCharacterScale =
olc::vf2d(1.0f, 2.0f) / (
olc::vf2d(vViewSize) * vInvScreenSize);
3896 if (vConsoleSize.
y != sConsoleLines.size())
3898 vConsoleCursor = { 0,0 };
3899 sConsoleLines.clear();
3900 sConsoleLines.resize(vConsoleSize.
y);
3903 auto TypeCharacter = [&](
const char c)
3905 if (c >= 32 && c < 127)
3907 sConsoleLines[vConsoleCursor.
y].append(1, c);
3911 if( c ==
'\n' || vConsoleCursor.
x >= vConsoleSize.
x)
3913 vConsoleCursor.
y++; vConsoleCursor.
x = 0;
3916 if (vConsoleCursor.
y >= vConsoleSize.
y)
3918 vConsoleCursor.
y = vConsoleSize.
y - 1;
3919 for (
int i = 1; i < vConsoleSize.
y; i++)
3920 sConsoleLines[i - 1] = sConsoleLines[i];
3921 sConsoleLines[vConsoleCursor.
y].clear();
3926 while (ssConsoleOutput.rdbuf()->sgetc() != -1)
3928 char c = ssConsoleOutput.rdbuf()->sbumpc();
3933 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));
3937 for (int32_t nLine = 0; nLine < vConsoleSize.
y; nLine++)
3947 {
return vDroppedFiles; }
3950 {
return vDroppedFilesPoint; }
3957 nTextEntryCursor = int32_t(sText.size());
3958 sTextEntryString = sText;
3959 bTextEntryEnable =
true;
3963 bTextEntryEnable =
false;
3968 {
return sTextEntryString; }
3971 {
return nTextEntryCursor; }
3974 {
return bTextEntryEnable; }
3977 void PixelGameEngine::UpdateTextEntry()
3980 for (
const auto& key : vKeyboardMap)
3981 if (
GetKey(std::get<0>(key)).bPressed)
3983 sTextEntryString.insert(nTextEntryCursor,
GetKey(
olc::Key::SHIFT).bHeld ? std::get<2>(key) : std::get<1>(key));
3989 nTextEntryCursor = std::max(0, nTextEntryCursor - 1);
3991 nTextEntryCursor = std::min(int32_t(sTextEntryString.size()), nTextEntryCursor + 1);
3994 sTextEntryString.erase(nTextEntryCursor-1, 1);
3995 nTextEntryCursor = std::max(0, nTextEntryCursor - 1);
3998 sTextEntryString.erase(nTextEntryCursor, 1);
4002 if (!sCommandHistory.empty())
4004 if (sCommandHistoryIt != sCommandHistory.begin())
4005 sCommandHistoryIt--;
4007 nTextEntryCursor = int32_t(sCommandHistoryIt->size());
4008 sTextEntryString = *sCommandHistoryIt;
4014 if (!sCommandHistory.empty())
4016 if (sCommandHistoryIt != sCommandHistory.end())
4018 sCommandHistoryIt++;
4019 if (sCommandHistoryIt != sCommandHistory.end())
4021 nTextEntryCursor = int32_t(sCommandHistoryIt->size());
4022 sTextEntryString = *sCommandHistoryIt;
4026 nTextEntryCursor = 0;
4027 sTextEntryString =
"";
4037 std::cout <<
">" + sTextEntryString +
"\n";
4040 sCommandHistory.push_back(sTextEntryString);
4041 sCommandHistoryIt = sCommandHistory.end();
4043 sTextEntryString.clear();
4044 nTextEntryCursor = 0;
4062 {
UNUSED(fElapsedTime);
return false; }
4074 return platform->SetWindowSize(vPos, vSize);
4082 return platform->ShowWindowFrame(bShowFrame);
4091 if (bRealWindowMode)
4093 vPixelSize = { 1,1 };
4094 vViewSize = vScreenSize;
4099 int32_t ww = vScreenSize.
x * vPixelSize.x;
4100 int32_t wh = vScreenSize.
y * vPixelSize.y;
4101 float wasp = (float)ww / (
float)wh;
4105 vScreenPixelSize = (vWindowSize / vScreenSize);
4106 vViewSize = (vWindowSize / vScreenSize) * vScreenSize;
4110 vViewSize.
x = (int32_t)vWindowSize.
x;
4111 vViewSize.
y = (int32_t)((
float)vViewSize.
x / wasp);
4113 if (vViewSize.
y > vWindowSize.
y)
4115 vViewSize.
y = vWindowSize.
y;
4116 vViewSize.
x = (int32_t)((
float)vViewSize.
y * wasp);
4120 vViewPos = (vWindowSize - vViewSize) / 2;
4125 vWindowPos = { x, y };
4131 vWindowSize = { x, y };
4133 if (bRealWindowMode)
4135 vResizeRequested = vWindowSize;
4136 bResizeRequested =
true;
4143 { nMouseWheelDeltaCache += delta; }
4149 bHasMouseFocus =
true;
4150 vMouseWindowPos = { x, y };
4154 vMousePosCache.
x = (int32_t)(((
float)x / (
float)(vWindowSize.
x - (vViewPos.
x * 2)) * (
float)vScreenSize.
x));
4155 vMousePosCache.
y = (int32_t)(((
float)y / (float)(vWindowSize.
y - (vViewPos.
y * 2)) * (
float)vScreenSize.
y));
4156 if (vMousePosCache.
x >= (int32_t)vScreenSize.
x) vMousePosCache.
x = vScreenSize.
x - 1;
4157 if (vMousePosCache.
y >= (int32_t)vScreenSize.
y) vMousePosCache.
y = vScreenSize.
y - 1;
4158 if (vMousePosCache.
x < 0) vMousePosCache.
x = 0;
4159 if (vMousePosCache.
y < 0) vMousePosCache.
y = 0;
4163 { pMouseNewState[button] = state; }
4166 { pKeyNewState[key] = state; }
4169 { bHasMouseFocus = state; }
4172 { bHasInputFocus = state; }
4178 vDroppedFilesPointCache.
x = (int32_t)(((
float)x / (
float)(vWindowSize.
x - (vViewPos.
x * 2)) * (
float)vScreenSize.
x));
4179 vDroppedFilesPointCache.
y = (int32_t)(((
float)y / (float)(vWindowSize.
y - (vViewPos.
y * 2)) * (
float)vScreenSize.
y));
4180 if (vDroppedFilesPointCache.
x >= (int32_t)vScreenSize.
x) vDroppedFilesPointCache.
x = vScreenSize.
x - 1;
4181 if (vDroppedFilesPointCache.
y >= (int32_t)vScreenSize.
y) vDroppedFilesPointCache.
y = vScreenSize.
y - 1;
4182 if (vDroppedFilesPointCache.
x < 0) vDroppedFilesPointCache.
x = 0;
4183 if (vDroppedFilesPointCache.
y < 0) vDroppedFilesPointCache.
y = 0;
4184 vDroppedFilesCache = vFiles;
4188 { bAtomActive =
true; }
4191 {
return bAtomActive; }
4194 { bAtomActive =
false; }
4196 void PixelGameEngine::EngineThread()
4200 if (platform->ThreadStartUp() ==
olc::FAIL)
return;
4206 for (
auto& ext : vExtensions) ext->OnBeforeUserCreate();
4208 for (
auto& ext : vExtensions) ext->OnAfterUserCreate();
4223 platform->ThreadCleanUp();
4229 if (platform->CreateGraphics(bFullScreen, bEnableVSYNC, vViewPos, vViewSize) ==
olc::FAIL)
return;
4236 vLayers[0].bUpdate =
true;
4237 vLayers[0].bShow =
true;
4240 m_tp1 = std::chrono::system_clock::now();
4241 m_tp2 = std::chrono::system_clock::now();
4247 bManualRenderEnable = bEnable;
4254 renderer->UpdateViewport(vViewPos + vNewPos * vViewSize, vNewSize * vViewSize);
4260 renderer->PrepareDrawing();
4263 vInvScreenSize = 1.0f /
olc::vf2d(viewSize);
4265 vInvScreenSize = 1.0f /
olc::vf2d(vScreenSize);
4270 auto& layer = vLayers[nLayerID];
4274 if (layer.funcHook ==
nullptr)
4276 renderer->ApplyTexture(layer.pDrawTarget.Decal()->id);
4277 if (!bSuspendTextureTransfer)
4279 layer.pDrawTarget.Decal()->Update();
4280 layer.bUpdate =
false;
4289 (layer.vOffset.x * vInvScreenSize.
x) * 2.0f - 1.0f,
4290 ((layer.vOffset.y * vInvScreenSize.
y) * 2.0f - 1.0f) * -1.0f
4295 vScreenSpacePos.
x + (2.0f * (float(layer.pDrawTarget.Sprite()->width) * vInvScreenSize.
x)) * layer.vScale.x,
4296 vScreenSpacePos.
y - (2.0f * (float(layer.pDrawTarget.Sprite()->height) * vInvScreenSize.
y)) * layer.vScale.y
4300 di.decal = layer.pDrawTarget.Decal();
4303 di.pos = { { vScreenSpacePos.
x, vScreenSpacePos.
y }, { vScreenSpacePos.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpaceDim.
y }, { vScreenSpaceDim.
x, vScreenSpacePos.
y } };
4304 di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} };
4305 di.w = { 1, 1, 1, 1 };
4308 renderer->DrawDecal(di);
4321 auto& layer = vLayers[nLayerID];
4322 for (
auto& decal : layer.vecDecalInstance)
4324 layer.vecDecalInstance.clear();
4332 m_tp2 = std::chrono::system_clock::now();
4333 std::chrono::duration<float> elapsedTime = m_tp2 - m_tp1;
4337 float fElapsedTime = elapsedTime.count();
4338 fLastElapsed = fElapsedTime;
4340 if (bConsoleSuspendTime)
4341 fElapsedTime = 0.0f;
4344 platform->HandleSystemEvent();
4347 auto ScanHardware = [&](HWButton* pKeys,
bool* pStateOld,
bool* pStateNew, uint32_t nKeyCount)
4349 for (uint32_t i = 0; i < nKeyCount; i++)
4351 pKeys[i].bPressed =
false;
4352 pKeys[i].bReleased =
false;
4353 if (pStateNew[i] != pStateOld[i])
4357 pKeys[i].bPressed = !pKeys[i].bHeld;
4358 pKeys[i].bHeld =
true;
4362 pKeys[i].bReleased =
true;
4363 pKeys[i].bHeld =
false;
4366 pStateOld[i] = pStateNew[i];
4370 ScanHardware(pKeyboardState, pKeyOldState, pKeyNewState, 256);
4371 ScanHardware(pMouseState, pMouseOldState, pMouseNewState,
nMouseButtons);
4374 vMousePos = vMousePosCache;
4375 nMouseWheelDelta = nMouseWheelDeltaCache;
4376 nMouseWheelDeltaCache = 0;
4378 vDroppedFiles = vDroppedFilesCache;
4379 vDroppedFilesPoint = vDroppedFilesPointCache;
4380 vDroppedFilesCache.clear();
4382 if (bTextEntryEnable)
4388 bool bExtensionBlockFrame =
false;
4389 for (
auto& ext : vExtensions) bExtensionBlockFrame |= ext->OnBeforeUserUpdate(fElapsedTime);
4390 if (!bExtensionBlockFrame)
4395 for (
auto& ext : vExtensions) ext->OnAfterUserUpdate(fElapsedTime);
4399 if (bRealWindowMode)
4401 vPixelSize = { 1,1 };
4402 vViewSize = vScreenSize;
4406 if (!bManualRenderEnable)
4415 renderer->UpdateViewport(vViewPos, vViewSize);
4419 vLayers[0].bUpdate =
true;
4420 vLayers[0].bShow =
true;
4422 renderer->PrepareDrawing();
4424 for (
auto layer = vLayers.rbegin(); layer != vLayers.rend(); ++layer)
4428 if (layer->funcHook ==
nullptr)
4430 renderer->ApplyTexture(layer->pDrawTarget.Decal()->id);
4431 if (!bSuspendTextureTransfer && layer->bUpdate)
4433 layer->pDrawTarget.Decal()->Update();
4434 layer->bUpdate =
false;
4437 renderer->DrawLayerQuad(layer->vOffset, layer->vScale, layer->tint);
4440 for (
auto& decal : layer->vecDecalInstance)
4442 layer->vecDecalInstance.clear();
4454 renderer->DisplayFrame();
4456 if (bResizeRequested)
4458 bResizeRequested =
false;
4460 renderer->UpdateViewport({ 0,0 }, vWindowSize);
4464 fFrameTimer += fElapsedTime;
4466 if (fFrameTimer >= 1.0f)
4468 nLastFPS = nFrameCount;
4469 fFrameTimer -= 1.0f;
4470 std::string sTitle =
"OneLoneCoder.com - Pixel Game Engine - " +
sAppName +
" - FPS: " + std::to_string(nFrameCount);
4471 platform->SetWindowTitle(sTitle);
4479 data +=
"?Q`0001oOch0o01o@F40o0<AGD4090LAGD<090@A7ch0?00O7Q`0600>00000000";
4480 data +=
"O000000nOT0063Qo4d8>?7a14Gno94AA4gno94AaOT0>o3`oO400o7QN00000400";
4481 data +=
"Of80001oOg<7O7moBGT7O7lABET024@aBEd714AiOdl717a_=TH013Q>00000000";
4482 data +=
"720D000V?V5oB3Q_HdUoE7a9@DdDE4A9@DmoE4A;Hg]oM4Aj8S4D84@`00000000";
4483 data +=
"OaPT1000Oa`^13P1@AI[?g`1@A=[OdAoHgljA4Ao?WlBA7l1710007l100000000";
4484 data +=
"ObM6000oOfMV?3QoBDD`O7a0BDDH@5A0BDD<@5A0BGeVO5ao@CQR?5Po00000000";
4485 data +=
"Oc``000?Ogij70PO2D]??0Ph2DUM@7i`2DTg@7lh2GUj?0TO0C1870T?00000000";
4486 data +=
"70<4001o?P<7?1QoHg43O;`h@GT0@:@LB@d0>:@hN@L0@?aoN@<0O7ao0000?000";
4487 data +=
"OcH0001SOglLA7mg24TnK7ln24US>0PL24U140PnOgl0>7QgOcH0K71S0000A000";
4488 data +=
"00H00000@Dm1S007@DUSg00?OdTnH7YhOfTL<7Yh@Cl0700?@Ah0300700000000";
4489 data +=
"<008001QL00ZA41a@6HnI<1i@FHLM81M@@0LG81?O`0nC?Y7?`0ZA7Y300080000";
4490 data +=
"O`082000Oh0827mo6>Hn?Wmo?6HnMb11MP08@C11H`08@FP0@@0004@000000000";
4491 data +=
"00P00001Oab00003OcKP0006@6=PMgl<@440MglH@000000`@000001P00000000";
4492 data +=
"Ob@8@@00Ob@8@Ga13R@8Mga172@8?PAo3R@827QoOb@820@0O`0007`0000007P0";
4493 data +=
"O`000P08Od400g`<3V=P0G`673IP0`@3>1`00P@6O`P00g`<O`000GP800000000";
4494 data +=
"?P9PL020O`<`N3R0@E4HC7b0@ET<ATB0@@l6C4B0O`H3N7b0?P01L3R000000020";
4496 fontRenderable.
Create(128, 48);
4499 for (
size_t b = 0; b < 1024; b += 4)
4501 uint32_t sym1 = (uint32_t)data[b + 0] - 48;
4502 uint32_t sym2 = (uint32_t)data[b + 1] - 48;
4503 uint32_t sym3 = (uint32_t)data[b + 2] - 48;
4504 uint32_t sym4 = (uint32_t)data[b + 3] - 48;
4505 uint32_t r = sym1 << 18 | sym2 << 12 | sym3 << 6 | sym4;
4507 for (
int i = 0; i < 24; i++)
4509 int k = r & (1 << i) ? 255 : 0;
4511 if (++py == 48) { px++; py = 0; }
4517 constexpr std::array<uint8_t, 96> vSpacing = { {
4518 0x03,0x25,0x16,0x08,0x07,0x08,0x08,0x04,0x15,0x15,0x08,0x07,0x15,0x07,0x24,0x08,
4519 0x08,0x17,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x24,0x15,0x06,0x07,0x16,0x17,
4520 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x17,0x08,0x08,0x17,0x08,0x08,0x08,
4521 0x08,0x08,0x08,0x08,0x17,0x08,0x08,0x08,0x08,0x17,0x08,0x15,0x08,0x15,0x08,0x08,
4522 0x24,0x18,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x33,0x17,0x17,0x33,0x18,0x17,0x17,
4523 0x17,0x17,0x17,0x17,0x07,0x17,0x17,0x18,0x18,0x17,0x17,0x07,0x33,0x07,0x08,0x00, } };
4525 for (
auto c : vSpacing) vFontSpacing.push_back({ c >> 4, c & 15 });
4528#ifdef OLC_KEYBOARD_UK
4531 {
olc::Key::A,
"a",
"A"}, {
olc::Key::B,
"b",
"B"}, {
olc::Key::C,
"c",
"C"}, {
olc::Key::D,
"d",
"D"}, {
olc::Key::E,
"e",
"E"},
4532 {
olc::Key::F,
"f",
"F"}, {
olc::Key::G,
"g",
"G"}, {
olc::Key::H,
"h",
"H"}, {
olc::Key::I,
"i",
"I"}, {
olc::Key::J,
"j",
"J"},
4533 {
olc::Key::K,
"k",
"K"}, {
olc::Key::L,
"l",
"L"}, {
olc::Key::M,
"m",
"M"}, {
olc::Key::N,
"n",
"N"}, {
olc::Key::O,
"o",
"O"},
4534 {
olc::Key::P,
"p",
"P"}, {
olc::Key::Q,
"q",
"Q"}, {
olc::Key::R,
"r",
"R"}, {
olc::Key::S,
"s",
"S"}, {
olc::Key::T,
"t",
"T"},
4535 {
olc::Key::U,
"u",
"U"}, {
olc::Key::V,
"v",
"V"}, {
olc::Key::W,
"w",
"W"}, {
olc::Key::X,
"x",
"X"}, {
olc::Key::Y,
"y",
"Y"},
4538 {
olc::Key::K0,
"0",
")"}, {
olc::Key::K1,
"1",
"!"}, {
olc::Key::K2,
"2",
"\""}, {
olc::Key::K3,
"3",
"#"}, {
olc::Key::K4,
"4",
"$"},
4539 {
olc::Key::K5,
"5",
"%"}, {
olc::Key::K6,
"6",
"^"}, {
olc::Key::K7,
"7",
"&"}, {
olc::Key::K8,
"8",
"*"}, {
olc::Key::K9,
"9",
"("},
4541 {
olc::Key::NP0,
"0",
"0"}, {
olc::Key::NP1,
"1",
"1"}, {
olc::Key::NP2,
"2",
"2"}, {
olc::Key::NP3,
"3",
"3"}, {
olc::Key::NP4,
"4",
"4"},
4542 {
olc::Key::NP5,
"5",
"5"}, {
olc::Key::NP6,
"6",
"6"}, {
olc::Key::NP7,
"7",
"7"}, {
olc::Key::NP8,
"8",
"8"}, {
olc::Key::NP9,
"9",
"9"},
4543 {
olc::Key::NP_MUL,
"*",
"*"}, {
olc::Key::NP_DIV,
"/",
"/"}, {
olc::Key::NP_ADD,
"+",
"+"}, {
olc::Key::NP_SUB,
"-",
"-"}, {
olc::Key::NP_DECIMAL,
".",
"."},
4545 {
olc::Key::PERIOD,
".",
">"}, {
olc::Key::EQUALS,
"=",
"+"}, {
olc::Key::COMMA,
",",
"<"}, {
olc::Key::MINUS,
"-",
"_"}, {
olc::Key::SPACE,
" ",
" "},
4547 {
olc::Key::OEM_1,
";",
":"}, {
olc::Key::OEM_2,
"/",
"?"}, {
olc::Key::OEM_3,
"\'",
"@"}, {
olc::Key::OEM_4,
"[",
"{"},
4557 if (std::find(vExtensions.begin(), vExtensions.end(), pgex) == vExtensions.end())
4558 vExtensions.push_back(pgex);
4570 std::atomic<bool> PixelGameEngine::bAtomActive{
false };
4579#pragma region platform_headless
4582#if defined(OLC_GFX_HEADLESS)
4586 virtual void PrepareDevice() {};
4587 virtual olc::rcode CreateDevice(std::vector<void*> params,
bool bFullScreen,
bool bVSYNC) {
return olc::rcode::OK; }
4589 virtual void DisplayFrame() {}
4590 virtual void PrepareDrawing() {}
4594 virtual uint32_t CreateTexture(
const uint32_t width,
const uint32_t height,
const bool filtered =
false,
const bool clamp =
true) {
return 1;};
4595 virtual void UpdateTexture(uint32_t
id,
olc::Sprite* spr) {}
4596 virtual void ReadTexture(uint32_t
id,
olc::Sprite* spr) {}
4597 virtual uint32_t DeleteTexture(
const uint32_t
id) {
return 1;}
4598 virtual void ApplyTexture(uint32_t
id) {}
4600 virtual void ClearBuffer(
olc::Pixel p,
bool bDepth) {}
4603#if defined(OLC_PLATFORM_HEADLESS)
4610 virtual olc::rcode ShowWindowFrame(
const bool bShowFrame =
true)
override
4631#pragma region image_stb
4643#if defined(OLC_IMAGE_STB)
4644#define STB_IMAGE_IMPLEMENTATION
4645#include "stb_image.h"
4651 ImageLoader_STB() : ImageLoader()
4660 stbi_uc* bytes =
nullptr;
4661 int w = 0, h = 0, cmp = 0;
4662 if (pack !=
nullptr)
4665 bytes = stbi_load_from_memory((
unsigned char*)rb.vMemory.data(), rb.vMemory.size(), &w, &h, &cmp, 4);
4671 bytes = stbi_load(sImageFile.c_str(), &w, &h, &cmp, 4);
4696#if !defined(OLC_PGE_HEADLESS)
4698#pragma region renderer_ogl10
4702#if defined(OLC_GFX_OPENGL10)
4704#if defined(OLC_PLATFORM_WINAPI)
4707 #if !defined(__MINGW32__)
4708 #pragma comment(lib, "Dwmapi.lib")
4710 typedef BOOL(WINAPI wglSwapInterval_t) (
int interval);
4711 static wglSwapInterval_t* wglSwapInterval =
nullptr;
4712 typedef HDC glDeviceContext_t;
4713 typedef HGLRC glRenderContext_t;
4716#if defined(__linux__) || defined(__FreeBSD__)
4720#if defined(OLC_PLATFORM_X11)
4725 typedef int(glSwapInterval_t)(X11::Display* dpy, X11::GLXDrawable drawable,
int interval);
4726 static glSwapInterval_t* glSwapIntervalEXT;
4727 typedef X11::GLXContext glDeviceContext_t;
4728 typedef X11::GLXContext glRenderContext_t;
4731#if defined(__APPLE__)
4732 #define GL_SILENCE_DEPRECATION
4733 #include <OpenGL/OpenGL.h>
4734 #include <OpenGL/gl.h>
4735 #include <OpenGL/glu.h>
4743#if defined(OLC_PLATFORM_GLUT)
4744 bool mFullScreen =
false;
4746 glDeviceContext_t glDeviceContext = 0;
4747 glRenderContext_t glRenderContext = 0;
4753#if defined(OLC_PLATFORM_X11)
4754 X11::Display* olc_Display =
nullptr;
4755 X11::Window* olc_Window =
nullptr;
4756 X11::XVisualInfo* olc_VisualInfo =
nullptr;
4760 void PrepareDevice()
override
4762#if defined(OLC_PLATFORM_GLUT)
4765 char* argv[1] = { (
char*)
"" };
4766 glutInit(&argc, argv);
4767 glutInitWindowPosition(0, 0);
4768 glutInitWindowSize(512, 512);
4769 glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
4771 glutCreateWindow(
"OneLoneCoder.com - Pixel Game Engine");
4772 glEnable(GL_TEXTURE_2D);
4773 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
4777 olc::rcode CreateDevice(std::vector<void*> params,
bool bFullScreen,
bool bVSYNC)
override
4779#if defined(OLC_PLATFORM_WINAPI)
4781 glDeviceContext = GetDC((HWND)(params[0]));
4782 PIXELFORMATDESCRIPTOR pfd =
4784 sizeof(PIXELFORMATDESCRIPTOR), 1,
4785 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
4786 PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4787 PFD_MAIN_PLANE, 0, 0, 0, 0
4791 if (!(pf = ChoosePixelFormat(glDeviceContext, &pfd)))
return olc::FAIL;
4792 SetPixelFormat(glDeviceContext, pf, &pfd);
4794 if (!(glRenderContext = wglCreateContext(glDeviceContext)))
return olc::FAIL;
4795 wglMakeCurrent(glDeviceContext, glRenderContext);
4798 wglSwapInterval = (wglSwapInterval_t*)wglGetProcAddress(
"wglSwapIntervalEXT");
4799 if (wglSwapInterval && !bVSYNC) wglSwapInterval(0);
4803#if defined(OLC_PLATFORM_X11)
4804 using namespace X11;
4807 olc_Display = (X11::Display*)(params[0]);
4808 olc_Window = (X11::Window*)(params[1]);
4809 olc_VisualInfo = (X11::XVisualInfo*)(params[2]);
4811 glDeviceContext = glXCreateContext(olc_Display, olc_VisualInfo,
nullptr, GL_TRUE);
4812 glXMakeCurrent(olc_Display, *olc_Window, glDeviceContext);
4814 XWindowAttributes gwa;
4815 XGetWindowAttributes(olc_Display, *olc_Window, &gwa);
4816 glViewport(0, 0, gwa.width, gwa.height);
4818 glSwapIntervalEXT =
nullptr;
4819 glSwapIntervalEXT = (glSwapInterval_t*)glXGetProcAddress((
unsigned char*)
"glXSwapIntervalEXT");
4821 if (glSwapIntervalEXT ==
nullptr && !bVSYNC)
4823 printf(
"NOTE: Could not disable VSYNC, glXSwapIntervalEXT() was not found!\n");
4824 printf(
" Don't worry though, things will still work, it's just the\n");
4825 printf(
" frame rate will be capped to your monitors refresh rate - javidx9\n");
4828 if (glSwapIntervalEXT !=
nullptr && !bVSYNC)
4829 glSwapIntervalEXT(olc_Display, *olc_Window, 0);
4832#if defined(OLC_PLATFORM_GLUT)
4833 mFullScreen = bFullScreen;
4836#if defined(__APPLE__)
4838 CGLContextObj ctx = CGLGetCurrentContext();
4839 if (ctx) CGLSetParameter(ctx, kCGLCPSwapInterval, &sync);
4843 glEnable(GL_TEXTURE_2D);
4844 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
4851#if defined(OLC_PLATFORM_WINAPI)
4852 wglDeleteContext(glRenderContext);
4855#if defined(OLC_PLATFORM_X11)
4856 glXMakeCurrent(olc_Display, None, NULL);
4857 glXDestroyContext(olc_Display, glDeviceContext);
4860#if defined(OLC_PLATFORM_GLUT)
4861 glutDestroyWindow(glutGetWindow());
4866 void DisplayFrame()
override
4868#if defined(OLC_PLATFORM_WINAPI)
4869 SwapBuffers(glDeviceContext);
4870 if (bSync) DwmFlush();
4873#if defined(OLC_PLATFORM_X11)
4874 X11::glXSwapBuffers(olc_Display, *olc_Window);
4877#if defined(OLC_PLATFORM_GLUT)
4882 void PrepareDrawing()
override
4887 nDecalMode = DecalMode::NORMAL;
4888 nDecalStructure = DecalStructure::FAN;
4889 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4894 if (mode != nDecalMode)
4899 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4902 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
4905 glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
4908 glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
4911 glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
4914 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4925 glColor4ub(tint.
r, tint.
g, tint.
b, tint.
a);
4926 glTexCoord2f(0.0f * scale.
x + offset.
x, 1.0f * scale.
y + offset.
y);
4927 glVertex3f(-1.0f , -1.0f , 0.0f);
4928 glTexCoord2f(0.0f * scale.
x + offset.
x, 0.0f * scale.
y + offset.
y);
4929 glVertex3f(-1.0f , 1.0f , 0.0f);
4930 glTexCoord2f(1.0f * scale.
x + offset.
x, 0.0f * scale.
y + offset.
y);
4931 glVertex3f(1.0f , 1.0f , 0.0f);
4932 glTexCoord2f(1.0f * scale.
x + offset.
x, 1.0f * scale.
y + offset.
y);
4933 glVertex3f(1.0f , -1.0f , 0.0f);
4939 SetDecalMode(decal.
mode);
4941 if (decal.
decal ==
nullptr)
4942 glBindTexture(GL_TEXTURE_2D, 0);
4944 glBindTexture(GL_TEXTURE_2D, decal.
decal->
id);
4948 glEnable(GL_DEPTH_TEST);
4951 if (nDecalMode == DecalMode::WIREFRAME)
4952 glBegin(GL_LINE_LOOP);
4956 glBegin(GL_TRIANGLE_FAN);
4958 glBegin(GL_TRIANGLE_STRIP);
4960 glBegin(GL_TRIANGLES);
4967 for (uint32_t n = 0; n < decal.
points; n++)
4969 glColor4ub(decal.
tint[n].r, decal.
tint[n].g, decal.
tint[n].b, decal.
tint[n].a);
4970 glTexCoord4f(decal.
uv[n].x, decal.
uv[n].y, 0.0f, decal.
w[n]);
4971 glVertex3f(decal.
pos[n].x, decal.
pos[n].y, decal.
z[n]);
4977 for (uint32_t n = 0; n < decal.
points; n++)
4979 glColor4ub(decal.
tint[n].r, decal.
tint[n].g, decal.
tint[n].b, decal.
tint[n].a);
4980 glTexCoord4f(decal.
uv[n].x, decal.
uv[n].y, 0.0f, decal.
w[n]);
4981 glVertex2f(decal.
pos[n].x, decal.
pos[n].y);
4989 glDisable(GL_DEPTH_TEST);
4994 uint32_t CreateTexture(
const uint32_t width,
const uint32_t height,
const bool filtered,
const bool clamp)
override
4999 glGenTextures(1, &
id);
5000 glBindTexture(GL_TEXTURE_2D,
id);
5003 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5004 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5008 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5009 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5014 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
5015 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
5019 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
5020 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
5023 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
5027 uint32_t DeleteTexture(
const uint32_t
id)
override
5029 glDeleteTextures(1, &
id);
5033 void UpdateTexture(uint32_t
id,
olc::Sprite* spr)
override
5036 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spr->
width, spr->
height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spr->
GetData());
5039 void ReadTexture(uint32_t
id,
olc::Sprite* spr)
override
5041 glReadPixels(0, 0, spr->
width, spr->
height, GL_RGBA, GL_UNSIGNED_BYTE, spr->
GetData());
5044 void ApplyTexture(uint32_t
id)
override
5046 glBindTexture(GL_TEXTURE_2D,
id);
5049 void ClearBuffer(
olc::Pixel p,
bool bDepth)
override
5051 glClearColor(
float(p.
r) / 255.0f,
float(p.
g) / 255.0f,
float(p.
b) / 255.0f,
float(p.
a) / 255.0f);
5052 glClear(GL_COLOR_BUFFER_BIT);
5053 if (bDepth) glClear(GL_DEPTH_BUFFER_BIT);
5058 glViewport(pos.
x, pos.
y, size.
x, size.
y);
5068#pragma region renderer_ogl33
5072#if defined(OLC_GFX_OPENGL33)
5074#if defined(OLC_PLATFORM_WINAPI)
5077 #if !defined(__MINGW32__)
5078 #pragma comment(lib, "Dwmapi.lib")
5081 typedef HDC glDeviceContext_t;
5082 typedef HGLRC glRenderContext_t;
5084 #define OGL_LOAD(t, n) (t*)wglGetProcAddress(#n)
5091#if defined(OLC_PLATFORM_X11)
5097 typedef X11::GLXContext glDeviceContext_t;
5098 typedef X11::GLXContext glRenderContext_t;
5100 #define OGL_LOAD(t, n) (t*)glXGetProcAddress((unsigned char*)#n);
5110#if defined(OLC_PLATFORM_EMSCRIPTEN)
5111 #include <EGL/egl.h>
5112 #include <GLES2/gl2.h>
5113 #define GL_GLEXT_PROTOTYPES
5114 #include <GLES2/gl2ext.h>
5115 #include <emscripten/emscripten.h>
5117 typedef EGLBoolean(locSwapInterval_t)(EGLDisplay display, EGLint interval);
5118 #define GL_CLAMP GL_CLAMP_TO_EDGE
5119 #define OGL_LOAD(t, n) n;
5165#if defined(OLC_PLATFORM_EMSCRIPTEN)
5166 EGLDisplay olc_Display;
5167 EGLConfig olc_Config;
5168 EGLContext olc_Context;
5169 EGLSurface olc_Surface;
5172#if defined(OLC_PLATFORM_GLUT)
5173 bool mFullScreen =
false;
5175 #if !defined(OLC_PLATFORM_EMSCRIPTEN)
5176 glDeviceContext_t glDeviceContext = 0;
5177 glRenderContext_t glRenderContext = 0;
5182#if defined(OLC_PLATFORM_X11)
5183 X11::Display* olc_Display =
nullptr;
5184 X11::Window* olc_Window =
nullptr;
5185 X11::XVisualInfo* olc_VisualInfo =
nullptr;
5189 locCreateShader_t* locCreateShader =
nullptr;
5190 locShaderSource_t* locShaderSource =
nullptr;
5191 locCompileShader_t* locCompileShader =
nullptr;
5192 locDeleteShader_t* locDeleteShader =
nullptr;
5193 locCreateProgram_t* locCreateProgram =
nullptr;
5194 locDeleteProgram_t* locDeleteProgram =
nullptr;
5195 locLinkProgram_t* locLinkProgram =
nullptr;
5196 locAttachShader_t* locAttachShader =
nullptr;
5197 locBindBuffer_t* locBindBuffer =
nullptr;
5198 locBufferData_t* locBufferData =
nullptr;
5199 locGenBuffers_t* locGenBuffers =
nullptr;
5200 locVertexAttribPointer_t* locVertexAttribPointer =
nullptr;
5201 locEnableVertexAttribArray_t* locEnableVertexAttribArray =
nullptr;
5202 locUseProgram_t* locUseProgram =
nullptr;
5203 locBindVertexArray_t* locBindVertexArray =
nullptr;
5204 locGenVertexArrays_t* locGenVertexArrays =
nullptr;
5205 locSwapInterval_t* locSwapInterval =
nullptr;
5206 locGetShaderInfoLog_t* locGetShaderInfoLog =
nullptr;
5210 uint32_t m_nQuadShader = 0;
5211 uint32_t m_vbQuad = 0;
5212 uint32_t m_vaQuad = 0;
5226 void PrepareDevice()
override
5228#if defined(OLC_PLATFORM_GLUT)
5231 char* argv[1] = { (
char*)
"" };
5232 glutInit(&argc, argv);
5233 glutInitWindowPosition(0, 0);
5234 glutInitWindowSize(512, 512);
5235 glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
5237 glutCreateWindow(
"OneLoneCoder.com - Pixel Game Engine");
5238 glEnable(GL_TEXTURE_2D);
5239 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
5243 olc::rcode CreateDevice(std::vector<void*> params,
bool bFullScreen,
bool bVSYNC)
override
5246#if defined(OLC_PLATFORM_WINAPI)
5248 glDeviceContext = GetDC((HWND)(params[0]));
5249 PIXELFORMATDESCRIPTOR pfd =
5251 sizeof(PIXELFORMATDESCRIPTOR), 1,
5252 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
5253 PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5254 PFD_MAIN_PLANE, 0, 0, 0, 0
5258 if (!(pf = ChoosePixelFormat(glDeviceContext, &pfd)))
return olc::FAIL;
5259 SetPixelFormat(glDeviceContext, pf, &pfd);
5261 if (!(glRenderContext = wglCreateContext(glDeviceContext)))
return olc::FAIL;
5262 wglMakeCurrent(glDeviceContext, glRenderContext);
5265 locSwapInterval = OGL_LOAD(locSwapInterval_t, wglSwapIntervalEXT);
5266 if (locSwapInterval && !bVSYNC) locSwapInterval(0);
5270#if defined(OLC_PLATFORM_X11)
5271 using namespace X11;
5274 olc_Display = (X11::Display*)(params[0]);
5275 olc_Window = (X11::Window*)(params[1]);
5276 olc_VisualInfo = (X11::XVisualInfo*)(params[2]);
5278 glDeviceContext = glXCreateContext(olc_Display, olc_VisualInfo,
nullptr, GL_TRUE);
5279 glXMakeCurrent(olc_Display, *olc_Window, glDeviceContext);
5281 XWindowAttributes gwa;
5282 XGetWindowAttributes(olc_Display, *olc_Window, &gwa);
5283 glViewport(0, 0, gwa.width, gwa.height);
5285 locSwapInterval = OGL_LOAD(locSwapInterval_t, glXSwapIntervalEXT);
5287 if (locSwapInterval ==
nullptr && !bVSYNC)
5289 printf(
"NOTE: Could not disable VSYNC, glXSwapIntervalEXT() was not found!\n");
5290 printf(
" Don't worry though, things will still work, it's just the\n");
5291 printf(
" frame rate will be capped to your monitors refresh rate - javidx9\n");
5294 if (locSwapInterval !=
nullptr && !bVSYNC)
5295 locSwapInterval(olc_Display, *olc_Window, 0);
5298#if defined(OLC_PLATFORM_EMSCRIPTEN)
5299 EGLint
const attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_NONE };
5300 EGLint
const context_config[] = { EGL_CONTEXT_CLIENT_VERSION , 2, EGL_NONE };
5303 olc_Display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
5304 eglInitialize(olc_Display,
nullptr,
nullptr);
5305 eglChooseConfig(olc_Display, attribute_list, &olc_Config, 1, &num_config);
5308 olc_Context = eglCreateContext(olc_Display, olc_Config, EGL_NO_CONTEXT, context_config);
5309 olc_Surface = eglCreateWindowSurface(olc_Display, olc_Config, NULL,
nullptr);
5310 eglMakeCurrent(olc_Display, olc_Surface, olc_Surface, olc_Context);
5312 locSwapInterval = &eglSwapInterval;
5313 locSwapInterval(olc_Display, bVSYNC ? 1 : 0);
5316#if defined(OLC_PLATFORM_GLUT)
5317 mFullScreen = bFullScreen;
5320#if defined(__APPLE__)
5322 CGLContextObj ctx = CGLGetCurrentContext();
5323 if (ctx) CGLSetParameter(ctx, kCGLCPSwapInterval, &sync);
5327 #if !defined(OLC_PLATFORM_EMSCRIPTEN)
5328 glEnable(GL_TEXTURE_2D);
5329 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
5333 locCreateShader = OGL_LOAD(locCreateShader_t, glCreateShader);
5334 locCompileShader = OGL_LOAD(locCompileShader_t, glCompileShader);
5335 locShaderSource = OGL_LOAD(locShaderSource_t, glShaderSource);
5336 locDeleteShader = OGL_LOAD(locDeleteShader_t, glDeleteShader);
5337 locCreateProgram = OGL_LOAD(locCreateProgram_t, glCreateProgram);
5338 locDeleteProgram = OGL_LOAD(locDeleteProgram_t, glDeleteProgram);
5339 locLinkProgram = OGL_LOAD(locLinkProgram_t, glLinkProgram);
5340 locAttachShader = OGL_LOAD(locAttachShader_t, glAttachShader);
5341 locBindBuffer = OGL_LOAD(locBindBuffer_t, glBindBuffer);
5342 locBufferData = OGL_LOAD(locBufferData_t, glBufferData);
5343 locGenBuffers = OGL_LOAD(locGenBuffers_t, glGenBuffers);
5344 locVertexAttribPointer = OGL_LOAD(locVertexAttribPointer_t, glVertexAttribPointer);
5345 locEnableVertexAttribArray = OGL_LOAD(locEnableVertexAttribArray_t, glEnableVertexAttribArray);
5346 locUseProgram = OGL_LOAD(locUseProgram_t, glUseProgram);
5347 locGetShaderInfoLog = OGL_LOAD(locGetShaderInfoLog_t, glGetShaderInfoLog);
5348#if !defined(OLC_PLATFORM_EMSCRIPTEN)
5349 locBindVertexArray = OGL_LOAD(locBindVertexArray_t, glBindVertexArray);
5350 locGenVertexArrays = OGL_LOAD(locGenVertexArrays_t, glGenVertexArrays);
5352 locBindVertexArray = glBindVertexArrayOES;
5353 locGenVertexArrays = glGenVertexArraysOES;
5357 m_nFS = locCreateShader(0x8B30);
5358 const GLchar* strFS =
5359#if defined(__arm__) || defined(OLC_PLATFORM_EMSCRIPTEN)
5361 "precision mediump float;"
5363 "#version 330 core\n"
5365 "out vec4 pixel;\n""in vec2 oTex;\n"
5366 "in vec4 oCol;\n""uniform sampler2D sprTex;\n""void main(){pixel = texture(sprTex, oTex) * oCol;}";
5367 locShaderSource(m_nFS, 1, &strFS, NULL);
5368 locCompileShader(m_nFS);
5370 m_nVS = locCreateShader(0x8B31);
5371 const GLchar* strVS =
5372#if defined(__arm__) || defined(OLC_PLATFORM_EMSCRIPTEN)
5374 "precision mediump float;"
5376 "#version 330 core\n"
5378 "layout(location = 0) in vec3 aPos;\n""layout(location = 1) in vec2 aTex;\n"
5379 "layout(location = 2) in vec4 aCol;\n""out vec2 oTex;\n""out vec4 oCol;\n"
5380 "void main(){ float p = 1.0 / aPos.z; gl_Position = p * vec4(aPos.x, aPos.y, 0.0, 1.0); oTex = p * aTex; oCol = aCol;}";
5381 locShaderSource(m_nVS, 1, &strVS, NULL);
5382 locCompileShader(m_nVS);
5384 m_nQuadShader = locCreateProgram();
5385 locAttachShader(m_nQuadShader, m_nFS);
5386 locAttachShader(m_nQuadShader, m_nVS);
5387 locLinkProgram(m_nQuadShader);
5390 locGenBuffers(1, &m_vbQuad);
5391 locGenVertexArrays(1, &m_vaQuad);
5392 locBindVertexArray(m_vaQuad);
5393 locBindBuffer(0x8892, m_vbQuad);
5396 locBufferData(0x8892,
sizeof(locVertex) * OLC_MAX_VERTS, verts, 0x88E0);
5397 locVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
sizeof(locVertex), 0); locEnableVertexAttribArray(0);
5398 locVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
sizeof(locVertex), (
void*)(3 *
sizeof(
float))); locEnableVertexAttribArray(1);
5399 locVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE,
sizeof(locVertex), (
void*)(5 *
sizeof(
float))); locEnableVertexAttribArray(2);
5400 locBindBuffer(0x8892, 0);
5401 locBindVertexArray(0);
5404 rendBlankQuad.
Create(1, 1);
5412#if defined(OLC_PLATFORM_WINAPI)
5413 wglDeleteContext(glRenderContext);
5416#if defined(OLC_PLATFORM_X11)
5417 glXMakeCurrent(olc_Display, None, NULL);
5418 glXDestroyContext(olc_Display, glDeviceContext);
5421#if defined(OLC_PLATFORM_GLUT)
5422 glutDestroyWindow(glutGetWindow());
5425#if defined(OLC_PLATFORM_EMSCRIPTEN)
5426 eglMakeCurrent(olc_Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
5427 eglDestroyContext(olc_Display, olc_Context);
5428 eglDestroySurface(olc_Display, olc_Surface);
5429 eglTerminate(olc_Display);
5430 olc_Display = EGL_NO_DISPLAY;
5431 olc_Surface = EGL_NO_SURFACE;
5432 olc_Context = EGL_NO_CONTEXT;
5437 void DisplayFrame()
override
5439#if defined(OLC_PLATFORM_WINAPI)
5440 SwapBuffers(glDeviceContext);
5441 if (bSync) DwmFlush();
5444#if defined(OLC_PLATFORM_X11)
5445 X11::glXSwapBuffers(olc_Display, *olc_Window);
5448#if defined(OLC_PLATFORM_GLUT)
5452#if defined(OLC_PLATFORM_EMSCRIPTEN)
5453 eglSwapBuffers(olc_Display, olc_Surface);
5457 void PrepareDrawing()
override
5460 nDecalMode = DecalMode::NORMAL;
5461 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
5462 locUseProgram(m_nQuadShader);
5463 locBindVertexArray(m_vaQuad);
5465#if defined(OLC_PLATFORM_EMSCRIPTEN)
5466 locVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
sizeof(locVertex), 0); locEnableVertexAttribArray(0);
5467 locVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
sizeof(locVertex), (
void*)(3 *
sizeof(
float))); locEnableVertexAttribArray(1);
5468 locVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE,
sizeof(locVertex), (
void*)(5 *
sizeof(
float))); locEnableVertexAttribArray(2);
5474 if (mode != nDecalMode)
5492 locBindBuffer(0x8892, m_vbQuad);
5493 locVertex verts[4] = {
5494 {{-1.0f, -1.0f, 1.0}, {0.0f * scale.
x + offset.
x, 1.0f * scale.
y + offset.
y}, tint},
5495 {{+1.0f, -1.0f, 1.0}, {1.0f * scale.
x + offset.
x, 1.0f * scale.
y + offset.
y}, tint},
5496 {{-1.0f, +1.0f, 1.0}, {0.0f * scale.
x + offset.
x, 0.0f * scale.
y + offset.
y}, tint},
5497 {{+1.0f, +1.0f, 1.0}, {1.0f * scale.
x + offset.
x, 0.0f * scale.
y + offset.
y}, tint},
5500 locBufferData(0x8892,
sizeof(locVertex) * 4, verts, 0x88E0);
5501 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5506 SetDecalMode(decal.
mode);
5507 if (decal.
decal ==
nullptr)
5508 glBindTexture(GL_TEXTURE_2D, rendBlankQuad.
Decal()->
id);
5510 glBindTexture(GL_TEXTURE_2D, decal.
decal->
id);
5512 locBindBuffer(0x8892, m_vbQuad);
5514 for (uint32_t i = 0; i < decal.
points; i++)
5515 pVertexMem[i] = { { decal.
pos[i].x, decal.
pos[i].y, decal.
w[i] }, { decal.
uv[i].x, decal.
uv[i].y }, decal.
tint[i] };
5517 locBufferData(0x8892,
sizeof(locVertex) * decal.
points, pVertexMem, 0x88E0);
5519 if (nDecalMode == DecalMode::WIREFRAME)
5520 glDrawArrays(GL_LINE_LOOP, 0, decal.
points);
5524 glDrawArrays(GL_TRIANGLE_FAN, 0, decal.
points);
5526 glDrawArrays(GL_TRIANGLE_STRIP, 0, decal.
points);
5528 glDrawArrays(GL_TRIANGLES, 0, decal.
points);
5532 uint32_t CreateTexture(
const uint32_t width,
const uint32_t height,
const bool filtered,
const bool clamp)
override
5537 glGenTextures(1, &
id);
5538 glBindTexture(GL_TEXTURE_2D,
id);
5542 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5543 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5547 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5548 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5553 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
5554 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
5558 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
5559 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
5561#if !defined(OLC_PLATFORM_EMSCRIPTEN)
5562 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
5567 uint32_t DeleteTexture(
const uint32_t
id)
override
5569 glDeleteTextures(1, &
id);
5573 void UpdateTexture(uint32_t
id,
olc::Sprite* spr)
override
5576 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spr->
width, spr->
height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spr->
GetData());
5579 void ReadTexture(uint32_t
id,
olc::Sprite* spr)
override
5581 glReadPixels(0, 0, spr->
width, spr->
height, GL_RGBA, GL_UNSIGNED_BYTE, spr->
GetData());
5584 void ApplyTexture(uint32_t
id)
override
5586 glBindTexture(GL_TEXTURE_2D,
id);
5589 void ClearBuffer(
olc::Pixel p,
bool bDepth)
override
5591 glClearColor(
float(p.
r) / 255.0f,
float(p.
g) / 255.0f,
float(p.
b) / 255.0f,
float(p.
a) / 255.0f);
5592 glClear(GL_COLOR_BUFFER_BIT);
5593 if (bDepth) glClear(GL_DEPTH_BUFFER_BIT);
5598 glViewport(pos.
x, pos.
y, size.
x, size.
y);
5612#pragma region image_gdi
5616#if defined(OLC_IMAGE_GDI)
5618#define min(a, b) ((a < b) ? a : b)
5619#define max(a, b) ((a > b) ? a : b)
5622#if defined(__MINGW32__)
5623 #include <gdiplus/gdiplusinit.h>
5625 #include <gdiplusinit.h>
5631#if !defined(__MINGW32__)
5632 #pragma comment(lib, "gdiplus.lib")
5633 #pragma comment(lib, "Shlwapi.lib")
5640 static class GDIPlusStartup
5645 Gdiplus::GdiplusStartupInput startupInput;
5646 GdiplusStartup(&token, &startupInput, NULL);
5654 Gdiplus::GdiplusShutdown(token);
5661 std::wstring ConvertS2W(std::string s)
5664 wchar_t* buffer =
new wchar_t[s.length() + 1];
5665 mbstowcs(buffer, s.c_str(), s.length());
5666 buffer[s.length()] =
L'\0';
5668 int count = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
5669 wchar_t* buffer =
new wchar_t[count];
5670 MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer, count);
5672 std::wstring w(buffer);
5678 ImageLoader_GDIPlus() : ImageLoader()
5688 Gdiplus::Bitmap* bmp =
nullptr;
5689 if (pack !=
nullptr)
5693 bmp = Gdiplus::Bitmap::FromStream(SHCreateMemStream((BYTE*)rb.vMemory.data(), UINT(rb.vMemory.size())));
5701 bmp = Gdiplus::Bitmap::FromFile(ConvertS2W(sImageFile).c_str());
5705 spr->
width = bmp->GetWidth();
5706 spr->
height = bmp->GetHeight();
5710 for (
int y = 0; y < spr->
height; y++)
5711 for (
int x = 0; x < spr->
width; x++)
5714 bmp->GetPixel(x, y, &c);
5715 spr->
SetPixel(x, y,
olc::Pixel(c.GetRed(), c.GetGreen(), c.GetBlue(), c.GetAlpha()));
5733#pragma region image_libpng
5737#if defined(OLC_IMAGE_LIBPNG)
5741 void pngReadStream(png_structp pngPtr, png_bytep data, png_size_t length)
5743 png_voidp a = png_get_io_ptr(pngPtr);
5744 ((std::istream*)a)->read((
char*)data, length);
5750 ImageLoader_LibPNG() : ImageLoader()
5768 auto loadPNG = [&]()
5770 png_read_info(png, info);
5771 png_byte color_type;
5773 png_bytep* row_pointers;
5774 spr->
width = png_get_image_width(png, info);
5775 spr->
height = png_get_image_height(png, info);
5776 color_type = png_get_color_type(png, info);
5777 bit_depth = png_get_bit_depth(png, info);
5778 if (bit_depth == 16) png_set_strip_16(png);
5779 if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
5780 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png);
5781 if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png);
5782 if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE)
5783 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
5784 if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
5785 png_set_gray_to_rgb(png);
5786 png_read_update_info(png, info);
5787 row_pointers = (png_bytep*)malloc(
sizeof(png_bytep) * spr->
height);
5788 for (
int y = 0; y < spr->
height; y++) {
5789 row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
5791 png_read_image(png, row_pointers);
5796 for (
int y = 0; y < spr->
height; y++)
5798 png_bytep row = row_pointers[y];
5799 for (
int x = 0; x < spr->
width; x++)
5801 png_bytep px = &(row[x * 4]);
5802 spr->
SetPixel(x, y, Pixel(px[0], px[1], px[2], px[3]));
5806 for (
int y = 0; y < spr->
height; y++)
5807 free(row_pointers[y]);
5809 png_destroy_read_struct(&png, &info,
nullptr);
5812 png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
5813 if (!png)
goto fail_load;
5815 info = png_create_info_struct(png);
5816 if (!info)
goto fail_load;
5818 if (setjmp(png_jmpbuf(png)))
goto fail_load;
5820 if (pack ==
nullptr)
5822 FILE* f = fopen(sImageFile.c_str(),
"rb");
5824 png_init_io(png, f);
5831 std::istream is(&rb);
5832 png_set_read_fn(png, (png_voidp)&is, pngReadStream);
5862#pragma region platform_windows
5866#if defined(OLC_PLATFORM_WINAPI)
5868#if defined(_WIN32) && !defined(__MINGW32__)
5869 #pragma comment(lib, "user32.lib")
5870 #pragma comment(lib, "gdi32.lib")
5871 #pragma comment(lib, "opengl32.lib")
5879 HWND olc_hWnd =
nullptr;
5880 std::wstring wsAppName;
5884 std::wstring ConvertS2W(std::string s)
5887 wchar_t* buffer =
new wchar_t[s.length() + 1];
5888 mbstowcs(buffer, s.c_str(), s.length());
5889 buffer[s.length()] =
L'\0';
5891 int count = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
5892 wchar_t* buffer =
new wchar_t[count];
5893 MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer, count);
5895 std::wstring w(buffer);
5909 renderer->DestroyDevice();
5910 PostMessage(olc_hWnd, WM_DESTROY, 0, 0);
5916 if (renderer->CreateDevice({ olc_hWnd }, bFullScreen, bEnableVSYNC) ==
olc::rcode::OK)
5918 renderer->UpdateViewport(vViewPos, vViewSize);
5928 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
5929 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
5930 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
5931 wc.hInstance = GetModuleHandle(
nullptr);
5932 wc.lpfnWndProc = olc_WindowEvent;
5935 wc.lpszMenuName =
nullptr;
5936 wc.hbrBackground =
nullptr;
5937 wc.lpszClassName =
olcT(
"OLC_PIXEL_GAME_ENGINE");
5940 vWinPos = vWindowPos;
5941 vWinSize = vWindowSize;
5944 DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
5945 DWORD dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_THICKFRAME;
5953 dwStyle = WS_VISIBLE | WS_POPUP;
5954 HMONITOR hmon = MonitorFromWindow(olc_hWnd, MONITOR_DEFAULTTONEAREST);
5955 MONITORINFO mi = {
sizeof(mi) };
5957 vWindowSize = { mi.rcMonitor.right, mi.rcMonitor.bottom };
5963 RECT rWndRect = { 0, 0, vWindowSize.
x, vWindowSize.
y };
5964 AdjustWindowRectEx(&rWndRect, dwStyle, FALSE, dwExStyle);
5965 int width = rWndRect.right - rWndRect.left;
5966 int height = rWndRect.bottom - rWndRect.top;
5968 olc_hWnd = CreateWindowEx(dwExStyle,
olcT(
"OLC_PIXEL_GAME_ENGINE"),
olcT(
""), dwStyle,
5969 vTopLeft.
x, vTopLeft.
y, width, height, NULL, NULL, GetModuleHandle(
nullptr),
this);
5971 DragAcceptFiles(olc_hWnd,
true);
5974 mapKeys[0x00] = Key::NONE;
5975 mapKeys[0x41] = Key::A; mapKeys[0x42] = Key::B; mapKeys[0x43] = Key::C; mapKeys[0x44] = Key::D; mapKeys[0x45] = Key::E;
5976 mapKeys[0x46] = Key::F; mapKeys[0x47] = Key::G; mapKeys[0x48] = Key::H; mapKeys[0x49] = Key::I; mapKeys[0x4A] = Key::J;
5977 mapKeys[0x4B] = Key::K; mapKeys[0x4C] = Key::L; mapKeys[0x4D] = Key::M; mapKeys[0x4E] = Key::N; mapKeys[0x4F] = Key::O;
5978 mapKeys[0x50] = Key::P; mapKeys[0x51] = Key::Q; mapKeys[0x52] = Key::R; mapKeys[0x53] = Key::S; mapKeys[0x54] = Key::T;
5979 mapKeys[0x55] = Key::U; mapKeys[0x56] = Key::V; mapKeys[0x57] = Key::W; mapKeys[0x58] = Key::X; mapKeys[0x59] = Key::Y;
5980 mapKeys[0x5A] = Key::Z;
5982 mapKeys[VK_F1] = Key::F1; mapKeys[VK_F2] = Key::F2; mapKeys[VK_F3] = Key::F3; mapKeys[VK_F4] = Key::F4;
5983 mapKeys[VK_F5] = Key::F5; mapKeys[VK_F6] = Key::F6; mapKeys[VK_F7] = Key::F7; mapKeys[VK_F8] = Key::F8;
5984 mapKeys[VK_F9] = Key::F9; mapKeys[VK_F10] = Key::F10; mapKeys[VK_F11] = Key::F11; mapKeys[VK_F12] = Key::F12;
5986 mapKeys[VK_DOWN] = Key::DOWN; mapKeys[VK_LEFT] = Key::LEFT; mapKeys[VK_RIGHT] = Key::RIGHT; mapKeys[VK_UP] = Key::UP;
5989 mapKeys[VK_BACK] = Key::BACK; mapKeys[VK_ESCAPE] = Key::ESCAPE; mapKeys[VK_RETURN] = Key::ENTER; mapKeys[VK_PAUSE] = Key::PAUSE;
5990 mapKeys[VK_SCROLL] = Key::SCROLL; mapKeys[VK_TAB] = Key::TAB; mapKeys[VK_DELETE] = Key::DEL; mapKeys[VK_HOME] = Key::HOME;
5991 mapKeys[VK_END] = Key::END; mapKeys[VK_PRIOR] = Key::PGUP; mapKeys[VK_NEXT] = Key::PGDN; mapKeys[VK_INSERT] = Key::INS;
5992 mapKeys[VK_SHIFT] = Key::SHIFT; mapKeys[VK_CONTROL] = Key::CTRL;
5993 mapKeys[VK_SPACE] = Key::SPACE;
5995 mapKeys[0x30] = Key::K0; mapKeys[0x31] = Key::K1; mapKeys[0x32] = Key::K2; mapKeys[0x33] = Key::K3; mapKeys[0x34] = Key::K4;
5996 mapKeys[0x35] = Key::K5; mapKeys[0x36] = Key::K6; mapKeys[0x37] = Key::K7; mapKeys[0x38] = Key::K8; mapKeys[0x39] = Key::K9;
5998 mapKeys[VK_NUMPAD0] = Key::NP0; mapKeys[VK_NUMPAD1] = Key::NP1; mapKeys[VK_NUMPAD2] = Key::NP2; mapKeys[VK_NUMPAD3] = Key::NP3; mapKeys[VK_NUMPAD4] = Key::NP4;
5999 mapKeys[VK_NUMPAD5] = Key::NP5; mapKeys[VK_NUMPAD6] = Key::NP6; mapKeys[VK_NUMPAD7] = Key::NP7; mapKeys[VK_NUMPAD8] = Key::NP8; mapKeys[VK_NUMPAD9] = Key::NP9;
6000 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;
6003 mapKeys[VK_OEM_1] = Key::OEM_1;
6004 mapKeys[VK_OEM_2] = Key::OEM_2;
6005 mapKeys[VK_OEM_3] = Key::OEM_3;
6006 mapKeys[VK_OEM_4] = Key::OEM_4;
6007 mapKeys[VK_OEM_5] = Key::OEM_5;
6008 mapKeys[VK_OEM_6] = Key::OEM_6;
6009 mapKeys[VK_OEM_7] = Key::OEM_7;
6010 mapKeys[VK_OEM_8] = Key::OEM_8;
6011 mapKeys[VK_OEM_PLUS] = Key::EQUALS;
6012 mapKeys[VK_OEM_COMMA] = Key::COMMA;
6013 mapKeys[VK_OEM_MINUS] = Key::MINUS;
6014 mapKeys[VK_OEM_PERIOD] = Key::PERIOD;
6015 mapKeys[VK_CAPITAL] = Key::CAPS_LOCK;
6019 virtual olc::rcode SetWindowTitle(
const std::string& s)
override
6022 SetWindowText(olc_hWnd, ConvertS2W(s).c_str());
6024 SetWindowText(olc_hWnd, s.c_str());
6029 olc::rcode ShowWindowFrame(
const bool bShowFrame)
6032 DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
6033 DWORD dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_THICKFRAME;
6035 RECT rWndRect, rWndRectNow;
6036 GetWindowRect(olc_hWnd, &rWndRectNow);
6040 LONG_PTR lp = GetWindowLongPtr(olc_hWnd, GWL_STYLE);
6041 SetWindowLongPtr(olc_hWnd, GWL_STYLE, lp & ~(WS_CAPTION | WS_SYSMENU | WS_POPUPWINDOW | WS_THICKFRAME));
6042 lp = GetWindowLongPtr(olc_hWnd, GWL_EXSTYLE);
6043 SetWindowLongPtr(olc_hWnd, GWL_EXSTYLE, lp & ~(WS_EX_WINDOWEDGE));
6044 dwExStyle = WS_EX_APPWINDOW;
6049 LONG_PTR lp = GetWindowLongPtr(olc_hWnd, GWL_STYLE);
6050 SetWindowLongPtr(olc_hWnd, GWL_STYLE, lp | (WS_CAPTION | WS_SYSMENU | WS_POPUPWINDOW|WS_THICKFRAME));
6051 lp = GetWindowLongPtr(olc_hWnd, GWL_EXSTYLE);
6052 SetWindowLongPtr(olc_hWnd, GWL_EXSTYLE, lp | (WS_EX_WINDOWEDGE));
6056 rWndRectNow.right = rWndRectNow.left + vWinSize.
x;
6057 rWndRectNow.bottom = rWndRectNow.top + vWinSize.
y;
6058 rWndRect = rWndRectNow;
6059 AdjustWindowRectEx(&rWndRect, dwStyle, FALSE, dwExStyle);
6060 int width = rWndRect.right - rWndRect.left;
6061 int height = rWndRect.bottom - rWndRect.top;
6062 vWinPos = { rWndRect.left, rWndRect.top };
6063 vWinSize = { width, height };
6064 SetWindowPos(olc_hWnd, NULL, rWndRectNow.left, rWndRectNow.top, width, height, SWP_SHOWWINDOW);
6072 vWinPos = vWindowPos;
6073 vWinSize = vWindowSize;
6075 rWndRect.left = vWinPos.
x;
6076 rWndRect.top = vWinPos.
y;
6077 rWndRect.right = rWndRect.left + vWinSize.
x;
6078 rWndRect.bottom = rWndRect.top + vWinSize.
y;
6079 rWndRect = rWndRect;
6080 DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
6081 DWORD dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_THICKFRAME;
6082 AdjustWindowRectEx(&rWndRect, dwStyle, FALSE, dwExStyle);
6083 int width = rWndRect.right - rWndRect.left;
6084 int height = rWndRect.bottom - rWndRect.top;
6085 vWinPos = { rWndRect.left, rWndRect.top };
6086 vWinSize = { width, height };
6087 SetWindowPos(olc_hWnd, NULL, vWinPos.
x, vWinPos.
y, width, height, SWP_SHOWWINDOW);
6091 virtual olc::rcode StartSystemEventLoop()
override
6094 while (GetMessage(&msg, NULL, 0, 0) > 0)
6096 TranslateMessage(&msg);
6097 DispatchMessage(&msg);
6105 static LRESULT CALLBACK olc_WindowEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
6112 uint16_t x = lParam & 0xFFFF; uint16_t y = (lParam >> 16) & 0xFFFF;
6113 int16_t ix = *(int16_t*)&x; int16_t iy = *(int16_t*)&y;
6114 ptrPGE->olc_UpdateMouse(ix, iy);
6117 case WM_MOVE: vWinPos =
olc::vi2d(lParam & 0xFFFF, (lParam >> 16) & 0xFFFF); ptrPGE->olc_UpdateWindowPos(lParam & 0xFFFF, (lParam >> 16) & 0xFFFF);
return 0;
6118 case WM_SIZE: vWinSize =
olc::vi2d(lParam & 0xFFFF, (lParam >> 16) & 0xFFFF); ptrPGE->olc_UpdateWindowSize(lParam & 0xFFFF, (lParam >> 16) & 0xFFFF);
return 0;
6119 case WM_MOUSEWHEEL: ptrPGE->olc_UpdateMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam));
return 0;
6120 case WM_MOUSELEAVE: ptrPGE->olc_UpdateMouseFocus(
false);
return 0;
6121 case WM_SETFOCUS: ptrPGE->olc_UpdateKeyFocus(
true);
return 0;
6122 case WM_KILLFOCUS: ptrPGE->olc_UpdateKeyFocus(
false);
return 0;
6123 case WM_KEYDOWN: ptrPGE->olc_UpdateKeyState(mapKeys[wParam],
true);
return 0;
6124 case WM_KEYUP: ptrPGE->olc_UpdateKeyState(mapKeys[wParam],
false);
return 0;
6125 case WM_SYSKEYDOWN: ptrPGE->olc_UpdateKeyState(mapKeys[wParam],
true);
return 0;
6126 case WM_SYSKEYUP: ptrPGE->olc_UpdateKeyState(mapKeys[wParam],
false);
return 0;
6127 case WM_LBUTTONDOWN:ptrPGE->olc_UpdateMouseState(0,
true);
return 0;
6128 case WM_LBUTTONUP: ptrPGE->olc_UpdateMouseState(0,
false);
return 0;
6129 case WM_RBUTTONDOWN:ptrPGE->olc_UpdateMouseState(1,
true);
return 0;
6130 case WM_RBUTTONUP: ptrPGE->olc_UpdateMouseState(1,
false);
return 0;
6131 case WM_MBUTTONDOWN:ptrPGE->olc_UpdateMouseState(2,
true);
return 0;
6132 case WM_MBUTTONUP: ptrPGE->olc_UpdateMouseState(2,
false);
return 0;
6136 HDROP drop = (HDROP)wParam;
6138 uint32_t nFiles = DragQueryFile(drop, 0xFFFFFFFF,
nullptr, 0);
6139 std::vector<std::string> vFiles;
6140 for (uint32_t i = 0; i < nFiles; i++)
6142 TCHAR dfbuffer[256]{};
6143 uint32_t len = DragQueryFile(drop, i,
nullptr, 0);
6144 DragQueryFile(drop, i, dfbuffer, 256);
6147 char* buffer =
new char[len + 1];
6148 wcstombs(buffer, dfbuffer, len);
6151 int count = WideCharToMultiByte(CP_UTF8, 0, dfbuffer, -1, NULL, 0, NULL, NULL);
6152 char* buffer =
new char[count];
6153 WideCharToMultiByte(CP_UTF8, 0, dfbuffer, -1, buffer, count, NULL, NULL);
6155 vFiles.push_back(std::string(buffer));
6158 vFiles.push_back(std::string(dfbuffer));
6163 POINT p; DragQueryPoint(drop, &p);
6164 ptrPGE->olc_DropFiles(p.x, p.y, vFiles);
6171 case WM_CLOSE: ptrPGE->olc_Terminate();
return 0;
6172 case WM_DESTROY: PostQuitMessage(0); DestroyWindow(hWnd);
return 0;
6174 return DefWindowProc(hWnd, uMsg, wParam, lParam);
6184#pragma region platform_linux
6188#if defined(OLC_PLATFORM_X11)
6194 X11::Display* olc_Display =
nullptr;
6195 X11::Window olc_WindowRoot;
6196 X11::Window olc_Window;
6197 X11::XVisualInfo* olc_VisualInfo;
6198 X11::Colormap olc_ColourMap;
6199 X11::XSetWindowAttributes olc_SetWindowAttribs;
6202 virtual olc::rcode ApplicationStartUp()
override
6207 virtual olc::rcode ApplicationCleanUp()
override
6209 XDestroyWindow(olc_Display, olc_Window);
6220 renderer->DestroyDevice();
6226 if (renderer->CreateDevice({ olc_Display, &olc_Window, olc_VisualInfo }, bFullScreen, bEnableVSYNC) ==
olc::rcode::OK)
6228 renderer->UpdateViewport(vViewPos, vViewSize);
6237 using namespace X11;
6241 olc_Display = XOpenDisplay(NULL);
6242 olc_WindowRoot = DefaultRootWindow(olc_Display);
6245 GLint olc_GLAttribs[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
6246 olc_VisualInfo = glXChooseVisual(olc_Display, 0, olc_GLAttribs);
6247 olc_ColourMap = XCreateColormap(olc_Display, olc_WindowRoot, olc_VisualInfo->visual, AllocNone);
6248 olc_SetWindowAttribs.colormap = olc_ColourMap;
6251 olc_SetWindowAttribs.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
6252 ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask | StructureNotifyMask;
6255 olc_Window = XCreateWindow(olc_Display, olc_WindowRoot, vWindowPos.
x, vWindowPos.
y,
6256 vWindowSize.
x, vWindowSize.
y,
6257 0, olc_VisualInfo->depth, InputOutput, olc_VisualInfo->visual,
6258 CWColormap | CWEventMask, &olc_SetWindowAttribs);
6260 Atom wmDelete = XInternAtom(olc_Display,
"WM_DELETE_WINDOW",
true);
6261 XSetWMProtocols(olc_Display, olc_Window, &wmDelete, 1);
6263 XMapWindow(olc_Display, olc_Window);
6264 XStoreName(olc_Display, olc_Window,
"OneLoneCoder.com - Pixel Game Engine");
6270 wm_state = XInternAtom(olc_Display,
"_NET_WM_STATE", False);
6271 fullscreen = XInternAtom(olc_Display,
"_NET_WM_STATE_FULLSCREEN", False);
6273 xev.type = ClientMessage;
6274 xev.xclient.window = olc_Window;
6275 xev.xclient.message_type = wm_state;
6276 xev.xclient.format = 32;
6277 xev.xclient.data.l[0] = (bFullScreen ? 1 : 0);
6278 xev.xclient.data.l[1] = fullscreen;
6279 xev.xclient.data.l[2] = 0;
6280 xev.xclient.data.l[3] = 0;
6281 XMapWindow(olc_Display, olc_Window);
6282 XSendEvent(olc_Display, DefaultRootWindow(olc_Display), False,
6283 SubstructureRedirectMask | SubstructureNotifyMask, &xev);
6284 XFlush(olc_Display);
6285 XWindowAttributes gwa;
6286 XGetWindowAttributes(olc_Display, olc_Window, &gwa);
6287 vWindowSize.
x = gwa.width;
6288 vWindowSize.
y = gwa.height;
6292 mapKeys[0x00] = Key::NONE;
6293 mapKeys[0x61] = Key::A; mapKeys[0x62] = Key::B; mapKeys[0x63] = Key::C; mapKeys[0x64] = Key::D; mapKeys[0x65] = Key::E;
6294 mapKeys[0x66] = Key::F; mapKeys[0x67] = Key::G; mapKeys[0x68] = Key::H; mapKeys[0x69] = Key::I; mapKeys[0x6A] = Key::J;
6295 mapKeys[0x6B] = Key::K; mapKeys[0x6C] = Key::L; mapKeys[0x6D] = Key::M; mapKeys[0x6E] = Key::N; mapKeys[0x6F] = Key::O;
6296 mapKeys[0x70] = Key::P; mapKeys[0x71] = Key::Q; mapKeys[0x72] = Key::R; mapKeys[0x73] = Key::S; mapKeys[0x74] = Key::T;
6297 mapKeys[0x75] = Key::U; mapKeys[0x76] = Key::V; mapKeys[0x77] = Key::W; mapKeys[0x78] = Key::X; mapKeys[0x79] = Key::Y;
6298 mapKeys[0x7A] = Key::Z;
6300 mapKeys[XK_F1] = Key::F1; mapKeys[XK_F2] = Key::F2; mapKeys[XK_F3] = Key::F3; mapKeys[XK_F4] = Key::F4;
6301 mapKeys[XK_F5] = Key::F5; mapKeys[XK_F6] = Key::F6; mapKeys[XK_F7] = Key::F7; mapKeys[XK_F8] = Key::F8;
6302 mapKeys[XK_F9] = Key::F9; mapKeys[XK_F10] = Key::F10; mapKeys[XK_F11] = Key::F11; mapKeys[XK_F12] = Key::F12;
6304 mapKeys[XK_Down] = Key::DOWN; mapKeys[XK_Left] = Key::LEFT; mapKeys[XK_Right] = Key::RIGHT; mapKeys[XK_Up] = Key::UP;
6305 mapKeys[XK_KP_Enter] = Key::ENTER; mapKeys[XK_Return] = Key::ENTER;
6307 mapKeys[XK_BackSpace] = Key::BACK; mapKeys[XK_Escape] = Key::ESCAPE; mapKeys[XK_Linefeed] = Key::ENTER; mapKeys[XK_Pause] = Key::PAUSE;
6308 mapKeys[XK_Scroll_Lock] = Key::SCROLL; mapKeys[XK_Tab] = Key::TAB; mapKeys[XK_Delete] = Key::DEL; mapKeys[XK_Home] = Key::HOME;
6309 mapKeys[XK_End] = Key::END; mapKeys[XK_Page_Up] = Key::PGUP; mapKeys[XK_Page_Down] = Key::PGDN; mapKeys[XK_Insert] = Key::INS;
6310 mapKeys[XK_Shift_L] = Key::SHIFT; mapKeys[XK_Shift_R] = Key::SHIFT; mapKeys[XK_Control_L] = Key::CTRL; mapKeys[XK_Control_R] = Key::CTRL;
6311 mapKeys[XK_space] = Key::SPACE; mapKeys[XK_period] = Key::PERIOD;
6313 mapKeys[XK_0] = Key::K0; mapKeys[XK_1] = Key::K1; mapKeys[XK_2] = Key::K2; mapKeys[XK_3] = Key::K3; mapKeys[XK_4] = Key::K4;
6314 mapKeys[XK_5] = Key::K5; mapKeys[XK_6] = Key::K6; mapKeys[XK_7] = Key::K7; mapKeys[XK_8] = Key::K8; mapKeys[XK_9] = Key::K9;
6316 mapKeys[XK_KP_0] = Key::NP0; mapKeys[XK_KP_1] = Key::NP1; mapKeys[XK_KP_2] = Key::NP2; mapKeys[XK_KP_3] = Key::NP3; mapKeys[XK_KP_4] = Key::NP4;
6317 mapKeys[XK_KP_5] = Key::NP5; mapKeys[XK_KP_6] = Key::NP6; mapKeys[XK_KP_7] = Key::NP7; mapKeys[XK_KP_8] = Key::NP8; mapKeys[XK_KP_9] = Key::NP9;
6318 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;
6321 mapKeys[XK_semicolon] = Key::OEM_1;
6322 mapKeys[XK_slash] = Key::OEM_2;
6323 mapKeys[XK_asciitilde] = Key::OEM_3;
6324 mapKeys[XK_bracketleft] = Key::OEM_4;
6325 mapKeys[XK_backslash] = Key::OEM_5;
6326 mapKeys[XK_bracketright] = Key::OEM_6;
6327 mapKeys[XK_apostrophe] = Key::OEM_7;
6328 mapKeys[XK_numbersign] = Key::OEM_8;
6329 mapKeys[XK_equal] = Key::EQUALS;
6330 mapKeys[XK_comma] = Key::COMMA;
6331 mapKeys[XK_minus] = Key::MINUS;
6333 mapKeys[XK_Caps_Lock] = Key::CAPS_LOCK;
6338 virtual olc::rcode SetWindowTitle(
const std::string& s)
override
6340 X11::XStoreName(olc_Display, olc_Window, s.c_str());
6349 virtual olc::rcode ShowWindowFrame(
const bool bShowFrame =
true)
override
6355 virtual olc::rcode StartSystemEventLoop()
override
6360 virtual olc::rcode HandleSystemEvent()
override
6362 using namespace X11;
6367 while (XPending(olc_Display))
6369 XNextEvent(olc_Display, &xev);
6370 if (xev.type == Expose)
6372 XWindowAttributes gwa;
6373 XGetWindowAttributes(olc_Display, olc_Window, &gwa);
6374 ptrPGE->olc_UpdateWindowSize(gwa.width, gwa.height);
6376 else if (xev.type == ConfigureNotify)
6378 XConfigureEvent xce = xev.xconfigure;
6379 ptrPGE->olc_UpdateWindowSize(xce.width, xce.height);
6381 else if (xev.type == KeyPress)
6383 KeySym sym = XLookupKeysym(&xev.xkey, 0);
6384 ptrPGE->olc_UpdateKeyState(mapKeys[sym],
true);
6385 XKeyEvent* e = (XKeyEvent*)&xev;
6386 XLookupString(e, NULL, 0, &sym, NULL);
6387 ptrPGE->olc_UpdateKeyState(mapKeys[sym],
true);
6389 else if (xev.type == KeyRelease)
6391 KeySym sym = XLookupKeysym(&xev.xkey, 0);
6392 ptrPGE->olc_UpdateKeyState(mapKeys[sym],
false);
6393 XKeyEvent* e = (XKeyEvent*)&xev;
6394 XLookupString(e, NULL, 0, &sym, NULL);
6395 ptrPGE->olc_UpdateKeyState(mapKeys[sym],
false);
6397 else if (xev.type == ButtonPress)
6399 switch (xev.xbutton.button)
6401 case 1: ptrPGE->olc_UpdateMouseState(0,
true);
break;
6402 case 2: ptrPGE->olc_UpdateMouseState(2,
true);
break;
6403 case 3: ptrPGE->olc_UpdateMouseState(1,
true);
break;
6404 case 4: ptrPGE->olc_UpdateMouseWheel(120);
break;
6405 case 5: ptrPGE->olc_UpdateMouseWheel(-120);
break;
6409 else if (xev.type == ButtonRelease)
6411 switch (xev.xbutton.button)
6413 case 1: ptrPGE->olc_UpdateMouseState(0,
false);
break;
6414 case 2: ptrPGE->olc_UpdateMouseState(2,
false);
break;
6415 case 3: ptrPGE->olc_UpdateMouseState(1,
false);
break;
6419 else if (xev.type == MotionNotify)
6421 ptrPGE->olc_UpdateMouse(xev.xmotion.x, xev.xmotion.y);
6423 else if (xev.type == FocusIn)
6425 ptrPGE->olc_UpdateKeyFocus(
true);
6427 else if (xev.type == FocusOut)
6429 ptrPGE->olc_UpdateKeyFocus(
false);
6431 else if (xev.type == ClientMessage)
6433 ptrPGE->olc_Terminate();
6446#pragma region platform_glut
6457#if defined(OLC_PLATFORM_GLUT)
6463 static std::atomic<bool>* bActiveRef;
6470 virtual olc::rcode ShowWindowFrame(
const bool bShowFrame =
true)
override
6476 virtual olc::rcode ApplicationStartUp()
override {
6480 virtual olc::rcode ApplicationCleanUp()
override
6492 renderer->DestroyDevice();
6498 if (renderer->CreateDevice({}, bFullScreen, bEnableVSYNC) ==
olc::rcode::OK)
6500 renderer->UpdateViewport(vViewPos, vViewSize);
6507 static void ExitMainLoop() {
6508 if (!ptrPGE->OnUserDestroy()) {
6512 platform->ThreadCleanUp();
6513 platform->ApplicationCleanUp();
6517#if defined(__APPLE__)
6518 static void scrollWheelUpdate(
id selff,
SEL _sel,
id theEvent) {
6519 static const SEL deltaYSel = sel_registerName(
"deltaY");
6521#if defined(__aarch64__)
6522 double deltaY = ((double (*)(id, SEL))objc_msgSend)(theEvent, deltaYSel);
6524 double deltaY = ((double (*)(id, SEL))objc_msgSend_fpret)(theEvent, deltaYSel);
6527 for (
int i = 0; i < abs(deltaY); i++) {
6529 ptrPGE->olc_UpdateMouseWheel(-1);
6531 else if (deltaY < 0) {
6532 ptrPGE->olc_UpdateMouseWheel(1);
6537 static void ThreadFunct() {
6538#if defined(__APPLE__)
6539 static bool hasEnabledCocoa =
false;
6540 if (!hasEnabledCocoa) {
6542 Class NSApplicationClass = objc_getClass(
"NSApplication");
6545 SEL sharedApplicationSel = sel_registerName(
"sharedApplication");
6546 id NSApp = ((id(*)(Class, SEL))objc_msgSend)(NSApplicationClass, sharedApplicationSel);
6548 SEL mainWindowSel = sel_registerName(
"mainWindow");
6549 id window = ((id(*)(id, SEL))objc_msgSend)(NSApp, mainWindowSel);
6552 SEL setStyleMaskSel = sel_registerName(
"setStyleMask:");
6553 ((void (*)(id, SEL, NSUInteger))objc_msgSend)(window, setStyleMaskSel, 7);
6555 hasEnabledCocoa =
true;
6562 glutPostRedisplay();
6565 static void DrawFunct() {
6566 ptrPGE->olc_CoreUpdate();
6571#if defined(__APPLE__)
6572 Class GLUTViewClass = objc_getClass(
"GLUTView");
6574 SEL scrollWheelSel = sel_registerName(
"scrollWheel:");
6575 bool resultAddMethod = class_addMethod(GLUTViewClass, scrollWheelSel, (IMP)scrollWheelUpdate,
"v@:@");
6576 assert(resultAddMethod);
6579 renderer->PrepareDevice();
6583 vWindowSize.
x = glutGet(GLUT_SCREEN_WIDTH);
6584 vWindowSize.
y = glutGet(GLUT_SCREEN_HEIGHT);
6589 if (vWindowSize.
x > glutGet(GLUT_SCREEN_WIDTH) || vWindowSize.
y > glutGet(GLUT_SCREEN_HEIGHT))
6591 perror(
"ERROR: The specified window dimensions do not fit on your screen\n");
6594 glutReshapeWindow(vWindowSize.
x, vWindowSize.
y - 1);
6598 mapKeys[0x00] = Key::NONE;
6599 mapKeys[
'A'] = Key::A; mapKeys[
'B'] = Key::B; mapKeys[
'C'] = Key::C; mapKeys[
'D'] = Key::D; mapKeys[
'E'] = Key::E;
6600 mapKeys[
'F'] = Key::F; mapKeys[
'G'] = Key::G; mapKeys[
'H'] = Key::H; mapKeys[
'I'] = Key::I; mapKeys[
'J'] = Key::J;
6601 mapKeys[
'K'] = Key::K; mapKeys[
'L'] = Key::L; mapKeys[
'M'] = Key::M; mapKeys[
'N'] = Key::N; mapKeys[
'O'] = Key::O;
6602 mapKeys[
'P'] = Key::P; mapKeys[
'Q'] = Key::Q; mapKeys[
'R'] = Key::R; mapKeys[
'S'] = Key::S; mapKeys[
'T'] = Key::T;
6603 mapKeys[
'U'] = Key::U; mapKeys[
'V'] = Key::V; mapKeys[
'W'] = Key::W; mapKeys[
'X'] = Key::X; mapKeys[
'Y'] = Key::Y;
6604 mapKeys[
'Z'] = Key::Z;
6606 mapKeys[GLUT_KEY_F1] = Key::F1; mapKeys[GLUT_KEY_F2] = Key::F2; mapKeys[GLUT_KEY_F3] = Key::F3; mapKeys[GLUT_KEY_F4] = Key::F4;
6607 mapKeys[GLUT_KEY_F5] = Key::F5; mapKeys[GLUT_KEY_F6] = Key::F6; mapKeys[GLUT_KEY_F7] = Key::F7; mapKeys[GLUT_KEY_F8] = Key::F8;
6608 mapKeys[GLUT_KEY_F9] = Key::F9; mapKeys[GLUT_KEY_F10] = Key::F10; mapKeys[GLUT_KEY_F11] = Key::F11; mapKeys[GLUT_KEY_F12] = Key::F12;
6610 mapKeys[GLUT_KEY_DOWN] = Key::DOWN; mapKeys[GLUT_KEY_LEFT] = Key::LEFT; mapKeys[GLUT_KEY_RIGHT] = Key::RIGHT; mapKeys[GLUT_KEY_UP] = Key::UP;
6611 mapKeys[13] = Key::ENTER;
6613 mapKeys[127] = Key::BACK; mapKeys[27] = Key::ESCAPE;
6614 mapKeys[9] = Key::TAB; mapKeys[GLUT_KEY_HOME] = Key::HOME;
6615 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;
6616 mapKeys[32] = Key::SPACE; mapKeys[46] = Key::PERIOD;
6618 mapKeys[48] = Key::K0; mapKeys[49] = Key::K1; mapKeys[50] = Key::K2; mapKeys[51] = Key::K3; mapKeys[52] = Key::K4;
6619 mapKeys[53] = Key::K5; mapKeys[54] = Key::K6; mapKeys[55] = Key::K7; mapKeys[56] = Key::K8; mapKeys[57] = Key::K9;
6623 glutKeyboardFunc([](
unsigned char key,
int x,
int y) ->
void {
6624 switch (glutGetModifiers()) {
6626 if (
'a' <= key && key <=
'z') key -= 32;
6628 case GLUT_ACTIVE_SHIFT:
6629 ptrPGE->olc_UpdateKeyState(Key::SHIFT,
true);
6631 case GLUT_ACTIVE_CTRL:
6632 if (
'a' <= key && key <=
'z') key -= 32;
6633 ptrPGE->olc_UpdateKeyState(Key::CTRL,
true);
6635 case GLUT_ACTIVE_ALT:
6636 if (
'a' <= key && key <=
'z') key -= 32;
6641 ptrPGE->olc_UpdateKeyState(mapKeys[key],
true);
6644 glutKeyboardUpFunc([](
unsigned char key,
int x,
int y) ->
void {
6645 switch (glutGetModifiers()) {
6647 if (
'a' <= key && key <=
'z') key -= 32;
6649 case GLUT_ACTIVE_SHIFT:
6650 ptrPGE->olc_UpdateKeyState(Key::SHIFT,
false);
6652 case GLUT_ACTIVE_CTRL:
6653 if (
'a' <= key && key <=
'z') key -= 32;
6654 ptrPGE->olc_UpdateKeyState(Key::CTRL,
false);
6656 case GLUT_ACTIVE_ALT:
6657 if (
'a' <= key && key <=
'z') key -= 32;
6663 ptrPGE->olc_UpdateKeyState(mapKeys[key],
false);
6667 glutSpecialFunc([](
int key,
int x,
int y) ->
void {
6669 ptrPGE->olc_UpdateKeyState(mapKeys[key],
true);
6672 glutSpecialUpFunc([](
int key,
int x,
int y) ->
void {
6674 ptrPGE->olc_UpdateKeyState(mapKeys[key],
false);
6677 glutMouseFunc([](
int button,
int state,
int x,
int y) ->
void {
6679 case GLUT_LEFT_BUTTON:
6680 if (state == GLUT_UP) ptrPGE->olc_UpdateMouseState(0,
false);
6681 else if (state == GLUT_DOWN) ptrPGE->olc_UpdateMouseState(0,
true);
6683 case GLUT_MIDDLE_BUTTON:
6684 if (state == GLUT_UP) ptrPGE->olc_UpdateMouseState(2,
false);
6685 else if (state == GLUT_DOWN) ptrPGE->olc_UpdateMouseState(2,
true);
6687 case GLUT_RIGHT_BUTTON:
6688 if (state == GLUT_UP) ptrPGE->olc_UpdateMouseState(1,
false);
6689 else if (state == GLUT_DOWN) ptrPGE->olc_UpdateMouseState(1,
true);
6694 auto mouseMoveCall = [](
int x,
int y) ->
void {
6695 ptrPGE->olc_UpdateMouse(x, y);
6698 glutMotionFunc(mouseMoveCall);
6699 glutPassiveMotionFunc(mouseMoveCall);
6701 glutEntryFunc([](
int state) ->
void {
6702 if (state == GLUT_ENTERED) ptrPGE->olc_UpdateKeyFocus(
true);
6703 else if (state == GLUT_LEFT) ptrPGE->olc_UpdateKeyFocus(
false);
6706 glutDisplayFunc(DrawFunct);
6707 glutIdleFunc(ThreadFunct);
6712 virtual olc::rcode SetWindowTitle(
const std::string& s)
override
6714 glutSetWindowTitle(s.c_str());
6718 virtual olc::rcode StartSystemEventLoop()
override {
6723 virtual olc::rcode HandleSystemEvent()
override
6729 std::atomic<bool>* Platform_GLUT::bActiveRef{
nullptr };
6737 if (platform->CreateWindowPane({ 30,30 }, vWindowSize, bFullScreen) !=
olc::OK)
return olc::FAIL;
6743 Platform_GLUT::bActiveRef = &bAtomActive;
6744 glutWMCloseFunc(Platform_GLUT::ExitMainLoop);
6746 platform->StartSystemEventLoop();
6765#pragma region platform_emscripten
6782#if defined(OLC_PLATFORM_EMSCRIPTEN)
6784#include <emscripten/html5.h>
6785#include <emscripten/key_codes.h>
6789 EMSCRIPTEN_KEEPALIVE
inline int olc_OnPageUnload()
6790 { olc::platform->ApplicationCleanUp();
return 0; }
6802 virtual olc::rcode ShowWindowFrame(
const bool bShowFrame =
true)
override
6805 virtual olc::rcode ApplicationStartUp()
override
6808 virtual olc::rcode ApplicationCleanUp()
override
6815 { renderer->DestroyDevice();
return olc::OK; }
6819 if (renderer->CreateDevice({}, bFullScreen, bEnableVSYNC) ==
olc::rcode::OK)
6821 renderer->UpdateViewport(vViewPos, vViewSize);
6830 emscripten_set_canvas_element_size(
"#canvas", vWindowSize.
x, vWindowSize.
y);
6832 mapKeys[DOM_PK_UNKNOWN] = Key::NONE;
6833 mapKeys[DOM_PK_A] = Key::A; mapKeys[DOM_PK_B] = Key::B; mapKeys[DOM_PK_C] = Key::C; mapKeys[DOM_PK_D] = Key::D;
6834 mapKeys[DOM_PK_E] = Key::E; mapKeys[DOM_PK_F] = Key::F; mapKeys[DOM_PK_G] = Key::G; mapKeys[DOM_PK_H] = Key::H;
6835 mapKeys[DOM_PK_I] = Key::I; mapKeys[DOM_PK_J] = Key::J; mapKeys[DOM_PK_K] = Key::K; mapKeys[DOM_PK_L] = Key::L;
6836 mapKeys[DOM_PK_M] = Key::M; mapKeys[DOM_PK_N] = Key::N; mapKeys[DOM_PK_O] = Key::O; mapKeys[DOM_PK_P] = Key::P;
6837 mapKeys[DOM_PK_Q] = Key::Q; mapKeys[DOM_PK_R] = Key::R; mapKeys[DOM_PK_S] = Key::S; mapKeys[DOM_PK_T] = Key::T;
6838 mapKeys[DOM_PK_U] = Key::U; mapKeys[DOM_PK_V] = Key::V; mapKeys[DOM_PK_W] = Key::W; mapKeys[DOM_PK_X] = Key::X;
6839 mapKeys[DOM_PK_Y] = Key::Y; mapKeys[DOM_PK_Z] = Key::Z;
6840 mapKeys[DOM_PK_0] = Key::K0; mapKeys[DOM_PK_1] = Key::K1; mapKeys[DOM_PK_2] = Key::K2;
6841 mapKeys[DOM_PK_3] = Key::K3; mapKeys[DOM_PK_4] = Key::K4; mapKeys[DOM_PK_5] = Key::K5;
6842 mapKeys[DOM_PK_6] = Key::K6; mapKeys[DOM_PK_7] = Key::K7; mapKeys[DOM_PK_8] = Key::K8;
6843 mapKeys[DOM_PK_9] = Key::K9;
6844 mapKeys[DOM_PK_F1] = Key::F1; mapKeys[DOM_PK_F2] = Key::F2; mapKeys[DOM_PK_F3] = Key::F3; mapKeys[DOM_PK_F4] = Key::F4;
6845 mapKeys[DOM_PK_F5] = Key::F5; mapKeys[DOM_PK_F6] = Key::F6; mapKeys[DOM_PK_F7] = Key::F7; mapKeys[DOM_PK_F8] = Key::F8;
6846 mapKeys[DOM_PK_F9] = Key::F9; mapKeys[DOM_PK_F10] = Key::F10; mapKeys[DOM_PK_F11] = Key::F11; mapKeys[DOM_PK_F12] = Key::F12;
6847 mapKeys[DOM_PK_ARROW_UP] = Key::UP; mapKeys[DOM_PK_ARROW_DOWN] = Key::DOWN;
6848 mapKeys[DOM_PK_ARROW_LEFT] = Key::LEFT; mapKeys[DOM_PK_ARROW_RIGHT] = Key::RIGHT;
6849 mapKeys[DOM_PK_SPACE] = Key::SPACE; mapKeys[DOM_PK_TAB] = Key::TAB;
6850 mapKeys[DOM_PK_SHIFT_LEFT] = Key::SHIFT; mapKeys[DOM_PK_SHIFT_RIGHT] = Key::SHIFT;
6851 mapKeys[DOM_PK_CONTROL_LEFT] = Key::CTRL; mapKeys[DOM_PK_CONTROL_RIGHT] = Key::CTRL;
6852 mapKeys[DOM_PK_INSERT] = Key::INS; mapKeys[DOM_PK_DELETE] = Key::DEL; mapKeys[DOM_PK_HOME] = Key::HOME;
6853 mapKeys[DOM_PK_END] = Key::END; mapKeys[DOM_PK_PAGE_UP] = Key::PGUP; mapKeys[DOM_PK_PAGE_DOWN] = Key::PGDN;
6854 mapKeys[DOM_PK_BACKSPACE] = Key::BACK; mapKeys[DOM_PK_ESCAPE] = Key::ESCAPE;
6855 mapKeys[DOM_PK_ENTER] = Key::ENTER; mapKeys[DOM_PK_NUMPAD_EQUAL] = Key::EQUALS;
6856 mapKeys[DOM_PK_NUMPAD_ENTER] = Key::ENTER; mapKeys[DOM_PK_PAUSE] = Key::PAUSE;
6857 mapKeys[DOM_PK_SCROLL_LOCK] = Key::SCROLL;
6858 mapKeys[DOM_PK_NUMPAD_0] = Key::NP0; mapKeys[DOM_PK_NUMPAD_1] = Key::NP1; mapKeys[DOM_PK_NUMPAD_2] = Key::NP2;
6859 mapKeys[DOM_PK_NUMPAD_3] = Key::NP3; mapKeys[DOM_PK_NUMPAD_4] = Key::NP4; mapKeys[DOM_PK_NUMPAD_5] = Key::NP5;
6860 mapKeys[DOM_PK_NUMPAD_6] = Key::NP6; mapKeys[DOM_PK_NUMPAD_7] = Key::NP7; mapKeys[DOM_PK_NUMPAD_8] = Key::NP8;
6861 mapKeys[DOM_PK_NUMPAD_9] = Key::NP9;
6862 mapKeys[DOM_PK_NUMPAD_MULTIPLY] = Key::NP_MUL; mapKeys[DOM_PK_NUMPAD_DIVIDE] = Key::NP_DIV;
6863 mapKeys[DOM_PK_NUMPAD_ADD] = Key::NP_ADD; mapKeys[DOM_PK_NUMPAD_SUBTRACT] = Key::NP_SUB;
6864 mapKeys[DOM_PK_NUMPAD_DECIMAL] = Key::NP_DECIMAL;
6865 mapKeys[DOM_PK_PERIOD] = Key::PERIOD; mapKeys[DOM_PK_EQUAL] = Key::EQUALS;
6866 mapKeys[DOM_PK_COMMA] = Key::COMMA; mapKeys[DOM_PK_MINUS] = Key::MINUS;
6867 mapKeys[DOM_PK_CAPS_LOCK] = Key::CAPS_LOCK;
6868 mapKeys[DOM_PK_SEMICOLON] = Key::OEM_1; mapKeys[DOM_PK_SLASH] = Key::OEM_2; mapKeys[DOM_PK_BACKQUOTE] = Key::OEM_3;
6869 mapKeys[DOM_PK_BRACKET_LEFT] = Key::OEM_4; mapKeys[DOM_PK_BACKSLASH] = Key::OEM_5; mapKeys[DOM_PK_BRACKET_RIGHT] = Key::OEM_6;
6870 mapKeys[DOM_PK_QUOTE] = Key::OEM_7; mapKeys[DOM_PK_BACKSLASH] = Key::OEM_8;
6873 emscripten_set_keydown_callback(
"#canvas", 0, 1, keyboard_callback);
6874 emscripten_set_keyup_callback(
"#canvas", 0, 1, keyboard_callback);
6877 emscripten_set_wheel_callback(
"#canvas", 0, 1, wheel_callback);
6878 emscripten_set_mousedown_callback(
"#canvas", 0, 1, mouse_callback);
6879 emscripten_set_mouseup_callback(
"#canvas", 0, 1, mouse_callback);
6880 emscripten_set_mousemove_callback(
"#canvas", 0, 1, mouse_callback);
6883 emscripten_set_touchstart_callback(
"#canvas", 0, 1, touch_callback);
6884 emscripten_set_touchmove_callback(
"#canvas", 0, 1, touch_callback);
6885 emscripten_set_touchend_callback(
"#canvas", 0, 1, touch_callback);
6888 emscripten_set_blur_callback(
"#canvas", 0, 1, focus_callback);
6889 emscripten_set_focus_callback(
"#canvas", 0, 1, focus_callback);
6891#pragma warning disable format
6892 EM_ASM( window.onunload = Module._olc_OnPageUnload; );
6913 Module.olc_AspectRatio = $0 / $1;
6919 Module.olc_AssumeDefaultShells = (document.querySelectorAll(
'.emscripten').length >= 3) ? true :
false;
6924 var olc_ResizeHandler = function()
6927 let isFullscreen = (document.fullscreenElement != null);
6930 let width = (isFullscreen) ? window.innerWidth : Module.canvas.parentNode.clientWidth;
6931 let height = (isFullscreen) ? window.innerHeight : Module.canvas.parentNode.clientHeight;
6934 let viewWidth = width;
6935 let viewHeight = width / Module.olc_AspectRatio;
6938 if(viewHeight > height)
6940 viewWidth = height * Module.olc_AspectRatio;
6941 viewHeight = height;
6945 viewWidth = parseInt(viewWidth);
6946 viewHeight = parseInt(viewHeight);
6948 setTimeout(function()
6951 if(Module.olc_AssumeDefaultShells)
6952 Module.canvas.parentNode.setAttribute(
'style',
'width: 100%; height: 70vh; margin-left: auto; margin-right: auto;');
6955 Module.canvas.setAttribute(
'width', viewWidth);
6956 Module.canvas.setAttribute(
'height', viewHeight);
6957 Module.canvas.setAttribute(
'style', `width: ${viewWidth}px; height: ${viewHeight}px;`);
6960 Module._olc_PGE_UpdateWindowSize(viewWidth, viewHeight);
6963 Module.canvas.focus();
6971 var olc_Init = function()
6973 if(Module.olc_AspectRatio === undefined)
6975 setTimeout(function() { Module.olc_Init(); }, 50);
6979 let resizeObserver =
new ResizeObserver(function(entries)
6981 Module.olc_ResizeHandler();
6982 }).observe(Module.canvas.parentNode);
6984 let mutationObserver =
new MutationObserver(function(mutationsList, observer)
6986 setTimeout(function() { Module.olc_ResizeHandler(); }, 200);
6987 }).observe(Module.canvas.parentNode, { attributes: false, childList: true, subtree: false });
6989 window.addEventListener(
'fullscreenchange', function(e)
6991 setTimeout(function() { Module.olc_ResizeHandler();}, 200);
6996 Module.olc_ResizeHandler = (Module.olc_ResizeHandler != undefined) ? Module.olc_ResizeHandler : olc_ResizeHandler;
6997 Module.olc_Init = (Module.olc_Init != undefined) ? Module.olc_Init : olc_Init;
7002 }, vWindowSize.
x, vWindowSize.
y);
7003#pragma warning restore format
7008 void UpdateWindowSize(
int width,
int height)
7010 ptrPGE->olc_UpdateWindowSize(width, height);
7014 static EM_BOOL focus_callback(
int eventType,
const EmscriptenFocusEvent* focusEvent,
void* userData)
7016 if (eventType == EMSCRIPTEN_EVENT_BLUR)
7018 ptrPGE->olc_UpdateKeyFocus(
false);
7019 ptrPGE->olc_UpdateMouseFocus(
false);
7021 else if (eventType == EMSCRIPTEN_EVENT_FOCUS)
7023 ptrPGE->olc_UpdateKeyFocus(
true);
7024 ptrPGE->olc_UpdateMouseFocus(
true);
7031 static EM_BOOL keyboard_callback(
int eventType,
const EmscriptenKeyboardEvent* e,
void* userData)
7033 if (eventType == EMSCRIPTEN_EVENT_KEYDOWN)
7034 ptrPGE->olc_UpdateKeyState(mapKeys[emscripten_compute_dom_pk_code(e->code)],
true);
7037 if (eventType == EMSCRIPTEN_EVENT_KEYUP)
7038 ptrPGE->olc_UpdateKeyState(mapKeys[emscripten_compute_dom_pk_code(e->code)],
false);
7045 static EM_BOOL wheel_callback(
int eventType,
const EmscriptenWheelEvent* e,
void* userData)
7047 if (eventType == EMSCRIPTEN_EVENT_WHEEL)
7048 ptrPGE->olc_UpdateMouseWheel(-1 * e->deltaY);
7054 static EM_BOOL touch_callback(
int eventType,
const EmscriptenTouchEvent* e,
void* userData)
7057 if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE)
7059 ptrPGE->olc_UpdateMouse(e->touches->targetX, e->touches->targetY);
7063 if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART)
7065 ptrPGE->olc_UpdateMouse(e->touches->targetX, e->touches->targetY);
7066 ptrPGE->olc_UpdateMouseState(0,
true);
7070 if (eventType == EMSCRIPTEN_EVENT_TOUCHEND)
7072 ptrPGE->olc_UpdateMouseState(0,
false);
7079 static EM_BOOL mouse_callback(
int eventType,
const EmscriptenMouseEvent* e,
void* userData)
7082 if (eventType == EMSCRIPTEN_EVENT_MOUSEMOVE)
7083 ptrPGE->olc_UpdateMouse(e->targetX, e->targetY);
7089 if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN)
7090 ptrPGE->olc_UpdateMouseState(0,
true);
7091 else if (eventType == EMSCRIPTEN_EVENT_MOUSEUP)
7092 ptrPGE->olc_UpdateMouseState(0,
false);
7097 if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN)
7098 ptrPGE->olc_UpdateMouseState(1,
true);
7099 else if (eventType == EMSCRIPTEN_EVENT_MOUSEUP)
7100 ptrPGE->olc_UpdateMouseState(1,
false);
7106 if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN)
7107 ptrPGE->olc_UpdateMouseState(2,
true);
7108 else if (eventType == EMSCRIPTEN_EVENT_MOUSEUP)
7109 ptrPGE->olc_UpdateMouseState(2,
false);
7119 virtual olc::rcode SetWindowTitle(
const std::string& s)
override
7120 { emscripten_set_window_title(s.c_str());
return olc::OK; }
7122 virtual olc::rcode StartSystemEventLoop()
override
7125 virtual olc::rcode HandleSystemEvent()
override
7128 static void MainLoop()
7131 if (!ptrPGE->olc_IsRunning())
7133 if (ptrPGE->OnUserDestroy())
7135 emscripten_cancel_main_loop();
7136 platform->ApplicationCleanUp();
7140 ptrPGE->olc_Reanimate();
7153 if (platform->CreateWindowPane({ 30,30 }, vWindowSize, bFullScreen) !=
olc::OK)
return olc::FAIL;
7166 for (
auto& ext : vExtensions) ext->OnBeforeUserCreate();
7168 for (
auto& ext : vExtensions) ext->OnAfterUserCreate();
7170 platform->StartSystemEventLoop();
7174 emscripten_set_main_loop(&Platform_Emscripten::MainLoop, 0, 1);
7184 EMSCRIPTEN_KEEPALIVE
inline void olc_PGE_UpdateWindowSize(
int width,
int height)
7186 emscripten_set_canvas_element_size(
"#canvas", width, height);
7188 ((olc::Platform_Emscripten*)olc::platform.get())->UpdateWindowSize(width, height);
7204#pragma region pge_config
7214#if defined(OLC_IMAGE_GDI)
7218#if defined(OLC_IMAGE_LIBPNG)
7222#if defined(OLC_IMAGE_STB)
7226#if defined(OLC_IMAGE_CUSTOM_EX)
7231#if defined(OLC_PLATFORM_HEADLESS)
7232 platform = std::make_unique<olc::Platform_Headless>();
7235#if defined(OLC_PLATFORM_WINAPI)
7236 platform = std::make_unique<olc::Platform_Windows>();
7239#if defined(OLC_PLATFORM_X11)
7240 platform = std::make_unique<olc::Platform_Linux>();
7243#if defined(OLC_PLATFORM_GLUT)
7244 platform = std::make_unique<olc::Platform_GLUT>();
7247#if defined(OLC_PLATFORM_EMSCRIPTEN)
7248 platform = std::make_unique<olc::Platform_Emscripten>();
7251#if defined(OLC_PLATFORM_CUSTOM_EX)
7252 platform = std::make_unique<OLC_PLATFORM_CUSTOM_EX>();
7255#if defined(OLC_GFX_HEADLESS)
7256 renderer = std::make_unique<olc::Renderer_Headless>();
7259#if defined(OLC_GFX_OPENGL10)
7260 renderer = std::make_unique<olc::Renderer_OGL10>();
7263#if defined(OLC_GFX_OPENGL33)
7264 renderer = std::make_unique<olc::Renderer_OGL33>();
7267#if defined(OLC_GFX_OPENGLES2)
7268 renderer = std::make_unique<olc::Renderer_OGLES2>();
7271#if defined(OLC_GFX_DIRECTX10)
7272 renderer = std::make_unique<olc::Renderer_DX10>();
7275#if defined(OLC_GFX_DIRECTX11)
7276 renderer = std::make_unique<olc::Renderer_DX11>();
7279#if defined(OLC_GFX_CUSTOM_EX)
7280 renderer = std::make_unique<OLC_RENDERER_CUSTOM_EX>();
7284 platform->ptrPGE =
this;
7285 renderer->ptrPGE =
this;
Definition olcPixelGameEngine.h:1089
Decal(olc::Sprite *spr, bool filter=false, bool clamp=true)
int32_t id
Definition olcPixelGameEngine.h:1098
olc::Sprite * sprite
Definition olcPixelGameEngine.h:1099
Decal(const uint32_t nExistingTextureResource, olc::Sprite *spr)
olc::vf2d vUVScale
Definition olcPixelGameEngine.h:1100
Definition olcPixelGameEngine.h:1034
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:1615
static PixelGameEngine * pge
Definition olcPixelGameEngine.h:1627
virtual void OnAfterUserCreate()
virtual void OnAfterUserUpdate(float fElapsedTime)
virtual void OnBeforeUserCreate()
virtual bool OnBeforeUserUpdate(float &fElapsedTime)
Definition olcPixelGameEngine.h:1225
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:1488
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 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
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="")
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 olc_UpdateKeyState(int32_t key, bool state)
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 })
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 ConsoleShow(const olc::Key &keyExit, bool bSuspendTime=true)
const olc::vi2d & GetMousePos() 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)
void olc_UpdateMouseFocus(bool state)
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)
static const std::map< size_t, uint8_t > & GetKeyMap()
Definition olcPixelGameEngine.h:1266
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 DrawWarpedDecal(olc::Decal *decal, const olc::vf2d *pos, const olc::Pixel &tint=olc::WHITE)
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()
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:1125
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:1175
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 DisplayFrame()=0
virtual void PrepareDevice()=0
virtual ~Renderer()=default
static olc::PixelGameEngine * ptrPGE
Definition olcPixelGameEngine.h:1193
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:1015
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:1047
static std::unique_ptr< olc::ImageLoader > loader
Definition olcPixelGameEngine.h:1082
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:1061
@ NORMAL
Definition olcPixelGameEngine.h:1061
@ PERIODIC
Definition olcPixelGameEngine.h:1061
@ CLAMP
Definition olcPixelGameEngine.h:1061
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:1060
Pixel Sample(const olc::vf2d &uv) const
Mode modeSample
Definition olcPixelGameEngine.h:1080
Flip
Definition olcPixelGameEngine.h:1062
@ HORIZ
Definition olcPixelGameEngine.h:1062
@ NONE
Definition olcPixelGameEngine.h:1062
@ VERT
Definition olcPixelGameEngine.h:1062
Sprite(const std::string &sImageFile, olc::ResourcePack *pack=nullptr)
std::vector< olc::Pixel > pColData
Definition olcPixelGameEngine.h:1079
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:1059
Definition olcPixelGameEngine.h:593
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:872
v_2d< float > vf2d
Definition olcPixelGameEngine.h:894
constexpr uint32_t nDefaultPixel
Definition olcPixelGameEngine.h:914
constexpr auto operator/=(v_2d< TL > &lhs, const TR &rhs)
Definition olcPixelGameEngine.h:791
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:773
DecalStructure
Definition olcPixelGameEngine.h:1114
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:747
static const Pixel GREEN(0, 255, 0)
static const Pixel DARK_YELLOW(128, 128, 0)
rcode
Definition olcPixelGameEngine.h:917
@ OK
Definition olcPixelGameEngine.h:917
@ FAIL
Definition olcPixelGameEngine.h:917
@ NO_FILE
Definition olcPixelGameEngine.h:917
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:864
constexpr std::ostream & operator<<(std::ostream &os, const v_2d< T > &rhs)
Definition olcPixelGameEngine.h:885
constexpr auto operator+=(v_2d< TL > &lhs, const TR &rhs)
Definition olcPixelGameEngine.h:824
constexpr auto operator+(const v_2d< T > &lhs)
Definition olcPixelGameEngine.h:799
v_2d< uint32_t > vu2d
Definition olcPixelGameEngine.h:893
constexpr uint8_t nTabSizeInSpaces
Definition olcPixelGameEngine.h:915
v_2d< double > vd2d
Definition olcPixelGameEngine.h:895
static const Pixel YELLOW(255, 255, 0)
static const Pixel DARK_GREY(128, 128, 128)
v_2d< int32_t > vi2d
Definition olcPixelGameEngine.h:892
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:916
constexpr auto operator*=(v_2d< TL > &lhs, const TR &rhs)
Definition olcPixelGameEngine.h:765
constexpr auto operator-(const v_2d< T > &lhs)
Definition olcPixelGameEngine.h:839
static const Pixel VERY_DARK_GREY(64, 64, 64)
static const Pixel DARK_CYAN(0, 128, 128)
Key
Definition olcPixelGameEngine.h:972
@ S
Definition olcPixelGameEngine.h:974
@ NP5
Definition olcPixelGameEngine.h:980
@ PGUP
Definition olcPixelGameEngine.h:978
@ PAUSE
Definition olcPixelGameEngine.h:979
@ F6
Definition olcPixelGameEngine.h:976
@ K
Definition olcPixelGameEngine.h:974
@ NP0
Definition olcPixelGameEngine.h:980
@ V
Definition olcPixelGameEngine.h:974
@ F1
Definition olcPixelGameEngine.h:976
@ G
Definition olcPixelGameEngine.h:974
@ PERIOD
Definition olcPixelGameEngine.h:981
@ F2
Definition olcPixelGameEngine.h:976
@ H
Definition olcPixelGameEngine.h:974
@ X
Definition olcPixelGameEngine.h:974
@ HOME
Definition olcPixelGameEngine.h:978
@ P
Definition olcPixelGameEngine.h:974
@ UP
Definition olcPixelGameEngine.h:977
@ NP_DECIMAL
Definition olcPixelGameEngine.h:981
@ K0
Definition olcPixelGameEngine.h:975
@ F9
Definition olcPixelGameEngine.h:976
@ ENTER
Definition olcPixelGameEngine.h:979
@ K1
Definition olcPixelGameEngine.h:975
@ K5
Definition olcPixelGameEngine.h:975
@ ENUM_END
Definition olcPixelGameEngine.h:984
@ BACK
Definition olcPixelGameEngine.h:979
@ OEM_1
Definition olcPixelGameEngine.h:983
@ F4
Definition olcPixelGameEngine.h:976
@ OEM_7
Definition olcPixelGameEngine.h:983
@ A
Definition olcPixelGameEngine.h:974
@ NP4
Definition olcPixelGameEngine.h:980
@ SCROLL
Definition olcPixelGameEngine.h:979
@ NP8
Definition olcPixelGameEngine.h:980
@ J
Definition olcPixelGameEngine.h:974
@ MINUS
Definition olcPixelGameEngine.h:982
@ SHIFT
Definition olcPixelGameEngine.h:978
@ L
Definition olcPixelGameEngine.h:974
@ LEFT
Definition olcPixelGameEngine.h:977
@ RETURN
Definition olcPixelGameEngine.h:979
@ DOWN
Definition olcPixelGameEngine.h:977
@ CAPS_LOCK
Definition olcPixelGameEngine.h:984
@ END
Definition olcPixelGameEngine.h:978
@ NP9
Definition olcPixelGameEngine.h:980
@ NONE
Definition olcPixelGameEngine.h:973
@ F3
Definition olcPixelGameEngine.h:976
@ RIGHT
Definition olcPixelGameEngine.h:977
@ DEL
Definition olcPixelGameEngine.h:978
@ F
Definition olcPixelGameEngine.h:974
@ Y
Definition olcPixelGameEngine.h:974
@ U
Definition olcPixelGameEngine.h:974
@ K8
Definition olcPixelGameEngine.h:975
@ INS
Definition olcPixelGameEngine.h:978
@ Q
Definition olcPixelGameEngine.h:974
@ D
Definition olcPixelGameEngine.h:974
@ R
Definition olcPixelGameEngine.h:974
@ Z
Definition olcPixelGameEngine.h:974
@ NP2
Definition olcPixelGameEngine.h:980
@ O
Definition olcPixelGameEngine.h:974
@ K6
Definition olcPixelGameEngine.h:975
@ K7
Definition olcPixelGameEngine.h:975
@ B
Definition olcPixelGameEngine.h:974
@ SPACE
Definition olcPixelGameEngine.h:978
@ K9
Definition olcPixelGameEngine.h:975
@ T
Definition olcPixelGameEngine.h:974
@ NP1
Definition olcPixelGameEngine.h:980
@ F12
Definition olcPixelGameEngine.h:976
@ OEM_4
Definition olcPixelGameEngine.h:983
@ EQUALS
Definition olcPixelGameEngine.h:982
@ C
Definition olcPixelGameEngine.h:974
@ NP3
Definition olcPixelGameEngine.h:980
@ K4
Definition olcPixelGameEngine.h:975
@ NP_SUB
Definition olcPixelGameEngine.h:981
@ PGDN
Definition olcPixelGameEngine.h:978
@ K2
Definition olcPixelGameEngine.h:975
@ OEM_8
Definition olcPixelGameEngine.h:983
@ N
Definition olcPixelGameEngine.h:974
@ F5
Definition olcPixelGameEngine.h:976
@ F8
Definition olcPixelGameEngine.h:976
@ K3
Definition olcPixelGameEngine.h:975
@ F11
Definition olcPixelGameEngine.h:976
@ OEM_3
Definition olcPixelGameEngine.h:983
@ F10
Definition olcPixelGameEngine.h:976
@ W
Definition olcPixelGameEngine.h:974
@ I
Definition olcPixelGameEngine.h:974
@ ESCAPE
Definition olcPixelGameEngine.h:979
@ F7
Definition olcPixelGameEngine.h:976
@ E
Definition olcPixelGameEngine.h:974
@ OEM_2
Definition olcPixelGameEngine.h:983
@ NP6
Definition olcPixelGameEngine.h:980
@ OEM_5
Definition olcPixelGameEngine.h:983
@ NP_MUL
Definition olcPixelGameEngine.h:981
@ COMMA
Definition olcPixelGameEngine.h:982
@ CTRL
Definition olcPixelGameEngine.h:978
@ NP_DIV
Definition olcPixelGameEngine.h:981
@ TAB
Definition olcPixelGameEngine.h:978
@ NP_ADD
Definition olcPixelGameEngine.h:981
@ OEM_6
Definition olcPixelGameEngine.h:983
@ M
Definition olcPixelGameEngine.h:974
@ NP7
Definition olcPixelGameEngine.h:980
static const Pixel DARK_MAGENTA(128, 0, 128)
constexpr uint8_t nMouseButtons
Definition olcPixelGameEngine.h:912
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:913
static const Pixel WHITE(255, 255, 255)
DecalMode
Definition olcPixelGameEngine.h:1104
static const Pixel VERY_DARK_CYAN(0, 64, 64)
constexpr bool operator>(const v_2d< TL > &lhs, const v_2d< TR > &rhs)
Definition olcPixelGameEngine.h:878
#define UNUSED(x)
Definition olcPixelGameEngine.h:461
#define olcT(s)
Definition olcPixelGameEngine.h:458
Definition olcPixelGameEngine.h:1148
olc::DecalStructure structure
Definition olcPixelGameEngine.h:1156
std::vector< olc::Pixel > tint
Definition olcPixelGameEngine.h:1154
std::vector< float > z
Definition olcPixelGameEngine.h:1153
std::vector< float > w
Definition olcPixelGameEngine.h:1152
bool depth
Definition olcPixelGameEngine.h:1158
olc::DecalMode mode
Definition olcPixelGameEngine.h:1155
std::vector< olc::vf2d > uv
Definition olcPixelGameEngine.h:1151
std::vector< olc::vf2d > pos
Definition olcPixelGameEngine.h:1150
uint32_t points
Definition olcPixelGameEngine.h:1157
olc::Decal * decal
Definition olcPixelGameEngine.h:1149
Definition olcPixelGameEngine.h:1162
olc::vf2d vOffset
Definition olcPixelGameEngine.h:1163
std::function< void()> funcHook
Definition olcPixelGameEngine.h:1171
bool bUpdate
Definition olcPixelGameEngine.h:1166
olc::Renderable pDrawTarget
Definition olcPixelGameEngine.h:1167
uint32_t nResID
Definition olcPixelGameEngine.h:1168
olc::vf2d vScale
Definition olcPixelGameEngine.h:1164
std::vector< DecalInstance > vecDecalInstance
Definition olcPixelGameEngine.h:1169
bool bShow
Definition olcPixelGameEngine.h:1165
olc::Pixel tint
Definition olcPixelGameEngine.h:1170
Definition olcPixelGameEngine.h:924
Pixel & operator-=(const Pixel &p)
uint8_t g
Definition olcPixelGameEngine.h:928
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:928
bool operator==(const Pixel &p) const
Pixel & operator=(const Pixel &v)=default
Pixel operator/(const float i) const
uint8_t b
Definition olcPixelGameEngine.h:928
uint8_t r
Definition olcPixelGameEngine.h:928
uint32_t n
Definition olcPixelGameEngine.h:927
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:931
@ MASK
Definition olcPixelGameEngine.h:931
@ ALPHA
Definition olcPixelGameEngine.h:931
@ NORMAL
Definition olcPixelGameEngine.h:931
@ CUSTOM
Definition olcPixelGameEngine.h:931
bool operator!=(const Pixel &p) const
Definition olcPixelGameEngine.h:1009
std::vector< char > vMemory
Definition olcPixelGameEngine.h:1011
ResourceBuffer(std::ifstream &ifs, uint32_t offset, uint32_t size)
Definition olcPixelGameEngine.h:600
constexpr v_2d clamp(const v_2d &v1, const v_2d &v2) const
Definition olcPixelGameEngine.h:702
T x
Definition olcPixelGameEngine.h:604
constexpr auto cross(const v_2d &rhs) const
Definition olcPixelGameEngine.h:684
T y
Definition olcPixelGameEngine.h:606
constexpr v_2d & operator=(const v_2d &v)=default
constexpr v_2d lerp(const v_2d &v1, const double t) const
Definition olcPixelGameEngine.h:708
constexpr auto dot(const v_2d &rhs) const
Definition olcPixelGameEngine.h:678
constexpr T mag2() const
Definition olcPixelGameEngine.h:635
v_2d norm() const
Definition olcPixelGameEngine.h:641
constexpr bool operator!=(const v_2d &rhs) const
Definition olcPixelGameEngine.h:720
std::string str() const
Definition olcPixelGameEngine.h:726
constexpr auto area() const
Definition olcPixelGameEngine.h:623
constexpr v_2d polar() const
Definition olcPixelGameEngine.h:696
constexpr v_2d(T _x, T _y)
Definition olcPixelGameEngine.h:612
constexpr v_2d min(const v_2d &v) const
Definition olcPixelGameEngine.h:672
constexpr v_2d(const v_2d &v)=default
constexpr bool operator==(const v_2d &rhs) const
Definition olcPixelGameEngine.h:714
constexpr v_2d max(const v_2d &v) const
Definition olcPixelGameEngine.h:666
constexpr v_2d ceil() const
Definition olcPixelGameEngine.h:660
constexpr v_2d reflect(const v_2d &n) const
Definition olcPixelGameEngine.h:732
constexpr v_2d perp() const
Definition olcPixelGameEngine.h:648
constexpr v_2d floor() const
Definition olcPixelGameEngine.h:654
constexpr v_2d cart() const
Definition olcPixelGameEngine.h:690
auto mag() const
Definition olcPixelGameEngine.h:629