Skip to content

Instantly share code, notes, and snippets.

@nommiin
Last active March 3, 2026 21:04
Show Gist options
  • Select an option

  • Save nommiin/364d1c1b8a80f9e74fa373502a0fe242 to your computer and use it in GitHub Desktop.

Select an option

Save nommiin/364d1c1b8a80f9e74fa373502a0fe242 to your computer and use it in GitHub Desktop.
A basic shim for adding keyboard support to Minecraft Console Edition
#include "stdafx.h"
#include <Windows64\4JLibs\inc\4J_Input.h>
#include <Common\App_enums.h>
#include <Windows.h>
C_4JInput InputManager;
void C_4JInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC)
{
}
bool m_CurrentKeys[256] = {};
bool m_PreviousKeys[256] = {};
void C_4JInput::Tick(void)
{
for (int i = 0; i < 256; ++i)
{
m_PreviousKeys[i] = m_CurrentKeys[i];
m_CurrentKeys[i] = (GetAsyncKeyState(i) & 0x8000) != 0;
}
}
void C_4JInput::SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax)
{
}
void C_4JInput::SetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction, unsigned int uiActionVal)
{
}
unsigned int C_4JInput::GetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction)
{
return 0;
}
void C_4JInput::SetJoypadMapVal(int iPad, unsigned char ucMap)
{
}
unsigned char C_4JInput::GetJoypadMapVal(int iPad)
{
return 0;
}
void C_4JInput::SetJoypadSensitivity(int iPad, float fSensitivity)
{
}
bool KeyDown(int key) {
return (GetAsyncKeyState(key) & 0x8000) != 0;
}
bool KeyPressed(int key) {
return m_CurrentKeys[key] && !m_PreviousKeys[key];
}
bool KeyReleased(int key) {
return !m_CurrentKeys[key] && m_PreviousKeys[key];
}
bool C_4JInput::ButtonPressed(int iPad, unsigned char ucAction)
{
switch (ucAction) {
case ACTION_MENU_UP: return KeyPressed(VK_UP);
case ACTION_MENU_DOWN: return KeyPressed(VK_DOWN);
case ACTION_MENU_LEFT: return KeyPressed(VK_LEFT);
case ACTION_MENU_RIGHT: return KeyPressed(VK_RIGHT);
case ACTION_MENU_OK:
case ACTION_MENU_A: return KeyPressed(VK_RETURN);
case ACTION_MENU_CANCEL:
case ACTION_MENU_B: return KeyPressed(VK_ESCAPE);
case MINECRAFT_ACTION_FORWARD: return KeyPressed('W');
case MINECRAFT_ACTION_BACKWARD: return KeyPressed('S');
case MINECRAFT_ACTION_LEFT: return KeyPressed('A');
case MINECRAFT_ACTION_RIGHT: return KeyPressed('D');
case MINECRAFT_ACTION_JUMP: return KeyPressed(VK_SPACE);
case MINECRAFT_ACTION_INVENTORY: return KeyPressed('E');
case MINECRAFT_ACTION_DROP: return KeyPressed('Q');
case MINECRAFT_ACTION_ACTION: return KeyPressed(VK_LBUTTON);
case MINECRAFT_ACTION_USE: return KeyPressed(VK_RBUTTON);
case MINECRAFT_ACTION_RENDER_THIRD_PERSON: return KeyPressed(VK_F5);
}
return false;
}
bool C_4JInput::ButtonReleased(int iPad, unsigned char ucAction)
{
switch (ucAction) {
case ACTION_MENU_UP: return KeyReleased(VK_UP);
case ACTION_MENU_DOWN: return KeyReleased(VK_DOWN);
case ACTION_MENU_LEFT: return KeyReleased(VK_LEFT);
case ACTION_MENU_RIGHT: return KeyReleased(VK_RIGHT);
case ACTION_MENU_OK:
case ACTION_MENU_A: return KeyReleased(VK_RETURN);
case ACTION_MENU_CANCEL:
case ACTION_MENU_B: return KeyReleased(VK_ESCAPE);
case MINECRAFT_ACTION_FORWARD: return KeyReleased('W');
case MINECRAFT_ACTION_BACKWARD: return KeyReleased('S');
case MINECRAFT_ACTION_LEFT: return KeyReleased('A');
case MINECRAFT_ACTION_RIGHT: return KeyReleased('D');
case MINECRAFT_ACTION_JUMP: return KeyReleased(VK_SPACE);
case MINECRAFT_ACTION_INVENTORY: return KeyReleased('E');
case MINECRAFT_ACTION_DROP: return KeyReleased('Q');
case MINECRAFT_ACTION_ACTION: return KeyReleased(VK_LBUTTON);
case MINECRAFT_ACTION_USE: return KeyReleased(VK_RBUTTON);
case MINECRAFT_ACTION_RENDER_THIRD_PERSON: return KeyReleased(VK_F5);
}
return false;
}
bool C_4JInput::ButtonDown(int iPad, unsigned char ucAction)
{
switch (ucAction) {
case ACTION_MENU_UP: return KeyDown(VK_UP);
case ACTION_MENU_DOWN: return KeyDown(VK_DOWN);
case ACTION_MENU_LEFT: return KeyDown(VK_LEFT);
case ACTION_MENU_RIGHT: return KeyDown(VK_RIGHT);
case ACTION_MENU_OK:
case ACTION_MENU_A: return KeyDown(VK_RETURN);
case ACTION_MENU_CANCEL:
case ACTION_MENU_B: return KeyDown(VK_ESCAPE);
case MINECRAFT_ACTION_FORWARD: return KeyDown('W');
case MINECRAFT_ACTION_BACKWARD: return KeyDown('S');
case MINECRAFT_ACTION_LEFT: return KeyDown('A');
case MINECRAFT_ACTION_RIGHT: return KeyDown('D');
case MINECRAFT_ACTION_JUMP: return KeyDown(VK_SPACE);
case MINECRAFT_ACTION_INVENTORY: return KeyDown('E');
case MINECRAFT_ACTION_DROP: return KeyDown('Q');
case MINECRAFT_ACTION_ACTION: return KeyDown(VK_LBUTTON);
case MINECRAFT_ACTION_USE: return KeyDown(VK_RBUTTON);
case MINECRAFT_ACTION_RENDER_THIRD_PERSON: return KeyDown(VK_F5);
}
return false;
}
bool C_4JInput::ButtonPressedDirect(int key) {
return KeyPressed(key);
}
unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat)
{
return ButtonDown(iPad, ucAction);
}
void C_4JInput::SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
{
}
void C_4JInput::SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
{
}
void C_4JInput::SetKeyRepeatRate(float fRepeatDelaySecs, float fRepeatRateSecs)
{
}
void C_4JInput::SetDebugSequence(const char* chSequenceA, int(*Func)(LPVOID), LPVOID lpParam)
{
}
FLOAT C_4JInput::GetIdleSeconds(int iPad)
{
return 0.0f;
}
bool C_4JInput::IsPadConnected(int iPad)
{
if (iPad == 0) return true;
return false;
}
float C_4JInput::GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay)
{
if (KeyDown('A')) {
return -1.0f;
} else if (KeyDown('D')) {
return 1.0f;
}
return 0.0f;
}
float C_4JInput::GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay)
{
if (KeyDown('W')) {
return 1.0f;
} else if (KeyDown('S')) {
return -1.0f;
}
return 0.0f;
}
float C_4JInput::GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay)
{
if (KeyDown(VK_LEFT)) {
return -1.0f;
} else if (KeyDown(VK_RIGHT)) {
return 1.0f;
}
return 0.0f;
}
float C_4JInput::GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay)
{
if (KeyDown(VK_UP)) {
return 1.0f;
} else if (KeyDown(VK_DOWN)) {
return -1.0f;
}
return 0.0f;
}
unsigned char C_4JInput::GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay)
{
if (KeyDown(VK_RBUTTON)) {
return 1;
}
return 0;
}
unsigned char C_4JInput::GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay)
{
if (KeyDown(VK_LBUTTON)) {
return 1;
}
return 0;
}
void C_4JInput::SetMenuDisplayed(int iPad, bool bVal)
{
}
EKeyboardResult C_4JInput::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int( *Func)(LPVOID,const bool),LPVOID lpParam,C_4JInput::EKeyboardMode eMode)
{
return EKeyboard_Pending;
}
void C_4JInput::GetText(uint16_t* UTF16String)
{
}
bool C_4JInput::VerifyStrings(
WCHAR** pwStringA,
int iStringC,
int(*Func)(LPVOID, STRING_VERIFY_RESPONSE*),
LPVOID lpParam)
{
return false;
}
void C_4JInput::CancelQueuedVerifyStrings(
int(*Func)(LPVOID, STRING_VERIFY_RESPONSE*),
LPVOID lpParam)
{
}
void C_4JInput::CancelAllVerifyInProgress(void)
{
}
@DaBigJGit
Copy link

Can I apply this to a pre built version?

@BlackAnt1968601851
Copy link

BlackAnt1968601851 commented Mar 1, 2026

im getting compilation errors such as C_4JInput::ButtonPressedDirect(int key) not existing and etc.

and also this too
2>Minecraft.obj : error LNK2019: unresolved external symbol "public: __cdecl Input::Input(void)" (??0Input@@qeaa@XZ) referenced in function "public: class std::shared_ptr __cdecl Minecraft::createExtraLocalPlayer(int,class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &,int,int,class ClientConnection *,class MultiPlayerLevel *)" (?createExtraLocalPlayer@Minecraft@@qeaa?AV?$shared_ptr@VMultiplayerLocalPlayer@@@std@@HAEBV?$basic_string@_WU?$char_traits@_W@std@@v?$allocator@_W@2@@3@HHPEAVClientConnection@@PEAVMultiPlayerLevel@@@z)

@greensci
Copy link

greensci commented Mar 1, 2026

where do i even put this?

@s1099
Copy link

s1099 commented Mar 1, 2026

where do i even put this?

Make a new .cpp file in Minecraft.Client folder, and paste in the code.
Then inside of VS, right click Minecraft.Client in solution explorer select add - existing item.
Compile and you are done
and if you get error at C_4JInput::ButtonPressedDirect then you can comment out the 3 lines

@Lilicogamer13
Copy link

i know im kinda late but how are you suposed to build it and run it outside from visual studio? even with the code leak by itself and no patches i cant get it to run outside of vs2012

@BrokenScript2
Copy link

BrokenScript2 commented Mar 1, 2026

I got it working, but for the Mouse + Keyboard part, I'm still trying to figure out. Do you have to keep the already existing "Input.cpp" file and create a new .cpp file, being the code from this post and name it "input.cpp"? Or replace Input.cpp? I need a lil bit more specific information. (Replying to @s1099)

@TheWhiteCat1000
Copy link

where do i even put this?

Make a new .cpp file in Minecraft.Client folder, and paste in the code. Then inside of VS, right click Minecraft.Client in solution explorer select add - existing item. Compile and you are done and if you get error at C_4JInput::ButtonPressedDirect then you can comment out the 3 lines

is the mouse not supposed to work? keyboard works fine but you can't look around with the mouse

@BrainFart17
Copy link

i know im kinda late but how are you suposed to build it and run it outside from visual studio? even with the code leak by itself and no patches i cant get it to run outside of vs2012

This video should help, he explains how to compile the release version.
https://www.youtube.com/watch?v=g-qCSz-pUm0

@BrainFart17
Copy link

where do i even put this?

Make a new .cpp file in Minecraft.Client folder, and paste in the code. Then inside of VS, right click Minecraft.Client in solution explorer select add - existing item. Compile and you are done and if you get error at C_4JInput::ButtonPressedDirect then you can comment out the 3 lines

is the mouse not supposed to work? keyboard works fine but you can't look around with the mouse

It looks like as of now you can look around using the arrow keys, not the mouse

@ob-cell
Copy link

ob-cell commented Mar 2, 2026

Thank you

@BlockyEggs1324
Copy link

I made a version that allows for keyboard input and controller input

#include "stdafx.h"

#include <Windows64\4JLibs\inc\4J_Input.h>
#include <Common\App_enums.h>
#include <Windows.h>
#include <Xinput.h>

XINPUT_STATE m_PreviousState[4];
XINPUT_STATE m_CurrentState[4];

bool IsControllerPressed(int pad, WORD button)
{
	return !(m_PreviousState[pad].Gamepad.wButtons & button) &&
		(m_CurrentState[pad].Gamepad.wButtons & button);
}

bool IsControllerReleased(int pad, WORD button)
{
	return  (m_PreviousState[pad].Gamepad.wButtons & button) &&
		!(m_CurrentState[pad].Gamepad.wButtons & button);
}

bool IsControllerDown(int pad, WORD button)
{
	return (m_CurrentState[pad].Gamepad.wButtons & button) != 0;
}

bool IsTriggerPressed(int pad, bool left)
{
	XINPUT_STATE state;
	if (XInputGetState(pad, &state) != ERROR_SUCCESS)
		return false;

	return left
		? state.Gamepad.bLeftTrigger > 30
		: state.Gamepad.bRightTrigger > 30;
}

bool IsTriggerReleased(int pad, bool left)
{
	BYTE prev = left ?
		m_PreviousState[pad].Gamepad.bLeftTrigger :
	m_PreviousState[pad].Gamepad.bRightTrigger;

	BYTE curr = left ?
		m_CurrentState[pad].Gamepad.bLeftTrigger :
	m_CurrentState[pad].Gamepad.bRightTrigger;

	return prev > 30 && curr <= 30;
}

bool IsTriggerDown(int pad, bool left)
{
	BYTE value = left ?
		m_CurrentState[pad].Gamepad.bLeftTrigger :
	m_CurrentState[pad].Gamepad.bRightTrigger;

	return value > 30; // 30 = deadzone threshold
}

C_4JInput InputManager;


void C_4JInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC)
{
}

bool m_CurrentKeys[256] = {};
bool m_PreviousKeys[256] = {};

void C_4JInput::Tick(void)
{

	for (int i = 0; i < 256; ++i)
	{
		m_PreviousKeys[i] = m_CurrentKeys[i];
		m_CurrentKeys[i] = (GetAsyncKeyState(i) & 0x8000) != 0;
	}

	int pad = 0;

	m_PreviousState[pad] = m_CurrentState[pad];

	ZeroMemory(&m_CurrentState[pad], sizeof(XINPUT_STATE));
	XInputGetState(pad, &m_CurrentState[pad]);
}

void C_4JInput::SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax)
{
}

void C_4JInput::SetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction, unsigned int uiActionVal)
{
}

unsigned int C_4JInput::GetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction)
{
	return 0;
}

void C_4JInput::SetJoypadMapVal(int iPad, unsigned char ucMap)
{
}

unsigned char C_4JInput::GetJoypadMapVal(int iPad)
{
	return 0;
}

void C_4JInput::SetJoypadSensitivity(int iPad, float fSensitivity)
{
}

bool KeyDown(int key) {
	return (GetAsyncKeyState(key) & 0x8000) != 0;
}

bool KeyPressed(int key) {
	return m_CurrentKeys[key] && !m_PreviousKeys[key];
}

bool KeyReleased(int key) {
	return !m_CurrentKeys[key] && m_PreviousKeys[key];
}

bool C_4JInput::ButtonPressed(int iPad, unsigned char ucAction)
{
	switch (ucAction)
	{
	case ACTION_MENU_UP: return KeyPressed(VK_UP) || IsControllerPressed(iPad, XINPUT_GAMEPAD_DPAD_UP);
	case ACTION_MENU_DOWN: return KeyPressed(VK_DOWN) || IsControllerPressed(iPad, XINPUT_GAMEPAD_DPAD_DOWN);
	case ACTION_MENU_LEFT: return KeyPressed(VK_LEFT) || IsControllerPressed(iPad, XINPUT_GAMEPAD_DPAD_LEFT);
	case ACTION_MENU_RIGHT: return KeyPressed(VK_RIGHT) || IsControllerPressed(iPad, XINPUT_GAMEPAD_DPAD_RIGHT);
	case ACTION_MENU_OK: 
	case ACTION_MENU_A: return KeyPressed(VK_RETURN) || IsControllerPressed(iPad, XINPUT_GAMEPAD_A);
	case ACTION_MENU_CANCEL:
	case ACTION_MENU_B: return KeyPressed(VK_ESCAPE) || IsControllerPressed(iPad, XINPUT_GAMEPAD_B);

	case ACTION_MENU_LEFT_SCROLL:
		return KeyPressed('Z') || IsControllerPressed(iPad, XINPUT_GAMEPAD_LEFT_SHOULDER);

	case ACTION_MENU_RIGHT_SCROLL:
		return KeyPressed('C') || IsControllerPressed(iPad, XINPUT_GAMEPAD_RIGHT_SHOULDER);

	// Movement and stuff
	case MINECRAFT_ACTION_FORWARD:
		return KeyPressed('W');

	case MINECRAFT_ACTION_BACKWARD:
		return KeyPressed('S');

	case MINECRAFT_ACTION_LEFT:
		return KeyPressed('A');

	case MINECRAFT_ACTION_RIGHT:
		return KeyPressed('D');

	case MINECRAFT_ACTION_JUMP:
		return KeyPressed(VK_SPACE) ||
			IsControllerPressed(iPad, XINPUT_GAMEPAD_A);

	case MINECRAFT_ACTION_INVENTORY: return KeyPressed('E') || IsControllerPressed(iPad, XINPUT_GAMEPAD_Y);

	case MINECRAFT_ACTION_CRAFTING: return KeyPressed('F') || IsControllerPressed(iPad, XINPUT_GAMEPAD_X);

	case MINECRAFT_ACTION_DROP: return KeyPressed('Q') || IsControllerPressed(iPad, XINPUT_GAMEPAD_B);

	case MINECRAFT_ACTION_LEFT_SCROLL: return KeyPressed('Z') || IsControllerPressed(iPad, XINPUT_GAMEPAD_LEFT_SHOULDER);
	case MINECRAFT_ACTION_RIGHT_SCROLL: return KeyPressed('C') || IsControllerPressed(iPad, XINPUT_GAMEPAD_RIGHT_SHOULDER);

	case MINECRAFT_ACTION_ACTION:
		return KeyPressed(VK_LBUTTON);

	case MINECRAFT_ACTION_USE:
		return KeyPressed(VK_RBUTTON);

	case MINECRAFT_ACTION_PAUSEMENU:
		return KeyPressed('P') ||
			IsControllerPressed(iPad, XINPUT_GAMEPAD_START);
	}

	return false;
}

bool C_4JInput::ButtonReleased(int iPad, unsigned char ucAction)
{
	switch (ucAction) {
	case ACTION_MENU_UP: return KeyReleased(VK_UP);
	case ACTION_MENU_DOWN: return KeyReleased(VK_DOWN);
	case ACTION_MENU_LEFT: return KeyReleased(VK_LEFT);
	case ACTION_MENU_RIGHT: return KeyReleased(VK_RIGHT);
	case ACTION_MENU_OK: 
	case ACTION_MENU_A: return KeyReleased(VK_RETURN);
	case ACTION_MENU_CANCEL:
	case ACTION_MENU_B: return KeyReleased(VK_ESCAPE);

	case ACTION_MENU_LEFT_SCROLL:
		return KeyReleased('Z') || IsControllerReleased(iPad, XINPUT_GAMEPAD_LEFT_SHOULDER);

	case ACTION_MENU_RIGHT_SCROLL:
		return KeyReleased('C') || IsControllerReleased(iPad, XINPUT_GAMEPAD_RIGHT_SHOULDER);

	case MINECRAFT_ACTION_FORWARD:
		return KeyReleased('W');

	case MINECRAFT_ACTION_BACKWARD:
		return KeyReleased('S');

	case MINECRAFT_ACTION_LEFT:
		return KeyReleased('A');

	case MINECRAFT_ACTION_RIGHT:
		return KeyReleased('D');

	case MINECRAFT_ACTION_JUMP:
		return KeyReleased(VK_SPACE) ||
			IsControllerReleased(iPad, XINPUT_GAMEPAD_A);

	case MINECRAFT_ACTION_INVENTORY: return KeyReleased('E') || IsControllerReleased(iPad, XINPUT_GAMEPAD_Y);

	case MINECRAFT_ACTION_CRAFTING: return KeyReleased('F') || IsControllerReleased(iPad, XINPUT_GAMEPAD_X);

	case MINECRAFT_ACTION_DROP: return KeyReleased('Q') || IsControllerReleased(iPad, XINPUT_GAMEPAD_B);

	case MINECRAFT_ACTION_LEFT_SCROLL: return KeyReleased('Z') || IsControllerReleased(iPad, XINPUT_GAMEPAD_LEFT_SHOULDER);
	case MINECRAFT_ACTION_RIGHT_SCROLL: return KeyReleased('C') || IsControllerReleased(iPad, XINPUT_GAMEPAD_RIGHT_SHOULDER);

	case MINECRAFT_ACTION_ACTION:
		return KeyReleased(VK_LBUTTON);

	case MINECRAFT_ACTION_USE:
		return KeyReleased(VK_RBUTTON);

	case MINECRAFT_ACTION_PAUSEMENU:
		return KeyReleased('P') ||
			IsControllerReleased(iPad, XINPUT_GAMEPAD_START);
	}
	return false;
}

bool C_4JInput::ButtonDown(int iPad, unsigned char ucAction)
{
	switch (ucAction) {
	case ACTION_MENU_UP: return KeyDown(VK_UP) || IsControllerDown(iPad, XINPUT_GAMEPAD_DPAD_UP);
	case ACTION_MENU_DOWN: return KeyDown(VK_DOWN) || IsControllerDown(iPad, XINPUT_GAMEPAD_DPAD_DOWN);
	case ACTION_MENU_LEFT: return KeyDown(VK_LEFT) || IsControllerDown(iPad, XINPUT_GAMEPAD_DPAD_LEFT);
	case ACTION_MENU_RIGHT: return KeyDown(VK_RIGHT) || IsControllerDown(iPad, XINPUT_GAMEPAD_DPAD_RIGHT);
	case ACTION_MENU_OK: 
	case ACTION_MENU_A: return KeyDown(VK_RETURN);
	case ACTION_MENU_CANCEL:
	case ACTION_MENU_B: return KeyDown(VK_ESCAPE);

	case ACTION_MENU_LEFT_SCROLL:
		return KeyDown('Z') || IsControllerDown(iPad, XINPUT_GAMEPAD_LEFT_SHOULDER);

	case ACTION_MENU_RIGHT_SCROLL:
		return KeyDown('C') || IsControllerDown(iPad, XINPUT_GAMEPAD_RIGHT_SHOULDER);

	case MINECRAFT_ACTION_FORWARD:
		return KeyDown('W');

	case MINECRAFT_ACTION_BACKWARD:
		return KeyDown('S');

	case MINECRAFT_ACTION_LEFT:
		return KeyDown('A');

	case MINECRAFT_ACTION_RIGHT:
		return KeyDown('D');

	case MINECRAFT_ACTION_JUMP: return KeyDown(VK_SPACE) || IsControllerDown(iPad, XINPUT_GAMEPAD_A);

	case MINECRAFT_ACTION_INVENTORY: return KeyDown('E') || IsControllerDown(iPad, XINPUT_GAMEPAD_Y);

	case MINECRAFT_ACTION_CRAFTING: return KeyDown('F') || IsControllerDown(iPad, XINPUT_GAMEPAD_X);

	case MINECRAFT_ACTION_DROP: return KeyDown('Q') || IsControllerDown(iPad, XINPUT_GAMEPAD_B);

	case MINECRAFT_ACTION_LEFT_SCROLL: return KeyDown('Z') || IsControllerDown(iPad, XINPUT_GAMEPAD_LEFT_SHOULDER);
	case MINECRAFT_ACTION_RIGHT_SCROLL: return KeyDown('C') || IsControllerDown(iPad, XINPUT_GAMEPAD_RIGHT_SHOULDER);

	case MINECRAFT_ACTION_ACTION: return KeyDown(VK_LBUTTON) ||
									  IsTriggerDown(iPad, false);

	case MINECRAFT_ACTION_USE: return KeyDown(VK_RBUTTON)||
								   IsTriggerDown(iPad, true);

	case MINECRAFT_ACTION_RENDER_THIRD_PERSON: return KeyDown(VK_F5);
	}

	return false;
}

unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat)
{
	return ButtonDown(iPad, ucAction);
}


void C_4JInput::SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
{
}

void C_4JInput::SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
{
}

void C_4JInput::SetKeyRepeatRate(float fRepeatDelaySecs, float fRepeatRateSecs)
{
}

void C_4JInput::SetDebugSequence(const char* chSequenceA, int(*Func)(LPVOID), LPVOID lpParam)
{
}

FLOAT C_4JInput::GetIdleSeconds(int iPad)
{
	return 0.0f;
}

bool C_4JInput::IsPadConnected(int iPad)
{
	if (iPad == 0) return true;
	return false;
}

float C_4JInput::GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay)
{
    // Keyboard fallback
    if (KeyDown('A')) return -1.0f;
    if (KeyDown('D')) return 1.0f;

    short raw = m_CurrentState[iPad].Gamepad.sThumbLX;

    if (abs(raw) < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
        return 0.0f;

    return raw / 32767.0f; // normalize to -1 -> 1
}

float C_4JInput::GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay)
{
    if (KeyDown('W')) return 1.0f;
    if (KeyDown('S')) return -1.0f;

    short raw = m_CurrentState[iPad].Gamepad.sThumbLY;

    if (abs(raw) < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
        return 0.0f;

    return raw / 32767.0f;
}

float C_4JInput::GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay)
{
    if (KeyDown(VK_LEFT)) return -1.0f;
    if (KeyDown(VK_RIGHT)) return 1.0f;

    short raw = m_CurrentState[iPad].Gamepad.sThumbRX;

    if (abs(raw) < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
        return 0.0f;

    return raw / 32767.0f;
}

float C_4JInput::GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay)
{
    if (KeyDown(VK_UP)) return 1.0f;
    if (KeyDown(VK_DOWN)) return -1.0f;

    short raw = m_CurrentState[iPad].Gamepad.sThumbRY;

    if (abs(raw) < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
        return 0.0f;

    return raw / 32767.0f;
}

unsigned char C_4JInput::GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay)
{
    if (KeyDown(VK_RBUTTON))
        return 255;

    BYTE raw = m_CurrentState[iPad].Gamepad.bLeftTrigger;

    if (raw < 30)
        return 0;

    return raw;
}

unsigned char C_4JInput::GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay)
{
    if (KeyDown(VK_LBUTTON))
        return 255;

    BYTE raw = m_CurrentState[iPad].Gamepad.bRightTrigger;

    if (raw < 30)
        return 0;

    return raw;
}

void C_4JInput::SetMenuDisplayed(int iPad, bool bVal)
{
}


EKeyboardResult C_4JInput::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int( *Func)(LPVOID,const bool),LPVOID lpParam,C_4JInput::EKeyboardMode eMode)
{
	return EKeyboard_Pending;
}

void C_4JInput::GetText(uint16_t* UTF16String)
{
}

bool C_4JInput::VerifyStrings(
	WCHAR** pwStringA,
	int iStringC,
	int(*Func)(LPVOID, STRING_VERIFY_RESPONSE*),
	LPVOID lpParam)
{
	return false;
}

void C_4JInput::CancelQueuedVerifyStrings(
	int(*Func)(LPVOID, STRING_VERIFY_RESPONSE*),
	LPVOID lpParam)
{
}

void C_4JInput::CancelAllVerifyInProgress(void)

@redmixtv
Copy link

redmixtv commented Mar 3, 2026

does anyone know of any modded versions of the leak and such? ones that people wouldve tried to fix bugs in or push updates too. would be cool to see what the comm could do with this

@Kaloyan501
Copy link

Made a version with mouse support: https://gist.github.com/Kaloyan501/6d6abc33e84abca1432304b01a14d098#file-input_keyboard-cpp-L201
Its a lil bit janky (the sensitivity is low as hell and when its not, everything else breaks), but if you adjust the sensitivity in game its fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment