diff --git a/Minecraft.Client/Common/Media/MediaWindows64.arc b/Minecraft.Client/Common/Media/MediaWindows64.arc index 3b0d2298..15806103 100644 Binary files a/Minecraft.Client/Common/Media/MediaWindows64.arc and b/Minecraft.Client/Common/Media/MediaWindows64.arc differ diff --git a/Minecraft.Client/Common/Media/SettingsGraphicsMenu1080.swf b/Minecraft.Client/Common/Media/SettingsGraphicsMenu1080.swf index cdf75cff..ec7bc5d5 100644 Binary files a/Minecraft.Client/Common/Media/SettingsGraphicsMenu1080.swf and b/Minecraft.Client/Common/Media/SettingsGraphicsMenu1080.swf differ diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp index d120fbea..83fee401 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_SettingsGraphicsMenu.cpp @@ -74,7 +74,7 @@ UIScene_SettingsGraphicsMenu::UIScene_SettingsGraphicsMenu(int iPad, void *initD WCHAR TempString[256]; swprintf(TempString, 256, L"Render Distance: %d",app.GetGameSettings(m_iPad,eGameSetting_RenderDistance)); - m_sliderRenderDistance.init(TempString,eControl_RenderDistance,0,5,DistanceToLevel(app.GetGameSettings(m_iPad,eGameSetting_RenderDistance))); + m_sliderRenderDistance.init(TempString,eControl_RenderDistance,0,3,DistanceToLevel(app.GetGameSettings(m_iPad,eGameSetting_RenderDistance))); swprintf( TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_GAMMA ),app.GetGameSettings(m_iPad,eGameSetting_Gamma)); m_sliderGamma.init(TempString,eControl_Gamma,0,100,app.GetGameSettings(m_iPad,eGameSetting_Gamma)); @@ -93,6 +93,24 @@ UIScene_SettingsGraphicsMenu::UIScene_SettingsGraphicsMenu(int iPad, void *initD // VSync and Exclusive Fullscreen are only available on PC removeControl(&m_checkboxVSync, true); removeControl(&m_checkboxExclusiveFullscreen, true); +#else + // The SWF's original focus chain skips VSync, Fullscreen, and RenderDistance + // (CustomSkinAnim -> Gamma). Rewire the navigation so all controls are reachable: + // CustomSkinAnim -> VSync -> Fullscreen -> RenderDistance -> Gamma + { + IggyName navDown = registerFastName(L"m_objNavDown"); + IggyName navUp = registerFastName(L"m_objNavUp"); + + IggyValueSetStringUTF8RS(m_checkboxCustomSkinAnim.getIggyValuePath(), navDown, nullptr, "VSync", -1); + + IggyValueSetStringUTF8RS(m_checkboxVSync.getIggyValuePath(), navUp, nullptr, "CustomSkinAnim", -1); + IggyValueSetStringUTF8RS(m_checkboxVSync.getIggyValuePath(), navDown, nullptr, "ExclusiveFullscreen", -1); + + IggyValueSetStringUTF8RS(m_checkboxExclusiveFullscreen.getIggyValuePath(), navUp, nullptr, "VSync", -1); + IggyValueSetStringUTF8RS(m_checkboxExclusiveFullscreen.getIggyValuePath(), navDown, nullptr, "RenderDistance", -1); + + IggyValueSetStringUTF8RS(m_sliderRenderDistance.getIggyValuePath(), navUp, nullptr, "ExclusiveFullscreen", -1); + } #endif const bool bInGame=(Minecraft::GetInstance()->level!=nullptr); diff --git a/README.md b/README.md index 9c753d5a..5e952532 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,12 @@ This project is based on source code of Minecraft Legacy Console Edition v1.6.05 ## Latest: +### Graphics Settings Menu Fixes + +- Fixed keyboard/gamepad navigation skipping VSync, Fullscreen, and Render Distance options. The SWF focus chain only linked the original console controls; added C++ post-init rewiring of `m_objNavDown`/`m_objNavUp` via Iggy so all controls are reachable +- Shifted the graphics menu layout up by 60 pixels for better vertical centering +- Fixed skin preview walking and attack animations running too fast with VSync off. The per-frame animation increments now scale by delta time relative to a 60fps baseline + ### Async Autosave (Dedicated Server) - Autosave no longer freezes the server. Previously, every autosave compressed the entire world save file with zlib synchronously on the main thread, blocking all game ticks for 2-6 seconds depending on world size diff --git a/tools/ShiftMenuY.java b/tools/ShiftMenuY.java new file mode 100644 index 00000000..d32e3f00 --- /dev/null +++ b/tools/ShiftMenuY.java @@ -0,0 +1,61 @@ +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; +import com.jpexs.decompiler.flash.types.MATRIX; +import java.io.*; + +/** + * Shifts a named PlaceObject element's Y position in a SWF. + * Usage: ShiftMenuY + * + * Positive offset = move down, negative = move up. + * SWF uses twips (1 pixel = 20 twips). + */ +public class ShiftMenuY { + public static void main(String[] args) throws Exception { + if (args.length < 3) { + System.out.println("Usage: ShiftMenuY [element_name]"); + System.out.println(" Shifts all elements (or a named element) by the given pixel offset."); + System.out.println(" Negative values move up, positive move down."); + return; + } + + String inputPath = args[0]; + String outputPath = args[1]; + int offsetPixels = Integer.parseInt(args[2]); + String targetName = args.length > 3 ? args[3] : null; + int offsetTwips = offsetPixels * 20; + + SWF swf = new SWF(new FileInputStream(inputPath), false); + + int modified = 0; + for (Tag tag : swf.getTags()) { + if (tag instanceof PlaceObjectTypeTag) { + PlaceObjectTypeTag po = (PlaceObjectTypeTag) tag; + String name = po.getInstanceName(); + if (targetName != null && !targetName.equals(name)) continue; + MATRIX matrix = po.getMatrix(); + if (matrix != null) { + int oldY = matrix.translateY; + matrix.translateY += offsetTwips; + System.out.printf(" %s: Y %d -> %d twips (%+d px)%n", + name != null ? name : "(unnamed)", + oldY, matrix.translateY, offsetPixels); + po.setModified(true); + modified++; + } + } + } + + if (modified == 0) { + System.out.println("No elements modified."); + return; + } + System.out.printf("Modified %d element(s) by %+d pixels%n", modified, offsetPixels); + + try (FileOutputStream fos = new FileOutputStream(outputPath)) { + swf.saveTo(fos); + } + System.out.println("Saved: " + outputPath); + } +}