/******************************************************************** Minecraft: Pocket Edition - Decompilation Project Copyright (C) 2023 iProgramInCpp The following code is licensed under the BSD 1 clause license. SPDX-License-Identifier: BSD-1-Clause ********************************************************************/ #include "Screen.hpp" Screen::Screen() { m_width = 1; m_height = 1; field_10 = false; m_tabButtonIndex = 0; m_pClickedButton = 0; m_yOffset = -1; } Screen::~Screen() { m_pClickedButton = nullptr; m_buttons.clear(); } void Screen::init(Minecraft* pMinecraft, int a3, int a4) { m_width = a3; m_height = a4; m_pMinecraft = pMinecraft; m_pFont = pMinecraft->m_pFont; init(); updateTabButtonSelection(); } void Screen::init() { } void Screen::buttonClicked(Button* pButton) { } void Screen::confirmResult(bool b, int i) { } bool Screen::handleBackEvent(bool b) { return false; } bool Screen::isPauseScreen() { return true; } bool Screen::isErrorScreen() { return false; } bool Screen::isInGameScreen() { return true; } void Screen::keyPressed(int key) { if (m_pMinecraft->getOptions()->isKey(KM_MENU_CANCEL, key)) { m_pMinecraft->setScreen(nullptr); } if (m_buttonTabList.size()) { #ifndef ENH_HIGHLIGHT_BY_HOVER if (m_pMinecraft->getOptions()->isKey(MENU_NEXT, key)) { m_tabButtonIndex++; if (m_tabButtonIndex == int(m_buttonTabList.size())) m_tabButtonIndex = 0; } if (m_pMinecraft->getOptions()->isKey(MENU_PREVIOUS, key)) { m_tabButtonIndex--; if (m_tabButtonIndex == -1) m_tabButtonIndex = int(m_buttonTabList.size() - 1); } if (m_pMinecraft->getOptions()->isKey(MENU_OK, key)) { if (m_buttonTabList[m_tabButtonIndex]->m_bEnabled) { m_pMinecraft->m_pSoundEngine->play("random.click"); buttonClicked(m_buttonTabList[m_tabButtonIndex]); } } updateTabButtonSelection(); #endif } for (int i = 0; i < int(m_textInputs.size()); i++) { TextInputBox* textInput = m_textInputs[i]; textInput->keyPressed(m_pMinecraft, key); } } void Screen::charInput(char chr) { for (int i = 0; i < int(m_textInputs.size()); i++) { TextInputBox* textInput = m_textInputs[i]; textInput->charPressed(chr); } } static const char* g_panoramaList[] = { "gui/background/panorama_0.png", "gui/background/panorama_1.png", "gui/background/panorama_2.png", "gui/background/panorama_3.png", "gui/background/panorama_4.png", "gui/background/panorama_5.png", }; static float g_panoramaAngle = 0.0f; // TODO: This should be inside of an initialized "Minecraft" instance rather than the global namespace bool g_bIsMenuBackgroundAvailable = false; void Screen::renderMenuBackground(float f) { if (!g_bIsMenuBackgroundAvailable) { renderDirtBackground(0); return; } g_panoramaAngle += float(30.0 * m_pMinecraft->m_fDeltaTime); float aspectRatio; aspectRatio = 1.0f; //aspectRatio = float(m_width) / float(m_height); // not in 0.8 glDisable(GL_BLEND); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPerspective(120.0f, aspectRatio, 0.05f, 10.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glRotatef(180.0f, 1.0f, 0.0f, 0.0f); glRotatef(Mth::sin((f + g_panoramaAngle) / 400.0f) * 25.0f + 20.0f, 1.0f, 0.0f, 0.0f); glRotatef(-0.1f * (f + g_panoramaAngle), 0.0f, 1.0f, 0.0f); for (int i = 0; i < 6; i++) { glPushMatrix(); float xm = 0.0f, ym = 0.0f, ang = 0.0f; switch (i) { case 1: ang = 90.0f; xm = 0.0f; ym = 1.0f; break; case 2: ang = 180.0f; xm = 0.0f; ym = 1.0f; break; case 3: ang = -90.0f; xm = 0.0f; ym = 1.0f; break; case 4: ang = 90.0f; ym = 0.0f; xm = 1.0f; break; case 5: ang = -90.0f; ym = 0.0f; xm = 1.0f; break; default: goto skip_rotate; } glRotatef(ang, xm, ym, 0.0f); skip_rotate: m_pMinecraft->m_pTextures->setSmoothing(true); m_pMinecraft->m_pTextures->setClampToEdge(true); m_pMinecraft->m_pTextures->loadAndBindTexture(std::string(g_panoramaList[i])); m_pMinecraft->m_pTextures->setSmoothing(false); m_pMinecraft->m_pTextures->setClampToEdge(false); Tesselator& t = Tesselator::instance; t.begin(); t.vertexUV(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f); t.vertexUV(+1.0f, -1.0f, 1.0f, 1.0f, 0.0f); t.vertexUV(+1.0f, +1.0f, 1.0f, 1.0f, 1.0f); t.vertexUV(-1.0f, +1.0f, 1.0f, 0.0f, 1.0f); t.draw(); glPopMatrix(); } glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glEnable(GL_BLEND); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); fillGradient(0, 0, m_width, m_height, 0x89000000, 0x89FFFFFF); } void Screen::mouseClicked(int xPos, int yPos, int d) // d = clicked? { if (!d) return; for (int i = 0; i < int(m_buttons.size()); i++) { Button* button = m_buttons[i]; if (button->clicked(m_pMinecraft, xPos, yPos)) { m_pClickedButton = button; m_pMinecraft->m_pSoundEngine->play("random.click"); buttonClicked(button); } } #ifndef ORIGINAL_CODE for (int i = 0; i < int(m_textInputs.size()); i++) { TextInputBox* textInput = m_textInputs[i]; textInput->onClick(xPos, yPos); } // if the keyboard is shown: if (m_pMinecraft->platform()->getKeyboardUpOffset()) { // if there are none focused at the moment: bool areAnyFocused = false; for (int i = 0; i < int(m_textInputs.size()); i++) { TextInputBox* textInput = m_textInputs[i]; if (textInput->m_bFocused) { areAnyFocused = true; break; } } if (!areAnyFocused) m_pMinecraft->platform()->showKeyboard(false); } #endif } void Screen::mouseReleased(int xPos, int yPos, int d) { if (!d) return; if (m_pClickedButton) { m_pClickedButton->released(xPos, yPos); m_pClickedButton = nullptr; } } void Screen::render(int xPos, int yPos, float unused) { for (int i = 0; i < int(m_buttons.size()); i++) { Button* button = m_buttons[i]; button->render(m_pMinecraft, xPos, yPos); } #ifndef ORIGINAL_CODE for (int i = 0; i < int(m_textInputs.size()); i++) { TextInputBox* textInput = m_textInputs[i]; textInput->tick(); textInput->render(); } #endif } void Screen::tick() { g_panoramaAngle++; } void Screen::removed() { } void Screen::setSize(int width, int height) { m_width = width; m_height = height; // not original code. Will need to re-init again m_buttons.clear(); m_textInputs.clear(); init(); } void Screen::onRender(int mouseX, int mouseY, float f) { m_yOffset = getYOffset(); if (m_yOffset != 0) { // push the entire screen up glPushMatrix(); glTranslatef(0.0f, -float(m_yOffset), 0.0f); } render(mouseX, mouseY, f); if (m_yOffset != 0) glPopMatrix(); } int Screen::getYOffset() { int keybOffset = m_pMinecraft->platform()->getKeyboardUpOffset(); if (!keybOffset) return 0; int offset = 0; // look through every text box, see if one's open // and determine its offset from there for (int i = 0; i < int(m_textInputs.size()); i++) { TextInputBox* pBox = m_textInputs[i]; if (!pBox->m_bFocused) continue; int heightLeft = m_height - int(float(keybOffset) * Gui::InvGuiScale); // we want to keep the center of the text box in the center of the screen int textCenterY = pBox->m_yPos + pBox->m_height / 2; int scrnCenterY = heightLeft / 2; int diff = textCenterY - scrnCenterY; // Prevent the difference from revealing the outside of the screen. if (diff > m_height - heightLeft) diff = m_height - heightLeft; if (diff < 0) diff = 0; offset = diff; break; } return offset; } void Screen::updateEvents() { if (field_10) return; while (Mouse::next()) mouseEvent(); while (Keyboard::next()) keyboardEvent(); } void Screen::keyboardEvent() { if (Keyboard::getEventKeyState()) keyPressed(Keyboard::getEventKey()); } void Screen::mouseEvent() { MouseAction* pAction = Mouse::getEvent(); if (pAction->isButton()) { if (Mouse::getEventButtonState()) mouseClicked (m_width * pAction->_posX / Minecraft::width, m_height * pAction->_posY / Minecraft::height - 1 + getYOffset(), Mouse::getEventButton()); else mouseReleased(m_width * pAction->_posX / Minecraft::width, m_height * pAction->_posY / Minecraft::height - 1 + getYOffset(), Mouse::getEventButton()); } } void Screen::renderBackground(int unk) { if (m_pMinecraft->isLevelGenerated()) { // draw the background offset by the Y offset so that the smaller virtual // keyboards don't reveal undrawn areas fillGradient(0, m_yOffset, m_width, m_height, 0xC0101010, 0xD0101010); } else { renderDirtBackground(unk); } } void Screen::renderBackground() { renderBackground(0); } void Screen::renderDirtBackground(int unk) { glDisable(GL_FOG); m_pMinecraft->m_pTextures->loadAndBindTexture("gui/background.png"); glColor4f(1, 1, 1, 1); Tesselator& t = Tesselator::instance; t.begin(); t.offset(0, m_yOffset, 0); t.color(0x404040); t.vertexUV(0.0f, float(m_height), 0, 0, float(unk) + float(m_height) / 32.0f); t.vertexUV(float(m_width), float(m_height), 0, float(m_width) / 32.0f, float(unk) + float(m_height) / 32.0f); t.vertexUV(float(m_width), 0, 0, float(m_width) / 32.0f, float(unk) + 0.0f); t.vertexUV(0.0f, 0, 0, 0, float(unk) + 0.0f); t.offset(0, 0, 0); t.draw(); } void Screen::updateTabButtonSelection() { #ifndef ENH_HIGHLIGHT_BY_HOVER for (int i = 0; i < int(m_buttonTabList.size()); i++) { m_buttonTabList[i]->field_36 = m_tabButtonIndex == i; } #endif }