You are on page 1of 105

...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.

h 1
1 /*
2 clang++ ­arch x86_64 ­std=c++17 ­mmacosx­version­min=10.15 ­Wall ­
framework OpenGL ­framework GLUT ­lpng YourSource.cpp ­o YourProgName
3
4 Using stb_image.h
5 ~~~~~~~~~~~~~~~~~
6 The PGE will load png images by default (with help from libpng on non ­
windows systems).
7 However, the excellent "stb_image.h" can be used instead, supporting a 
variety of
8 image formats, and has no library dependence  ­ something we like at OLC 
studios ;)
9 To use stb_image.h, make sure it's in your code base, and simply:
10
11 #define OLC_IMAGE_STB
12
13 Before including the olcPixelGameEngine.h header file. stb_image.h works 
on many systems
14 and can be downloaded here: https://github.com/nothings/stb/blob/master/
stb_image.h
15
16 Ports
17 ~~~~~
18 olc::PixelGameEngine has been ported and tested with varying degrees of
19 success to: WinXP, Win7, Win8, Win10, Various Linux, Raspberry Pi,
20 Chromebook, Playstation Portable (PSP) and Nintendo Switch. If you are
21 interested in the details of these ports, come and visit the Discord!
22
23 2.01: Made renderer and platform static for multifile projects
24 2.02: Added Decal destructor, optimised Pixel constructor
25 2.03: Added FreeBSD flags, Added DrawStringDecal()
26 2.04: Windows Full­Screen bug fixed
27 2.05: +DrawPartialWarpedDecal() ­ draws a warped decal from a subset image
28 +DrawPartialRotatedDecal()  ­ draws a rotated decal from a subset 
image
29 2.06: +GetTextSize() ­ returns area occupied by multiline string
30   +GetWindowSize() ­ returns actual window size
31   +GetElapsedTime() ­ returns last calculated fElapsedTime
32   +GetWindowMouse() ­ returns actual mouse location in window
33   +DrawExplicitDecal() ­ bow­chikka­bow­bow
34 +DrawPartialDecal(pos, size)  ­ draws a partial decal to specified 
area
35   +FillRectDecal() ­ draws a flat shaded rectangle as a decal
36 +GradientFillRectDecal()  ­ draws a rectangle, with unique colour 
corners
37   +Modified DrawCircle() & FillCircle() ­ Thanks IanM­Matrix1 (#PR121)
38   +Gone someway to appeasing pedants
39 2.07: +GetPixelSize() ­ returns user specified pixel size
40   +GetScreenPixelSize() ­ returns actual size in monitor pixels
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 2
41 +Pixel Cohesion Mode (flag in Construct())  ­ disallows arbitrary 
window scaling
42   +Working VSYNC in Windows windowed application ­ now much smoother
43   +Added string conversion for olc::vectors
44   +Added comparator operators for olc::vectors
45   +Added DestroyWindow() on windows platforms for serial PGE launches
46   +Added GetMousePos() to stop TarriestPython whinging
47 2.08: Fix SetScreenSize() aspect ratio pre­calculation
48   Fix DrawExplicitDecal() ­ stupid oversight with multiple decals
49   Disabled olc::Sprite copy constructor
50   +olc::Sprite Duplicate() ­ produces a new clone of the sprite
51 +olc::Sprite Duplicate(pos, size)  ­ produces a new sprite from the 
region defined
52   +Unary operators for vectors
53   +More pedant mollification ­ Thanks TheLandfill
54 +ImageLoader modules ­ user selectable image handling core, gdi+, 
libpng, stb_image
55   +Mac Support via GLUT ­ thanks Mumflr!
56 2.09: Fix olc::Renderable Image load error  ­ Thanks MaGetzUb & Zij­IT for 
finding and moaning about it
57   Fix file rejection in image loaders when using resource packs
58   Tidied Compiler defines per platform ­ Thanks slavka
59   +Pedant fixes, const correctness in parts
60   +DecalModes ­ Normal, Additive, Multiplicative blend modes
61   +Pixel Operators & Lerping
62   +Filtered Decals ­ If you hate pixels, then erase this file
63 +DrawStringProp(), GetTextSizeProp(), DrawStringPropDecal()  ­ Draws 
non­monospaced font
64
65
66 */
67
68 //////////////////////////////////////////////////////////////////////////////
////////////
69
70
71 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
72 // | Example "Hello World" Program (main.cpp)                                 
    |
73 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
74 /*
75
76 #define OLC_PGE_APPLICATION
77 #include "olcPixelGameEngine.h"
78
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 3
79 // Override base class with your custom functionality
80 class Example : public olc::PixelGameEngine
81 {
82 public:
83 Example()
84 {
85 // Name you application
86 sAppName = "Example";
87 }
88
89 public:
90 bool OnUserCreate() override
91 {
92 // Called once at the start, so create things here
93 return true;
94 }
95
96 bool OnUserUpdate(float fElapsedTime) override
97 {
98 // Called once per frame, draws random coloured pixels
99 for (int x = 0; x < ScreenWidth(); x++)
100 for (int y = 0; y < ScreenHeight(); y++)
101 Draw(x, y, olc::Pixel(rand() % 256, rand() % 256, rand() % 
256));
102 return true;
103 }
104 };
105
106 int main()
107 {
108 Example demo;
109 if (demo.Construct(256, 240, 4, 4))
110 demo.Start();
111 return 0;
112 }
113
114 */
115
116 #ifndef OLC_PGE_DEF
117 #define OLC_PGE_DEF
118
119 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
120 // | STANDARD INCLUDES                                                        
    |
121 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 4
122 #include <cmath>
123 #include <cstdint>
124 #include <string>
125 #include <iostream>
126 #include <streambuf>
127 #include <sstream>
128 #include <chrono>
129 #include <vector>
130 #include <list>
131 #include <thread>
132 #include <atomic>
133 #include <fstream>
134 #include <map>
135 #include <functional>
136 #include <algorithm>
137 #include <array>
138 #include <cstring>
139
140 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
141 // | COMPILER CONFIGURATION ODDITIES                                          
    |
142 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
143 #define USE_EXPERIMENTAL_FS
144
145 #if defined(_WIN32)
146 #if _MSC_VER >= 1920 && _MSVC_LANG >= 201703L
147
148 #endif
149 #endif
150
151 #if defined(__linux__) || defined(__MINGW32__) || defined(__EMSCRIPTEN__) || 
defined(__FreeBSD__) || defined(__APPLE__)
152
153
154
155 #endif
156
157 #if defined(__APPLE__)
158
159 #endif
160
161 #if defined(USE_EXPERIMENTAL_FS) || defined(FORCE_EXPERIMENTAL_FS)
162 // C++14
163 #define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
164 #include <experimental/filesystem>
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 5
165 namespace _gfs = std::experimental::filesystem::v1;
166 #else
167
168
169
170 #endif
171
172 #if defined(UNICODE) || defined(_UNICODE)
173 #define olcT(s) L##s
174 #else
175
176 #endif
177
178 #define UNUSED(x) (void)(x)
179
180 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
181 // | PLATFORM SELECTION CODE, Thanks slavka!                                  
    |
182 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
183
184 // Platform
185 #if !defined(OLC_PLATFORM_WINAPI) && !defined(OLC_PLATFORM_X11) && !defined
(OLC_PLATFORM_GLUT)
186 #if defined(_WIN32)
187 #define OLC_PLATFORM_WINAPI
188 #endif
189 #if defined(__linux__) || defined(__FreeBSD__)
190
191 #endif
192 #if defined(__APPLE__)
193
194 #endif
195 #endif
196
197 // Renderer
198 #if !defined(OLC_GFX_OPENGL10) || !defined(OLC_GFX_OPENGL33) && !defined
(OLC_GFX_DIRECTX10)
199 #define OLC_GFX_OPENGL10
200 #endif
201
202 // Image loader
203 #if !defined(OLC_IMAGE_STB) && !defined(OLC_IMAGE_GDI) && !defined
(OLC_IMAGE_LIBPNG)
204 #if defined(_WIN32)
205 #define OLC_IMAGE_GDI
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 6
206 #endif
207 #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
208
209 #endif
210 #endif
211
212
213 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
214 // | PLATFORM­SPECIFIC DEPENDENCIES                                           
    |
215 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
216 #if defined(OLC_PLATFORM_WINAPI)
217 #define _WINSOCKAPI_ // Thanks Cornchipss
218
219 //#if !defined(WIN32_LEAN_AND_MEAN) // Removes something GDI requires
220 // #define WIN32_LEAN_AND_MEAN
221 //#endif
222 #if !defined(VC_EXTRALEAN)
223 #define VC_EXTRALEAN
224 #endif
225 #if !defined(NOMINMAX)
226 #define NOMINMAX
227 #endif
228
229 // In Code::Blocks
230 #if !defined(_WIN32_WINNT)
231 #ifdef HAVE_MSMF
232
233 #else
234 #define _WIN32_WINNT 0x0500 // Windows 2000
235 #endif
236 #endif
237
238 #include <windows.h>
239
240 #undef _WINSOCKAPI_
241 #endif
242
243 #if defined(OLC_PLATFORM_X11)
244
245
246
247
248
249 #endif
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 7
250
251 #if defined(OLC_PLATFORM_GLUT)
252
253
254
255
256
257
258
259
260 #endif
261
262
263 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
264 // | olcPixelGameEngine INTERFACE DECLARATION                                 
    |
265 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
266 namespace olc
267 {
268 class PixelGameEngine;
269 class Sprite;
270
271 // Pixel Game Engine Advanced Configuration
272 constexpr uint8_t  nMouseButtons = 5;
273 constexpr uint8_t  nDefaultAlpha = 0xFF;
274 constexpr uint32_t nDefaultPixel = (nDefaultAlpha << 24);
275 enum rcode { FAIL = 0, OK = 1, NO_FILE = ­1 };
276
277 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
278 // | olc::Pixel ­ Represents a 32­Bit RGBA colour                         
        |
279 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
280 struct Pixel
281 {
282 union
283 {
284 uint32_t n = nDefaultPixel;
285 struct { uint8_t r; uint8_t g; uint8_t b; uint8_t a; };
286 };
287
288 enum Mode { NORMAL, MASK, ALPHA, CUSTOM };
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 8
289
290 Pixel();
291 Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 
nDefaultAlpha);
292 Pixel(uint32_t p);
293 Pixel& operator = (const Pixel& v) = default;
294 bool   operator ==(const Pixel& p) const;
295 bool   operator !=(const Pixel& p) const;
296 Pixel  operator * (const float i) const;
297 Pixel  operator / (const float i) const;
298 Pixel& operator *=(const float i);
299 Pixel& operator /=(const float i);
300 Pixel  operator + (const Pixel& p) const;
301 Pixel  operator ­ (const Pixel& p) const;
302 Pixel& operator +=(const Pixel& p);
303 Pixel& operator ­=(const Pixel& p);
304 Pixel  inv() const;
305 };
306
307 Pixel PixelF(float red, float green, float blue, float alpha = 1.0f);
308 Pixel PixelLerp(const olc::Pixel& p1, const olc::Pixel& p2, float t);
309
310
311 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
312 // | USEFUL CONSTANTS                                                     
        |
313 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
314 static const Pixel
315 GREY(192, 192, 192), DARK_GREY(128, 128, 128), VERY_DARK_GREY(64, 64, 
64),
316 RED(255, 0, 0), DARK_RED(128, 0, 0), VERY_DARK_RED(64, 0, 0),
317 YELLOW(255, 255, 0), DARK_YELLOW(128, 128, 0), VERY_DARK_YELLOW(64, 
64, 0),
318 GREEN(0, 255, 0), DARK_GREEN(0, 128, 0), VERY_DARK_GREEN(0, 64, 0),
319 CYAN(0, 255, 255), DARK_CYAN(0, 128, 128), VERY_DARK_CYAN(0, 64, 64),
320 BLUE(0, 0, 255), DARK_BLUE(0, 0, 128), VERY_DARK_BLUE(0, 0, 64),
321 MAGENTA(255, 0, 255), DARK_MAGENTA(128, 0, 128), VERY_DARK_MAGENTA(64,
 0, 64),
322 WHITE(255, 255, 255), BLACK(0, 0, 0), BLANK(0, 0, 0, 0);
323
324 // Thanks to scripticuk and others for updating the key maps
325 // MOTE: The GLUT platform will need updating, open to contributions ;)
326 enum Key
327 {
328 NONE,
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 9
329 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,
330 K0, K1, K2, K3, K4, K5, K6, K7, K8, K9,
331 F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
332 UP, DOWN, LEFT, RIGHT,
333 SPACE, TAB, SHIFT, CTRL, INS, DEL, HOME, END, PGUP, PGDN,
334 BACK, ESCAPE, RETURN, ENTER, PAUSE, SCROLL,
335 NP0, NP1, NP2, NP3, NP4, NP5, NP6, NP7, NP8, NP9,
336 NP_MUL, NP_DIV, NP_ADD, NP_SUB, NP_DECIMAL, PERIOD,
337 EQUALS, COMMA, MINUS,
338 OEM_1, OEM_2, OEM_3, OEM_4, OEM_5, OEM_6, OEM_7, OEM_8,
339 CAPS_LOCK, ENUM_END
340 };
341
342
343
344 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
345 // | olc::vX2d ­ A generic 2D vector type                                 
        |
346 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
347 #if !defined(OLC_IGNORE_VEC2D)
348 template <class T>
349 struct v2d_generic
350 {
351 T x = 0;
352 T y = 0;
353 v2d_generic() : x(0), y(0) {}
354 v2d_generic(T _x, T _y) : x(_x), y(_y) {}
355 v2d_generic(const v2d_generic& v) : x(v.x), y(v.y) {}
356 v2d_generic& operator=(const v2d_generic& v) = default;
357 T mag() const { return T(std::sqrt(x * x + y * y)); }
358 T mag2() const { return x * x + y * y; }
359 v2d_generic  norm() const { T r = 1 / mag(); return v2d_generic(x * r,
 y * r); }
360 v2d_generic  perp() const { return v2d_generic(­y, x); }
361 T dot(const v2d_generic& rhs) const { return this­>x * rhs.x + this­>y
 * rhs.y; }
362 T cross(const v2d_generic& rhs) const { return this­>x * rhs.y ­ this­
>y * rhs.x; }
363 v2d_generic operator +  (const v2d_generic& rhs) const { return 
v2d_generic(this­>x + rhs.x, this­>y + rhs.y); }
364 v2d_generic operator ­ (const v2d_generic& rhs) const { return 
v2d_generic(this­>x ­ rhs.x, this­>y ­ rhs.y); }
365 v2d_generic operator *  (const T& rhs)           const { return 
v2d_generic(this­>x * rhs, this­>y * rhs); }
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 10
366 v2d_generic operator *  (const v2d_generic& rhs) const { return 
v2d_generic(this­>x * rhs.x, this­>y * rhs.y); }
367 v2d_generic operator /  (const T& rhs)           const { return 
v2d_generic(this­>x / rhs, this­>y / rhs); }
368 v2d_generic operator /  (const v2d_generic& rhs) const { return 
v2d_generic(this­>x / rhs.x, this­>y / rhs.y); }
369 v2d_generic& operator += (const v2d_generic& rhs) { this­>x += rhs.x; 
this­>y += rhs.y; return *this; }
370 v2d_generic& operator ­= (const v2d_generic& rhs) { this­>x ­= rhs.x; 
this­>y ­= rhs.y; return *this; }
371 v2d_generic& operator *= (const T& rhs) { this­>x *= rhs; this­>y *= 
rhs; return *this; }
372 v2d_generic& operator /= (const T& rhs) { this­>x /= rhs; this­>y /= 
rhs; return *this; }
373 v2d_generic  operator +  () const { return { +x, +y }; }
374 v2d_generic  operator ­  () const { return { ­x, ­y }; }
375 bool operator == (const v2d_generic& rhs) const { return (this­>x == 
rhs.x && this­>y == rhs.y); }
376 bool operator != (const v2d_generic& rhs) const { return (this­>x != 
rhs.x || this­>y != rhs.y); }
377 const std::string str() const { return std::string("(") + 
std::to_string(this­>x) + "," + std::to_string(this­>y) + ")"; }
378 friend std::ostream& operator << (std::ostream& os, const v2d_generic&
rhs) { os << rhs.str(); return os; }
379 operator v2d_generic<int32_t>() const { return { static_cast<int32_t>
(this­>x), static_cast<int32_t>(this­>y) }; }
380 operator v2d_generic<float>() const { return { static_cast<float>
(this­>x), static_cast<float>(this­>y) }; }
381 operator v2d_generic<double>() const { return { static_cast<double>
(this­>x), static_cast<double>(this­>y) }; }
382 };
383
384 // Note: joshinils has some good suggestions here, but they are 
complicated to implement at this moment, 
385 // however they will appear in a future version of PGE
386 template<class T> inline v2d_generic<T> operator * (const float& lhs, 
const v2d_generic<T>& rhs)
387 {
388 return v2d_generic<T>((T)(lhs * (float)rhs.x), (T)(lhs * (float)
rhs.y));
389 }
390 template<class T> inline v2d_generic<T> operator * (const double& lhs, 
const v2d_generic<T>& rhs)
391 {
392 return v2d_generic<T>((T)(lhs * (double)rhs.x), (T)(lhs * (double)
rhs.y));
393 }
394 template<class T> inline v2d_generic<T> operator * (const int& lhs, const 
v2d_generic<T>& rhs)
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 11
395 {
396 return v2d_generic<T>((T)(lhs * (int)rhs.x), (T)(lhs * (int)rhs.y));
397 }
398 template<class T> inline v2d_generic<T> operator / (const float& lhs, 
const v2d_generic<T>& rhs)
399 {
400 return v2d_generic<T>((T)(lhs / (float)rhs.x), (T)(lhs / (float)
rhs.y));
401 }
402 template<class T> inline v2d_generic<T> operator / (const double& lhs, 
const v2d_generic<T>& rhs)
403 {
404 return v2d_generic<T>((T)(lhs / (double)rhs.x), (T)(lhs / (double)
rhs.y));
405 }
406 template<class T> inline v2d_generic<T> operator / (const int& lhs, const 
v2d_generic<T>& rhs)
407 {
408 return v2d_generic<T>((T)(lhs / (int)rhs.x), (T)(lhs / (int)rhs.y));
409 }
410
411 typedef v2d_generic<int32_t> vi2d;
412 typedef v2d_generic<uint32_t> vu2d;
413 typedef v2d_generic<float> vf2d;
414 typedef v2d_generic<double> vd2d;
415 #endif
416
417
418
419 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
420 // | olc::HWButton ­ Represents the state of a hardware button (mouse/key/
joy)    |
421 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
422 struct HWButton
423 {
424 bool bPressed = false; // Set once during the frame the event occurs
425 bool bReleased = false; // Set once during the frame the event occurs
426 bool bHeld = false; // Set true for all frames between pressed and
 released events
427 };
428
429
430
431 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 12
­­­­­­­O
432 // | olc::ResourcePack ­ A virtual scrambled filesystem to pack your 
assets into  |
433 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
434 struct ResourceBuffer : public std::streambuf
435 {
436 ResourceBuffer(std::ifstream& ifs, uint32_t offset, uint32_t size);
437 std::vector<char> vMemory;
438 };
439
440 class ResourcePack : public std::streambuf
441 {
442 public:
443 ResourcePack();
444 ~ResourcePack();
445 bool AddFile(const std::string& sFile);
446 bool LoadPack(const std::string& sFile, const std::string& sKey);
447 bool SavePack(const std::string& sFile, const std::string& sKey);
448 ResourceBuffer GetFileBuffer(const std::string& sFile);
449 bool Loaded();
450 private:
451 struct sResourceFile { uint32_t nSize; uint32_t nOffset; };
452 std::map<std::string, sResourceFile> mapFiles;
453 std::ifstream baseFile;
454 std::vector<char> scramble(const std::vector<char>& data, const 
std::string& key);
455 std::string makeposix(const std::string& path);
456 };
457
458
459 class ImageLoader
460 {
461 public:
462 ImageLoader() = default;
463 virtual ~ImageLoader() = default;
464 virtual olc::rcode LoadImageResource(olc::Sprite* spr, const 
std::string& sImageFile, olc::ResourcePack* pack) = 0;
465 virtual olc::rcode SaveImageResource(olc::Sprite* spr, const 
std::string& sImageFile) = 0;
466 };
467
468
469 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
470 // | olc::Sprite ­ An image represented by a 2D array of olc::Pixel       
        |
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 13
471 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
472 class Sprite
473 {
474 public:
475 Sprite();
476 Sprite(const std::string& sImageFile, olc::ResourcePack* pack =
nullptr);
477 Sprite(int32_t w, int32_t h);
478 Sprite(const olc::Sprite&) = delete;
479 ~Sprite();
480
481 public:
482 olc::rcode LoadFromFile(const std::string& sImageFile,
olc::ResourcePack* pack = nullptr);
483 olc::rcode LoadFromPGESprFile(const std::string& sImageFile,
olc::ResourcePack* pack = nullptr);
484 olc::rcode SaveToPGESprFile(const std::string& sImageFile);
485
486 public:
487 int32_t width = 0;
488 int32_t height = 0;
489 enum Mode { NORMAL, PERIODIC };
490 enum Flip { NONE = 0, HORIZ = 1, VERT = 2 };
491
492 public:
493 void SetSampleMode(olc::Sprite::Mode mode =
olc::Sprite::Mode::NORMAL);
494 Pixel GetPixel(int32_t x, int32_t y) const;
495 bool SetPixel(int32_t x, int32_t y, Pixel p);
496 Pixel GetPixel(const olc::vi2d& a) const;
497 bool SetPixel(const olc::vi2d& a, Pixel p);
498 Pixel Sample(float x, float y) const;
499 Pixel SampleBL(float u, float v) const;
500 Pixel* GetData();
501 olc::Sprite* Duplicate();
502 olc::Sprite* Duplicate(const olc::vi2d& vPos, const olc::vi2d& vSize);
503 Pixel* pColData = nullptr;
504 Mode modeSample = Mode::NORMAL;
505
506 static std::unique_ptr<olc::ImageLoader> loader;
507 };
508
509 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
510 // | olc::Decal ­ A GPU resident storage of an olc::Sprite
|
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 14
511 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
512 class Decal
513 {
514 public:
515 Decal(olc::Sprite* spr, bool filter = false);
516 virtual ~Decal();
517 void Update();
518
519 public: // But dont touch
520 int32_t id = ­1;
521 olc::Sprite* sprite = nullptr;
522 olc::vf2d vUVScale = { 1.0f, 1.0f };
523 };
524
525 enum class DecalMode
526 {
527 NORMAL,
528 ADDITIVE,
529 MULTIPLICATIVE,
530 STENCIL,
531 ILLUMINATE,
532 };
533
534 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
535 // | olc::Renderable ­ Convenience class to keep a sprite and decal
together |
536 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
537 class Renderable
538 {
539 public:
540 Renderable() = default;
541 olc::rcode Load(const std::string& sFile, ResourcePack* pack =
nullptr, bool filter = false);
542 void Create(uint32_t width, uint32_t height, bool filter = false);
543 olc::Decal* Decal() const;
544 olc::Sprite* Sprite() const;
545
546 private:
547 std::unique_ptr<olc::Sprite> pSprite = nullptr;
548 std::unique_ptr<olc::Decal> pDecal = nullptr;
549 };
550
551
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 15
552 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
553 // | Auxilliary components internal to engine
|
554 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
555
556 struct DecalInstance
557 {
558 olc::Decal* decal = nullptr;
559 olc::vf2d pos[4] = { { 0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f,
0.0f} };
560 olc::vf2d uv[4] = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f,
0.0f} };
561 float w[4] = { 1, 1, 1, 1 };
562 olc::Pixel tint[4] = { olc::WHITE, olc::WHITE, olc::WHITE,
olc::WHITE };
563 olc::DecalMode mode = olc::DecalMode::NORMAL;
564 };
565
566 struct DecalTriangleInstance
567 {
568 olc::vf2d points[3];
569 olc::vf2d texture[3];
570 olc::Pixel colours[3];
571 olc::Decal* decal = nullptr;
572 };
573
574 struct LayerDesc
575 {
576 olc::vf2d vOffset = { 0, 0 };
577 olc::vf2d vScale = { 1, 1 };
578 bool bShow = false;
579 bool bUpdate = false;
580 olc::Sprite* pDrawTarget = nullptr;
581 uint32_t nResID = 0;
582 std::vector<DecalInstance> vecDecalInstance;
583 olc::Pixel tint = olc::WHITE;
584 std::function<void()> funcHook = nullptr;
585 };
586
587 class Renderer
588 {
589 public:
590 virtual ~Renderer() = default;
591 virtual void PrepareDevice() = 0;
592 virtual olc::rcode CreateDevice(std::vector<void*> params, bool
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 16
bFullScreen, bool bVSYNC) = 0;
593 virtual olc::rcode DestroyDevice() = 0;
594 virtual void DisplayFrame() = 0;
595 virtual void PrepareDrawing() = 0;
596 virtual void SetDecalMode(const olc::DecalMode& mode) = 0;
597 virtual void DrawLayerQuad(const olc::vf2d& offset, const
olc::vf2d& scale, const olc::Pixel tint) = 0;
598 virtual void DrawDecalQuad(const olc::DecalInstance& decal) = 0;
599 virtual uint32_t CreateTexture(const uint32_t width, const uint32_t
height, const bool filtered = false) = 0;
600 virtual void UpdateTexture(uint32_t id, olc::Sprite* spr) = 0;
601 virtual uint32_t DeleteTexture(const uint32_t id) = 0;
602 virtual void ApplyTexture(uint32_t id) = 0;
603 virtual void UpdateViewport(const olc::vi2d& pos, const
olc::vi2d& size) = 0;
604 virtual void ClearBuffer(olc::Pixel p, bool bDepth) = 0;
605 static olc::PixelGameEngine* ptrPGE;
606 };
607
608 class Platform
609 {
610 public:
611 virtual ~Platform() = default;
612 virtual olc::rcode ApplicationStartUp() = 0;
613 virtual olc::rcode ApplicationCleanUp() = 0;
614 virtual olc::rcode ThreadStartUp() = 0;
615 virtual olc::rcode ThreadCleanUp() = 0;
616 virtual olc::rcode CreateGraphics(bool bFullScreen, bool bEnableVSYNC,
const olc::vi2d& vViewPos, const olc::vi2d& vViewSize) = 0;
617 virtual olc::rcode CreateWindowPane(const olc::vi2d& vWindowPos,
olc::vi2d& vWindowSize, bool bFullScreen) = 0;
618 virtual olc::rcode SetWindowTitle(const std::string& s) = 0;
619 virtual olc::rcode StartSystemEventLoop() = 0;
620 virtual olc::rcode HandleSystemEvent() = 0;
621 static olc::PixelGameEngine* ptrPGE;
622 };
623
624
625
626 static std::unique_ptr<Renderer> renderer;
627 static std::unique_ptr<Platform> platform;
628 static std::map<size_t, uint8_t> mapKeys;
629
630 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
631 // | olc::PixelGameEngine ­ The main BASE class for your application
|
632 //
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 17
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
633 class PixelGameEngine
634 {
635 public:
636 PixelGameEngine();
637 virtual ~PixelGameEngine();
638 public:
639 olc::rcode Construct(int32_t screen_w, int32_t screen_h, int32_t
pixel_w, int32_t pixel_h,
640 bool full_screen = false, bool vsync = false, bool cohesion =
false);
641 olc::rcode Start();
642
643 public: // User Override Interfaces
644 // Called once on application startup, use to load your resources
645 virtual bool OnUserCreate();
646 // Called every frame, and provides you with a time per frame value
647 virtual bool OnUserUpdate(float fElapsedTime);
648 // Called once on application termination, so you can be one clean
coder
649 virtual bool OnUserDestroy();
650
651 public: // Hardware Interfaces
652 // Returns true if window is currently in focus
653 bool IsFocused() const;
654 // Get the state of a specific keyboard button
655 HWButton GetKey(Key k) const;
656 // Get the state of a specific mouse button
657 HWButton GetMouse(uint32_t b) const;
658 // Get Mouse X coordinate in "pixel" space
659 int32_t GetMouseX() const;
660 // Get Mouse Y coordinate in "pixel" space
661 int32_t GetMouseY() const;
662 // Get Mouse Wheel Delta
663 int32_t GetMouseWheel() const;
664 // Get the mouse in window space
665 const olc::vi2d& GetWindowMouse() const;
666 // Gets the mouse as a vector to keep Tarriest happy
667 const olc::vi2d& GetMousePos() const;
668
669 public: // Utility
670 // Returns the width of the screen in "pixels"
671 int32_t ScreenWidth() const;
672 // Returns the height of the screen in "pixels"
673 int32_t ScreenHeight() const;
674 // Returns the width of the currently selected drawing target in
"pixels"
675 int32_t GetDrawTargetWidth() const;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 18
676 // Returns the height of the currently selected drawing target in
"pixels"
677 int32_t GetDrawTargetHeight() const;
678 // Returns the currently active draw target
679 olc::Sprite* GetDrawTarget() const;
680 // Resize the primary screen sprite
681 void SetScreenSize(int w, int h);
682 // Specify which Sprite should be the target of drawing functions, use
nullptr
683 // to specify the primary screen
684 void SetDrawTarget(Sprite* target);
685 // Gets the current Frames Per Second
686 uint32_t GetFPS() const;
687 // Gets last update of elapsed time
688 float GetElapsedTime() const;
689 // Gets Actual Window size
690 const olc::vi2d& GetWindowSize() const;
691 // Gets pixel scale
692 const olc::vi2d& GetPixelSize() const;
693 // Gets actual pixel scale
694 const olc::vi2d& GetScreenPixelSize() const;
695
696 public: // CONFIGURATION ROUTINES
697 // Layer targeting functions
698 void SetDrawTarget(uint8_t layer);
699 void EnableLayer(uint8_t layer, bool b);
700 void SetLayerOffset(uint8_t layer, const olc::vf2d& offset);
701 void SetLayerOffset(uint8_t layer, float x, float y);
702 void SetLayerScale(uint8_t layer, const olc::vf2d& scale);
703 void SetLayerScale(uint8_t layer, float x, float y);
704 void SetLayerTint(uint8_t layer, const olc::Pixel& tint);
705 void SetLayerCustomRenderFunction( uint8_t layer, std::function<void()>
f);
706
707 std::vector<LayerDesc>& GetLayers();
708 uint32_t CreateLayer();
709
710 // Change the pixel mode for different optimisations
711 // olc::Pixel::NORMAL = No transparency
712 // olc::Pixel::MASK = Transparent if alpha is < 255
713 // olc::Pixel::ALPHA = Full transparency
714 void SetPixelMode(Pixel::Mode m);
715 Pixel::Mode GetPixelMode();
716 // Use a custom blend function
717 void SetPixelMode(std::function<olc::Pixel(const int x, const int y,
const olc::Pixel& pSource, const olc::Pixel& pDest)> pixelMode);
718 // Change the blend factor form between 0.0f to 1.0f;
719 void SetPixelBlend(float fBlend);
720
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 19
721
722
723 public: // DRAWING ROUTINES
724 // Draws a single Pixel
725 virtual bool Draw(int32_t x, int32_t y, Pixel p = olc::WHITE);
726 bool Draw(const olc::vi2d& pos, Pixel p = olc::WHITE);
727 // Draws a line from (x1,y1) to (x2,y2)
728 void DrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, Pixel p
= olc::WHITE, uint32_t pattern = 0xFFFFFFFF);
729 void DrawLine(const olc::vi2d& pos1, const olc::vi2d& pos2, Pixel p =
olc::WHITE, uint32_t pattern = 0xFFFFFFFF);
730 // Draws a circle located at (x,y) with radius
731 void DrawCircle(int32_t x, int32_t y, int32_t radius, Pixel p =
olc::WHITE, uint8_t mask = 0xFF);
732 void DrawCircle(const olc::vi2d& pos, int32_t radius, Pixel p =
olc::WHITE, uint8_t mask = 0xFF);
733 // Fills a circle located at (x,y) with radius
734 void FillCircle(int32_t x, int32_t y, int32_t radius, Pixel p =
olc::WHITE);
735 void FillCircle(const olc::vi2d& pos, int32_t radius, Pixel p =
olc::WHITE);
736 // Draws a rectangle at (x,y) to (x+w,y+h)
737 void DrawRect(int32_t x, int32_t y, int32_t w, int32_t h, Pixel p =
olc::WHITE);
738 void DrawRect(const olc::vi2d& pos, const olc::vi2d& size, Pixel p =
olc::WHITE);
739 // Fills a rectangle at (x,y) to (x+w,y+h)
740 void FillRect(int32_t x, int32_t y, int32_t w, int32_t h, Pixel p =
olc::WHITE);
741 void FillRect(const olc::vi2d& pos, const olc::vi2d& size, Pixel p =
olc::WHITE);
742 // Draws a triangle between points (x1,y1), (x2,y2) and (x3,y3)
743 void DrawTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
int32_t x3, int32_t y3, Pixel p = olc::WHITE);
744 void DrawTriangle(const olc::vi2d& pos1, const olc::vi2d& pos2, const
olc::vi2d& pos3, Pixel p = olc::WHITE);
745 // Flat fills a triangle between points (x1,y1), (x2,y2) and (x3,y3)
746 void FillTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
int32_t x3, int32_t y3, Pixel p = olc::WHITE);
747 void FillTriangle(const olc::vi2d& pos1, const olc::vi2d& pos2, const
olc::vi2d& pos3, Pixel p = olc::WHITE);
748 // Draws an entire sprite at well location (x,y)
749 void DrawSprite(int32_t x, int32_t y, Sprite* sprite, uint32_t scale =
1, uint8_t flip = olc::Sprite::NONE);
750 void DrawSprite(const olc::vi2d& pos, Sprite* sprite, uint32_t scale =
1, uint8_t flip = olc::Sprite::NONE);
751 // Draws an area of a sprite at location (x,y), where the
752 // selected area is (ox,oy) to (ox+w,oy+h)
753 void DrawPartialSprite(int32_t x, int32_t y, Sprite* sprite, int32_t
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 20
ox, int32_t oy, int32_t w, int32_t h, uint32_t scale = 1, uint8_t
flip = olc::Sprite::NONE);
754 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);
755
756 // Decal Quad functions
757 void SetDecalMode(const olc::DecalMode& mode);
758 // Draws a whole decal, with optional scale and tinting
759 void DrawDecal(const olc::vf2d& pos, olc::Decal* decal, const
olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint =
olc::WHITE);
760 // Draws a region of a decal, with optional scale and tinting
761 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);
762 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);
763 // Draws fully user controlled 4 vertices, pos(pixels), uv(pixels),
colours
764 void DrawExplicitDecal(olc::Decal* decal, const olc::vf2d* pos, const
olc::vf2d* uv, const olc::Pixel* col);
765 // Draws a decal with 4 arbitrary points, warping the texture to look
"correct"
766 void DrawWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4],
const olc::Pixel& tint = olc::WHITE);
767 void DrawWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const
olc::Pixel& tint = olc::WHITE);
768 void DrawWarpedDecal(olc::Decal* decal, const std::array<olc::vf2d,
4>& pos, const olc::Pixel& tint = olc::WHITE);
769 // As above, but you can specify a region of a decal source sprite
770 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);
771 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);
772 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);
773 // Draws a decal rotated to specified angle, wit point of rotation
offset
774 void DrawRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const
float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const
olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint =
olc::WHITE);
775 void DrawPartialRotatedDecal(const olc::vf2d& pos, olc::Decal* decal,
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 21
const float fAngle, const olc::vf2d& center, const olc::vf2d& 
source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = 
{ 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE);
776 // Draws a multiline string as a decal, with tiniting and scaling
777 void DrawStringDecal(const olc::vf2d& pos, const std::string& sText, 
const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 
1.0f });
778 void DrawStringPropDecal(const olc::vf2d& pos, const std::string& 
sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = 
{ 1.0f, 1.0f });
779 // Draws a single shaded filled rectangle as a decal
780 void FillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const 
olc::Pixel col = olc::WHITE);
781 // Draws a corner shaded rectangle as a decal
782 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);
783
784 // Draws a single line of text ­ traditional monospaced
785 void DrawString(int32_t x, int32_t y, const std::string& sText, Pixel
col = olc::WHITE, uint32_t scale = 1);
786 void DrawString(const olc::vi2d& pos, const std::string& sText, Pixel
col = olc::WHITE, uint32_t scale = 1);
787 olc::vi2d GetTextSize(const std::string& s);
788
789 // Draws a single line of text ­ non­monospaced
790 void DrawStringProp(int32_t x, int32_t y, const std::string& sText, 
Pixel col = olc::WHITE, uint32_t scale = 1);
791 void DrawStringProp(const olc::vi2d& pos, const std::string& sText, 
Pixel col = olc::WHITE, uint32_t scale = 1);
792 olc::vi2d GetTextSizeProp(const std::string& s);
793
794 // Clears entire draw target to Pixel
795 void Clear(Pixel p);
796 // Clears the rendering back buffer
797 void ClearBuffer(Pixel p, bool bDepth = true);
798
799 public: // Branding
800 std::string sAppName;
801
802 private: // Inner mysterious workings
803 Sprite* pDrawTarget = nullptr;
804 Pixel::Mode nPixelMode = Pixel::NORMAL;
805 float fBlendFactor = 1.0f;
806 olc::vi2d vScreenSize = { 256, 240 };
807 olc::vf2d vInvScreenSize = { 1.0f / 256.0f, 1.0f / 240.0f };
808 olc::vi2d vPixelSize = { 4, 4 };
809 olc::vi2d   vScreenPixelSize = { 4, 4 };
810 olc::vi2d vMousePos = { 0, 0 };
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 22
811 int32_t nMouseWheelDelta = 0;
812 olc::vi2d vMousePosCache = { 0, 0 };
813 olc::vi2d   vMouseWindowPos = { 0, 0 };
814 int32_t nMouseWheelDeltaCache = 0;
815 olc::vi2d vWindowSize = { 0, 0 };
816 olc::vi2d vViewPos = { 0, 0 };
817 olc::vi2d vViewSize = { 0,0 };
818 bool bFullScreen = false;
819 olc::vf2d vPixel = { 1.0f, 1.0f };
820 bool bHasInputFocus = false;
821 bool bHasMouseFocus = false;
822 bool bEnableVSYNC = false;
823 float fFrameTimer = 1.0f;
824 float fLastElapsed = 0.0f;
825 int nFrameCount = 0;
826 Sprite* fontSprite = nullptr;
827 Decal* fontDecal = nullptr;
828 Sprite* pDefaultDrawTarget = nullptr;
829 std::vector<LayerDesc> vLayers;
830 uint8_t nTargetLayer = 0;
831 uint32_t nLastFPS = 0;
832 bool        bPixelCohesion = false;
833 DecalMode   nDecalMode = DecalMode::NORMAL;
834 std::function<olc::Pixel(const int x, const int y, const olc::Pixel&, 
const olc::Pixel&)> funcPixelMode;
835 std::chrono::time_point<std::chrono::system_clock> m_tp1, m_tp2;
836 std::vector<olc::vi2d> vFontSpacing;
837
838 // State of keyboard
839 bool pKeyNewState[256] = { 0 };
840 bool pKeyOldState[256] = { 0 };
841 HWButton pKeyboardState[256] = { 0 };
842
843 // State of mouse
844 bool pMouseNewState[nMouseButtons] = { 0 };
845 bool pMouseOldState[nMouseButtons] = { 0 };
846 HWButton pMouseState[nMouseButtons] = { 0 };
847
848 // The main engine thread
849 void EngineThread();
850
851 // At the very end of this file, chooses which
852 // components to compile
853 void        olc_ConfigureSystem();
854
855 // If anything sets this flag to false, the engine
856 // "should" shut down gracefully
857 static std::atomic<bool> bAtomActive;
858
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 23
859 public:
860 // "Break In" Functions
861 void olc_UpdateMouse(int32_t x, int32_t y);
862 void olc_UpdateMouseWheel(int32_t delta);
863 void olc_UpdateWindowSize(int32_t x, int32_t y);
864 void olc_UpdateViewport();
865 void olc_ConstructFontSheet();
866 void olc_CoreUpdate();
867 void olc_PrepareEngine();
868 void olc_UpdateMouseState(int32_t button, bool state);
869 void olc_UpdateKeyState(int32_t key, bool state);
870 void olc_UpdateMouseFocus(bool state);
871 void olc_UpdateKeyFocus(bool state);
872 void olc_Terminate();
873
874 // NOTE: Items Here are to be deprecated, I have left them in for now
875 // in case you are using them, but they will be removed.
876 // olc::vf2d vSubPixelOffset = { 0.0f, 0.0f };
877
878 friend class PGEX;
879 };
880
881
882
883 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
884 // | PGE EXTENSION BASE CLASS  ­ Permits access to PGE functions from 
extension    |
885 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
886 class PGEX
887 {
888 friend class olc::PixelGameEngine;
889 protected:
890 static PixelGameEngine* pge;
891 };
892 }
893
894 #endif // OLC_PGE_DEF
895
896
897
898
899 /*
900 Object Oriented Mode
901 ~~~~~~~~~~~~~~~~~~~~
902
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 24
903 If the olcPixelGameEngine.h is called from several sources it can cause
904 multiple definitions of objects. To prevent this, ONLY ONE of the pathways
905 to including this file must have OLC_PGE_APPLICATION defined before it. 
This prevents
906 the definitions being duplicated.
907
908 If all else fails, create a file called "olcPixelGameEngine.cpp" with the 
following
909 two lines. Then you can just #include "olcPixelGameEngine.h" as normal 
without worrying
910 about defining things. Dont forget to include that cpp file as part of 
your build!
911
912 #define OLC_PGE_APPLICATION
913 #include "olcPixelGameEngine.h"
914
915 */
916
917
918 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
919 // | START OF OLC_PGE_APPLICATION                                             
    |
920 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
921 #ifdef OLC_PGE_APPLICATION
922 #undef OLC_PGE_APPLICATION
923
924 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
925 // | olcPixelGameEngine INTERFACE IMPLEMENTATION (CORE)                       
    |
926 // | Note: The core implementation is platform independent                    
    |
927 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
928 namespace olc
929 {
930 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
931 // | olc::Pixel IMPLEMENTATION                                            
        |
932 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 25
­­­­­­­O
933 Pixel::Pixel()
934 {
935 r = 0; g = 0; b = 0; a = nDefaultAlpha;
936 }
937
938 Pixel::Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
939 {
940 n = red | (green << 8) | (blue << 16) | (alpha << 24);
941 } // Thanks jarekpelczar 
942
943
944 Pixel::Pixel(uint32_t p)
945 {
946 n = p;
947 }
948
949 bool Pixel::operator==(const Pixel& p) const
950 {
951 return n == p.n;
952 }
953
954 bool Pixel::operator!=(const Pixel& p) const
955 {
956 return n != p.n;
957 }
958
959 Pixel Pixel::operator * (const float i) const
960 {
961 float fR = std::min(255.0f, std::max(0.0f,  float(r) * i));
962 float fG = std::min(255.0f, std::max(0.0f,  float(g) * i));
963 float fB = std::min(255.0f, std::max(0.0f,  float(b) * i));
964 return Pixel(uint8_t(fR), uint8_t(fG), uint8_t(fB), a);
965 }
966
967 Pixel Pixel::operator / (const float i) const
968 {
969 float fR = std::min(255.0f, std::max(0.0f,  float(r) / i));
970 float fG = std::min(255.0f, std::max(0.0f,  float(g) / i));
971 float fB = std::min(255.0f, std::max(0.0f,  float(b) / i));
972 return Pixel(uint8_t(fR), uint8_t(fG), uint8_t(fB), a);
973 }
974
975 Pixel& Pixel::operator *=(const float i)
976 {
977 this­>r = uint8_t(std::min(255.0f, std::max(0.0f,  float(r) * i)));
978 this­>g = uint8_t(std::min(255.0f, std::max(0.0f,  float(g) * i)));
979 this­>b = uint8_t(std::min(255.0f, std::max(0.0f,  float(b) * i)));
980 return *this;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 26
981 }
982
983 Pixel& Pixel::operator /=(const float i)
984 {
985 this­>r = uint8_t(std::min(255.0f, std::max(0.0f,  float(r) / i)));
986 this­>g = uint8_t(std::min(255.0f, std::max(0.0f,  float(g) / i)));
987 this­>b = uint8_t(std::min(255.0f, std::max(0.0f,  float(b) / i)));
988 return *this;
989 }
990
991 Pixel Pixel::operator + (const Pixel& p) const
992 {
993 uint8_t nR = uint8_t(std::min(255, std::max(0, int(r) + int(p.r))));
994 uint8_t nG = uint8_t(std::min(255, std::max(0, int(g) + int(p.g))));
995 uint8_t nB = uint8_t(std::min(255, std::max(0, int(b) + int(p.b))));
996 return Pixel(nR, nG, nB, a);
997 }
998
999 Pixel Pixel::operator ­ (const Pixel& p) const
1000 {
1001 uint8_t nR = uint8_t(std::min(255, std::max(0, int(r) ­ int(p.r))));
1002 uint8_t nG = uint8_t(std::min(255, std::max(0, int(g) ­ int(p.g))));
1003 uint8_t nB = uint8_t(std::min(255, std::max(0, int(b) ­ int(p.b))));
1004 return Pixel(nR, nG, nB, a);
1005 }
1006
1007 Pixel& Pixel::operator += (const Pixel& p)
1008 {
1009 this­>r = uint8_t(std::min(255, std::max(0, int(r) + int(p.r))));
1010 this­>g = uint8_t(std::min(255, std::max(0, int(g) + int(p.g))));
1011 this­>b = uint8_t(std::min(255, std::max(0, int(b) + int(p.b))));
1012 return *this;
1013 }
1014
1015 Pixel& Pixel::operator ­= (const Pixel& p)
1016 {
1017 this­>r = uint8_t(std::min(255, std::max(0, int(r) + int(p.r))));
1018 this­>g = uint8_t(std::min(255, std::max(0, int(g) + int(p.g))));
1019 this­>b = uint8_t(std::min(255, std::max(0, int(b) + int(p.b))));
1020 return *this;
1021 }
1022
1023 Pixel Pixel::inv() const
1024 {
1025 uint8_t nR = uint8_t(std::min(255, std::max(0, 255 ­  int(r))));
1026 uint8_t nG = uint8_t(std::min(255, std::max(0, 255 ­  int(g))));
1027 uint8_t nB = uint8_t(std::min(255, std::max(0, 255 ­  int(b))));
1028 return Pixel(nR, nG, nB, a);
1029 }
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 27
1030
1031 Pixel PixelF(float red, float green, float blue, float alpha)
1032 {
1033 return Pixel(uint8_t(red * 255.0f), uint8_t(green * 255.0f), uint8_t
(blue * 255.0f), uint8_t(alpha * 255.0f));
1034 }
1035
1036 Pixel PixelLerp(const olc::Pixel& p1, const olc::Pixel& p2, float t)
1037 {
1038 return (p1 * t) + p2 * (1.0f ­ t);
1039 }
1040
1041 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
1042 // | olc::Sprite IMPLEMENTATION                                           
        |
1043 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
1044 Sprite::Sprite()
1045 {
1046 pColData = nullptr; width = 0; height = 0;
1047 }
1048
1049 Sprite::Sprite(const std::string& sImageFile, olc::ResourcePack* pack)
1050 {
1051 LoadFromFile(sImageFile, pack);
1052 }
1053
1054 Sprite::Sprite(int32_t w, int32_t h)
1055 {
1056 if (pColData) delete[] pColData;
1057 width = w; height = h;
1058 pColData = new Pixel[width * height];
1059 for (int32_t i = 0; i < width * height; i++)
1060 pColData[i] = Pixel();
1061 }
1062
1063 Sprite::~Sprite()
1064 {
1065 if (pColData) delete[] pColData;
1066 }
1067
1068
1069 olc::rcode Sprite::LoadFromPGESprFile(const std::string& sImageFile, 
olc::ResourcePack* pack)
1070 {
1071 if (pColData) delete[] pColData;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 28
1072 auto ReadData = [&](std::istream& is)
1073 {
1074 is.read((char*)&width, sizeof(int32_t));
1075 is.read((char*)&height, sizeof(int32_t));
1076 pColData = new Pixel[width * height];
1077 is.read((char*)pColData, (size_t)width * (size_t)height * sizeof
(uint32_t));
1078 };
1079
1080 // These are essentially Memory Surfaces represented by olc::Sprite
1081 // which load very fast, but are completely uncompressed
1082 if (pack == nullptr)
1083 {
1084 std::ifstream ifs;
1085 ifs.open(sImageFile, std::ifstream::binary);
1086 if (ifs.is_open())
1087 {
1088 ReadData(ifs);
1089 return olc::OK;
1090 }
1091 else
1092 return olc::FAIL;
1093 }
1094 else
1095 {
1096 ResourceBuffer rb = pack­>GetFileBuffer(sImageFile);
1097 std::istream is(&rb);
1098 ReadData(is);
1099 return olc::OK;
1100 }
1101 return olc::FAIL;
1102 }
1103
1104 olc::rcode Sprite::SaveToPGESprFile(const std::string& sImageFile)
1105 {
1106 if (pColData == nullptr) return olc::FAIL;
1107
1108 std::ofstream ofs;
1109 ofs.open(sImageFile, std::ifstream::binary);
1110 if (ofs.is_open())
1111 {
1112 ofs.write((char*)&width, sizeof(int32_t));
1113 ofs.write((char*)&height, sizeof(int32_t));
1114 ofs.write((char*)pColData, (size_t)width * (size_t)height * sizeof
(uint32_t));
1115 ofs.close();
1116 return olc::OK;
1117 }
1118
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 29
1119 return olc::FAIL;
1120 }
1121
1122 void Sprite::SetSampleMode(olc::Sprite::Mode mode)
1123 {
1124 modeSample = mode;
1125 }
1126
1127 Pixel Sprite::GetPixel(const olc::vi2d& a) const
1128 {
1129 return GetPixel(a.x, a.y);
1130 }
1131
1132 bool Sprite::SetPixel(const olc::vi2d& a, Pixel p)
1133 {
1134 return SetPixel(a.x, a.y, p);
1135 }
1136
1137 Pixel Sprite::GetPixel(int32_t x, int32_t y) const
1138 {
1139 if (modeSample == olc::Sprite::Mode::NORMAL)
1140 {
1141 if (x >= 0 && x < width && y >= 0 && y < height)
1142 return pColData[y * width + x];
1143 else
1144 return Pixel(0, 0, 0, 0);
1145 }
1146 else
1147 {
1148 return pColData[abs(y % height) * width + abs(x % width)];
1149 }
1150 }
1151
1152 bool Sprite::SetPixel(int32_t x, int32_t y, Pixel p)
1153 {
1154 if (x >= 0 && x < width && y >= 0 && y < height)
1155 {
1156 pColData[y * width + x] = p;
1157 return true;
1158 }
1159 else
1160 return false;
1161 }
1162
1163 Pixel Sprite::Sample(float x, float y) const
1164 {
1165 int32_t sx = std::min((int32_t)((x * (float)width)), width ­ 1);
1166 int32_t sy = std::min((int32_t)((y * (float)height)), height ­ 1);
1167 return GetPixel(sx, sy);
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 30
1168 }
1169
1170 Pixel Sprite::SampleBL(float u, float v) const
1171 {
1172 u = u * width ­ 0.5f;
1173 v = v * height ­ 0.5f;
1174 int x = (int)floor(u); // cast to int rounds toward zero, not downward
1175 int y = (int)floor(v); // Thanks @joshinils
1176 float u_ratio = u ­ x;
1177 float v_ratio = v ­ y;
1178 float u_opposite = 1 ­ u_ratio;
1179 float v_opposite = 1 ­ v_ratio;
1180
1181 olc::Pixel p1 = GetPixel(std::max(x, 0), std::max(y, 0));
1182 olc::Pixel p2 = GetPixel(std::min(x + 1, ( int)width ­ 1), std::max(y,
0));
1183 olc::Pixel p3 = GetPixel(std::max(x, 0), std::min(y + 1, ( int)height ­
1));
1184 olc::Pixel p4 = GetPixel(std::min(x + 1, ( int)width ­ 1), std::min(y +
1, (int)height ­ 1));
1185
1186 return olc::Pixel(
1187 (uint8_t)((p1.r * u_opposite + p2.r * u_ratio) * v_opposite +
(p3.r * u_opposite + p4.r * u_ratio) * v_ratio),
1188 (uint8_t)((p1.g * u_opposite + p2.g * u_ratio) * v_opposite +
(p3.g * u_opposite + p4.g * u_ratio) * v_ratio),
1189 (uint8_t)((p1.b * u_opposite + p2.b * u_ratio) * v_opposite +
(p3.b * u_opposite + p4.b * u_ratio) * v_ratio));
1190 }
1191
1192 Pixel* Sprite::GetData()
1193 {
1194 return pColData;
1195 }
1196
1197
1198 olc::rcode Sprite::LoadFromFile(const std::string& sImageFile,
olc::ResourcePack* pack)
1199 {
1200 UNUSED(pack);
1201 return loader­>LoadImageResource(this, sImageFile, pack);
1202 }
1203
1204 olc::Sprite* Sprite::Duplicate()
1205 {
1206 olc::Sprite* spr = new olc::Sprite(width, height);
1207 std::memcpy(spr­>GetData(), GetData(), width * height * sizeof
(olc::Pixel));
1208 spr­>modeSample = modeSample;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 31
1209 return spr;
1210 }
1211
1212 olc::Sprite* Sprite::Duplicate(const olc::vi2d& vPos, const olc::vi2d& 
vSize)
1213 {
1214 olc::Sprite* spr = new olc::Sprite(vSize.x, vSize.y);
1215 for (int y = 0; y < vSize.y; y++)
1216 for (int x = 0; x < vSize.x; x++)
1217 spr­>SetPixel(x, y, GetPixel( vPos.x + x, vPos.y + y));
1218 return spr;
1219 }
1220
1221 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
1222 // | olc::Decal IMPLEMENTATION                                            
       |
1223 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
1224 Decal::Decal(olc::Sprite* spr, bool filter)
1225 {
1226 id = ­1;
1227 if (spr == nullptr) return;
1228 sprite = spr;
1229 id = renderer­>CreateTexture(sprite­>width, sprite­>height,  filter);
1230 Update();
1231 }
1232
1233 void Decal::Update()
1234 {
1235 if (sprite == nullptr) return;
1236 vUVScale = { 1.0f / float(sprite­>width), 1.0f / float(sprite­
>height) };
1237 renderer­>ApplyTexture(id);
1238 renderer­>UpdateTexture(id, sprite);
1239 }
1240
1241 Decal::~Decal()
1242 {
1243 if (id != ­1)
1244 {
1245 renderer­>DeleteTexture(id);
1246 id = ­1;
1247 }
1248 }
1249
1250 void Renderable::Create(uint32_t width, uint32_t height, bool filter)
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 32
1251 {
1252 pSprite = std::make_unique<olc::Sprite>(width, height);
1253 pDecal = std::make_unique<olc::Decal>(pSprite.get(), filter);
1254 }
1255
1256 olc::rcode Renderable::Load(const std::string& sFile, ResourcePack* pack, 
bool filter)
1257 {
1258 pSprite = std::make_unique<olc::Sprite>();
1259 if (pSprite­>LoadFromFile(sFile, pack) == olc::rcode::OK)
1260 {
1261 pDecal = std::make_unique<olc::Decal>(pSprite.get(), filter);
1262 return olc::rcode::OK;
1263 }
1264 else
1265 {
1266 pSprite.release();
1267 pSprite = nullptr;
1268 return olc::rcode::NO_FILE;
1269 }
1270 }
1271
1272 olc::Decal* Renderable::Decal() const
1273 {
1274 return pDecal.get();
1275 }
1276
1277 olc::Sprite* Renderable::Sprite() const
1278 {
1279 return pSprite.get();
1280 }
1281
1282 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
1283 // | olc::ResourcePack IMPLEMENTATION                                     
        |
1284 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
1285
1286
1287 //=============================================================
1288 // Resource Packs ­ Allows you to store files in one large 
1289 // scrambled file ­ Thanks MaGetzUb for debugging a null char in 
std::stringstream bug
1290 ResourceBuffer::ResourceBuffer(std::ifstream& ifs, uint32_t offset, 
uint32_t size)
1291 {
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 33
1292 vMemory.resize(size);
1293 ifs.seekg(offset); ifs.read(vMemory.data(), vMemory.size());
1294 setg(vMemory.data(), vMemory.data(), vMemory.data() +  size);
1295 }
1296
1297 ResourcePack::ResourcePack() { }
1298 ResourcePack::~ResourcePack() { baseFile.close(); }
1299
1300 bool ResourcePack::AddFile(const std::string& sFile)
1301 {
1302 const std::string file = makeposix(sFile);
1303
1304 if (_gfs::exists(file))
1305 {
1306 sResourceFile e;
1307 e.nSize = (uint32_t)_gfs::file_size(file);
1308 e.nOffset = 0; // Unknown at this stage
1309 mapFiles[file] = e;
1310 return true;
1311 }
1312 return false;
1313 }
1314
1315 bool ResourcePack::LoadPack(const std::string& sFile, const std::string& 
sKey)
1316 {
1317 // Open the resource file
1318 baseFile.open(sFile, std::ifstream::binary);
1319 if (!baseFile.is_open()) return false;
1320
1321 // 1) Read Scrambled index
1322 uint32_t nIndexSize = 0;
1323 baseFile.read((char*)&nIndexSize, sizeof(uint32_t));
1324
1325 std::vector<char> buffer(nIndexSize);
1326 for (uint32_t j = 0; j < nIndexSize; j++)
1327 buffer[j] = baseFile.get();
1328
1329 std::vector<char> decoded = scramble(buffer,  sKey);
1330 size_t pos = 0;
1331 auto read = [&decoded, &pos](char* dst, size_t size) {
1332 memcpy((void*)dst, (const void*)(decoded.data() + pos), size);
1333 pos += size;
1334 };
1335
1336 auto get = [&read]() ­> int {
1337 char c;
1338 read(&c, 1);
1339 return c;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 34
1340 };
1341
1342 // 2) Read Map
1343 uint32_t nMapEntries = 0;
1344 read((char*)&nMapEntries, sizeof(uint32_t));
1345 for (uint32_t i = 0; i < nMapEntries; i++)
1346 {
1347 uint32_t nFilePathSize = 0;
1348 read((char*)&nFilePathSize, sizeof(uint32_t));
1349
1350 std::string sFileName(nFilePathSize, ' ');
1351 for (uint32_t j = 0; j < nFilePathSize; j++)
1352 sFileName[j] = get();
1353
1354 sResourceFile e;
1355 read((char*)&e.nSize, sizeof(uint32_t));
1356 read((char*)&e.nOffset, sizeof(uint32_t));
1357 mapFiles[sFileName] = e;
1358 }
1359
1360 // Don't close base file! we will provide a stream
1361 // pointer when the file is requested
1362 return true;
1363 }
1364
1365 bool ResourcePack::SavePack(const std::string& sFile, const std::string& 
sKey)
1366 {
1367 // Create/Overwrite the resource file
1368 std::ofstream ofs(sFile, std::ofstream::binary);
1369 if (!ofs.is_open()) return false;
1370
1371 // Iterate through map
1372 uint32_t nIndexSize = 0; // Unknown for now
1373 ofs.write((char*)&nIndexSize, sizeof(uint32_t));
1374 uint32_t nMapSize = uint32_t(mapFiles.size());
1375 ofs.write((char*)&nMapSize, sizeof(uint32_t));
1376 for (auto& e : mapFiles)
1377 {
1378 // Write the path of the file
1379 size_t nPathSize = e.first.size();
1380 ofs.write((char*)&nPathSize, sizeof(uint32_t));
1381 ofs.write(e.first.c_str(), nPathSize);
1382
1383 // Write the file entry properties
1384 ofs.write((char*)&e.second.nSize, sizeof(uint32_t));
1385 ofs.write((char*)&e.second.nOffset, sizeof(uint32_t));
1386 }
1387
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 35
1388 // 2) Write the individual Data
1389 std::streampos offset = ofs.tellp();
1390 nIndexSize = (uint32_t)offset;
1391 for (auto& e : mapFiles)
1392 {
1393 // Store beginning of file offset within resource pack file
1394 e.second.nOffset = (uint32_t)offset;
1395
1396 // Load the file to be added
1397 std::vector<uint8_t> vBuffer(e.second.nSize);
1398 std::ifstream i(e.first, std::ifstream::binary);
1399 i.read((char*)vBuffer.data(), e.second.nSize);
1400 i.close();
1401
1402 // Write the loaded file into resource pack file
1403 ofs.write((char*)vBuffer.data(), e.second.nSize);
1404 offset += e.second.nSize;
1405 }
1406
1407 // 3) Scramble Index
1408 std::vector<char> stream;
1409 auto write = [&stream](const char* data, size_t size) {
1410 size_t sizeNow = stream.size();
1411 stream.resize(sizeNow + size);
1412 memcpy(stream.data() + sizeNow,  data, size);
1413 };
1414
1415 // Iterate through map
1416 write((char*)&nMapSize, sizeof(uint32_t));
1417 for (auto& e : mapFiles)
1418 {
1419 // Write the path of the file
1420 size_t nPathSize = e.first.size();
1421 write((char*)&nPathSize, sizeof(uint32_t));
1422 write(e.first.c_str(), nPathSize);
1423
1424 // Write the file entry properties
1425 write((char*)&e.second.nSize, sizeof(uint32_t));
1426 write((char*)&e.second.nOffset, sizeof(uint32_t));
1427 }
1428 std::vector<char> sIndexString = scramble(stream,  sKey);
1429 uint32_t nIndexStringLen = uint32_t(sIndexString.size());
1430 // 4) Rewrite Map (it has been updated with offsets now)
1431 // at start of file
1432 ofs.seekp(0, std::ios::beg);
1433 ofs.write((char*)&nIndexStringLen, sizeof(uint32_t));
1434 ofs.write(sIndexString.data(), nIndexStringLen);
1435 ofs.close();
1436 return true;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 36
1437 }
1438
1439 ResourceBuffer ResourcePack::GetFileBuffer(const std::string& sFile)
1440 {
1441 return ResourceBuffer(baseFile, mapFiles[sFile].nOffset, mapFiles
[sFile].nSize);
1442 }
1443
1444 bool ResourcePack::Loaded()
1445 {
1446 return baseFile.is_open();
1447 }
1448
1449 std::vector<char> ResourcePack::scramble(const std::vector<char>& data, 
const std::string& key)
1450 {
1451 if (key.empty()) return data;
1452 std::vector<char> o;
1453 size_t c = 0;
1454 for (auto s : data) o.push_back(s ^ key[(c++) % key.size()]);
1455 return o;
1456 };
1457
1458 std::string ResourcePack::makeposix(const std::string& path)
1459 {
1460 std::string o;
1461 for (auto s : path) o += std::string(1, s == '\\' ? '/' : s);
1462 return o;
1463 };
1464
1465 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
1466 // | olc::PixelGameEngine IMPLEMENTATION                                  
        |
1467 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­­­­­O
1468 PixelGameEngine::PixelGameEngine()
1469 {
1470 sAppName = "Undefined";
1471 olc::PGEX::pge = this;
1472
1473 // Bring in relevant Platform & Rendering systems depending
1474 // on compiler parameters
1475 olc_ConfigureSystem();
1476 }
1477
1478 PixelGameEngine::~PixelGameEngine()
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 37
1479 {}
1480
1481
1482 olc::rcode PixelGameEngine::Construct(int32_t screen_w, int32_t screen_h, 
int32_t pixel_w, int32_t pixel_h, bool full_screen, bool vsync, bool 
cohesion)
1483 {
1484 bPixelCohesion = cohesion;
1485 vScreenSize = { screen_w, screen_h };
1486 vInvScreenSize = { 1.0f / float(screen_w), 1.0f / float(screen_h) };
1487 vPixelSize = { pixel_w, pixel_h };
1488 vWindowSize = vScreenSize * vPixelSize;
1489 bFullScreen = full_screen;
1490 bEnableVSYNC = vsync;
1491 vPixel = 2.0f / vScreenSize;
1492
1493 if (vPixelSize.x <= 0 || vPixelSize.y <= 0 || vScreenSize.x <= 0 || 
vScreenSize.y <= 0)
1494 return olc::FAIL;
1495
1496
1497 return olc::OK;
1498 }
1499
1500
1501 void PixelGameEngine::SetScreenSize(int w, int h)
1502 {
1503 vScreenSize = { w, h };
1504 vInvScreenSize = { 1.0f / float(w), 1.0f / float(h) };
1505 for (auto& layer : vLayers)
1506 {
1507 delete layer.pDrawTarget; // Erase existing layer sprites
1508 layer.pDrawTarget = new Sprite(vScreenSize.x, vScreenSize.y);
1509 layer.bUpdate = true;
1510 }
1511 SetDrawTarget(nullptr);
1512
1513 renderer­>ClearBuffer(olc::BLACK, true);
1514 renderer­>DisplayFrame();
1515 renderer­>ClearBuffer(olc::BLACK, true);
1516 renderer­>UpdateViewport(vViewPos, vViewSize);
1517 }
1518
1519 #if !defined(PGE_USE_CUSTOM_START)
1520 olc::rcode PixelGameEngine::Start()
1521 {
1522 if (platform­>ApplicationStartUp() != olc:: OK) return olc::FAIL;
1523
1524 // Construct the window
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 38
1525 if (platform­>CreateWindowPane({ 30,30 }, vWindowSize, bFullScreen) !=
 olc::OK) return olc::FAIL;
1526 olc_UpdateWindowSize(vWindowSize.x, vWindowSize.y);
1527
1528 // Start the thread
1529 bAtomActive = true;
1530 std::thread t = std::thread(&PixelGameEngine::EngineThread, this);
1531
1532 // Some implementations may form an event loop here
1533 platform­>StartSystemEventLoop();
1534
1535 // Wait for thread to be exited
1536 t.join();
1537
1538 if (platform­>ApplicationCleanUp() != olc:: OK) return olc::FAIL;
1539
1540 return olc::OK;
1541 }
1542 #endif
1543
1544 void PixelGameEngine::SetDrawTarget(Sprite* target)
1545 {
1546 if (target)
1547 {
1548 pDrawTarget = target;
1549 }
1550 else
1551 {
1552 nTargetLayer = 0;
1553 pDrawTarget = vLayers[0].pDrawTarget;
1554 }
1555 }
1556
1557 void PixelGameEngine::SetDrawTarget(uint8_t layer)
1558 {
1559 if (layer < vLayers.size())
1560 {
1561 pDrawTarget = vLayers[layer].pDrawTarget;
1562 vLayers[layer].bUpdate = true;
1563 nTargetLayer = layer;
1564 }
1565 }
1566
1567 void PixelGameEngine::EnableLayer(uint8_t layer, bool b)
1568 {
1569 if (layer < vLayers.size()) vLayers[layer].bShow = b;
1570 }
1571
1572 void PixelGameEngine::SetLayerOffset(uint8_t layer, const olc::vf2d& 
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 39
offset)
1573 {
1574 SetLayerOffset(layer, offset.x, offset.y);
1575 }
1576
1577 void PixelGameEngine::SetLayerOffset(uint8_t layer, float x, float y)
1578 {
1579 if (layer < vLayers.size()) vLayers[layer].vOffset = { x, y };
1580 }
1581
1582 void PixelGameEngine::SetLayerScale(uint8_t layer, const olc::vf2d& scale)
1583 {
1584 SetLayerScale(layer, scale.x, scale.y);
1585 }
1586
1587 void PixelGameEngine::SetLayerScale(uint8_t layer, float x, float y)
1588 {
1589 if (layer < vLayers.size()) vLayers[layer].vScale = { x, y };
1590 }
1591
1592 void PixelGameEngine::SetLayerTint(uint8_t layer, const olc::Pixel& tint)
1593 {
1594 if (layer < vLayers.size()) vLayers[layer].tint = tint;
1595 }
1596
1597 void PixelGameEngine::SetLayerCustomRenderFunction( uint8_t layer, 
std::function<void()> f)
1598 {
1599 if (layer < vLayers.size()) vLayers[layer].funcHook = f;
1600 }
1601
1602 std::vector<LayerDesc>& PixelGameEngine::GetLayers()
1603 {
1604 return vLayers;
1605 }
1606
1607 uint32_t PixelGameEngine::CreateLayer()
1608 {
1609 LayerDesc ld;
1610 ld.pDrawTarget = new olc::Sprite(vScreenSize.x, vScreenSize.y);
1611 ld.nResID = renderer­>CreateTexture(vScreenSize.x, vScreenSize.y);
1612 renderer­>UpdateTexture(ld.nResID, ld.pDrawTarget);
1613 vLayers.push_back(ld);
1614 return uint32_t(vLayers.size()) ­ 1;
1615 }
1616
1617 Sprite* PixelGameEngine::GetDrawTarget() const
1618 {
1619 return pDrawTarget;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 40
1620 }
1621
1622 int32_t PixelGameEngine::GetDrawTargetWidth() const
1623 {
1624 if (pDrawTarget)
1625 return pDrawTarget­>width;
1626 else
1627 return 0;
1628 }
1629
1630 int32_t PixelGameEngine::GetDrawTargetHeight() const
1631 {
1632 if (pDrawTarget)
1633 return pDrawTarget­>height;
1634 else
1635 return 0;
1636 }
1637
1638 uint32_t PixelGameEngine::GetFPS() const
1639 {
1640 return nLastFPS;
1641 }
1642
1643 bool PixelGameEngine::IsFocused() const
1644 {
1645 return bHasInputFocus;
1646 }
1647
1648 HWButton PixelGameEngine::GetKey(Key k) const
1649 {
1650 return pKeyboardState[k];
1651 }
1652
1653 HWButton PixelGameEngine::GetMouse(uint32_t b) const
1654 {
1655 return pMouseState[b];
1656 }
1657
1658 int32_t PixelGameEngine::GetMouseX() const
1659 {
1660 return vMousePos.x;
1661 }
1662
1663 int32_t PixelGameEngine::GetMouseY() const
1664 {
1665 return vMousePos.y;
1666 }
1667
1668 const olc::vi2d& PixelGameEngine::GetMousePos() const
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 41
1669 {
1670 return vMousePos;
1671 }
1672
1673 int32_t PixelGameEngine::GetMouseWheel() const
1674 {
1675 return nMouseWheelDelta;
1676 }
1677
1678 int32_t PixelGameEngine::ScreenWidth() const
1679 {
1680 return vScreenSize.x;
1681 }
1682
1683 int32_t PixelGameEngine::ScreenHeight() const
1684 {
1685 return vScreenSize.y;
1686 }
1687
1688 float PixelGameEngine::GetElapsedTime() const
1689 {
1690 return fLastElapsed;
1691 }
1692
1693 const olc::vi2d& PixelGameEngine::GetWindowSize() const
1694 {
1695 return vWindowSize;
1696 }
1697
1698 const olc::vi2d& PixelGameEngine::GetPixelSize() const
1699 {
1700 return vPixelSize;
1701 }
1702
1703 const olc::vi2d& PixelGameEngine::GetScreenPixelSize() const
1704 {
1705 return vScreenPixelSize;
1706 }
1707
1708 const olc::vi2d& PixelGameEngine::GetWindowMouse() const
1709 {
1710 return vMouseWindowPos;
1711 }
1712
1713
1714 bool PixelGameEngine::Draw(const olc::vi2d& pos, Pixel p)
1715 {
1716 return Draw(pos.x, pos.y, p);
1717 }
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 42
1718
1719 // This is it, the critical function that plots a pixel
1720 bool PixelGameEngine::Draw(int32_t x, int32_t y, Pixel p)
1721 {
1722 if (!pDrawTarget) return false;
1723
1724 if (nPixelMode == Pixel::NORMAL)
1725 {
1726 return pDrawTarget­>SetPixel(x, y, p);
1727 }
1728
1729 if (nPixelMode == Pixel::MASK)
1730 {
1731 if (p.a == 255)
1732 return pDrawTarget­>SetPixel(x, y, p);
1733 }
1734
1735 if (nPixelMode == Pixel::ALPHA)
1736 {
1737 Pixel d = pDrawTarget­>GetPixel(x, y);
1738 float a = (float)(p.a / 255.0f) * fBlendFactor;
1739 float c = 1.0f ­ a;
1740 float r = a * (float)p.r + c * (float)d.r;
1741 float g = a * (float)p.g + c * (float)d.g;
1742 float b = a * (float)p.b + c * (float)d.b;
1743 return pDrawTarget­>SetPixel(x, y, Pixel((uint8_t)r, (uint8_t)g, 
(uint8_t)b/*, (uint8_t)(p.a * fBlendFactor)*/ ));
1744 }
1745
1746 if (nPixelMode == Pixel::CUSTOM)
1747 {
1748 return pDrawTarget­>SetPixel(x, y, funcPixelMode(x, y, p, 
pDrawTarget­>GetPixel(x, y)));
1749 }
1750
1751 return false;
1752 }
1753
1754
1755 void PixelGameEngine::DrawLine(const olc::vi2d& pos1, const olc::vi2d& 
pos2, Pixel p, uint32_t pattern)
1756 {
1757 DrawLine(pos1.x, pos1.y, pos2.x, pos2.y, p, pattern);
1758 }
1759
1760 void PixelGameEngine::DrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t
 y2, Pixel p, uint32_t pattern)
1761 {
1762 int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 43
1763 dx = x2 ­ x1; dy = y2 ­ y1;
1764
1765 auto rol = [&](void) { pattern = (pattern << 1) | (pattern >> 31); 
return pattern & 1; };
1766
1767 // straight lines idea by gurkanctn
1768 if (dx == 0) // Line is vertical
1769 {
1770 if (y2 < y1) std::swap(y1, y2);
1771 for (y = y1; y <= y2; y++) if (rol()) Draw(x1, y, p);
1772 return;
1773 }
1774
1775 if (dy == 0) // Line is horizontal
1776 {
1777 if (x2 < x1) std::swap(x1, x2);
1778 for (x = x1; x <= x2; x++) if (rol()) Draw(x, y1, p);
1779 return;
1780 }
1781
1782 // Line is Funk­aye
1783 dx1 = abs(dx); dy1 = abs(dy);
1784 px = 2 * dy1 ­ dx1; py = 2 * dx1 ­ dy1;
1785 if (dy1 <= dx1)
1786 {
1787 if (dx >= 0)
1788 {
1789 x = x1; y = y1; xe = x2;
1790 }
1791 else
1792 {
1793 x = x2; y = y2; xe = x1;
1794 }
1795
1796 if (rol()) Draw(x, y, p);
1797
1798 for (i = 0; x < xe; i++)
1799 {
1800 x = x + 1;
1801 if (px < 0)
1802 px = px + 2 * dy1;
1803 else
1804 {
1805 if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) y = y + 1; 
else y = y ­ 1;
1806 px = px + 2 * (dy1 ­ dx1);
1807 }
1808 if (rol()) Draw(x, y, p);
1809 }
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 44
1810 }
1811 else
1812 {
1813 if (dy >= 0)
1814 {
1815 x = x1; y = y1; ye = y2;
1816 }
1817 else
1818 {
1819 x = x2; y = y2; ye = y1;
1820 }
1821
1822 if (rol()) Draw(x, y, p);
1823
1824 for (i = 0; y < ye; i++)
1825 {
1826 y = y + 1;
1827 if (py <= 0)
1828 py = py + 2 * dx1;
1829 else
1830 {
1831 if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) x = x + 1; 
else x = x ­ 1;
1832 py = py + 2 * (dx1 ­ dy1);
1833 }
1834 if (rol()) Draw(x, y, p);
1835 }
1836 }
1837 }
1838
1839 void PixelGameEngine::DrawCircle(const olc::vi2d& pos, int32_t radius, 
Pixel p, uint8_t mask)
1840 {
1841 DrawCircle(pos.x, pos.y, radius, p, mask);
1842 }
1843
1844 void PixelGameEngine::DrawCircle(int32_t x, int32_t y, int32_t radius, 
Pixel p, uint8_t mask)
1845 { // Thanks to IanM­Matrix1 #PR121
1846 if (radius < 0 || x < ­radius || y < ­radius || x ­ GetDrawTargetWidth
() > radius || y ­ GetDrawTargetHeight() > radius)
1847 return;
1848
1849 if (radius > 0)
1850 {
1851 int x0 = 0;
1852 int y0 = radius;
1853 int d = 3 ­ 2 * radius;
1854
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 45
1855 while (y0 >= x0) // only formulate 1/8 of circle
1856 {
1857 // Draw even octants
1858 if (mask & 0x01) Draw(x + x0, y ­ y0, p);// Q6 ­ upper right 
right
1859 if (mask & 0x04) Draw(x + y0, y + x0, p);// Q4 ­ lower lower 
right
1860 if (mask & 0x10) Draw(x ­ x0, y + y0, p);// Q2 ­ lower left 
left
1861 if (mask & 0x40) Draw(x ­ y0, y ­ x0, p);// Q0 ­ upper upper 
left
1862 if (x0 != 0 && x0 != y0)
1863 {
1864 if (mask & 0x02) Draw(x + y0, y ­ x0, p);// Q7 ­ upper 
upper right
1865 if (mask & 0x08) Draw(x + x0, y + y0, p);// Q5 ­ lower 
right right
1866 if (mask & 0x20) Draw(x ­ y0, y + x0, p);// Q3 ­ lower 
lower left
1867 if (mask & 0x80) Draw(x ­ x0, y ­ y0, p);// Q1 ­ upper 
left left
1868 }
1869
1870 if (d < 0)
1871 d += 4 * x0++ + 6;
1872 else
1873 d += 4 * (x0++ ­ y0­­) + 10;
1874 }
1875 }
1876 else
1877 Draw(x, y, p);
1878 }
1879
1880 void PixelGameEngine::FillCircle(const olc::vi2d& pos, int32_t radius, 
Pixel p)
1881 {
1882 FillCircle(pos.x, pos.y, radius, p);
1883 }
1884
1885 void PixelGameEngine::FillCircle(int32_t x, int32_t y, int32_t radius, 
Pixel p)
1886 { // Thanks to IanM­Matrix1 #PR121
1887 if (radius < 0 || x < ­radius || y < ­radius || x ­ GetDrawTargetWidth
() > radius || y ­ GetDrawTargetHeight() > radius)
1888 return;
1889
1890 if (radius > 0)
1891 {
1892 int x0 = 0;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 46
1893 int y0 = radius;
1894 int d = 3 ­ 2 * radius;
1895
1896 auto drawline = [&](int sx, int ex, int y)
1897 {
1898 for (int x = sx; x <= ex; x++)
1899 Draw(x, y, p);
1900 };
1901
1902 while (y0 >= x0)
1903 {
1904 drawline(x ­ y0, x + y0, y ­ x0);
1905 if (x0 > 0) drawline(x ­ y0, x + y0, y + x0);
1906
1907 if (d < 0)
1908 d += 4 * x0++ + 6;
1909 else
1910 {
1911 if (x0 != y0)
1912 {
1913 drawline(x ­ x0, x + x0, y ­ y0);
1914 drawline(x ­ x0, x + x0, y + y0);
1915 }
1916 d += 4 * (x0++ ­ y0­­) + 10;
1917 }
1918 }
1919 }
1920 else
1921 Draw(x, y, p);
1922 }
1923
1924 void PixelGameEngine::DrawRect(const olc::vi2d& pos, const olc::vi2d& 
size, Pixel p)
1925 {
1926 DrawRect(pos.x, pos.y, size.x, size.y, p);
1927 }
1928
1929 void PixelGameEngine::DrawRect(int32_t x, int32_t y, int32_t w, int32_t h,
Pixel p)
1930 {
1931 DrawLine(x, y, x + w, y, p);
1932 DrawLine(x + w, y, x + w, y + h, p);
1933 DrawLine(x + w, y + h, x, y + h, p);
1934 DrawLine(x, y + h, x, y, p);
1935 }
1936
1937 void PixelGameEngine::Clear(Pixel p)
1938 {
1939 int pixels = GetDrawTargetWidth() * GetDrawTargetHeight();
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 47
1940 Pixel* m = GetDrawTarget()­>GetData();
1941 for (int i = 0; i < pixels; i++) m[i]  = p;
1942 }
1943
1944 void PixelGameEngine::ClearBuffer(Pixel p, bool bDepth)
1945 {
1946 renderer­>ClearBuffer(p, bDepth);
1947 }
1948
1949 void PixelGameEngine::FillRect(const olc::vi2d& pos, const olc::vi2d& 
size, Pixel p)
1950 {
1951 FillRect(pos.x, pos.y, size.x, size.y, p);
1952 }
1953
1954 void PixelGameEngine::FillRect(int32_t x, int32_t y, int32_t w, int32_t h,
Pixel p)
1955 {
1956 int32_t x2 = x + w;
1957 int32_t y2 = y + h;
1958
1959 if (x < 0) x = 0;
1960 if (x >= (int32_t)GetDrawTargetWidth()) x = (int32_t)
GetDrawTargetWidth();
1961 if (y < 0) y = 0;
1962 if (y >= (int32_t)GetDrawTargetHeight()) y = (int32_t)
GetDrawTargetHeight();
1963
1964 if (x2 < 0) x2 = 0;
1965 if (x2 >= (int32_t)GetDrawTargetWidth()) x2 = ( int32_t)
GetDrawTargetWidth();
1966 if (y2 < 0) y2 = 0;
1967 if (y2 >= (int32_t)GetDrawTargetHeight()) y2 = ( int32_t)
GetDrawTargetHeight();
1968
1969 for (int i = x; i < x2; i++)
1970 for (int j = y; j < y2; j++)
1971 Draw(i, j, p);
1972 }
1973
1974 void PixelGameEngine::DrawTriangle(const olc::vi2d& pos1, const olc::vi2d&
pos2, const olc::vi2d& pos3, Pixel p)
1975 {
1976 DrawTriangle(pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y, p);
1977 }
1978
1979 void PixelGameEngine::DrawTriangle(int32_t x1, int32_t y1, int32_t x2, 
int32_t y2, int32_t x3, int32_t y3, Pixel p)
1980 {
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 48
1981 DrawLine(x1, y1, x2, y2, p);
1982 DrawLine(x2, y2, x3, y3, p);
1983 DrawLine(x3, y3, x1, y1, p);
1984 }
1985
1986 void PixelGameEngine::FillTriangle(const olc::vi2d& pos1, const olc::vi2d&
pos2, const olc::vi2d& pos3, Pixel p)
1987 {
1988 FillTriangle(pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y, p);
1989 }
1990
1991 // https://www.avrfreaks.net/sites/default/files/triangles.c
1992 void PixelGameEngine::FillTriangle(int32_t x1, int32_t y1, int32_t x2, 
int32_t y2, int32_t x3, int32_t y3, Pixel p)
1993 {
1994 auto drawline = [&](int sx, int ex, int ny) { for (int i = sx; i <= 
ex; i++) Draw(i, ny, p); };
1995
1996 int t1x, t2x, y, minx, maxx, t1xp, t2xp;
1997 bool changed1 = false;
1998 bool changed2 = false;
1999 int signx1, signx2, dx1, dy1, dx2, dy2;
2000 int e1, e2;
2001 // Sort vertices
2002 if (y1 > y2) { std::swap(y1, y2); std::swap(x1, x2); }
2003 if (y1 > y3) { std::swap(y1, y3); std::swap(x1, x3); }
2004 if (y2 > y3) { std::swap(y2, y3); std::swap(x2, x3); }
2005
2006 t1x = t2x = x1; y = y1;   // Starting points
2007 dx1 = (int)(x2 ­ x1);
2008 if (dx1 < 0) { dx1 = ­dx1; signx1 = ­1; }
2009 else signx1 = 1;
2010 dy1 = (int)(y2 ­ y1);
2011
2012 dx2 = (int)(x3 ­ x1);
2013 if (dx2 < 0) { dx2 = ­dx2; signx2 = ­1; }
2014 else signx2 = 1;
2015 dy2 = (int)(y3 ­ y1);
2016
2017 if (dy1 > dx1) { std::swap(dx1, dy1); changed1 =  true; }
2018 if (dy2 > dx2) { std::swap(dy2, dx2); changed2 =  true; }
2019
2020 e2 = (int)(dx2 >> 1);
2021 // Flat top, just process the second half
2022 if (y1 == y2) goto next;
2023 e1 = (int)(dx1 >> 1);
2024
2025 for (int i = 0; i < dx1;) {
2026 t1xp = 0; t2xp = 0;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 49
2027 if (t1x < t2x) { minx = t1x; maxx = t2x; }
2028 else { minx = t2x; maxx = t1x; }
2029 // process first line until y value is about to change
2030 while (i < dx1) {
2031 i++;
2032 e1 += dy1;
2033 while (e1 >= dx1) {
2034 e1 ­= dx1;
2035 if (changed1) t1xp = signx1;//t1x += signx1;
2036 else          goto next1;
2037 }
2038 if (changed1) break;
2039 else t1x += signx1;
2040 }
2041 // Move line
2042 next1:
2043 // process second line until y value is about to change
2044 while (1) {
2045 e2 += dy2;
2046 while (e2 >= dx2) {
2047 e2 ­= dx2;
2048 if (changed2) t2xp = signx2;//t2x += signx2;
2049 else          goto next2;
2050 }
2051 if (changed2)     break;
2052 else              t2x += signx2;
2053 }
2054 next2:
2055 if (minx > t1x) minx = t1x;
2056 if (minx > t2x) minx = t2x;
2057 if (maxx < t1x) maxx = t1x;
2058 if (maxx < t2x) maxx = t2x;
2059 drawline(minx, maxx, y);     // Draw line from min to max points 
found on the y
2060 // Now increase y
2061 if (!changed1) t1x += signx1;
2062 t1x += t1xp;
2063 if (!changed2) t2x += signx2;
2064 t2x += t2xp;
2065 y += 1;
2066 if (y == y2) break;
2067
2068 }
2069 next:
2070 // Second half
2071 dx1 = (int)(x3 ­ x2); if (dx1 < 0) { dx1 = ­dx1; signx1 = ­1; }
2072 else signx1 = 1;
2073 dy1 = (int)(y3 ­ y2);
2074 t1x = x2;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 50
2075
2076 if (dy1 > dx1) {   // swap values
2077 std::swap(dy1, dx1);
2078 changed1 = true;
2079 }
2080 else changed1 = false;
2081
2082 e1 = (int)(dx1 >> 1);
2083
2084 for (int i = 0; i <= dx1; i++) {
2085 t1xp = 0; t2xp = 0;
2086 if (t1x < t2x) { minx = t1x; maxx = t2x; }
2087 else { minx = t2x; maxx = t1x; }
2088 // process first line until y value is about to change
2089 while (i < dx1) {
2090 e1 += dy1;
2091 while (e1 >= dx1) {
2092 e1 ­= dx1;
2093 if (changed1) { t1xp = signx1;  break; }//t1x += signx1;
2094 else          goto next3;
2095 }
2096 if (changed1) break;
2097 else    t1x += signx1;
2098 if (i < dx1) i++;
2099 }
2100 next3:
2101 // process second line until y value is about to change
2102 while (t2x != x3) {
2103 e2 += dy2;
2104 while (e2 >= dx2) {
2105 e2 ­= dx2;
2106 if (changed2) t2xp = signx2;
2107 else          goto next4;
2108 }
2109 if (changed2)     break;
2110 else              t2x += signx2;
2111 }
2112 next4:
2113
2114 if (minx > t1x) minx = t1x;
2115 if (minx > t2x) minx = t2x;
2116 if (maxx < t1x) maxx = t1x;
2117 if (maxx < t2x) maxx = t2x;
2118 drawline(minx, maxx, y);
2119 if (!changed1) t1x += signx1;
2120 t1x += t1xp;
2121 if (!changed2) t2x += signx2;
2122 t2x += t2xp;
2123 y += 1;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 51
2124 if (y > y3) return;
2125 }
2126 }
2127
2128 void PixelGameEngine::DrawSprite(const olc::vi2d& pos, Sprite* sprite, 
uint32_t scale, uint8_t flip)
2129 {
2130 DrawSprite(pos.x, pos.y, sprite, scale, flip);
2131 }
2132
2133 void PixelGameEngine::DrawSprite(int32_t x, int32_t y, Sprite* sprite, 
uint32_t scale, uint8_t flip)
2134 {
2135 if (sprite == nullptr)
2136 return;
2137
2138 int32_t fxs = 0, fxm = 1, fx = 0;
2139 int32_t fys = 0, fym = 1, fy = 0;
2140 if (flip & olc::Sprite::Flip::HORIZ) { fxs = sprite­>width ­ 1; fxm = 
­1; }
2141 if (flip & olc::Sprite::Flip::VERT) { fys = sprite­>height ­ 1; fym = 
­1; }
2142
2143 if (scale > 1)
2144 {
2145 fx = fxs;
2146 for (int32_t i = 0; i < sprite­>width; i++, fx += fxm)
2147 {
2148 fy = fys;
2149 for (int32_t j = 0; j < sprite­>height; j++, fy += fym)
2150 for (uint32_t is = 0; is < scale; is++)
2151 for (uint32_t js = 0; js < scale; js++)
2152 Draw(x + (i * scale) + is, y + (j * scale) + js, 
sprite­>GetPixel(fx, fy));
2153 }
2154 }
2155 else
2156 {
2157 fx = fxs;
2158 for (int32_t i = 0; i < sprite­>width; i++, fx += fxm)
2159 {
2160 fy = fys;
2161 for (int32_t j = 0; j < sprite­>height; j++, fy += fym)
2162 Draw(x + i, y + j, sprite­>GetPixel(fx, fy));
2163 }
2164 }
2165 }
2166
2167 void PixelGameEngine::DrawPartialSprite(const olc::vi2d& pos, Sprite* 
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 52
sprite, const olc::vi2d& sourcepos, const olc::vi2d& size, uint32_t
scale, uint8_t flip)
2168 {
2169 DrawPartialSprite(pos.x, pos.y, sprite, sourcepos.x, sourcepos.y, 
size.x, size.y, scale, flip);
2170 }
2171
2172 void PixelGameEngine::DrawPartialSprite(int32_t x, int32_t y, Sprite* 
sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, uint32_t scale, 
uint8_t flip)
2173 {
2174 if (sprite == nullptr)
2175 return;
2176
2177 int32_t fxs = 0, fxm = 1, fx = 0;
2178 int32_t fys = 0, fym = 1, fy = 0;
2179 if (flip & olc::Sprite::Flip::HORIZ) { fxs = w ­ 1; fxm = ­1; }
2180 if (flip & olc::Sprite::Flip::VERT) { fys = h ­ 1; fym = ­1; }
2181
2182 if (scale > 1)
2183 {
2184 fx = fxs;
2185 for (int32_t i = 0; i < w; i++, fx += fxm)
2186 {
2187 fy = fys;
2188 for (int32_t j = 0; j < h; j++, fy += fym)
2189 for (uint32_t is = 0; is < scale; is++)
2190 for (uint32_t js = 0; js < scale; js++)
2191 Draw(x + (i * scale) + is, y + (j * scale) + js, 
sprite­>GetPixel(fx + ox, fy + oy));
2192 }
2193 }
2194 else
2195 {
2196 fx = fxs;
2197 for (int32_t i = 0; i < w; i++, fx += fxm)
2198 {
2199 fy = fys;
2200 for (int32_t j = 0; j < h; j++, fy += fym)
2201 Draw(x + i, y + j, sprite­>GetPixel(fx + ox, fy + oy));
2202 }
2203 }
2204 }
2205
2206 void PixelGameEngine::SetDecalMode(const olc::DecalMode& mode)
2207 {
2208 nDecalMode = mode;
2209 }
2210
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 53
2211 void PixelGameEngine::DrawPartialDecal(const olc::vf2d& pos, olc::Decal*
decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const
olc::vf2d& scale, const olc::Pixel& tint)
2212 {
2213 olc::vf2d vScreenSpacePos =
2214 {
2215 (pos.x * vInvScreenSize.x) * 2.0f ­ 1.0f,
2216 ((pos.y * vInvScreenSize.y) * 2.0f ­ 1.0f) * ­1.0f
2217 };
2218
2219 olc::vf2d vScreenSpaceDim =
2220 {
2221 vScreenSpacePos.x + (2.0f * source_size.x * vInvScreenSize.x) *
scale.x,
2222 vScreenSpacePos.y ­ (2.0f * source_size.y * vInvScreenSize.y) *
scale.y
2223 };
2224
2225 DecalInstance di; di.decal = decal; di.tint[0] = tint;
2226
2227 di.pos[0] = { vScreenSpacePos.x, vScreenSpacePos.y };
2228 di.pos[1] = { vScreenSpacePos.x, vScreenSpaceDim.y };
2229 di.pos[2] = { vScreenSpaceDim.x, vScreenSpaceDim.y };
2230 di.pos[3] = { vScreenSpaceDim.x, vScreenSpacePos.y };
2231
2232 olc::vf2d uvtl = source_pos * decal­>vUVScale;
2233 olc::vf2d uvbr = uvtl + (source_size * decal­>vUVScale);
2234 di.uv[0] = { uvtl.x, uvtl.y }; di.uv[1] = { uvtl.x, uvbr.y };
2235 di.uv[2] = { uvbr.x, uvbr.y }; di.uv[3] = { uvbr.x, uvtl.y };
2236 di.mode = nDecalMode;
2237 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
2238 }
2239
2240 void PixelGameEngine::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)
2241 {
2242 olc::vf2d vScreenSpacePos =
2243 {
2244 (pos.x * vInvScreenSize.x) * 2.0f ­ 1.0f,
2245 ((pos.y * vInvScreenSize.y) * 2.0f ­ 1.0f) * ­1.0f
2246 };
2247
2248 olc::vf2d vScreenSpaceDim =
2249 {
2250 vScreenSpacePos.x + (2.0f * size.x * vInvScreenSize.x),
2251 vScreenSpacePos.y ­ (2.0f * size.y * vInvScreenSize.y)
2252 };
2253
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 54
2254 DecalInstance di; di.decal = decal; di.tint[0] = tint;
2255
2256 di.pos[0] = { vScreenSpacePos.x, vScreenSpacePos.y };
2257 di.pos[1] = { vScreenSpacePos.x, vScreenSpaceDim.y };
2258 di.pos[2] = { vScreenSpaceDim.x, vScreenSpaceDim.y };
2259 di.pos[3] = { vScreenSpaceDim.x, vScreenSpacePos.y };
2260
2261 olc::vf2d uvtl = source_pos * decal­>vUVScale;
2262 olc::vf2d uvbr = uvtl + (source_size * decal­>vUVScale);
2263 di.uv[0] = { uvtl.x, uvtl.y }; di.uv[1] = { uvtl.x, uvbr.y };
2264 di.uv[2] = { uvbr.x, uvbr.y }; di.uv[3] = { uvbr.x, uvtl.y };
2265 di.mode = nDecalMode;
2266 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
2267 }
2268
2269
2270 void PixelGameEngine::DrawDecal(const olc::vf2d& pos, olc::Decal* decal,
const olc::vf2d& scale, const olc::Pixel& tint)
2271 {
2272 olc::vf2d vScreenSpacePos =
2273 {
2274 (pos.x * vInvScreenSize.x) * 2.0f ­ 1.0f,
2275 ((pos.y * vInvScreenSize.y) * 2.0f ­ 1.0f) * ­1.0f
2276 };
2277
2278 olc::vf2d vScreenSpaceDim =
2279 {
2280 vScreenSpacePos.x + (2.0f * ( float(decal­>sprite­>width) *
vInvScreenSize.x)) * scale.x,
2281 vScreenSpacePos.y ­ (2.0f * (float(decal­>sprite­>height) *
vInvScreenSize.y)) * scale.y
2282 };
2283
2284 DecalInstance di;
2285 di.decal = decal;
2286 di.tint[0] = tint;
2287 di.pos[0] = { vScreenSpacePos.x, vScreenSpacePos.y };
2288 di.pos[1] = { vScreenSpacePos.x, vScreenSpaceDim.y };
2289 di.pos[2] = { vScreenSpaceDim.x, vScreenSpaceDim.y };
2290 di.pos[3] = { vScreenSpaceDim.x, vScreenSpacePos.y };
2291 di.mode = nDecalMode;
2292 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
2293 }
2294
2295 void PixelGameEngine::DrawRotatedDecal(const olc::vf2d& pos, olc::Decal*
decal, const float fAngle, const olc::vf2d& center, const olc::vf2d&
scale, const olc::Pixel& tint)
2296 {
2297 DecalInstance di;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 55
2298 di.decal = decal;
2299 di.tint[0] = tint;
2300 di.pos[0] = (olc::vf2d(0.0f, 0.0f) ­ center) * scale;
2301 di.pos[1] = (olc::vf2d(0.0f, float(decal­>sprite­>height)) ­ center) *
scale;
2302 di.pos[2] = (olc::vf2d(float(decal­>sprite­>width), float(decal­
>sprite­>height)) ­ center) * scale;
2303 di.pos[3] = (olc::vf2d(float(decal­>sprite­>width), 0.0f) ­ center) *
scale;
2304 float c = cos(fAngle), s = sin(fAngle);
2305 for (int i = 0; i < 4; i++)
2306 {
2307 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);
2308 di.pos[i] = di.pos[i] * vInvScreenSize * 2.0f ­ olc::vf2d(1.0f,
1.0f);
2309 di.pos[i].y *= ­1.0f;
2310 }
2311 di.mode = nDecalMode;
2312 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
2313 }
2314
2315 void PixelGameEngine::DrawExplicitDecal(olc::Decal* decal, const
olc::vf2d* pos, const olc::vf2d* uv, const olc::Pixel* col)
2316 {
2317 DecalInstance di;
2318 di.decal = decal;
2319 for (int i = 0; i < 4; i++)
2320 {
2321 di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f ­ 1.0f, ((pos
[i].y * vInvScreenSize.y) * 2.0f ­ 1.0f) * ­1.0f };
2322 di.uv[i] = uv[i];
2323 di.tint[i] = col[i];
2324 }
2325 di.mode = nDecalMode;
2326 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
2327 }
2328
2329 void PixelGameEngine::FillRectDecal(const olc::vf2d& pos, const olc::vf2d&
size, const olc::Pixel col)
2330 {
2331 std::array<olc::vf2d, 4> points = { { {pos}, {pos.x, pos.y + size.y},
{pos + size}, {pos.x + size.x, pos.y} } };
2332 std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0},{0,0}} };
2333 std::array<olc::Pixel, 4> cols = { {col, col, col, col} };
2334 DrawExplicitDecal(nullptr, points.data(), uvs.data(), cols.data());
2335 }
2336
2337 void PixelGameEngine::GradientFillRectDecal(const olc::vf2d& pos, const
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 56
olc::vf2d& size, const olc::Pixel colTL, const olc::Pixel colBL, const
olc::Pixel colBR, const olc::Pixel colTR)
2338 {
2339 std::array<olc::vf2d, 4> points = { { {pos}, {pos.x, pos.y + size.y},
{pos + size}, {pos.x + size.x, pos.y} } };
2340 std::array<olc::vf2d, 4> uvs = { {{0,0},{0,0},{0,0},{0,0}} };
2341 std::array<olc::Pixel, 4> cols = { {colTL, colBL, colBR, colTR} };
2342 DrawExplicitDecal(nullptr, points.data(), uvs.data(), cols.data());
2343 }
2344
2345
2346 void PixelGameEngine::DrawPartialRotatedDecal(const olc::vf2d& pos,
olc::Decal* decal, const float fAngle, const olc::vf2d& center, const
olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d&
scale, const olc::Pixel& tint)
2347 {
2348 DecalInstance di;
2349 di.decal = decal;
2350 di.tint[0] = tint;
2351 di.pos[0] = (olc::vf2d(0.0f, 0.0f) ­ center) * scale;
2352 di.pos[1] = (olc::vf2d(0.0f, source_size.y) ­ center) * scale;
2353 di.pos[2] = (olc::vf2d(source_size.x, source_size.y) ­ center) *
scale;
2354 di.pos[3] = (olc::vf2d(source_size.x, 0.0f) ­ center) * scale;
2355 float c = cos(fAngle), s = sin(fAngle);
2356 for (int i = 0; i < 4; i++)
2357 {
2358 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);
2359 di.pos[i] = di.pos[i] * vInvScreenSize * 2.0f ­ olc::vf2d(1.0f,
1.0f);
2360 di.pos[i].y *= ­1.0f;
2361 }
2362
2363 olc::vf2d uvtl = source_pos * decal­>vUVScale;
2364 olc::vf2d uvbr = uvtl + (source_size * decal­>vUVScale);
2365 di.uv[0] = { uvtl.x, uvtl.y }; di.uv[1] = { uvtl.x, uvbr.y };
2366 di.uv[2] = { uvbr.x, uvbr.y }; di.uv[3] = { uvbr.x, uvtl.y };
2367 di.mode = nDecalMode;
2368 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
2369 }
2370
2371 void PixelGameEngine::DrawPartialWarpedDecal(olc:: Decal* decal, const
olc::vf2d* pos, const olc::vf2d& source_pos, const olc::vf2d&
source_size, const olc::Pixel& tint)
2372 {
2373 DecalInstance di;
2374 di.decal = decal;
2375 di.tint[0] = tint;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 57
2376 olc::vf2d center;
2377 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));
2378 if (rd != 0)
2379 {
2380 olc::vf2d uvtl = source_pos * decal­>vUVScale;
2381 olc::vf2d uvbr = uvtl + (source_size * decal­>vUVScale);
2382 di.uv[0] = { uvtl.x, uvtl.y }; di.uv[1]  = { uvtl.x, uvbr.y };
2383 di.uv[2] = { uvbr.x, uvbr.y }; di.uv[3]  = { uvbr.x, uvtl.y };
2384
2385 rd = 1.0f / rd;
2386 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;
2387 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;
2388 if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center  = pos
[0] + rn * (pos[2] ­ pos[0]);
2389 float d[4]; for (int i = 0; i < 4; i++) d[i] = (pos[i] ­
center).mag();
2390 for (int i = 0; i < 4; i++)
2391 {
2392 float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i
 + 2) & 3];
2393 di.uv[i] *= q; di.w[i] *= q;
2394 di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f  ­ 1.0f, 
((pos[i].y * vInvScreenSize.y) * 2.0f ­ 1.0f) * ­1.0f };
2395 }
2396 di.mode = nDecalMode;
2397 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
2398 }
2399 }
2400
2401 void PixelGameEngine::DrawWarpedDecal(olc::Decal* decal, const olc::vf2d* 
pos, const olc::Pixel& tint)
2402 {
2403 // Thanks Nathan Reed, a brilliant article explaining whats going on 
here
2404 // http://www.reedbeta.com/blog/quadrilateral­interpolation­part­1/
2405 DecalInstance di;
2406 di.decal = decal;
2407 di.tint[0] = tint;
2408 olc::vf2d center;
2409 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));
2410 if (rd != 0)
2411 {
2412 rd = 1.0f / rd;
2413 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;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 58
2414 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;
2415 if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center  = pos
[0] + rn * (pos[2] ­ pos[0]);
2416 float d[4]; for (int i = 0; i < 4; i++) d[i] = (pos[i] ­
center).mag();
2417 for (int i = 0; i < 4; i++)
2418 {
2419 float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i
 + 2) & 3];
2420 di.uv[i] *= q; di.w[i] *= q;
2421 di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f  ­ 1.0f, 
((pos[i].y * vInvScreenSize.y) * 2.0f ­ 1.0f) * ­1.0f };
2422 }
2423 di.mode = nDecalMode;
2424 vLayers[nTargetLayer].vecDecalInstance.push_back(di);
2425 }
2426 }
2427
2428 void PixelGameEngine::DrawWarpedDecal(olc::Decal* decal, const 
std::array<olc::vf2d, 4>& pos, const olc::Pixel& tint)
2429 {
2430 DrawWarpedDecal(decal, pos.data(), tint);
2431 }
2432
2433 void PixelGameEngine::DrawWarpedDecal(olc::Decal* decal, const olc::vf2d
(&pos)[4], const olc::Pixel& tint)
2434 {
2435 DrawWarpedDecal(decal, &pos[0], tint);
2436 }
2437
2438 void PixelGameEngine::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)
2439 {
2440 DrawPartialWarpedDecal(decal, pos.data(), source_pos, source_size, 
tint);
2441 }
2442
2443 void PixelGameEngine::DrawPartialWarpedDecal(olc:: Decal* decal, const 
olc::vf2d(&pos)[4], const olc::vf2d& source_pos, const olc::vf2d& 
source_size, const olc::Pixel& tint)
2444 {
2445 DrawPartialWarpedDecal(decal, &pos[0], source_pos, source_size, tint);
2446 }
2447
2448 void PixelGameEngine::DrawStringDecal(const olc::vf2d& pos, const 
std::string& sText, const Pixel col, const olc::vf2d& scale)
2449 {
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 59
2450 olc::vf2d spos = { 0.0f, 0.0f };
2451 for (auto c : sText)
2452 {
2453 if (c == '\n')
2454 {
2455 spos.x = 0; spos.y += 8.0f *  scale.y;
2456 }
2457 else
2458 {
2459 int32_t ox = (c ­ 32) % 16;
2460 int32_t oy = (c ­ 32) / 16;
2461 DrawPartialDecal(pos + spos, fontDecal, { float(ox) * 8.0f, 
float(oy) * 8.0f }, { 8.0f, 8.0f },  scale, col);
2462 spos.x += 8.0f * scale.x;
2463 }
2464 }
2465 }
2466
2467 void PixelGameEngine::DrawStringPropDecal(const olc::vf2d& pos, const 
std::string& sText, const Pixel col, const olc::vf2d& scale)
2468 {
2469 olc::vf2d spos = { 0.0f, 0.0f };
2470 for (auto c : sText)
2471 {
2472 if (c == '\n')
2473 {
2474 spos.x = 0; spos.y += 8.0f *  scale.y;
2475 }
2476 else
2477 {
2478 int32_t ox = (c ­ 32) % 16;
2479 int32_t oy = (c ­ 32) / 16;
2480 DrawPartialDecal(pos + spos, fontDecal, { float(ox) * 8.0f + 
float(vFontSpacing[c ­ 32].x), float(oy) * 8.0f }, { float
(vFontSpacing[c ­ 32].y), 8.0f }, scale, col);
2481 spos.x += float(vFontSpacing[c ­ 32].y) * scale.x;
2482 }
2483 }
2484 }
2485
2486 olc::vi2d PixelGameEngine::GetTextSize(const std::string& s)
2487 {
2488 olc::vi2d size = { 0,1 };
2489 olc::vi2d pos = { 0,1 };
2490 for (auto c : s)
2491 {
2492 if (c == '\n') { pos.y++;  pos.x = 0; }
2493 else pos.x++;
2494 size.x = std::max(size.x, pos.x);
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 60
2495 size.y = std::max(size.y, pos.y);
2496 }
2497 return size * 8;
2498 }
2499
2500 void PixelGameEngine::DrawString(const olc::vi2d& pos, const std::string& 
sText, Pixel col, uint32_t scale)
2501 {
2502 DrawString(pos.x, pos.y, sText, col, scale);
2503 }
2504
2505 void PixelGameEngine::DrawString(int32_t x, int32_t y, const std::string& 
sText, Pixel col, uint32_t scale)
2506 {
2507 int32_t sx = 0;
2508 int32_t sy = 0;
2509 Pixel::Mode m = nPixelMode;
2510 // Thanks @tucna, spotted bug with col.ALPHA :P
2511 if (col.a != 255) SetPixelMode(Pixel::ALPHA);
2512 else SetPixelMode(Pixel::MASK);
2513 for (auto c : sText)
2514 {
2515 if (c == '\n')
2516 {
2517 sx = 0; sy += 8 * scale;
2518 }
2519 else
2520 {
2521 int32_t ox = (c ­ 32) % 16;
2522 int32_t oy = (c ­ 32) / 16;
2523
2524 if (scale > 1)
2525 {
2526 for (uint32_t i = 0; i < 8; i++)
2527 for (uint32_t j = 0; j < 8; j++)
2528 if (fontSprite­>GetPixel(i + ox * 8, j + oy * 8).r
 > 0)
2529 for (uint32_t is = 0; is < scale; is++)
2530 for (uint32_t js = 0; js < scale; js++)
2531 Draw(x + sx + (i * scale) + is, y + sy
 + (j * scale) + js, col);
2532 }
2533 else
2534 {
2535 for (uint32_t i = 0; i < 8; i++)
2536 for (uint32_t j = 0; j < 8; j++)
2537 if (fontSprite­>GetPixel(i + ox * 8, j + oy * 8).r
 > 0)
2538 Draw(x + sx + i, y + sy + j, col);
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 61
2539 }
2540 sx += 8 * scale;
2541 }
2542 }
2543 SetPixelMode(m);
2544 }
2545
2546 olc::vi2d PixelGameEngine::GetTextSizeProp(const std::string& s)
2547 {
2548 olc::vi2d size = { 0,1 };
2549 olc::vi2d pos = { 0,1 };
2550 for (auto c : s)
2551 {
2552 if (c == '\n') { pos.y += 8;  pos.x = 0; }
2553 else pos.x += vFontSpacing[c ­ 32].y;
2554 size.x = std::max(size.x, pos.x);
2555 size.y = std::max(size.y, pos.y);
2556 }
2557
2558 size.y *= 8;
2559 return size;
2560 }
2561
2562 void PixelGameEngine::DrawStringProp(const olc::vi2d& pos, const 
std::string& sText, Pixel col, uint32_t scale)
2563 {
2564 DrawStringProp(pos.x, pos.y, sText, col, scale);
2565 }
2566
2567 void PixelGameEngine::DrawStringProp(int32_t x, int32_t y, const 
std::string& sText, Pixel col, uint32_t scale)
2568 {
2569 int32_t sx = 0;
2570 int32_t sy = 0;
2571 Pixel::Mode m = nPixelMode;
2572
2573 if (col.a != 255) SetPixelMode(Pixel::ALPHA);
2574 else SetPixelMode(Pixel::MASK);
2575 for (auto c : sText)
2576 {
2577 if (c == '\n')
2578 {
2579 sx = 0; sy += 8 * scale;
2580 }
2581 else
2582 {
2583 int32_t ox = (c ­ 32) % 16;
2584 int32_t oy = (c ­ 32) / 16;
2585
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 62
2586 if (scale > 1)
2587 {
2588 for (int32_t i = 0; i < vFontSpacing[c ­ 32].y; i++)
2589 for (int32_t j = 0; j < 8; j++)
2590 if (fontSprite­>GetPixel(i + ox * 8 + vFontSpacing
[c ­ 32].x, j + oy * 8).r > 0)
2591 for (int32_t is = 0; is < int(scale); is++)
2592 for (int32_t js = 0; js < int(scale); js+
+)
2593 Draw(x + sx + (i * scale) + is, y + sy
 + (j * scale) + js, col);
2594 }
2595 else
2596 {
2597 for (int32_t i = 0; i < vFontSpacing[c ­ 32].y; i++)
2598 for (int32_t j = 0; j < 8; j++)
2599 if (fontSprite­>GetPixel(i + ox * 8 + vFontSpacing
[c ­ 32].x, j + oy * 8).r > 0)
2600 Draw(x + sx + i, y + sy + j, col);
2601 }
2602 sx += vFontSpacing[c ­ 32].y * scale;
2603 }
2604 }
2605 SetPixelMode(m);
2606 }
2607
2608 void PixelGameEngine::SetPixelMode(Pixel::Mode m)
2609 {
2610 nPixelMode = m;
2611 }
2612
2613 Pixel::Mode PixelGameEngine::GetPixelMode()
2614 {
2615 return nPixelMode;
2616 }
2617
2618 void PixelGameEngine::SetPixelMode(std::function<olc::Pixel(const int x, 
const int y, const olc::Pixel&, const olc::Pixel&)> pixelMode)
2619 {
2620 funcPixelMode = pixelMode;
2621 nPixelMode = Pixel::Mode::CUSTOM;
2622 }
2623
2624 void PixelGameEngine::SetPixelBlend(float fBlend)
2625 {
2626 fBlendFactor = fBlend;
2627 if (fBlendFactor < 0.0f) fBlendFactor = 0.0f;
2628 if (fBlendFactor > 1.0f) fBlendFactor = 1.0f;
2629 }
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 63
2630
2631 // User must override these functions as required. I have not made
2632 // them abstract because I do need a default behaviour to occur if
2633 // they are not overwritten
2634
2635 bool PixelGameEngine::OnUserCreate()
2636 {
2637 return false;
2638 }
2639
2640 bool PixelGameEngine::OnUserUpdate(float fElapsedTime)
2641 {
2642 UNUSED(fElapsedTime);  return false;
2643 }
2644
2645 bool PixelGameEngine::OnUserDestroy()
2646 {
2647 return true;
2648 }
2649 //////////////////////////////////////////////////////////////////
2650
2651 void PixelGameEngine::olc_UpdateViewport()
2652 {
2653 int32_t ww = vScreenSize.x * vPixelSize.x;
2654 int32_t wh = vScreenSize.y * vPixelSize.y;
2655 float wasp = (float)ww / (float)wh;
2656
2657 if (bPixelCohesion)
2658 {
2659 vScreenPixelSize = (vWindowSize / vScreenSize);
2660 vViewSize = (vWindowSize / vScreenSize) * vScreenSize;
2661 }
2662 else
2663 {
2664 vViewSize.x = (int32_t)vWindowSize.x;
2665 vViewSize.y = (int32_t)((float)vViewSize.x / wasp);
2666
2667 if (vViewSize.y > vWindowSize.y)
2668 {
2669 vViewSize.y = vWindowSize.y;
2670 vViewSize.x = (int32_t)((float)vViewSize.y * wasp);
2671 }
2672 }
2673
2674 vViewPos = (vWindowSize ­ vViewSize) / 2;
2675 }
2676
2677 void PixelGameEngine::olc_UpdateWindowSize(int32_t x, int32_t y)
2678 {
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 64
2679 vWindowSize = { x, y };
2680 olc_UpdateViewport();
2681 }
2682
2683 void PixelGameEngine::olc_UpdateMouseWheel(int32_t delta)
2684 {
2685 nMouseWheelDeltaCache += delta;
2686 }
2687
2688 void PixelGameEngine::olc_UpdateMouse(int32_t x, int32_t y)
2689 {
2690 // Mouse coords come in screen space
2691 // But leave in pixel space
2692 bHasMouseFocus = true;
2693 vMouseWindowPos = { x, y };
2694 // Full Screen mode may have a weird viewport we must clamp to
2695 x ­= vViewPos.x;
2696 y ­= vViewPos.y;
2697 vMousePosCache.x = (int32_t)(((float)x / (float)(vWindowSize.x ­
(vViewPos.x * 2)) * (float)vScreenSize.x));
2698 vMousePosCache.y = (int32_t)(((float)y / (float)(vWindowSize.y ­
(vViewPos.y * 2)) * (float)vScreenSize.y));
2699 if (vMousePosCache.x >= (int32_t)vScreenSize.x) vMousePosCache.x = 
vScreenSize.x ­ 1;
2700 if (vMousePosCache.y >= (int32_t)vScreenSize.y) vMousePosCache.y = 
vScreenSize.y ­ 1;
2701 if (vMousePosCache.x < 0) vMousePosCache.x = 0;
2702 if (vMousePosCache.y < 0) vMousePosCache.y = 0;
2703 }
2704
2705 void PixelGameEngine::olc_UpdateMouseState(int32_t button, bool state)
2706 {
2707 pMouseNewState[button] = state;
2708 }
2709
2710 void PixelGameEngine::olc_UpdateKeyState(int32_t key, bool state)
2711 {
2712 pKeyNewState[key] = state;
2713 }
2714
2715 void PixelGameEngine::olc_UpdateMouseFocus(bool state)
2716 {
2717 bHasMouseFocus = state;
2718 }
2719
2720 void PixelGameEngine::olc_UpdateKeyFocus(bool state)
2721 {
2722 bHasInputFocus = state;
2723 }
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 65
2724
2725 void PixelGameEngine::olc_Terminate()
2726 {
2727 bAtomActive = false;
2728 }
2729
2730 void PixelGameEngine::EngineThread()
2731 {
2732 // Allow platform to do stuff here if needed, since its now in the
2733 // context of this thread
2734 if (platform­>ThreadStartUp() == olc::FAIL) return;
2735
2736 // Do engine context specific initialisation
2737 olc_PrepareEngine();
2738
2739 // Create user resources as part of this thread
2740 if (!OnUserCreate()) bAtomActive  = false;
2741
2742 while (bAtomActive)
2743 {
2744 // Run as fast as possible
2745 while (bAtomActive) { olc_CoreUpdate(); }
2746
2747 // Allow the user to free resources if they have overrided the 
destroy function
2748 if (!OnUserDestroy())
2749 {
2750 // User denied destroy for some reason, so continue running
2751 bAtomActive = true;
2752 }
2753 }
2754
2755 platform­>ThreadCleanUp();
2756 }
2757
2758 void PixelGameEngine::olc_PrepareEngine()
2759 {
2760 // Start OpenGL, the context is owned by the game thread
2761 if (platform­>CreateGraphics(bFullScreen, bEnableVSYNC, vViewPos, 
vViewSize) == olc::FAIL) return;
2762
2763 // Construct default font sheet
2764 olc_ConstructFontSheet();
2765
2766 // Create Primary Layer "0"
2767 CreateLayer();
2768 vLayers[0].bUpdate = true;
2769 vLayers[0].bShow = true;
2770 SetDrawTarget(nullptr);
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 66
2771
2772 m_tp1 = std::chrono::system_clock::now();
2773 m_tp2 = std::chrono::system_clock::now();
2774 }
2775
2776
2777 void PixelGameEngine::olc_CoreUpdate()
2778 {
2779 // Handle Timing
2780 m_tp2 = std::chrono::system_clock::now();
2781 std::chrono::duration<float> elapsedTime = m_tp2 ­ m_tp1;
2782 m_tp1 = m_tp2;
2783
2784 // Our time per frame coefficient
2785 float fElapsedTime = elapsedTime.count();
2786 fLastElapsed = fElapsedTime;
2787
2788 // Some platforms will need to check for events
2789 platform­>HandleSystemEvent();
2790
2791 // Compare hardware input states from previous frame
2792 auto ScanHardware = [&](HWButton* pKeys, bool* pStateOld, bool* 
pStateNew, uint32_t nKeyCount)
2793 {
2794 for (uint32_t i = 0; i < nKeyCount; i++)
2795 {
2796 pKeys[i].bPressed = false;
2797 pKeys[i].bReleased = false;
2798 if (pStateNew[i] != pStateOld[i])
2799 {
2800 if (pStateNew[i])
2801 {
2802 pKeys[i].bPressed = !pKeys[i].bHeld;
2803 pKeys[i].bHeld = true;
2804 }
2805 else
2806 {
2807 pKeys[i].bReleased = true;
2808 pKeys[i].bHeld = false;
2809 }
2810 }
2811 pStateOld[i] = pStateNew[i];
2812 }
2813 };
2814
2815 ScanHardware(pKeyboardState, pKeyOldState, pKeyNewState, 256);
2816 ScanHardware(pMouseState, pMouseOldState, pMouseNewState, 
nMouseButtons);
2817
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 67
2818 // Cache mouse coordinates so they remain consistent during frame
2819 vMousePos = vMousePosCache;
2820 nMouseWheelDelta = nMouseWheelDeltaCache;
2821 nMouseWheelDeltaCache = 0;
2822
2823 // renderer­>ClearBuffer(olc::BLACK, true);
2824
2825 // Handle Frame Update
2826 if (!OnUserUpdate(fElapsedTime))
2827 bAtomActive = false;
2828
2829 // Display Frame
2830 renderer­>UpdateViewport(vViewPos, vViewSize);
2831 renderer­>ClearBuffer(olc::BLACK, true);
2832
2833 // Layer 0 must always exist
2834 vLayers[0].bUpdate = true;
2835 vLayers[0].bShow = true;
2836 renderer­>PrepareDrawing();
2837
2838 for (auto layer = vLayers.rbegin(); layer  != vLayers.rend(); ++layer)
2839 {
2840 if (layer­>bShow)
2841 {
2842 if (layer­>funcHook == nullptr)
2843 {
2844 renderer­>ApplyTexture(layer­>nResID);
2845 if (layer­>bUpdate)
2846 {
2847 renderer­>UpdateTexture(layer­>nResID, layer­
>pDrawTarget);
2848 layer­>bUpdate = false;
2849 }
2850
2851 renderer­>DrawLayerQuad(layer­>vOffset, layer­>vScale, 
layer­>tint);
2852
2853 // Display Decals in order for this layer
2854 for (auto& decal : layer­>vecDecalInstance)
2855 renderer­>DrawDecalQuad(decal);
2856 layer­>vecDecalInstance.clear();
2857 }
2858 else
2859 {
2860 // Mwa ha ha.... Have Fun!!!
2861 layer­>funcHook();
2862 }
2863 }
2864 }
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 68
2865
2866 // Present Graphics to screen
2867 renderer­>DisplayFrame();
2868
2869 // Update Title Bar
2870 fFrameTimer += fElapsedTime;
2871 nFrameCount++;
2872 if (fFrameTimer >= 1.0f)
2873 {
2874 nLastFPS = nFrameCount;
2875 fFrameTimer ­= 1.0f;
2876 std::string sTitle = "OneLoneCoder.com ­ Pixel Game Engine ­ " + 
sAppName + " ­ FPS: " + std::to_string(nFrameCount);
2877 platform­>SetWindowTitle(sTitle);
2878 nFrameCount = 0;
2879 }
2880 }
2881
2882 void PixelGameEngine::olc_ConstructFontSheet()
2883 {
2884 std::string data;
2885 data += "?Q`0001oOch0o01o@F40o0<AGD4090LAGD<090@A7ch0?
00O7Q`0600>00000000";
2886 data += "O000000nOT0063Qo4d8>?
7a14Gno94AA4gno94AaOT0>o3`oO400o7QN00000400" ;
2887 data += 
"Of80001oOg<7O7moBGT7O7lABET024@aBEd714AiOdl717a_=TH013Q>00000000" ;
2888 data += "720D000V?V5oB3Q_HdUoE7a9@DdDE4A9@DmoE4A;Hg]
oM4Aj8S4D84@`00000000";
2889 data += "OaPT1000Oa`^13P1@AI[?g`1@A=[OdAoHgljA4Ao?
WlBA7l1710007l100000000";
2890 data += "ObM6000oOfMV?3QoBDD`O7a0BDDH@5A0BDD<@5A0BGeVO5ao@CQR?
5Po00000000";
2891 data += "Oc``000?Ogij70PO2D]??0Ph2DUM@7i`2DTg@7lh2GUj?0TO0C1870T?
00000000";
2892 data += "70<4001o?P<7?1QoHg43O;`h@GT0@:@LB@d0>:@hN@L0@?aoN@<0O7ao0000?
000";
2893 data += 
"OcH0001SOglLA7mg24TnK7ln24US>0PL24U140PnOgl0>7QgOcH0K71S0000A000" ;
2894 data += "00H00000@Dm1S007@DUSg00?OdTnH7YhOfTL<7Yh@Cl0700?
@Ah0300700000000";
2895 data += "<008001QL00ZA41a@6HnI<1i@FHLM81M@@0LG81?O`0nC?Y7?
`0ZA7Y300080000";
2896 data += "O`082000Oh0827mo6>Hn?Wmo?
6HnMb11MP08@C11H`08@FP0@@0004@000000000" ;
2897 data += 
"00P00001Oab00003OcKP0006@6=PMgl<@440MglH@000000`@000001P00000000" ;
2898 data += "Ob@8@@00Ob@8@Ga13R@8Mga172@8?
PAo3R@827QoOb@820@0O`0007`0000007P0" ;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 69
2899 data += 
"O`000P08Od400g`<3V=P0G`673IP0`@3>1`00P@6O`P00g`<O`000GP800000000" ;
2900 data += "?P9PL020O`<`N3R0@E4HC7b0@ET<ATB0@@l6C4B0O`H3N7b0?
P01L3R000000020";
2901
2902 fontSprite = new olc::Sprite(128, 48);
2903 int px = 0, py = 0;
2904 for (size_t b = 0; b < 1024; b += 4)
2905 {
2906 uint32_t sym1 = (uint32_t)data[b + 0] ­ 48;
2907 uint32_t sym2 = (uint32_t)data[b + 1] ­ 48;
2908 uint32_t sym3 = (uint32_t)data[b + 2] ­ 48;
2909 uint32_t sym4 = (uint32_t)data[b + 3] ­ 48;
2910 uint32_t r = sym1 << 18 | sym2 << 12 | sym3 << 6 | sym4;
2911
2912 for (int i = 0; i < 24; i++)
2913 {
2914 int k = r & (1 << i) ? 255 : 0;
2915 fontSprite­>SetPixel(px, py, olc:: Pixel(k, k, k, k));
2916 if (++py == 48) { px++; py = 0; }
2917 }
2918 }
2919
2920 fontDecal = new olc::Decal(fontSprite);
2921
2922 constexpr std::array<uint8_t, 96> vSpacing = { {
2923
0x03,0x25,0x16,0x08,0x07,0x08,0x08,0x04,0x15,0x15,0x08,0x07,0x15,0x07,0x24,0x0
8,
2924
0x08,0x17,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x24,0x15,0x06,0x07,0x16,0x1
7,
2925
0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x17,0x08,0x08,0x17,0x08,0x08,0x0
8,
2926
0x08,0x08,0x08,0x08,0x17,0x08,0x08,0x08,0x08,0x17,0x08,0x15,0x08,0x15,0x08,0x0
8,
2927
0x24,0x18,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x33,0x17,0x17,0x33,0x18,0x17,0x1
7,
2928
0x17,0x17,0x17,0x17,0x07,0x17,0x17,0x18,0x18,0x17,0x17,0x07,0x33,0x07,0x08,0x0
0, } };
2929
2930 for (auto c : vSpacing) vFontSpacing.push_back({ c >> 4, c & 15 });
2931
2932 }
2933
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 70
2934 // Need a couple of statics as these are singleton instances
2935 // read from multiple locations
2936 std::atomic<bool> PixelGameEngine::bAtomActive{ false };
2937 olc::PixelGameEngine* olc::PGEX::pge = nullptr;
2938 olc::PixelGameEngine* olc::Platform::ptrPGE = nullptr;
2939 olc::PixelGameEngine* olc::Renderer::ptrPGE = nullptr;
2940 std::unique_ptr<ImageLoader> olc::Sprite::loader = nullptr;
2941 };
2942
2943
2944
2945 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
2946 // | olcPixelGameEngine PLATFORM SPECIFIC IMPLEMENTATIONS                     
    |
2947 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
2948
2949 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
2950 // | START RENDERER: OpenGL 1.0 (the original, the best...)                   
    |
2951 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
2952 #if defined(OLC_GFX_OPENGL10)
2953 #if defined(OLC_PLATFORM_WINAPI)
2954 #include <dwmapi.h>
2955 #include <GL/gl.h>
2956
2957 #if !defined(__MINGW32__)
2958 #pragma comment(lib, "Dwmapi.lib")
2959 #endif
2960 typedef BOOL(WINAPI wglSwapInterval_t) (int interval);
2961 static wglSwapInterval_t* wglSwapInterval = nullptr;
2962 typedef HDC glDeviceContext_t;
2963 typedef HGLRC glRenderContext_t;
2964 #endif
2965
2966 #if defined(__linux__) || defined(__FreeBSD__)
2967
2968 #endif
2969
2970 #if defined(OLC_PLATFORM_X11)
2971
2972
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 71
2973
2974
2975
2976

2977
2978
2979
2980 #endif
2981
2982 #if defined(__APPLE__)
2983
2984
2985
2986
2987 #endif
2988
2989 namespace olc
2990 {
2991 class Renderer_OGL10 : public olc::Renderer
2992 {
2993 private:
2994 #if defined(OLC_PLATFORM_GLUT)
2995
2996 #else
2997 glDeviceContext_t glDeviceContext = 0;
2998 glRenderContext_t glRenderContext = 0;
2999 #endif
3000
3001 bool bSync = false;
3002 olc::DecalMode nDecalMode = olc::DecalMode(­1); // Thanks Gusgo & 
Bispoo
3003
3004 #if defined(OLC_PLATFORM_X11)
3005
3006
3007
3008 #endif
3009
3010 public:
3011 void PrepareDevice() override
3012 {
3013 #if defined(OLC_PLATFORM_GLUT)
3014
3015
3016
3017
3018
3019
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 72
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029 #endif
3030 }
3031
3032 olc::rcode CreateDevice(std::vector<void*> params, bool bFullScreen, 
bool bVSYNC) override
3033 {
3034 #if defined(OLC_PLATFORM_WINAPI)
3035 // Create Device Context
3036 glDeviceContext = GetDC((HWND)(params[0]));
3037 PIXELFORMATDESCRIPTOR pfd =
3038 {
3039 sizeof(PIXELFORMATDESCRIPTOR), 1,
3040 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
3041 PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0,
3042 PFD_MAIN_PLANE, 0, 0, 0, 0
3043 };
3044
3045 int pf = 0;
3046 if (!(pf = ChoosePixelFormat(glDeviceContext, &pfd)))  return 
olc::FAIL;
3047 SetPixelFormat(glDeviceContext, pf, &pfd);
3048
3049 if (!(glRenderContext = wglCreateContext(glDeviceContext)))  return
olc::FAIL;
3050 wglMakeCurrent(glDeviceContext, glRenderContext);
3051
3052 // Remove Frame cap
3053 wglSwapInterval = (wglSwapInterval_t*)wglGetProcAddress
("wglSwapIntervalEXT");
3054 if (wglSwapInterval && !bVSYNC) wglSwapInterval(0);
3055 bSync = bVSYNC;
3056 #endif
3057
3058 #if defined(OLC_PLATFORM_X11)
3059
3060
3061
3062
3063
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 73
3064
3065
3066

3067
3068
3069
3070
3071
3072
3073
3074

3075
3076
3077
3078

3079

3080

3081
3082
3083
3084
3085 #endif
3086
3087 #if defined(OLC_PLATFORM_GLUT)
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097 #else
3098 glEnable(GL_TEXTURE_2D); // Turn on texturing
3099 glHint(GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST);
3100 #endif
3101 return olc::rcode::OK;
3102 }
3103
3104 olc::rcode DestroyDevice() override
3105 {
3106 #if defined(OLC_PLATFORM_WINAPI)
3107 wglDeleteContext(glRenderContext);
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 74
3108 #endif
3109
3110 #if defined(OLC_PLATFORM_X11)
3111
3112
3113 #endif
3114
3115 #if defined(OLC_PLATFORM_GLUT)
3116
3117 #endif
3118 return olc::rcode::OK;
3119 }
3120
3121 void DisplayFrame() override
3122 {
3123 #if defined(OLC_PLATFORM_WINAPI)
3124 SwapBuffers(glDeviceContext);
3125 if (bSync) DwmFlush(); // Woooohooooooo!!!! SMOOOOOOOTH!
3126 #endif
3127
3128 #if defined(OLC_PLATFORM_X11)
3129
3130 #endif
3131
3132 #if defined(OLC_PLATFORM_GLUT)
3133
3134 #endif
3135 }
3136
3137 void PrepareDrawing() override
3138 {
3139 glEnable(GL_BLEND);
3140 SetDecalMode(olc::DecalMode::NORMAL);
3141 }
3142
3143 void SetDecalMode(const olc::DecalMode& mode)
3144 {
3145 if (mode != nDecalMode)
3146 {
3147 switch (mode)
3148 {
3149 case olc::DecalMode::NORMAL:
3150 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3151 break;
3152 case olc::DecalMode::ADDITIVE:
3153 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
3154 break;
3155 case olc::DecalMode::MULTIPLICATIVE:
3156 glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 75
3157 break;
3158 case olc::DecalMode::STENCIL:
3159 glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
3160 break;
3161 case olc::DecalMode::ILLUMINATE:
3162 glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
3163 break;
3164 }
3165
3166 nDecalMode = mode;
3167 }
3168 }
3169
3170 void DrawLayerQuad(const olc::vf2d& offset, const olc::vf2d& scale, 
const olc::Pixel tint) override
3171 {
3172 glBegin(GL_QUADS);
3173 glColor4ub(tint.r, tint.g, tint.b, tint.a);
3174 glTexCoord2f(0.0f * scale.x + offset.x, 1.0f * scale.y + 
offset.y);
3175 glVertex3f(­1.0f /*+ vSubPixelOffset.x*/, ­1.0f /*+ 
vSubPixelOffset.y*/, 0.0f);
3176 glTexCoord2f(0.0f * scale.x + offset.x, 0.0f * scale.y + 
offset.y);
3177 glVertex3f(­1.0f /*+ vSubPixelOffset.x*/, 1.0f /*+ 
vSubPixelOffset.y*/, 0.0f);
3178 glTexCoord2f(1.0f * scale.x + offset.x, 0.0f * scale.y + 
offset.y);
3179 glVertex3f(1.0f /*+ vSubPixelOffset.x*/, 1.0f /*+ 
vSubPixelOffset.y*/, 0.0f);
3180 glTexCoord2f(1.0f * scale.x + offset.x, 1.0f * scale.y + 
offset.y);
3181 glVertex3f(1.0f /*+ vSubPixelOffset.x*/, ­1.0f /*+ 
vSubPixelOffset.y*/, 0.0f);
3182 glEnd();
3183 }
3184
3185 void DrawDecalQuad(const olc::DecalInstance& decal) override
3186 {
3187 if (decal.decal == nullptr)
3188 {
3189 SetDecalMode(decal.mode);
3190 glBindTexture(GL_TEXTURE_2D, 0);
3191 glBegin(GL_QUADS);
3192 glColor4ub(decal.tint[0].r, decal.tint[0].g, decal.tint[0].b, 
decal.tint[0].a);
3193 glTexCoord4f(decal.uv[0].x, decal.uv[0].y, 0.0f, decal.w[0]); 
glVertex2f(decal.pos[0].x, decal.pos[0].y);
3194 glColor4ub(decal.tint[1].r, decal.tint[1].g, decal.tint[1].b, 
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 76
decal.tint[1].a);
3195 glTexCoord4f(decal.uv[1].x, decal.uv[1].y, 0.0f, decal.w[1]); 
glVertex2f(decal.pos[1].x, decal.pos[1].y);
3196 glColor4ub(decal.tint[2].r, decal.tint[2].g, decal.tint[2].b, 
decal.tint[2].a);
3197 glTexCoord4f(decal.uv[2].x, decal.uv[2].y, 0.0f, decal.w[2]); 
glVertex2f(decal.pos[2].x, decal.pos[2].y);
3198 glColor4ub(decal.tint[3].r, decal.tint[3].g, decal.tint[3].b, 
decal.tint[3].a);
3199 glTexCoord4f(decal.uv[3].x, decal.uv[3].y, 0.0f, decal.w[3]); 
glVertex2f(decal.pos[3].x, decal.pos[3].y);
3200 glEnd();
3201 }
3202 else
3203 {
3204 SetDecalMode(decal.mode);
3205 glBindTexture(GL_TEXTURE_2D, decal.decal­>id);
3206 glBegin(GL_QUADS);
3207 glColor4ub(decal.tint[0].r, decal.tint[0].g, decal.tint[0].b, 
decal.tint[0].a);
3208 glTexCoord4f(decal.uv[0].x, decal.uv[0].y, 0.0f, decal.w[0]); 
glVertex2f(decal.pos[0].x, decal.pos[0].y);
3209 glTexCoord4f(decal.uv[1].x, decal.uv[1].y, 0.0f, decal.w[1]); 
glVertex2f(decal.pos[1].x, decal.pos[1].y);
3210 glTexCoord4f(decal.uv[2].x, decal.uv[2].y, 0.0f, decal.w[2]); 
glVertex2f(decal.pos[2].x, decal.pos[2].y);
3211 glTexCoord4f(decal.uv[3].x, decal.uv[3].y, 0.0f, decal.w[3]); 
glVertex2f(decal.pos[3].x, decal.pos[3].y);
3212 glEnd();
3213 }
3214 }
3215
3216 uint32_t CreateTexture(const uint32_t width, const uint32_t height, 
const bool filtered) override
3217 {
3218 UNUSED(width);
3219 UNUSED(height);
3220 uint32_t id = 0;
3221 glGenTextures(1, &id);
3222 glBindTexture(GL_TEXTURE_2D, id);
3223 if (filtered)
3224 {
3225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
GL_LINEAR);
3226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
GL_LINEAR);
3227 }
3228 else
3229 {
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 77
3230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
3231 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
3232 }
3233
3234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
3235 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
3236 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
3237 return id;
3238 }
3239
3240 uint32_t DeleteTexture(const uint32_t id) override
3241 {
3242 glDeleteTextures(1, &id);
3243 return id;
3244 }
3245
3246 void UpdateTexture(uint32_t id, olc::Sprite* spr) override
3247 {
3248 UNUSED(id);
3249 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spr­>width, spr­>height,
0, GL_RGBA, GL_UNSIGNED_BYTE, spr­>GetData());
3250 }
3251
3252 void ApplyTexture(uint32_t id) override
3253 {
3254 glBindTexture(GL_TEXTURE_2D, id);
3255 }
3256
3257 void ClearBuffer(olc::Pixel p, bool bDepth) override
3258 {
3259 glClearColor(float(p.r) / 255.0f, float(p.g) / 255.0f, float
(p.b) / 255.0f, float(p.a) / 255.0f);
3260 glClear(GL_COLOR_BUFFER_BIT);
3261 if (bDepth) glClear(GL_DEPTH_BUFFER_BIT);
3262 }
3263
3264 void UpdateViewport(const olc::vi2d& pos, const olc::vi2d& size)
override
3265 {
3266 #if defined(OLC_PLATFORM_GLUT)
3267
3268 #else
3269 glViewport(pos.x, pos.y, size.x, size.y);
3270 #endif
3271 }
3272 };
3273 }
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 78
3274 #endif
3275 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3276 // | END RENDERER: OpenGL 1.0 (the original, the best...)                     
    |
3277 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3278
3279
3280
3281
3282 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3283 // | START IMAGE LOADER: GDI+, Windows Only, always exists, a little slow     
    |
3284 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3285 #if defined(OLC_IMAGE_GDI)
3286
3287 #define min(a, b) ((a < b) ? a : b)
3288 #define max(a, b) ((a > b) ? a : b)
3289 #include <gdiplus.h>
3290 #include <shlwapi.h>
3291 #undef min
3292 #undef max
3293
3294 #if !defined(__MINGW32__)
3295 #pragma comment(lib, "gdiplus.lib")
3296 #pragma comment(lib, "Shlwapi.lib")
3297 #endif
3298
3299 namespace olc
3300 {
3301 // Thanks @MaGetzUb for this, which allows sprites to be defined
3302 // at construction, by initialising the GDI subsystem
3303 static class GDIPlusStartup
3304 {
3305 public:
3306 GDIPlusStartup()
3307 {
3308 Gdiplus::GdiplusStartupInput startupInput;
3309 ULONG_PTR token;
3310 Gdiplus::GdiplusStartup(&token, &startupInput,  NULL);
3311 };
3312 } gdistartup;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 79
3313
3314 class ImageLoader_GDIPlus : public olc::ImageLoader
3315 {
3316 private:
3317 std::wstring ConvertS2W(std::string s)
3318 {
3319 #ifdef __MINGW32__
3320
3321
3322
3323 #else
3324 int count = MultiByteToWideChar( CP_UTF8, 0, s.c_str(), ­1, NULL, 
0);
3325 wchar_t* buffer = new wchar_t[count];
3326 MultiByteToWideChar(CP_UTF8, 0, s.c_str(), ­1, buffer, count);
3327 #endif
3328 std::wstring w(buffer);
3329 delete[] buffer;
3330 return w;
3331 }
3332
3333 public:
3334 ImageLoader_GDIPlus() : ImageLoader()
3335 {}
3336
3337 olc::rcode LoadImageResource(olc::Sprite* spr, const std::string& 
sImageFile, olc::ResourcePack* pack) override
3338 {
3339 // clear out existing sprite
3340 if (spr­>pColData != nullptr) delete[] spr­>pColData;
3341
3342 // Open file
3343 UNUSED(pack);
3344 Gdiplus::Bitmap* bmp = nullptr;
3345 if (pack != nullptr)
3346 {
3347 // Load sprite from input stream
3348 ResourceBuffer rb = pack­>GetFileBuffer(sImageFile);
3349 bmp = Gdiplus::Bitmap::FromStream(SHCreateMemStream(( BYTE*)
rb.vMemory.data(), UINT(rb.vMemory.size())));
3350 }
3351 else
3352 {
3353 // Check file exists
3354 if (!_gfs::exists(sImageFile)) return olc::rcode::NO_FILE;
3355
3356 // Load sprite from file
3357 bmp = Gdiplus::Bitmap::FromFile(ConvertS2W(sImageFile).c_str
());
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 80
3358 }
3359
3360 if (bmp­>GetLastStatus() != Gdiplus:: Ok) return olc::rcode::FAIL;
3361 spr­>width = bmp­>GetWidth();
3362 spr­>height = bmp­>GetHeight();
3363 spr­>pColData = new Pixel[spr­>width * spr­>height];
3364
3365 for (int y = 0; y < spr­>height; y++)
3366 for (int x = 0; x < spr­>width; x++)
3367 {
3368 Gdiplus::Color c;
3369 bmp­>GetPixel(x, y, &c);
3370 spr­>SetPixel(x, y, olc::Pixel(c.GetRed(), c.GetGreen(), 
c.GetBlue(), c.GetAlpha()));
3371 }
3372 delete bmp;
3373 return olc::rcode::OK;
3374 }
3375
3376 olc::rcode SaveImageResource(olc::Sprite* spr, const std::string& 
sImageFile) override
3377 {
3378 return olc::rcode::OK;
3379 }
3380 };
3381 }
3382 #endif
3383 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3384 // | END IMAGE LOADER: GDI+                                                   
    |
3385 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3386
3387
3388
3389
3390 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3391 // | START IMAGE LOADER: libpng, default on linux, requires  ­lpng  (libpng­
dev)   |
3392 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3393 #if defined(OLC_IMAGE_LIBPNG)
3394
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 81
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409

3410
3411
3412
3413
3414
3415
3416

3417
3418
3419
3420

3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435

3436

3437
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 82
3438

3439
3440

3441
3442
3443

3444
3445

3446
3447
3448

3449
3450
3451
3452
3453
3454
3455
3456
3457
3458

3459
3460
3461
3462
3463
3464
3465
3466
3467
3468

3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 83
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501

3502
3503
3504
3505
3506
3507 #endif
3508 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3509 // | END IMAGE LOADER:
|
3510 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3511
3512
3513
3514
3515 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3516 // | START IMAGE LOADER: stb_image.h, all systems, very fast
|
3517 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 84
3518 // Thanks to Sean Barrett ­ https://github.com/nothings/stb/blob/master/
stb_image.h
3519 // MIT License ­ Copyright(c) 2017 Sean Barrett
3520
3521 // Note you need to download the above file into your project folder, and
3522 // #define OLC_IMAGE_STB
3523 // #define OLC_PGE_APPLICATION
3524 // #include "olcPixelGameEngine.h"
3525
3526 #if defined(OLC_IMAGE_STB)
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537

3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548

3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 85
3564
3565

3566
3567
3568
3569
3570
3571 #endif
3572 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3573 // | START IMAGE LOADER: stb_image.h                                          
    |
3574 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3575
3576
3577 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3578 // | START PLATFORM: MICROSOFT WINDOWS XP, VISTA, 7, 8, 10                    
    |
3579 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3580 #if defined(OLC_PLATFORM_WINAPI)
3581
3582 #if defined(_WIN32) && !defined(__MINGW32__)
3583 #pragma comment(lib, "user32.lib") // Visual Studio Only
3584 #pragma comment(lib, "gdi32.lib") // For other Windows Compilers please 
add
3585 #pragma comment(lib, "opengl32.lib") // these libs to your linker input
3586 #endif
3587
3588 namespace olc
3589 {
3590 class Platform_Windows : public olc::Platform
3591 {
3592 private:
3593 HWND olc_hWnd = nullptr;
3594 std::wstring wsAppName;
3595
3596 std::wstring ConvertS2W(std::string s)
3597 {
3598 #ifdef __MINGW32__
3599
3600
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 86
3601
3602 #else
3603 int count = MultiByteToWideChar( CP_UTF8, 0, s.c_str(), ­1, NULL, 
0);
3604 wchar_t* buffer = new wchar_t[count];
3605 MultiByteToWideChar(CP_UTF8, 0, s.c_str(), ­1, buffer, count);
3606 #endif
3607 std::wstring w(buffer);
3608 delete[] buffer;
3609 return w;
3610 }
3611
3612 public:
3613 virtual olc::rcode ApplicationStartUp() override { return 
olc::rcode::OK; }
3614 virtual olc::rcode ApplicationCleanUp() override { return 
olc::rcode::OK; }
3615 virtual olc::rcode ThreadStartUp() override { return olc::rcode::OK; }
3616
3617 virtual olc::rcode ThreadCleanUp() override
3618 {
3619 renderer­>DestroyDevice();
3620 PostMessage(olc_hWnd, WM_DESTROY, 0, 0);
3621 return olc::OK;
3622 }
3623
3624 virtual olc::rcode CreateGraphics(bool bFullScreen, bool bEnableVSYNC,
const olc::vi2d& vViewPos, const olc::vi2d& vViewSize) override
3625 {
3626 if (renderer­>CreateDevice({ olc_hWnd }, bFullScreen, 
bEnableVSYNC) == olc::rcode::OK)
3627 {
3628 renderer­>UpdateViewport(vViewPos, vViewSize);
3629 return olc::rcode::OK;
3630 }
3631 else
3632 return olc::rcode::FAIL;
3633 }
3634
3635 virtual olc::rcode CreateWindowPane(const olc::vi2d& vWindowPos, 
olc::vi2d& vWindowSize, bool bFullScreen) override
3636 {
3637 WNDCLASS wc;
3638 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
3639 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
3640 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
3641 wc.hInstance = GetModuleHandle(nullptr);
3642 wc.lpfnWndProc = olc_WindowEvent;
3643 wc.cbClsExtra = 0;
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 87
3644 wc.cbWndExtra = 0;
3645 wc.lpszMenuName = nullptr;
3646 wc.hbrBackground = nullptr;
3647 wc.lpszClassName = olcT("OLC_PIXEL_GAME_ENGINE");
3648 RegisterClass(&wc);
3649
3650 // Define window furniture
3651 DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
3652 DWORD dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | 
WS_THICKFRAME;
3653
3654 olc::vi2d vTopLeft = vWindowPos;
3655
3656 // Handle Fullscreen
3657 if (bFullScreen)
3658 {
3659 dwExStyle = 0;
3660 dwStyle = WS_VISIBLE | WS_POPUP;
3661 HMONITOR hmon = MonitorFromWindow(olc_hWnd, 
MONITOR_DEFAULTTONEAREST);
3662 MONITORINFO mi = { sizeof(mi) };
3663 if (!GetMonitorInfo(hmon, &mi)) return olc::rcode::FAIL;
3664 vWindowSize = { mi.rcMonitor.right, mi.rcMonitor.bottom };
3665 vTopLeft.x = 0;
3666 vTopLeft.y = 0;
3667 }
3668
3669 // Keep client size as requested
3670 RECT rWndRect = { 0, 0, vWindowSize.x, vWindowSize.y };
3671 AdjustWindowRectEx(&rWndRect, dwStyle,  FALSE, dwExStyle);
3672 int width = rWndRect.right ­ rWndRect.left;
3673 int height = rWndRect.bottom ­ rWndRect.top;
3674
3675 olc_hWnd = CreateWindowEx(dwExStyle, olcT
("OLC_PIXEL_GAME_ENGINE"), olcT(""), dwStyle,
3676 vTopLeft.x, vTopLeft.y, width, height,  NULL, NULL, 
GetModuleHandle(nullptr), this);
3677
3678 // Create Keyboard Mapping
3679 mapKeys[0x00] = Key::NONE;
3680 mapKeys[0x41] = Key::A; mapKeys[0x42] = Key::B; mapKeys[0x43] = 
Key::C; mapKeys[0x44] = Key::D; mapKeys[0x45] = Key::E;
3681 mapKeys[0x46] = Key::F; mapKeys[0x47] = Key::G; mapKeys[0x48] = 
Key::H; mapKeys[0x49] = Key::I; mapKeys[0x4A] = Key::J;
3682 mapKeys[0x4B] = Key::K; mapKeys[0x4C] = Key::L; mapKeys[0x4D] = 
Key::M; mapKeys[0x4E] = Key::N; mapKeys[0x4F] = Key::O;
3683 mapKeys[0x50] = Key::P; mapKeys[0x51] = Key::Q; mapKeys[0x52] = 
Key::R; mapKeys[0x53] = Key::S; mapKeys[0x54] = Key::T;
3684 mapKeys[0x55] = Key::U; mapKeys[0x56] = Key::V; mapKeys[0x57] = 
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 88
Key::W; mapKeys[0x58] = Key::X; mapKeys[0x59] = Key::Y;
3685 mapKeys[0x5A] = Key::Z;
3686
3687 mapKeys[VK_F1] = Key::F1; mapKeys[VK_F2] = Key::F2; mapKeys[VK_F3]
= Key::F3; mapKeys[VK_F4] = Key::F4;
3688 mapKeys[VK_F5] = Key::F5; mapKeys[VK_F6] = Key::F6; mapKeys[VK_F7]
= Key::F7; mapKeys[VK_F8] = Key::F8;
3689 mapKeys[VK_F9] = Key::F9; mapKeys[VK_F10] = Key::F10; mapKeys
[VK_F11] = Key::F11; mapKeys[VK_F12] = Key::F12;
3690
3691 mapKeys[VK_DOWN] = Key::DOWN; mapKeys[VK_LEFT] = Key::LEFT; 
mapKeys[VK_RIGHT] = Key::RIGHT; mapKeys[VK_UP] = Key::UP;
3692 mapKeys[VK_RETURN] = Key::ENTER; //mapKeys[VK_RETURN] = 
Key::RETURN;
3693
3694 mapKeys[VK_BACK] = Key::BACK; mapKeys[VK_ESCAPE] = Key::ESCAPE; 
mapKeys[VK_RETURN] = Key::ENTER; mapKeys[VK_PAUSE] = Key::PAUSE;
3695 mapKeys[VK_SCROLL] = Key::SCROLL; mapKeys[VK_TAB] = Key::TAB; 
mapKeys[VK_DELETE] = Key::DEL; mapKeys[VK_HOME] = Key::HOME;
3696 mapKeys[VK_END] = Key::END; mapKeys[VK_PRIOR] = Key::PGUP; mapKeys
[VK_NEXT] = Key::PGDN; mapKeys[VK_INSERT] = Key::INS;
3697 mapKeys[VK_SHIFT] = Key::SHIFT; mapKeys[VK_CONTROL] = Key::CTRL;
3698 mapKeys[VK_SPACE] = Key::SPACE;
3699
3700 mapKeys[0x30] = Key::K0; mapKeys[0x31] = Key::K1; mapKeys[0x32] = 
Key::K2; mapKeys[0x33] = Key::K3; mapKeys[0x34] = Key::K4;
3701 mapKeys[0x35] = Key::K5; mapKeys[0x36] = Key::K6; mapKeys[0x37] = 
Key::K7; mapKeys[0x38] = Key::K8; mapKeys[0x39] = Key::K9;
3702
3703 mapKeys[VK_NUMPAD0] = Key::NP0; mapKeys[VK_NUMPAD1] = Key::NP1; 
mapKeys[VK_NUMPAD2] = Key::NP2; mapKeys[VK_NUMPAD3] = Key::NP3; 
mapKeys[VK_NUMPAD4] = Key::NP4;
3704 mapKeys[VK_NUMPAD5] = Key::NP5; mapKeys[VK_NUMPAD6] = Key::NP6; 
mapKeys[VK_NUMPAD7] = Key::NP7; mapKeys[VK_NUMPAD8] = Key::NP8; 
mapKeys[VK_NUMPAD9] = Key::NP9;
3705 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;
3706
3707 // Thanks scripticuk
3708 mapKeys[VK_OEM_1] = Key::OEM_1; // On US and UK keyboards 
this is the ';:' key
3709 mapKeys[VK_OEM_2] = Key::OEM_2; // On US and UK keyboards 
this is the '/?' key
3710 mapKeys[VK_OEM_3] = Key::OEM_3; // On US keyboard this is 
the '~' key
3711 mapKeys[VK_OEM_4] = Key::OEM_4; // On US and UK keyboards 
this is the '[{' key
3712 mapKeys[VK_OEM_5] = Key::OEM_5; // On US keyboard this is 
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 89
'\|' key.
3713 mapKeys[VK_OEM_6] = Key::OEM_6; // On US and UK keyboards
this is the ']}' key
3714 mapKeys[VK_OEM_7] = Key::OEM_7; // On US keyboard this is
the single/double quote key. On UK, this is the single quote/@
symbol key
3715 mapKeys[VK_OEM_8] = Key::OEM_8; // miscellaneous
characters. Varies by keyboard
3716 mapKeys[VK_OEM_PLUS] = Key::EQUALS; // the '+' key on any
keyboard
3717 mapKeys[VK_OEM_COMMA] = Key::COMMA; // the comma key on any
keyboard
3718 mapKeys[VK_OEM_MINUS] = Key::MINUS; // the minus key on any
keyboard
3719 mapKeys[VK_OEM_PERIOD] = Key::PERIOD; // the period key on any
keyboard
3720 mapKeys[VK_CAPITAL] = Key::CAPS_LOCK;
3721 return olc::OK;
3722 }
3723
3724 virtual olc::rcode SetWindowTitle(const std::string& s) override
3725 {
3726 #ifdef UNICODE
3727 SetWindowText(olc_hWnd, ConvertS2W(s).c_str());
3728 #else
3729
3730 #endif
3731 return olc::OK;
3732 }
3733
3734 virtual olc::rcode StartSystemEventLoop() override
3735 {
3736 MSG msg;
3737 while (GetMessage(&msg, NULL, 0, 0) > 0)
3738 {
3739 TranslateMessage(&msg);
3740 DispatchMessage(&msg);
3741 }
3742 return olc::OK;
3743 }
3744
3745 virtual olc::rcode HandleSystemEvent() override { return
olc::rcode::FAIL; }
3746
3747 // Windows Event Handler ­ this is statically connected to the windows
event system
3748 static LRESULT CALLBACK olc_WindowEvent(HWND hWnd, UINT uMsg, WPARAM
wParam, LPARAM lParam)
3749 {
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 90
3750 switch (uMsg)
3751 {
3752 case WM_MOUSEMOVE:
3753 {
3754 // Thanks @ForAbby (Discord)
3755 uint16_t x = lParam & 0xFFFF; uint16_t y = (lParam >> 16) &
0xFFFF;
3756 int16_t ix = *(int16_t*)&x; int16_t iy = *(int16_t*)&y;
3757 ptrPGE­>olc_UpdateMouse(ix, iy);
3758 return 0;
3759 }
3760 case WM_SIZE: ptrPGE­>olc_UpdateWindowSize(lParam & 0xFFFF,
(lParam >> 16) & 0xFFFF); return 0;
3761 case WM_MOUSEWHEEL: ptrPGE­>olc_UpdateMouseWheel
(GET_WHEEL_DELTA_WPARAM(wParam)); return 0;
3762 case WM_MOUSELEAVE: ptrPGE­>olc_UpdateMouseFocus( false);
return 0;
3763 case WM_SETFOCUS: ptrPGE­>olc_UpdateKeyFocus(true);
return 0;
3764 case WM_KILLFOCUS: ptrPGE­>olc_UpdateKeyFocus(false);
return 0;
3765 case WM_KEYDOWN: ptrPGE­>olc_UpdateKeyState(mapKeys[wParam],
true); return 0;
3766 case WM_KEYUP: ptrPGE­>olc_UpdateKeyState(mapKeys[wParam],
false); return 0;
3767 case WM_SYSKEYDOWN: ptrPGE­>olc_UpdateKeyState(mapKeys[wParam],
true); return 0;
3768 case WM_SYSKEYUP: ptrPGE­>olc_UpdateKeyState(mapKeys[wParam],
false); return 0;
3769 case WM_LBUTTONDOWN:ptrPGE­>olc_UpdateMouseState(0, true);
return 0;
3770 case WM_LBUTTONUP: ptrPGE­>olc_UpdateMouseState(0, false);
return 0;
3771 case WM_RBUTTONDOWN:ptrPGE­>olc_UpdateMouseState(1, true);
return 0;
3772 case WM_RBUTTONUP: ptrPGE­>olc_UpdateMouseState(1, false);
return 0;
3773 case WM_MBUTTONDOWN:ptrPGE­>olc_UpdateMouseState(2, true);
return 0;
3774 case WM_MBUTTONUP: ptrPGE­>olc_UpdateMouseState(2, false);
return 0;
3775 case WM_CLOSE: ptrPGE­>olc_Terminate();
return 0;
3776 case WM_DESTROY: PostQuitMessage(0); DestroyWindow( hWnd);
return 0;
3777 }
3778 return DefWindowProc(hWnd, uMsg, wParam, lParam);
3779 }
3780 };
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 91
3781 }
3782 #endif
3783 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3784 // | END PLATFORM: MICROSOFT WINDOWS XP, VISTA, 7, 8, 10
|
3785 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3786
3787
3788
3789
3790
3791 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3792 // | START PLATFORM: LINUX
|
3793 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
3794 #if defined(OLC_PLATFORM_X11)
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 92
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829

3830
3831

3832
3833
3834
3835
3836
3837
3838
3839
3840

3841
3842
3843
3844
3845
3846
3847
3848
3849

3850

3851
3852

3853
3854
3855
3856

3857

3858
3859
3860
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 93

3861
3862
3863
3864
3865

3866
3867
3868
3869

3870
3871
3872
3873
3874
3875
3876

3877
3878
3879
3880
3881
3882

3883

3884

3885

3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898

3899
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 94
3900

3901

3902

3903
3904
3905

3906

3907

3908
3909

3910

3911
3912

3913

3914

3915

3916
3917
3918

3919

3920
3921

3922

3923

3924
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 95
3925

3926

3927

3928

3929

3930

3931

3932

3933

3934

3935

3936

3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 96
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979

3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 97
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034 #endif
4035 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
4036 // | END PLATFORM: LINUX                                                      
    |
4037 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
4038
4039
4040
4041
4042 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
4043 // | START PLATFORM: GLUT (used to make it simple for Apple)                  
    |
4044 // 
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
4045 //
4046 // VERY IMPORTANT!!! The Apple port was originally created by @Mumflr 
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 98
(discord)
4047 // and the repo for the development of this project can be found here:
4048 // https://github.com/MumflrFumperdink/olcPGEMac which contains maccy goodness
4049 // and support on how to setup your build environment.
4050 //
4051 // "MASSIVE MASSIVE THANKS TO MUMFLR" ­ Javidx9
4052 #if defined(OLC_PLATFORM_GLUT)
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080

4081
4082

4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 99
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113

4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125

4126

4127
4128
4129
4130
4131
4132

4133

4134

4135
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 100

4136

4137
4138
4139

4140

4141

4142
4143

4144
4145
4146
4147
4148

4149
4150
4151

4152

4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 101
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213

4214

4215
4216
4217

4218
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 102

4219
4220
4221

4222

4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236

4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 103
4264
4265
4266
4267
4268
4269
4270

4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295 #endif
4296 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
4297 // | END PLATFORM: GLUT
|
4298 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
4299
4300
4301
4302 namespace olc
4303 {
4304 void PixelGameEngine::olc_ConfigureSystem()
4305 {
4306
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 104
4307 #if defined(OLC_IMAGE_GDI)
4308 olc::Sprite::loader = std::make_unique<olc::ImageLoader_GDIPlus>();
4309 #endif
4310
4311 #if defined(OLC_IMAGE_LIBPNG)
4312
4313 #endif
4314
4315 #if defined(OLC_IMAGE_STB)
4316
4317 #endif
4318
4319
4320
4321
4322 #if defined(OLC_PLATFORM_WINAPI)
4323 platform = std::make_unique<olc::Platform_Windows>();
4324 #endif
4325
4326 #if defined(OLC_PLATFORM_X11)
4327
4328 #endif
4329
4330 #if defined(OLC_PLATFORM_GLUT)
4331
4332 #endif
4333
4334
4335
4336 #if defined(OLC_GFX_OPENGL10)
4337 renderer = std::make_unique<olc::Renderer_OGL10>();
4338 #endif
4339
4340 #if defined(OLC_GFX_OPENGL33)
4341
4342 #endif
4343
4344 #if defined(OLC_GFX_OPENGLES2)
4345
4346 #endif
4347
4348 #if defined(OLC_GFX_DIRECTX10)
4349
4350 #endif
4351
4352 #if defined(OLC_GFX_DIRECTX11)
4353
4354 #endif
4355
...y\C++\MyPixelGameEngine\Polymorphism\olcPixelGameEngine.h 105
4356 // Associate components with PGE instance
4357 platform­>ptrPGE = this;
4358 renderer­>ptrPGE = this;
4359 }
4360 }
4361
4362 #endif // End olc namespace
4363
4364 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
4365 // | END OF OLC_PGE_APPLICATION
|
4366 //
O­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
­­­O
4367
4368

You might also like