feat: improve mouse input handling
This commit is contained in:
@@ -5,6 +5,9 @@
|
|||||||
#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
|
||||||
|
#include "..\..\Windows64\KeyboardMouseInput.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
UIScene_AbstractContainerMenu::UIScene_AbstractContainerMenu(int iPad, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
UIScene_AbstractContainerMenu::UIScene_AbstractContainerMenu(int iPad, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
||||||
{
|
{
|
||||||
@@ -25,6 +28,9 @@ 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()
|
||||||
@@ -106,8 +112,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;
|
||||||
@@ -173,13 +179,118 @@ void UIScene_AbstractContainerMenu::tick()
|
|||||||
{
|
{
|
||||||
UIScene::tick();
|
UIScene::tick();
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
bool mouseActive = (m_iPad == 0 && !KMInput.IsCaptured());
|
||||||
|
float rawMouseMovieX = 0, rawMouseMovieY = 0;
|
||||||
|
// Map Windows mouse position to the virtual pointer in movie coordinates
|
||||||
|
if (mouseActive)
|
||||||
|
{
|
||||||
|
RECT clientRect;
|
||||||
|
GetClientRect(KMInput.GetHWnd(), &clientRect);
|
||||||
|
int clientWidth = clientRect.right;
|
||||||
|
int clientHeight = clientRect.bottom;
|
||||||
|
if (clientWidth > 0 && clientHeight > 0)
|
||||||
|
{
|
||||||
|
int mouseX = KMInput.GetMouseX();
|
||||||
|
int mouseY = KMInput.GetMouseY();
|
||||||
|
|
||||||
|
// Convert mouse position to movie coordinates using the movie/client ratio
|
||||||
|
float mx = (float)mouseX * ((float)m_movieWidth / (float)clientWidth);
|
||||||
|
float my = (float)mouseY * ((float)m_movieHeight / (float)clientHeight);
|
||||||
|
|
||||||
|
m_pointerPos.x = mx;
|
||||||
|
m_pointerPos.y = my;
|
||||||
|
rawMouseMovieX = mx;
|
||||||
|
rawMouseMovieY = my;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#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 tab switching
|
||||||
|
int scrollDelta = KMInput.ConsumeScrollDelta();
|
||||||
|
if (scrollDelta > 0)
|
||||||
|
{
|
||||||
|
handleKeyDown(m_iPad, ACTION_MENU_LEFT_SCROLL, false);
|
||||||
|
}
|
||||||
|
else if (scrollDelta < 0)
|
||||||
|
{
|
||||||
|
handleKeyDown(m_iPad, ACTION_MENU_RIGHT_SCROLL, 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);
|
||||||
|
|
||||||
|
#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 x = m_pointerPos.x*((float)width/m_movieWidth);
|
||||||
S32 y = m_pointerPos.y*((float)height/m_movieHeight);
|
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
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ class UIScene_AbstractContainerMenu : public UIScene, public virtual IUIScene_Ab
|
|||||||
private:
|
private:
|
||||||
ESceneSection m_focusSection;
|
ESceneSection m_focusSection;
|
||||||
bool m_bIgnoreInput;
|
bool m_bIgnoreInput;
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
bool m_bMouseDragSlider;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UIControl m_controlMainPanel;
|
UIControl m_controlMainPanel;
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
#include "Tesselator.h"
|
#include "Tesselator.h"
|
||||||
#include "Textures.h"
|
#include "Textures.h"
|
||||||
#include "..\Minecraft.World\SoundTypes.h"
|
#include "..\Minecraft.World\SoundTypes.h"
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
#include "Windows64\KeyboardMouseInput.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -103,20 +106,71 @@ void Screen::init()
|
|||||||
|
|
||||||
void Screen::updateEvents()
|
void Screen::updateEvents()
|
||||||
{
|
{
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
// Poll mouse button state and dispatch click/release events
|
||||||
|
for (int btn = 0; btn < 3; btn++)
|
||||||
|
{
|
||||||
|
if (KMInput.ConsumeMousePress(btn))
|
||||||
|
{
|
||||||
|
int xm = Mouse::getX() * width / minecraft->width;
|
||||||
|
int ym = height - Mouse::getY() * height / minecraft->height - 1;
|
||||||
|
mouseClicked(xm, ym, btn);
|
||||||
|
}
|
||||||
|
if (KMInput.ConsumeMouseRelease(btn))
|
||||||
|
{
|
||||||
|
int xm = Mouse::getX() * width / minecraft->width;
|
||||||
|
int ym = height - Mouse::getY() * height / minecraft->height - 1;
|
||||||
|
mouseReleased(xm, ym, btn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Poll keyboard events
|
||||||
|
for (int vk = 0; vk < 256; vk++)
|
||||||
|
{
|
||||||
|
if (KMInput.ConsumeKeyPress(vk))
|
||||||
|
{
|
||||||
|
// Map Windows virtual key to the Keyboard constants used by Screen::keyPressed
|
||||||
|
int mappedKey = -1;
|
||||||
|
wchar_t ch = 0;
|
||||||
|
if (vk == VK_ESCAPE) mappedKey = Keyboard::KEY_ESCAPE;
|
||||||
|
else if (vk == VK_RETURN) mappedKey = Keyboard::KEY_RETURN;
|
||||||
|
else if (vk == VK_BACK) mappedKey = Keyboard::KEY_BACK;
|
||||||
|
else if (vk == VK_UP) mappedKey = Keyboard::KEY_UP;
|
||||||
|
else if (vk == VK_DOWN) mappedKey = Keyboard::KEY_DOWN;
|
||||||
|
else if (vk == VK_LEFT) mappedKey = Keyboard::KEY_LEFT;
|
||||||
|
else if (vk == VK_RIGHT) mappedKey = Keyboard::KEY_RIGHT;
|
||||||
|
else if (vk == VK_LSHIFT || vk == VK_RSHIFT) mappedKey = Keyboard::KEY_LSHIFT;
|
||||||
|
else if (vk == VK_TAB) mappedKey = Keyboard::KEY_TAB;
|
||||||
|
else if (vk >= 'A' && vk <= 'Z')
|
||||||
|
{
|
||||||
|
ch = (wchar_t)(vk - 'A' + L'a');
|
||||||
|
if (KMInput.IsKeyDown(VK_SHIFT)) ch = (wchar_t)vk;
|
||||||
|
}
|
||||||
|
else if (vk >= '0' && vk <= '9') ch = (wchar_t)vk;
|
||||||
|
else if (vk == VK_SPACE) ch = L' ';
|
||||||
|
|
||||||
|
if (mappedKey != -1) keyPressed(ch, mappedKey);
|
||||||
|
else if (ch != 0) keyPressed(ch, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
/* 4J - TODO
|
/* 4J - TODO
|
||||||
while (Mouse.next()) {
|
while (Mouse.next()) {
|
||||||
mouseEvent();
|
mouseEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (Keyboard.next()) {
|
while (Keyboard.next()) {
|
||||||
keyboardEvent();
|
keyboardEvent();
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::mouseEvent()
|
void Screen::mouseEvent()
|
||||||
{
|
{
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
// Mouse event dispatching is handled directly in updateEvents() for Windows
|
||||||
|
#else
|
||||||
/* 4J - TODO
|
/* 4J - TODO
|
||||||
if (Mouse.getEventButtonState()) {
|
if (Mouse.getEventButtonState()) {
|
||||||
int xm = Mouse.getEventX() * width / minecraft.width;
|
int xm = Mouse.getEventX() * width / minecraft.width;
|
||||||
@@ -128,6 +182,7 @@ void Screen::mouseEvent()
|
|||||||
mouseReleased(xm, ym, Mouse.getEventButton());
|
mouseReleased(xm, ym, Mouse.getEventButton());
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::keyboardEvent()
|
void Screen::keyboardEvent()
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ KeyboardMouseInput::KeyboardMouseInput()
|
|||||||
, m_captured(false)
|
, m_captured(false)
|
||||||
, m_hWnd(NULL)
|
, m_hWnd(NULL)
|
||||||
, m_initialized(false)
|
, m_initialized(false)
|
||||||
|
, m_mouseX(0)
|
||||||
|
, m_mouseY(0)
|
||||||
{
|
{
|
||||||
memset(m_keyState, 0, sizeof(m_keyState));
|
memset(m_keyState, 0, sizeof(m_keyState));
|
||||||
memset(m_keyStatePrev, 0, sizeof(m_keyStatePrev));
|
memset(m_keyStatePrev, 0, sizeof(m_keyStatePrev));
|
||||||
@@ -20,6 +22,7 @@ KeyboardMouseInput::KeyboardMouseInput()
|
|||||||
memset(m_mouseButtonsPrev, 0, sizeof(m_mouseButtonsPrev));
|
memset(m_mouseButtonsPrev, 0, sizeof(m_mouseButtonsPrev));
|
||||||
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
|
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
|
||||||
memset(m_mousePressedAccum, 0, sizeof(m_mousePressedAccum));
|
memset(m_mousePressedAccum, 0, sizeof(m_mousePressedAccum));
|
||||||
|
memset(m_mouseReleasedAccum, 0, sizeof(m_mouseReleasedAccum));
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardMouseInput::~KeyboardMouseInput()
|
KeyboardMouseInput::~KeyboardMouseInput()
|
||||||
@@ -103,6 +106,7 @@ void KeyboardMouseInput::OnMouseButton(int button, bool down)
|
|||||||
if (button >= 0 && button < 3)
|
if (button >= 0 && button < 3)
|
||||||
{
|
{
|
||||||
if (down && !m_mouseButtons[button]) m_mousePressedAccum[button] = true;
|
if (down && !m_mouseButtons[button]) m_mousePressedAccum[button] = true;
|
||||||
|
if (!down && m_mouseButtons[button]) m_mouseReleasedAccum[button] = true;
|
||||||
m_mouseButtons[button] = down;
|
m_mouseButtons[button] = down;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,12 +116,23 @@ void KeyboardMouseInput::OnMouseWheel(int delta)
|
|||||||
m_scrollDeltaAccum += delta;
|
m_scrollDeltaAccum += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KeyboardMouseInput::OnMouseMove(int x, int y)
|
||||||
|
{
|
||||||
|
m_mouseX = x;
|
||||||
|
m_mouseY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int KeyboardMouseInput::GetMouseX() const { return m_mouseX; }
|
||||||
|
int KeyboardMouseInput::GetMouseY() const { return m_mouseY; }
|
||||||
|
HWND KeyboardMouseInput::GetHWnd() const { return m_hWnd; }
|
||||||
|
|
||||||
void KeyboardMouseInput::ClearAllState()
|
void KeyboardMouseInput::ClearAllState()
|
||||||
{
|
{
|
||||||
memset(m_keyState, 0, sizeof(m_keyState));
|
memset(m_keyState, 0, sizeof(m_keyState));
|
||||||
memset(m_mouseButtons, 0, sizeof(m_mouseButtons));
|
memset(m_mouseButtons, 0, sizeof(m_mouseButtons));
|
||||||
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
|
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
|
||||||
memset(m_mousePressedAccum, 0, sizeof(m_mousePressedAccum));
|
memset(m_mousePressedAccum, 0, sizeof(m_mousePressedAccum));
|
||||||
|
memset(m_mouseReleasedAccum, 0, sizeof(m_mouseReleasedAccum));
|
||||||
m_mouseDeltaXAccum = 0.0f;
|
m_mouseDeltaXAccum = 0.0f;
|
||||||
m_mouseDeltaYAccum = 0.0f;
|
m_mouseDeltaYAccum = 0.0f;
|
||||||
m_scrollDeltaAccum = 0;
|
m_scrollDeltaAccum = 0;
|
||||||
@@ -178,6 +193,14 @@ bool KeyboardMouseInput::ConsumeMousePress(int btn)
|
|||||||
return pressed;
|
return pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KeyboardMouseInput::ConsumeMouseRelease(int btn)
|
||||||
|
{
|
||||||
|
if (btn < 0 || btn >= 3) return false;
|
||||||
|
bool released = m_mouseReleasedAccum[btn];
|
||||||
|
m_mouseReleasedAccum[btn] = false;
|
||||||
|
return released;
|
||||||
|
}
|
||||||
|
|
||||||
void KeyboardMouseInput::ConsumeMouseDelta(float &dx, float &dy)
|
void KeyboardMouseInput::ConsumeMouseDelta(float &dx, float &dy)
|
||||||
{
|
{
|
||||||
dx = m_mouseDeltaXAccum;
|
dx = m_mouseDeltaXAccum;
|
||||||
|
|||||||
@@ -42,9 +42,16 @@ public:
|
|||||||
// Use these from code that runs at game tick rate (20Hz).
|
// Use these from code that runs at game tick rate (20Hz).
|
||||||
bool ConsumeKeyPress(int vk);
|
bool ConsumeKeyPress(int vk);
|
||||||
bool ConsumeMousePress(int btn);
|
bool ConsumeMousePress(int btn);
|
||||||
|
bool ConsumeMouseRelease(int btn);
|
||||||
void ConsumeMouseDelta(float &dx, float &dy);
|
void ConsumeMouseDelta(float &dx, float &dy);
|
||||||
int ConsumeScrollDelta();
|
int ConsumeScrollDelta();
|
||||||
|
|
||||||
|
// Absolute cursor position (client-area coordinates, for GUI when not captured)
|
||||||
|
void OnMouseMove(int x, int y);
|
||||||
|
int GetMouseX() const;
|
||||||
|
int GetMouseY() const;
|
||||||
|
HWND GetHWnd() const;
|
||||||
|
|
||||||
// Mouse capture for FPS look
|
// Mouse capture for FPS look
|
||||||
void SetCapture(bool capture);
|
void SetCapture(bool capture);
|
||||||
bool IsCaptured() const;
|
bool IsCaptured() const;
|
||||||
@@ -61,6 +68,7 @@ private:
|
|||||||
// Sticky press accumulators (persist until consumed by game tick)
|
// Sticky press accumulators (persist until consumed by game tick)
|
||||||
bool m_keyPressedAccum[256];
|
bool m_keyPressedAccum[256];
|
||||||
bool m_mousePressedAccum[3];
|
bool m_mousePressedAccum[3];
|
||||||
|
bool m_mouseReleasedAccum[3];
|
||||||
|
|
||||||
// Mouse delta accumulators (persist until consumed by game tick)
|
// Mouse delta accumulators (persist until consumed by game tick)
|
||||||
float m_mouseDeltaXAccum;
|
float m_mouseDeltaXAccum;
|
||||||
@@ -72,6 +80,10 @@ private:
|
|||||||
bool m_captured;
|
bool m_captured;
|
||||||
HWND m_hWnd;
|
HWND m_hWnd;
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
|
|
||||||
|
// Absolute cursor position in client coordinates
|
||||||
|
int m_mouseX;
|
||||||
|
int m_mouseY;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern KeyboardMouseInput KMInput;
|
extern KeyboardMouseInput KMInput;
|
||||||
|
|||||||
@@ -395,6 +395,9 @@ 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);
|
||||||
@@ -404,6 +407,15 @@ 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);
|
||||||
}
|
}
|
||||||
@@ -1184,7 +1196,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);
|
bool shouldCapture = app.GetGameStarted() && !ui.GetMenuDisplayed(0) && pMinecraft->screen == NULL;
|
||||||
// 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))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ typedef unsigned __int64 __uint64;
|
|||||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||||
// Windows Header Files:
|
// Windows Header Files:
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <windowsx.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
// TODO: reference additional headers your program requires here
|
// TODO: reference additional headers your program requires here
|
||||||
|
|||||||
@@ -1,5 +1,46 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
#include "Windows64\KeyboardMouseInput.h"
|
||||||
|
|
||||||
|
int Mouse::getX()
|
||||||
|
{
|
||||||
|
return KMInput.GetMouseX();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Mouse::getY()
|
||||||
|
{
|
||||||
|
// Return Y in bottom-up coordinates (OpenGL convention, matching original Java LWJGL Mouse)
|
||||||
|
RECT rect;
|
||||||
|
GetClientRect(KMInput.GetHWnd(), &rect);
|
||||||
|
return (rect.bottom - 1) - KMInput.GetMouseY();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mouse::isButtonDown(int button)
|
||||||
|
{
|
||||||
|
return KMInput.IsMouseDown(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::isKeyDown(int key)
|
||||||
|
{
|
||||||
|
// Map Keyboard constants to Windows virtual key codes
|
||||||
|
if (key == Keyboard::KEY_LSHIFT) return KMInput.IsKeyDown(VK_LSHIFT);
|
||||||
|
if (key == Keyboard::KEY_RSHIFT) return KMInput.IsKeyDown(VK_RSHIFT);
|
||||||
|
if (key == Keyboard::KEY_ESCAPE) return KMInput.IsKeyDown(VK_ESCAPE);
|
||||||
|
if (key == Keyboard::KEY_RETURN) return KMInput.IsKeyDown(VK_RETURN);
|
||||||
|
if (key == Keyboard::KEY_BACK) return KMInput.IsKeyDown(VK_BACK);
|
||||||
|
if (key == Keyboard::KEY_SPACE) return KMInput.IsKeyDown(VK_SPACE);
|
||||||
|
if (key == Keyboard::KEY_TAB) return KMInput.IsKeyDown(VK_TAB);
|
||||||
|
if (key == Keyboard::KEY_UP) return KMInput.IsKeyDown(VK_UP);
|
||||||
|
if (key == Keyboard::KEY_DOWN) return KMInput.IsKeyDown(VK_DOWN);
|
||||||
|
if (key == Keyboard::KEY_LEFT) return KMInput.IsKeyDown(VK_LEFT);
|
||||||
|
if (key == Keyboard::KEY_RIGHT) return KMInput.IsKeyDown(VK_RIGHT);
|
||||||
|
if (key >= Keyboard::KEY_A && key <= Keyboard::KEY_Z)
|
||||||
|
return KMInput.IsKeyDown('A' + (key - Keyboard::KEY_A));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void glReadPixels(int,int, int, int, int, int, ByteBuffer *)
|
void glReadPixels(int,int, int, int, int, int, ByteBuffer *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,7 +186,11 @@ class Keyboard
|
|||||||
public:
|
public:
|
||||||
static void create() {}
|
static void create() {}
|
||||||
static void destroy() {}
|
static void destroy() {}
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
static bool isKeyDown(int key);
|
||||||
|
#else
|
||||||
static bool isKeyDown(int) {return false;}
|
static bool isKeyDown(int) {return false;}
|
||||||
|
#endif
|
||||||
static wstring getKeyName(int) { return L"KEYNAME"; }
|
static wstring getKeyName(int) { return L"KEYNAME"; }
|
||||||
static void enableRepeatEvents(bool) {}
|
static void enableRepeatEvents(bool) {}
|
||||||
static const int KEY_A = 0;
|
static const int KEY_A = 0;
|
||||||
@@ -224,6 +228,8 @@ public:
|
|||||||
static const int KEY_UP = 32;
|
static const int KEY_UP = 32;
|
||||||
static const int KEY_DOWN = 33;
|
static const int KEY_DOWN = 33;
|
||||||
static const int KEY_TAB = 34;
|
static const int KEY_TAB = 34;
|
||||||
|
static const int KEY_LEFT = 35;
|
||||||
|
static const int KEY_RIGHT = 36;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mouse
|
class Mouse
|
||||||
@@ -231,9 +237,15 @@ class Mouse
|
|||||||
public:
|
public:
|
||||||
static void create() {}
|
static void create() {}
|
||||||
static void destroy() {}
|
static void destroy() {}
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
static int getX();
|
||||||
|
static int getY();
|
||||||
|
static bool isButtonDown(int button);
|
||||||
|
#else
|
||||||
static int getX() { return 0; }
|
static int getX() { return 0; }
|
||||||
static int getY() { return 0; }
|
static int getY() { return 0; }
|
||||||
static bool isButtonDown(int) { return false; }
|
static bool isButtonDown(int) { return false; }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class Display
|
class Display
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# MinecraftConsoles
|
# MinecraftConsoles
|
||||||
|
|
||||||
|
[](https://discord.gg/5CSzhc9t)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
@@ -20,9 +22,9 @@ This project contains the source code of Minecraft Legacy Console Edition v1.3.0
|
|||||||
2. Clone the repository
|
2. Clone the repository
|
||||||
3. Open the project by double-clicking `MinecraftConsoles.sln`
|
3. Open the project by double-clicking `MinecraftConsoles.sln`
|
||||||
4. Make sure `Minecraft.Client` is set as the Startup Project
|
4. Make sure `Minecraft.Client` is set as the Startup Project
|
||||||
5. Set the build configuration to **Debug** or **Release** and the target platform to **Windows64**, then build and run
|
5. Set the build configuration to **Debug** (Release is also OK but has some bugs) and the target platform to **Windows64**, then build and run
|
||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
|
|
||||||
- Builds for other platforms have not been tested and are most likely non-functional
|
- Builds for other platforms have not been tested and are most likely non-functional
|
||||||
- Other unknown issues may exist
|
- There are some render bugs in the Release mode build
|
||||||
|
|||||||
Reference in New Issue
Block a user