Latest olcCGE.h

master
Javidx9 7 years ago committed by GitHub
parent 8b34076cbe
commit fc3771eae8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 135
      olcConsoleGameEngine.h

@ -33,9 +33,9 @@ Beginners Guide: https://youtu.be/u5BhrA8ED0o
Shout Outs! Shout Outs!
~~~~~~~~~~~ ~~~~~~~~~~~
Thanks to cool people who helped with testing, bug-finding and fixing! Thanks to cool people who helped with testing, bug-finding and fixing!
YouTube: wowLinh, JavaJack59, idkwid YouTube: wowLinh, JavaJack59, idkwid, kingtatgi
Last Updated: 07/12/2017 Last Updated: 04/02/2018
Usage: Usage:
~~~~~~ ~~~~~~
@ -191,7 +191,7 @@ private:
public: public:
void SetGlyph(int x, int y, wchar_t c) void SetGlyph(int x, int y, wchar_t c)
{ {
if (x <0 || x > nWidth || y < 0 || y > nHeight) if (x <0 || x >= nWidth || y < 0 || y >= nHeight)
return; return;
else else
m_Glyphs[y * nWidth + x] = c; m_Glyphs[y * nWidth + x] = c;
@ -199,7 +199,7 @@ public:
void SetColour(int x, int y, short c) void SetColour(int x, int y, short c)
{ {
if (x <0 || x > nWidth || y < 0 || y > nHeight) if (x <0 || x >= nWidth || y < 0 || y >= nHeight)
return; return;
else else
m_Colours[y * nWidth + x] = c; m_Colours[y * nWidth + x] = c;
@ -207,7 +207,7 @@ public:
wchar_t GetGlyph(int x, int y) wchar_t GetGlyph(int x, int y)
{ {
if (x <0 || x > nWidth || y < 0 || y > nHeight) if (x <0 || x >= nWidth || y < 0 || y >= nHeight)
return L' '; return L' ';
else else
return m_Glyphs[y * nWidth + x]; return m_Glyphs[y * nWidth + x];
@ -215,7 +215,7 @@ public:
short GetColour(int x, int y) short GetColour(int x, int y)
{ {
if (x <0 || x > nWidth || y < 0 || y > nHeight) if (x <0 || x >= nWidth || y < 0 || y >= nHeight)
return FG_BLACK; return FG_BLACK;
else else
return m_Colours[y * nWidth + x]; return m_Colours[y * nWidth + x];
@ -225,7 +225,7 @@ public:
{ {
int sx = (int)(x * (float)nWidth); int sx = (int)(x * (float)nWidth);
int sy = (int)(y * (float)nHeight-1.0f); int sy = (int)(y * (float)nHeight-1.0f);
if (sx <0 || sx > nWidth || sy < 0 || sy > nHeight) if (sx <0 || sx >= nWidth || sy < 0 || sy >= nHeight)
return L' '; return L' ';
else else
return m_Glyphs[sy * nWidth + sx]; return m_Glyphs[sy * nWidth + sx];
@ -235,7 +235,7 @@ public:
{ {
int sx = (int)(x * (float)nWidth); int sx = (int)(x * (float)nWidth);
int sy = (int)(y * (float)nHeight-1.0f); int sy = (int)(y * (float)nHeight-1.0f);
if (sx <0 || sx > nWidth || sy < 0 || sy > nHeight) if (sx <0 || sx >= nWidth || sy < 0 || sy >= nHeight)
return FG_BLACK; return FG_BLACK;
else else
return m_Colours[sy * nWidth + sx]; return m_Colours[sy * nWidth + sx];
@ -296,12 +296,9 @@ public:
m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE); m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
m_hConsoleIn = GetStdHandle(STD_INPUT_HANDLE); m_hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
m_keyNewState = new short[256];
m_keyOldState = new short[256];
memset(m_keyNewState, 0, 256 * sizeof(short)); memset(m_keyNewState, 0, 256 * sizeof(short));
memset(m_keyOldState, 0, 256 * sizeof(short)); memset(m_keyOldState, 0, 256 * sizeof(short));
memset(m_keys, 0, 256 * sizeof(sKeyState)); memset(m_keys, 0, 256 * sizeof(sKeyState));
m_mousePosX = 0; m_mousePosX = 0;
m_mousePosY = 0; m_mousePosY = 0;
@ -350,6 +347,7 @@ public:
cfi.dwFontSize.Y = fonth; cfi.dwFontSize.Y = fonth;
cfi.FontFamily = FF_DONTCARE; cfi.FontFamily = FF_DONTCARE;
cfi.FontWeight = FW_NORMAL; cfi.FontWeight = FW_NORMAL;
//wcscpy_s(cfi.FaceName, L"Liberation Mono");
wcscpy_s(cfi.FaceName, L"Consolas"); wcscpy_s(cfi.FaceName, L"Consolas");
if (!SetCurrentConsoleFontEx(m_hConsole, false, &cfi)) if (!SetCurrentConsoleFontEx(m_hConsole, false, &cfi))
return Error(L"SetCurrentConsoleFontEx"); return Error(L"SetCurrentConsoleFontEx");
@ -522,6 +520,32 @@ public:
} }
} }
void FillCircle(int xc, int yc, int r, wchar_t c = 0x2588, short col = 0x000F)
{
// Taken from wikipedia
int x = 0;
int y = r;
int p = 3 - 2 * r;
if (!r) return;
auto drawline = [&](int sx, int ex, int ny)
{
for (int i = sx; i < ex; i++)
Draw(i, ny, c, col);
};
while (y >= x)
{
// Modified to draw scan-lines instead of edges
drawline(xc - x, xc + x, yc - y);
drawline(xc - y, xc + y, yc - x);
drawline(xc - x, xc + x, yc + y);
drawline(xc - y, xc + y, yc + x);
if (p < 0) p += 4 * x++ + 6;
else p += 4 * (x++ - y--) + 10;
}
};
void DrawSprite(int x, int y, olcSprite *sprite) void DrawSprite(int x, int y, olcSprite *sprite)
{ {
if (sprite == nullptr) if (sprite == nullptr)
@ -607,10 +631,6 @@ public:
thread t = thread(&olcConsoleGameEngine::GameThread, this); thread t = thread(&olcConsoleGameEngine::GameThread, this);
// Wait for thread to be exited // Wait for thread to be exited
unique_lock<mutex> ul(m_muxGame);
m_cvGameFinished.wait(ul);
// Tidy up
t.join(); t.join();
} }
@ -634,6 +654,8 @@ private:
auto tp1 = chrono::system_clock::now(); auto tp1 = chrono::system_clock::now();
auto tp2 = chrono::system_clock::now(); auto tp2 = chrono::system_clock::now();
while (m_bAtomActive)
{
// Run as fast as possible // Run as fast as possible
while (m_bAtomActive) while (m_bAtomActive)
{ {
@ -681,6 +703,12 @@ private:
{ {
switch (inBuf[i].EventType) switch (inBuf[i].EventType)
{ {
case FOCUS_EVENT:
{
m_bConsoleInFocus = inBuf[i].Event.FocusEvent.bSetFocus;
}
break;
case MOUSE_EVENT: case MOUSE_EVENT:
{ {
switch (inBuf[i].Event.MouseEvent.dwEventFlags) switch (inBuf[i].Event.MouseEvent.dwEventFlags)
@ -746,23 +774,36 @@ private:
WriteConsoleOutput(m_hConsole, m_bufScreen, { (short)m_nScreenWidth, (short)m_nScreenHeight }, { 0,0 }, &m_rectWindow); WriteConsoleOutput(m_hConsole, m_bufScreen, { (short)m_nScreenWidth, (short)m_nScreenHeight }, { 0,0 }, &m_rectWindow);
} }
if (OnUserDestroy())
{
// User has permitted destroy, so exit and clean up
delete[] m_bufScreen;
SetConsoleActiveScreenBuffer(m_hOriginalConsole);
m_cvGameFinished.notify_one(); m_cvGameFinished.notify_one();
} }
else
{
// User denied destroy for some reason, so continue running
m_bAtomActive = true;
}
}
}
public: public:
// User MUST OVERRIDE THESE!! // User MUST OVERRIDE THESE!!
virtual bool OnUserCreate() = 0; virtual bool OnUserCreate() = 0;
virtual bool OnUserUpdate(float fElapsedTime) = 0; virtual bool OnUserUpdate(float fElapsedTime) = 0;
// Optional for clean up
virtual bool OnUserDestroy()
{
return true;
}
protected: protected:
int m_nScreenWidth;
int m_nScreenHeight;
CHAR_INFO *m_bufScreen;
atomic<bool> m_bAtomActive;
condition_variable m_cvGameFinished;
mutex m_muxGame;
wstring m_sAppName;
struct sKeyState struct sKeyState
{ {
@ -775,11 +816,11 @@ protected:
int m_mousePosY; int m_mousePosY;
public: public:
sKeyState GetKey(int nKeyID) sKeyState GetKey(int nKeyID){ return m_keys[nKeyID]; }
{ int GetMouseX() { return m_mousePosX; }
return m_keys[nKeyID]; int GetMouseY() { return m_mousePosY; }
} sKeyState GetMouse(int nMouseButtonID) { return m_mouse[nMouseButtonID]; }
bool IsFocused() { return m_bConsoleInFocus; }
protected: protected:
@ -789,17 +830,45 @@ protected:
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
SetConsoleActiveScreenBuffer(m_hOriginalConsole); SetConsoleActiveScreenBuffer(m_hOriginalConsole);
wprintf(L"ERROR: %s\n\t%s\n", msg, buf); wprintf(L"ERROR: %s\n\t%s\n", msg, buf);
return -1; return 0;
} }
private: static BOOL CloseHandler(DWORD evt)
{
// Note this gets called in a seperate OS thread, so it must
// only exit when the game has finished cleaning up, or else
// the process will be killed before OnUserDestroy() has finished
if (evt == CTRL_CLOSE_EVENT)
{
m_bAtomActive = false;
// Wait for thread to be exited
unique_lock<mutex> ul(m_muxGame);
m_cvGameFinished.wait(ul);
}
return true;
}
protected:
int m_nScreenWidth;
int m_nScreenHeight;
CHAR_INFO *m_bufScreen;
wstring m_sAppName;
HANDLE m_hOriginalConsole; HANDLE m_hOriginalConsole;
CONSOLE_SCREEN_BUFFER_INFO m_OriginalConsoleInfo; CONSOLE_SCREEN_BUFFER_INFO m_OriginalConsoleInfo;
HANDLE m_hConsole; HANDLE m_hConsole;
HANDLE m_hConsoleIn; HANDLE m_hConsoleIn;
SMALL_RECT m_rectWindow; SMALL_RECT m_rectWindow;
short *m_keyOldState; short m_keyOldState[256] = { 0 };
short *m_keyNewState; short m_keyNewState[256] = { 0 };
bool m_mouseOldState[5]; bool m_mouseOldState[5] = { 0 };
bool m_mouseNewState[5]; bool m_mouseNewState[5] = { 0 };
bool m_bConsoleInFocus = true;
static atomic<bool> m_bAtomActive;
static condition_variable m_cvGameFinished;
static mutex m_muxGame;
}; };
atomic<bool> olcConsoleGameEngine::m_bAtomActive = false;
condition_variable olcConsoleGameEngine::m_cvGameFinished;
mutex olcConsoleGameEngine::m_muxGame;
Loading…
Cancel
Save