olcPixelGameEngine 2.19

2.19: Textual Input(of)course Edition!
=Built in font is now olc::Renderable
+EnablePixelTransfer() - Gate if layer content transfers occur (speedup in decal only apps)
+TextEntryEnable() - Enables/Disables text entry mode
+TextEntryGetString() - Gets the current accumulated string in text entry mode
+TextEntryGetCursor() - Gets the current cursor position in text entry mode
+IsTextEntryEnabled() - Returns true if text entry mode is activated
+OnTextEntryComplete() - Override is called when user presses "ENTER" in text entry mode
+Potential for regional keyboard mappings - needs volunteers to do this
+ConsoleShow() - Opens built in command console
+ConsoleClear() - Clears built in command console output
+ConsoleOut() - Stream strings to command console output
+ConsoleCaptureStdOut() - Capture std::cout by redirecting to built-in console
+IsConsoleShowing() - Returns true if console is currently active
+OnConsoleCommand() - Override is called when command is entered into built in console
pull/236/merge v2.19
Javidx9 3 years ago committed by GitHub
parent 12f634007c
commit 6cc039c2fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 369
      olcPixelGameEngine.h

@ -3,7 +3,7 @@
olcPixelGameEngine.h
+-------------------------------------------------------------+
| OneLoneCoder Pixel Game Engine v2.17 |
| OneLoneCoder Pixel Game Engine v2.19 |
| "What do you need? Pixels... Lots of Pixels..." - javidx9 |
+-------------------------------------------------------------+
@ -282,7 +282,23 @@
+Reintroduced sub-pixel decals
+Modified DrawPartialDecal() to quantise and correctly sample from tile atlasses
+olc::Sprite::GetPixel() - Clamp Mode
2.18: +Option to not "dirty" layers with SetDrawTarget() - Thanks TerasKasi!
=Detection for Mac M1, fix for scroll wheel interrogation - Thanks ruarq!
2.19: Textual Input(of)course Edition!
=Built in font is now olc::Renderable
+EnablePixelTransfer() - Gate if layer content transfers occur (speedup in decal only apps)
+TextEntryEnable() - Enables/Disables text entry mode
+TextEntryGetString() - Gets the current accumulated string in text entry mode
+TextEntryGetCursor() - Gets the current cursor position in text entry mode
+IsTextEntryEnabled() - Returns true if text entry mode is activated
+OnTextEntryComplete() - Override is called when user presses "ENTER" in text entry mode
+Potential for regional keyboard mappings - needs volunteers to do this
+ConsoleShow() - Opens built in command console
+ConsoleClear() - Clears built in command console output
+ConsoleOut() - Stream strings to command console output
+ConsoleCaptureStdOut() - Capture std::cout by redirecting to built-in console
+IsConsoleShowing() - Returns true if console is currently active
+OnConsoleCommand() - Override is called when command is entered into built in console
!! Apple Platforms will not see these updates immediately - Sorry, I dont have a mac to test... !!
!! Volunteers willing to help appreciated, though PRs are manually integrated with credit !!
@ -362,7 +378,7 @@ int main()
#include <cstring>
#pragma endregion
#define PGE_VER 217
#define PGE_VER 219
// O------------------------------------------------------------------------------O
// | COMPILER CONFIGURATION ODDITIES |
@ -380,6 +396,10 @@ int main()
#endif
#endif
#if !defined(OLC_KEYBOARD_UK)
#define OLC_KEYBOARD_UK
#endif
#if defined(USE_EXPERIMENTAL_FS) || defined(FORCE_EXPERIMENTAL_FS)
// C++14
@ -909,6 +929,11 @@ namespace olc
// Called once on application termination, so you can be one clean coder
virtual bool OnUserDestroy();
// Called when a text entry is confirmed with "enter" key
virtual void OnTextEntryComplete(const std::string& sText);
// Called when a console command is executed
virtual bool OnConsoleCommand(const std::string& sCommand);
public: // Hardware Interfaces
// Returns true if window is currently in focus
bool IsFocused() const;
@ -958,7 +983,7 @@ namespace olc
public: // CONFIGURATION ROUTINES
// Layer targeting functions
void SetDrawTarget(uint8_t layer);
void SetDrawTarget(uint8_t layer, bool bDirty = true);
void EnableLayer(uint8_t layer, bool b);
void SetLayerOffset(uint8_t layer, const olc::vf2d& offset);
void SetLayerOffset(uint8_t layer, float x, float y);
@ -1071,6 +1096,30 @@ namespace olc
// Clip a line segment to visible area
bool ClipLineToScreen(olc::vi2d& in_p1, olc::vi2d& in_p2);
// Dont allow PGE to mark layers as dirty, so pixel graphics don't update
void EnablePixelTransfer(const bool bEnable = true);
// Command Console Routines
void ConsoleShow(const olc::Key &keyExit, bool bSuspendTime = true);
bool IsConsoleShowing() const;
void ConsoleClear();
std::stringstream& ConsoleOut();
void ConsoleCaptureStdOut(const bool bCapture);
// Text Entry Routines
void TextEntryEnable(const bool bEnable, const std::string& sText = "");
std::string TextEntryGetString() const;
int32_t TextEntryGetCursor() const;
bool IsTextEntryEnabled() const;
private:
void UpdateTextEntry();
void UpdateConsole();
public:
// Experimental Lightweight 3D Routines ================
#ifdef OLC_ENABLE_EXPERIMENTAL
// Set Manual View Matrix
@ -1123,9 +1172,9 @@ namespace olc
bool bEnableVSYNC = false;
float fFrameTimer = 1.0f;
float fLastElapsed = 0.0f;
int nFrameCount = 0;
Sprite* fontSprite = nullptr;
Decal* fontDecal = nullptr;
int nFrameCount = 0;
bool bSuspendTextureTransfer = false;
Renderable fontRenderable;
std::vector<LayerDesc> vLayers;
uint8_t nTargetLayer = 0;
uint32_t nLastFPS = 0;
@ -1136,6 +1185,27 @@ namespace olc
std::chrono::time_point<std::chrono::system_clock> m_tp1, m_tp2;
std::vector<olc::vi2d> vFontSpacing;
// Command Console Specific
bool bConsoleShow = false;
bool bConsoleSuspendTime = false;
olc::Key keyConsoleExit = olc::Key::F1;
std::stringstream ssConsoleOutput;
std::streambuf* sbufOldCout = nullptr;
olc::vi2d vConsoleSize;
olc::vi2d vConsoleCursor = { 0,0 };
olc::vf2d vConsoleCharacterScale = { 1.0f, 2.0f };
std::vector<std::string> sConsoleLines;
std::list<std::string> sCommandHistory;
std::list<std::string>::iterator sCommandHistoryIt;
// Text Entry Specific
bool bTextEntryEnable = false;
std::string sTextEntryString = "";
int32_t nTextEntryCursor = 0;
std::vector<std::tuple<olc::Key, std::string, std::string>> vKeyboardMap;
// State of keyboard
bool pKeyNewState[256] = { 0 };
bool pKeyOldState[256] = { 0 };
@ -1769,12 +1839,12 @@ namespace olc
}
}
void PixelGameEngine::SetDrawTarget(uint8_t layer)
void PixelGameEngine::SetDrawTarget(uint8_t layer, bool bDirty)
{
if (layer < vLayers.size())
{
pDrawTarget = vLayers[layer].pDrawTarget.Sprite();
vLayers[layer].bUpdate = true;
vLayers[layer].bUpdate = bDirty;
nTargetLayer = layer;
}
}
@ -2105,7 +2175,7 @@ namespace olc
{ renderer->ClearBuffer(p, bDepth); }
olc::Sprite* PixelGameEngine::GetFontSprite()
{ return fontSprite; }
{ return fontRenderable.Sprite(); }
bool PixelGameEngine::ClipLineToScreen(olc::vi2d& in_p1, olc::vi2d& in_p2)
{
@ -2140,6 +2210,11 @@ namespace olc
return true;
}
void PixelGameEngine::EnablePixelTransfer(const bool bEnable)
{
bSuspendTextureTransfer = !bEnable;
}
void PixelGameEngine::FillRect(const olc::vi2d& pos, const olc::vi2d& size, Pixel p)
{ FillRect(pos.x, pos.y, size.x, size.y, p); }
@ -2776,7 +2851,7 @@ namespace olc
{
int32_t ox = (c - 32) % 16;
int32_t oy = (c - 32) / 16;
DrawPartialDecal(pos + spos, fontDecal, { float(ox) * 8.0f, float(oy) * 8.0f }, { 8.0f, 8.0f }, scale, col);
DrawPartialDecal(pos + spos, fontRenderable.Decal(), {float(ox) * 8.0f, float(oy) * 8.0f}, {8.0f, 8.0f}, scale, col);
spos.x += 8.0f * scale.x;
}
}
@ -2799,7 +2874,7 @@ namespace olc
{
int32_t ox = (c - 32) % 16;
int32_t oy = (c - 32) / 16;
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);
DrawPartialDecal(pos + spos, fontRenderable.Decal(), { float(ox) * 8.0f + float(vFontSpacing[c - 32].x), float(oy) * 8.0f }, { float(vFontSpacing[c - 32].y), 8.0f }, scale, col);
spos.x += float(vFontSpacing[c - 32].y) * scale.x;
}
}
@ -2822,7 +2897,7 @@ namespace olc
{
int32_t ox = (c - 32) % 16;
int32_t oy = (c - 32) / 16;
DrawPartialRotatedDecal(pos, fontDecal, fAngle, spos, { float(ox) * 8.0f, float(oy) * 8.0f }, { 8.0f, 8.0f }, scale, col);
DrawPartialRotatedDecal(pos, fontRenderable.Decal(), fAngle, spos, { float(ox) * 8.0f, float(oy) * 8.0f }, { 8.0f, 8.0f }, scale, col);
spos.x -= 8.0f;
}
}
@ -2845,7 +2920,7 @@ namespace olc
{
int32_t ox = (c - 32) % 16;
int32_t oy = (c - 32) / 16;
DrawPartialRotatedDecal(pos, fontDecal, fAngle, spos, { float(ox) * 8.0f + float(vFontSpacing[c - 32].x), float(oy) * 8.0f }, { float(vFontSpacing[c - 32].y), 8.0f }, scale, col);
DrawPartialRotatedDecal(pos, fontRenderable.Decal(), fAngle, spos, { float(ox) * 8.0f + float(vFontSpacing[c - 32].x), float(oy) * 8.0f }, { float(vFontSpacing[c - 32].y), 8.0f }, scale, col);
spos.x -= float(vFontSpacing[c - 32].y);
}
}
@ -2899,7 +2974,7 @@ namespace olc
{
for (uint32_t i = 0; i < 8; i++)
for (uint32_t j = 0; j < 8; j++)
if (fontSprite->GetPixel(i + ox * 8, j + oy * 8).r > 0)
if (fontRenderable.Sprite()->GetPixel(i + ox * 8, j + oy * 8).r > 0)
for (uint32_t is = 0; is < scale; is++)
for (uint32_t js = 0; js < scale; js++)
Draw(x + sx + (i * scale) + is, y + sy + (j * scale) + js, col);
@ -2908,7 +2983,7 @@ namespace olc
{
for (uint32_t i = 0; i < 8; i++)
for (uint32_t j = 0; j < 8; j++)
if (fontSprite->GetPixel(i + ox * 8, j + oy * 8).r > 0)
if (fontRenderable.Sprite()->GetPixel(i + ox * 8, j + oy * 8).r > 0)
Draw(x + sx + i, y + sy + j, col);
}
sx += 8 * scale;
@ -2967,7 +3042,7 @@ namespace olc
{
for (int32_t i = 0; i < vFontSpacing[c - 32].y; i++)
for (int32_t j = 0; j < 8; j++)
if (fontSprite->GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).r > 0)
if (fontRenderable.Sprite()->GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).r > 0)
for (int32_t is = 0; is < int(scale); is++)
for (int32_t js = 0; js < int(scale); js++)
Draw(x + sx + (i * scale) + is, y + sy + (j * scale) + js, col);
@ -2976,7 +3051,7 @@ namespace olc
{
for (int32_t i = 0; i < vFontSpacing[c - 32].y; i++)
for (int32_t j = 0; j < 8; j++)
if (fontSprite->GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).r > 0)
if (fontRenderable.Sprite()->GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).r > 0)
Draw(x + sx + i, y + sy + j, col);
}
sx += vFontSpacing[c - 32].y * scale;
@ -3004,6 +3079,204 @@ namespace olc
if (fBlendFactor > 1.0f) fBlendFactor = 1.0f;
}
std::stringstream& PixelGameEngine::ConsoleOut()
{ return ssConsoleOutput; }
bool PixelGameEngine::IsConsoleShowing() const
{ return bConsoleShow; }
void PixelGameEngine::ConsoleShow(const olc::Key& keyExit, bool bSuspendTime)
{
if (bConsoleShow)
return;
bConsoleShow = true;
bConsoleSuspendTime = bSuspendTime;
TextEntryEnable(true);
keyConsoleExit = keyExit;
pKeyboardState[keyConsoleExit].bHeld = false;
pKeyboardState[keyConsoleExit].bPressed = false;
pKeyboardState[keyConsoleExit].bReleased = true;
}
void PixelGameEngine::ConsoleClear()
{ sConsoleLines.clear(); }
void PixelGameEngine::ConsoleCaptureStdOut(const bool bCapture)
{
if(bCapture)
sbufOldCout = std::cout.rdbuf(ssConsoleOutput.rdbuf());
else
std::cout.rdbuf(sbufOldCout);
}
void PixelGameEngine::UpdateConsole()
{
if (GetKey(keyConsoleExit).bPressed)
{
TextEntryEnable(false);
bConsoleSuspendTime = false;
bConsoleShow = false;
return;
}
// Keep Console sizes based in real screen dimensions
vConsoleCharacterScale = olc::vf2d(1.0f, 2.0f) / (olc::vf2d(vViewSize) * vInvScreenSize);
vConsoleSize = (vViewSize / olc::vi2d(8, 16)) - olc::vi2d(2, 4);
// If console has changed size, simply reset it
if (vConsoleSize.y != sConsoleLines.size())
{
vConsoleCursor = { 0,0 };
sConsoleLines.clear();
sConsoleLines.resize(vConsoleSize.y);
}
auto TypeCharacter = [&](const char c)
{
if (c >= 32 && c < 127)
{
sConsoleLines[vConsoleCursor.y].append(1, c);
vConsoleCursor.x++;
}
if( c == '\n' || vConsoleCursor.x >= vConsoleSize.x)
{
vConsoleCursor.y++; vConsoleCursor.x = 0;
}
if (vConsoleCursor.y >= vConsoleSize.y)
{
vConsoleCursor.y = vConsoleSize.y - 1;
for (size_t i = 1; i < vConsoleSize.y; i++)
sConsoleLines[i - 1] = sConsoleLines[i];
sConsoleLines[vConsoleCursor.y].clear();
}
};
// Empty out "std::cout", parsing as we go
while (ssConsoleOutput.rdbuf()->sgetc() != -1)
{
char c = ssConsoleOutput.rdbuf()->sbumpc();
TypeCharacter(c);
}
// Draw Shadow
GradientFillRectDecal({ 0,0 }, olc::vf2d(vScreenSize), olc::PixelF(0, 0, 0.5f, 0.5f), olc::PixelF(0, 0, 0.25f, 0.5f), olc::PixelF(0, 0, 0.25f, 0.5f), olc::PixelF(0, 0, 0.25f, 0.5f));
// Draw the console buffer
SetDecalMode(olc::DecalMode::NORMAL);
for (int32_t nLine = 0; nLine < vConsoleSize.y; nLine++)
DrawStringDecal(olc::vf2d( 1, 1 + float(nLine) ) * vConsoleCharacterScale * 8.0f, sConsoleLines[nLine], olc::WHITE, vConsoleCharacterScale);
// Draw Input State
FillRectDecal(olc::vf2d(1 + float((TextEntryGetCursor() + 1)), 1 + float((vConsoleSize.y - 1))) * vConsoleCharacterScale * 8.0f, olc::vf2d(8, 8) * vConsoleCharacterScale, olc::DARK_CYAN);
DrawStringDecal(olc::vf2d(1, 1 + float((vConsoleSize.y - 1))) * vConsoleCharacterScale * 8.0f, std::string(">") + TextEntryGetString(), olc::YELLOW, vConsoleCharacterScale);
}
void PixelGameEngine::TextEntryEnable(const bool bEnable, const std::string& sText)
{
if (bEnable)
{
nTextEntryCursor = int32_t(sText.size());
sTextEntryString = sText;
bTextEntryEnable = true;
}
else
{
bTextEntryEnable = false;
}
}
std::string PixelGameEngine::TextEntryGetString() const
{ return sTextEntryString; }
int32_t PixelGameEngine::TextEntryGetCursor() const
{ return nTextEntryCursor; }
bool PixelGameEngine::IsTextEntryEnabled() const
{ return bTextEntryEnable; }
void PixelGameEngine::UpdateTextEntry()
{
// Check for typed characters
for (const auto& key : vKeyboardMap)
if (GetKey(std::get<0>(key)).bPressed)
{
sTextEntryString.insert(nTextEntryCursor, GetKey(olc::Key::SHIFT).bHeld ? std::get<2>(key) : std::get<1>(key));
nTextEntryCursor++;
}
// Check for command characters
if (GetKey(olc::Key::LEFT).bPressed)
nTextEntryCursor = std::max(0, nTextEntryCursor - 1);
if (GetKey(olc::Key::RIGHT).bPressed)
nTextEntryCursor = std::min(int32_t(sTextEntryString.size()), nTextEntryCursor + 1);
if (GetKey(olc::Key::BACK).bPressed && nTextEntryCursor > 0)
{
sTextEntryString.erase(nTextEntryCursor-1, 1);
nTextEntryCursor = std::max(0, nTextEntryCursor - 1);
}
if (GetKey(olc::Key::DEL).bPressed && nTextEntryCursor < sTextEntryString.size())
sTextEntryString.erase(nTextEntryCursor, 1);
if (GetKey(olc::Key::UP).bPressed)
{
if (!sCommandHistory.empty())
{
if (sCommandHistoryIt != sCommandHistory.begin())
sCommandHistoryIt--;
nTextEntryCursor = int32_t(sCommandHistoryIt->size());
sTextEntryString = *sCommandHistoryIt;
}
}
if (GetKey(olc::Key::DOWN).bPressed)
{
if (!sCommandHistory.empty())
{
if (sCommandHistoryIt != sCommandHistory.end())
{
sCommandHistoryIt++;
if (sCommandHistoryIt != sCommandHistory.end())
{
nTextEntryCursor = int32_t(sCommandHistoryIt->size());
sTextEntryString = *sCommandHistoryIt;
}
else
{
nTextEntryCursor = 0;
sTextEntryString = "";
}
}
}
}
if (GetKey(olc::Key::ENTER).bPressed)
{
if (bConsoleShow)
{
std::cout << ">" + sTextEntryString + "\n";
if (OnConsoleCommand(sTextEntryString))
{
sCommandHistory.push_back(sTextEntryString);
sCommandHistoryIt = sCommandHistory.end();
}
sTextEntryString.clear();
nTextEntryCursor = 0;
}
else
{
OnTextEntryComplete(sTextEntryString);
TextEntryEnable(false);
}
}
}
// User must override these functions as required. I have not made
// them abstract because I do need a default behaviour to occur if
// they are not overwritten
@ -3016,7 +3289,12 @@ namespace olc
bool PixelGameEngine::OnUserDestroy()
{ return true; }
void PixelGameEngine::OnTextEntryComplete(const std::string& sText) { UNUSED(sText); }
bool PixelGameEngine::OnConsoleCommand(const std::string& sCommand) { UNUSED(sCommand); return false; }
// Externalised API
void PixelGameEngine::olc_UpdateViewport()
{
int32_t ww = vScreenSize.x * vPixelSize.x;
@ -3150,6 +3428,9 @@ namespace olc
float fElapsedTime = elapsedTime.count();
fLastElapsed = fElapsedTime;
if (bConsoleSuspendTime)
fElapsedTime = 0.0f;
// Some platforms will need to check for events
platform->HandleSystemEvent();
@ -3185,7 +3466,10 @@ namespace olc
nMouseWheelDelta = nMouseWheelDeltaCache;
nMouseWheelDeltaCache = 0;
// renderer->ClearBuffer(olc::BLACK, true);
if (bTextEntryEnable)
{
UpdateTextEntry();
}
// Handle Frame Update
bool bExtensionBlockFrame = false;
@ -3196,6 +3480,12 @@ namespace olc
}
for (auto& ext : vExtensions) ext->OnAfterUserUpdate(fElapsedTime);
if (bConsoleShow)
{
SetDrawTarget((uint8_t)0);
UpdateConsole();
}
// Display Frame
renderer->UpdateViewport(vViewPos, vViewSize);
renderer->ClearBuffer(olc::BLACK, true);
@ -3213,7 +3503,7 @@ namespace olc
if (layer->funcHook == nullptr)
{
renderer->ApplyTexture(layer->pDrawTarget.Decal()->id);
if (layer->bUpdate)
if (!bSuspendTextureTransfer && layer->bUpdate)
{
layer->pDrawTarget.Decal()->Update();
layer->bUpdate = false;
@ -3234,6 +3524,8 @@ namespace olc
}
}
// Present Graphics to screen
renderer->DisplayFrame();
@ -3270,7 +3562,8 @@ namespace olc
data += "O`000P08Od400g`<3V=P0G`673IP0`@3>1`00P@6O`P00g`<O`000GP800000000";
data += "?P9PL020O`<`N3R0@E4HC7b0@ET<ATB0@@l6C4B0O`H3N7b0?P01L3R000000020";
fontSprite = new olc::Sprite(128, 48);
fontRenderable.Create(128, 48);
int px = 0, py = 0;
for (size_t b = 0; b < 1024; b += 4)
{
@ -3283,12 +3576,12 @@ namespace olc
for (int i = 0; i < 24; i++)
{
int k = r & (1 << i) ? 255 : 0;
fontSprite->SetPixel(px, py, olc::Pixel(k, k, k, k));
fontRenderable.Sprite()->SetPixel(px, py, olc::Pixel(k, k, k, k));
if (++py == 48) { px++; py = 0; }
}
}
fontDecal = new olc::Decal(fontSprite);
fontRenderable.Decal()->Update();
constexpr std::array<uint8_t, 96> vSpacing = { {
0x03,0x25,0x16,0x08,0x07,0x08,0x08,0x04,0x15,0x15,0x08,0x07,0x15,0x07,0x24,0x08,
@ -3300,6 +3593,32 @@ namespace olc
for (auto c : vSpacing) vFontSpacing.push_back({ c >> 4, c & 15 });
// UK Standard Layout
#ifdef OLC_KEYBOARD_UK
vKeyboardMap =
{
{olc::Key::A, "a", "A"}, {olc::Key::B, "b", "B"}, {olc::Key::C, "c", "C"}, {olc::Key::D, "d", "D"}, {olc::Key::E, "e", "E"},
{olc::Key::F, "f", "F"}, {olc::Key::G, "g", "G"}, {olc::Key::H, "h", "H"}, {olc::Key::I, "i", "I"}, {olc::Key::J, "j", "J"},
{olc::Key::K, "k", "K"}, {olc::Key::L, "l", "L"}, {olc::Key::M, "m", "M"}, {olc::Key::N, "n", "N"}, {olc::Key::O, "o", "O"},
{olc::Key::P, "p", "P"}, {olc::Key::Q, "q", "Q"}, {olc::Key::R, "r", "R"}, {olc::Key::S, "s", "S"}, {olc::Key::T, "t", "T"},
{olc::Key::U, "u", "U"}, {olc::Key::V, "v", "V"}, {olc::Key::W, "w", "W"}, {olc::Key::X, "x", "X"}, {olc::Key::Y, "y", "Y"},
{olc::Key::Z, "z", "Z"},
{olc::Key::K0, "0", ")"}, {olc::Key::K1, "1", "!"}, {olc::Key::K2, "2", "\""}, {olc::Key::K3, "3", "#"}, {olc::Key::K4, "4", "$"},
{olc::Key::K5, "5", "%"}, {olc::Key::K6, "6", "^"}, {olc::Key::K7, "7", "&"}, {olc::Key::K8, "8", "*"}, {olc::Key::K9, "9", "("},
{olc::Key::NP0, "0", "0"}, {olc::Key::NP1, "1", "1"}, {olc::Key::NP2, "2", "2"}, {olc::Key::NP3, "3", "3"}, {olc::Key::NP4, "4", "4"},
{olc::Key::NP5, "5", "5"}, {olc::Key::NP6, "6", "6"}, {olc::Key::NP7, "7", "7"}, {olc::Key::NP8, "8", "8"}, {olc::Key::NP9, "9", "9"},
{olc::Key::NP_MUL, "*", "*"}, {olc::Key::NP_DIV, "/", "/"}, {olc::Key::NP_ADD, "+", "+"}, {olc::Key::NP_SUB, "-", "-"}, {olc::Key::NP_DECIMAL, ".", "."},
{olc::Key::PERIOD, ".", ">"}, {olc::Key::EQUALS, "=", "+"}, {olc::Key::COMMA, ",", "<"}, {olc::Key::MINUS, "-", "_"}, {olc::Key::SPACE, " ", " "},
{olc::Key::OEM_1, ";", ":"}, {olc::Key::OEM_2, "/", "?"}, {olc::Key::OEM_3, "\'", "@"}, {olc::Key::OEM_4, "[", "{"},
{olc::Key::OEM_5, "\\", "|"}, {olc::Key::OEM_6, "]", "}"}, {olc::Key::OEM_7, "#", "~"},
// {olc::Key::TAB, "\t", "\t"}
};
#endif
}
void PixelGameEngine::pgex_Register(olc::PGEX* pgex)
@ -5086,7 +5405,11 @@ namespace olc {
static void scrollWheelUpdate(id selff, SEL _sel, id theEvent) {
static const SEL deltaYSel = sel_registerName("deltaY");
#if defined(__aarch64__) // Thanks ruarq!
double deltaY = ((double (*)(id, SEL))objc_msgSend)(theEvent, deltaYSel);
#else
double deltaY = ((double (*)(id, SEL))objc_msgSend_fpret)(theEvent, deltaYSel);
#endif
for (int i = 0; i < abs(deltaY); i++) {
if (deltaY > 0) {

Loading…
Cancel
Save