Files
MinecraftConsoles/Minecraft.Client/Common/XUI/XUI_HelpControls.cpp
ModMaker101 a9be52c41a Project modernization (#630)
* Fixed boats falling and a TP glitch #266

* Replaced every C-style cast with C++ ones

* Replaced every C-style cast with C++ ones

* Fixed boats falling and a TP glitch #266

* Updated NULL to nullptr and fixing some type issues

* Modernized and fixed a few bugs

- Replaced most instances of `NULL` with `nullptr`.
- Replaced most `shared_ptr(new ...)` with `make_shared`.
- Removed the `nullptr` macro as it was interfering with the actual nullptr keyword in some instances.

* Fixing more conflicts

* Replace int loops with size_t and start work on overrides
2026-03-08 09:56:03 +07:00

567 lines
15 KiB
C++

#include "stdafx.h"
#include <assert.h>
#include "..\XUI\XUI_HelpControls.h"
#include "XUI_Ctrl_4JList.h"
#include "..\..\..\Minecraft.World\net.minecraft.world.level.h"
#include "..\..\..\Minecraft.World\LevelData.h"
#include "..\..\MultiplayerLocalPlayer.h"
#define ALIGN_START 0
#define ALIGN_END 1
typedef struct
{
WCHAR wchName[20];
int iAlign;
D3DXVECTOR3 vPos;
}
CONTROLDETAILS;
LPCWSTR CScene_Controls::m_LayoutNameA[3]=
{
L"1",
L"2",
L"3",
};
CONTROLDETAILS controlDetailsA[MAX_CONTROLS]=
{
{
L"FigA",ALIGN_END // _360_JOY_BUTTON_A
},
{
L"FigB",ALIGN_END // _360_JOY_BUTTON_B
},
{
L"FigX",ALIGN_END // _360_JOY_BUTTON_X
},
{
L"FigY",ALIGN_END // _360_JOY_BUTTON_Y
},
{
L"FigStart",ALIGN_END // _360_JOY_BUTTON_START
},
{
L"FigBack",ALIGN_START // _360_JOY_BUTTON_BACK
},
{
L"FigRB",ALIGN_END // _360_JOY_BUTTON_RB
},
{
L"FigLB",ALIGN_START // _360_JOY_BUTTON_LB
},
{
L"FigRStickButton",ALIGN_END // _360_JOY_BUTTON_RTHUMB
},
{
L"FigLStickButton",ALIGN_START // _360_JOY_BUTTON_LTHUMB
},
// Move
{
L"FigRStick",ALIGN_END // _360_JOY_BUTTON_RSTICK_RIGHT
},
// Look
{
L"FigLStick",ALIGN_START // _360_JOY_BUTTON_LSTICK_RIGHT
},
{
L"FigRT",ALIGN_END // RT
},
{
L"FigLT",ALIGN_START // LT
},
{
L"FigDpadR",ALIGN_START // DpadR
},
{
L"FigDpadL",ALIGN_START // DpadL
},
{
L"FigDpad",ALIGN_START // DpadL
},
};
//----------------------------------------------------------------------------------
// Performs initialization tasks - retrieves controls.
//----------------------------------------------------------------------------------
HRESULT CScene_Controls::OnInit( XUIMessageInit* pInitData, BOOL& bHandled )
{
MapChildControls();
XuiControlSetText(m_SouthPaw,app.GetString(IDS_SOUTHPAW));
XuiControlSetText(m_InvertLook,app.GetString(IDS_INVERT_LOOK));
m_iPad=*static_cast<int *>(pInitData->pvInitData);
// if we're not in the game, we need to use basescene 0
bool bNotInGame=(Minecraft::GetInstance()->level==nullptr);
bool bSplitscreen=(app.GetLocalPlayerCount()>1);
m_iCurrentTextIndex=0;
m_bCreativeMode = !bNotInGame && Minecraft::GetInstance()->localplayers[m_iPad] && Minecraft::GetInstance()->localplayers[m_iPad]->abilities.mayfly;
if(!bNotInGame)
{
// disable the build ver display
m_BuildVer.SetShow(FALSE);
}
if(bSplitscreen)
{
app.AdjustSplitscreenScene(m_hObj,&m_OriginalPosition,m_iPad,32.0f);
CXuiSceneBase::ShowLogo( m_iPad, FALSE );
}
else
{
if(bNotInGame)
{
CXuiSceneBase::ShowLogo( DEFAULT_XUI_MENU_USER, TRUE );
}
else
{
CXuiSceneBase::ShowLogo( m_iPad, TRUE );
}
}
// if we're not in the game, we need to use basescene 0
if(bNotInGame)
{
ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK);
}
else
{
ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK);
}
m_iSchemeTextA[0]=IDS_CONTROLS_SCHEME0;
m_iSchemeTextA[1]=IDS_CONTROLS_SCHEME1;
m_iSchemeTextA[2]=IDS_CONTROLS_SCHEME2;
// get the figures
HXUIOBJ hObj;
HRESULT hr;
// turn off all the figures to start with
for(int i=0;i<MAX_CONTROLS;i++)
{
m_FigA[i].GetChildById(controlDetailsA[i].wchName,&hObj);
hr=XuiElementGetPosition(hObj,&controlDetailsA[i].vPos);
if(controlDetailsA[i].iAlign==ALIGN_END)
{
float fW,fH;
hr=XuiElementGetBounds(hObj,&fW,&fH);
controlDetailsA[i].vPos.x+=fW;
controlDetailsA[i].vPos.y+=fH;
}
// if we're in splitscreen, half all the numbers
if(bSplitscreen)
{
controlDetailsA[i].vPos.x/=2.0f;
controlDetailsA[i].vPos.y/=2.0f;
}
m_FigA[i].SetShow(FALSE);
m_TextPresenterA[i] = nullptr;
}
// fill out the layouts list
VOID *pObj;
XuiObjectFromHandle( m_SchemeList, &pObj );
m_pLayoutList = static_cast<CXuiCtrl4JList *>(pObj);
CXuiCtrl4JList::LIST_ITEM_INFO ListInfo[3];
ZeroMemory(ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO)*3);
for(int i=0;i<3;i++)
{
ListInfo[i].pwszText=m_LayoutNameA[i];
ListInfo[i].hXuiBrush=nullptr;
ListInfo[i].fEnabled=TRUE;
m_pLayoutList->AddData(ListInfo[i]);
}
m_bIgnoreNotifies=true;
m_bIgnoreNotifies=false;
int iSelected=app.GetGameSettings(m_iPad,eGameSetting_ControlScheme);
XuiControlSetText(m_SchemeList,app.GetString(IDS_CONTROLS_LAYOUT));
hr=m_pLayoutList->SetCurSelVisible(iSelected);
m_iCurrentNavigatedControlsLayout=iSelected;
LPWSTR layoutString = new wchar_t[ 128 ];
swprintf( layoutString, 128, L"%ls : %ls", app.GetString( IDS_CURRENT_LAYOUT ),app.GetString(m_iSchemeTextA[iSelected]));
XuiControlSetText(m_CurrentLayout,layoutString);
//PositionAllText(m_iPad);
swprintf( layoutString, 128, L"%ls%ls", VER_PRODUCTVERSION_STR_W,app.DLCInstallProcessCompleted()?L"_DLC":L" ");
m_BuildVer.SetText(layoutString);
delete [] layoutString;
// Set check box initial states.
BOOL bInvertLook = app.GetGameSettings(m_iPad,eGameSetting_ControlInvertLook);
m_InvertLook.SetCheck( bInvertLook );
BOOL bSouthPaw = app.GetGameSettings(m_iPad,eGameSetting_ControlSouthPaw);
m_SouthPaw.SetCheck( bSouthPaw );
return S_OK;
}
HRESULT CScene_Controls::OnTransitionStart( XUIMessageTransition *pTransition, BOOL& bHandled )
{
if(pTransition->dwTransAction==XUI_TRANSITION_ACTION_DESTROY ) return S_OK;
if(pTransition->dwTransType == XUI_TRANSITION_TO || pTransition->dwTransType == XUI_TRANSITION_BACKTO)
{
int iSelected=app.GetGameSettings(m_iPad,eGameSetting_ControlScheme);
// and update the highlight on the current selection
m_pLayoutList->SetBorder(iSelected,TRUE);
PositionAllText(m_iPad);
}
return S_OK;
}
void CScene_Controls::PositionAllText(int iPad)
{
// turn off all the figures to start with
for(int i=0;i<MAX_CONTROLS;i++)
{
m_FigA[i].SetShow(FALSE);
}
m_iCurrentTextIndex=0;
if(m_bCreativeMode)
{
PositionText(iPad,IDS_CONTROLS_JUMPFLY,MINECRAFT_ACTION_JUMP);
}
else
{
PositionText(iPad,IDS_CONTROLS_JUMP,MINECRAFT_ACTION_JUMP);
}
PositionText(iPad,IDS_CONTROLS_INVENTORY,MINECRAFT_ACTION_INVENTORY);
PositionText(iPad,IDS_CONTROLS_PAUSE,MINECRAFT_ACTION_PAUSEMENU);
if(m_bCreativeMode)
{
PositionText(iPad,IDS_CONTROLS_SNEAKFLY,MINECRAFT_ACTION_SNEAK_TOGGLE);
}
else
{
PositionText(iPad,IDS_CONTROLS_SNEAK,MINECRAFT_ACTION_SNEAK_TOGGLE);
}
PositionText(iPad,IDS_CONTROLS_USE,MINECRAFT_ACTION_USE);
PositionText(iPad,IDS_CONTROLS_ACTION,MINECRAFT_ACTION_ACTION);
PositionText(iPad,IDS_CONTROLS_HELDITEM,MINECRAFT_ACTION_RIGHT_SCROLL);
PositionText(iPad,IDS_CONTROLS_HELDITEM,MINECRAFT_ACTION_LEFT_SCROLL);
PositionText(iPad,IDS_CONTROLS_DROP,MINECRAFT_ACTION_DROP);
PositionText(iPad,IDS_CONTROLS_CRAFTING,MINECRAFT_ACTION_CRAFTING);
PositionText(iPad,IDS_CONTROLS_THIRDPERSON,MINECRAFT_ACTION_RENDER_THIRD_PERSON);
PositionText(iPad,IDS_CONTROLS_PLAYERS,MINECRAFT_ACTION_GAME_INFO);
// Swap for southpaw.
if ( app.GetGameSettings(m_iPad,eGameSetting_ControlSouthPaw) )
{
// Move
PositionText(iPad,IDS_CONTROLS_LOOK,MINECRAFT_ACTION_RIGHT);
// Look
PositionText(iPad,IDS_CONTROLS_MOVE,MINECRAFT_ACTION_LOOK_RIGHT);
}
else // Normal right handed.
{
// Move
PositionText(iPad,IDS_CONTROLS_MOVE,MINECRAFT_ACTION_RIGHT);
// Look
PositionText(iPad,IDS_CONTROLS_LOOK,MINECRAFT_ACTION_LOOK_RIGHT);
}
// If we're in controls mode 1, and creative mode show the dpad for Creative Mode
if(m_bCreativeMode && (m_iCurrentNavigatedControlsLayout==0))
{
PositionTextDirect(iPad,IDS_CONTROLS_DPAD,16,true);
}
else
{
PositionTextDirect(iPad,IDS_CONTROLS_DPAD,16,false);
}
}
HRESULT CScene_Controls::OnKeyDown(XUIMessageInput* pInputData, BOOL& rfHandled)
{
ui.AnimateKeyPress(pInputData->UserIndex, pInputData->dwKeyCode);
HRESULT hr=S_OK;
// Explicitly handle B button presses
switch(pInputData->dwKeyCode)
{
case VK_PAD_B:
case VK_ESCAPE:
app.CheckGameSettingsChanged(true,pInputData->UserIndex);
app.NavigateBack(pInputData->UserIndex);
rfHandled = TRUE;
break;
}
return hr;
}
void CScene_Controls::PositionText(int iPad,int iTextID, unsigned char ucAction)
{
// position the text depending on the control id
//int iTextWidth;
XUIRect xuiRect;
LPCWSTR pwchText;
D3DXVECTOR3 vpos,vScale;
HXUIOBJ hFigGroup;
unsigned int uiVal=InputManager.GetGameJoypadMaps(m_iCurrentNavigatedControlsLayout,ucAction);
// get the visual of the fig group and use any scaling in it to adjust the text positions
XuiElementGetChildById(m_hObj,L"FigGroup",&hFigGroup);
XuiElementGetScale(hFigGroup,&vScale);
// check the width of the control with the text set in it
if(m_TextPresenterA[m_iCurrentTextIndex]==nullptr)
{
HXUIOBJ hObj=nullptr;
HRESULT hr=XuiControlGetVisual(m_TextA[m_iCurrentTextIndex].m_hObj,&hObj);
hr=XuiElementGetChildById(hObj,L"Text",&m_TextPresenterA[m_iCurrentTextIndex]);
}
pwchText=app.GetString(iTextID);
HRESULT hr=XuiTextPresenterMeasureText(m_TextPresenterA[m_iCurrentTextIndex], pwchText, &xuiRect);
m_TextA[m_iCurrentTextIndex].SetBounds(xuiRect.right,xuiRect.bottom);
int iControlDetailsIndex=0;
switch(uiVal)
{
case _360_JOY_BUTTON_A:
iControlDetailsIndex=0;
break;
case _360_JOY_BUTTON_B:
iControlDetailsIndex=1;
break;
case _360_JOY_BUTTON_X:
iControlDetailsIndex=2;
break;
case _360_JOY_BUTTON_Y:
iControlDetailsIndex=3;
break;
case _360_JOY_BUTTON_START:
iControlDetailsIndex=4;
break;
case _360_JOY_BUTTON_BACK:
iControlDetailsIndex=5;
break;
case _360_JOY_BUTTON_RB:
iControlDetailsIndex=6;
break;
case _360_JOY_BUTTON_LB:
iControlDetailsIndex=7;
break;
case _360_JOY_BUTTON_RTHUMB:
iControlDetailsIndex=8;
break;
case _360_JOY_BUTTON_LTHUMB:
iControlDetailsIndex=9;
break;
// Look
case _360_JOY_BUTTON_RSTICK_RIGHT:
iControlDetailsIndex=10;
break;
// Move
case _360_JOY_BUTTON_LSTICK_RIGHT:
iControlDetailsIndex=11;
break;
case _360_JOY_BUTTON_RT:
iControlDetailsIndex=12;
break;
// Move
case _360_JOY_BUTTON_LT:
iControlDetailsIndex=13;
break;
case _360_JOY_BUTTON_DPAD_RIGHT:
iControlDetailsIndex=14;
break;
case _360_JOY_BUTTON_DPAD_LEFT:
iControlDetailsIndex=15;
break;
}
hr=m_FigA[iControlDetailsIndex].SetShow(TRUE);
// position the control depending on the text width
if(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen())
{
// 480 mode - we need to scale the text positions
if(controlDetailsA[iControlDetailsIndex].iAlign==ALIGN_END)
{
vpos.x=(controlDetailsA[iControlDetailsIndex].vPos.x + 5.0f)* vScale.x;
}
else
{
vpos.x=(controlDetailsA[iControlDetailsIndex].vPos.x - 5.0f)* vScale.x - xuiRect.right;
}
vpos.y=(controlDetailsA[iControlDetailsIndex].vPos.y * vScale.y) - (xuiRect.bottom/2.0f);
}
else
{
if(controlDetailsA[iControlDetailsIndex].iAlign==ALIGN_END)
{
vpos.x=(controlDetailsA[iControlDetailsIndex].vPos.x + 5.0f);
}
else
{
vpos.x=(controlDetailsA[iControlDetailsIndex].vPos.x - 5.0f) - xuiRect.right;
}
vpos.y=(controlDetailsA[iControlDetailsIndex].vPos.y ) - (xuiRect.bottom/2.0f);
}
vpos.x=floor(vpos.x);
vpos.y=floor(vpos.y);
vpos.z=0.0f;
m_TextA[m_iCurrentTextIndex].SetPosition(&vpos);
m_TextA[m_iCurrentTextIndex].SetText(pwchText);
m_TextA[m_iCurrentTextIndex].SetShow(TRUE);
m_iCurrentTextIndex++;
}
void CScene_Controls::PositionTextDirect(int iPad,int iTextID, int iControlDetailsIndex, bool bShow)
{
// position the text depending on the control id
//int iTextWidth;
XUIRect xuiRect;
LPCWSTR pwchText;
D3DXVECTOR3 vpos,vScale;
HXUIOBJ hFigGroup;
if(bShow==false)
{
m_TextA[m_iCurrentTextIndex++].SetShow(FALSE);
return;
}
// get the visual of the fig group and use any scaling in it to adjust the text positions
XuiElementGetChildById(m_hObj,L"FigGroup",&hFigGroup);
XuiElementGetScale(hFigGroup,&vScale);
// check the width of the control with the text set in it
if(m_TextPresenterA[m_iCurrentTextIndex]==nullptr)
{
HXUIOBJ hObj=nullptr;
HRESULT hr=XuiControlGetVisual(m_TextA[m_iCurrentTextIndex].m_hObj,&hObj);
hr=XuiElementGetChildById(hObj,L"Text",&m_TextPresenterA[m_iCurrentTextIndex]);
}
pwchText=app.GetString(iTextID);
HRESULT hr=XuiTextPresenterMeasureText(m_TextPresenterA[m_iCurrentTextIndex], pwchText, &xuiRect);
m_TextA[m_iCurrentTextIndex].SetBounds(xuiRect.right,xuiRect.bottom);
hr=m_FigA[iControlDetailsIndex].SetShow(TRUE);
// position the control depending on the text width
if(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen())
{
// 480 mode - we need to scale the text positions
if(controlDetailsA[iControlDetailsIndex].iAlign==ALIGN_END)
{
vpos.x=(controlDetailsA[iControlDetailsIndex].vPos.x + 5.0f)* vScale.x;
}
else
{
vpos.x=(controlDetailsA[iControlDetailsIndex].vPos.x - 5.0f)* vScale.x - xuiRect.right;
}
vpos.y=(controlDetailsA[iControlDetailsIndex].vPos.y * vScale.y) - (xuiRect.bottom/2.0f);
}
else
{
if(controlDetailsA[iControlDetailsIndex].iAlign==ALIGN_END)
{
vpos.x=(controlDetailsA[iControlDetailsIndex].vPos.x + 5.0f);
}
else
{
vpos.x=(controlDetailsA[iControlDetailsIndex].vPos.x - 5.0f) - xuiRect.right;
}
vpos.y=(controlDetailsA[iControlDetailsIndex].vPos.y ) - (xuiRect.bottom/2.0f);
}
vpos.x=floor(vpos.x);
vpos.y=floor(vpos.y);
vpos.z=0.0f;
m_TextA[m_iCurrentTextIndex].SetPosition(&vpos);
m_TextA[m_iCurrentTextIndex].SetText(pwchText);
m_TextA[m_iCurrentTextIndex].SetShow(TRUE);
m_iCurrentTextIndex++;
}
HRESULT CScene_Controls::OnNotifySelChanged( HXUIOBJ hObjSource, XUINotifySelChanged* pNotifySelChangedData, BOOL& bHandled )
{
if( ( !m_bIgnoreNotifies )&&( hObjSource==m_pLayoutList->m_hObj ) )
{
m_iCurrentNavigatedControlsLayout=pNotifySelChangedData->iItem;
PositionAllText(m_iPad);
}
if(pNotifySelChangedData->iOldItem!=-1 && hObjSource==m_SchemeList )
{
CXuiSceneBase::PlayUISFX(eSFX_Focus);
}
return S_OK;
}
HRESULT CScene_Controls::OnNotifyPressEx(HXUIOBJ hObjPressed, XUINotifyPress* pNotifyPressData,BOOL& rfHandled)
{
// This assumes all buttons can only be pressed with the A button
ui.AnimateKeyPress(pNotifyPressData->UserIndex, VK_PAD_A);
// Handle check box changes.
if ( hObjPressed == m_InvertLook.m_hObj )
{
BOOL bIsChecked = m_InvertLook.IsChecked();
app.SetGameSettings(m_iPad,eGameSetting_ControlInvertLook,static_cast<unsigned char>(bIsChecked) );
}
else if ( hObjPressed == m_SouthPaw.m_hObj )
{
BOOL bIsChecked = m_SouthPaw.IsChecked();
app.SetGameSettings(m_iPad,eGameSetting_ControlSouthPaw,static_cast<unsigned char>(bIsChecked) );
PositionAllText(m_iPad);
}
else if( hObjPressed == m_SchemeList)
{
// check what's been selected
app.SetGameSettings(m_iPad,eGameSetting_ControlScheme,static_cast<unsigned char>(m_SchemeList.GetCurSel()));
LPWSTR layoutString = new wchar_t[ 128 ];
swprintf( layoutString, 128, L"%ls : %ls", app.GetString( IDS_CURRENT_LAYOUT ),app.GetString(m_iSchemeTextA[m_SchemeList.GetCurSel()]) );
XuiControlSetText(m_CurrentLayout,layoutString);
delete [] layoutString;
// and update the highlight on the current selection
for(int i=0;i<m_pLayoutList->GetItemCount();i++)
{
m_pLayoutList->SetBorder(i,FALSE);
}
m_pLayoutList->SetBorder(m_SchemeList.GetCurSel(),TRUE);
}
return S_OK;
}
HRESULT CScene_Controls::OnCustomMessage_Splitscreenplayer(bool bJoining, BOOL& bHandled)
{
bHandled=true;
return app.AdjustSplitscreenScene_PlayerChanged(m_hObj,&m_OriginalPosition,m_iPad,bJoining,32.0f);
}