Version 1.8 - Quite a few things
+periodic sprite sampling +global buffer sub-pixel offsets +custom pixel "shaders" -references to deprecated codecvt -horrible mess of strings for title bar
This commit is contained in:
parent
d0a2e2fcf1
commit
219718b66f
@ -2,7 +2,7 @@
|
|||||||
olcPixelGameEngine.h
|
olcPixelGameEngine.h
|
||||||
|
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
| OneLoneCoder Pixel Game Engine v1.7 |
|
| OneLoneCoder Pixel Game Engine v1.8 |
|
||||||
| "Like the command prompt console one, but not..." - javidx9 |
|
| "Like the command prompt console one, but not..." - javidx9 |
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
|
|
||||||
@ -123,18 +123,20 @@
|
|||||||
my appreciation to the 14K YouTube followers and 1K Discord server
|
my appreciation to the 14K YouTube followers and 1K Discord server
|
||||||
members who give me the motivation to keep going with all this :D
|
members who give me the motivation to keep going with all this :D
|
||||||
|
|
||||||
|
Special thanks to those who bring gifts!
|
||||||
|
GnarGnarHead for Domina
|
||||||
|
Gorbit for Bastion
|
||||||
|
|
||||||
Author
|
Author
|
||||||
~~~~~~
|
~~~~~~
|
||||||
David Barr, aka javidx9, ©OneLoneCoder 2018
|
David Barr, aka javidx9, ©OneLoneCoder 2018
|
||||||
*/
|
*/
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/* Example Usage (main.cpp)
|
/* Example Usage (main.cpp)
|
||||||
|
|
||||||
#define OLC_PGE_APPLICATION
|
#define OLC_PGE_APPLICATION
|
||||||
#include "olcPixelGameEngine.h"
|
#include "olcPixelGameEngine.h"
|
||||||
|
|
||||||
// Override base class with your custom functionality
|
// Override base class with your custom functionality
|
||||||
class Example : public olc::PixelGameEngine
|
class Example : public olc::PixelGameEngine
|
||||||
{
|
{
|
||||||
@ -143,14 +145,12 @@
|
|||||||
{
|
{
|
||||||
sAppName = "Example";
|
sAppName = "Example";
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool OnUserCreate() override
|
bool OnUserCreate() override
|
||||||
{
|
{
|
||||||
// Called once at the start, so create things here
|
// Called once at the start, so create things here
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OnUserUpdate(float fElapsedTime) override
|
bool OnUserUpdate(float fElapsedTime) override
|
||||||
{
|
{
|
||||||
// called once per frame, draws random coloured pixels
|
// called once per frame, draws random coloured pixels
|
||||||
@ -160,7 +160,6 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Example demo;
|
Example demo;
|
||||||
@ -184,9 +183,6 @@
|
|||||||
// In Code::Blocks, Select C++14 in your build options, and add the
|
// In Code::Blocks, Select C++14 in your build options, and add the
|
||||||
// following libs to your linker: user32 gdi32 opengl32 gdiplus
|
// following libs to your linker: user32 gdi32 opengl32 gdiplus
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Include WinAPI
|
// Include WinAPI
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <gdiplus.h>
|
#include <gdiplus.h>
|
||||||
@ -219,9 +215,7 @@
|
|||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#ifndef __MINGW32__
|
#include <functional>
|
||||||
#include <codecvt> // Need GCC 5.1+ people...
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
@ -241,7 +235,8 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
|||||||
|
|
||||||
Pixel();
|
Pixel();
|
||||||
Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255);
|
Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255);
|
||||||
enum Mode { NORMAL, MASK, ALPHA };
|
Pixel(uint32_t p);
|
||||||
|
enum Mode { NORMAL, MASK, ALPHA, CUSTOM };
|
||||||
};
|
};
|
||||||
|
|
||||||
// Some constants for symbolic naming of Pixels
|
// Some constants for symbolic naming of Pixels
|
||||||
@ -291,8 +286,10 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
|||||||
public:
|
public:
|
||||||
int32_t width = 0;
|
int32_t width = 0;
|
||||||
int32_t height = 0;
|
int32_t height = 0;
|
||||||
|
enum Mode { NORMAL, PERIODIC };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void SetSampleMode(olc::Sprite::Mode mode = olc::Sprite::Mode::NORMAL);
|
||||||
Pixel GetPixel(int32_t x, int32_t y);
|
Pixel GetPixel(int32_t x, int32_t y);
|
||||||
void SetPixel(int32_t x, int32_t y, Pixel p);
|
void SetPixel(int32_t x, int32_t y, Pixel p);
|
||||||
Pixel Sample(float x, float y);
|
Pixel Sample(float x, float y);
|
||||||
@ -300,6 +297,7 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Pixel *pColData = nullptr;
|
Pixel *pColData = nullptr;
|
||||||
|
Mode modeSample = Mode::NORMAL;
|
||||||
|
|
||||||
#ifdef OLC_DBG_OVERDRAW
|
#ifdef OLC_DBG_OVERDRAW
|
||||||
public:
|
public:
|
||||||
@ -329,7 +327,7 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
|||||||
PixelGameEngine();
|
PixelGameEngine();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
olc::rcode Construct(uint32_t screen_w, uint32_t screen_h, uint32_t pixel_w, uint32_t pixel_h, int32_t framerate = -1);
|
olc::rcode Construct(uint32_t screen_w, uint32_t screen_h, uint32_t pixel_w, uint32_t pixel_h);
|
||||||
olc::rcode Start();
|
olc::rcode Start();
|
||||||
|
|
||||||
public: // Override Interfaces
|
public: // Override Interfaces
|
||||||
@ -342,7 +340,7 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
|||||||
|
|
||||||
public: // Hardware Interfaces
|
public: // Hardware Interfaces
|
||||||
// Returns true if window is currently in focus
|
// Returns true if window is currently in focus
|
||||||
bool IsFocused();
|
bool IsFocused();
|
||||||
// Get the state of a specific keyboard button
|
// Get the state of a specific keyboard button
|
||||||
HWButton GetKey(Key k);
|
HWButton GetKey(Key k);
|
||||||
// Get the state of a specific mouse button
|
// Get the state of a specific mouse button
|
||||||
@ -373,9 +371,11 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
|||||||
// olc::Pixel::MASK = Transparent if alpha is < 255
|
// olc::Pixel::MASK = Transparent if alpha is < 255
|
||||||
// olc::Pixel::ALPHA = Full transparency
|
// olc::Pixel::ALPHA = Full transparency
|
||||||
void SetPixelMode(Pixel::Mode m);
|
void SetPixelMode(Pixel::Mode m);
|
||||||
|
// Use a custom blend function
|
||||||
|
void SetPixelMode(std::function<olc::Pixel(const int x, const int y, const olc::Pixel& pSource, const olc::Pixel& pDest)> pixelMode);
|
||||||
// Change the blend factor form between 0.0f to 1.0f;
|
// Change the blend factor form between 0.0f to 1.0f;
|
||||||
void SetPixelBlend(float fBlend);
|
void SetPixelBlend(float fBlend);
|
||||||
|
// Offset texels by sub-pixel amount (advanced, do not use)
|
||||||
void SetSubPixelOffset(float ox, float oy);
|
void SetSubPixelOffset(float ox, float oy);
|
||||||
|
|
||||||
// Draws a single Pixel
|
// Draws a single Pixel
|
||||||
@ -425,9 +425,8 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
|||||||
bool bHasInputFocus = false;
|
bool bHasInputFocus = false;
|
||||||
float fFrameTimer = 1.0f;
|
float fFrameTimer = 1.0f;
|
||||||
int nFrameCount = 0;
|
int nFrameCount = 0;
|
||||||
float fFramePeriod = 0.0f;
|
|
||||||
Sprite *fontSprite = nullptr;
|
Sprite *fontSprite = nullptr;
|
||||||
|
std::function<olc::Pixel(const int x, const int y, const olc::Pixel&, const olc::Pixel&)> funcPixelMode;
|
||||||
|
|
||||||
static std::map<uint16_t, uint8_t> mapKeys;
|
static std::map<uint16_t, uint8_t> mapKeys;
|
||||||
bool pKeyNewState[256]{ 0 };
|
bool pKeyNewState[256]{ 0 };
|
||||||
@ -498,7 +497,7 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
|||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If the olcPixelGameEngine.h is called from several sources it can cause
|
If the olcPixelGameEngine.h is called from several sources it can cause
|
||||||
multiple definitions of objects. To prevent this, ALL but ONE of the pathways
|
multiple definitions of objects. To prevent this, ONLY ONE of the pathways
|
||||||
to including this file must have OLC_PGE_APPLICATION defined before it. This prevents
|
to including this file must have OLC_PGE_APPLICATION defined before it. This prevents
|
||||||
the definitions being duplicated.
|
the definitions being duplicated.
|
||||||
|
|
||||||
@ -510,6 +509,10 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
|||||||
Class2.cpp - #define OLC_PGE_APPLICATION #include "Class2.h"
|
Class2.cpp - #define OLC_PGE_APPLICATION #include "Class2.h"
|
||||||
main.cpp - Includes Class1.h and Class2.h
|
main.cpp - Includes Class1.h and Class2.h
|
||||||
|
|
||||||
|
If all of this is a bit too confusing, you can split this file in two!
|
||||||
|
Everything below this comment block can go into olcPixelGameEngineOOP.cpp
|
||||||
|
and everything above it can go into olcPixelGameEngineOOP.h
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef OLC_PGE_APPLICATION
|
#ifdef OLC_PGE_APPLICATION
|
||||||
@ -527,8 +530,32 @@ namespace olc
|
|||||||
r = red; g = green; b = blue; a = alpha;
|
r = red; g = green; b = blue; a = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pixel::Pixel(uint32_t p)
|
||||||
|
{
|
||||||
|
n = p;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================
|
//==========================================================
|
||||||
|
|
||||||
|
std::wstring ConvertS2W(std::string s)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
int count = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
|
||||||
|
wchar_t* buffer = new wchar_t[count];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer, count);
|
||||||
|
std::wstring w(buffer);
|
||||||
|
delete[] buffer;
|
||||||
|
return w;
|
||||||
|
#endif
|
||||||
|
//#ifdef __MINGW32__
|
||||||
|
// wchar_t *buffer = new wchar_t[sImageFile.length() + 1];
|
||||||
|
// mbstowcs(buffer, sImageFile.c_str(), sImageFile.length());
|
||||||
|
// buffer[sImageFile.length()] = L'\0';
|
||||||
|
// wsImageFile = buffer;
|
||||||
|
// delete[] buffer;
|
||||||
|
//#else
|
||||||
|
}
|
||||||
|
|
||||||
Sprite::Sprite()
|
Sprite::Sprite()
|
||||||
{
|
{
|
||||||
pColData = nullptr;
|
pColData = nullptr;
|
||||||
@ -572,8 +599,7 @@ namespace olc
|
|||||||
wsImageFile = buffer;
|
wsImageFile = buffer;
|
||||||
delete [] buffer;
|
delete [] buffer;
|
||||||
#else
|
#else
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
wsImageFile = ConvertS2W(sImageFile);
|
||||||
wsImageFile = converter.from_bytes(sImageFile);
|
|
||||||
#endif
|
#endif
|
||||||
Gdiplus::Bitmap *bmp = Gdiplus::Bitmap::FromFile(wsImageFile.c_str());
|
Gdiplus::Bitmap *bmp = Gdiplus::Bitmap::FromFile(wsImageFile.c_str());
|
||||||
if (bmp == nullptr)
|
if (bmp == nullptr)
|
||||||
@ -669,17 +695,28 @@ namespace olc
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
pColData = nullptr;
|
pColData = nullptr;
|
||||||
return olc::FAIL;
|
return olc::FAIL;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sprite::SetSampleMode(olc::Sprite::Mode mode)
|
||||||
|
{
|
||||||
|
modeSample = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Pixel Sprite::GetPixel(int32_t x, int32_t y)
|
Pixel Sprite::GetPixel(int32_t x, int32_t y)
|
||||||
{
|
{
|
||||||
if (x >= 0 && x < width && y >= 0 && y < height)
|
if (modeSample == olc::Sprite::Mode::NORMAL)
|
||||||
return pColData[y*width + x];
|
{
|
||||||
|
if (x >= 0 && x < width && y >= 0 && y < height)
|
||||||
|
return pColData[y*width + x];
|
||||||
|
else
|
||||||
|
return Pixel(0, 0, 0, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return Pixel(0,0,0,0);
|
{
|
||||||
|
return pColData[(y%height)*width + (x%width)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::SetPixel(int32_t x, int32_t y, Pixel p)
|
void Sprite::SetPixel(int32_t x, int32_t y, Pixel p)
|
||||||
@ -710,13 +747,12 @@ namespace olc
|
|||||||
olc::PGEX::pge = this;
|
olc::PGEX::pge = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
olc::rcode PixelGameEngine::Construct(uint32_t screen_w, uint32_t screen_h, uint32_t pixel_w, uint32_t pixel_h, int32_t framerate)
|
olc::rcode PixelGameEngine::Construct(uint32_t screen_w, uint32_t screen_h, uint32_t pixel_w, uint32_t pixel_h)
|
||||||
{
|
{
|
||||||
nScreenWidth = screen_w;
|
nScreenWidth = screen_w;
|
||||||
nScreenHeight = screen_h;
|
nScreenHeight = screen_h;
|
||||||
nPixelWidth = pixel_w;
|
nPixelWidth = pixel_w;
|
||||||
nPixelHeight = pixel_h;
|
nPixelHeight = pixel_h;
|
||||||
fFramePeriod = 1.0f / (float)framerate;
|
|
||||||
|
|
||||||
fPixelX = 2.0f / (float)(nScreenWidth);
|
fPixelX = 2.0f / (float)(nScreenWidth);
|
||||||
fPixelY = 2.0f / (float)(nScreenHeight);
|
fPixelY = 2.0f / (float)(nScreenHeight);
|
||||||
@ -727,8 +763,7 @@ namespace olc
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
wsAppName = ConvertS2W(sAppName);
|
||||||
wsAppName = converter.from_bytes(sAppName);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -869,6 +904,12 @@ namespace olc
|
|||||||
pDrawTarget->SetPixel(x, y, Pixel((uint8_t)r, (uint8_t)g, (uint8_t)b));
|
pDrawTarget->SetPixel(x, y, Pixel((uint8_t)r, (uint8_t)g, (uint8_t)b));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nPixelMode == Pixel::CUSTOM)
|
||||||
|
{
|
||||||
|
pDrawTarget->SetPixel(x, y, funcPixelMode(x, y, p, pDrawTarget->GetPixel(x, y)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelGameEngine::SetSubPixelOffset(float ox, float oy)
|
void PixelGameEngine::SetSubPixelOffset(float ox, float oy)
|
||||||
@ -1256,6 +1297,12 @@ namespace olc
|
|||||||
nPixelMode = m;
|
nPixelMode = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PixelGameEngine::SetPixelMode(std::function<olc::Pixel(const int x, const int y, const olc::Pixel&, const olc::Pixel&)> pixelMode)
|
||||||
|
{
|
||||||
|
funcPixelMode = pixelMode;
|
||||||
|
nPixelMode = Pixel::Mode::CUSTOM;
|
||||||
|
}
|
||||||
|
|
||||||
void PixelGameEngine::SetPixelBlend(float fBlend)
|
void PixelGameEngine::SetPixelBlend(float fBlend)
|
||||||
{
|
{
|
||||||
fBlendFactor = fBlend;
|
fBlendFactor = fBlend;
|
||||||
@ -1280,6 +1327,10 @@ namespace olc
|
|||||||
// But leave in pixel space
|
// But leave in pixel space
|
||||||
nMousePosX = x / nPixelWidth;
|
nMousePosX = x / nPixelWidth;
|
||||||
nMousePosY = y / nPixelHeight;
|
nMousePosY = y / nPixelHeight;
|
||||||
|
if (nMousePosX < 0) nMousePosX = 0;
|
||||||
|
if (nMousePosY < 0) nMousePosY = 0;
|
||||||
|
if (nMousePosX >= nScreenWidth) nMousePosX = nScreenWidth-1;
|
||||||
|
if (nMousePosX >= nScreenHeight) nMousePosY = nScreenHeight-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelGameEngine::EngineThread()
|
void PixelGameEngine::EngineThread()
|
||||||
@ -1450,29 +1501,19 @@ namespace olc
|
|||||||
if (fFrameTimer >= 1.0f)
|
if (fFrameTimer >= 1.0f)
|
||||||
{
|
{
|
||||||
fFrameTimer -= 1.0f;
|
fFrameTimer -= 1.0f;
|
||||||
|
|
||||||
|
std::string sTitle = "OneLoneCoder.com - Pixel Game Engine - " + sAppName + " - FPS: " + std::to_string(nFrameCount);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
wchar_t sTitle[256];
|
SetWindowText(olc_hWnd, ConvertS2W(sTitle).c_str());
|
||||||
swprintf(sTitle, 256, L"OneLoneCoder.com - Pixel Game Engine - %s - FPS: %d", wsAppName.c_str(), nFrameCount);
|
|
||||||
#else
|
#else
|
||||||
#ifndef __MINGW32__
|
SetWindowText(olc_hWnd, sTitle.c_str());
|
||||||
char sTitle[256];
|
|
||||||
sprintf_s(sTitle, 256, "OneLoneCoder.com - Pixel Game Engine - %s - FPS: %d", sAppName.c_str(), nFrameCount);
|
|
||||||
#else
|
|
||||||
char sTitle[256];
|
|
||||||
sprintf(sTitle, "OneLoneCoder.com - Pixel Game Engine - %s - FPS: %d", sAppName.c_str(), nFrameCount);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
SetWindowText(olc_hWnd, sTitle);
|
|
||||||
#else
|
#else
|
||||||
char sTitle[256];
|
XStoreName(olc_Display, olc_Window, sTitle.c_str());
|
||||||
sprintf(sTitle, "OneLoneCoder.com - Pixel Game Engine - %s - FPS: %d", sAppName.c_str(), nFrameCount);
|
|
||||||
XStoreName(olc_Display, olc_Window, sTitle);
|
|
||||||
#endif
|
#endif
|
||||||
nFrameCount = 0;
|
nFrameCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow the user to free resources if they have overrided the destroy function
|
// Allow the user to free resources if they have overrided the destroy function
|
||||||
|
Loading…
x
Reference in New Issue
Block a user