/******************************************************************** 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 "TouchscreenInput_TestFps.hpp" #include "Multitouch.hpp" #include "client/app/Minecraft.hpp" #include "client/options/Options.hpp" #include "world/entity/Player.hpp" TouchscreenInput_TestFps::TouchscreenInput_TestFps(Minecraft* pMinecraft, Options* pOptions) : m_rectArea(0.0f, 0.0f, 1.0f, 1.0f), m_pOptions(pOptions), field_40(false), m_bJumpBeingHeld(false), m_pMinecraft(pMinecraft), m_pAreaLeft(nullptr), m_pAreaRight(nullptr), m_pAreaForward(nullptr), m_pAreaBackward(nullptr), m_pAreaJump(nullptr) { for (int i = 0; i < 10; i++) field_30[i] = 0; // Note! Only the first five button entries are used. for (int i = 0; i < 8; i++) field_6C[i] = 0; setScreenSize(Minecraft::width, Minecraft::height); } void TouchscreenInput_TestFps::releaseAllKeys() { m_horzInput = 0.0f; m_vertInput = 0.0f; for (int i = 0; i < 5; i++) field_6C[i] = false; } void TouchscreenInput_TestFps::setKey(int key, bool state) { } static void CopyCoordinateArray(int count, float* xs, float* ys, float* xd, float* yd) { for (int i = 0; i < count; i++) { xd[i] = xs[i]; yd[i] = ys[i]; } } static void MultiplyCoordinateArray(int count, float* x, float* y, float xm, float ym) { for (int i = 0; i < count; i++) { x[i] *= xm; y[i] *= ym; } } static void AddCoordinateArray(int count, float* x, float* y, float xd, float yd) { for (int i = 0; i < count; i++) { x[i] += xd; y[i] += yd; } } static void TransformArray(int count, float* x1, float* y1, float* x2, float* y2, float xd, float yd, float xm, float ym) { CopyCoordinateArray(count, x1, y1, x2, y2); MultiplyCoordinateArray(count, x2, y2, xm, ym); AddCoordinateArray(count, x2, y2, xd, yd); } void TouchscreenInput_TestFps::setScreenSize(int width, int height) { m_touchAreaModel.clear(); float widthM = float(width) * 0.11f; float heightM = float(height) * 0.18f; float x1[4], y1[4], x2[4], y2[4]; x1[0] = 0.0f; x1[1] = widthM; x1[2] = widthM; x1[3] = 0.0f; y1[0] = 0.0f; y1[1] = 0.0f; y1[2] = heightM; y1[3] = heightM; x2[0] = 0.0f; x2[1] = 0.0f; x2[2] = 0.0f; x2[3] = 0.0f; y2[0] = 0.0f; y2[1] = 0.0f; y2[2] = 0.0f; y2[3] = 0.0f; float rx1, rx2, ry1, ry2; float offX = 8.0f; rx1 = 0.0f; ry1 = height - 8.0f - heightM * 3.0f; rx2 = widthM * 3.0f + 8.0f; ry2 = ry1 + heightM * 3.0f; m_rectArea = RectangleArea(rx1, ry1, rx2, ry2); float middleX = offX + widthM; float middleY = ry1 + heightM; TransformArray(4, x1, y1, x2, y2, middleX, middleY - heightM, 1.0f, 1.0f); m_pAreaForward = new PolygonArea(4, x2, y2); m_touchAreaModel.addArea(100 + INPUT_FORWARD, m_pAreaForward); TransformArray(4, x1, y1, x2, y2, middleX, middleY, 1.0f, 1.0f); m_pAreaJump = new PolygonArea(4, x2, y2); m_touchAreaModel.addArea(100 + INPUT_JUMP, m_pAreaJump); TransformArray(4, x1, y1, x2, y2, middleX, middleY + heightM, 1.0f, 1.0f); m_pAreaBackward = new PolygonArea(4, x2, y2); m_touchAreaModel.addArea(100 + INPUT_BACKWARD, m_pAreaBackward); TransformArray(4, x1, y1, x2, y2, middleX - widthM, ry1 + heightM, 1.0f, 1.0f); m_pAreaLeft = new PolygonArea(4, x2, y2); m_touchAreaModel.addArea(100 + INPUT_LEFT, m_pAreaLeft); TransformArray(4, x1, y1, x2, y2, middleX + widthM, ry1 + heightM, 1.0f, 1.0f); m_pAreaRight = new PolygonArea(4, x2, y2); m_touchAreaModel.addArea(100 + INPUT_RIGHT, m_pAreaRight); // NOTE: We are not leaking memory! Since by default IArea's constructor sets // field_4 to true, TouchAreaModel owns the pointers, so when it's destroyed, // so are these areas we allocated. } void TouchscreenInput_TestFps::tick(Player* pPlayer) { m_horzInput = 0.0f; m_vertInput = 0.0f; m_bJumpButton = false; for (int i = 0; i < 5; i++) field_6C[i] = false; const int* activePointers; int activePointerCount = Multitouch::getActivePointerIds(&activePointers); bool bJumpPressed = false, bForwardPressed = false; for (int i = 0; i < activePointerCount; i++) { int finger = activePointers[i]; int x = Multitouch::getX(finger); int y = Multitouch::getY(finger); int pointerId = m_touchAreaModel.getPointerId(x, y, finger); if (pointerId > 99) field_6C[pointerId - 100] = true; if (pointerId == 100 + INPUT_SNEAK) // Unused { if (pPlayer->isInWater()) m_bJumpButton = true; else bJumpPressed = true; pointerId = 100; // forward } if (pointerId == 100 + INPUT_JUMP) // jump { if (pPlayer->isInWater()) m_bJumpButton = true; else if (Multitouch::isPressed(finger)) m_bJumpButton = true; else if (field_40) { pointerId = 100; // forward bJumpPressed = true; m_vertInput += 1.0f; } } switch (pointerId) { case 100 + INPUT_FORWARD: if (pPlayer->isInWater()) m_bJumpButton = true; else bForwardPressed = true; m_vertInput += 1.0f; break; case 100 + INPUT_BACKWARD: m_vertInput -= 1.0f; break; case 100 + INPUT_LEFT: m_horzInput += 1.0f; break; case 100 + INPUT_RIGHT: m_horzInput -= 1.0f; break; } } field_40 = bForwardPressed; if (bJumpPressed) { // Don't allow the player to hold jump to repeatedly jump. // Only let them jump once - have them jump again if (!m_bJumpBeingHeld) m_bJumpButton = true; m_bJumpBeingHeld = true; } else { m_bJumpBeingHeld = false; } } static void RenderTouchButton(Tesselator* t, PolygonArea* pArea, int srcX, int srcY) { float tc[8]; tc[0] = float(srcX) / 256.0f; tc[1] = float(srcY) / 256.0f; tc[2] = tc[0] + 64.0f / 256.0f; tc[3] = tc[1]; tc[4] = tc[2]; tc[5] = tc[1] + 64.0f / 256.0f; tc[6] = tc[0]; tc[7] = tc[5]; for (int i = 0; i < pArea->m_count; i++) { t->vertexUV( Gui::InvGuiScale * pArea->m_xPos[i], Gui::InvGuiScale * pArea->m_yPos[i], 0.0f, tc[(2 * i) % 8], tc[(2 * i + 1) % 8] ); } } void TouchscreenInput_TestFps::render(float f) { glDisable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); m_pMinecraft->m_pTextures->loadAndBindTexture("gui/gui.png"); Tesselator& t = Tesselator::instance; t.begin(); t.color(isButtonDown(100 + INPUT_LEFT) ? 0xC0C0C0 : 0xFFFFFF, 0x80); RenderTouchButton(&t, m_pAreaLeft, 64, 112); t.color(isButtonDown(100 + INPUT_RIGHT) ? 0xC0C0C0 : 0xFFFFFF, 0x80); RenderTouchButton(&t, m_pAreaRight, 192, 112); t.color(isButtonDown(100 + INPUT_FORWARD) ? 0xC0C0C0 : 0xFFFFFF, 0x80); RenderTouchButton(&t, m_pAreaForward, 0, 112); t.color(isButtonDown(100 + INPUT_BACKWARD) ? 0xC0C0C0 : 0xFFFFFF, 0x80); RenderTouchButton(&t, m_pAreaBackward, 128, 112); t.color(isButtonDown(100 + INPUT_JUMP) ? 0xC0C0C0 : 0xFFFFFF, 0x80); RenderTouchButton(&t, m_pAreaJump, 0, 176); t.draw(); glDisable(GL_BLEND); glEnable(GL_CULL_FACE); } RectangleArea TouchscreenInput_TestFps::getRectangleArea() { return m_rectArea; } bool TouchscreenInput_TestFps::isButtonDown(int key) { return field_6C[key - 100]; }