From bee5b34f9471c2184b4c2833a3b9c499110f80fe Mon Sep 17 00:00:00 2001 From: DrPerkyLegit Date: Fri, 10 Apr 2026 15:45:26 -0400 Subject: [PATCH 1/2] chat scrolling --- Minecraft.Client/ChatScreen.cpp | 18 ++++++++++++ Minecraft.Client/ChatScreen.h | 4 +++ Minecraft.Client/Common/UI/UIController.cpp | 4 +++ Minecraft.Client/Common/UI/UIScene_HUD.cpp | 31 ++++++++++++++++----- Minecraft.Client/Gui.h | 1 + Minecraft.Client/Screen.cpp | 2 +- 6 files changed, 52 insertions(+), 8 deletions(-) diff --git a/Minecraft.Client/ChatScreen.cpp b/Minecraft.Client/ChatScreen.cpp index 53c9072242..cb1d875df7 100644 --- a/Minecraft.Client/ChatScreen.cpp +++ b/Minecraft.Client/ChatScreen.cpp @@ -11,6 +11,7 @@ const wstring ChatScreen::allowedChars = SharedConstants::acceptableLetters; vector ChatScreen::s_chatHistory; int ChatScreen::s_historyIndex = -1; wstring ChatScreen::s_historyDraft; +int ChatScreen::s_chatIndex = 0; bool ChatScreen::isAllowedChatChar(wchar_t c) { @@ -22,6 +23,8 @@ ChatScreen::ChatScreen() frame = 0; cursorIndex = 0; s_historyIndex = -1; + + ChatScreen::s_chatIndex = 0; } void ChatScreen::init() @@ -83,6 +86,20 @@ void ChatScreen::handleHistoryDown() applyHistoryMessage(); } +int ChatScreen::getChatIndex() +{ + return ChatScreen::s_chatIndex; +} + +void ChatScreen::correctChatIndex(int newChatIndex) { + ChatScreen::s_chatIndex = newChatIndex; +} + +void ChatScreen::setWheelValue(int wheel) { + ChatScreen::s_chatIndex += wheel; + if (ChatScreen::s_chatIndex < 0) ChatScreen::s_chatIndex = 0; +} + void ChatScreen::keyPressed(wchar_t ch, int eventKey) { if (eventKey == Keyboard::KEY_ESCAPE) @@ -131,6 +148,7 @@ void ChatScreen::keyPressed(wchar_t ch, int eventKey) cursorIndex--; return; } + if (isAllowedChatChar(ch) && static_cast(message.length()) < SharedConstants::maxChatLength) { message.insert(cursorIndex, 1, ch); diff --git a/Minecraft.Client/ChatScreen.h b/Minecraft.Client/ChatScreen.h index c4e37a9373..70d65e8ce4 100644 --- a/Minecraft.Client/ChatScreen.h +++ b/Minecraft.Client/ChatScreen.h @@ -16,6 +16,7 @@ class ChatScreen : public Screen static std::vector s_chatHistory; static int s_historyIndex; static wstring s_historyDraft; + static int s_chatIndex; static const wstring allowedChars; static bool isAllowedChatChar(wchar_t c); @@ -28,6 +29,9 @@ class ChatScreen : public Screen virtual void handleHistoryUp(); virtual void handleHistoryDown(); + static int getChatIndex(); + static void correctChatIndex(int newChatIndex); + static void setWheelValue(int wheel); protected: void keyPressed(wchar_t ch, int eventKey); public: diff --git a/Minecraft.Client/Common/UI/UIController.cpp b/Minecraft.Client/Common/UI/UIController.cpp index b12ea5e739..046acefe5c 100644 --- a/Minecraft.Client/Common/UI/UIController.cpp +++ b/Minecraft.Client/Common/UI/UIController.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "UIController.h" +#include #include "UI.h" #include "UIScene.h" #include "UIControl_Slider.h" @@ -1428,6 +1429,9 @@ void UIController::handleKeyPress(unsigned int iPad, unsigned int key) } #endif + if (key == 4) ChatScreen::setWheelValue(1); + if (key == 5) ChatScreen::setWheelValue(-1); + if(pressed) app.DebugPrintf("Pressed %d\n",key); if(released) app.DebugPrintf("Released %d\n",key); // Repeat handling diff --git a/Minecraft.Client/Common/UI/UIScene_HUD.cpp b/Minecraft.Client/Common/UI/UIScene_HUD.cpp index 213caa8dc6..7d34ba0ded 100644 --- a/Minecraft.Client/Common/UI/UIScene_HUD.cpp +++ b/Minecraft.Client/Common/UI/UIScene_HUD.cpp @@ -9,6 +9,7 @@ #include "..\..\EnderDragonRenderer.h" #include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h" #include "..\..\..\Minecraft.World\StringHelpers.h" +#include UIScene_HUD::UIScene_HUD(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) { @@ -761,16 +762,31 @@ void UIScene_HUD::render(S32 width, S32 height, C4JRender::eViewportType viewpor void UIScene_HUD::handleTimerComplete(int id) { Minecraft *pMinecraft = Minecraft::GetInstance(); + bool isChatOpen = (dynamic_cast(pMinecraft->getScreen()) != nullptr); bool anyVisible = false; if(pMinecraft->localplayers[m_iPad]!= nullptr) { Gui *pGui = pMinecraft->gui; - //DWORD messagesToDisplay = min( CHAT_LINES_COUNT, pGui->getMessagesCount(m_iPad) ); - for( unsigned int i = 0; i < CHAT_LINES_COUNT; ++i ) + DWORD totalMessages = pGui->getMessagesCount(m_iPad); + DWORD messagesToDisplay = min( CHAT_LINES_COUNT, totalMessages); + DWORD maxScroll = max(0, totalMessages - messagesToDisplay); + + bool canScroll = messagesToDisplay < totalMessages; + int startIndex = (canScroll && isChatOpen ? ChatScreen::getChatIndex() : 0); + + if (startIndex > maxScroll) { + ChatScreen::correctChatIndex(maxScroll); + startIndex = maxScroll; + } + + app.DebugPrintf("handleTimerComplete: %d | %d | %d\n", maxScroll, startIndex, totalMessages); + + for( unsigned int i = 0; i < messagesToDisplay; ++i ) { - float opacity = pGui->getOpacity(m_iPad, i); - if( opacity > 0 ) + unsigned int msgIndex = startIndex + i; + float opacity = pGui->getOpacity(m_iPad, msgIndex); + if( opacity > 0 || isChatOpen) { #if 0 // def _WINDOWS64 // Use Iggy chat until Gui::render has visual parity // Chat drawn by Gui::render with color codes. Hides Iggy chat to avoid double chats. @@ -778,9 +794,10 @@ void UIScene_HUD::handleTimerComplete(int id) m_labelChatText[i].setOpacity(0); m_labelChatText[i].setLabel(L""); #else - m_controlLabelBackground[i].setOpacity(opacity); - m_labelChatText[i].setOpacity(opacity); - m_labelChatText[i].setLabel( pGui->getMessagesCount(m_iPad) ? pGui->getMessage(m_iPad,i) : L"" ); + + m_controlLabelBackground[i].setOpacity((isChatOpen ? 1 : opacity)); + m_labelChatText[i].setOpacity((isChatOpen ? 1 : opacity)); + m_labelChatText[i].setLabel(pGui->getMessage(m_iPad, msgIndex)); #endif anyVisible = true; } diff --git a/Minecraft.Client/Gui.h b/Minecraft.Client/Gui.h index 64b8dfbe8e..440d4e5b41 100644 --- a/Minecraft.Client/Gui.h +++ b/Minecraft.Client/Gui.h @@ -17,6 +17,7 @@ class Gui : public GuiComponent static const int m_iMaxMessageWidth = 280; static ItemRenderer *itemRenderer; vector guiMessages[XUSER_MAX_COUNT]; + int chatIndex = 0; Random *random; Minecraft *minecraft; diff --git a/Minecraft.Client/Screen.cpp b/Minecraft.Client/Screen.cpp index 7966c5c96e..efcb148cdb 100644 --- a/Minecraft.Client/Screen.cpp +++ b/Minecraft.Client/Screen.cpp @@ -161,7 +161,7 @@ void Screen::updateEvents() static bool s_arrowFirstRepeat[2] = { false, false }; const DWORD ARROW_REPEAT_DELAY_MS = 250; const DWORD ARROW_REPEAT_INTERVAL_MS = 50; - DWORD now = GetTickCount(); + DWORD now = GetTickCount64(); // Poll keyboard events (special keys that may not come through WM_CHAR, e.g. Escape, arrows) for (int vk = 0; vk < 256; vk++) From 1a8084cb3214e7ea065d2a19b651d017509dc854 Mon Sep 17 00:00:00 2001 From: DrPerkyLegit Date: Fri, 10 Apr 2026 15:46:10 -0400 Subject: [PATCH 2/2] allow escape to close chat instead of opening pause --- Minecraft.Client/Minecraft.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 1ba432fd04..10167f9556 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1537,8 +1537,12 @@ void Minecraft::run_middle() // Utility keys always work regardless of KBM active state if(g_KBMInput.IsKeyPressed(KeyboardMouseInput::KEY_PAUSE) && !ui.GetMenuDisplayed(i)) { - localplayers[i]->ullButtonsPressed|=1LL<(getScreen()) != nullptr) { + setScreen(nullptr); + } else { + localplayers[i]->ullButtonsPressed|=1LL<