mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
feat: improve Windows mouse input for menus and containers
Add robust keyboard/mouse menu focus/click handling, keep container cursor input responsive under capture, and align input consumption rules to prevent gameplay and UI from stealing each other’s mouse events.
This commit is contained in:
parent
b865228eed
commit
287d43a255
|
|
@ -21,6 +21,7 @@ IUIScene_AbstractContainerMenu::IUIScene_AbstractContainerMenu()
|
||||||
|
|
||||||
m_pointerPos.x = 0.0f;
|
m_pointerPos.x = 0.0f;
|
||||||
m_pointerPos.y = 0.0f;
|
m_pointerPos.y = 0.0f;
|
||||||
|
m_bMousePointerControl = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,6 +64,7 @@ void IUIScene_AbstractContainerMenu::Initialize(int iPad, AbstractContainerMenu*
|
||||||
m_eMaxSection = maxSection;
|
m_eMaxSection = maxSection;
|
||||||
|
|
||||||
m_iConsectiveInputTicks = 0;
|
m_iConsectiveInputTicks = 0;
|
||||||
|
m_bMousePointerControl = false;
|
||||||
|
|
||||||
m_bNavigateBack = bNavigateBack;
|
m_bNavigateBack = bNavigateBack;
|
||||||
|
|
||||||
|
|
@ -463,6 +465,25 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (m_bMousePointerControl)
|
||||||
|
{
|
||||||
|
// Force pointer to the externally provided mouse position so any
|
||||||
|
// residual stick input/drift cannot desync the software cursor.
|
||||||
|
vPointerPos = m_pointerPos;
|
||||||
|
vPointerPos.x += m_fPointerImageOffsetX;
|
||||||
|
vPointerPos.y += m_fPointerImageOffsetY;
|
||||||
|
|
||||||
|
bStickInput = true;
|
||||||
|
m_iConsectiveInputTicks = 0;
|
||||||
|
m_eCurrTapState = eTapStateNoInput;
|
||||||
|
#ifdef USE_POINTER_ACCEL
|
||||||
|
m_fPointerVelX = 0.0f;
|
||||||
|
m_fPointerVelY = 0.0f;
|
||||||
|
m_fPointerAccelX = 0.0f;
|
||||||
|
m_fPointerAccelY = 0.0f;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Determine which slot the pointer is currently over.
|
// Determine which slot the pointer is currently over.
|
||||||
ESceneSection eSectionUnderPointer = eSectionNone;
|
ESceneSection eSectionUnderPointer = eSectionNone;
|
||||||
int iNewSlotX = -1;
|
int iNewSlotX = -1;
|
||||||
|
|
@ -689,10 +710,13 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clamp to pointer extents.
|
// Clamp to pointer extents.
|
||||||
if ( vPointerPos.x < m_fPointerMinX ) vPointerPos.x = m_fPointerMinX;
|
if (!m_bMousePointerControl)
|
||||||
else if ( vPointerPos.x > m_fPointerMaxX ) vPointerPos.x = m_fPointerMaxX;
|
{
|
||||||
if ( vPointerPos.y < m_fPointerMinY ) vPointerPos.y = m_fPointerMinY;
|
if ( vPointerPos.x < m_fPointerMinX ) vPointerPos.x = m_fPointerMinX;
|
||||||
else if ( vPointerPos.y > m_fPointerMaxY ) vPointerPos.y = m_fPointerMaxY;
|
else if ( vPointerPos.x > m_fPointerMaxX ) vPointerPos.x = m_fPointerMaxX;
|
||||||
|
if ( vPointerPos.y < m_fPointerMinY ) vPointerPos.y = m_fPointerMinY;
|
||||||
|
else if ( vPointerPos.y > m_fPointerMaxY ) vPointerPos.y = m_fPointerMaxY;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the pointer is outside of the panel.
|
// Check if the pointer is outside of the panel.
|
||||||
bool bPointerIsOutsidePanel = false;
|
bool bPointerIsOutsidePanel = false;
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ protected:
|
||||||
Slot *m_lastPointerLabelSlot;
|
Slot *m_lastPointerLabelSlot;
|
||||||
|
|
||||||
bool m_bSplitscreen;
|
bool m_bSplitscreen;
|
||||||
|
bool m_bMousePointerControl;
|
||||||
bool m_bNavigateBack; // should we exit the xuiscenes or just navigate back on exit?
|
bool m_bNavigateBack; // should we exit the xuiscenes or just navigate back on exit?
|
||||||
|
|
||||||
virtual bool IsSectionSlotList( ESceneSection eSection ) { return eSection != eSectionNone; }
|
virtual bool IsSectionSlotList( ESceneSection eSection ) { return eSection != eSectionNone; }
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,18 @@ UIController::UIController()
|
||||||
m_currentRenderViewport = C4JRender::VIEWPORT_TYPE_FULLSCREEN;
|
m_currentRenderViewport = C4JRender::VIEWPORT_TYPE_FULLSCREEN;
|
||||||
m_bCustomRenderPosition = false;
|
m_bCustomRenderPosition = false;
|
||||||
m_winUserIndex = 0;
|
m_winUserIndex = 0;
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
m_menuMouseOkPressed = false;
|
||||||
|
m_menuMouseOkReleased = false;
|
||||||
|
m_menuMousePageUpPressed = false;
|
||||||
|
m_menuMousePageDownPressed = false;
|
||||||
|
m_menuMouseFocusMovie = NULL;
|
||||||
|
m_menuMouseFocusObject = IGGY_FOCUS_NULL;
|
||||||
|
m_menuMouseX = -1;
|
||||||
|
m_menuMouseY = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
m_accumulatedTicks = 0;
|
m_accumulatedTicks = 0;
|
||||||
|
|
||||||
InitializeCriticalSection(&m_navigationLock);
|
InitializeCriticalSection(&m_navigationLock);
|
||||||
|
|
@ -694,6 +706,10 @@ void UIController::tickInput()
|
||||||
|
|
||||||
void UIController::handleInput()
|
void UIController::handleInput()
|
||||||
{
|
{
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
handleMouseMenuInput();
|
||||||
|
#endif
|
||||||
|
|
||||||
// For each user, loop over each key type and send messages based on the state
|
// For each user, loop over each key type and send messages based on the state
|
||||||
for(unsigned int iPad = 0; iPad < XUSER_MAX_COUNT; ++iPad)
|
for(unsigned int iPad = 0; iPad < XUSER_MAX_COUNT; ++iPad)
|
||||||
{
|
{
|
||||||
|
|
@ -753,6 +769,264 @@ void UIController::handleInput()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
void UIController::handleMouseMenuInput()
|
||||||
|
{
|
||||||
|
m_menuMouseOkPressed = false;
|
||||||
|
m_menuMouseOkReleased = false;
|
||||||
|
m_menuMousePageUpPressed = false;
|
||||||
|
m_menuMousePageDownPressed = false;
|
||||||
|
|
||||||
|
if (KMInput.IsCaptured() || !GetMenuDisplayed(0))
|
||||||
|
{
|
||||||
|
m_menuMouseFocusMovie = NULL;
|
||||||
|
m_menuMouseFocusObject = IGGY_FOCUS_NULL;
|
||||||
|
m_menuMouseX = -1;
|
||||||
|
m_menuMouseY = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_menuMouseOkPressed = KMInput.IsMousePressed(0);
|
||||||
|
m_menuMouseOkReleased = KMInput.IsMouseReleased(0);
|
||||||
|
|
||||||
|
int wheel = KMInput.ConsumeScrollDelta();
|
||||||
|
if (wheel > 0) m_menuMousePageUpPressed = true;
|
||||||
|
else if (wheel < 0) m_menuMousePageDownPressed = true;
|
||||||
|
|
||||||
|
if (IsContainerMenuDisplayed(0))
|
||||||
|
{
|
||||||
|
m_menuMouseFocusMovie = NULL;
|
||||||
|
m_menuMouseFocusObject = IGGY_FOCUS_NULL;
|
||||||
|
m_menuMouseX = -1;
|
||||||
|
m_menuMouseY = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EUIGroup group = eUIGroup_Fullscreen;
|
||||||
|
UIScene *scene = getMouseFocusableScene(group);
|
||||||
|
if (!scene || !scene->hasMovie())
|
||||||
|
{
|
||||||
|
m_menuMouseFocusMovie = NULL;
|
||||||
|
m_menuMouseFocusObject = IGGY_FOCUS_NULL;
|
||||||
|
m_menuMouseX = -1;
|
||||||
|
m_menuMouseY = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clientWidth = 0;
|
||||||
|
int clientHeight = 0;
|
||||||
|
if (!KMInput.GetClientSize(clientWidth, clientHeight) || clientWidth <= 0 || clientHeight <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clientX = 0;
|
||||||
|
int clientY = 0;
|
||||||
|
if (!KMInput.GetMouseClientPosition(clientX, clientY))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 uiX = (S32)((float)clientX * (m_fScreenWidth / (float)clientWidth));
|
||||||
|
S32 uiY = (S32)((float)clientY * (m_fScreenHeight / (float)clientHeight));
|
||||||
|
|
||||||
|
S32 viewportX = 0;
|
||||||
|
S32 viewportY = 0;
|
||||||
|
S32 viewportW = 0;
|
||||||
|
S32 viewportH = 0;
|
||||||
|
m_groups[(int)group]->getRenderDimensions(viewportW, viewportH);
|
||||||
|
getViewportOffset(m_groups[(int)group]->GetViewportType(), viewportX, viewportY);
|
||||||
|
|
||||||
|
if (viewportW <= 0 || viewportH <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 localX = uiX - viewportX;
|
||||||
|
S32 localY = uiY - viewportY;
|
||||||
|
if (localX < 0 || localY < 0 || localX >= viewportW || localY >= viewportH)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iggy *movie = scene->getMovie();
|
||||||
|
IggyFocusableObject focusableObjects[256];
|
||||||
|
S32 numFocusableObjects = 0;
|
||||||
|
IggyFocusHandle currentFocus = IGGY_FOCUS_NULL;
|
||||||
|
if (!IggyPlayerGetFocusableObjects(movie, ¤tFocus, focusableObjects, 256, &numFocusableObjects))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 mouseX = (S32)((float)localX * ((float)scene->getRenderWidth() / (float)viewportW));
|
||||||
|
S32 mouseY = (S32)((float)localY * ((float)scene->getRenderHeight() / (float)viewportH));
|
||||||
|
|
||||||
|
IggyFocusHandle bestFocus = IGGY_FOCUS_NULL;
|
||||||
|
float bestArea = 3.4e38f;
|
||||||
|
|
||||||
|
for (S32 i = 0; i < numFocusableObjects; ++i)
|
||||||
|
{
|
||||||
|
const IggyFocusableObject &obj = focusableObjects[i];
|
||||||
|
float minX = min(obj.x0, obj.x1);
|
||||||
|
float maxX = max(obj.x0, obj.x1);
|
||||||
|
float minY = min(obj.y0, obj.y1);
|
||||||
|
float maxY = max(obj.y0, obj.y1);
|
||||||
|
|
||||||
|
if ((float)mouseX < minX || (float)mouseX > maxX || (float)mouseY < minY || (float)mouseY > maxY)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float area = max(1.0f, (maxX - minX) * (maxY - minY));
|
||||||
|
if (area <= bestArea)
|
||||||
|
{
|
||||||
|
bestArea = area;
|
||||||
|
bestFocus = obj.object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestFocus == IGGY_FOCUS_NULL)
|
||||||
|
{
|
||||||
|
float fallbackBestArea = 3.4e38f;
|
||||||
|
for (S32 i = 0; i < numFocusableObjects; ++i)
|
||||||
|
{
|
||||||
|
const IggyFocusableObject &obj = focusableObjects[i];
|
||||||
|
float minX = min(obj.x0, obj.x1);
|
||||||
|
float maxX = max(obj.x0, obj.x1);
|
||||||
|
float minY = min(obj.y0, obj.y1);
|
||||||
|
float maxY = max(obj.y0, obj.y1);
|
||||||
|
|
||||||
|
if ((float)localX < minX || (float)localX > maxX || (float)localY < minY || (float)localY > maxY)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float area = max(1.0f, (maxX - minX) * (maxY - minY));
|
||||||
|
if (area <= fallbackBestArea)
|
||||||
|
{
|
||||||
|
fallbackBestArea = area;
|
||||||
|
bestFocus = obj.object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestFocus != IGGY_FOCUS_NULL)
|
||||||
|
{
|
||||||
|
mouseX = localX;
|
||||||
|
mouseY = localY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IggyEvent mouseEvent;
|
||||||
|
IggyEventResult eventResult;
|
||||||
|
IggyMakeEventMouseMove(&mouseEvent, mouseX, mouseY);
|
||||||
|
IggyPlayerDispatchEventRS(movie, &mouseEvent, &eventResult);
|
||||||
|
|
||||||
|
if (movie == m_menuMouseFocusMovie && mouseX == m_menuMouseX && mouseY == m_menuMouseY)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool movieChanged = (movie != m_menuMouseFocusMovie);
|
||||||
|
|
||||||
|
m_menuMouseFocusMovie = movie;
|
||||||
|
m_menuMouseX = mouseX;
|
||||||
|
m_menuMouseY = mouseY;
|
||||||
|
if (movieChanged) m_menuMouseFocusObject = IGGY_FOCUS_NULL;
|
||||||
|
|
||||||
|
if (bestFocus != IGGY_FOCUS_NULL && bestFocus != m_menuMouseFocusObject)
|
||||||
|
{
|
||||||
|
IggyPlayerSetFocusRS(movie, bestFocus, 0);
|
||||||
|
}
|
||||||
|
m_menuMouseFocusObject = bestFocus;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIScene *UIController::getMouseFocusableScene(EUIGroup &group) const
|
||||||
|
{
|
||||||
|
static const EUILayer kLayerOrder[] =
|
||||||
|
{
|
||||||
|
eUILayer_Error,
|
||||||
|
eUILayer_Alert,
|
||||||
|
eUILayer_Popup,
|
||||||
|
eUILayer_Scene,
|
||||||
|
eUILayer_Fullscreen,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int groupIndex = 0; groupIndex < eUIGroup_COUNT; ++groupIndex)
|
||||||
|
{
|
||||||
|
EUIGroup testGroup = (EUIGroup)groupIndex;
|
||||||
|
for (int layerIndex = 0; layerIndex < (int)(sizeof(kLayerOrder) / sizeof(kLayerOrder[0])); ++layerIndex)
|
||||||
|
{
|
||||||
|
UIScene *scene = m_groups[groupIndex]->GetTopScene(kLayerOrder[layerIndex]);
|
||||||
|
if (!scene || !scene->canHandleInput() || !scene->hasMovie()) continue;
|
||||||
|
if (isContainerSceneType(scene->getSceneType())) continue;
|
||||||
|
group = testGroup;
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIController::getViewportOffset(C4JRender::eViewportType viewport, S32 &xPos, S32 &yPos) const
|
||||||
|
{
|
||||||
|
xPos = 0;
|
||||||
|
yPos = 0;
|
||||||
|
const float screenWidth = m_fScreenWidth;
|
||||||
|
const float screenHeight = m_fScreenHeight;
|
||||||
|
|
||||||
|
switch (viewport)
|
||||||
|
{
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
||||||
|
xPos = (S32)(screenWidth / 4);
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
||||||
|
xPos = (S32)(screenWidth / 4);
|
||||||
|
yPos = (S32)(screenHeight / 2);
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
||||||
|
yPos = (S32)(screenHeight / 4);
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
|
||||||
|
xPos = (S32)(screenWidth / 2);
|
||||||
|
yPos = (S32)(screenHeight / 4);
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
||||||
|
xPos = (S32)(screenWidth / 2);
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
||||||
|
yPos = (S32)(screenHeight / 2);
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
||||||
|
xPos = (S32)(screenWidth / 2);
|
||||||
|
yPos = (S32)(screenHeight / 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UIController::isContainerSceneType(EUIScene sceneType) const
|
||||||
|
{
|
||||||
|
switch (sceneType)
|
||||||
|
{
|
||||||
|
case eUIScene_Crafting2x2Menu:
|
||||||
|
case eUIScene_Crafting3x3Menu:
|
||||||
|
case eUIScene_FurnaceMenu:
|
||||||
|
case eUIScene_ContainerMenu:
|
||||||
|
case eUIScene_LargeContainerMenu:
|
||||||
|
case eUIScene_InventoryMenu:
|
||||||
|
case eUIScene_DispenserMenu:
|
||||||
|
case eUIScene_CreativeMenu:
|
||||||
|
case eUIScene_EnchantingMenu:
|
||||||
|
case eUIScene_BrewingStandMenu:
|
||||||
|
case eUIScene_TradingMenu:
|
||||||
|
case eUIScene_AnvilMenu:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void UIController::handleKeyPress(unsigned int iPad, unsigned int key)
|
void UIController::handleKeyPress(unsigned int iPad, unsigned int key)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -924,17 +1198,23 @@ void UIController::handleKeyPress(unsigned int iPad, unsigned int key)
|
||||||
if (iPad == 0)
|
if (iPad == 0)
|
||||||
{
|
{
|
||||||
bool kbDown = false, kbPressed = false, kbReleased = false;
|
bool kbDown = false, kbPressed = false, kbReleased = false;
|
||||||
|
bool capturedContainerMenu = IsContainerMenuDisplayed(0) && KMInput.IsCaptured();
|
||||||
|
bool capturedMouseOkDown = capturedContainerMenu && KMInput.IsMouseDown(0);
|
||||||
|
bool capturedMouseOkPressed = capturedContainerMenu && KMInput.IsMousePressed(0);
|
||||||
|
bool capturedMouseOkReleased = capturedContainerMenu && KMInput.IsMouseReleased(0);
|
||||||
switch(key)
|
switch(key)
|
||||||
{
|
{
|
||||||
case ACTION_MENU_UP: kbDown = KMInput.IsKeyDown(VK_UP); kbPressed = KMInput.IsKeyPressed(VK_UP); kbReleased = KMInput.IsKeyReleased(VK_UP); break;
|
case ACTION_MENU_UP: kbDown = KMInput.IsKeyDown(VK_UP); kbPressed = KMInput.IsKeyPressed(VK_UP); kbReleased = KMInput.IsKeyReleased(VK_UP); break;
|
||||||
case ACTION_MENU_DOWN: kbDown = KMInput.IsKeyDown(VK_DOWN); kbPressed = KMInput.IsKeyPressed(VK_DOWN); kbReleased = KMInput.IsKeyReleased(VK_DOWN); break;
|
case ACTION_MENU_DOWN: kbDown = KMInput.IsKeyDown(VK_DOWN); kbPressed = KMInput.IsKeyPressed(VK_DOWN); kbReleased = KMInput.IsKeyReleased(VK_DOWN); break;
|
||||||
case ACTION_MENU_LEFT: kbDown = KMInput.IsKeyDown(VK_LEFT); kbPressed = KMInput.IsKeyPressed(VK_LEFT); kbReleased = KMInput.IsKeyReleased(VK_LEFT); break;
|
case ACTION_MENU_LEFT: kbDown = KMInput.IsKeyDown(VK_LEFT); kbPressed = KMInput.IsKeyPressed(VK_LEFT); kbReleased = KMInput.IsKeyReleased(VK_LEFT); break;
|
||||||
case ACTION_MENU_RIGHT: kbDown = KMInput.IsKeyDown(VK_RIGHT); kbPressed = KMInput.IsKeyPressed(VK_RIGHT); kbReleased = KMInput.IsKeyReleased(VK_RIGHT); break;
|
case ACTION_MENU_RIGHT: kbDown = KMInput.IsKeyDown(VK_RIGHT); kbPressed = KMInput.IsKeyPressed(VK_RIGHT); kbReleased = KMInput.IsKeyReleased(VK_RIGHT); break;
|
||||||
case ACTION_MENU_OK: kbDown = KMInput.IsKeyDown(VK_RETURN); kbPressed = KMInput.IsKeyPressed(VK_RETURN); kbReleased = KMInput.IsKeyReleased(VK_RETURN); break;
|
case ACTION_MENU_OK: kbDown = KMInput.IsKeyDown(VK_RETURN) || capturedMouseOkDown; kbPressed = KMInput.IsKeyPressed(VK_RETURN) || m_menuMouseOkPressed || capturedMouseOkPressed; kbReleased = KMInput.IsKeyReleased(VK_RETURN) || m_menuMouseOkReleased || capturedMouseOkReleased; break;
|
||||||
case ACTION_MENU_A: kbDown = KMInput.IsKeyDown(VK_RETURN); kbPressed = KMInput.IsKeyPressed(VK_RETURN); kbReleased = KMInput.IsKeyReleased(VK_RETURN); break;
|
case ACTION_MENU_A: kbDown = KMInput.IsKeyDown(VK_RETURN) || capturedMouseOkDown; kbPressed = KMInput.IsKeyPressed(VK_RETURN) || m_menuMouseOkPressed || capturedMouseOkPressed; kbReleased = KMInput.IsKeyReleased(VK_RETURN) || m_menuMouseOkReleased || capturedMouseOkReleased; break;
|
||||||
case ACTION_MENU_CANCEL: kbDown = KMInput.IsKeyDown(VK_ESCAPE); kbPressed = KMInput.IsKeyPressed(VK_ESCAPE); kbReleased = KMInput.IsKeyReleased(VK_ESCAPE); break;
|
case ACTION_MENU_CANCEL: kbDown = KMInput.IsKeyDown(VK_ESCAPE); kbPressed = KMInput.IsKeyPressed(VK_ESCAPE); kbReleased = KMInput.IsKeyReleased(VK_ESCAPE); break;
|
||||||
case ACTION_MENU_B: kbDown = KMInput.IsKeyDown(VK_ESCAPE); kbPressed = KMInput.IsKeyPressed(VK_ESCAPE); kbReleased = KMInput.IsKeyReleased(VK_ESCAPE); break;
|
case ACTION_MENU_B: kbDown = KMInput.IsKeyDown(VK_ESCAPE); kbPressed = KMInput.IsKeyPressed(VK_ESCAPE); kbReleased = KMInput.IsKeyReleased(VK_ESCAPE); break;
|
||||||
case ACTION_MENU_PAUSEMENU: kbDown = KMInput.IsKeyDown(VK_ESCAPE); kbPressed = KMInput.IsKeyPressed(VK_ESCAPE); kbReleased = KMInput.IsKeyReleased(VK_ESCAPE); break;
|
case ACTION_MENU_PAUSEMENU: kbDown = KMInput.IsKeyDown(VK_ESCAPE); kbPressed = KMInput.IsKeyPressed(VK_ESCAPE); kbReleased = KMInput.IsKeyReleased(VK_ESCAPE); break;
|
||||||
|
case ACTION_MENU_PAGEUP: kbPressed = m_menuMousePageUpPressed; break;
|
||||||
|
case ACTION_MENU_PAGEDOWN: kbPressed = m_menuMousePageDownPressed; break;
|
||||||
}
|
}
|
||||||
pressed = pressed || kbPressed;
|
pressed = pressed || kbPressed;
|
||||||
released = released || kbReleased;
|
released = released || kbReleased;
|
||||||
|
|
@ -3035,4 +3315,4 @@ void UIController::SendTouchInput(unsigned int iPad, unsigned int key, bool bPre
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,18 @@ private:
|
||||||
vector<QueuedMessageBoxData *> m_queuedMessageBoxData;
|
vector<QueuedMessageBoxData *> m_queuedMessageBoxData;
|
||||||
|
|
||||||
unsigned int m_winUserIndex;
|
unsigned int m_winUserIndex;
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
bool m_menuMouseOkPressed;
|
||||||
|
bool m_menuMouseOkReleased;
|
||||||
|
bool m_menuMousePageUpPressed;
|
||||||
|
bool m_menuMousePageDownPressed;
|
||||||
|
Iggy *m_menuMouseFocusMovie;
|
||||||
|
IggyFocusHandle m_menuMouseFocusObject;
|
||||||
|
int m_menuMouseX;
|
||||||
|
int m_menuMouseY;
|
||||||
|
#endif
|
||||||
|
|
||||||
//bool m_bSysUIShowing;
|
//bool m_bSysUIShowing;
|
||||||
bool m_bSystemUIShowing;
|
bool m_bSystemUIShowing;
|
||||||
C4JThread *m_reloadSkinThread;
|
C4JThread *m_reloadSkinThread;
|
||||||
|
|
@ -208,6 +220,12 @@ private:
|
||||||
void tickInput();
|
void tickInput();
|
||||||
void handleInput();
|
void handleInput();
|
||||||
void handleKeyPress(unsigned int iPad, unsigned int key);
|
void handleKeyPress(unsigned int iPad, unsigned int key);
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
void handleMouseMenuInput();
|
||||||
|
UIScene *getMouseFocusableScene(EUIGroup &group) const;
|
||||||
|
void getViewportOffset(C4JRender::eViewportType viewport, S32 &xPos, S32 &yPos) const;
|
||||||
|
bool isContainerSceneType(EUIScene sceneType) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static rrbool RADLINK ExternalFunctionCallback( void * user_callback_data , Iggy * player , IggyExternalFunctionCallUTF16 * call );
|
static rrbool RADLINK ExternalFunctionCallback( void * user_callback_data , Iggy * player , IggyExternalFunctionCallUTF16 * call );
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,63 @@
|
||||||
#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h"
|
#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h"
|
||||||
#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
|
#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
|
||||||
#include "..\..\MultiplayerLocalPlayer.h"
|
#include "..\..\MultiplayerLocalPlayer.h"
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
#include "..\..\Windows64\KeyboardMouseInput.h"
|
static void GetViewportRect(C4JRender::eViewportType viewport, S32 fullWidth, S32 fullHeight, S32 &xPos, S32 &yPos, S32 &width, S32 &height)
|
||||||
|
{
|
||||||
|
xPos = 0;
|
||||||
|
yPos = 0;
|
||||||
|
width = fullWidth;
|
||||||
|
height = fullHeight;
|
||||||
|
|
||||||
|
switch (viewport)
|
||||||
|
{
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
|
||||||
|
xPos = width / 4;
|
||||||
|
width /= 2;
|
||||||
|
height /= 2;
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
|
||||||
|
xPos = width / 4;
|
||||||
|
yPos = height / 2;
|
||||||
|
width /= 2;
|
||||||
|
height /= 2;
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
|
||||||
|
yPos = height / 4;
|
||||||
|
width /= 2;
|
||||||
|
height /= 2;
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
|
||||||
|
xPos = width / 2;
|
||||||
|
yPos = height / 4;
|
||||||
|
width /= 2;
|
||||||
|
height /= 2;
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
|
||||||
|
width /= 2;
|
||||||
|
height /= 2;
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
|
||||||
|
xPos = width / 2;
|
||||||
|
width /= 2;
|
||||||
|
height /= 2;
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
|
||||||
|
yPos = height / 2;
|
||||||
|
width /= 2;
|
||||||
|
height /= 2;
|
||||||
|
break;
|
||||||
|
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
|
||||||
|
xPos = width / 2;
|
||||||
|
yPos = height / 2;
|
||||||
|
width /= 2;
|
||||||
|
height /= 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UIScene_AbstractContainerMenu::UIScene_AbstractContainerMenu(int iPad, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
UIScene_AbstractContainerMenu::UIScene_AbstractContainerMenu(int iPad, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
||||||
|
|
@ -28,9 +83,6 @@ UIScene_AbstractContainerMenu::UIScene_AbstractContainerMenu(int iPad, UILayer *
|
||||||
ui.OverrideSFX(m_iPad,ACTION_MENU_DOWN,true);
|
ui.OverrideSFX(m_iPad,ACTION_MENU_DOWN,true);
|
||||||
|
|
||||||
m_bIgnoreInput=false;
|
m_bIgnoreInput=false;
|
||||||
#ifdef _WINDOWS64
|
|
||||||
m_bMouseDragSlider=false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UIScene_AbstractContainerMenu::~UIScene_AbstractContainerMenu()
|
UIScene_AbstractContainerMenu::~UIScene_AbstractContainerMenu()
|
||||||
|
|
@ -112,8 +164,8 @@ void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex)
|
||||||
#ifdef __ORBIS__
|
#ifdef __ORBIS__
|
||||||
// we need to map the touchpad rectangle to the UI rectangle. While it works great for the creative menu, it is much too sensitive for the smaller menus.
|
// we need to map the touchpad rectangle to the UI rectangle. While it works great for the creative menu, it is much too sensitive for the smaller menus.
|
||||||
//X coordinate of the touch point (0 to 1919)
|
//X coordinate of the touch point (0 to 1919)
|
||||||
//Y coordinate of the touch point (0 to 941: DUALSHOCK<43>4 wireless controllers and the CUH-ZCT1J/CAP-ZCT1J/CAP-ZCT1U controllers for the PlayStation<6F>4 development tool,
|
//Y coordinate of the touch point (0 to 941: DUALSHOCK<43>4 wireless controllers and the CUH-ZCT1J/CAP-ZCT1J/CAP-ZCT1U controllers for the PlayStation<6F>4 development tool,)
|
||||||
//0 to 753: JDX-1000x series controllers for the PlayStation<6F>4 development tool,)
|
//0 to 753: JDX-1000x series controllers for the PlayStation<6F>4 development tool,)
|
||||||
m_fTouchPadMulX=fPanelWidth/1919.0f;
|
m_fTouchPadMulX=fPanelWidth/1919.0f;
|
||||||
m_fTouchPadMulY=fPanelHeight/941.0f;
|
m_fTouchPadMulY=fPanelHeight/941.0f;
|
||||||
m_fTouchPadDeadZoneX=15.0f*m_fTouchPadMulX;
|
m_fTouchPadDeadZoneX=15.0f*m_fTouchPadMulX;
|
||||||
|
|
@ -160,8 +212,8 @@ void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex)
|
||||||
IggyEvent mouseEvent;
|
IggyEvent mouseEvent;
|
||||||
S32 width, height;
|
S32 width, height;
|
||||||
m_parentLayer->getRenderDimensions(width, height);
|
m_parentLayer->getRenderDimensions(width, height);
|
||||||
S32 x = m_pointerPos.x*((float)width/m_movieWidth);
|
S32 x = m_pointerPos.x*((float)width/m_renderWidth);
|
||||||
S32 y = m_pointerPos.y*((float)height/m_movieHeight);
|
S32 y = m_pointerPos.y*((float)height/m_renderHeight);
|
||||||
IggyMakeEventMouseMove( &mouseEvent, x, y);
|
IggyMakeEventMouseMove( &mouseEvent, x, y);
|
||||||
|
|
||||||
IggyEventResult result;
|
IggyEventResult result;
|
||||||
|
|
@ -179,118 +231,61 @@ void UIScene_AbstractContainerMenu::tick()
|
||||||
{
|
{
|
||||||
UIScene::tick();
|
UIScene::tick();
|
||||||
|
|
||||||
|
m_bMousePointerControl = false;
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
bool mouseActive = (m_iPad == 0 && !KMInput.IsCaptured());
|
if (getPad() == 0)
|
||||||
float rawMouseMovieX = 0, rawMouseMovieY = 0;
|
|
||||||
// Map Windows mouse position to the virtual pointer in movie coordinates
|
|
||||||
if (mouseActive)
|
|
||||||
{
|
{
|
||||||
RECT clientRect;
|
if (KMInput.IsCaptured())
|
||||||
GetClientRect(KMInput.GetHWnd(), &clientRect);
|
|
||||||
int clientWidth = clientRect.right;
|
|
||||||
int clientHeight = clientRect.bottom;
|
|
||||||
if (clientWidth > 0 && clientHeight > 0)
|
|
||||||
{
|
{
|
||||||
int mouseX = KMInput.GetMouseX();
|
float dx = 0.0f;
|
||||||
int mouseY = KMInput.GetMouseY();
|
float dy = 0.0f;
|
||||||
|
KMInput.ConsumeMouseDelta(dx, dy);
|
||||||
|
|
||||||
// Convert mouse position to movie coordinates using the movie/client ratio
|
const float pointerSensitivity = 1.00f;
|
||||||
float mx = (float)mouseX * ((float)m_movieWidth / (float)clientWidth);
|
m_pointerPos.x += dx * pointerSensitivity;
|
||||||
float my = (float)mouseY * ((float)m_movieHeight / (float)clientHeight);
|
m_pointerPos.y += dy * pointerSensitivity;
|
||||||
|
m_bMousePointerControl = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int clientX = 0;
|
||||||
|
int clientY = 0;
|
||||||
|
int clientWidth = 0;
|
||||||
|
int clientHeight = 0;
|
||||||
|
if (KMInput.GetMouseClientPosition(clientX, clientY) && KMInput.GetClientSize(clientWidth, clientHeight) && clientWidth > 0 && clientHeight > 0)
|
||||||
|
{
|
||||||
|
S32 viewportX = 0;
|
||||||
|
S32 viewportY = 0;
|
||||||
|
S32 viewportW = 0;
|
||||||
|
S32 viewportH = 0;
|
||||||
|
GetViewportRect(m_parentLayer->m_parentGroup->GetViewportType(), (S32)clientWidth, (S32)clientHeight, viewportX, viewportY, viewportW, viewportH);
|
||||||
|
|
||||||
m_pointerPos.x = mx;
|
if (viewportW > 0 && viewportH > 0)
|
||||||
m_pointerPos.y = my;
|
{
|
||||||
rawMouseMovieX = mx;
|
S32 localX = (S32)clientX - viewportX;
|
||||||
rawMouseMovieY = my;
|
S32 localY = (S32)clientY - viewportY;
|
||||||
|
if (localX >= 0 && localY >= 0 && localX < viewportW && localY < viewportH)
|
||||||
|
{
|
||||||
|
float pointerX = ((float)localX / (float)viewportW) * (float)m_renderWidth;
|
||||||
|
float pointerY = ((float)localY / (float)viewportH) * (float)m_renderHeight;
|
||||||
|
m_pointerPos.x = pointerX;
|
||||||
|
m_pointerPos.y = pointerY;
|
||||||
|
m_bMousePointerControl = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
onMouseTick();
|
onMouseTick();
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
|
||||||
// Dispatch mouse clicks AFTER onMouseTick() has updated m_eCurrSection from the new pointer position
|
|
||||||
if (mouseActive)
|
|
||||||
{
|
|
||||||
if (KMInput.ConsumeMousePress(0))
|
|
||||||
{
|
|
||||||
if (m_eCurrSection == eSectionInventoryCreativeSlider)
|
|
||||||
{
|
|
||||||
// Scrollbar click: use raw mouse position (onMouseTick may have snapped m_pointerPos)
|
|
||||||
m_bMouseDragSlider = true;
|
|
||||||
m_pointerPos.x = rawMouseMovieX;
|
|
||||||
m_pointerPos.y = rawMouseMovieY;
|
|
||||||
handleOtherClicked(m_iPad, eSectionInventoryCreativeSlider, 0, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_A, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_bMouseDragSlider && KMInput.IsMouseDown(0))
|
|
||||||
{
|
|
||||||
// Continue scrollbar drag: update scroll position from current mouse Y
|
|
||||||
m_pointerPos.x = rawMouseMovieX;
|
|
||||||
m_pointerPos.y = rawMouseMovieY;
|
|
||||||
handleOtherClicked(m_iPad, eSectionInventoryCreativeSlider, 0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!KMInput.IsMouseDown(0))
|
|
||||||
m_bMouseDragSlider = false;
|
|
||||||
|
|
||||||
if (KMInput.ConsumeMousePress(1))
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_X, false);
|
|
||||||
}
|
|
||||||
if (KMInput.ConsumeMousePress(2))
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_Y, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse scroll wheel for page scrolling
|
|
||||||
int scrollDelta = KMInput.ConsumeScrollDelta();
|
|
||||||
if (scrollDelta > 0)
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_OTHER_STICK_UP, false);
|
|
||||||
}
|
|
||||||
else if (scrollDelta < 0)
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_OTHER_STICK_DOWN, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ESC to close — must be last since it may destroy this scene
|
|
||||||
if (KMInput.ConsumeKeyPress(VK_ESCAPE))
|
|
||||||
{
|
|
||||||
handleKeyDown(m_iPad, ACTION_MENU_B, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IggyEvent mouseEvent;
|
IggyEvent mouseEvent;
|
||||||
S32 width, height;
|
S32 width, height;
|
||||||
m_parentLayer->getRenderDimensions(width, height);
|
m_parentLayer->getRenderDimensions(width, height);
|
||||||
|
S32 x = m_pointerPos.x*((float)width/m_renderWidth);
|
||||||
|
S32 y = m_pointerPos.y*((float)height/m_renderHeight);
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
|
||||||
S32 x, y;
|
|
||||||
if (mouseActive)
|
|
||||||
{
|
|
||||||
// Send raw mouse position directly as Iggy event to avoid coordinate round-trip errors
|
|
||||||
// Scale mouse client coords to the Iggy display space (which was set to getRenderDimensions())
|
|
||||||
RECT clientRect;
|
|
||||||
GetClientRect(KMInput.GetHWnd(), &clientRect);
|
|
||||||
x = (S32)((float)KMInput.GetMouseX() * ((float)width / (float)clientRect.right));
|
|
||||||
y = (S32)((float)KMInput.GetMouseY() * ((float)height / (float)clientRect.bottom));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x = (S32)(m_pointerPos.x * ((float)width / m_movieWidth));
|
|
||||||
y = (S32)(m_pointerPos.y * ((float)height / m_movieHeight));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
S32 x = m_pointerPos.x*((float)width/m_movieWidth);
|
|
||||||
S32 y = m_pointerPos.y*((float)height/m_movieHeight);
|
|
||||||
#endif
|
|
||||||
IggyMakeEventMouseMove( &mouseEvent, x, y);
|
IggyMakeEventMouseMove( &mouseEvent, x, y);
|
||||||
|
|
||||||
// 4J Stu - This seems to be broken on Durango, so do it ourself
|
// 4J Stu - This seems to be broken on Durango, so do it ourself
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ void Input::tick(LocalPlayer *player)
|
||||||
// Mouse look is now handled per-frame in Minecraft::applyFrameMouseLook()
|
// Mouse look is now handled per-frame in Minecraft::applyFrameMouseLook()
|
||||||
// to eliminate the 20Hz tick delay. Only flush any remaining delta here
|
// to eliminate the 20Hz tick delay. Only flush any remaining delta here
|
||||||
// as a safety measure.
|
// as a safety measure.
|
||||||
if (iPad == 0 && KMInput.IsCaptured())
|
if (iPad == 0 && KMInput.IsCaptured() && !ui.GetMenuDisplayed(iPad))
|
||||||
{
|
{
|
||||||
float rawDx, rawDy;
|
float rawDx, rawDy;
|
||||||
KMInput.ConsumeMouseDelta(rawDx, rawDy);
|
KMInput.ConsumeMouseDelta(rawDx, rawDy);
|
||||||
|
|
|
||||||
|
|
@ -1238,6 +1238,7 @@ void Minecraft::applyFrameMouseLook()
|
||||||
if (iPad != 0) continue; // Mouse only applies to pad 0
|
if (iPad != 0) continue; // Mouse only applies to pad 0
|
||||||
|
|
||||||
if (!KMInput.IsCaptured()) continue;
|
if (!KMInput.IsCaptured()) continue;
|
||||||
|
if (ui.GetMenuDisplayed(iPad)) continue;
|
||||||
if (localgameModes[iPad] == NULL) continue;
|
if (localgameModes[iPad] == NULL) continue;
|
||||||
|
|
||||||
float rawDx, rawDy;
|
float rawDx, rawDy;
|
||||||
|
|
@ -1250,6 +1251,12 @@ void Minecraft::applyFrameMouseLook()
|
||||||
if (app.GetGameSettings(iPad, eGameSetting_ControlInvertLook))
|
if (app.GetGameSettings(iPad, eGameSetting_ControlInvertLook))
|
||||||
mdy = -mdy;
|
mdy = -mdy;
|
||||||
|
|
||||||
|
bool canLookYaw = localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_LEFT) || localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_RIGHT);
|
||||||
|
bool canLookPitch = localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_UP) || localgameModes[iPad]->isInputAllowed(MINECRAFT_ACTION_LOOK_DOWN);
|
||||||
|
if (!canLookYaw) mdx = 0.0f;
|
||||||
|
if (!canLookPitch) mdy = 0.0f;
|
||||||
|
if (mdx == 0.0f && mdy == 0.0f) continue;
|
||||||
|
|
||||||
// Apply 0.15f scaling (same as Entity::interpolateTurn / Entity::turn)
|
// Apply 0.15f scaling (same as Entity::interpolateTurn / Entity::turn)
|
||||||
float dyaw = mdx * 0.15f;
|
float dyaw = mdx * 0.15f;
|
||||||
float dpitch = -mdy * 0.15f;
|
float dpitch = -mdy * 0.15f;
|
||||||
|
|
@ -3274,22 +3281,32 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||||
// Mouse scroll wheel for hotbar
|
// Mouse scroll wheel for hotbar
|
||||||
if (iPad == 0)
|
if (iPad == 0)
|
||||||
{
|
{
|
||||||
int kbWheel = KMInput.ConsumeScrollDelta();
|
int kbWheel = 0;
|
||||||
|
if (KMInput.IsCaptured())
|
||||||
|
{
|
||||||
|
kbWheel = KMInput.ConsumeScrollDelta();
|
||||||
|
}
|
||||||
|
else if (!ui.GetMenuDisplayed(0))
|
||||||
|
{
|
||||||
|
KMInput.ConsumeScrollDelta();
|
||||||
|
}
|
||||||
if (kbWheel > 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_LEFT_SCROLL)) wheel += 1;
|
if (kbWheel > 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_LEFT_SCROLL)) wheel += 1;
|
||||||
else if (kbWheel < 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_RIGHT_SCROLL)) wheel -= 1;
|
else if (kbWheel < 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_RIGHT_SCROLL)) wheel -= 1;
|
||||||
|
|
||||||
// 1-9 keys for direct hotbar selection
|
// 1-9 keys for direct hotbar selection
|
||||||
if (gameMode->isInputAllowed(MINECRAFT_ACTION_LEFT_SCROLL))
|
for (int k = '1'; k <= '9'; k++)
|
||||||
{
|
{
|
||||||
for (int k = '1'; k <= '9'; k++)
|
if (!KMInput.ConsumeKeyPress(k))
|
||||||
{
|
{
|
||||||
if (KMInput.ConsumeKeyPress(k))
|
continue;
|
||||||
{
|
|
||||||
player->inventory->selected = k - '1';
|
|
||||||
app.SetOpacityTimer(iPad);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (KMInput.IsCaptured() && gameMode->isInputAllowed(MINECRAFT_ACTION_LEFT_SCROLL))
|
||||||
|
{
|
||||||
|
player->inventory->selected = k - '1';
|
||||||
|
app.SetOpacityTimer(iPad);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,31 @@ int KeyboardMouseInput::ConsumeScrollDelta()
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KeyboardMouseInput::GetMouseClientPosition(int &x, int &y) const
|
||||||
|
{
|
||||||
|
if (!m_hWnd) return false;
|
||||||
|
|
||||||
|
POINT cursor;
|
||||||
|
if (!GetCursorPos(&cursor)) return false;
|
||||||
|
if (!ScreenToClient(m_hWnd, &cursor)) return false;
|
||||||
|
|
||||||
|
x = cursor.x;
|
||||||
|
y = cursor.y;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardMouseInput::GetClientSize(int &width, int &height) const
|
||||||
|
{
|
||||||
|
if (!m_hWnd) return false;
|
||||||
|
|
||||||
|
RECT rect;
|
||||||
|
if (!GetClientRect(m_hWnd, &rect)) return false;
|
||||||
|
|
||||||
|
width = rect.right - rect.left;
|
||||||
|
height = rect.bottom - rect.top;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Mouse capture
|
// Mouse capture
|
||||||
void KeyboardMouseInput::SetCapture(bool capture)
|
void KeyboardMouseInput::SetCapture(bool capture)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ public:
|
||||||
bool ConsumeMouseRelease(int btn);
|
bool ConsumeMouseRelease(int btn);
|
||||||
void ConsumeMouseDelta(float &dx, float &dy);
|
void ConsumeMouseDelta(float &dx, float &dy);
|
||||||
int ConsumeScrollDelta();
|
int ConsumeScrollDelta();
|
||||||
|
bool GetMouseClientPosition(int &x, int &y) const;
|
||||||
|
bool GetClientSize(int &width, int &height) const;
|
||||||
|
|
||||||
// Absolute cursor position (client-area coordinates, for GUI when not captured)
|
// Absolute cursor position (client-area coordinates, for GUI when not captured)
|
||||||
void OnMouseMove(int x, int y);
|
void OnMouseMove(int x, int y);
|
||||||
|
|
|
||||||
|
|
@ -395,9 +395,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_MOUSEWHEEL:
|
case WM_MOUSEWHEEL:
|
||||||
KMInput.OnMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam));
|
KMInput.OnMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam));
|
||||||
break;
|
break;
|
||||||
case WM_MOUSEMOVE:
|
|
||||||
KMInput.OnMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
|
||||||
break;
|
|
||||||
case WM_ACTIVATE:
|
case WM_ACTIVATE:
|
||||||
if (LOWORD(wParam) == WA_INACTIVE)
|
if (LOWORD(wParam) == WA_INACTIVE)
|
||||||
KMInput.SetCapture(false);
|
KMInput.SetCapture(false);
|
||||||
|
|
@ -407,15 +404,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
KMInput.ClearAllState();
|
KMInput.ClearAllState();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_SETCURSOR:
|
|
||||||
// Hide the OS cursor when an Iggy/Flash menu is displayed (it has its own Flash cursor)
|
|
||||||
if (LOWORD(lParam) == HTCLIENT && !KMInput.IsCaptured() && ui.GetMenuDisplayed(0))
|
|
||||||
{
|
|
||||||
SetCursor(NULL);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
@ -606,7 +594,6 @@ app.DebugPrintf("width: %d, height: %d\n", width, height);
|
||||||
|
|
||||||
// Create a depth stencil buffer
|
// Create a depth stencil buffer
|
||||||
D3D11_TEXTURE2D_DESC descDepth;
|
D3D11_TEXTURE2D_DESC descDepth;
|
||||||
ZeroMemory(&descDepth, sizeof(descDepth));
|
|
||||||
|
|
||||||
descDepth.Width = width;
|
descDepth.Width = width;
|
||||||
descDepth.Height = height;
|
descDepth.Height = height;
|
||||||
|
|
@ -622,7 +609,6 @@ app.DebugPrintf("width: %d, height: %d\n", width, height);
|
||||||
hr = g_pd3dDevice->CreateTexture2D(&descDepth, NULL, &g_pDepthStencilBuffer);
|
hr = g_pd3dDevice->CreateTexture2D(&descDepth, NULL, &g_pDepthStencilBuffer);
|
||||||
|
|
||||||
D3D11_DEPTH_STENCIL_VIEW_DESC descDSView;
|
D3D11_DEPTH_STENCIL_VIEW_DESC descDSView;
|
||||||
ZeroMemory(&descDSView, sizeof(descDSView));
|
|
||||||
descDSView.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
descDSView.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||||
descDSView.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
|
descDSView.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||||
descDSView.Texture2D.MipSlice = 0;
|
descDSView.Texture2D.MipSlice = 0;
|
||||||
|
|
@ -716,26 +702,6 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||||
UNREFERENCED_PARAMETER(hPrevInstance);
|
UNREFERENCED_PARAMETER(hPrevInstance);
|
||||||
UNREFERENCED_PARAMETER(lpCmdLine);
|
UNREFERENCED_PARAMETER(lpCmdLine);
|
||||||
|
|
||||||
|
|
||||||
WCHAR exePath[MAX_PATH] = { 0 };
|
|
||||||
GetModuleFileNameW(NULL, exePath, MAX_PATH);
|
|
||||||
WCHAR* lastSlash = wcsrchr(exePath, L'\\');
|
|
||||||
if (lastSlash) {
|
|
||||||
*lastSlash = L'\0';
|
|
||||||
|
|
||||||
WCHAR devCheckPath[MAX_PATH] = { 0 };
|
|
||||||
swprintf_s(devCheckPath, MAX_PATH, L"%s\\..\\..\\Minecraft.Client\\Minecraft.Client.vcxproj", exePath);
|
|
||||||
|
|
||||||
if (GetFileAttributesW(devCheckPath) != INVALID_FILE_ATTRIBUTES) {
|
|
||||||
WCHAR projectPath[MAX_PATH] = { 0 };
|
|
||||||
swprintf_s(projectPath, MAX_PATH, L"%s\\..\\..\\Minecraft.Client", exePath);
|
|
||||||
SetCurrentDirectoryW(projectPath);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SetCurrentDirectoryW(exePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Declare DPI awareness so GetSystemMetrics returns physical pixels
|
// Declare DPI awareness so GetSystemMetrics returns physical pixels
|
||||||
SetProcessDPIAware();
|
SetProcessDPIAware();
|
||||||
g_iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
|
g_iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
|
||||||
|
|
@ -1216,7 +1182,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||||
// Update mouse capture: capture when in-game and no menu is open
|
// Update mouse capture: capture when in-game and no menu is open
|
||||||
{
|
{
|
||||||
static bool altToggleSuppressCapture = false;
|
static bool altToggleSuppressCapture = false;
|
||||||
bool shouldCapture = app.GetGameStarted() && !ui.GetMenuDisplayed(0) && pMinecraft->screen == NULL;
|
bool shouldCapture = app.GetGameStarted() && (!ui.GetMenuDisplayed(0) || ui.IsContainerMenuDisplayed(0));
|
||||||
// Left Alt key toggles capture on/off for debugging
|
// Left Alt key toggles capture on/off for debugging
|
||||||
if (KMInput.IsKeyPressed(VK_MENU))
|
if (KMInput.IsKeyPressed(VK_MENU))
|
||||||
{
|
{
|
||||||
|
|
@ -1526,4 +1492,4 @@ void MemPixStuff()
|
||||||
PIXAddNamedCounter(((float)allSectsTotal)/(4096.0f),"MemSect total pages");
|
PIXAddNamedCounter(((float)allSectsTotal)/(4096.0f),"MemSect total pages");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue