diff --git a/Minecraft.Client/Platform/Common/UI/UIController.cpp b/Minecraft.Client/Platform/Common/UI/UIController.cpp index 05102f0f8..1ab74b80f 100644 --- a/Minecraft.Client/Platform/Common/UI/UIController.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIController.cpp @@ -1203,6 +1203,8 @@ void UIController::setupCustomDrawGameState() RenderManager.StartFrame(); #elif defined __PSVITA__ RenderManager.StartFrame(); +#elif defined __linux__ + RenderManager.StartFrame(); #elif defined __ORBIS__ RenderManager.StartFrame(false); // Set up a viewport for the render that matches Iggy's own viewport, apart form using an opengl-style z-range (Iggy uses a DX-style range on PS4), so diff --git a/Minecraft.Client/Platform/Common/UI/UIScene.cpp b/Minecraft.Client/Platform/Common/UI/UIScene.cpp index e6127c8e4..3b7b11046 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene.cpp @@ -283,7 +283,7 @@ void UIScene::loadMovie() #elif defined __PSVITA__ moviePath.append(L"Vita.swf"); m_loadedResolution = eSceneResolution_Vita; -#elif defined _WINDOWS64 || defined __linux__ +#elif defined _WINDOWS64 if(ui.getScreenHeight() == 720) { moviePath.append(L"720.swf"); @@ -994,8 +994,7 @@ bool UIScene::allowRepeat(int key) void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) { - if(wcscmp((wchar_t *)call->function_name.string,L"handlePress")==0) - { + if(std::char_traits::compare(call->function_name.string, u"handlePress", 12) == 0) { if(call->num_arguments != 2) { app.DebugPrintf("Callback for handlePress did not have the correct number of arguments\n"); @@ -1014,7 +1013,7 @@ void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) } handlePress(call->arguments[0].number, call->arguments[1].number); } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleFocusChange")==0) + else if(std::char_traits::compare(call->function_name.string, u"handleFocusChange", 18) == 0) { if(call->num_arguments != 2) { @@ -1034,7 +1033,7 @@ void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) } _handleFocusChange(call->arguments[0].number, call->arguments[1].number); } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleInitFocus")==0) + else if(std::char_traits::compare(call->function_name.string, u"handleInitFocus", 16) == 0) { if(call->num_arguments != 2) { @@ -1054,7 +1053,7 @@ void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) } _handleInitFocus(call->arguments[0].number, call->arguments[1].number); } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleCheckboxToggled")==0) + else if(std::char_traits::compare(call->function_name.string, u"handleCheckboxToggled", 22) == 0) { if(call->num_arguments != 2) { @@ -1074,7 +1073,7 @@ void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) } handleCheckboxToggled(call->arguments[0].number, call->arguments[1].boolval); } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleSliderMove")==0) + else if(std::char_traits::compare(call->function_name.string, u"handleSliderMove", 17) == 0) { if(call->num_arguments != 2) { @@ -1094,7 +1093,7 @@ void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) } handleSliderMove(call->arguments[0].number, call->arguments[1].number); } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleAnimationEnd")==0) + else if(std::char_traits::compare(call->function_name.string, u"handleAnimationEnd", 19) == 0) { if(call->num_arguments != 0) { @@ -1106,7 +1105,7 @@ void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) } handleAnimationEnd(); } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleSelectionChanged")==0) + else if(std::char_traits::compare(call->function_name.string, u"handleSelectionChanged", 23) == 0) { if(call->num_arguments != 1) { @@ -1126,7 +1125,7 @@ void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) } handleSelectionChanged(call->arguments[0].number); } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleRequestMoreData")==0) + else if(std::char_traits::compare(call->function_name.string, u"handleRequestMoreData", 22) == 0) { if(call->num_arguments == 0) { @@ -1153,7 +1152,7 @@ void UIScene::externalCallback(IggyExternalFunctionCallUTF16 * call) handleRequestMoreData(call->arguments[0].number, call->arguments[1].boolval); } } - else if(wcscmp((wchar_t *)call->function_name.string,L"handleTouchBoxRebuild")==0) + else if(std::char_traits::compare(call->function_name.string, u"handleTouchBoxRebuild", 22) == 0) { handleTouchBoxRebuild(); } @@ -1248,3 +1247,25 @@ bool UIScene::isReadyToDelete() { return true; } + +static int UIScene::parseSlotId(const char16_t *s) { + // must be nonnull, must start with 'slot_', first char after the underscore must be a digit + if (!s || + (s[0] != u's' || s[1] != u'l' || s[2] != u'o' || s[3] != u't' || + s[4] != u'_') || + (s[5] < u'0' || s[5] > u'9')) { + return -1; + } + + int i = 5; + int id = 0; + + // keep consuming digits until we reach a non-digit. each digit scales the existing id value + // by 10 plus the actual digit value. (this is referred to as a 'number' by the way) + while (s[i] >= u'0' && s[i] <= u'9') { + id = id * 10 + (s[i] - u'0'); + i++; + } + + return id; +} \ No newline at end of file diff --git a/Minecraft.Client/Platform/Common/UI/UIScene.h b/Minecraft.Client/Platform/Common/UI/UIScene.h index 315229390..a2e3a8f61 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene.h +++ b/Minecraft.Client/Platform/Common/UI/UIScene.h @@ -267,4 +267,6 @@ protected: size_t GetCallbackUniqueId(); virtual bool isReadyToDelete(); + + static int parseSlotId(const char16_t *s); }; diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_AbstractContainerMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_AbstractContainerMenu.cpp index 7757e135d..ce233bf4a 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_AbstractContainerMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_AbstractContainerMenu.cpp @@ -222,15 +222,14 @@ void UIScene_AbstractContainerMenu::customDraw(IggyCustomDrawCallbackRegion *reg if(pMinecraft->localplayers[m_iPad] == NULL || pMinecraft->localgameModes[m_iPad] == NULL) return; std::shared_ptr item = nullptr; - if(wcscmp((wchar_t *)region->name,L"pointerIcon")==0) + if(std::char_traits::compare(region->name, u"pointerIcon", 11) == 0) { m_cacheSlotRenders = false; item = pMinecraft->localplayers[m_iPad]->inventory->getCarried(); } else { - int slotId = -1; - swscanf((wchar_t*)region->name,L"slot_%d",&slotId); + int slotId = parseSlotId(region->name); if (slotId == -1) { app.DebugPrintf("This is not the control we are looking for\n"); diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_CraftingMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_CraftingMenu.cpp index ba5673bbf..a15900d9a 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_CraftingMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_CraftingMenu.cpp @@ -436,11 +436,10 @@ void UIScene_CraftingMenu::customDraw(IggyCustomDrawCallbackRegion *region) if(pMinecraft->localplayers[m_iPad] == NULL || pMinecraft->localgameModes[m_iPad] == NULL) return; std::shared_ptr item = nullptr; - int slotId = -1; float alpha = 1.0f; bool decorations = true; bool inventoryItem = false; - swscanf((wchar_t*)region->name,L"slot_%d",&slotId); + int slotId = parseSlotId(region->name); if (slotId == -1) { app.DebugPrintf("This is not the control we are looking for\n"); diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_DebugOverlay.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_DebugOverlay.cpp index e9fabdfac..3ff5cacb5 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_DebugOverlay.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_DebugOverlay.cpp @@ -120,6 +120,7 @@ void UIScene_DebugOverlay::customDraw(IggyCustomDrawCallbackRegion *region) if(pMinecraft->localplayers[m_iPad] == NULL || pMinecraft->localgameModes[m_iPad] == NULL) return; int itemId = -1; + // 4jcraft: TODO: UB on our platform since this casts char16_t* to wchar_t* swscanf((wchar_t*)region->name,L"item_%d",&itemId); if (itemId == -1 || itemId > Item::ITEM_NUM_COUNT || Item::items[itemId] == NULL) { diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_EnchantingMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_EnchantingMenu.cpp index 15734fa95..6d55dfba8 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_EnchantingMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_EnchantingMenu.cpp @@ -250,7 +250,7 @@ void UIScene_EnchantingMenu::customDraw(IggyCustomDrawCallbackRegion *region) if(pMinecraft->localplayers[m_iPad] == NULL || pMinecraft->localgameModes[m_iPad] == NULL) return; - if(wcscmp((wchar_t *)region->name,L"EnchantmentBook")==0) + if(std::char_traits::compare(region->name, u"EnchantmentBook", 15) == 0) { // Setup GDraw, normal game render states and matrices CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region); @@ -263,8 +263,7 @@ void UIScene_EnchantingMenu::customDraw(IggyCustomDrawCallbackRegion *region) } else { - int slotId = -1; - swscanf((wchar_t*)region->name,L"slot_Button%d",&slotId); + int slotId = parseSlotId(region->name); if(slotId >= 0) { // Setup GDraw, normal game render states and matrices diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_HUD.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_HUD.cpp index b1883b4ed..ff8f3b079 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_HUD.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_HUD.cpp @@ -182,8 +182,7 @@ void UIScene_HUD::customDraw(IggyCustomDrawCallbackRegion *region) Minecraft *pMinecraft = Minecraft::GetInstance(); if(pMinecraft->localplayers[m_iPad] == NULL || pMinecraft->localgameModes[m_iPad] == NULL) return; - int slot = -1; - swscanf((wchar_t*)region->name,L"slot_%d",&slot); + int slot = parseSlotId(region->name); if (slot == -1) { app.DebugPrintf("This is not the control we are looking for\n"); diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_InventoryMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_InventoryMenu.cpp index 7a94452fc..22378c97d 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_InventoryMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_InventoryMenu.cpp @@ -222,7 +222,7 @@ void UIScene_InventoryMenu::customDraw(IggyCustomDrawCallbackRegion *region) Minecraft *pMinecraft = Minecraft::GetInstance(); if(pMinecraft->localplayers[m_iPad] == NULL || pMinecraft->localgameModes[m_iPad] == NULL) return; - if(wcscmp((wchar_t *)region->name,L"player")==0) + if(std::char_traits::compare(region->name, u"player", 6) == 0) { // Setup GDraw, normal game render states and matrices CustomDrawData *customDrawRegion = ui.setupCustomDraw(this,region); diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_LeaderboardsMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_LeaderboardsMenu.cpp index 8bc4ab11b..77ec06275 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_LeaderboardsMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_LeaderboardsMenu.cpp @@ -961,11 +961,11 @@ int UIScene_LeaderboardsMenu::SetLeaderboardTitleIcons() void UIScene_LeaderboardsMenu::customDraw(IggyCustomDrawCallbackRegion *region) { - int slotId = -1; - swscanf((wchar_t*)region->name,L"slot_%d",&slotId); + int slotId = parseSlotId(region->name); if (slotId == -1) { - //app.DebugPrintf("This is not the control we are looking for\n"); + //assert(0); +app.DebugPrintf("This is not the control we are looking for\n"); } else { diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp index 207dc28a5..7c0575186 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp @@ -424,7 +424,7 @@ void UIScene_MainMenu::RunAction(int iPad) void UIScene_MainMenu::customDraw(IggyCustomDrawCallbackRegion *region) { - if(wcscmp((wchar_t *)region->name,L"Splash")==0) + if(std::char_traits::compare(region->name, u"Splash", 6) == 0) { PIXBeginNamedEvent(0,"Custom draw splash"); customDrawSplash(region); diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_TradingMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_TradingMenu.cpp index 619a22bf3..c4ea9e469 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_TradingMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_TradingMenu.cpp @@ -148,8 +148,7 @@ void UIScene_TradingMenu::customDraw(IggyCustomDrawCallbackRegion *region) if(pMinecraft->localplayers[m_iPad] == NULL || pMinecraft->localgameModes[m_iPad] == NULL) return; std::shared_ptr item = nullptr; - int slotId = -1; - swscanf((wchar_t*)region->name,L"slot_%d",&slotId); + int slotId = parseSlotId(region->name); if(slotId < MerchantMenu::USE_ROW_SLOT_END) {