diff options
| author | qwasdrizzel <145519042+qwasdrizzel@users.noreply.github.com> | 2026-03-16 21:44:26 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-16 21:44:26 -0500 |
| commit | ce739f6045ec72127491286ea3f3f21e537c1b55 (patch) | |
| tree | f33bd42a47c1b4a7b2153a7fb77127ee3b407db9 /Minecraft.Client/Screen.cpp | |
| parent | 255a18fe8e9b57377975f82e2b227afe2a12eda0 (diff) | |
| parent | 5a59f5d146b43811dde6a5a0245ee9875d7b5cd1 (diff) | |
Merge branch 'smartcmd:main' into main
Diffstat (limited to 'Minecraft.Client/Screen.cpp')
| -rw-r--r-- | Minecraft.Client/Screen.cpp | 146 |
1 files changed, 110 insertions, 36 deletions
diff --git a/Minecraft.Client/Screen.cpp b/Minecraft.Client/Screen.cpp index 131cf013..7966c5c9 100644 --- a/Minecraft.Client/Screen.cpp +++ b/Minecraft.Client/Screen.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "Screen.h" #include "Button.h" +#include "ChatScreen.h" #include "GuiParticles.h" #include "Tesselator.h" #include "Textures.h" @@ -13,13 +14,13 @@ Screen::Screen() // 4J added { - minecraft = NULL; + minecraft = nullptr; width = 0; height = 0; passEvents = false; - font = NULL; - particles = NULL; - clickedButton = NULL; + font = nullptr; + particles = nullptr; + clickedButton = nullptr; } void Screen::render(int xm, int ym, float a) @@ -35,20 +36,39 @@ void Screen::keyPressed(wchar_t eventCharacter, int eventKey) { if (eventKey == Keyboard::KEY_ESCAPE) { - minecraft->setScreen(NULL); + minecraft->setScreen(nullptr); // minecraft->grabMouse(); // 4J - removed } } wstring Screen::getClipboard() { - // 4J - removed - return NULL; +#ifdef _WINDOWS64 + if (!OpenClipboard(nullptr)) return wstring(); + HANDLE h = GetClipboardData(CF_UNICODETEXT); + wstring out; + if (h) + { + const wchar_t *p = static_cast<const wchar_t*>(GlobalLock(h)); + if (p) { out = p; GlobalUnlock(h); } + } + CloseClipboard(); + return out; +#else + return wstring(); +#endif } void Screen::setClipboard(const wstring& str) { - // 4J - removed +#ifdef _WINDOWS64 + if (!OpenClipboard(nullptr)) return; + EmptyClipboard(); + size_t len = (str.length() + 1) * sizeof(wchar_t); + HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, len); + if (h) { memcpy(GlobalLock(h), str.c_str(), len); GlobalUnlock(h); SetClipboardData(CF_UNICODETEXT, h); } + CloseClipboard(); +#endif } void Screen::mouseClicked(int x, int y, int buttonNum) @@ -69,10 +89,10 @@ void Screen::mouseClicked(int x, int y, int buttonNum) void Screen::mouseReleased(int x, int y, int buttonNum) { - if (clickedButton!=NULL && buttonNum==0) + if (clickedButton!=nullptr && buttonNum==0) { clickedButton->released(x, y); - clickedButton = NULL; + clickedButton = nullptr; } } @@ -121,34 +141,88 @@ void Screen::updateEvents() } } - // Poll keyboard events + // Only drain WM_CHAR when this screen wants text input (e.g. ChatScreen); otherwise we'd steal keys from the game + if (dynamic_cast<ChatScreen*>(this) != nullptr) + { + wchar_t ch; + while (g_KBMInput.ConsumeChar(ch)) + { + if (ch >= 0x20) + keyPressed(ch, -1); + else if (ch == 0x08) + keyPressed(0, Keyboard::KEY_BACK); + else if (ch == 0x0D) + keyPressed(0, Keyboard::KEY_RETURN); + } + } + + // Arrow key repeat: deliver on first press (when key down and last==0) and while held (throttled) + static DWORD s_arrowLastTime[2] = { 0, 0 }; + static bool s_arrowFirstRepeat[2] = { false, false }; + const DWORD ARROW_REPEAT_DELAY_MS = 250; + const DWORD ARROW_REPEAT_INTERVAL_MS = 50; + DWORD now = GetTickCount(); + + // Poll keyboard events (special keys that may not come through WM_CHAR, e.g. Escape, arrows) for (int vk = 0; vk < 256; vk++) { - if (g_KBMInput.IsKeyPressed(vk)) + bool deliver = g_KBMInput.IsKeyPressed(vk); + if (vk == VK_LEFT || vk == VK_RIGHT) { - // Map Windows virtual key to the Keyboard constants used by Screen::keyPressed - int mappedKey = -1; - wchar_t ch = 0; - if (vk == VK_ESCAPE) mappedKey = Keyboard::KEY_ESCAPE; - else if (vk == VK_RETURN) mappedKey = Keyboard::KEY_RETURN; - else if (vk == VK_BACK) mappedKey = Keyboard::KEY_BACK; - else if (vk == VK_UP) mappedKey = Keyboard::KEY_UP; - else if (vk == VK_DOWN) mappedKey = Keyboard::KEY_DOWN; - else if (vk == VK_LEFT) mappedKey = Keyboard::KEY_LEFT; - else if (vk == VK_RIGHT) mappedKey = Keyboard::KEY_RIGHT; - else if (vk == VK_LSHIFT || vk == VK_RSHIFT) mappedKey = Keyboard::KEY_LSHIFT; - else if (vk == VK_TAB) mappedKey = Keyboard::KEY_TAB; - else if (vk >= 'A' && vk <= 'Z') + int idx = (vk == VK_LEFT) ? 0 : 1; + if (!g_KBMInput.IsKeyDown(vk)) { - ch = (wchar_t)(vk - 'A' + L'a'); - if (g_KBMInput.IsKeyDown(VK_LSHIFT) || g_KBMInput.IsKeyDown(VK_RSHIFT)) ch = (wchar_t)vk; + s_arrowLastTime[idx] = 0; + s_arrowFirstRepeat[idx] = false; } - else if (vk >= '0' && vk <= '9') ch = (wchar_t)vk; - else if (vk == VK_SPACE) ch = L' '; + else + { + DWORD last = s_arrowLastTime[idx]; + if (last == 0) + deliver = true; + else if (!deliver) + { + DWORD interval = s_arrowFirstRepeat[idx] ? ARROW_REPEAT_INTERVAL_MS : ARROW_REPEAT_DELAY_MS; + if ((now - last) >= interval) + { + deliver = true; + s_arrowFirstRepeat[idx] = true; + } + } + if (deliver) + s_arrowLastTime[idx] = now; + } + } + // Escape: deliver when key is down so we don't miss it (IsKeyPressed can be one frame late) + if (vk == VK_ESCAPE && g_KBMInput.IsKeyDown(VK_ESCAPE)) + deliver = true; + if (!deliver) continue; - if (mappedKey != -1) keyPressed(ch, mappedKey); - else if (ch != 0) keyPressed(ch, -1); + if (dynamic_cast<ChatScreen*>(this) != nullptr && + (vk >= 'A' && vk <= 'Z' || vk >= '0' && vk <= '9' || vk == VK_SPACE || vk == VK_RETURN || vk == VK_BACK)) + continue; + // Map to Screen::keyPressed + int mappedKey = -1; + wchar_t ch = 0; + if (vk == VK_ESCAPE) mappedKey = Keyboard::KEY_ESCAPE; + else if (vk == VK_RETURN) mappedKey = Keyboard::KEY_RETURN; + else if (vk == VK_BACK) mappedKey = Keyboard::KEY_BACK; + else if (vk == VK_UP) mappedKey = Keyboard::KEY_UP; + else if (vk == VK_DOWN) mappedKey = Keyboard::KEY_DOWN; + else if (vk == VK_LEFT) mappedKey = Keyboard::KEY_LEFT; + else if (vk == VK_RIGHT) mappedKey = Keyboard::KEY_RIGHT; + else if (vk == VK_LSHIFT || vk == VK_RSHIFT) mappedKey = Keyboard::KEY_LSHIFT; + else if (vk == VK_TAB) mappedKey = Keyboard::KEY_TAB; + else if (vk >= 'A' && vk <= 'Z') + { + ch = static_cast<wchar_t>(vk - 'A' + L'a'); + if (g_KBMInput.IsKeyDown(VK_LSHIFT) || g_KBMInput.IsKeyDown(VK_RSHIFT)) ch = static_cast<wchar_t>(vk); } + else if (vk >= '0' && vk <= '9') ch = static_cast<wchar_t>(vk); + else if (vk == VK_SPACE) ch = L' '; + + if (mappedKey != -1) keyPressed(ch, mappedKey); + else if (ch != 0) keyPressed(ch, -1); } #else /* 4J - TODO @@ -210,7 +284,7 @@ void Screen::renderBackground() void Screen::renderBackground(int vo) { - if (minecraft->level != NULL) + if (minecraft->level != nullptr) { fillGradient(0, 0, width, height, 0xc0101010, 0xd0101010); } @@ -232,10 +306,10 @@ void Screen::renderDirtBackground(int vo) float s = 32; t->begin(); t->color(0x404040); - t->vertexUV((float)(0), (float)( height), (float)( 0), (float)( 0), (float)( height / s + vo)); - t->vertexUV((float)(width), (float)( height), (float)( 0), (float)( width / s), (float)( height / s + vo)); - t->vertexUV((float)(width), (float)( 0), (float)( 0), (float)( width / s), (float)( 0 + vo)); - t->vertexUV((float)(0), (float)( 0), (float)( 0), (float)( 0), (float)( 0 + vo)); + t->vertexUV(static_cast<float>(0), static_cast<float>(height), static_cast<float>(0), static_cast<float>(0), static_cast<float>(height / s + vo)); + t->vertexUV(static_cast<float>(width), static_cast<float>(height), static_cast<float>(0), static_cast<float>(width / s), static_cast<float>(height / s + vo)); + t->vertexUV(static_cast<float>(width), static_cast<float>(0), static_cast<float>(0), static_cast<float>(width / s), static_cast<float>(0 + vo)); + t->vertexUV(static_cast<float>(0), static_cast<float>(0), static_cast<float>(0), static_cast<float>(0), static_cast<float>(0 + vo)); t->end(); #endif } |
