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