/******************************************************************** 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 "RolledSelectionList.hpp" static float g_RolledSelectionListUnk, g_RolledSelectionListUnk2; RolledSelectionList::RolledSelectionList(Minecraft* minecraft, int a, int b, int c, int d, int e, int f, int g) { m_pMinecraft = minecraft; m_itemWidth = g; field_18 = a; field_C = float(c); field_10 = float(d); field_1C = b; field_20 = float(e); field_24 = float(f); field_28 = -2; field_2C = 0.0f; field_38 = 0.0f; field_3C = -1; m_bRenderSelection = true; m_bComponentSelected = false; field_44 = 0; field_48 = false; field_4C = 0; field_50 = 1; g_RolledSelectionListUnk = field_30 = field_34 = float(g - a) / 2.0f; } int RolledSelectionList::getItemAtXPositionRaw(int x) { if (x < 0) return -1; // @NOTE: redundant check int idx = x / m_itemWidth; if (idx < 0) return -1; if (idx >= getNumberOfItems()) return -1; return idx; } int RolledSelectionList::getItemAtPosition(int x, int y) { if (float(y) < field_20) return -1; if (float(y) > field_24) return -1; return getItemAtXPositionRaw(transformX(x)); } bool RolledSelectionList::capXPosition() { float f1 = float(m_itemWidth - field_18) / 2.0f; int i1 = getNumberOfItems(); if (field_30 < f1) { field_30 = f1; field_38 = 0.0f; return true; } f1 += float(m_itemWidth * (i1 - 1)); if (field_30 > f1) { field_30 = f1; field_38 = 0.0f; return true; } return false; } void RolledSelectionList::tick() { float diff = g_RolledSelectionListUnk - field_34; g_RolledSelectionListUnk = field_34; g_RolledSelectionListUnk2 = diff; field_34 = field_30 - field_38; } void RolledSelectionList::render(int mouseX, int mouseY, float f) { renderBackground(); int nItems = getNumberOfItems(); // @TODO: fix gotos. if (!Mouse::isButtonDown(BUTTON_LEFT)) { if (field_28 < 0) { _crap: field_28 = -1; field_30 = getPos(f); goto _done; } if (g_RolledSelectionListUnk2 < 0.0f) field_38 = Mth::Max(-20.0f, g_RolledSelectionListUnk2); else field_38 = Mth::Min(20.0f, g_RolledSelectionListUnk2); if (fabsf(field_38) < 2.0f) { field_38 = 0.0f; _continue: if (getTimeMs() - field_4C < 300) { int idx = transformX(mouseX) / m_itemWidth; if (idx >= 0) { if (field_50 == idx && abs(field_3C - mouseX) <= 9) selectItem(field_50, 0); } goto _crap; } goto _crap; } if (fabsf(field_38) > 10.0f) { goto _crap; } goto _continue; } else { touched(); if (float(mouseY) >= field_20 && float(mouseY) <= field_24) { if (field_28 == -1) { field_4C = getTimeMs(); field_3C = mouseX; field_50 = getItemAtPosition(mouseX, field_1C / 2); } else if (field_28 >= 0) { field_34 = field_30 = field_30 - (float(mouseX) - field_2C); } field_28 = 0; } } _done: field_2C = float(mouseX); capXPosition(); glDisable(GL_LIGHTING); glDisable(GL_FOG); m_pMinecraft->m_pTextures->loadAndBindTexture("gui/background.png"); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); Tesselator& t = Tesselator::instance; t.begin(); t.color(0x202020); t.vertexUV(field_C, field_24, 0.0f, (field_C + float(int(field_30))) / 32.0f, field_24 / 32.0f); t.vertexUV(field_10, field_24, 0.0f, (field_10 + float(int(field_30))) / 32.0f, field_24 / 32.0f); t.vertexUV(field_10, field_20, 0.0f, (field_10 + float(int(field_30))) / 32.0f, field_20 / 32.0f); t.vertexUV(field_C, field_20, 0.0f, (field_C + float(int(field_30))) / 32.0f, field_20 / 32.0f); t.draw(); if (!getNumberOfItems()) field_30 = 0.0f; if (field_48) renderHeader(int(field_C + 4.0f - float(int(field_30))), field_1C / 2 - 40, t); for (int i = 0; i < nItems; i++) { float itemX = float(field_44 + float(int(field_C + 4.0f - float(field_30))) + m_itemWidth * i); if (field_10 < itemX) continue; float width = m_itemWidth - 4.0f; if (itemX + width < field_C) continue; if (m_bRenderSelection && isSelectedItem(i)) { glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glDisable(GL_TEXTURE_2D); t.begin(); t.color(m_bComponentSelected ? 0x7F89BF : 0x808080); float right = itemX + width; float up = float(field_1C) / 2.0f - 48.0f - 4.0f; float dn = float(field_1C) / 2.0f + 48.0f - 4.0f; t.vertexUV(itemX - 2, up, 0.0f, 0.0f, 0.0f); t.vertexUV(itemX - 2, dn, 0.0f, 1.0f, 0.0f); t.vertexUV(right + 2, dn, 0.0f, 1.0f, 1.0f); t.vertexUV(right + 2, up, 0.0f, 0.0f, 1.0f); t.color(0x000000); t.vertexUV(itemX - 1, up + 1.0f, 0.0f, 0.0f, 0.0f); t.vertexUV(itemX - 1, dn - 1.0f, 0.0f, 1.0f, 0.0f); t.vertexUV(right + 1, dn - 1.0f, 0.0f, 1.0f, 1.0f); t.vertexUV(right + 1, up + 1.0f, 0.0f, 0.0f, 1.0f); t.draw(); glEnable(GL_TEXTURE_2D); } renderItem(i, int(itemX), field_1C / 2 - 40, int(width), t); } glDisable(GL_DEPTH_TEST); renderHoleBackground(0.0f, field_20, 255, 255); renderHoleBackground(field_24, float(field_1C), 255, 255); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_ALPHA_TEST); glShadeModel(GL_SMOOTH); glDisable(GL_TEXTURE_2D); // @BUG: The X and Y coordinates have been swapped. This causes the gradient to not render // in the right place. #ifdef ORIGINAL_CODE t.begin(); t.color(0, 0); t.vertexUV(field_20, m_rotX + 4.0f, 0.0f, 0.0f, 1.0f); t.vertexUV(field_24, m_rotX + 4.0f, 0.0f, 1.0f, 1.0f); t.color(0, 255); t.vertexUV(field_24, m_rotX, 0.0f, 1.0f, 0.0f); t.vertexUV(field_20, m_rotX, 0.0f, 0.0f, 0.0f); t.draw(); t.begin(); t.color(0, 255); t.vertexUV(field_20, m_rotY, 0.0f, 0.0f, 1.0f); t.vertexUV(field_24, m_rotY, 0.0f, 1.0f, 1.0f); t.color(0, 0); t.vertexUV(field_24, m_rotY - 4.0f, 0.0f, 1.0f, 0.0f); t.vertexUV(field_20, m_rotY - 4.0f, 0.0f, 0.0f, 0.0f); t.draw(); #else t.begin(); t.color(0, 0); t.vertexUV(field_C + 4.0f, field_20, 0.0f, 0.0f, 1.0f); t.vertexUV(field_C + 4.0f, field_24, 0.0f, 1.0f, 1.0f); t.color(0, 255); t.vertexUV(field_C, field_24, 0.0f, 1.0f, 0.0f); t.vertexUV(field_C, field_20, 0.0f, 0.0f, 0.0f); t.draw(); t.begin(); t.color(0, 255); t.vertexUV(field_10, field_20, 0.0f, 0.0f, 1.0f); t.vertexUV(field_10, field_24, 0.0f, 1.0f, 1.0f); t.color(0, 0); t.vertexUV(field_10 - 4.0f, field_24, 0.0f, 1.0f, 0.0f); t.vertexUV(field_10 - 4.0f, field_20, 0.0f, 0.0f, 0.0f); t.draw(); #endif renderDecorations(mouseX, mouseY); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); glEnable(GL_ALPHA_TEST); glDisable(GL_BLEND); } void RolledSelectionList::renderHoleBackground(float y1, float y2, int a, int b) { m_pMinecraft->m_pTextures->loadAndBindTexture("gui/background.png"); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); Tesselator& t = Tesselator::instance; t.begin(); t.color(0x505050, b); t.vertexUV(0.0f, y2, 0.0f, 0.0f, y2 / 32.0f); t.vertexUV(float(field_18), y2, 0.0f, float(field_18) / 32.0f, y2 / 32.0f); t.color(0x505050, a); t.vertexUV(float(field_18), y1, 0.0f, float(field_18) / 32.0f, y1 / 32.0f); t.vertexUV(0.0f, y1, 0.0f, 0.0f, y1 / 32.0f); t.draw(); } void RolledSelectionList::setRenderSelection(bool b) { m_bRenderSelection = b; } void RolledSelectionList::setComponentSelected(bool b) { m_bComponentSelected = b; } int RolledSelectionList::getMaxPosition() { return field_44 + m_itemWidth * getNumberOfItems(); } float RolledSelectionList::getPos(float f) { return field_34 - field_38 * f; } void RolledSelectionList::touched() { } void RolledSelectionList::renderHeader(int a, int b, Tesselator& t) { } void RolledSelectionList::renderDecorations(int x, int y) { } void RolledSelectionList::clickedHeader(int x, int y) { }