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
pull/113/head
Javidx9 6 years ago committed by GitHub
parent e0bdd8cfbd
commit c9a1deef45
  1. 127
      olcPixelGameEngine.h

@ -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
@ -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 (modeSample == olc::Sprite::Mode::NORMAL)
{ {
if (x >= 0 && x < width && y >= 0 && y < height) if (x >= 0 && x < width && y >= 0 && y < height)
return pColData[y*width + x]; return pColData[y*width + x];
else else
return Pixel(0,0,0,0); return Pixel(0, 0, 0, 0);
}
else
{
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…
Cancel
Save