mirror of
https://github.com/celisej567/mcpe.git
synced 2026-09-23 20:09:46 +03:00
Integrate touch related development. (#90)
* * Add BuildActionIntention crap * * Set Client and World projects to use MP compilation * asd * * Use the new BuildActionIntention to break and place blocks. * * Reverse engineer the IArea system. * * Copy break logic from survival into creative conditionally * * Reverse IBuildInput and MouseHandler * Replace the new relative paths in the client project with $(MC_ROOT) again * * Reverse Multitouch, MouseDevice * * Reverse a bunch of auxiliary classes for input. * * Use CustomInputHolder instead of holding inputs manually. * * Reverse a whole BUNCH of things! * * Add feedback textures to the gitignore. * * D-pad now renders! Also loads of other work. * * More Stuff * * Finish touch control bug fixing. * * Finalize work. * * One last thing.. * * Add a "cramped" mode to the options screen and start menu. * * Oh, forgot to do something
This commit is contained in:
@@ -106,6 +106,11 @@ Texture AppPlatform::loadTexture(const std::string&, bool)
|
||||
return Texture(0, 0, nullptr, 1, 0);
|
||||
}
|
||||
|
||||
bool AppPlatform::isTouchscreen()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void AppPlatform::recenterMouse()
|
||||
{
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@ public:
|
||||
virtual Texture loadTexture(const std::string&, bool);
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
// From v0.1.1. Also add these to determine touch screen use within the game.
|
||||
virtual bool isTouchscreen();
|
||||
// Also add these to allow proper turning within the game.
|
||||
virtual void recenterMouse();
|
||||
virtual void setMouseGrabbed(bool b);
|
||||
|
||||
@@ -18,11 +18,13 @@
|
||||
#include "world/gamemode/SurvivalMode.hpp"
|
||||
#include "world/gamemode/CreativeMode.hpp"
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
#include "client/player/input/MouseTurnInput.hpp"
|
||||
#else
|
||||
#include "client/player/input/ControllerTurnInput.hpp"
|
||||
#endif
|
||||
#include "client/player/input/MouseTurnInput.hpp"
|
||||
#include "client/player/input/KeyboardInput.hpp"
|
||||
#include "client/player/input/IBuildInput.hpp"
|
||||
#include "client/player/input/CustomInputHolder.hpp"
|
||||
#include "client/player/input/TouchInputHolder.hpp"
|
||||
#include "client/player/input/Multitouch.hpp"
|
||||
|
||||
#include "world/tile/SandTile.hpp"
|
||||
|
||||
@@ -71,9 +73,7 @@ Minecraft::Minecraft() :
|
||||
m_pPrepThread = nullptr;
|
||||
m_pScreen = nullptr;
|
||||
field_D18 = 10;
|
||||
m_pTurnInput = nullptr;
|
||||
field_D20 = 0.0f;
|
||||
field_D24 = 0.0f;
|
||||
m_pInputHolder = nullptr;
|
||||
m_bGrabbedMouse = true;
|
||||
m_progressPercent = 0;
|
||||
m_bPreparingLevel = false;
|
||||
@@ -107,10 +107,14 @@ void Minecraft::releaseMouse()
|
||||
return;
|
||||
|
||||
if (m_pLocalPlayer)
|
||||
m_pLocalPlayer->m_pKeyboardInput->releaseAllKeys();
|
||||
m_pLocalPlayer->m_pMoveInput->releaseAllKeys();
|
||||
|
||||
m_bGrabbedMouse = false;
|
||||
m_mouseHandler.release();
|
||||
|
||||
// Note, normally the platform stuff would be located within
|
||||
// the mouse handler, but we don't have access to the platform
|
||||
// from there!
|
||||
platform()->setMouseGrabbed(false);
|
||||
}
|
||||
|
||||
@@ -120,11 +124,11 @@ void Minecraft::grabMouse()
|
||||
return;
|
||||
|
||||
m_bGrabbedMouse = true;
|
||||
field_D20 = 0.0f;
|
||||
field_D24 = 0.0f;
|
||||
m_mouseHandler.grab();
|
||||
|
||||
setScreen(nullptr);
|
||||
|
||||
platform()->setMouseGrabbed(true);
|
||||
platform()->setMouseGrabbed(!isTouchscreen());
|
||||
}
|
||||
|
||||
void Minecraft::setScreen(Screen* pScreen)
|
||||
@@ -209,6 +213,11 @@ bool Minecraft::isOnlineClient()
|
||||
return m_pLevel->m_bIsMultiplayer;
|
||||
}
|
||||
|
||||
bool Minecraft::isTouchscreen()
|
||||
{
|
||||
return m_bIsTouchscreen;
|
||||
}
|
||||
|
||||
void Minecraft::setGuiScaleMultiplier(float f)
|
||||
{
|
||||
guiScaleMultiplier = f;
|
||||
@@ -230,123 +239,129 @@ void Minecraft::handleMouseDown(int type, bool b)
|
||||
}
|
||||
}
|
||||
|
||||
void Minecraft::handleMouseClick(int type)
|
||||
void Minecraft::handleBuildAction(BuildActionIntention* pAction)
|
||||
{
|
||||
int a;
|
||||
|
||||
HitResult& hr = m_hitResult;
|
||||
|
||||
// @TODO: fix goto hell
|
||||
if (type == 1)
|
||||
if (pAction->isRemove())
|
||||
{
|
||||
if (field_DA4 > 0)
|
||||
return;
|
||||
|
||||
m_pLocalPlayer->swing();
|
||||
|
||||
if (m_hitResult.m_hitType != HitResult::NONE)
|
||||
goto label_3;
|
||||
|
||||
label_9:
|
||||
if (type != 1)
|
||||
goto label_5;
|
||||
|
||||
if (!m_pGameMode->isCreativeType())
|
||||
field_DA4 = 10;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_hitResult.m_hitType == HitResult::NONE)
|
||||
goto label_9;
|
||||
|
||||
label_3:
|
||||
if (m_hitResult.m_hitType != HitResult::ENTITY)
|
||||
bool bInteract = true;
|
||||
if (!m_hitResult.isHit())
|
||||
{
|
||||
if (m_hitResult.m_hitType != HitResult::AABB)
|
||||
goto label_5;
|
||||
|
||||
// @NOTE: extra scope to avoid error
|
||||
if (pAction->isRemove() && !m_pGameMode->isCreativeType())
|
||||
field_DA4 = 10;
|
||||
}
|
||||
else if (m_hitResult.m_hitType == HitResult::ENTITY)
|
||||
{
|
||||
if (pAction->isAttack())
|
||||
{
|
||||
Tile* pTile = Tile::tiles[m_pLevel->getTile(hr.m_tileX, hr.m_tileY, hr.m_tileZ)];
|
||||
m_pGameMode->attack(m_pLocalPlayer, m_hitResult.m_pEnt);
|
||||
}
|
||||
else if (pAction->isInteract())
|
||||
{
|
||||
if (m_hitResult.m_pEnt->interactPreventDefault())
|
||||
bInteract = false;
|
||||
|
||||
if (type == 1)
|
||||
{
|
||||
if (pTile)
|
||||
{
|
||||
// @BUG: This is only done on the client side.
|
||||
m_pLevel->extinguishFire(hr.m_tileX, hr.m_tileY, hr.m_tileZ, hr.m_hitSide);
|
||||
m_pGameMode->interact(m_pLocalPlayer, m_hitResult.m_pEnt);
|
||||
}
|
||||
}
|
||||
else if (m_hitResult.m_hitType == HitResult::AABB)
|
||||
{
|
||||
Tile* pTile = Tile::tiles[m_pLevel->getTile(m_hitResult.m_tileX, m_hitResult.m_tileY, m_hitResult.m_tileZ)];
|
||||
|
||||
if (pTile != Tile::unbreakable || (m_pLocalPlayer->field_B94 > 99 && !hr.m_bUnk24))
|
||||
{
|
||||
m_pGameMode->startDestroyBlock(hr.m_tileX, hr.m_tileY, hr.m_tileZ, hr.m_hitSide);
|
||||
}
|
||||
}
|
||||
if (pAction->isRemove())
|
||||
{
|
||||
if (!pTile)
|
||||
return;
|
||||
}
|
||||
|
||||
ItemInstance* pItem = getSelectedItem();
|
||||
// @BUG: This is only done on the client side.
|
||||
m_pLevel->extinguishFire(m_hitResult.m_tileX, m_hitResult.m_tileY, m_hitResult.m_tileZ, m_hitResult.m_hitSide);
|
||||
|
||||
if (m_pGameMode->useItemOn(m_pLocalPlayer, m_pLevel, pItem->m_itemID <= 0 ? nullptr : pItem, hr.m_tileX, hr.m_tileY, hr.m_tileZ, hr.m_hitSide))
|
||||
if (pTile != Tile::unbreakable || (m_pLocalPlayer->field_B94 > 99 && m_hitResult.m_bUnk24 != 1))
|
||||
{
|
||||
m_pLocalPlayer->swing();
|
||||
if (!isOnline())
|
||||
return;
|
||||
|
||||
if (pItem->m_itemID > C_MAX_TILES || pItem->m_itemID < 0)
|
||||
return;
|
||||
|
||||
int dx = hr.m_tileX, dz = hr.m_tileZ;
|
||||
uint8_t dy = uint8_t(hr.m_tileY);
|
||||
|
||||
if (m_pLevel->getTile(hr.m_tileX, hr.m_tileY, hr.m_tileZ) != Tile::topSnow->m_ID)
|
||||
{
|
||||
switch (hr.m_hitSide)
|
||||
{
|
||||
case HitResult::NOHIT: break;
|
||||
case HitResult::MINY: dy--; break;
|
||||
case HitResult::MAXY: dy++; break;
|
||||
case HitResult::MINZ: dz--; break;
|
||||
case HitResult::MAXZ: dz++; break;
|
||||
case HitResult::MINX: dx--; break;
|
||||
case HitResult::MAXX: dx++; break;
|
||||
}
|
||||
}
|
||||
|
||||
m_pRakNetInstance->send(new PlaceBlockPacket(m_pLocalPlayer->m_EntityID, dx, dy, dz, uint8_t(pItem->m_itemID), uint8_t(hr.m_hitSide)));
|
||||
return;
|
||||
m_pGameMode->startDestroyBlock(m_hitResult.m_tileX, m_hitResult.m_tileY, m_hitResult.m_tileZ, m_hitResult.m_hitSide);
|
||||
}
|
||||
}
|
||||
|
||||
label_5:
|
||||
if (type != 2)
|
||||
return;
|
||||
goto label_15;
|
||||
}
|
||||
|
||||
if (type == 1)
|
||||
{
|
||||
m_pGameMode->attack(m_pLocalPlayer, hr.m_pEnt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == 2)
|
||||
{
|
||||
a = hr.m_pEnt->interactPreventDefault();
|
||||
m_pGameMode->interact(m_pLocalPlayer, hr.m_pEnt);
|
||||
if (!a)
|
||||
else
|
||||
{
|
||||
label_15:
|
||||
int id = m_pLocalPlayer->m_pInventory->getSelectedItemId();
|
||||
if (id > 0)
|
||||
ItemInstance* pItem = getSelectedItem();
|
||||
if (m_pGameMode->useItemOn(
|
||||
m_pLocalPlayer,
|
||||
m_pLevel,
|
||||
pItem->m_itemID <= 0 ? nullptr : pItem,
|
||||
m_hitResult.m_tileX,
|
||||
m_hitResult.m_tileY,
|
||||
m_hitResult.m_tileZ,
|
||||
m_hitResult.m_hitSide))
|
||||
{
|
||||
ItemInstance* pItem = getSelectedItem();
|
||||
bInteract = false;
|
||||
|
||||
if (m_pGameMode->useItem(m_pLocalPlayer, m_pLevel, pItem))
|
||||
m_pGameRenderer->m_pItemInHandRenderer->itemUsed();
|
||||
m_pLocalPlayer->swing();
|
||||
|
||||
if (isOnline())
|
||||
{
|
||||
if (pItem->m_itemID > C_MAX_TILES || pItem->m_itemID < 0)
|
||||
return;
|
||||
|
||||
int dx = m_hitResult.m_tileX, dz = m_hitResult.m_tileZ;
|
||||
uint8_t dy = uint8_t(m_hitResult.m_tileY);
|
||||
|
||||
uint8_t hitSide = m_hitResult.m_hitSide;
|
||||
|
||||
if (m_pLevel->getTile(m_hitResult.m_tileX, m_hitResult.m_tileY, m_hitResult.m_tileZ) != Tile::topSnow->m_ID)
|
||||
{
|
||||
switch (m_hitResult.m_hitSide)
|
||||
{
|
||||
case HitResult::NOHIT: break;
|
||||
case HitResult::MINY: dy--; break;
|
||||
case HitResult::MAXY: dy++; break;
|
||||
case HitResult::MINZ: dz--; break;
|
||||
case HitResult::MAXZ: dz++; break;
|
||||
case HitResult::MINX: dx--; break;
|
||||
case HitResult::MAXX: dx++; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hitSide = HitResult::MINY;
|
||||
}
|
||||
|
||||
m_pRakNetInstance->send(new PlaceBlockPacket(m_pLocalPlayer->m_EntityID, dx, dy, dz, uint8_t(pItem->m_itemID), hitSide));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bInteract && pAction->isInteract())
|
||||
{
|
||||
ItemInstance* pItem = getSelectedItem();
|
||||
if (pItem)
|
||||
{
|
||||
if (m_pGameMode->useItem(m_pLocalPlayer, m_pLevel, pItem))
|
||||
m_pGameRenderer->m_pItemInHandRenderer->itemUsed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Minecraft::handleMouseClick(int type)
|
||||
{
|
||||
if (!isTouchscreen())
|
||||
{
|
||||
if (type == 1)
|
||||
{
|
||||
BuildActionIntention bai(INTENT_HELD);
|
||||
handleBuildAction(&bai);
|
||||
}
|
||||
if (type == 2)
|
||||
{
|
||||
BuildActionIntention bai(INTENT_CLICKED);
|
||||
handleBuildAction(&bai);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Minecraft::tickInput()
|
||||
@@ -379,42 +394,40 @@ void Minecraft::tickInput()
|
||||
if (getTimeMs() - field_2B4 > 200)
|
||||
continue;
|
||||
|
||||
if (Mouse::isButtonDown(1))
|
||||
if (Mouse::isButtonDown(BUTTON_LEFT))
|
||||
m_gui.handleClick(1, Mouse::getX(), Mouse::getY());
|
||||
|
||||
if (!bIsInGUI && getOptions()->field_19)
|
||||
{
|
||||
if (Mouse::getEventButton() == Mouse::LEFT && Mouse::getEventButtonState() == Mouse::DOWN)
|
||||
if (Mouse::getEventButton() == BUTTON_LEFT && Mouse::getEventButtonState())
|
||||
{
|
||||
handleMouseClick(1);
|
||||
field_DAC = field_DA8;
|
||||
}
|
||||
if (Mouse::getEventButton() == Mouse::RIGHT && Mouse::getEventButtonState() == Mouse::DOWN)
|
||||
if (Mouse::getEventButton() == BUTTON_RIGHT && Mouse::getEventButtonState())
|
||||
{
|
||||
handleMouseClick(2);
|
||||
field_DAC = field_DA8;
|
||||
}
|
||||
#ifdef ENH_ALLOW_SCROLL_WHEEL
|
||||
if (Mouse::getEventButton() == Mouse::SCROLLWHEEL)
|
||||
if (Mouse::getEventButton() == BUTTON_SCROLLWHEEL)
|
||||
{
|
||||
int slot = m_pLocalPlayer->m_pInventory->m_SelectedHotbarSlot;
|
||||
|
||||
#ifdef ENH_ENABLE_9TH_SLOT
|
||||
#define MAX_ITEMS (C_MAX_HOTBAR_ITEMS - 1)
|
||||
#else
|
||||
#define MAX_ITEMS (C_MAX_HOTBAR_ITEMS - 2)
|
||||
#endif
|
||||
int maxItems = m_gui.getNumSlots() - 1;
|
||||
if (isTouchscreen())
|
||||
maxItems--;
|
||||
|
||||
if (Mouse::getEventButtonState() <= 0) // @NOTE: Scroll up
|
||||
if (Mouse::getEventButtonState() == 0) // @NOTE: Scroll up
|
||||
{
|
||||
if (slot-- == 0)
|
||||
{
|
||||
slot = MAX_ITEMS;
|
||||
slot = maxItems;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (slot++ == MAX_ITEMS) // @NOTE: Scroll down
|
||||
if (slot++ == maxItems) // @NOTE: Scroll down
|
||||
{
|
||||
slot = 0;
|
||||
}
|
||||
@@ -431,13 +444,13 @@ void Minecraft::tickInput()
|
||||
int keyCode = Keyboard::getEventKey();
|
||||
bool bPressed = Keyboard::getEventKeyState() == 1;
|
||||
|
||||
m_pLocalPlayer->m_pKeyboardInput->setKey(keyCode, bPressed);
|
||||
m_pLocalPlayer->m_pMoveInput->setKey(keyCode, bPressed);
|
||||
|
||||
if (bPressed)
|
||||
{
|
||||
m_gui.handleKeyPressed(keyCode);
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
for (int i = 0; i < m_gui.getNumSlots(); i++)
|
||||
{
|
||||
if (getOptions()->isKey(eKeyMappingIndex(KM_SLOT_1 + i), keyCode))
|
||||
m_pLocalPlayer->m_pInventory->selectSlot(i);
|
||||
@@ -485,42 +498,41 @@ void Minecraft::tickInput()
|
||||
if (getTimeMs() - field_2B4 <= 200)
|
||||
{
|
||||
if (getOptions()->getKey(KM_DESTROY) == keyCode && bPressed)
|
||||
handleMouseClick(1);
|
||||
{
|
||||
BuildActionIntention intention(INTENT_HELD);
|
||||
handleBuildAction(&intention);
|
||||
}
|
||||
|
||||
if (getOptions()->getKey(KM_PLACE) == keyCode && bPressed)
|
||||
handleMouseClick(2);
|
||||
{
|
||||
BuildActionIntention intention(INTENT_CLICKED);
|
||||
handleBuildAction(&intention);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @TODO: fix gotos
|
||||
bool v12 = false;
|
||||
BuildActionIntention bai;
|
||||
bool b = m_pInputHolder->getBuildInput()->tickBuild(m_pLocalPlayer, &bai);
|
||||
|
||||
if (getOptions()->field_19)
|
||||
{
|
||||
if (!Mouse::isButtonDown(Mouse::LEFT) || bIsInGUI)
|
||||
goto label_12;
|
||||
}
|
||||
else if (Keyboard::isKeyDown(getOptions()->getKey(KM_DESTROY)))
|
||||
{
|
||||
goto label_12;
|
||||
}
|
||||
if (b && !bai.isRemoveContinue())
|
||||
handleBuildAction(&bai);
|
||||
|
||||
if (!m_pScreen && (field_DA8 - field_DAC) >= (m_timer.m_ticksPerSecond * 0.25f))
|
||||
bool flag =
|
||||
// If we are mouse operated, the LMB is held down and it's not in the GUI
|
||||
((m_options->field_19 && Mouse::isButtonDown(BUTTON_LEFT) && !bIsInGUI) ||
|
||||
// We are instead keyboard operated, so check for the KM_DESTROY key being held down
|
||||
(!m_options->field_19 && Keyboard::isKeyDown(m_options->m_keyMappings[KM_DESTROY].value)) ||
|
||||
// The build action intention is a remove one
|
||||
b && bai.isRemove());
|
||||
|
||||
if (flag && !m_pScreen && (field_DA8 - field_DAC) >= (m_timer.m_ticksPerSecond * 0.25f))
|
||||
{
|
||||
handleMouseClick(1);
|
||||
bai = BuildActionIntention(INTENT_HELD);
|
||||
handleBuildAction(&bai); // handleMouseClick(BUTTON_LEFT)
|
||||
field_DAC = field_DA8;
|
||||
}
|
||||
|
||||
if (m_bGrabbedMouse)
|
||||
{
|
||||
v12 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
label_12:
|
||||
v12 = false;
|
||||
}
|
||||
|
||||
handleMouseDown(1, v12);
|
||||
handleMouseDown(BUTTON_LEFT, flag);
|
||||
|
||||
field_2B4 = getTimeMs();
|
||||
|
||||
@@ -607,6 +619,38 @@ std::string Minecraft::getVersionString()
|
||||
return "v0.1.0 alpha";
|
||||
}
|
||||
|
||||
void Minecraft::_reloadInput()
|
||||
{
|
||||
if (m_pInputHolder)
|
||||
delete m_pInputHolder;
|
||||
|
||||
if (isTouchscreen())
|
||||
{
|
||||
m_pInputHolder = new TouchInputHolder(this, m_options);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pInputHolder = new CustomInputHolder(
|
||||
new KeyboardInput(m_options),
|
||||
#ifdef ORIGINAL_CODE
|
||||
new ControllerTurnInput,
|
||||
#else
|
||||
new MouseTurnInput(this),
|
||||
#endif
|
||||
new IBuildInput
|
||||
);
|
||||
}
|
||||
|
||||
m_mouseHandler.setTurnInput(m_pInputHolder->getTurnInput());
|
||||
|
||||
if (m_pLevel && m_pLocalPlayer)
|
||||
{
|
||||
m_pLocalPlayer->m_pMoveInput = m_pInputHolder->getMoveInput();
|
||||
}
|
||||
|
||||
m_options->field_19 = !isTouchscreen();
|
||||
}
|
||||
|
||||
void Minecraft::_levelGenerated()
|
||||
{
|
||||
if (m_pNetEventCallback)
|
||||
@@ -678,6 +722,8 @@ void Minecraft::tick()
|
||||
|
||||
if (m_pScreen)
|
||||
m_pScreen->tick();
|
||||
|
||||
Multitouch::reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -731,11 +777,9 @@ void Minecraft::init()
|
||||
else
|
||||
m_options = new Options();
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
m_pTurnInput = new MouseTurnInput(this);
|
||||
#else
|
||||
m_pTurnInput = new ControllerTurnInput;
|
||||
#endif
|
||||
m_bIsTouchscreen = platform()->isTouchscreen();
|
||||
|
||||
_reloadInput();
|
||||
|
||||
m_pRakNetInstance = new RakNetInstance;
|
||||
|
||||
@@ -796,7 +840,7 @@ Minecraft::~Minecraft()
|
||||
|
||||
SAFE_DELETE(m_pUser);
|
||||
SAFE_DELETE(m_pLevelStorageSource);
|
||||
SAFE_DELETE(m_pTurnInput);
|
||||
SAFE_DELETE(m_pInputHolder);
|
||||
SAFE_DELETE(m_Logger);
|
||||
|
||||
//@BUG: potentially leaking a CThread instance if this is destroyed early?
|
||||
@@ -904,6 +948,9 @@ void Minecraft::sizeUpdate(int newWidth, int newHeight)
|
||||
|
||||
if (m_pScreen)
|
||||
m_pScreen->setSize(int(Minecraft::width * Gui::InvGuiScale), int(Minecraft::height * Gui::InvGuiScale));
|
||||
|
||||
if (m_pInputHolder)
|
||||
m_pInputHolder->setScreenSize(newWidth, newHeight);
|
||||
}
|
||||
|
||||
float Minecraft::getBestScaleForThisScreenSize(int width, int height)
|
||||
@@ -911,23 +958,25 @@ float Minecraft::getBestScaleForThisScreenSize(int width, int height)
|
||||
if (height > 1800)
|
||||
return 1.0f / 4.0f;
|
||||
|
||||
// phones only
|
||||
#if !defined(_WIN32) && !defined(USE_SDL2)
|
||||
if (height > 600)
|
||||
return 1.0f / 4.0f;
|
||||
if (isTouchscreen())
|
||||
{
|
||||
if (height > 600)
|
||||
return 1.0f / 4.0f;
|
||||
|
||||
if (height > 400)
|
||||
return 1.0f / 3.0f;
|
||||
if (height > 400)
|
||||
return 1.0f / 3.0f;
|
||||
|
||||
if (height > 300)
|
||||
return 1.0f / 2.0f;
|
||||
#else
|
||||
if (height > 1000)
|
||||
return 1.0f / 3.0f;
|
||||
if (height > 300)
|
||||
return 1.0f / 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (height > 1000)
|
||||
return 1.0f / 3.0f;
|
||||
|
||||
if (height > 400)
|
||||
return 1.0f / 2.0f;
|
||||
#endif
|
||||
if (height > 400)
|
||||
return 1.0f / 2.0f;
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
@@ -953,9 +1002,7 @@ void Minecraft::generateLevel(const std::string& unused, Level* pLevel)
|
||||
}
|
||||
|
||||
if (pLocalPlayer)
|
||||
{
|
||||
pLocalPlayer->m_pKeyboardInput = new KeyboardInput(m_options);
|
||||
}
|
||||
pLocalPlayer->m_pMoveInput = m_pInputHolder->getMoveInput();
|
||||
|
||||
if (m_pLevelRenderer)
|
||||
m_pLevelRenderer->setLevel(pLevel);
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
#include "client/gui/Screen.hpp"
|
||||
#include "network/RakNetInstance.hpp"
|
||||
#include "network/NetEventCallback.hpp"
|
||||
#include "client/player/input/ITurnInput.hpp"
|
||||
#include "client/player/input/IInputHolder.hpp"
|
||||
#include "client/player/input/MouseHandler.hpp"
|
||||
#include "client/player/input/BuildActionIntention.hpp"
|
||||
#include "client/renderer/GameRenderer.hpp"
|
||||
#include "client/renderer/LevelRenderer.hpp"
|
||||
#include "client/renderer/entity/EntityRenderDispatcher.hpp"
|
||||
@@ -43,6 +45,7 @@ public:
|
||||
void saveOptions();
|
||||
void handleMouseClick(int type);
|
||||
void handleMouseDown(int type, bool b);
|
||||
void handleBuildAction(BuildActionIntention*);
|
||||
bool isLevelGenerated();
|
||||
void selectLevel(const std::string&, const std::string&, int);
|
||||
void setLevel(Level*, const std::string&, LocalPlayer*);
|
||||
@@ -58,6 +61,7 @@ public:
|
||||
void resetPlayer(Player* player);
|
||||
void respawnPlayer(Player* player);
|
||||
std::string getVersionString();
|
||||
bool isTouchscreen();
|
||||
|
||||
virtual void update() override;
|
||||
virtual void init() override;
|
||||
@@ -68,7 +72,6 @@ public:
|
||||
float getBestScaleForThisScreenSize(int width, int height);
|
||||
void generateLevel(const std::string& unused, Level* pLevel);
|
||||
void prepareLevel(const std::string& unused);
|
||||
void _levelGenerated();
|
||||
bool isOnline();
|
||||
bool isOnlineClient();
|
||||
static void* prepareLevel_tspawn(void* pMinecraft);
|
||||
@@ -80,6 +83,10 @@ public:
|
||||
|
||||
static void setGuiScaleMultiplier(float f);
|
||||
|
||||
private:
|
||||
void _reloadInput();
|
||||
void _levelGenerated();
|
||||
|
||||
public:
|
||||
static float guiScaleMultiplier;
|
||||
static int width, height;
|
||||
@@ -116,10 +123,10 @@ public:
|
||||
CThread* m_pPrepThread;
|
||||
Screen* m_pScreen;
|
||||
int field_D18;
|
||||
ITurnInput* m_pTurnInput;
|
||||
float field_D20;
|
||||
float field_D24;
|
||||
IInputHolder* m_pInputHolder;
|
||||
MouseHandler m_mouseHandler;
|
||||
bool m_bGrabbedMouse;
|
||||
bool m_bIsTouchscreen;
|
||||
HitResult m_hitResult;
|
||||
int m_progressPercent;
|
||||
std::string m_externalStorageDir;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "NinecraftApp.hpp"
|
||||
#include "world/item/Item.hpp"
|
||||
#include "client/player/input/Multitouch.hpp"
|
||||
#include "client/gui/screens/StartMenuScreen.hpp"
|
||||
|
||||
#ifdef DEMO
|
||||
@@ -107,6 +108,7 @@ void NinecraftApp::teardown()
|
||||
void NinecraftApp::update()
|
||||
{
|
||||
++m_fps;
|
||||
Multitouch::commit();
|
||||
Minecraft::update();
|
||||
|
||||
#ifdef ORIGINAL_CODE
|
||||
|
||||
@@ -134,6 +134,8 @@ void Gui::render(float f, bool bHaveScreen, int mouseX, int mouseY)
|
||||
if (!m->m_pLevel || !m->m_pLocalPlayer)
|
||||
return;
|
||||
|
||||
bool isTouchscreen = m->isTouchscreen();
|
||||
|
||||
field_4 = -90.0f;
|
||||
|
||||
#ifndef ENH_TRANSPARENT_HOTBAR
|
||||
@@ -156,25 +158,86 @@ void Gui::render(float f, bool bHaveScreen, int mouseX, int mouseY)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
#endif
|
||||
|
||||
int nSlots = getNumSlots();
|
||||
int hotbarWidth = 2 + nSlots * 20;
|
||||
|
||||
// hotbar
|
||||
int cenX = width / 2;
|
||||
blit(cenX - 182 / 2, height - 22, 0, 0, 182, 22, 0, 0);
|
||||
blit(cenX - hotbarWidth / 2, height - 22, 0, 0, hotbarWidth, 22, 0, 0);
|
||||
|
||||
// selection mark
|
||||
blit(cenX - 92 + 20 * pInventory->m_SelectedHotbarSlot, height - 23, 0, 22, 24, 22, 0, 0);
|
||||
blit(cenX - 1 - hotbarWidth / 2 + 20 * pInventory->m_SelectedHotbarSlot, height - 23, 0, 22, 24, 22, 0, 0);
|
||||
|
||||
m->m_pTextures->loadAndBindTexture("gui/icons.png");
|
||||
|
||||
if (!isTouchscreen)
|
||||
{
|
||||
#ifndef ENH_TRANSPARENT_HOTBAR
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_BLEND);
|
||||
#endif
|
||||
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR);
|
||||
blit(cenX - 8, height / 2 - 8, 0, 0, 16, 16, 0, 0);
|
||||
#ifndef ENH_TRANSPARENT_HOTBAR
|
||||
glDisable(GL_BLEND);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// if needed, draw feedback
|
||||
|
||||
// NOTE: real Minecraft PE takes it directly from the gamemode as "current progress" and
|
||||
// "last progress". Well guess what? The game mode in question updates our field_8 with
|
||||
// the pre-interpolated break progress! Isn't that awesome?!
|
||||
float breakProgress = field_8;
|
||||
|
||||
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR);
|
||||
// don't know about this if-structure, it feels like it'd be like
|
||||
// if (field_C >= 0.0f && breakProgress <= 0.0f)
|
||||
// that;
|
||||
// else
|
||||
// this;
|
||||
if (breakProgress > 0.0f || m_pMinecraft->m_pInputHolder->m_feedbackAlpha < 0.0f)
|
||||
{
|
||||
if (breakProgress > 0.0f)
|
||||
{
|
||||
float xPos = m_pMinecraft->m_pInputHolder->m_feedbackX;
|
||||
float yPos = m_pMinecraft->m_pInputHolder->m_feedbackY;
|
||||
|
||||
// crosshair
|
||||
blit(cenX - 8, height / 2 - 8, 0, 0, 16, 16, 0, 0);
|
||||
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/feedback_outer.png");
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
blit(InvGuiScale * xPos - 44.0f, InvGuiScale * yPos - 44.0f, 0, 0, 88, 88, 256, 256);
|
||||
|
||||
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR);
|
||||
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/feedback_fill.png");
|
||||
|
||||
// note: scale starts from 4.0f
|
||||
float halfWidth = (40.0f * breakProgress + 48.0f) / 2.0f;
|
||||
|
||||
blit(InvGuiScale * xPos - halfWidth, InvGuiScale * yPos - halfWidth, 0, 0, halfWidth * 2, halfWidth * 2, 256, 256);
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float xPos = m_pMinecraft->m_pInputHolder->m_feedbackX;
|
||||
float yPos = m_pMinecraft->m_pInputHolder->m_feedbackY;
|
||||
|
||||
m_pMinecraft->m_pTextures->loadAndBindTexture("gui/feedback_outer.png");
|
||||
glColor4f(1.0f, 1.0f, 1.0f, Mth::Min(1.0f, m_pMinecraft->m_pInputHolder->m_feedbackAlpha));
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
blit(InvGuiScale * xPos - 44.0f, InvGuiScale * yPos - 44.0f, 0, 0, 88, 88, 256, 256);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENH_TRANSPARENT_HOTBAR
|
||||
glDisable(GL_BLEND);
|
||||
#endif
|
||||
|
||||
if (m_pMinecraft->m_pGameMode->canHurtPlayer())
|
||||
{
|
||||
@@ -259,29 +322,34 @@ void Gui::render(float f, bool bHaveScreen, int mouseX, int mouseY)
|
||||
|
||||
m->m_pTextures->loadAndBindTexture("gui/gui_blocks.png");
|
||||
|
||||
int slotX = cenX - 88;
|
||||
for (int i = 0; i < C_MAX_HOTBAR_ITEMS; i++)
|
||||
int diff = m->isTouchscreen();
|
||||
|
||||
int slotX = cenX - hotbarWidth / 2 + 3;
|
||||
for (int i = 0; i < nSlots - diff; i++)
|
||||
{
|
||||
renderSlot(i, slotX, height - 19, f);
|
||||
|
||||
slotX += 20;
|
||||
}
|
||||
|
||||
slotX = cenX - 88;
|
||||
for (int i = 0; i < C_MAX_HOTBAR_ITEMS; i++)
|
||||
slotX = cenX - hotbarWidth / 2 + 3;
|
||||
for (int i = 0; i < nSlots - diff; i++)
|
||||
{
|
||||
renderSlotOverlay(i, slotX, height - 19, f);
|
||||
|
||||
slotX += 20;
|
||||
}
|
||||
|
||||
#undef DIFF
|
||||
|
||||
field_A3C = false;
|
||||
|
||||
// blit the "more items" button
|
||||
#ifndef ENH_ENABLE_9TH_SLOT
|
||||
m->m_pTextures->loadAndBindTexture(C_TERRAIN_NAME);
|
||||
blit(cenX + 72, height - 19, 208, 208, 16, 16, 0, 0);
|
||||
#endif
|
||||
if (m->isTouchscreen())
|
||||
{
|
||||
m->m_pTextures->loadAndBindTexture(C_TERRAIN_NAME);
|
||||
blit(cenX + hotbarWidth / 2 - 19, height - 19, 208, 208, 16, 16, 0, 0);
|
||||
}
|
||||
|
||||
// render messages
|
||||
if (m_bRenderMessages)
|
||||
@@ -339,16 +407,17 @@ int Gui::getSlotIdAt(int mouseX, int mouseY)
|
||||
|
||||
if (scaledY >= scaledHeight)
|
||||
return -1;
|
||||
if (scaledY < scaledHeight-19)
|
||||
if (scaledY < scaledHeight - 19)
|
||||
return -1;
|
||||
|
||||
int slotX = (int(InvGuiScale * mouseX) - int(InvGuiScale * Minecraft::width) / 2 + 88 + 20) / 20;
|
||||
int hotbarOffset = getNumSlots() * 20 / 2 - 2;
|
||||
|
||||
int slotX = (int(InvGuiScale * mouseX) - int(InvGuiScale * Minecraft::width) / 2 + hotbarOffset + 20) / 20;
|
||||
|
||||
//@NOTE: Why not just -88?
|
||||
if (slotX >= 0)
|
||||
slotX--;
|
||||
|
||||
if (slotX > 8)
|
||||
if (slotX > getNumSlots())
|
||||
slotX = -1;
|
||||
|
||||
return slotX;
|
||||
@@ -368,16 +437,10 @@ void Gui::handleClick(int clickID, int mouseX, int mouseY)
|
||||
if (slot == -1)
|
||||
return;
|
||||
|
||||
#ifndef ENH_ENABLE_9TH_SLOT
|
||||
if (slot == 8)
|
||||
{
|
||||
if (m_pMinecraft->isTouchscreen() && slot == getNumSlots() - 1)
|
||||
m_pMinecraft->setScreen(new IngameBlockSelectionScreen);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
m_pMinecraft->m_pLocalPlayer->m_pInventory->selectSlot(slot);
|
||||
}
|
||||
}
|
||||
|
||||
void Gui::handleKeyPressed(int keyCode)
|
||||
@@ -387,17 +450,16 @@ void Gui::handleKeyPressed(int keyCode)
|
||||
m_pMinecraft->setScreen(new IngameBlockSelectionScreen);
|
||||
return;
|
||||
}
|
||||
|
||||
int maxItems = getNumSlots() - 1;
|
||||
if (m_pMinecraft->isTouchscreen())
|
||||
maxItems--;
|
||||
|
||||
if (m_pMinecraft->getOptions()->isKey(KM_SLOT_R, keyCode))
|
||||
{
|
||||
int* slot = &m_pMinecraft->m_pLocalPlayer->m_pInventory->m_SelectedHotbarSlot;
|
||||
|
||||
#ifdef ENH_ENABLE_9TH_SLOT
|
||||
#define MAX_ITEMS (C_MAX_HOTBAR_ITEMS - 2)
|
||||
#else
|
||||
#define MAX_ITEMS (C_MAX_HOTBAR_ITEMS - 3)
|
||||
#endif
|
||||
//@HUH: for whatever reason, it ignores the 7th item
|
||||
if (*slot <= MAX_ITEMS)
|
||||
if (*slot <= maxItems)
|
||||
(*slot)++;
|
||||
|
||||
return;
|
||||
@@ -465,3 +527,22 @@ void Gui::renderMessages(bool bShowAll)
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
int Gui::getNumSlots()
|
||||
{
|
||||
if (m_pMinecraft->isTouchscreen())
|
||||
return 4;
|
||||
|
||||
return 9;
|
||||
}
|
||||
|
||||
RectangleArea Gui::getRectangleArea(bool b)
|
||||
{
|
||||
float centerX = Minecraft::width / 2;
|
||||
float hotbarWidthHalf = (10 * getNumSlots() + 5) / InvGuiScale;
|
||||
return RectangleArea(
|
||||
b ? (centerX - hotbarWidthHalf) : 0,
|
||||
Minecraft::height - 24.0f / InvGuiScale,
|
||||
centerX + hotbarWidthHalf,
|
||||
Minecraft::height);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "GuiComponent.hpp"
|
||||
#include "client/player/input/RectangleArea.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "common/Random.hpp"
|
||||
#include "common/Utils.hpp"
|
||||
@@ -41,6 +42,8 @@ public:
|
||||
void handleClick(int id, int mx, int my);
|
||||
void handleKeyPressed(int keyCode);
|
||||
void renderMessages(bool bShowAll);
|
||||
int getNumSlots();
|
||||
RectangleArea getRectangleArea(bool b);
|
||||
|
||||
public:
|
||||
static float InvGuiScale;
|
||||
|
||||
@@ -97,7 +97,7 @@ void RolledSelectionList::render(int mouseX, int mouseY, float f)
|
||||
int nItems = getNumberOfItems();
|
||||
|
||||
// @TODO: fix gotos.
|
||||
if (!Mouse::isButtonDown(1))
|
||||
if (!Mouse::isButtonDown(BUTTON_LEFT))
|
||||
{
|
||||
if (field_28 < 0)
|
||||
{
|
||||
|
||||
@@ -81,7 +81,7 @@ void ScrolledSelectionList::render(int mouseX, int mouseY, float f)
|
||||
renderBackground();
|
||||
|
||||
int nItems = getNumberOfItems();
|
||||
if (Mouse::isButtonDown(1))
|
||||
if (Mouse::isButtonDown(BUTTON_LEFT))
|
||||
{
|
||||
if (float(mouseY) >= field_C && float(mouseY) <= field_10 && mouseY != field_28)
|
||||
{
|
||||
|
||||
@@ -46,7 +46,7 @@ void WorldSelectionList::tick()
|
||||
{
|
||||
RolledSelectionList::tick();
|
||||
field_D0++;
|
||||
if (Mouse::isButtonDown(1) || !field_28)
|
||||
if (Mouse::isButtonDown(BUTTON_LEFT) || !field_28)
|
||||
return;
|
||||
|
||||
m_selectedIndex = -1;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
********************************************************************/
|
||||
|
||||
#include "IngameBlockSelectionScreen.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "client/renderer/entity/ItemRenderer.hpp"
|
||||
|
||||
std::string g_sNotAvailableInDemoVersion = "Not available in the demo version";
|
||||
@@ -178,7 +179,7 @@ void IngameBlockSelectionScreen::selectSlotAndClose()
|
||||
{
|
||||
Inventory* pInv = getInventory();
|
||||
|
||||
pInv->selectItem(m_selectedSlot);
|
||||
pInv->selectItem(m_selectedSlot, m_pMinecraft->m_gui.getNumSlots());
|
||||
|
||||
m_pMinecraft->m_pSoundEngine->play("random.click");
|
||||
m_pMinecraft->setScreen(nullptr);
|
||||
|
||||
@@ -43,11 +43,11 @@ OptionsScreen::OptionsScreen()
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
static std::string BoolOptionStr(bool b)
|
||||
{
|
||||
return b ? "ON" : "OFF";
|
||||
}
|
||||
|
||||
static std::string ViewDistanceStr(int dist)
|
||||
{
|
||||
switch (dist)
|
||||
@@ -66,7 +66,7 @@ static std::string ViewDistanceStr(int dist)
|
||||
}
|
||||
}
|
||||
|
||||
void OptionsScreen::UpdateTexts()
|
||||
void OptionsScreen::updateTexts()
|
||||
{
|
||||
Options& o = *(m_pMinecraft->getOptions());
|
||||
|
||||
@@ -78,20 +78,62 @@ void OptionsScreen::UpdateTexts()
|
||||
m_flightHaxButton.m_text = "Flight hax: " + BoolOptionStr(o.m_bFlyCheat);
|
||||
m_autoJumpButton.m_text = "Auto Jump: " + BoolOptionStr(o.m_bAutoJump);
|
||||
m_viewDistButton.m_text = "View distance: " + ViewDistanceStr(o.m_iViewDistance);
|
||||
m_srvVisButton.m_text = "Server " + std::string(o.m_bServerVisibleDefault ? "visible" : "invisible") + " by default";
|
||||
m_blockLinesButton.m_text = "Block outlines: " + BoolOptionStr(o.m_bBlockOutlines);
|
||||
|
||||
if (!isCramped())
|
||||
m_srvVisButton.m_text = "Server " + std::string(o.m_bServerVisibleDefault ? "visible" : "invisible") + " by default";
|
||||
else
|
||||
m_srvVisButton.m_text = "Server " + std::string(o.m_bServerVisibleDefault ? "visible" : "invisible");
|
||||
}
|
||||
bool OptionsScreen::isCramped()
|
||||
{
|
||||
return m_width < 150 * 2 + 20 || m_height < 200;
|
||||
}
|
||||
|
||||
void OptionsScreen::setWidthAllButtons(int width)
|
||||
{
|
||||
m_AOButton.m_width =
|
||||
m_srvVisButton.m_width =
|
||||
m_fancyGfxButton.m_width =
|
||||
m_viewDistButton.m_width =
|
||||
m_blockLinesButton.m_width =
|
||||
m_invertYButton.m_width =
|
||||
m_anaglyphsButton.m_width =
|
||||
m_viewBobButton.m_width =
|
||||
m_flightHaxButton.m_width =
|
||||
m_autoJumpButton.m_width = width;
|
||||
}
|
||||
#endif
|
||||
|
||||
void OptionsScreen::init()
|
||||
{
|
||||
m_pMinecraft->platform()->showDialog(AppPlatform::DLG_OPTIONS);
|
||||
m_pMinecraft->platform()->createUserInput();
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
bool crampedMode = isCramped();
|
||||
|
||||
int incrementY = 25;
|
||||
int yPos = 40;
|
||||
int backGap = 12;
|
||||
|
||||
// If the screen's width can't fit two buttons and a small amount of padding,
|
||||
// consider ourselves cramped.
|
||||
if (crampedMode)
|
||||
{
|
||||
crampedMode = true;
|
||||
incrementY = 22;
|
||||
yPos = 20;
|
||||
backGap = 5;
|
||||
setWidthAllButtons(125);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Initialize the default buttons' widths.
|
||||
setWidthAllButtons(150);
|
||||
}
|
||||
|
||||
m_BackButton.m_xPos = m_width / 2 - m_BackButton.m_width / 2;
|
||||
m_BackButton.m_yPos = m_height - 33;
|
||||
m_BackButton.m_height = 20;
|
||||
m_BackButton.m_yPos = m_height - m_BackButton.m_height - backGap;
|
||||
m_buttons.push_back(&m_BackButton);
|
||||
|
||||
m_AOButton.m_xPos =
|
||||
@@ -106,12 +148,11 @@ void OptionsScreen::init()
|
||||
m_flightHaxButton.m_xPos =
|
||||
m_autoJumpButton.m_xPos = m_width / 2 + 5;
|
||||
|
||||
int yPos = 40;
|
||||
m_AOButton.m_yPos = m_invertYButton.m_yPos = yPos; yPos += 25;
|
||||
m_srvVisButton.m_yPos = m_anaglyphsButton.m_yPos = yPos; yPos += 25;
|
||||
m_fancyGfxButton.m_yPos = m_viewBobButton.m_yPos = yPos; yPos += 25;
|
||||
m_viewDistButton.m_yPos = m_flightHaxButton.m_yPos = yPos; yPos += 25;
|
||||
m_autoJumpButton.m_yPos = m_blockLinesButton.m_yPos = yPos; yPos += 25;
|
||||
m_AOButton.m_yPos = m_invertYButton.m_yPos = yPos; yPos += incrementY;
|
||||
m_srvVisButton.m_yPos = m_anaglyphsButton.m_yPos = yPos; yPos += incrementY;
|
||||
m_fancyGfxButton.m_yPos = m_viewBobButton.m_yPos = yPos; yPos += incrementY;
|
||||
m_viewDistButton.m_yPos = m_flightHaxButton.m_yPos = yPos; yPos += incrementY;
|
||||
m_autoJumpButton.m_yPos = m_blockLinesButton.m_yPos = yPos; yPos += incrementY;
|
||||
|
||||
m_buttons.push_back(&m_AOButton);
|
||||
m_buttons.push_back(&m_srvVisButton);
|
||||
@@ -137,12 +178,11 @@ void OptionsScreen::init()
|
||||
|
||||
m_buttonTabList.push_back(&m_BackButton);
|
||||
|
||||
UpdateTexts();
|
||||
updateTexts();
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
m_srvVisButton.m_bEnabled = false;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void OptionsScreen::render(int a, int b, float c)
|
||||
@@ -158,7 +198,7 @@ void OptionsScreen::render(int a, int b, float c)
|
||||
}
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
drawCenteredString(m_pFont, "Options", m_width / 2, 20, 0xFFFFFF);
|
||||
drawCenteredString(m_pFont, "Options", m_width / 2, isCramped() ? 5 : 20, 0xFFFFFF);
|
||||
|
||||
Screen::render(a, b, c);
|
||||
#endif
|
||||
@@ -188,17 +228,17 @@ void OptionsScreen::buttonClicked(Button* pButton)
|
||||
o.m_bAmbientOcclusion = !o.m_bAmbientOcclusion;
|
||||
Minecraft::useAmbientOcclusion = o.m_bAmbientOcclusion;
|
||||
m_pMinecraft->m_pLevelRenderer->allChanged();
|
||||
UpdateTexts();
|
||||
updateTexts();
|
||||
return;
|
||||
case OB_FANCY_GFX:
|
||||
o.m_bFancyGraphics ^= 1;
|
||||
m_pMinecraft->m_pLevelRenderer->allChanged();
|
||||
UpdateTexts();
|
||||
updateTexts();
|
||||
return;
|
||||
case OB_VIEW_DIST:
|
||||
// @TODO: fix the 'extreme' render distance
|
||||
o.m_iViewDistance = (o.m_iViewDistance + 1) % 4;
|
||||
UpdateTexts();
|
||||
updateTexts();
|
||||
return;
|
||||
|
||||
case OB_ANAGLYPHS:
|
||||
@@ -228,7 +268,7 @@ void OptionsScreen::buttonClicked(Button* pButton)
|
||||
return;
|
||||
|
||||
*pOption = !(*pOption);
|
||||
UpdateTexts();
|
||||
updateTexts();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,9 @@ public:
|
||||
#ifndef ORIGINAL_CODE
|
||||
void buttonClicked(Button* pButton) override;
|
||||
|
||||
void UpdateTexts();
|
||||
void setWidthAllButtons(int width);
|
||||
void updateTexts();
|
||||
bool isCramped();
|
||||
|
||||
private:
|
||||
Button m_BackButton;
|
||||
|
||||
@@ -45,7 +45,7 @@ void SelectWorldScreen::init()
|
||||
m_buttons.push_back(&m_btnBack);
|
||||
m_buttons.push_back(&m_btnDelete);
|
||||
|
||||
field_12C = Mouse::getButtonState(Mouse::NONE) == Mouse::UP;
|
||||
field_12C = Mouse::getButtonState(BUTTON_LEFT);
|
||||
|
||||
m_buttonTabList.push_back(&m_btnUnknown);
|
||||
m_buttonTabList.push_back(&m_btnDelete);
|
||||
@@ -173,7 +173,7 @@ void SelectWorldScreen::render(int mouseX, int mouseY, float f)
|
||||
else
|
||||
{
|
||||
m_pWorldSelectionList->render(0, 0, f);
|
||||
field_12C = Mouse::getButtonState(Mouse::LEFT) == Mouse::UP;
|
||||
field_12C = Mouse::getButtonState(BUTTON_LEFT);
|
||||
}
|
||||
|
||||
Screen::render(mouseX, mouseY, f);
|
||||
|
||||
@@ -337,7 +337,6 @@ StartMenuScreen::StartMenuScreen() :
|
||||
m_optionsButton(4, 0, 0, 78, 22, "Options"),
|
||||
m_testButton (999, 0, 0, 78, 22, "Test"),
|
||||
m_buyButton (5, 0, 0, 78, 22, "Buy")
|
||||
//, m_testBox(1, 10, 10, 200, 16, "Insert some text...")
|
||||
{
|
||||
m_chosenSplash = -1;
|
||||
}
|
||||
@@ -466,9 +465,11 @@ void StartMenuScreen::render(int a, int b, float c)
|
||||
int id = tx->loadTexture("gui/title.png", true);
|
||||
Texture *pTex = tx->getTemporaryTextureData(id);
|
||||
|
||||
//const int titleYPos = 4;
|
||||
//const int titleYPos = 30; // -- MC Java position
|
||||
const int titleYPos = 15;
|
||||
//int titleYPos = 4;
|
||||
//int titleYPos = 30; // -- MC Java position
|
||||
int titleYPos = 15;
|
||||
|
||||
bool crampedMode = false;
|
||||
|
||||
if (pTex)
|
||||
{
|
||||
@@ -482,6 +483,12 @@ void StartMenuScreen::render(int a, int b, float c)
|
||||
int width = pTex->m_width;
|
||||
int height = pTex->m_height;
|
||||
|
||||
if (m_width * 3 / 4 < width)
|
||||
{
|
||||
crampedMode = true;
|
||||
titleYPos = 4;
|
||||
}
|
||||
|
||||
Tesselator& t = Tesselator::instance;
|
||||
glColor4f(1, 1, 1, 1);
|
||||
t.begin();
|
||||
@@ -495,12 +502,26 @@ void StartMenuScreen::render(int a, int b, float c)
|
||||
drawString(m_pFont, field_170, field_188, 58 + titleYPos, 0xFFCCCCCC);
|
||||
drawString(m_pFont, field_154, field_16C, m_height - 10, 0x00FFFFFF);
|
||||
|
||||
// Draw the splash text.
|
||||
// Draw the splash text, if we have enough room.
|
||||
if (!crampedMode)
|
||||
drawSplash();
|
||||
|
||||
Screen::render(a, b, c);
|
||||
}
|
||||
|
||||
void StartMenuScreen::tick()
|
||||
{
|
||||
Screen::tick();
|
||||
_updateLicense();
|
||||
}
|
||||
|
||||
void StartMenuScreen::drawSplash()
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
std::string splashText = getSplashString();
|
||||
int textWidth = m_pFont->width(splashText);
|
||||
//int textHeight = m_pFont->height(splashText);
|
||||
int textWidth = m_pFont->width(splashText);
|
||||
//int textHeight = m_pFont->height(splashText);
|
||||
|
||||
glTranslatef(float(m_width) / 2.0f + 90.0f, 70.0f, 0.0f);
|
||||
glRotatef(-20.0f, 0.0f, 0.0f, 1.0f);
|
||||
@@ -513,21 +534,6 @@ void StartMenuScreen::render(int a, int b, float c)
|
||||
drawCenteredString(m_pFont, splashText, 0, -8, 0xFFFF00);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
// for debugging
|
||||
/*
|
||||
m_pMinecraft->m_pTextures->loadAndBindTexture(C_TERRAIN_NAME);
|
||||
glColor4f(1, 1, 1, 1);
|
||||
blit(0, 0, 0, 0, 256, 256, 0, 0);
|
||||
*/
|
||||
|
||||
Screen::render(a, b, c);
|
||||
}
|
||||
|
||||
void StartMenuScreen::tick()
|
||||
{
|
||||
Screen::tick();
|
||||
_updateLicense();
|
||||
}
|
||||
|
||||
std::string StartMenuScreen::getSplashString()
|
||||
|
||||
@@ -22,6 +22,8 @@ public:
|
||||
void render(int, int, float) override;
|
||||
void tick() override;
|
||||
|
||||
void drawSplash();
|
||||
|
||||
std::string getSplashString();
|
||||
|
||||
private:
|
||||
|
||||
@@ -361,7 +361,7 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, PlayerE
|
||||
return;
|
||||
}
|
||||
|
||||
pPlayer->m_pInventory->selectItemById(pPlayerEquipmentPkt->m_itemID);
|
||||
pPlayer->m_pInventory->selectItemById(pPlayerEquipmentPkt->m_itemID, C_MAX_HOTBAR_ITEMS);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, LevelDataPacket* packet)
|
||||
|
||||
@@ -50,12 +50,12 @@ void Options::_initDefaultValues()
|
||||
m_bViewBobbing = 1;
|
||||
m_bAutoJump = true;
|
||||
m_bFancyGraphics = true;
|
||||
field_19 = 1;
|
||||
field_1C = "Default";
|
||||
m_playerName = "Steve";
|
||||
m_bServerVisibleDefault = true;
|
||||
m_bDebugText = false;
|
||||
m_bBlockOutlines = false;
|
||||
field_19 = 1;
|
||||
|
||||
// Win32 key codes are being used by default
|
||||
#define KM(idx, name, code) m_keyMappings[idx] = KeyMapping(name, code)
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
uint8_t field_16;
|
||||
bool m_bFancyGraphics;
|
||||
bool m_bAmbientOcclusion;
|
||||
uint8_t field_19;
|
||||
uint8_t field_19; // use Mouse as input for breaking
|
||||
std::string field_1C;
|
||||
KeyMapping m_keyMappings[KM_COUNT];
|
||||
int field_238;
|
||||
|
||||
47
source/client/player/input/BuildActionIntention.hpp
Normal file
47
source/client/player/input/BuildActionIntention.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/********************************************************************
|
||||
ReMinecraftPE
|
||||
Copyright (C) 2023 iProgramInCpp
|
||||
|
||||
The following code is licensed under the BSD 1 clause license.
|
||||
SPDX-License-Identifier: BSD-1-Clause
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum eBuildActionIntent
|
||||
{
|
||||
INTENT_CLICKED = 1, // touch screen was clicked
|
||||
INTENT_HELD = 2, // touch screen is being held down
|
||||
INTENT_FIRST_REMOVE = 10, // after a small delay, starts breaking with this as a signal
|
||||
};
|
||||
|
||||
class BuildActionIntention
|
||||
{
|
||||
public:
|
||||
BuildActionIntention() : m_type(0) {}
|
||||
BuildActionIntention(int type) : m_type(type) {}
|
||||
|
||||
bool isAttack() const {
|
||||
return m_type == INTENT_CLICKED;
|
||||
}
|
||||
|
||||
bool isFirstRemove() const {
|
||||
return m_type == INTENT_FIRST_REMOVE;
|
||||
}
|
||||
|
||||
bool isInteract() const {
|
||||
return m_type == INTENT_HELD;
|
||||
}
|
||||
|
||||
bool isRemove() const {
|
||||
return isFirstRemove() || isRemoveContinue();
|
||||
}
|
||||
|
||||
bool isRemoveContinue() const {
|
||||
return m_type == INTENT_HELD;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_type;
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ ControllerTurnInput::ControllerTurnInput()
|
||||
field_18 = false;
|
||||
}
|
||||
|
||||
ITurnInput::Delta ControllerTurnInput::getTurnDelta()
|
||||
TurnDelta ControllerTurnInput::getTurnDelta()
|
||||
{
|
||||
bool isTouched = Controller::isTouched(m_stickNo);
|
||||
float deltaX, deltaY;
|
||||
@@ -129,5 +129,10 @@ ITurnInput::Delta ControllerTurnInput::getTurnDelta()
|
||||
}
|
||||
|
||||
field_18 = isTouched;
|
||||
return Delta(deltaX, deltaY);
|
||||
return TurnDelta(deltaX, deltaY);
|
||||
}
|
||||
|
||||
bool ControllerTurnInput::smoothTurning()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ class ControllerTurnInput : public ITurnInput
|
||||
{
|
||||
public:
|
||||
ControllerTurnInput();
|
||||
ITurnInput::Delta getTurnDelta();
|
||||
TurnDelta getTurnDelta() override;
|
||||
bool smoothTurning() override;
|
||||
|
||||
private:
|
||||
int field_8;
|
||||
|
||||
36
source/client/player/input/CustomInputHolder.cpp
Normal file
36
source/client/player/input/CustomInputHolder.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/********************************************************************
|
||||
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 "CustomInputHolder.hpp"
|
||||
|
||||
CustomInputHolder::CustomInputHolder(IMoveInput* pMoveInput, ITurnInput* pTurnInput, IBuildInput* pBuildInput)
|
||||
{
|
||||
setInputs(pMoveInput, pTurnInput, pBuildInput);
|
||||
}
|
||||
|
||||
IMoveInput* CustomInputHolder::getMoveInput()
|
||||
{
|
||||
return m_pMoveInput;
|
||||
}
|
||||
|
||||
ITurnInput* CustomInputHolder::getTurnInput()
|
||||
{
|
||||
return m_pTurnInput;
|
||||
}
|
||||
|
||||
IBuildInput* CustomInputHolder::getBuildInput()
|
||||
{
|
||||
return m_pBuildInput;
|
||||
}
|
||||
|
||||
void CustomInputHolder::setInputs(IMoveInput* pMoveInput, ITurnInput* pTurnInput, IBuildInput* pBuildInput)
|
||||
{
|
||||
m_pMoveInput = pMoveInput;
|
||||
m_pTurnInput = pTurnInput;
|
||||
m_pBuildInput = pBuildInput;
|
||||
}
|
||||
30
source/client/player/input/CustomInputHolder.hpp
Normal file
30
source/client/player/input/CustomInputHolder.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IInputHolder.hpp"
|
||||
|
||||
class CustomInputHolder : public IInputHolder
|
||||
{
|
||||
public:
|
||||
CustomInputHolder(IMoveInput*, ITurnInput*, IBuildInput*);
|
||||
|
||||
IMoveInput* getMoveInput() override;
|
||||
ITurnInput* getTurnInput() override;
|
||||
IBuildInput* getBuildInput() override;
|
||||
|
||||
void setInputs(IMoveInput*, ITurnInput*, IBuildInput*);
|
||||
|
||||
|
||||
private:
|
||||
IMoveInput* m_pMoveInput;
|
||||
ITurnInput* m_pTurnInput;
|
||||
IBuildInput* m_pBuildInput;
|
||||
};
|
||||
|
||||
20
source/client/player/input/IArea.hpp
Normal file
20
source/client/player/input/IArea.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
class IArea
|
||||
{
|
||||
public:
|
||||
IArea() : field_4(true) {}
|
||||
virtual bool isInside(float, float) = 0;
|
||||
|
||||
public:
|
||||
bool field_4; // could this mean something like "was allocated via new()"?
|
||||
};
|
||||
|
||||
14
source/client/player/input/IBuildInput.cpp
Normal file
14
source/client/player/input/IBuildInput.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "IBuildInput.hpp"
|
||||
|
||||
IBuildInput::~IBuildInput()
|
||||
{
|
||||
}
|
||||
|
||||
void IBuildInput::setScreenSize(int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
bool IBuildInput::tickBuild(Player* pPlayer, BuildActionIntention* pIntention)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
14
source/client/player/input/IBuildInput.hpp
Normal file
14
source/client/player/input/IBuildInput.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "BuildActionIntention.hpp"
|
||||
|
||||
class Player;
|
||||
|
||||
class IBuildInput
|
||||
{
|
||||
public:
|
||||
virtual ~IBuildInput();
|
||||
virtual void setScreenSize(int width, int height);
|
||||
virtual bool tickBuild(Player*, BuildActionIntention*);
|
||||
};
|
||||
|
||||
34
source/client/player/input/IInputHolder.cpp
Normal file
34
source/client/player/input/IInputHolder.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/********************************************************************
|
||||
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 "IInputHolder.hpp"
|
||||
#include "Mouse.hpp"
|
||||
|
||||
IInputHolder::IInputHolder() :
|
||||
m_feedbackX(0),
|
||||
m_feedbackY(0)
|
||||
{
|
||||
}
|
||||
|
||||
IInputHolder::~IInputHolder()
|
||||
{
|
||||
}
|
||||
|
||||
bool IInputHolder::allowPicking()
|
||||
{
|
||||
m_feedbackX = float(Mouse::getX());
|
||||
m_feedbackY = float(Mouse::getY());
|
||||
return Mouse::getButtonState(BUTTON_LEFT);
|
||||
}
|
||||
|
||||
void IInputHolder::setScreenSize(int width, int height)
|
||||
{
|
||||
getMoveInput()->setScreenSize(width, height);
|
||||
getTurnInput()->setScreenSize(width, height);
|
||||
getBuildInput()->setScreenSize(width, height);
|
||||
}
|
||||
34
source/client/player/input/IInputHolder.hpp
Normal file
34
source/client/player/input/IInputHolder.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IMoveInput.hpp"
|
||||
#include "ITurnInput.hpp"
|
||||
#include "IBuildInput.hpp"
|
||||
|
||||
class IInputHolder
|
||||
{
|
||||
public:
|
||||
IInputHolder();
|
||||
virtual ~IInputHolder();
|
||||
virtual bool allowPicking();
|
||||
virtual void setScreenSize(int width, int height);
|
||||
virtual IMoveInput* getMoveInput() = 0;
|
||||
virtual ITurnInput* getTurnInput() = 0;
|
||||
virtual IBuildInput* getBuildInput() = 0;
|
||||
|
||||
protected:
|
||||
friend class UnifiedTurnBuild;
|
||||
friend class GameRenderer;
|
||||
friend class Gui;
|
||||
float m_feedbackX;
|
||||
float m_feedbackY;
|
||||
float m_feedbackAlpha;
|
||||
};
|
||||
|
||||
42
source/client/player/input/IMoveInput.cpp
Normal file
42
source/client/player/input/IMoveInput.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/********************************************************************
|
||||
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 "IMoveInput.hpp"
|
||||
|
||||
IMoveInput::IMoveInput() :
|
||||
m_horzInput(0.0f),
|
||||
m_vertInput(0.0f),
|
||||
field_C(false),
|
||||
m_bJumpButton(false),
|
||||
m_bSneakButton(false)
|
||||
{
|
||||
}
|
||||
|
||||
IMoveInput::~IMoveInput()
|
||||
{
|
||||
}
|
||||
|
||||
void IMoveInput::releaseAllKeys()
|
||||
{
|
||||
}
|
||||
|
||||
void IMoveInput::render(float f)
|
||||
{
|
||||
}
|
||||
|
||||
void IMoveInput::setKey(int key, bool state)
|
||||
{
|
||||
}
|
||||
|
||||
void IMoveInput::setScreenSize(int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
void IMoveInput::tick(Player* pPlayer)
|
||||
{
|
||||
}
|
||||
42
source/client/player/input/IMoveInput.hpp
Normal file
42
source/client/player/input/IMoveInput.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
class Player;
|
||||
|
||||
enum
|
||||
{
|
||||
INPUT_FORWARD,
|
||||
INPUT_BACKWARD,
|
||||
INPUT_LEFT,
|
||||
INPUT_RIGHT,
|
||||
INPUT_JUMP,
|
||||
INPUT_SNEAK,
|
||||
};
|
||||
|
||||
class IMoveInput
|
||||
{
|
||||
public:
|
||||
IMoveInput();
|
||||
virtual ~IMoveInput();
|
||||
|
||||
virtual void releaseAllKeys();
|
||||
virtual void render(float f);
|
||||
virtual void setKey(int key, bool state);
|
||||
virtual void setScreenSize(int width, int height);
|
||||
virtual void tick(Player*);
|
||||
|
||||
public:
|
||||
float m_horzInput;
|
||||
float m_vertInput;
|
||||
bool field_C;
|
||||
bool m_bJumpButton;
|
||||
bool m_bSneakButton;
|
||||
};
|
||||
|
||||
23
source/client/player/input/ITouchScreenModel.cpp
Normal file
23
source/client/player/input/ITouchScreenModel.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/********************************************************************
|
||||
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 "ITouchScreenModel.hpp"
|
||||
|
||||
ITouchScreenModel::~ITouchScreenModel()
|
||||
{
|
||||
}
|
||||
|
||||
int ITouchScreenModel::getPointerId(const MouseAction& action)
|
||||
{
|
||||
return action._fingerId;
|
||||
}
|
||||
|
||||
int ITouchScreenModel::getPointerId(int x, int y, int pointerId)
|
||||
{
|
||||
return pointerId;
|
||||
}
|
||||
20
source/client/player/input/ITouchScreenModel.hpp
Normal file
20
source/client/player/input/ITouchScreenModel.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MouseDevice.hpp"
|
||||
|
||||
class ITouchScreenModel
|
||||
{
|
||||
public:
|
||||
virtual ~ITouchScreenModel();
|
||||
virtual int getPointerId(const MouseAction&);
|
||||
virtual int getPointerId(int x, int y, int pointerId);
|
||||
};
|
||||
|
||||
@@ -9,6 +9,19 @@
|
||||
#include "common/Utils.hpp"
|
||||
#include "ITurnInput.hpp"
|
||||
|
||||
ITurnInput::~ITurnInput()
|
||||
{
|
||||
}
|
||||
|
||||
void ITurnInput::setScreenSize(int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
bool ITurnInput::smoothTurning()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float ITurnInput::getDeltaTime()
|
||||
{
|
||||
if (m_prevTime == -1.0f)
|
||||
@@ -20,3 +33,24 @@ float ITurnInput::getDeltaTime()
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
// @TODO: Where does the a1 parameter come from? It's not `this` because it's used
|
||||
// directly as a float. Its mangled name is _ZN10ITurnInput15linearTransformEfffb
|
||||
float ITurnInput::linearTransform(float a1, float a2, float a3, bool a4)
|
||||
{
|
||||
float v1;
|
||||
if (a1 < 0.0f)
|
||||
v1 = -a2;
|
||||
else
|
||||
v1 = a2;
|
||||
|
||||
float v2 = abs(v1);
|
||||
if (v2 >= abs(a1))
|
||||
return 0.0f;
|
||||
|
||||
float v3 = (a1 - v1) * a3;
|
||||
if (a4 && abs(v3) > 1.0f)
|
||||
v3 /= abs(v3);
|
||||
|
||||
return v3;
|
||||
}
|
||||
|
||||
@@ -8,25 +8,28 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
struct TurnDelta
|
||||
{
|
||||
float x, y;
|
||||
TurnDelta() { x = 0.0f; y = 0.0f; }
|
||||
TurnDelta(float x, float y) : x(x), y(y) {}
|
||||
};
|
||||
|
||||
class ITurnInput
|
||||
{
|
||||
public:
|
||||
struct Delta
|
||||
{
|
||||
float x, y;
|
||||
Delta() { x = 0.0f; y = 0.0f; }
|
||||
Delta(float x, float y) : x(x), y(y) {}
|
||||
};
|
||||
|
||||
protected:
|
||||
ITurnInput()
|
||||
{
|
||||
m_prevTime = -1.0f;
|
||||
}
|
||||
public:
|
||||
float getDeltaTime();
|
||||
float linearTransform(float, float, float, bool);
|
||||
|
||||
virtual ~ITurnInput();
|
||||
virtual Delta getTurnDelta() = 0;
|
||||
virtual void setScreenSize(int width, int height);
|
||||
virtual TurnDelta getTurnDelta() = 0;
|
||||
virtual bool smoothTurning();
|
||||
|
||||
private:
|
||||
float m_prevTime;
|
||||
|
||||
104
source/client/player/input/IncludeExcludeArea.cpp
Normal file
104
source/client/player/input/IncludeExcludeArea.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/********************************************************************
|
||||
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 "IncludeExcludeArea.hpp"
|
||||
|
||||
IncludeExcludeArea::IncludeExcludeArea()
|
||||
{
|
||||
}
|
||||
|
||||
IncludeExcludeArea::~IncludeExcludeArea()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void IncludeExcludeArea::include(IArea* pArea)
|
||||
{
|
||||
m_include.push_back(pArea);
|
||||
}
|
||||
|
||||
void IncludeExcludeArea::exclude(IArea* pArea)
|
||||
{
|
||||
m_exclude.push_back(pArea);
|
||||
}
|
||||
|
||||
void IncludeExcludeArea::clear()
|
||||
{
|
||||
if (field_4)
|
||||
{
|
||||
for (int i = 0; i < int(m_include.size()); i++)
|
||||
{
|
||||
IArea* area = m_include[i];
|
||||
|
||||
// @BUG: Invalid access order! If m_include[i] is null (which,
|
||||
// by the way, _really_ shouldn't be, then there will
|
||||
// be a NULL dereference!
|
||||
#ifdef ORIGINAL_CODE
|
||||
if (area->field_4 && area)
|
||||
#else
|
||||
if (area && area->field_4)
|
||||
#endif
|
||||
{
|
||||
delete area;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < int(m_exclude.size()); i++)
|
||||
{
|
||||
IArea* area = m_exclude[i];
|
||||
|
||||
// @BUG: Same as the include bug.
|
||||
#ifdef ORIGINAL_CODE
|
||||
if (area->field_4 && area)
|
||||
#else
|
||||
if (area && area->field_4)
|
||||
#endif
|
||||
{
|
||||
delete area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_include.clear();
|
||||
m_exclude.clear();
|
||||
}
|
||||
|
||||
bool IncludeExcludeArea::isInside(float x, float y)
|
||||
{
|
||||
// @NOTE: This could be done a lot easier. Here's a way:
|
||||
// for (each area in m_exclude)
|
||||
// if (area.isInside(x,y))
|
||||
// return false;
|
||||
// for (each area in m_include)
|
||||
// if (area.isInside(x,y))
|
||||
// return true;
|
||||
// return false;
|
||||
|
||||
for (int i = 0; i < int(m_include.size()); i++)
|
||||
{
|
||||
IArea* includeArea = m_include[i];
|
||||
if (!includeArea->isInside(x, y))
|
||||
continue;
|
||||
|
||||
bool good = true;
|
||||
for (int j = 0; j < int(m_exclude.size()); j++)
|
||||
{
|
||||
IArea* excludeArea = m_exclude[j];
|
||||
if (excludeArea->isInside(x, y))
|
||||
{
|
||||
good = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (good)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
29
source/client/player/input/IncludeExcludeArea.hpp
Normal file
29
source/client/player/input/IncludeExcludeArea.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "IArea.hpp"
|
||||
|
||||
class IncludeExcludeArea : public IArea
|
||||
{
|
||||
public:
|
||||
IncludeExcludeArea();
|
||||
~IncludeExcludeArea();
|
||||
void include(IArea*);
|
||||
void exclude(IArea*);
|
||||
void clear();
|
||||
|
||||
bool isInside(float x, float y) override;
|
||||
|
||||
private:
|
||||
std::vector<IArea*> m_include;
|
||||
std::vector<IArea*> m_exclude;
|
||||
};
|
||||
|
||||
@@ -45,20 +45,20 @@ void KeyboardInput::setKey(int keyCode, bool b)
|
||||
m_keys[index] = b;
|
||||
}
|
||||
|
||||
void KeyboardInput::tick(/* Player* */)
|
||||
void KeyboardInput::tick(Player* pPlayer)
|
||||
{
|
||||
m_horzInput = 0.0f;
|
||||
m_vertInput = 0.0f;
|
||||
|
||||
if (m_keys[FORWARD]) m_vertInput += 1.0f;
|
||||
if (m_keys[BACKWARD]) m_vertInput -= 1.0f;
|
||||
if (m_keys[LEFT]) m_horzInput += 1.0f;
|
||||
if (m_keys[RIGHT]) m_horzInput -= 1.0f;
|
||||
if (m_keys[INPUT_FORWARD]) m_vertInput += 1.0f;
|
||||
if (m_keys[INPUT_BACKWARD]) m_vertInput -= 1.0f;
|
||||
if (m_keys[INPUT_LEFT]) m_horzInput += 1.0f;
|
||||
if (m_keys[INPUT_RIGHT]) m_horzInput -= 1.0f;
|
||||
|
||||
m_bJumpButton = m_keys[JUMP];
|
||||
m_bSneakButton = m_keys[SNEAK];
|
||||
m_bJumpButton = m_keys[INPUT_JUMP];
|
||||
m_bSneakButton = m_keys[INPUT_SNEAK];
|
||||
|
||||
if (m_keys[SNEAK])
|
||||
if (m_keys[INPUT_SNEAK])
|
||||
{
|
||||
m_horzInput = m_horzInput * 0.3f;
|
||||
m_vertInput = m_vertInput * 0.3f;
|
||||
|
||||
@@ -8,34 +8,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IMoveInput.hpp"
|
||||
|
||||
#include "client/options/Options.hpp"
|
||||
|
||||
class KeyboardInput
|
||||
class KeyboardInput : public IMoveInput
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
FORWARD,
|
||||
BACKWARD,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
JUMP,
|
||||
SNEAK,
|
||||
};
|
||||
|
||||
public:
|
||||
KeyboardInput(Options*);
|
||||
|
||||
virtual void releaseAllKeys();
|
||||
virtual void setKey(int index, bool b);
|
||||
virtual void tick(/* Player* */);
|
||||
void releaseAllKeys() override;
|
||||
void setKey(int index, bool b) override;
|
||||
void tick(Player*) override;
|
||||
|
||||
public:
|
||||
float m_horzInput;
|
||||
float m_vertInput ;
|
||||
bool field_C;
|
||||
bool m_bJumpButton;
|
||||
bool m_bSneakButton;
|
||||
bool m_keys[10];
|
||||
Options* m_pOptions;
|
||||
};
|
||||
|
||||
@@ -9,95 +9,59 @@
|
||||
#include "Mouse.hpp"
|
||||
#include "common/Utils.hpp"
|
||||
|
||||
std::vector<MouseAction> Mouse::_inputs;
|
||||
int Mouse::_index, Mouse::_x, Mouse::_y;
|
||||
int Mouse::_xOld, Mouse::_yOld;
|
||||
Mouse::ButtonState Mouse::_buttonStates[Mouse::COUNT];
|
||||
MouseDevice Mouse::_instance;
|
||||
|
||||
void Mouse::feed(ButtonType buttonType, ButtonState buttonState, int posX, int posY)
|
||||
void Mouse::feed(MouseButtonType buttonType, bool buttonState, int posX, int posY)
|
||||
{
|
||||
if (buttonType != NONE)
|
||||
_inputs.push_back(MouseAction(buttonType, buttonState, posX, posY));
|
||||
|
||||
// Make sure button type is valid
|
||||
if (buttonType < COUNT)
|
||||
{
|
||||
// Check if we're processing a button-state update
|
||||
if (buttonType != NONE)
|
||||
_buttonStates[buttonType] = buttonState;
|
||||
|
||||
_xOld = _x;
|
||||
_yOld = _y;
|
||||
_x = posX;
|
||||
_y = posY;
|
||||
}
|
||||
_instance.feed(buttonType, buttonState, posX, posY);
|
||||
}
|
||||
|
||||
short Mouse::getX()
|
||||
{
|
||||
return short(_x);
|
||||
return _instance.getX();
|
||||
}
|
||||
|
||||
short Mouse::getY()
|
||||
{
|
||||
return short(_y);
|
||||
return _instance.getY();
|
||||
}
|
||||
|
||||
bool Mouse::next()
|
||||
{
|
||||
if (_index + 1 >= _inputs.size())
|
||||
return false;
|
||||
|
||||
_index++;
|
||||
return true;
|
||||
return _instance.next();
|
||||
}
|
||||
|
||||
Mouse::ButtonType Mouse::getEventButton()
|
||||
bool Mouse::isButtonDown(MouseButtonType btn)
|
||||
{
|
||||
return _inputs[_index]._buttonType;
|
||||
return _instance.isButtonDown(btn);
|
||||
}
|
||||
|
||||
bool Mouse::isButtonDown(int btn)
|
||||
bool Mouse::getButtonState(MouseButtonType btn)
|
||||
{
|
||||
return _buttonStates[btn];
|
||||
return _instance.getButtonState(btn);
|
||||
}
|
||||
|
||||
bool Mouse::getEventButtonState()
|
||||
{
|
||||
return _instance.getEventButtonState();
|
||||
}
|
||||
|
||||
void Mouse::reset()
|
||||
{
|
||||
_inputs.clear();
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
MouseAction* Mouse::getEvent()
|
||||
{
|
||||
return &_inputs[_index];
|
||||
}
|
||||
|
||||
Mouse::ButtonState Mouse::getButtonState(ButtonType btn)
|
||||
{
|
||||
if (btn < MIN || btn >= COUNT)
|
||||
return UP;
|
||||
|
||||
return _buttonStates[btn];
|
||||
}
|
||||
|
||||
void Mouse::setX(int x)
|
||||
{
|
||||
_x = x;
|
||||
}
|
||||
|
||||
void Mouse::setY(int y)
|
||||
{
|
||||
_y = y;
|
||||
_instance.reset();
|
||||
}
|
||||
|
||||
void Mouse::reset2()
|
||||
{
|
||||
_xOld = _x;
|
||||
_yOld = _y;
|
||||
_instance.reset2();
|
||||
}
|
||||
|
||||
Mouse::ButtonState Mouse::getEventButtonState()
|
||||
MouseButtonType Mouse::getEventButton()
|
||||
{
|
||||
return _inputs[_index]._buttonState;
|
||||
return _instance.getEventButton();
|
||||
}
|
||||
|
||||
MouseAction* Mouse::getEvent()
|
||||
{
|
||||
return _instance.getEvent();
|
||||
}
|
||||
|
||||
@@ -10,82 +10,27 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "MouseDevice.hpp"
|
||||
|
||||
struct MouseAction;
|
||||
|
||||
class Mouse
|
||||
{
|
||||
public:
|
||||
enum ButtonType
|
||||
{
|
||||
NONE,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
MIDDLE,
|
||||
COUNT,
|
||||
SCROLLWHEEL,
|
||||
|
||||
MIN = LEFT,
|
||||
};
|
||||
|
||||
enum ButtonState
|
||||
{
|
||||
UP,
|
||||
DOWN,
|
||||
};
|
||||
|
||||
static void feed(ButtonType buttonType, ButtonState buttonState, int posX, int posY);
|
||||
|
||||
static void feed(MouseButtonType buttonType, bool buttonState, int posX, int posY);
|
||||
static short getX();
|
||||
static short getY();
|
||||
static bool next();
|
||||
static bool isButtonDown(int btn);
|
||||
static ButtonState getButtonState(ButtonType btn);
|
||||
static ButtonType getEventButton();
|
||||
static ButtonState getEventButtonState();
|
||||
static MouseAction* getEvent();
|
||||
static void setX(int x);
|
||||
static void setY(int y);
|
||||
static bool isButtonDown(MouseButtonType btn);
|
||||
static bool getButtonState(MouseButtonType btn);
|
||||
static bool getEventButtonState();
|
||||
//static void setX(int x);
|
||||
//static void setY(int y);
|
||||
static void reset();
|
||||
static void reset2();
|
||||
|
||||
// @TODO: There's plenty of inlined code here. Out-line it.
|
||||
static MouseButtonType getEventButton();
|
||||
static MouseAction* getEvent();
|
||||
|
||||
private:
|
||||
static std::vector<MouseAction> _inputs;
|
||||
static int _index;
|
||||
static int _x, _y;
|
||||
static int _xOld, _yOld;
|
||||
static ButtonState _buttonStates[Mouse::COUNT];
|
||||
};
|
||||
|
||||
struct MouseAction
|
||||
{
|
||||
Mouse::ButtonType _buttonType;
|
||||
Mouse::ButtonState _buttonState;
|
||||
int _posX;
|
||||
int _posY;
|
||||
|
||||
MouseAction()
|
||||
{
|
||||
_buttonType = Mouse::NONE;
|
||||
_buttonState = Mouse::UP;
|
||||
_posX = 0;
|
||||
_posY = 0;
|
||||
}
|
||||
|
||||
MouseAction(Mouse::ButtonType buttonType, Mouse::ButtonState buttonState, int posX, int posY)
|
||||
{
|
||||
_buttonType = buttonType;
|
||||
_buttonState = buttonState;
|
||||
_posX = posX;
|
||||
_posY = posY;
|
||||
}
|
||||
|
||||
bool isButton()
|
||||
{
|
||||
return
|
||||
_buttonType == Mouse::LEFT ||
|
||||
_buttonType == Mouse::RIGHT ||
|
||||
_buttonType == Mouse::MIDDLE;
|
||||
}
|
||||
static MouseDevice _instance;
|
||||
};
|
||||
|
||||
97
source/client/player/input/MouseDevice.cpp
Normal file
97
source/client/player/input/MouseDevice.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/********************************************************************
|
||||
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 "MouseDevice.hpp"
|
||||
|
||||
void MouseDevice::feed(MouseButtonType buttonType, bool buttonState, int posX, int posY)
|
||||
{
|
||||
if (buttonType != BUTTON_NONE)
|
||||
_inputs.push_back(MouseAction(buttonType, buttonState, posX, posY, 0));
|
||||
|
||||
// Make sure button type is valid
|
||||
if (buttonType < BUTTON_COUNT)
|
||||
{
|
||||
// Check if we're processing a button-state update
|
||||
if (buttonType != BUTTON_NONE)
|
||||
_buttonStates[buttonType] = buttonState;
|
||||
|
||||
_xOld = _x;
|
||||
_yOld = _y;
|
||||
_x = posX;
|
||||
_y = posY;
|
||||
}
|
||||
}
|
||||
|
||||
short MouseDevice::getX()
|
||||
{
|
||||
return short(_x);
|
||||
}
|
||||
|
||||
short MouseDevice::getY()
|
||||
{
|
||||
return short(_y);
|
||||
}
|
||||
|
||||
bool MouseDevice::next()
|
||||
{
|
||||
if (_index + 1 >= _inputs.size())
|
||||
return false;
|
||||
|
||||
_index++;
|
||||
return true;
|
||||
}
|
||||
|
||||
MouseButtonType MouseDevice::getEventButton()
|
||||
{
|
||||
return _inputs[_index]._buttonType;
|
||||
}
|
||||
|
||||
bool MouseDevice::isButtonDown(MouseButtonType btn)
|
||||
{
|
||||
return getButtonState(btn);
|
||||
}
|
||||
|
||||
void MouseDevice::reset()
|
||||
{
|
||||
_inputs.clear();
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
MouseAction* MouseDevice::getEvent()
|
||||
{
|
||||
return &_inputs[_index];
|
||||
}
|
||||
|
||||
bool MouseDevice::getButtonState(MouseButtonType btn)
|
||||
{
|
||||
if (btn < BUTTON_MIN || btn >= BUTTON_COUNT)
|
||||
return false;
|
||||
|
||||
return _buttonStates[btn];
|
||||
}
|
||||
/*
|
||||
void MouseDevice::setX(int x)
|
||||
{
|
||||
_x = x;
|
||||
}
|
||||
|
||||
void MouseDevice::setY(int y)
|
||||
{
|
||||
_y = y;
|
||||
}
|
||||
*/
|
||||
void MouseDevice::reset2()
|
||||
{
|
||||
_xOld = _x;
|
||||
_yOld = _y;
|
||||
}
|
||||
|
||||
bool MouseDevice::getEventButtonState()
|
||||
{
|
||||
return _inputs[_index]._buttonState;
|
||||
}
|
||||
83
source/client/player/input/MouseDevice.hpp
Normal file
83
source/client/player/input/MouseDevice.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
enum MouseButtonType
|
||||
{
|
||||
BUTTON_NONE,
|
||||
BUTTON_LEFT,
|
||||
BUTTON_RIGHT,
|
||||
BUTTON_MIDDLE,
|
||||
BUTTON_COUNT,
|
||||
BUTTON_SCROLLWHEEL,
|
||||
BUTTON_MIN = BUTTON_LEFT,
|
||||
};
|
||||
|
||||
struct MouseAction
|
||||
{
|
||||
MouseButtonType _buttonType;
|
||||
bool _buttonState;
|
||||
int _posX;
|
||||
int _posY;
|
||||
int _fingerId;
|
||||
|
||||
MouseAction()
|
||||
{
|
||||
_buttonType = BUTTON_NONE;
|
||||
_buttonState = 0;
|
||||
_posX = 0;
|
||||
_posY = 0;
|
||||
_fingerId = 0;
|
||||
}
|
||||
|
||||
MouseAction(MouseButtonType buttonType, bool buttonState, int posX, int posY, int fingerId)
|
||||
{
|
||||
_buttonType = buttonType;
|
||||
_buttonState = buttonState;
|
||||
_posX = posX;
|
||||
_posY = posY;
|
||||
_fingerId = fingerId;
|
||||
}
|
||||
|
||||
bool isButton()
|
||||
{
|
||||
return
|
||||
_buttonType == BUTTON_LEFT ||
|
||||
_buttonType == BUTTON_RIGHT ||
|
||||
_buttonType == BUTTON_MIDDLE;
|
||||
}
|
||||
};
|
||||
|
||||
class MouseDevice
|
||||
{
|
||||
public:
|
||||
void feed(MouseButtonType buttonType, bool buttonState, int posX, int posY);
|
||||
short getX();
|
||||
short getY();
|
||||
bool next();
|
||||
bool isButtonDown(MouseButtonType btn);
|
||||
bool getButtonState(MouseButtonType btn);
|
||||
bool getEventButtonState();
|
||||
//void setX(int x);
|
||||
//void setY(int y);
|
||||
void reset();
|
||||
void reset2();
|
||||
MouseButtonType getEventButton();
|
||||
MouseAction* getEvent();
|
||||
|
||||
private:
|
||||
int _index;
|
||||
int _x, _y;
|
||||
int _xOld, _yOld;
|
||||
bool _buttonStates[BUTTON_COUNT];
|
||||
std::vector<MouseAction> _inputs;
|
||||
};
|
||||
|
||||
34
source/client/player/input/MouseHandler.cpp
Normal file
34
source/client/player/input/MouseHandler.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "MouseHandler.hpp"
|
||||
|
||||
MouseHandler::MouseHandler() :
|
||||
m_pTurnInput(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void MouseHandler::setTurnInput(ITurnInput* pTurnInput)
|
||||
{
|
||||
m_pTurnInput = pTurnInput;
|
||||
}
|
||||
|
||||
void MouseHandler::grab()
|
||||
{
|
||||
m_delta = TurnDelta();
|
||||
}
|
||||
|
||||
void MouseHandler::poll()
|
||||
{
|
||||
if (m_pTurnInput)
|
||||
m_delta = m_pTurnInput->getTurnDelta();
|
||||
}
|
||||
|
||||
void MouseHandler::release()
|
||||
{
|
||||
}
|
||||
|
||||
bool MouseHandler::smoothTurning()
|
||||
{
|
||||
if (!m_pTurnInput)
|
||||
return false;
|
||||
|
||||
return m_pTurnInput->smoothTurning();
|
||||
}
|
||||
19
source/client/player/input/MouseHandler.hpp
Normal file
19
source/client/player/input/MouseHandler.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "ITurnInput.hpp"
|
||||
|
||||
class MouseHandler
|
||||
{
|
||||
public:
|
||||
MouseHandler();
|
||||
void setTurnInput(ITurnInput*);
|
||||
void grab();
|
||||
void poll();
|
||||
void release();
|
||||
bool smoothTurning();
|
||||
|
||||
public:
|
||||
TurnDelta m_delta;
|
||||
ITurnInput* m_pTurnInput;
|
||||
};
|
||||
|
||||
@@ -17,17 +17,13 @@ MouseTurnInput::MouseTurnInput(Minecraft* pMC)
|
||||
m_lastX = m_lastY = -1;
|
||||
}
|
||||
|
||||
ITurnInput::~ITurnInput()
|
||||
{
|
||||
}
|
||||
|
||||
ITurnInput::Delta MouseTurnInput::getTurnDelta()
|
||||
TurnDelta MouseTurnInput::getTurnDelta()
|
||||
{
|
||||
int deltaX = 0, deltaY = 0;
|
||||
m_pMinecraft->platform()->getMouseDiff(deltaX, deltaY);
|
||||
m_pMinecraft->platform()->clearDiff();
|
||||
|
||||
Delta d;
|
||||
TurnDelta d;
|
||||
d.x = C_SENSITIVITY * deltaX;
|
||||
d.y = C_SENSITIVITY * deltaY;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class MouseTurnInput : public ITurnInput
|
||||
{
|
||||
public:
|
||||
MouseTurnInput(Minecraft*);
|
||||
Delta getTurnDelta() override;
|
||||
TurnDelta getTurnDelta() override;
|
||||
|
||||
private:
|
||||
int m_lastX;
|
||||
|
||||
167
source/client/player/input/Multitouch.cpp
Normal file
167
source/client/player/input/Multitouch.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/********************************************************************
|
||||
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 "Multitouch.hpp"
|
||||
|
||||
int Multitouch::_activePointerCount;
|
||||
int Multitouch::_activePointerList[MAX_TOUCHES];
|
||||
int Multitouch::_index = -1;
|
||||
bool Multitouch::_wasPressed[MAX_TOUCHES];
|
||||
bool Multitouch::_wasReleased[MAX_TOUCHES];
|
||||
bool Multitouch::_wasPressedThisUpdate[MAX_TOUCHES];
|
||||
bool Multitouch::_wasReleasedThisUpdate[MAX_TOUCHES];
|
||||
MouseDevice Multitouch::_pointers[MAX_TOUCHES];
|
||||
std::vector<MouseAction> Multitouch::_inputs;
|
||||
|
||||
int Multitouch::_clampPointerId(int Id)
|
||||
{
|
||||
if (Id < 0)
|
||||
return Id; //! @BUG
|
||||
|
||||
if (Id >= MAX_TOUCHES)
|
||||
return MAX_TOUCHES - 1;
|
||||
|
||||
return Id;
|
||||
}
|
||||
|
||||
void Multitouch::commit()
|
||||
{
|
||||
_activePointerCount = 0;
|
||||
for (int i = 0; i < MAX_TOUCHES; i++)
|
||||
{
|
||||
if (_pointers[i].isButtonDown(BUTTON_LEFT))
|
||||
{
|
||||
_activePointerList[_activePointerCount++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Multitouch::feed(MouseButtonType a1, bool a2, int a3, int a4, int fingerId)
|
||||
{
|
||||
fingerId = _clampPointerId(fingerId);
|
||||
MouseAction action(a1, a2, a3, a4, fingerId);
|
||||
_inputs.push_back(action);
|
||||
|
||||
MouseDevice* pDevice = g(fingerId);
|
||||
pDevice->feed(a1, a2, a3, a4);
|
||||
|
||||
if (a1)
|
||||
{
|
||||
if (a2)
|
||||
{
|
||||
_wasPressed[fingerId] = true;
|
||||
_wasPressedThisUpdate[fingerId] = true;
|
||||
}
|
||||
else if (a2 == 0)
|
||||
{
|
||||
_wasReleased[fingerId] = true;
|
||||
_wasReleasedThisUpdate[fingerId] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseDevice* Multitouch::g(int Index)
|
||||
{
|
||||
return &_pointers[_clampPointerId(Index)];
|
||||
}
|
||||
|
||||
int Multitouch::getActivePointerIds(const int** out)
|
||||
{
|
||||
*out = _activePointerList;
|
||||
return _activePointerCount;
|
||||
}
|
||||
|
||||
MouseAction* Multitouch::getEvent()
|
||||
{
|
||||
return &_inputs[_index];
|
||||
}
|
||||
|
||||
int Multitouch::getFirstActivePointerIdEx()
|
||||
{
|
||||
for (int i = 0; i < MAX_TOUCHES; i++)
|
||||
{
|
||||
if (_pointers[i].isButtonDown(BUTTON_LEFT))
|
||||
return i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_TOUCHES; i++)
|
||||
{
|
||||
if (_wasReleased[i])
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Multitouch::getFirstActivePointerIdExThisUpdate()
|
||||
{
|
||||
for (int i = 0; i < MAX_TOUCHES; i++)
|
||||
{
|
||||
if (_pointers[i].isButtonDown(BUTTON_LEFT))
|
||||
return i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_TOUCHES; i++)
|
||||
{
|
||||
if (_wasReleasedThisUpdate[i])
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Multitouch::getX(int fingerId)
|
||||
{
|
||||
return g(fingerId)->getX();
|
||||
}
|
||||
|
||||
int Multitouch::getY(int fingerId)
|
||||
{
|
||||
return g(fingerId)->getY();
|
||||
}
|
||||
|
||||
bool Multitouch::isPressed(int fingerId)
|
||||
{
|
||||
return _wasPressed[_clampPointerId(fingerId)];
|
||||
}
|
||||
|
||||
bool Multitouch::next()
|
||||
{
|
||||
if (_index + 1 >= _inputs.size())
|
||||
return false;
|
||||
|
||||
_index++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Multitouch::reset()
|
||||
{
|
||||
_inputs.clear();
|
||||
_index = -1;
|
||||
|
||||
for (int i = 0; i < MAX_TOUCHES; i++)
|
||||
{
|
||||
g(i)->reset();
|
||||
_wasPressed[i] = 0;
|
||||
_wasReleased[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Multitouch::resetThisUpdate()
|
||||
{
|
||||
for (int i = 0; i < MAX_TOUCHES; i++)
|
||||
{
|
||||
_wasPressedThisUpdate[i] = 0;
|
||||
_wasReleasedThisUpdate[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Multitouch::rewind()
|
||||
{
|
||||
_index = -1;
|
||||
}
|
||||
50
source/client/player/input/Multitouch.hpp
Normal file
50
source/client/player/input/Multitouch.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "Mouse.hpp"
|
||||
#include "MouseDevice.hpp"
|
||||
|
||||
#define MAX_TOUCHES (8)
|
||||
|
||||
struct MouseAction;
|
||||
class MouseDevice;
|
||||
|
||||
class Multitouch
|
||||
{
|
||||
public:
|
||||
static int _clampPointerId(int Id);
|
||||
static void commit();
|
||||
static void feed(MouseButtonType, bool state, int x, int y, int fingerId);
|
||||
static MouseDevice* g(int Index);
|
||||
static int getActivePointerIds(const int** out);
|
||||
static MouseAction* getEvent();
|
||||
static int getFirstActivePointerIdEx();
|
||||
static int getFirstActivePointerIdExThisUpdate();
|
||||
static int getX(int fingerId);
|
||||
static int getY(int fingerId);
|
||||
static bool isPressed(int fingerId);
|
||||
static bool next();
|
||||
static void reset();
|
||||
static void resetThisUpdate();
|
||||
static void rewind();
|
||||
|
||||
private:
|
||||
static int _activePointerCount;
|
||||
static int _activePointerList[MAX_TOUCHES];
|
||||
static int _index;
|
||||
static bool _wasPressed[MAX_TOUCHES];
|
||||
static bool _wasReleased[MAX_TOUCHES];
|
||||
static bool _wasPressedThisUpdate[MAX_TOUCHES];
|
||||
static bool _wasReleasedThisUpdate[MAX_TOUCHES];
|
||||
static MouseDevice _pointers[MAX_TOUCHES];
|
||||
static std::vector<MouseAction> _inputs;
|
||||
};
|
||||
|
||||
43
source/client/player/input/PolygonArea.cpp
Normal file
43
source/client/player/input/PolygonArea.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "PolygonArea.hpp"
|
||||
#include "common/Utils.hpp"
|
||||
|
||||
PolygonArea::PolygonArea(int count, const float* x, const float* y)
|
||||
{
|
||||
m_count = count;
|
||||
m_xPos = new float[count];
|
||||
m_yPos = new float[count];
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
m_xPos[i] = x[i];
|
||||
m_yPos[i] = y[i];
|
||||
}
|
||||
}
|
||||
|
||||
PolygonArea::~PolygonArea()
|
||||
{
|
||||
SAFE_DELETE_ARRAY(m_xPos);
|
||||
SAFE_DELETE_ARRAY(m_yPos);
|
||||
}
|
||||
|
||||
bool PolygonArea::isInside(float x, float y)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
int idx = 0, idx2 = m_count - 1;
|
||||
while (idx < m_count)
|
||||
{
|
||||
// horrible ass condition
|
||||
if ((m_yPos[idx] <= y && m_yPos[idx2] > y || m_yPos[idx2] <= y && m_yPos[idx] > y)
|
||||
&& ((((m_xPos[idx2] - m_xPos[idx]) * (y - m_yPos[idx]))
|
||||
/ (m_yPos[idx2] - m_yPos[idx]))
|
||||
+ m_xPos[idx]) > x)
|
||||
{
|
||||
result = !result;
|
||||
}
|
||||
|
||||
idx2 = idx++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
26
source/client/player/input/PolygonArea.hpp
Normal file
26
source/client/player/input/PolygonArea.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IArea.hpp"
|
||||
|
||||
class PolygonArea : public IArea
|
||||
{
|
||||
public:
|
||||
PolygonArea(int count, const float* x, const float* y);
|
||||
~PolygonArea();
|
||||
|
||||
bool isInside(float x, float y) override;
|
||||
|
||||
public:
|
||||
float* m_xPos;
|
||||
float* m_yPos;
|
||||
int m_count;
|
||||
};
|
||||
|
||||
25
source/client/player/input/RectangleArea.cpp
Normal file
25
source/client/player/input/RectangleArea.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/********************************************************************
|
||||
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 "RectangleArea.hpp"
|
||||
|
||||
RectangleArea::RectangleArea(float _left, float _top, float _right, float _bottom) :
|
||||
left(_left),
|
||||
right(_right),
|
||||
top(_top),
|
||||
bottom(_bottom)
|
||||
{
|
||||
}
|
||||
|
||||
bool RectangleArea::isInside(float x, float y)
|
||||
{
|
||||
return left <= x &&
|
||||
right >= x &&
|
||||
top <= y &&
|
||||
bottom >= y;
|
||||
}
|
||||
19
source/client/player/input/RectangleArea.hpp
Normal file
19
source/client/player/input/RectangleArea.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "IArea.hpp"
|
||||
|
||||
class RectangleArea : public IArea
|
||||
{
|
||||
public:
|
||||
RectangleArea(float _left, float _right, float _top, float _bottom);
|
||||
bool isInside(float x, float y) override;
|
||||
|
||||
protected:
|
||||
friend class UnifiedTurnBuild;
|
||||
|
||||
float left;
|
||||
float right;
|
||||
float top;
|
||||
float bottom;
|
||||
};
|
||||
|
||||
54
source/client/player/input/TouchAreaModel.cpp
Normal file
54
source/client/player/input/TouchAreaModel.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/********************************************************************
|
||||
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 "TouchAreaModel.hpp"
|
||||
|
||||
TouchAreaModel::~TouchAreaModel()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
int TouchAreaModel::getPointerId(const MouseAction& action)
|
||||
{
|
||||
return getPointerId(action._posX, action._posY, action._fingerId);
|
||||
}
|
||||
|
||||
int TouchAreaModel::getPointerId(int x, int y, int pointerId)
|
||||
{
|
||||
// Yes, it explicitly uses .size() in the original
|
||||
for (size_t i = 0; i < m_areas.size(); i++)
|
||||
{
|
||||
Area* pArea = m_areas[i];
|
||||
if (pArea->m_pArea->isInside(float(x), float(y)))
|
||||
return pArea->m_id;
|
||||
}
|
||||
|
||||
return pointerId;
|
||||
}
|
||||
|
||||
void TouchAreaModel::clear()
|
||||
{
|
||||
for (size_t i = 0; i < m_areas.size(); i++)
|
||||
delete m_areas[i];
|
||||
|
||||
m_areas.clear();
|
||||
}
|
||||
|
||||
void TouchAreaModel::addArea(int id, IArea* pArea)
|
||||
{
|
||||
Area* pTArea = new Area();
|
||||
|
||||
// NOTE: The original code first initializes the
|
||||
// fields of the new Area instance to zero, and
|
||||
// then sets them to these values.
|
||||
// So we do the same here.
|
||||
pTArea->m_pArea = pArea;
|
||||
pTArea->m_id = id;
|
||||
|
||||
m_areas.push_back(pTArea);
|
||||
}
|
||||
37
source/client/player/input/TouchAreaModel.hpp
Normal file
37
source/client/player/input/TouchAreaModel.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ITouchScreenModel.hpp"
|
||||
#include "IArea.hpp"
|
||||
|
||||
class TouchAreaModel : public ITouchScreenModel
|
||||
{
|
||||
public:
|
||||
struct Area
|
||||
{
|
||||
IArea* m_pArea;
|
||||
int m_id;
|
||||
|
||||
Area() : m_pArea(0), m_id(0) {}
|
||||
};
|
||||
|
||||
public:
|
||||
~TouchAreaModel();
|
||||
|
||||
int getPointerId(const MouseAction&) override;
|
||||
int getPointerId(int x, int y, int pointerId) override;
|
||||
|
||||
void clear();
|
||||
void addArea(int id, IArea* m_pArea);
|
||||
|
||||
private:
|
||||
std::vector<Area*> m_areas;
|
||||
};
|
||||
|
||||
63
source/client/player/input/TouchInputHolder.cpp
Normal file
63
source/client/player/input/TouchInputHolder.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/********************************************************************
|
||||
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 "TouchInputHolder.hpp"
|
||||
#include "Multitouch.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "client/options/Options.hpp"
|
||||
|
||||
TouchInputHolder::TouchInputHolder(Minecraft* pMinecraft, Options* pOptions) :
|
||||
m_touchScreenInput(pMinecraft, pOptions),
|
||||
m_unifiedTurnBuild(2, Minecraft::width, Minecraft::height, 200.0f, 1.05f, this),
|
||||
m_pMinecraft(pMinecraft)
|
||||
{
|
||||
}
|
||||
|
||||
bool TouchInputHolder::allowPicking()
|
||||
{
|
||||
const int* ids;
|
||||
int count = Multitouch::getActivePointerIds(&ids);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
int finger = ids[i];
|
||||
float x = float(Multitouch::getX(finger));
|
||||
float y = float(Multitouch::getY(finger));
|
||||
if (m_unifiedTurnBuild.isInsideArea(x, y))
|
||||
{
|
||||
m_feedbackX = x;
|
||||
m_feedbackY = y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
IMoveInput* TouchInputHolder::getMoveInput()
|
||||
{
|
||||
return &m_touchScreenInput;
|
||||
}
|
||||
|
||||
ITurnInput* TouchInputHolder::getTurnInput()
|
||||
{
|
||||
return &m_unifiedTurnBuild;
|
||||
}
|
||||
|
||||
IBuildInput* TouchInputHolder::getBuildInput()
|
||||
{
|
||||
return &m_unifiedTurnBuild;
|
||||
}
|
||||
|
||||
void TouchInputHolder::setScreenSize(int width, int height)
|
||||
{
|
||||
m_touchScreenInput.setScreenSize(width, height);
|
||||
m_unifiedTurnBuild.field_40 = m_touchScreenInput.getRectangleArea();
|
||||
m_unifiedTurnBuild.field_58 = m_pMinecraft->m_gui.getRectangleArea(false);
|
||||
m_unifiedTurnBuild.setScreenSize(width, height);
|
||||
}
|
||||
33
source/client/player/input/TouchInputHolder.hpp
Normal file
33
source/client/player/input/TouchInputHolder.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IInputHolder.hpp"
|
||||
#include "TouchscreenInput_TestFps.hpp"
|
||||
#include "UnifiedTurnBuild.hpp"
|
||||
|
||||
class Minecraft;
|
||||
class Options;
|
||||
|
||||
class TouchInputHolder : public IInputHolder
|
||||
{
|
||||
public:
|
||||
TouchInputHolder(Minecraft*, Options*);
|
||||
bool allowPicking() override;
|
||||
IMoveInput* getMoveInput() override;
|
||||
ITurnInput* getTurnInput() override;
|
||||
IBuildInput* getBuildInput() override;
|
||||
void setScreenSize(int width, int height) override;
|
||||
|
||||
public:
|
||||
TouchscreenInput_TestFps m_touchScreenInput;
|
||||
UnifiedTurnBuild m_unifiedTurnBuild;
|
||||
Minecraft* m_pMinecraft;
|
||||
};
|
||||
|
||||
289
source/client/player/input/TouchscreenInput_TestFps.cpp
Normal file
289
source/client/player/input/TouchscreenInput_TestFps.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
/********************************************************************
|
||||
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];
|
||||
}
|
||||
50
source/client/player/input/TouchscreenInput_TestFps.hpp
Normal file
50
source/client/player/input/TouchscreenInput_TestFps.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IMoveInput.hpp"
|
||||
#include "client/gui/GuiComponent.hpp"
|
||||
#include "RectangleArea.hpp"
|
||||
#include "PolygonArea.hpp"
|
||||
#include "TouchAreaModel.hpp"
|
||||
|
||||
class Minecraft;
|
||||
class Options;
|
||||
|
||||
class TouchscreenInput_TestFps : public IMoveInput, public GuiComponent
|
||||
{
|
||||
public:
|
||||
TouchscreenInput_TestFps(Minecraft*, Options*);
|
||||
|
||||
// IMoveInput
|
||||
void releaseAllKeys() override;
|
||||
void setKey(int key, bool state) override;
|
||||
void setScreenSize(int width, int height) override;
|
||||
void tick(Player*) override;
|
||||
void render(float f) override;
|
||||
|
||||
RectangleArea getRectangleArea();
|
||||
bool isButtonDown(int key);
|
||||
|
||||
private:
|
||||
RectangleArea m_rectArea;
|
||||
bool field_30[10];
|
||||
Options* m_pOptions;
|
||||
bool field_40;
|
||||
bool m_bJumpBeingHeld;
|
||||
TouchAreaModel m_touchAreaModel;
|
||||
Minecraft* m_pMinecraft;
|
||||
PolygonArea* m_pAreaLeft;
|
||||
PolygonArea* m_pAreaRight;
|
||||
PolygonArea* m_pAreaForward;
|
||||
PolygonArea* m_pAreaBackward;
|
||||
PolygonArea* m_pAreaJump;
|
||||
bool field_6C[8];
|
||||
};
|
||||
|
||||
242
source/client/player/input/UnifiedTurnBuild.cpp
Normal file
242
source/client/player/input/UnifiedTurnBuild.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
/********************************************************************
|
||||
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 "UnifiedTurnBuild.hpp"
|
||||
#include "Multitouch.hpp"
|
||||
|
||||
#include "common/Utils.hpp"
|
||||
#include "world/entity/Player.hpp"
|
||||
|
||||
UnifiedTurnBuild::UnifiedTurnBuild(int a, int width, int height, float d, float e, IInputHolder* pHolder) :
|
||||
field_C(a),
|
||||
field_10(0),
|
||||
m_screenArea(-1, -1, 0, 0),
|
||||
field_40(-1, -1, 0, 0),
|
||||
field_58(-1, -1, 0, 0),
|
||||
m_pInputHolder(pHolder),
|
||||
field_78(0.0f),
|
||||
field_7C(0.0f),
|
||||
m_bWasTouched(false),
|
||||
field_BC(0.0f),
|
||||
field_C0(d),
|
||||
field_C4(e),
|
||||
m_pPlayer(nullptr),
|
||||
field_D8(0)
|
||||
{
|
||||
m_includeExcludeArea.field_4 = false;
|
||||
|
||||
setScreenSize(width, height);
|
||||
field_B8 = getTimeS();
|
||||
field_CC = field_B8;
|
||||
field_D0 = 0;
|
||||
field_24 = 0;
|
||||
field_D4 = false;
|
||||
}
|
||||
|
||||
void UnifiedTurnBuild::setScreenSize(int width, int height)
|
||||
{
|
||||
m_screenArea = RectangleArea(0.0f, 0.0f, float(width), float(height));
|
||||
|
||||
field_40.right += 10.0f + 0.05f * (field_40.right - field_40.left);
|
||||
field_40.top -= 10.0f + 0.05f * (field_40.bottom - field_40.top);
|
||||
|
||||
m_includeExcludeArea.clear();
|
||||
m_includeExcludeArea.include(&m_screenArea);
|
||||
m_includeExcludeArea.exclude(&field_40);
|
||||
m_includeExcludeArea.exclude(&field_58);
|
||||
|
||||
m_touchAreaModel.clear();
|
||||
m_touchAreaModel.addArea(100, &m_includeExcludeArea);
|
||||
}
|
||||
|
||||
TurnDelta UnifiedTurnBuild::getTurnDelta()
|
||||
{
|
||||
float timeS = getTimeS();
|
||||
|
||||
float m1 = 0.0f, m2 = 0.0f;
|
||||
float xd = 0.0f, yd = 0.0f;
|
||||
bool touched = false;
|
||||
|
||||
const int* activePtrs;
|
||||
int activePtrCount = Multitouch::getActivePointerIds(&activePtrs);
|
||||
|
||||
for (int i = 0; i < activePtrCount; i++)
|
||||
{
|
||||
int finger = activePtrs[i];
|
||||
int x = Multitouch::getX(finger);
|
||||
int y = Multitouch::getY(finger);
|
||||
if (m_touchAreaModel.getPointerId(x, y, finger) == 100)
|
||||
{
|
||||
touched = true;
|
||||
m1 = float(x) * 0.5f;
|
||||
m2 = float(y) * -0.5f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (touched && !m_bWasTouched) // if this is the first frame we were touched
|
||||
{
|
||||
field_B8 = timeS;
|
||||
field_BC = 0.0f;
|
||||
bool b2 = m_pPlayer && getSpeedSquared(m_pPlayer) > 0.01f;
|
||||
field_D8 = 1;
|
||||
field_D4 = !b2;
|
||||
field_24 = 0;
|
||||
}
|
||||
else if (m_bWasTouched && !touched) // if that was the last frame we were touched
|
||||
{
|
||||
field_24 = 0;
|
||||
field_D8 = 0;
|
||||
}
|
||||
|
||||
if (field_C == 2 && (m_bWasTouched || touched))
|
||||
{
|
||||
// note: return value dropped
|
||||
(void) getDeltaTime();
|
||||
|
||||
if (!m_bWasTouched)
|
||||
{
|
||||
field_78 = m1;
|
||||
field_7C = m2;
|
||||
}
|
||||
|
||||
if (touched)
|
||||
{
|
||||
xd = field_C4 * linearTransform(m1 - field_78, 0.0f, 1.0f, false);
|
||||
yd = field_C4 * linearTransform(m2 - field_7C, 0.0f, 1.0f, false);
|
||||
|
||||
float c3 = abs(xd) * abs(yd);
|
||||
if (field_C0 < c3)
|
||||
c3 = yd = xd = 0.0f;
|
||||
|
||||
field_BC += c3;
|
||||
|
||||
if (field_D8 == 1 && field_BC >= 20.0f)
|
||||
field_D8 = 2;
|
||||
|
||||
if (field_D8 == 1 && timeS - field_B8 >= 0.4f)
|
||||
{
|
||||
bool check = m_pPlayer && getSpeedSquared(m_pPlayer) > 0.01f;
|
||||
|
||||
if (field_BC > 20.0f || check)
|
||||
field_D8 = 2;
|
||||
else
|
||||
field_D8 = 3;
|
||||
}
|
||||
|
||||
if (field_D8 == 1)
|
||||
{
|
||||
xd = yd = 0.0f;
|
||||
}
|
||||
|
||||
field_78 = m1;
|
||||
field_7C = m2;
|
||||
}
|
||||
}
|
||||
|
||||
if (field_D4)
|
||||
{
|
||||
// Yes, again, this is what IDA gave me. It was either a switch that the compiler
|
||||
// for some reason forgot to optimize into a jump table, or was actually an if chain.
|
||||
// I believe it's the latter though because the build I'm reversing (0.1.1j) is unoptimized)
|
||||
if (field_D8 == 1)
|
||||
m_pInputHolder->m_feedbackAlpha = m_smoothFloat.getNewDeltaValue((timeS - field_B8) / 0.4f, 0.05f);
|
||||
else if (field_D8 == 3)
|
||||
m_pInputHolder->m_feedbackAlpha = m_smoothFloat.getNewDeltaValue(1.0f, 0.25f);
|
||||
else if (field_D8 == 2)
|
||||
m_pInputHolder->m_feedbackAlpha = m_smoothFloat.getNewDeltaValue(-0.05f, 0.5f);
|
||||
else if (field_D8 == 0)
|
||||
m_pInputHolder->m_feedbackAlpha = m_smoothFloat.getNewDeltaValue(-0.05f, 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pInputHolder->m_feedbackAlpha = -0.05f;
|
||||
}
|
||||
|
||||
m_bWasTouched = touched;
|
||||
|
||||
return TurnDelta(xd, -yd);
|
||||
}
|
||||
|
||||
bool UnifiedTurnBuild::smoothTurning()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UnifiedTurnBuild::tickBuild(Player* pPlayer, BuildActionIntention* pIntention)
|
||||
{
|
||||
m_pPlayer = pPlayer;
|
||||
|
||||
if (field_D8 == 3)
|
||||
{
|
||||
if (field_24 != 1)
|
||||
{
|
||||
*pIntention = BuildActionIntention(INTENT_FIRST_REMOVE);
|
||||
field_24 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pIntention = BuildActionIntention(INTENT_HELD);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Multitouch::rewind();
|
||||
|
||||
float timeS = getTimeS();
|
||||
field_10 = 0;
|
||||
|
||||
bool wroteIntention = false;
|
||||
|
||||
while (Multitouch::next())
|
||||
{
|
||||
MouseAction* pEvent = Multitouch::getEvent();
|
||||
|
||||
if (pEvent->_buttonType)
|
||||
{
|
||||
int finger = m_touchAreaModel.getPointerId(pEvent->_posX, pEvent->_posY, pEvent->_fingerId);
|
||||
|
||||
if (finger == 100)
|
||||
{
|
||||
if (field_BC > 20.0f || pEvent->_buttonState || wroteIntention)
|
||||
{
|
||||
if (pEvent->_buttonState)
|
||||
{
|
||||
field_CC = timeS;
|
||||
field_D0 = 0;
|
||||
field_D8 = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float delta = timeS - field_CC;
|
||||
if (field_D8 <= 1 && delta >= 0.0f && delta < 0.25f)
|
||||
{
|
||||
*pIntention = BuildActionIntention(INTENT_CLICKED);
|
||||
wroteIntention = true;
|
||||
}
|
||||
|
||||
field_D8 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wroteIntention;
|
||||
}
|
||||
|
||||
bool UnifiedTurnBuild::isInsideArea(float x, float y)
|
||||
{
|
||||
return m_includeExcludeArea.isInside(x, y);
|
||||
}
|
||||
|
||||
float UnifiedTurnBuild::getSpeedSquared(Entity* pEnt)
|
||||
{
|
||||
return (pEnt->m_pos - pEnt->field_3C).lengthSqr();
|
||||
}
|
||||
62
source/client/player/input/UnifiedTurnBuild.hpp
Normal file
62
source/client/player/input/UnifiedTurnBuild.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/********************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ITurnInput.hpp"
|
||||
#include "IBuildInput.hpp"
|
||||
#include "IInputHolder.hpp"
|
||||
#include "common/SmoothFloat.hpp"
|
||||
#include "RectangleArea.hpp"
|
||||
#include "IncludeExcludeArea.hpp"
|
||||
#include "TouchAreaModel.hpp"
|
||||
|
||||
class Entity;
|
||||
|
||||
class UnifiedTurnBuild : public ITurnInput, public IBuildInput
|
||||
{
|
||||
public:
|
||||
UnifiedTurnBuild(int, int width, int height, float, float, IInputHolder*);
|
||||
|
||||
// ITurnInput
|
||||
void setScreenSize(int width, int height) override; // actually IBuildInput also has it
|
||||
TurnDelta getTurnDelta() override;
|
||||
bool smoothTurning() override;
|
||||
|
||||
// IBuildInput
|
||||
bool tickBuild(Player*, BuildActionIntention*) override;
|
||||
|
||||
bool isInsideArea(float x, float y);
|
||||
|
||||
static float getSpeedSquared(Entity* pEnt);
|
||||
|
||||
public:
|
||||
int field_C;
|
||||
int field_10;
|
||||
SmoothFloat m_smoothFloat;
|
||||
int field_24;
|
||||
RectangleArea m_screenArea;
|
||||
RectangleArea field_40;
|
||||
RectangleArea field_58;
|
||||
IInputHolder* m_pInputHolder;
|
||||
float field_78;
|
||||
float field_7C;
|
||||
bool m_bWasTouched;
|
||||
TouchAreaModel m_touchAreaModel;
|
||||
IncludeExcludeArea m_includeExcludeArea;
|
||||
float field_B8;
|
||||
float field_BC;
|
||||
float field_C0;
|
||||
float field_C4;
|
||||
Entity* m_pPlayer;
|
||||
float field_CC;
|
||||
int field_D0;
|
||||
bool field_D4;
|
||||
int field_D8;
|
||||
};
|
||||
|
||||
@@ -9,8 +9,11 @@
|
||||
#include "thirdparty/GL/GL.hpp"
|
||||
#include "GameRenderer.hpp"
|
||||
#include "client/app/Minecraft.hpp"
|
||||
#include "client/player/input/Multitouch.hpp"
|
||||
#include "Frustum.hpp"
|
||||
#include "renderer/GL/GL.hpp"
|
||||
|
||||
static int t_keepHitResult; // that is its address in v0.1.1j
|
||||
int t_keepPic;
|
||||
|
||||
void GameRenderer::_init()
|
||||
@@ -534,62 +537,64 @@ void GameRenderer::render(float f)
|
||||
if (m_pMinecraft->m_pLocalPlayer && m_pMinecraft->m_bGrabbedMouse)
|
||||
{
|
||||
Minecraft *pMC = m_pMinecraft;
|
||||
ITurnInput::Delta delta = pMC->m_pTurnInput->getTurnDelta();
|
||||
pMC->field_D20 = delta.x;
|
||||
pMC->field_D24 = delta.y;
|
||||
pMC->m_mouseHandler.poll();
|
||||
|
||||
#ifndef ENH_DISABLE_TURN_ACCEL
|
||||
float multPitch = -1.0f;
|
||||
float mult1 = 2.0f * (0.2f + pMC->getOptions()->field_8 * 0.6f);
|
||||
mult1 = mult1 * mult1 * mult1;
|
||||
|
||||
float xd = 4.0f * mult1 * pMC->field_D20;
|
||||
float yd = 4.0f * mult1 * pMC->field_D24;
|
||||
|
||||
float old_field_84 = field_84;
|
||||
field_84 = float(m_rotX) + f;
|
||||
float diff_field_84 = field_84 - old_field_84;
|
||||
field_74 += xd;
|
||||
field_78 += yd;
|
||||
|
||||
if (diff_field_84 > 3.0f)
|
||||
diff_field_84 = 3.0f;
|
||||
|
||||
if (pMC->getOptions()->m_bInvertMouse)
|
||||
multPitch = 1.0f;
|
||||
|
||||
if (!pMC->getOptions()->field_240)
|
||||
float multPitch, diff_field_84;
|
||||
if (pMC->m_mouseHandler.smoothTurning())
|
||||
{
|
||||
// @TODO: untangle this code
|
||||
float v17 = xd + m_rotZ;
|
||||
float v18 = field_18;
|
||||
float v19 = field_1C;
|
||||
m_rotZ = v17;
|
||||
float v20 = mult1 * 0.25f * (v17 - v18);
|
||||
float v21 = v19 + (v20 - v19) * 0.5f;
|
||||
field_1C = v21;
|
||||
if ((v20 <= 0.0 || v20 <= v21) && (v20 >= 0.0 || v20 >= v21))
|
||||
v21 = mult1 * 0.25f * (v17 - v18);
|
||||
float v22 = yd + field_20;
|
||||
field_18 = v18 + v21;
|
||||
float v23 = field_24;
|
||||
field_20 = v22;
|
||||
float v24 = mult1 * 0.15f * (v22 - v23);
|
||||
float v25 = field_28 + (v24 - field_28) * 0.5f;
|
||||
field_28 = v25;
|
||||
if ((v24 <= 0.0 || v24 <= v25) && (v24 >= 0.0 || v24 >= v25))
|
||||
v25 = v24;
|
||||
field_24 = v23 + v25;
|
||||
}
|
||||
#else
|
||||
float multPitch = -1.0f;
|
||||
if (pMC->getOptions()->m_bInvertMouse)
|
||||
multPitch = 1.0f;
|
||||
multPitch = -1.0f;
|
||||
float mult1 = 2.0f * (0.2f + pMC->getOptions()->field_8 * 0.6f);
|
||||
mult1 = mult1 * mult1 * mult1;
|
||||
|
||||
float diff_field_84 = 1.0f;
|
||||
field_7C = pMC->field_D20;
|
||||
field_80 = pMC->field_D24;
|
||||
#endif
|
||||
float xd = 4.0f * mult1 * pMC->m_mouseHandler.m_delta.x;
|
||||
float yd = 4.0f * mult1 * pMC->m_mouseHandler.m_delta.y;
|
||||
|
||||
float old_field_84 = field_84;
|
||||
field_84 = float(field_C) + f;
|
||||
diff_field_84 = field_84 - old_field_84;
|
||||
field_74 += xd;
|
||||
field_78 += yd;
|
||||
|
||||
if (diff_field_84 > 3.0f)
|
||||
diff_field_84 = 3.0f;
|
||||
|
||||
if (pMC->getOptions()->m_bInvertMouse)
|
||||
multPitch = 1.0f;
|
||||
|
||||
if (!pMC->getOptions()->field_240)
|
||||
{
|
||||
// @TODO: untangle this code
|
||||
float v17 = xd + field_14;
|
||||
float v18 = field_18;
|
||||
float v19 = field_1C;
|
||||
field_14 = v17;
|
||||
float v20 = mult1 * 0.25f * (v17 - v18);
|
||||
float v21 = v19 + (v20 - v19) * 0.5f;
|
||||
field_1C = v21;
|
||||
if ((v20 <= 0.0 || v20 <= v21) && (v20 >= 0.0 || v20 >= v21))
|
||||
v21 = mult1 * 0.25f * (v17 - v18);
|
||||
float v22 = yd + field_20;
|
||||
field_18 = v18 + v21;
|
||||
float v23 = field_24;
|
||||
field_20 = v22;
|
||||
float v24 = mult1 * 0.15f * (v22 - v23);
|
||||
float v25 = field_28 + (v24 - field_28) * 0.5f;
|
||||
field_28 = v25;
|
||||
if ((v24 <= 0.0 || v24 <= v25) && (v24 >= 0.0 || v24 >= v25))
|
||||
v25 = v24;
|
||||
field_24 = v23 + v25;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
multPitch = -1.0f;
|
||||
if (pMC->getOptions()->m_bInvertMouse)
|
||||
multPitch = 1.0f;
|
||||
|
||||
diff_field_84 = 1.0f;
|
||||
field_7C = pMC->m_mouseHandler.m_delta.x;
|
||||
field_80 = pMC->m_mouseHandler.m_delta.y;
|
||||
}
|
||||
|
||||
pMC->m_pLocalPlayer->turn(diff_field_84 * field_7C, diff_field_84 * multPitch * field_80);
|
||||
}
|
||||
@@ -597,7 +602,20 @@ void GameRenderer::render(float f)
|
||||
int mouseX = int(Mouse::getX() * Gui::InvGuiScale);
|
||||
int mouseY = int(Mouse::getY() * Gui::InvGuiScale);
|
||||
|
||||
// note: Multitouch code here
|
||||
if (m_pMinecraft->isTouchscreen())
|
||||
{
|
||||
int pointerId = Multitouch::getFirstActivePointerIdExThisUpdate();
|
||||
if (pointerId < 0)
|
||||
{
|
||||
mouseX = -9999;
|
||||
mouseY = -9999;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseX = int(float(Multitouch::getX(pointerId)) * Gui::InvGuiScale);
|
||||
mouseY = int(float(Multitouch::getY(pointerId)) * Gui::InvGuiScale);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pMinecraft->isLevelGenerated())
|
||||
{
|
||||
@@ -623,6 +641,10 @@ void GameRenderer::render(float f)
|
||||
setupGuiScreen();
|
||||
}
|
||||
|
||||
if (m_pMinecraft->m_pLocalPlayer &&
|
||||
m_pMinecraft->m_pLocalPlayer->m_pMoveInput)
|
||||
m_pMinecraft->m_pLocalPlayer->m_pMoveInput->render(f);
|
||||
|
||||
if (m_pMinecraft->m_pScreen)
|
||||
{
|
||||
glClear(GL_ACCUM);
|
||||
@@ -677,45 +699,54 @@ void GameRenderer::tick()
|
||||
t_keepPic = -100;
|
||||
#endif
|
||||
|
||||
if (m_pMinecraft->m_pLocalPlayer)
|
||||
if (!m_pMinecraft->m_pLocalPlayer)
|
||||
return;
|
||||
|
||||
if (--t_keepHitResult == 0)
|
||||
m_pMinecraft->m_hitResult.m_hitType = HitResult::NONE;
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
// Not harmless to let it underflow, but we won't anyway
|
||||
if (t_keepHitResult < -100)
|
||||
t_keepHitResult = -100;
|
||||
#endif
|
||||
|
||||
float x1 = powf(fabsf(field_74), 1.2f);
|
||||
field_7C = x1 * 0.4f;
|
||||
if (field_74 < 0.0f)
|
||||
field_7C = -field_7C;
|
||||
|
||||
float x2 = powf(fabsf(field_78), 1.2f);
|
||||
field_80 = x2 * 0.4f;
|
||||
if (field_78 < 0.0f)
|
||||
field_80 = -field_80;
|
||||
|
||||
field_74 = 0.0f;
|
||||
field_78 = 0.0f;
|
||||
field_6C = field_70;
|
||||
field_30 = field_2C;
|
||||
field_38 = field_34;
|
||||
field_40 = field_3C;
|
||||
field_54 = field_50;
|
||||
field_5C = field_58;
|
||||
|
||||
Mob* pMob = m_pMinecraft->m_pMobPersp;
|
||||
if (!pMob)
|
||||
{
|
||||
float x1 = powf(fabsf(field_74), 1.2f);
|
||||
field_7C = x1 * 0.4f;
|
||||
if (field_74 < 0.0f)
|
||||
field_7C = -field_7C;
|
||||
|
||||
float x2 = powf(fabsf(field_78), 1.2f);
|
||||
field_80 = x2 * 0.4f;
|
||||
if (field_78 < 0.0f)
|
||||
field_80 = -field_80;
|
||||
|
||||
field_74 = 0.0f;
|
||||
field_78 = 0.0f;
|
||||
field_6C = field_70;
|
||||
field_30 = field_2C;
|
||||
field_38 = field_34;
|
||||
field_40 = field_3C;
|
||||
field_54 = field_50;
|
||||
field_5C = field_58;
|
||||
|
||||
Mob* pMob = m_pMinecraft->m_pMobPersp;
|
||||
if (!pMob)
|
||||
{
|
||||
pMob = m_pMinecraft->m_pMobPersp = m_pMinecraft->m_pLocalPlayer;
|
||||
}
|
||||
|
||||
float bright = m_pMinecraft->m_pLevel->getBrightness(Mth::floor(pMob->m_pos.x), Mth::floor(pMob->m_pos.y), Mth::floor(pMob->m_pos.z));
|
||||
float x3 = float(3 - m_pMinecraft->getOptions()->m_iViewDistance);
|
||||
|
||||
field_C++;
|
||||
|
||||
float x4 = x3 / 3.0f;
|
||||
float x5 = (x4 + bright * (1.0f - x4) - field_70) * 0.1f;
|
||||
|
||||
field_70 += x5;
|
||||
|
||||
m_pItemInHandRenderer->tick();
|
||||
pMob = m_pMinecraft->m_pMobPersp = m_pMinecraft->m_pLocalPlayer;
|
||||
}
|
||||
|
||||
float bright = m_pMinecraft->m_pLevel->getBrightness(Mth::floor(pMob->m_pos.x), Mth::floor(pMob->m_pos.y), Mth::floor(pMob->m_pos.z));
|
||||
float x3 = float(3 - m_pMinecraft->getOptions()->m_iViewDistance);
|
||||
|
||||
field_C++;
|
||||
|
||||
float x4 = x3 / 3.0f;
|
||||
float x5 = (x4 + bright * (1.0f - x4) - field_70) * 0.1f;
|
||||
|
||||
field_70 += x5;
|
||||
|
||||
m_pItemInHandRenderer->tick();
|
||||
}
|
||||
|
||||
void GameRenderer::renderItemInHand(float f, int i)
|
||||
@@ -784,25 +815,95 @@ void GameRenderer::pick(float f)
|
||||
if (!m_pMinecraft->m_pMobPersp || !m_pMinecraft->m_pLevel)
|
||||
return;
|
||||
|
||||
HitResult& mchr = m_pMinecraft->m_hitResult;
|
||||
|
||||
Mob* pMob = m_pMinecraft->m_pMobPersp;
|
||||
|
||||
HitResult& mchr = m_pMinecraft->m_hitResult;
|
||||
float dist = m_pMinecraft->m_pGameMode->getPickRange();
|
||||
bool isFirstPerson = !m_pMinecraft->getOptions()->m_bThirdPerson;
|
||||
|
||||
HitResult hrMob = pMob->pick(dist, f);
|
||||
mchr = hrMob;
|
||||
if (m_pMinecraft->isTouchscreen())
|
||||
{
|
||||
Vec3 mobPos = pMob->getPos(f);
|
||||
Vec3 foundPosNear, foundPosFar;
|
||||
bool flag = true;
|
||||
float offset = isFirstPerson ? 6.0f : 12.0f;
|
||||
|
||||
if (m_pMinecraft->m_pInputHolder->allowPicking())
|
||||
{
|
||||
int viewport[4] = { 0 };
|
||||
viewport[2] = Minecraft::width;
|
||||
viewport[3] = Minecraft::height;
|
||||
float obj_coord[3] = { 0 };
|
||||
|
||||
if (glhUnProjectf(m_pMinecraft->m_pInputHolder->m_feedbackX,
|
||||
Minecraft::height - m_pMinecraft->m_pInputHolder->m_feedbackY,
|
||||
1.0f,
|
||||
m_matrix_model_view,
|
||||
m_matrix_projection,
|
||||
viewport,
|
||||
obj_coord))
|
||||
{
|
||||
foundPosFar = mobPos + Vec3(obj_coord[0], obj_coord[1], obj_coord[2]);
|
||||
|
||||
glhUnProjectf(m_pMinecraft->m_pInputHolder->m_feedbackX,
|
||||
Minecraft::height - m_pMinecraft->m_pInputHolder->m_feedbackY,
|
||||
0.0f,
|
||||
m_matrix_model_view,
|
||||
m_matrix_projection,
|
||||
viewport,
|
||||
obj_coord);
|
||||
|
||||
foundPosNear = mobPos + Vec3(obj_coord[0], obj_coord[1], obj_coord[2]);
|
||||
|
||||
Vec3 diff = foundPosFar - foundPosNear;
|
||||
Vec3 normDiff = diff.normalize();
|
||||
Vec3 normScaledDiff = normDiff.scale(offset);
|
||||
|
||||
mobPos = foundPosNear + normScaledDiff;
|
||||
|
||||
foundPosFar = mobPos;
|
||||
}
|
||||
|
||||
// keep the hit result forever
|
||||
t_keepHitResult = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
t_keepHitResult = 1; // keep the tick result for exactly one frame
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
if (isFirstPerson)
|
||||
{
|
||||
mchr = m_pMinecraft->m_pLevel->clip(foundPosNear, foundPosFar, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
HitResult hr = m_pMinecraft->m_pLevel->clip(foundPosNear, foundPosFar, false);
|
||||
|
||||
float diffX = float(hr.m_tileX) - m_pMinecraft->m_pMobPersp->m_pos.x;
|
||||
float diffY = float(hr.m_tileY) - m_pMinecraft->m_pMobPersp->m_pos.y;
|
||||
float diffZ = float(hr.m_tileZ) - m_pMinecraft->m_pMobPersp->m_pos.z;
|
||||
|
||||
if (hr.m_hitType == HitResult::NONE || diffX * diffX + diffY * diffY + diffZ * diffZ > offset * offset)
|
||||
mchr.m_hitType = HitResult::NONE;
|
||||
else
|
||||
mchr = hr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// easy case: pick from the middle of the screen
|
||||
HitResult hrMob = pMob->pick(dist, f);
|
||||
mchr = hrMob;
|
||||
}
|
||||
|
||||
Vec3 mobPos = pMob->getPos(f);
|
||||
|
||||
if (m_pMinecraft->m_hitResult.m_hitType != HitResult::NONE)
|
||||
{
|
||||
float dX = mobPos.x - mchr.m_hitPos.x;
|
||||
float dY = mobPos.y - mchr.m_hitPos.y;
|
||||
float dZ = mobPos.z - mchr.m_hitPos.z;
|
||||
|
||||
dist = sqrtf(dX * dX + dY * dY + dZ * dZ);
|
||||
}
|
||||
dist = mchr.m_hitPos.distanceTo(mobPos);
|
||||
|
||||
if (m_pMinecraft->m_pGameMode->isCreativeType())
|
||||
dist = 32.0f;
|
||||
|
||||
Reference in New Issue
Block a user