From 1d4294dd94e2e9bea6b6a9f391111b19bacba43c Mon Sep 17 00:00:00 2001 From: Wilyicaro Date: Tue, 24 Feb 2026 04:08:08 -0300 Subject: [PATCH 01/11] -Added input hotswap, tested between controller and kbm for now -Added a HashMap implementation in common, and implemented in some places -Now, Console UI Theme tooltips will be accurate -Now, sneaking with the controller will be toggleable -Now, the UI Theme will be applied when exiting the options screen -Now, the font rendering will be faster -Now, Vertical Layout will always navigate to the next element when scrolling down -Fixed Skeleton arrow shooting not accounting the head height -Fixed item swapping not calling slot changed, not changing the crafting result -Fixed Vertical Layout labels being selectable -Fixed not being able to navigate if there aren't selected elements --- game/assets/materials/ui.material | 2 +- .../xinput/GameControllerHandler_xinput.cpp | 12 +- platforms/sdl/base/AppPlatform_sdl.cpp | 53 ++- platforms/sdl/base/AppPlatform_sdl.hpp | 2 + platforms/sdl/sdl2/main.cpp | 6 +- platforms/windows/main.cpp | 3 +- .../windows/projects/Common/Common.vcxproj | 1 + .../projects/Common/Common.vcxproj.filters | 3 + source/client/app/Minecraft.cpp | 198 +++++---- source/client/app/NinecraftApp.cpp | 17 +- source/client/gui/Gui.cpp | 12 +- source/client/gui/Gui.hpp | 2 +- source/client/gui/GuiElement.cpp | 2 +- source/client/gui/GuiElement.hpp | 2 +- source/client/gui/Screen.cpp | 70 ++- source/client/gui/Screen.hpp | 5 +- source/client/gui/ScreenChooser.cpp | 1 - source/client/gui/VerticalLayout.cpp | 44 +- source/client/gui/VerticalLayout.hpp | 2 + source/client/gui/components/OptionList.cpp | 3 +- source/client/gui/components/TextBox.cpp | 8 +- source/client/gui/components/TextBox.hpp | 2 +- source/client/gui/screens/ChatScreen.cpp | 11 +- source/client/gui/screens/ChatScreen.hpp | 3 +- source/client/gui/screens/CreditsScreen.cpp | 4 +- source/client/gui/screens/CreditsScreen.hpp | 2 +- .../screens/IngameBlockSelectionScreen.cpp | 11 +- .../screens/IngameBlockSelectionScreen.hpp | 3 +- source/client/gui/screens/OptionsScreen.cpp | 10 + source/client/gui/screens/OptionsScreen.hpp | 1 + .../gui/screens/OptionsScreen_Console.cpp | 13 +- .../gui/screens/OptionsScreen_Console.hpp | 1 + source/client/gui/screens/PauseScreen.cpp | 10 + source/client/gui/screens/PauseScreen.hpp | 9 +- .../gui/screens/PauseScreen_Console.cpp | 12 +- .../gui/screens/PauseScreen_Console.hpp | 1 + .../client/gui/screens/SelectWorldScreen.cpp | 11 +- .../client/gui/screens/SelectWorldScreen.hpp | 2 +- source/client/gui/screens/StartMenuScreen.cpp | 12 +- source/client/gui/screens/StartMenuScreen.hpp | 1 + .../gui/screens/StartMenuScreen_Console.cpp | 12 +- .../gui/screens/StartMenuScreen_Console.hpp | 1 + .../gui/screens/inventory/ContainerScreen.cpp | 30 +- .../gui/screens/inventory/ContainerScreen.hpp | 2 +- source/client/options/Options.cpp | 95 ++-- source/client/options/Options.hpp | 57 ++- .../player/input/ControllerMoveInput.cpp | 10 +- .../player/input/ControllerMoveInput.hpp | 2 +- .../client/player/input/CustomInputHolder.cpp | 9 +- .../client/player/input/CustomInputHolder.hpp | 4 +- source/client/player/input/GameController.hpp | 1 + .../player/input/GameControllerHandler.hpp | 7 +- .../player/input/GameControllerManager.cpp | 66 +++ .../player/input/GameControllerManager.hpp | 9 + source/client/player/input/IInputHolder.cpp | 7 + source/client/player/input/IInputHolder.hpp | 13 + source/client/player/input/IMoveInput.cpp | 2 +- source/client/player/input/IMoveInput.hpp | 4 +- source/client/player/input/Keyboard.cpp | 6 + source/client/player/input/KeyboardInput.cpp | 36 +- source/client/player/input/KeyboardInput.hpp | 2 +- source/client/player/input/MouseDevice.cpp | 7 + source/client/player/input/Multitouch.cpp | 2 + .../client/player/input/TouchInputHolder.cpp | 5 + .../client/player/input/TouchInputHolder.hpp | 1 + .../player/input/TouchscreenInput_TestFps.cpp | 2 +- .../player/input/TouchscreenInput_TestFps.hpp | 2 +- source/client/renderer/Font.cpp | 58 ++- source/client/renderer/Font.hpp | 2 + source/client/renderer/GameRenderer.cpp | 2 +- source/common/utility/HashMap.hpp | 413 ++++++++++++++++++ source/nbt/CompoundTag.cpp | 37 +- source/nbt/CompoundTag.hpp | 3 +- source/world/entity/Arrow.hpp | 2 +- source/world/entity/Skeleton.cpp | 2 +- source/world/inventory/ContainerMenu.cpp | 4 +- source/world/item/ItemStack.cpp | 6 +- source/world/level/Level.cpp | 4 +- source/world/level/Level.hpp | 4 +- 79 files changed, 1173 insertions(+), 325 deletions(-) create mode 100644 source/common/utility/HashMap.hpp diff --git a/game/assets/materials/ui.material b/game/assets/materials/ui.material index 73b1858d0..7c086d6ab 100644 --- a/game/assets/materials/ui.material +++ b/game/assets/materials/ui.material @@ -35,7 +35,7 @@ "states": ["DisableCulling"] }, - "ui_text:ui_texture_and_color": { + "ui_text:ui_textured_and_glcolor": { "fragmentShader": "shaders/text.fragment" }, diff --git a/platforms/input/xinput/GameControllerHandler_xinput.cpp b/platforms/input/xinput/GameControllerHandler_xinput.cpp index 02701c6f2..8cc544280 100644 --- a/platforms/input/xinput/GameControllerHandler_xinput.cpp +++ b/platforms/input/xinput/GameControllerHandler_xinput.cpp @@ -42,11 +42,6 @@ void GameControllerHandler_xinput::_initButtonMap() m[XINPUT_GAMEPAD_START] = GameController::BUTTON_START; } -Keyboard::KeyState _getKeyState(bool value) -{ - return value ? Keyboard::DOWN : Keyboard::UP; -} - void GameControllerHandler_xinput::_processButton(GameController::ID controllerId, const XINPUT_STATE& state, GameController::NativeButtonID nativeBtn, GameController::EngineButtonID engineBtn, bool& joinGameAlreadyFired) { bool bButtonPressed = (state.Gamepad.wButtons & nativeBtn) != 0; @@ -63,8 +58,7 @@ void GameControllerHandler_xinput::_processButton(GameController::ID controllerI joinGameAlreadyFired = true; } - // @TODO: should call GameControllerManager::feedButton() instead - Keyboard::feed(_getKeyState(bButtonPressed), engineBtn); + GameControllerManager::feedButton(btnState, engineBtn); lastBtnState = btnState; } @@ -95,9 +89,9 @@ void GameControllerHandler_xinput::refresh() { XINPUT_STATE& inputState = m_inputStates.m_inputState[id]; bool joinGameAlreadyFired = false; - for (ButtonIDMap::const_iterator it = m_buttonIdMap.begin(); it != m_buttonIdMap.end(); it++) + for (ButtonIDMap::Iterator it = m_buttonIdMap.begin(); it != m_buttonIdMap.end(); it++) { - _processButton(id, inputState, it->first, it->second, joinGameAlreadyFired); + _processButton(id, inputState, it.key(), it.value(), joinGameAlreadyFired); } GameControllerManager::feedTrigger(1, (float)inputState.Gamepad.bLeftTrigger / 255.0f); diff --git a/platforms/sdl/base/AppPlatform_sdl.cpp b/platforms/sdl/base/AppPlatform_sdl.cpp index ecacb41fb..3f586caae 100644 --- a/platforms/sdl/base/AppPlatform_sdl.cpp +++ b/platforms/sdl/base/AppPlatform_sdl.cpp @@ -312,7 +312,7 @@ void AppPlatform_sdl::handleKeyEvent(const SDL_Event& event) void AppPlatform_sdl::handleControllerButtonEvent(SDL_JoystickID controllerIndex, uint8_t button, uint8_t state) { // Normal Key Press - Keyboard::feed(GetKeyState(state), button); + GameControllerManager::feedButton(state == SDL_PRESSED ? GameController::BTN_STATE_DOWN : GameController::BTN_STATE_UP, GetEngineButton(button)); } void AppPlatform_sdl::handleControllerAxisEvent(SDL_JoystickID controllerIndex, uint8_t axis, int16_t value) @@ -492,3 +492,54 @@ Keyboard::KeyState AppPlatform_sdl::GetKeyState(uint8_t state) return Keyboard::DOWN; } } + +GameController::EngineButtonID AppPlatform_sdl::GetEngineButton(uint8_t button) +{ + switch (button) + { + case SDL_CONTROLLER_BUTTON_A: + return GameController::BUTTON_A; + case SDL_CONTROLLER_BUTTON_B: + return GameController::BUTTON_B; + case SDL_CONTROLLER_BUTTON_X: + return GameController::BUTTON_X; + case SDL_CONTROLLER_BUTTON_Y: + return GameController::BUTTON_Y; + case SDL_CONTROLLER_BUTTON_DPAD_UP: + return GameController::BUTTON_DPAD_UP; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + return GameController::BUTTON_DPAD_DOWN; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + return GameController::BUTTON_DPAD_LEFT; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + return GameController::BUTTON_DPAD_RIGHT; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: + return GameController::BUTTON_LEFTSTICK; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: + return GameController::BUTTON_RIGHTSTICK; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + return GameController::BUTTON_LEFTSHOULDER; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + return GameController::BUTTON_RIGHTSHOULDER; + case SDL_CONTROLLER_BUTTON_BACK: + return GameController::BUTTON_BACK; + case SDL_CONTROLLER_BUTTON_START: + return GameController::BUTTON_START; + case SDL_CONTROLLER_BUTTON_GUIDE: + return GameController::BUTTON_GUIDE; + case SDL_CONTROLLER_BUTTON_MISC1: + return GameController::BUTTON_MISC1; + case SDL_CONTROLLER_BUTTON_PADDLE1: + return GameController::BUTTON_PADDLE1; + case SDL_CONTROLLER_BUTTON_PADDLE2: + return GameController::BUTTON_PADDLE2; + case SDL_CONTROLLER_BUTTON_PADDLE3: + return GameController::BUTTON_PADDLE3; + case SDL_CONTROLLER_BUTTON_PADDLE4: + return GameController::BUTTON_PADDLE4; + case SDL_CONTROLLER_BUTTON_TOUCHPAD: + return GameController::BUTTON_TOUCHPAD; + default: + return GameController::BUTTON_NONE; + } +} diff --git a/platforms/sdl/base/AppPlatform_sdl.hpp b/platforms/sdl/base/AppPlatform_sdl.hpp index c93d4f4b2..0bdf38fd9 100644 --- a/platforms/sdl/base/AppPlatform_sdl.hpp +++ b/platforms/sdl/base/AppPlatform_sdl.hpp @@ -8,6 +8,7 @@ #include "client/player/input/Mouse.hpp" #include "client/player/input/Keyboard.hpp" +#include "client/player/input/GameController.hpp" #include "common/Logger.hpp" class AppPlatform_sdl : public AppPlatform @@ -72,6 +73,7 @@ class AppPlatform_sdl : public AppPlatform static MouseButtonType GetMouseButtonType(uint8_t button); static bool GetMouseButtonState(const SDL_Event& event); static Keyboard::KeyState GetKeyState(uint8_t state); + static GameController::EngineButtonID GetEngineButton(uint8_t button); protected: ImageData m_iconImage; diff --git a/platforms/sdl/sdl2/main.cpp b/platforms/sdl/sdl2/main.cpp index 3cbaabbe5..c0183b7b3 100644 --- a/platforms/sdl/sdl2/main.cpp +++ b/platforms/sdl/sdl2/main.cpp @@ -233,7 +233,8 @@ static void handle_events() float x = event.button.x * scale; float y = event.button.y * scale; Mouse::feed(type, state, x, y); - Multitouch::feed(type, state, x, y, 0); + if (g_pAppPlatform->isTouchscreen()) + Multitouch::feed(type, state, x, y, 0); } break; } @@ -244,7 +245,8 @@ static void handle_events() float scale = g_fPointToPixelScale; float x = event.motion.x * scale; float y = event.motion.y * scale; - Multitouch::feed(MOUSE_BUTTON_NONE, false, x, y, 0); + if (g_pAppPlatform->isTouchscreen()) + Multitouch::feed(MOUSE_BUTTON_NONE, false, x, y, 0); Mouse::feed(MOUSE_BUTTON_NONE, false, x, y); g_pAppPlatform->setMouseDiff(event.motion.xrel * scale, event.motion.yrel * scale); } diff --git a/platforms/windows/main.cpp b/platforms/windows/main.cpp index 00f703ea1..4848500a9 100644 --- a/platforms/windows/main.cpp +++ b/platforms/windows/main.cpp @@ -61,7 +61,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) posY = Mouse::getY(); } Mouse::feed(buttonType, buttonState, posX, posY); - Multitouch::feed(buttonType, buttonState, posX, posY, 0); + if (g_AppPlatform.isTouchscreen()) + Multitouch::feed(buttonType, buttonState, posX, posY, 0); break; } diff --git a/platforms/windows/projects/Common/Common.vcxproj b/platforms/windows/projects/Common/Common.vcxproj index a497af7e0..9ee2aa6ef 100644 --- a/platforms/windows/projects/Common/Common.vcxproj +++ b/platforms/windows/projects/Common/Common.vcxproj @@ -115,6 +115,7 @@ + diff --git a/platforms/windows/projects/Common/Common.vcxproj.filters b/platforms/windows/projects/Common/Common.vcxproj.filters index 56d68fb15..fdd8109f3 100644 --- a/platforms/windows/projects/Common/Common.vcxproj.filters +++ b/platforms/windows/projects/Common/Common.vcxproj.filters @@ -127,5 +127,8 @@ Header Files\Threading + + Header Files\Utility + \ No newline at end of file diff --git a/source/client/app/Minecraft.cpp b/source/client/app/Minecraft.cpp index 27a162a15..d1713f144 100644 --- a/source/client/app/Minecraft.cpp +++ b/source/client/app/Minecraft.cpp @@ -181,14 +181,21 @@ void Minecraft::_reloadInput() if (isTouchscreen()) { m_pInputHolder = new TouchInputHolder(this, getOptions()); + + if (m_bGrabbedMouse) + platform()->setMouseGrabbed(false); } else if (useController()) { m_pInputHolder = new CustomInputHolder( new ControllerMoveInput(getOptions()), new ControllerTurnInput(), - new ControllerBuildInput() + new ControllerBuildInput(), + true ); + + if (m_bGrabbedMouse) + platform()->setMouseGrabbed(false); } else { @@ -197,6 +204,9 @@ void Minecraft::_reloadInput() new MouseTurnInput(this), new MouseBuildInput() ); + + if (m_bGrabbedMouse) + platform()->setMouseGrabbed(true); } m_mouseHandler.setTurnInput(m_pInputHolder->getTurnInput()); @@ -262,7 +272,6 @@ void Minecraft::recenterMouse() void Minecraft::setScreen(Screen* pScreen) { - float lastScale = getBestScaleForThisScreenSize(Minecraft::width, Minecraft::height); #ifndef ORIGINAL_CODE if (pScreen == nullptr && !isLevelGenerated()) { @@ -277,13 +286,15 @@ void Minecraft::setScreen(Screen* pScreen) return; } - if (pScreen && pScreen->isErrorScreen()) + if (pScreen && (pScreen->isErrorScreen() || pScreen->isInvalid(this))) { // not in original delete pScreen; return; } + float lastScale = getBestScaleForThisScreenSize(Minecraft::width, Minecraft::height); + if (m_pScreen) { m_pScreen->removed(); @@ -361,17 +372,17 @@ bool Minecraft::isOnlineClient() const bool Minecraft::isTouchscreen() const { - return m_bIsTouchscreen; + return IInputHolder::activeType == IInputHolder::TOUCHSCREEN; } bool Minecraft::useSplitControls() const { - return !m_bIsTouchscreen || getOptions()->m_splitControls.get(); + return !isTouchscreen() || getOptions()->m_splitControls.get(); } bool Minecraft::useController() const { - return m_pPlatform->hasGamepad() && getOptions()->m_bUseController.get(); + return m_pPlatform->hasGamepad() && (IInputHolder::activeType == IInputHolder::CONTROLLER || getOptions()->m_bUseController.get()); } void Minecraft::setGameMode(GameType gameType) @@ -505,6 +516,9 @@ void Minecraft::handleBuildAction(const BuildActionIntention& action) void Minecraft::tickInput() { + if (!m_pInputHolder->allowsType(IInputHolder::activeType)) + _reloadInput(); + if (m_pScreen) { if (!m_pScreen->m_bPassEvents) @@ -550,93 +564,132 @@ void Minecraft::tickInput() #endif } - while (Keyboard::next()) + if (useController()) { - int keyCode = Keyboard::getEventKey(); - bool bPressed = Keyboard::getEventKeyState() == 1; + //Clearing, so the events don't accumulate + Keyboard::reset(); - m_pLocalPlayer->m_pMoveInput->setKey(keyCode, bPressed); - - if (bPressed) + while (GameControllerManager::next()) { - m_pGui->handleKeyPressed(keyCode); + if (!useController()) continue; + GameController::EngineButtonID button = GameControllerManager::getEventButton(); + bool bPressed = GameControllerManager::getEventButtonState() == GameController::BTN_STATE_DOWN; - for (int i = 0; i < m_pGui->getNumUsableSlots(); i++) - { - if (getOptions()->isKey(eKeyMappingIndex(KM_SLOT_1 + i), keyCode)) - m_pLocalPlayer->m_pInventory->selectSlot(i); - } + if (bPressed) + m_pGui->handleControlPressed(ControlBind(-1, button)); - if (getOptions()->isKey(KM_TOGGLE3RD, keyCode)) + for (size_t i = 0; i < KM_COUNT; ++i) { - getOptions()->m_thirdPerson.toggle(); + eControlMappingIndex ctrl = (eControlMappingIndex)i; + if (!getOptions()->getControl(ctrl).isButton(button)) continue; + + m_pLocalPlayer->m_pMoveInput->setKey(ctrl, bPressed); + if (bPressed) + getOptions()->getControlMapping(ctrl).pressed(); + else + getOptions()->getControlMapping(ctrl).reset(); } - else if (getOptions()->isKey(KM_MENU_PAUSE, keyCode)) + } + } + else + { + //Clearing, so the events don't accumulate + GameControllerManager::clear(); + while (Keyboard::next()) + { + int keyCode = Keyboard::getEventKey(); + bool bPressed = Keyboard::getEventKeyState() == Keyboard::DOWN; + + if (bPressed) + m_pGui->handleControlPressed(ControlBind(keyCode, GameController::BUTTON_NONE)); + + for (size_t i = 0; i < KM_COUNT; ++i) { - handleBack(false); + eControlMappingIndex ctrl = (eControlMappingIndex)i; + if (!getOptions()->isKey(ctrl, keyCode)) continue; + + m_pLocalPlayer->m_pMoveInput->setKey(ctrl, bPressed); + if (bPressed) + getOptions()->getControlMapping(ctrl).pressed(); + else + getOptions()->getControlMapping(ctrl).reset(); } - else if (getOptions()->isKey(KM_DROP, keyCode)) + + if (getOptions()->field_19) + continue; + + // @TODO: Replace with KeyboardBuildInput + if (!useController() && getTimeMs() - field_2B4 <= 200) { - ItemStack& item = m_pLocalPlayer->m_pInventory->getSelected(); - if (!item.isEmpty()) + if (getOptions()->isKey(KM_DESTROY, keyCode) && bPressed) { - ItemStack itemDrop(item); - itemDrop.m_count = 1; - - if (m_pLocalPlayer->isSurvival()) - item.shrink(1); + BuildActionIntention intention(BuildActionIntention::KEY_DESTROY); + handleBuildAction(intention); + } - m_pLocalPlayer->drop(itemDrop); + if (getOptions()->isKey(KM_PLACE, keyCode) && bPressed) + { + BuildActionIntention intention(BuildActionIntention::KEY_USE); + handleBuildAction(intention); } } - else if (getOptions()->isKey(KM_TOGGLEGUI, keyCode)) - { - getOptions()->m_hideGui.toggle(); - } - else if (getOptions()->isKey(KM_TOGGLEDEBUG, keyCode)) - { - getOptions()->m_debugText.toggle(); - } -#ifdef ENH_ALLOW_AO_TOGGLE - else if (getOptions()->isKey(KM_TOGGLEAO, keyCode)) - { - // Toggle ambient occlusion. - getOptions()->m_ambientOcclusion.toggle(); - Minecraft::useAmbientOcclusion = getOptions()->m_ambientOcclusion.get(); - m_pLevelRenderer->allChanged(); - } -#endif } + } - if (getOptions()->field_19) - continue; + for (int i = 0; i < m_pGui->getNumUsableSlots(); i++) + { + while (getOptions()->getControlMapping(eControlMappingIndex(KM_SLOT_1 + i)).consume()) + m_pLocalPlayer->m_pInventory->selectSlot(i); + } + + while (getOptions()->getControlMapping(KM_TOGGLE3RD).consume()) + { + getOptions()->m_thirdPerson.toggle(); + } - // @TODO: Replace with KeyboardBuildInput - if (!useController() && getTimeMs() - field_2B4 <= 200) + while (getOptions()->getControlMapping(KM_MENU_PAUSE).consume()) + { + handleBack(false); + } + + while (getOptions()->getControlMapping(KM_DROP).consume()) + { + ItemStack& item = m_pLocalPlayer->m_pInventory->getSelected(); + if (!item.isEmpty()) { - if (getOptions()->getKey(KM_DESTROY) == keyCode && bPressed) - { - BuildActionIntention intention(BuildActionIntention::KEY_DESTROY); - handleBuildAction(intention); - } + ItemStack itemDrop(item); + itemDrop.m_count = 1; - if (getOptions()->getKey(KM_PLACE) == keyCode && bPressed) - { - BuildActionIntention intention(BuildActionIntention::KEY_USE); - handleBuildAction(intention); - } + item.shrink(1); + + m_pLocalPlayer->drop(itemDrop); } } + while (getOptions()->getControlMapping(KM_TOGGLEGUI).consume()) + { + getOptions()->m_hideGui.toggle(); + } + + while (getOptions()->getControlMapping(KM_TOGGLEDEBUG).consume()) + { + getOptions()->m_debugText.toggle(); + } +#ifdef ENH_ALLOW_AO_TOGGLE + while (getOptions()->getControlMapping(KM_TOGGLEAO).consume()) + { + // Toggle ambient occlusion. + getOptions()->m_ambientOcclusion.toggle(); + m_pLevelRenderer->allChanged(); + } +#endif + BuildActionIntention bai; IBuildInput* buildInput = m_pInputHolder->getBuildInput(); if (buildInput && buildInput->tickBuild(m_pLocalPlayer, &bai)) handleBuildAction(bai); field_2B4 = getTimeMs(); - - Keyboard::reset(); - Mouse::reset(); } void Minecraft::tickMouse() @@ -847,6 +900,9 @@ void Minecraft::tick() m_pScreen->tick(); Multitouch::reset(); + + // Actually pause the game, because fuck bedrock edition + m_bIsGamePaused = !isOnline() || (m_pLevel && m_pLevel->m_players.size() == 1 && m_pScreen && m_pScreen->isPauseScreen()); } } @@ -1001,13 +1057,12 @@ void Minecraft::prepareLevel(const std::string& unused) void Minecraft::sizeUpdate(int newWidth, int newHeight) { // re-calculate the GUI scale. - Gui::GuiScale = getBestScaleForThisScreenSize(newWidth, newHeight) / getRenderScaleMultiplier(); + Gui::GuiScale = getBestScaleForThisScreenSize(newWidth, newHeight) / getRenderScaleMultiplier(); // The ceil gives an extra pixel to the screen's width and height, in case the GUI scale doesn't // divide evenly into width or height, so that none of the game screen is uncovered. + Gui::GuiWidth = ceilf(Minecraft::width * Gui::GuiScale); Gui::GuiHeight = ceilf(Minecraft::height * Gui::GuiScale); - Gui::GuiScale = float(Gui::GuiHeight) / height; - Gui::GuiWidth = ceilf(Minecraft::width * Gui::GuiScale); if (m_pScreen) m_pScreen->setSize( @@ -1049,7 +1104,7 @@ float Minecraft::getBestScaleForThisScreenSize(int width, int height) for (scale = 1; width / (scale + 1) >= 320 && height / (scale + 1) >= 240; ++scale) { } - return scale; + return 1.0f / scale; } #endif @@ -1153,11 +1208,6 @@ bool Minecraft::pauseGame() { if (isGamePaused() || m_pScreen) return false; - if (!isOnline() || m_pLevel->m_players.size() == 1) - { - // Actually pause the game, because fuck bedrock edition - m_bIsGamePaused = true; - } m_pLevel->savePlayerData(); getScreenChooser()->pushPauseScreen(); diff --git a/source/client/app/NinecraftApp.cpp b/source/client/app/NinecraftApp.cpp index 1c7bd839c..f0c610914 100644 --- a/source/client/app/NinecraftApp.cpp +++ b/source/client/app/NinecraftApp.cpp @@ -102,7 +102,13 @@ void NinecraftApp::_initRenderMaterials() void NinecraftApp::_initInput() { m_bIsTouchscreen = platform()->isTouchscreen(); - getOptions()->m_bUseController.set(platform()->hasGamepad()); + + //If someone has a gamepad connected, certainly they want to use it + if (platform()->hasGamepad()) + IInputHolder::activeType = IInputHolder::CONTROLLER; + else if (platform()->isTouchscreen()) + IInputHolder::activeType = IInputHolder::TOUCHSCREEN; + getOptions()->loadControls(); _reloadInput(); } @@ -365,13 +371,10 @@ void NinecraftApp::update() Multitouch::commit(); - if (getOptions()->m_bUseController.get()) + GameControllerHandler* pControllerHandler = platform()->getGameControllerHandler(); + if (pControllerHandler) { - GameControllerHandler* pControllerHandler = platform()->getGameControllerHandler(); - if (pControllerHandler) - { - pControllerHandler->refresh(); - } + pControllerHandler->refresh(); } Minecraft::update(); diff --git a/source/client/gui/Gui.cpp b/source/client/gui/Gui.cpp index 38ccbf65c..944f4b1bf 100644 --- a/source/client/gui/Gui.cpp +++ b/source/client/gui/Gui.cpp @@ -366,11 +366,11 @@ void Gui::handleScrollWheel(bool down) m_pMinecraft->m_pLocalPlayer->m_pInventory->selectSlot(slot); } -void Gui::handleKeyPressed(int keyCode) +void Gui::handleControlPressed(const ControlBind& bind) { Options* options = m_pMinecraft->getOptions(); - if (options->isKey(KM_INVENTORY, keyCode)) + if (options->isControl(KM_INVENTORY, bind)) { if (m_pMinecraft->m_pGameMode->isSurvivalType()) m_pMinecraft->setScreen(new InventoryScreen(m_pMinecraft->m_pLocalPlayer)); @@ -379,8 +379,8 @@ void Gui::handleKeyPressed(int keyCode) return; } - bool slotL = options->isKey(KM_SLOT_L, keyCode); - bool slotR = options->isKey(KM_SLOT_R, keyCode); + bool slotL = options->isControl(KM_SLOT_L, bind); + bool slotR = options->isControl(KM_SLOT_R, bind); if (slotL || slotR) { int maxItems = getNumSlots() - 1; @@ -405,10 +405,10 @@ void Gui::handleKeyPressed(int keyCode) return; } - if (options->isKey(KM_CHAT, keyCode) || options->isKey(KM_CHAT_CMD, keyCode)) + if (options->isControl(KM_CHAT, bind) || options->isControl(KM_CHAT_CMD, bind)) { if (!m_pMinecraft->m_pScreen) - m_pMinecraft->setScreen(new ChatScreen(m_pMinecraft->getOptions()->isKey(KM_CHAT_CMD, keyCode))); + m_pMinecraft->setScreen(new ChatScreen(m_pMinecraft->getOptions()->isControl(KM_CHAT_CMD, bind))); } } diff --git a/source/client/gui/Gui.hpp b/source/client/gui/Gui.hpp index 9957d2f65..8d6167b34 100644 --- a/source/client/gui/Gui.hpp +++ b/source/client/gui/Gui.hpp @@ -65,7 +65,7 @@ class Gui : public GuiComponent bool isInside(int mx, int my); void handleClick(int id, int mx, int my); void handleScrollWheel(bool down); - void handleKeyPressed(int keyCode); + void handleControlPressed(const ControlBind&); void renderMessages(bool bShowAll); void renderHearts(bool topLeft); void renderArmor(bool topLeft); diff --git a/source/client/gui/GuiElement.cpp b/source/client/gui/GuiElement.cpp index 2ddae5136..67e2a20fd 100644 --- a/source/client/gui/GuiElement.cpp +++ b/source/client/gui/GuiElement.cpp @@ -63,7 +63,7 @@ bool GuiElement::areaNavigation(Minecraft* pMinecraft, AreaNavigation::Direction return false; } -void GuiElement::handleButtonPress(Minecraft* pMinecraft, int key) +void GuiElement::handleControlPress(Minecraft* pMinecraft, const ControlBind& key) { } diff --git a/source/client/gui/GuiElement.hpp b/source/client/gui/GuiElement.hpp index 8ac2bc45c..95072c66c 100644 --- a/source/client/gui/GuiElement.hpp +++ b/source/client/gui/GuiElement.hpp @@ -42,7 +42,7 @@ class GuiElement : public GuiComponent virtual bool pointerPressed(Minecraft* pMinecraft, const MenuPointer& pointer); virtual bool pointerReleased(Minecraft* pMinecraft, const MenuPointer& pointer); virtual bool areaNavigation(Minecraft* pMinecraft, AreaNavigation::Direction); - virtual void handleButtonPress(Minecraft* pMinecraft, int key); + virtual void handleControlPress(Minecraft* pMinecraft, const ControlBind& key); virtual void handleTextChar(Minecraft* pMinecraft, int chr); virtual void handleClipboardPaste(const std::string& content); virtual void handleScroll(float force); diff --git a/source/client/gui/Screen.cpp b/source/client/gui/Screen.cpp index 5c029da2b..83346e7a9 100644 --- a/source/client/gui/Screen.cpp +++ b/source/client/gui/Screen.cpp @@ -56,7 +56,7 @@ Screen::~Screen() m_elements.clear(); } -void Screen::controllerEvent(GameController::StickID stickID, double deltaTime) +void Screen::controllerStickEvent(GameController::StickID stickID, double deltaTime) { // @TODO: this probably shouldn't be here GameController::StickEvent event; @@ -139,10 +139,10 @@ void Screen::init(Minecraft* pMinecraft, int width, int height) m_pFont = pMinecraft->m_pFont; // Apply UI theme to current Screen based on user preference - UITheme userTheme = m_pMinecraft->getOptions()->getUiTheme(); + UITheme userTheme = pMinecraft->getOptions()->getUiTheme(); // We don't bother applying the console theme automatically for generic screens because this completely fucks scaling if (m_uiTheme == UI_UNIVERSAL || (m_uiTheme == UI_GENERIC && userTheme != UI_CONSOLE)) - m_uiTheme = m_pMinecraft->getOptions()->getUiTheme(); + m_uiTheme = userTheme; setSize(width, height); initMenuPointer(); @@ -150,44 +150,44 @@ void Screen::init(Minecraft* pMinecraft, int width, int height) m_bLastPointerPressedState = false; } -void Screen::keyPressed(int key) +void Screen::controlPressed(const ControlBind& bind) { Options& options = *m_pMinecraft->getOptions(); GuiElement* element = _getSelectedElement(); - if (options.isKey(KM_MENU_CANCEL, key)) + if (options.isControl(KM_MENU_CANCEL, bind)) { m_pMinecraft->handleBack(false); } - if (m_pMinecraft->getOptions()->isKey(KM_MENU_TAB_LEFT, key)) + if (options.isControl(KM_MENU_TAB_LEFT, bind)) { prevTab(); } - if (m_pMinecraft->getOptions()->isKey(KM_MENU_TAB_RIGHT, key)) + if (options.isControl(KM_MENU_TAB_RIGHT, bind)) { nextTab(); } if (doElementTabbing()) { - if (options.isKey(KM_MENU_DOWN, key)) + if (options.isControl(KM_MENU_DOWN, bind)) { _areaNavigation(AreaNavigation::DOWN); } - else if (options.isKey(KM_MENU_UP, key)) + else if (options.isControl(KM_MENU_UP, bind)) { _areaNavigation(AreaNavigation::UP); } - else if (options.isKey(KM_MENU_RIGHT, key)) + else if (options.isControl(KM_MENU_RIGHT, bind)) { _areaNavigation(AreaNavigation::RIGHT); } - else if (options.isKey(KM_MENU_LEFT, key)) + else if (options.isControl(KM_MENU_LEFT, bind)) { _areaNavigation(AreaNavigation::LEFT); } - else if (options.isKey(KM_MENU_OK, key)) + else if (options.isControl(KM_MENU_OK, bind)) { if (element && element->isEnabled()) { @@ -204,7 +204,7 @@ void Screen::keyPressed(int key) if (element && element->isEnabled()) { - element->handleButtonPress(m_pMinecraft, key); + element->handleControlPress(m_pMinecraft, bind); } } @@ -255,6 +255,11 @@ void Screen::handleKeyboardClosed() } } +bool Screen::isInvalid(Minecraft*) +{ + return false; +} + static const char* g_panoramaList[] = { "gui/background/panorama_0.png", @@ -530,11 +535,14 @@ void Screen::selectElement(GuiElement* element) bool Screen::_areaNavigation(AreaNavigation::Direction dir) { - if (!m_pSelectedElement) return false; - - if (m_pSelectedElement->areaNavigation(m_pMinecraft, dir)) return true; + if (m_pSelectedElement && m_pSelectedElement->areaNavigation(m_pMinecraft, dir)) return true; - if (selectElementById(Navigation(this).navigateCyclic(dir, m_pSelectedElement->m_xPos + m_pSelectedElement->m_width / 2, m_pSelectedElement->m_yPos + m_pSelectedElement->m_height / 2))) + if ((m_pSelectedElement && selectElementById(Navigation(this).navigateCyclic(dir, + m_pSelectedElement->m_xPos + m_pSelectedElement->m_width / 2, + m_pSelectedElement->m_yPos + m_pSelectedElement->m_height / 2))) || + (!m_pSelectedElement && selectElementById(Navigation(this).navigate(dir, + m_width / 2, + m_height / 2, true)))) { _playSelectSound(); return true; @@ -723,7 +731,14 @@ void Screen::updateEvents() if (_useController()) { checkForPointerEvent(MOUSE_BUTTON_LEFT); - controllerEvent(); + + while(GameControllerManager::next()) + controllerEvent(); + + _processControllerDirection(1); + _processControllerDirection(2); + + controllerStickEvent(2); } } @@ -758,15 +773,26 @@ void Screen::keyboardEvent() } if (Keyboard::getEventKeyState()) - keyPressed(Keyboard::getEventKey()); + controlPressed(ControlBind(Keyboard::getEventKey(), GameController::BUTTON_NONE)); } void Screen::controllerEvent() { - _processControllerDirection(1); - _processControllerDirection(2); + // Ugly hack x2 + if (!doElementTabbing()) + { + if (GameControllerManager::getEventButtonState() && m_pMinecraft->getOptions()->getControl(KM_MENU_OK).isButton(GameControllerManager::getEventButton())) + { + m_menuPointer.isPressed = true; + } + else + { + m_menuPointer.isPressed = false; + } + } - controllerEvent(2); + if (GameControllerManager::getEventButtonState()) + controlPressed(ControlBind(-1, GameControllerManager::getEventButton())); } void Screen::checkForPointerEvent(MouseButtonType button) diff --git a/source/client/gui/Screen.hpp b/source/client/gui/Screen.hpp index a936e10ed..1f243d542 100644 --- a/source/client/gui/Screen.hpp +++ b/source/client/gui/Screen.hpp @@ -76,7 +76,7 @@ class Screen : public GuiComponent int getYOffset(); unsigned int getCursorMoveThrottle() const { return 65; } bool doElementTabbing() const; - void controllerEvent(GameController::StickID stickId, double deltaTime = 0.0); + void controllerStickEvent(GameController::StickID stickId, double deltaTime = 0.0); protected: virtual bool _areaNavigation(AreaNavigation::Direction); @@ -117,13 +117,14 @@ class Screen : public GuiComponent virtual void onTextBoxUpdated(int id) {}; virtual void pointerPressed(const MenuPointer& pointer, MouseButtonType btn); virtual void pointerReleased(const MenuPointer& pointer, MouseButtonType btn); - virtual void keyPressed(int); + virtual void controlPressed(const ControlBind&); virtual void handleTextChar(char); virtual void keyboardTextPaste(const std::string& text); virtual float getScale(int width, int height); static float GetConsoleScale(int height); virtual void setTextboxText(const std::string& text); virtual void handleKeyboardClosed(); + virtual bool isInvalid(Minecraft*); // ported from 0.8 virtual void renderMenuBackground(float f); diff --git a/source/client/gui/ScreenChooser.cpp b/source/client/gui/ScreenChooser.cpp index d2620083f..f48be2e22 100644 --- a/source/client/gui/ScreenChooser.cpp +++ b/source/client/gui/ScreenChooser.cpp @@ -6,7 +6,6 @@ #include "screens/inventory/CraftingScreen.hpp" #include "screens/inventory/ChestScreen.hpp" #include "screens/OptionsScreen.hpp" -#include "screens/OptionsScreen_Console.hpp" #include "screens/CreateWorldScreen.hpp" #include "screens/ProgressScreen.hpp" #include "screens/CreditsScreen.hpp" diff --git a/source/client/gui/VerticalLayout.cpp b/source/client/gui/VerticalLayout.cpp index b85fc8847..d5e4795e1 100644 --- a/source/client/gui/VerticalLayout.cpp +++ b/source/client/gui/VerticalLayout.cpp @@ -26,6 +26,11 @@ GuiElement* VerticalLayout::getElement(ID index) const return nullptr; } +bool VerticalLayout::isLastIn(AreaNavigation::Direction dir) +{ + return m_pSelectedElement && Navigation(this).navigate(dir, m_pSelectedElement->m_xPos + m_pSelectedElement->m_width / 2, m_pSelectedElement->m_yPos + m_pSelectedElement->m_height / 2) < 0; +} + bool VerticalLayout::selectElementById(ID id, bool sound) { GuiElement* element = getElement(id); @@ -99,7 +104,7 @@ void VerticalLayout::organize() } if (isSelected() && !m_pSelectedElement && m_pScreen->_useController()) - selectElementById(0, false); + startNavigation(); } void VerticalLayout::clear() @@ -115,18 +120,24 @@ void VerticalLayout::clear() } } +void VerticalLayout::startNavigation() +{ + AreaNavigation::ID id = Navigation(this).navigate(AreaNavigation::DOWN, m_pScreen->m_width / 2, 0); + if (id >= 0) + selectElementById(m_scrollAmount + id); +} + bool VerticalLayout::areaNavigation(Minecraft* mc, AreaNavigation::Direction dir) { if (m_pSelectedElement && m_pSelectedElement->areaNavigation(mc, dir)) return true; if (dir == AreaNavigation::DOWN) { - GuiElement* element = m_pSelectedElement; - if (element && isBottomElement(*element)) + if (isLastIn(dir)) { - if (m_bCyclic && !m_bCanScrollDown && m_scrollAmount > 0) + if (m_bCyclic && !m_bCanScrollDown) { - int x = element->m_xPos + element->m_width / 2; + int x = m_pSelectedElement->m_xPos + m_pSelectedElement->m_width / 2; updateScroll(0); AreaNavigation::ID id = Navigation(this).navigate(dir, x, 0, true); if (id >= 0) @@ -134,21 +145,28 @@ bool VerticalLayout::areaNavigation(Minecraft* mc, AreaNavigation::Direction dir return true; } - handleScroll(false); - areaNavigation(dir, element == getElement(ID(m_elements.size() - 1))); - return true; + if (m_bCanScrollDown) + { + GuiElement* oldElement = m_pSelectedElement; + while (oldElement == m_pSelectedElement) + { + handleScroll(false); + areaNavigation(dir, false); + } + + return true; + } } areaNavigation(dir); return true; } else if (dir == AreaNavigation::UP) { - GuiElement* element = m_pSelectedElement; - if (element && isTopElement(*element)) + if (isLastIn(dir)) { if (m_bCyclic && !m_scrollAmount) { - int x = element->m_xPos + element->m_width / 2; + int x = m_pSelectedElement->m_xPos + m_pSelectedElement->m_width / 2; while (m_bCanScrollDown) { updateScroll(m_scrollAmount + 1); @@ -189,7 +207,7 @@ void VerticalLayout::setSelected(bool b) GuiElement::setSelected(b); if (b && !m_pSelectedElement && m_pScreen->_useController()) - selectElementById(0, false); + startNavigation(); if (!b) selectElement(nullptr); @@ -284,5 +302,5 @@ bool VerticalLayout::Navigation::next(int& x, int& y, bool cycle) bool VerticalLayout::Navigation::isValid(ID id) { - return m_pLayout->m_pSelectedElement->getId() != (m_pLayout->m_scrollAmount + id); + return !m_pLayout->m_pSelectedElement || m_pLayout->m_pSelectedElement->getId() != (m_pLayout->m_scrollAmount + id); } \ No newline at end of file diff --git a/source/client/gui/VerticalLayout.hpp b/source/client/gui/VerticalLayout.hpp index d3dd64699..78d0673b5 100644 --- a/source/client/gui/VerticalLayout.hpp +++ b/source/client/gui/VerticalLayout.hpp @@ -12,6 +12,7 @@ class VerticalLayout : public GuiElement ~VerticalLayout(); GuiElement* getElement(ID) const; + bool isLastIn(AreaNavigation::Direction dir); bool isTopElement(GuiElement& element) const { return element.m_yPos == m_yPos; }; bool isBottomElement(GuiElement& element) const { return element.m_yPos == m_bottom; }; bool selectElementById(ID, bool sound = true); @@ -21,6 +22,7 @@ class VerticalLayout : public GuiElement void organize(); void clear(); + void startNavigation(); bool areaNavigation(Minecraft*, AreaNavigation::Direction) override; void areaNavigation(AreaNavigation::Direction, bool cyclic = false); void setSelected(bool); diff --git a/source/client/gui/components/OptionList.cpp b/source/client/gui/components/OptionList.cpp index 062f32f5e..fdbcfeebd 100644 --- a/source/client/gui/components/OptionList.cpp +++ b/source/client/gui/components/OptionList.cpp @@ -173,7 +173,8 @@ void OptionList::initControlsMenu() if (!m_pMinecraft->isTouchscreen()) m_items[idxSplit]->setEnabled(false); - m_items[idxController]->setEnabled(false); + if (!m_pMinecraft->platform()->hasGamepad()) + m_items[idxController]->setEnabled(false); } void OptionList::initVideoMenu() diff --git a/source/client/gui/components/TextBox.cpp b/source/client/gui/components/TextBox.cpp index f18371498..2351c501f 100644 --- a/source/client/gui/components/TextBox.cpp +++ b/source/client/gui/components/TextBox.cpp @@ -205,26 +205,26 @@ char TextBox::guessCharFromKey(int key) { #endif -void TextBox::handleButtonPress(Minecraft* pMinecraft, int key) +void TextBox::handleControlPress(Minecraft* pMinecraft, const ControlBind& bind) { Options& options = *pMinecraft->getOptions(); if (!hasFocus()) { - if (options.isKey(KM_MENU_OK, key)) + if (options.isControl(KM_MENU_OK, bind)) setFocused(true); return; } #ifndef HANDLE_CHARS_SEPARATELY - char guess = guessCharFromKey(key); + char guess = guessCharFromKey(bind.keyId); if (guess != '\0') { handleTextChar(guess); return; } #endif - switch (key) { + switch (bind.keyId) { case AKEYCODE_DEL: { // handled elsewhere, do not dupe diff --git a/source/client/gui/components/TextBox.hpp b/source/client/gui/components/TextBox.hpp index 59c02b0b1..ae2de1eec 100644 --- a/source/client/gui/components/TextBox.hpp +++ b/source/client/gui/components/TextBox.hpp @@ -40,7 +40,7 @@ class TextBox : public GuiElement public: void init(Font* pFont); bool pointerPressed(Minecraft* pMinecraft, const MenuPointer& pointer) override; - void handleButtonPress(Minecraft* pMinecraft, int key) override; + void handleControlPress(Minecraft* pMinecraft, const ControlBind&) override; void handleTextChar(Minecraft* pMinecraft, int chr) override; void handleClipboardPaste(const std::string& text) override; void render(Minecraft* pMinecraft, const MenuPointer& pointer) override; diff --git a/source/client/gui/screens/ChatScreen.cpp b/source/client/gui/screens/ChatScreen.cpp index 748b0aeac..042775d3e 100644 --- a/source/client/gui/screens/ChatScreen.cpp +++ b/source/client/gui/screens/ChatScreen.cpp @@ -58,15 +58,15 @@ void ChatScreen::render(float f) Screen::render(f); } -void ChatScreen::keyPressed(int keyCode) +void ChatScreen::controlPressed(const ControlBind& bind) { if (!_useController()) { - if (m_pMinecraft->getOptions()->isKey(KM_MENU_OK, keyCode)) + if (m_pMinecraft->getOptions()->isControl(KM_MENU_OK, bind)) sendMessageAndExit(); } - Screen::keyPressed(keyCode); + Screen::controlPressed(bind); } void ChatScreen::handleKeyboardClosed() @@ -77,6 +77,11 @@ void ChatScreen::handleKeyboardClosed() Screen::handleKeyboardClosed(); } +bool ChatScreen::isPauseScreen() +{ + return false; +} + void ChatScreen::sendMessageAndExit() { m_pMinecraft->sendMessage(m_textChat.getText()); diff --git a/source/client/gui/screens/ChatScreen.hpp b/source/client/gui/screens/ChatScreen.hpp index 2be599ab8..df2f8e56d 100644 --- a/source/client/gui/screens/ChatScreen.hpp +++ b/source/client/gui/screens/ChatScreen.hpp @@ -24,8 +24,9 @@ class ChatScreen : public Screen void init() override; void removed() override; void render(float f) override; - void keyPressed(int keyCode) override; + void controlPressed(const ControlBind& bind) override; void handleKeyboardClosed() override; + bool isPauseScreen() override; void sendMessageAndExit(); diff --git a/source/client/gui/screens/CreditsScreen.cpp b/source/client/gui/screens/CreditsScreen.cpp index b5bfb604d..a3afde9ea 100644 --- a/source/client/gui/screens/CreditsScreen.cpp +++ b/source/client/gui/screens/CreditsScreen.cpp @@ -53,9 +53,9 @@ bool CreditsScreen::isInGameScreen() return true; } -void CreditsScreen::keyPressed(int code) +void CreditsScreen::controlPressed(const ControlBind& bind) { - Screen::keyPressed(code); + Screen::controlPressed(bind); } void CreditsScreen::tick() diff --git a/source/client/gui/screens/CreditsScreen.hpp b/source/client/gui/screens/CreditsScreen.hpp index 27185894e..e922449fc 100644 --- a/source/client/gui/screens/CreditsScreen.hpp +++ b/source/client/gui/screens/CreditsScreen.hpp @@ -15,7 +15,7 @@ class CreditsScreen : public Screen public: void init() override; bool isInGameScreen() override; - void keyPressed(int code) override; + void controlPressed(const ControlBind&) override; void tick() override; void render(float f) override; bool handleBackEvent(bool b) override; diff --git a/source/client/gui/screens/IngameBlockSelectionScreen.cpp b/source/client/gui/screens/IngameBlockSelectionScreen.cpp index 1875b5ba9..27e7124ae 100644 --- a/source/client/gui/screens/IngameBlockSelectionScreen.cpp +++ b/source/client/gui/screens/IngameBlockSelectionScreen.cpp @@ -337,18 +337,23 @@ void IngameBlockSelectionScreen::removed() m_pMinecraft->m_pGui->inventoryUpdated(); } -void IngameBlockSelectionScreen::keyPressed(int keyCode) +void IngameBlockSelectionScreen::controlPressed(const ControlBind& bind) { - if (!_useController() && m_pMinecraft->getOptions()->isKey(KM_INVENTORY, keyCode)) + if (!_useController() && m_pMinecraft->getOptions()->isControl(KM_INVENTORY, bind)) { m_pMinecraft->handleBack(false); } else { - Screen::keyPressed(keyCode); + Screen::controlPressed(bind); } } +bool IngameBlockSelectionScreen::isPauseScreen() +{ + return false; +} + void IngameBlockSelectionScreen::selectSlotAndClose() { Inventory* pInv = getInventory(); diff --git a/source/client/gui/screens/IngameBlockSelectionScreen.hpp b/source/client/gui/screens/IngameBlockSelectionScreen.hpp index 097af0f64..45b14dcbc 100644 --- a/source/client/gui/screens/IngameBlockSelectionScreen.hpp +++ b/source/client/gui/screens/IngameBlockSelectionScreen.hpp @@ -40,7 +40,8 @@ class IngameBlockSelectionScreen : public Screen void pointerPressed(const MenuPointer& pointer, MouseButtonType btn) override; void pointerReleased(const MenuPointer& pointer, MouseButtonType btn) override; void removed() override; - void keyPressed(int key) override; + void controlPressed(const ControlBind&) override; + bool isPauseScreen() override; private: SlotID m_selectedSlot; diff --git a/source/client/gui/screens/OptionsScreen.cpp b/source/client/gui/screens/OptionsScreen.cpp index 2490863a9..d76d3544c 100644 --- a/source/client/gui/screens/OptionsScreen.cpp +++ b/source/client/gui/screens/OptionsScreen.cpp @@ -164,6 +164,16 @@ void OptionsScreen::handleScrollWheel(float force) m_pList->handleScrollWheel(force); } +bool OptionsScreen::isInvalid(Minecraft* mc) +{ + if (mc->getOptions()->getUiTheme() == UI_CONSOLE) + { + mc->getScreenChooser()->pushOptionsScreen(m_pParent); + return true; + } + return false; +} + #else #include "client/renderer/PatchManager.hpp" diff --git a/source/client/gui/screens/OptionsScreen.hpp b/source/client/gui/screens/OptionsScreen.hpp index 0100b20a9..c3e4f873c 100644 --- a/source/client/gui/screens/OptionsScreen.hpp +++ b/source/client/gui/screens/OptionsScreen.hpp @@ -42,6 +42,7 @@ class OptionsScreen : public Screen void _buttonClicked(Button* pButton) override; bool handleBackEvent(bool b) override; void handleScrollWheel(float force) override; + bool isInvalid(Minecraft*) override; private: void setCategory(OptionsCategory category); diff --git a/source/client/gui/screens/OptionsScreen_Console.cpp b/source/client/gui/screens/OptionsScreen_Console.cpp index 934283210..16037b173 100644 --- a/source/client/gui/screens/OptionsScreen_Console.cpp +++ b/source/client/gui/screens/OptionsScreen_Console.cpp @@ -35,7 +35,7 @@ void OptionsScreen_Console::_buttonClicked(Button* btn) void OptionsScreen_Console::init() { - Button* layoutButtons[] = {&m_btnHowToPlay, &m_btnControls, &m_btnSettings, &m_btnCredits, &m_btnResetToDefaults}; + Button* layoutButtons[] = { &m_btnHowToPlay, &m_btnControls, &m_btnSettings, &m_btnCredits, &m_btnResetToDefaults }; int buttonsWidth = 450; int buttonsHeight = 40; @@ -70,6 +70,16 @@ bool OptionsScreen_Console::handleBackEvent(bool b) return true; } +bool OptionsScreen_Console::isInvalid(Minecraft* mc) +{ + if (mc->getOptions()->getUiTheme() != UI_CONSOLE) + { + mc->getScreenChooser()->pushOptionsScreen(m_pParent); + return true; + } + return false; +} + #define HEADER(text) do { m_layout.m_elements.push_back(new OptionHeader_Console(text)); currentIndex++; } while (0) #define OPTION(name) do { options.name.addGuiElement(m_layout.m_elements, m_uiTheme); currentIndex++; } while (0) @@ -134,6 +144,7 @@ OptionHeader_Console::OptionHeader_Console(const std::string& text) : m_text(text) { m_height = 22; + setNavigable(false); } void OptionHeader_Console::render(Minecraft* pMinecraft, const MenuPointer& pointer) diff --git a/source/client/gui/screens/OptionsScreen_Console.hpp b/source/client/gui/screens/OptionsScreen_Console.hpp index 3a7a3cbe7..f8733cc0f 100644 --- a/source/client/gui/screens/OptionsScreen_Console.hpp +++ b/source/client/gui/screens/OptionsScreen_Console.hpp @@ -32,6 +32,7 @@ class OptionsScreen_Console : public Screen void init() override; void render(float) override; bool handleBackEvent(bool) override; + bool isInvalid(Minecraft*) override; private: Screen* m_pParent; diff --git a/source/client/gui/screens/PauseScreen.cpp b/source/client/gui/screens/PauseScreen.cpp index 0700e676c..e18752e77 100644 --- a/source/client/gui/screens/PauseScreen.cpp +++ b/source/client/gui/screens/PauseScreen.cpp @@ -119,3 +119,13 @@ void PauseScreen::_buttonClicked(Button* pButton) } #endif } + +bool PauseScreen::isInvalid(Minecraft* mc) +{ + if (mc->getOptions()->getUiTheme() == UI_CONSOLE) + { + mc->getScreenChooser()->pushPauseScreen(); + return true; + } + return false; +} diff --git a/source/client/gui/screens/PauseScreen.hpp b/source/client/gui/screens/PauseScreen.hpp index 80a94bee6..3fade2e3a 100644 --- a/source/client/gui/screens/PauseScreen.hpp +++ b/source/client/gui/screens/PauseScreen.hpp @@ -15,10 +15,11 @@ class PauseScreen : public Screen { public: PauseScreen(); - virtual void init() override; - virtual void tick() override; - virtual void render(float f) override; - virtual void _buttonClicked(Button*) override; + void init() override; + void tick() override; + void render(float f) override; + void _buttonClicked(Button*) override; + bool isInvalid(Minecraft*) override; void updateServerVisibilityText(); diff --git a/source/client/gui/screens/PauseScreen_Console.cpp b/source/client/gui/screens/PauseScreen_Console.cpp index 9c20d057d..641a18d4d 100644 --- a/source/client/gui/screens/PauseScreen_Console.cpp +++ b/source/client/gui/screens/PauseScreen_Console.cpp @@ -54,4 +54,14 @@ void PauseScreen_Console::_buttonClicked(Button* btn) m_pMinecraft->m_pLevel->saveGame(); // Minecraft auto-saves automatically when we hit the pause screen else if (btn->getId() == m_btnExitGame.getId()) m_pMinecraft->leaveGame(false); -} \ No newline at end of file +} + +bool PauseScreen_Console::isInvalid(Minecraft* mc) +{ + if (mc->getOptions()->getUiTheme() != UI_CONSOLE) + { + mc->getScreenChooser()->pushPauseScreen(); + return true; + } + return false; +} diff --git a/source/client/gui/screens/PauseScreen_Console.hpp b/source/client/gui/screens/PauseScreen_Console.hpp index 018fef1e8..05318350e 100644 --- a/source/client/gui/screens/PauseScreen_Console.hpp +++ b/source/client/gui/screens/PauseScreen_Console.hpp @@ -10,6 +10,7 @@ class PauseScreen_Console : public Screen void init() override; void render(float) override; void _buttonClicked(Button*) override; + bool isInvalid(Minecraft*) override; private: Button m_btnResume; diff --git a/source/client/gui/screens/SelectWorldScreen.cpp b/source/client/gui/screens/SelectWorldScreen.cpp index 18c54f512..daf86b280 100644 --- a/source/client/gui/screens/SelectWorldScreen.cpp +++ b/source/client/gui/screens/SelectWorldScreen.cpp @@ -76,23 +76,24 @@ bool SelectWorldScreen::isInGameScreen() return true; } -void SelectWorldScreen::keyPressed(int code) +void SelectWorldScreen::controlPressed(const ControlBind& bind) { + Options& options = *m_pMinecraft->getOptions(); #ifndef ORIGINAL_CODE - if (m_pMinecraft->getOptions()->getKey(KM_MENU_OK) == code) + if (options.isControl(KM_MENU_OK, bind)) m_pWorldSelectionList->selectItem(m_pWorldSelectionList->getItemAtPosition(m_width / 2, m_height / 2), false); #endif if (m_btnWorld.isSelected()) { - if (m_pMinecraft->getOptions()->getKey(KM_LEFT) == code) + if (options.isControl(KM_LEFT, bind)) m_pWorldSelectionList->stepLeft(); - if (m_pMinecraft->getOptions()->getKey(KM_RIGHT) == code) + if (options.isControl(KM_RIGHT, bind)) m_pWorldSelectionList->stepRight(); } - Screen::keyPressed(code); + Screen::controlPressed(bind); } static char g_SelectWorldFilterArray[] = { '/','\n','\r','\x09','\0','\xC','`','?','*','\\','<','>','|','"',':'}; diff --git a/source/client/gui/screens/SelectWorldScreen.hpp b/source/client/gui/screens/SelectWorldScreen.hpp index 7d1937175..b0b722ffb 100644 --- a/source/client/gui/screens/SelectWorldScreen.hpp +++ b/source/client/gui/screens/SelectWorldScreen.hpp @@ -24,7 +24,7 @@ class SelectWorldScreen : public Screen public: void init() override; bool isInGameScreen() override; - void keyPressed(int code) override; + void controlPressed(const ControlBind&) override; void tick() override; void render(float f) override; bool handleBackEvent(bool b) override; diff --git a/source/client/gui/screens/StartMenuScreen.cpp b/source/client/gui/screens/StartMenuScreen.cpp index 4d2dc03ac..7e7ca77a6 100644 --- a/source/client/gui/screens/StartMenuScreen.cpp +++ b/source/client/gui/screens/StartMenuScreen.cpp @@ -238,4 +238,14 @@ bool StartMenuScreen::handleBackEvent(bool b) m_pMinecraft->quit(); } return true; -} \ No newline at end of file +} + +bool StartMenuScreen::isInvalid(Minecraft* mc) +{ + if (mc->getOptions()->getUiTheme() == UI_CONSOLE) + { + mc->getScreenChooser()->pushStartScreen(); + return true; + } + return false; +} diff --git a/source/client/gui/screens/StartMenuScreen.hpp b/source/client/gui/screens/StartMenuScreen.hpp index f924d935f..abe355603 100644 --- a/source/client/gui/screens/StartMenuScreen.hpp +++ b/source/client/gui/screens/StartMenuScreen.hpp @@ -33,6 +33,7 @@ class StartMenuScreen : public Screen void drawSplash(); bool handleBackEvent(bool b) override; + bool isInvalid(Minecraft*) override; protected: Button m_startButton; diff --git a/source/client/gui/screens/StartMenuScreen_Console.cpp b/source/client/gui/screens/StartMenuScreen_Console.cpp index f67c0e40d..6961b3495 100644 --- a/source/client/gui/screens/StartMenuScreen_Console.cpp +++ b/source/client/gui/screens/StartMenuScreen_Console.cpp @@ -72,4 +72,14 @@ void StartMenuScreen_Console::_buttonClicked(Button* btn) m_pMinecraft->getScreenChooser()->pushOptionsScreen(this); else if (btn->getId() == m_btnExitGame.getId()) m_pMinecraft->quit(); -} \ No newline at end of file +} + +bool StartMenuScreen_Console::isInvalid(Minecraft* mc) +{ + if (mc->getOptions()->getUiTheme() != UI_CONSOLE) + { + mc->getScreenChooser()->pushStartScreen(); + return true; + } + return false; +} diff --git a/source/client/gui/screens/StartMenuScreen_Console.hpp b/source/client/gui/screens/StartMenuScreen_Console.hpp index 715122f1f..774f306ba 100644 --- a/source/client/gui/screens/StartMenuScreen_Console.hpp +++ b/source/client/gui/screens/StartMenuScreen_Console.hpp @@ -10,6 +10,7 @@ class StartMenuScreen_Console : public Screen void init() override; void render(float) override; void _buttonClicked(Button*) override; + bool isInvalid(Minecraft*) override; private: Button m_btnPlayGame; diff --git a/source/client/gui/screens/inventory/ContainerScreen.cpp b/source/client/gui/screens/inventory/ContainerScreen.cpp index c751f60af..9713dccc6 100644 --- a/source/client/gui/screens/inventory/ContainerScreen.cpp +++ b/source/client/gui/screens/inventory/ContainerScreen.cpp @@ -212,16 +212,17 @@ void ContainerScreen::render(float partialTicks) if (!name.empty()) { int w = m_pFont->width(name); - int tx = m_menuPointer.x - m_leftPos + 12; - int ty = m_menuPointer.y - m_topPos - 12; if (m_uiTheme == UI_CONSOLE) { - blitNineSlice(*m_pMinecraft->m_pTextures, ScreenRenderer::POINTER_TEXT_PANEL_SLICES, tx - 6, ty - 6, w * 2 + 12, 28, 8); - MatrixStack::Ref tooltipMatrix = MatrixStack::World.push(); - m_pFont->drawScalable(name, tx, ty, -1); + int tx = m_menuPointer.x - m_leftPos + 12; + int ty = m_menuPointer.y - m_topPos - 28; + blitNineSlice(*m_pMinecraft->m_pTextures, ScreenRenderer::POINTER_TEXT_PANEL_SLICES, tx - 6, ty - 10, w * 2 + 12, 33, 8); + m_pFont->drawScalableShadow(name, tx, ty, -1); } else { + int tx = m_menuPointer.x - m_leftPos + 12; + int ty = m_menuPointer.y - m_topPos - 12; fillGradient(tx - 3, ty - 3, tx + w + 3, ty + 8 + 3, 0xC0000000, 0xC0000000); m_pFont->drawShadow(name, tx, ty, -1); } @@ -285,33 +286,34 @@ void ContainerScreen::slotClicked(const MenuPointer& pointer, MouseButtonType bu slotClicked(pointer, button, m_pMinecraft->m_pPlatform->shiftPressed()); } -void ContainerScreen::keyPressed(int keyCode) +void ContainerScreen::controlPressed(const ControlBind& bind) { - if (!_useController() && m_pMinecraft->getOptions()->isKey(KM_INVENTORY, keyCode)) + Options& options = *m_pMinecraft->getOptions(); + if (!_useController() && options.isControl(KM_INVENTORY, bind)) { m_pMinecraft->handleBack(false); } - else if (m_pMinecraft->getOptions()->isKey(KM_CONTAINER_QUICKMOVE, keyCode) && _useController()) + else if (options.isControl(KM_CONTAINER_QUICKMOVE, bind) && _useController()) { slotClicked(m_menuPointer, MOUSE_BUTTON_LEFT, true); } - else if (m_pMinecraft->getOptions()->isKey(KM_CONTAINER_SPLIT, keyCode) && _useController()) + else if (options.isControl(KM_CONTAINER_SPLIT, bind) && _useController()) { slotClicked(m_menuPointer, MOUSE_BUTTON_RIGHT, false); } else { if (_useController() && - ((m_pMinecraft->getOptions()->isKey(KM_MENU_UP, keyCode) && _selectSlotInDirection(AreaNavigation::UP)) || - (m_pMinecraft->getOptions()->isKey(KM_MENU_DOWN, keyCode) && _selectSlotInDirection(AreaNavigation::DOWN)) || - (m_pMinecraft->getOptions()->isKey(KM_MENU_RIGHT, keyCode) && _selectSlotInDirection(AreaNavigation::RIGHT)) || - (m_pMinecraft->getOptions()->isKey(KM_MENU_LEFT, keyCode) && _selectSlotInDirection(AreaNavigation::LEFT)))) + ((options.isControl(KM_MENU_UP, bind) && _selectSlotInDirection(AreaNavigation::UP)) || + (options.isControl(KM_MENU_DOWN, bind) && _selectSlotInDirection(AreaNavigation::DOWN)) || + (options.isControl(KM_MENU_RIGHT, bind) && _selectSlotInDirection(AreaNavigation::RIGHT)) || + (options.isControl(KM_MENU_LEFT, bind) && _selectSlotInDirection(AreaNavigation::LEFT)))) { _playSelectSound(); return; } - Screen::keyPressed(keyCode); + Screen::controlPressed(bind); } } diff --git a/source/client/gui/screens/inventory/ContainerScreen.hpp b/source/client/gui/screens/inventory/ContainerScreen.hpp index 274120153..b8de9a5e1 100644 --- a/source/client/gui/screens/inventory/ContainerScreen.hpp +++ b/source/client/gui/screens/inventory/ContainerScreen.hpp @@ -65,7 +65,7 @@ class ContainerScreen : public Screen void pointerPressed(const MenuPointer& pointer, MouseButtonType button) override; void pointerReleased(const MenuPointer& pointer, MouseButtonType button) override; void handlePointerPressed(bool isPressed) override; - void keyPressed(int key) override; + void controlPressed(const ControlBind&) override; const SlotDisplay& getSlotDisplay(const Slot&) const; diff --git a/source/client/options/Options.cpp b/source/client/options/Options.cpp index 4aea60bbc..220961692 100644 --- a/source/client/options/Options.cpp +++ b/source/client/options/Options.cpp @@ -152,9 +152,9 @@ void Options::_load() { std::string key = strings[i], value = strings[i + 1]; - std::map::iterator opt = m_options.find(key); - if (opt != m_options.end()) - opt->second->load(value); + HashMap::Iterator it = m_options.find(key); + if (it != m_options.end()) + it.value()->load(value); else if (key == "misc_oldtitle") logo3d = !readBool(value); else if (key == "gfx_resourcepacks") @@ -404,11 +404,11 @@ std::vector Options::getOptionStrings() #define SO(optname, value) do { vec.push_back(optname); vec.push_back(value); } while (0) std::stringstream ss; - for (std::map::iterator it = m_options.begin(); it != m_options.end(); ++it) + for (HashMap::Iterator it = m_options.begin(); it != m_options.end(); ++it) { ss.str(""); - it->second->save(ss); - SO(it->first, ss.str()); + it.value()->save(ss); + SO(it.key(), ss.str()); } SO("gfx_resourcepacks", savePackArray(m_resourcePacks)); @@ -418,7 +418,7 @@ std::vector Options::getOptionStrings() void Options::loadControls() { // Win32 key codes are being used by default -#define KM(idx, name, code) m_keyMappings[idx] = KeyMapping(name, code) +#define KM(idx, name, code) m_controlMappings[idx] = ControlMapping(name, code) KM(KM_FORWARD, "key.forward", 'W'); KM(KM_LEFT, "key.left", 'A'); KM(KM_BACKWARD, "key.back", 'S'); @@ -465,7 +465,7 @@ void Options::loadControls() // @TODO: These should **really** not be defined in here. How about AppPlatform? -#define KM(idx,code) m_keyMappings[idx].value = code +#define KM(idx,code) m_controlMappings[idx].bind.keyId = code #ifdef USE_SDL KM(KM_FORWARD, SDLVK_w); KM(KM_LEFT, SDLVK_a); @@ -577,64 +577,37 @@ void Options::loadControls() #endif #undef KM - if (m_bUseController.get()) - { -#define KM(idx,code) m_keyMappings[idx].value = code -#ifdef USE_SDL - KM(KM_TOGGLEDEBUG, SDL_CONTROLLER_BUTTON_GUIDE); - KM(KM_JUMP, SDL_CONTROLLER_BUTTON_A); - KM(KM_MENU_UP, SDL_CONTROLLER_BUTTON_DPAD_UP); - KM(KM_MENU_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN); - KM(KM_MENU_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT); - KM(KM_MENU_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); - KM(KM_MENU_TAB_LEFT, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); - KM(KM_MENU_TAB_RIGHT, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); - KM(KM_MENU_OK, SDL_CONTROLLER_BUTTON_A); - KM(KM_MENU_CANCEL, SDL_CONTROLLER_BUTTON_B); - KM(KM_DROP, SDL_CONTROLLER_BUTTON_B); - KM(KM_CHAT, SDL_CONTROLLER_BUTTON_BACK); - KM(KM_INVENTORY, SDL_CONTROLLER_BUTTON_Y); - KM(KM_SNEAK, SDL_CONTROLLER_BUTTON_RIGHTSTICK); - KM(KM_CONTAINER_QUICKMOVE, SDL_CONTROLLER_BUTTON_Y); - KM(KM_CONTAINER_SPLIT, SDL_CONTROLLER_BUTTON_X); - KM(KM_TOGGLE3RD, SDL_CONTROLLER_BUTTON_LEFTSTICK); - KM(KM_SLOT_L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); - KM(KM_SLOT_R, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); - KM(KM_FLY_UP, SDL_CONTROLLER_BUTTON_A); - KM(KM_FLY_DOWN, SDL_CONTROLLER_BUTTON_RIGHTSTICK); -#else - KM(KM_TOGGLEDEBUG, GameController::BUTTON_GUIDE); - KM(KM_JUMP, GameController::BUTTON_A); - KM(KM_MENU_UP, GameController::BUTTON_DPAD_UP); - KM(KM_MENU_DOWN, GameController::BUTTON_DPAD_DOWN); - KM(KM_MENU_LEFT, GameController::BUTTON_DPAD_LEFT); - KM(KM_MENU_RIGHT, GameController::BUTTON_DPAD_RIGHT); - KM(KM_MENU_TAB_LEFT, GameController::BUTTON_LEFTSHOULDER); - KM(KM_MENU_TAB_RIGHT, GameController::BUTTON_RIGHTSHOULDER); - KM(KM_MENU_OK, GameController::BUTTON_A); - KM(KM_MENU_CANCEL, GameController::BUTTON_B); - KM(KM_MENU_PAUSE, GameController::BUTTON_START); - KM(KM_DROP, GameController::BUTTON_B); - KM(KM_CHAT, GameController::BUTTON_BACK); - KM(KM_INVENTORY, GameController::BUTTON_Y); - KM(KM_SNEAK, GameController::BUTTON_RIGHTSTICK); - KM(KM_CONTAINER_QUICKMOVE, GameController::BUTTON_Y); - KM(KM_CONTAINER_SPLIT, GameController::BUTTON_X); - KM(KM_TOGGLE3RD, GameController::BUTTON_LEFTSTICK); - KM(KM_SLOT_L, GameController::BUTTON_LEFTSHOULDER); - KM(KM_SLOT_R, GameController::BUTTON_RIGHTSHOULDER); - KM(KM_FLY_UP, GameController::BUTTON_A); - KM(KM_FLY_DOWN, GameController::BUTTON_RIGHTSTICK); -#endif -#undef KM - } +#define BTN(idx,code) m_controlMappings[idx].bind.buttonId = code + BTN(KM_TOGGLEDEBUG, GameController::BUTTON_GUIDE); + BTN(KM_JUMP, GameController::BUTTON_A); + BTN(KM_MENU_UP, GameController::BUTTON_DPAD_UP); + BTN(KM_MENU_DOWN, GameController::BUTTON_DPAD_DOWN); + BTN(KM_MENU_LEFT, GameController::BUTTON_DPAD_LEFT); + BTN(KM_MENU_RIGHT, GameController::BUTTON_DPAD_RIGHT); + BTN(KM_MENU_TAB_LEFT, GameController::BUTTON_LEFTSHOULDER); + BTN(KM_MENU_TAB_RIGHT, GameController::BUTTON_RIGHTSHOULDER); + BTN(KM_MENU_OK, GameController::BUTTON_A); + BTN(KM_MENU_CANCEL, GameController::BUTTON_B); + BTN(KM_MENU_PAUSE, GameController::BUTTON_START); + BTN(KM_DROP, GameController::BUTTON_B); + BTN(KM_CHAT, GameController::BUTTON_BACK); + BTN(KM_INVENTORY, GameController::BUTTON_Y); + BTN(KM_SNEAK, GameController::BUTTON_RIGHTSTICK); + BTN(KM_CONTAINER_QUICKMOVE, GameController::BUTTON_Y); + BTN(KM_CONTAINER_SPLIT, GameController::BUTTON_X); + BTN(KM_TOGGLE3RD, GameController::BUTTON_LEFTSTICK); + BTN(KM_SLOT_L, GameController::BUTTON_LEFTSHOULDER); + BTN(KM_SLOT_R, GameController::BUTTON_RIGHTSHOULDER); + BTN(KM_FLY_UP, GameController::BUTTON_A); + BTN(KM_FLY_DOWN, GameController::BUTTON_RIGHTSTICK); +#undef BTN } void Options::reset() { - for (std::map::iterator it = m_options.begin(); it != m_options.end(); ++it) + for (HashMap::Iterator it = m_options.begin(); it != m_options.end(); ++it) { - it->second->reset(); + it.value()->reset(); } } diff --git a/source/client/options/Options.hpp b/source/client/options/Options.hpp index d82d9e9e5..7723e2182 100644 --- a/source/client/options/Options.hpp +++ b/source/client/options/Options.hpp @@ -15,10 +15,12 @@ #include #include +#include "common/utility/HashMap.hpp" #include "common/threading/AsyncTask.hpp" +#include "client/player/input/GameController.hpp" #include "client/resources/ResourcePackManager.hpp" -enum eKeyMappingIndex +enum eControlMappingIndex { KM_FORWARD, KM_LEFT, @@ -65,13 +67,44 @@ enum eKeyMappingIndex KM_COUNT }; -struct KeyMapping +struct ControlBind +{ + //@TODO: Replace this with an universal key + int keyId; + GameController::EngineButtonID buttonId; + + ControlBind() : keyId(-1), buttonId(GameController::BUTTON_NONE) {} + ControlBind(int key, GameController::EngineButtonID button) : keyId(key), buttonId(button) {} + + bool isKey(int key) const { return keyId >= 0 && key == keyId; } + bool isButton(GameController::EngineButtonID button) const { return buttonId > GameController::BUTTON_NONE && button == buttonId; } + bool operator==(const ControlBind& other) const + { + return isKey(other.keyId) || isButton(other.buttonId); + } +}; + +struct ControlMapping { std::string key; - int value; + ControlBind bind; + int timesPressed; - KeyMapping() : value(-1) {} // key is automatically clear when constructed - KeyMapping(const char* keyName, int keyCode) : key(keyName), value(keyCode) {} + ControlMapping() : timesPressed(0) {} // key is automatically clear when constructed + ControlMapping(const char* keyName, int keyCode) : key(keyName), timesPressed(0) + { + bind.keyId = keyCode; + } + + void pressed() { ++timesPressed; } + void reset() { timesPressed = 0; } + bool consume() + { + if (timesPressed == 0) return false; + + --timesPressed; + return true; + } }; enum UITheme @@ -330,8 +363,6 @@ class HUDSizeOption : public MinMaxOption class Options { -public: - struct KeyBind; private: static bool _hasResourcePack(const ResourcePack& pack, ResourcePackStack& packs); static void _tryAddResourcePack(const std::string& name, ResourcePackStack& packs); @@ -368,8 +399,12 @@ class Options const AsyncTask& save(); std::vector getOptionStrings(); - int getKey(eKeyMappingIndex idx) const { return m_keyMappings[idx].value; } - bool isKey(eKeyMappingIndex idx, int keyCode) const { return getKey(idx) == keyCode; } + int getKey(eControlMappingIndex idx) const { return m_controlMappings[idx].bind.keyId; } + bool isKey(eControlMappingIndex idx, int keyCode) const { return getKey(idx) == keyCode; } + + ControlMapping& getControlMapping(eControlMappingIndex idx) { return m_controlMappings[idx]; } + const ControlBind& getControl(eControlMappingIndex idx) const { return m_controlMappings[idx].bind; } + bool isControl(eControlMappingIndex idx, const ControlBind& bind) const { return m_controlMappings[idx].bind == bind; } void loadControls(); void reset(); @@ -380,10 +415,10 @@ class Options private: Minecraft* m_pMinecraft; - std::map m_options; + HashMap m_options; AsyncTask m_saveTask; std::string m_filePath; - KeyMapping m_keyMappings[KM_COUNT]; + ControlMapping m_controlMappings[KM_COUNT]; public: friend class BoolOption; diff --git a/source/client/player/input/ControllerMoveInput.cpp b/source/client/player/input/ControllerMoveInput.cpp index cf813abe8..2da8e9475 100644 --- a/source/client/player/input/ControllerMoveInput.cpp +++ b/source/client/player/input/ControllerMoveInput.cpp @@ -43,9 +43,15 @@ void ControllerMoveInput::tick(Player* player) IMoveInput::tick(player); } -void ControllerMoveInput::setKey(int eventKey, bool eventKeyState) +void ControllerMoveInput::setKey(eControlMappingIndex ctrl, bool eventKeyState) { - KeyboardInput::setKey(eventKey, eventKeyState); + if (ctrl == KM_SNEAK) + { + if (eventKeyState) + KeyboardInput::setKey(ctrl, m_keys[INPUT_SNEAK] ^ 1); + } + else + KeyboardInput::setKey(ctrl, eventKeyState); //this->m_culledEntities = m_pOptions[36] == eventKey && eventKeyState; //this->field_21 = m_pOptions[34] == eventKey && eventKeyState; } diff --git a/source/client/player/input/ControllerMoveInput.hpp b/source/client/player/input/ControllerMoveInput.hpp index bfdaa8369..62e073982 100644 --- a/source/client/player/input/ControllerMoveInput.hpp +++ b/source/client/player/input/ControllerMoveInput.hpp @@ -12,7 +12,7 @@ class ControllerMoveInput : public KeyboardInput ControllerMoveInput(Options *options); void tick(Player *player) override; - void setKey(int eventKey, bool eventKeyState) override; + void setKey(eControlMappingIndex, bool eventKeyState) override; void releaseAllKeys() override; }; diff --git a/source/client/player/input/CustomInputHolder.cpp b/source/client/player/input/CustomInputHolder.cpp index c4dacfd4a..8f3d78600 100644 --- a/source/client/player/input/CustomInputHolder.cpp +++ b/source/client/player/input/CustomInputHolder.cpp @@ -8,11 +8,18 @@ #include "CustomInputHolder.hpp" -CustomInputHolder::CustomInputHolder(IMoveInput* pMoveInput, ITurnInput* pTurnInput, IBuildInput* pBuildInput) +CustomInputHolder::CustomInputHolder(IMoveInput* pMoveInput, ITurnInput* pTurnInput, IBuildInput* pBuildInput, bool isController) : + m_bIsController(isController) { setInputs(pMoveInput, pTurnInput, pBuildInput); } +bool CustomInputHolder::allowsType(Type type) const +{ + if (m_bIsController) return type == CONTROLLER; + return IInputHolder::allowsType(type); +} + IMoveInput* CustomInputHolder::getMoveInput() { return m_pMoveInput; diff --git a/source/client/player/input/CustomInputHolder.hpp b/source/client/player/input/CustomInputHolder.hpp index 3f4d2cb49..af49844cf 100644 --- a/source/client/player/input/CustomInputHolder.hpp +++ b/source/client/player/input/CustomInputHolder.hpp @@ -13,8 +13,9 @@ class CustomInputHolder : public IInputHolder { public: - CustomInputHolder(IMoveInput*, ITurnInput*, IBuildInput*); + CustomInputHolder(IMoveInput*, ITurnInput*, IBuildInput*, bool isController = false); + bool allowsType(Type) const override; IMoveInput* getMoveInput() override; ITurnInput* getTurnInput() override; IBuildInput* getBuildInput() override; @@ -26,5 +27,6 @@ class CustomInputHolder : public IInputHolder IMoveInput* m_pMoveInput; ITurnInput* m_pTurnInput; IBuildInput* m_pBuildInput; + bool m_bIsController; }; diff --git a/source/client/player/input/GameController.hpp b/source/client/player/input/GameController.hpp index f65ccf4f7..127ad9677 100644 --- a/source/client/player/input/GameController.hpp +++ b/source/client/player/input/GameController.hpp @@ -29,6 +29,7 @@ class GameController }; enum EngineButtonID { + BUTTON_NONE = -1, BUTTON_A, BUTTON_B, BUTTON_X, diff --git a/source/client/player/input/GameControllerHandler.hpp b/source/client/player/input/GameControllerHandler.hpp index 9b9064a99..4dc1e53a3 100644 --- a/source/client/player/input/GameControllerHandler.hpp +++ b/source/client/player/input/GameControllerHandler.hpp @@ -1,7 +1,6 @@ #pragma once -#include - +#include "common/utility/HashMap.hpp" #include "client/app/AppPlatform.hpp" #include "world/phys/Vec2.hpp" #include "GameController.hpp" @@ -11,8 +10,8 @@ class GameControllerHandler { public: - typedef std::map ButtonIDMap; - typedef std::map ButtonStateLookup; + typedef HashMap ButtonIDMap; + typedef HashMap ButtonStateLookup; public: GameControllerHandler(); diff --git a/source/client/player/input/GameControllerManager.cpp b/source/client/player/input/GameControllerManager.cpp index 404e57f2b..b370fd6e0 100644 --- a/source/client/player/input/GameControllerManager.cpp +++ b/source/client/player/input/GameControllerManager.cpp @@ -9,6 +9,7 @@ #include #include "GameControllerManager.hpp" +#include "IInputHolder.hpp" const float GameControllerManager::DIRECTION_X_THRESHOLD = 0.3f; const float GameControllerManager::DIRECTION_Y_THRESHOLD = 0.3f; @@ -17,6 +18,9 @@ const float GameControllerManager::DIRECTION_Y_THRESHOLD = 0.3f; // 0.3051f float GameControllerManager::_deadzonesX[][2] = { DEADZONE(0.3f), DEADZONE(0.3f) }; // Java: { DEADZONE(0.15f), DEADZONE(0.20f) }; float GameControllerManager::_deadzonesY[][2] = { DEADZONE(0.3f), DEADZONE(0.3f) }; // Java: { DEADZONE(0.15f), DEADZONE(0.20f) }; +std::vector GameControllerManager::_inputs; +GameController::ButtonState GameControllerManager::_states[]; +size_t GameControllerManager::_index = -1; bool GameControllerManager::isTouchedValues[] = { false, false }; float GameControllerManager::stickValuesX[] = { 0.0f, 0.0f }; @@ -24,6 +28,55 @@ float GameControllerManager::stickValuesY[] = { 0.0f, 0.0f }; float GameControllerManager::triggerValues[] = { 0.0f, 0.0f }; bool GameControllerManager::inReset = true; +void GameControllerManager::feedButton(GameController::ButtonState state, GameController::EngineButtonID button) +{ + // Prevent Crashes + if (button >= GameController::BUTTON_MAX || button < 0) { + return; + } + + IInputHolder::activeType = IInputHolder::CONTROLLER; + + GameController::ButtonEvent event; + event.state = state; + event.id = button; + event.bAllowRemapping = false; + + _inputs.push_back(event); + + _states[button] = state; +} + +bool GameControllerManager::next() +{ + if ((size_t)_index + 1 >= _inputs.size()) + { + if (!_inputs.empty()) clear(); + return false; + } + + _index++; + return true; +} + +GameController::EngineButtonID GameControllerManager::getEventButton() +{ + return _inputs[_index].id; +} + +GameController::ButtonState GameControllerManager::getEventButtonState() +{ + return _inputs[_index].state; +} + +bool GameControllerManager::isButtonDown(GameController::EngineButtonID button) +{ + if (button < 0 || button >= GameController::BUTTON_MAX) + return false; + + return _states[button] == GameController::BTN_STATE_DOWN; +} + bool GameControllerManager::isValidStick(GameController::StickID stickId) { // We have 2 'sticks' on the Xperia Play @@ -63,6 +116,9 @@ void GameControllerManager::feedStickX(GameController::StickID stickId, bool tou stickValuesX[index] = x; // LCE has a deadzone of 20000, ~0.3f on 360 inReset = false; + + if (x) + IInputHolder::activeType = IInputHolder::CONTROLLER; } void GameControllerManager::feedStickY(GameController::StickID stickId, bool touched, float y) @@ -83,6 +139,9 @@ void GameControllerManager::feedStickY(GameController::StickID stickId, bool tou stickValuesY[index] = y; // LCE has a deadzone of 20000, ~0.3f on 360 inReset = false; + + if (y) + IInputHolder::activeType = IInputHolder::CONTROLLER; } void GameControllerManager::feedStick(GameController::StickID stickId, bool touched, float x, float y) @@ -192,8 +251,15 @@ float GameControllerManager::getPressure(int triggerNo) return isValidTrigger(triggerNo) ? triggerValues[triggerNo - 1] : 0; } +void GameControllerManager::clear() +{ + _index = -1; + _inputs.clear(); +} + void GameControllerManager::reset() { + clear(); feedStick(1, 0, 0.0f, 0.0f); feedStick(2, 0, 0.0f, 0.0f); feedTrigger(1, 0.0f); diff --git a/source/client/player/input/GameControllerManager.hpp b/source/client/player/input/GameControllerManager.hpp index 346aba1ea..38c1ee497 100644 --- a/source/client/player/input/GameControllerManager.hpp +++ b/source/client/player/input/GameControllerManager.hpp @@ -19,8 +19,16 @@ class GameControllerManager static const float DIRECTION_Y_THRESHOLD; static float _deadzonesX[2][2], _deadzonesY[2][2]; + static std::vector _inputs; + static GameController::ButtonState _states[GameController::BUTTON_MAX]; + static size_t _index; public: + static void feedButton(GameController::ButtonState, GameController::EngineButtonID); + static bool next(); + static GameController::EngineButtonID getEventButton(); + static GameController::ButtonState getEventButtonState(); + static bool isButtonDown(GameController::EngineButtonID); static bool isValidStick(GameController::StickID stickId); static float linearTransform(float, float, float, bool); // SDL2 feeds controller stick update events one axis at a time @@ -39,6 +47,7 @@ class GameControllerManager static bool isValidTrigger(int triggerNo); static void feedTrigger(int triggerNo, float x); static float getPressure(int triggerNo); + static void clear(); static void reset(); static bool isReset() { return inReset; } diff --git a/source/client/player/input/IInputHolder.cpp b/source/client/player/input/IInputHolder.cpp index 4d017b5d5..69f1a2d64 100644 --- a/source/client/player/input/IInputHolder.cpp +++ b/source/client/player/input/IInputHolder.cpp @@ -9,6 +9,8 @@ #include "IInputHolder.hpp" #include "Mouse.hpp" +IInputHolder::Type IInputHolder::activeType = KEYBOARD; + IInputHolder::IInputHolder() : m_feedbackX(0), m_feedbackY(0) @@ -32,3 +34,8 @@ void IInputHolder::setScreenSize(int width, int height) getTurnInput()->setScreenSize(width, height); getBuildInput()->setScreenSize(width, height); } + +bool IInputHolder::allowsType(Type type) const +{ + return type == KEYBOARD || type == MOUSE; +} diff --git a/source/client/player/input/IInputHolder.hpp b/source/client/player/input/IInputHolder.hpp index 233d97dce..0aa9448c3 100644 --- a/source/client/player/input/IInputHolder.hpp +++ b/source/client/player/input/IInputHolder.hpp @@ -15,10 +15,19 @@ class IInputHolder { public: + enum Type + { + KEYBOARD, + MOUSE, + CONTROLLER, + TOUCHSCREEN + }; + IInputHolder(); virtual ~IInputHolder(); virtual bool allowPicking(); virtual void setScreenSize(int width, int height); + virtual bool allowsType(Type) const; virtual IMoveInput* getMoveInput() = 0; virtual ITurnInput* getTurnInput() = 0; virtual IBuildInput* getBuildInput() = 0; @@ -30,5 +39,9 @@ class IInputHolder float m_feedbackX; float m_feedbackY; float m_feedbackAlpha; + +public: + static Type activeType; + static Type lastType; }; diff --git a/source/client/player/input/IMoveInput.cpp b/source/client/player/input/IMoveInput.cpp index 7b646287f..385213791 100644 --- a/source/client/player/input/IMoveInput.cpp +++ b/source/client/player/input/IMoveInput.cpp @@ -30,7 +30,7 @@ void IMoveInput::render(float f) { } -void IMoveInput::setKey(int eventKey, bool eventKeyState) +void IMoveInput::setKey(eControlMappingIndex, bool eventKeyState) { } diff --git a/source/client/player/input/IMoveInput.hpp b/source/client/player/input/IMoveInput.hpp index bcde29324..862b1cb56 100644 --- a/source/client/player/input/IMoveInput.hpp +++ b/source/client/player/input/IMoveInput.hpp @@ -10,6 +10,8 @@ #include "compat/LegacyCPP.hpp" +#include "client/options/Options.hpp" + class Player; enum @@ -32,7 +34,7 @@ class IMoveInput virtual void releaseAllKeys(); virtual void render(float f); - virtual void setKey(int eventKey, bool eventKeyState); + virtual void setKey(eControlMappingIndex, bool eventKeyState); virtual void setScreenSize(int width, int height); virtual void tick(Player*); diff --git a/source/client/player/input/Keyboard.cpp b/source/client/player/input/Keyboard.cpp index 562003650..2fefc279b 100644 --- a/source/client/player/input/Keyboard.cpp +++ b/source/client/player/input/Keyboard.cpp @@ -8,6 +8,7 @@ #include #include "Keyboard.hpp" +#include "IInputHolder.hpp" #include "GameMods.hpp" @@ -22,6 +23,8 @@ void Keyboard::feed(KeyState state, int key) return; } + IInputHolder::activeType = IInputHolder::KEYBOARD; + _inputs.push_back(KeyboardAction(key, state)); _states[key] = state; @@ -30,7 +33,10 @@ void Keyboard::feed(KeyState state, int key) bool Keyboard::next() { if ((size_t)_index + 1 >= _inputs.size()) + { + if (!_inputs.empty()) reset(); return false; + } _index++; return true; diff --git a/source/client/player/input/KeyboardInput.cpp b/source/client/player/input/KeyboardInput.cpp index 739a8106f..5d6343ac6 100644 --- a/source/client/player/input/KeyboardInput.cpp +++ b/source/client/player/input/KeyboardInput.cpp @@ -29,19 +29,33 @@ void KeyboardInput::releaseAllKeys() m_keys[i] = false; } -void KeyboardInput::setKey(int eventKey, bool eventKeyState) +void KeyboardInput::setKey(eControlMappingIndex ctrl, bool eventKeyState) { - int index = -1; - - if (m_pOptions->getKey(KM_FORWARD) == eventKey) index = INPUT_FORWARD; - else if (m_pOptions->getKey(KM_BACKWARD) == eventKey) index = INPUT_BACKWARD; - else if (m_pOptions->getKey(KM_LEFT) == eventKey) index = INPUT_LEFT; - else if (m_pOptions->getKey(KM_RIGHT) == eventKey) index = INPUT_RIGHT; - else if (m_pOptions->getKey(KM_JUMP) == eventKey) index = INPUT_JUMP; - else if (m_pOptions->getKey(KM_SNEAK) == eventKey) index = INPUT_SNEAK; - - if (index == -1) + int index; + switch (ctrl) + { + case KM_FORWARD: + index = INPUT_FORWARD; + break; + case KM_BACKWARD: + index = INPUT_BACKWARD; + break; + case KM_LEFT: + index = INPUT_LEFT; + break; + case KM_RIGHT: + index = INPUT_RIGHT; + break; + case KM_JUMP: + index = INPUT_JUMP; + break; + case KM_SNEAK: + index = INPUT_SNEAK; + break; + default: + index = -1; return; + } m_keys[index] = eventKeyState; } diff --git a/source/client/player/input/KeyboardInput.hpp b/source/client/player/input/KeyboardInput.hpp index 156af6b70..ae09499a4 100644 --- a/source/client/player/input/KeyboardInput.hpp +++ b/source/client/player/input/KeyboardInput.hpp @@ -20,7 +20,7 @@ class KeyboardInput : public IMoveInput KeyboardInput(Options*); void releaseAllKeys() override; - void setKey(int eventKey, bool eventKeyState) override; + void setKey(eControlMappingIndex, bool eventKeyState) override; void tick(Player*) override; public: diff --git a/source/client/player/input/MouseDevice.cpp b/source/client/player/input/MouseDevice.cpp index 393f7f214..450e451e6 100644 --- a/source/client/player/input/MouseDevice.cpp +++ b/source/client/player/input/MouseDevice.cpp @@ -8,6 +8,7 @@ #include #include "MouseDevice.hpp" +#include "IInputHolder.hpp" MouseDevice::MouseDevice() { @@ -24,7 +25,10 @@ MouseDevice::MouseDevice() void MouseDevice::feed(MouseButtonType buttonType, bool buttonState, int posX, int posY) { if (buttonType != MOUSE_BUTTON_NONE) + { _inputs.push_back(MouseAction(buttonType, buttonState, posX, posY, 0)); + IInputHolder::activeType = IInputHolder::MOUSE; + } // Make sure button type is valid if (buttonType < MOUSE_BUTTON_COUNT) @@ -53,7 +57,10 @@ short MouseDevice::getY() bool MouseDevice::next() { if ((size_t)_index + 1 >= _inputs.size()) + { + if (!_inputs.empty()) reset(); return false; + } _index++; return true; diff --git a/source/client/player/input/Multitouch.cpp b/source/client/player/input/Multitouch.cpp index 3ba22d8d3..81dd970e9 100644 --- a/source/client/player/input/Multitouch.cpp +++ b/source/client/player/input/Multitouch.cpp @@ -8,6 +8,7 @@ #include #include "Multitouch.hpp" +#include "IInputHolder.hpp" int Multitouch::_activePointerCount; int Multitouch::_activePointerList[MAX_TOUCHES]; @@ -50,6 +51,7 @@ void Multitouch::feed(MouseButtonType a1, bool a2, int a3, int a4, int fingerId) MouseDevice* pDevice = g(fingerId); pDevice->feed(a1, a2, a3, a4); + IInputHolder::activeType = IInputHolder::TOUCHSCREEN; if (a1 != MOUSE_BUTTON_NONE) { diff --git a/source/client/player/input/TouchInputHolder.cpp b/source/client/player/input/TouchInputHolder.cpp index 95f7873fe..06709abd8 100644 --- a/source/client/player/input/TouchInputHolder.cpp +++ b/source/client/player/input/TouchInputHolder.cpp @@ -39,6 +39,11 @@ bool TouchInputHolder::allowPicking() return false; } +bool TouchInputHolder::allowsType(Type type) const +{ + return type == TOUCHSCREEN; +} + IMoveInput* TouchInputHolder::getMoveInput() { return &m_touchScreenInput; diff --git a/source/client/player/input/TouchInputHolder.hpp b/source/client/player/input/TouchInputHolder.hpp index 36ba4944d..f3c383497 100644 --- a/source/client/player/input/TouchInputHolder.hpp +++ b/source/client/player/input/TouchInputHolder.hpp @@ -20,6 +20,7 @@ class TouchInputHolder : public IInputHolder public: TouchInputHolder(Minecraft*, Options*); bool allowPicking() override; + bool allowsType(Type) const override; IMoveInput* getMoveInput() override; ITurnInput* getTurnInput() override; IBuildInput* getBuildInput() override; diff --git a/source/client/player/input/TouchscreenInput_TestFps.cpp b/source/client/player/input/TouchscreenInput_TestFps.cpp index af67bd4f8..38f2d7bf7 100644 --- a/source/client/player/input/TouchscreenInput_TestFps.cpp +++ b/source/client/player/input/TouchscreenInput_TestFps.cpp @@ -48,7 +48,7 @@ void TouchscreenInput_TestFps::releaseAllKeys() field_6C[i] = false; } -void TouchscreenInput_TestFps::setKey(int eventKey, bool eventKeyState) +void TouchscreenInput_TestFps::setKey(eControlMappingIndex, bool eventKeyState) { } diff --git a/source/client/player/input/TouchscreenInput_TestFps.hpp b/source/client/player/input/TouchscreenInput_TestFps.hpp index 25ac08599..d19f93a98 100644 --- a/source/client/player/input/TouchscreenInput_TestFps.hpp +++ b/source/client/player/input/TouchscreenInput_TestFps.hpp @@ -24,7 +24,7 @@ class TouchscreenInput_TestFps : public IMoveInput, public GuiComponent // IMoveInput void releaseAllKeys() override; - void setKey(int eventKey, bool eventKeyState) override; + void setKey(eControlMappingIndex, bool eventKeyState) override; void setScreenSize(int width, int height) override; void tick(Player*) override; void render(float f) override; diff --git a/source/client/renderer/Font.cpp b/source/client/renderer/Font.cpp index 6ec81196f..da91b56bb 100644 --- a/source/client/renderer/Font.cpp +++ b/source/client/renderer/Font.cpp @@ -8,7 +8,6 @@ #include "Font.hpp" #include "client/renderer/renderer/RenderMaterialGroup.hpp" -#include "client/renderer/renderer/Tesselator.hpp" #include "renderer/ShaderConstants.hpp" #include "renderer/MatrixStack.hpp" #include @@ -64,6 +63,10 @@ void Font::init(Options* pOpts) m_charWidthInt[i] = widthMax + 2; m_charWidthFloat[i] = float (widthMax) + 2; + Tesselator& t = Tesselator::instance; + t.begin(4); + buildChar(i, 0, 0); + m_charMeshes[i] = t.end(); } } @@ -165,7 +168,49 @@ void Font::drawWordWrap(const std::vector& lines, int x, int y, con void Font::draw(const std::string& str, int x, int y, const Color& color, bool bShadow) { - drawSlow(str, x, y, color, bShadow); + if (str.empty()) return; + + if (bShadow) + { + currentShaderDarkColor = Color(0.25f, 0.25f, 0.25f); + } + else + { + currentShaderDarkColor = Color::WHITE; + } + + m_pTextures->loadAndBindTexture(m_fileName); + + Color finalColor = color; + // For hex colors which don't specify an alpha + if (finalColor.a == 0.0f) + finalColor.a = 1.0f; + + MatrixStack::Ref mtx = MatrixStack::World.push(); + mtx->translate(Vec3(x, y, 0.0f)); + + currentShaderColor = finalColor; + float xOff = 0.0f; + + for (size_t i = 0; i < str.size(); i++) + { + if (str[i] == '\n') + { + mtx->translate(Vec3(0.0f, 12.0f, 0.0f)); + xOff = 0.0f; + continue; + } + + uint8_t x = uint8_t(str[i]); + + MatrixStack::Ref xmtx = MatrixStack::World.push(); + xmtx->translate(Vec3(xOff, 0.0f, 0.0f)); + m_charMeshes[x].render(m_materials.ui_text); + + xOff += m_charWidthFloat[x]; + } + + currentShaderColor = Color::WHITE; } void Font::drawSlow(const std::string& str, int x, int y, const Color& color, bool bShadow) @@ -188,18 +233,13 @@ void Font::drawSlow(const std::string& str, int x, int y, const Color& color, bo if (finalColor.a == 0.0f) finalColor.a = 1.0f; -#ifndef FEATURE_GFX_SHADERS - finalColor *= currentShaderDarkColor; -#endif - MatrixStack::Ref mtx = MatrixStack::World.push(); mtx->translate(Vec3(x, y, 0.0f)); + currentShaderColor = finalColor; Tesselator& t = Tesselator::instance; t.begin(4 * str.size()); - t.color(finalColor); - float cXPos = 0.0f, cYPos = 0.0f; for (size_t i = 0; i < str.size(); i++) @@ -219,6 +259,8 @@ void Font::drawSlow(const std::string& str, int x, int y, const Color& color, bo } t.draw(m_materials.ui_text); + + currentShaderColor = Color::WHITE; } void Font::onGraphicsReset() diff --git a/source/client/renderer/Font.hpp b/source/client/renderer/Font.hpp index 92020c250..49cc1303b 100644 --- a/source/client/renderer/Font.hpp +++ b/source/client/renderer/Font.hpp @@ -11,6 +11,7 @@ #include "Textures.hpp" #include "client/options/Options.hpp" #include "renderer/MaterialPtr.hpp" +#include "client/renderer/renderer/Tesselator.hpp" class Font { @@ -49,6 +50,7 @@ class Font int field_0; int m_charWidthInt[256]; float m_charWidthFloat[256]; + mce::Mesh m_charMeshes[256]; // huge gap, don't know why it's there... std::string m_fileName; Options* m_pOptions; diff --git a/source/client/renderer/GameRenderer.cpp b/source/client/renderer/GameRenderer.cpp index d71fd3d4e..96d8b0280 100644 --- a/source/client/renderer/GameRenderer.cpp +++ b/source/client/renderer/GameRenderer.cpp @@ -657,7 +657,7 @@ void GameRenderer::render(const Timer& timer) { if (m_pMinecraft->m_pScreen) { - m_pMinecraft->m_pScreen->controllerEvent(1, timer.m_deltaTime); + m_pMinecraft->m_pScreen->controllerStickEvent(1, timer.m_deltaTime); } } else diff --git a/source/common/utility/HashMap.hpp b/source/common/utility/HashMap.hpp new file mode 100644 index 000000000..9759033f6 --- /dev/null +++ b/source/common/utility/HashMap.hpp @@ -0,0 +1,413 @@ +#pragma once + +#include +#include +#include +#include + +template +struct HashMapEntry +{ + TKey key; + TValue value; + bool bOccupied; + bool bDeleted; + + HashMapEntry() : bOccupied(false), bDeleted(false) {} +}; + +template +struct HashFunction +{ + size_t operator()(const TKey& key) const; +}; + +template<> +struct HashFunction +{ + size_t operator()(const int8_t& key) const { return key; } +}; + +template<> +struct HashFunction +{ + size_t operator()(const uint8_t& key) const { return key; } +}; + +template<> +struct HashFunction +{ + size_t operator()(const int16_t& key) const { return key; } +}; + +template<> +struct HashFunction +{ + size_t operator()(const uint16_t& key) const { return key; } +}; + +template<> +struct HashFunction +{ + size_t operator()(const int32_t& key) const { return key; } +}; + +template<> +struct HashFunction +{ + size_t operator()(const uint32_t& key) const { return key; } +}; + +template<> +struct HashFunction +{ + size_t operator()(const int64_t& key) const { return key; } +}; + +template<> +struct HashFunction +{ + size_t operator()(const uint64_t& key) const { return key; } +}; + +template<> +struct HashFunction +{ + size_t operator()(const std::string& key) const + { + size_t hash = 5381; + for (size_t i = 0; i < key.length(); i++) + hash = ((hash << 5) + hash) + key[i]; + return hash; + } +}; + +template<> +struct HashFunction +{ + size_t operator()(const char* key) const + { + size_t hash = 5381; + while (*key) + hash = ((hash << 5) + hash) + size_t(*key++); + return hash; + } +}; + +template > +class HashMap +{ +private: + size_t _findSlot(const TKey& key) const + { + size_t hash = m_HashFunc(key); + size_t slot = hash % capacity(); + size_t originalSlot = slot; + + while (m_entries[slot].bOccupied) + { + if (!m_entries[slot].bDeleted && _keysEqual(m_entries[slot].key, key)) + return slot; + + slot = (slot + 1) % capacity(); + + if (slot == originalSlot) + break; + } + + return capacity(); + } + + size_t _findSlotForInsert(const TKey& key) const + { + size_t hash = m_HashFunc(key); + size_t slot = hash % capacity(); + size_t firstDeleted = capacity(); + size_t originalSlot = slot; + + while (m_entries[slot].bOccupied) + { + if (m_entries[slot].bDeleted) + { + if (firstDeleted == capacity()) + firstDeleted = slot; + } + else if (_keysEqual(m_entries[slot].key, key)) + { + return slot; + } + + slot = (slot + 1) % capacity(); + + if (slot == originalSlot) + break; + } + + if (firstDeleted != capacity()) + return firstDeleted; + + return slot; + } + + void _resize(size_t newCapacity) + { + std::vector> oldEntries = m_entries; + + m_entries.clear(); + m_entries.resize(newCapacity); + m_size = 0; + + for (size_t i = 0; i < oldEntries.size(); i++) + { + if (oldEntries[i].bOccupied && !oldEntries[i].bDeleted) + insert(oldEntries[i].key, oldEntries[i].value); + } + } + + bool _keysEqual(const TKey& a, const TKey& b) const { return a == b; } + +public: + HashMap() : m_size(0) + { + _resize(DEFAULT_CAPACITY); + } + + HashMap(size_t initialCapacity) : + m_size(0) + { + _resize(initialCapacity); + } + + bool insert(const TKey& key, const TValue& value) + { + if ((m_size * 100) / capacity() >= MAX_LOAD_FACTOR_PERCENT) + _resize(capacity() * 2); + + size_t slot = _findSlotForInsert(key); + + if (m_entries[slot].bOccupied && !m_entries[slot].bDeleted) + { + m_entries[slot].value = value; + return false; + } + + m_entries[slot].key = key; + m_entries[slot].value = value; + m_entries[slot].bOccupied = true; + m_entries[slot].bDeleted = false; + m_size++; + + return true; + } + + bool remove(const TKey& key) + { + return erase(find(key)) != end(); + } + + TValue* get(const TKey& key) + { + if (m_size == 0) + return nullptr; + + size_t slot = _findSlot(key); + + if (slot == capacity()) + return nullptr; + + return &m_entries[slot].value; + } + + const TValue* get(const TKey& key) const + { + if (m_size == 0) + return nullptr; + + size_t slot = _findSlot(key); + + if (slot == capacity()) + return nullptr; + + return &m_entries[slot].value; + } + + TValue& operator[](const TKey& key) + { + TValue* pValue = get(key); + if (pValue) + return *pValue; + + insert(key, TValue()); + return *get(key); + } + + void clear() + { + for (size_t i = 0; i < capacity(); ++i) + { + m_entries[i] = HashMapEntry(); + } + m_size = 0; + } + + size_t size() const { return m_size; } + size_t capacity() const { return m_entries.size(); } + bool empty() const { return m_size == 0; } + + class Iterator + { + private: + void _findNextOccupied() + { + while (m_index < m_entries->size() && (!m_entries->at(m_index).bOccupied || m_entries->at(m_index).bDeleted)) + m_index++; + } + + public: + Iterator(std::vector>* entries, size_t index) : + m_entries(entries), + m_index(index) + { + if (m_index < m_entries->size() && (!m_entries->at(m_index).bOccupied || m_entries->at(m_index).bDeleted)) + _findNextOccupied(); + } + + Iterator& operator++() + { + m_index++; + _findNextOccupied(); + return *this; + } + + Iterator operator++(int) + { + Iterator it = *this; + ++(*this); + return it; + } + + bool operator==(const Iterator& other) const { return m_entries == other.m_entries && m_index == other.m_index; } + bool operator!=(const Iterator& other) const { return !(*this == other); } + + TKey& key() { return m_entries->at(m_index).key; } + TValue& value() { return m_entries->at(m_index).value; } + + private: + std::vector>* m_entries; + size_t m_index; + + friend class HashMap; + }; + + Iterator find(const TKey& key) + { + if (m_size == 0) + return end(); + + size_t slot = _findSlot(key); + + if (slot == capacity()) + return end(); + + return Iterator(&m_entries, slot); + } + + Iterator begin() { return Iterator(&m_entries, 0); } + Iterator end() { return Iterator(&m_entries, capacity()); } + + Iterator erase(Iterator it) + { + if (it == end()) + return it; + + size_t slot = it.m_index; + if (slot < capacity() && + m_entries[slot].bOccupied && + !m_entries[slot].bDeleted) + { + m_entries[slot] = HashMapEntry(); + m_entries[slot].bOccupied = true; + m_entries[slot].bDeleted = true; + m_size--; + } + + return ++it; + } + + Iterator erase(Iterator first, Iterator last) + { + while (first != last) + first = erase(first); + + return first; + } + + class ConstIterator + { + private: + void _findNextOccupied() + { + while (m_index < m_entries->size() && (!m_entries->at(m_index).bOccupied || m_entries->at(m_index).bDeleted)) + m_index++; + } + + public: + ConstIterator(const std::vector>* entries, size_t index) : + m_entries(entries), + m_index(index) + { + if (m_index < entries->size() && (!m_entries->at(m_index).bOccupied || m_entries->at(m_index).bDeleted)) + _findNextOccupied(); + } + + ConstIterator& operator++() + { + m_index++; + _findNextOccupied(); + return *this; + } + + ConstIterator operator++(int) + { + ConstIterator it = *this; + ++(*this); + return it; + } + + bool operator==(const ConstIterator& other) const { return m_entries == other.m_entries && m_index == other.m_index; } + bool operator!=(const ConstIterator& other) const { return !(*this == other); } + + const TKey& key() { return m_entries->at(m_index).key; } + const TValue& value() { return m_entries->at(m_index).value; } + + private: + const std::vector>* m_entries; + size_t m_index; + + friend class HashMap; + }; + + ConstIterator find(const TKey& key) const + { + if (m_size == 0) + return end(); + + size_t slot = _findSlot(key); + + if (slot == capacity()) + return end(); + + return ConstIterator(&m_entries, slot); + } + + ConstIterator begin() const { return ConstIterator(&m_entries, 0); } + ConstIterator end() const { return ConstIterator(&m_entries, capacity()); } + +private: + std::vector> m_entries; + size_t m_size; + THash m_HashFunc; + + static const size_t DEFAULT_CAPACITY = 16; + static const size_t MAX_LOAD_FACTOR_PERCENT = 75; +}; \ No newline at end of file diff --git a/source/nbt/CompoundTag.cpp b/source/nbt/CompoundTag.cpp index 398ae945b..970e94bcb 100644 --- a/source/nbt/CompoundTag.cpp +++ b/source/nbt/CompoundTag.cpp @@ -3,6 +3,7 @@ #include "CompoundTag.hpp" #include "common/Util.hpp" +#include "common/Logger.hpp" CompoundTag::CompoundTag() { @@ -11,9 +12,9 @@ CompoundTag::CompoundTag() void CompoundTag::write(IDataOutput& dos) const { - for (std::map::const_iterator it = m_tags.begin(); it != m_tags.end(); it++) + for (NamedTagMap::ConstIterator it = m_tags.begin(); it != m_tags.end(); it++) { - writeNamedTag(it->first, *it->second, dos); + writeNamedTag(it.key(), *it.value(), dos); } dos.writeInt8(TAG_TYPE_END); @@ -144,15 +145,15 @@ bool CompoundTag::contains(const std::string& name, Tag::Type type) const const Tag* CompoundTag::get(const std::string& name) const { - std::map::const_iterator it = m_tags.find(name); - if (it != m_tags.end()) return it->second; + NamedTagMap::ConstIterator it = m_tags.find(name); + if (it != m_tags.end()) return it.value(); return nullptr; } Tag* CompoundTag::get(const std::string& name) { - std::map::iterator it = m_tags.find(name); - if (it != m_tags.end()) return it->second; + NamedTagMap::Iterator it = m_tags.find(name); + if (it != m_tags.end()) return it.value(); return nullptr; } @@ -298,9 +299,9 @@ CompoundTag* CompoundTag::uniqueClone() const { CompoundTag* newTag = new CompoundTag(); - for (NamedTagMap::const_iterator it = m_tags.begin(); it != m_tags.end(); it++) + for (NamedTagMap::ConstIterator it = m_tags.begin(); it != m_tags.end(); it++) { - newTag->put(it->first, it->second->copy()); + newTag->put(it.key(), it.value()->copy()); } return newTag; @@ -308,12 +309,12 @@ CompoundTag* CompoundTag::uniqueClone() const bool CompoundTag::remove(const std::string& name) { - std::map::iterator it = m_tags.find(name); + NamedTagMap::Iterator it = m_tags.find(name); if (it == m_tags.end()) return false; - delete it->second; - m_tags.erase(it); + delete it.value(); + m_tags.remove(name); return true; } @@ -322,9 +323,9 @@ void CompoundTag::deleteChildren() { if (!m_bLeak) { - for (std::map::iterator it = m_tags.begin(); it != m_tags.end(); it++) + for (NamedTagMap::Iterator it = m_tags.begin(); it != m_tags.end(); it++) { - Tag* tag = it->second; + Tag* tag = it.value(); tag->deleteChildren(); delete tag; } @@ -338,17 +339,13 @@ bool CompoundTag::operator==(const Tag& other) const const CompoundTag& other2 = (const CompoundTag&)(other); if (getId() == other2.getId() && m_tags.size() == other2.m_tags.size()) { - for (std::map::const_iterator it = m_tags.begin(); it != m_tags.end(); it++) + for (NamedTagMap::ConstIterator it = m_tags.begin(); it != m_tags.end(); it++) { - std::pair pair = *it, pair2; - std::map::const_iterator it2 = other2.m_tags.find(pair.first); + NamedTagMap::ConstIterator it2 = other2.m_tags.find(it.key()); if (it2 == other2.m_tags.end()) return false; // Failed to find tag in other by name - pair2 = *it2; - Tag *tag = pair.second, *tag2 = pair2.second; - - if (tag != tag2) + if (it.value() != it2.value()) return false; } diff --git a/source/nbt/CompoundTag.hpp b/source/nbt/CompoundTag.hpp index 4ed865255..6b02c3165 100644 --- a/source/nbt/CompoundTag.hpp +++ b/source/nbt/CompoundTag.hpp @@ -14,11 +14,12 @@ #include "StringTag.hpp" #include "FloatTag.hpp" #include "DoubleTag.hpp" +#include "common/utility/HashMap.hpp" class CompoundTag : public Tag { public: - typedef std::map NamedTagMap; + typedef HashMap NamedTagMap; public: CompoundTag(); diff --git a/source/world/entity/Arrow.hpp b/source/world/entity/Arrow.hpp index 5a08fc1da..83b90f6ad 100644 --- a/source/world/entity/Arrow.hpp +++ b/source/world/entity/Arrow.hpp @@ -21,7 +21,7 @@ class Arrow : public Entity public: void shoot(float x, float y, float z, float speed, float r) { shoot(Vec3(x, y, z), speed, r); }; - void shoot(Vec3 pos, float speed, float r); + void shoot(Vec3, float speed, float r); void lerpMotion(float x, float y, float z) { lerpMotion(Vec3(x, y, z)); }; void lerpMotion(const Vec3& vel) override; diff --git a/source/world/entity/Skeleton.cpp b/source/world/entity/Skeleton.cpp index 84ce64d2d..5858a3eea 100644 --- a/source/world/entity/Skeleton.cpp +++ b/source/world/entity/Skeleton.cpp @@ -33,7 +33,7 @@ void Skeleton::checkHurtTarget(Entity* ent, float f) { Arrow* arrow = new Arrow(m_pLevel, this); arrow->m_pos.y += 1; - float var8 = ent->m_pos.y - 0.2f - arrow->m_pos.y; + float var8 = ent->m_pos.y + ent->getHeadHeight() - 0.2f - arrow->m_pos.y; float var10 = Mth::sqrt(delta_x * delta_x + delta_z * delta_z) * 0.2f; m_pLevel->playSound(this, "random.bow", 1.0f, 1.0f / (m_random.nextFloat() * 0.4f + 0.8f)); m_pLevel->addEntity(arrow); diff --git a/source/world/inventory/ContainerMenu.cpp b/source/world/inventory/ContainerMenu.cpp index 8c083c908..78efea533 100644 --- a/source/world/inventory/ContainerMenu.cpp +++ b/source/world/inventory/ContainerMenu.cpp @@ -258,7 +258,9 @@ ItemStack ContainerMenu::clicked(int slotIndex, MouseButtonType mouseButton, boo { if (carried.m_count <= slot->getMaxStackSize()) { - std::swap(carried, slotItem); + ItemStack oldSlotItem = slotItem; + slot->set(carried); + inv->setCarried(oldSlotItem); } } else if (slotItem.getId() == carried.getId()) diff --git a/source/world/item/ItemStack.cpp b/source/world/item/ItemStack.cpp index 0ced312cf..9a8cf079f 100644 --- a/source/world/item/ItemStack.cpp +++ b/source/world/item/ItemStack.cpp @@ -158,10 +158,10 @@ CompoundTag* ItemStack::getNetworkUserData() const { CompoundTag* userData = new CompoundTag(); CompoundTag::NamedTagMap& tags = m_userData->rawView(); - for (CompoundTag::NamedTagMap::iterator it = tags.begin(); it != tags.end(); it++) + for (CompoundTag::NamedTagMap::Iterator it = tags.begin(); it != tags.end(); it++) { - const std::string& name = it->first; - const Tag* tag = it->second; + const std::string& name = it.key(); + const Tag* tag = it.value(); if (!tag) continue; if (name == TAG_REPAIR_COST) diff --git a/source/world/level/Level.cpp b/source/world/level/Level.cpp index e91a3c8f2..e64885541 100644 --- a/source/world/level/Level.cpp +++ b/source/world/level/Level.cpp @@ -322,10 +322,10 @@ Entity* Level::getEntity(Entity::ID id) const unsigned int Level::getEntityCount(const EntityCategories& category) const { EntityCategories::CategoriesMask mask = category.getCategoryMask(); - std::map::const_iterator it = m_entityCountsByCategory.find(mask); + HashMap::ConstIterator it = m_entityCountsByCategory.find(mask); if (it == m_entityCountsByCategory.end()) return 0; - return it->second; + return it.value(); } const EntityVector* Level::getAllEntities() const diff --git a/source/world/level/Level.hpp b/source/world/level/Level.hpp index 993830cf6..998e28748 100644 --- a/source/world/level/Level.hpp +++ b/source/world/level/Level.hpp @@ -9,12 +9,12 @@ #pragma once #include -#include #ifndef _USE_MATH_DEFINES #define _USE_MATH_DEFINES #endif #include +#include "common/utility/HashMap.hpp" #include "client/renderer/LightUpdate.hpp" #include "world/tile/Tile.hpp" #include "world/entity/Entity.hpp" @@ -236,6 +236,6 @@ class Level : public LevelSource PathFinder* m_pPathFinder; MobSpawner* m_pMobSpawner; - std::map m_entityCountsByCategory; + HashMap m_entityCountsByCategory; }; From a6ecfee0990776458c4cb193760f8a6d3b9cb2d4 Mon Sep 17 00:00:00 2001 From: Wilyicaro Date: Tue, 24 Feb 2026 04:17:54 -0300 Subject: [PATCH 02/11] ugly. --- source/common/utility/HashMap.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/common/utility/HashMap.hpp b/source/common/utility/HashMap.hpp index 9759033f6..fe18f1235 100644 --- a/source/common/utility/HashMap.hpp +++ b/source/common/utility/HashMap.hpp @@ -151,7 +151,7 @@ class HashMap void _resize(size_t newCapacity) { - std::vector> oldEntries = m_entries; + std::vector > oldEntries = m_entries; m_entries.clear(); m_entries.resize(newCapacity); @@ -264,7 +264,7 @@ class HashMap } public: - Iterator(std::vector>* entries, size_t index) : + Iterator(std::vector >* entries, size_t index) : m_entries(entries), m_index(index) { @@ -293,7 +293,7 @@ class HashMap TValue& value() { return m_entries->at(m_index).value; } private: - std::vector>* m_entries; + std::vector >* m_entries; size_t m_index; friend class HashMap; @@ -352,7 +352,7 @@ class HashMap } public: - ConstIterator(const std::vector>* entries, size_t index) : + ConstIterator(const std::vector >* entries, size_t index) : m_entries(entries), m_index(index) { @@ -381,7 +381,7 @@ class HashMap const TValue& value() { return m_entries->at(m_index).value; } private: - const std::vector>* m_entries; + const std::vector >* m_entries; size_t m_index; friend class HashMap; @@ -404,7 +404,7 @@ class HashMap ConstIterator end() const { return ConstIterator(&m_entries, capacity()); } private: - std::vector> m_entries; + std::vector > m_entries; size_t m_size; THash m_HashFunc; From d9ae022daa52f85f1b96690c5f4e5fc09fa8774b Mon Sep 17 00:00:00 2001 From: Wilyicaro Date: Tue, 24 Feb 2026 04:20:58 -0300 Subject: [PATCH 03/11] removed nullptr usage from HashMap --- source/common/utility/HashMap.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/common/utility/HashMap.hpp b/source/common/utility/HashMap.hpp index fe18f1235..6788d7790 100644 --- a/source/common/utility/HashMap.hpp +++ b/source/common/utility/HashMap.hpp @@ -208,12 +208,12 @@ class HashMap TValue* get(const TKey& key) { if (m_size == 0) - return nullptr; + return NULL; size_t slot = _findSlot(key); if (slot == capacity()) - return nullptr; + return NULL; return &m_entries[slot].value; } @@ -221,12 +221,12 @@ class HashMap const TValue* get(const TKey& key) const { if (m_size == 0) - return nullptr; + return NULL; size_t slot = _findSlot(key); if (slot == capacity()) - return nullptr; + return NULL; return &m_entries[slot].value; } From cf76139a8bb12382f1cfebf264361ace72a3dd1c Mon Sep 17 00:00:00 2001 From: Wilyicaro Date: Tue, 24 Feb 2026 18:25:27 -0300 Subject: [PATCH 04/11] -Now, HashMap has the same general interface semantics as `std::map` -Fixed tickbox translucency not working right anymore --- GameMods.hpp | 1 - .../xinput/GameControllerHandler_xinput.cpp | 2 +- platforms/sdl/base/AppPlatform_sdl.cpp | 70 ++++++---------- platforms/sdl/base/AppPlatform_sdl.hpp | 1 - source/client/app/Minecraft.cpp | 16 ++-- source/client/gui/Screen.cpp | 10 ++- source/client/gui/Screen.hpp | 11 ++- source/client/gui/components/TickBox.cpp | 11 +-- source/client/gui/screens/OptionsScreen.cpp | 10 --- source/client/gui/screens/OptionsScreen.hpp | 1 - .../gui/screens/OptionsScreen_Console.cpp | 6 +- .../gui/screens/OptionsScreen_Console.hpp | 2 +- .../gui/screens/PanelScreen_Console.cpp | 1 + source/client/gui/screens/PauseScreen.cpp | 6 +- source/client/gui/screens/PauseScreen.hpp | 2 +- .../gui/screens/PauseScreen_Console.cpp | 7 +- .../gui/screens/PauseScreen_Console.hpp | 2 +- source/client/gui/screens/StartMenuScreen.cpp | 6 +- source/client/gui/screens/StartMenuScreen.hpp | 2 +- .../gui/screens/StartMenuScreen_Console.cpp | 7 +- .../gui/screens/StartMenuScreen_Console.hpp | 2 +- .../gui/screens/inventory/ContainerScreen.cpp | 2 +- source/client/options/Options.cpp | 6 +- source/client/options/Options.hpp | 5 +- .../player/input/GameControllerManager.cpp | 4 +- source/client/player/input/KeyboardInput.cpp | 28 ++----- source/client/renderer/Font.cpp | 2 +- source/client/renderer/Font.hpp | 8 +- source/common/utility/HashMap.hpp | 81 ++++++++++--------- source/nbt/CompoundTag.cpp | 16 ++-- source/world/item/ItemStack.cpp | 2 +- source/world/level/Level.cpp | 2 +- 32 files changed, 147 insertions(+), 185 deletions(-) diff --git a/GameMods.hpp b/GameMods.hpp index f3b2234c9..af788fb83 100644 --- a/GameMods.hpp +++ b/GameMods.hpp @@ -39,7 +39,6 @@ #define ENH_USE_OWN_AO // Use own ambient occlusion engine - looks pretty much the same except it fixes the corners #define ENH_ADD_OPTIONS_PAUSE // Add an 'options' button in the pause menu #define ENH_ALLOW_SAND_GRAVITY // Allow sand to fall. -#define ENH_USE_GUI_SCALE_2 // Use a 2x GUI scale instead of 3x. Looks better on PC #define ENH_ALLOW_SCROLL_WHEEL // Allow use of the scroll wheel to change selected inventory slots #define ENH_3D_INVENTORY_TILES // Uses 3D rendered inventory tiles, use with ENH_SHADE_HELD_TILES to render correctly. #define ENH_MENU_BACKGROUND // Renders a spinning panorama (if it's available) in the background of the main menu diff --git a/platforms/input/xinput/GameControllerHandler_xinput.cpp b/platforms/input/xinput/GameControllerHandler_xinput.cpp index 8cc544280..ea7eb7e87 100644 --- a/platforms/input/xinput/GameControllerHandler_xinput.cpp +++ b/platforms/input/xinput/GameControllerHandler_xinput.cpp @@ -89,7 +89,7 @@ void GameControllerHandler_xinput::refresh() { XINPUT_STATE& inputState = m_inputStates.m_inputState[id]; bool joinGameAlreadyFired = false; - for (ButtonIDMap::Iterator it = m_buttonIdMap.begin(); it != m_buttonIdMap.end(); it++) + for (ButtonIDMap::iterator it = m_buttonIdMap.begin(); it != m_buttonIdMap.end(); it++) { _processButton(id, inputState, it.key(), it.value(), joinGameAlreadyFired); } diff --git a/platforms/sdl/base/AppPlatform_sdl.cpp b/platforms/sdl/base/AppPlatform_sdl.cpp index 3f586caae..43ffbd19a 100644 --- a/platforms/sdl/base/AppPlatform_sdl.cpp +++ b/platforms/sdl/base/AppPlatform_sdl.cpp @@ -312,7 +312,7 @@ void AppPlatform_sdl::handleKeyEvent(const SDL_Event& event) void AppPlatform_sdl::handleControllerButtonEvent(SDL_JoystickID controllerIndex, uint8_t button, uint8_t state) { // Normal Key Press - GameControllerManager::feedButton(state == SDL_PRESSED ? GameController::BTN_STATE_DOWN : GameController::BTN_STATE_UP, GetEngineButton(button)); + GameControllerManager::feedButton(state == SDL_PRESSED ? GameController::BTN_STATE_DOWN : GameController::BTN_STATE_UP, _getEngineButton(button)); } void AppPlatform_sdl::handleControllerAxisEvent(SDL_JoystickID controllerIndex, uint8_t axis, int16_t value) @@ -493,53 +493,31 @@ Keyboard::KeyState AppPlatform_sdl::GetKeyState(uint8_t state) } } -GameController::EngineButtonID AppPlatform_sdl::GetEngineButton(uint8_t button) +static GameController::EngineButtonID _getEngineButton(uint8_t button) { switch (button) { - case SDL_CONTROLLER_BUTTON_A: - return GameController::BUTTON_A; - case SDL_CONTROLLER_BUTTON_B: - return GameController::BUTTON_B; - case SDL_CONTROLLER_BUTTON_X: - return GameController::BUTTON_X; - case SDL_CONTROLLER_BUTTON_Y: - return GameController::BUTTON_Y; - case SDL_CONTROLLER_BUTTON_DPAD_UP: - return GameController::BUTTON_DPAD_UP; - case SDL_CONTROLLER_BUTTON_DPAD_DOWN: - return GameController::BUTTON_DPAD_DOWN; - case SDL_CONTROLLER_BUTTON_DPAD_LEFT: - return GameController::BUTTON_DPAD_LEFT; - case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: - return GameController::BUTTON_DPAD_RIGHT; - case SDL_CONTROLLER_BUTTON_LEFTSTICK: - return GameController::BUTTON_LEFTSTICK; - case SDL_CONTROLLER_BUTTON_RIGHTSTICK: - return GameController::BUTTON_RIGHTSTICK; - case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: - return GameController::BUTTON_LEFTSHOULDER; - case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: - return GameController::BUTTON_RIGHTSHOULDER; - case SDL_CONTROLLER_BUTTON_BACK: - return GameController::BUTTON_BACK; - case SDL_CONTROLLER_BUTTON_START: - return GameController::BUTTON_START; - case SDL_CONTROLLER_BUTTON_GUIDE: - return GameController::BUTTON_GUIDE; - case SDL_CONTROLLER_BUTTON_MISC1: - return GameController::BUTTON_MISC1; - case SDL_CONTROLLER_BUTTON_PADDLE1: - return GameController::BUTTON_PADDLE1; - case SDL_CONTROLLER_BUTTON_PADDLE2: - return GameController::BUTTON_PADDLE2; - case SDL_CONTROLLER_BUTTON_PADDLE3: - return GameController::BUTTON_PADDLE3; - case SDL_CONTROLLER_BUTTON_PADDLE4: - return GameController::BUTTON_PADDLE4; - case SDL_CONTROLLER_BUTTON_TOUCHPAD: - return GameController::BUTTON_TOUCHPAD; - default: - return GameController::BUTTON_NONE; + case SDL_CONTROLLER_BUTTON_A: return GameController::BUTTON_A; + case SDL_CONTROLLER_BUTTON_B: return GameController::BUTTON_B; + case SDL_CONTROLLER_BUTTON_X: return GameController::BUTTON_X; + case SDL_CONTROLLER_BUTTON_Y: return GameController::BUTTON_Y; + case SDL_CONTROLLER_BUTTON_DPAD_UP: return GameController::BUTTON_DPAD_UP; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: return GameController::BUTTON_DPAD_DOWN; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: return GameController::BUTTON_DPAD_LEFT; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return GameController::BUTTON_DPAD_RIGHT; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: return GameController::BUTTON_LEFTSTICK; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: return GameController::BUTTON_RIGHTSTICK; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return GameController::BUTTON_LEFTSHOULDER; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return GameController::BUTTON_RIGHTSHOULDER; + case SDL_CONTROLLER_BUTTON_BACK: return GameController::BUTTON_BACK; + case SDL_CONTROLLER_BUTTON_START: return GameController::BUTTON_START; + case SDL_CONTROLLER_BUTTON_GUIDE: return GameController::BUTTON_GUIDE; + case SDL_CONTROLLER_BUTTON_MISC1: return GameController::BUTTON_MISC1; + case SDL_CONTROLLER_BUTTON_PADDLE1: return GameController::BUTTON_PADDLE1; + case SDL_CONTROLLER_BUTTON_PADDLE2: return GameController::BUTTON_PADDLE2; + case SDL_CONTROLLER_BUTTON_PADDLE3: return GameController::BUTTON_PADDLE3; + case SDL_CONTROLLER_BUTTON_PADDLE4: return GameController::BUTTON_PADDLE4; + case SDL_CONTROLLER_BUTTON_TOUCHPAD: return GameController::BUTTON_TOUCHPAD; + default: return GameController::BUTTON_NONE; } } diff --git a/platforms/sdl/base/AppPlatform_sdl.hpp b/platforms/sdl/base/AppPlatform_sdl.hpp index 0bdf38fd9..9b6c8bfc2 100644 --- a/platforms/sdl/base/AppPlatform_sdl.hpp +++ b/platforms/sdl/base/AppPlatform_sdl.hpp @@ -73,7 +73,6 @@ class AppPlatform_sdl : public AppPlatform static MouseButtonType GetMouseButtonType(uint8_t button); static bool GetMouseButtonState(const SDL_Event& event); static Keyboard::KeyState GetKeyState(uint8_t state); - static GameController::EngineButtonID GetEngineButton(uint8_t button); protected: ImageData m_iconImage; diff --git a/source/client/app/Minecraft.cpp b/source/client/app/Minecraft.cpp index d1713f144..5c0616d83 100644 --- a/source/client/app/Minecraft.cpp +++ b/source/client/app/Minecraft.cpp @@ -286,7 +286,7 @@ void Minecraft::setScreen(Screen* pScreen) return; } - if (pScreen && (pScreen->isErrorScreen() || pScreen->isInvalid(this))) + if (pScreen && (pScreen->isErrorScreen() || !pScreen->validate(this))) { // not in original delete pScreen; @@ -571,7 +571,6 @@ void Minecraft::tickInput() while (GameControllerManager::next()) { - if (!useController()) continue; GameController::EngineButtonID button = GameControllerManager::getEventButton(); bool bPressed = GameControllerManager::getEventButtonState() == GameController::BTN_STATE_DOWN; @@ -619,7 +618,7 @@ void Minecraft::tickInput() continue; // @TODO: Replace with KeyboardBuildInput - if (!useController() && getTimeMs() - field_2B4 <= 200) + if (getTimeMs() - field_2B4 <= 200) { if (getOptions()->isKey(KM_DESTROY, keyCode) && bPressed) { @@ -897,7 +896,10 @@ void Minecraft::tick() } if (m_pScreen) + { + m_pScreen->validate(this); m_pScreen->tick(); + } Multitouch::reset(); @@ -1093,12 +1095,7 @@ float Minecraft::getBestScaleForThisScreenSize(int width, int height) else if (m_pOptions->getUiTheme() == UI_CONSOLE) return Screen::GetConsoleScale(height); -#if MC_PLATFORM_XBOX -#define USE_JAVA_SCREEN_SCALING -#endif -#ifdef USE_JAVA_SCREEN_SCALING - // @HACK: the scaling code for Java/Pocket Screens when using the Console theme is pretty broken - if (m_pOptions->getUiTheme() != UI_CONSOLE) + if (getUiTheme() == UI_JAVA) { int scale; for (scale = 1; width / (scale + 1) >= 320 && height / (scale + 1) >= 240; ++scale) @@ -1106,7 +1103,6 @@ float Minecraft::getBestScaleForThisScreenSize(int width, int height) } return 1.0f / scale; } -#endif if (height > 1800) return 1.0f / 8.0f; diff --git a/source/client/gui/Screen.cpp b/source/client/gui/Screen.cpp index 83346e7a9..6611bbab2 100644 --- a/source/client/gui/Screen.cpp +++ b/source/client/gui/Screen.cpp @@ -47,7 +47,9 @@ Screen::Screen() m_bRenderPointer = false; m_lastTimeMoved = 0; m_cursorTick = 0; - m_uiTheme = UI_GENERIC; + m_themeSelection = UI_GENERIC; + m_uiTheme = UI_POCKET; + m_bUniversalUiTheme = false; } Screen::~Screen() @@ -141,7 +143,7 @@ void Screen::init(Minecraft* pMinecraft, int width, int height) // Apply UI theme to current Screen based on user preference UITheme userTheme = pMinecraft->getOptions()->getUiTheme(); // We don't bother applying the console theme automatically for generic screens because this completely fucks scaling - if (m_uiTheme == UI_UNIVERSAL || (m_uiTheme == UI_GENERIC && userTheme != UI_CONSOLE)) + if (m_themeSelection == UI_UNIVERSAL || (m_themeSelection == UI_GENERIC && userTheme != UI_CONSOLE)) m_uiTheme = userTheme; setSize(width, height); @@ -255,9 +257,9 @@ void Screen::handleKeyboardClosed() } } -bool Screen::isInvalid(Minecraft*) +bool Screen::validate(Minecraft*) { - return false; + return true; } static const char* g_panoramaList[] = diff --git a/source/client/gui/Screen.hpp b/source/client/gui/Screen.hpp index 1f243d542..316d2d59b 100644 --- a/source/client/gui/Screen.hpp +++ b/source/client/gui/Screen.hpp @@ -124,7 +124,7 @@ class Screen : public GuiComponent static float GetConsoleScale(int height); virtual void setTextboxText(const std::string& text); virtual void handleKeyboardClosed(); - virtual bool isInvalid(Minecraft*); + virtual bool validate(Minecraft*); // ported from 0.8 virtual void renderMenuBackground(float f); @@ -153,16 +153,25 @@ class Screen : public GuiComponent Screen* m_pScreen; }; + enum ThemeSelection + { + UI_SPECIFIC, // The Screen handles a specific UI Theme + UI_GENERIC, // The Screen is a Java / Pocket mix + UI_UNIVERSAL // The Screen automatically handles all UI themes + }; + int m_width; int m_height; bool m_bPassEvents; //@NOTE: This should be enabled only if the the actual screen handles the deletion of the previous screen, otherwise, there will be a memory leak! bool m_bDeletePrevious; + bool m_bUniversalUiTheme; Minecraft* m_pMinecraft; GuiElementList m_elements; GuiElement* m_pSelectedElement; Font* m_pFont; GuiElement* m_pClickedElement; + ThemeSelection m_themeSelection; UITheme m_uiTheme; #ifndef ORIGINAL_CODE diff --git a/source/client/gui/components/TickBox.cpp b/source/client/gui/components/TickBox.cpp index 2bce1cf86..a4451515d 100644 --- a/source/client/gui/components/TickBox.cpp +++ b/source/client/gui/components/TickBox.cpp @@ -48,11 +48,9 @@ void TickBox::render(Minecraft* mc, const MenuPointer& pointer) if (!mc->m_pScreen->doElementTabbing()) setSelected(isHovered(mc, pointer)); - if (!isEnabled()) - currentShaderColor.a *= 0.5f; - Color unselectedColor = Color::TEXT_GREY; - unselectedColor.a = currentShaderColor.a; + if (!isEnabled()) + unselectedColor.a = 0.5f; mc->m_pFont->drawScalable( getMessage(), m_xPos + C_TICKBOX_SIZE + 5, @@ -64,7 +62,10 @@ void TickBox::render(Minecraft* mc, const MenuPointer& pointer) getMessage(), m_xPos + C_TICKBOX_SIZE + 4, m_yPos + m_height / 2 - 9, - Color(204, 196, 13, currentShaderColor.a)); + Color(204, 196, 13, unselectedColor.a)); + + if (!isEnabled()) + currentShaderColor.a *= 0.5f; blitSprite(*mc->m_pTextures, isSelected() ? "gui/console/Graphics/Tickbox_Over.png" : "gui/console/Graphics/Tickbox_Norm.png", m_xPos, m_yPos + (m_height - C_TICKBOX_SIZE) / 2, C_TICKBOX_SIZE, C_TICKBOX_SIZE, &m_materials.ui_textured_and_glcolor); diff --git a/source/client/gui/screens/OptionsScreen.cpp b/source/client/gui/screens/OptionsScreen.cpp index d76d3544c..2490863a9 100644 --- a/source/client/gui/screens/OptionsScreen.cpp +++ b/source/client/gui/screens/OptionsScreen.cpp @@ -164,16 +164,6 @@ void OptionsScreen::handleScrollWheel(float force) m_pList->handleScrollWheel(force); } -bool OptionsScreen::isInvalid(Minecraft* mc) -{ - if (mc->getOptions()->getUiTheme() == UI_CONSOLE) - { - mc->getScreenChooser()->pushOptionsScreen(m_pParent); - return true; - } - return false; -} - #else #include "client/renderer/PatchManager.hpp" diff --git a/source/client/gui/screens/OptionsScreen.hpp b/source/client/gui/screens/OptionsScreen.hpp index c3e4f873c..0100b20a9 100644 --- a/source/client/gui/screens/OptionsScreen.hpp +++ b/source/client/gui/screens/OptionsScreen.hpp @@ -42,7 +42,6 @@ class OptionsScreen : public Screen void _buttonClicked(Button* pButton) override; bool handleBackEvent(bool b) override; void handleScrollWheel(float force) override; - bool isInvalid(Minecraft*) override; private: void setCategory(OptionsCategory category); diff --git a/source/client/gui/screens/OptionsScreen_Console.cpp b/source/client/gui/screens/OptionsScreen_Console.cpp index 16037b173..b829f07e4 100644 --- a/source/client/gui/screens/OptionsScreen_Console.cpp +++ b/source/client/gui/screens/OptionsScreen_Console.cpp @@ -70,14 +70,14 @@ bool OptionsScreen_Console::handleBackEvent(bool b) return true; } -bool OptionsScreen_Console::isInvalid(Minecraft* mc) +bool OptionsScreen_Console::validate(Minecraft* mc) { if (mc->getOptions()->getUiTheme() != UI_CONSOLE) { mc->getScreenChooser()->pushOptionsScreen(m_pParent); - return true; + return false; } - return false; + return true; } #define HEADER(text) do { m_layout.m_elements.push_back(new OptionHeader_Console(text)); currentIndex++; } while (0) diff --git a/source/client/gui/screens/OptionsScreen_Console.hpp b/source/client/gui/screens/OptionsScreen_Console.hpp index f8733cc0f..52f4db0ee 100644 --- a/source/client/gui/screens/OptionsScreen_Console.hpp +++ b/source/client/gui/screens/OptionsScreen_Console.hpp @@ -32,7 +32,7 @@ class OptionsScreen_Console : public Screen void init() override; void render(float) override; bool handleBackEvent(bool) override; - bool isInvalid(Minecraft*) override; + bool validate(Minecraft*) override; private: Screen* m_pParent; diff --git a/source/client/gui/screens/PanelScreen_Console.cpp b/source/client/gui/screens/PanelScreen_Console.cpp index d70b231be..6be5760fc 100644 --- a/source/client/gui/screens/PanelScreen_Console.cpp +++ b/source/client/gui/screens/PanelScreen_Console.cpp @@ -6,6 +6,7 @@ PanelScreen_Console::PanelScreen_Console(Screen* parent) : m_pParent(parent) , m_layout(this) { + m_themeSelection = UI_SPECIFIC; m_uiTheme = UI_CONSOLE; m_bDeletePrevious = false; } diff --git a/source/client/gui/screens/PauseScreen.cpp b/source/client/gui/screens/PauseScreen.cpp index e18752e77..440ea537f 100644 --- a/source/client/gui/screens/PauseScreen.cpp +++ b/source/client/gui/screens/PauseScreen.cpp @@ -120,12 +120,12 @@ void PauseScreen::_buttonClicked(Button* pButton) #endif } -bool PauseScreen::isInvalid(Minecraft* mc) +bool PauseScreen::validate(Minecraft* mc) { if (mc->getOptions()->getUiTheme() == UI_CONSOLE) { mc->getScreenChooser()->pushPauseScreen(); - return true; + return false; } - return false; + return true; } diff --git a/source/client/gui/screens/PauseScreen.hpp b/source/client/gui/screens/PauseScreen.hpp index 3fade2e3a..8c69621a8 100644 --- a/source/client/gui/screens/PauseScreen.hpp +++ b/source/client/gui/screens/PauseScreen.hpp @@ -19,7 +19,7 @@ class PauseScreen : public Screen void tick() override; void render(float f) override; void _buttonClicked(Button*) override; - bool isInvalid(Minecraft*) override; + bool validate(Minecraft*) override; void updateServerVisibilityText(); diff --git a/source/client/gui/screens/PauseScreen_Console.cpp b/source/client/gui/screens/PauseScreen_Console.cpp index 641a18d4d..2e5380c1c 100644 --- a/source/client/gui/screens/PauseScreen_Console.cpp +++ b/source/client/gui/screens/PauseScreen_Console.cpp @@ -14,6 +14,7 @@ PauseScreen_Console::PauseScreen_Console() : m_btnLeaderboards.setEnabled(false); m_btnAchievements.setEnabled(false); + m_themeSelection = UI_SPECIFIC; m_uiTheme = UI_CONSOLE; } @@ -56,12 +57,12 @@ void PauseScreen_Console::_buttonClicked(Button* btn) m_pMinecraft->leaveGame(false); } -bool PauseScreen_Console::isInvalid(Minecraft* mc) +bool PauseScreen_Console::validate(Minecraft* mc) { if (mc->getOptions()->getUiTheme() != UI_CONSOLE) { mc->getScreenChooser()->pushPauseScreen(); - return true; + return false; } - return false; + return true; } diff --git a/source/client/gui/screens/PauseScreen_Console.hpp b/source/client/gui/screens/PauseScreen_Console.hpp index 05318350e..8243c5be9 100644 --- a/source/client/gui/screens/PauseScreen_Console.hpp +++ b/source/client/gui/screens/PauseScreen_Console.hpp @@ -10,7 +10,7 @@ class PauseScreen_Console : public Screen void init() override; void render(float) override; void _buttonClicked(Button*) override; - bool isInvalid(Minecraft*) override; + bool validate(Minecraft*) override; private: Button m_btnResume; diff --git a/source/client/gui/screens/StartMenuScreen.cpp b/source/client/gui/screens/StartMenuScreen.cpp index 7e7ca77a6..292a3ff9c 100644 --- a/source/client/gui/screens/StartMenuScreen.cpp +++ b/source/client/gui/screens/StartMenuScreen.cpp @@ -240,12 +240,12 @@ bool StartMenuScreen::handleBackEvent(bool b) return true; } -bool StartMenuScreen::isInvalid(Minecraft* mc) +bool StartMenuScreen::validate(Minecraft* mc) { if (mc->getOptions()->getUiTheme() == UI_CONSOLE) { mc->getScreenChooser()->pushStartScreen(); - return true; + return false; } - return false; + return true; } diff --git a/source/client/gui/screens/StartMenuScreen.hpp b/source/client/gui/screens/StartMenuScreen.hpp index abe355603..9a44c74d3 100644 --- a/source/client/gui/screens/StartMenuScreen.hpp +++ b/source/client/gui/screens/StartMenuScreen.hpp @@ -33,7 +33,7 @@ class StartMenuScreen : public Screen void drawSplash(); bool handleBackEvent(bool b) override; - bool isInvalid(Minecraft*) override; + bool validate(Minecraft*) override; protected: Button m_startButton; diff --git a/source/client/gui/screens/StartMenuScreen_Console.cpp b/source/client/gui/screens/StartMenuScreen_Console.cpp index 6961b3495..ce84afc66 100644 --- a/source/client/gui/screens/StartMenuScreen_Console.cpp +++ b/source/client/gui/screens/StartMenuScreen_Console.cpp @@ -17,6 +17,7 @@ StartMenuScreen_Console::StartMenuScreen_Console() : m_btnAchievements.setEnabled(false); m_btnDownload.setEnabled(false); + m_themeSelection = UI_SPECIFIC; m_uiTheme = UI_CONSOLE; m_splash = SplashManager::singleton().getSplash(); @@ -74,12 +75,12 @@ void StartMenuScreen_Console::_buttonClicked(Button* btn) m_pMinecraft->quit(); } -bool StartMenuScreen_Console::isInvalid(Minecraft* mc) +bool StartMenuScreen_Console::validate(Minecraft* mc) { if (mc->getOptions()->getUiTheme() != UI_CONSOLE) { mc->getScreenChooser()->pushStartScreen(); - return true; + return false; } - return false; + return true; } diff --git a/source/client/gui/screens/StartMenuScreen_Console.hpp b/source/client/gui/screens/StartMenuScreen_Console.hpp index 774f306ba..100472c68 100644 --- a/source/client/gui/screens/StartMenuScreen_Console.hpp +++ b/source/client/gui/screens/StartMenuScreen_Console.hpp @@ -10,7 +10,7 @@ class StartMenuScreen_Console : public Screen void init() override; void render(float) override; void _buttonClicked(Button*) override; - bool isInvalid(Minecraft*) override; + bool validate(Minecraft*) override; private: Button m_btnPlayGame; diff --git a/source/client/gui/screens/inventory/ContainerScreen.cpp b/source/client/gui/screens/inventory/ContainerScreen.cpp index 9713dccc6..77cde805a 100644 --- a/source/client/gui/screens/inventory/ContainerScreen.cpp +++ b/source/client/gui/screens/inventory/ContainerScreen.cpp @@ -13,7 +13,7 @@ ContainerScreen::ContainerScreen(ContainerMenu* menu) : m_topPos(0), m_timeSlotDragged(0) { - m_uiTheme = UI_UNIVERSAL; + m_themeSelection = UI_UNIVERSAL; m_bRenderPointer = true; } diff --git a/source/client/options/Options.cpp b/source/client/options/Options.cpp index 220961692..98ccf792b 100644 --- a/source/client/options/Options.cpp +++ b/source/client/options/Options.cpp @@ -152,7 +152,7 @@ void Options::_load() { std::string key = strings[i], value = strings[i + 1]; - HashMap::Iterator it = m_options.find(key); + HashMap::iterator it = m_options.find(key); if (it != m_options.end()) it.value()->load(value); else if (key == "misc_oldtitle") @@ -404,7 +404,7 @@ std::vector Options::getOptionStrings() #define SO(optname, value) do { vec.push_back(optname); vec.push_back(value); } while (0) std::stringstream ss; - for (HashMap::Iterator it = m_options.begin(); it != m_options.end(); ++it) + for (HashMap::iterator it = m_options.begin(); it != m_options.end(); ++it) { ss.str(""); it.value()->save(ss); @@ -605,7 +605,7 @@ void Options::loadControls() void Options::reset() { - for (HashMap::Iterator it = m_options.begin(); it != m_options.end(); ++it) + for (HashMap::iterator it = m_options.begin(); it != m_options.end(); ++it) { it.value()->reset(); } diff --git a/source/client/options/Options.hpp b/source/client/options/Options.hpp index 7be1de521..adeba0084 100644 --- a/source/client/options/Options.hpp +++ b/source/client/options/Options.hpp @@ -111,10 +111,7 @@ enum UITheme { UI_POCKET, UI_JAVA, - UI_CONSOLE, - - UI_GENERIC, // The Screen is a Java / Pocket mix - UI_UNIVERSAL // The Screen automatically handles all UI themes + UI_CONSOLE }; enum LogoType diff --git a/source/client/player/input/GameControllerManager.cpp b/source/client/player/input/GameControllerManager.cpp index b370fd6e0..6580508db 100644 --- a/source/client/player/input/GameControllerManager.cpp +++ b/source/client/player/input/GameControllerManager.cpp @@ -117,7 +117,7 @@ void GameControllerManager::feedStickX(GameController::StickID stickId, bool tou inReset = false; - if (x) + if (x != 0.0f) IInputHolder::activeType = IInputHolder::CONTROLLER; } @@ -140,7 +140,7 @@ void GameControllerManager::feedStickY(GameController::StickID stickId, bool tou inReset = false; - if (y) + if (y != 0.0f) IInputHolder::activeType = IInputHolder::CONTROLLER; } diff --git a/source/client/player/input/KeyboardInput.cpp b/source/client/player/input/KeyboardInput.cpp index 5d6343ac6..ff9bb2040 100644 --- a/source/client/player/input/KeyboardInput.cpp +++ b/source/client/player/input/KeyboardInput.cpp @@ -34,27 +34,13 @@ void KeyboardInput::setKey(eControlMappingIndex ctrl, bool eventKeyState) int index; switch (ctrl) { - case KM_FORWARD: - index = INPUT_FORWARD; - break; - case KM_BACKWARD: - index = INPUT_BACKWARD; - break; - case KM_LEFT: - index = INPUT_LEFT; - break; - case KM_RIGHT: - index = INPUT_RIGHT; - break; - case KM_JUMP: - index = INPUT_JUMP; - break; - case KM_SNEAK: - index = INPUT_SNEAK; - break; - default: - index = -1; - return; + case KM_FORWARD: index = INPUT_FORWARD; break; + case KM_BACKWARD: index = INPUT_BACKWARD; break; + case KM_LEFT: index = INPUT_LEFT; break; + case KM_RIGHT: index = INPUT_RIGHT; break; + case KM_JUMP: index = INPUT_JUMP; break; + case KM_SNEAK: index = INPUT_SNEAK; break; + default: index = -1; return; } m_keys[index] = eventKeyState; diff --git a/source/client/renderer/Font.cpp b/source/client/renderer/Font.cpp index da91b56bb..4712bf336 100644 --- a/source/client/renderer/Font.cpp +++ b/source/client/renderer/Font.cpp @@ -32,7 +32,7 @@ void Font::init(Options* pOpts) TextureData* pTexture = m_pTextures->getTextureData(m_fileName, true); if (!pTexture) return; - for (int i = 0; i < 256; i++) // character number + for (int i = 0; i < FONT_CHARS_AMOUNT; i++) // character number { // note: the 'widthMax' behavior is assumed. It might not be like that exactly int widthMax = 0; diff --git a/source/client/renderer/Font.hpp b/source/client/renderer/Font.hpp index 49cc1303b..7823b5233 100644 --- a/source/client/renderer/Font.hpp +++ b/source/client/renderer/Font.hpp @@ -13,6 +13,8 @@ #include "renderer/MaterialPtr.hpp" #include "client/renderer/renderer/Tesselator.hpp" +#define FONT_CHARS_AMOUNT (256) + class Font { protected: @@ -48,9 +50,9 @@ class Font private: int field_0; - int m_charWidthInt[256]; - float m_charWidthFloat[256]; - mce::Mesh m_charMeshes[256]; + int m_charWidthInt[FONT_CHARS_AMOUNT]; + float m_charWidthFloat[FONT_CHARS_AMOUNT]; + mce::Mesh m_charMeshes[FONT_CHARS_AMOUNT]; // huge gap, don't know why it's there... std::string m_fileName; Options* m_pOptions; diff --git a/source/common/utility/HashMap.hpp b/source/common/utility/HashMap.hpp index 6788d7790..b9ea7800e 100644 --- a/source/common/utility/HashMap.hpp +++ b/source/common/utility/HashMap.hpp @@ -3,13 +3,13 @@ #include #include #include +#include #include template struct HashMapEntry { - TKey key; - TValue value; + std::pair pair; bool bOccupied; bool bDeleted; @@ -106,7 +106,7 @@ class HashMap while (m_entries[slot].bOccupied) { - if (!m_entries[slot].bDeleted && _keysEqual(m_entries[slot].key, key)) + if (!m_entries[slot].bDeleted && _keysEqual(m_entries[slot].pair.first, key)) return slot; slot = (slot + 1) % capacity(); @@ -132,7 +132,7 @@ class HashMap if (firstDeleted == capacity()) firstDeleted = slot; } - else if (_keysEqual(m_entries[slot].key, key)) + else if (_keysEqual(m_entries[slot].pair.first, key)) { return slot; } @@ -160,7 +160,7 @@ class HashMap for (size_t i = 0; i < oldEntries.size(); i++) { if (oldEntries[i].bOccupied && !oldEntries[i].bDeleted) - insert(oldEntries[i].key, oldEntries[i].value); + insert(oldEntries[i].pair.first, oldEntries[i].pair.second); } } @@ -187,12 +187,12 @@ class HashMap if (m_entries[slot].bOccupied && !m_entries[slot].bDeleted) { - m_entries[slot].value = value; + m_entries[slot].pair.second = value; return false; } - m_entries[slot].key = key; - m_entries[slot].value = value; + m_entries[slot].pair.first = key; + m_entries[slot].pair.second = value; m_entries[slot].bOccupied = true; m_entries[slot].bDeleted = false; m_size++; @@ -215,7 +215,7 @@ class HashMap if (slot == capacity()) return NULL; - return &m_entries[slot].value; + return &m_entries[slot].pair.second; } const TValue* get(const TKey& key) const @@ -228,7 +228,7 @@ class HashMap if (slot == capacity()) return NULL; - return &m_entries[slot].value; + return &m_entries[slot].pair.second; } TValue& operator[](const TKey& key) @@ -254,7 +254,7 @@ class HashMap size_t capacity() const { return m_entries.size(); } bool empty() const { return m_size == 0; } - class Iterator + class iterator { private: void _findNextOccupied() @@ -264,7 +264,7 @@ class HashMap } public: - Iterator(std::vector >* entries, size_t index) : + iterator(std::vector >* entries, size_t index) : m_entries(entries), m_index(index) { @@ -272,25 +272,26 @@ class HashMap _findNextOccupied(); } - Iterator& operator++() + iterator& operator++() { m_index++; _findNextOccupied(); return *this; } - Iterator operator++(int) + iterator operator++(int) { - Iterator it = *this; + iterator it = *this; ++(*this); return it; } - bool operator==(const Iterator& other) const { return m_entries == other.m_entries && m_index == other.m_index; } - bool operator!=(const Iterator& other) const { return !(*this == other); } + bool operator==(const iterator& other) const { return m_entries == other.m_entries && m_index == other.m_index; } + bool operator!=(const iterator& other) const { return !(*this == other); } - TKey& key() { return m_entries->at(m_index).key; } - TValue& value() { return m_entries->at(m_index).value; } + TKey& key() { return m_entries->at(m_index).pair.first; } + TValue& value() { return m_entries->at(m_index).pair.second; } + std::pair* operator->() { return &m_entries->at(m_index); } private: std::vector >* m_entries; @@ -299,7 +300,7 @@ class HashMap friend class HashMap; }; - Iterator find(const TKey& key) + iterator find(const TKey& key) { if (m_size == 0) return end(); @@ -309,13 +310,13 @@ class HashMap if (slot == capacity()) return end(); - return Iterator(&m_entries, slot); + return iterator(&m_entries, slot); } - Iterator begin() { return Iterator(&m_entries, 0); } - Iterator end() { return Iterator(&m_entries, capacity()); } + iterator begin() { return iterator(&m_entries, 0); } + iterator end() { return iterator(&m_entries, capacity()); } - Iterator erase(Iterator it) + iterator erase(iterator it) { if (it == end()) return it; @@ -325,8 +326,7 @@ class HashMap m_entries[slot].bOccupied && !m_entries[slot].bDeleted) { - m_entries[slot] = HashMapEntry(); - m_entries[slot].bOccupied = true; + m_entries[slot].pair = std::pair(); m_entries[slot].bDeleted = true; m_size--; } @@ -334,7 +334,7 @@ class HashMap return ++it; } - Iterator erase(Iterator first, Iterator last) + iterator erase(iterator first, iterator last) { while (first != last) first = erase(first); @@ -342,7 +342,7 @@ class HashMap return first; } - class ConstIterator + class const_iterator { private: void _findNextOccupied() @@ -352,7 +352,7 @@ class HashMap } public: - ConstIterator(const std::vector >* entries, size_t index) : + const_iterator(const std::vector >* entries, size_t index) : m_entries(entries), m_index(index) { @@ -360,25 +360,26 @@ class HashMap _findNextOccupied(); } - ConstIterator& operator++() + const_iterator& operator++() { m_index++; _findNextOccupied(); return *this; } - ConstIterator operator++(int) + const_iterator operator++(int) { - ConstIterator it = *this; + const_iterator it = *this; ++(*this); return it; } - bool operator==(const ConstIterator& other) const { return m_entries == other.m_entries && m_index == other.m_index; } - bool operator!=(const ConstIterator& other) const { return !(*this == other); } + bool operator==(const const_iterator& other) const { return m_entries == other.m_entries && m_index == other.m_index; } + bool operator!=(const const_iterator& other) const { return !(*this == other); } - const TKey& key() { return m_entries->at(m_index).key; } - const TValue& value() { return m_entries->at(m_index).value; } + const TKey& key() { return m_entries->at(m_index).pair.first; } + const TValue& value() { return m_entries->at(m_index).pair.second; } + const std::pair* operator->() { return &m_entries->at(m_index); } private: const std::vector >* m_entries; @@ -387,7 +388,7 @@ class HashMap friend class HashMap; }; - ConstIterator find(const TKey& key) const + const_iterator find(const TKey& key) const { if (m_size == 0) return end(); @@ -397,11 +398,11 @@ class HashMap if (slot == capacity()) return end(); - return ConstIterator(&m_entries, slot); + return const_iterator(&m_entries, slot); } - ConstIterator begin() const { return ConstIterator(&m_entries, 0); } - ConstIterator end() const { return ConstIterator(&m_entries, capacity()); } + const_iterator begin() const { return const_iterator(&m_entries, 0); } + const_iterator end() const { return const_iterator(&m_entries, capacity()); } private: std::vector > m_entries; diff --git a/source/nbt/CompoundTag.cpp b/source/nbt/CompoundTag.cpp index 970e94bcb..74b50795d 100644 --- a/source/nbt/CompoundTag.cpp +++ b/source/nbt/CompoundTag.cpp @@ -12,7 +12,7 @@ CompoundTag::CompoundTag() void CompoundTag::write(IDataOutput& dos) const { - for (NamedTagMap::ConstIterator it = m_tags.begin(); it != m_tags.end(); it++) + for (NamedTagMap::const_iterator it = m_tags.begin(); it != m_tags.end(); it++) { writeNamedTag(it.key(), *it.value(), dos); } @@ -145,14 +145,14 @@ bool CompoundTag::contains(const std::string& name, Tag::Type type) const const Tag* CompoundTag::get(const std::string& name) const { - NamedTagMap::ConstIterator it = m_tags.find(name); + NamedTagMap::const_iterator it = m_tags.find(name); if (it != m_tags.end()) return it.value(); return nullptr; } Tag* CompoundTag::get(const std::string& name) { - NamedTagMap::Iterator it = m_tags.find(name); + NamedTagMap::iterator it = m_tags.find(name); if (it != m_tags.end()) return it.value(); return nullptr; } @@ -299,7 +299,7 @@ CompoundTag* CompoundTag::uniqueClone() const { CompoundTag* newTag = new CompoundTag(); - for (NamedTagMap::ConstIterator it = m_tags.begin(); it != m_tags.end(); it++) + for (NamedTagMap::const_iterator it = m_tags.begin(); it != m_tags.end(); it++) { newTag->put(it.key(), it.value()->copy()); } @@ -309,7 +309,7 @@ CompoundTag* CompoundTag::uniqueClone() const bool CompoundTag::remove(const std::string& name) { - NamedTagMap::Iterator it = m_tags.find(name); + NamedTagMap::iterator it = m_tags.find(name); if (it == m_tags.end()) return false; @@ -323,7 +323,7 @@ void CompoundTag::deleteChildren() { if (!m_bLeak) { - for (NamedTagMap::Iterator it = m_tags.begin(); it != m_tags.end(); it++) + for (NamedTagMap::iterator it = m_tags.begin(); it != m_tags.end(); it++) { Tag* tag = it.value(); tag->deleteChildren(); @@ -339,9 +339,9 @@ bool CompoundTag::operator==(const Tag& other) const const CompoundTag& other2 = (const CompoundTag&)(other); if (getId() == other2.getId() && m_tags.size() == other2.m_tags.size()) { - for (NamedTagMap::ConstIterator it = m_tags.begin(); it != m_tags.end(); it++) + for (NamedTagMap::const_iterator it = m_tags.begin(); it != m_tags.end(); it++) { - NamedTagMap::ConstIterator it2 = other2.m_tags.find(it.key()); + NamedTagMap::const_iterator it2 = other2.m_tags.find(it.key()); if (it2 == other2.m_tags.end()) return false; // Failed to find tag in other by name diff --git a/source/world/item/ItemStack.cpp b/source/world/item/ItemStack.cpp index 9a8cf079f..de3a56dd0 100644 --- a/source/world/item/ItemStack.cpp +++ b/source/world/item/ItemStack.cpp @@ -158,7 +158,7 @@ CompoundTag* ItemStack::getNetworkUserData() const { CompoundTag* userData = new CompoundTag(); CompoundTag::NamedTagMap& tags = m_userData->rawView(); - for (CompoundTag::NamedTagMap::Iterator it = tags.begin(); it != tags.end(); it++) + for (CompoundTag::NamedTagMap::iterator it = tags.begin(); it != tags.end(); it++) { const std::string& name = it.key(); const Tag* tag = it.value(); diff --git a/source/world/level/Level.cpp b/source/world/level/Level.cpp index e64885541..e68c42ece 100644 --- a/source/world/level/Level.cpp +++ b/source/world/level/Level.cpp @@ -322,7 +322,7 @@ Entity* Level::getEntity(Entity::ID id) const unsigned int Level::getEntityCount(const EntityCategories& category) const { EntityCategories::CategoriesMask mask = category.getCategoryMask(); - HashMap::ConstIterator it = m_entityCountsByCategory.find(mask); + HashMap::const_iterator it = m_entityCountsByCategory.find(mask); if (it == m_entityCountsByCategory.end()) return 0; return it.value(); From 6bcbbb7b65fddc35d10460c4ef1fab3a47bfa738 Mon Sep 17 00:00:00 2001 From: Wilyicaro Date: Tue, 24 Feb 2026 18:28:17 -0300 Subject: [PATCH 05/11] fixed pausing when the game isn't online --- source/client/app/Minecraft.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/client/app/Minecraft.cpp b/source/client/app/Minecraft.cpp index 5c0616d83..888bb09a9 100644 --- a/source/client/app/Minecraft.cpp +++ b/source/client/app/Minecraft.cpp @@ -904,7 +904,7 @@ void Minecraft::tick() Multitouch::reset(); // Actually pause the game, because fuck bedrock edition - m_bIsGamePaused = !isOnline() || (m_pLevel && m_pLevel->m_players.size() == 1 && m_pScreen && m_pScreen->isPauseScreen()); + m_bIsGamePaused = (!isOnline() || (m_pLevel && m_pLevel->m_players.size() == 1)) && (m_pScreen && m_pScreen->isPauseScreen()); } } From af832895ac480e0fedf63e16015899a21962656c Mon Sep 17 00:00:00 2001 From: Wilyicaro <81383021+Wilyicaro@users.noreply.github.com> Date: Tue, 24 Feb 2026 18:33:10 -0300 Subject: [PATCH 06/11] should work --- platforms/sdl/base/AppPlatform_sdl.cpp | 58 +++++++++++++------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/platforms/sdl/base/AppPlatform_sdl.cpp b/platforms/sdl/base/AppPlatform_sdl.cpp index 43ffbd19a..52ee56012 100644 --- a/platforms/sdl/base/AppPlatform_sdl.cpp +++ b/platforms/sdl/base/AppPlatform_sdl.cpp @@ -309,6 +309,35 @@ void AppPlatform_sdl::handleKeyEvent(const SDL_Event& event) return _handleKeyEvent(key, state); } +static GameController::EngineButtonID _getEngineButton(uint8_t button) +{ + switch (button) + { + case SDL_CONTROLLER_BUTTON_A: return GameController::BUTTON_A; + case SDL_CONTROLLER_BUTTON_B: return GameController::BUTTON_B; + case SDL_CONTROLLER_BUTTON_X: return GameController::BUTTON_X; + case SDL_CONTROLLER_BUTTON_Y: return GameController::BUTTON_Y; + case SDL_CONTROLLER_BUTTON_DPAD_UP: return GameController::BUTTON_DPAD_UP; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: return GameController::BUTTON_DPAD_DOWN; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: return GameController::BUTTON_DPAD_LEFT; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return GameController::BUTTON_DPAD_RIGHT; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: return GameController::BUTTON_LEFTSTICK; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: return GameController::BUTTON_RIGHTSTICK; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return GameController::BUTTON_LEFTSHOULDER; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return GameController::BUTTON_RIGHTSHOULDER; + case SDL_CONTROLLER_BUTTON_BACK: return GameController::BUTTON_BACK; + case SDL_CONTROLLER_BUTTON_START: return GameController::BUTTON_START; + case SDL_CONTROLLER_BUTTON_GUIDE: return GameController::BUTTON_GUIDE; + case SDL_CONTROLLER_BUTTON_MISC1: return GameController::BUTTON_MISC1; + case SDL_CONTROLLER_BUTTON_PADDLE1: return GameController::BUTTON_PADDLE1; + case SDL_CONTROLLER_BUTTON_PADDLE2: return GameController::BUTTON_PADDLE2; + case SDL_CONTROLLER_BUTTON_PADDLE3: return GameController::BUTTON_PADDLE3; + case SDL_CONTROLLER_BUTTON_PADDLE4: return GameController::BUTTON_PADDLE4; + case SDL_CONTROLLER_BUTTON_TOUCHPAD: return GameController::BUTTON_TOUCHPAD; + default: return GameController::BUTTON_NONE; + } +} + void AppPlatform_sdl::handleControllerButtonEvent(SDL_JoystickID controllerIndex, uint8_t button, uint8_t state) { // Normal Key Press @@ -492,32 +521,3 @@ Keyboard::KeyState AppPlatform_sdl::GetKeyState(uint8_t state) return Keyboard::DOWN; } } - -static GameController::EngineButtonID _getEngineButton(uint8_t button) -{ - switch (button) - { - case SDL_CONTROLLER_BUTTON_A: return GameController::BUTTON_A; - case SDL_CONTROLLER_BUTTON_B: return GameController::BUTTON_B; - case SDL_CONTROLLER_BUTTON_X: return GameController::BUTTON_X; - case SDL_CONTROLLER_BUTTON_Y: return GameController::BUTTON_Y; - case SDL_CONTROLLER_BUTTON_DPAD_UP: return GameController::BUTTON_DPAD_UP; - case SDL_CONTROLLER_BUTTON_DPAD_DOWN: return GameController::BUTTON_DPAD_DOWN; - case SDL_CONTROLLER_BUTTON_DPAD_LEFT: return GameController::BUTTON_DPAD_LEFT; - case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return GameController::BUTTON_DPAD_RIGHT; - case SDL_CONTROLLER_BUTTON_LEFTSTICK: return GameController::BUTTON_LEFTSTICK; - case SDL_CONTROLLER_BUTTON_RIGHTSTICK: return GameController::BUTTON_RIGHTSTICK; - case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return GameController::BUTTON_LEFTSHOULDER; - case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return GameController::BUTTON_RIGHTSHOULDER; - case SDL_CONTROLLER_BUTTON_BACK: return GameController::BUTTON_BACK; - case SDL_CONTROLLER_BUTTON_START: return GameController::BUTTON_START; - case SDL_CONTROLLER_BUTTON_GUIDE: return GameController::BUTTON_GUIDE; - case SDL_CONTROLLER_BUTTON_MISC1: return GameController::BUTTON_MISC1; - case SDL_CONTROLLER_BUTTON_PADDLE1: return GameController::BUTTON_PADDLE1; - case SDL_CONTROLLER_BUTTON_PADDLE2: return GameController::BUTTON_PADDLE2; - case SDL_CONTROLLER_BUTTON_PADDLE3: return GameController::BUTTON_PADDLE3; - case SDL_CONTROLLER_BUTTON_PADDLE4: return GameController::BUTTON_PADDLE4; - case SDL_CONTROLLER_BUTTON_TOUCHPAD: return GameController::BUTTON_TOUCHPAD; - default: return GameController::BUTTON_NONE; - } -} From 74bcbabeddd88e14d81668a6b1d73b73d903a5a7 Mon Sep 17 00:00:00 2001 From: Wilyicaro Date: Wed, 25 Feb 2026 03:47:30 -0300 Subject: [PATCH 07/11] -Now, the Console Create World screen has a creative mode selector -Fixed inventory being reset to the default items when loading in creative mode -Fixed pocket buttons being stretched --- .../windows/projects/Client/Client.vcxproj | 1 + .../projects/Client/Client.vcxproj.filters | 3 + source/client/app/Minecraft.cpp | 54 +-- source/client/app/Minecraft.hpp | 4 + source/client/app/NinecraftApp.cpp | 4 +- source/client/gui/Gui.cpp | 12 +- source/client/gui/Gui.hpp | 2 +- source/client/gui/GuiElement.cpp | 2 +- source/client/gui/GuiElement.hpp | 2 +- source/client/gui/Screen.cpp | 29 +- source/client/gui/Screen.hpp | 3 +- source/client/gui/components/Button.cpp | 2 +- source/client/gui/components/TextBox.cpp | 6 +- source/client/gui/components/TextBox.hpp | 2 +- source/client/gui/screens/ChatScreen.cpp | 6 +- source/client/gui/screens/ChatScreen.hpp | 2 +- .../gui/screens/CreateWorldScreen_Console.cpp | 23 +- .../gui/screens/CreateWorldScreen_Console.hpp | 2 + source/client/gui/screens/CreditsScreen.cpp | 4 +- source/client/gui/screens/CreditsScreen.hpp | 2 +- .../screens/IngameBlockSelectionScreen.cpp | 6 +- .../screens/IngameBlockSelectionScreen.hpp | 2 +- .../client/gui/screens/SelectWorldScreen.cpp | 10 +- .../client/gui/screens/SelectWorldScreen.hpp | 2 +- .../gui/screens/inventory/ContainerScreen.cpp | 18 +- .../gui/screens/inventory/ContainerScreen.hpp | 2 +- source/client/options/Options.cpp | 342 +++++++++--------- source/client/options/Options.hpp | 124 +++---- source/client/player/LocalPlayer.cpp | 4 +- .../player/input/ControllerMoveInput.cpp | 4 +- .../player/input/ControllerMoveInput.hpp | 2 +- .../client/player/input/CustomInputHolder.cpp | 4 +- .../client/player/input/CustomInputHolder.hpp | 2 +- .../player/input/GameControllerManager.cpp | 8 +- source/client/player/input/IInputHolder.cpp | 6 +- source/client/player/input/IInputHolder.hpp | 15 +- source/client/player/input/IMoveInput.cpp | 2 +- source/client/player/input/IMoveInput.hpp | 2 +- source/client/player/input/InputType.hpp | 13 + source/client/player/input/Keyboard.cpp | 4 +- source/client/player/input/KeyboardInput.cpp | 14 +- source/client/player/input/KeyboardInput.hpp | 2 +- source/client/player/input/MouseDevice.cpp | 4 +- source/client/player/input/Multitouch.cpp | 4 +- .../client/player/input/TouchInputHolder.cpp | 4 +- .../client/player/input/TouchInputHolder.hpp | 2 +- .../player/input/TouchscreenInput_TestFps.cpp | 2 +- .../player/input/TouchscreenInput_TestFps.hpp | 2 +- source/client/renderer/Font.cpp | 2 +- source/client/renderer/Font.hpp | 8 +- source/client/renderer/ScreenRenderer.cpp | 57 +-- source/client/renderer/ScreenRenderer.hpp | 3 +- source/client/renderer/Textures.cpp | 7 + source/client/renderer/Textures.hpp | 6 +- .../client/renderer/texture/TextureAtlas.cpp | 20 +- .../client/renderer/texture/TextureAtlas.hpp | 10 +- source/common/utility/HashMap.hpp | 2 +- source/world/gamemode/CreativeMode.cpp | 1 - source/world/item/Inventory.cpp | 11 - source/world/item/ItemStack.cpp | 4 +- source/world/level/Level.cpp | 3 + 61 files changed, 467 insertions(+), 438 deletions(-) create mode 100644 source/client/player/input/InputType.hpp diff --git a/platforms/windows/projects/Client/Client.vcxproj b/platforms/windows/projects/Client/Client.vcxproj index c046d534d..3d035bcd8 100644 --- a/platforms/windows/projects/Client/Client.vcxproj +++ b/platforms/windows/projects/Client/Client.vcxproj @@ -258,6 +258,7 @@ + diff --git a/platforms/windows/projects/Client/Client.vcxproj.filters b/platforms/windows/projects/Client/Client.vcxproj.filters index 55cd0f467..c83e56ddc 100644 --- a/platforms/windows/projects/Client/Client.vcxproj.filters +++ b/platforms/windows/projects/Client/Client.vcxproj.filters @@ -677,6 +677,9 @@ Header Files\GUI\Screens\Inventory + + Header Files\Player\Input + diff --git a/source/client/app/Minecraft.cpp b/source/client/app/Minecraft.cpp index 888bb09a9..9a78beb31 100644 --- a/source/client/app/Minecraft.cpp +++ b/source/client/app/Minecraft.cpp @@ -51,6 +51,7 @@ int Minecraft::width = C_DEFAULT_SCREEN_WIDTH; int Minecraft::height = C_DEFAULT_SCREEN_HEIGHT; bool Minecraft::useAmbientOcclusion = false; int Minecraft::customDebugId = 0; +InputType::Name Minecraft::_inputType = InputType::KEYBOARD; //@HUH: For the demo, this is defined as TRUE. //@HUH: deadmau5 had camera cheats? That's interesting. @@ -372,7 +373,7 @@ bool Minecraft::isOnlineClient() const bool Minecraft::isTouchscreen() const { - return IInputHolder::activeType == IInputHolder::TOUCHSCREEN; + return getInputType() == InputType::TOUCHSCREEN; } bool Minecraft::useSplitControls() const @@ -382,7 +383,7 @@ bool Minecraft::useSplitControls() const bool Minecraft::useController() const { - return m_pPlatform->hasGamepad() && (IInputHolder::activeType == IInputHolder::CONTROLLER || getOptions()->m_bUseController.get()); + return m_pPlatform->hasGamepad() && (getInputType() == InputType::CONTROLLER || getOptions()->m_bUseController.get()); } void Minecraft::setGameMode(GameType gameType) @@ -516,7 +517,7 @@ void Minecraft::handleBuildAction(const BuildActionIntention& action) void Minecraft::tickInput() { - if (!m_pInputHolder->allowsType(IInputHolder::activeType)) + if (!m_pInputHolder->allowsType(getInputType())) _reloadInput(); if (m_pScreen) @@ -575,18 +576,18 @@ void Minecraft::tickInput() bool bPressed = GameControllerManager::getEventButtonState() == GameController::BTN_STATE_DOWN; if (bPressed) - m_pGui->handleControlPressed(ControlBind(-1, button)); + m_pGui->handleButtonPressed(ButtonInfo(-1, button)); - for (size_t i = 0; i < KM_COUNT; ++i) + for (size_t i = 0; i < BM_COUNT; ++i) { - eControlMappingIndex ctrl = (eControlMappingIndex)i; - if (!getOptions()->getControl(ctrl).isButton(button)) continue; + eButtonMappingIndex ctrl = (eButtonMappingIndex)i; + if (!getOptions()->getButton(ctrl).isControllerButton(button)) continue; m_pLocalPlayer->m_pMoveInput->setKey(ctrl, bPressed); if (bPressed) - getOptions()->getControlMapping(ctrl).pressed(); + getOptions()->getButtonMapping(ctrl).pressed(); else - getOptions()->getControlMapping(ctrl).reset(); + getOptions()->getButtonMapping(ctrl).reset(); } } } @@ -600,18 +601,18 @@ void Minecraft::tickInput() bool bPressed = Keyboard::getEventKeyState() == Keyboard::DOWN; if (bPressed) - m_pGui->handleControlPressed(ControlBind(keyCode, GameController::BUTTON_NONE)); + m_pGui->handleButtonPressed(ButtonInfo(keyCode, GameController::BUTTON_NONE)); - for (size_t i = 0; i < KM_COUNT; ++i) + for (size_t i = 0; i < BM_COUNT; ++i) { - eControlMappingIndex ctrl = (eControlMappingIndex)i; + eButtonMappingIndex ctrl = (eButtonMappingIndex)i; if (!getOptions()->isKey(ctrl, keyCode)) continue; m_pLocalPlayer->m_pMoveInput->setKey(ctrl, bPressed); if (bPressed) - getOptions()->getControlMapping(ctrl).pressed(); + getOptions()->getButtonMapping(ctrl).pressed(); else - getOptions()->getControlMapping(ctrl).reset(); + getOptions()->getButtonMapping(ctrl).reset(); } if (getOptions()->field_19) @@ -620,13 +621,13 @@ void Minecraft::tickInput() // @TODO: Replace with KeyboardBuildInput if (getTimeMs() - field_2B4 <= 200) { - if (getOptions()->isKey(KM_DESTROY, keyCode) && bPressed) + if (getOptions()->isKey(BM_DESTROY, keyCode) && bPressed) { BuildActionIntention intention(BuildActionIntention::KEY_DESTROY); handleBuildAction(intention); } - if (getOptions()->isKey(KM_PLACE, keyCode) && bPressed) + if (getOptions()->isKey(BM_PLACE, keyCode) && bPressed) { BuildActionIntention intention(BuildActionIntention::KEY_USE); handleBuildAction(intention); @@ -637,21 +638,21 @@ void Minecraft::tickInput() for (int i = 0; i < m_pGui->getNumUsableSlots(); i++) { - while (getOptions()->getControlMapping(eControlMappingIndex(KM_SLOT_1 + i)).consume()) + while (getOptions()->getButtonMapping(eButtonMappingIndex(BM_SLOT_1 + i)).consume()) m_pLocalPlayer->m_pInventory->selectSlot(i); } - while (getOptions()->getControlMapping(KM_TOGGLE3RD).consume()) + while (getOptions()->getButtonMapping(BM_TOGGLE3RD).consume()) { getOptions()->m_thirdPerson.toggle(); } - while (getOptions()->getControlMapping(KM_MENU_PAUSE).consume()) + while (getOptions()->getButtonMapping(BM_MENU_PAUSE).consume()) { handleBack(false); } - while (getOptions()->getControlMapping(KM_DROP).consume()) + while (getOptions()->getButtonMapping(BM_DROP).consume()) { ItemStack& item = m_pLocalPlayer->m_pInventory->getSelected(); if (!item.isEmpty()) @@ -665,17 +666,17 @@ void Minecraft::tickInput() } } - while (getOptions()->getControlMapping(KM_TOGGLEGUI).consume()) + while (getOptions()->getButtonMapping(BM_TOGGLEGUI).consume()) { getOptions()->m_hideGui.toggle(); } - while (getOptions()->getControlMapping(KM_TOGGLEDEBUG).consume()) + while (getOptions()->getButtonMapping(BM_TOGGLEDEBUG).consume()) { getOptions()->m_debugText.toggle(); } #ifdef ENH_ALLOW_AO_TOGGLE - while (getOptions()->getControlMapping(KM_TOGGLEAO).consume()) + while (getOptions()->getButtonMapping(BM_TOGGLEAO).consume()) { // Toggle ambient occlusion. getOptions()->m_ambientOcclusion.toggle(); @@ -846,6 +847,10 @@ void Minecraft::tick() setScreen(new DeathScreen); } } + else + { + m_pScreen->validate(this); + } tickInput(); @@ -896,10 +901,7 @@ void Minecraft::tick() } if (m_pScreen) - { - m_pScreen->validate(this); m_pScreen->tick(); - } Multitouch::reset(); diff --git a/source/client/app/Minecraft.hpp b/source/client/app/Minecraft.hpp index edd594852..24b1d12dc 100644 --- a/source/client/app/Minecraft.hpp +++ b/source/client/app/Minecraft.hpp @@ -115,9 +115,13 @@ class Minecraft : public App UITheme getUiTheme(); //const Entity& getCameraEntity() const { return *m_pCameraEntity; } + static InputType::Name getInputType() { return _inputType; } + static void setInputType(InputType::Name inputType) { _inputType = inputType; } + private: // Value provided by the OS static float _renderScaleMultiplier; + static InputType::Name _inputType; public: static float getRenderScaleMultiplier() { return _renderScaleMultiplier; } static void setRenderScaleMultiplier(float value) { _renderScaleMultiplier = value; } diff --git a/source/client/app/NinecraftApp.cpp b/source/client/app/NinecraftApp.cpp index f0c610914..2bc05a62b 100644 --- a/source/client/app/NinecraftApp.cpp +++ b/source/client/app/NinecraftApp.cpp @@ -105,9 +105,9 @@ void NinecraftApp::_initInput() //If someone has a gamepad connected, certainly they want to use it if (platform()->hasGamepad()) - IInputHolder::activeType = IInputHolder::CONTROLLER; + setInputType(InputType::CONTROLLER); else if (platform()->isTouchscreen()) - IInputHolder::activeType = IInputHolder::TOUCHSCREEN; + setInputType(InputType::TOUCHSCREEN); getOptions()->loadControls(); _reloadInput(); diff --git a/source/client/gui/Gui.cpp b/source/client/gui/Gui.cpp index 944f4b1bf..26e7914dd 100644 --- a/source/client/gui/Gui.cpp +++ b/source/client/gui/Gui.cpp @@ -366,11 +366,11 @@ void Gui::handleScrollWheel(bool down) m_pMinecraft->m_pLocalPlayer->m_pInventory->selectSlot(slot); } -void Gui::handleControlPressed(const ControlBind& bind) +void Gui::handleButtonPressed(const ButtonInfo& info) { Options* options = m_pMinecraft->getOptions(); - if (options->isControl(KM_INVENTORY, bind)) + if (options->isButton(BM_INVENTORY, info)) { if (m_pMinecraft->m_pGameMode->isSurvivalType()) m_pMinecraft->setScreen(new InventoryScreen(m_pMinecraft->m_pLocalPlayer)); @@ -379,8 +379,8 @@ void Gui::handleControlPressed(const ControlBind& bind) return; } - bool slotL = options->isControl(KM_SLOT_L, bind); - bool slotR = options->isControl(KM_SLOT_R, bind); + bool slotL = options->isButton(BM_SLOT_L, info); + bool slotR = options->isButton(BM_SLOT_R, info); if (slotL || slotR) { int maxItems = getNumSlots() - 1; @@ -405,10 +405,10 @@ void Gui::handleControlPressed(const ControlBind& bind) return; } - if (options->isControl(KM_CHAT, bind) || options->isControl(KM_CHAT_CMD, bind)) + if (options->isButton(BM_CHAT, info) || options->isButton(BM_CHAT_CMD, info)) { if (!m_pMinecraft->m_pScreen) - m_pMinecraft->setScreen(new ChatScreen(m_pMinecraft->getOptions()->isControl(KM_CHAT_CMD, bind))); + m_pMinecraft->setScreen(new ChatScreen(m_pMinecraft->getOptions()->isButton(BM_CHAT_CMD, info))); } } diff --git a/source/client/gui/Gui.hpp b/source/client/gui/Gui.hpp index 8d6167b34..8adc206a2 100644 --- a/source/client/gui/Gui.hpp +++ b/source/client/gui/Gui.hpp @@ -65,7 +65,7 @@ class Gui : public GuiComponent bool isInside(int mx, int my); void handleClick(int id, int mx, int my); void handleScrollWheel(bool down); - void handleControlPressed(const ControlBind&); + void handleButtonPressed(const ButtonInfo&); void renderMessages(bool bShowAll); void renderHearts(bool topLeft); void renderArmor(bool topLeft); diff --git a/source/client/gui/GuiElement.cpp b/source/client/gui/GuiElement.cpp index 67e2a20fd..de8ea7dd5 100644 --- a/source/client/gui/GuiElement.cpp +++ b/source/client/gui/GuiElement.cpp @@ -63,7 +63,7 @@ bool GuiElement::areaNavigation(Minecraft* pMinecraft, AreaNavigation::Direction return false; } -void GuiElement::handleControlPress(Minecraft* pMinecraft, const ControlBind& key) +void GuiElement::handleButtonPress(Minecraft* pMinecraft, const ButtonInfo& key) { } diff --git a/source/client/gui/GuiElement.hpp b/source/client/gui/GuiElement.hpp index 95072c66c..3350dd2bc 100644 --- a/source/client/gui/GuiElement.hpp +++ b/source/client/gui/GuiElement.hpp @@ -42,7 +42,7 @@ class GuiElement : public GuiComponent virtual bool pointerPressed(Minecraft* pMinecraft, const MenuPointer& pointer); virtual bool pointerReleased(Minecraft* pMinecraft, const MenuPointer& pointer); virtual bool areaNavigation(Minecraft* pMinecraft, AreaNavigation::Direction); - virtual void handleControlPress(Minecraft* pMinecraft, const ControlBind& key); + virtual void handleButtonPress(Minecraft* pMinecraft, const ButtonInfo& button); virtual void handleTextChar(Minecraft* pMinecraft, int chr); virtual void handleClipboardPaste(const std::string& content); virtual void handleScroll(float force); diff --git a/source/client/gui/Screen.cpp b/source/client/gui/Screen.cpp index 6611bbab2..95beb7c83 100644 --- a/source/client/gui/Screen.cpp +++ b/source/client/gui/Screen.cpp @@ -49,7 +49,6 @@ Screen::Screen() m_cursorTick = 0; m_themeSelection = UI_GENERIC; m_uiTheme = UI_POCKET; - m_bUniversalUiTheme = false; } Screen::~Screen() @@ -152,44 +151,44 @@ void Screen::init(Minecraft* pMinecraft, int width, int height) m_bLastPointerPressedState = false; } -void Screen::controlPressed(const ControlBind& bind) +void Screen::buttonPressed(const ButtonInfo& info) { Options& options = *m_pMinecraft->getOptions(); GuiElement* element = _getSelectedElement(); - if (options.isControl(KM_MENU_CANCEL, bind)) + if (options.isButton(BM_MENU_CANCEL, info)) { m_pMinecraft->handleBack(false); } - if (options.isControl(KM_MENU_TAB_LEFT, bind)) + if (options.isButton(BM_MENU_TAB_LEFT, info)) { prevTab(); } - if (options.isControl(KM_MENU_TAB_RIGHT, bind)) + if (options.isButton(BM_MENU_TAB_RIGHT, info)) { nextTab(); } if (doElementTabbing()) { - if (options.isControl(KM_MENU_DOWN, bind)) + if (options.isButton(BM_MENU_DOWN, info)) { _areaNavigation(AreaNavigation::DOWN); } - else if (options.isControl(KM_MENU_UP, bind)) + else if (options.isButton(BM_MENU_UP, info)) { _areaNavigation(AreaNavigation::UP); } - else if (options.isControl(KM_MENU_RIGHT, bind)) + else if (options.isButton(BM_MENU_RIGHT, info)) { _areaNavigation(AreaNavigation::RIGHT); } - else if (options.isControl(KM_MENU_LEFT, bind)) + else if (options.isButton(BM_MENU_LEFT, info)) { _areaNavigation(AreaNavigation::LEFT); } - else if (options.isControl(KM_MENU_OK, bind)) + else if (options.isButton(BM_MENU_OK, info)) { if (element && element->isEnabled()) { @@ -206,7 +205,7 @@ void Screen::controlPressed(const ControlBind& bind) if (element && element->isEnabled()) { - element->handleControlPress(m_pMinecraft, bind); + element->handleButtonPress(m_pMinecraft, info); } } @@ -764,7 +763,7 @@ void Screen::keyboardEvent() // Ugly hack if (!doElementTabbing()) { - if (Keyboard::getEventKeyState() && m_pMinecraft->getOptions()->isKey(KM_MENU_OK, Keyboard::getEventKey())) + if (Keyboard::getEventKeyState() && m_pMinecraft->getOptions()->isKey(BM_MENU_OK, Keyboard::getEventKey())) { m_menuPointer.isPressed = true; } @@ -775,7 +774,7 @@ void Screen::keyboardEvent() } if (Keyboard::getEventKeyState()) - controlPressed(ControlBind(Keyboard::getEventKey(), GameController::BUTTON_NONE)); + buttonPressed(ButtonInfo(Keyboard::getEventKey(), GameController::BUTTON_NONE)); } void Screen::controllerEvent() @@ -783,7 +782,7 @@ void Screen::controllerEvent() // Ugly hack x2 if (!doElementTabbing()) { - if (GameControllerManager::getEventButtonState() && m_pMinecraft->getOptions()->getControl(KM_MENU_OK).isButton(GameControllerManager::getEventButton())) + if (GameControllerManager::getEventButtonState() && m_pMinecraft->getOptions()->getButton(BM_MENU_OK).isControllerButton(GameControllerManager::getEventButton())) { m_menuPointer.isPressed = true; } @@ -794,7 +793,7 @@ void Screen::controllerEvent() } if (GameControllerManager::getEventButtonState()) - controlPressed(ControlBind(-1, GameControllerManager::getEventButton())); + buttonPressed(ButtonInfo(-1, GameControllerManager::getEventButton())); } void Screen::checkForPointerEvent(MouseButtonType button) diff --git a/source/client/gui/Screen.hpp b/source/client/gui/Screen.hpp index 316d2d59b..eeb1ed0ab 100644 --- a/source/client/gui/Screen.hpp +++ b/source/client/gui/Screen.hpp @@ -117,7 +117,7 @@ class Screen : public GuiComponent virtual void onTextBoxUpdated(int id) {}; virtual void pointerPressed(const MenuPointer& pointer, MouseButtonType btn); virtual void pointerReleased(const MenuPointer& pointer, MouseButtonType btn); - virtual void controlPressed(const ControlBind&); + virtual void buttonPressed(const ButtonInfo&); virtual void handleTextChar(char); virtual void keyboardTextPaste(const std::string& text); virtual float getScale(int width, int height); @@ -165,7 +165,6 @@ class Screen : public GuiComponent bool m_bPassEvents; //@NOTE: This should be enabled only if the the actual screen handles the deletion of the previous screen, otherwise, there will be a memory leak! bool m_bDeletePrevious; - bool m_bUniversalUiTheme; Minecraft* m_pMinecraft; GuiElementList m_elements; GuiElement* m_pSelectedElement; diff --git a/source/client/gui/components/Button.cpp b/source/client/gui/components/Button.cpp index a1d0b1eee..9e9952cdd 100644 --- a/source/client/gui/components/Button.cpp +++ b/source/client/gui/components/Button.cpp @@ -32,7 +32,7 @@ void Button::_renderBgPocket(Minecraft* mc, const MenuPointer& pointer) int iXPos = isSelected() ? 66 : 0; currentShaderColor = isEnabled() ? Color::WHITE : Color::GREY; mc->m_pTextures->loadAndBindTexture("gui/touchgui.png"); - blit(m_xPos, m_yPos, iXPos, 0, m_width, m_height, 66, 26, &m_materials.ui_textured_and_glcolor); + blitNineSlice(*mc->m_pTextures, TextureAtlasSprite(iXPos, 0, 66, 26, "gui/touchgui.png", 256, 256), m_xPos, m_yPos, m_width, m_height, 3, &m_materials.ui_textured_and_glcolor); } void Button::_renderBgConsole(Minecraft* mc, const MenuPointer& pointer) diff --git a/source/client/gui/components/TextBox.cpp b/source/client/gui/components/TextBox.cpp index 2351c501f..badb258f0 100644 --- a/source/client/gui/components/TextBox.cpp +++ b/source/client/gui/components/TextBox.cpp @@ -205,13 +205,13 @@ char TextBox::guessCharFromKey(int key) { #endif -void TextBox::handleControlPress(Minecraft* pMinecraft, const ControlBind& bind) +void TextBox::handleButtonPress(Minecraft* pMinecraft, const ButtonInfo& info) { Options& options = *pMinecraft->getOptions(); if (!hasFocus()) { - if (options.isControl(KM_MENU_OK, bind)) + if (options.isButton(BM_MENU_OK, info)) setFocused(true); return; } @@ -224,7 +224,7 @@ void TextBox::handleControlPress(Minecraft* pMinecraft, const ControlBind& bind) } #endif - switch (bind.keyId) { + switch (info.keyId) { case AKEYCODE_DEL: { // handled elsewhere, do not dupe diff --git a/source/client/gui/components/TextBox.hpp b/source/client/gui/components/TextBox.hpp index ae2de1eec..4bd3a15af 100644 --- a/source/client/gui/components/TextBox.hpp +++ b/source/client/gui/components/TextBox.hpp @@ -40,7 +40,7 @@ class TextBox : public GuiElement public: void init(Font* pFont); bool pointerPressed(Minecraft* pMinecraft, const MenuPointer& pointer) override; - void handleControlPress(Minecraft* pMinecraft, const ControlBind&) override; + void handleButtonPress(Minecraft* pMinecraft, const ButtonInfo&) override; void handleTextChar(Minecraft* pMinecraft, int chr) override; void handleClipboardPaste(const std::string& text) override; void render(Minecraft* pMinecraft, const MenuPointer& pointer) override; diff --git a/source/client/gui/screens/ChatScreen.cpp b/source/client/gui/screens/ChatScreen.cpp index 042775d3e..3f948f0a6 100644 --- a/source/client/gui/screens/ChatScreen.cpp +++ b/source/client/gui/screens/ChatScreen.cpp @@ -58,15 +58,15 @@ void ChatScreen::render(float f) Screen::render(f); } -void ChatScreen::controlPressed(const ControlBind& bind) +void ChatScreen::buttonPressed(const ButtonInfo& button) { if (!_useController()) { - if (m_pMinecraft->getOptions()->isControl(KM_MENU_OK, bind)) + if (m_pMinecraft->getOptions()->isButton(BM_MENU_OK, button)) sendMessageAndExit(); } - Screen::controlPressed(bind); + Screen::buttonPressed(button); } void ChatScreen::handleKeyboardClosed() diff --git a/source/client/gui/screens/ChatScreen.hpp b/source/client/gui/screens/ChatScreen.hpp index df2f8e56d..65763a80d 100644 --- a/source/client/gui/screens/ChatScreen.hpp +++ b/source/client/gui/screens/ChatScreen.hpp @@ -24,7 +24,7 @@ class ChatScreen : public Screen void init() override; void removed() override; void render(float f) override; - void controlPressed(const ControlBind& bind) override; + void buttonPressed(const ButtonInfo& info) override; void handleKeyboardClosed() override; bool isPauseScreen() override; diff --git a/source/client/gui/screens/CreateWorldScreen_Console.cpp b/source/client/gui/screens/CreateWorldScreen_Console.cpp index 3de2b5952..7352049d4 100644 --- a/source/client/gui/screens/CreateWorldScreen_Console.cpp +++ b/source/client/gui/screens/CreateWorldScreen_Console.cpp @@ -9,8 +9,10 @@ CreateWorldScreen_Console::CreateWorldScreen_Console(Options& options, Screen* p m_inviteOnly(0, 0, false, Language::get("playGame.inviteOnly")), m_textName(this, 0, 0, 400, 38, "", "New World"), m_textSeed(this, 0, 0, 400, 38, ""), + m_btnGameMode(0, 0, 400, 40, ""), m_difficultySlider(0, 0, 400, 32, &options.m_difficulty, options.m_difficulty.getMessage(), options.m_difficulty.toFloat()), - m_btnCreate(0, 0, 400, 40, Language::get("playGame.createNewWorld")) + m_btnCreate(0, 0, 400, 40, Language::get("playGame.createNewWorld")), + m_gameMode(GAME_TYPE_SURVIVAL) { m_onlineGame.setEnabled(false); m_inviteOnly.setEnabled(false); @@ -38,15 +40,20 @@ void CreateWorldScreen_Console::_buttonClicked(Button* pButton) seed = Util::hashCode(seedThing); } - LevelSettings levelSettings(seed); + LevelSettings levelSettings(seed, m_gameMode); m_pMinecraft->selectLevel(levelUniqueName, levelNickname, levelSettings); } + else if (pButton->getId() == m_btnGameMode.getId()) + { + m_gameMode = static_cast((static_cast(m_gameMode) + 1) % (GAME_TYPES_MAX + 1)); + m_btnGameMode.setMessage("Game Mode: " + GameTypeConv::GameTypeToNonLocString(m_gameMode)); + } } void CreateWorldScreen_Console::init() { m_panel.w = 450; - m_panel.h = 390; + m_panel.h = 418; m_panel.x = (m_width - m_panel.w) / 2; m_panel.y = (m_height - m_panel.h) / 2 + 45; @@ -67,12 +74,18 @@ void CreateWorldScreen_Console::init() m_textSeed.m_yPos = m_panel.y + 188; _addElement(m_textSeed); + m_btnGameMode.setMessage("Game Mode: " + GameTypeConv::GameTypeToNonLocString(m_gameMode)); + + m_btnGameMode.m_xPos = left; + m_btnGameMode.m_yPos = m_panel.y + 259; + _addElement(m_btnGameMode); + m_difficultySlider.m_xPos = left; - m_difficultySlider.m_yPos = m_panel.y + 267; + m_difficultySlider.m_yPos = m_panel.y + 308; _addElement(m_difficultySlider); m_btnCreate.m_xPos = left; - m_btnCreate.m_yPos = m_panel.y + 322; + m_btnCreate.m_yPos = m_panel.y + 350; _addElement(m_btnCreate); m_textName.init(m_pFont); diff --git a/source/client/gui/screens/CreateWorldScreen_Console.hpp b/source/client/gui/screens/CreateWorldScreen_Console.hpp index 7643a1196..88de45a6e 100644 --- a/source/client/gui/screens/CreateWorldScreen_Console.hpp +++ b/source/client/gui/screens/CreateWorldScreen_Console.hpp @@ -24,6 +24,8 @@ class CreateWorldScreen_Console : public PanelScreen_Console TickBox m_inviteOnly; TextBox m_textName; TextBox m_textSeed; + Button m_btnGameMode; SliderButton m_difficultySlider; Button m_btnCreate; + GameType m_gameMode; }; \ No newline at end of file diff --git a/source/client/gui/screens/CreditsScreen.cpp b/source/client/gui/screens/CreditsScreen.cpp index a3afde9ea..fd70417bb 100644 --- a/source/client/gui/screens/CreditsScreen.cpp +++ b/source/client/gui/screens/CreditsScreen.cpp @@ -53,9 +53,9 @@ bool CreditsScreen::isInGameScreen() return true; } -void CreditsScreen::controlPressed(const ControlBind& bind) +void CreditsScreen::buttonPressed(const ButtonInfo& info) { - Screen::controlPressed(bind); + Screen::buttonPressed(info); } void CreditsScreen::tick() diff --git a/source/client/gui/screens/CreditsScreen.hpp b/source/client/gui/screens/CreditsScreen.hpp index e922449fc..29f2af1be 100644 --- a/source/client/gui/screens/CreditsScreen.hpp +++ b/source/client/gui/screens/CreditsScreen.hpp @@ -15,7 +15,7 @@ class CreditsScreen : public Screen public: void init() override; bool isInGameScreen() override; - void controlPressed(const ControlBind&) override; + void buttonPressed(const ButtonInfo&) override; void tick() override; void render(float f) override; bool handleBackEvent(bool b) override; diff --git a/source/client/gui/screens/IngameBlockSelectionScreen.cpp b/source/client/gui/screens/IngameBlockSelectionScreen.cpp index 27e7124ae..f67756031 100644 --- a/source/client/gui/screens/IngameBlockSelectionScreen.cpp +++ b/source/client/gui/screens/IngameBlockSelectionScreen.cpp @@ -337,15 +337,15 @@ void IngameBlockSelectionScreen::removed() m_pMinecraft->m_pGui->inventoryUpdated(); } -void IngameBlockSelectionScreen::controlPressed(const ControlBind& bind) +void IngameBlockSelectionScreen::buttonPressed(const ButtonInfo& info) { - if (!_useController() && m_pMinecraft->getOptions()->isControl(KM_INVENTORY, bind)) + if (!_useController() && m_pMinecraft->getOptions()->isButton(BM_INVENTORY, info)) { m_pMinecraft->handleBack(false); } else { - Screen::controlPressed(bind); + Screen::buttonPressed(info); } } diff --git a/source/client/gui/screens/IngameBlockSelectionScreen.hpp b/source/client/gui/screens/IngameBlockSelectionScreen.hpp index 45b14dcbc..f80726b82 100644 --- a/source/client/gui/screens/IngameBlockSelectionScreen.hpp +++ b/source/client/gui/screens/IngameBlockSelectionScreen.hpp @@ -40,7 +40,7 @@ class IngameBlockSelectionScreen : public Screen void pointerPressed(const MenuPointer& pointer, MouseButtonType btn) override; void pointerReleased(const MenuPointer& pointer, MouseButtonType btn) override; void removed() override; - void controlPressed(const ControlBind&) override; + void buttonPressed(const ButtonInfo&) override; bool isPauseScreen() override; private: diff --git a/source/client/gui/screens/SelectWorldScreen.cpp b/source/client/gui/screens/SelectWorldScreen.cpp index daf86b280..6d1df8468 100644 --- a/source/client/gui/screens/SelectWorldScreen.cpp +++ b/source/client/gui/screens/SelectWorldScreen.cpp @@ -76,24 +76,24 @@ bool SelectWorldScreen::isInGameScreen() return true; } -void SelectWorldScreen::controlPressed(const ControlBind& bind) +void SelectWorldScreen::buttonPressed(const ButtonInfo& button) { Options& options = *m_pMinecraft->getOptions(); #ifndef ORIGINAL_CODE - if (options.isControl(KM_MENU_OK, bind)) + if (options.isButton(BM_MENU_OK, button)) m_pWorldSelectionList->selectItem(m_pWorldSelectionList->getItemAtPosition(m_width / 2, m_height / 2), false); #endif if (m_btnWorld.isSelected()) { - if (options.isControl(KM_LEFT, bind)) + if (options.isButton(BM_LEFT, button)) m_pWorldSelectionList->stepLeft(); - if (options.isControl(KM_RIGHT, bind)) + if (options.isButton(BM_RIGHT, button)) m_pWorldSelectionList->stepRight(); } - Screen::controlPressed(bind); + Screen::buttonPressed(button); } static char g_SelectWorldFilterArray[] = { '/','\n','\r','\x09','\0','\xC','`','?','*','\\','<','>','|','"',':'}; diff --git a/source/client/gui/screens/SelectWorldScreen.hpp b/source/client/gui/screens/SelectWorldScreen.hpp index b0b722ffb..7b4e6010f 100644 --- a/source/client/gui/screens/SelectWorldScreen.hpp +++ b/source/client/gui/screens/SelectWorldScreen.hpp @@ -24,7 +24,7 @@ class SelectWorldScreen : public Screen public: void init() override; bool isInGameScreen() override; - void controlPressed(const ControlBind&) override; + void buttonPressed(const ButtonInfo&) override; void tick() override; void render(float f) override; bool handleBackEvent(bool b) override; diff --git a/source/client/gui/screens/inventory/ContainerScreen.cpp b/source/client/gui/screens/inventory/ContainerScreen.cpp index 77cde805a..09717dec8 100644 --- a/source/client/gui/screens/inventory/ContainerScreen.cpp +++ b/source/client/gui/screens/inventory/ContainerScreen.cpp @@ -286,34 +286,34 @@ void ContainerScreen::slotClicked(const MenuPointer& pointer, MouseButtonType bu slotClicked(pointer, button, m_pMinecraft->m_pPlatform->shiftPressed()); } -void ContainerScreen::controlPressed(const ControlBind& bind) +void ContainerScreen::buttonPressed(const ButtonInfo& button) { Options& options = *m_pMinecraft->getOptions(); - if (!_useController() && options.isControl(KM_INVENTORY, bind)) + if (!_useController() && options.isButton(BM_INVENTORY, button)) { m_pMinecraft->handleBack(false); } - else if (options.isControl(KM_CONTAINER_QUICKMOVE, bind) && _useController()) + else if (options.isButton(BM_CONTAINER_QUICKMOVE, button) && _useController()) { slotClicked(m_menuPointer, MOUSE_BUTTON_LEFT, true); } - else if (options.isControl(KM_CONTAINER_SPLIT, bind) && _useController()) + else if (options.isButton(BM_CONTAINER_SPLIT, button) && _useController()) { slotClicked(m_menuPointer, MOUSE_BUTTON_RIGHT, false); } else { if (_useController() && - ((options.isControl(KM_MENU_UP, bind) && _selectSlotInDirection(AreaNavigation::UP)) || - (options.isControl(KM_MENU_DOWN, bind) && _selectSlotInDirection(AreaNavigation::DOWN)) || - (options.isControl(KM_MENU_RIGHT, bind) && _selectSlotInDirection(AreaNavigation::RIGHT)) || - (options.isControl(KM_MENU_LEFT, bind) && _selectSlotInDirection(AreaNavigation::LEFT)))) + ((options.isButton(BM_MENU_UP, button) && _selectSlotInDirection(AreaNavigation::UP)) || + (options.isButton(BM_MENU_DOWN, button) && _selectSlotInDirection(AreaNavigation::DOWN)) || + (options.isButton(BM_MENU_RIGHT, button) && _selectSlotInDirection(AreaNavigation::RIGHT)) || + (options.isButton(BM_MENU_LEFT, button) && _selectSlotInDirection(AreaNavigation::LEFT)))) { _playSelectSound(); return; } - Screen::controlPressed(bind); + Screen::buttonPressed(button); } } diff --git a/source/client/gui/screens/inventory/ContainerScreen.hpp b/source/client/gui/screens/inventory/ContainerScreen.hpp index b8de9a5e1..a6d76d022 100644 --- a/source/client/gui/screens/inventory/ContainerScreen.hpp +++ b/source/client/gui/screens/inventory/ContainerScreen.hpp @@ -65,7 +65,7 @@ class ContainerScreen : public Screen void pointerPressed(const MenuPointer& pointer, MouseButtonType button) override; void pointerReleased(const MenuPointer& pointer, MouseButtonType button) override; void handlePointerPressed(bool isPressed) override; - void controlPressed(const ControlBind&) override; + void buttonPressed(const ButtonInfo&) override; const SlotDisplay& getSlotDisplay(const Slot&) const; diff --git a/source/client/options/Options.cpp b/source/client/options/Options.cpp index 98ccf792b..a45e50bab 100644 --- a/source/client/options/Options.cpp +++ b/source/client/options/Options.cpp @@ -418,188 +418,188 @@ std::vector Options::getOptionStrings() void Options::loadControls() { // Win32 key codes are being used by default -#define KM(idx, name, code) m_controlMappings[idx] = ControlMapping(name, code) - KM(KM_FORWARD, "key.forward", 'W'); - KM(KM_LEFT, "key.left", 'A'); - KM(KM_BACKWARD, "key.back", 'S'); - KM(KM_RIGHT, "key.right", 'D'); - KM(KM_JUMP, "key.jump", ' '); - KM(KM_INVENTORY, "key.inventory", 'E'); - KM(KM_DROP, "key.drop", 'Q'); - KM(KM_CHAT, "key.chat", 'T'); - KM(KM_FOG, "key.fog", 'F'); - KM(KM_SNEAK, "key.sneak", 0x10); // VK_SHIFT. In original, it's 10 (misspelling?) - KM(KM_DESTROY, "key.destroy", 'K'); // was 'X' - KM(KM_PLACE, "key.place", 'L'); // was 'C' - KM(KM_MENU_UP, "key.menu.up", 0x26); // VK_UP - KM(KM_MENU_DOWN, "key.menu.down", 0x28); // VK_DOWN - KM(KM_MENU_LEFT, "key.menu.left", 0x25); // VK_LEFT - KM(KM_MENU_RIGHT, "key.menu.right", 0x27); // VK_RIGHT - KM(KM_MENU_TAB_LEFT,"key.menu.tab.left", 0x25); // VK_LEFT - KM(KM_MENU_TAB_RIGHT, "key.menu.tab.right", 0x27);// VK_RIGHT - KM(KM_MENU_OK, "key.menu.ok", 0x0D); // VK_RETURN - KM(KM_MENU_CANCEL, "key.menu.cancel", 0x1B); // VK_ESCAPE, was 0x08 = VK_BACK - KM(KM_MENU_PAUSE, "key.menu.pause", 0x1B); // VK_ESCAPE - KM(KM_SLOT_1, "key.slot.1", '1'); - KM(KM_SLOT_2, "key.slot.2", '2'); - KM(KM_SLOT_3, "key.slot.3", '3'); - KM(KM_SLOT_4, "key.slot.4", '4'); - KM(KM_SLOT_5, "key.slot.5", '5'); - KM(KM_SLOT_6, "key.slot.6", '6'); - KM(KM_SLOT_7, "key.slot.7", '7'); - KM(KM_SLOT_8, "key.slot.8", '8'); - KM(KM_SLOT_9, "key.slot.9", '9'); - KM(KM_SLOT_L, "key.slot.left", 'Y'); - KM(KM_SLOT_R, "key.slot.right", 'U'); - KM(KM_CONTAINER_QUICKMOVE, "key.container.quickmove", 0x10); // VK_SHIFT - KM(KM_CONTAINER_SPLIT, "key.container.split", 0xBF); // VK_OEM_2 (keymap is unused on mouse & keyboard) - KM(KM_TOGGLEGUI, "key.fn.gui", 0x70); // VK_F1 - KM(KM_SCREENSHOT, "key.fn.screenshot", 0x71); // VK_F2 - KM(KM_TOGGLEDEBUG, "key.fn.debug", 0x72); // VK_F3 - KM(KM_TOGGLEAO, "key.fn.ao", 0x73); // VK_F4 - KM(KM_TOGGLE3RD, "key.fn.3rd", 0x74); // VK_F5 - KM(KM_FLY_UP, "key.fly.up", 'X'); - KM(KM_FLY_DOWN, "key.fly.down", 'C'); - KM(KM_CHAT_CMD, "key.chat.cmd", 0xBF); // VK_OEM_2 -#undef KM +#define BM(idx, name, code) m_buttonMappings[idx] = ButtonMapping(name, code) + BM(BM_FORWARD, "key.forward", 'W'); + BM(BM_LEFT, "key.left", 'A'); + BM(BM_BACKWARD, "key.back", 'S'); + BM(BM_RIGHT, "key.right", 'D'); + BM(BM_JUMP, "key.jump", ' '); + BM(BM_INVENTORY, "key.inventory", 'E'); + BM(BM_DROP, "key.drop", 'Q'); + BM(BM_CHAT, "key.chat", 'T'); + BM(BM_FOG, "key.fog", 'F'); + BM(BM_SNEAK, "key.sneak", 0x10); // VK_SHIFT. In original, it's 10 (misspelling?) + BM(BM_DESTROY, "key.destroy", 'K'); // was 'X' + BM(BM_PLACE, "key.place", 'L'); // was 'C' + BM(BM_MENU_UP, "key.menu.up", 0x26); // VK_UP + BM(BM_MENU_DOWN, "key.menu.down", 0x28); // VK_DOWN + BM(BM_MENU_LEFT, "key.menu.left", 0x25); // VK_LEFT + BM(BM_MENU_RIGHT, "key.menu.right", 0x27); // VK_RIGHT + BM(BM_MENU_TAB_LEFT,"key.menu.tab.left", 0x25); // VK_LEFT + BM(BM_MENU_TAB_RIGHT, "key.menu.tab.right", 0x27);// VK_RIGHT + BM(BM_MENU_OK, "key.menu.ok", 0x0D); // VK_RETURN + BM(BM_MENU_CANCEL, "key.menu.cancel", 0x1B); // VK_ESCAPE, was 0x08 = VK_BACK + BM(BM_MENU_PAUSE, "key.menu.pause", 0x1B); // VK_ESCAPE + BM(BM_SLOT_1, "key.slot.1", '1'); + BM(BM_SLOT_2, "key.slot.2", '2'); + BM(BM_SLOT_3, "key.slot.3", '3'); + BM(BM_SLOT_4, "key.slot.4", '4'); + BM(BM_SLOT_5, "key.slot.5", '5'); + BM(BM_SLOT_6, "key.slot.6", '6'); + BM(BM_SLOT_7, "key.slot.7", '7'); + BM(BM_SLOT_8, "key.slot.8", '8'); + BM(BM_SLOT_9, "key.slot.9", '9'); + BM(BM_SLOT_L, "key.slot.left", 'Y'); + BM(BM_SLOT_R, "key.slot.right", 'U'); + BM(BM_CONTAINER_QUICKMOVE, "key.container.quickmove", 0x10); // VK_SHIFT + BM(BM_CONTAINER_SPLIT, "key.container.split", 0xBF); // VK_OEM_2 (keymap is unused on mouse & keyboard) + BM(BM_TOGGLEGUI, "key.fn.gui", 0x70); // VK_F1 + BM(BM_SCREENSHOT, "key.fn.screenshot", 0x71); // VK_F2 + BM(BM_TOGGLEDEBUG, "key.fn.debug", 0x72); // VK_F3 + BM(BM_TOGGLEAO, "key.fn.ao", 0x73); // VK_F4 + BM(BM_TOGGLE3RD, "key.fn.3rd", 0x74); // VK_F5 + BM(BM_FLY_UP, "key.fly.up", 'X'); + BM(BM_FLY_DOWN, "key.fly.down", 'C'); + BM(BM_CHAT_CMD, "key.chat.cmd", 0xBF); // VK_OEM_2 +#undef BM // @TODO: These should **really** not be defined in here. How about AppPlatform? -#define KM(idx,code) m_controlMappings[idx].bind.keyId = code +#define BM(idx,code) m_buttonMappings[idx].info.keyId = code #ifdef USE_SDL - KM(KM_FORWARD, SDLVK_w); - KM(KM_LEFT, SDLVK_a); - KM(KM_BACKWARD, SDLVK_s); - KM(KM_RIGHT, SDLVK_d); - KM(KM_JUMP, SDLVK_SPACE); - KM(KM_DESTROY, SDLVK_x); - KM(KM_PLACE, SDLVK_c); - KM(KM_MENU_UP, SDLVK_UP); - KM(KM_MENU_DOWN, SDLVK_DOWN); - KM(KM_MENU_LEFT, SDLVK_LEFT); - KM(KM_MENU_RIGHT, SDLVK_RIGHT); - KM(KM_MENU_TAB_LEFT, SDLVK_LEFT); - KM(KM_MENU_TAB_RIGHT, SDLVK_RIGHT); - KM(KM_MENU_OK, SDLVK_RETURN); - KM(KM_MENU_CANCEL, SDLVK_ESCAPE); - KM(KM_MENU_PAUSE, SDLVK_ESCAPE); - KM(KM_DROP, SDLVK_q); - KM(KM_CHAT, SDLVK_t); - KM(KM_FOG, SDLVK_f); - KM(KM_INVENTORY, SDLVK_e); - KM(KM_SNEAK, SDLVK_LSHIFT); - KM(KM_SLOT_1, SDLVK_1); - KM(KM_SLOT_2, SDLVK_2); - KM(KM_SLOT_3, SDLVK_3); - KM(KM_SLOT_4, SDLVK_4); - KM(KM_SLOT_5, SDLVK_5); - KM(KM_SLOT_6, SDLVK_6); - KM(KM_SLOT_7, SDLVK_7); - KM(KM_SLOT_8, SDLVK_8); - KM(KM_SLOT_9, SDLVK_9); - KM(KM_CONTAINER_QUICKMOVE, SDLVK_LSHIFT); - KM(KM_TOGGLEGUI, SDLVK_F1); - KM(KM_SCREENSHOT, SDLVK_F2); - KM(KM_TOGGLEDEBUG, SDLVK_F3); - KM(KM_TOGGLEAO, SDLVK_F4); - KM(KM_TOGGLE3RD, SDLVK_F5); - KM(KM_SLOT_L, SDLVK_y); - KM(KM_SLOT_R, SDLVK_u); - KM(KM_FLY_UP, SDLVK_c); - KM(KM_FLY_DOWN, SDLVK_x); - KM(KM_CHAT_CMD, SDLVK_SLASH); + BM(BM_FORWARD, SDLVK_w); + BM(BM_LEFT, SDLVK_a); + BM(BM_BACKWARD, SDLVK_s); + BM(BM_RIGHT, SDLVK_d); + BM(BM_JUMP, SDLVK_SPACE); + BM(BM_DESTROY, SDLVK_x); + BM(BM_PLACE, SDLVK_c); + BM(BM_MENU_UP, SDLVK_UP); + BM(BM_MENU_DOWN, SDLVK_DOWN); + BM(BM_MENU_LEFT, SDLVK_LEFT); + BM(BM_MENU_RIGHT, SDLVK_RIGHT); + BM(BM_MENU_TAB_LEFT, SDLVK_LEFT); + BM(BM_MENU_TAB_RIGHT, SDLVK_RIGHT); + BM(BM_MENU_OK, SDLVK_RETURN); + BM(BM_MENU_CANCEL, SDLVK_ESCAPE); + BM(BM_MENU_PAUSE, SDLVK_ESCAPE); + BM(BM_DROP, SDLVK_q); + BM(BM_CHAT, SDLVK_t); + BM(BM_FOG, SDLVK_f); + BM(BM_INVENTORY, SDLVK_e); + BM(BM_SNEAK, SDLVK_LSHIFT); + BM(BM_SLOT_1, SDLVK_1); + BM(BM_SLOT_2, SDLVK_2); + BM(BM_SLOT_3, SDLVK_3); + BM(BM_SLOT_4, SDLVK_4); + BM(BM_SLOT_5, SDLVK_5); + BM(BM_SLOT_6, SDLVK_6); + BM(BM_SLOT_7, SDLVK_7); + BM(BM_SLOT_8, SDLVK_8); + BM(BM_SLOT_9, SDLVK_9); + BM(BM_CONTAINER_QUICKMOVE, SDLVK_LSHIFT); + BM(BM_TOGGLEGUI, SDLVK_F1); + BM(BM_SCREENSHOT, SDLVK_F2); + BM(BM_TOGGLEDEBUG, SDLVK_F3); + BM(BM_TOGGLEAO, SDLVK_F4); + BM(BM_TOGGLE3RD, SDLVK_F5); + BM(BM_SLOT_L, SDLVK_y); + BM(BM_SLOT_R, SDLVK_u); + BM(BM_FLY_UP, SDLVK_c); + BM(BM_FLY_DOWN, SDLVK_x); + BM(BM_CHAT_CMD, SDLVK_SLASH); #elif defined(USE_NATIVE_ANDROID) // -- Original xperia play controls - //KM(KM_FORWARD, AKEYCODE_DPAD_UP); - //KM(KM_LEFT, AKEYCODE_DPAD_LEFT); - //KM(KM_BACKWARD, AKEYCODE_DPAD_DOWN); - //KM(KM_RIGHT, AKEYCODE_DPAD_RIGHT); - //KM(KM_JUMP, AKEYCODE_DPAD_CENTER); - //KM(KM_DESTROY, AKEYCODE_BUTTON_L1); - //KM(KM_PLACE, AKEYCODE_BUTTON_R1); - //KM(KM_MENU_UP, AKEYCODE_DPAD_UP); - //KM(KM_MENU_DOWN, AKEYCODE_DPAD_DOWN); - //KM(KM_MENU_LEFT, AKEYCODE_DPAD_LEFT); - //KM(KM_MENU_RIGHT, AKEYCODE_DPAD_RIGHT); - //KM(KM_MENU_OK, AKEYCODE_DPAD_CENTER); - //KM(KM_MENU_CANCEL, AKEYCODE_BACK); + //BM(BM_FORWARD, AKEYCODE_DPAD_UP); + //BM(BM_LEFT, AKEYCODE_DPAD_LEFT); + //BM(BM_BACKWARD, AKEYCODE_DPAD_DOWN); + //BM(BM_RIGHT, AKEYCODE_DPAD_RIGHT); + //BM(BM_JUMP, AKEYCODE_DPAD_CENTER); + //BM(BM_DESTROY, AKEYCODE_BUTTON_L1); + //BM(BM_PLACE, AKEYCODE_BUTTON_R1); + //BM(BM_MENU_UP, AKEYCODE_DPAD_UP); + //BM(BM_MENU_DOWN, AKEYCODE_DPAD_DOWN); + //BM(BM_MENU_LEFT, AKEYCODE_DPAD_LEFT); + //BM(BM_MENU_RIGHT, AKEYCODE_DPAD_RIGHT); + //BM(BM_MENU_OK, AKEYCODE_DPAD_CENTER); + //BM(BM_MENU_CANCEL, AKEYCODE_BACK); //custom - //KM(KM_INVENTORY, AKEYCODE_BUTTON_Y); - //KM(KM_SLOT_R, AKEYCODE_BACK); - //KM(KM_SLOT_L, AKEYCODE_BUTTON_X); - //KM(KM_FLY_UP, AKEYCODE_BUTTON_R1); - //KM(KM_FLY_DOWN, AKEYCODE_BUTTON_L1); + //BM(BM_INVENTORY, AKEYCODE_BUTTON_Y); + //BM(BM_SLOT_R, AKEYCODE_BACK); + //BM(BM_SLOT_L, AKEYCODE_BUTTON_X); + //BM(BM_FLY_UP, AKEYCODE_BUTTON_R1); + //BM(BM_FLY_DOWN, AKEYCODE_BUTTON_L1); //use controller input on android for now. - KM(KM_FORWARD, AKEYCODE_W); - KM(KM_LEFT, AKEYCODE_A); - KM(KM_BACKWARD, AKEYCODE_S); - KM(KM_RIGHT, AKEYCODE_D); - KM(KM_JUMP, AKEYCODE_BUTTON_A); - KM(KM_DESTROY, AKEYCODE_X); - KM(KM_PLACE, AKEYCODE_C); - KM(KM_MENU_UP, AKEYCODE_DPAD_UP); - KM(KM_MENU_DOWN, AKEYCODE_DPAD_DOWN); - KM(KM_MENU_LEFT, AKEYCODE_DPAD_LEFT); - KM(KM_MENU_RIGHT, AKEYCODE_DPAD_RIGHT); - KM(KM_MENU_TAB_LEFT, AKEYCODE_BUTTON_L1); - KM(KM_MENU_TAB_RIGHT, AKEYCODE_BUTTON_R1); - KM(KM_MENU_OK, AKEYCODE_ENTER); - KM(KM_MENU_CANCEL, AKEYCODE_BUTTON_B); - KM(KM_MENU_PAUSE, AKEYCODE_BUTTON_START); + BM(BM_FORWARD, AKEYCODE_W); + BM(BM_LEFT, AKEYCODE_A); + BM(BM_BACKWARD, AKEYCODE_S); + BM(BM_RIGHT, AKEYCODE_D); + BM(BM_JUMP, AKEYCODE_BUTTON_A); + BM(BM_DESTROY, AKEYCODE_X); + BM(BM_PLACE, AKEYCODE_C); + BM(BM_MENU_UP, AKEYCODE_DPAD_UP); + BM(BM_MENU_DOWN, AKEYCODE_DPAD_DOWN); + BM(BM_MENU_LEFT, AKEYCODE_DPAD_LEFT); + BM(BM_MENU_RIGHT, AKEYCODE_DPAD_RIGHT); + BM(BM_MENU_TAB_LEFT, AKEYCODE_BUTTON_L1); + BM(BM_MENU_TAB_RIGHT, AKEYCODE_BUTTON_R1); + BM(BM_MENU_OK, AKEYCODE_ENTER); + BM(BM_MENU_CANCEL, AKEYCODE_BUTTON_B); + BM(BM_MENU_PAUSE, AKEYCODE_BUTTON_START); // custom - KM(KM_SLOT_L, AKEYCODE_BUTTON_L1); - KM(KM_SLOT_R, AKEYCODE_BUTTON_R1); - KM(KM_DROP, AKEYCODE_Q); - KM(KM_CHAT, AKEYCODE_T); - KM(KM_FOG, AKEYCODE_F); - KM(KM_INVENTORY, AKEYCODE_BUTTON_Y); - KM(KM_SNEAK, AKEYCODE_SHIFT_LEFT); - KM(KM_SLOT_1, AKEYCODE_1); - KM(KM_SLOT_2, AKEYCODE_2); - KM(KM_SLOT_3, AKEYCODE_3); - KM(KM_SLOT_4, AKEYCODE_4); - KM(KM_SLOT_5, AKEYCODE_5); - KM(KM_SLOT_6, AKEYCODE_6); - KM(KM_SLOT_7, AKEYCODE_7); - KM(KM_SLOT_8, AKEYCODE_8); - KM(KM_SLOT_9, AKEYCODE_9); - KM(KM_CONTAINER_QUICKMOVE, AKEYCODE_BUTTON_Y); - KM(KM_CONTAINER_SPLIT, AKEYCODE_BUTTON_X); - KM(KM_TOGGLEGUI, AKEYCODE_F1); - KM(KM_SCREENSHOT, AKEYCODE_F2); - KM(KM_TOGGLEDEBUG, AKEYCODE_F3); - KM(KM_TOGGLEAO, AKEYCODE_F4); - KM(KM_TOGGLE3RD, AKEYCODE_F5); - KM(KM_FLY_UP, AKEYCODE_C); - KM(KM_FLY_DOWN, AKEYCODE_X); - KM(KM_CHAT_CMD, AKEYCODE_SLASH); + BM(BM_SLOT_L, AKEYCODE_BUTTON_L1); + BM(BM_SLOT_R, AKEYCODE_BUTTON_R1); + BM(BM_DROP, AKEYCODE_Q); + BM(BM_CHAT, AKEYCODE_T); + BM(BM_FOG, AKEYCODE_F); + BM(BM_INVENTORY, AKEYCODE_BUTTON_Y); + BM(BM_SNEAK, AKEYCODE_SHIFT_LEFT); + BM(BM_SLOT_1, AKEYCODE_1); + BM(BM_SLOT_2, AKEYCODE_2); + BM(BM_SLOT_3, AKEYCODE_3); + BM(BM_SLOT_4, AKEYCODE_4); + BM(BM_SLOT_5, AKEYCODE_5); + BM(BM_SLOT_6, AKEYCODE_6); + BM(BM_SLOT_7, AKEYCODE_7); + BM(BM_SLOT_8, AKEYCODE_8); + BM(BM_SLOT_9, AKEYCODE_9); + BM(BM_CONTAINER_QUICKMOVE, AKEYCODE_BUTTON_Y); + BM(BM_CONTAINER_SPLIT, AKEYCODE_BUTTON_X); + BM(BM_TOGGLEGUI, AKEYCODE_F1); + BM(BM_SCREENSHOT, AKEYCODE_F2); + BM(BM_TOGGLEDEBUG, AKEYCODE_F3); + BM(BM_TOGGLEAO, AKEYCODE_F4); + BM(BM_TOGGLE3RD, AKEYCODE_F5); + BM(BM_FLY_UP, AKEYCODE_C); + BM(BM_FLY_DOWN, AKEYCODE_X); + BM(BM_CHAT_CMD, AKEYCODE_SLASH); #endif -#undef KM - -#define BTN(idx,code) m_controlMappings[idx].bind.buttonId = code - BTN(KM_TOGGLEDEBUG, GameController::BUTTON_GUIDE); - BTN(KM_JUMP, GameController::BUTTON_A); - BTN(KM_MENU_UP, GameController::BUTTON_DPAD_UP); - BTN(KM_MENU_DOWN, GameController::BUTTON_DPAD_DOWN); - BTN(KM_MENU_LEFT, GameController::BUTTON_DPAD_LEFT); - BTN(KM_MENU_RIGHT, GameController::BUTTON_DPAD_RIGHT); - BTN(KM_MENU_TAB_LEFT, GameController::BUTTON_LEFTSHOULDER); - BTN(KM_MENU_TAB_RIGHT, GameController::BUTTON_RIGHTSHOULDER); - BTN(KM_MENU_OK, GameController::BUTTON_A); - BTN(KM_MENU_CANCEL, GameController::BUTTON_B); - BTN(KM_MENU_PAUSE, GameController::BUTTON_START); - BTN(KM_DROP, GameController::BUTTON_B); - BTN(KM_CHAT, GameController::BUTTON_BACK); - BTN(KM_INVENTORY, GameController::BUTTON_Y); - BTN(KM_SNEAK, GameController::BUTTON_RIGHTSTICK); - BTN(KM_CONTAINER_QUICKMOVE, GameController::BUTTON_Y); - BTN(KM_CONTAINER_SPLIT, GameController::BUTTON_X); - BTN(KM_TOGGLE3RD, GameController::BUTTON_LEFTSTICK); - BTN(KM_SLOT_L, GameController::BUTTON_LEFTSHOULDER); - BTN(KM_SLOT_R, GameController::BUTTON_RIGHTSHOULDER); - BTN(KM_FLY_UP, GameController::BUTTON_A); - BTN(KM_FLY_DOWN, GameController::BUTTON_RIGHTSTICK); +#undef BM + +#define BTN(idx,code) m_buttonMappings[idx].info.controllerButtonId = code + BTN(BM_TOGGLEDEBUG, GameController::BUTTON_GUIDE); + BTN(BM_JUMP, GameController::BUTTON_A); + BTN(BM_MENU_UP, GameController::BUTTON_DPAD_UP); + BTN(BM_MENU_DOWN, GameController::BUTTON_DPAD_DOWN); + BTN(BM_MENU_LEFT, GameController::BUTTON_DPAD_LEFT); + BTN(BM_MENU_RIGHT, GameController::BUTTON_DPAD_RIGHT); + BTN(BM_MENU_TAB_LEFT, GameController::BUTTON_LEFTSHOULDER); + BTN(BM_MENU_TAB_RIGHT, GameController::BUTTON_RIGHTSHOULDER); + BTN(BM_MENU_OK, GameController::BUTTON_A); + BTN(BM_MENU_CANCEL, GameController::BUTTON_B); + BTN(BM_MENU_PAUSE, GameController::BUTTON_START); + BTN(BM_DROP, GameController::BUTTON_B); + BTN(BM_CHAT, GameController::BUTTON_BACK); + BTN(BM_INVENTORY, GameController::BUTTON_Y); + BTN(BM_SNEAK, GameController::BUTTON_RIGHTSTICK); + BTN(BM_CONTAINER_QUICKMOVE, GameController::BUTTON_Y); + BTN(BM_CONTAINER_SPLIT, GameController::BUTTON_X); + BTN(BM_TOGGLE3RD, GameController::BUTTON_LEFTSTICK); + BTN(BM_SLOT_L, GameController::BUTTON_LEFTSHOULDER); + BTN(BM_SLOT_R, GameController::BUTTON_RIGHTSHOULDER); + BTN(BM_FLY_UP, GameController::BUTTON_A); + BTN(BM_FLY_DOWN, GameController::BUTTON_RIGHTSTICK); #undef BTN } diff --git a/source/client/options/Options.hpp b/source/client/options/Options.hpp index adeba0084..7ba657055 100644 --- a/source/client/options/Options.hpp +++ b/source/client/options/Options.hpp @@ -20,80 +20,80 @@ #include "client/player/input/GameController.hpp" #include "client/resources/ResourcePackManager.hpp" -enum eControlMappingIndex +enum eButtonMappingIndex { - KM_FORWARD, - KM_LEFT, - KM_BACKWARD, - KM_RIGHT, - KM_JUMP, - KM_INVENTORY, - KM_DROP, - KM_CHAT, - KM_FOG, - KM_SNEAK, - KM_DESTROY, - KM_PLACE, - KM_MENU_UP, - KM_MENU_DOWN, - KM_MENU_LEFT, - KM_MENU_RIGHT, - KM_MENU_TAB_LEFT, - KM_MENU_TAB_RIGHT, - KM_MENU_OK, - KM_MENU_CANCEL, KM_BACK = KM_MENU_CANCEL, - KM_MENU_PAUSE, - KM_SLOT_1, - KM_SLOT_2, - KM_SLOT_3, - KM_SLOT_4, - KM_SLOT_5, - KM_SLOT_6, - KM_SLOT_7, - KM_SLOT_8, - KM_SLOT_9, - KM_SLOT_L, - KM_SLOT_R, - KM_CONTAINER_QUICKMOVE, - KM_CONTAINER_SPLIT, - KM_TOGGLEGUI, - KM_SCREENSHOT, - KM_TOGGLEDEBUG, - KM_TOGGLEAO, - KM_TOGGLE3RD, - KM_FLY_UP, - KM_FLY_DOWN, - KM_CHAT_CMD, // called "Open Chat" in Release 1.8 - KM_COUNT + BM_FORWARD, + BM_LEFT, + BM_BACKWARD, + BM_RIGHT, + BM_JUMP, + BM_INVENTORY, + BM_DROP, + BM_CHAT, + BM_FOG, + BM_SNEAK, + BM_DESTROY, + BM_PLACE, + BM_MENU_UP, + BM_MENU_DOWN, + BM_MENU_LEFT, + BM_MENU_RIGHT, + BM_MENU_TAB_LEFT, + BM_MENU_TAB_RIGHT, + BM_MENU_OK, + BM_MENU_CANCEL, BM_BACK = BM_MENU_CANCEL, + BM_MENU_PAUSE, + BM_SLOT_1, + BM_SLOT_2, + BM_SLOT_3, + BM_SLOT_4, + BM_SLOT_5, + BM_SLOT_6, + BM_SLOT_7, + BM_SLOT_8, + BM_SLOT_9, + BM_SLOT_L, + BM_SLOT_R, + BM_CONTAINER_QUICKMOVE, + BM_CONTAINER_SPLIT, + BM_TOGGLEGUI, + BM_SCREENSHOT, + BM_TOGGLEDEBUG, + BM_TOGGLEAO, + BM_TOGGLE3RD, + BM_FLY_UP, + BM_FLY_DOWN, + BM_CHAT_CMD, // called "Open Chat" in Release 1.8 + BM_COUNT }; -struct ControlBind +struct ButtonInfo { //@TODO: Replace this with an universal key int keyId; - GameController::EngineButtonID buttonId; + GameController::EngineButtonID controllerButtonId; - ControlBind() : keyId(-1), buttonId(GameController::BUTTON_NONE) {} - ControlBind(int key, GameController::EngineButtonID button) : keyId(key), buttonId(button) {} + ButtonInfo() : keyId(-1), controllerButtonId(GameController::BUTTON_NONE) {} + ButtonInfo(int key, GameController::EngineButtonID button) : keyId(key), controllerButtonId(button) {} bool isKey(int key) const { return keyId >= 0 && key == keyId; } - bool isButton(GameController::EngineButtonID button) const { return buttonId > GameController::BUTTON_NONE && button == buttonId; } - bool operator==(const ControlBind& other) const + bool isControllerButton(GameController::EngineButtonID button) const { return controllerButtonId > GameController::BUTTON_NONE && button == controllerButtonId; } + bool operator==(const ButtonInfo& other) const { - return isKey(other.keyId) || isButton(other.buttonId); + return isKey(other.keyId) || isControllerButton(other.controllerButtonId); } }; -struct ControlMapping +struct ButtonMapping { std::string key; - ControlBind bind; + ButtonInfo info; int timesPressed; - ControlMapping() : timesPressed(0) {} // key is automatically clear when constructed - ControlMapping(const char* keyName, int keyCode) : key(keyName), timesPressed(0) + ButtonMapping() : timesPressed(0) {} // key is automatically clear when constructed + ButtonMapping(const char* keyName, int keyCode) : key(keyName), timesPressed(0) { - bind.keyId = keyCode; + info.keyId = keyCode; } void pressed() { ++timesPressed; } @@ -396,12 +396,12 @@ class Options const AsyncTask& save(); std::vector getOptionStrings(); - int getKey(eControlMappingIndex idx) const { return m_controlMappings[idx].bind.keyId; } - bool isKey(eControlMappingIndex idx, int keyCode) const { return getKey(idx) == keyCode; } + int getKey(eButtonMappingIndex idx) const { return m_buttonMappings[idx].info.keyId; } + bool isKey(eButtonMappingIndex idx, int keyCode) const { return getKey(idx) == keyCode; } - ControlMapping& getControlMapping(eControlMappingIndex idx) { return m_controlMappings[idx]; } - const ControlBind& getControl(eControlMappingIndex idx) const { return m_controlMappings[idx].bind; } - bool isControl(eControlMappingIndex idx, const ControlBind& bind) const { return m_controlMappings[idx].bind == bind; } + ButtonMapping& getButtonMapping(eButtonMappingIndex idx) { return m_buttonMappings[idx]; } + const ButtonInfo& getButton(eButtonMappingIndex idx) const { return m_buttonMappings[idx].info; } + bool isButton(eButtonMappingIndex idx, const ButtonInfo& info) const { return m_buttonMappings[idx].info == info; } void loadControls(); void reset(); @@ -415,7 +415,7 @@ class Options HashMap m_options; AsyncTask m_saveTask; std::string m_filePath; - ControlMapping m_controlMappings[KM_COUNT]; + ButtonMapping m_buttonMappings[BM_COUNT]; public: friend class BoolOption; diff --git a/source/client/player/LocalPlayer.cpp b/source/client/player/LocalPlayer.cpp index ec62ed15b..607419d0c 100644 --- a/source/client/player/LocalPlayer.cpp +++ b/source/client/player/LocalPlayer.cpp @@ -200,9 +200,9 @@ void LocalPlayer::calculateFlight(const Vec3& pos) float z1 = f1 * pos.z; float y1 = 0.0f; - if (Keyboard::isKeyDown(m_pMinecraft->getOptions()->getKey(KM_FLY_UP))) + if (Keyboard::isKeyDown(m_pMinecraft->getOptions()->getKey(BM_FLY_UP))) y1 = f1 * 0.2f; - if (Keyboard::isKeyDown(m_pMinecraft->getOptions()->getKey(KM_FLY_DOWN))) + if (Keyboard::isKeyDown(m_pMinecraft->getOptions()->getKey(BM_FLY_DOWN))) y1 = f1 * -0.2f; field_BFC += x1; diff --git a/source/client/player/input/ControllerMoveInput.cpp b/source/client/player/input/ControllerMoveInput.cpp index 2da8e9475..487d31022 100644 --- a/source/client/player/input/ControllerMoveInput.cpp +++ b/source/client/player/input/ControllerMoveInput.cpp @@ -43,9 +43,9 @@ void ControllerMoveInput::tick(Player* player) IMoveInput::tick(player); } -void ControllerMoveInput::setKey(eControlMappingIndex ctrl, bool eventKeyState) +void ControllerMoveInput::setKey(eButtonMappingIndex ctrl, bool eventKeyState) { - if (ctrl == KM_SNEAK) + if (ctrl == BM_SNEAK) { if (eventKeyState) KeyboardInput::setKey(ctrl, m_keys[INPUT_SNEAK] ^ 1); diff --git a/source/client/player/input/ControllerMoveInput.hpp b/source/client/player/input/ControllerMoveInput.hpp index 62e073982..3ac067dc3 100644 --- a/source/client/player/input/ControllerMoveInput.hpp +++ b/source/client/player/input/ControllerMoveInput.hpp @@ -12,7 +12,7 @@ class ControllerMoveInput : public KeyboardInput ControllerMoveInput(Options *options); void tick(Player *player) override; - void setKey(eControlMappingIndex, bool eventKeyState) override; + void setKey(eButtonMappingIndex, bool eventKeyState) override; void releaseAllKeys() override; }; diff --git a/source/client/player/input/CustomInputHolder.cpp b/source/client/player/input/CustomInputHolder.cpp index 8f3d78600..ab260ade6 100644 --- a/source/client/player/input/CustomInputHolder.cpp +++ b/source/client/player/input/CustomInputHolder.cpp @@ -14,9 +14,9 @@ CustomInputHolder::CustomInputHolder(IMoveInput* pMoveInput, ITurnInput* pTurnIn setInputs(pMoveInput, pTurnInput, pBuildInput); } -bool CustomInputHolder::allowsType(Type type) const +bool CustomInputHolder::allowsType(InputType::Name type) const { - if (m_bIsController) return type == CONTROLLER; + if (m_bIsController) return type == InputType::CONTROLLER; return IInputHolder::allowsType(type); } diff --git a/source/client/player/input/CustomInputHolder.hpp b/source/client/player/input/CustomInputHolder.hpp index af49844cf..544e6fe0e 100644 --- a/source/client/player/input/CustomInputHolder.hpp +++ b/source/client/player/input/CustomInputHolder.hpp @@ -15,7 +15,7 @@ class CustomInputHolder : public IInputHolder public: CustomInputHolder(IMoveInput*, ITurnInput*, IBuildInput*, bool isController = false); - bool allowsType(Type) const override; + bool allowsType(InputType::Name) const override; IMoveInput* getMoveInput() override; ITurnInput* getTurnInput() override; IBuildInput* getBuildInput() override; diff --git a/source/client/player/input/GameControllerManager.cpp b/source/client/player/input/GameControllerManager.cpp index 6580508db..f5751a58d 100644 --- a/source/client/player/input/GameControllerManager.cpp +++ b/source/client/player/input/GameControllerManager.cpp @@ -9,7 +9,7 @@ #include #include "GameControllerManager.hpp" -#include "IInputHolder.hpp" +#include "client/app/Minecraft.hpp" const float GameControllerManager::DIRECTION_X_THRESHOLD = 0.3f; const float GameControllerManager::DIRECTION_Y_THRESHOLD = 0.3f; @@ -35,7 +35,7 @@ void GameControllerManager::feedButton(GameController::ButtonState state, GameCo return; } - IInputHolder::activeType = IInputHolder::CONTROLLER; + Minecraft::setInputType(InputType::CONTROLLER); GameController::ButtonEvent event; event.state = state; @@ -118,7 +118,7 @@ void GameControllerManager::feedStickX(GameController::StickID stickId, bool tou inReset = false; if (x != 0.0f) - IInputHolder::activeType = IInputHolder::CONTROLLER; + Minecraft::setInputType(InputType::CONTROLLER); } void GameControllerManager::feedStickY(GameController::StickID stickId, bool touched, float y) @@ -141,7 +141,7 @@ void GameControllerManager::feedStickY(GameController::StickID stickId, bool tou inReset = false; if (y != 0.0f) - IInputHolder::activeType = IInputHolder::CONTROLLER; + Minecraft::setInputType(InputType::CONTROLLER); } void GameControllerManager::feedStick(GameController::StickID stickId, bool touched, float x, float y) diff --git a/source/client/player/input/IInputHolder.cpp b/source/client/player/input/IInputHolder.cpp index 69f1a2d64..0b04c53b8 100644 --- a/source/client/player/input/IInputHolder.cpp +++ b/source/client/player/input/IInputHolder.cpp @@ -9,8 +9,6 @@ #include "IInputHolder.hpp" #include "Mouse.hpp" -IInputHolder::Type IInputHolder::activeType = KEYBOARD; - IInputHolder::IInputHolder() : m_feedbackX(0), m_feedbackY(0) @@ -35,7 +33,7 @@ void IInputHolder::setScreenSize(int width, int height) getBuildInput()->setScreenSize(width, height); } -bool IInputHolder::allowsType(Type type) const +bool IInputHolder::allowsType(InputType::Name type) const { - return type == KEYBOARD || type == MOUSE; + return type == InputType::KEYBOARD || type == InputType::MOUSE; } diff --git a/source/client/player/input/IInputHolder.hpp b/source/client/player/input/IInputHolder.hpp index 0aa9448c3..a6a4c831f 100644 --- a/source/client/player/input/IInputHolder.hpp +++ b/source/client/player/input/IInputHolder.hpp @@ -11,23 +11,16 @@ #include "IMoveInput.hpp" #include "ITurnInput.hpp" #include "IBuildInput.hpp" +#include "InputType.hpp" class IInputHolder { public: - enum Type - { - KEYBOARD, - MOUSE, - CONTROLLER, - TOUCHSCREEN - }; - IInputHolder(); virtual ~IInputHolder(); virtual bool allowPicking(); virtual void setScreenSize(int width, int height); - virtual bool allowsType(Type) const; + virtual bool allowsType(InputType::Name) const; virtual IMoveInput* getMoveInput() = 0; virtual ITurnInput* getTurnInput() = 0; virtual IBuildInput* getBuildInput() = 0; @@ -39,9 +32,5 @@ class IInputHolder float m_feedbackX; float m_feedbackY; float m_feedbackAlpha; - -public: - static Type activeType; - static Type lastType; }; diff --git a/source/client/player/input/IMoveInput.cpp b/source/client/player/input/IMoveInput.cpp index 385213791..a076a796a 100644 --- a/source/client/player/input/IMoveInput.cpp +++ b/source/client/player/input/IMoveInput.cpp @@ -30,7 +30,7 @@ void IMoveInput::render(float f) { } -void IMoveInput::setKey(eControlMappingIndex, bool eventKeyState) +void IMoveInput::setKey(eButtonMappingIndex, bool eventKeyState) { } diff --git a/source/client/player/input/IMoveInput.hpp b/source/client/player/input/IMoveInput.hpp index 862b1cb56..a0e40ddde 100644 --- a/source/client/player/input/IMoveInput.hpp +++ b/source/client/player/input/IMoveInput.hpp @@ -34,7 +34,7 @@ class IMoveInput virtual void releaseAllKeys(); virtual void render(float f); - virtual void setKey(eControlMappingIndex, bool eventKeyState); + virtual void setKey(eButtonMappingIndex, bool eventKeyState); virtual void setScreenSize(int width, int height); virtual void tick(Player*); diff --git a/source/client/player/input/InputType.hpp b/source/client/player/input/InputType.hpp new file mode 100644 index 000000000..7ff3b2cb6 --- /dev/null +++ b/source/client/player/input/InputType.hpp @@ -0,0 +1,13 @@ +#pragma once + +class InputType +{ +public: + enum Name + { + KEYBOARD, + MOUSE, + CONTROLLER, + TOUCHSCREEN + }; +}; \ No newline at end of file diff --git a/source/client/player/input/Keyboard.cpp b/source/client/player/input/Keyboard.cpp index 2fefc279b..f32566140 100644 --- a/source/client/player/input/Keyboard.cpp +++ b/source/client/player/input/Keyboard.cpp @@ -8,7 +8,7 @@ #include #include "Keyboard.hpp" -#include "IInputHolder.hpp" +#include "client/app/Minecraft.hpp" #include "GameMods.hpp" @@ -23,7 +23,7 @@ void Keyboard::feed(KeyState state, int key) return; } - IInputHolder::activeType = IInputHolder::KEYBOARD; + Minecraft::setInputType(InputType::KEYBOARD); _inputs.push_back(KeyboardAction(key, state)); diff --git a/source/client/player/input/KeyboardInput.cpp b/source/client/player/input/KeyboardInput.cpp index ff9bb2040..b76118eb5 100644 --- a/source/client/player/input/KeyboardInput.cpp +++ b/source/client/player/input/KeyboardInput.cpp @@ -29,17 +29,17 @@ void KeyboardInput::releaseAllKeys() m_keys[i] = false; } -void KeyboardInput::setKey(eControlMappingIndex ctrl, bool eventKeyState) +void KeyboardInput::setKey(eButtonMappingIndex ctrl, bool eventKeyState) { int index; switch (ctrl) { - case KM_FORWARD: index = INPUT_FORWARD; break; - case KM_BACKWARD: index = INPUT_BACKWARD; break; - case KM_LEFT: index = INPUT_LEFT; break; - case KM_RIGHT: index = INPUT_RIGHT; break; - case KM_JUMP: index = INPUT_JUMP; break; - case KM_SNEAK: index = INPUT_SNEAK; break; + case BM_FORWARD: index = INPUT_FORWARD; break; + case BM_BACKWARD: index = INPUT_BACKWARD; break; + case BM_LEFT: index = INPUT_LEFT; break; + case BM_RIGHT: index = INPUT_RIGHT; break; + case BM_JUMP: index = INPUT_JUMP; break; + case BM_SNEAK: index = INPUT_SNEAK; break; default: index = -1; return; } diff --git a/source/client/player/input/KeyboardInput.hpp b/source/client/player/input/KeyboardInput.hpp index ae09499a4..ba5695f3e 100644 --- a/source/client/player/input/KeyboardInput.hpp +++ b/source/client/player/input/KeyboardInput.hpp @@ -20,7 +20,7 @@ class KeyboardInput : public IMoveInput KeyboardInput(Options*); void releaseAllKeys() override; - void setKey(eControlMappingIndex, bool eventKeyState) override; + void setKey(eButtonMappingIndex, bool eventKeyState) override; void tick(Player*) override; public: diff --git a/source/client/player/input/MouseDevice.cpp b/source/client/player/input/MouseDevice.cpp index 450e451e6..790b13611 100644 --- a/source/client/player/input/MouseDevice.cpp +++ b/source/client/player/input/MouseDevice.cpp @@ -8,7 +8,7 @@ #include #include "MouseDevice.hpp" -#include "IInputHolder.hpp" +#include "client/app/Minecraft.hpp" MouseDevice::MouseDevice() { @@ -27,7 +27,7 @@ void MouseDevice::feed(MouseButtonType buttonType, bool buttonState, int posX, i if (buttonType != MOUSE_BUTTON_NONE) { _inputs.push_back(MouseAction(buttonType, buttonState, posX, posY, 0)); - IInputHolder::activeType = IInputHolder::MOUSE; + Minecraft::setInputType(InputType::MOUSE); } // Make sure button type is valid diff --git a/source/client/player/input/Multitouch.cpp b/source/client/player/input/Multitouch.cpp index 81dd970e9..61f420be0 100644 --- a/source/client/player/input/Multitouch.cpp +++ b/source/client/player/input/Multitouch.cpp @@ -8,7 +8,7 @@ #include #include "Multitouch.hpp" -#include "IInputHolder.hpp" +#include "client/app/Minecraft.hpp" int Multitouch::_activePointerCount; int Multitouch::_activePointerList[MAX_TOUCHES]; @@ -51,7 +51,7 @@ void Multitouch::feed(MouseButtonType a1, bool a2, int a3, int a4, int fingerId) MouseDevice* pDevice = g(fingerId); pDevice->feed(a1, a2, a3, a4); - IInputHolder::activeType = IInputHolder::TOUCHSCREEN; + Minecraft::setInputType(InputType::TOUCHSCREEN); if (a1 != MOUSE_BUTTON_NONE) { diff --git a/source/client/player/input/TouchInputHolder.cpp b/source/client/player/input/TouchInputHolder.cpp index 06709abd8..bec4b8e97 100644 --- a/source/client/player/input/TouchInputHolder.cpp +++ b/source/client/player/input/TouchInputHolder.cpp @@ -39,9 +39,9 @@ bool TouchInputHolder::allowPicking() return false; } -bool TouchInputHolder::allowsType(Type type) const +bool TouchInputHolder::allowsType(InputType::Name type) const { - return type == TOUCHSCREEN; + return type == InputType::TOUCHSCREEN; } IMoveInput* TouchInputHolder::getMoveInput() diff --git a/source/client/player/input/TouchInputHolder.hpp b/source/client/player/input/TouchInputHolder.hpp index f3c383497..ce8c8d125 100644 --- a/source/client/player/input/TouchInputHolder.hpp +++ b/source/client/player/input/TouchInputHolder.hpp @@ -20,7 +20,7 @@ class TouchInputHolder : public IInputHolder public: TouchInputHolder(Minecraft*, Options*); bool allowPicking() override; - bool allowsType(Type) const override; + bool allowsType(InputType::Name) const override; IMoveInput* getMoveInput() override; ITurnInput* getTurnInput() override; IBuildInput* getBuildInput() override; diff --git a/source/client/player/input/TouchscreenInput_TestFps.cpp b/source/client/player/input/TouchscreenInput_TestFps.cpp index 38f2d7bf7..9a8de79b1 100644 --- a/source/client/player/input/TouchscreenInput_TestFps.cpp +++ b/source/client/player/input/TouchscreenInput_TestFps.cpp @@ -48,7 +48,7 @@ void TouchscreenInput_TestFps::releaseAllKeys() field_6C[i] = false; } -void TouchscreenInput_TestFps::setKey(eControlMappingIndex, bool eventKeyState) +void TouchscreenInput_TestFps::setKey(eButtonMappingIndex, bool eventKeyState) { } diff --git a/source/client/player/input/TouchscreenInput_TestFps.hpp b/source/client/player/input/TouchscreenInput_TestFps.hpp index d19f93a98..c806f0577 100644 --- a/source/client/player/input/TouchscreenInput_TestFps.hpp +++ b/source/client/player/input/TouchscreenInput_TestFps.hpp @@ -24,7 +24,7 @@ class TouchscreenInput_TestFps : public IMoveInput, public GuiComponent // IMoveInput void releaseAllKeys() override; - void setKey(eControlMappingIndex, bool eventKeyState) override; + void setKey(eButtonMappingIndex, bool eventKeyState) override; void setScreenSize(int width, int height) override; void tick(Player*) override; void render(float f) override; diff --git a/source/client/renderer/Font.cpp b/source/client/renderer/Font.cpp index 4712bf336..f18d78426 100644 --- a/source/client/renderer/Font.cpp +++ b/source/client/renderer/Font.cpp @@ -32,7 +32,7 @@ void Font::init(Options* pOpts) TextureData* pTexture = m_pTextures->getTextureData(m_fileName, true); if (!pTexture) return; - for (int i = 0; i < FONT_CHARS_AMOUNT; i++) // character number + for (int i = 0; i < C_FONT_CHARS_AMOUNT; i++) // character number { // note: the 'widthMax' behavior is assumed. It might not be like that exactly int widthMax = 0; diff --git a/source/client/renderer/Font.hpp b/source/client/renderer/Font.hpp index 7823b5233..93b97b148 100644 --- a/source/client/renderer/Font.hpp +++ b/source/client/renderer/Font.hpp @@ -13,7 +13,7 @@ #include "renderer/MaterialPtr.hpp" #include "client/renderer/renderer/Tesselator.hpp" -#define FONT_CHARS_AMOUNT (256) +#define C_FONT_CHARS_AMOUNT (256) class Font { @@ -50,9 +50,9 @@ class Font private: int field_0; - int m_charWidthInt[FONT_CHARS_AMOUNT]; - float m_charWidthFloat[FONT_CHARS_AMOUNT]; - mce::Mesh m_charMeshes[FONT_CHARS_AMOUNT]; + int m_charWidthInt[C_FONT_CHARS_AMOUNT]; + float m_charWidthFloat[C_FONT_CHARS_AMOUNT]; + mce::Mesh m_charMeshes[C_FONT_CHARS_AMOUNT]; // huge gap, don't know why it's there... std::string m_fileName; Options* m_pOptions; diff --git a/source/client/renderer/ScreenRenderer.cpp b/source/client/renderer/ScreenRenderer.cpp index f7081f3de..14418bb84 100644 --- a/source/client/renderer/ScreenRenderer.cpp +++ b/source/client/renderer/ScreenRenderer.cpp @@ -116,22 +116,25 @@ void ScreenRenderer::blitTexture(Textures& textures, const std::string& texture, void ScreenRenderer::blitSprite(Textures& textures, const std::string& texture, int x, int y, int width, int height, mce::MaterialPtr* materialPtr, float u, float v, int uvWidth, int uvHeight) { - blitSprite(textures, textures.getGuiSprite(texture), x, y, width, height, materialPtr, u, v, uvWidth, uvHeight); + const TextureAtlasSprite* sprite = textures.getGuiSprite(texture); + if (sprite) + blitSprite(textures, *sprite, x, y, width, height, materialPtr, u, v, uvWidth, uvHeight); } -void ScreenRenderer::blitSprite(Textures& textures, const TextureAtlasSprite* sprite, int x, int y, int width, int height, mce::MaterialPtr* materialPtr, float u, float v, int uvWidth, int uvHeight) +void ScreenRenderer::blitSprite(Textures& textures, const TextureAtlasSprite& sprite, int x, int y, int width, int height, mce::MaterialPtr* materialPtr, float u, float v, int uvWidth, int uvHeight) { - if (!sprite || !sprite->m_pAtlas) return; + TextureData* tex = textures.getTextureData(sprite.atlasName, true); - TextureAtlas& atlas = *sprite->m_pAtlas; + if (!tex) return; + ImageData& data = tex->m_imageData; - float u0 = u ? sprite->minU + u / atlas.getWidth() : sprite->minU; - float u1 = u || uvWidth ? sprite->minU + (u + uvWidth) / atlas.getWidth() : sprite->maxU; - float v0 = v ? sprite->minV + v / atlas.getHeight() : sprite->minV; - float v1 = v || uvHeight ? sprite->minV + (v + uvHeight) / atlas.getHeight() : sprite->maxV; + float u0 = u ? sprite.minU + u / data.m_width : sprite.minU; + float u1 = u || uvWidth ? sprite.minU + (u + uvWidth) / data.m_width : sprite.maxU; + float v0 = v ? sprite.minV + v / data.m_height : sprite.minV; + float v1 = v || uvHeight ? sprite.minV + (v + uvHeight) / data.m_height : sprite.maxV; - textures.loadAndBindTexture(sprite->m_pAtlas->m_name); + tex->bind(); Tesselator& t = Tesselator::instance; t.begin(4); t.vertexUV(x, y + height, m_blitOffset, u0, v1); @@ -166,17 +169,16 @@ void ScreenRenderer::blitNineSlice(Textures& textures, const std::string* slices blitSprite(textures, slices[8], x + width - border, y + height - border, border, border, materialPtr, 0, 0, border, border); } -void ScreenRenderer::blitNineSlice(Textures& textures, const std::string& spriteName, int x, int y, int width, int height, int border, mce::MaterialPtr* materialPtr) +void ScreenRenderer::blitNineSlice(Textures& textures, const TextureAtlasSprite& sprite, int x, int y, int width, int height, int border, mce::MaterialPtr* materialPtr) { - const TextureAtlasSprite* sprite = textures.getGuiSprite(spriteName); - if (!sprite || !sprite->m_pAtlas) return; + if (!textures.getTextureData(sprite.atlasName, true)) return; - int iw = sprite->w; - int ih = sprite->h; + int iw = sprite.w; + int ih = sprite.h; if (iw == width && ih == height) { - blitSprite(textures, spriteName, x, y, width, height, materialPtr); + blitSprite(textures, sprite, x, y, width, height, materialPtr); return; } @@ -196,15 +198,22 @@ void ScreenRenderer::blitNineSlice(Textures& textures, const std::string& sprite return; } - blitSprite(textures, sprite, x, y, border, border, materialPtr, 0, 0, border, border); - blitSprite(textures, sprite, x + border, y, width - 2 * border, border, materialPtr, border, 0, border, border); - blitSprite(textures, sprite, x + width - border, y, border, border, materialPtr, iw - border, 0, border, border); - blitSprite(textures, sprite, x, y + border, border, height - 2 * border, materialPtr, 0, border, border, border); - blitSprite(textures, sprite, x + border, y + border, width - 2 * border, height - 2 * border, materialPtr, border, border, border, border); - blitSprite(textures, sprite, x + width - border, y + border, border, height - 2 * border, materialPtr, iw - border, border, border, border); - blitSprite(textures, sprite, x, y + height - border, border, border, materialPtr, 0, ih - border, border, border); - blitSprite(textures, sprite, x + border, y + height - border, width - 2 * border, border, materialPtr, border, ih - border, border, border); - blitSprite(textures, sprite, x + width - border, y + height - border, border, border, materialPtr, iw - border, ih - border, border, border); + blitSprite(textures, sprite, x, y, border, border, materialPtr, 0, 0, border, border); + blitSprite(textures, sprite, x + border, y, width - 2 * border, border, materialPtr, border, 0, border, border); + blitSprite(textures, sprite, x + width - border, y, border, border, materialPtr, iw - border, 0, border, border); + blitSprite(textures, sprite, x, y + border, border, height - 2 * border, materialPtr, 0, border, border, border); + blitSprite(textures, sprite, x + border, y + border, width - 2 * border, height - 2 * border, materialPtr, border, border, iw - 2 * border, ih - 2 * border); + blitSprite(textures, sprite, x + width - border, y + border, border, height - 2 * border, materialPtr, iw - border, border, border, border); + blitSprite(textures, sprite, x, y + height - border, border, border, materialPtr, 0, ih - border, border, border); + blitSprite(textures, sprite, x + border, y + height - border, width - 2 * border, border, materialPtr, border, ih - border, border, border); + blitSprite(textures, sprite, x + width - border, y + height - border, border, border, materialPtr, iw - border, ih - border, border, border); +} + +void ScreenRenderer::blitNineSlice(Textures& textures, const std::string& spriteName, int x, int y, int width, int height, int border, mce::MaterialPtr* materialPtr) +{ + const TextureAtlasSprite* sprite = textures.getGuiSprite(spriteName); + if (sprite) + blitNineSlice(textures, *sprite, x, y, width, height, border, materialPtr); } void ScreenRenderer::drawCenteredString(Font& font, const std::string& str, int cx, int cy, const Color& color) diff --git a/source/client/renderer/ScreenRenderer.hpp b/source/client/renderer/ScreenRenderer.hpp index 2bfe8effa..6e42c6e51 100644 --- a/source/client/renderer/ScreenRenderer.hpp +++ b/source/client/renderer/ScreenRenderer.hpp @@ -42,9 +42,10 @@ class ScreenRenderer void blitTexture(Textures&, const std::string&, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight, mce::MaterialPtr* materialPtr = nullptr); void blitTexture(Textures&, const std::string&, int x, int y, float u, float v, int width, int height, mce::MaterialPtr* materialPtr = nullptr); void blitSprite(Textures&, const std::string&, int x, int y, int width, int height, mce::MaterialPtr* materialPtr = nullptr, float u = 0, float v = 0, int uvWidth = 0, int uvHeight = 0); - void blitSprite(Textures&, const TextureAtlasSprite*, int x, int y, int width, int height, mce::MaterialPtr* materialPtr = nullptr, float u = 0, float v = 0, int uvWidth = 0, int uvHeight = 0); + void blitSprite(Textures&, const TextureAtlasSprite&, int x, int y, int width, int height, mce::MaterialPtr* materialPtr = nullptr, float u = 0, float v = 0, int uvWidth = 0, int uvHeight = 0); void blitRaw(float x1, float x2, float y1, float y2, float z, float u1, float u2, float v1, float v2); void blitNineSlice(Textures&, const std::string* slices, int x, int y, int width, int height, int tileSize, mce::MaterialPtr* materialPtr = nullptr); + void blitNineSlice(Textures&, const TextureAtlasSprite&, int x, int y, int width, int height, int border, mce::MaterialPtr* materialPtr = nullptr); void blitNineSlice(Textures&, const std::string&, int x, int y, int width, int height, int border, mce::MaterialPtr* materialPtr = nullptr); void drawCenteredString(Font& font, const std::string& str, int cx, int cy, const Color& color = Color::WHITE); void drawString(Font& font, const std::string& str, int cx, int cy, const Color& color = Color::WHITE); diff --git a/source/client/renderer/Textures.cpp b/source/client/renderer/Textures.cpp index 5fdc17b52..ab1c180e2 100644 --- a/source/client/renderer/Textures.cpp +++ b/source/client/renderer/Textures.cpp @@ -118,6 +118,12 @@ TextureData* Textures::uploadTexture(const std::string& name, TextureData& t) return result; } +TextureAtlas* Textures::getTextureAtlas(const std::string& name) +{ + TextureAtlasMap::iterator it = m_atlases.find(name); + return it != m_atlases.end() ? it->second : nullptr; +} + void Textures::unloadAll() { for (TextureMap::iterator it = m_textures.begin(); it != m_textures.end(); it++) @@ -276,6 +282,7 @@ void Textures::setupAtlas(TextureAtlas& atlas) { atlas.build(); uploadTexture(atlas.m_name, atlas.m_texture); + m_atlases[atlas.m_name] = &atlas; } const TextureAtlasSprite* Textures::getGuiSprite(const std::string& spriteTexture) diff --git a/source/client/renderer/Textures.hpp b/source/client/renderer/Textures.hpp index eb7a15a80..55090035c 100644 --- a/source/client/renderer/Textures.hpp +++ b/source/client/renderer/Textures.hpp @@ -13,6 +13,7 @@ #include "client/app/AppPlatform.hpp" #include "DynamicTexture.hpp" #include "texture/TextureAtlas.hpp" +#include "common/utility/HashMap.hpp" #define C_TERRAIN_NAME "terrain.png" #define C_ITEMS_NAME "gui/items.png" @@ -23,13 +24,15 @@ class DynamicTexture; // in case we are being included from DynamicTexture. We d class Textures { protected: - typedef std::map TextureMap; + typedef HashMap TextureMap; + typedef HashMap TextureAtlasMap; public: TextureData* loadTexture(const std::string& name, bool bRequired); TextureData* loadAndBindTexture(const std::string& name, bool isRequired = true, unsigned int textureUnit = 0); TextureData* getTextureData(const std::string& name, bool isRequired); TextureData* uploadTexture(const std::string& name, TextureData& t); + TextureAtlas* getTextureAtlas(const std::string& name); void unloadAll(); void clear(); void tick(); @@ -59,6 +62,7 @@ class Textures protected: TextureMap m_textures; + TextureAtlasMap m_atlases; int m_currBoundTex; bool m_bClamp; bool m_bBlur; diff --git a/source/client/renderer/texture/TextureAtlas.cpp b/source/client/renderer/texture/TextureAtlas.cpp index 1501a8d2a..22b1916e1 100644 --- a/source/client/renderer/texture/TextureAtlas.cpp +++ b/source/client/renderer/texture/TextureAtlas.cpp @@ -76,7 +76,7 @@ void TextureAtlas::_init() m_texture.m_imageData.release(); int size = getWidth() * getHeight() * 4; - uint8_t *mem = (uint8_t *)malloc(size); + uint8_t* mem = (uint8_t*)malloc(size); if (!mem) throw std::bad_alloc(); m_texture.m_imageData.m_data = mem; @@ -110,10 +110,9 @@ bool TextureAtlas::pack() blitSprite(pending.data, pending.width, pending.height, m_currentX, m_currentY); m_sprites[pending.name] = TextureAtlasSprite( - pending.name, m_currentX, m_currentY, pending.width, pending.height, - this + m_name, getWidth(), getHeight() ); m_currentX += pending.width; @@ -167,13 +166,12 @@ int TextureAtlas::getHeight() const return m_texture.m_imageData.m_height; } -TextureAtlasSprite::TextureAtlasSprite(const std::string& name, int x, int y, int width, int height, TextureAtlas* atlas) : +TextureAtlasSprite::TextureAtlasSprite(int x, int y, int width, int height, const std::string& atlasName, int atlasWidth, int atlasHeight) : IntRectangle(x, y, width, height), - name(name), - m_pAtlas(atlas) + atlasName(atlasName) { - minU = float(x) / atlas->getWidth(); - minV = float(y) / atlas->getHeight(); - maxU = float(x + width) / atlas->getWidth(); - maxV = float(y + height) / atlas->getHeight(); -} + minU = float(x) / atlasWidth; + minV = float(y) / atlasHeight; + maxU = float(x + width) / atlasWidth; + maxV = float(y + height) / atlasHeight; +} \ No newline at end of file diff --git a/source/client/renderer/texture/TextureAtlas.hpp b/source/client/renderer/texture/TextureAtlas.hpp index 9cf063257..75a2a04a4 100644 --- a/source/client/renderer/texture/TextureAtlas.hpp +++ b/source/client/renderer/texture/TextureAtlas.hpp @@ -9,25 +9,21 @@ #define DEFAULT_ATLAS_SIZE (256) #define MAX_ATLAS_SIZE (16384) -class TextureAtlas; - struct TextureAtlasSprite : IntRectangle { - std::string name; float minU, minV, maxU, maxV; - TextureAtlas* m_pAtlas; + std::string atlasName; TextureAtlasSprite() : IntRectangle(0, 0, 0, 0), minU(0.0f), minV(0.0f), maxU(0.0f), - maxV(0.0f), - m_pAtlas(nullptr) + maxV(0.0f) { } - TextureAtlasSprite(const std::string& name, int x, int y, int width, int height, TextureAtlas* atlas); + TextureAtlasSprite(int x, int y, int width, int height, const std::string& atlasName, int atlasWidth, int atlasHeight); }; struct PendingSprite diff --git a/source/common/utility/HashMap.hpp b/source/common/utility/HashMap.hpp index b9ea7800e..8fdf11cd7 100644 --- a/source/common/utility/HashMap.hpp +++ b/source/common/utility/HashMap.hpp @@ -291,7 +291,7 @@ class HashMap TKey& key() { return m_entries->at(m_index).pair.first; } TValue& value() { return m_entries->at(m_index).pair.second; } - std::pair* operator->() { return &m_entries->at(m_index); } + std::pair* operator->() { return &m_entries->at(m_index).pair; } private: std::vector >* m_entries; diff --git a/source/world/gamemode/CreativeMode.cpp b/source/world/gamemode/CreativeMode.cpp index 5b3d62645..22f79c05a 100644 --- a/source/world/gamemode/CreativeMode.cpp +++ b/source/world/gamemode/CreativeMode.cpp @@ -76,5 +76,4 @@ void CreativeMode::render(float f) void CreativeMode::initPlayer(Player* p) { p->m_rot.x = -180.0f; - p->m_pInventory->prepareCreativeInventory(); } diff --git a/source/world/item/Inventory.cpp b/source/world/item/Inventory.cpp index e0471397b..2b2c2e0a5 100644 --- a/source/world/item/Inventory.cpp +++ b/source/world/item/Inventory.cpp @@ -548,9 +548,6 @@ void Inventory::dropAll(bool onlyClearContainer) void Inventory::save(ListTag& tag) const { - if (_getGameMode() == GAME_TYPE_CREATIVE) - return; - for (size_t i = 0; i < m_items.size(); i++) { const ItemStack& item = m_items[i]; @@ -590,9 +587,6 @@ void Inventory::save(ListTag& tag) const void Inventory::load(const ListTag& tag) { - if (_getGameMode() == GAME_TYPE_CREATIVE) - return; - const std::vector& itemTags = tag.rawView(); for (std::vector::const_iterator it = itemTags.begin(); it != itemTags.end(); it++) @@ -622,8 +616,3 @@ void Inventory::load(const ListTag& tag) } } } - -GameType Inventory::_getGameMode() const -{ - return m_pPlayer->getPlayerGameType(); -} diff --git a/source/world/item/ItemStack.cpp b/source/world/item/ItemStack.cpp index de3a56dd0..e83f2fb32 100644 --- a/source/world/item/ItemStack.cpp +++ b/source/world/item/ItemStack.cpp @@ -157,8 +157,8 @@ int ItemStack::getIdAux() const CompoundTag* ItemStack::getNetworkUserData() const { CompoundTag* userData = new CompoundTag(); - CompoundTag::NamedTagMap& tags = m_userData->rawView(); - for (CompoundTag::NamedTagMap::iterator it = tags.begin(); it != tags.end(); it++) + const CompoundTag::NamedTagMap& tags = m_userData->rawView(); + for (CompoundTag::NamedTagMap::const_iterator it = tags.begin(); it != tags.end(); it++) { const std::string& name = it.key(); const Tag* tag = it.value(); diff --git a/source/world/level/Level.cpp b/source/world/level/Level.cpp index e68c42ece..fce4ee0ed 100644 --- a/source/world/level/Level.cpp +++ b/source/world/level/Level.cpp @@ -1265,6 +1265,9 @@ void Level::loadPlayer(Player& player) m_pLevelData->setLoadedPlayerTag(nullptr); //addEntity(&player); } + else if (player.isCreative()) + player.m_pInventory->prepareCreativeInventory(); + m_pLevelData->setLoadedPlayerTo(player); // 0.2.1 had us only adding the player if LevelData had a CompoundTag From 9c2b9118990fd5205763e4408e17567239ab489e Mon Sep 17 00:00:00 2001 From: Wilyicaro Date: Wed, 25 Feb 2026 04:03:03 -0300 Subject: [PATCH 08/11] renamings --- game/assets/lang/en_us.json | 2 +- source/client/app/Minecraft.cpp | 2 +- source/client/gui/Screen.cpp | 4 ++-- source/client/gui/Screen.hpp | 10 +++++----- source/client/gui/components/Button.cpp | 12 ++++++++---- source/client/gui/screens/PanelScreen_Console.cpp | 2 +- source/client/gui/screens/PauseScreen_Console.cpp | 2 +- .../client/gui/screens/StartMenuScreen_Console.cpp | 2 +- .../client/gui/screens/inventory/ContainerScreen.cpp | 2 +- source/client/options/Options.cpp | 3 ++- source/client/options/Options.hpp | 4 ++-- 11 files changed, 25 insertions(+), 20 deletions(-) diff --git a/game/assets/lang/en_us.json b/game/assets/lang/en_us.json index 337c2ace6..60fc2ba6c 100644 --- a/game/assets/lang/en_us.json +++ b/game/assets/lang/en_us.json @@ -79,7 +79,7 @@ "options.dynamicHand": "Dynamic Hand Movement", "options.autoJump": "Auto Jump", "options.splitControls": "Split Controls", - "options.useController": "Use Controller", + "options.controllerOnly": "Controller Only", "options.flightHax": "Flight Hax", "options.serverVisibleDefault": "Local Server Multiplayer", "options.debugText": "Debug Text", diff --git a/source/client/app/Minecraft.cpp b/source/client/app/Minecraft.cpp index 9a78beb31..a017a6f9b 100644 --- a/source/client/app/Minecraft.cpp +++ b/source/client/app/Minecraft.cpp @@ -383,7 +383,7 @@ bool Minecraft::useSplitControls() const bool Minecraft::useController() const { - return m_pPlatform->hasGamepad() && (getInputType() == InputType::CONTROLLER || getOptions()->m_bUseController.get()); + return m_pPlatform->hasGamepad() && (getInputType() == InputType::CONTROLLER || getOptions()->m_controllerOnly.get()); } void Minecraft::setGameMode(GameType gameType) diff --git a/source/client/gui/Screen.cpp b/source/client/gui/Screen.cpp index 95beb7c83..94e024246 100644 --- a/source/client/gui/Screen.cpp +++ b/source/client/gui/Screen.cpp @@ -47,7 +47,7 @@ Screen::Screen() m_bRenderPointer = false; m_lastTimeMoved = 0; m_cursorTick = 0; - m_themeSelection = UI_GENERIC; + m_screenType = SCREEN_GENERIC; m_uiTheme = UI_POCKET; } @@ -142,7 +142,7 @@ void Screen::init(Minecraft* pMinecraft, int width, int height) // Apply UI theme to current Screen based on user preference UITheme userTheme = pMinecraft->getOptions()->getUiTheme(); // We don't bother applying the console theme automatically for generic screens because this completely fucks scaling - if (m_themeSelection == UI_UNIVERSAL || (m_themeSelection == UI_GENERIC && userTheme != UI_CONSOLE)) + if (m_screenType == SCREEN_UNIVERSAL || (m_screenType == SCREEN_GENERIC && userTheme != UI_CONSOLE)) m_uiTheme = userTheme; setSize(width, height); diff --git a/source/client/gui/Screen.hpp b/source/client/gui/Screen.hpp index eeb1ed0ab..d1968b786 100644 --- a/source/client/gui/Screen.hpp +++ b/source/client/gui/Screen.hpp @@ -153,11 +153,11 @@ class Screen : public GuiComponent Screen* m_pScreen; }; - enum ThemeSelection + enum Type { - UI_SPECIFIC, // The Screen handles a specific UI Theme - UI_GENERIC, // The Screen is a Java / Pocket mix - UI_UNIVERSAL // The Screen automatically handles all UI themes + SCREEN_SPECIFIC, // The Screen handles a specific UI Theme + SCREEN_GENERIC, // The Screen is a Java / Pocket mix + SCREEN_UNIVERSAL // The Screen automatically handles all UI themes }; int m_width; @@ -170,7 +170,7 @@ class Screen : public GuiComponent GuiElement* m_pSelectedElement; Font* m_pFont; GuiElement* m_pClickedElement; - ThemeSelection m_themeSelection; + Type m_screenType; UITheme m_uiTheme; #ifndef ORIGINAL_CODE diff --git a/source/client/gui/components/Button.cpp b/source/client/gui/components/Button.cpp index 9e9952cdd..bbe56d909 100644 --- a/source/client/gui/components/Button.cpp +++ b/source/client/gui/components/Button.cpp @@ -47,8 +47,8 @@ void Button::_renderBgConsole(Minecraft* mc, const MenuPointer& pointer) float timer = (getTimeMs() % 1200) / 1200.0f; currentShaderColor.a *= 0.5f + (timer >= 0.5f ? 1 - timer : timer); blitSprite(texs, "gui/console/Graphics/MainMenuButton_Over.png", m_xPos, m_yPos, m_width, m_height, &m_materials.ui_textured_and_glcolor); - currentShaderColor = m_color; } + currentShaderColor = m_color; } void Button::_renderMessage(Font& font) @@ -69,14 +69,18 @@ void Button::_renderMessageConsole(Font& font) if (hasFocus()) { float timer = (getTimeMs() % 1200) / 1200.0f; - textColor = Color(220, 220, Mth::round((0.5f - (timer >= 0.5f ? 1 - timer : timer)) * 220), currentShaderColor.a); + textColor = Color(220, 220, Mth::round((0.5f - (timer >= 0.5f ? 1 - timer : timer)) * 220)); } else if (isSelected()) { - textColor = Color(220, 220, 0, currentShaderColor.a); // 0xDCDC00 + textColor = Color(220, 220, 0); // 0xDCDC00 } else - textColor = Color(224, 224, 224, currentShaderColor.a); // 0xE0E0E0U + textColor = Color(224, 224, 224); // 0xE0E0E0U + + if (!isEnabled()) + textColor.a *= 0.5f; + int textWidth = font.width(getMessage()) * 2; font.drawScalableShadow(getMessage(), m_xPos + (m_width - textWidth) / 2, m_yPos + (m_height - 16) / 2, textColor); } diff --git a/source/client/gui/screens/PanelScreen_Console.cpp b/source/client/gui/screens/PanelScreen_Console.cpp index 6be5760fc..03d7c0560 100644 --- a/source/client/gui/screens/PanelScreen_Console.cpp +++ b/source/client/gui/screens/PanelScreen_Console.cpp @@ -6,7 +6,7 @@ PanelScreen_Console::PanelScreen_Console(Screen* parent) : m_pParent(parent) , m_layout(this) { - m_themeSelection = UI_SPECIFIC; + m_screenType = SCREEN_SPECIFIC; m_uiTheme = UI_CONSOLE; m_bDeletePrevious = false; } diff --git a/source/client/gui/screens/PauseScreen_Console.cpp b/source/client/gui/screens/PauseScreen_Console.cpp index 2e5380c1c..113ca9b72 100644 --- a/source/client/gui/screens/PauseScreen_Console.cpp +++ b/source/client/gui/screens/PauseScreen_Console.cpp @@ -14,7 +14,7 @@ PauseScreen_Console::PauseScreen_Console() : m_btnLeaderboards.setEnabled(false); m_btnAchievements.setEnabled(false); - m_themeSelection = UI_SPECIFIC; + m_screenType = SCREEN_SPECIFIC; m_uiTheme = UI_CONSOLE; } diff --git a/source/client/gui/screens/StartMenuScreen_Console.cpp b/source/client/gui/screens/StartMenuScreen_Console.cpp index ce84afc66..76f177862 100644 --- a/source/client/gui/screens/StartMenuScreen_Console.cpp +++ b/source/client/gui/screens/StartMenuScreen_Console.cpp @@ -17,7 +17,7 @@ StartMenuScreen_Console::StartMenuScreen_Console() : m_btnAchievements.setEnabled(false); m_btnDownload.setEnabled(false); - m_themeSelection = UI_SPECIFIC; + m_screenType = SCREEN_SPECIFIC; m_uiTheme = UI_CONSOLE; m_splash = SplashManager::singleton().getSplash(); diff --git a/source/client/gui/screens/inventory/ContainerScreen.cpp b/source/client/gui/screens/inventory/ContainerScreen.cpp index 09717dec8..fb1c0ea2f 100644 --- a/source/client/gui/screens/inventory/ContainerScreen.cpp +++ b/source/client/gui/screens/inventory/ContainerScreen.cpp @@ -13,7 +13,7 @@ ContainerScreen::ContainerScreen(ContainerMenu* menu) : m_topPos(0), m_timeSlotDragged(0) { - m_themeSelection = UI_UNIVERSAL; + m_screenType = SCREEN_UNIVERSAL; m_bRenderPointer = true; } diff --git a/source/client/options/Options.cpp b/source/client/options/Options.cpp index a45e50bab..63a315d88 100644 --- a/source/client/options/Options.cpp +++ b/source/client/options/Options.cpp @@ -86,7 +86,7 @@ Options::Options(Minecraft* mc, const std::string& folderPath) : , m_fancyGrass("gfx_fancygrass", "options.fancyGrass", true) , m_biomeColors("gfx_biomecolors", "options.biomeColors", true) , m_splitControls("ctrl_split", "options.splitControls", false) - , m_bUseController("ctrl_usecontroller", "options.useController", false) + , m_controllerOnly("ctrl_onlycontroller", "options.controllerOnly", false) , m_dynamicHand("gfx_dynamichand", "options.dynamicHand", false) , m_menuPanorama("misc_menupano", "options.menuPanorama", true) , m_guiScale("gfx_guiscale", "options.guiScale", 0, ValuesBuilder().add("options.guiScale.auto").add("options.guiScale.small").add("options.guiScale.normal").add(("options.guiScale.large"))) @@ -130,6 +130,7 @@ Options::Options(Minecraft* mc, const std::string& folderPath) : add(m_logoType); add(m_hudSize); add(m_classicCrafting); + add(m_controllerOnly); _initDefaultValues(); if (folderPath.empty()) return; m_filePath = folderPath + "/options.txt"; diff --git a/source/client/options/Options.hpp b/source/client/options/Options.hpp index 7ba657055..2a9086f40 100644 --- a/source/client/options/Options.hpp +++ b/source/client/options/Options.hpp @@ -454,7 +454,7 @@ class Options GraphicsOption m_fancyGrass; GraphicsOption m_biomeColors; BoolOption m_splitControls; - BoolOption m_bUseController; + BoolOption m_controllerOnly; BoolOption m_dynamicHand; BoolOption m_menuPanorama; GuiScaleOption m_guiScale; @@ -486,7 +486,7 @@ class Options /*OPTION(m_swapJumpSneak);*/ \ /*OPTION(m_buttonSize);*/ \ OPTION(m_autoJump); \ - OPTION(m_bUseController); idxController = currentIndex; \ + OPTION(m_controllerOnly); idxController = currentIndex; \ #define OPTIONS_LIST_CONTROLS_FEEDBACK \ /*HEADER("Feedback");*/ \ From e0b60d9d8071cf1114efa1b7cb1ea8fc254fb790 Mon Sep 17 00:00:00 2001 From: Wilyicaro Date: Wed, 25 Feb 2026 04:20:00 -0300 Subject: [PATCH 09/11] fixes --- game/assets/lang/en_us.json | 1 - source/client/app/Minecraft.cpp | 5 ++++- source/client/gui/screens/OptionsScreen_Console.cpp | 3 ++- source/client/options/Options.cpp | 2 -- source/client/options/Options.hpp | 2 -- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/game/assets/lang/en_us.json b/game/assets/lang/en_us.json index 60fc2ba6c..94ed3b226 100644 --- a/game/assets/lang/en_us.json +++ b/game/assets/lang/en_us.json @@ -79,7 +79,6 @@ "options.dynamicHand": "Dynamic Hand Movement", "options.autoJump": "Auto Jump", "options.splitControls": "Split Controls", - "options.controllerOnly": "Controller Only", "options.flightHax": "Flight Hax", "options.serverVisibleDefault": "Local Server Multiplayer", "options.debugText": "Debug Text", diff --git a/source/client/app/Minecraft.cpp b/source/client/app/Minecraft.cpp index a017a6f9b..22c43e14d 100644 --- a/source/client/app/Minecraft.cpp +++ b/source/client/app/Minecraft.cpp @@ -383,7 +383,7 @@ bool Minecraft::useSplitControls() const bool Minecraft::useController() const { - return m_pPlatform->hasGamepad() && (getInputType() == InputType::CONTROLLER || getOptions()->m_controllerOnly.get()); + return getInputType() == InputType::CONTROLLER; } void Minecraft::setGameMode(GameType gameType) @@ -517,6 +517,9 @@ void Minecraft::handleBuildAction(const BuildActionIntention& action) void Minecraft::tickInput() { + if (!platform()->hasGamepad() && useController()) + setInputType(platform()->isTouchscreen() ? InputType::TOUCHSCREEN : InputType::KEYBOARD); + if (!m_pInputHolder->allowsType(getInputType())) _reloadInput(); diff --git a/source/client/gui/screens/OptionsScreen_Console.cpp b/source/client/gui/screens/OptionsScreen_Console.cpp index b829f07e4..06978a2f5 100644 --- a/source/client/gui/screens/OptionsScreen_Console.cpp +++ b/source/client/gui/screens/OptionsScreen_Console.cpp @@ -95,7 +95,8 @@ ControlsPanelScreen::ControlsPanelScreen(Screen* parent, Minecraft* mc) : PanelS if (!mc->isTouchscreen()) m_layout.m_elements[idxSplit]->setEnabled(false); - m_layout.m_elements[idxController]->setEnabled(false); + if (!mc->platform()->hasGamepad()) + m_layout.m_elements[idxController]->setEnabled(false); } void ControlsPanelScreen::removed() diff --git a/source/client/options/Options.cpp b/source/client/options/Options.cpp index 63a315d88..c168658e7 100644 --- a/source/client/options/Options.cpp +++ b/source/client/options/Options.cpp @@ -86,7 +86,6 @@ Options::Options(Minecraft* mc, const std::string& folderPath) : , m_fancyGrass("gfx_fancygrass", "options.fancyGrass", true) , m_biomeColors("gfx_biomecolors", "options.biomeColors", true) , m_splitControls("ctrl_split", "options.splitControls", false) - , m_controllerOnly("ctrl_onlycontroller", "options.controllerOnly", false) , m_dynamicHand("gfx_dynamichand", "options.dynamicHand", false) , m_menuPanorama("misc_menupano", "options.menuPanorama", true) , m_guiScale("gfx_guiscale", "options.guiScale", 0, ValuesBuilder().add("options.guiScale.auto").add("options.guiScale.small").add("options.guiScale.normal").add(("options.guiScale.large"))) @@ -130,7 +129,6 @@ Options::Options(Minecraft* mc, const std::string& folderPath) : add(m_logoType); add(m_hudSize); add(m_classicCrafting); - add(m_controllerOnly); _initDefaultValues(); if (folderPath.empty()) return; m_filePath = folderPath + "/options.txt"; diff --git a/source/client/options/Options.hpp b/source/client/options/Options.hpp index 2a9086f40..c38e42eeb 100644 --- a/source/client/options/Options.hpp +++ b/source/client/options/Options.hpp @@ -454,7 +454,6 @@ class Options GraphicsOption m_fancyGrass; GraphicsOption m_biomeColors; BoolOption m_splitControls; - BoolOption m_controllerOnly; BoolOption m_dynamicHand; BoolOption m_menuPanorama; GuiScaleOption m_guiScale; @@ -486,7 +485,6 @@ class Options /*OPTION(m_swapJumpSneak);*/ \ /*OPTION(m_buttonSize);*/ \ OPTION(m_autoJump); \ - OPTION(m_controllerOnly); idxController = currentIndex; \ #define OPTIONS_LIST_CONTROLS_FEEDBACK \ /*HEADER("Feedback");*/ \ From e4429e4a9d8ac32d82b8cf8d893b69094aa3e330 Mon Sep 17 00:00:00 2001 From: Wilyicaro Date: Wed, 25 Feb 2026 04:56:28 -0300 Subject: [PATCH 10/11] -Fixed broken text rendering in d3d11 and d3d9 --- game/assets/materials/ui.material | 2 +- game/assets/shaders/glsl/text.fragment | 12 +++++----- game/assets/shaders/hlsl/text.fragment.hlsl | 5 +---- source/client/renderer/Font.cpp | 25 +++++++-------------- 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/game/assets/materials/ui.material b/game/assets/materials/ui.material index 7c086d6ab..67acebd16 100644 --- a/game/assets/materials/ui.material +++ b/game/assets/materials/ui.material @@ -35,7 +35,7 @@ "states": ["DisableCulling"] }, - "ui_text:ui_textured_and_glcolor": { + "ui_text:ui_textured": { "fragmentShader": "shaders/text.fragment" }, diff --git a/game/assets/shaders/glsl/text.fragment b/game/assets/shaders/glsl/text.fragment index c507b9d6a..ade6f93f9 100644 --- a/game/assets/shaders/glsl/text.fragment +++ b/game/assets/shaders/glsl/text.fragment @@ -1,18 +1,18 @@ // __multiversion__ #include "ShaderConstants.h" -uniform sampler2D TEXTURE_0; -uniform vec4 DARKEN; -varying vec4 color; varying vec2 uv; +uniform vec4 CURRENT_COLOR; +uniform sampler2D TEXTURE_0; + void main() { - vec4 diffuse = texture2D( TEXTURE_0, uv ); + vec4 diffuse = texture2D( TEXTURE_0, uv ); if(diffuse.a < 0.5) - discard; + discard; - gl_FragColor = diffuse * color * DARKEN; + gl_FragColor = CURRENT_COLOR * diffuse; } diff --git a/game/assets/shaders/hlsl/text.fragment.hlsl b/game/assets/shaders/hlsl/text.fragment.hlsl index 8f8a87e2f..ae3909a4b 100644 --- a/game/assets/shaders/hlsl/text.fragment.hlsl +++ b/game/assets/shaders/hlsl/text.fragment.hlsl @@ -4,7 +4,6 @@ struct PS_Input { float4 position : SV_Position; - float4 color : COLOR; float2 uv : TEXCOORD_0; }; @@ -16,12 +15,10 @@ struct PS_Output PS_MAIN_BEGIN const float4 diffuse = sampleTex0( TextureSampler0, PSInput.uv ); -#ifdef ALPHA_TEST if( diffuse.a < 0.5 ) { discard; } -#endif - PSOutput.color = diffuse * PSInput.color * DARKEN; + PSOutput.color = CURRENT_COLOR * diffuse; PS_MAIN_END diff --git a/source/client/renderer/Font.cpp b/source/client/renderer/Font.cpp index f18d78426..38eaa904e 100644 --- a/source/client/renderer/Font.cpp +++ b/source/client/renderer/Font.cpp @@ -170,18 +170,12 @@ void Font::draw(const std::string& str, int x, int y, const Color& color, bool b { if (str.empty()) return; - if (bShadow) - { - currentShaderDarkColor = Color(0.25f, 0.25f, 0.25f); - } - else - { - currentShaderDarkColor = Color::WHITE; - } - m_pTextures->loadAndBindTexture(m_fileName); Color finalColor = color; + + if (bShadow) + finalColor *= 0.25f; // For hex colors which don't specify an alpha if (finalColor.a == 0.0f) finalColor.a = 1.0f; @@ -217,18 +211,15 @@ void Font::drawSlow(const std::string& str, int x, int y, const Color& color, bo { if (str.empty()) return; + m_pTextures->loadAndBindTexture(m_fileName); + + Color finalColor = color; + if (bShadow) { - currentShaderDarkColor = Color(0.25f, 0.25f, 0.25f); + finalColor *= 0.25f; } - else - { - currentShaderDarkColor = Color::WHITE; - } - - m_pTextures->loadAndBindTexture(m_fileName); - Color finalColor = color; // For hex colors which don't specify an alpha if (finalColor.a == 0.0f) finalColor.a = 1.0f; From 4dc06952bc3186e95d3de16f8b891d97af9728bf Mon Sep 17 00:00:00 2001 From: Wilyicaro Date: Wed, 25 Feb 2026 18:49:30 -0300 Subject: [PATCH 11/11] reverted font rendering changes, and fixed crash in options screen --- game/assets/materials/ui.material | 4 +- game/assets/shaders/glsl/text.fragment | 12 ++-- game/assets/shaders/hlsl/text.fragment.hlsl | 5 +- source/client/gui/components/OptionList.cpp | 4 +- .../gui/screens/OptionsScreen_Console.cpp | 4 +- source/client/renderer/Font.cpp | 64 +++++-------------- source/client/renderer/Font.hpp | 1 - 7 files changed, 29 insertions(+), 65 deletions(-) diff --git a/game/assets/materials/ui.material b/game/assets/materials/ui.material index 67acebd16..c9a574953 100644 --- a/game/assets/materials/ui.material +++ b/game/assets/materials/ui.material @@ -35,7 +35,7 @@ "states": ["DisableCulling"] }, - "ui_text:ui_textured": { + "ui_text:ui_texture_and_color": { "fragmentShader": "shaders/text.fragment" }, @@ -222,4 +222,4 @@ "vertexShader": "shaders/uv.vertex", "fragmentShader": "shaders/texture.fragment" } -} +} \ No newline at end of file diff --git a/game/assets/shaders/glsl/text.fragment b/game/assets/shaders/glsl/text.fragment index ade6f93f9..c507b9d6a 100644 --- a/game/assets/shaders/glsl/text.fragment +++ b/game/assets/shaders/glsl/text.fragment @@ -1,18 +1,18 @@ // __multiversion__ #include "ShaderConstants.h" +uniform sampler2D TEXTURE_0; +uniform vec4 DARKEN; +varying vec4 color; varying vec2 uv; -uniform vec4 CURRENT_COLOR; -uniform sampler2D TEXTURE_0; - void main() { - vec4 diffuse = texture2D( TEXTURE_0, uv ); + vec4 diffuse = texture2D( TEXTURE_0, uv ); if(diffuse.a < 0.5) - discard; + discard; - gl_FragColor = CURRENT_COLOR * diffuse; + gl_FragColor = diffuse * color * DARKEN; } diff --git a/game/assets/shaders/hlsl/text.fragment.hlsl b/game/assets/shaders/hlsl/text.fragment.hlsl index ae3909a4b..8f8a87e2f 100644 --- a/game/assets/shaders/hlsl/text.fragment.hlsl +++ b/game/assets/shaders/hlsl/text.fragment.hlsl @@ -4,6 +4,7 @@ struct PS_Input { float4 position : SV_Position; + float4 color : COLOR; float2 uv : TEXCOORD_0; }; @@ -15,10 +16,12 @@ struct PS_Output PS_MAIN_BEGIN const float4 diffuse = sampleTex0( TextureSampler0, PSInput.uv ); +#ifdef ALPHA_TEST if( diffuse.a < 0.5 ) { discard; } +#endif - PSOutput.color = CURRENT_COLOR * diffuse; + PSOutput.color = diffuse * PSInput.color * DARKEN; PS_MAIN_END diff --git a/source/client/gui/components/OptionList.cpp b/source/client/gui/components/OptionList.cpp index fdbcfeebd..643294e25 100644 --- a/source/client/gui/components/OptionList.cpp +++ b/source/client/gui/components/OptionList.cpp @@ -165,7 +165,7 @@ void OptionList::initControlsMenu() { Options* pOptions = m_pMinecraft->getOptions(); int currentIndex = -1; - int idxSplit = -1, idxController = -1; + int idxSplit = -1; OPTIONS_LIST_CONTROLS_CONTROLS; OPTIONS_LIST_CONTROLS_FEEDBACK; @@ -173,8 +173,6 @@ void OptionList::initControlsMenu() if (!m_pMinecraft->isTouchscreen()) m_items[idxSplit]->setEnabled(false); - if (!m_pMinecraft->platform()->hasGamepad()) - m_items[idxController]->setEnabled(false); } void OptionList::initVideoMenu() diff --git a/source/client/gui/screens/OptionsScreen_Console.cpp b/source/client/gui/screens/OptionsScreen_Console.cpp index 06978a2f5..e28f2195a 100644 --- a/source/client/gui/screens/OptionsScreen_Console.cpp +++ b/source/client/gui/screens/OptionsScreen_Console.cpp @@ -87,7 +87,7 @@ ControlsPanelScreen::ControlsPanelScreen(Screen* parent, Minecraft* mc) : PanelS { Options& options = *mc->getOptions(); int currentIndex = -1; - int idxSplit = -1, idxController = -1; + int idxSplit = -1; OPTIONS_LIST_CONTROLS_CONTROLS; OPTIONS_LIST_CONTROLS_FEEDBACK; @@ -95,8 +95,6 @@ ControlsPanelScreen::ControlsPanelScreen(Screen* parent, Minecraft* mc) : PanelS if (!mc->isTouchscreen()) m_layout.m_elements[idxSplit]->setEnabled(false); - if (!mc->platform()->hasGamepad()) - m_layout.m_elements[idxController]->setEnabled(false); } void ControlsPanelScreen::removed() diff --git a/source/client/renderer/Font.cpp b/source/client/renderer/Font.cpp index 38eaa904e..dffb8076f 100644 --- a/source/client/renderer/Font.cpp +++ b/source/client/renderer/Font.cpp @@ -63,10 +63,6 @@ void Font::init(Options* pOpts) m_charWidthInt[i] = widthMax + 2; m_charWidthFloat[i] = float (widthMax) + 2; - Tesselator& t = Tesselator::instance; - t.begin(4); - buildChar(i, 0, 0); - m_charMeshes[i] = t.end(); } } @@ -168,69 +164,41 @@ void Font::drawWordWrap(const std::vector& lines, int x, int y, con void Font::draw(const std::string& str, int x, int y, const Color& color, bool bShadow) { - if (str.empty()) return; - - m_pTextures->loadAndBindTexture(m_fileName); - - Color finalColor = color; - - if (bShadow) - finalColor *= 0.25f; - // For hex colors which don't specify an alpha - if (finalColor.a == 0.0f) - finalColor.a = 1.0f; - - MatrixStack::Ref mtx = MatrixStack::World.push(); - mtx->translate(Vec3(x, y, 0.0f)); - - currentShaderColor = finalColor; - float xOff = 0.0f; - - for (size_t i = 0; i < str.size(); i++) - { - if (str[i] == '\n') - { - mtx->translate(Vec3(0.0f, 12.0f, 0.0f)); - xOff = 0.0f; - continue; - } - - uint8_t x = uint8_t(str[i]); - - MatrixStack::Ref xmtx = MatrixStack::World.push(); - xmtx->translate(Vec3(xOff, 0.0f, 0.0f)); - m_charMeshes[x].render(m_materials.ui_text); - - xOff += m_charWidthFloat[x]; - } - - currentShaderColor = Color::WHITE; + drawSlow(str, x, y, color, bShadow); } void Font::drawSlow(const std::string& str, int x, int y, const Color& color, bool bShadow) { if (str.empty()) return; - m_pTextures->loadAndBindTexture(m_fileName); - - Color finalColor = color; - if (bShadow) { - finalColor *= 0.25f; + currentShaderDarkColor = Color(0.25f, 0.25f, 0.25f); } + else + { + currentShaderDarkColor = Color::WHITE; + } + + m_pTextures->loadAndBindTexture(m_fileName); + Color finalColor = color; // For hex colors which don't specify an alpha if (finalColor.a == 0.0f) finalColor.a = 1.0f; +#ifndef FEATURE_GFX_SHADERS + finalColor *= currentShaderDarkColor; +#endif + MatrixStack::Ref mtx = MatrixStack::World.push(); mtx->translate(Vec3(x, y, 0.0f)); - currentShaderColor = finalColor; Tesselator& t = Tesselator::instance; t.begin(4 * str.size()); + t.color(finalColor); + float cXPos = 0.0f, cYPos = 0.0f; for (size_t i = 0; i < str.size(); i++) @@ -250,8 +218,6 @@ void Font::drawSlow(const std::string& str, int x, int y, const Color& color, bo } t.draw(m_materials.ui_text); - - currentShaderColor = Color::WHITE; } void Font::onGraphicsReset() diff --git a/source/client/renderer/Font.hpp b/source/client/renderer/Font.hpp index 93b97b148..9241b8b2b 100644 --- a/source/client/renderer/Font.hpp +++ b/source/client/renderer/Font.hpp @@ -52,7 +52,6 @@ class Font int field_0; int m_charWidthInt[C_FONT_CHARS_AMOUNT]; float m_charWidthFloat[C_FONT_CHARS_AMOUNT]; - mce::Mesh m_charMeshes[C_FONT_CHARS_AMOUNT]; // huge gap, don't know why it's there... std::string m_fileName; Options* m_pOptions;