aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Screen.cpp
diff options
context:
space:
mode:
authorqwasdrizzel <145519042+qwasdrizzel@users.noreply.github.com>2026-03-16 21:44:26 -0500
committerGitHub <noreply@github.com>2026-03-16 21:44:26 -0500
commitce739f6045ec72127491286ea3f3f21e537c1b55 (patch)
treef33bd42a47c1b4a7b2153a7fb77127ee3b407db9 /Minecraft.Client/Screen.cpp
parent255a18fe8e9b57377975f82e2b227afe2a12eda0 (diff)
parent5a59f5d146b43811dde6a5a0245ee9875d7b5cd1 (diff)
Merge branch 'smartcmd:main' into main
Diffstat (limited to 'Minecraft.Client/Screen.cpp')
-rw-r--r--Minecraft.Client/Screen.cpp146
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
}