#include "../../Minecraft.World/Platform/stdafx.h" #include #include "XUI_HelpControls.h" #include "XUI_Ctrl_4JList.h" #include "../../Minecraft.World/Headers/net.minecraft.world.level.h" #include "../../Minecraft.World/Level/LevelData.h" #include "../../Minecraft.Client/Player/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 = *(int*)pInitData->pvInitData; // if we're not in the game, we need to use basescene 0 bool bNotInGame = (Minecraft::GetInstance()->level == NULL); 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] = NULL; } // fill out the layouts list void* pObj; XuiObjectFromHandle(m_SchemeList, &pObj); m_pLayoutList = (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 = NULL; 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) != 0; m_InvertLook.SetCheck(bInvertLook); bool bSouthPaw = app.GetGameSettings(m_iPad, eGameSetting_ControlSouthPaw) != 0; 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] == NULL) { HXUIOBJ hObj = NULL; 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] == NULL) { HXUIOBJ hObj = NULL; 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() != FALSE; app.SetGameSettings(m_iPad, eGameSetting_ControlInvertLook, (unsigned char)(bIsChecked)); } else if (hObjPressed == m_SouthPaw.m_hObj) { bool bIsChecked = m_SouthPaw.IsChecked() != FALSE; app.SetGameSettings(m_iPad, eGameSetting_ControlSouthPaw, (unsigned char)(bIsChecked)); PositionAllText(m_iPad); } else if (hObjPressed == m_SchemeList) { // check what's been selected app.SetGameSettings(m_iPad, eGameSetting_ControlScheme, (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); }