32 Commits
Author SHA1 Message Date
str1k3r 9dc7353939 push something i forgot on my macbook for a month 2026-06-28 14:44:19 -04:00
Byte 3e8284ace8 fix: Minecraft Store 1; feat: Community-Made Packs integration 2026-06-25 23:04:35 +02:00
Byte e7a44db374 fix: achievements crashes 2026-06-24 22:27:22 +02:00
Byte 028dcdce41 feat: achievements, minecraft store, languages, auto lb sendStats, more Language Strings 2026-06-23 20:40:27 +02:00
Byte 658849b427 add the shitty lcen code 2026-06-22 07:25:49 +02:00
str1k3r 8a6d21779d Fix Sending Auth Token Over Header & Update Leaderboard 2026-06-20 03:01:29 -04:00
str1k3r a9e98d3c03 Send Token Over Header 2026-06-19 20:23:13 -04:00
str1k3r 7f72bf5549 Fix Not Building 2026-06-18 14:35:11 -04:00
str1k3r 584d2a517f Feat: Add Leaderboard 2026-06-18 05:50:13 -04:00
str1k3r 525c5170b9 Give WinsockNetLayer::DoWinHttpRequest a url instead of it just being 1 2026-06-15 22:38:00 -04:00
str1k3r fc93ed09bf Fix Strings 2026-06-06 13:22:21 -04:00
str1k3r eec0e6bdc4 Update: Modify submodule URL for 4JLibs and add .idea to .gitignore 2026-06-05 11:58:50 -04:00
str1k3r 39cb8cbc54 Fix: Game not launching with launcher 2026-06-03 11:03:07 -04:00
str1k3r e44a98b518 Update to new Paths 2026-06-02 13:46:50 -04:00
str1k3r 0002344ea3 Remove RapidJson 2026-05-28 01:18:46 -04:00
str1k3r 9795b96e8f Feat: Allow Launching from launchers 2026-05-27 08:21:56 -04:00
str1k3r 77b5b16de4 Fix: Splitscreen for proper backend detection 2026-05-25 05:04:04 -04:00
str1k3r ed0823fe95 Fix: add the discordgamesdk dll to fix the newest build 😭 2026-05-22 03:02:32 -04:00
str1k3r 62fdc45d3f Feat: update to Game SDK, add Discord Login
This is honestly shitty code that works imo
2026-05-21 23:11:34 -04:00
str1k3r 02f1e14855 Remove Critical Hit Sound to Be Accurate to TU19/24 2026-05-13 06:36:55 -04:00
str1k3r d6232544ca Remove Stained Glass, Sword of Debug & Updated PORTING.md
Remove stained glass as its not accurate to TU19 up to TU24, Update PORTING.md to include versions we are trying to achieve & Remove the sword of debug as it was a debug item thats not needed.
2026-05-13 05:49:50 -04:00
str1k3randGitHub fb83868d25 Update server release tags link in README 2026-05-13 02:35:52 -04:00
str1k3r e3056038b9 Add Banner to Readme 2026-05-13 02:31:27 -04:00
str1k3r 80bc1e74d8 Update COMPILE.md & CONTRIBUTING.md 2026-05-13 02:24:43 -04:00
str1k3r 0fc8b1ef44 fix README.md 2026-05-13 02:20:21 -04:00
str1k3r 5f79f00dd2 Add all .md files needed 2026-05-13 02:16:10 -04:00
str1k3randGitHub 568e5a5a7f Change trigger branch from 'main' to 'TU19' 2026-05-13 01:17:01 -04:00
str1k3r 590556ae49 Move all settings to Windows64/Settings & Ensure the folder exists 2026-05-13 01:11:43 -04:00
str1k3randGitHub e0c09e7afb Update TU31.yml 2026-05-12 22:59:48 -04:00
str1k3randGitHub 84a59834a7 Add nightly release workflow for TU31 2026-05-12 22:58:49 -04:00
str1k3r 70086d3b28 New Repo Initial Commit
Add Discord RPC back with new features, add beta splitscreen support,

PR's from MCLCE used in this
https://github.com/MCLCE/MinecraftConsoles/pull/1044
https://github.com/MCLCE/MinecraftConsoles/pull/1136
https://github.com/MCLCE/MinecraftConsoles/pull/1245
2026-05-12 20:57:36 -04:00
str1k3randGitHub cbe40abcdb Initial commit 2026-05-12 20:34:42 -04:00
842 changed files with 115927 additions and 169223 deletions
-3
View File
@@ -1,3 +0,0 @@
.github/workflows/docker-nightly.yml merge=ours
.github/workflows/nightly.yml merge=ours
docker-compose.dedicated-server.ghcr.yml merge=ours
Binary file not shown.

Before

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 952 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 646 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 778 KiB

+107
View File
@@ -0,0 +1,107 @@
name: TU31 Release
on:
workflow_dispatch:
push:
branches:
- 'TU31'
paths:
- '**'
- '!.gitignore'
- '!*.md'
- '!.github/**'
- '.github/workflows/nightly.yml'
permissions:
contents: write
concurrency:
group: TU31
cancel-in-progress: true
jobs:
build:
runs-on: windows-latest
strategy:
matrix:
platform: [Windows64]
steps:
- name: Checkout
uses: actions/checkout@v6
with:
submodules: recursive
- name: Set platform lowercase
run: echo "MATRIX_PLATFORM=$('${{ matrix.platform }}'.ToLower())" >> $env:GITHUB_ENV
- name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1
- name: Setup CMake
uses: lukka/get-cmake@latest
- name: Run CMake
uses: lukka/run-cmake@v10
env:
VCPKG_ROOT: "" # Disable vcpkg for CI builds
with:
configurePreset: ${{ env.MATRIX_PLATFORM }}
buildPreset: ${{ env.MATRIX_PLATFORM }}-release
buildPresetAdditionalArgs: "['--target', 'Minecraft.Client']"
- name: Zip Build
run: 7z a -r LCE${{ matrix.platform }}.zip ./build/${{ env.MATRIX_PLATFORM }}/Minecraft.Client/Release/* "-x!*.ipdb" "-x!*.iobj"
- name: Stage artifacts
run: |
New-Item -ItemType Directory -Force -Path staging
Copy-Item LCE${{ matrix.platform }}.zip staging/
- name: Stage exe and pdb
if: matrix.platform == 'Windows64'
run: |
Copy-Item ./build/${{ env.MATRIX_PLATFORM }}/Minecraft.Client/Release/Minecraft.Client.exe staging/
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
name: build-${{ matrix.platform }}
path: staging/*
release:
needs: build
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v7
with:
path: artifacts
merge-multiple: true
- name: Update release
uses: andelf/nightly-release@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: TU31
name: Nightly Client Release
body: |
Requires at least Windows 7 and DirectX 11 compatible GPU to run.
# 🚨 First time here? 🚨
If you've never downloaded the game before, you need to download `LCEWindows64.zip` and extract it to the folder where you'd like to keep the game. The other files are included in this `.zip` file!
files: |
artifacts/*
cleanup:
needs: [build, release]
if: always()
runs-on: ubuntu-latest
steps:
- name: Cleanup artifacts
uses: geekyeggo/delete-artifact@v5
with:
name: build-*
+60 -166
View File
@@ -2,212 +2,106 @@ name: Nightly Release
on: on:
workflow_dispatch: workflow_dispatch:
push:
branches:
- 'TU19'
paths:
- '**'
- '!.gitignore'
- '!*.md'
- '!.github/**'
- '.github/workflows/nightly.yml'
permissions: permissions:
contents: write contents: write
id-token: write
attestations: write
packages: write
concurrency: concurrency:
group: nightly group: nightly
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
build-client: build:
name: Build Client runs-on: windows-latest
runs-on: [self-hosted, windows]
strategy:
matrix:
platform: [Windows64]
steps: steps:
- name: Checkout - name: Checkout
uses: https://github.com/actions/checkout@v6 uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
- name: Set platform lowercase
run: echo "MATRIX_PLATFORM=$('${{ matrix.platform }}'.ToLower())" >> $env:GITHUB_ENV
- name: Setup MSVC - name: Setup MSVC
uses: https://github.com/ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
- name: Setup CMake - name: Setup CMake
uses: https://github.com/lukka/get-cmake@latest uses: lukka/get-cmake@latest
- name: Run CMake - name: Run CMake
uses: https://github.com/lukka/run-cmake@v10 uses: lukka/run-cmake@v10
env: env:
VCPKG_ROOT: "" VCPKG_ROOT: "" # Disable vcpkg for CI builds
with: with:
configurePreset: windows64 configurePreset: ${{ env.MATRIX_PLATFORM }}
buildPreset: windows64-release buildPreset: ${{ env.MATRIX_PLATFORM }}-release
buildPresetAdditionalArgs: "['--target', 'Minecraft.Client']" buildPresetAdditionalArgs: "['--target', 'Minecraft.Client']"
- name: Zip Build - name: Zip Build
shell: pwsh run: 7z a -r LCE${{ matrix.platform }}.zip ./build/${{ env.MATRIX_PLATFORM }}/Minecraft.Client/Release/* "-x!*.ipdb" "-x!*.iobj"
run: |
$source = "./build/windows64/Minecraft.Client/Release"
$zip = "LCE-Online-Client-Win64.zip"
$topLevel = "LCE-Online-Client-Win64"
$files = Get-ChildItem -Path $source -Recurse -File |
Where-Object { $_.Extension -notin '.pch', '.pdb', '.zip', '.ipdb', '.iobj', '.exp', '.lib' }
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
$basePath = (Resolve-Path $source).Path
$fs = [System.IO.File]::Open($zip, [System.IO.FileMode]::Create)
try {
$archive = New-Object System.IO.Compression.ZipArchive($fs, [System.IO.Compression.ZipArchiveMode]::Create)
try {
Get-ChildItem -Path $basePath -Recurse -Directory | ForEach-Object {
$rel = $_.FullName.Substring($basePath.Length).TrimStart('\', '/')
$archive.CreateEntry("$topLevel/$($rel -replace '\\','/')/") | Out-Null
}
foreach ($file in $files) {
$rel = $file.FullName.Substring($basePath.Length).TrimStart('\', '/')
$entryName = "$topLevel/$($rel -replace '\\','/')"
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile(
$archive, $file.FullName, $entryName,
[System.IO.Compression.CompressionLevel]::Optimal
) | Out-Null
}
} finally { $archive.Dispose() }
} finally { $fs.Dispose() }
Write-Host "Created $zip"
- name: Stage artifacts - name: Stage artifacts
shell: pwsh
run: | run: |
New-Item -ItemType Directory -Force -Path staging New-Item -ItemType Directory -Force -Path staging
Copy-Item LCE-Online-Client-Win64.zip staging/ Copy-Item LCE${{ matrix.platform }}.zip staging/
Copy-Item ./build/windows64/Minecraft.Client/Release/Minecraft.Client.exe staging/
Copy-Item ./build/windows64/Minecraft.Client/Release/Minecraft.Client.pdb staging/ - name: Stage exe and pdb
if: matrix.platform == 'Windows64'
run: |
Copy-Item ./build/${{ env.MATRIX_PLATFORM }}/Minecraft.Client/Release/Minecraft.Client.exe staging/
- name: Upload artifacts - name: Upload artifacts
uses: https://github.com/actions/upload-artifact@v3 uses: actions/upload-artifact@v6
with: with:
name: client-build name: build-${{ matrix.platform }}
path: staging/* path: staging/*
release-client: release:
name: Release Client needs: build
needs: build-client runs-on: ubuntu-latest
runs-on: [self-hosted, linux]
steps: steps:
- name: Checkout - name: Download all artifacts
uses: https://github.com/actions/checkout@v6 uses: actions/download-artifact@v7
- name: Download client artifacts
uses: https://github.com/actions/download-artifact@v3
with: with:
name: client-build
path: artifacts path: artifacts
merge-multiple: true
- name: Install jq - name: Update release
run: apt-get update && apt-get install -y --no-install-recommends jq uses: andelf/nightly-release@main
- name: Get short SHA
id: sha
run: echo "short=$(echo '${{ github.sha }}' | cut -c1-7)" >> "$GITHUB_OUTPUT"
- name: Delete old release and tag
env: env:
FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
TAG="Nightly"
API="${{ github.server_url }}/api/v1/repos/${{ github.repository }}"
AUTH="Authorization: token $FORGEJO_TOKEN"
EXISTING_ID=$(curl -sf -H "$AUTH" "$API/releases/tags/$TAG" 2>/dev/null | jq -r '.id // empty' || true)
if [ -n "$EXISTING_ID" ]; then
curl -sf -X DELETE -H "$AUTH" "$API/releases/$EXISTING_ID"
fi
curl -s -X DELETE -H "$AUTH" "$API/tags/$TAG" > /dev/null || true
- name: Import GPG key
uses: https://github.com/crazy-max/ghaction-import-gpg@v6
with: with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} tag_name: nightly
passphrase: ${{ secrets.GPG_PASSPHRASE }} name: Nightly Client Release
git_user_signingkey: true body: |
git_tag_gpgsign: true Requires at least Windows 7 and DirectX 11 compatible GPU to run.
- name: Create signed tag # 🚨 First time here? 🚨
run: | If you've never downloaded the game before, you need to download `LCEWindows64.zip` and extract it to the folder where you'd like to keep the game. The other files are included in this `.zip` file!
git tag -s -f Nightly -m "Nightly release ${{ steps.sha.outputs.short }}" files: |
git push origin Nightly --force artifacts/*
- name: Write release notes cleanup:
run: | needs: [build, release]
cat > notes.md <<'NOTES' if: always()
# Instructions: runs-on: ubuntu-latest
**Newcomers:** steps:
- If this is your first time, download `LCE-Online-Client-Win64.zip` and extract it wherever you would like to keep it. - name: Cleanup artifacts
- I would recommend to set your username prior to launch (create a file called `username.txt`, put your desired username into the file, and save). uses: geekyeggo/delete-artifact@v5
- To play, simply run `Minecraft.Client.exe`. with:
name: build-*
**For those that wish to update their existing installation with the latest build:**
- Download `Minecraft.Client.exe` and copy it over to your existing LCE-Online-Client-Win64 build (overwrite your old version of Minecraft.Client.exe).
**For developers:**
- `Minecraft.Client.pdb` contains debug symbols for crash analysis and development. Place it next to `Minecraft.Client.exe` for stack traces to show function names and line numbers.
**Steam Deck & Linux:**
- Y'all know the drill. Download the `LCE-Online-Client-Win64.zip`, extract it, add the `Minecraft.Client.exe` as a "Non-Steam Game" within the Steam library, turn on compatibility mode with Proton Experimental, and then run it!
# Multiplayer instructions:
LAN games are natively supported, and any LAN games will appear automatically on the right. However, if you'd like to play with your friends online (and if you don't want to require them to setup a vpn, and/or if you don't want to port forward), I would recommend the following setup. Please keep in mind, you do NOT need to do this to enjoy the game. This is just how I have it setup for me so my friends can join without any hassle:
Prerequisites:
- Premium playit.gg account, costs about $3 USD per month. This is for setting up the tunnel.
- playit.gg agent installed on host PC.
How-to:
- Ensure your playit.gg agent is connected to your playit.gg account
- On the playit.gg website, setup a new tunnel (choose TCP). Ensure the configurable settings are set to the below values, assuming your agent is installed on the same computer as your LCE Online game is hosted from.
- Configurable settings:
- Local IP: `127.0.0.1`
- Local Port: `25565`
- Proxy Protocol: `None`
- After creating your tunnel, navigate to the "Tunnels" main page. You'll see the IP address and port for your tunnel. This is what your friends will input when adding your server in order to join your online game!
NOTES
- name: Create release on Forgejo
env:
FORGEJO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
TAG="Nightly"
TITLE="Client: ${{ steps.sha.outputs.short }}"
API="${{ github.server_url }}/api/v1/repos/${{ github.repository }}"
AUTH="Authorization: token $FORGEJO_TOKEN"
BODY=$(cat notes.md)
PAYLOAD=$(jq -nc --arg tag "$TAG" --arg name "$TITLE" --arg body "$BODY" \
'{tag_name:$tag, name:$name, body:$body, draft:false, prerelease:false}')
RID=$(curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
-d "$PAYLOAD" "$API/releases" | jq -r '.id')
if [ -z "$RID" ] || [ "$RID" = "null" ]; then
echo "Failed to create release" >&2
exit 1
fi
echo "Created release id=$RID"
for asset in artifacts/*; do
name=$(basename "$asset")
size=$(stat -c%s "$asset")
echo "Uploading $name ($size bytes)"
HTTP=$(curl -sS -w '%{http_code}' -o /tmp/upload-resp -X POST -H "$AUTH" \
-F "attachment=@$asset" \
"$API/releases/$RID/assets?name=$name")
if [ "$HTTP" -lt 200 ] || [ "$HTTP" -ge 300 ]; then
echo "Upload failed: HTTP $HTTP" >&2
echo "--- response body ---" >&2
cat /tmp/upload-resp >&2 || true
echo "" >&2
exit 1
fi
echo "Uploaded $name OK (HTTP $HTTP)"
done
+11 -14
View File
@@ -4,34 +4,31 @@ on:
workflow_dispatch: workflow_dispatch:
pull_request: pull_request:
types: [opened, reopened, synchronize] types: [opened, reopened, synchronize]
paths-ignore: paths:
- '.gitignore' - '**'
- '*.md' - '!.gitignore'
- '.github/*.md' - '!*.md'
- '!.github/**'
- '.github/workflows/pull-request.yml'
jobs: jobs:
build: build:
runs-on: [self-hosted, windows] runs-on: windows-latest
steps: steps:
- name: Checkout - name: Checkout
uses: https://github.com/actions/checkout@v6 uses: actions/checkout@v6
with: with:
submodules: recursive submodules: recursive
- name: Setup MSVC - name: Setup MSVC
uses: https://github.com/ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
- name: Setup CMake - name: Setup CMake
uses: https://github.com/lukka/get-cmake@latest uses: lukka/get-cmake@latest
- name: Setup .NET
uses: https://github.com/actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Run CMake - name: Run CMake
uses: https://github.com/lukka/run-cmake@v10 uses: lukka/run-cmake@v10
env: env:
VCPKG_ROOT: "" # Disable vcpkg for CI builds VCPKG_ROOT: "" # Disable vcpkg for CI builds
with: with:
+1 -9
View File
@@ -26,7 +26,6 @@ mono_crash.*
[Rr]elease/ [Rr]elease/
[Rr]eleases/ [Rr]eleases/
x64/ x64/
x64_*/
x86/ x86/
[Ww][Ii][Nn]32/ [Ww][Ii][Nn]32/
[Aa][Rr][Mm]/ [Aa][Rr][Mm]/
@@ -416,19 +415,12 @@ tmp*/
_server_asset_probe/ _server_asset_probe/
server-data/ server-data/
# Tools build artifacts and intermediates
tools/*.class
tools/*.swf
tools/staging/
tools/server-monitor/
# Nix # Nix
result result
result-* result-*
.direnv/ .direnv/
.xwin-cache/ .xwin-cache/
.xwin/
# macOS # macOS
.DS_Store .DS_Store
/.idea
+1 -1
View File
@@ -1,3 +1,3 @@
[submodule "Minecraft.Client/Windows64/4JLibs"] [submodule "Minecraft.Client/Windows64/4JLibs"]
path = Minecraft.Client/Windows64/4JLibs path = Minecraft.Client/Windows64/4JLibs
url = https://github.com/itsRevela/4JLibs.git url = https://gitea.str1k3r.xyz/str1k3r/4JLibs.git
-116
View File
@@ -1,116 +0,0 @@
{
"search.exclude": {
"**/Minecraft.Client/Common/DummyTexturePack/res": true,
"**/Minecraft.Client/Common/Media": true,
"**/Minecraft.Client/Common/res": true,
"**/Minecraft.Client/Common/Trial": true,
"**/Minecraft.Client/Durango/4JLibs/libs": true,
"**/Minecraft.Client/Durango/CU": true,
"**/Minecraft.Client/Durango/DLCImages": true,
"**/Minecraft.Client/Durango/DurangoExtras/xcompress.dll": true,
"**/Minecraft.Client/Durango/DurangoExtras/xcompress.lib": true,
"**/Minecraft.Client/Durango/Iggy/lib": true,
"**/Minecraft.Client/Durango/Layout": true,
"**/Minecraft.Client/Durango/Miles/lib": true,
"**/Minecraft.Client/Durango/Network/Windows.Xbox.Networking.RealtimeSession.dll": true,
"**/Minecraft.Client/Durango/Network/windows.xbox.networking.realtimesession.pdb": true,
"**/Minecraft.Client/Durango/Network/windows.xbox.networking.realtimesession.winmd": true,
"**/Minecraft.Client/Durango/ServiceConfig": true,
"**/Minecraft.Client/Durango/Sound": true,
"**/Minecraft.Client/Durango/DLCXbox1.cmp": true,
"**/Minecraft.Client/Durango/*.png": true,
"**/Minecraft.Client/DurangoMedia/DLC": true,
"**/Minecraft.Client/DurangoMedia/Layout": true,
"**/Minecraft.Client/DurangoMedia/loc": true,
"**/Minecraft.Client/DurangoMedia/loc/strings.h": false,
"**/Minecraft.Client/DurangoMedia/Media": true,
"**/Minecraft.Client/DurangoMedia/Sound": true,
"**/Minecraft.Client/music": true,
"**/Minecraft.Client/Orbis/4JLibs/Libs": true,
"**/Minecraft.Client/Orbis/DLCImages": true,
"**/Minecraft.Client/Orbis/GameConfig": true,
"**/Minecraft.Client/Orbis/GameConfig/Minecraft.spa.h": false,
"**/Minecraft.Client/Orbis/Iggy/lib": true,
"**/Minecraft.Client/Orbis/Miles/lib": true,
"**/Minecraft.Client/Orbis/min/min.sig": true,
"**/Minecraft.Client/Orbis/min/pronunciation.sig": true,
"**/Minecraft.Client/Orbis/MinecraftPronunciation/MinecraftPronunciation.sig": true,
"**/Minecraft.Client/Orbis/MinecraftPronunciation/pronunciation.sig": true,
"**/Minecraft.Client/Orbis/PS4ProductCodes.bin": true,
"**/Minecraft.Client/Orbis/session_image.jpg": true,
"**/Minecraft.Client/Orbis/session_image.png": true,
"**/Minecraft.Client/OrbisMedia/DLC": true,
"**/Minecraft.Client/OrbisMedia/loc": true,
"**/Minecraft.Client/OrbisMedia/loc/strings.h": false,
"**/Minecraft.Client/OrbisMedia/Media": true,
"**/Minecraft.Client/PS3/4JLibs/libs": true,
"**/Minecraft.Client/PS3/DATA": true,
"**/Minecraft.Client/PS3/Edge": true,
"**/Minecraft.Client/PS3/GameConfig/MinecraftIcon.png": true,
"**/Minecraft.Client/PS3/GameConfig/set.png": true,
"**/Minecraft.Client/PS3/Iggy/lib": true,
"**/Minecraft.Client/PS3/Media": true,
"**/Minecraft.Client/PS3/Media/*.h": true,
"**/Minecraft.Client/PS3/Miles/lib": true,
"**/Minecraft.Client/PS3/Sound": true,
"**/Minecraft.Client/PS3/SPU_Tasks/*.o": true,
"**/Minecraft.Client/PS3/SPU_Tasks/mssspurs.elf": true,
"**/Minecraft.Client/PS3/PS3ProductCodes.bin": true,
"**/Minecraft.Client/PS3_GAME": true,
"**/Minecraft.Client/PS3Media/DLC": true,
"**/Minecraft.Client/PS3Media/loc": true,
"**/Minecraft.Client/PS3Media/Media": true,
"**/Minecraft.Client/PS4_GAME": true,
"**/Minecraft.Client/PSVita/4JLibs/libs": true,
"**/Minecraft.Client/PSVita/app": true,
"**/Minecraft.Client/PSVita/Builds": true,
"**/Minecraft.Client/PSVita/GameConfig": true,
"**/Minecraft.Client/PSVita/GameConfig/Minecraft.spa.h": false,
"**/Minecraft.Client/PSVita/Iggy/lib": true,
"**/Minecraft.Client/PSVita/Miles/lib": true,
"**/Minecraft.Client/PSVita/Sound": true,
"**/Minecraft.Client/PSVita/Tutorial": true,
"**/Minecraft.Client/PSVita/configuration.psp2path": true,
"**/Minecraft.Client/PSVita/PSVitaProductCodes.bin": true,
"**/Minecraft.Client/PSVita/session_image.png": true,
"**/Minecraft.Client/PSVitaMedia/DLC": true,
"**/Minecraft.Client/PSVitaMedia/loc": true,
"**/Minecraft.Client/PSVitaMedia/Media": true,
"**/Minecraft.Client/PSVitaMedia/Tutorial": true,
"**/Minecraft.Client/PSVitaMedia/Minecraft.Client.self": true,
"**/Minecraft.Client/redist64": true
"**/Minecraft.Client/sce_sys": true
"**/Minecraft.Client/TROPDIR": true
"**/Minecraft.Client/Windows64/4JLibs/libs": true,
"**/Minecraft.Client/Windows64/GameConfig/Minecraft.spa": true,
"**/Minecraft.Client/Windows64/GameHDD": true,
"**/Minecraft.Client/Windows64/Iggy/lib": true,
"**/Minecraft.Client/Windows64Media": true,
"**/Minecraft.Client/Windows64Media/4J_strings.h": false,
"**/Minecraft.Client/Windows64Media/strings.h": false,
"**/Minecraft.Client/x64": true,
"**/Minecraft.Client/Xbox/4JLibs/libs": true,
"**/Minecraft.Client/Xbox/4JLibs/Media": true,
"**/Minecraft.Client/Xbox/Cheats": true,
"**/Minecraft.Client/Xbox/ContentPackageBuild": true,
"**/Minecraft.Client/Xbox/Docs": true,
"**/Minecraft.Client/Xbox/GameConfig": true,
"**/Minecraft.Client/Xbox/GameConfig/Minecraft.spa.h": false,
"**/Minecraft.Client/Xbox/kinect": true,
"**/Minecraft.Client/Xbox/loc": true,
"**/Minecraft.Client/Xbox/ReleaseBuild": true,
"**/Minecraft.Client/Xbox/SubmissionBuild": true,
"**/Minecraft.Client/Xbox/Title Update": true,
"**/Minecraft.Client/Xbox/TMSFiles": true,
"**/Minecraft.Client/Xbox/MinecraftWindows.ico": true,
"**/Minecraft.Client/Xbox/small.ico": true,
"**/Minecraft.Client/alphaTest.png": true,
"**/Minecraft.Client/thumbnailTest64.png": true,
"**/Minecraft.Client/thumbnailTest128.png": true,
"**/Minecraft.Client/thumbnailTest256.png": true,
"**/Minecraft.Client/thumbnailTest1028.png": true,
"**/Minecraft.World/x64_Debug": true,
"**/Minecraft.World/x64_Release": true
"**/x64": true
}
}
+5 -16
View File
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.24) cmake_minimum_required(VERSION 3.24)
project(LCE-Revelations LANGUAGES C CXX RC ASM_MASM) project(MinecraftConsoles LANGUAGES C CXX RC ASM_MASM)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
@@ -12,6 +12,7 @@ endif()
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
message(FATAL_ERROR "Use a 64-bit generator/toolchain (x64).") message(FATAL_ERROR "Use a 64-bit generator/toolchain (x64).")
endif() endif()
set(CMAKE_CONFIGURATION_TYPES set(CMAKE_CONFIGURATION_TYPES
"Debug" "Debug"
"Release" "Release"
@@ -20,7 +21,7 @@ set(CMAKE_CONFIGURATION_TYPES
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
function(configure_compiler_target target) function(configure_compiler_target target)
# MSVC and compatible compilers (like Clang-cl) ! # MSVC and compatible compilers (like Clang-cl)
if (MSVC) if (MSVC)
target_compile_options(${target} PRIVATE target_compile_options(${target} PRIVATE
$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:C,CXX>>:/W3> $<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:C,CXX>>:/W3>
@@ -38,10 +39,10 @@ function(configure_compiler_target target)
# MSVC # MSVC
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options(${target} PRIVATE target_compile_options(${target} PRIVATE
$<$<AND:$<CONFIG:Release>,$<COMPILE_LANGUAGE:C,CXX>>:/GL /Zi> $<$<AND:$<CONFIG:Release>,$<COMPILE_LANGUAGE:C,CXX>>:/GL>
) )
target_link_options(${target} PRIVATE target_link_options(${target} PRIVATE
$<$<CONFIG:Release>:/LTCG:incremental /DEBUG /OPT:REF /OPT:ICF> $<$<CONFIG:Release>:/LTCG:incremental>
) )
endif() endif()
@@ -67,14 +68,9 @@ set(MINECRAFT_SHARED_DEFINES
$<$<CONFIG:Debug>:_DEBUG> $<$<CONFIG:Debug>:_DEBUG>
_CRT_NON_CONFORMING_SWPRINTFS _CRT_NON_CONFORMING_SWPRINTFS
_CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_WARNINGS
_HAS_STD_BYTE=0
) )
# Add platform-specific defines # Add platform-specific defines
if(PLATFORM_NAME STREQUAL "Windows64")
list(APPEND MINECRAFT_SHARED_DEFINES _WINDOWS64)
set(IGGY_LIBS iggy_w64.lib)
endif()
list(APPEND MINECRAFT_SHARED_DEFINES ${PLATFORM_DEFINES}) list(APPEND MINECRAFT_SHARED_DEFINES ${PLATFORM_DEFINES})
# --- # ---
@@ -84,10 +80,6 @@ add_subdirectory("Minecraft.Client/${PLATFORM_NAME}/4JLibs")
add_subdirectory(Minecraft.World) add_subdirectory(Minecraft.World)
add_subdirectory(Minecraft.Client) add_subdirectory(Minecraft.Client)
if(PLATFORM_NAME STREQUAL "Windows64") # Server is only supported on Windows for now
add_subdirectory(Minecraft.Server.FourKit)
add_subdirectory(Minecraft.Server)
endif()
# --- # ---
# Build versioning # Build versioning
@@ -105,9 +97,6 @@ add_custom_target(GenerateBuildVer
add_dependencies(Minecraft.World GenerateBuildVer) add_dependencies(Minecraft.World GenerateBuildVer)
add_dependencies(Minecraft.Client GenerateBuildVer) add_dependencies(Minecraft.Client GenerateBuildVer)
if(PLATFORM_NAME STREQUAL "Windows64")
add_dependencies(Minecraft.Server GenerateBuildVer)
endif()
# --- # ---
# Project organisation # Project organisation
+61 -121
View File
@@ -1,59 +1,14 @@
# Compile Instructions # Compile Instructions
## Prerequisites ## Visual Studio
- **Visual Studio 2022** with the **Desktop development with C++** workload (this includes the CMake tools, MSVC toolchain, and Windows 10 SDK). 1. Clone the repo, including submodules.
- **.NET 10 SDK**, required to build the FourKit plugin host (`Minecraft.Server.FourKit`). - If you don't, the build will fail. `git clone --recurse-submodules https://github.com/mclemp/MCLEClient.git`
- Download: https://dotnet.microsoft.com/download/dotnet/10.0 (pick the **x64 SDK** installer) 2. Open the repo folder in Visual Studio 2022+.
- The exact SDK version is pinned in `global.json` at the repo root. 3. Wait for cmake to configure the project and load all assets (this may take a few minutes on the first run).
- CMake will fail configure with a clear error message if .NET 10 is not installed, so you find out immediately rather than partway through a build. 4. Right click a folder in the solution explorer and switch to the 'CMake Targets View'
- The build invokes `dotnet publish ... --runtime win-x64 --self-contained true`, so the published output bundles a complete .NET 10 runtime alongside the FourKit assembly. End users running the produced server do **not** need to install .NET themselves. 5. Select platform and configuration from the dropdown. EG: `Windows64 - Release`
- All FourKit runtime files (DLL + .NET runtime + `hostfxr.dll`) land in a `runtime/` subfolder next to `Minecraft.Server.exe`. An empty `plugins/` folder is also created. Both are produced automatically by the build. 6. Pick the startup project `Minecraft.Client.exe`
## Visual Studio 2022 quick start (recommended)
VS 2022 has built-in CMake support, so there is no need to generate a `.sln` file by hand.
1. Install the prerequisites above.
2. Clone the repo with submodules. If you don't, you will get a build error!
- `git clone --recurse-submodules https://github.com/itsRevela/LCE-Revelations.git`
3. In Visual Studio: `File > Open > Folder...` and select the **repo root** (the folder that contains `CMakeLists.txt`).
4. Wait for CMake to configure (~5 seconds on a warm cache, a few minutes on the first run while assets copy).
5. Pick a build configuration in the dropdown, for example `windows64-release`.
6. `Build > Build All` (or `F7`). Targets of interest:
- `Minecraft.Client`: the game client.
- `Minecraft.Server`: the **vanilla** dedicated server. Standalone C++ binary, no plugin host, no .NET dependency at runtime, smallest distribution.
- `Minecraft.Server.FourKit`: the **FourKit-enabled** dedicated server. Bundles the .NET 10 plugin host alongside the exe (in `runtime/`) and creates an empty `plugins/` folder for end users to drop plugin DLLs into. Building this target also triggers the `Minecraft.Server.FourKit.Managed` target which publishes the C# project.
7. Use the debug target dropdown to pick `Minecraft.Client.exe` or whichever server flavour you want, then `F5` to launch.
### Server flavours
Both server targets compile from the same source tree and produce a binary literally named `Minecraft.Server.exe`. The variant identity lives in the build directory:
```
build/<preset>/Minecraft.Server/Release/
Minecraft.Server.exe (vanilla, no plugin support)
Common/, Windows64/, ...
build/<preset>/Minecraft.Server.FourKit/Release/
Minecraft.Server.exe (FourKit-enabled, same exe name on purpose)
runtime/ (self-contained .NET 10 + Minecraft.Server.FourKit.dll)
plugins/ (empty drop point)
Common/, Windows64/, ...
```
The FourKit target gets the `MINECRAFT_SERVER_FOURKIT_BUILD` preprocessor define. Inside `FourKitBridge.h`, the real plugin entry points are conditional on that define; the vanilla target sees inline no-op stubs instead, so gameplay code can call `FourKitBridge::Fire*` unconditionally and produce the right behaviour for each flavour without per-call-site `#ifdef`s.
### Dedicated server debug arguments
- Default debugger arguments for both `Minecraft.Server` and `Minecraft.Server.FourKit`:
- `-port 25565 -bind 0.0.0.0 -name DedicatedServer`
- You can override arguments in:
- `Project Properties > Debugging > Command Arguments`
- Both server targets post-build copy the dedicated-server asset set:
- `Common/Media/MediaWindows64.arc`
- `Common/res`
- `Windows64/GameHDD`
## CMake (Windows x64) ## CMake (Windows x64)
@@ -65,48 +20,12 @@ Open `Developer PowerShell for VS` and run:
cmake --preset windows64 cmake --preset windows64
``` ```
Build Debug:
```powershell
cmake --build --preset windows64-debug --target Minecraft.Client
```
Build Release: Build Release:
```powershell ```powershell
cmake --build --preset windows64-release --target Minecraft.Client cmake --build --preset windows64-release --target Minecraft.Client
``` ```
Build vanilla Dedicated Server (Debug):
```powershell
cmake --build --preset windows64-debug --target Minecraft.Server
```
Build vanilla Dedicated Server (Release):
```powershell
cmake --build --preset windows64-release --target Minecraft.Server
```
Build FourKit Dedicated Server (Debug):
```powershell
cmake --build --preset windows64-debug --target Minecraft.Server.FourKit
```
Build FourKit Dedicated Server (Release):
```powershell
cmake --build --preset windows64-release --target Minecraft.Server.FourKit
```
Build everything (client + both server flavours):
```powershell
cmake --build --preset windows64-release
```
Run executable: Run executable:
```powershell ```powershell
@@ -114,20 +33,6 @@ cd .\build\windows64\Minecraft.Client\Debug
.\Minecraft.Client.exe .\Minecraft.Client.exe
``` ```
Run vanilla dedicated server:
```powershell
cd .\build\windows64\Minecraft.Server\Debug
.\Minecraft.Server.exe -port 25565 -bind 0.0.0.0 -name DedicatedServer
```
Run FourKit dedicated server:
```powershell
cd .\build\windows64\Minecraft.Server.FourKit\Debug
.\Minecraft.Server.exe -port 25565 -bind 0.0.0.0 -name DedicatedServer
```
Notes: Notes:
- Post-build asset copy is automatic for `Minecraft.Client` in CMake (Debug and Release variants). - Post-build asset copy is automatic for `Minecraft.Client` in CMake (Debug and Release variants).
- The game relies on relative paths (for example `Common\Media\...`), so launching from the output directory is required. - The game relies on relative paths (for example `Common\Media\...`), so launching from the output directory is required.
@@ -150,40 +55,75 @@ Install xwin for downloading the Windows SDK:
cargo install xwin cargo install xwin
``` ```
### Compile ### Download Windows SDK
Download and extract the Windows SDK and CRT:
Run this (Release):
```bash ```bash
./build-linux.sh xwin --accept-license splat --output ~/.cache/xwin/splat
``` ```
Or, for debug: Create symlinks to account for Linux filesystems being case sensitive:
```bash ```bash
./build-linux.sh . Debug WINSDK=~/.cache/xwin/splat
ln -sf $WINSDK/sdk/include/shared/sdkddkver.h $WINSDK/sdk/include/shared/SDKDDKVer.h
ln -sf $WINSDK/sdk/lib/um/x86_64/xinput9_1_0.lib $WINSDK/sdk/lib/um/x86_64/XInput9_1_0.lib
ln -sf $WINSDK/sdk/lib/um/x86_64/ws2_32.lib $WINSDK/sdk/lib/um/x86_64/Ws2_32.lib
``` ```
### Configure
### NixOS / Nix Set environment variables and configure CMake:
For NixOS or systems with Nix installed, use the provided flake:
```bash ```bash
nix build .#client export WINSDK=~/.cache/xwin/splat
nix build .#server export INCLUDE="$WINSDK/crt/include;$WINSDK/sdk/include/um;$WINSDK/sdk/include/ucrt;$WINSDK/sdk/include/shared"
export LIB="$WINSDK/crt/lib/x86_64;$WINSDK/sdk/lib/um/x86_64;$WINSDK/sdk/lib/ucrt/x86_64"
cmake -S . -B build/windows64-clang \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=clang-cl \
-DCMAKE_CXX_COMPILER=clang-cl \
-DCMAKE_LINKER=lld-link \
-DCMAKE_RC_COMPILER=llvm-rc \
-DCMAKE_MT=llvm-mt \
-DPLATFORM_DEFINES="_WINDOWS64" \
-DPLATFORM_NAME="Windows64" \
-DIGGY_LIBS="iggy_w64.lib;iggyperfmon_w64.lib;iggyexpruntime_w64.lib" \
-DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded \
-DCMAKE_C_FLAGS="/MT -fms-compatibility -fms-extensions --target=x86_64-pc-windows-msvc -imsvc $WINSDK/crt/include -imsvc $WINSDK/sdk/include/ucrt -imsvc $WINSDK/sdk/include/um -imsvc $WINSDK/sdk/include/shared" \
-DCMAKE_CXX_FLAGS="/MT -fms-compatibility -fms-extensions --target=x86_64-pc-windows-msvc -imsvc $WINSDK/crt/include -imsvc $WINSDK/sdk/include/ucrt -imsvc $WINSDK/sdk/include/um -imsvc $WINSDK/sdk/include/shared" \
-DCMAKE_ASM_MASM_FLAGS="-m64" \
-DCMAKE_EXE_LINKER_FLAGS="-libpath:$WINSDK/crt/lib/x86_64 -libpath:$WINSDK/sdk/lib/um/x86_64 -libpath:$WINSDK/sdk/lib/ucrt/x86_64"
``` ```
Or enter the development shell with all dependencies: ### Build
Build Release:
```bash ```bash
nix develop cmake --build build/windows64-clang --config Release
```
Build specific target:
```bash
cmake --build build/windows64-clang --config Release --target Minecraft.Client
```
### Run with Wine
Run executable:
```bash
cd build/windows64-clang/Minecraft.Client
wine ./Minecraft.Client.exe
``` ```
Notes: Notes:
- Requires LLVM 15+ with clang-cl, lld-link, llvm-rc, and llvm-mt. - Requires LLVM 15+ with clang-cl, lld-link, llvm-rc, and llvm-mt.
- The xwin tool downloads ~1GB of SDK files on first run.
- Wine is required to run the compiled Windows executables on Linux. - Wine is required to run the compiled Windows executables on Linux.
### Troubleshooting
- **`'vswhere.exe' is not recognized`**: harmless warning. This appears if you ran `vcvars64.bat` from a plain command prompt instead of `Developer PowerShell for VS`. The Visual Studio Installer's `vswhere.exe` lives at `C:\Program Files (x86)\Microsoft Visual Studio\Installer\` and is not on the default `PATH`. Use the Developer PowerShell shortcut, or open the repo folder directly in VS (which handles the dev env for you).
- **`.NET 10 SDK not found` at configure time**: install the x64 SDK from https://dotnet.microsoft.com/download/dotnet/10.0 and re-run CMake configure (`Project > Configure Cache` in VS, or `cmake --preset windows64` from a shell).
- **Server starts but logs `hostfxr_initialize_for_dotnet_command_line failed`**: the `runtime/` folder next to `Minecraft.Server.exe` is missing or stale. Rebuild the `Minecraft.Server.FourKit` target (which re-stages `runtime/`), or do a clean rebuild of `Minecraft.Server`.
+4 -11
View File
@@ -1,5 +1,8 @@
# Scope of Project # Scope of Project
At the moment, this project's scope is generally limited outside of adding new content to the game (blocks, mobs, items). We are currently prioritizing stability, quality of life, and platform support over these things. At the moment, this project's scope is generally limited outside of adding new content to the game (blocks, mobs, items). We are currently prioritizing stability, and platform support over these things.
## Backporting
If you're backporting a feature or downporting, please read [PORTING.md](./PORTING.md)
## Parity ## Parity
We are attempting to keep our version of LCE as close to visual and experience parity with the original console experience of LCE as possible. This means that we will not be accepting changes that... We are attempting to keep our version of LCE as close to visual and experience parity with the original console experience of LCE as possible. This means that we will not be accepting changes that...
@@ -30,21 +33,11 @@ However, we would accept changes that...
## Current Goals ## Current Goals
- Being a robust Desktop version of LCE
- Having proper controller support across all types, brands on Desktop or Desktop-like platforms (Steam Deck) - Having proper controller support across all types, brands on Desktop or Desktop-like platforms (Steam Deck)
- Improving stability as much as possible - Improving stability as much as possible
- Fixing as many bugs as possible - Fixing as many bugs as possible
- Enabling Desktop multiplayer options
- LAN P2P Multiplayer
- Splitscreen Multiplayer
- WAN Servers (IP:Port connectivity)
- Platform-based P2P Connectivity
- Steam Networking
- GameDate?
- Maybe more?
- Refining rendering settings, renderer options, as well as reaching rendering parity with true LCE - Refining rendering settings, renderer options, as well as reaching rendering parity with true LCE
- Having workable multi-platform compilation for ARM, Consoles, Linux - Having workable multi-platform compilation for ARM, Consoles, Linux
- Being a good base for further expansion and modding of LCE, such as backports and "modpacks".
# Scope of PRs # Scope of PRs
All Pull Requests should fully document the changes they include in their file changes. They should also be limited to one general topic and not touch all over the codebase unless its justifiable. All Pull Requests should fully document the changes they include in their file changes. They should also be limited to one general topic and not touch all over the codebase unless its justifiable.
+13 -12
View File
@@ -6,8 +6,6 @@
ResourceLocation BeaconRenderer::BEAM_LOCATION = ResourceLocation(TN_MISC_BEACON_BEAM); ResourceLocation BeaconRenderer::BEAM_LOCATION = ResourceLocation(TN_MISC_BEACON_BEAM);
bool BeaconRenderer::s_renderOuterHalo = false;
void BeaconRenderer::render(shared_ptr<TileEntity> _beacon, double x, double y, double z, float a, bool setColor, float alpha, bool useCompiled) void BeaconRenderer::render(shared_ptr<TileEntity> _beacon, double x, double y, double z, float a, bool setColor, float alpha, bool useCompiled)
{ {
shared_ptr<BeaconTileEntity> beacon = dynamic_pointer_cast<BeaconTileEntity>(_beacon); shared_ptr<BeaconTileEntity> beacon = dynamic_pointer_cast<BeaconTileEntity>(_beacon);
@@ -20,18 +18,21 @@ void BeaconRenderer::render(shared_ptr<TileEntity> _beacon, double x, double y,
bindTexture(&BEAM_LOCATION); bindTexture(&BEAM_LOCATION);
// TODO: 4J: Put this back in
//assert(0);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDepthMask(true);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
float tt = beacon->getLevel()->getGameTime() + a; float tt = beacon->getLevel()->getGameTime() + a;
float texVOff = -tt * .20f - floor(-tt * .10f); float texVOff = -tt * .20f - floor(-tt * .10f);
if (!s_renderOuterHalo)
{ {
glDisable(GL_BLEND);
glDepthMask(true);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
int r = 1; int r = 1;
double rot = tt * .025 * (1 - (r & 1) * 2.5); double rot = tt * .025 * (1 - (r & 1) * 2.5);
@@ -80,12 +81,12 @@ void BeaconRenderer::render(shared_ptr<TileEntity> _beacon, double x, double y,
t->end(); t->end();
} }
else
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
{
t->begin(); t->begin();
t->color(255, 255, 255, 32); t->color(255, 255, 255, 32);
-2
View File
@@ -9,7 +9,5 @@ private:
static ResourceLocation BEAM_LOCATION; static ResourceLocation BEAM_LOCATION;
public: public:
static bool s_renderOuterHalo;
virtual void render(shared_ptr<TileEntity> _beacon, double x, double y, double z, float a, bool setColor, float alpha, bool useCompiled); virtual void render(shared_ptr<TileEntity> _beacon, double x, double y, double z, float a, bool setColor, float alpha, bool useCompiled);
}; };
+3 -11
View File
@@ -21,13 +21,9 @@ set(MINECRAFT_CLIENT_SOURCES
$<$<STREQUAL:${PLATFORM_NAME},Windows64>:${MINECRAFT_CLIENT_WINDOWS}> $<$<STREQUAL:${PLATFORM_NAME},Windows64>:${MINECRAFT_CLIENT_WINDOWS}>
$<$<STREQUAL:${PLATFORM_NAME},Xbox>:${MINECRAFT_CLIENT_XBOX360}> $<$<STREQUAL:${PLATFORM_NAME},Xbox>:${MINECRAFT_CLIENT_XBOX360}>
${SOURCES_COMMON} ${SOURCES_COMMON}
"${CMAKE_SOURCE_DIR}/Minecraft.Client/Common/StringUtils.cpp"
) )
add_executable(Minecraft.Client ${MINECRAFT_CLIENT_SOURCES} "Common/UI/UIScene_AchievementsMenu.cpp" "Common/UI/UIScene_AchievementsMenu.h" "Common/UI/UIControl_AchievementsList.cpp" "Common/UI/UIControl_AchievementsList.h")
add_executable(Minecraft.Client ${MINECRAFT_CLIENT_SOURCES} "Common/UI/UIScene_AchievementsMenu.cpp" "Common/UI/UIScene_AchievementsMenu.h" "Common/UI/UIControl_AchievementsList.cpp" "Common/UI/UIControl_AchievementsList.h" "Windows64/NetworkHelpers.h" "Windows64/NetworkHelpers.cpp" "Windows64/Windows64_Launcher.cpp" "Windows64/Windows64_Launcher.h"
)
# Only define executable on windows # Only define executable on windows
if(PLATFORM_NAME STREQUAL "Windows64") if(PLATFORM_NAME STREQUAL "Windows64")
@@ -39,7 +35,6 @@ target_include_directories(Minecraft.Client PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/Iggy/include" "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/Iggy/include"
"${CMAKE_SOURCE_DIR}/include/" "${CMAKE_SOURCE_DIR}/include/"
"${CMAKE_CURRENT_SOURCE_DIR}/Windows64/ExtraLibs/webview2/build/native/include"
) )
target_compile_definitions(Minecraft.Client PRIVATE target_compile_definitions(Minecraft.Client PRIVATE
${MINECRAFT_SHARED_DEFINES} ${MINECRAFT_SHARED_DEFINES}
@@ -57,7 +52,6 @@ set_target_properties(Minecraft.Client PROPERTIES
target_link_libraries(Minecraft.Client PRIVATE target_link_libraries(Minecraft.Client PRIVATE
Minecraft.World Minecraft.World
d3d11 d3d11
dxgi
d3dcompiler d3dcompiler
XInput9_1_0 XInput9_1_0
wsock32 wsock32
@@ -67,9 +61,6 @@ target_link_libraries(Minecraft.Client PRIVATE
4JLibs.${PLATFORM_NAME}.Storage 4JLibs.${PLATFORM_NAME}.Storage
4JLibs.${PLATFORM_NAME}.Render 4JLibs.${PLATFORM_NAME}.Render
$<$<STREQUAL:${PLATFORM_NAME},Windows64>:${CMAKE_CURRENT_SOURCE_DIR}/Windows64/ExtraLibs/discordsdk/discord_game_sdk.dll.lib> $<$<STREQUAL:${PLATFORM_NAME},Windows64>:${CMAKE_CURRENT_SOURCE_DIR}/Windows64/ExtraLibs/discordsdk/discord_game_sdk.dll.lib>
$<$<STREQUAL:${PLATFORM_NAME},Windows64>:${CMAKE_CURRENT_SOURCE_DIR}/Windows64/ExtraLibs/webview2/build/native/x64/WebView2LoaderStatic.lib>
$<$<STREQUAL:${PLATFORM_NAME},Windows64>:shlwapi>
$<$<STREQUAL:${PLATFORM_NAME},Windows64>:ole32>
) )
# Iggy libs # Iggy libs
@@ -82,7 +73,7 @@ endforeach()
# --- # ---
include("${CMAKE_SOURCE_DIR}/cmake/CopyAssets.cmake") include("${CMAKE_SOURCE_DIR}/cmake/CopyAssets.cmake")
set(ASSET_FOLDER_PAIRS set(ASSET_FOLDER_PAIRS
"${CMAKE_CURRENT_SOURCE_DIR}/music" "music" "${CMAKE_CURRENT_SOURCE_DIR}/Music" "${PLATFORM_NAME}Media/Music"
"${CMAKE_CURRENT_SOURCE_DIR}/Common/Media" "Common/Media" "${CMAKE_CURRENT_SOURCE_DIR}/Common/Media" "Common/Media"
"${CMAKE_CURRENT_SOURCE_DIR}/Common/res" "Common/res" "${CMAKE_CURRENT_SOURCE_DIR}/Common/res" "Common/res"
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}Media" "${PLATFORM_NAME}Media" "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}Media" "${PLATFORM_NAME}Media"
@@ -95,4 +86,5 @@ add_copyredist_target(Minecraft.Client)
# Make sure GameHDD exists on Windows # Make sure GameHDD exists on Windows
if(PLATFORM_NAME STREQUAL "Windows64") if(PLATFORM_NAME STREQUAL "Windows64")
add_gamehdd_target(Minecraft.Client) add_gamehdd_target(Minecraft.Client)
add_settings_target(Minecraft.Client)
endif() endif()
+8 -25
View File
@@ -6,7 +6,6 @@
#include "../Minecraft.World/SharedConstants.h" #include "../Minecraft.World/SharedConstants.h"
#include "../Minecraft.World/StringHelpers.h" #include "../Minecraft.World/StringHelpers.h"
#include "../Minecraft.World/ChatPacket.h" #include "../Minecraft.World/ChatPacket.h"
#include "../Minecraft.World/ArabicShaping.h"
const wstring ChatScreen::allowedChars = SharedConstants::acceptableLetters; const wstring ChatScreen::allowedChars = SharedConstants::acceptableLetters;
vector<wstring> ChatScreen::s_chatHistory; vector<wstring> ChatScreen::s_chatHistory;
@@ -16,12 +15,7 @@ int ChatScreen::s_chatIndex = 0;
bool ChatScreen::isAllowedChatChar(wchar_t c) bool ChatScreen::isAllowedChatChar(wchar_t c)
{ {
if (c < 0x20) return false; return c >= 0x20 && (c == L'\u00A7' || allowedChars.empty() || allowedChars.find(c) != wstring::npos);
// Block Unicode bidirectional override characters that can be used to
// spoof chat messages or impersonate players.
if (c >= 0x202A && c <= 0x202E) return false; // LRE, RLE, PDF, LRO, RLO
if (c >= 0x2066 && c <= 0x2069) return false; // LRI, RLI, FSI, PDI
return true;
} }
ChatScreen::ChatScreen() ChatScreen::ChatScreen()
@@ -116,9 +110,6 @@ void ChatScreen::keyPressed(wchar_t ch, int eventKey)
if (eventKey == Keyboard::KEY_RETURN) if (eventKey == Keyboard::KEY_RETURN)
{ {
wstring trim = trimString(message); wstring trim = trimString(message);
{ char buf[64]; sprintf_s(buf, "[CHAT] Sending (%d chars): ", (int)trim.length()); OutputDebugStringA(buf); }
OutputDebugStringW(trim.c_str());
OutputDebugStringA("\n");
if (trim.length() > 0) if (trim.length() > 0)
{ {
if (!minecraft->handleClientSideCommand(trim)) if (!minecraft->handleClientSideCommand(trim))
@@ -161,7 +152,6 @@ void ChatScreen::keyPressed(wchar_t ch, int eventKey)
{ {
message.insert(cursorIndex, 1, ch); message.insert(cursorIndex, 1, ch);
cursorIndex++; cursorIndex++;
{ char buf[64]; sprintf_s(buf, "[CHAT] Char U+%04X accepted (%d chars)\n", (unsigned)ch, (int)message.length()); OutputDebugStringA(buf); }
} }
} }
@@ -172,21 +162,14 @@ void ChatScreen::render(int xm, int ym, float a)
int x = 4; int x = 4;
drawString(font, prefix, x, height - 12, 0xe0e0e0); drawString(font, prefix, x, height - 12, 0xe0e0e0);
x += font->width(prefix); x += font->width(prefix);
wstring beforeCursor = message.substr(0, cursorIndex);
// Shape the full message as one unit so letter connections and word order wstring afterCursor = message.substr(cursorIndex);
// are correct. Track where the logical cursor maps in the visual string. drawStringLiteral(font, beforeCursor, x, height - 12, 0xe0e0e0);
int visualCursorPos = 0; x += font->widthLiteral(beforeCursor);
wstring shaped = shapeArabicText(message, cursorIndex, &visualCursorPos);
// Render the full shaped message without re-shaping it
drawStringPreshaped(font, shaped, x, height - 12, 0xe0e0e0);
// Place the cursor at the correct visual position
wstring beforeCursorVisual = shaped.substr(0, visualCursorPos);
int cursorX = x + font->widthPreshaped(beforeCursorVisual);
if (frame / 6 % 2 == 0) if (frame / 6 % 2 == 0)
drawString(font, L"_", cursorX, height - 12, 0xe0e0e0); drawString(font, L"_", x, height - 12, 0xe0e0e0);
x += font->width(L"_");
drawStringLiteral(font, afterCursor, x, height - 12, 0xe0e0e0);
Screen::render(xm, ym, a); Screen::render(xm, ym, a);
} }
+16 -231
View File
@@ -58,7 +58,6 @@
#ifdef _WINDOWS64 #ifdef _WINDOWS64
#include "Xbox/Network/NetworkPlayerXbox.h" #include "Xbox/Network/NetworkPlayerXbox.h"
#include "Common/Network/PlatformNetworkManagerStub.h" #include "Common/Network/PlatformNetworkManagerStub.h"
#include "Windows64/Network/WinsockNetLayer.h"
#endif #endif
@@ -67,30 +66,6 @@
#include "../Minecraft.World/GenericStats.h" #include "../Minecraft.World/GenericStats.h"
#endif #endif
namespace
{
char mapIconToFrame(char iconSlot)
{
if (iconSlot >= 8) return iconSlot - 4;
return iconSlot;
}
// Same hash as getRandomPlayerMapIcon in MapItemSavedData.cpp, returning
// the Iggy/SWF frame index (0-7) instead of the raw icon slot.
char computePlayerMapFrame(int entityId, int playerIndex)
{
static const char PLAYER_MAP_ICON_SLOTS[] = { 0, 1, 2, 3, 8, 9, 10, 11 };
unsigned int seed = static_cast<unsigned int>(entityId);
seed ^= static_cast<unsigned int>(playerIndex * 0x9E3779B9u);
seed ^= (seed >> 16);
seed *= 0x7FEB352Du;
seed ^= (seed >> 15);
seed *= 0x846CA68Bu;
seed ^= (seed >> 16);
return mapIconToFrame(PLAYER_MAP_ICON_SLOTS[seed % 8]);
}
}
ClientConnection::ClientConnection(Minecraft *minecraft, const wstring& ip, int port) ClientConnection::ClientConnection(Minecraft *minecraft, const wstring& ip, int port)
{ {
// 4J Stu - No longer used as we use the socket version below. // 4J Stu - No longer used as we use the socket version below.
@@ -135,7 +110,6 @@ ClientConnection::ClientConnection(Minecraft *minecraft, Socket *socket, int iUs
started = false; started = false;
savedDataStorage = new SavedDataStorage(nullptr); savedDataStorage = new SavedDataStorage(nullptr);
maxPlayers = 20; maxPlayers = 20;
m_isForkServer = false;
this->minecraft = minecraft; this->minecraft = minecraft;
@@ -368,7 +342,7 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
Level *dimensionLevel = minecraft->getLevel( packet->dimension ); Level *dimensionLevel = minecraft->getLevel( packet->dimension );
if( dimensionLevel == nullptr ) if( dimensionLevel == nullptr )
{ {
level = new MultiPlayerLevel(this, new LevelSettings(packet->seed, GameType::byId(packet->gameType), false, packet->m_isHardcore, packet->m_newSeaLevel, packet->m_pLevelType, packet->m_xzSize, packet->m_hellScale), packet->dimension, packet->difficulty); level = new MultiPlayerLevel(this, new LevelSettings(packet->seed, GameType::byId(packet->gameType), false, false, packet->m_newSeaLevel, packet->m_pLevelType, packet->m_xzSize, packet->m_hellScale), packet->dimension, packet->difficulty);
// 4J Stu - We want to share the SavedDataStorage between levels // 4J Stu - We want to share the SavedDataStorage between levels
int otherDimensionId = packet->dimension == 0 ? -1 : 0; int otherDimensionId = packet->dimension == 0 ? -1 : 0;
@@ -403,7 +377,6 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
BYTE networkSmallId = getSocket()->getSmallId(); BYTE networkSmallId = getSocket()->getSmallId();
app.UpdatePlayerInfo(networkSmallId, packet->m_playerIndex, packet->m_uiGamePrivileges); app.UpdatePlayerInfo(networkSmallId, packet->m_playerIndex, packet->m_uiGamePrivileges);
app.SetPlayerMapIcon(minecraft->player->getName().c_str(), computePlayerMapFrame(packet->clientVersion, packet->m_playerIndex));
minecraft->player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_All, packet->m_uiGamePrivileges); minecraft->player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_All, packet->m_uiGamePrivileges);
// Assume all privileges are on, so that the first message we see only indicates things that have been turned off // Assume all privileges are on, so that the first message we see only indicates things that have been turned off
@@ -438,7 +411,7 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
activeLevel = minecraft->getLevel(otherDimensionId); activeLevel = minecraft->getLevel(otherDimensionId);
} }
MultiPlayerLevel *dimensionLevel = new MultiPlayerLevel(this, new LevelSettings(packet->seed, GameType::byId(packet->gameType), false, packet->m_isHardcore, packet->m_newSeaLevel, packet->m_pLevelType, packet->m_xzSize, packet->m_hellScale), packet->dimension, packet->difficulty); MultiPlayerLevel *dimensionLevel = new MultiPlayerLevel(this, new LevelSettings(packet->seed, GameType::byId(packet->gameType), false, false, packet->m_newSeaLevel, packet->m_pLevelType, packet->m_xzSize, packet->m_hellScale), packet->dimension, packet->difficulty);
dimensionLevel->savedDataStorage = activeLevel->savedDataStorage; dimensionLevel->savedDataStorage = activeLevel->savedDataStorage;
@@ -474,7 +447,6 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
BYTE networkSmallId = getSocket()->getSmallId(); BYTE networkSmallId = getSocket()->getSmallId();
app.UpdatePlayerInfo(networkSmallId, packet->m_playerIndex, packet->m_uiGamePrivileges); app.UpdatePlayerInfo(networkSmallId, packet->m_playerIndex, packet->m_uiGamePrivileges);
app.SetPlayerMapIcon(player->getName().c_str(), computePlayerMapFrame(packet->clientVersion, packet->m_playerIndex));
player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_All, packet->m_uiGamePrivileges); player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_All, packet->m_uiGamePrivileges);
// Assume all privileges are on, so that the first message we see only indicates things that have been turned off // Assume all privileges are on, so that the first message we see only indicates things that have been turned off
@@ -945,36 +917,6 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
} }
} }
// Client-side registration: if we still have no IQNet entry for this remote
// player, create one so they appear in the Tab player list.
// Find the first available IQNet slot (customData == 0, skip slot 0 which
// is the host). We can't use packet->m_playerIndex directly because on
// dedicated servers the game-level player index starts at 0 for real
// players, conflicting with the IQNet host slot.
if (matchedQNetPlayer == nullptr)
{
for (int s = 1; s < MINECRAFT_NET_MAX_PLAYERS; ++s)
{
IQNetPlayer* qp = &IQNet::m_player[s];
if (qp->GetCustomDataValue() == 0 && qp->m_gamertag[0] == 0)
{
BYTE smallId = static_cast<BYTE>(s);
qp->m_smallId = smallId;
qp->m_isRemote = true;
qp->m_isHostPlayer = false;
qp->m_resolvedXuid = pktXuid;
wcsncpy_s(qp->m_gamertag, 32, packet->name.c_str(), _TRUNCATE);
if (smallId >= IQNet::s_playerCount)
IQNet::s_playerCount = smallId + 1;
extern CPlatformNetworkManagerStub* g_pPlatformNetworkManager;
g_pPlatformNetworkManager->NotifyPlayerJoined(qp);
matchedQNetPlayer = qp;
break;
}
}
}
if (matchedQNetPlayer != nullptr) if (matchedQNetPlayer != nullptr)
{ {
// Store packet-authoritative XUID on this network slot so later lookups by XUID // Store packet-authoritative XUID on this network slot so later lookups by XUID
@@ -1004,7 +946,6 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
player->setPlayerIndex( packet->m_playerIndex ); player->setPlayerIndex( packet->m_playerIndex );
player->setCustomSkin( packet->m_skinId ); player->setCustomSkin( packet->m_skinId );
player->setCustomCape( packet->m_capeId ); player->setCustomCape( packet->m_capeId );
app.SetPlayerMapIcon(packet->name.c_str(), computePlayerMapFrame(packet->id, packet->m_playerIndex));
player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_All, packet->m_uiGamePrivileges); player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_All, packet->m_uiGamePrivileges);
if (!player->customTextureUrl.empty() && player->customTextureUrl.substr(0, 3).compare(L"def") != 0 && !app.IsFileInMemoryTextures(player->customTextureUrl)) if (!player->customTextureUrl.empty() && player->customTextureUrl.substr(0, 3).compare(L"def") != 0 && !app.IsFileInMemoryTextures(player->customTextureUrl))
@@ -1142,35 +1083,33 @@ void ClientConnection::handleMoveEntitySmall(shared_ptr<MoveEntityPacketSmall> p
void ClientConnection::handleRemoveEntity(shared_ptr<RemoveEntitiesPacket> packet) void ClientConnection::handleRemoveEntity(shared_ptr<RemoveEntitiesPacket> packet)
{ {
#ifdef _WINDOWS64 #ifdef _WINDOWS64
// On fork servers, IQNet cleanup is handled by the MC|ForkPLeave custom if (!g_NetworkManager.IsHost())
// payload so players stay in Tab regardless of render distance. On
// upstream servers (no MC|ForkHello received), fall back to the old
// behaviour of cleaning up IQNet here.
if (!m_isForkServer && !g_NetworkManager.IsHost())
{ {
for (int i = 0; i < packet->ids.length; i++) for (int i = 0; i < packet->ids.length; i++)
{ {
shared_ptr<Entity> entity = getEntity(packet->ids[i]); shared_ptr<Entity> entity = getEntity(packet->ids[i]);
if (entity != nullptr) if (entity != nullptr && entity->GetType() == eTYPE_PLAYER)
{ {
shared_ptr<Player> player = dynamic_pointer_cast<Player>(entity); shared_ptr<Player> player = dynamic_pointer_cast<Player>(entity);
if (player != nullptr) if (player != nullptr)
{ {
for (int s = 1; s < MINECRAFT_NET_MAX_PLAYERS; ++s) PlayerUID xuid = player->getXuid();
INetworkPlayer* np = g_NetworkManager.GetPlayerByXuid(xuid);
if (np != nullptr)
{ {
IQNetPlayer* qp = &IQNet::m_player[s]; NetworkPlayerXbox* npx = (NetworkPlayerXbox*)np;
if (qp->GetCustomDataValue() != 0 && IQNetPlayer* qp = npx->GetQNetPlayer();
_wcsicmp(qp->m_gamertag, player->getName().c_str()) == 0) if (qp != nullptr)
{ {
extern CPlatformNetworkManagerStub* g_pPlatformNetworkManager; extern CPlatformNetworkManagerStub* g_pPlatformNetworkManager;
g_pPlatformNetworkManager->NotifyPlayerLeaving(qp); g_pPlatformNetworkManager->NotifyPlayerLeaving(qp);
qp->m_smallId = 0; qp->m_smallId = 0;
qp->m_isRemote = false; qp->m_isRemote = false;
qp->m_isHostPlayer = false; qp->m_isHostPlayer = false;
// Clear resolved id to avoid stale XUID -> player matches after disconnect.
qp->m_resolvedXuid = INVALID_XUID; qp->m_resolvedXuid = INVALID_XUID;
qp->m_gamertag[0] = 0; qp->m_gamertag[0] = 0;
qp->SetCustomDataValue(0); qp->SetCustomDataValue(0);
break;
} }
} }
} }
@@ -2944,7 +2883,7 @@ void ClientConnection::handleRespawn(shared_ptr<RespawnPacket> packet)
MultiPlayerLevel *dimensionLevel = (MultiPlayerLevel *)minecraft->getLevel( packet->dimension ); MultiPlayerLevel *dimensionLevel = (MultiPlayerLevel *)minecraft->getLevel( packet->dimension );
if( dimensionLevel == nullptr ) if( dimensionLevel == nullptr )
{ {
dimensionLevel = new MultiPlayerLevel(this, new LevelSettings(packet->mapSeed, packet->playerGameType, false, packet->m_isHardcore, packet->m_newSeaLevel, packet->m_pLevelType, packet->m_xzSize, packet->m_hellScale), packet->dimension, packet->difficulty); dimensionLevel = new MultiPlayerLevel(this, new LevelSettings(packet->mapSeed, packet->playerGameType, false, minecraft->level->getLevelData()->isHardcore(), packet->m_newSeaLevel, packet->m_pLevelType, packet->m_xzSize, packet->m_hellScale), packet->dimension, packet->difficulty);
// 4J Stu - We want to shared the savedDataStorage between both levels // 4J Stu - We want to shared the savedDataStorage between both levels
//if( dimensionLevel->savedDataStorage != nullptr ) //if( dimensionLevel->savedDataStorage != nullptr )
@@ -3389,9 +3328,7 @@ void ClientConnection::handleTileEditorOpen(shared_ptr<TileEditorOpenPacket> pac
void ClientConnection::handleSignUpdate(shared_ptr<SignUpdatePacket> packet) void ClientConnection::handleSignUpdate(shared_ptr<SignUpdatePacket> packet)
{ {
app.DebugPrintf("[SIGN] handleSignUpdate at (%d, %d, %d):\n", packet->x, packet->y, packet->z); app.DebugPrintf("ClientConnection::handleSignUpdate - ");
for (int i = 0; i < MAX_SIGN_LINES; i++)
app.DebugPrintf("[SIGN] Line%d: \"%ls\"\n", i+1, packet->lines[i].c_str());
if (minecraft->level->hasChunkAt(packet->x, packet->y, packet->z)) if (minecraft->level->hasChunkAt(packet->x, packet->y, packet->z))
{ {
shared_ptr<TileEntity> te = minecraft->level->getTileEntity(packet->x, packet->y, packet->z); shared_ptr<TileEntity> te = minecraft->level->getTileEntity(packet->x, packet->y, packet->z);
@@ -3405,7 +3342,7 @@ void ClientConnection::handleSignUpdate(shared_ptr<SignUpdatePacket> packet)
ste->SetMessage(i,packet->lines[i]); ste->SetMessage(i,packet->lines[i]);
} }
app.DebugPrintf("[SIGN] verified=%d censored=%d\n", packet->m_bVerified, packet->m_bCensored); app.DebugPrintf("verified = %d\tCensored = %d\n",packet->m_bVerified,packet->m_bCensored);
ste->SetVerified(packet->m_bVerified); ste->SetVerified(packet->m_bVerified);
ste->SetCensored(packet->m_bCensored); ste->SetCensored(packet->m_bCensored);
@@ -3413,12 +3350,12 @@ void ClientConnection::handleSignUpdate(shared_ptr<SignUpdatePacket> packet)
} }
else else
{ {
app.DebugPrintf("[SIGN] ERROR: tile entity is not a SignTileEntity\n"); app.DebugPrintf("dynamic_pointer_cast<SignTileEntity>(te) == nullptr\n");
} }
} }
else else
{ {
app.DebugPrintf("[SIGN] ERROR: chunk not loaded at position\n"); app.DebugPrintf("hasChunkAt failed\n");
} }
} }
@@ -3805,158 +3742,6 @@ void ClientConnection::handleSoundEvent(shared_ptr<LevelSoundPacket> packet)
void ClientConnection::handleCustomPayload(shared_ptr<CustomPayloadPacket> customPayloadPacket) void ClientConnection::handleCustomPayload(shared_ptr<CustomPayloadPacket> customPayloadPacket)
{ {
#ifdef _WINDOWS64
// Build a server-specific identity token file path next to the executable.
// Each server gets its own token file based on a hash of the server address,
// so connecting to multiple secured servers doesn't overwrite tokens.
auto buildIdentityTokenPath = []() -> std::string {
char exePath[MAX_PATH] = {};
DWORD len = GetModuleFileNameA(NULL, exePath, MAX_PATH);
if (len == 0 || len >= MAX_PATH) return std::string();
char *lastSlash = strrchr(exePath, '\\');
if (lastSlash != NULL) *(lastSlash + 1) = 0;
// Hash the server IP:port to create a unique filename per server
char serverAddr[300] = {};
sprintf_s(serverAddr, sizeof(serverAddr), "%s:%d", g_Win64MultiplayerIP, g_Win64MultiplayerPort);
unsigned int hash = 5381;
for (const char *p = serverAddr; *p; ++p)
hash = ((hash << 5) + hash) + static_cast<unsigned char>(*p);
char filename[64] = {};
sprintf_s(filename, sizeof(filename), "identity-token-%08x.dat", hash);
return std::string(exePath) + filename;
};
// Identity token: server issued us a new token - store it locally
if (CustomPayloadPacket::IDENTITY_TOKEN_ISSUE.compare(customPayloadPacket->identifier) == 0)
{
if (customPayloadPacket->data.data != nullptr && customPayloadPacket->length == 32)
{
std::string tokenPath = buildIdentityTokenPath();
if (!tokenPath.empty())
{
FILE *f = nullptr;
fopen_s(&f, tokenPath.c_str(), "wb");
if (f != nullptr)
{
size_t written = fwrite(customPayloadPacket->data.data, 1, 32, f);
fclose(f);
if (written == 32)
{
app.DebugPrintf("Client: Stored identity token to %s\n", tokenPath.c_str());
}
else
{
app.DebugPrintf("Client: Failed to write full identity token (wrote %zu/32)\n", written);
}
}
else
{
app.DebugPrintf("Client: Failed to open %s for writing\n", tokenPath.c_str());
}
}
}
return;
}
// Identity token: server is challenging us to present our stored token
if (CustomPayloadPacket::IDENTITY_TOKEN_CHALLENGE.compare(customPayloadPacket->identifier) == 0)
{
std::string tokenPath = buildIdentityTokenPath();
FILE *f = nullptr;
if (!tokenPath.empty())
fopen_s(&f, tokenPath.c_str(), "rb");
if (f != nullptr)
{
uint8_t token[32] = {};
size_t bytesRead = fread(token, 1, 32, f);
fclose(f);
if (bytesRead == 32)
{
byteArray tokenData(32);
memcpy(tokenData.data, token, 32);
connection->send(std::make_shared<CustomPayloadPacket>(
CustomPayloadPacket::IDENTITY_TOKEN_RESPONSE, tokenData));
app.DebugPrintf("Client: Sent identity token response\n");
}
else
{
app.DebugPrintf("Client: identity-token.dat is invalid (%zu bytes)\n", bytesRead);
connection->send(std::make_shared<CustomPayloadPacket>(
CustomPayloadPacket::IDENTITY_TOKEN_RESPONSE, byteArray()));
}
SecureZeroMemory(token, sizeof(token));
}
else
{
app.DebugPrintf("Client: No identity-token.dat found, sending empty response\n");
connection->send(std::make_shared<CustomPayloadPacket>(
CustomPayloadPacket::IDENTITY_TOKEN_RESPONSE, byteArray()));
}
return;
}
// Stream cipher handshake: server sent us a key
if (CustomPayloadPacket::CIPHER_KEY_CHANNEL.compare(customPayloadPacket->identifier) == 0)
{
if (customPayloadPacket->length == ServerRuntime::Security::StreamCipher::KEY_SIZE &&
customPayloadPacket->data.data != nullptr)
{
app.DebugPrintf("Client: Received MC|CKey from server (%d bytes)\n", customPayloadPacket->length);
// Store key and send ack+activate atomically to prevent ResetClientCipher race
WinsockNetLayer::StoreClientCipherKey(customPayloadPacket->data.data);
if (!WinsockNetLayer::SendAckAndActivateClientSendCipher())
{
app.DebugPrintf("Client: Failed to send cipher ack, connection will be closed\n");
}
}
else
{
app.DebugPrintf("Client: Received malformed MC|CKey (length=%d)\n", customPayloadPacket->length);
}
return;
}
// Fork server identification: enables render-distance-independent player list
if (CustomPayloadPacket::FORK_HELLO_CHANNEL.compare(customPayloadPacket->identifier) == 0)
{
m_isForkServer = true;
app.DebugPrintf("Client: Connected to fork server\n");
return;
}
// Fork server player leave: clean up IQNet slot so player leaves Tab list
if (CustomPayloadPacket::FORK_PLAYER_LEAVE_CHANNEL.compare(customPayloadPacket->identifier) == 0)
{
if (customPayloadPacket->data.data != nullptr && customPayloadPacket->length > 0)
{
int nameLen = customPayloadPacket->length / static_cast<int>(sizeof(wchar_t));
wstring leavingName(reinterpret_cast<const wchar_t*>(customPayloadPacket->data.data), nameLen);
for (int s = 1; s < MINECRAFT_NET_MAX_PLAYERS; ++s)
{
IQNetPlayer* qp = &IQNet::m_player[s];
if (qp->GetCustomDataValue() != 0 &&
_wcsicmp(qp->m_gamertag, leavingName.c_str()) == 0)
{
extern CPlatformNetworkManagerStub* g_pPlatformNetworkManager;
g_pPlatformNetworkManager->NotifyPlayerLeaving(qp);
qp->m_smallId = 0;
qp->m_isRemote = false;
qp->m_isHostPlayer = false;
qp->m_resolvedXuid = INVALID_XUID;
qp->m_gamertag[0] = 0;
qp->SetCustomDataValue(0);
app.DebugPrintf("Client: Player \"%ls\" left fork server, cleared IQNet slot %d\n", leavingName.c_str(), s);
break;
}
}
}
return;
}
#endif
if (CustomPayloadPacket::TRADER_LIST_PACKET.compare(customPayloadPacket->identifier) == 0) if (CustomPayloadPacket::TRADER_LIST_PACKET.compare(customPayloadPacket->identifier) == 0)
{ {
ByteArrayInputStream bais(customPayloadPacket->data); ByteArrayInputStream bais(customPayloadPacket->data);
-1
View File
@@ -48,7 +48,6 @@ private:
std::unordered_set<int> m_trackedEntityIds; std::unordered_set<int> m_trackedEntityIds;
std::unordered_set<int64_t> m_visibleChunks; std::unordered_set<int64_t> m_visibleChunks;
bool m_isForkServer; // true when connected to a fork server (received MC|ForkHello)
static int64_t chunkKey(int x, int z) { return ((int64_t)x << 32) | ((int64_t)z & 0xFFFFFFFF); } static int64_t chunkKey(int x, int z) { return ((int64_t)x << 32) | ((int64_t)z & 0xFFFFFFFF); }
+2 -10
View File
@@ -1,13 +1,5 @@
#include "stdafx.h" #include "stdafx.h"
#include "ClientConstants.h" #include "ClientConstants.h"
#include <string>
const wchar_t* ClientConstants::LCEN_HOST = L""; const wstring ClientConstants::VERSION_STRING = wstring(L"Minecraft LCE ") + VER_FILEVERSION_STR_W;//+ SharedConstants::VERSION_STRING;
const wstring ClientConstants::BRANCH_STRING = VER_BRANCHVERSION_STR_W;
const std::wstring ClientConstants::VERSION_STRING =
L"Minecraft: Legacy Network Beta Build 2026.06.14-128 [DO NOT DISTRIBUTE]";
std::wstring ClientConstants::GetLCENString()
{
return L"";
}
+1 -3
View File
@@ -13,9 +13,7 @@ class ClientConstants
// INTERNAL DEVELOPMENT SETTINGS // INTERNAL DEVELOPMENT SETTINGS
public: public:
static const wstring VERSION_STRING; static const wstring VERSION_STRING;
static const wstring LCEN_STRING; static const wstring BRANCH_STRING;
static const wchar_t* LCEN_HOST;
static std::wstring GetLCENString();
static const bool DEADMAU5_CAMERA_CHEATS = false; static const bool DEADMAU5_CAMERA_CHEATS = false;
}; };
-3
View File
@@ -45,7 +45,6 @@
#define GAME_HOST_OPTION_BITMASK_DOTILEDROPS 0x08000000 #define GAME_HOST_OPTION_BITMASK_DOTILEDROPS 0x08000000
#define GAME_HOST_OPTION_BITMASK_NATURALREGEN 0x10000000 #define GAME_HOST_OPTION_BITMASK_NATURALREGEN 0x10000000
#define GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE 0x20000000 #define GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE 0x20000000
#define GAME_HOST_OPTION_BITMASK_HARDCORE 0x40000000 // 4J Added - for hardcore mode
#define GAME_HOST_OPTION_BITMASK_ALL 0xFFFFFFFF #define GAME_HOST_OPTION_BITMASK_ALL 0xFFFFFFFF
#define GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT 20 #define GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT 20
@@ -105,8 +104,6 @@ enum EGameHostOptionWorldSize
#define GAMESETTING_ANIMATEDCHARACTER 0x00008000 #define GAMESETTING_ANIMATEDCHARACTER 0x00008000
#define GAMESETTING_PS3EULAREAD 0x00010000 #define GAMESETTING_PS3EULAREAD 0x00010000
#define GAMESETTING_PSVITANETWORKMODEADHOC 0x00020000 #define GAMESETTING_PSVITANETWORKMODEADHOC 0x00020000
#define GAMESETTING_VSYNC 0x01000000
#define GAMESETTING_EXCLUSIVEFULLSCREEN 0x02000000
// defines for languages // defines for languages
-4
View File
@@ -178,9 +178,6 @@ enum eGameSetting
// PSVita // PSVita
eGameSetting_PSVita_NetworkModeAdhoc, eGameSetting_PSVita_NetworkModeAdhoc,
// PC
eGameSetting_VSync,
eGameSetting_ExclusiveFullscreen,
}; };
@@ -651,7 +648,6 @@ enum eGameHostOption
eGameHostOption_DoTileDrops, eGameHostOption_DoTileDrops,
eGameHostOption_NaturalRegeneration, eGameHostOption_NaturalRegeneration,
eGameHostOption_DoDaylightCycle, eGameHostOption_DoDaylightCycle,
eGameHostOption_Hardcore, // 4J Added - for hardcore mode
}; };
// 4J-PB - If any new DLC items are added to the TMSFiles, this array needs updated // 4J-PB - If any new DLC items are added to the TMSFiles, this array needs updated
+80 -159
View File
@@ -8,8 +8,6 @@
#include "../../Minecraft.World/Mth.h" #include "../../Minecraft.World/Mth.h"
#include "../../TexturePackRepository.h" #include "../../TexturePackRepository.h"
#include "../../DLCTexturePack.h" #include "../../DLCTexturePack.h"
#include "../../MultiPlayerGameMode.h"
#include "../../Minecraft.World/LevelSettings.h"
#include "Common/DLC/DLCAudioFile.h" #include "Common/DLC/DLCAudioFile.h"
#ifdef __PSVITA__ #ifdef __PSVITA__
@@ -27,7 +25,7 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <lce_filesystem/lce_filesystem.h> #include <lce_filesystem\lce_filesystem.h>
#ifdef __ORBIS__ #ifdef __ORBIS__
#include <audioout.h> #include <audioout.h>
@@ -67,7 +65,7 @@ void SoundEngine::playMusicTick() {};
#ifdef _WINDOWS64 #ifdef _WINDOWS64
char SoundEngine::m_szSoundPath[]={"Windows64Media\\Sound\\"}; char SoundEngine::m_szSoundPath[]={"Windows64Media\\Sound\\"};
char SoundEngine::m_szMusicPath[]={"music\\"}; char SoundEngine::m_szMusicPath[]={"Windows64Media\\Music\\"};
char SoundEngine::m_szRedistName[]={"redist64"}; char SoundEngine::m_szRedistName[]={"redist64"};
#elif defined _DURANGO #elif defined _DURANGO
char SoundEngine::m_szSoundPath[]={"Sound\\"}; char SoundEngine::m_szSoundPath[]={"Sound\\"};
@@ -116,9 +114,6 @@ const char *SoundEngine::m_szStreamFileA[eStream_Max]=
"hal4", "hal4",
"nuance1", "nuance1",
"nuance2", "nuance2",
"piano1",
"piano2",
"piano3",
#ifndef _XBOX #ifndef _XBOX
"creative1", "creative1",
@@ -133,6 +128,10 @@ const char *SoundEngine::m_szStreamFileA[eStream_Max]=
"menu4", "menu4",
#endif #endif
"piano1",
"piano2",
"piano3",
// Nether // Nether
"nether1", "nether1",
"nether2", "nether2",
@@ -410,13 +409,6 @@ SoundEngine::SoundEngine()
eStream_end_dragon,eStream_end_end, eStream_end_dragon,eStream_end_end,
eStream_CD_1); eStream_CD_1);
#ifndef _XBOX
m_iStream_Creative_Min = eStream_Overworld_Creative1;
m_iStream_Creative_Max = eStream_Overworld_Creative6;
m_iStream_Menu_Min = eStream_Overworld_Menu1;
m_iStream_Menu_Max = eStream_Overworld_Menu4;
#endif
m_musicID=getMusicID(LevelData::DIMENSION_OVERWORLD); m_musicID=getMusicID(LevelData::DIMENSION_OVERWORLD);
m_StreamingAudioInfo.bIs3D=false; m_StreamingAudioInfo.bIs3D=false;
@@ -476,69 +468,65 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, floa
sprintf_s(basePath, "Windows64Media/Sound/%s", (char*)szSoundName); sprintf_s(basePath, "Windows64Media/Sound/%s", (char*)szSoundName);
char finalPath[256]; char finalPath[256];
sprintf_s(finalPath, "%s.wav", basePath);
// Check path cache first to avoid expensive filesystem probing const char* extensions[] = { ".ogg", ".wav", ".mp3" };
auto cacheIt = m_soundPathCache.find(iSound); size_t extCount = sizeof(extensions) / sizeof(extensions[0]);
if (cacheIt != m_soundPathCache.end()) bool found = false;
for (size_t extIdx = 0; extIdx < extCount; extIdx++)
{ {
const auto& paths = cacheIt->second; char basePlusExt[256];
if (paths.empty()) sprintf_s(basePlusExt, "%s%s", basePath, extensions[extIdx]);
return; // previously probed, no files found
const std::string& chosen = paths[rand() % paths.size()]; DWORD attr = GetFileAttributesA(basePlusExt);
sprintf_s(finalPath, "%s", chosen.c_str()); if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
{
sprintf_s(finalPath, "%s", basePlusExt);
found = true;
break;
}
} }
else
{
// Cache miss — probe filesystem and store results
std::vector<std::string> validPaths;
const char* extensions[] = { ".ogg", ".wav", ".mp3" };
size_t extCount = sizeof(extensions) / sizeof(extensions[0]);
bool found = false;
// Check base name with each extension (non-numbered) if (!found)
{
int count = 0;
for (size_t extIdx = 0; extIdx < extCount; extIdx++) for (size_t extIdx = 0; extIdx < extCount; extIdx++)
{ {
char basePlusExt[256]; for (size_t i = 1; i < 32; i++)
sprintf_s(basePlusExt, "%s%s", basePath, extensions[extIdx]);
DWORD attr = GetFileAttributesA(basePlusExt);
if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
{ {
validPaths.push_back(basePlusExt); char numberedPath[256];
found = true; sprintf_s(numberedPath, "%s%d%s", basePath, i, extensions[extIdx]);
break; // non-numbered: only one base file needed
}
}
if (!found) DWORD attr = GetFileAttributesA(numberedPath);
{ if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
// Check numbered variants (e.g. sound1.ogg, sound2.ogg, ...)
for (size_t extIdx = 0; extIdx < extCount; extIdx++)
{
for (int i = 1; i < 32; i++)
{ {
char numberedPath[256]; count = i;
sprintf_s(numberedPath, "%s%d%s", basePath, i, extensions[extIdx]);
DWORD attr = GetFileAttributesA(numberedPath);
if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
{
validPaths.push_back(numberedPath);
}
} }
} }
} }
m_soundPathCache[iSound] = validPaths; if (count > 0)
{
int chosen = (rand() % count) + 1;
for (size_t extIdx = 0; extIdx < extCount; extIdx++)
{
char numberedPath[256];
sprintf_s(numberedPath, "%s%d%s", basePath, chosen, extensions[extIdx]);
if (validPaths.empty()) DWORD attr = GetFileAttributesA(numberedPath);
{ if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
sprintf_s(finalPath, "%s.wav", basePath); // fallback for debug print {
} sprintf_s(finalPath, "%s", numberedPath);
else found = true;
{ break;
const std::string& chosen = validPaths[rand() % validPaths.size()]; }
sprintf_s(finalPath, "%s", chosen.c_str()); }
if (!found)
{
sprintf_s(finalPath, "%s%d.wav", basePath, chosen);
}
} }
} }
@@ -558,7 +546,7 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, floa
if (ma_sound_init_from_file( if (ma_sound_init_from_file(
&m_engine, &m_engine,
finalPath, finalPath,
MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_ASYNC, MA_SOUND_FLAG_ASYNC,
nullptr, nullptr,
nullptr, nullptr,
&s->sound) != MA_SUCCESS) &s->sound) != MA_SUCCESS)
@@ -617,40 +605,24 @@ void SoundEngine::playUI(int iSound, float volume, float pitch)
sprintf_s(basePath, "Windows64Media/Sound/%s/%s", soundDir, ConvertSoundPathToName(name)); sprintf_s(basePath, "Windows64Media/Sound/%s/%s", soundDir, ConvertSoundPathToName(name));
char finalPath[256]; char finalPath[256];
sprintf_s(finalPath, "%s.wav", basePath);
// Check UI sound path cache first const char* extensions[] = { ".ogg", ".wav", ".mp3" };
auto cacheIt = m_uiSoundPathCache.find(iSound); size_t count = sizeof(extensions) / sizeof(extensions[0]);
if (cacheIt != m_uiSoundPathCache.end()) bool found = false;
for (size_t i = 0; i < count; i++)
{ {
if (cacheIt->second.empty()) sprintf_s(finalPath, "%s%s", basePath, extensions[i]);
if (FileExists(finalPath))
{ {
app.DebugPrintf("No sound file found for UI sound (cached): %s\n", basePath); found = true;
return; break;
} }
sprintf_s(finalPath, "%s", cacheIt->second.c_str());
} }
else if (!found)
{ {
// Cache miss — probe filesystem and store result app.DebugPrintf("No sound file found for UI sound: %s\n", basePath);
const char* extensions[] = { ".ogg", ".wav", ".mp3" }; return;
size_t count = sizeof(extensions) / sizeof(extensions[0]);
bool found = false;
for (size_t i = 0; i < count; i++)
{
sprintf_s(finalPath, "%s%s", basePath, extensions[i]);
if (FileExists(finalPath))
{
found = true;
break;
}
}
if (!found)
{
m_uiSoundPathCache[iSound] = ""; // cache negative result
app.DebugPrintf("No sound file found for UI sound: %s\n", basePath);
return;
}
m_uiSoundPathCache[iSound] = finalPath;
} }
MiniAudioSound* s = new MiniAudioSound(); MiniAudioSound* s = new MiniAudioSound();
@@ -664,7 +636,7 @@ void SoundEngine::playUI(int iSound, float volume, float pitch)
if (ma_sound_init_from_file( if (ma_sound_init_from_file(
&m_engine, &m_engine,
finalPath, finalPath,
MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_ASYNC, MA_SOUND_FLAG_ASYNC,
nullptr, nullptr,
nullptr, nullptr,
&s->sound) != MA_SUCCESS) &s->sound) != MA_SUCCESS)
@@ -817,46 +789,6 @@ int SoundEngine::GetRandomishTrack(int iStart,int iEnd)
app.DebugPrintf("Select track %d\n",iVal); app.DebugPrintf("Select track %d\n",iVal);
return iVal; return iVal;
} }
/////////////////////////////////////////////
//
// getOverworldMusicID - selects overworld music based on game mode
//
/////////////////////////////////////////////
int SoundEngine::getOverworldMusicID(Minecraft *pMinecraft)
{
#ifndef _XBOX
// Check if any local player is in creative mode
bool isCreative = false;
for(unsigned int i = 0; i < MAX_LOCAL_PLAYERS; i++)
{
if(pMinecraft->localplayers[i] != nullptr && pMinecraft->localgameModes[i] != nullptr)
{
GameType *mode = pMinecraft->localgameModes[i]->getLocalPlayerMode();
if(mode != nullptr && mode->isCreative())
{
isCreative = true;
break;
}
}
}
if(isCreative)
{
// Creative: survival tracks + creative tracks
int survivalCount = m_iStream_Overworld_Max - m_iStream_Overworld_Min + 1;
int creativeCount = m_iStream_Creative_Max - m_iStream_Creative_Min + 1;
int pick = random->nextInt(survivalCount + creativeCount);
if(pick < survivalCount)
return GetRandomishTrack(m_iStream_Overworld_Min, m_iStream_Overworld_Max);
else
return GetRandomishTrack(m_iStream_Creative_Min, m_iStream_Creative_Max);
}
#endif
// Survival/Adventure: survival tracks only
return GetRandomishTrack(m_iStream_Overworld_Min, m_iStream_Overworld_Max);
}
///////////////////////////////////////////// /////////////////////////////////////////////
// //
// getMusicID // getMusicID
@@ -864,33 +796,29 @@ int SoundEngine::getOverworldMusicID(Minecraft *pMinecraft)
///////////////////////////////////////////// /////////////////////////////////////////////
int SoundEngine::getMusicID(int iDomain) int SoundEngine::getMusicID(int iDomain)
{ {
int result=-1; int iRandomVal=0;
Minecraft *pMinecraft=Minecraft::GetInstance(); Minecraft *pMinecraft=Minecraft::GetInstance();
// Before the game has started? // Before the game has started?
if(pMinecraft==nullptr) if(pMinecraft==nullptr)
{ {
#ifndef _XBOX // any track from the overworld
// Title screen: play menu music return GetRandomishTrack(m_iStream_Overworld_Min,m_iStream_Overworld_Max);
result = GetRandomishTrack(m_iStream_Menu_Min,m_iStream_Menu_Max);
#else
result = GetRandomishTrack(m_iStream_Overworld_Min,m_iStream_Overworld_Max);
#endif
} }
else if(pMinecraft->skins->isUsingDefaultSkin())
if(pMinecraft->skins->isUsingDefaultSkin())
{ {
switch(iDomain) switch(iDomain)
{ {
case LevelData::DIMENSION_END: case LevelData::DIMENSION_END:
// the end isn't random - it has different music depending on whether the dragon is alive or not, but we've not added the dead dragon music yet // the end isn't random - it has different music depending on whether the dragon is alive or not, but we've not added the dead dragon music yet
result = m_iStream_End_Min; return m_iStream_End_Min;
break;
case LevelData::DIMENSION_NETHER: case LevelData::DIMENSION_NETHER:
result = GetRandomishTrack(m_iStream_Nether_Min,m_iStream_Nether_Max); return GetRandomishTrack(m_iStream_Nether_Min,m_iStream_Nether_Max);
break; //return m_iStream_Nether_Min + random->nextInt(m_iStream_Nether_Max-m_iStream_Nether_Min);
default: //overworld default: //overworld
result = getOverworldMusicID(pMinecraft); //return m_iStream_Overworld_Min + random->nextInt(m_iStream_Overworld_Max-m_iStream_Overworld_Min);
break; return GetRandomishTrack(m_iStream_Overworld_Min,m_iStream_Overworld_Max);
} }
} }
else else
@@ -899,22 +827,15 @@ int SoundEngine::getMusicID(int iDomain)
switch(iDomain) switch(iDomain)
{ {
case LevelData::DIMENSION_END: case LevelData::DIMENSION_END:
result = GetRandomishTrack(m_iStream_End_Min,m_iStream_End_Max); return GetRandomishTrack(m_iStream_End_Min,m_iStream_End_Max);
break;
case LevelData::DIMENSION_NETHER: case LevelData::DIMENSION_NETHER:
result = GetRandomishTrack(m_iStream_Nether_Min,m_iStream_Nether_Max); //return m_iStream_Nether_Min + random->nextInt(m_iStream_Nether_Max-m_iStream_Nether_Min);
break; return GetRandomishTrack(m_iStream_Nether_Min,m_iStream_Nether_Max);
default: //overworld default: //overworld
result = getOverworldMusicID(pMinecraft); //return m_iStream_Overworld_Min + random->nextInt(m_iStream_Overworld_Max-m_iStream_Overworld_Min);
break; return GetRandomishTrack(m_iStream_Overworld_Min,m_iStream_Overworld_Max);
} }
} }
#ifdef _DEBUG
if(result >= 0 && result < eStream_Max)
app.DebugPrintf("getMusicID: selected track '%s' (id=%d, domain=%d)\n", m_szStreamFileA[result], result, iDomain);
#endif
return result;
} }
///////////////////////////////////////////// /////////////////////////////////////////////
+5 -15
View File
@@ -1,13 +1,10 @@
#pragma once #pragma once
class Minecraft;
class Mob; class Mob;
class Options; class Options;
using namespace std; using namespace std;
#include "..\..\Minecraft.World\SoundTypes.h" #include "../../Minecraft.World/SoundTypes.h"
#include "miniaudio.h" #include "miniaudio.h"
#include <unordered_map>
#include <string>
constexpr float SFX_3D_MIN_DISTANCE = 1.0f; constexpr float SFX_3D_MIN_DISTANCE = 1.0f;
constexpr float SFX_3D_MAX_DISTANCE = 16.0f; constexpr float SFX_3D_MAX_DISTANCE = 16.0f;
@@ -26,10 +23,8 @@ enum eMUSICFILES
eStream_Overworld_hal4, eStream_Overworld_hal4,
eStream_Overworld_nuance1, eStream_Overworld_nuance1,
eStream_Overworld_nuance2, eStream_Overworld_nuance2,
eStream_Overworld_piano1,
eStream_Overworld_piano2,
eStream_Overworld_piano3, // <-- make piano3 the last survival overworld one
#ifndef _XBOX #ifndef _XBOX
// Add the new music tracks
eStream_Overworld_Creative1, eStream_Overworld_Creative1,
eStream_Overworld_Creative2, eStream_Overworld_Creative2,
eStream_Overworld_Creative3, eStream_Overworld_Creative3,
@@ -41,6 +36,9 @@ enum eMUSICFILES
eStream_Overworld_Menu3, eStream_Overworld_Menu3,
eStream_Overworld_Menu4, eStream_Overworld_Menu4,
#endif #endif
eStream_Overworld_piano1,
eStream_Overworld_piano2,
eStream_Overworld_piano3, // <-- make piano3 the last overworld one
// Nether // Nether
eStream_Nether1, eStream_Nether1,
eStream_Nether2, eStream_Nether2,
@@ -136,7 +134,6 @@ public:
bool isStreamingWavebankReady(); // 4J Added bool isStreamingWavebankReady(); // 4J Added
int getMusicID(int iDomain); int getMusicID(int iDomain);
int getMusicID(const wstring& name); int getMusicID(const wstring& name);
int getOverworldMusicID(Minecraft *pMinecraft);
void SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1); void SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1);
void updateMiniAudio(); void updateMiniAudio();
void playMusicUpdate(); void playMusicUpdate();
@@ -188,15 +185,8 @@ private:
int m_iStream_Nether_Min,m_iStream_Nether_Max; int m_iStream_Nether_Min,m_iStream_Nether_Max;
int m_iStream_End_Min,m_iStream_End_Max; int m_iStream_End_Min,m_iStream_End_Max;
int m_iStream_CD_1; int m_iStream_CD_1;
#ifndef _XBOX
int m_iStream_Creative_Min, m_iStream_Creative_Max;
int m_iStream_Menu_Min, m_iStream_Menu_Max;
#endif
bool *m_bHeardTrackA; bool *m_bHeardTrackA;
std::unordered_map<int, std::vector<std::string>> m_soundPathCache; // play(): sound ID → all valid variant paths
std::unordered_map<int, std::string> m_uiSoundPathCache; // playUI(): sound ID → resolved path
#ifdef __ORBIS__ #ifdef __ORBIS__
int32_t m_hBGMAudio; int32_t m_hBGMAudio;
#endif #endif
+38 -40
View File
@@ -6,14 +6,14 @@
const WCHAR *ConsoleSoundEngine::wchSoundNames[eSoundType_MAX]= const WCHAR *ConsoleSoundEngine::wchSoundNames[eSoundType_MAX]=
{ {
L"mob.chicken.say", // eSoundType_MOB_CHICKEN_AMBIENT L"mob.chicken.say", // eSoundType_MOB_CHICKEN_AMBIENT
L"mob.chicken.hurt", // eSoundType_MOB_CHICKEN_HURT L"mob.chicken.hurt", // eSoundType_MOB_CHICKEN_HURT
L"mob.chicken.plop", // eSoundType_MOB_CHICKENPLOP L"mob.chicken.plop", // eSoundType_MOB_CHICKENPLOP
L"mob.cow.say", // eSoundType_MOB_COW_AMBIENT L"mob.cow.say", // eSoundType_MOB_COW_AMBIENT
L"mob.cow.hurt", // eSoundType_MOB_COW_HURT L"mob.cow.hurt", // eSoundType_MOB_COW_HURT
L"mob.pig.say", // eSoundType_MOB_PIG_AMBIENT L"mob.pig.say", // eSoundType_MOB_PIG_AMBIENT
L"mob.pig.death", // eSoundType_MOB_PIG_DEATH L"mob.pig.death", // eSoundType_MOB_PIG_DEATH
L"mob.sheep.say", // eSoundType_MOB_SHEEP_AMBIENT L"mob.sheep.say", // eSoundType_MOB_SHEEP_AMBIENT
L"mob.wolf.growl", // eSoundType_MOB_WOLF_GROWL L"mob.wolf.growl", // eSoundType_MOB_WOLF_GROWL
L"mob.wolf.whine", // eSoundType_MOB_WOLF_WHINE L"mob.wolf.whine", // eSoundType_MOB_WOLF_WHINE
L"mob.wolf.panting", // eSoundType_MOB_WOLF_PANTING L"mob.wolf.panting", // eSoundType_MOB_WOLF_PANTING
@@ -43,15 +43,15 @@ const WCHAR *ConsoleSoundEngine::wchSoundNames[eSoundType_MAX]=
L"mob.silverfish.step", // eSoundType_MOB_SILVERFISH_STEP, L"mob.silverfish.step", // eSoundType_MOB_SILVERFISH_STEP,
L"mob.skeleton", // eSoundType_MOB_SKELETON_AMBIENT, L"mob.skeleton", // eSoundType_MOB_SKELETON_AMBIENT,
L"mob.skeletonhurt", // eSoundType_MOB_SKELETON_HURT, L"mob.skeletonhurt", // eSoundType_MOB_SKELETON_HURT,
L"mob.spider.say", // eSoundType_MOB_SPIDER_AMBIENT, L"mob.spider.say", // eSoundType_MOB_SPIDER_AMBIENT,
L"mob.spider.death", // eSoundType_MOB_SPIDER_DEATH, L"mob.spider.death", // eSoundType_MOB_SPIDER_DEATH,
L"mob.slime", // eSoundType_MOB_SLIME, L"mob.slime", // eSoundType_MOB_SLIME,
L"mob.slime.attack", // eSoundType_MOB_SLIME_ATTACK, L"mob.slime.attack", // eSoundType_MOB_SLIME_ATTACK,
L"mob.creeper.say", // eSoundType_MOB_CREEPER_HURT, L"mob.creeper.say", // eSoundType_MOB_CREEPER_HURT,
L"mob.creeper.death", // eSoundType_MOB_CREEPER_DEATH, L"mob.creeper.death", // eSoundType_MOB_CREEPER_DEATH,
L"mob.zombie.say", // eSoundType_MOB_ZOMBIE_AMBIENT, L"mob.zombie.say", // eSoundType_MOB_ZOMBIE_AMBIENT,
L"mob.zombie.hurt", // eSoundType_MOB_ZOMBIE_HURT, L"mob.zombie.hurt", // eSoundType_MOB_ZOMBIE_HURT,
L"mob.zombie.death", // eSoundType_MOB_ZOMBIE_DEATH, L"mob.zombie.death", // eSoundType_MOB_ZOMBIE_DEATH,
L"mob.zombie.wood", // eSoundType_MOB_ZOMBIE_WOOD, L"mob.zombie.wood", // eSoundType_MOB_ZOMBIE_WOOD,
L"mob.zombie.woodbreak", // eSoundType_MOB_ZOMBIE_WOOD_BREAK, L"mob.zombie.woodbreak", // eSoundType_MOB_ZOMBIE_WOOD_BREAK,
L"mob.zombie.metal", // eSoundType_MOB_ZOMBIE_METAL, L"mob.zombie.metal", // eSoundType_MOB_ZOMBIE_METAL,
@@ -61,7 +61,7 @@ const WCHAR *ConsoleSoundEngine::wchSoundNames[eSoundType_MAX]=
L"mob.cat.purreow", // eSoundType_MOB_CAT_PURREOW L"mob.cat.purreow", // eSoundType_MOB_CAT_PURREOW
L"mob.cat.meow", // eSoundType_MOB_CAT_MEOW L"mob.cat.meow", // eSoundType_MOB_CAT_MEOW
// 4J-PB - correct the name of the event for hitting ocelots // 4J-PB - correct the name of the event for hitting ocelots
L"mob.cat.hit", // eSoundType_MOB_CAT_HITT L"mob.cat.hit", // eSoundType_MOB_CAT_HITT
// L"mob.irongolem.throw", // eSoundType_MOB_IRONGOLEM_THROW // L"mob.irongolem.throw", // eSoundType_MOB_IRONGOLEM_THROW
// L"mob.irongolem.hit", // eSoundType_MOB_IRONGOLEM_HIT // L"mob.irongolem.hit", // eSoundType_MOB_IRONGOLEM_HIT
// L"mob.irongolem.death", // eSoundType_MOB_IRONGOLEM_DEATH // L"mob.irongolem.death", // eSoundType_MOB_IRONGOLEM_DEATH
@@ -86,7 +86,7 @@ const WCHAR *ConsoleSoundEngine::wchSoundNames[eSoundType_MAX]=
L"random.door_close", // eSoundType_RANDOM_DOOR_CLOSE, L"random.door_close", // eSoundType_RANDOM_DOOR_CLOSE,
L"ambient.weather.rain", // eSoundType_AMBIENT_WEATHER_RAIN, L"ambient.weather.rain", // eSoundType_AMBIENT_WEATHER_RAIN,
L"ambient.weather.thunder", // eSoundType_AMBIENT_WEATHER_THUNDER, L"ambient.weather.thunder", // eSoundType_AMBIENT_WEATHER_THUNDER,
L"ambient.cave", // eSoundType_CAVE_CAVE, DON'T USE FOR XBOX 360!!! L"ambient.cave", // eSoundType_CAVE_CAVE, DON'T USE FOR XBOX 360!!!
#ifdef _XBOX #ifdef _XBOX
L"ambient.cave.cave2", // eSoundType_CAVE_CAVE2 - removed the two sounds that were at 192k in the first ambient cave event L"ambient.cave.cave2", // eSoundType_CAVE_CAVE2 - removed the two sounds that were at 192k in the first ambient cave event
#endif #endif
@@ -187,30 +187,30 @@ const WCHAR *ConsoleSoundEngine::wchSoundNames[eSoundType_MAX]=
L"liquid.swim", //eSoundType_LIQUID_SWIM, L"liquid.swim", //eSoundType_LIQUID_SWIM,
L"Mob.horse.land", //eSoundType_MOB_HORSE_LAND, L"mob.horse.land", //eSoundType_MOB_HORSE_LAND,
L"Mob.horse.armor", //eSoundType_MOB_HORSE_ARMOR, L"mob.horse.armor", //eSoundType_MOB_HORSE_ARMOR,
L"Mob.horse.leather", //eSoundType_MOB_HORSE_LEATHER, L"mob.horse.leather", //eSoundType_MOB_HORSE_LEATHER,
L"Mob.horse.zombie.death", //eSoundType_MOB_HORSE_ZOMBIE_DEATH, L"mob.horse.zombie.death", //eSoundType_MOB_HORSE_ZOMBIE_DEATH,
L"Mob.horse.skeleton.death", //eSoundType_MOB_HORSE_SKELETON_DEATH, L"mob.horse.skeleton.death", //eSoundType_MOB_HORSE_SKELETON_DEATH,
L"Mob.horse.donkey.death", //eSoundType_MOB_HORSE_DONKEY_DEATH, L"mob.horse.donkey.death", //eSoundType_MOB_HORSE_DONKEY_DEATH,
L"Mob.horse.death", //eSoundType_MOB_HORSE_DEATH, L"mob.horse.death", //eSoundType_MOB_HORSE_DEATH,
L"Mob.horse.zombie.hit", //eSoundType_MOB_HORSE_ZOMBIE_HIT, L"mob.horse.zombie.hit", //eSoundType_MOB_HORSE_ZOMBIE_HIT,
L"Mob.horse.skeleton.hit", //eSoundType_MOB_HORSE_SKELETON_HIT, L"mob.horse.skeleton.hit", //eSoundType_MOB_HORSE_SKELETON_HIT,
L"Mob.horse.donkey.hit", //eSoundType_MOB_HORSE_DONKEY_HIT, L"mob.horse.donkey.hit", //eSoundType_MOB_HORSE_DONKEY_HIT,
L"Mob.horse.hit", //eSoundType_MOB_HORSE_HIT, L"mob.horse.hit", //eSoundType_MOB_HORSE_HIT,
L"Mob.horse.zombie.idle", //eSoundType_MOB_HORSE_ZOMBIE_IDLE, L"mob.horse.zombie.idle", //eSoundType_MOB_HORSE_ZOMBIE_IDLE,
L"Mob.horse.skeleton.idle", //eSoundType_MOB_HORSE_SKELETON_IDLE, L"mob.horse.skeleton.idle", //eSoundType_MOB_HORSE_SKELETON_IDLE,
L"Mob.horse.donkey.idle", //eSoundType_MOB_HORSE_DONKEY_IDLE, L"mob.horse.donkey.idle", //eSoundType_MOB_HORSE_DONKEY_IDLE,
L"Mob.horse.idle", //eSoundType_MOB_HORSE_IDLE, L"mob.horse.idle", //eSoundType_MOB_HORSE_IDLE,
L"Mob.horse.donkey.angry", //eSoundType_MOB_HORSE_DONKEY_ANGRY, L"mob.horse.donkey.angry", //eSoundType_MOB_HORSE_DONKEY_ANGRY,
L"Mob.horse.angry", //eSoundType_MOB_HORSE_ANGRY, L"mob.horse.angry", //eSoundType_MOB_HORSE_ANGRY,
L"Mob.horse.gallop", //eSoundType_MOB_HORSE_GALLOP, L"mob.horse.gallop", //eSoundType_MOB_HORSE_GALLOP,
L"Mob.horse.breathe", //eSoundType_MOB_HORSE_BREATHE, L"mob.horse.breathe", //eSoundType_MOB_HORSE_BREATHE,
L"Mob.horse.wood", //eSoundType_MOB_HORSE_WOOD, L"mob.horse.wood", //eSoundType_MOB_HORSE_WOOD,
L"Mob.horse.soft", //eSoundType_MOB_HORSE_SOFT, L"mob.horse.soft", //eSoundType_MOB_HORSE_SOFT,
L"Mob.horse.jump", //eSoundType_MOB_HORSE_JUMP, L"mob.horse.jump", //eSoundType_MOB_HORSE_JUMP,
L"mob.witch.ambient", //eSoundType_MOB_WITCH_IDLE, L"mob.witch.ambient", //eSoundType_MOB_WITCH_IDLE,
L"mob.witch.hurt", //eSoundType_MOB_WITCH_HURT, L"mob.witch.hurt", //eSoundType_MOB_WITCH_HURT,
L"mob.witch.death", //eSoundType_MOB_WITCH_DEATH, L"mob.witch.death", //eSoundType_MOB_WITCH_DEATH,
@@ -223,8 +223,6 @@ const WCHAR *ConsoleSoundEngine::wchSoundNames[eSoundType_MAX]=
// 4J-PB - Some sounds were updated, but we can't do that for the 360 or we have to do a new sound bank // 4J-PB - Some sounds were updated, but we can't do that for the 360 or we have to do a new sound bank
// instead, we'll add the sounds as new ones and change the code to reference them // instead, we'll add the sounds as new ones and change the code to reference them
L"fire.new_ignite", L"fire.new_ignite",
L"damage.critical", //eSoundType_DAMAGE_CRITICAL,
}; };
@@ -45,7 +45,6 @@ enum eAward
eAward_bookcase, eAward_bookcase,
#endif #endif
eAward_adventuringTime, eAward_adventuringTime,
eAward_repopulation, eAward_repopulation,
//eAward_porkChop, //eAward_porkChop,
+15 -122
View File
@@ -188,7 +188,6 @@ CMinecraftApp::CMinecraftApp()
#endif #endif
ZeroMemory(m_playerColours,MINECRAFT_NET_MAX_PLAYERS); ZeroMemory(m_playerColours,MINECRAFT_NET_MAX_PLAYERS);
ZeroMemory(m_playerMapIcons,MINECRAFT_NET_MAX_PLAYERS);
m_iDLCOfferC=0; m_iDLCOfferC=0;
m_bAllDLCContentRetrieved=true; m_bAllDLCContentRetrieved=true;
@@ -208,8 +207,6 @@ CMinecraftApp::CMinecraftApp()
m_dwRequiredTexturePackID=0; m_dwRequiredTexturePackID=0;
m_bResetNether=false; m_bResetNether=false;
m_seedOverride = 0;
m_hasSeedOverride = false;
#ifdef _XBOX #ifdef _XBOX
// m_bTransferSavesToXboxOne=false; // m_bTransferSavesToXboxOne=false;
@@ -791,7 +788,7 @@ static void Win64_GetSettingsPath(char *outPath, DWORD size)
GetModuleFileNameA(nullptr, outPath, size); GetModuleFileNameA(nullptr, outPath, size);
char *lastSlash = strrchr(outPath, '\\'); char *lastSlash = strrchr(outPath, '\\');
if (lastSlash) *(lastSlash + 1) = '\0'; if (lastSlash) *(lastSlash + 1) = '\0';
strncat_s(outPath, size, "settings.dat", _TRUNCATE); strncat_s(outPath, size, "Windows64/Settings/settings.dat", _TRUNCATE);
} }
static void Win64_SaveSettings(GAME_SETTINGS *gs) static void Win64_SaveSettings(GAME_SETTINGS *gs)
{ {
@@ -842,8 +839,11 @@ void CMinecraftApp::InitGameSettings()
memset(pProfileSettings,0,sizeof(C_4JProfile::PROFILESETTINGS)); memset(pProfileSettings,0,sizeof(C_4JProfile::PROFILESETTINGS));
SetDefaultOptions(pProfileSettings,i); SetDefaultOptions(pProfileSettings,i);
Win64_LoadSettings(GameSettingsA[i]); Win64_LoadSettings(GameSettingsA[i]);
app.SetMinecraftLocale(i, GameSettingsA[i]->ucLocale); app.DebugPrintf("Loaded language: %d\n", GameSettingsA[i]->ucLanguage);
app.loadStringTable(); app.SetMinecraftLanguage(i, GameSettingsA[i]->ucLanguage);
app.SetMinecraftLocale(i, GameSettingsA[i]->ucLocale);
app.loadStringTable();
ApplyGameSettingsChanged(i); ApplyGameSettingsChanged(i);
#elif defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ #elif defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__
C4JStorage::PROFILESETTINGS *pProfileSettings=StorageManager.GetDashboardProfileSettings(i); C4JStorage::PROFILESETTINGS *pProfileSettings=StorageManager.GetDashboardProfileSettings(i);
@@ -851,12 +851,6 @@ void CMinecraftApp::InitGameSettings()
SetDefaultOptions(pProfileSettings,i,false); SetDefaultOptions(pProfileSettings,i,false);
#endif #endif
Minecraft* minecraft = Minecraft::GetInstance();
if (minecraft != nullptr && minecraft->stats[i] != nullptr)
{
minecraft->stats[i]->clear();
minecraft->stats[i]->parse(GameSettingsA[i]);
}
} }
} }
@@ -866,6 +860,7 @@ int CMinecraftApp::SetDefaultOptions(C4JStorage::PROFILESETTINGS *pSettings,cons
int CMinecraftApp::SetDefaultOptions(C_4JProfile::PROFILESETTINGS *pSettings,const int iPad) int CMinecraftApp::SetDefaultOptions(C_4JProfile::PROFILESETTINGS *pSettings,const int iPad)
#endif #endif
{ {
app.DebugPrintf("SetDefaultOptions language BEFORE: %d\n", GameSettingsA[iPad]->ucLanguage);
SetGameSettings(iPad,eGameSetting_MusicVolume,DEFAULT_VOLUME_LEVEL); SetGameSettings(iPad,eGameSetting_MusicVolume,DEFAULT_VOLUME_LEVEL);
SetGameSettings(iPad,eGameSetting_SoundFXVolume,DEFAULT_VOLUME_LEVEL); SetGameSettings(iPad,eGameSetting_SoundFXVolume,DEFAULT_VOLUME_LEVEL);
SetGameSettings(iPad,eGameSetting_RenderDistance,16); SetGameSettings(iPad,eGameSetting_RenderDistance,16);
@@ -950,6 +945,7 @@ int CMinecraftApp::SetDefaultOptions(C_4JProfile::PROFILESETTINGS *pSettings,con
if (!app.GetGameStarted()) if (!app.GetGameStarted())
{ {
GameSettingsA[iPad]->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language GameSettingsA[iPad]->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language
app.DebugPrintf("SetDefaultOptions language AFTER: %d\n", GameSettingsA[iPad]->ucLanguage);
GameSettingsA[iPad]->ucLocale = MINECRAFT_LANGUAGE_DEFAULT; // use the system locale GameSettingsA[iPad]->ucLocale = MINECRAFT_LANGUAGE_DEFAULT; // use the system locale
} }
@@ -1391,7 +1387,6 @@ void CMinecraftApp::ApplyGameSettingsChanged(int iPad)
ActionGameSettings(iPad,eGameSetting_AnimatedCharacter); ActionGameSettings(iPad,eGameSetting_AnimatedCharacter);
ActionGameSettings(iPad,eGameSetting_PS3_EULA_Read); ActionGameSettings(iPad,eGameSetting_PS3_EULA_Read);
ActionGameSettings(iPad,eGameSetting_VSync);
} }
@@ -1627,22 +1622,6 @@ void CMinecraftApp::ActionGameSettings(int iPad,eGameSetting eVal)
case eGameSetting_PSVita_NetworkModeAdhoc: case eGameSetting_PSVita_NetworkModeAdhoc:
//nothing to do here //nothing to do here
break; break;
case eGameSetting_VSync:
#ifdef _WINDOWS64
{
extern bool g_bVSync;
g_bVSync = (GetGameSettings(iPad, eGameSetting_VSync) != 0);
}
#endif
break;
case eGameSetting_ExclusiveFullscreen:
#ifdef _WINDOWS64
{
extern void SetExclusiveFullscreen(bool enabled);
SetExclusiveFullscreen(GetGameSettings(iPad, eGameSetting_ExclusiveFullscreen) != 0);
}
#endif
break;
} }
} }
@@ -2354,38 +2333,6 @@ void CMinecraftApp::SetGameSettings(int iPad,eGameSetting eVal,unsigned char ucV
} }
break; break;
case eGameSetting_VSync:
if(((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_VSYNC)>>24)!=(ucVal&0x01))
{
if(ucVal==1)
{
GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_VSYNC;
}
else
{
GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_VSYNC;
}
ActionGameSettings(iPad,eVal);
GameSettingsA[iPad]->bSettingsChanged=true;
}
break;
case eGameSetting_ExclusiveFullscreen:
if(((GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_EXCLUSIVEFULLSCREEN)>>25)!=(ucVal&0x01))
{
if(ucVal==1)
{
GameSettingsA[iPad]->uiBitmaskValues|=GAMESETTING_EXCLUSIVEFULLSCREEN;
}
else
{
GameSettingsA[iPad]->uiBitmaskValues&=~GAMESETTING_EXCLUSIVEFULLSCREEN;
}
ActionGameSettings(iPad,eVal);
GameSettingsA[iPad]->bSettingsChanged=true;
}
break;
} }
} }
@@ -2521,12 +2468,6 @@ unsigned char CMinecraftApp::GetGameSettings(int iPad,eGameSetting eVal)
case eGameSetting_PSVita_NetworkModeAdhoc: case eGameSetting_PSVita_NetworkModeAdhoc:
return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PSVITANETWORKMODEADHOC)>>17; return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_PSVITANETWORKMODEADHOC)>>17;
case eGameSetting_VSync:
return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_VSYNC)>>24;
case eGameSetting_ExclusiveFullscreen:
return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_EXCLUSIVEFULLSCREEN)>>25;
} }
return 0; return 0;
} }
@@ -4713,7 +4654,6 @@ int CMinecraftApp::SignoutExitWorldThreadProc( void* lpParameter )
break; break;
case DisconnectPacket::eDisconnect_OutdatedClient: case DisconnectPacket::eDisconnect_OutdatedClient:
exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD; exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD;
break;
default: default:
exitReasonStringId = IDS_DISCONNECTED; exitReasonStringId = IDS_DISCONNECTED;
} }
@@ -6663,11 +6603,12 @@ wstring CMinecraftApp::FormatHTMLString(int iPad, const wstring &desc, int shado
//found list of html escapes at https://stackoverflow.com/questions/7381974/which-characters-need-to-be-escaped-in-html //found list of html escapes at https://stackoverflow.com/questions/7381974/which-characters-need-to-be-escaped-in-html
wstring CMinecraftApp::EscapeHTMLString(const wstring& desc) wstring CMinecraftApp::EscapeHTMLString(const wstring& desc)
{ {
static std::unordered_map<wchar_t, wchar_t*> replacementMap = { static std::unordered_map<wchar_t, wchar_t*> replacementMap = {
{L'&', L"&amp;"}, {L'&', L"&amp;"},
{L'<', L"&lt;"}, {L'<', L"&lt;"},
{L'>', L"&gt;"}, {L'>', L"&gt;"},
}; {L'\"', L"&quot;"},
};
wstring finalString = L""; wstring finalString = L"";
for (int i = 0; i < desc.size(); i++) { for (int i = 0; i < desc.size(); i++) {
@@ -6738,8 +6679,6 @@ wstring CMinecraftApp::FormatChatMessage(const wstring& desc, bool applyStyling)
results = replaceAll(results, L"§f", replacements); results = replaceAll(results, L"§f", replacements);
results = replaceAll(results, L"§r", replacements); //we only support color so reset is the same as white color results = replaceAll(results, L"§r", replacements); //we only support color so reset is the same as white color
results = replaceAll(results, L"'", L"\u2019");
if (applyStyling) { if (applyStyling) {
std::wsmatch match; std::wsmatch match;
while (std::regex_search(results, match, IDS_Pattern)) { while (std::regex_search(results, match, IDS_Pattern)) {
@@ -8240,16 +8179,6 @@ void CMinecraftApp::SetGameHostOption(unsigned int &uiHostSettings, eGameHostOpt
uiHostSettings&=~GAME_HOST_OPTION_BITMASK_WORLDSIZE; uiHostSettings&=~GAME_HOST_OPTION_BITMASK_WORLDSIZE;
uiHostSettings|=(GAME_HOST_OPTION_BITMASK_WORLDSIZE & (uiVal<<GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT)); uiHostSettings|=(GAME_HOST_OPTION_BITMASK_WORLDSIZE & (uiVal<<GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT));
break; break;
case eGameHostOption_Hardcore: // 4J Added - for hardcore mode
if(uiVal!=0)
{
uiHostSettings |= GAME_HOST_OPTION_BITMASK_HARDCORE;
}
else
{
uiHostSettings &= ~GAME_HOST_OPTION_BITMASK_HARDCORE;
}
break;
case eGameHostOption_All: case eGameHostOption_All:
uiHostSettings=uiVal; uiHostSettings=uiVal;
break; break;
@@ -8351,9 +8280,6 @@ unsigned int CMinecraftApp::GetGameHostOption(unsigned int uiHostSettings, eGame
case eGameHostOption_DoDaylightCycle: case eGameHostOption_DoDaylightCycle:
return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE); return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE);
break; break;
case eGameHostOption_Hardcore: // 4J Added - for hardcore mode
return (uiHostSettings&GAME_HOST_OPTION_BITMASK_HARDCORE) ? 1 : 0;
break;
} }
return false; return false;
@@ -8632,39 +8558,6 @@ short CMinecraftApp::GetPlayerColour(BYTE networkSmallId)
return index; return index;
} }
void CMinecraftApp::SetPlayerMapIcon(const wchar_t* name, char icon)
{
if (name == nullptr) return;
// Update existing entry or use first empty slot
int emptySlot = -1;
for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i)
{
if (m_playerMapIcons[i].name[0] != 0 && _wcsicmp(m_playerMapIcons[i].name, name) == 0)
{
m_playerMapIcons[i].icon = icon;
return;
}
if (emptySlot < 0 && m_playerMapIcons[i].name[0] == 0)
emptySlot = i;
}
if (emptySlot >= 0)
{
wcsncpy_s(m_playerMapIcons[emptySlot].name, 32, name, _TRUNCATE);
m_playerMapIcons[emptySlot].icon = icon;
}
}
char CMinecraftApp::GetPlayerMapIconByName(const wchar_t* name)
{
if (name == nullptr) return 0;
for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i)
{
if (m_playerMapIcons[i].name[0] != 0 && _wcsicmp(m_playerMapIcons[i].name, name) == 0)
return m_playerMapIcons[i].icon;
}
return 0;
}
unsigned int CMinecraftApp::GetPlayerPrivileges(BYTE networkSmallId) unsigned int CMinecraftApp::GetPlayerPrivileges(BYTE networkSmallId)
{ {
@@ -9806,7 +9699,7 @@ bool CMinecraftApp::IsLocalMultiplayerAvailable()
// 4J-PB - language and locale function // 4J-PB - language and locale function
// getLocale from LCEN Client pasted ig
void CMinecraftApp::getLocale(vector<wstring> &vecWstrLocales) void CMinecraftApp::getLocale(vector<wstring> &vecWstrLocales)
{ {
#ifdef _WINDOWS64 #ifdef _WINDOWS64
+1 -16
View File
@@ -97,7 +97,7 @@ public:
*/ */
static const int GAME_DEFINED_PROFILE_DATA_BYTES = 2*972; // per user static const int GAME_DEFINED_PROFILE_DATA_BYTES = 2*972; // per user
#else #else
static const int GAME_DEFINED_PROFILE_DATA_BYTES = 2*972; // per user static const int GAME_DEFINED_PROFILE_DATA_BYTES = 3*972; // per user
#endif #endif
unsigned int uiGameDefinedDataChangedBitmask; unsigned int uiGameDefinedDataChangedBitmask;
@@ -708,8 +708,6 @@ private:
bool m_bGameNewWorldSizeUseMoat; bool m_bGameNewWorldSizeUseMoat;
unsigned int m_GameNewHellScale; unsigned int m_GameNewHellScale;
#endif #endif
int64_t m_seedOverride;
bool m_hasSeedOverride;
unsigned int FromBigEndian(unsigned int uiValue); unsigned int FromBigEndian(unsigned int uiValue);
public: public:
@@ -727,10 +725,6 @@ public:
void SetGameNewHellScale(unsigned int newScale) { m_GameNewHellScale = newScale; } void SetGameNewHellScale(unsigned int newScale) { m_GameNewHellScale = newScale; }
unsigned int GetGameNewHellScale() { return m_GameNewHellScale; } unsigned int GetGameNewHellScale() { return m_GameNewHellScale; }
#endif #endif
void SetSeedOverride(int64_t seed) { m_seedOverride = seed; m_hasSeedOverride = true; }
bool HasSeedOverride() { return m_hasSeedOverride; }
int64_t GetSeedOverride() { return m_seedOverride; }
void SetResetNether(bool bResetNether) {m_bResetNether=bResetNether;} void SetResetNether(bool bResetNether) {m_bResetNether=bResetNether;}
bool GetResetNether() {return m_bResetNether;} bool GetResetNether() {return m_bResetNether;}
bool CanRecordStatsAndAchievements(); bool CanRecordStatsAndAchievements();
@@ -755,14 +749,10 @@ public:
private: private:
BYTE m_playerColours[MINECRAFT_NET_MAX_PLAYERS]; // An array of QNet small-id's BYTE m_playerColours[MINECRAFT_NET_MAX_PLAYERS]; // An array of QNet small-id's
unsigned int m_playerGamePrivileges[MINECRAFT_NET_MAX_PLAYERS]; unsigned int m_playerGamePrivileges[MINECRAFT_NET_MAX_PLAYERS];
struct PlayerMapIconEntry { wchar_t name[32]; char icon; };
PlayerMapIconEntry m_playerMapIcons[MINECRAFT_NET_MAX_PLAYERS];
public: public:
void UpdatePlayerInfo(BYTE networkSmallId, SHORT playerColourIndex, unsigned int playerGamePrivileges); void UpdatePlayerInfo(BYTE networkSmallId, SHORT playerColourIndex, unsigned int playerGamePrivileges);
short GetPlayerColour(BYTE networkSmallId); short GetPlayerColour(BYTE networkSmallId);
void SetPlayerMapIcon(const wchar_t* name, char icon);
char GetPlayerMapIconByName(const wchar_t* name);
unsigned int GetPlayerPrivileges(BYTE networkSmallId); unsigned int GetPlayerPrivileges(BYTE networkSmallId);
wstring getEntityName(eINSTANCEOF type); wstring getEntityName(eINSTANCEOF type);
@@ -817,10 +807,6 @@ public:
void SetCorruptSaveDeleted(bool bVal) {m_bCorruptSaveDeleted=bVal;} void SetCorruptSaveDeleted(bool bVal) {m_bCorruptSaveDeleted=bVal;}
bool GetCorruptSaveDeleted(void) {return m_bCorruptSaveDeleted;} bool GetCorruptSaveDeleted(void) {return m_bCorruptSaveDeleted;}
// 4J Added: Store save folder name for hardcore world deletion on Win64
void SetCurrentSaveFolderName(const wstring& name) { m_currentSaveFolderName = name; }
const wstring& GetCurrentSaveFolderName() const { return m_currentSaveFolderName; }
void EnterSaveNotificationSection(); void EnterSaveNotificationSection();
void LeaveSaveNotificationSection(); void LeaveSaveNotificationSection();
private: private:
@@ -842,7 +828,6 @@ private:
CRITICAL_SECTION csAdditionalSkinBoxes; CRITICAL_SECTION csAdditionalSkinBoxes;
CRITICAL_SECTION csAnimOverrideBitmask; CRITICAL_SECTION csAnimOverrideBitmask;
bool m_bCorruptSaveDeleted; bool m_bCorruptSaveDeleted;
wstring m_currentSaveFolderName; // 4J Added: for hardcore world deletion on Win64
DWORD m_dwAdditionalModelParts[XUSER_MAX_COUNT]; DWORD m_dwAdditionalModelParts[XUSER_MAX_COUNT];
Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 B

Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -38220,56 +38220,6 @@
<Time>19</Time> <Time>19</Time>
<Command>stop</Command> <Command>stop</Command>
</NamedFrame> </NamedFrame>
<NamedFrame>
<Name>NormalHardcore</Name>
<Time>20</Time>
<Command>stop</Command>
</NamedFrame>
<NamedFrame>
<Name>HalfHardcore</Name>
<Time>21</Time>
<Command>stop</Command>
</NamedFrame>
<NamedFrame>
<Name>FullHardcore</Name>
<Time>22</Time>
<Command>stop</Command>
</NamedFrame>
<NamedFrame>
<Name>HalfPoisonHardcore</Name>
<Time>23</Time>
<Command>stop</Command>
</NamedFrame>
<NamedFrame>
<Name>FullPoisonHardcore</Name>
<Time>24</Time>
<Command>stop</Command>
</NamedFrame>
<NamedFrame>
<Name>NormalFlashHardcore</Name>
<Time>25</Time>
<Command>stop</Command>
</NamedFrame>
<NamedFrame>
<Name>HalfFlashHardcore</Name>
<Time>26</Time>
<Command>stop</Command>
</NamedFrame>
<NamedFrame>
<Name>FullFlashHardcore</Name>
<Time>27</Time>
<Command>stop</Command>
</NamedFrame>
<NamedFrame>
<Name>HalfPoisonFlashHardcore</Name>
<Time>28</Time>
<Command>stop</Command>
</NamedFrame>
<NamedFrame>
<Name>FullPoisonFlashHardcore</Name>
<Time>29</Time>
<Command>stop</Command>
</NamedFrame>
</NamedFrames> </NamedFrames>
<Timeline> <Timeline>
<Id>Border</Id> <Id>Border</Id>
@@ -38324,16 +38274,6 @@
<Interpolation>0</Interpolation> <Interpolation>0</Interpolation>
<Prop>Graphics\HUD\Health_Background_Flash.png</Prop> <Prop>Graphics\HUD\Health_Background_Flash.png</Prop>
</KeyFrame> </KeyFrame>
<KeyFrame>
<Time>20</Time>
<Interpolation>0</Interpolation>
<Prop>Graphics\HUD\Health_Background_Hardcore.png</Prop>
</KeyFrame>
<KeyFrame>
<Time>25</Time>
<Interpolation>0</Interpolation>
<Prop>Graphics\HUD\Health_Background_Hardcore_Flash.png</Prop>
</KeyFrame>
</Timeline> </Timeline>
<Timeline> <Timeline>
<Id>Heart</Id> <Id>Heart</Id>
@@ -38459,66 +38399,6 @@
<Prop>true</Prop> <Prop>true</Prop>
<Prop>Graphics\HUD\HorseHealth_Half_Flash.png</Prop> <Prop>Graphics\HUD\HorseHealth_Half_Flash.png</Prop>
</KeyFrame> </KeyFrame>
<KeyFrame>
<Time>20</Time>
<Interpolation>0</Interpolation>
<Prop>false</Prop>
<Prop></Prop>
</KeyFrame>
<KeyFrame>
<Time>21</Time>
<Interpolation>0</Interpolation>
<Prop>true</Prop>
<Prop>Graphics\HUD\Health_Half_Hardcore.png</Prop>
</KeyFrame>
<KeyFrame>
<Time>22</Time>
<Interpolation>0</Interpolation>
<Prop>true</Prop>
<Prop>Graphics\HUD\Health_Full_Hardcore.png</Prop>
</KeyFrame>
<KeyFrame>
<Time>23</Time>
<Interpolation>0</Interpolation>
<Prop>true</Prop>
<Prop>Graphics\HUD\Health_Half_Poison_Hardcore.png</Prop>
</KeyFrame>
<KeyFrame>
<Time>24</Time>
<Interpolation>0</Interpolation>
<Prop>true</Prop>
<Prop>Graphics\HUD\Health_Full_Poison_Hardcore.png</Prop>
</KeyFrame>
<KeyFrame>
<Time>25</Time>
<Interpolation>0</Interpolation>
<Prop>false</Prop>
<Prop></Prop>
</KeyFrame>
<KeyFrame>
<Time>26</Time>
<Interpolation>0</Interpolation>
<Prop>true</Prop>
<Prop>Graphics\HUD\Health_Half_Flash_Hardcore.png</Prop>
</KeyFrame>
<KeyFrame>
<Time>27</Time>
<Interpolation>0</Interpolation>
<Prop>true</Prop>
<Prop>Graphics\HUD\Health_Full_Flash_Hardcore.png</Prop>
</KeyFrame>
<KeyFrame>
<Time>28</Time>
<Interpolation>0</Interpolation>
<Prop>true</Prop>
<Prop>Graphics\HUD\Health_Half_Poison_Flash_Hardcore.png</Prop>
</KeyFrame>
<KeyFrame>
<Time>29</Time>
<Interpolation>0</Interpolation>
<Prop>true</Prop>
<Prop>Graphics\HUD\Health_Full_Poison_Flash_Hardcore.png</Prop>
</KeyFrame>
</Timeline> </Timeline>
</Timelines> </Timelines>
</XuiVisual> </XuiVisual>
File diff suppressed because it is too large Load Diff
@@ -214,7 +214,6 @@ private:
int GetJoiningReadyPercentage(); int GetJoiningReadyPercentage();
bool m_bLastDisconnectWasLostRoomOnly; bool m_bLastDisconnectWasLostRoomOnly;
bool m_bFullSessionMessageOnNextSessionChange; bool m_bFullSessionMessageOnNextSessionChange;
bool m_bCancelRequested;
#if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__ #if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__
bool m_bSignedOutofPSN; bool m_bSignedOutofPSN;
#endif #endif
File diff suppressed because it is too large Load Diff
@@ -76,8 +76,11 @@ private:
bool m_bIsOfflineGame; bool m_bIsOfflineGame;
bool m_bIsPrivateGame; bool m_bIsPrivateGame;
int m_flagIndexSize; int m_flagIndexSize;
#ifdef _WINDOWS64 #ifdef _WINDOWS64
bool m_bJoinPending; bool m_bJoinPending;
int m_joinLocalUsersMask;
wchar_t m_joinHostName[32];
#endif #endif
// This is only maintained by the host, and is not valid on client machines // This is only maintained by the host, and is not valid on client machines
-212
View File
@@ -1,212 +0,0 @@
#include "stdafx.h"
#include "StringUtils.h"
#include <cctype>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
namespace UtilityGame
{
namespace StringUtils
{
std::string WideToUtf8(const std::wstring &value)
{
if (value.empty())
{
return std::string();
}
int charCount = WideCharToMultiByte(CP_UTF8, 0, value.c_str(), (int)value.length(), NULL, 0, NULL, NULL);
if (charCount <= 0)
{
return std::string();
}
std::string utf8;
utf8.resize(charCount);
WideCharToMultiByte(CP_UTF8, 0, value.c_str(), (int)value.length(), &utf8[0], charCount, NULL, NULL);
return utf8;
}
std::wstring Utf8ToWide(const char *value)
{
if (value == NULL || value[0] == 0)
{
return std::wstring();
}
int wideCount = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0);
if (wideCount <= 0)
{
// Fall back to the current ANSI code page so legacy non-UTF-8 inputs remain readable.
wideCount = MultiByteToWideChar(CP_ACP, 0, value, -1, NULL, 0);
if (wideCount <= 0)
{
return std::wstring();
}
std::wstring wide;
wide.resize(wideCount - 1);
MultiByteToWideChar(CP_ACP, 0, value, -1, &wide[0], wideCount);
return wide;
}
std::wstring wide;
wide.resize(wideCount - 1);
MultiByteToWideChar(CP_UTF8, 0, value, -1, &wide[0], wideCount);
return wide;
}
std::wstring Utf8ToWide(const std::string &value)
{
return Utf8ToWide(value.c_str());
}
std::string StripUtf8Bom(const std::string &value)
{
if (value.size() >= 3 &&
(unsigned char)value[0] == 0xEF &&
(unsigned char)value[1] == 0xBB &&
(unsigned char)value[2] == 0xBF)
{
return value.substr(3);
}
return value;
}
std::string TrimAscii(const std::string &value)
{
size_t start = 0;
while (start < value.length() && std::isspace((unsigned char)value[start]))
{
++start;
}
size_t end = value.length();
while (end > start && std::isspace((unsigned char)value[end - 1]))
{
--end;
}
return value.substr(start, end - start);
}
std::string ToLowerAscii(const std::string &value)
{
std::string lowered = value;
for (size_t i = 0; i < lowered.length(); ++i)
{
lowered[i] = (char)std::tolower((unsigned char)lowered[i]);
}
return lowered;
}
std::string JoinTokens(const std::vector<std::string> &tokens, size_t startIndex, const char *separator)
{
if (startIndex >= tokens.size())
{
return std::string();
}
const auto joinSeparator = std::string((separator != nullptr) ? separator : " ");
size_t totalLength = 0;
for (size_t i = startIndex; i < tokens.size(); ++i)
{
totalLength += tokens[i].size();
}
totalLength += (tokens.size() - startIndex - 1) * joinSeparator.size();
std::string joined;
joined.reserve(totalLength);
for (size_t i = startIndex; i < tokens.size(); ++i)
{
if (!joined.empty())
{
joined += joinSeparator;
}
joined += tokens[i];
}
return joined;
}
bool StartsWithIgnoreCase(const std::string &value, const std::string &prefix)
{
if (prefix.size() > value.size())
{
return false;
}
for (size_t i = 0; i < prefix.size(); ++i)
{
unsigned char a = (unsigned char)value[i];
unsigned char b = (unsigned char)prefix[i];
if (std::tolower(a) != std::tolower(b))
{
return false;
}
}
return true;
}
bool TryParseUnsignedLongLong(const std::string &value, unsigned long long *outValue)
{
if (outValue == nullptr)
{
return false;
}
const std::string trimmed = TrimAscii(value);
if (trimmed.empty())
{
return false;
}
errno = 0;
char *end = nullptr;
const unsigned long long parsed = _strtoui64(trimmed.c_str(), &end, 0);
if (end == trimmed.c_str() || errno != 0)
{
return false;
}
while (*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n')
{
++end;
}
if (*end != 0)
{
return false;
}
*outValue = parsed;
return true;
}
std::string GetCurrentUtcTimestampIso8601()
{
SYSTEMTIME utc = {};
GetSystemTime(&utc);
char created[64] = {};
sprintf_s(
created,
sizeof(created),
"%04u-%02u-%02uT%02u:%02u:%02uZ",
(unsigned)utc.wYear,
(unsigned)utc.wMonth,
(unsigned)utc.wDay,
(unsigned)utc.wHour,
(unsigned)utc.wMinute,
(unsigned)utc.wSecond);
return created;
}
}
}
-23
View File
@@ -1,23 +0,0 @@
#pragma once
#include <string>
#include <vector>
namespace UtilityGame
{
namespace StringUtils
{
std::string WideToUtf8(const std::wstring &value);
std::wstring Utf8ToWide(const char *value);
std::wstring Utf8ToWide(const std::string &value);
std::string StripUtf8Bom(const std::string &value);
std::string TrimAscii(const std::string &value);
std::string ToLowerAscii(const std::string &value);
std::string JoinTokens(const std::vector<std::string> &tokens, size_t startIndex = 0, const char *separator = " ");
bool StartsWithIgnoreCase(const std::string &value, const std::string &prefix);
bool TryParseUnsignedLongLong(const std::string &value, unsigned long long *outValue);
std::string GetCurrentUtcTimestampIso8601();
}
}
@@ -29,7 +29,6 @@ IUIScene_AbstractContainerMenu::IUIScene_AbstractContainerMenu()
m_pointerPos.y = 0.0f; m_pointerPos.y = 0.0f;
m_bPointerDrivenByMouse = false; m_bPointerDrivenByMouse = false;
m_iLastMouseTickTimeNs = -1;
} }
IUIScene_AbstractContainerMenu::~IUIScene_AbstractContainerMenu() IUIScene_AbstractContainerMenu::~IUIScene_AbstractContainerMenu()
@@ -267,21 +266,6 @@ void IUIScene_AbstractContainerMenu::UpdateTooltips()
void IUIScene_AbstractContainerMenu::onMouseTick() void IUIScene_AbstractContainerMenu::onMouseTick()
{ {
// Frame-rate independent cursor input, normalized to a 60Hz reference frame.
const int64_t kRefFrameNs = 1000000000LL / 60;
const int64_t kMinDeltaNs = 1000000LL;
const int64_t kMaxDeltaNs = 100000000LL;
int64_t iNowNs = System::nanoTime();
float fFrameScale = 1.0f;
if ( m_iLastMouseTickTimeNs > 0 )
{
int64_t iDeltaNs = iNowNs - m_iLastMouseTickTimeNs;
if ( iDeltaNs < kMinDeltaNs ) iDeltaNs = kMinDeltaNs;
if ( iDeltaNs > kMaxDeltaNs ) iDeltaNs = kMaxDeltaNs;
fFrameScale = static_cast<float>(iDeltaNs) / static_cast<float>(kRefFrameNs);
}
m_iLastMouseTickTimeNs = iNowNs;
Minecraft *pMinecraft = Minecraft::GetInstance(); Minecraft *pMinecraft = Minecraft::GetInstance();
if( pMinecraft->localgameModes[getPad()] != nullptr) if( pMinecraft->localgameModes[getPad()] != nullptr)
{ {
@@ -438,8 +422,8 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
// The SD/splitscreen scenes are approximately 0.6 times the size of the fullscreen on // The SD/splitscreen scenes are approximately 0.6 times the size of the fullscreen on
if(!RenderManager.IsHiDef() || app.GetLocalPlayerCount() > 1) fInputScale *= 0.6f; if(!RenderManager.IsHiDef() || app.GetLocalPlayerCount() > 1) fInputScale *= 0.6f;
fInputX *= fInputScale * fFrameScale; fInputX *= fInputScale;
fInputY *= fInputScale * fFrameScale; fInputY *= fInputScale;
#ifdef USE_POINTER_ACCEL #ifdef USE_POINTER_ACCEL
m_fPointerAccelX += fInputX / 50.0f; m_fPointerAccelX += fInputX / 50.0f;
@@ -1285,8 +1269,36 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
vPointerPos.x -= m_fPointerImageOffsetX; vPointerPos.x -= m_fPointerImageOffsetX;
vPointerPos.y -= m_fPointerImageOffsetY; vPointerPos.y -= m_fPointerImageOffsetY;
// Keep sub-pixel float state so deltas <1px accumulate across frames; the renderer // Update pointer position.
// truncates to integer pixels when emitting the Iggy mouse event. // 4J-PB - do not allow sub pixel positions or we get broken lines in box edges
// problem here when sensitivity is low - we'll be moving a sub pixel size, so it'll clamp, and we'll never move. In that case, move 1 pixel
if(fInputDirX!=0.0f)
{
if(fInputDirX==1.0f)
{
vPointerPos.x+=0.999999f;
}
else
{
vPointerPos.x-=0.999999f;
}
}
if(fInputDirY!=0.0f)
{
if(fInputDirY==1.0f)
{
vPointerPos.y+=0.999999f;
}
else
{
vPointerPos.y-=0.999999f;
}
}
vPointerPos.x = static_cast<float>(floor(vPointerPos.x + 0.5f));
vPointerPos.y = static_cast<float>(floor(vPointerPos.y + 0.5f));
m_pointerPos = vPointerPos; m_pointerPos = vPointerPos;
adjustPointerForSafeZone(); adjustPointerForSafeZone();
@@ -145,8 +145,6 @@ protected:
int m_iConsectiveInputTicks; int m_iConsectiveInputTicks;
int64_t m_iLastMouseTickTimeNs;
// Used for detecting quick "taps" in a direction, should jump cursor to next slot. // Used for detecting quick "taps" in a direction, should jump cursor to next slot.
enum ETapState enum ETapState
{ {
@@ -210,40 +210,6 @@ void IUIScene_CreativeMenu::staticCtor()
ITEM_AUX(Tile::woolCarpet_Id,13) // Green ITEM_AUX(Tile::woolCarpet_Id,13) // Green
ITEM_AUX(Tile::woolCarpet_Id,12) // Brown ITEM_AUX(Tile::woolCarpet_Id,12) // Brown
ITEM_AUX(Tile::stained_glass_Id,14) // Red
ITEM_AUX(Tile::stained_glass_Id,1) // Orange
ITEM_AUX(Tile::stained_glass_Id,4) // Yellow
ITEM_AUX(Tile::stained_glass_Id,5) // Lime
ITEM_AUX(Tile::stained_glass_Id,3) // Light Blue
ITEM_AUX(Tile::stained_glass_Id,9) // Cyan
ITEM_AUX(Tile::stained_glass_Id,11) // Blue
ITEM_AUX(Tile::stained_glass_Id,10) // Purple
ITEM_AUX(Tile::stained_glass_Id,2) // Magenta
ITEM_AUX(Tile::stained_glass_Id,6) // Pink
ITEM_AUX(Tile::stained_glass_Id,0) // White
ITEM_AUX(Tile::stained_glass_Id,8) // Light Gray
ITEM_AUX(Tile::stained_glass_Id,7) // Gray
ITEM_AUX(Tile::stained_glass_Id,15) // Black
ITEM_AUX(Tile::stained_glass_Id,13) // Green
ITEM_AUX(Tile::stained_glass_Id,12) // Brown
ITEM_AUX(Tile::stained_glass_pane_Id,14) // Red
ITEM_AUX(Tile::stained_glass_pane_Id,1) // Orange
ITEM_AUX(Tile::stained_glass_pane_Id,4) // Yellow
ITEM_AUX(Tile::stained_glass_pane_Id,5) // Lime
ITEM_AUX(Tile::stained_glass_pane_Id,3) // Light Blue
ITEM_AUX(Tile::stained_glass_pane_Id,9) // Cyan
ITEM_AUX(Tile::stained_glass_pane_Id,11) // Blue
ITEM_AUX(Tile::stained_glass_pane_Id,10) // Purple
ITEM_AUX(Tile::stained_glass_pane_Id,2) // Magenta
ITEM_AUX(Tile::stained_glass_pane_Id,6) // Pink
ITEM_AUX(Tile::stained_glass_pane_Id,0) // White
ITEM_AUX(Tile::stained_glass_pane_Id,8) // Light Gray
ITEM_AUX(Tile::stained_glass_pane_Id,7) // Gray
ITEM_AUX(Tile::stained_glass_pane_Id,15) // Black
ITEM_AUX(Tile::stained_glass_pane_Id,13) // Green
ITEM_AUX(Tile::stained_glass_pane_Id,12) // Brown
#ifndef _CONTENT_PACKAGE #ifndef _CONTENT_PACKAGE
DEF(eCreativeInventory_ArtToolsDecorations) DEF(eCreativeInventory_ArtToolsDecorations)
if(app.DebugSettingsOn()) if(app.DebugSettingsOn())
@@ -492,16 +458,6 @@ void IUIScene_CreativeMenu::staticCtor()
list->push_back(Item::enchantedBook->createForEnchantment(new EnchantmentInstance(enchantment, enchantment->getMaxLevel()))); list->push_back(Item::enchantedBook->createForEnchantment(new EnchantmentInstance(enchantment, enchantment->getMaxLevel())));
} }
#ifndef _CONTENT_PACKAGE
if(app.DebugSettingsOn())
{
shared_ptr<ItemInstance> debugSword = std::make_shared<ItemInstance>(Item::sword_diamond_Id, 1, 0);
debugSword->enchant( Enchantment::damageBonus, 50 );
debugSword->setHoverName(L"Sword of Debug");
list->push_back(debugSword);
}
#endif
// Materials // Materials
DEF(eCreativeInventory_Materials) DEF(eCreativeInventory_Materials)
ITEM(Item::coal_Id) ITEM(Item::coal_Id)
@@ -5,8 +5,6 @@
#include "../../../Minecraft.World/net.minecraft.world.item.h" #include "../../../Minecraft.World/net.minecraft.world.item.h"
#include "../../../Minecraft.World/net.minecraft.world.entity.ai.attributes.h" #include "../../../Minecraft.World/net.minecraft.world.entity.ai.attributes.h"
#include "../../../Minecraft.World/net.minecraft.world.entity.monster.h" #include "../../../Minecraft.World/net.minecraft.world.entity.monster.h"
#include "../../MultiPlayerLevel.h"
#include "../../../Minecraft.World/LevelData.h"
#include "IUIScene_HUD.h" #include "IUIScene_HUD.h"
#include "UI.h" #include "UI.h"
@@ -22,7 +20,6 @@ IUIScene_HUD::IUIScene_HUD()
m_lastMaxHealth = 20; m_lastMaxHealth = 20;
m_lastHealthBlink = false; m_lastHealthBlink = false;
m_lastHealthPoison = false; m_lastHealthPoison = false;
m_lastHealthHardcore = false;
m_iCurrentFood = -1; m_iCurrentFood = -1;
m_lastFoodPoison = false; m_lastFoodPoison = false;
m_lastAir = 10; m_lastAir = 10;
@@ -100,7 +97,6 @@ void IUIScene_HUD::updateFrameTick()
ShowArmour(false); ShowArmour(false);
ShowExpBar(false); ShowExpBar(false);
SetHealthAbsorb(0); SetHealthAbsorb(0);
SetHardcoreMode(false);
} }
if(pMinecraft->localplayers[iPad]->isRidingJumpable()) if(pMinecraft->localplayers[iPad]->isRidingJumpable())
@@ -210,12 +206,6 @@ void IUIScene_HUD::renderPlayerHealth()
// Update armour // Update armour
int armor = pMinecraft->localplayers[iPad]->getArmorValue(); int armor = pMinecraft->localplayers[iPad]->getArmorValue();
// Check hardcore mode
bool bHardcore = pMinecraft->level != nullptr
&& pMinecraft->level->getLevelData() != nullptr
&& pMinecraft->level->getLevelData()->isHardcore();
SetHardcoreMode(bHardcore);
SetHealth(currentHealth, oldHealth, blink, bHasPoison || bHasWither, bHasWither); SetHealth(currentHealth, oldHealth, blink, bHasPoison || bHasWither, bHasWither);
SetHealthAbsorb(totalAbsorption); SetHealthAbsorb(totalAbsorption);
@@ -11,7 +11,6 @@ protected:
int m_iCurrentHealth; int m_iCurrentHealth;
int m_lastMaxHealth; int m_lastMaxHealth;
bool m_lastHealthBlink, m_lastHealthPoison, m_lastHealthWither; bool m_lastHealthBlink, m_lastHealthPoison, m_lastHealthWither;
bool m_lastHealthHardcore;
int m_iCurrentFood; int m_iCurrentFood;
bool m_lastFoodPoison; bool m_lastFoodPoison;
int m_lastAir, m_currentExtraAir; int m_lastAir, m_currentExtraAir;
@@ -47,7 +46,6 @@ protected:
virtual void SetActiveSlot(int slot) = 0; virtual void SetActiveSlot(int slot) = 0;
virtual void SetHealth(int iHealth, int iLastHealth, bool bBlink, bool bPoison, bool bWither) = 0; virtual void SetHealth(int iHealth, int iLastHealth, bool bBlink, bool bPoison, bool bWither) = 0;
virtual void SetHardcoreMode(bool bHardcore) = 0;
virtual void SetFood(int iFood, int iLastFood, bool bPoison) = 0; virtual void SetFood(int iFood, int iLastFood, bool bPoison) = 0;
virtual void SetAir(int iAir, int extra) = 0; virtual void SetAir(int iAir, int extra) = 0;
virtual void SetArmour(int iArmour) = 0; virtual void SetArmour(int iArmour) = 0;
@@ -410,72 +410,11 @@ int IUIScene_PauseMenu::ExitWorldThreadProc( void* lpParameter )
return S_OK; return S_OK;
} }
#ifdef _WINDOWS64
static bool Win64_DeleteSaveDirectory(const wchar_t* wPath)
{
wchar_t wSearch[MAX_PATH];
swprintf_s(wSearch, MAX_PATH, L"%s\\*", wPath);
WIN32_FIND_DATAW fd;
HANDLE hFind = FindFirstFileW(wSearch, &fd);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
if (wcscmp(fd.cFileName, L".") == 0 || wcscmp(fd.cFileName, L"..") == 0) continue;
wchar_t wChild[MAX_PATH];
swprintf_s(wChild, MAX_PATH, L"%s\\%s", wPath, fd.cFileName);
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
Win64_DeleteSaveDirectory(wChild);
else
DeleteFileW(wChild);
} while (FindNextFileW(hFind, &fd));
FindClose(hFind);
}
return RemoveDirectoryW(wPath) != 0;
}
#endif // _WINDOWS64
// This function performs the meat of exiting from a level. It should be called from a thread other than the main thread. // This function performs the meat of exiting from a level. It should be called from a thread other than the main thread.
void IUIScene_PauseMenu::_ExitWorld(LPVOID lpParameter) void IUIScene_PauseMenu::_ExitWorld(LPVOID lpParameter)
{ {
Minecraft *pMinecraft=Minecraft::GetInstance(); Minecraft *pMinecraft=Minecraft::GetInstance();
// 4J Added: Capture hardcore delete info before the server is destroyed
#ifdef _WINDOWS64
bool shouldDeleteHardcoreWorld = false;
wstring hardcoreSaveFolderName;
if (MinecraftServer::getInstance() != nullptr && MinecraftServer::getInstance()->getDeleteWorldOnExit())
{
shouldDeleteHardcoreWorld = true;
// Try 1: Use the save folder name stored by UIScene_LoadMenu::StartGameFromSave (works for existing saves)
hardcoreSaveFolderName = app.GetCurrentSaveFolderName();
if (!hardcoreSaveFolderName.empty())
{
app.DebugPrintf("Hardcore mode: save folder from app = '%ls'\n", hardcoreSaveFolderName.c_str());
}
// Try 2: StorageManager (may work for new saves after first autosave)
if (hardcoreSaveFolderName.empty())
{
char szSaveFolder[MAX_SAVEFILENAME_LENGTH] = {};
StorageManager.GetSaveUniqueFilename(szSaveFolder);
if (szSaveFolder[0] != '\0')
{
wchar_t wSaveFolder[MAX_SAVEFILENAME_LENGTH] = {};
mbstowcs(wSaveFolder, szSaveFolder, MAX_SAVEFILENAME_LENGTH - 1);
hardcoreSaveFolderName = wSaveFolder;
app.DebugPrintf("Hardcore mode: save folder from StorageManager = '%s'\n", szSaveFolder);
}
}
// Try 3: Stored during loadLevel
if (hardcoreSaveFolderName.empty())
{
hardcoreSaveFolderName = MinecraftServer::getInstance()->getSaveFolderName();
app.DebugPrintf("Hardcore mode: save folder from server = '%ls'\n", hardcoreSaveFolderName.c_str());
}
MinecraftServer::getInstance()->setDeleteWorldOnExit(false);
}
#endif
int exitReasonStringId = pMinecraft->progressRenderer->getCurrentTitle(); int exitReasonStringId = pMinecraft->progressRenderer->getCurrentTitle();
int exitReasonTitleId = IDS_CONNECTION_LOST; int exitReasonTitleId = IDS_CONNECTION_LOST;
@@ -686,17 +625,6 @@ void IUIScene_PauseMenu::_ExitWorld(LPVOID lpParameter)
{ {
Sleep(1); Sleep(1);
} }
// 4J Added: Hardcore mode — delete world save data now that the server is fully stopped
#ifdef _WINDOWS64
if (shouldDeleteHardcoreWorld && !hardcoreSaveFolderName.empty())
{
wchar_t wFolderPath[MAX_PATH] = {};
swprintf_s(wFolderPath, MAX_PATH, L"Windows64\\GameHDD\\%s", hardcoreSaveFolderName.c_str());
app.DebugPrintf("Hardcore mode: Deleting world save folder '%ls'\n", wFolderPath);
Win64_DeleteSaveDirectory(wFolderPath);
}
#endif
pMinecraft->setLevel(nullptr,exitReasonStringId,nullptr,saveStats); pMinecraft->setLevel(nullptr,exitReasonStringId,nullptr,saveStats);
TelemetryManager->Flush(); TelemetryManager->Flush();
+13 -3
View File
@@ -141,9 +141,6 @@ S32 UIBitmapFont::GetCodepointGlyph(U32 codepoint)
// 4J-JEV: Change "right single quotation marks" to apostrophies. // 4J-JEV: Change "right single quotation marks" to apostrophies.
if (codepoint == 0x2019) codepoint = 0x27; if (codepoint == 0x2019) codepoint = 0x27;
if (!m_cFontData->hasGlyph(codepoint))
return IGGY_GLYPH_INVALID;
return m_cFontData->getGlyphId(codepoint); return m_cFontData->getGlyphId(codepoint);
} }
@@ -256,6 +253,19 @@ rrbool UIBitmapFont::GetGlyphBitmap(S32 glyph,F32 pixel_scale,IggyBitmapCharacte
while ( (0.5f + glyphScale) * truePixelScale < pixel_scale) while ( (0.5f + glyphScale) * truePixelScale < pixel_scale)
glyphScale++; glyphScale++;
// Debug: log each unique (font, pixel_scale) pair
{
static std::unordered_set<int> s_loggedScaleKeys;
// Encode font pointer + quantized scale into a key to log each combo once
int scaleKey = (int)(pixel_scale * 100.0f) ^ (int)(uintptr_t)m_cFontData;
if (s_loggedScaleKeys.find(scaleKey) == s_loggedScaleKeys.end() && s_loggedScaleKeys.size() < 50) {
s_loggedScaleKeys.insert(scaleKey);
float tps = truePixelScale;
app.DebugPrintf("[FONT-DBG] GetGlyphBitmap: font=%s glyph=%d pixel_scale=%.3f truePixelScale=%.1f glyphScale=%.0f\n",
m_cFontData->getFontName().c_str(), glyph, pixel_scale, tps, glyphScale);
}
}
// 4J-JEV: Debug code to check which font sizes are being used. // 4J-JEV: Debug code to check which font sizes are being used.
#if (!defined _CONTENT_PACKAGE) && (VERBOSE_FONT_OUTPUT > 0) #if (!defined _CONTENT_PACKAGE) && (VERBOSE_FONT_OUTPUT > 0)
@@ -120,7 +120,7 @@ void UIComponent_PressStartToPlay::handleTimerComplete(int id)
for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i)
{ {
m_showingPressStart[i] = false; m_showingPressStart[i] = false;
if (id == 1) { if (id == 1) {
HideAchievementToast(); HideAchievementToast();
killTimer(id); killTimer(id);
ui.toastOn = false; ui.toastOn = false;
@@ -3,7 +3,6 @@
#include "UIScene.h" #include "UIScene.h"
#include "UIControl_Label.h" #include "UIControl_Label.h"
class UIComponent_PressStartToPlay : public UIScene class UIComponent_PressStartToPlay : public UIScene
{ {
private: private:
@@ -51,7 +50,7 @@ public:
// Returns true if lower scenes in this scenes layer, or in any layer below this scenes layers should be hidden // Returns true if lower scenes in this scenes layer, or in any layer below this scenes layers should be hidden
virtual bool hidesLowerScenes() { return false; } virtual bool hidesLowerScenes() { return false; }
void ShowAchievementToast(string achievementName, string achievementDescription, string achT = ""); void ShowAchievementToast(string achievementName, string achievementDescription, string achT = "");
void HideAchievementToast(); void HideAchievementToast();
virtual void handleReload(); virtual void handleReload();
@@ -3,13 +3,13 @@
#include "UIComponent_Tooltips.h" #include "UIComponent_Tooltips.h"
#include "UISplitScreenHelpers.h" #include "UISplitScreenHelpers.h"
UIComponent_Tooltips::UIComponent_Tooltips(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) UIComponent_Tooltips::UIComponent_Tooltips(int iPad, void* initData, UILayer* parentLayer) : UIScene(iPad, parentLayer)
{ {
for(int i=0;i<XUSER_MAX_COUNT;i++) for (int i = 0; i < XUSER_MAX_COUNT; i++)
{ {
for(int j=0;j<ACTION_MAX_MENU;j++) for (int j = 0; j < ACTION_MAX_MENU; j++)
{ {
m_overrideSFX[i][j]=false; m_overrideSFX[i][j] = false;
} }
} }
// Setup all the Iggy references we need for this scene // Setup all the Iggy references we need for this scene
@@ -17,27 +17,27 @@ UIComponent_Tooltips::UIComponent_Tooltips(int iPad, void *initData, UILayer *pa
#ifdef __PSVITA__ #ifdef __PSVITA__
// initialise vita touch controls with ids // initialise vita touch controls with ids
for(unsigned int i = 0; i < ETouchInput_Count; ++i) for (unsigned int i = 0; i < ETouchInput_Count; ++i)
{ {
m_TouchController[i].init(i); m_TouchController[i].init(i);
} }
#endif #endif
#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) #if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
if(InputManager.IsCircleCrossSwapped()) if (InputManager.IsCircleCrossSwapped())
{ {
IggyDataValue result; IggyDataValue result;
IggyDataValue value[1]; IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_boolean; value[0].type = IGGY_DATATYPE_boolean;
value[0].boolval = true; value[0].boolval = true;
IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetABSwap , 1 , value ); IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetABSwap, 1, value);
} }
#endif #endif
} }
wstring UIComponent_Tooltips::getMoviePath() wstring UIComponent_Tooltips::getMoviePath()
{ {
switch( m_parentLayer->getViewport() ) switch (m_parentLayer->getViewport())
{ {
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
@@ -66,7 +66,7 @@ F64 UIComponent_Tooltips::getSafeZoneHalfWidth()
#ifndef __PSVITA__ #ifndef __PSVITA__
// 85% safezone for tooltips in either SD mode // 85% safezone for tooltips in either SD mode
if( !RenderManager.IsHiDef() ) if (!RenderManager.IsHiDef())
{ {
// 85% safezone // 85% safezone
safeWidth = m_movieWidth * (0.15f / 2); safeWidth = m_movieWidth * (0.15f / 2);
@@ -88,27 +88,23 @@ void UIComponent_Tooltips::updateSafeZone()
F64 safeLeft = 0.0; F64 safeLeft = 0.0;
F64 safeRight = 0.0; F64 safeRight = 0.0;
switch( m_parentLayer->getViewport() ) switch (m_parentLayer->getViewport())
{ {
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP: case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
safeTop = getSafeZoneHalfHeight(); safeTop = getSafeZoneHalfHeight();
safeLeft = getSafeZoneHalfWidth(); safeLeft = getSafeZoneHalfWidth();
break; break;
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
safeTop = getSafeZoneHalfHeight(); safeBottom = getSafeZoneHalfHeight();
safeLeft = getSafeZoneHalfWidth(); safeLeft = getSafeZoneHalfWidth();
break; break;
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
safeTop = getSafeZoneHalfHeight();
safeBottom = getSafeZoneHalfHeight();
safeLeft = getSafeZoneHalfWidth(); safeLeft = getSafeZoneHalfWidth();
safeBottom = getSafeZoneHalfHeight();
break; break;
case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
safeTop = getSafeZoneHalfHeight(); safeRight = getSafeZoneHalfWidth();
safeBottom = getSafeZoneHalfHeight(); safeBottom = getSafeZoneHalfHeight();
break; break;
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT: case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
safeTop = getSafeZoneHalfHeight(); safeTop = getSafeZoneHalfHeight();
@@ -116,22 +112,22 @@ void UIComponent_Tooltips::updateSafeZone()
break; break;
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT: case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
safeTop = getSafeZoneHalfHeight(); safeTop = getSafeZoneHalfHeight();
safeRight = getSafeZoneHalfWidth();
break; break;
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
safeTop = getSafeZoneHalfHeight(); safeBottom = getSafeZoneHalfHeight();
safeLeft = getSafeZoneHalfWidth(); safeLeft = getSafeZoneHalfWidth();
break; break;
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT: case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
safeTop = getSafeZoneHalfHeight(); safeBottom = getSafeZoneHalfHeight();
safeRight = getSafeZoneHalfWidth();
break; break;
case C4JRender::VIEWPORT_TYPE_FULLSCREEN: case C4JRender::VIEWPORT_TYPE_FULLSCREEN:
default: default:
safeTop = getSafeZoneHalfHeight(); safeTop = getSafeZoneHalfHeight();
safeBottom = getSafeZoneHalfHeight(); safeBottom = getSafeZoneHalfHeight();
safeLeft = getSafeZoneHalfWidth(); safeLeft = getSafeZoneHalfWidth();
safeRight = getSafeZoneHalfWidth();
break; break;
} }
setSafeZone(safeTop, safeBottom, safeLeft, safeRight); setSafeZone(safeTop, safeBottom, safeLeft, safeRight);
@@ -142,51 +138,51 @@ void UIComponent_Tooltips::tick()
UIScene::tick(); UIScene::tick();
// set the opacity of the tooltip items // set the opacity of the tooltip items
unsigned char ucAlpha=app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_InterfaceOpacity); unsigned char ucAlpha = app.GetGameSettings(ProfileManager.GetPrimaryPad(), eGameSetting_InterfaceOpacity);
float fVal; float fVal;
if(ucAlpha<80) if (ucAlpha < 80)
{ {
// if we are in a menu, set the minimum opacity for tooltips to 15% // if we are in a menu, set the minimum opacity for tooltips to 15%
if(ui.GetMenuDisplayed(m_iPad) && (ucAlpha<15)) if (ui.GetMenuDisplayed(m_iPad) && (ucAlpha < 15))
{ {
ucAlpha=15; ucAlpha = 15;
} }
// check if we have the timer running for the opacity // check if we have the timer running for the opacity
unsigned int uiOpacityTimer=app.GetOpacityTimer(m_iPad); unsigned int uiOpacityTimer = app.GetOpacityTimer(m_iPad);
if(uiOpacityTimer!=0) if (uiOpacityTimer != 0)
{ {
if(uiOpacityTimer<10) if (uiOpacityTimer < 10)
{ {
float fStep=(80.0f-static_cast<float>(ucAlpha))/10.0f; float fStep = (80.0f - static_cast<float>(ucAlpha)) / 10.0f;
fVal=0.01f*(80.0f-((10.0f-static_cast<float>(uiOpacityTimer))*fStep)); fVal = 0.01f * (80.0f - ((10.0f - static_cast<float>(uiOpacityTimer)) * fStep));
} }
else else
{ {
fVal=0.01f*80.0f; fVal = 0.01f * 80.0f;
} }
} }
else else
{ {
fVal=0.01f*static_cast<float>(ucAlpha); fVal = 0.01f * static_cast<float>(ucAlpha);
} }
} }
else else
{ {
// if we are in a menu, set the minimum opacity for tooltips to 15% // if we are in a menu, set the minimum opacity for tooltips to 15%
if(ui.GetMenuDisplayed(m_iPad) && (ucAlpha<15)) if (ui.GetMenuDisplayed(m_iPad) && (ucAlpha < 15))
{ {
ucAlpha=15; ucAlpha = 15;
} }
fVal=0.01f*static_cast<float>(ucAlpha); fVal = 0.01f * static_cast<float>(ucAlpha);
} }
setOpacity(fVal); setOpacity(fVal);
bool layoutChanges = false; bool layoutChanges = false;
for (int i = 0; i < eToolTipNumButtons; i++) for (int i = 0; i < eToolTipNumButtons; i++)
{ {
if ( !ui.IsReloadingSkin() && m_tooltipValues[i].show && m_tooltipValues[i].label.needsUpdating() ) if (!ui.IsReloadingSkin() && m_tooltipValues[i].show && m_tooltipValues[i].label.needsUpdating())
{ {
layoutChanges = true; layoutChanges = true;
_SetTooltip(i, m_tooltipValues[i].label, m_tooltipValues[i].show, true); _SetTooltip(i, m_tooltipValues[i].label, m_tooltipValues[i].show, true);
@@ -198,16 +194,29 @@ void UIComponent_Tooltips::tick()
void UIComponent_Tooltips::render(S32 width, S32 height, C4JRender::eViewportType viewport) void UIComponent_Tooltips::render(S32 width, S32 height, C4JRender::eViewportType viewport)
{ {
if((ProfileManager.GetLockedProfile()!=-1) && !ui.GetMenuDisplayed(m_iPad) && (app.GetGameSettings(m_iPad,eGameSetting_Tooltips)==0 || app.GetGameSettings(m_iPad,eGameSetting_DisplayHUD)==0))
//This is the proper flag for single player, NOT for all players
bool renderTooltipsOK = !((ProfileManager.GetLockedProfile() == -1) || (app.GetGameSettings(m_iPad, eGameSetting_Tooltips) == 0 || app.GetGameSettings(m_iPad, eGameSetting_DisplayHUD) == 0));
// However, if we are in the menu, we want to show the tooltips regardless of the tooltip setting so that players can navigate the menu and change the setting if they want to. So we will override the renderTooltipsOK flag if we are in a menu.
bool menuOKoverride = false;
Minecraft* pMinecraft = Minecraft::GetInstance();
if (pMinecraft != nullptr)
{ {
return; if (pMinecraft->level == nullptr || pMinecraft->player == nullptr)
{
menuOKoverride = true;
}
} }
if(m_bSplitscreen)
{ if (m_bSplitscreen) {
//Individiualize the flags for each viewport :)
S32 xPos = 0; S32 xPos = 0;
S32 yPos = 0; S32 yPos = 0;
switch( viewport ) switch (viewport)
{ {
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM: case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT: case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
@@ -222,6 +231,7 @@ void UIComponent_Tooltips::render(S32 width, S32 height, C4JRender::eViewportTyp
yPos = static_cast<S32>(ui.getScreenHeight() / 2); yPos = static_cast<S32>(ui.getScreenHeight() / 2);
break; break;
} }
ui.setupRenderPosition(xPos, yPos); ui.setupRenderPosition(xPos, yPos);
S32 tileXStart = 0; S32 tileXStart = 0;
@@ -230,7 +240,7 @@ void UIComponent_Tooltips::render(S32 width, S32 height, C4JRender::eViewportTyp
S32 tileHeight = height; S32 tileHeight = height;
bool needsYTile = false; bool needsYTile = false;
switch( viewport ) switch (viewport)
{ {
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT: case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT: case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
@@ -248,88 +258,127 @@ void UIComponent_Tooltips::render(S32 width, S32 height, C4JRender::eViewportTyp
needsYTile = true; needsYTile = true;
break; break;
} }
// I'm not sure if this is a good way to iterate pads...
//Anyways, new pad based on render settings to differentiate splitscreen players
int plr_pad;
switch (viewport)
{
//Player zero;
case C4JRender::VIEWPORT_TYPE_FULLSCREEN:
case C4JRender::VIEWPORT_TYPE_SPLIT_LEFT:
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_LEFT:
plr_pad = m_iPad;
break;
//Player one;
case C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM:
case C4JRender::VIEWPORT_TYPE_QUADRANT_TOP_RIGHT:
case C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT:
plr_pad = 1;
break;
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT:
plr_pad = 2;
break;
case C4JRender::VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT:
plr_pad = 3;
break;
default:
plr_pad = -1;
break;
}
if (plr_pad == -1) {
renderTooltipsOK = false;
}
else {
renderTooltipsOK = (app.GetGameSettings(plr_pad, eGameSetting_Tooltips) != 0) && (app.GetGameSettings(plr_pad, eGameSetting_DisplayHUD) != 0);
}
m_renderWidth = tileWidth;
m_renderHeight = tileHeight;
F32 scale; F32 scale;
ComputeTileScale(tileWidth, tileHeight, m_movieWidth, m_movieHeight, needsYTile, scale, tileYStart); ComputeTileScale(tileWidth, tileHeight, m_movieWidth, m_movieHeight, needsYTile, scale, tileYStart);
// For vertical split, scale down to fit the full SWF height when the // For vertical split, scale down to fit the full SWF height when the
// window is shorter than the movie (same fix as HUD). // window is shorter than the movie (same fix as HUD).
if(!needsYTile && m_movieHeight > 0) if (!needsYTile && m_movieHeight > 0)
{ {
F32 scaleH = (F32)tileHeight / (F32)m_movieHeight; F32 scaleH = (F32)tileHeight / (F32)m_movieHeight;
if(scaleH < scale) if (scaleH < scale)
scale = scaleH; scale = scaleH;
} }
IggyPlayerSetDisplaySize( getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale) ); IggyPlayerSetDisplaySize(getMovie(), (S32)(m_movieWidth * scale), (S32)(m_movieHeight * scale));
IggyPlayerDrawTilesStart ( getMovie() ); if (!renderTooltipsOK && !menuOKoverride) return;
IggyPlayerDrawTilesStart(getMovie());
m_renderWidth = tileWidth; IggyPlayerDrawTile(getMovie(),
m_renderHeight = tileHeight; tileXStart,
IggyPlayerDrawTile ( getMovie() , tileYStart,
tileXStart , tileXStart + tileWidth,
tileYStart , tileYStart + tileHeight,
tileXStart + tileWidth , 0);
tileYStart + tileHeight , IggyPlayerDrawTilesEnd(getMovie());
0 );
IggyPlayerDrawTilesEnd ( getMovie() );
} }
else else
{ {
if (!renderTooltipsOK && !menuOKoverride) return;
UIScene::render(width, height, viewport); UIScene::render(width, height, viewport);
} }
} }
void UIComponent_Tooltips::SetTooltipText( unsigned int tooltip, int iTextID ) void UIComponent_Tooltips::SetTooltipText(unsigned int tooltip, int iTextID)
{ {
if( _SetTooltip(tooltip, iTextID) ) _Relayout(); if (_SetTooltip(tooltip, iTextID)) _Relayout();
} }
void UIComponent_Tooltips::SetEnableTooltips( bool bVal ) void UIComponent_Tooltips::SetEnableTooltips(bool bVal)
{ {
} }
void UIComponent_Tooltips::ShowTooltip( unsigned int tooltip, bool show ) void UIComponent_Tooltips::ShowTooltip(unsigned int tooltip, bool show)
{ {
if(show != m_tooltipValues[tooltip].show) if (show != m_tooltipValues[tooltip].show)
{ {
_SetTooltip(tooltip, L"", show); _SetTooltip(tooltip, L"", show);
_Relayout(); _Relayout();
} }
} }
void UIComponent_Tooltips::SetTooltips( int iA, int iB, int iX, int iY , int iLT, int iRT, int iLB, int iRB, int iLS, int iRS, int iBack, bool forceUpdate) void UIComponent_Tooltips::SetTooltips(int iA, int iB, int iX, int iY, int iLT, int iRT, int iLB, int iRB, int iLS, int iRS, int iBack, bool forceUpdate)
{ {
bool needsRelayout = false; bool needsRelayout = false;
needsRelayout = _SetTooltip( eToolTipButtonA, iA ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonA, iA) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonB, iB ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonB, iB) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonX, iX ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonX, iX) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonY, iY ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonY, iY) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonLT, iLT ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonLT, iLT) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonRT, iRT ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonRT, iRT) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonLB, iLB ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonLB, iLB) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonRB, iRB ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonRB, iRB) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonLS, iLS ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonLS, iLS) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonRS, iRS ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonRS, iRS) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonRS, iRS ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonRS, iRS) || needsRelayout;
needsRelayout = _SetTooltip( eToolTipButtonBack, iBack ) || needsRelayout; needsRelayout = _SetTooltip(eToolTipButtonBack, iBack) || needsRelayout;
if (needsRelayout) _Relayout(); if (needsRelayout) _Relayout();
} }
void UIComponent_Tooltips::EnableTooltip( unsigned int tooltip, bool enable ) void UIComponent_Tooltips::EnableTooltip(unsigned int tooltip, bool enable)
{ {
} }
bool UIComponent_Tooltips::_SetTooltip(unsigned int iToolTip, int iTextID) bool UIComponent_Tooltips::_SetTooltip(unsigned int iToolTip, int iTextID)
{ {
bool changed = false; bool changed = false;
if(iTextID != m_tooltipValues[iToolTip].iString || (iTextID > -1 && !m_tooltipValues[iToolTip].show)) if (iTextID != m_tooltipValues[iToolTip].iString || (iTextID > -1 && !m_tooltipValues[iToolTip].show))
{ {
m_tooltipValues[iToolTip].iString = iTextID; m_tooltipValues[iToolTip].iString = iTextID;
changed = true; changed = true;
if(iTextID > -1) _SetTooltip(iToolTip, iTextID, true); if (iTextID > -1) _SetTooltip(iToolTip, iTextID, true);
else if(iTextID == -2) _SetTooltip(iToolTip, L"", true); else if (iTextID == -2) _SetTooltip(iToolTip, L"", true);
else _SetTooltip(iToolTip, L"", false); else _SetTooltip(iToolTip, L"", false);
} }
return changed; return changed;
@@ -337,7 +386,7 @@ bool UIComponent_Tooltips::_SetTooltip(unsigned int iToolTip, int iTextID)
void UIComponent_Tooltips::_SetTooltip(unsigned int iToolTipId, UIString label, bool show, bool force) void UIComponent_Tooltips::_SetTooltip(unsigned int iToolTipId, UIString label, bool show, bool force)
{ {
if(!force && !show && !m_tooltipValues[iToolTipId].show) if (!force && !show && !m_tooltipValues[iToolTipId].show)
{ {
return; return;
} }
@@ -358,7 +407,7 @@ void UIComponent_Tooltips::_SetTooltip(unsigned int iToolTipId, UIString label,
value[2].type = IGGY_DATATYPE_boolean; value[2].type = IGGY_DATATYPE_boolean;
value[2].boolval = show; value[2].boolval = show;
IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetTooltip , 3 , value ); IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetTooltip, 3, value);
//app.DebugPrintf("Actual tooltip update!\n"); //app.DebugPrintf("Actual tooltip update!\n");
} }
@@ -366,7 +415,7 @@ void UIComponent_Tooltips::_SetTooltip(unsigned int iToolTipId, UIString label,
void UIComponent_Tooltips::_Relayout() void UIComponent_Tooltips::_Relayout()
{ {
IggyDataValue result; IggyDataValue result;
IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcUpdateLayout, 0 , nullptr ); IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcUpdateLayout, 0, nullptr);
#ifdef __PSVITA__ #ifdef __PSVITA__
// rebuild touchboxes // rebuild touchboxes
@@ -381,64 +430,64 @@ void UIComponent_Tooltips::handleTouchInput(unsigned int iPad, S32 x, S32 y, int
bool handled = false; bool handled = false;
// 4J - TomK no tooltips no touch! // 4J - TomK no tooltips no touch!
if((!ui.GetMenuDisplayed(ProfileManager.GetPrimaryPad())) && (app.GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_Tooltips) == 0)) if ((!ui.GetMenuDisplayed(ProfileManager.GetPrimaryPad())) && (app.GetGameSettings(ProfileManager.GetPrimaryPad(), eGameSetting_Tooltips) == 0))
return; return;
// perform action on release // perform action on release
if(bReleased) if (bReleased)
{ {
switch(iId) switch (iId)
{ {
case ETouchInput_Touch_A: case ETouchInput_Touch_A:
app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_X\n", iId); app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_X\n", iId);
if(InputManager.IsCircleCrossSwapped()) if (InputManager.IsCircleCrossSwapped())
InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_O); InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_O);
else else
InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_X); InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_X);
break; break;
case ETouchInput_Touch_B: case ETouchInput_Touch_B:
app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_O\n", iId); app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_O\n", iId);
if(InputManager.IsCircleCrossSwapped()) if (InputManager.IsCircleCrossSwapped())
InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_X); InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_X);
else else
InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_O); InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_O);
break; break;
case ETouchInput_Touch_X: case ETouchInput_Touch_X:
app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_SQUARE\n", iId); app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_SQUARE\n", iId);
InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_SQUARE); InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_SQUARE);
break; break;
case ETouchInput_Touch_Y: case ETouchInput_Touch_Y:
app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_TRIANGLE\n", iId); app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_TRIANGLE\n", iId);
InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_TRIANGLE); InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_TRIANGLE);
break; break;
case ETouchInput_Touch_LT: case ETouchInput_Touch_LT:
/* not in use on vita */ /* not in use on vita */
app.DebugPrintf("ToolTip no action\n", iId); app.DebugPrintf("ToolTip no action\n", iId);
break; break;
case ETouchInput_Touch_RightTrigger: case ETouchInput_Touch_RightTrigger:
app.DebugPrintf("ToolTip no action\n", iId); app.DebugPrintf("ToolTip no action\n", iId);
/* no action */ /* no action */
break; break;
case ETouchInput_Touch_LeftBumper: case ETouchInput_Touch_LeftBumper:
app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_L1\n", iId); app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_L1\n", iId);
InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_L1); InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_L1);
break; break;
case ETouchInput_Touch_RightBumper: case ETouchInput_Touch_RightBumper:
app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_R1\n", iId); app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_R1\n", iId);
InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_R1); InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_R1);
break; break;
case ETouchInput_Touch_LeftStick: case ETouchInput_Touch_LeftStick:
app.DebugPrintf("ToolTip no action\n", iId); app.DebugPrintf("ToolTip no action\n", iId);
/* no action */ /* no action */
break; break;
case ETouchInput_Touch_RightStick: case ETouchInput_Touch_RightStick:
app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_DPAD_DOWN\n", iId); app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_DPAD_DOWN\n", iId);
InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_DPAD_DOWN); InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_DPAD_DOWN);
break; break;
case ETouchInput_Touch_Select: case ETouchInput_Touch_Select:
app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_SELECT\n", iId); app.DebugPrintf("ToolTip Map Touch to _PSV_JOY_BUTTON_SELECT\n", iId);
InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_SELECT); InputManager.MapTouchInput(iPad, _PSV_JOY_BUTTON_SELECT);
break; break;
} }
} }
} }
@@ -449,29 +498,29 @@ void UIComponent_Tooltips::handleReload()
app.DebugPrintf("UIComponent_Tooltips::handleReload\n"); app.DebugPrintf("UIComponent_Tooltips::handleReload\n");
#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) #if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
if(InputManager.IsCircleCrossSwapped()) if (InputManager.IsCircleCrossSwapped())
{ {
IggyDataValue result; IggyDataValue result;
IggyDataValue value[1]; IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_boolean; value[0].type = IGGY_DATATYPE_boolean;
value[0].boolval = true; value[0].boolval = true;
IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetABSwap , 1 , value ); IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetABSwap, 1, value);
} }
#endif #endif
for(unsigned int i = 0; i < eToolTipNumButtons; ++i) for (unsigned int i = 0; i < eToolTipNumButtons; ++i)
{ {
_SetTooltip(i, m_tooltipValues[i].iString, m_tooltipValues[i].show, true); _SetTooltip(i, m_tooltipValues[i].iString, m_tooltipValues[i].show, true);
} }
_Relayout(); _Relayout();
} }
void UIComponent_Tooltips::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled) void UIComponent_Tooltips::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled)
{ {
if( (0 <= iPad) && (iPad <= 3) && m_overrideSFX[iPad][key] ) if ((0 <= iPad) && (iPad <= 3) && m_overrideSFX[iPad][key])
{ {
// don't play a sound for this action // don't play a sound for this action
switch(key) switch (key)
{ {
case ACTION_MENU_A: case ACTION_MENU_A:
case ACTION_MENU_OK: case ACTION_MENU_OK:
@@ -493,7 +542,7 @@ void UIComponent_Tooltips::handleInput(int iPad, int key, bool repeat, bool pres
} }
else else
{ {
switch(key) switch (key)
{ {
case ACTION_MENU_OK: case ACTION_MENU_OK:
case ACTION_MENU_CANCEL: case ACTION_MENU_CANCEL:
@@ -545,5 +594,5 @@ void UIComponent_Tooltips::handleInput(int iPad, int key, bool repeat, bool pres
void UIComponent_Tooltips::overrideSFX(int iPad, int key, bool bVal) void UIComponent_Tooltips::overrideSFX(int iPad, int key, bool bVal)
{ {
m_overrideSFX[iPad][key]=bVal; m_overrideSFX[iPad][key] = bVal;
} }
+4 -11
View File
@@ -3,7 +3,6 @@
#include "UIControl.h" #include "UIControl.h"
#include "../../../Minecraft.World/StringHelpers.h" #include "../../../Minecraft.World/StringHelpers.h"
#include "../../../Minecraft.World/JavaMath.h" #include "../../../Minecraft.World/JavaMath.h"
#include "../../../Minecraft.World/ArabicShaping.h"
UIControl_Base::UIControl_Base() UIControl_Base::UIControl_Base()
{ {
@@ -33,16 +32,13 @@ void UIControl_Base::tick()
//app.DebugPrintf("Calling SetLabel - '%ls'\n", m_label.c_str()); //app.DebugPrintf("Calling SetLabel - '%ls'\n", m_label.c_str());
m_bLabelChanged = false; m_bLabelChanged = false;
// Shape the text before sending to Iggy; m_label stays unshaped for future updates
wstring shaped = shapeArabicText(m_label.getString());
IggyDataValue result; IggyDataValue result;
IggyDataValue value[1]; IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_string_UTF16; value[0].type = IGGY_DATATYPE_string_UTF16;
IggyStringUTF16 stringVal; IggyStringUTF16 stringVal;
stringVal.string = (IggyUTF16*) shaped.c_str(); stringVal.string = (IggyUTF16*) m_label.c_str();
stringVal.length = (int)shaped.length(); stringVal.length = m_label.length();
value[0].string16 = stringVal; value[0].string16 = stringVal;
IggyResult out = IggyPlayerCallMethodRS ( m_parentScene->getMovie() , &result, getIggyValuePath() , m_setLabelFunc , 1 , value ); IggyResult out = IggyPlayerCallMethodRS ( m_parentScene->getMovie() , &result, getIggyValuePath() , m_setLabelFunc , 1 , value );
@@ -60,16 +56,13 @@ void UIControl_Base::setLabel(UIString label, bool instant, bool force)
{ {
m_bLabelChanged = false; m_bLabelChanged = false;
// Shape the text before sending to Iggy; m_label stays unshaped for future updates
wstring shaped = shapeArabicText(m_label.getString());
IggyDataValue result; IggyDataValue result;
IggyDataValue value[1]; IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_string_UTF16; value[0].type = IGGY_DATATYPE_string_UTF16;
IggyStringUTF16 stringVal; IggyStringUTF16 stringVal;
stringVal.string = (IggyUTF16*) shaped.c_str(); stringVal.string = (IggyUTF16*)m_label.c_str();
stringVal.length = (int)shaped.length(); stringVal.length = m_label.length();
value[0].string16 = stringVal; value[0].string16 = stringVal;
IggyResult out = IggyPlayerCallMethodRS ( m_parentScene->getMovie() , &result, getIggyValuePath() , m_setLabelFunc , 1 , value ); IggyResult out = IggyPlayerCallMethodRS ( m_parentScene->getMovie() , &result, getIggyValuePath() , m_setLabelFunc , 1 , value );
@@ -9,7 +9,6 @@ UIControl_BeaconEffectButton::UIControl_BeaconEffectButton()
m_selected = false; m_selected = false;
m_active = false; m_active = false;
m_focus = false; m_focus = false;
m_lastState = eState_Disabled;
} }
bool UIControl_BeaconEffectButton::setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName) bool UIControl_BeaconEffectButton::setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName)
@@ -2,7 +2,6 @@
#include "UI.h" #include "UI.h"
#include "UIControl_Label.h" #include "UIControl_Label.h"
#include "../../../Minecraft.World/StringHelpers.h" #include "../../../Minecraft.World/StringHelpers.h"
#include "../../../Minecraft.World/ArabicShaping.h"
UIControl_Label::UIControl_Label() UIControl_Label::UIControl_Label()
{ {
@@ -23,15 +22,13 @@ void UIControl_Label::init(UIString label)
{ {
m_label = label; m_label = label;
wstring shaped = shapeArabicText(m_label.getString());
IggyDataValue result; IggyDataValue result;
IggyDataValue value[1]; IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_string_UTF16; value[0].type = IGGY_DATATYPE_string_UTF16;
IggyStringUTF16 stringVal; IggyStringUTF16 stringVal;
stringVal.string = (IggyUTF16*)shaped.c_str(); stringVal.string = (IggyUTF16*)label.c_str();
stringVal.length = (int)shaped.length(); stringVal.length = label.length();
value[0].string16 = stringVal; value[0].string16 = stringVal;
IggyResult out = IggyPlayerCallMethodRS ( m_parentScene->getMovie() , &result, getIggyValuePath() , m_initFunc , 1 , value ); IggyResult out = IggyPlayerCallMethodRS ( m_parentScene->getMovie() , &result, getIggyValuePath() , m_initFunc , 1 , value );
} }
@@ -13,56 +13,6 @@
//#define SKIN_PREVIEW_BOB_ANIM //#define SKIN_PREVIEW_BOB_ANIM
#define SKIN_PREVIEW_WALKING_ANIM #define SKIN_PREVIEW_WALKING_ANIM
#ifdef _WINDOWS64
// Frame-rate-independent animation scaling.
// The skin preview animations were designed for ~60fps (VSync on).
// With uncapped FPS, each frame's contribution must be scaled down.
// The scale is computed once per frame (keyed by frame counter) so
// that multiple skin previews rendered in the same frame all use the
// same value instead of measuring near-zero deltas between each other.
static float s_skinAnimCachedScale = 1.0f;
static double s_skinAnimLastTime = 0.0;
static double s_skinAnimFreqInv = 0.0;
static float GetSkinAnimDeltaScale()
{
// Use the main loop's frame counter to detect a new frame.
// GetTickCount changes every ~16ms, but we need per-frame detection.
// Use a simple time threshold: if <0.1ms since last call, same frame.
if (s_skinAnimFreqInv == 0.0)
{
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
s_skinAnimFreqInv = 1.0 / (double)freq.QuadPart;
}
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
double currentTime = (double)now.QuadPart * s_skinAnimFreqInv;
// If less than 0.5ms since last call, assume same frame -- reuse cached scale
double elapsed = currentTime - s_skinAnimLastTime;
if (s_skinAnimLastTime != 0.0 && elapsed < 0.0005)
{
return s_skinAnimCachedScale;
}
if (s_skinAnimLastTime == 0.0)
{
s_skinAnimLastTime = currentTime;
s_skinAnimCachedScale = 1.0f;
return 1.0f;
}
s_skinAnimLastTime = currentTime;
const double kBaselineFrameTime = 1.0 / 60.0;
float scale = static_cast<float>(elapsed / kBaselineFrameTime);
if (scale > 3.0f) scale = 3.0f;
s_skinAnimCachedScale = scale;
return scale;
}
#endif
UIControl_PlayerSkinPreview::UIControl_PlayerSkinPreview() UIControl_PlayerSkinPreview::UIControl_PlayerSkinPreview()
{ {
UIControl::setControlType(UIControl::ePlayerSkinPreview); UIControl::setControlType(UIControl::ePlayerSkinPreview);
@@ -337,11 +287,7 @@ void UIControl_PlayerSkinPreview::render(EntityRenderer *renderer, double x, dou
break; break;
case e_SkinPreviewAnimation_Attacking: case e_SkinPreviewAnimation_Attacking:
model->holdingRightHand = true; model->holdingRightHand = true;
#ifdef _WINDOWS64
m_swingTime += GetSkinAnimDeltaScale();
#else
m_swingTime++; m_swingTime++;
#endif
if (m_swingTime >= (Player::SWING_DURATION * 3) ) if (m_swingTime >= (Player::SWING_DURATION * 3) )
{ {
m_swingTime = 0; m_swingTime = 0;
@@ -394,16 +340,8 @@ void UIControl_PlayerSkinPreview::render(EntityRenderer *renderer, double x, dou
#ifdef SKIN_PREVIEW_WALKING_ANIM #ifdef SKIN_PREVIEW_WALKING_ANIM
m_walkAnimSpeedO = m_walkAnimSpeed; m_walkAnimSpeedO = m_walkAnimSpeed;
#ifdef _WINDOWS64
{
float animScale = GetSkinAnimDeltaScale();
m_walkAnimSpeed += (0.1f - m_walkAnimSpeed) * 0.4f * animScale;
m_walkAnimPos += m_walkAnimSpeed * animScale;
}
#else
m_walkAnimSpeed += (0.1f - m_walkAnimSpeed) * 0.4f; m_walkAnimSpeed += (0.1f - m_walkAnimSpeed) * 0.4f;
m_walkAnimPos += m_walkAnimSpeed; m_walkAnimPos += m_walkAnimSpeed;
#endif
float ws = m_walkAnimSpeedO + (m_walkAnimSpeed - m_walkAnimSpeedO) * a; float ws = m_walkAnimSpeedO + (m_walkAnimSpeed - m_walkAnimSpeedO) * a;
float wp = m_walkAnimPos - m_walkAnimSpeed * (1 - a); float wp = m_walkAnimPos - m_walkAnimSpeed * (1 - a);
#else #else
@@ -1,7 +1,6 @@
#include "stdafx.h" #include "stdafx.h"
#include "UI.h" #include "UI.h"
#include "UIControl_SaveList.h" #include "UIControl_SaveList.h"
#include "../../../Minecraft.World/ArabicShaping.h"
bool UIControl_SaveList::setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName) bool UIControl_SaveList::setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName)
{ {
@@ -70,14 +69,12 @@ void UIControl_SaveList::addItem(const string &label, const wstring &iconName, i
void UIControl_SaveList::addItem(const wstring &label, const wstring &iconName, int data) void UIControl_SaveList::addItem(const wstring &label, const wstring &iconName, int data)
{ {
wstring shaped = shapeArabicText(label);
IggyDataValue result; IggyDataValue result;
IggyDataValue value[3]; IggyDataValue value[3];
IggyStringUTF16 stringVal; IggyStringUTF16 stringVal;
stringVal.string = (IggyUTF16*)shaped.c_str(); stringVal.string = (IggyUTF16*)label.c_str();
stringVal.length = static_cast<S32>(shaped.length()); stringVal.length = static_cast<S32>(label.length());
value[0].type = IGGY_DATATYPE_string_UTF16; value[0].type = IGGY_DATATYPE_string_UTF16;
value[0].string16 = stringVal; value[0].string16 = stringVal;
+12 -15
View File
@@ -16,7 +16,6 @@
#include "../../EnderDragonRenderer.h" #include "../../EnderDragonRenderer.h"
#include "../../MultiPlayerLocalPlayer.h" #include "../../MultiPlayerLocalPlayer.h"
#include "UIFontData.h" #include "UIFontData.h"
#include "UIUnicodeBitmapFont.h"
#include "UISplitScreenHelpers.h" #include "UISplitScreenHelpers.h"
#ifdef _WINDOWS64 #ifdef _WINDOWS64
#include "../../Windows64/KeyboardMouseInput.h" #include "../../Windows64/KeyboardMouseInput.h"
@@ -197,7 +196,6 @@ UIController::UIController()
m_mcTTFFont = nullptr; m_mcTTFFont = nullptr;
m_moj7 = nullptr; m_moj7 = nullptr;
m_moj11 = nullptr; m_moj11 = nullptr;
m_unicodeBitmapFont = nullptr;
// 4J-JEV: It's important that these remain the same, unless updateCurrentLanguage is going to be called. // 4J-JEV: It's important that these remain the same, unless updateCurrentLanguage is going to be called.
m_eCurrentFont = m_eTargetFont = eFont_NotLoaded; m_eCurrentFont = m_eTargetFont = eFont_NotLoaded;
@@ -312,14 +310,6 @@ void UIController::postInit()
IggySetAS3ExternalFunctionCallbackUTF16 ( &UIController::ExternalFunctionCallback, this ); IggySetAS3ExternalFunctionCallbackUTF16 ( &UIController::ExternalFunctionCallback, this );
IggySetTextureSubstitutionCallbacks ( &UIController::TextureSubstitutionCreateCallback , &UIController::TextureSubstitutionDestroyCallback, this ); IggySetTextureSubstitutionCallbacks ( &UIController::TextureSubstitutionCreateCallback , &UIController::TextureSubstitutionDestroyCallback, this );
// Load a unicode bitmap font as Iggy's global fallback for characters not
// covered by the Mojangles bitmap font (CJK, Thai, Arabic, Korean, etc.).
// Uses the same glyph page PNGs as the legacy Font class, with matching
// Mojangles metrics for correct vertical alignment.
m_unicodeBitmapFont = new UIUnicodeBitmapFont("Mojangles_Unicode_Bitmap", SFontData::Mojangles_7);
m_unicodeBitmapFont->registerFont();
IggyFontSetFallbackFontUTF8("Mojangles_Unicode_Bitmap", -1, IGGY_FONTFLAG_none);
SetupFont(); SetupFont();
// //
loadSkins(); loadSkins();
@@ -592,6 +582,9 @@ void UIController::loadSkins()
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHDHud.swf", L"skinHDHud.swf"); m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHDHud.swf", L"skinHDHud.swf");
m_iggyLibraries[eLibrary_Tooltips] = loadSkin(L"skinHDTooltips.swf", L"skinHDTooltips.swf"); m_iggyLibraries[eLibrary_Tooltips] = loadSkin(L"skinHDTooltips.swf", L"skinHDTooltips.swf");
m_iggyLibraries[eLibrary_Default] = loadSkin(L"skinHD.swf", L"skinHD.swf"); m_iggyLibraries[eLibrary_Default] = loadSkin(L"skinHD.swf", L"skinHD.swf");
//Load skins specifcally edited for use on achievements, if we
//used these as skin.swf and skinInGame.swf it breaks some other things
m_iggyLibraries[eLibrary_LCDefault] = loadSkin(L"skinLC.swf", L"skinLC.swf"); m_iggyLibraries[eLibrary_LCDefault] = loadSkin(L"skinLC.swf", L"skinLC.swf");
m_iggyLibraries[eLibrary_LCInGame] = loadSkin(L"skinInGameLC.swf", L"skinInGameLC.swf"); m_iggyLibraries[eLibrary_LCInGame] = loadSkin(L"skinInGameLC.swf", L"skinInGameLC.swf");
@@ -938,7 +931,7 @@ void UIController::tickInput()
UIControl::eUIControlType type = ctrl->getControlType(); UIControl::eUIControlType type = ctrl->getControlType();
if (type != UIControl::eButton && type != UIControl::eTextInput && if (type != UIControl::eButton && type != UIControl::eTextInput &&
type != UIControl::eCheckBox && type != UIControl::eSlider && type != UIControl::eCheckBox && type != UIControl::eSlider &&
type != UIControl::eButtonList && type != UIControl::eAchievementList) type != UIControl::eButtonList && type != UIControl::eTexturePackList && type != UIControl::eAchievementList)
continue; continue;
// If the scene has an active panel (e.g. tab menus), // If the scene has an active panel (e.g. tab menus),
@@ -972,7 +965,7 @@ void UIController::tickInput()
hitCtrl = NULL; hitCtrl = NULL;
break; // ButtonList takes priority break; // ButtonList takes priority
} }
if (type == UIControl::eAchievementList) if (type == UIControl::eAchievementList)
{ {
auto t = (UIScene_AchievementsMenu*)pScene; auto t = (UIScene_AchievementsMenu*)pScene;
static_cast<UIControl_AchievementsList*>(ctrl)->SetTouchFocus( static_cast<UIControl_AchievementsList*>(ctrl)->SetTouchFocus(
@@ -1855,9 +1848,11 @@ GDrawTexture * RADLINK UIController::TextureSubstitutionCreateCallback ( void *
image.preMultiplyAlpha(); image.preMultiplyAlpha();
Textures *t = Minecraft::GetInstance()->textures; Textures *t = Minecraft::GetInstance()->textures;
int id = t->getTexture(&image,C4JRender::TEXTURE_FORMAT_RxGyBzAw,false); int id = t->getTexture(&image,C4JRender::TEXTURE_FORMAT_RxGyBzAw,false);
std::string result(texture_name, texture_name + wcslen(texture_name));
std::string result(texture_name, texture_name + wcslen(texture_name));
bool isSub = result.find("sub") != std::string::npos; bool isSub = result.find("sub") != std::string::npos;
// 4J Stu - All our flash controls that allow replacing textures use a special 64x64 symbol // 4J Stu - All our flash controls that allow replacing textures use a special 64x64 symbol
// Force this size here so that our images don't get scaled wildly // Force this size here so that our images don't get scaled wildly
#if (defined __ORBIS__ || defined _DURANGO ) #if (defined __ORBIS__ || defined _DURANGO )
@@ -1871,13 +1866,15 @@ GDrawTexture * RADLINK UIController::TextureSubstitutionCreateCallback ( void *
#if defined _WINDOWS64 #if defined _WINDOWS64
// Only set the size to 96x96 for 1080p on Windows // Only set the size to 96x96 for 1080p on Windows
UIScene *scene = uiController->GetTopScene(0); UIScene *scene = uiController->GetTopScene(0);
if (scene) { //Fix for icon size changing on Achievements
if (scene->getSceneResolution() == UIScene::eSceneResolution_1080 && (scene->getSceneType() != eUIScene_PauseMenu && scene->getSceneType() != eUIScene_MainMenu && scene->getSceneType() != eUIScene_AchievementsMenu) && isSub == false) if (scene) {
if (scene->getSceneResolution() == UIScene::eSceneResolution_1080 && (scene->getSceneType() != eUIScene_PauseMenu && scene->getSceneType() != eUIScene_MainMenu && scene->getSceneType() != eUIScene_AchievementsMenu) && isSub == false)
{ {
*width = 96; *width = 96;
*height = 96; *height = 96;
} }
} }
#endif #endif
*destroy_callback_data = (void *)id; *destroy_callback_data = (void *)id;
+2 -3
View File
@@ -7,7 +7,6 @@ using namespace std;
class UIAbstractBitmapFont; class UIAbstractBitmapFont;
class UIBitmapFont; class UIBitmapFont;
class UIUnicodeBitmapFont;
class UITTFFont; class UITTFFont;
class UIComponent_DebugUIConsole; class UIComponent_DebugUIConsole;
class UIComponent_DebugUIMarketingGuide; class UIComponent_DebugUIMarketingGuide;
@@ -20,6 +19,7 @@ public:
static int64_t iggyAllocCount; static int64_t iggyAllocCount;
bool toastOn = false; bool toastOn = false;
// MGH - added to prevent crash loading Iggy movies while the skins were being reloaded // MGH - added to prevent crash loading Iggy movies while the skins were being reloaded
static CRITICAL_SECTION ms_reloadSkinCS; static CRITICAL_SECTION ms_reloadSkinCS;
static bool ms_bReloadSkinCSInitialised; static bool ms_bReloadSkinCSInitialised;
@@ -65,7 +65,6 @@ private:
UIAbstractBitmapFont *m_mcBitmapFont; UIAbstractBitmapFont *m_mcBitmapFont;
UITTFFont *m_mcTTFFont; UITTFFont *m_mcTTFFont;
UIBitmapFont *m_moj7, *m_moj11; UIBitmapFont *m_moj7, *m_moj11;
UIUnicodeBitmapFont *m_unicodeBitmapFont;
std::mt19937 m_randomGenerator; std::mt19937 m_randomGenerator;
std::uniform_real_distribution<float> m_randomDistribution; std::uniform_real_distribution<float> m_randomDistribution;
@@ -103,7 +102,6 @@ private:
eLibrary_HUD, eLibrary_HUD,
eLibrary_Tooltips, eLibrary_Tooltips,
eLibrary_Default, eLibrary_Default,
eLibrary_LCDefault, eLibrary_LCDefault,
eLibrary_LCInGame, eLibrary_LCInGame,
@@ -206,6 +204,7 @@ protected:
public: public:
auto& getGroups() { return m_groups; } auto& getGroups() { return m_groups; }
void showComponent(int iPad, EUIScene scene, EUILayer layer, EUIGroup group, bool show) void showComponent(int iPad, EUIScene scene, EUILayer layer, EUIGroup group, bool show)
{ {
m_groups[group]->showComponent(iPad, scene, layer, show); m_groups[group]->showComponent(iPad, scene, layer, show);
@@ -335,11 +335,6 @@ bool CFontData::unicodeIsWhitespace(unsigned int unicode)
return false; return false;
} }
bool CFontData::hasGlyph(unsigned int unicodepoint)
{
return m_unicodeMap.find(unicodepoint) != m_unicodeMap.end();
}
void CFontData::moveCursor(unsigned char *&cursor, unsigned int dx, unsigned int dy) void CFontData::moveCursor(unsigned char *&cursor, unsigned int dx, unsigned int dy)
{ {
cursor += (dy * m_sFontData->m_uiGlyphMapX) + dx; cursor += (dy * m_sFontData->m_uiGlyphMapX) + dx;
-3
View File
@@ -125,9 +125,6 @@ public:
// Returns true if this unicodepoint is whitespace // Returns true if this unicodepoint is whitespace
bool unicodeIsWhitespace(unsigned int unicodepoint); bool unicodeIsWhitespace(unsigned int unicodepoint);
// Returns true if this unicodepoint exists in the font's glyph map.
bool hasGlyph(unsigned int unicodepoint);
private: private:
// Move a pointer in an image dx pixels right and dy pixels down, wrap around in either dimension leads to unknown behaviour. // Move a pointer in an image dx pixels right and dy pixels down, wrap around in either dimension leads to unknown behaviour.
+5 -12
View File
@@ -2,6 +2,7 @@
#include "UI.h" #include "UI.h"
#include "UIScene.h" #include "UIScene.h"
#include "UISplitScreenHelpers.h" #include "UISplitScreenHelpers.h"
#include "../../Lighting.h" #include "../../Lighting.h"
#include "../../LocalPlayer.h" #include "../../LocalPlayer.h"
#include "../../ItemRenderer.h" #include "../../ItemRenderer.h"
@@ -309,27 +310,19 @@ void UIScene::loadMovie()
if(!app.hasArchiveFile(moviePath)) if(!app.hasArchiveFile(moviePath))
{ {
app.DebugPrintf("WARNING: Could not find iggy movie %ls, trying other resolutions\n", moviePath.c_str()); app.DebugPrintf("WARNING: Could not find iggy movie %ls, falling back on 720\n", moviePath.c_str());
// Try 720 first, then 1080 as final fallback
moviePath = getMoviePath(); moviePath = getMoviePath();
moviePath.append(L"720.swf"); moviePath.append(L"720.swf");
m_loadedResolution = eSceneResolution_720; m_loadedResolution = eSceneResolution_720;
if(!app.hasArchiveFile(moviePath)) if(!app.hasArchiveFile(moviePath))
{ {
moviePath = getMoviePath(); app.DebugPrintf("ERROR: Could not find any iggy movie for %ls!\n", moviePath.c_str());
moviePath.append(L"1080.swf");
m_loadedResolution = eSceneResolution_1080;
if(!app.hasArchiveFile(moviePath))
{
app.DebugPrintf("ERROR: Could not find any iggy movie for %ls!\n", moviePath.c_str());
#ifndef _CONTENT_PACKAGE #ifndef _CONTENT_PACKAGE
DEBUG_BREAK(); DEBUG_BREAK();
#endif #endif
app.FatalLoadError(); app.FatalLoadError();
}
} }
} }
@@ -8,15 +8,12 @@
#include "StatsCounter.h" #include "StatsCounter.h"
#include "MultiPlayerLocalPlayer.h" #include "MultiPlayerLocalPlayer.h"
#include "Windows64/KeyboardMouseInput.h" #include "Windows64/KeyboardMouseInput.h"
#include "UIControl_Label.h"
extern HWND g_hWnd; extern HWND g_hWnd;
UIScene_AchievementsMenu::UIScene_AchievementsMenu(int iPad, void* _initData, UILayer* parentLayer) : UIScene(iPad, parentLayer) UIScene_AchievementsMenu::UIScene_AchievementsMenu(int iPad, void* _initData, UILayer* parentLayer) : UIScene(iPad, parentLayer)
{ {
// Setup all the Iggy references we need for this scene // Setup all the Iggy references we need for this scene
initialiseMovie(); initialiseMovie();
/*RECT rc; /*RECT rc;
GetClientRect(g_hWnd, &rc); GetClientRect(g_hWnd, &rc);
POINT center; POINT center;
@@ -24,8 +21,7 @@ UIScene_AchievementsMenu::UIScene_AchievementsMenu(int iPad, void* _initData, UI
center.y = rc.top; center.y = rc.top;
ClientToScreen(g_hWnd, &center); ClientToScreen(g_hWnd, &center);
SetCursorPos(center.x, center.y);*/ SetCursorPos(center.x, center.y);*/
m_labelAchievements.init(app.GetString(IDS_ACHIEVEMENTS));
m_labelAchievements.init(L"Achievements");
//m_labelDesc.init(L""); //m_labelDesc.init(L"");
m_labelName.init(L""); m_labelName.init(L"");
m_achievementsList.init(0); m_achievementsList.init(0);
@@ -35,19 +31,16 @@ UIScene_AchievementsMenu::UIScene_AchievementsMenu(int iPad, void* _initData, UI
{ {
std::wstring iconStr(Achievements::achievements->at(i)->iconInt.begin(), std::wstring iconStr(Achievements::achievements->at(i)->iconInt.begin(),
Achievements::achievements->at(i)->iconInt.end()); Achievements::achievements->at(i)->iconInt.end());
path = L"Graphics\\Achievements\\TROP" + path = L"Graphics\\Achievements\\TROP" +
(iconStr.empty() ? L"000" : iconStr) + (iconStr.empty() ? L"000" : iconStr) +
L".png"; L".png";
byteArray ba = app.getArchiveFile(path); byteArray ba = app.getArchiveFile(path);
registerSubstitutionTexture(path, ba.data, ba.length); registerSubstitutionTexture(path, ba.data, ba.length);
} }
std::string result = "Graphics\\Achievements\\" "TROP" + Achievements::achievements->at(i)->iconInt + ".png"; //media\\ std::string result = "Graphics\\Achievements\\" "TROP" + Achievements::achievements->at(i)->iconInt + ".png"; //media\\
m_achievementsList.addnewItem(i+1, path); m_achievementsList.addnewItem(i+1, path);
int newPad = 0; int newPad = 0;
if (Minecraft::GetInstance()->player != nullptr) { if (Minecraft::GetInstance()->player != nullptr) {
newPad = Minecraft::GetInstance()->player->GetXboxPad(); newPad = Minecraft::GetInstance()->player->GetXboxPad();
} }
@@ -61,27 +54,21 @@ UIScene_AchievementsMenu::UIScene_AchievementsMenu(int iPad, void* _initData, UI
} }
} }
m_funcSetDesc = registerFastName(L"SetAchievementDescription"); m_funcSetDesc = registerFastName(L"SetAchievementDescription");
m_achievementsList.setCurrentSelection(Minecraft::GetInstance()->achID + 1); m_achievementsList.setCurrentSelection(Minecraft::GetInstance()->achID + 1);
m_achievementsList.m_iCurrentSelection = Minecraft::GetInstance()->achID + 1; m_achievementsList.m_iCurrentSelection = Minecraft::GetInstance()->achID + 1;
} }
void UIScene_AchievementsMenu::handleDestroy() void UIScene_AchievementsMenu::handleDestroy()
{ {
m_parentLayer->showComponent(m_iPad, eUIComponent_MenuBackground, false); m_parentLayer->showComponent(m_iPad, eUIComponent_MenuBackground, false);
} }
void UIScene_AchievementsMenu::SetAchievementDescription(wstring desc) { void UIScene_AchievementsMenu::SetAchievementDescription(wstring desc) {
wstring desc2 = L""; wstring desc2 = L"";
if (desc != L"") { if (desc != L"") {
HtmlString test = HtmlString(desc, eHTMLColor_White); HtmlString test = HtmlString(desc, eHTMLColor_White);
vector<HtmlString>* lines = new vector<HtmlString>(); vector<HtmlString>* lines = new vector<HtmlString>();
lines->push_back(test); lines->push_back(test);
desc2 = HtmlString::Compose(lines); desc2 = HtmlString::Compose(lines);
} }
IggyDataValue result; IggyDataValue result;
IggyDataValue value[1]; IggyDataValue value[1];
IggyStringUTF16 stringVal1; IggyStringUTF16 stringVal1;
@@ -89,10 +76,8 @@ void UIScene_AchievementsMenu::SetAchievementDescription(wstring desc) {
stringVal1.string = (IggyUTF16*)desc2.c_str(); stringVal1.string = (IggyUTF16*)desc2.c_str();
stringVal1.length = desc2.length(); stringVal1.length = desc2.length();
value[0].string16 = stringVal1; value[0].string16 = stringVal1;
IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetDesc, 1, value); IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetDesc, 1, value);
} }
wstring UIScene_AchievementsMenu::getMoviePath() wstring UIScene_AchievementsMenu::getMoviePath()
{ {
if (app.GetLocalPlayerCount() > 1) if (app.GetLocalPlayerCount() > 1)
@@ -104,7 +89,6 @@ wstring UIScene_AchievementsMenu::getMoviePath()
return L"AchievementsMenu"; return L"AchievementsMenu";
} }
} }
void UIScene_AchievementsMenu::updateComponents() void UIScene_AchievementsMenu::updateComponents()
{ {
bool bNotInGame = (Minecraft::GetInstance()->level == nullptr); bool bNotInGame = (Minecraft::GetInstance()->level == nullptr);
@@ -113,9 +97,7 @@ void UIScene_AchievementsMenu::updateComponents()
m_parentLayer->showComponent(m_iPad, eUIComponent_MenuBackground, true); m_parentLayer->showComponent(m_iPad, eUIComponent_MenuBackground, true);
} }
m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, false); m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, false);
} }
void UIScene_AchievementsMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled) void UIScene_AchievementsMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled)
{ {
ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released); ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released);
@@ -127,7 +109,6 @@ void UIScene_AchievementsMenu::handleInput(int iPad, int key, bool repeat, bool
case ACTION_MENU_Y: case ACTION_MENU_Y:
if (pressed) { if (pressed) {
showDescription = !showDescription; showDescription = !showDescription;
if (showDescription) { if (showDescription) {
SetAchievementDescription(app.GetString(Achievements::achievements->at(m_achievementsList.m_iCurrentSelection - 1)->descID)); SetAchievementDescription(app.GetString(Achievements::achievements->at(m_achievementsList.m_iCurrentSelection - 1)->descID));
} }
@@ -175,10 +156,8 @@ void UIScene_AchievementsMenu::handleInput(int iPad, int key, bool repeat, bool
handled = true; handled = true;
break; break;
} }
//m_achievementsList.updateChildFocus(static_cast<int>(childId)); //m_achievementsList.updateChildFocus(static_cast<int>(childId));
}; };
void UIScene_AchievementsMenu::getMouseToSWFScale(float& scaleX, float& scaleY) void UIScene_AchievementsMenu::getMouseToSWFScale(float& scaleX, float& scaleY)
{ {
extern HWND g_hWnd; extern HWND g_hWnd;
@@ -187,19 +166,16 @@ void UIScene_AchievementsMenu::getMouseToSWFScale(float& scaleX, float& scaleY)
int winW = rc.right - rc.left; int winW = rc.right - rc.left;
int winH = rc.bottom - rc.top; int winH = rc.bottom - rc.top;
if (winW <= 0 || winH <= 0) { scaleX = 1.0f; scaleY = 1.0f; return; } if (winW <= 0 || winH <= 0) { scaleX = 1.0f; scaleY = 1.0f; return; }
S32 renderW, renderH; S32 renderW, renderH;
C4JRender::eViewportType vp = GetParentLayer()->getViewport(); C4JRender::eViewportType vp = GetParentLayer()->getViewport();
ui.getRenderDimensions(vp, renderW, renderH); ui.getRenderDimensions(vp, renderW, renderH);
if (vp != C4JRender::VIEWPORT_TYPE_FULLSCREEN) if (vp != C4JRender::VIEWPORT_TYPE_FULLSCREEN)
Fit16x9(renderW, renderH); Fit16x9(renderW, renderH);
float screenW = (float)ui.getScreenWidth(); float screenW = (float)ui.getScreenWidth();
float screenH = (float)ui.getScreenHeight(); float screenH = (float)ui.getScreenHeight();
scaleX = static_cast<float>(m_movieWidth) * screenW / (static_cast<float>(renderW) * static_cast<float>(winW)); scaleX = static_cast<float>(m_movieWidth) * screenW / (static_cast<float>(renderW) * static_cast<float>(winW));
scaleY = static_cast<float>(m_movieHeight) * screenH / (static_cast<float>(renderH) * static_cast<float>(winH)); scaleY = static_cast<float>(m_movieHeight) * screenH / (static_cast<float>(renderH) * static_cast<float>(winH));
} }
void UIScene_AchievementsMenu::tick() void UIScene_AchievementsMenu::tick()
{ {
UIScene::tick(); UIScene::tick();
@@ -207,7 +183,6 @@ void UIScene_AchievementsMenu::tick()
//m_cursorPath1.setVisible(g_KBMInput.IsKBMActive()); //m_cursorPath1.setVisible(g_KBMInput.IsKBMActive());
//g_KBMInput.SetMouseGrabbed(false); //g_KBMInput.SetMouseGrabbed(false);
if (m_achievementsList.m_iCurrentSelection != selection && m_achievementsList.m_iCurrentSelection != 0) { if (m_achievementsList.m_iCurrentSelection != selection && m_achievementsList.m_iCurrentSelection != 0) {
m_achievementsList.setCurrentSelection(m_achievementsList.m_iCurrentSelection - 1); m_achievementsList.setCurrentSelection(m_achievementsList.m_iCurrentSelection - 1);
m_labelName.setLabel(app.GetString(Achievements::achievements->at(m_achievementsList.m_iCurrentSelection - 1)->nameID)); m_labelName.setLabel(app.GetString(Achievements::achievements->at(m_achievementsList.m_iCurrentSelection - 1)->nameID));
@@ -218,24 +193,20 @@ void UIScene_AchievementsMenu::tick()
SetAchievementDescription(L""); SetAchievementDescription(L"");
} }
} }
// Apply mouse delta // Apply mouse delta
/*int deltaX = g_KBMInput.GetMouseDeltaX(); /*int deltaX = g_KBMInput.GetMouseDeltaX();
int deltaY = g_KBMInput.GetMouseDeltaY(); int deltaY = g_KBMInput.GetMouseDeltaY();
if (deltaX != 0 || deltaY != 0) if (deltaX != 0 || deltaY != 0)
{ {
float scaleX, scaleY; float scaleX, scaleY;
getMouseToSWFScale(scaleX, scaleY); getMouseToSWFScale(scaleX, scaleY);
m_pointerPos.x += static_cast<float>(deltaX) * scaleX / 2; m_pointerPos.x += static_cast<float>(deltaX) * scaleX / 2;
m_pointerPos.y += static_cast<float>(deltaY) * scaleY / 2; m_pointerPos.y += static_cast<float>(deltaY) * scaleY / 2;
if (m_pointerPos.x < 0.0f) m_pointerPos.x = 0.0f; if (m_pointerPos.x < 0.0f) m_pointerPos.x = 0.0f;
if (m_pointerPos.x > static_cast<float>(m_movieWidth)) m_pointerPos.x = static_cast<float>(m_movieWidth); if (m_pointerPos.x > static_cast<float>(m_movieWidth)) m_pointerPos.x = static_cast<float>(m_movieWidth);
if (m_pointerPos.y < 0.0f) m_pointerPos.y = 0.0f; if (m_pointerPos.y < 0.0f) m_pointerPos.y = 0.0f;
if (m_pointerPos.y > static_cast<float>(m_movieHeight)) m_pointerPos.y = static_cast<float>(m_movieHeight); if (m_pointerPos.y > static_cast<float>(m_movieHeight)) m_pointerPos.y = static_cast<float>(m_movieHeight);
} }
IggyEvent mouseEvent; IggyEvent mouseEvent;
S32 width, height; S32 width, height;
m_parentLayer->getRenderDimensions(width, height); m_parentLayer->getRenderDimensions(width, height);
@@ -246,15 +217,12 @@ void UIScene_AchievementsMenu::tick()
IggyMakeEventMouseMove(&mouseEvent, x, y); IggyMakeEventMouseMove(&mouseEvent, x, y);
IggyEventResult result; IggyEventResult result;
IggyPlayerDispatchEventRS(getMovie(), &mouseEvent, &result);*/ IggyPlayerDispatchEventRS(getMovie(), &mouseEvent, &result);*/
selection = m_achievementsList.m_iCurrentSelection; selection = m_achievementsList.m_iCurrentSelection;
} }
void UIScene_AchievementsMenu::updateTooltips() void UIScene_AchievementsMenu::updateTooltips()
{ {
ui.SetTooltips(m_iPad, -1, IDS_TOOLTIPS_CANCEL, -1, IDS_TOOLTIPS_SHOW_DESCRIPTION); ui.SetTooltips(m_iPad, -1, IDS_TOOLTIPS_CANCEL, -1, IDS_TOOLTIPS_SHOW_DESCRIPTION);
} }
void UIScene_AchievementsMenu::handleFocusChange(F64 controlId, F64 childId) void UIScene_AchievementsMenu::handleFocusChange(F64 controlId, F64 childId)
{ {
switch (static_cast<int>(controlId)) switch (static_cast<int>(controlId))
@@ -1,16 +1,13 @@
#pragma once #pragma once
#include <string> #include <string>
#include "Common/UI/UIScene.h" #include "Common/UI/UIScene.h"
#include "Common/UI/UIControl_Button.h" #include "Common/UI/UIControl_Button.h"
#include "Common/UI/UIControl_Cursor.h" #include "Common/UI/UIControl_Cursor.h"
#include "UIControl_AchievementsList.h" #include "UIControl_AchievementsList.h"
#include "UIControl_Label.h" #include "Common/UI/UIControl_Label.h"
class UIScene_AchievementsMenu : public UIScene class UIScene_AchievementsMenu : public UIScene
{ {
private: private:
enum EControls enum EControls
{ {
eControl_AchievementsLabel, eControl_AchievementsLabel,
@@ -36,10 +33,8 @@ private:
UI_MAP_ELEMENT(m_achievementsList, "AchievementsList") UI_MAP_ELEMENT(m_achievementsList, "AchievementsList")
UI_END_MAP_CHILD_ELEMENTS() UI_END_MAP_CHILD_ELEMENTS()
UI_END_MAP_ELEMENTS_AND_NAMES() UI_END_MAP_ELEMENTS_AND_NAMES()
bool showDescription = false; bool showDescription = false;
public: public:
struct SceneMousePos struct SceneMousePos
{ {
@@ -62,7 +57,6 @@ public:
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled); virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled);
virtual void handleFocusChange(F64 controlId, F64 childId); virtual void handleFocusChange(F64 controlId, F64 childId);
virtual void updateComponents(); virtual void updateComponents();
virtual void updateTooltips(); virtual void updateTooltips();
protected: protected:
virtual wstring getMoviePath(); virtual wstring getMoviePath();
@@ -4,6 +4,7 @@
#include "../../Minecraft.h" #include "../../Minecraft.h"
#ifdef _WINDOWS64 #ifdef _WINDOWS64
#include "../../Windows64/Network/WinsockNetLayer.h" #include "../../Windows64/Network/WinsockNetLayer.h"
#include "../../../Minecraft.World/DisconnectPacket.h"
static int ConnectingProgress_OnRejectedDialogOK(LPVOID, int iPad, const C4JStorage::EMessageResult) static int ConnectingProgress_OnRejectedDialogOK(LPVOID, int iPad, const C4JStorage::EMessageResult)
{ {
@@ -52,10 +53,10 @@ UIScene_ConnectingProgress::UIScene_ConnectingProgress(int iPad, void *_initData
m_cancelFuncParam = param->cancelFuncParam; m_cancelFuncParam = param->cancelFuncParam;
m_removeLocalPlayer = false; m_removeLocalPlayer = false;
m_showingButton = false; m_showingButton = false;
#ifdef _WINDOWS64 #ifdef _WINDOWS64
WinsockNetLayer::eJoinState initState = WinsockNetLayer::GetJoinState(); WinsockNetLayer::eJoinState initState = WinsockNetLayer::GetJoinState();
m_asyncJoinActive = (initState == WinsockNetLayer::eJoinState_Connecting || m_asyncJoinActive = (initState != WinsockNetLayer::eJoinState_Idle && initState != WinsockNetLayer::eJoinState_Cancelled);
initState == WinsockNetLayer::eJoinState_Success);
m_asyncJoinFailed = false; m_asyncJoinFailed = false;
#endif #endif
} }
@@ -71,12 +72,12 @@ void UIScene_ConnectingProgress::updateTooltips()
#ifdef _WINDOWS64 #ifdef _WINDOWS64
if (m_asyncJoinActive) if (m_asyncJoinActive)
{ {
ui.SetTooltips(m_iPad, -1, IDS_TOOLTIPS_BACK); ui.SetTooltips( m_iPad, -1, IDS_TOOLTIPS_BACK);
return; return;
} }
if (m_asyncJoinFailed) if (m_asyncJoinFailed)
{ {
ui.SetTooltips(m_iPad, IDS_TOOLTIPS_SELECT, -1); ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT, -1);
return; return;
} }
#endif #endif
@@ -93,54 +94,78 @@ void UIScene_ConnectingProgress::tick()
if (m_asyncJoinActive) if (m_asyncJoinActive)
{ {
WinsockNetLayer::eJoinState state = WinsockNetLayer::GetJoinState(); WinsockNetLayer::eJoinState state = WinsockNetLayer::GetJoinState();
switch (state) if (state == WinsockNetLayer::eJoinState_Connecting)
{
case WinsockNetLayer::eJoinState_Connecting:
{ {
// connecting.............
int attempt = WinsockNetLayer::GetJoinAttempt(); int attempt = WinsockNetLayer::GetJoinAttempt();
int maxAttempts = WinsockNetLayer::GetJoinMaxAttempts(); int maxAttempts = WinsockNetLayer::GetJoinMaxAttempts();
wchar_t buf[128]; char buf[128];
if (attempt > 1) if (attempt <= 1)
swprintf_s(buf, L"Connecting... (attempt %d/%d)", attempt, maxAttempts); sprintf_s(buf, "Connecting...");
else else
swprintf_s(buf, L"Connecting..."); sprintf_s(buf, "Connecting failed, trying again (%d/%d)", attempt, maxAttempts);
m_labelTitle.setLabel(buf); wchar_t wbuf[128];
break; mbstowcs(wbuf, buf, 128);
m_labelTitle.setLabel(wstring(wbuf));
} }
case WinsockNetLayer::eJoinState_Success: else if (state == WinsockNetLayer::eJoinState_Success)
m_asyncJoinActive = false;
m_labelTitle.setLabel(L"Joining world...");
break;
case WinsockNetLayer::eJoinState_Cancelled:
m_asyncJoinActive = false;
navigateBack();
break;
case WinsockNetLayer::eJoinState_Rejected:
{ {
m_asyncJoinActive = false;
// go go go
}
else if (state == WinsockNetLayer::eJoinState_Cancelled)
{
// cancel
m_asyncJoinActive = false;
navigateBack();
}
else if (state == WinsockNetLayer::eJoinState_Rejected)
{
// server full and banned are passed differently compared to other disconnects it seems
m_asyncJoinActive = false; m_asyncJoinActive = false;
DisconnectPacket::eDisconnectReason reason = WinsockNetLayer::GetJoinRejectReason(); DisconnectPacket::eDisconnectReason reason = WinsockNetLayer::GetJoinRejectReason();
int reasonStringId = IDS_CONNECTION_LOST_SERVER; int exitReasonStringId;
if (reason == DisconnectPacket::eDisconnect_ServerFull) switch (reason)
reasonStringId = IDS_DISCONNECTED_SERVER_FULL; {
else if (reason == DisconnectPacket::eDisconnect_Kicked) case DisconnectPacket::eDisconnect_ServerFull:
reasonStringId = IDS_DISCONNECTED_KICKED; exitReasonStringId = IDS_DISCONNECTED_SERVER_FULL;
break;
case DisconnectPacket::eDisconnect_Banned:
exitReasonStringId = IDS_DISCONNECTED_KICKED;
break;
default:
exitReasonStringId = IDS_CONNECTION_LOST_SERVER;
break;
}
UINT uiIDA[1]; UINT uiIDA[1];
uiIDA[0] = IDS_CONFIRM_OK; uiIDA[0] = IDS_CONFIRM_OK;
ui.RequestErrorMessage(IDS_CONNECTION_FAILED, reasonStringId, uiIDA, 1, m_iPad, ConnectingProgress_OnRejectedDialogOK, nullptr); ui.RequestErrorMessage(IDS_CONNECTION_FAILED, exitReasonStringId, uiIDA, 1, ProfileManager.GetPrimaryPad(), ConnectingProgress_OnRejectedDialogOK, nullptr, nullptr);
break;
} }
case WinsockNetLayer::eJoinState_Failed: else if (state == WinsockNetLayer::eJoinState_Failed)
{
// FAIL
m_asyncJoinActive = false; m_asyncJoinActive = false;
m_asyncJoinFailed = true; m_asyncJoinFailed = true;
m_labelTitle.setLabel(app.GetString(IDS_CONNECTION_FAILED));
int maxAttempts = WinsockNetLayer::GetJoinMaxAttempts();
char buf[256];
sprintf_s(buf, "Failed to connect after %d attempts. The server may be unavailable.", maxAttempts);
wchar_t wbuf[256];
mbstowcs(wbuf, buf, 256);
// TIL that these exist
// not going to use a actual popup due to it requiring messing with strings which can really mess things up
// i dont trust myself with that
// these need to be touched up later as teh button is a bit offset
m_labelTitle.setLabel(L"Unable to connect to server");
m_progressBar.setLabel(wstring(wbuf));
m_progressBar.showBar(false);
m_progressBar.setVisible(true);
m_buttonConfirm.setVisible(true); m_buttonConfirm.setVisible(true);
m_showingButton = true; m_showingButton = true;
updateTooltips(); m_controlTimer.setVisible(false);
break;
default:
break;
} }
return;
} }
#endif #endif
@@ -177,6 +202,7 @@ void UIScene_ConnectingProgress::handleGainFocus(bool navBack)
void UIScene_ConnectingProgress::handleLoseFocus() void UIScene_ConnectingProgress::handleLoseFocus()
{ {
if (!m_runFailTimer) return; if (!m_runFailTimer) return;
int millisecsLeft = getTimer(0)->targetTime - System::currentTimeMillis(); int millisecsLeft = getTimer(0)->targetTime - System::currentTimeMillis();
int millisecsTaken = getTimer(0)->duration - millisecsLeft; int millisecsTaken = getTimer(0)->duration - millisecsLeft;
app.DebugPrintf("\n"); app.DebugPrintf("\n");
@@ -290,6 +316,7 @@ void UIScene_ConnectingProgress::handleInput(int iPad, int key, bool repeat, boo
switch(key) switch(key)
{ {
// 4J-PB - Removed the option to cancel join - it didn't work anyway
#ifdef _WINDOWS64 #ifdef _WINDOWS64
case ACTION_MENU_CANCEL: case ACTION_MENU_CANCEL:
if (pressed && m_asyncJoinActive) if (pressed && m_asyncJoinActive)
@@ -298,11 +325,9 @@ void UIScene_ConnectingProgress::handleInput(int iPad, int key, bool repeat, boo
WinsockNetLayer::CancelJoinGame(); WinsockNetLayer::CancelJoinGame();
navigateBack(); navigateBack();
handled = true; handled = true;
return;
} }
break; break;
#endif #endif
// 4J-PB - Removed the option to cancel join - it didn't work anyway
// case ACTION_MENU_CANCEL: // case ACTION_MENU_CANCEL:
// { // {
// if(m_cancelFunc != nullptr) // if(m_cancelFunc != nullptr)
@@ -349,8 +374,8 @@ void UIScene_ConnectingProgress::handlePress(F64 controlId, F64 childId)
if (m_asyncJoinFailed) if (m_asyncJoinFailed)
{ {
navigateBack(); navigateBack();
break;
} }
else
#endif #endif
if( m_iPad != ProfileManager.GetPrimaryPad() && g_NetworkManager.IsInSession() ) if( m_iPad != ProfileManager.GetPrimaryPad() && g_NetworkManager.IsInSession() )
{ {
@@ -12,6 +12,7 @@ private:
bool m_showingButton; bool m_showingButton;
void (*m_cancelFunc)(LPVOID param); void (*m_cancelFunc)(LPVOID param);
LPVOID m_cancelFuncParam; LPVOID m_cancelFuncParam;
#ifdef _WINDOWS64 #ifdef _WINDOWS64
bool m_asyncJoinActive; bool m_asyncJoinActive;
bool m_asyncJoinFailed; bool m_asyncJoinFailed;
@@ -26,9 +26,6 @@
#define GAME_CREATE_ONLINE_TIMER_ID 0 #define GAME_CREATE_ONLINE_TIMER_ID 0
#define GAME_CREATE_ONLINE_TIMER_TIME 100 #define GAME_CREATE_ONLINE_TIMER_TIME 100
// byte added: fuck hardcore
//static bool s_bHardcore = false; // 4J Added: tracks when difficulty slider is at Hardcore position (file-scope to avoid header layout changes)
int UIScene_CreateWorldMenu::m_iDifficultyTitleSettingA[4]= int UIScene_CreateWorldMenu::m_iDifficultyTitleSettingA[4]=
{ {
IDS_DIFFICULTY_TITLE_PEACEFUL, IDS_DIFFICULTY_TITLE_PEACEFUL,
@@ -657,14 +654,9 @@ void UIScene_CreateWorldMenu::handleSliderMove(F64 sliderId, F64 currentValue)
case eControl_Difficulty: case eControl_Difficulty:
m_sliderDifficulty.handleSliderMove(value); m_sliderDifficulty.handleSliderMove(value);
// 4J Added: Difficulty value 4 = Hardcore (store actual difficulty as Hard, track hardcore separately) app.SetGameSettings(m_iPad,eGameSetting_Difficulty,value);
app.SetGameSettings(m_iPad, eGameSetting_Difficulty, value); swprintf( (WCHAR *)TempString, 256, L"%ls: %ls", app.GetString( IDS_SLIDER_DIFFICULTY ),app.GetString(m_iDifficultyTitleSettingA[value]));
m_sliderDifficulty.setLabel(TempString);
swprintf((WCHAR*)TempString, 256, L"%ls: %ls",
app.GetString(IDS_SLIDER_DIFFICULTY),
app.GetString(m_iDifficultyTitleSettingA[value]));
m_sliderDifficulty.setLabel(TempString);
break; break;
} }
} }
@@ -831,7 +823,7 @@ void UIScene_CreateWorldMenu::checkStateAndStartGame()
// 4J Stu - This is a bit messy and is due to the library incorrectly returning false for IsSignedInLive if the npAvailability isn't SCE_OK // 4J Stu - This is a bit messy and is due to the library incorrectly returning false for IsSignedInLive if the npAvailability isn't SCE_OK
UINT uiIDA[1]; UINT uiIDA[1];
uiIDA[0]=IDS_OK; uiIDA[0]=IDS_OK;
ui.RequestAlertMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, iPadNotSignedInLive); ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, iPadNotSignedInLive);
} }
else else
{ {
@@ -1121,10 +1113,6 @@ void UIScene_CreateWorldMenu::CreateGame(UIScene_CreateWorldMenu* pClass, DWORD
StorageManager.ResetSaveData(); StorageManager.ResetSaveData();
// Make our next save default to the name of the level // Make our next save default to the name of the level
StorageManager.SetSaveTitle((wchar_t *)wWorldName.c_str()); StorageManager.SetSaveTitle((wchar_t *)wWorldName.c_str());
#ifdef _WINDOWS64
// New world — save folder doesn't exist yet, clear for now (will be set after first autosave)
app.SetCurrentSaveFolderName(L"");
#endif
wstring wSeed; wstring wSeed;
if(!pClass->m_MoreOptionsParams.seed.empty() ) if(!pClass->m_MoreOptionsParams.seed.empty() )
@@ -1191,8 +1179,7 @@ void UIScene_CreateWorldMenu::CreateGame(UIScene_CreateWorldMenu* pClass, DWORD
Minecraft *pMinecraft = Minecraft::GetInstance(); Minecraft *pMinecraft = Minecraft::GetInstance();
pMinecraft->skins->selectTexturePackById(pClass->m_MoreOptionsParams.dwTexturePack); pMinecraft->skins->selectTexturePackById(pClass->m_MoreOptionsParams.dwTexturePack);
// 4J Added: If hardcore was selected on difficulty slider, set difficulty to Hard and enable hardcore flag app.SetGameHostOption(eGameHostOption_Difficulty,Minecraft::GetInstance()->options->difficulty);
app.SetGameHostOption(eGameHostOption_Difficulty, Minecraft::GetInstance()->options->difficulty);
app.SetGameHostOption(eGameHostOption_FriendsOfFriends,pClass->m_MoreOptionsParams.bAllowFriendsOfFriends); app.SetGameHostOption(eGameHostOption_FriendsOfFriends,pClass->m_MoreOptionsParams.bAllowFriendsOfFriends);
app.SetGameHostOption(eGameHostOption_Gamertags,app.GetGameSettings(pClass->m_iPad,eGameSetting_GamertagsVisible)?1:0); app.SetGameHostOption(eGameHostOption_Gamertags,app.GetGameSettings(pClass->m_iPad,eGameSetting_GamertagsVisible)?1:0);
+9 -10
View File
@@ -490,21 +490,20 @@ SCreditTextItemDef UIScene_Credits::gs_aCreditDefs[MAX_CREDIT_STRINGS] =
#endif #endif
{L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText}, {L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText}, {L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"LCE-Revelations", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eExtraLargeText}, {L"MinecraftConsoles", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eExtraLargeText},
{L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText}, {L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"Project Maintainers", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eLargeText}, {L"Project Maintainers", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eLargeText},
{L"codeHusky", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText}, {L"codeHusky", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"mattsumi", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText}, {L"mattsumi", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"itsRevela", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"Former Maintainers", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eLargeText},
{L"smartcmd", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"Patoke", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"rtm516", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText}, {L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"Former Maintainers", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eLargeText},
{L"smartcmd", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"Patoke", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"rtm516", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"Thank you to our 120+ contributors on GitHub!", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eLargeText}, {L"Thank you to our 120+ contributors on GitHub!", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eLargeText},
{L"github.com/MCLCE/MinecraftConsoles", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText}, {L"github.com/MCLCE/MinecraftConsoles", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"(formerly smartcmd/MinecraftConsoles)", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText}, {L"(formerly smartcmd/MinecraftConsoles)", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText}, {L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText}, {L"", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eSmallText},
{L"Additional Thanks", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eLargeText}, {L"Additional Thanks", NO_TRANSLATED_STRING, NO_TRANSLATED_STRING, eLargeText},
@@ -3,42 +3,24 @@
#include "UIScene_DeathMenu.h" #include "UIScene_DeathMenu.h"
#include "IUIScene_PauseMenu.h" #include "IUIScene_PauseMenu.h"
#include "../../Minecraft.h" #include "../../Minecraft.h"
#include "../../MultiPlayerLevel.h"
#include "../../MultiPlayerLocalPlayer.h" #include "../../MultiPlayerLocalPlayer.h"
#include "../../MinecraftServer.h"
#include "../../../Minecraft.World/net.minecraft.world.level.storage.h"
UIScene_DeathMenu::UIScene_DeathMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) UIScene_DeathMenu::UIScene_DeathMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
{ {
// Setup all the Iggy references we need for this scene // Setup all the Iggy references we need for this scene
initialiseMovie(); initialiseMovie();
m_buttonRespawn.init(app.GetString(IDS_RESPAWN),eControl_Respawn);
m_buttonExitGame.init(app.GetString(IDS_EXIT_GAME),eControl_ExitGame); m_buttonExitGame.init(app.GetString(IDS_EXIT_GAME),eControl_ExitGame);
m_labelTitle.setLabel(app.GetString(IDS_YOU_DIED)); m_labelTitle.setLabel(app.GetString(IDS_YOU_DIED));
// 4J Added: In hardcore mode, disable respawn and show hardcore death message
Minecraft *pMC = Minecraft::GetInstance();
bool isHardcore = false;
if (pMC != nullptr && pMC->level != nullptr)
{
isHardcore = pMC->level->getLevelData()->isHardcore();
}
if (isHardcore)
{
m_buttonRespawn.setVisible(false);
}
else
{
m_buttonRespawn.init(app.GetString(IDS_RESPAWN), eControl_Respawn);
}
m_bIgnoreInput = false; m_bIgnoreInput = false;
if(pMC != nullptr && pMC->localgameModes[iPad] != nullptr ) Minecraft *pMinecraft = Minecraft::GetInstance();
if(pMinecraft != nullptr && pMinecraft->localgameModes[iPad] != nullptr )
{ {
TutorialMode *gameMode = static_cast<TutorialMode *>(pMC->localgameModes[iPad]); TutorialMode *gameMode = static_cast<TutorialMode *>(pMinecraft->localgameModes[iPad]);
// This just allows it to be shown // This just allows it to be shown
gameMode->getTutorial()->showTutorialPopup(false); gameMode->getTutorial()->showTutorialPopup(false);
@@ -102,16 +84,8 @@ void UIScene_DeathMenu::handlePress(F64 controlId, F64 childId)
switch(static_cast<int>(controlId)) switch(static_cast<int>(controlId))
{ {
case eControl_Respawn: case eControl_Respawn:
{ m_bIgnoreInput = true;
// 4J Added: Safeguard - don't respawn in hardcore mode app.SetAction(m_iPad,eAppAction_Respawn);
Minecraft *pMC = Minecraft::GetInstance();
if (pMC != nullptr && pMC->level != nullptr && pMC->level->getLevelData()->isHardcore())
{
break;
}
m_bIgnoreInput = true;
app.SetAction(m_iPad,eAppAction_Respawn);
}
#ifdef _DURANGO #ifdef _DURANGO
//InputManager.SetEnabledGtcButtons(_360_GTC_MENU|_360_GTC_PAUSE|_360_GTC_VIEW); //InputManager.SetEnabledGtcButtons(_360_GTC_MENU|_360_GTC_PAUSE|_360_GTC_VIEW);
#endif #endif
@@ -136,15 +110,6 @@ void UIScene_DeathMenu::handlePress(F64 controlId, F64 childId)
} }
TelemetryManager->RecordLevelExit(m_iPad, eSen_LevelExitStatus_Failed); TelemetryManager->RecordLevelExit(m_iPad, eSen_LevelExitStatus_Failed);
// 4J Added: Hardcore mode — skip save dialog, exit without saving, delete world
if (pMinecraft->level != nullptr && pMinecraft->level->getLevelData()->isHardcore() && g_NetworkManager.IsHost())
{
MinecraftServer::getInstance()->setSaveOnExit(false);
MinecraftServer::getInstance()->setDeleteWorldOnExit(true);
app.SetAction(m_iPad, eAppAction_ExitWorld);
break;
}
#if defined (_XBOX_ONE) || defined(__ORBIS__) #if defined (_XBOX_ONE) || defined(__ORBIS__)
if(g_NetworkManager.IsHost() && StorageManager.GetSaveDisabled()) if(g_NetworkManager.IsHost() && StorageManager.GetSaveDisabled())
{ {
@@ -240,17 +240,13 @@ void UIScene_DebugOverlay::handlePress(F64 controlId, F64 childId)
case eControl_SetDay: case eControl_SetDay:
{ {
ClientConnection *conn = Minecraft::GetInstance()->getConnection(ProfileManager.GetPrimaryPad()); ClientConnection *conn = Minecraft::GetInstance()->getConnection(ProfileManager.GetPrimaryPad());
conn->send( conn->send( TimeCommand::preparePacket(false) );
TimeCommand::preparePacket(L"set", L"day")
);
} }
break; break;
case eControl_SetNight: case eControl_SetNight:
{ {
ClientConnection *conn = Minecraft::GetInstance()->getConnection(ProfileManager.GetPrimaryPad()); ClientConnection *conn = Minecraft::GetInstance()->getConnection(ProfileManager.GetPrimaryPad());
conn->send( conn->send( TimeCommand::preparePacket(true) );
TimeCommand::preparePacket(L"set", L"night")
);
} }
break; break;
}; };
+1 -13
View File
@@ -50,19 +50,7 @@ UIScene_EndPoem::UIScene_EndPoem(int iPad, void *initData, UILayer *parentLayer)
Minecraft *pMinecraft = Minecraft::GetInstance(); Minecraft *pMinecraft = Minecraft::GetInstance();
wstring playerName = L""; wstring playerName = L"";
unsigned int winIdx = ui.GetWinUserIndex(); playerName = escapeXML( pMinecraft->localplayers[ProfileManager.GetPrimaryPad()]->getDisplayName() );
if(winIdx < XUSER_MAX_COUNT && pMinecraft->localplayers[winIdx] != nullptr)
{
playerName = escapeXML( pMinecraft->localplayers[winIdx]->getDisplayName() );
}
else if(pMinecraft->localplayers[ProfileManager.GetPrimaryPad()] != nullptr)
{
playerName = escapeXML( pMinecraft->localplayers[ProfileManager.GetPrimaryPad()]->getDisplayName() );
}
else
{
playerName = L"Player";
}
noNoiseString = replaceAll(noNoiseString,L"{*PLAYER*}",playerName); noNoiseString = replaceAll(noNoiseString,L"{*PLAYER*}",playerName);
Random random(8124371); Random random(8124371);
@@ -287,11 +287,7 @@ void UIScene_FullscreenProgress::handleInput(int iPad, int key, bool repeat, boo
case ACTION_MENU_CANCEL: case ACTION_MENU_CANCEL:
if( pressed && m_cancelFunc != nullptr && !m_bWasCancelled ) if( pressed && m_cancelFunc != nullptr && !m_bWasCancelled )
{ {
m_cancelText = -1;
updateTooltips();
m_bWasCancelled = true; m_bWasCancelled = true;
m_cancelFunc( m_cancelFuncParam ); m_cancelFunc( m_cancelFuncParam );
} }
break; break;
@@ -660,23 +660,6 @@ void UIScene_HUD::SetHorseJumpBarProgress(float progress)
} }
} }
void UIScene_HUD::SetHardcoreMode(bool bHardcore)
{
IggyDataValue result;
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_boolean;
value[0].boolval = bHardcore;
IggyResult out = IggyPlayerCallMethodRS ( getMovie() , &result, IggyPlayerRootPath( getMovie() ), m_funcSetHardcore , 1 , value );
// When hardcore state changes, invalidate SetHealth's dirty check
// so hearts are redrawn with the correct frame set on the next tick
if(bHardcore != m_lastHealthHardcore)
{
m_lastHealthHardcore = bHardcore;
m_lastMaxHealth = -1;
}
}
void UIScene_HUD::SetHealthAbsorb(int healthAbsorb) void UIScene_HUD::SetHealthAbsorb(int healthAbsorb)
{ {
if(m_iCurrentHealthAbsorb != healthAbsorb) if(m_iCurrentHealthAbsorb != healthAbsorb)
-4
View File
@@ -25,7 +25,6 @@ protected:
IggyName m_funcRepositionHud, m_funcSetDisplayName, m_funcSetTooltipsEnabled; IggyName m_funcRepositionHud, m_funcSetDisplayName, m_funcSetTooltipsEnabled;
IggyName m_funcSetRidingHorse, m_funcSetHorseHealth, m_funcSetHorseJumpBarProgress; IggyName m_funcSetRidingHorse, m_funcSetHorseHealth, m_funcSetHorseJumpBarProgress;
IggyName m_funcSetHealthAbsorb; IggyName m_funcSetHealthAbsorb;
IggyName m_funcSetHardcore;
UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene)
UI_MAP_ELEMENT(m_labelChatText[0],"Label1") UI_MAP_ELEMENT(m_labelChatText[0],"Label1")
UI_MAP_ELEMENT(m_labelChatText[1],"Label2") UI_MAP_ELEMENT(m_labelChatText[1],"Label2")
@@ -90,7 +89,6 @@ protected:
UI_MAP_NAME(m_funcSetHorseJumpBarProgress, L"SetHorseJumpBarProgress") UI_MAP_NAME(m_funcSetHorseJumpBarProgress, L"SetHorseJumpBarProgress")
UI_MAP_NAME(m_funcSetHealthAbsorb, L"SetHealthAbsorb") UI_MAP_NAME(m_funcSetHealthAbsorb, L"SetHealthAbsorb")
UI_MAP_NAME(m_funcSetHardcore, L"SetHardcore")
UI_END_MAP_ELEMENTS_AND_NAMES() UI_END_MAP_ELEMENTS_AND_NAMES()
public: public:
@@ -161,8 +159,6 @@ private:
void SetHealthAbsorb(int healthAbsorb); void SetHealthAbsorb(int healthAbsorb);
void SetHardcoreMode(bool bHardcore);
public: public:
void SetSelectedLabel(const wstring &label); void SetSelectedLabel(const wstring &label);
void ShowDisplayName(bool show); void ShowDisplayName(bool show);
@@ -27,13 +27,6 @@ UIScene_InGameInfoMenu::UIScene_InGameInfoMenu(int iPad, void *initData, UILayer
{ {
PlayerInfo *info = BuildPlayerInfo(player); PlayerInfo *info = BuildPlayerInfo(player);
// Skip the dedicated server's phantom host entry (slot 0, empty name)
if (info->m_smallId == 0 && info->m_name.empty())
{
delete info;
continue;
}
m_players.push_back(info); m_players.push_back(info);
m_playerList.addItem(info->m_name, info->m_colorState, info->m_voiceStatus); m_playerList.addItem(info->m_name, info->m_colorState, info->m_voiceStatus);
} }
@@ -181,13 +174,6 @@ void UIScene_InGameInfoMenu::handleReload()
{ {
PlayerInfo *info = BuildPlayerInfo(player); PlayerInfo *info = BuildPlayerInfo(player);
// Skip the dedicated server's phantom host entry (slot 0, empty name)
if (info->m_smallId == 0 && info->m_name.empty())
{
delete info;
continue;
}
m_players.push_back(info); m_players.push_back(info);
m_playerList.addItem(info->m_name, info->m_colorState, info->m_voiceStatus); m_playerList.addItem(info->m_name, info->m_colorState, info->m_voiceStatus);
} }
@@ -216,16 +202,17 @@ void UIScene_InGameInfoMenu::tick()
{ {
UIScene::tick(); UIScene::tick();
// Update players by their stored smallId (not sequential index, which can mismatch // Update players by index
// when entries like the dedicated server host are filtered from the UI list)
for(DWORD i = 0; i < m_players.size(); ++i) for(DWORD i = 0; i < m_players.size(); ++i)
{ {
INetworkPlayer *player = g_NetworkManager.GetPlayerBySmallId( m_players[i]->m_smallId ); INetworkPlayer *player = g_NetworkManager.GetPlayerByIndex( i );
if(player != nullptr) if(player != nullptr)
{ {
PlayerInfo *info = BuildPlayerInfo(player); PlayerInfo *info = BuildPlayerInfo(player);
m_players[i]->m_smallId = info->m_smallId;
if(info->m_voiceStatus != m_players[i]->m_voiceStatus) if(info->m_voiceStatus != m_players[i]->m_voiceStatus)
{ {
m_players[i]->m_voiceStatus = info->m_voiceStatus; m_players[i]->m_voiceStatus = info->m_voiceStatus;
@@ -437,17 +424,9 @@ void UIScene_InGameInfoMenu::OnPlayerChanged(void *callbackParam, INetworkPlayer
// If the player is joining // If the player is joining
if(!leaving) if(!leaving)
{ {
PlayerInfo *info = scene->BuildPlayerInfo(pPlayer);
// Skip the dedicated server's phantom host entry (slot 0, empty name)
if (pPlayer->GetSmallId() == 0 && info->m_name.empty())
{
delete info;
return;
}
app.DebugPrintf("<UIScene_InGameInfoMenu::OnPlayerChanged> Player \"%ls\" not found, adding\n", pPlayer->GetOnlineName()); app.DebugPrintf("<UIScene_InGameInfoMenu::OnPlayerChanged> Player \"%ls\" not found, adding\n", pPlayer->GetOnlineName());
PlayerInfo *info = scene->BuildPlayerInfo(pPlayer);
scene->m_players.push_back(info); scene->m_players.push_back(info);
// Note that the tick updates buttons every tick so it's only really important that we // Note that the tick updates buttons every tick so it's only really important that we
@@ -512,7 +491,7 @@ UIScene_InGameInfoMenu::PlayerInfo *UIScene_InGameInfoMenu::BuildPlayerInfo(INet
} }
info->m_voiceStatus = voiceStatus; info->m_voiceStatus = voiceStatus;
info->m_colorState = app.GetPlayerMapIconByName(player->GetOnlineName()); info->m_colorState = app.GetPlayerColour(info->m_smallId);
info->m_name = playerName; info->m_name = playerName;
return info; return info;
+10 -359
View File
@@ -1,15 +1,12 @@
#include "stdafx.h" #include "stdafx.h"
#include "UI.h" #include "UI.h"
#include "UIScene_JoinMenu.h" #include "UIScene_JoinMenu.h"
#include "../../Minecraft.h" #include "..\..\Minecraft.h"
#include "../../TexturePackRepository.h" #include "..\..\TexturePackRepository.h"
#include "../../Options.h" #include "..\..\Options.h"
#include "../../MinecraftServer.h" #include "..\..\MinecraftServer.h"
#include "../../../Minecraft.World/net.minecraft.world.level.h" #include "..\..\..\Minecraft.World\net.minecraft.world.level.h"
#include "../../../Minecraft.World/net.minecraft.world.h" #include "..\..\..\Minecraft.World\net.minecraft.world.h"
#ifdef _WINDOWS64
#include "../../Windows64/Network/WinsockNetLayer.h"
#endif
#define UPDATE_PLAYERS_TIMER_ID 0 #define UPDATE_PLAYERS_TIMER_ID 0
#define UPDATE_PLAYERS_TIMER_TIME 30000 #define UPDATE_PLAYERS_TIMER_TIME 30000
@@ -24,12 +21,6 @@ UIScene_JoinMenu::UIScene_JoinMenu(int iPad, void *_initData, UILayer *parentLay
m_friendInfoUpdatedOK = false; m_friendInfoUpdatedOK = false;
m_friendInfoUpdatedERROR = false; m_friendInfoUpdatedERROR = false;
m_friendInfoRequestIssued = false; m_friendInfoRequestIssued = false;
#ifdef _WINDOWS64
m_serverIndex = initData->serverIndex;
m_editServerPhase = eEditServer_Idle;
m_editServerButtonIndex = -1;
m_deleteServerButtonIndex = -1;
#endif
} }
void UIScene_JoinMenu::updateTooltips() void UIScene_JoinMenu::updateTooltips()
@@ -125,16 +116,6 @@ void UIScene_JoinMenu::tick()
} }
#endif #endif
#ifdef _WINDOWS64
if (m_serverIndex >= 0)
{
m_editServerButtonIndex = m_buttonListPlayers.getItemCount();
m_buttonListPlayers.addItem(L"Edit Server");
m_deleteServerButtonIndex = m_buttonListPlayers.getItemCount();
m_buttonListPlayers.addItem(L"Delete Server");
}
#endif
m_labelLabels[eLabel_Difficulty].init(app.GetString(IDS_LABEL_DIFFICULTY)); m_labelLabels[eLabel_Difficulty].init(app.GetString(IDS_LABEL_DIFFICULTY));
m_labelLabels[eLabel_GameType].init(app.GetString(IDS_LABEL_GAME_TYPE)); m_labelLabels[eLabel_GameType].init(app.GetString(IDS_LABEL_GAME_TYPE));
m_labelLabels[eLabel_GamertagsOn].init(app.GetString(IDS_LABEL_GAMERTAGS)); m_labelLabels[eLabel_GamertagsOn].init(app.GetString(IDS_LABEL_GAMERTAGS));
@@ -306,38 +287,12 @@ void UIScene_JoinMenu::handleInput(int iPad, int key, bool repeat, bool pressed,
if( uid != INVALID_XUID ) ProfileManager.ShowProfileCard(ProfileManager.GetLockedProfile(),uid); if( uid != INVALID_XUID ) ProfileManager.ShowProfileCard(ProfileManager.GetLockedProfile(),uid);
} }
break; break;
#endif
#ifdef _WINDOWS64
case ACTION_MENU_X:
if(pressed && m_serverIndex >= 0)
{
BeginDeleteServer();
handled = true;
}
break;
case ACTION_MENU_Y:
if(pressed && m_serverIndex >= 0)
{
BeginEditServer();
handled = true;
}
break;
#endif #endif
case ACTION_MENU_OK: case ACTION_MENU_OK:
if (getControlFocus() != eControl_GamePlayers) if (getControlFocus() != eControl_GamePlayers)
{ {
sendInputToMovie(key, repeat, pressed, released); sendInputToMovie(key, repeat, pressed, released);
} }
#ifdef _WINDOWS64
else if (pressed && m_serverIndex >= 0)
{
int sel = m_buttonListPlayers.getCurrentSelection();
if (sel == m_editServerButtonIndex)
BeginEditServer();
else if (sel == m_deleteServerButtonIndex)
BeginDeleteServer();
}
#endif
handled = true; handled = true;
break; break;
#ifdef __ORBIS__ #ifdef __ORBIS__
@@ -372,16 +327,6 @@ void UIScene_JoinMenu::handlePress(F64 controlId, F64 childId)
} }
break; break;
case eControl_GamePlayers: case eControl_GamePlayers:
#ifdef _WINDOWS64
if (m_serverIndex >= 0)
{
int sel = (int)childId;
if (sel == m_editServerButtonIndex)
BeginEditServer();
else if (sel == m_deleteServerButtonIndex)
BeginDeleteServer();
}
#endif
break; break;
}; };
} }
@@ -586,23 +531,6 @@ void UIScene_JoinMenu::JoinGame(UIScene_JoinMenu* pClass)
// Alert the app the we no longer want to be informed of ethernet connections // Alert the app the we no longer want to be informed of ethernet connections
app.SetLiveLinkRequired( false ); app.SetLiveLinkRequired( false );
#ifdef _WINDOWS64
if (result == CGameNetworkManager::JOINGAME_PENDING)
{
pClass->m_bIgnoreInput = false;
ConnectionProgressParams *param = new ConnectionProgressParams();
param->iPad = ProfileManager.GetPrimaryPad();
param->stringId = IDS_PROGRESS_CONNECTING;
param->showTooltips = true;
param->setFailTimer = false;
param->timerTime = 0;
param->cancelFunc = nullptr;
param->cancelFuncParam = nullptr;
ui.NavigateToScene(ProfileManager.GetPrimaryPad(), eUIScene_ConnectingProgress, param);
return;
}
#endif
if( result != CGameNetworkManager::JOINGAME_SUCCESS ) if( result != CGameNetworkManager::JOINGAME_SUCCESS )
{ {
int exitReasonStringId = -1; int exitReasonStringId = -1;
@@ -657,18 +585,16 @@ void UIScene_JoinMenu::JoinGame(UIScene_JoinMenu* pClass)
if( exitReasonStringId == -1 ) if( exitReasonStringId == -1 )
{ {
// No specific disconnect reason was set — the server was likely ui.NavigateBack(pClass->m_iPad);
// unreachable. Show a "Connection Failed" dialog instead of
// silently navigating back so the user knows what happened.
exitReasonStringId = IDS_CONNECTION_LOST_SERVER;
} }
else
{ {
UINT uiIDA[1]; UINT uiIDA[1];
uiIDA[0]=IDS_CONFIRM_OK; uiIDA[0]=IDS_CONFIRM_OK;
ui.RequestErrorMessage( IDS_CONNECTION_FAILED, exitReasonStringId, uiIDA,1,ProfileManager.GetPrimaryPad()); ui.RequestErrorMessage( IDS_CONNECTION_FAILED, exitReasonStringId, uiIDA,1,ProfileManager.GetPrimaryPad());
exitReasonStringId = -1;
pClass->m_bIgnoreInput = false; ui.NavigateToHomeMenu();
} }
} }
} }
@@ -719,278 +645,3 @@ void UIScene_JoinMenu::handleTimerComplete(int id)
break; break;
}; };
} }
#ifdef _WINDOWS64
void UIScene_JoinMenu::BeginDeleteServer()
{
m_bIgnoreInput = true;
UINT uiIDA[2];
uiIDA[0] = IDS_CONFIRM_CANCEL;
uiIDA[1] = IDS_CONFIRM_OK;
ui.RequestAlertMessage(IDS_TOOLTIPS_DELETE, IDS_TEXT_DELETE_SAVE, uiIDA, 2, m_iPad, &UIScene_JoinMenu::DeleteServerDialogReturned, this);
}
int UIScene_JoinMenu::DeleteServerDialogReturned(void *pParam, int iPad, C4JStorage::EMessageResult result)
{
UIScene_JoinMenu* pClass = (UIScene_JoinMenu*)pParam;
if (result == C4JStorage::EMessage_ResultDecline)
{
pClass->RemoveServerFromFile();
g_NetworkManager.ForceFriendsSessionRefresh();
pClass->navigateBack();
}
else
{
pClass->m_bIgnoreInput = false;
}
return 0;
}
void UIScene_JoinMenu::BeginEditServer()
{
m_bIgnoreInput = true;
m_editServerPhase = eEditServer_IP;
m_editServerIP.clear();
m_editServerPort.clear();
wchar_t wDefaultIP[64] = {};
mbstowcs(wDefaultIP, m_selectedSession->data.hostIP, 63);
UIKeyboardInitData kbData;
kbData.title = L"Server Address";
kbData.defaultText = wDefaultIP;
kbData.maxChars = 128;
kbData.callback = &UIScene_JoinMenu::EditServerKeyboardCallback;
kbData.lpParam = this;
kbData.pcMode = g_KBMInput.IsKBMActive();
ui.NavigateToScene(m_iPad, eUIScene_Keyboard, &kbData);
}
int UIScene_JoinMenu::EditServerKeyboardCallback(LPVOID lpParam, bool bRes)
{
UIScene_JoinMenu *pClass = (UIScene_JoinMenu *)lpParam;
if (!bRes)
{
pClass->m_editServerPhase = eEditServer_Idle;
pClass->m_bIgnoreInput = false;
return 0;
}
uint16_t ui16Text[256];
ZeroMemory(ui16Text, sizeof(ui16Text));
Win64_GetKeyboardText(ui16Text, 256);
wchar_t wBuf[256] = {};
for (int k = 0; k < 255 && ui16Text[k]; k++)
wBuf[k] = (wchar_t)ui16Text[k];
if (wBuf[0] == 0)
{
pClass->m_editServerPhase = eEditServer_Idle;
pClass->m_bIgnoreInput = false;
return 0;
}
switch (pClass->m_editServerPhase)
{
case eEditServer_IP:
{
pClass->m_editServerIP = wBuf;
pClass->m_editServerPhase = eEditServer_Port;
wchar_t wDefaultPort[16] = {};
swprintf(wDefaultPort, 16, L"%d", pClass->m_selectedSession->data.hostPort);
UIKeyboardInitData kbData;
kbData.title = L"Server Port";
kbData.defaultText = wDefaultPort;
kbData.maxChars = 6;
kbData.callback = &UIScene_JoinMenu::EditServerKeyboardCallback;
kbData.lpParam = pClass;
kbData.pcMode = g_KBMInput.IsKBMActive();
ui.NavigateToScene(pClass->m_iPad, eUIScene_Keyboard, &kbData);
break;
}
case eEditServer_Port:
{
pClass->m_editServerPort = wBuf;
pClass->m_editServerPhase = eEditServer_Name;
wchar_t wDefaultName[64] = {};
if (pClass->m_selectedSession->displayLabel)
wcsncpy(wDefaultName, pClass->m_selectedSession->displayLabel, 63);
UIKeyboardInitData kbData;
kbData.title = L"Server Name";
kbData.defaultText = wDefaultName;
kbData.maxChars = 64;
kbData.callback = &UIScene_JoinMenu::EditServerKeyboardCallback;
kbData.lpParam = pClass;
kbData.pcMode = g_KBMInput.IsKBMActive();
ui.NavigateToScene(pClass->m_iPad, eUIScene_Keyboard, &kbData);
break;
}
case eEditServer_Name:
{
wstring newName = wBuf;
pClass->UpdateServerInFile(pClass->m_editServerIP, pClass->m_editServerPort, newName);
pClass->m_editServerPhase = eEditServer_Idle;
pClass->m_bIgnoreInput = false;
g_NetworkManager.ForceFriendsSessionRefresh();
pClass->navigateBack();
break;
}
default:
pClass->m_editServerPhase = eEditServer_Idle;
pClass->m_bIgnoreInput = false;
break;
}
return 0;
}
void UIScene_JoinMenu::UpdateServerInFile(const wstring& newIP, const wstring& newPort, const wstring& newName)
{
char narrowNewIP[256] = {};
char narrowNewPort[16] = {};
char narrowNewName[256] = {};
wcstombs(narrowNewIP, newIP.c_str(), sizeof(narrowNewIP) - 1);
wcstombs(narrowNewPort, newPort.c_str(), sizeof(narrowNewPort) - 1);
wcstombs(narrowNewName, newName.c_str(), sizeof(narrowNewName) - 1);
uint16_t newPortNum = (uint16_t)atoi(narrowNewPort);
struct ServerEntry { std::string ip; uint16_t port; std::string name; };
std::vector<ServerEntry> entries;
FILE* file = fopen("servers.db", "rb");
if (file)
{
char magic[4] = {};
if (fread(magic, 1, 4, file) == 4 && memcmp(magic, "MCSV", 4) == 0)
{
uint32_t version = 0, count = 0;
fread(&version, sizeof(uint32_t), 1, file);
fread(&count, sizeof(uint32_t), 1, file);
if (version == 1)
{
for (uint32_t s = 0; s < count; s++)
{
uint16_t ipLen = 0, p = 0, nameLen = 0;
if (fread(&ipLen, sizeof(uint16_t), 1, file) != 1) break;
if (ipLen == 0 || ipLen > 256) break;
char ipBuf[257] = {};
if (fread(ipBuf, 1, ipLen, file) != ipLen) break;
if (fread(&p, sizeof(uint16_t), 1, file) != 1) break;
if (fread(&nameLen, sizeof(uint16_t), 1, file) != 1) break;
if (nameLen > 256) break;
char nameBuf[257] = {};
if (nameLen > 0 && fread(nameBuf, 1, nameLen, file) != nameLen) break;
entries.push_back({std::string(ipBuf), p, std::string(nameBuf)});
}
}
}
fclose(file);
}
// Find and update the matching entry by original IP and port
int idx = m_serverIndex;
if (idx >= 0 && idx < (int)entries.size())
{
entries[idx].ip = std::string(narrowNewIP);
entries[idx].port = newPortNum;
entries[idx].name = std::string(narrowNewName);
}
file = fopen("servers.db", "wb");
if (file)
{
fwrite("MCSV", 1, 4, file);
uint32_t version = 1;
uint32_t count = (uint32_t)entries.size();
fwrite(&version, sizeof(uint32_t), 1, file);
fwrite(&count, sizeof(uint32_t), 1, file);
for (size_t i = 0; i < entries.size(); i++)
{
uint16_t ipLen = (uint16_t)entries[i].ip.length();
fwrite(&ipLen, sizeof(uint16_t), 1, file);
fwrite(entries[i].ip.c_str(), 1, ipLen, file);
fwrite(&entries[i].port, sizeof(uint16_t), 1, file);
uint16_t nameLen = (uint16_t)entries[i].name.length();
fwrite(&nameLen, sizeof(uint16_t), 1, file);
fwrite(entries[i].name.c_str(), 1, nameLen, file);
}
fclose(file);
}
}
void UIScene_JoinMenu::RemoveServerFromFile()
{
struct ServerEntry { std::string ip; uint16_t port; std::string name; };
std::vector<ServerEntry> entries;
FILE* file = fopen("servers.db", "rb");
if (file)
{
char magic[4] = {};
if (fread(magic, 1, 4, file) == 4 && memcmp(magic, "MCSV", 4) == 0)
{
uint32_t version = 0, count = 0;
fread(&version, sizeof(uint32_t), 1, file);
fread(&count, sizeof(uint32_t), 1, file);
if (version == 1)
{
for (uint32_t s = 0; s < count; s++)
{
uint16_t ipLen = 0, p = 0, nameLen = 0;
if (fread(&ipLen, sizeof(uint16_t), 1, file) != 1) break;
if (ipLen == 0 || ipLen > 256) break;
char ipBuf[257] = {};
if (fread(ipBuf, 1, ipLen, file) != ipLen) break;
if (fread(&p, sizeof(uint16_t), 1, file) != 1) break;
if (fread(&nameLen, sizeof(uint16_t), 1, file) != 1) break;
if (nameLen > 256) break;
char nameBuf[257] = {};
if (nameLen > 0 && fread(nameBuf, 1, nameLen, file) != nameLen) break;
entries.push_back({std::string(ipBuf), p, std::string(nameBuf)});
}
}
}
fclose(file);
}
// Remove the entry at m_serverIndex
int idx = m_serverIndex;
if (idx >= 0 && idx < (int)entries.size())
{
entries.erase(entries.begin() + idx);
}
file = fopen("servers.db", "wb");
if (file)
{
fwrite("MCSV", 1, 4, file);
uint32_t version = 1;
uint32_t count = (uint32_t)entries.size();
fwrite(&version, sizeof(uint32_t), 1, file);
fwrite(&count, sizeof(uint32_t), 1, file);
for (size_t i = 0; i < entries.size(); i++)
{
uint16_t ipLen = (uint16_t)entries[i].ip.length();
fwrite(&ipLen, sizeof(uint16_t), 1, file);
fwrite(entries[i].ip.c_str(), 1, ipLen, file);
fwrite(&entries[i].port, sizeof(uint16_t), 1, file);
uint16_t nameLen = (uint16_t)entries[i].name.length();
fwrite(&nameLen, sizeof(uint16_t), 1, file);
fwrite(entries[i].name.c_str(), 1, nameLen, file);
}
fclose(file);
}
}
#endif // _WINDOWS64
@@ -105,13 +105,4 @@ protected:
static int StartGame_SignInReturned(void *pParam, bool, int); static int StartGame_SignInReturned(void *pParam, bool, int);
static void JoinGame(UIScene_JoinMenu* pClass); static void JoinGame(UIScene_JoinMenu* pClass);
#ifdef _WINDOWS64
void BeginEditServer();
void BeginDeleteServer();
static int EditServerKeyboardCallback(LPVOID lpParam, bool bRes);
static int DeleteServerDialogReturned(void *pParam, int iPad, C4JStorage::EMessageResult result);
void UpdateServerInFile(const wstring& newIP, const wstring& newPort, const wstring& newName);
void RemoveServerFromFile();
#endif
}; };
@@ -1,7 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "UI.h" #include "UI.h"
#include "UIScene_LanguageSelector.h" #include "UIScene_LanguageSelector.h"
// pasted from lcen client aswell
// strings for buttons in the list // strings for buttons in the list
const unsigned int UIScene_LanguageSelector::m_uiHTPButtonNameA[]= const unsigned int UIScene_LanguageSelector::m_uiHTPButtonNameA[]=
{ {
+24 -79
View File
@@ -24,7 +24,7 @@
#define CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME 50 #define CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME 50
#endif #endif
int UIScene_LoadMenu::m_iDifficultyTitleSettingA[5]= int UIScene_LoadMenu::m_iDifficultyTitleSettingA[4]=
{ {
IDS_DIFFICULTY_TITLE_PEACEFUL, IDS_DIFFICULTY_TITLE_PEACEFUL,
IDS_DIFFICULTY_TITLE_EASY, IDS_DIFFICULTY_TITLE_EASY,
@@ -53,7 +53,6 @@ int UIScene_LoadMenu::LoadSaveDataThumbnailReturned(LPVOID lpParam,PBYTE pbThumb
app.DebugPrintf("Thumbnail data is nullptr, or has size 0\n"); app.DebugPrintf("Thumbnail data is nullptr, or has size 0\n");
pClass->m_bThumbnailGetFailed = true; pClass->m_bThumbnailGetFailed = true;
} }
pClass->m_bRetrievingSaveThumbnail = false;
} }
return 0; return 0;
@@ -100,7 +99,6 @@ UIScene_LoadMenu::UIScene_LoadMenu(int iPad, void *initData, UILayer *parentLaye
m_bIsSaveOwner = true; m_bIsSaveOwner = true;
m_bSaveThumbnailReady = false; m_bSaveThumbnailReady = false;
m_bRetrievingSaveThumbnail = true;
m_bShowTimer = false; m_bShowTimer = false;
m_pDLCPack = nullptr; m_pDLCPack = nullptr;
m_bAvailableTexturePacksChecked=false; m_bAvailableTexturePacksChecked=false;
@@ -110,7 +108,8 @@ UIScene_LoadMenu::UIScene_LoadMenu(int iPad, void *initData, UILayer *parentLaye
m_bThumbnailGetFailed = false; m_bThumbnailGetFailed = false;
m_seed = 0; m_seed = 0;
m_bIsCorrupt = false; m_bIsCorrupt = false;
m_bHardcore = false; m_pbThumbnailData = nullptr;
m_uiThumbnailSize = 0;
m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad);
// 4J-PB - read the settings for the online flag. We'll only save this setting if the user changed it. // 4J-PB - read the settings for the online flag. We'll only save this setting if the user changed it.
@@ -250,17 +249,17 @@ UIScene_LoadMenu::UIScene_LoadMenu(int iPad, void *initData, UILayer *parentLaye
#endif #endif
#endif #endif
#ifdef _WINDOWS64 #ifdef _WINDOWS64
if (params->saveDetails != nullptr && params->saveDetails->UTF8SaveName[0] != '\0')
{
wchar_t wSaveName[128];
ZeroMemory(wSaveName, sizeof(wSaveName));
MultiByteToWideChar(CP_UTF8, 0, params->saveDetails->UTF8SaveName, -1, wSaveName, 127);
m_levelName = wstring(wSaveName);
m_labelGameName.init(m_levelName);
}
if (params->saveDetails != nullptr) if (params->saveDetails != nullptr)
{ {
// Set thumbnail name from save filename (needed for texture display in tick) if (params->saveDetails->UTF8SaveName[0] != '\0')
{
wchar_t wSaveName[128];
ZeroMemory(wSaveName, sizeof(wSaveName));
mbstowcs(wSaveName, params->saveDetails->UTF8SaveName, 127);
m_levelName = wstring(wSaveName);
m_labelGameName.init(m_levelName);
}
wchar_t wFilename[MAX_SAVEFILENAME_LENGTH]; wchar_t wFilename[MAX_SAVEFILENAME_LENGTH];
ZeroMemory(wFilename, sizeof(wFilename)); ZeroMemory(wFilename, sizeof(wFilename));
mbstowcs(wFilename, params->saveDetails->UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH - 1); mbstowcs(wFilename, params->saveDetails->UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH - 1);
@@ -268,24 +267,14 @@ UIScene_LoadMenu::UIScene_LoadMenu(int iPad, void *initData, UILayer *parentLaye
if (params->saveDetails->pbThumbnailData && params->saveDetails->dwThumbnailSize > 0) if (params->saveDetails->pbThumbnailData && params->saveDetails->dwThumbnailSize > 0)
{ {
// save list already loaded this, register and display it
registerSubstitutionTexture(wFilename, params->saveDetails->pbThumbnailData, params->saveDetails->dwThumbnailSize);
m_bitmapIcon.setTextureName(wFilename);
m_pbThumbnailData = params->saveDetails->pbThumbnailData; m_pbThumbnailData = params->saveDetails->pbThumbnailData;
m_uiThumbnailSize = params->saveDetails->dwThumbnailSize; m_uiThumbnailSize = params->saveDetails->dwThumbnailSize;
m_bSaveThumbnailReady = true; m_bSaveThumbnailReady = true;
m_bRetrievingSaveThumbnail = false;
} }
m_bHardcore = params->saveDetails->isHardcore;
if (m_bHardcore)
{
WCHAR TempString[256];
swprintf((WCHAR *)TempString, 256, L"%ls: %ls", app.GetString(IDS_SLIDER_DIFFICULTY), L"Hardcore");
m_sliderDifficulty.init(TempString, eControl_Difficulty, 0, 4, 4);
// Hardcore locks game mode to Survival
m_iGameModeId = GameType::SURVIVAL->getId();
m_bGameModeCreative = false;
m_buttonGamemode.setLabel(app.GetString(IDS_GAMEMODE_SURVIVAL));
}
} }
#endif #endif
} }
@@ -425,7 +414,15 @@ void UIScene_LoadMenu::updateTooltips()
void UIScene_LoadMenu::updateComponents() void UIScene_LoadMenu::updateComponents()
{ {
m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,true); m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,true);
m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,false);
if(RenderManager.IsWidescreen())
{
m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,true);
}
else
{
m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,false);
}
} }
wstring UIScene_LoadMenu::getMoviePath() wstring UIScene_LoadMenu::getMoviePath()
@@ -510,17 +507,6 @@ void UIScene_LoadMenu::tick()
m_MoreOptionsParams.bNaturalRegeneration = app.GetGameHostOption(uiHostOptions, eGameHostOption_NaturalRegeneration); m_MoreOptionsParams.bNaturalRegeneration = app.GetGameHostOption(uiHostOptions, eGameHostOption_NaturalRegeneration);
m_MoreOptionsParams.bDoDaylightCycle = app.GetGameHostOption(uiHostOptions, eGameHostOption_DoDaylightCycle); m_MoreOptionsParams.bDoDaylightCycle = app.GetGameHostOption(uiHostOptions, eGameHostOption_DoDaylightCycle);
unsigned int saveDifficulty = app.GetGameHostOption(uiHostOptions, eGameHostOption_Difficulty);
if (saveDifficulty <= 3)
{
m_CurrentDifficulty = static_cast<unsigned char>(saveDifficulty);
app.SetGameSettings(m_iPad, eGameSetting_Difficulty, m_CurrentDifficulty);
WCHAR difficultyLabel[256];
swprintf((WCHAR*)difficultyLabel, 256, L"%ls: %ls", app.GetString(IDS_SLIDER_DIFFICULTY), app.GetString(m_iDifficultyTitleSettingA[m_CurrentDifficulty]));
m_sliderDifficulty.init(difficultyLabel, eControl_Difficulty, 0, 3, m_CurrentDifficulty);
}
bool cheatsOn = m_MoreOptionsParams.bHostPrivileges; bool cheatsOn = m_MoreOptionsParams.bHostPrivileges;
if (!cheatsOn) if (!cheatsOn)
{ {
@@ -579,21 +565,6 @@ void UIScene_LoadMenu::tick()
{ {
m_MoreOptionsParams.bAllowFriendsOfFriends = TRUE; m_MoreOptionsParams.bAllowFriendsOfFriends = TRUE;
} }
// Use thumbnail host options if available, otherwise preserve the level.dat value
if (app.GetGameHostOption(uiHostOptions, eGameHostOption_Hardcore) > 0)
m_bHardcore = true;
if (m_bHardcore)
{
WCHAR TempString[256];
swprintf( (WCHAR *)TempString, 256, L"%ls: %ls", app.GetString( IDS_SLIDER_DIFFICULTY ), L"Hardcore");
m_sliderDifficulty.init(TempString, eControl_Difficulty, 0, 4, 4);
// Hardcore locks game mode to Survival
m_iGameModeId = GameType::SURVIVAL->getId();
m_bGameModeCreative = false;
m_buttonGamemode.setLabel(app.GetString(IDS_GAMEMODE_SURVIVAL));
}
} }
Minecraft *pMinecraft = Minecraft::GetInstance(); Minecraft *pMinecraft = Minecraft::GetInstance();
@@ -747,8 +718,6 @@ void UIScene_LoadMenu::handlePress(F64 controlId, F64 childId)
switch(static_cast<int>(controlId)) switch(static_cast<int>(controlId))
{ {
case eControl_GameMode: case eControl_GameMode:
if (m_bHardcore)
break; // Hardcore mode locks game mode to Survival
switch(m_iGameModeId) switch(m_iGameModeId)
{ {
case 0: // Survival case 0: // Survival
@@ -1000,11 +969,6 @@ void UIScene_LoadMenu::handleSliderMove(F64 sliderId, F64 currentValue)
switch(static_cast<int>(sliderId)) switch(static_cast<int>(sliderId))
{ {
case eControl_Difficulty: case eControl_Difficulty:
if (m_bHardcore)
{
m_sliderDifficulty.handleSliderMove(4);
break;
}
m_sliderDifficulty.handleSliderMove(value); m_sliderDifficulty.handleSliderMove(value);
app.SetGameSettings(m_iPad,eGameSetting_Difficulty,value); app.SetGameSettings(m_iPad,eGameSetting_Difficulty,value);
@@ -1635,24 +1599,6 @@ void UIScene_LoadMenu::StartGameFromSave(UIScene_LoadMenu* pClass, DWORD dwLocal
PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo(); PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
#ifdef _WINDOWS64
// 4J Added: Store save folder name for potential hardcore world deletion
app.DebugPrintf("StartGameFromSave: pSaveDetails=%p, levelGen=%p, saveInfoIndex=%d\n", pSaveDetails, pClass->m_levelGen, pClass->m_iSaveGameInfoIndex);
if (pSaveDetails != nullptr && pClass->m_levelGen == nullptr)
{
app.DebugPrintf("StartGameFromSave: UTF8SaveFilename='%s'\n", pSaveDetails->SaveInfoA[(int)pClass->m_iSaveGameInfoIndex].UTF8SaveFilename);
wchar_t wFolder[MAX_SAVEFILENAME_LENGTH] = {};
mbstowcs(wFolder, pSaveDetails->SaveInfoA[(int)pClass->m_iSaveGameInfoIndex].UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH - 1);
app.SetCurrentSaveFolderName(wFolder);
app.DebugPrintf("StartGameFromSave: stored folder name '%ls'\n", wFolder);
}
else
{
app.DebugPrintf("StartGameFromSave: no save details or is levelGen, clearing folder name\n");
app.SetCurrentSaveFolderName(L"");
}
#endif
NetworkGameInitData *param = new NetworkGameInitData(); NetworkGameInitData *param = new NetworkGameInitData();
param->seed = pClass->m_seed; param->seed = pClass->m_seed;
param->saveData = nullptr; param->saveData = nullptr;
@@ -1685,7 +1631,6 @@ void UIScene_LoadMenu::StartGameFromSave(UIScene_LoadMenu* pClass, DWORD dwLocal
app.SetGameHostOption(eGameHostOption_DoTileDrops, pClass->m_MoreOptionsParams.bDoTileDrops); app.SetGameHostOption(eGameHostOption_DoTileDrops, pClass->m_MoreOptionsParams.bDoTileDrops);
app.SetGameHostOption(eGameHostOption_NaturalRegeneration, pClass->m_MoreOptionsParams.bNaturalRegeneration); app.SetGameHostOption(eGameHostOption_NaturalRegeneration, pClass->m_MoreOptionsParams.bNaturalRegeneration);
app.SetGameHostOption(eGameHostOption_DoDaylightCycle, pClass->m_MoreOptionsParams.bDoDaylightCycle); app.SetGameHostOption(eGameHostOption_DoDaylightCycle, pClass->m_MoreOptionsParams.bDoDaylightCycle);
app.SetGameHostOption(eGameHostOption_Hardcore, pClass->m_bHardcore ? 1 : 0);
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
app.SetGameHostOption(eGameHostOption_WorldSize, pClass->m_MoreOptionsParams.worldSize+1 ); // 0 is GAME_HOST_OPTION_WORLDSIZE_UNKNOWN app.SetGameHostOption(eGameHostOption_WorldSize, pClass->m_MoreOptionsParams.worldSize+1 ); // 0 is GAME_HOST_OPTION_WORLDSIZE_UNKNOWN
@@ -15,7 +15,7 @@ private:
eControl_OnlineGame, eControl_OnlineGame,
}; };
static int m_iDifficultyTitleSettingA[5]; static int m_iDifficultyTitleSettingA[4];
UIControl m_controlMainPanel; UIControl m_controlMainPanel;
UIControl_Label m_labelGameName, m_labelSeed, m_labelCreatedMode; UIControl_Label m_labelGameName, m_labelSeed, m_labelCreatedMode;
@@ -50,7 +50,6 @@ private:
int m_iGameModeId; int m_iGameModeId;
bool m_bHasBeenInCreative; bool m_bHasBeenInCreative;
bool m_bIsSaveOwner; bool m_bIsSaveOwner;
bool m_bRetrievingSaveThumbnail;
bool m_bSaveThumbnailReady; bool m_bSaveThumbnailReady;
bool m_bMultiplayerAllowed; bool m_bMultiplayerAllowed;
bool m_bShowTimer; bool m_bShowTimer;
@@ -71,7 +70,6 @@ private:
wstring m_thumbnailName; wstring m_thumbnailName;
bool m_bRebuildTouchBoxes; bool m_bRebuildTouchBoxes;
bool m_bHardcore;
public: public:
UIScene_LoadMenu(int iPad, void *initData, UILayer *parentLayer); UIScene_LoadMenu(int iPad, void *initData, UILayer *parentLayer);
@@ -2,20 +2,20 @@
#include "UI.h" #include "UI.h"
#include "UIScene_LoadOrJoinMenu.h" #include "UIScene_LoadOrJoinMenu.h"
#include "../../../Minecraft.World/StringHelpers.h" #include "..\..\..\Minecraft.World\StringHelpers.h"
#include "../../../Minecraft.World/net.minecraft.world.item.h" #include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
#include "../../../Minecraft.World/net.minecraft.world.level.h" #include "..\..\..\Minecraft.World\net.minecraft.world.level.h"
#include "../../../Minecraft.World/net.minecraft.world.level.chunk.storage.h" #include "..\..\..\Minecraft.World\net.minecraft.world.level.chunk.storage.h"
#include "../../../Minecraft.World/ConsoleSaveFile.h" #include "..\..\..\Minecraft.World\ConsoleSaveFile.h"
#include "../../../Minecraft.World/ConsoleSaveFileOriginal.h" #include "..\..\..\Minecraft.World\ConsoleSaveFileOriginal.h"
#include "../../ProgressRenderer.h" #include "..\..\ProgressRenderer.h"
#include "../../MinecraftServer.h" #include "..\..\MinecraftServer.h"
#include "../../TexturePackRepository.h" #include "..\..\TexturePackRepository.h"
#include "../../TexturePack.h" #include "..\..\TexturePack.h"
#include "../Network/SessionInfo.h" #include "..\Network\SessionInfo.h"
#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) #if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
#include "Common/Network/Sony/SonyHttp.h" #include "Common\Network\Sony\SonyHttp.h"
#include "Common/Network/Sony/SonyRemoteStorage.h" #include "Common\Network\Sony\SonyRemoteStorage.h"
#include "DLCTexturePack.h" #include "DLCTexturePack.h"
#endif #endif
#if defined(__ORBIS__) || defined(__PSVITA__) #if defined(__ORBIS__) || defined(__PSVITA__)
@@ -26,13 +26,12 @@
#endif #endif
#ifdef _WINDOWS64 #ifdef _WINDOWS64
#include "../../../Minecraft.World/NbtIo.h" #include "..\..\..\Minecraft.World\NbtIo.h"
#include "../../../Minecraft.World/compression.h" #include "..\..\..\Minecraft.World\compression.h"
static wstring ReadLevelNameFromSaveFile(const wstring& filePath, bool *outHardcore = nullptr) static wstring ReadLevelNameFromSaveFile(const wstring& filePath)
{ {
// Check for a worldname.txt sidecar written by the rename feature first // Check for a worldname.txt sidecar written by the rename feature first
wstring sidecarName = L"";
size_t slashPos = filePath.rfind(L'\\'); size_t slashPos = filePath.rfind(L'\\');
if (slashPos != wstring::npos) if (slashPos != wstring::npos)
{ {
@@ -50,8 +49,8 @@ static wstring ReadLevelNameFromSaveFile(const wstring& filePath, bool *outHardc
if (len > 0) if (len > 0)
{ {
wchar_t wbuf[128] = {}; wchar_t wbuf[128] = {};
MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, 127); mbstowcs(wbuf, buf, 127);
sidecarName = wbuf; return wstring(wbuf);
} }
} }
else fclose(fr); else fclose(fr);
@@ -59,10 +58,10 @@ static wstring ReadLevelNameFromSaveFile(const wstring& filePath, bool *outHardc
} }
HANDLE hFile = CreateFileW(filePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr); HANDLE hFile = CreateFileW(filePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
if (hFile == INVALID_HANDLE_VALUE) return sidecarName; if (hFile == INVALID_HANDLE_VALUE) return L"";
DWORD fileSize = GetFileSize(hFile, nullptr); DWORD fileSize = GetFileSize(hFile, nullptr);
if (fileSize < 12 || fileSize == INVALID_FILE_SIZE) { CloseHandle(hFile); return sidecarName; } if (fileSize < 12 || fileSize == INVALID_FILE_SIZE) { CloseHandle(hFile); return L""; }
unsigned char *rawData = new unsigned char[fileSize]; unsigned char *rawData = new unsigned char[fileSize];
DWORD bytesRead = 0; DWORD bytesRead = 0;
@@ -70,7 +69,7 @@ static wstring ReadLevelNameFromSaveFile(const wstring& filePath, bool *outHardc
{ {
CloseHandle(hFile); CloseHandle(hFile);
delete[] rawData; delete[] rawData;
return sidecarName; return L"";
} }
CloseHandle(hFile); CloseHandle(hFile);
@@ -85,7 +84,7 @@ static wstring ReadLevelNameFromSaveFile(const wstring& filePath, bool *outHardc
if (decompSize == 0 || decompSize > 128 * 1024 * 1024) if (decompSize == 0 || decompSize > 128 * 1024 * 1024)
{ {
delete[] rawData; delete[] rawData;
return sidecarName; return L"";
} }
saveData = new unsigned char[decompSize]; saveData = new unsigned char[decompSize];
Compression::getCompression()->Decompress(saveData, &decompSize, rawData + 8, fileSize - 8); Compression::getCompression()->Decompress(saveData, &decompSize, rawData + 8, fileSize - 8);
@@ -125,11 +124,7 @@ static wstring ReadLevelNameFromSaveFile(const wstring& filePath, bool *outHardc
{ {
CompoundTag *dataTag = root->getCompound(L"Data"); CompoundTag *dataTag = root->getCompound(L"Data");
if (dataTag != nullptr) if (dataTag != nullptr)
{
result = dataTag->getString(L"LevelName"); result = dataTag->getString(L"LevelName");
if (outHardcore)
*outHardcore = dataTag->getBoolean(L"hardcore");
}
delete root; delete root;
} }
} }
@@ -141,10 +136,6 @@ static wstring ReadLevelNameFromSaveFile(const wstring& filePath, bool *outHardc
if (freeSaveData) delete[] saveData; if (freeSaveData) delete[] saveData;
delete[] rawData; delete[] rawData;
// Prefer the sidecar name (user-renamed) over the level.dat name
if (!sidecarName.empty()) return sidecarName;
// "world" is the engine default - it means no real name was ever set, // "world" is the engine default - it means no real name was ever set,
// so return empty to let the caller fall back to the save filename (timestamp). // so return empty to let the caller fall back to the save filename (timestamp).
if (result == L"world") result = L""; if (result == L"world") result = L"";
@@ -536,9 +527,6 @@ void UIScene_LoadOrJoinMenu::Initialise()
{ {
m_iSaveListIndex = 0; m_iSaveListIndex = 0;
m_iGameListIndex = 0; m_iGameListIndex = 0;
#ifdef _WINDOWS64
m_addServerPhase = eAddServer_Idle;
#endif
m_iDefaultButtonsC = 0; m_iDefaultButtonsC = 0;
m_iMashUpButtonsC=0; m_iMashUpButtonsC=0;
@@ -642,11 +630,6 @@ void UIScene_LoadOrJoinMenu::handleGainFocus(bool navBack)
if( m_bMultiplayerAllowed ) if( m_bMultiplayerAllowed )
{ {
#ifdef _WINDOWS64
// Refresh the games list immediately so that any server
// edits/deletions made in the JoinMenu are visible now.
UpdateGamesList();
#endif
#if TO_BE_IMPLEMENTED #if TO_BE_IMPLEMENTED
HXUICLASS hClassFullscreenProgress = XuiFindClass( L"CScene_FullscreenProgress" ); HXUICLASS hClassFullscreenProgress = XuiFindClass( L"CScene_FullscreenProgress" );
HXUICLASS hClassConnectingProgress = XuiFindClass( L"CScene_ConnectingProgress" ); HXUICLASS hClassConnectingProgress = XuiFindClass( L"CScene_ConnectingProgress" );
@@ -779,16 +762,7 @@ void UIScene_LoadOrJoinMenu::tick()
wchar_t wFilename[MAX_SAVEFILENAME_LENGTH]; wchar_t wFilename[MAX_SAVEFILENAME_LENGTH];
ZeroMemory(wFilename, sizeof(wFilename)); ZeroMemory(wFilename, sizeof(wFilename));
mbstowcs(wFilename, m_pSaveDetails->SaveInfoA[origIdx].UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH - 1); mbstowcs(wFilename, m_pSaveDetails->SaveInfoA[origIdx].UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH - 1);
wchar_t wTitle[MAX_DISPLAYNAME_LENGTH]; wstring filePath = wstring(L"Windows64\\GameHDD\\") + wstring(wFilename) + wstring(L"\\saveData.ms");
ZeroMemory(wTitle, sizeof(wTitle));
mbstowcs(wTitle, m_pSaveDetails->SaveInfoA[origIdx].UTF8SaveTitle, MAX_DISPLAYNAME_LENGTH - 1);
wstring filePath = wstring(L"Windows64\\GameHDD\\") + wstring(wFilename) + wstring(L"\\") + wstring(wTitle) + wstring(L".ms");
// Fallback to legacy saveData.ms if new-style filename doesn't exist
{
DWORD attrs = GetFileAttributesW(filePath.c_str());
if (attrs == INVALID_FILE_ATTRIBUTES)
filePath = wstring(L"Windows64\\GameHDD\\") + wstring(wFilename) + wstring(L"\\saveData.ms");
}
HANDLE hFile = CreateFileW(filePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr); HANDLE hFile = CreateFileW(filePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
DWORD fileSize = 0; DWORD fileSize = 0;
@@ -811,17 +785,13 @@ void UIScene_LoadOrJoinMenu::tick()
#else #else
#ifdef _WINDOWS64 #ifdef _WINDOWS64
{ {
bool saveHardcore = false; wstring levelName = ReadLevelNameFromSaveFile(filePath);
wstring levelName = ReadLevelNameFromSaveFile(filePath, &saveHardcore);
m_saveDetails[i].isHardcore = saveHardcore;
if (!levelName.empty()) if (!levelName.empty())
{ {
m_buttonListSaves.addItem(levelName, wstring(L"")); m_buttonListSaves.addItem(levelName, wstring(L""));
{ wcstombs(m_saveDetails[i].UTF8SaveName, levelName.c_str(), 127);
int n = WideCharToMultiByte(CP_UTF8, 0, levelName.c_str(), -1, m_saveDetails[i].UTF8SaveName, 127, nullptr, nullptr); m_saveDetails[i].UTF8SaveName[127] = '\0';
if (n <= 0) m_saveDetails[i].UTF8SaveName[0] = '\0';
m_saveDetails[i].UTF8SaveName[127] = '\0';
}
} }
else else
{ {
@@ -1466,9 +1436,9 @@ int UIScene_LoadOrJoinMenu::KeyboardCompleteWorldNameCallback(LPVOID lpParam,boo
for (int k = 0; k < 127 && ui16Text[k]; k++) for (int k = 0; k < 127 && ui16Text[k]; k++)
wNewName[k] = static_cast<wchar_t>(ui16Text[k]); wNewName[k] = static_cast<wchar_t>(ui16Text[k]);
// Convert to narrow for storage and in-memory update (UTF-8 to preserve Unicode) // Convert to narrow for storage and in-memory update
char narrowName[256] = {}; char narrowName[128] = {};
WideCharToMultiByte(CP_UTF8, 0, wNewName, -1, narrowName, 255, nullptr, nullptr); wcstombs(narrowName, wNewName, 127);
// Build the sidecar path: Windows64\GameHDD\{folder}\worldname.txt // Build the sidecar path: Windows64\GameHDD\{folder}\worldname.txt
wchar_t wFilename[MAX_SAVEFILENAME_LENGTH] = {}; wchar_t wFilename[MAX_SAVEFILENAME_LENGTH] = {};
@@ -1484,7 +1454,7 @@ int UIScene_LoadOrJoinMenu::KeyboardCompleteWorldNameCallback(LPVOID lpParam,boo
// Update the in-memory display name so the list reflects it immediately // Update the in-memory display name so the list reflects it immediately
strncpy_s(pClass->m_saveDetails[listPos].UTF8SaveName, narrowName, 127); strncpy_s(pClass->m_saveDetails[listPos].UTF8SaveName, narrowName, 127);
pClass->m_saveDetails[listPos].UTF8SaveName[127] = '\0'; // UTF8SaveName is still 128 bytes; narrowName fits as Arabic is <=2 bytes/char in UTF-8 pClass->m_saveDetails[listPos].UTF8SaveName[127] = '\0';
// Reuse the existing callback to trigger the list repopulate // Reuse the existing callback to trigger the list repopulate
UIScene_LoadOrJoinMenu::RenameSaveDataReturned(pClass, true); UIScene_LoadOrJoinMenu::RenameSaveDataReturned(pClass, true);
@@ -1519,10 +1489,6 @@ void UIScene_LoadOrJoinMenu::handleFocusChange(F64 controlId, F64 childId)
{ {
case eControl_GamesList: case eControl_GamesList:
m_iGameListIndex = childId; m_iGameListIndex = childId;
#ifdef _WINDOWS64
// Offset past the "Add Server" button so m_iGameListIndex is a session index
m_iGameListIndex -= 1;
#endif
m_buttonListGames.updateChildFocus( static_cast<int>(childId) ); m_buttonListGames.updateChildFocus( static_cast<int>(childId) );
break; break;
case eControl_SavesList: case eControl_SavesList:
@@ -1650,14 +1616,6 @@ void UIScene_LoadOrJoinMenu::handlePress(F64 controlId, F64 childId)
break; break;
case eControl_GamesList: case eControl_GamesList:
{ {
#ifdef _WINDOWS64
if (static_cast<int>(childId) == ADD_SERVER_BUTTON_INDEX)
{
ui.PlayUISFX(eSFX_Press);
BeginAddServer();
break;
}
#endif
m_bIgnoreInput=true; m_bIgnoreInput=true;
m_eAction = eAction_JoinGame; m_eAction = eAction_JoinGame;
@@ -1667,10 +1625,7 @@ void UIScene_LoadOrJoinMenu::handlePress(F64 controlId, F64 childId)
{ {
int nIndex = static_cast<int>(childId); int nIndex = static_cast<int>(childId);
#ifdef _WINDOWS64
// Offset by 1 because the "Add Server" button is at index 0
nIndex -= 1;
#endif
m_iGameListIndex = nIndex; m_iGameListIndex = nIndex;
CheckAndJoinGame(nIndex); CheckAndJoinGame(nIndex);
} }
@@ -1978,13 +1933,7 @@ void UIScene_LoadOrJoinMenu::UpdateGamesList()
if(DoesGamesListHaveFocus() && m_buttonListGames.getItemCount() > 0) if(DoesGamesListHaveFocus() && m_buttonListGames.getItemCount() > 0)
{ {
unsigned int nIndex = m_buttonListGames.getCurrentSelection(); unsigned int nIndex = m_buttonListGames.getCurrentSelection();
#ifdef _WINDOWS64
// Offset past the "Add Server" button
if (nIndex > 0)
pSelectedSession = m_currentSessions->at( nIndex - 1 );
#else
pSelectedSession = m_currentSessions->at( nIndex ); pSelectedSession = m_currentSessions->at( nIndex );
#endif
} }
SessionID selectedSessionId; SessionID selectedSessionId;
@@ -2066,11 +2015,6 @@ void UIScene_LoadOrJoinMenu::UpdateGamesList()
// clear out the games list and re-fill // clear out the games list and re-fill
m_buttonListGames.clearList(); m_buttonListGames.clearList();
#ifdef _WINDOWS64
// Always add the "Add Server" button as the first entry in the games list
m_buttonListGames.addItem(wstring(L"Add Server"));
#endif
if( filteredListSize > 0 ) if( filteredListSize > 0 )
{ {
// Reset the focus to the selected session if it still exists // Reset the focus to the selected session if it still exists
@@ -2136,12 +2080,7 @@ void UIScene_LoadOrJoinMenu::UpdateGamesList()
if(memcmp( &selectedSessionId, &sessionInfo->sessionId, sizeof(SessionID) ) == 0) if(memcmp( &selectedSessionId, &sessionInfo->sessionId, sizeof(SessionID) ) == 0)
{ {
#ifdef _WINDOWS64
// Offset past the "Add Server" button
m_buttonListGames.setCurrentSelection(sessionIndex + 1);
#else
m_buttonListGames.setCurrentSelection(sessionIndex); m_buttonListGames.setCurrentSelection(sessionIndex);
#endif
break; break;
} }
++sessionIndex; ++sessionIndex;
@@ -2552,7 +2491,7 @@ int UIScene_LoadOrJoinMenu::SaveOptionsDialogReturned(void *pParam,int iPad,C4JS
{ {
wchar_t wSaveName[128]; wchar_t wSaveName[128];
ZeroMemory(wSaveName, 128 * sizeof(wchar_t)); ZeroMemory(wSaveName, 128 * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, pClass->m_saveDetails[pClass->m_iSaveListIndex - pClass->m_iDefaultButtonsC].UTF8SaveName, -1, wSaveName, 127); mbstowcs_s(nullptr, wSaveName, 128, pClass->m_saveDetails[pClass->m_iSaveListIndex - pClass->m_iDefaultButtonsC].UTF8SaveName, _TRUNCATE);
UIKeyboardInitData kbData; UIKeyboardInitData kbData;
kbData.title = app.GetString(IDS_RENAME_WORLD_TITLE); kbData.title = app.GetString(IDS_RENAME_WORLD_TITLE);
kbData.defaultText = wSaveName; kbData.defaultText = wSaveName;
@@ -4178,168 +4117,3 @@ int UIScene_LoadOrJoinMenu::CopySaveErrorDialogFinishedCallback(void *pParam,int
} }
#endif // _XBOX_ONE #endif // _XBOX_ONE
#ifdef _WINDOWS64
// adding servers bellow
void UIScene_LoadOrJoinMenu::BeginAddServer()
{
m_addServerPhase = eAddServer_IP;
m_addServerIP.clear();
m_addServerPort.clear();
UIKeyboardInitData kbData;
kbData.title = L"Server Address";
kbData.defaultText = L"";
kbData.maxChars = 128;
kbData.callback = &UIScene_LoadOrJoinMenu::AddServerKeyboardCallback;
kbData.lpParam = this;
kbData.pcMode = g_KBMInput.IsKBMActive();
ui.NavigateToScene(m_iPad, eUIScene_Keyboard, &kbData);
}
int UIScene_LoadOrJoinMenu::AddServerKeyboardCallback(LPVOID lpParam, bool bRes)
{
UIScene_LoadOrJoinMenu *pClass = static_cast<UIScene_LoadOrJoinMenu*>(lpParam);
if (!bRes)
{
pClass->m_addServerPhase = eAddServer_Idle;
pClass->m_bIgnoreInput = false;
return 0;
}
uint16_t ui16Text[256];
ZeroMemory(ui16Text, sizeof(ui16Text));
Win64_GetKeyboardText(ui16Text, 256);
wchar_t wBuf[256] = {};
for (int k = 0; k < 255 && ui16Text[k]; k++)
wBuf[k] = static_cast<wchar_t>(ui16Text[k]);
if (wBuf[0] == 0)
{
pClass->m_addServerPhase = eAddServer_Idle;
pClass->m_bIgnoreInput = false;
return 0;
}
switch (pClass->m_addServerPhase)
{
case eAddServer_IP:
{
pClass->m_addServerIP = wBuf;
pClass->m_addServerPhase = eAddServer_Port;
UIKeyboardInitData kbData;
kbData.title = L"Server Port";
kbData.defaultText = L"25565";
kbData.maxChars = 6;
kbData.callback = &UIScene_LoadOrJoinMenu::AddServerKeyboardCallback;
kbData.lpParam = pClass;
kbData.pcMode = g_KBMInput.IsKBMActive();
ui.NavigateToScene(pClass->m_iPad, eUIScene_Keyboard, &kbData);
break;
}
case eAddServer_Port:
{
pClass->m_addServerPort = wBuf;
pClass->m_addServerPhase = eAddServer_Name;
UIKeyboardInitData kbData;
kbData.title = L"Server Name";
kbData.defaultText = L"Minecraft Server";
kbData.maxChars = 64;
kbData.callback = &UIScene_LoadOrJoinMenu::AddServerKeyboardCallback;
kbData.lpParam = pClass;
kbData.pcMode = g_KBMInput.IsKBMActive();
ui.NavigateToScene(pClass->m_iPad, eUIScene_Keyboard, &kbData);
break;
}
case eAddServer_Name:
{
wstring name = wBuf;
pClass->AppendServerToFile(pClass->m_addServerIP, pClass->m_addServerPort, name);
pClass->m_addServerPhase = eAddServer_Idle;
pClass->m_bIgnoreInput = false;
g_NetworkManager.ForceFriendsSessionRefresh();
break;
}
default:
pClass->m_addServerPhase = eAddServer_Idle;
pClass->m_bIgnoreInput = false;
break;
}
return 0;
}
void UIScene_LoadOrJoinMenu::AppendServerToFile(const wstring& ip, const wstring& port, const wstring& name)
{
char narrowIP[256] = {};
char narrowPort[16] = {};
char narrowName[256] = {};
wcstombs(narrowIP, ip.c_str(), sizeof(narrowIP) - 1);
wcstombs(narrowPort, port.c_str(), sizeof(narrowPort) - 1);
wcstombs(narrowName, name.c_str(), sizeof(narrowName) - 1);
uint16_t portNum = static_cast<uint16_t>(atoi(narrowPort));
struct ServerEntry { std::string ip; uint16_t port; std::string name; };
std::vector<ServerEntry> entries;
FILE* file = fopen("servers.db", "rb");
if (file)
{
char magic[4] = {};
if (fread(magic, 1, 4, file) == 4 && memcmp(magic, "MCSV", 4) == 0)
{
uint32_t version = 0, count = 0;
fread(&version, sizeof(uint32_t), 1, file);
fread(&count, sizeof(uint32_t), 1, file);
if (version == 1)
{
for (uint32_t s = 0; s < count; s++)
{
uint16_t ipLen = 0, p = 0, nameLen = 0;
if (fread(&ipLen, sizeof(uint16_t), 1, file) != 1) break;
if (ipLen == 0 || ipLen > 256) break;
char ipBuf[257] = {};
if (fread(ipBuf, 1, ipLen, file) != ipLen) break;
if (fread(&p, sizeof(uint16_t), 1, file) != 1) break;
if (fread(&nameLen, sizeof(uint16_t), 1, file) != 1) break;
if (nameLen > 256) break;
char nameBuf[257] = {};
if (nameLen > 0 && fread(nameBuf, 1, nameLen, file) != nameLen) break;
entries.push_back({std::string(ipBuf), p, std::string(nameBuf)});
}
}
}
fclose(file);
}
entries.push_back({std::string(narrowIP), portNum, std::string(narrowName)});
file = fopen("servers.db", "wb");
if (file)
{
fwrite("MCSV", 1, 4, file);
uint32_t version = 1;
uint32_t count = static_cast<uint32_t>(entries.size());
fwrite(&version, sizeof(uint32_t), 1, file);
fwrite(&count, sizeof(uint32_t), 1, file);
for (size_t i = 0; i < entries.size(); i++)
{
uint16_t ipLen = static_cast<uint16_t>(entries[i].ip.length());
fwrite(&ipLen, sizeof(uint16_t), 1, file);
fwrite(entries[i].ip.c_str(), 1, ipLen, file);
fwrite(&entries[i].port, sizeof(uint16_t), 1, file);
uint16_t nameLen = static_cast<uint16_t>(entries[i].name.length());
fwrite(&nameLen, sizeof(uint16_t), 1, file);
fwrite(entries[i].name.c_str(), 1, nameLen, file);
}
fclose(file);
}
}
#endif // _WINDOWS64
@@ -176,17 +176,6 @@ public:
private: private:
void CheckAndJoinGame(int gameIndex); void CheckAndJoinGame(int gameIndex);
#ifdef _WINDOWS64
static const int ADD_SERVER_BUTTON_INDEX = 0;
enum eAddServerPhase { eAddServer_Idle, eAddServer_IP, eAddServer_Port, eAddServer_Name };
eAddServerPhase m_addServerPhase;
wstring m_addServerIP;
wstring m_addServerPort;
void BeginAddServer();
void AppendServerToFile(const wstring& ip, const wstring& port, const wstring& name);
static int AddServerKeyboardCallback(LPVOID lpParam, bool bRes);
#endif
#if defined(__PS3__) || defined(__PSVITA__) || defined(__ORBIS__) #if defined(__PS3__) || defined(__PSVITA__) || defined(__ORBIS__)
static int MustSignInReturnedPSN(void *pParam,int iPad,C4JStorage::EMessageResult result); static int MustSignInReturnedPSN(void *pParam,int iPad,C4JStorage::EMessageResult result);
static int PSN_SignInReturned(void *pParam,bool bContinue, int iPad); static int PSN_SignInReturned(void *pParam,bool bContinue, int iPad);
@@ -619,23 +619,8 @@ void UIScene_PauseMenu::handlePress(F64 controlId, F64 childId)
Windows::Xbox::ApplicationModel::Help::Show(user); Windows::Xbox::ApplicationModel::Help::Show(user);
} }
break; break;
#elif TO_BE_IMPLEMENTED
case BUTTON_PAUSE_ACHIEVEMENTS:
// guests can't look at achievements
if(ProfileManager.IsGuest(pNotifyPressData->UserIndex))
{
UINT uiIDA[1];
uiIDA[0]=IDS_OK;
ui.RequestAlertMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad());
}
else
{
XShowAchievementsUI( pNotifyPressData->UserIndex );
}
break;
#endif #endif
case BUTTON_PAUSE_ACHIEVEMENTS: case BUTTON_PAUSE_ACHIEVEMENTS:
// guests can't look at achievements // guests can't look at achievements
/*if(ProfileManager.IsGuest(pNotifyPressData->UserIndex)) /*if(ProfileManager.IsGuest(pNotifyPressData->UserIndex))
@@ -647,9 +632,11 @@ void UIScene_PauseMenu::handlePress(F64 controlId, F64 childId)
else else
{ {
XShowAchievementsUI( pNotifyPressData->UserIndex ); XShowAchievementsUI( pNotifyPressData->UserIndex );
}
}*/ }*/
ui.NavigateToScene(m_iPad, eUIScene_AchievementsMenu); ui.NavigateToScene(m_iPad, eUIScene_AchievementsMenu);
break; break;
case BUTTON_PAUSE_HELPANDOPTIONS: case BUTTON_PAUSE_HELPANDOPTIONS:
ui.NavigateToScene(m_iPad,eUIScene_HelpAndOptionsMenu); ui.NavigateToScene(m_iPad,eUIScene_HelpAndOptionsMenu);
break; break;
@@ -5,11 +5,6 @@
#include "../../Options.h" #include "../../Options.h"
#include "../../GameRenderer.h" #include "../../GameRenderer.h"
#ifdef _WINDOWS64
extern bool g_bVSync;
extern void SetExclusiveFullscreen(bool enabled);
#endif
namespace namespace
{ {
constexpr int FOV_MIN = 70; constexpr int FOV_MIN = 70;
@@ -67,14 +62,12 @@ UIScene_SettingsGraphicsMenu::UIScene_SettingsGraphicsMenu(int iPad, void *initD
m_checkboxClouds.init(app.GetString(IDS_CHECKBOX_RENDER_CLOUDS),eControl_Clouds,(app.GetGameSettings(m_iPad,eGameSetting_Clouds)!=0)); m_checkboxClouds.init(app.GetString(IDS_CHECKBOX_RENDER_CLOUDS),eControl_Clouds,(app.GetGameSettings(m_iPad,eGameSetting_Clouds)!=0));
m_checkboxBedrockFog.init(app.GetString(IDS_CHECKBOX_RENDER_BEDROCKFOG),eControl_BedrockFog,(app.GetGameSettings(m_iPad,eGameSetting_BedrockFog)!=0)); m_checkboxBedrockFog.init(app.GetString(IDS_CHECKBOX_RENDER_BEDROCKFOG),eControl_BedrockFog,(app.GetGameSettings(m_iPad,eGameSetting_BedrockFog)!=0));
m_checkboxCustomSkinAnim.init(app.GetString(IDS_CHECKBOX_CUSTOM_SKIN_ANIM),eControl_CustomSkinAnim,(app.GetGameSettings(m_iPad,eGameSetting_CustomSkinAnim)!=0)); m_checkboxCustomSkinAnim.init(app.GetString(IDS_CHECKBOX_CUSTOM_SKIN_ANIM),eControl_CustomSkinAnim,(app.GetGameSettings(m_iPad,eGameSetting_CustomSkinAnim)!=0));
m_checkboxVSync.init(L"VSync",eControl_VSync,(app.GetGameSettings(m_iPad,eGameSetting_VSync)!=0));
m_checkboxExclusiveFullscreen.init(L"Fullscreen",eControl_ExclusiveFullscreen,(app.GetGameSettings(m_iPad,eGameSetting_ExclusiveFullscreen)!=0));
WCHAR TempString[256]; WCHAR TempString[256];
swprintf(TempString, 256, L"Render Distance: %d",app.GetGameSettings(m_iPad,eGameSetting_RenderDistance)); swprintf(TempString, 256, L"Render Distance: %d",app.GetGameSettings(m_iPad,eGameSetting_RenderDistance));
m_sliderRenderDistance.init(TempString,eControl_RenderDistance,0,3,DistanceToLevel(app.GetGameSettings(m_iPad,eGameSetting_RenderDistance))); m_sliderRenderDistance.init(TempString,eControl_RenderDistance,0,5,DistanceToLevel(app.GetGameSettings(m_iPad,eGameSetting_RenderDistance)));
swprintf( TempString, 256, L"%ls: %d%%", app.GetString( IDS_SLIDER_GAMMA ),app.GetGameSettings(m_iPad,eGameSetting_Gamma)); 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)); m_sliderGamma.init(TempString,eControl_Gamma,0,100,app.GetGameSettings(m_iPad,eGameSetting_Gamma));
@@ -89,50 +82,28 @@ UIScene_SettingsGraphicsMenu::UIScene_SettingsGraphicsMenu(int iPad, void *initD
doHorizontalResizeCheck(); doHorizontalResizeCheck();
#ifndef _WINDOWS64
// 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); const bool bInGame=(Minecraft::GetInstance()->level!=nullptr);
const bool bIsPrimaryPad=(ProfileManager.GetPrimaryPad()==m_iPad); const bool bIsPrimaryPad=(ProfileManager.GetPrimaryPad()==m_iPad);
// if we're not in the game, we need to use basescene 0 // if we're not in the game, we need to use basescene 0
if(bInGame) if(bInGame)
{ {
#ifndef _WINDOWS64 // If the game has started, then you need to be the host to change the in-game gamertags
// Console splitscreen: non-host and non-primary players can't change world-level settings
if(bIsPrimaryPad) if(bIsPrimaryPad)
{ {
// we are the primary player on this machine, but not the game host
// are we the game host? If not, we need to remove the bedrockfog setting
if(!g_NetworkManager.IsHost()) if(!g_NetworkManager.IsHost())
{ {
// hide the in-game bedrock fog setting
removeControl(&m_checkboxBedrockFog, true); removeControl(&m_checkboxBedrockFog, true);
} }
} }
else else
{ {
// We shouldn't have the bedrock fog option, or the m_CustomSkinAnim option
removeControl(&m_checkboxBedrockFog, true); removeControl(&m_checkboxBedrockFog, true);
removeControl(&m_checkboxCustomSkinAnim, true); removeControl(&m_checkboxCustomSkinAnim, true);
} }
#endif
} }
if(app.GetLocalPlayerCount()>1) if(app.GetLocalPlayerCount()>1)
@@ -194,12 +165,6 @@ void UIScene_SettingsGraphicsMenu::handleInput(int iPad, int key, bool repeat, b
app.SetGameSettings(m_iPad,eGameSetting_Clouds,m_checkboxClouds.IsChecked()?1:0); app.SetGameSettings(m_iPad,eGameSetting_Clouds,m_checkboxClouds.IsChecked()?1:0);
app.SetGameSettings(m_iPad,eGameSetting_BedrockFog,m_checkboxBedrockFog.IsChecked()?1:0); app.SetGameSettings(m_iPad,eGameSetting_BedrockFog,m_checkboxBedrockFog.IsChecked()?1:0);
app.SetGameSettings(m_iPad,eGameSetting_CustomSkinAnim,m_checkboxCustomSkinAnim.IsChecked()?1:0); app.SetGameSettings(m_iPad,eGameSetting_CustomSkinAnim,m_checkboxCustomSkinAnim.IsChecked()?1:0);
app.SetGameSettings(m_iPad,eGameSetting_VSync,m_checkboxVSync.IsChecked()?1:0);
app.SetGameSettings(m_iPad,eGameSetting_ExclusiveFullscreen,m_checkboxExclusiveFullscreen.IsChecked()?1:0);
#ifdef _WINDOWS64
g_bVSync = m_checkboxVSync.IsChecked();
SetExclusiveFullscreen(m_checkboxExclusiveFullscreen.IsChecked());
#endif
navigateBack(); navigateBack();
handled = true; handled = true;
@@ -12,22 +12,18 @@ private:
eControl_Clouds, eControl_Clouds,
eControl_BedrockFog, eControl_BedrockFog,
eControl_CustomSkinAnim, eControl_CustomSkinAnim,
eControl_VSync,
eControl_ExclusiveFullscreen,
eControl_RenderDistance, eControl_RenderDistance,
eControl_Gamma, eControl_Gamma,
eControl_FOV, eControl_FOV,
eControl_InterfaceOpacity eControl_InterfaceOpacity
}; };
UIControl_CheckBox m_checkboxClouds, m_checkboxBedrockFog, m_checkboxCustomSkinAnim, m_checkboxVSync, m_checkboxExclusiveFullscreen; // Checkboxes UIControl_CheckBox m_checkboxClouds, m_checkboxBedrockFog, m_checkboxCustomSkinAnim; // Checkboxes
UIControl_Slider m_sliderRenderDistance, m_sliderGamma, m_sliderFOV, m_sliderInterfaceOpacity; // Sliders UIControl_Slider m_sliderRenderDistance, m_sliderGamma, m_sliderFOV, m_sliderInterfaceOpacity; // Sliders
UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene)
UI_MAP_ELEMENT( m_checkboxClouds, "Clouds") UI_MAP_ELEMENT( m_checkboxClouds, "Clouds")
UI_MAP_ELEMENT( m_checkboxBedrockFog, "BedrockFog") UI_MAP_ELEMENT( m_checkboxBedrockFog, "BedrockFog")
UI_MAP_ELEMENT( m_checkboxCustomSkinAnim, "CustomSkinAnim") UI_MAP_ELEMENT( m_checkboxCustomSkinAnim, "CustomSkinAnim")
UI_MAP_ELEMENT( m_checkboxVSync, "VSync")
UI_MAP_ELEMENT( m_checkboxExclusiveFullscreen, "ExclusiveFullscreen")
UI_MAP_ELEMENT( m_sliderRenderDistance, "RenderDistance") UI_MAP_ELEMENT( m_sliderRenderDistance, "RenderDistance")
UI_MAP_ELEMENT( m_sliderGamma, "Gamma") UI_MAP_ELEMENT( m_sliderGamma, "Gamma")
UI_MAP_ELEMENT(m_sliderFOV, "FOV") UI_MAP_ELEMENT(m_sliderFOV, "FOV")
@@ -1,7 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "UI.h" #include "UI.h"
#include "UIScene_SettingsOptionsMenu.h" #include "UIScene_SettingsOptionsMenu.h"
// pasted legit out of lcen client lol
#define _ENABLE_LANGUAGE_SELECT #define _ENABLE_LANGUAGE_SELECT
int UIScene_SettingsOptionsMenu::m_iDifficultySettingA[4]= int UIScene_SettingsOptionsMenu::m_iDifficultySettingA[4]=
@@ -193,12 +193,12 @@ void UIScene_TeleportMenu::tick()
{ {
m_players[i] = player->GetSmallId(); m_players[i] = player->GetSmallId();
short icon = static_cast<short>(app.GetPlayerMapIconByName(player->GetOnlineName())); short icon = app.GetPlayerColour( m_players[i] );
if(icon != m_playersColourState[i]) if(icon != m_playersColourState[i])
{ {
m_playersColourState[i] = icon; m_playersColourState[i] = icon;
m_playerList.setPlayerIcon( i, (int)icon ); m_playerList.setPlayerIcon( i, (int)app.GetPlayerColour( m_players[i] ) );
} }
wstring playerName = L""; wstring playerName = L"";
-3
View File
@@ -247,14 +247,11 @@ typedef struct _SaveListDetails
#endif #endif
#endif #endif
bool isHardcore;
_SaveListDetails() _SaveListDetails()
{ {
saveId = 0; saveId = 0;
pbThumbnailData = nullptr; pbThumbnailData = nullptr;
dwThumbnailSize = 0; dwThumbnailSize = 0;
isHardcore = false;
#ifdef _DURANGO #ifdef _DURANGO
ZeroMemory(UTF16SaveName,sizeof(wchar_t)*128); ZeroMemory(UTF16SaveName,sizeof(wchar_t)*128);
ZeroMemory(UTF16SaveFilename,sizeof(wchar_t)*MAX_SAVEFILENAME_LENGTH); ZeroMemory(UTF16SaveFilename,sizeof(wchar_t)*MAX_SAVEFILENAME_LENGTH);
+4 -7
View File
@@ -4,7 +4,7 @@
#include "../../../Minecraft.World/File.h" #include "../../../Minecraft.World/File.h"
#include "UITTFFont.h" #include "UITTFFont.h"
UITTFFont::UITTFFont(const string &name, const string &path, S32 fallbackCharacter, bool registerAsDefaultFonts) UITTFFont::UITTFFont(const string &name, const string &path, S32 fallbackCharacter)
: m_strFontName(name) : m_strFontName(name)
{ {
app.DebugPrintf("UITTFFont opening %s\n",path.c_str()); app.DebugPrintf("UITTFFont opening %s\n",path.c_str());
@@ -41,12 +41,9 @@ UITTFFont::UITTFFont(const string &name, const string &path, S32 fallbackCharact
IggyFontInstallTruetypeFallbackCodepointUTF8( m_strFontName.c_str(), -1, IGGY_FONTFLAG_none, fallbackCharacter ); IggyFontInstallTruetypeFallbackCodepointUTF8( m_strFontName.c_str(), -1, IGGY_FONTFLAG_none, fallbackCharacter );
if (registerAsDefaultFonts) // 4J Stu - These are so we can use the default flash controls
{ IggyFontInstallTruetypeUTF8 ( (void *)pbData, IGGY_TTC_INDEX_none, "Times New Roman", -1, IGGY_FONTFLAG_none );
// 4J Stu - These are so we can use the default flash controls IggyFontInstallTruetypeUTF8 ( (void *)pbData, IGGY_TTC_INDEX_none, "Arial", -1, IGGY_FONTFLAG_none );
IggyFontInstallTruetypeUTF8 ( (void *)pbData, IGGY_TTC_INDEX_none, "Times New Roman", -1, IGGY_FONTFLAG_none );
IggyFontInstallTruetypeUTF8 ( (void *)pbData, IGGY_TTC_INDEX_none, "Arial", -1, IGGY_FONTFLAG_none );
}
} }
} }
+1 -1
View File
@@ -9,7 +9,7 @@ private:
//DWORD dwDataSize; //DWORD dwDataSize;
public: public:
UITTFFont(const string &name, const string &path, S32 fallbackCharacter, bool registerAsDefaultFonts = true); UITTFFont(const string &name, const string &path, S32 fallbackCharacter);
~UITTFFont(); ~UITTFFont();
string getFontName(); string getFontName();
@@ -1,164 +0,0 @@
#include "stdafx.h"
#include "BufferedImage.h"
#include "UIFontData.h"
#include "UIUnicodeBitmapFont.h"
UIUnicodeBitmapFont::UIUnicodeBitmapFont(const string &fontname, SFontData &referenceFontData)
: UIAbstractBitmapFont(fontname)
{
m_numGlyphs = 65536;
m_referenceFontData = &referenceFontData;
memset(m_glyphPages, 0, sizeof(m_glyphPages));
memset(m_unicodeWidth, 0, sizeof(m_unicodeWidth));
FILE *f = nullptr;
fopen_s(&f, "Common/res/1_2_2/font/glyph_sizes.bin", "rb");
if (f)
{
fread(m_unicodeWidth, 1, 65536, f);
fclose(f);
}
}
UIUnicodeBitmapFont::~UIUnicodeBitmapFont()
{
for (int i = 0; i < 256; i++)
delete[] m_glyphPages[i];
}
void UIUnicodeBitmapFont::loadGlyphPage(int page)
{
wchar_t fileName[64];
swprintf(fileName, 64, L"/1_2_2/font/glyph_%02X.png", page);
BufferedImage bimg(fileName);
int *rawData = bimg.getData();
if (!rawData) return;
int size = 256 * 256;
m_glyphPages[page] = new unsigned char[size];
for (int i = 0; i < size; i++)
m_glyphPages[page][i] = (rawData[i] & 0xFF000000) >> 24;
}
IggyFontMetrics *UIUnicodeBitmapFont::GetFontMetrics(IggyFontMetrics *metrics)
{
metrics->ascent = m_referenceFontData->m_fAscent;
metrics->descent = m_referenceFontData->m_fDescent;
metrics->average_glyph_width_for_tab_stops = 8.0f;
metrics->largest_glyph_bbox_y1 = metrics->descent;
return metrics;
}
S32 UIUnicodeBitmapFont::GetCodepointGlyph(U32 codepoint)
{
if (codepoint < 65536 && m_unicodeWidth[codepoint] != 0)
return (S32)codepoint;
return IGGY_GLYPH_INVALID;
}
IggyGlyphMetrics *UIUnicodeBitmapFont::GetGlyphMetrics(S32 glyph, IggyGlyphMetrics *metrics)
{
if (glyph < 0 || glyph >= 65536) { metrics->x0 = metrics->x1 = metrics->advance = metrics->y0 = metrics->y1 = 0; return metrics; }
int left = m_unicodeWidth[glyph] >> 4;
int right = (m_unicodeWidth[glyph] & 0xF) + 1;
float pixelWidth = (right - left) / 2.0f + 1.0f;
float advance = pixelWidth * m_referenceFontData->m_fAdvPerPixel;
metrics->x0 = 0.0f;
metrics->x1 = advance;
metrics->advance = advance;
metrics->y0 = 0.0f;
metrics->y1 = 1.0f;
return metrics;
}
rrbool UIUnicodeBitmapFont::IsGlyphEmpty(S32 glyph)
{
if (glyph < 0 || glyph >= 65536) return true;
return m_unicodeWidth[glyph] == 0;
}
F32 UIUnicodeBitmapFont::GetKerningForGlyphPair(S32 first_glyph, S32 second_glyph)
{
return 0.0f;
}
rrbool UIUnicodeBitmapFont::CanProvideBitmap(S32 glyph, F32 pixel_scale)
{
return glyph >= 0 && glyph < 65536;
}
rrbool UIUnicodeBitmapFont::GetGlyphBitmap(S32 glyph, F32 pixel_scale, IggyBitmapCharacter *bitmap)
{
if (glyph < 0 || glyph >= 65536) return false;
int page = glyph / 256;
if (!m_glyphPages[page])
{
loadGlyphPage(page);
if (!m_glyphPages[page]) return false;
}
int cx = (glyph % 16) * 16;
int cy = ((glyph & 0xFF) / 16) * 16;
bitmap->pixels_one_per_byte = m_glyphPages[page] + (cy * 256) + cx;
bitmap->width_in_pixels = 16;
bitmap->height_in_pixels = 16;
bitmap->stride_in_bytes = 256;
bitmap->top_left_x = 0;
bitmap->top_left_y = -static_cast<S32>(16) * m_referenceFontData->m_fAscent;
bitmap->oversample = 0;
// Scale parameters: match UIBitmapFont's approach.
// truePixelScale = the pixel_scale at which 1 glyph pixel = 1 screen pixel.
// For 16px glyphs displayed at the same visual size as Mojangles_7 (8px glyphs with advPerPixel 1/10):
// The reference truePixelScale for Mojangles_7 is 1.0f/m_fAdvPerPixel = 10.0f
// Since our glyphs are 16px (2x the Mojangles 8px), our truePixelScale is 20.0f
float truePixelScale = 2.0f / m_referenceFontData->m_fAdvPerPixel;
#ifdef _WINDOWS64
bitmap->pixel_scale_correct = truePixelScale;
if (pixel_scale < truePixelScale)
{
bitmap->pixel_scale_min = 0.0f;
bitmap->pixel_scale_max = truePixelScale;
bitmap->point_sample = false;
}
else
{
bitmap->pixel_scale_min = truePixelScale;
bitmap->pixel_scale_max = 99.0f;
bitmap->point_sample = true;
}
#else
float glyphScale = 1.0f;
while ((0.5f + glyphScale) * truePixelScale < pixel_scale)
glyphScale++;
if (glyphScale <= 1 && pixel_scale < truePixelScale)
{
bitmap->pixel_scale_correct = truePixelScale;
bitmap->pixel_scale_min = 0.0f;
bitmap->pixel_scale_max = truePixelScale * 1.001f;
bitmap->point_sample = false;
}
else
{
float actualScale = pixel_scale / glyphScale;
bitmap->pixel_scale_correct = actualScale;
bitmap->pixel_scale_min = truePixelScale;
bitmap->pixel_scale_max = 99.0f;
bitmap->point_sample = true;
}
#endif
bitmap->user_context_for_free = nullptr;
return true;
}
void UIUnicodeBitmapFont::FreeGlyphBitmap(S32 glyph, F32 pixel_scale, IggyBitmapCharacter *bitmap)
{
// Pixel data lives in m_glyphPages -- nothing to free.
}

Some files were not shown because too many files have changed in this diff Show More