mirror of
https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1.git
synced 2026-03-19 22:43:32 +00:00
Compare commits
139 Commits
0.6.1-alph
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0dac8a95c | ||
|
|
1cd73cfc1e | ||
|
|
c1fe428aa3 | ||
|
|
24d3b9488d | ||
|
|
f3f0918e77 | ||
|
|
e190335abe | ||
|
|
402b053432 | ||
|
|
0964e3ea4b | ||
|
|
0dc8deac93 | ||
|
|
13280cb8a7 | ||
|
|
11117cd4f6 | ||
|
|
78d218ccb1 | ||
|
|
a72c2c4094 | ||
|
|
193f63893d | ||
|
|
bb181ca838 | ||
|
|
eadbe78f6b | ||
|
|
bfc796b59f | ||
|
|
04d892c926 | ||
|
|
e469e03366 | ||
|
|
ca2af5edb4 | ||
|
|
e49f58bc89 | ||
|
|
e9914e3fbd | ||
|
|
157ef5ff05 | ||
|
|
4769d4ae72 | ||
|
|
d15051aab6 | ||
|
|
5ff8b54c4f | ||
|
|
48e3b11c4e | ||
|
|
2c132d5bc7 | ||
|
|
e0a39fb6c1 | ||
|
|
ccac464750 | ||
|
|
11e986bcf2 | ||
|
|
9d831bdb25 | ||
|
|
7e86e34189 | ||
|
|
1ca46fab32 | ||
|
|
7877301d7f | ||
|
|
b8df42d9bd | ||
|
|
cdada510a0 | ||
|
|
f3e94f697f | ||
|
|
aaad53761e | ||
|
|
183487853c | ||
|
|
2bc3be3153 | ||
|
|
997c3f2ebe | ||
|
|
d3cf64cfdc | ||
|
|
babd7b4d96 | ||
|
|
725353eb74 | ||
|
|
c52f5a4393 | ||
|
|
df99a29258 | ||
|
|
76a5e19e9b | ||
|
|
c7d6289781 | ||
|
|
a50877af9e | ||
|
|
fadcf3a7d0 | ||
|
|
b0fa2b820c | ||
|
|
c03f535c7e | ||
|
|
03ff7b118e | ||
|
|
1f5e1244f2 | ||
|
|
0aa94bc56f | ||
|
|
5f612652d9 | ||
|
|
bf1a6d79b4 | ||
|
|
e49fe348e3 | ||
|
|
bb95e75c47 | ||
|
|
4e179a47b6 | ||
|
|
badd59b644 | ||
|
|
76839dfbaa | ||
|
|
9fd54afd61 | ||
|
|
eb8caa887e | ||
|
|
97daa795fb | ||
|
|
754329fc49 | ||
|
|
5385342272 | ||
|
|
0db3a547c7 | ||
|
|
94f4317b71 | ||
|
|
bf2248063d | ||
|
|
13dcf593d8 | ||
|
|
b547286e53 | ||
|
|
ce5307aa30 | ||
|
|
85224c42b7 | ||
|
|
450f0d9ec2 | ||
|
|
12d5835711 | ||
|
|
969d6b3ee7 | ||
|
|
b0de432339 | ||
|
|
6f7812293e | ||
|
|
37e28d0fcc | ||
|
|
954ec6e505 | ||
|
|
b1cd6c6581 | ||
|
|
248e9cb69a | ||
|
|
caedc293eb | ||
|
|
2e9a9b810c | ||
|
|
ce4c3e9d93 | ||
|
|
470509ee52 | ||
|
|
0ea8b87970 | ||
|
|
b4f54083dc | ||
|
|
f17a11c670 | ||
|
|
adb23d18c6 | ||
|
|
4b6039d8a4 | ||
|
|
1e908423d5 | ||
|
|
4bd3821ff6 | ||
|
|
28a49debcf | ||
|
|
d2a5f4755c | ||
|
|
7f3af5c98a | ||
|
|
d82d19be68 | ||
|
|
33590751c5 | ||
|
|
a80d2ee847 | ||
|
|
8875342557 | ||
|
|
933ef9c988 | ||
|
|
09d28be195 | ||
|
|
ffd9dda611 | ||
|
|
6ed2d40edc | ||
|
|
ce6a987651 | ||
|
|
23cdc15285 | ||
|
|
904bf68cd6 | ||
|
|
e529bd5d64 | ||
|
|
099b560273 | ||
|
|
2d70b68b73 | ||
|
|
01f78eabc7 | ||
|
|
99164a781d | ||
|
|
d25a04f154 | ||
|
|
3c71139a7c | ||
|
|
9991ba312d | ||
|
|
11d5551d02 | ||
|
|
d0939875fc | ||
|
|
da1906f94b | ||
|
|
04f13ab4a7 | ||
|
|
2d17f9d152 | ||
|
|
ae84705332 | ||
|
|
12b30c245a | ||
|
|
7345f68aee | ||
|
|
311e97bd77 | ||
|
|
6d43273b18 | ||
|
|
2fc323639a | ||
|
|
0c97ceb340 | ||
|
|
65d25748db | ||
|
|
8a53d3432d | ||
|
|
5311b134ac | ||
|
|
310ff754ee | ||
|
|
416253ebc7 | ||
|
|
0370944cf6 | ||
|
|
6c22f3bc25 | ||
|
|
d0f6a9b805 | ||
|
|
d0995643a5 | ||
|
|
f82021117c |
27
.github/actions/setup-cache/action.yml
vendored
Normal file
27
.github/actions/setup-cache/action.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
name: Setup cache
|
||||||
|
description: Sets up sccache, CPM cache, etc.
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
host:
|
||||||
|
description: 'Host platform: win or linux'
|
||||||
|
required: true
|
||||||
|
target:
|
||||||
|
description: 'Target platform: win, linux'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Setup sccache
|
||||||
|
uses: hendrikmuhs/ccache-action@v1.2.13
|
||||||
|
with:
|
||||||
|
variant: sccache
|
||||||
|
key: ${{ inputs.target }}-v1
|
||||||
|
|
||||||
|
- name: Setup CPM Cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: cpm-cache
|
||||||
|
key: cpm-${{ inputs.target }}-v1-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}
|
||||||
|
restore-keys: |
|
||||||
|
cpm-${{ inputs.target }}-v1-
|
||||||
239
.github/workflows/build.yml
vendored
Normal file
239
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
name: Build Game
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '**' # every branch
|
||||||
|
- '!no-build-**' # unless marked as no-build
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CPM_SOURCE_CACHE: ${{ github.workspace }}/cpm-cache
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-windows:
|
||||||
|
name: Windows Build
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup caches
|
||||||
|
uses: ./.github/actions/setup-cache
|
||||||
|
with:
|
||||||
|
host: win
|
||||||
|
target: win
|
||||||
|
|
||||||
|
- name: Create Build Environment
|
||||||
|
# Some projects don't allow in-source building, so create a separate build directory
|
||||||
|
# We'll use this as our working directory for all subsequent commands
|
||||||
|
run: cmake -E make_directory ${{github.workspace}}/build
|
||||||
|
|
||||||
|
- name: Configure CMake
|
||||||
|
shell: powershell
|
||||||
|
working-directory: ${{github.workspace}}/build
|
||||||
|
run: cmake $env:GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$env:BUILD_TYPE
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
working-directory: ${{github.workspace}}/build
|
||||||
|
shell: powershell
|
||||||
|
run: cmake --build . --config $env:BUILD_TYPE --target MinecraftPE
|
||||||
|
|
||||||
|
- name: Upload Artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: mcpe-windows
|
||||||
|
path: |
|
||||||
|
${{github.workspace}}/build/${{ env.BUILD_TYPE }}/MinecraftPE.exe
|
||||||
|
${{github.workspace}}/build/${{ env.BUILD_TYPE }}/glfw3.dll
|
||||||
|
${{github.workspace}}/build/${{ env.BUILD_TYPE }}/libpng16.dll
|
||||||
|
${{github.workspace}}/build/${{ env.BUILD_TYPE }}/OpenAL32.dll
|
||||||
|
${{github.workspace}}/build/${{ env.BUILD_TYPE }}/z.dll
|
||||||
|
|
||||||
|
build-linux:
|
||||||
|
name: Linux Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup caches
|
||||||
|
uses: ./.github/actions/setup-cache
|
||||||
|
with:
|
||||||
|
host: linux
|
||||||
|
target: linux
|
||||||
|
|
||||||
|
- name: Create Build Environment
|
||||||
|
# Some projects don't allow in-source building, so create a separate build directory
|
||||||
|
# We'll use this as our working directory for all subsequent commands
|
||||||
|
run: cmake -E make_directory ${{github.workspace}}/build
|
||||||
|
|
||||||
|
- name: Setup Environment
|
||||||
|
run: |
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo apt-get install gcc-multilib
|
||||||
|
sudo apt-get install -y --no-install-recommends build-essential libgl-dev libwayland-dev xorg-dev libxkbcommon-dev
|
||||||
|
|
||||||
|
- name: Configure CMake
|
||||||
|
# Use a bash shell so we can use the same syntax for environment variable
|
||||||
|
# access regardless of the host operating system
|
||||||
|
shell: bash
|
||||||
|
working-directory: ${{github.workspace}}/build
|
||||||
|
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
working-directory: ${{github.workspace}}/build
|
||||||
|
shell: bash
|
||||||
|
run: cmake --build . --config $BUILD_TYPE
|
||||||
|
|
||||||
|
- name: Upload Artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: mcpe-linux
|
||||||
|
path: |
|
||||||
|
${{github.workspace}}/build/MinecraftPE
|
||||||
|
${{github.workspace}}/build/MinecraftPE-server
|
||||||
|
|
||||||
|
build-android: # pray to god
|
||||||
|
name: Build Android APK
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
ANDROID_SDK_ROOT: ${{ github.workspace }}/android-sdk
|
||||||
|
# ANDROID_NDK_PATH: ${{ env.ANDROID_NDK_PATH }}
|
||||||
|
ANDROID_PLATFORM_API: 36
|
||||||
|
ANDROID_BUILD_TOOLS_VERSION: 36.0.0
|
||||||
|
ADB: /bin/true
|
||||||
|
# JAVA_HOME: ${{ env.JAVA_HOME }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Cache Android command-line tools
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ${{ github.workspace }}/android-sdk/cmdline-tools
|
||||||
|
key: android-cmdline-tools-v36
|
||||||
|
|
||||||
|
- name: Setup Android command line tools
|
||||||
|
run: |
|
||||||
|
if [ ! -d "$ANDROID_SDK_ROOT/cmdline-tools/latest" ]; then
|
||||||
|
mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools"
|
||||||
|
curl -o cmdline-tools.zip -L "https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip"
|
||||||
|
unzip -q cmdline-tools.zip -d "$ANDROID_SDK_ROOT/cmdline-tools"
|
||||||
|
mv "$ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools" "$ANDROID_SDK_ROOT/cmdline-tools/latest"
|
||||||
|
fi
|
||||||
|
yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --sdk_root="$ANDROID_SDK_ROOT" "platform-tools" "platforms;android-${ANDROID_PLATFORM_API}" "build-tools;${ANDROID_BUILD_TOOLS_VERSION}"
|
||||||
|
|
||||||
|
- name: Cache Android NDK r14b
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ${{ github.workspace }}/android-ndk-r14b
|
||||||
|
key: android-ndk-r14b
|
||||||
|
|
||||||
|
- name: Install Android NDK r14b
|
||||||
|
run: |
|
||||||
|
if [ ! -d "$GITHUB_WORKSPACE/android-ndk-r14b" ]; then
|
||||||
|
curl -L -o ndk.zip "https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip"
|
||||||
|
unzip -q ndk.zip -d "$GITHUB_WORKSPACE"
|
||||||
|
fi
|
||||||
|
echo "ANDROID_NDK_PATH=$GITHUB_WORKSPACE/android-ndk-r14b" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Install system prerequisites
|
||||||
|
run: |
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo apt-get install -y --no-install-recommends wget unzip curl git python3 libncurses6 libtinfo6
|
||||||
|
if ! ldconfig -p | grep -q "libncurses.so.5"; then
|
||||||
|
sudo ln -sf /lib/x86_64-linux-gnu/libncurses.so.6 /usr/lib/x86_64-linux-gnu/libncurses.so.5 || true
|
||||||
|
fi
|
||||||
|
if ! ldconfig -p | grep -q "libtinfo.so.5"; then
|
||||||
|
sudo ln -sf /lib/x86_64-linux-gnu/libtinfo.so.6 /usr/lib/x86_64-linux-gnu/libtinfo.so.5 || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Setup Java 25
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: temurin
|
||||||
|
java-version: 25
|
||||||
|
|
||||||
|
- name: Validate environment
|
||||||
|
run: |
|
||||||
|
echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT"
|
||||||
|
echo "ANDROID_NDK_PATH=$ANDROID_NDK_PATH"
|
||||||
|
echo "JAVA_HOME=$JAVA_HOME"
|
||||||
|
$ANDROID_SDK_ROOT/platform-tools/adb version || true
|
||||||
|
java -version
|
||||||
|
javac -version
|
||||||
|
|
||||||
|
- name: Run Android build script
|
||||||
|
run: |
|
||||||
|
chmod +x ./build.sh
|
||||||
|
./build.sh
|
||||||
|
|
||||||
|
- name: Upload APK
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: minecraftpe-apk
|
||||||
|
path: ${{ github.workspace }}/build-apk/minecraftpe-debug.apk
|
||||||
|
|
||||||
|
publish:
|
||||||
|
name: Publish
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [ build-windows, build-linux, build-android ]
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Declare Version Variables
|
||||||
|
id: ref
|
||||||
|
run: |
|
||||||
|
echo "version=$(cat VERSION | xargs)" >> $GITHUB_OUTPUT
|
||||||
|
echo "hash=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Download Artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
|
||||||
|
- name: Zip Windows Artifacts
|
||||||
|
uses: vimtor/action-zip@v1.2
|
||||||
|
with:
|
||||||
|
files: ${{github.workspace}}/data/ mcpe-windows/MinecraftPE.exe mcpe-windows/glfw3.dll mcpe-windows/libpng16.dll mcpe-windows/OpenAL32.dll mcpe-windows/z.dll
|
||||||
|
dest: minecraftpe-${{ steps.ref.outputs.hash }}-windows.zip
|
||||||
|
|
||||||
|
- name: Zip Linux Artifacts
|
||||||
|
uses: vimtor/action-zip@v1.2
|
||||||
|
with:
|
||||||
|
files: ${{github.workspace}}/data/ mcpe-linux/MinecraftPE # ye, you should install libraries by urself :trollface:
|
||||||
|
dest: minecraftpe-${{ steps.ref.outputs.hash }}-linux.zip
|
||||||
|
|
||||||
|
- name: Zip Linux Server Artifacts
|
||||||
|
uses: vimtor/action-zip@v1.2
|
||||||
|
with:
|
||||||
|
files: mcpe-linux/MinecraftPE-server
|
||||||
|
dest: minecraftpe-server-${{ steps.ref.outputs.hash }}.zip
|
||||||
|
|
||||||
|
- name: Zip Android Artifact
|
||||||
|
uses: vimtor/action-zip@v1.2
|
||||||
|
with:
|
||||||
|
files: mcpe-apk/minecraftpe-debug.apk
|
||||||
|
dest: minecraftpe-${{ steps.ref.outputs.hash }}-android.zip
|
||||||
|
|
||||||
|
- name: Update Development Release
|
||||||
|
uses: andelf/nightly-release@main
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tag_name: dev
|
||||||
|
name: 'Development Release'
|
||||||
|
body: |
|
||||||
|
MinecraftPE development release for commit ${{ github.sha }}.
|
||||||
|
files: |
|
||||||
|
./minecraftpe-${{ steps.ref.outputs.hash }}-windows.zip
|
||||||
|
./minecraftpe-${{ steps.ref.outputs.hash }}-linux.zip
|
||||||
|
./minecraftpe-server-${{ steps.ref.outputs.hash }}.zip
|
||||||
|
./minecraftpe-${{ steps.ref.outputs.hash }}-android.zip
|
||||||
203
.gitignore
vendored
203
.gitignore
vendored
@@ -1,3 +1,204 @@
|
|||||||
|
# Build output
|
||||||
build/
|
build/
|
||||||
linux-build/
|
out/
|
||||||
|
bin/
|
||||||
|
lib/
|
||||||
|
build-apk/
|
||||||
|
cmake-build-*/
|
||||||
|
CMakeFiles/
|
||||||
|
CMakeCache.txt
|
||||||
|
cmake_install.cmake
|
||||||
|
Makefile
|
||||||
|
*.cmake
|
||||||
|
!cmake/CPM.cmake
|
||||||
|
|
||||||
|
# Compiled object files
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# CMake generated
|
||||||
|
install_manifest.txt
|
||||||
|
compile_commands.json
|
||||||
|
CTestTestfile.cmake
|
||||||
|
_CPack_Packages/
|
||||||
|
*.cbp
|
||||||
|
|
||||||
|
# Visual Studio
|
||||||
|
*.sdf
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
*.VC.db
|
||||||
|
*.VC.opendb
|
||||||
|
.vs/
|
||||||
|
ipch/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
Debug/
|
||||||
|
Release/
|
||||||
|
RelWithDebInfo/
|
||||||
|
MinSizeRel/
|
||||||
|
|
||||||
|
# Xcode
|
||||||
|
*.xcworkspace
|
||||||
|
xcuserdata/
|
||||||
|
*.xccheckout
|
||||||
|
*.xcuserstate
|
||||||
|
*.moved-aside
|
||||||
|
DerivedData/
|
||||||
|
*.hmap
|
||||||
|
*.ipa
|
||||||
|
*.dSYM.zip
|
||||||
|
*.dSYM
|
||||||
|
|
||||||
|
# Android
|
||||||
|
*.apk
|
||||||
|
*.aab
|
||||||
|
*.ap_
|
||||||
|
local.properties
|
||||||
|
.gradle/
|
||||||
|
project/.gradle/
|
||||||
|
project/android/bin/
|
||||||
|
project/android/gen/
|
||||||
|
project/android/obj/
|
||||||
|
project/android_java/bin/
|
||||||
|
project/android_java/gen/
|
||||||
|
project/android_java/obj/
|
||||||
|
project/android/libs/*.so
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Linux
|
||||||
|
*~
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
# CLion / JetBrains
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# Eclipse CDT
|
||||||
|
.project
|
||||||
|
.cproject
|
||||||
|
.settings/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Ninja
|
||||||
|
.ninja_deps
|
||||||
|
.ninja_log
|
||||||
|
build.ninja
|
||||||
|
|
||||||
|
# VS Code
|
||||||
|
.vscode/
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Visual Studio additional
|
||||||
|
*.ncb
|
||||||
|
*.aps
|
||||||
|
*.pdb
|
||||||
|
*.ilk
|
||||||
|
*.exp
|
||||||
|
*.iobj
|
||||||
|
*.ipdb
|
||||||
|
*.tlog
|
||||||
|
*.lastbuildstate
|
||||||
|
*.pch
|
||||||
|
*.ipch
|
||||||
|
*.VC.db-shm
|
||||||
|
*.VC.db-wal
|
||||||
|
*.svclog
|
||||||
|
*.vcxproj.user
|
||||||
|
|
||||||
|
# CMake generated project files
|
||||||
|
ALL_BUILD.vcxproj
|
||||||
|
ALL_BUILD.vcxproj.filters
|
||||||
|
INSTALL.vcxproj
|
||||||
|
INSTALL.vcxproj.filters
|
||||||
|
PACKAGE.vcxproj
|
||||||
|
PACKAGE.vcxproj.filters
|
||||||
|
ZERO_CHECK.vcxproj
|
||||||
|
ZERO_CHECK.vcxproj.filters
|
||||||
|
MinecraftPE.vcxproj
|
||||||
|
MinecraftPE.vcxproj.filters
|
||||||
|
MinecraftPE.sln
|
||||||
|
CPackConfig.cmake
|
||||||
|
CPackSourceConfig.cmake
|
||||||
|
cpm-package-lock.cmake
|
||||||
|
MinecraftPE.dir/
|
||||||
|
_deps/
|
||||||
|
|
||||||
|
# Test / coverage
|
||||||
|
Testing/
|
||||||
|
CTestResults/
|
||||||
|
*.gcno
|
||||||
|
*.gcda
|
||||||
|
*.gcov
|
||||||
|
coverage/
|
||||||
|
lcov.info
|
||||||
|
|
||||||
|
# Precompiled headers
|
||||||
|
*.gch
|
||||||
|
|
||||||
|
# Compiler / linker intermediates
|
||||||
|
*.map
|
||||||
|
*.res
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Patch / diff leftovers
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
*.patch
|
||||||
|
|
||||||
|
# Backup / temp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*.tmp
|
||||||
|
*~.nib
|
||||||
|
|
||||||
|
# Tags
|
||||||
|
tags
|
||||||
|
TAGS
|
||||||
|
.tags
|
||||||
|
ctags
|
||||||
|
|
||||||
|
# macOS extra
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
.fseventsd
|
||||||
|
Icon\r
|
||||||
|
|
||||||
|
# Windows extra
|
||||||
|
*.lnk
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# User / local config
|
||||||
|
options.txt
|
||||||
|
local.cmake
|
||||||
|
games/
|
||||||
|
|
||||||
|
# Dependency cache
|
||||||
|
vcpkg_installed/
|
||||||
.cache/
|
.cache/
|
||||||
|
conan/
|
||||||
|
|||||||
254
CMakeLists.txt
254
CMakeLists.txt
@@ -5,9 +5,47 @@ include(cmake/CPM.cmake)
|
|||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||||
set(CMAKE_CXX_FLAGS "-Wno-c++11-narrowing -Wno-invalid-source-encoding -Wno-reserved-user-defined-literal")
|
set(CMAKE_POLICY_VERSION_MINIMUM 3.10)
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
set(CMAKE_CXX_FLAGS "-Wno-c++11-narrowing -Wno-narrowing -Wno-invalid-source-encoding -Wno-reserved-user-defined-literal")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
find_package(OpenSSL)
|
||||||
|
|
||||||
|
if(EMSCRIPTEN)
|
||||||
|
set(AL_LIBTYPE "STATIC")
|
||||||
|
else()
|
||||||
|
set(AL_LIBTYPE "SHARED")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# I totally shocked
|
||||||
|
if(EMSCRIPTEN)
|
||||||
|
set(PNG_LIB png)
|
||||||
|
|
||||||
|
add_library(zlib INTERFACE IMPORTED)
|
||||||
|
set_target_properties(zlib PROPERTIES
|
||||||
|
INTERFACE_LINK_OPTIONS "-sUSE_ZLIB=1"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(png INTERFACE IMPORTED)
|
||||||
|
set_target_properties(png PROPERTIES
|
||||||
|
INTERFACE_LINK_OPTIONS "-sUSE_LIBPNG=1"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(glfw INTERFACE IMPORTED)
|
||||||
|
set_target_properties(glfw PROPERTIES
|
||||||
|
INTERFACE_LINK_OPTIONS "-sUSE_GLFW=3"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(PNG_LIB png_shared)
|
||||||
|
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME "zlib"
|
||||||
|
GIT_REPOSITORY "https://github.com/madler/zlib"
|
||||||
|
GIT_TAG "v1.3.2"
|
||||||
|
)
|
||||||
|
|
||||||
CPMAddPackage("gh:madler/zlib@1.3.2")
|
|
||||||
CPMAddPackage(
|
CPMAddPackage(
|
||||||
NAME "libpng"
|
NAME "libpng"
|
||||||
GIT_REPOSITORY "https://github.com/pnggroup/libpng.git"
|
GIT_REPOSITORY "https://github.com/pnggroup/libpng.git"
|
||||||
@@ -17,9 +55,20 @@ CPMAddPackage(
|
|||||||
"ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR}"
|
"ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR}"
|
||||||
"PNG_TOOLS OFF"
|
"PNG_TOOLS OFF"
|
||||||
"PNG_TESTS OFF"
|
"PNG_TESTS OFF"
|
||||||
"BUILD_SHARED_LIBS ON"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME "glfw"
|
||||||
|
GIT_REPOSITORY "https://github.com/glfw/glfw.git"
|
||||||
|
GIT_TAG "3.4"
|
||||||
|
EXCLUDE_FROM_ALL TRUE
|
||||||
|
OPTIONS
|
||||||
|
"GLFW_BUILD_EXAMPLES OFF"
|
||||||
|
"GLFW_BUILD_TESTS OFF"
|
||||||
|
"GLFW_BUILD_DOCS OFF"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
CPMAddPackage(
|
CPMAddPackage(
|
||||||
NAME "openal"
|
NAME "openal"
|
||||||
GIT_REPOSITORY "https://github.com/kcat/openal-soft.git"
|
GIT_REPOSITORY "https://github.com/kcat/openal-soft.git"
|
||||||
@@ -28,21 +77,113 @@ CPMAddPackage(
|
|||||||
"ALSOFT_EXAMPLES OFF"
|
"ALSOFT_EXAMPLES OFF"
|
||||||
"ALSOFT_TESTS OFF"
|
"ALSOFT_TESTS OFF"
|
||||||
"ALSOFT_UTILS OFF"
|
"ALSOFT_UTILS OFF"
|
||||||
"BUILD_SHARED_LIBS ON"
|
"LIBTYPE ${AL_LIBTYPE}"
|
||||||
)
|
)
|
||||||
|
|
||||||
CPMAddPackage(
|
# TODO: Clear this paths with *
|
||||||
NAME "glfw"
|
file(GLOB SERVER_SOURCES
|
||||||
GIT_REPOSITORY "https://github.com/glfw/glfw.git"
|
"project/lib_projects/raknet/jni/RaknetSources/*.cpp"
|
||||||
GIT_TAG "3.4"
|
"src/NinecraftApp.cpp"
|
||||||
OPTIONS
|
"src/Performance.cpp"
|
||||||
"GLFW_BUILD_EXAMPLES OFF"
|
"src/SharedConstants.cpp"
|
||||||
"GLFW_BUILD_TESTS OFF"
|
|
||||||
"GLFW_BUILD_DOCS OFF"
|
"src/client/IConfigListener.cpp"
|
||||||
"BUILD_SHARED_LIBS ON"
|
"src/client/Minecraft.cpp"
|
||||||
|
"src/client/OptionStrings.cpp"
|
||||||
|
"src/client/Option.cpp"
|
||||||
|
"src/client/Options.cpp"
|
||||||
|
"src/client/OptionsFile.cpp"
|
||||||
|
"src/client/ServerProfiler.cpp"
|
||||||
|
|
||||||
|
"src/client/gamemode/CreativeMode.cpp"
|
||||||
|
"src/client/gamemode/GameMode.cpp"
|
||||||
|
"src/client/gamemode/SurvivalMode.cpp"
|
||||||
|
|
||||||
|
"src/client/player/LocalPlayer.cpp"
|
||||||
|
"src/client/player/RemotePlayer.cpp"
|
||||||
|
"src/client/player/input/KeyboardInput.cpp"
|
||||||
|
|
||||||
|
"src/locale/I18n.cpp"
|
||||||
|
|
||||||
|
"src/main.cpp"
|
||||||
|
"src/main_dedicated.cpp"
|
||||||
|
|
||||||
|
"src/nbt/Tag.cpp"
|
||||||
|
|
||||||
|
"src/network/ClientSideNetworkHandler.cpp"
|
||||||
|
"src/network/NetEventCallback.cpp"
|
||||||
|
"src/network/Packet.cpp"
|
||||||
|
"src/network/RakNetInstance.cpp"
|
||||||
|
"src/network/ServerSideNetworkHandler.cpp"
|
||||||
|
"src/network/command/CommandServer.cpp"
|
||||||
|
|
||||||
|
"src/platform/CThread.cpp"
|
||||||
|
"src/platform/HttpClient.cpp"
|
||||||
|
"src/platform/PngLoader.cpp"
|
||||||
|
"src/platform/time.cpp"
|
||||||
|
|
||||||
|
"src/platform/input/Controller.cpp"
|
||||||
|
"src/platform/input/Keyboard.cpp"
|
||||||
|
"src/platform/input/Mouse.cpp"
|
||||||
|
"src/platform/input/Multitouch.cpp"
|
||||||
|
|
||||||
|
"src/server/ArgumentsSettings.cpp"
|
||||||
|
"src/server/ServerLevel.cpp"
|
||||||
|
"src/server/ServerPlayer.cpp"
|
||||||
|
|
||||||
|
"src/util/DataIO.cpp"
|
||||||
|
"src/util/Mth.cpp"
|
||||||
|
"src/util/PerfTimer.cpp"
|
||||||
|
"src/util/StringUtils.cpp"
|
||||||
|
|
||||||
|
"src/world/Direction.cpp"
|
||||||
|
|
||||||
|
"src/world/entity/*.cpp"
|
||||||
|
|
||||||
|
"src/world/entity/ai/control/MoveControl.cpp"
|
||||||
|
|
||||||
|
"src/world/entity/animal/*.cpp"
|
||||||
|
|
||||||
|
"src/world/entity/item/*.cpp"
|
||||||
|
|
||||||
|
"src/world/entity/monster/*.cpp"
|
||||||
|
|
||||||
|
"src/world/entity/player/Inventory.cpp"
|
||||||
|
"src/world/entity/player/Player.cpp"
|
||||||
|
|
||||||
|
"src/world/entity/projectile/Arrow.cpp"
|
||||||
|
"src/world/entity/projectile/Throwable.cpp"
|
||||||
|
|
||||||
|
"src/world/food/SimpleFoodData.cpp"
|
||||||
|
|
||||||
|
"src/world/inventory/*.cpp"
|
||||||
|
"src/world/item/*.cpp"
|
||||||
|
"src/world/item/crafting/*.cpp"
|
||||||
|
"src/world/level/*.cpp"
|
||||||
|
|
||||||
|
"src/world/level/biome/Biome.cpp"
|
||||||
|
"src/world/level/biome/BiomeSource.cpp"
|
||||||
|
|
||||||
|
"src/world/level/chunk/LevelChunk.cpp"
|
||||||
|
|
||||||
|
"src/world/level/dimension/Dimension.cpp"
|
||||||
|
|
||||||
|
"src/world/level/levelgen/*.cpp"
|
||||||
|
"src/world/level/levelgen/feature/Feature.cpp"
|
||||||
|
"src/world/level/levelgen/synth/*.cpp"
|
||||||
|
|
||||||
|
"src/world/level/material/Material.cpp"
|
||||||
|
|
||||||
|
"src/world/level/pathfinder/Path.cpp"
|
||||||
|
|
||||||
|
"src/world/level/storage/*.cpp"
|
||||||
|
"src/world/level/tile/*.cpp"
|
||||||
|
"src/world/level/tile/entity/*.cpp"
|
||||||
|
|
||||||
|
"src/world/phys/HitResult.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB SOURCES
|
file(GLOB CLIENT_SOURCES
|
||||||
"src/client/*.cpp"
|
"src/client/*.cpp"
|
||||||
|
|
||||||
"src/client/gamemode/*.cpp"
|
"src/client/gamemode/*.cpp"
|
||||||
@@ -126,18 +267,33 @@ endif()
|
|||||||
|
|
||||||
|
|
||||||
if(PLATFORM STREQUAL "PLATFORM_WIN32")
|
if(PLATFORM STREQUAL "PLATFORM_WIN32")
|
||||||
list(APPEND SOURCES "src/AppPlatform_win32.cpp")
|
list(APPEND CLIENT_SOURCES "src/AppPlatform_win32.cpp" "glad/src/glad.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(PLATFORM STREQUAL "PLATFORM_GLFW")
|
if(PLATFORM STREQUAL "PLATFORM_GLFW")
|
||||||
list(APPEND SOURCES "src/AppPlatform_glfw.cpp")
|
list(APPEND CLIENT_SOURCES "src/AppPlatform_glfw.cpp" "glad/src/glad.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME}
|
if(EMSCRIPTEN)
|
||||||
${SOURCES}
|
list(APPEND CLIENT_SOURCES "glad/src/glad.c")
|
||||||
"glad/src/glad.c"
|
endif()
|
||||||
|
|
||||||
|
# Server
|
||||||
|
if(UNIX)
|
||||||
|
add_executable("${PROJECT_NAME}-server" ${SERVER_SOURCES})
|
||||||
|
|
||||||
|
target_compile_definitions("${PROJECT_NAME}-server" PUBLIC "STANDALONE_SERVER" "SERVER_PROFILER")
|
||||||
|
|
||||||
|
target_include_directories("${PROJECT_NAME}-server" PUBLIC
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/"
|
||||||
|
"project/lib_projects/raknet/jni/RaknetSources"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_libraries("${PROJECT_NAME}-server" ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} ${CLIENT_SOURCES})
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(EXTRA_LIBS "ws2_32")
|
set(EXTRA_LIBS "ws2_32")
|
||||||
target_compile_definitions(${PROJECT_NAME} PUBLIC "_CRT_SECURE_NO_WARNINGS")
|
target_compile_definitions(${PROJECT_NAME} PUBLIC "_CRT_SECURE_NO_WARNINGS")
|
||||||
@@ -155,8 +311,58 @@ target_include_directories(${PROJECT_NAME} PUBLIC
|
|||||||
"lib/include"
|
"lib/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(EMSCRIPTEN)
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
# uuuh i hate it
|
||||||
|
set(EM_FLAGS "-pthread -sUSE_PTHREADS=1 -sSHARED_MEMORY=1")
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EM_FLAGS}")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EM_FLAGS}")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EM_FLAGS} --preload-file ${CMAKE_SOURCE_DIR}/data@/data -sPROXY_TO_PTHREAD")
|
||||||
|
|
||||||
|
target_compile_options(${PROJECT_NAME} PUBLIC
|
||||||
|
"-Os"
|
||||||
|
"-Wno-invalid-source-encoding"
|
||||||
|
"-Wno-narrowing"
|
||||||
|
"-Wno-deprecated-register"
|
||||||
|
"-Wno-reserved-user-defined-literal"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_options(${PROJECT_NAME} PUBLIC
|
||||||
|
"-Os"
|
||||||
|
"-sALLOW_MEMORY_GROWTH=1"
|
||||||
|
"-sFORCE_FILESYSTEM=1"
|
||||||
|
"-sLEGACY_GL_EMULATION=1"
|
||||||
|
"-sGL_UNSAFE_OPTS=0"
|
||||||
|
"-sEMULATE_FUNCTION_POINTER_CASTS=1"
|
||||||
|
"-sALLOW_TABLE_GROWTH=1"
|
||||||
|
"-sEXPORTED_RUNTIME_METHODS=['FS','stringToUTF8','UTF8ToString','cwrap','ccall','HEAP8','HEAPU8','HEAP32','HEAPU32']"
|
||||||
|
"-sEXPORTED_FUNCTIONS=['_main']"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
message("DEBUG MODE")
|
||||||
|
|
||||||
|
target_link_options(${PROJECT_NAME} PUBLIC
|
||||||
|
"-sASSERTIONS=2"
|
||||||
|
"-sSTACK_OVERFLOW_CHECK=2"
|
||||||
|
"-sSTACK_SIZE=5242880"
|
||||||
|
"-sGL_DEBUG=1"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PUBLIC "__EMSCRIPTEN__" "NO_SOUND" "NO_NETWORK")
|
||||||
|
set(EXTRA_LIBS "idbfs.js")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Client
|
||||||
target_compile_definitions(${PROJECT_NAME} PUBLIC "OPENGL_ES" "NO_EGL" ${PLATFORM})
|
target_compile_definitions(${PROJECT_NAME} PUBLIC "OPENGL_ES" "NO_EGL" ${PLATFORM})
|
||||||
target_link_libraries(${PROJECT_NAME} zlib png_shared alsoft.common OpenAL::OpenAL glfw ${EXTRA_LIBS})
|
target_link_libraries(${PROJECT_NAME} zlib ${PNG_LIB} alsoft.common OpenAL::OpenAL glfw ${EXTRA_LIBS})
|
||||||
|
|
||||||
|
if (OpenSSL_FOUND)
|
||||||
|
target_link_libraries(${PROJECT_NAME} OpenSSL::SSL OpenSSL::Crypto)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PUBLIC HTTPCLIENT_USE_OPENSSL)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (NOT UNIX)
|
if (NOT UNIX)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
@@ -167,8 +373,16 @@ add_custom_command(
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT EMSCRIPTEN)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ${PROJECT_NAME}
|
TARGET ${PROJECT_NAME}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/data" $<TARGET_FILE_DIR:${PROJECT_NAME}>/data
|
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/data" $<TARGET_FILE_DIR:${PROJECT_NAME}>/data
|
||||||
)
|
)
|
||||||
|
else()
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${PROJECT_NAME}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/misc/web/index.html" $<TARGET_FILE_DIR:${PROJECT_NAME}>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
194
README.md
194
README.md
@@ -1,18 +1,200 @@
|
|||||||
# MinecraftPE
|
# MinecraftPE
|
||||||
|
> [!Warning]
|
||||||
|
> Github repository **isnt main**. All issues and pull requests should be send in [Gitea Repository](https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1).
|
||||||
|
|
||||||
This is leaked source code of Minecraft PE 0.6.1 with my own impovements :sunglasses:
|
> [!Important]
|
||||||
|
> We have a discord server, where you can report bugs or send feedback https://discord.gg/c58YesBxve
|
||||||
|
|
||||||
First of all I made it build with CMake (w/o VS2012). Also I fixed some compile errors. And finally I ported it to GLFW to make it run on several platforms and remove binary dependencies.
|
Source code for **Minecraft Pocket Edition 0.6.1 alpha** with various fixes and improvements.
|
||||||
|
|
||||||
# TODO
|
This project aims to preserve and improve this early version of Minecraft PE.
|
||||||
|
|
||||||
|
# TODO / Roadmap
|
||||||
- [x] Add platform GLFW
|
- [x] Add platform GLFW
|
||||||
- [x] Compile for Linux
|
- [x] Compile for Linux
|
||||||
- [ ] Compile for android aarch64
|
- [x] Compile for android aarch64
|
||||||
|
- [x] Touch control improvements
|
||||||
|
- [ ] Screen fixes
|
||||||
|
- [ ] Rewrite platform logic
|
||||||
|
- [x] Fix sound
|
||||||
|
- [x] Do a server connection GUI
|
||||||
|
- [ ] Controller support
|
||||||
|
- [x] Minecraft server hosting
|
||||||
|
- [x] Screen fixess
|
||||||
|
- [x] Fix fog
|
||||||
|
- [x] Add sprinting
|
||||||
|
- [x] Chat (semi working) and commands
|
||||||
|
- [x] Implementing options
|
||||||
|
- [x] Better F3
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
|
|
||||||
## CMake
|
## CMake
|
||||||
|
### Linux
|
||||||
|
1. Install dependiences
|
||||||
|
|
||||||
|
(Debian-like)
|
||||||
|
|
||||||
|
``sudo apt install build-essential git cmake libgl-dev libwayland-dev xorg-dev libxkbcommon-dev``
|
||||||
|
|
||||||
|
(Arch-like)
|
||||||
|
|
||||||
|
``sudo pacman -S base-devel git cmake libglvnd wayland xorg-server-devel xorgproto libxkbcommon``
|
||||||
|
|
||||||
|
2. Create build folder
|
||||||
|
``mkdir build && cd build``
|
||||||
|
|
||||||
|
3. Generate CMake cache and build the project
|
||||||
|
```
|
||||||
|
cmake .. -B .
|
||||||
|
cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
1. Install [Visual studio Build Tools](https://aka.ms/vs/stable/vs_BuildTools.exe) and [CMake](https://github.com/Kitware/CMake/releases/download/v4.3.0-rc3/cmake-4.3.0-rc3-windows-x86_64.msi)
|
||||||
|
|
||||||
|
2. Create build folder
|
||||||
|
``mkdir build && cd build``
|
||||||
|
|
||||||
|
3. Generate CMake cache and build the project
|
||||||
|
```
|
||||||
|
cmake ..
|
||||||
|
cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Visual Studio
|
||||||
|
|
||||||
|
1. Open the repository folder in **Visual Studio**.
|
||||||
|
2. Visual Studio will automatically detect the `CMakeLists.txt` file and generate the project configuration.
|
||||||
|
3. Set **MinecraftPE.exe** as the **target**.
|
||||||
|
4. Press **Run** (or F5) to build and launch the game.
|
||||||
|
|
||||||
|
## Android
|
||||||
|
### Windows
|
||||||
|
1. Download **Android NDK r14b**:
|
||||||
|
http://dl.google.com/android/repository/android-ndk-r14b-windows-x86_64.zip
|
||||||
|
|
||||||
|
2. Extract it to the root of your `C:` drive so the path becomes:
|
||||||
|
|
||||||
|
```
|
||||||
|
C:\android-ndk-r14b
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Run the build script:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Full build (NDK + Java + APK + install)
|
||||||
|
.\build.ps1
|
||||||
|
|
||||||
|
# Skip C++ compilation (Java/assets changed only)
|
||||||
|
.\build.ps1 -NoCpp
|
||||||
|
|
||||||
|
# Skip Java compilation (C++ changed only)
|
||||||
|
.\build.ps1 -NoJava
|
||||||
|
|
||||||
|
# Only repackage + install (no compilation)
|
||||||
|
.\build.ps1 -NoBuild
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
1. Download **Command line tools**:
|
||||||
|
https://developer.android.com/studio#command-line-tools-only
|
||||||
|
|
||||||
|
2. Unzip it into a folder, e.g.:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p "$HOME/Android/Sdk/"
|
||||||
|
unzip commandlinetools-linux-*.zip -d "$HOME/Android/Sdk/"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Your structure should look like
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$HOME/Android/Sdk/cmdline-tools/bin/sdkmanager
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> `sdkmanager` expects the SDK to include a `cmdline-tools/latest/` folder.
|
||||||
|
> If you only have `cmdline-tools/bin`, create the required layout:
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> mkdir -p "$HOME/Android/Sdk/cmdline-tools/latest"
|
||||||
|
> ln -snf ../bin "$HOME/Android/Sdk/cmdline-tools/latest/bin"
|
||||||
|
> ln -snf ../lib "$HOME/Android/Sdk/cmdline-tools/latest/lib"
|
||||||
|
> ln -snf ../source.properties "$HOME/Android/Sdk/cmdline-tools/latest/source.properties"
|
||||||
|
> ln -snf ../NOTICE.txt "$HOME/Android/Sdk/cmdline-tools/latest/NOTICE.txt"
|
||||||
|
> ```
|
||||||
|
|
||||||
|
4. Install the build tools (and platform) using `sdkmanager`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export ANDROID_SDK_ROOT="$HOME/Android/Sdk"
|
||||||
|
export PATH="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$PATH"
|
||||||
|
|
||||||
|
sdkmanager --install "platform-tools" "platforms;android-35" "build-tools;35.0.0"
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> if you want build.sh to always find the SDK,
|
||||||
|
> Set ANDROID_SDK_ROOT in your shell config (~/.bashrc / ~/.profile / ~/.config/fish/config.fish), for example:
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> export ANDROID_SDK_ROOT="$HOME/Android/Sdk"
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> Then restart your shell (or `source` the file)
|
||||||
|
|
||||||
|
5. Verify the install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls "$ANDROID_SDK_ROOT/build-tools"
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see a version folder like:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
35.0.0
|
||||||
|
33.0.2
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Download **Android NDK r14b**:
|
||||||
|
https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip
|
||||||
|
|
||||||
|
7. Extract the archive to `/home/username/`, so that the final directory path is `/home/username/android-ndk-r14b/`
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Make sure you don’t end up with a nested folder like `/home/username/android-ndk-r14b/android-ndk-r14b/`.
|
||||||
|
|
||||||
|
8. Re run `build.sh`
|
||||||
|
|
||||||
|
## Web
|
||||||
|
1. Download and install **emsdk**: https://emscripten.org/docs/getting_started/downloads.html
|
||||||
|
> [!NOTE]
|
||||||
|
> On arch linux you can use AUR:
|
||||||
|
> `yay -Sy emsdk`
|
||||||
|
|
||||||
|
2. Configure and build project:
|
||||||
```
|
```
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -B .
|
cmake .. -B . -G Ninja "-DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"
|
||||||
make -j4
|
cmake --build . --target MinecraftPE
|
||||||
|
```
|
||||||
|
> [!NOTE]
|
||||||
|
> If you are using VSCode with CMake plugin, you can add Emscripten kit
|
||||||
|
> 1. Press Ctrl + Shift + P
|
||||||
|
> 2. Type `CMake: Edit User-Local CMake Kits` and hit Enter
|
||||||
|
> 3. Add this:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Emscripten",
|
||||||
|
"compilers": {
|
||||||
|
"C": "/usr/lib/emsdk/upstream/bin/clang",
|
||||||
|
"CXX": "/usr/lib/emsdk/upstream/bin/clang++"
|
||||||
|
},
|
||||||
|
"toolchainFile": "/usr/lib/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
3. Run game:
|
||||||
|
```
|
||||||
|
emrun --port 8080 .
|
||||||
```
|
```
|
||||||
305
build.ps1
Normal file
305
build.ps1
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
# ============================================================
|
||||||
|
# Usage:
|
||||||
|
# .\build.ps1 # full build (NDK + Java + APK + install)
|
||||||
|
# .\build.ps1 -NoCpp # skip NDK rebuild (Java/assets changed)
|
||||||
|
# .\build.ps1 -NoJava # skip Java recompile (C++ changed only)
|
||||||
|
# .\build.ps1 -NoBuild # repackage + install only (no recompile)
|
||||||
|
# .\build.ps1 -Clean # remove build output before building
|
||||||
|
# ============================================================
|
||||||
|
param(
|
||||||
|
[switch]$NoCpp,
|
||||||
|
[switch]$NoJava,
|
||||||
|
[switch]$NoBuild,
|
||||||
|
[switch]$Clean
|
||||||
|
)
|
||||||
|
|
||||||
|
Set-StrictMode -Version Latest
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
# ── Paths ────────────────────────────────────────────────────
|
||||||
|
$repo = $PSScriptRoot
|
||||||
|
$apkbuild = "C:\apkbuild"
|
||||||
|
$ndk = "C:\android-ndk-r14b"
|
||||||
|
$sdkTools = "$env:LOCALAPPDATA\Android\Sdk\build-tools\35.0.0"
|
||||||
|
$androidJar = "$env:LOCALAPPDATA\Android\Sdk\platforms\android-36\android.jar"
|
||||||
|
$adb = "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe"
|
||||||
|
$keystore = "$apkbuild\debug.keystore"
|
||||||
|
$pkg = "com.mojang.minecraftpe"
|
||||||
|
|
||||||
|
# Auto-detect keytool from JAVA_HOME, then from common install locations
|
||||||
|
$keytool = if ($env:JAVA_HOME) { "$env:JAVA_HOME\bin\keytool.exe" } else {
|
||||||
|
$found = Get-ChildItem "C:\Program Files\Java","C:\Program Files\Eclipse Adoptium" `
|
||||||
|
-Filter keytool.exe -Recurse -ErrorAction SilentlyContinue |
|
||||||
|
Sort-Object FullName -Descending | Select-Object -First 1 -ExpandProperty FullName
|
||||||
|
if (-not $found) { throw "keytool not found. Set JAVA_HOME or install a JDK." }
|
||||||
|
$found
|
||||||
|
}
|
||||||
|
|
||||||
|
$jniDir = "$repo\project\android\jni"
|
||||||
|
$libSrc = "$repo\project\android\libs\arm64-v8a\libminecraftpe.so"
|
||||||
|
$libDst = "$apkbuild\lib\arm64-v8a\libminecraftpe.so"
|
||||||
|
$manifest = "$repo\project\android_java\AndroidManifest.xml"
|
||||||
|
$res = "$repo\project\android_java\res"
|
||||||
|
$javaSrc = "$repo\project\android_java\src"
|
||||||
|
$stubsDir = "$apkbuild\stubs"
|
||||||
|
$rJava = "$apkbuild\gen\R.java"
|
||||||
|
$classesDir = "$apkbuild\classes"
|
||||||
|
$dexOut = "$apkbuild\classes.dex"
|
||||||
|
$dataDir = "$repo\data"
|
||||||
|
|
||||||
|
$unsigned = "$apkbuild\minecraftpe-unsigned.apk"
|
||||||
|
$aligned = "$apkbuild\minecraftpe-aligned.apk"
|
||||||
|
$signed = "$apkbuild\minecraftpe-debug.apk"
|
||||||
|
|
||||||
|
Add-Type -Assembly "System.IO.Compression.FileSystem"
|
||||||
|
|
||||||
|
function Write-Step([string]$msg) { Write-Host "`n==> $msg" -ForegroundColor Cyan }
|
||||||
|
function Assert-ExitCode([string]$step) {
|
||||||
|
if ($LASTEXITCODE -ne 0) { Write-Host "FAILED: $step (exit $LASTEXITCODE)" -ForegroundColor Red; exit 1 }
|
||||||
|
}
|
||||||
|
function New-Dir([string]$path) { New-Item $path -ItemType Directory -Force | Out-Null }
|
||||||
|
function Write-Stub([string]$rel, [string]$content) {
|
||||||
|
$full = "$stubsDir\$rel"
|
||||||
|
New-Dir (Split-Path $full -Parent)
|
||||||
|
if (-not (Test-Path $full)) { [System.IO.File]::WriteAllText($full, $content); Write-Host " stub: $rel" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 0. Clean (optional) ───────────────────────────────────────
|
||||||
|
if ($Clean) {
|
||||||
|
Write-Step "Cleaning build output"
|
||||||
|
Remove-Item -Recurse -Force $apkbuild -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 1. Bootstrap ─────────────────────────────────────────────
|
||||||
|
Write-Step "Bootstrap"
|
||||||
|
|
||||||
|
New-Dir $apkbuild
|
||||||
|
New-Dir "$apkbuild\lib\arm64-v8a"
|
||||||
|
New-Dir "$apkbuild\gen"
|
||||||
|
New-Dir $stubsDir
|
||||||
|
|
||||||
|
if (-not (Test-Path $keystore)) {
|
||||||
|
Write-Host " generating debug.keystore..."
|
||||||
|
$eap = $ErrorActionPreference; $ErrorActionPreference = "Continue"
|
||||||
|
& $keytool -genkeypair `
|
||||||
|
-keystore $keystore -storepass android -keypass android `
|
||||||
|
-alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 `
|
||||||
|
-dname "CN=Android Debug,O=Android,C=US" 2>&1 | Out-Null
|
||||||
|
$ErrorActionPreference = $eap
|
||||||
|
Assert-ExitCode "keytool"
|
||||||
|
Write-Host " keystore created"
|
||||||
|
} else { Write-Host " keystore OK" }
|
||||||
|
|
||||||
|
Write-Stub "com\mojang\android\StringValue.java" "package com.mojang.android;`npublic interface StringValue { String getStringValue(); }`n"
|
||||||
|
|
||||||
|
Write-Stub "com\mojang\android\licensing\LicenseCodes.java" "package com.mojang.android.licensing;`npublic class LicenseCodes { public static final int LICENSE_OK = 0; }`n"
|
||||||
|
|
||||||
|
Write-Stub "com\mojang\android\EditTextAscii.java" @"
|
||||||
|
package com.mojang.android;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.EditText;
|
||||||
|
public class EditTextAscii extends EditText implements TextWatcher {
|
||||||
|
public EditTextAscii(Context c) { super(c); addTextChangedListener(this); }
|
||||||
|
public EditTextAscii(Context c, AttributeSet a) { super(c,a); addTextChangedListener(this); }
|
||||||
|
public EditTextAscii(Context c, AttributeSet a, int d) { super(c,a,d); addTextChangedListener(this); }
|
||||||
|
@Override public void onTextChanged(CharSequence s,int st,int b,int co){}
|
||||||
|
public void beforeTextChanged(CharSequence s,int st,int co,int aft){}
|
||||||
|
public void afterTextChanged(Editable e){
|
||||||
|
String s=e.toString(),san=sanitize(s);
|
||||||
|
if(!s.equals(san))e.replace(0,e.length(),san);
|
||||||
|
}
|
||||||
|
static public String sanitize(String s){
|
||||||
|
StringBuilder sb=new StringBuilder();
|
||||||
|
for(int i=0;i<s.length();i++){char c=s.charAt(i);if(c<128)sb.append(c);}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
|
||||||
|
Write-Stub "com\mojang\android\preferences\SliderPreference.java" @"
|
||||||
|
package com.mojang.android.preferences;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.preference.DialogPreference;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
public class SliderPreference extends DialogPreference implements SeekBar.OnSeekBarChangeListener {
|
||||||
|
private static final String NS="http://schemas.android.com/apk/res/android";
|
||||||
|
private Context _ctx; private TextView _tv; private SeekBar _sb;
|
||||||
|
private String _suf; private int _def,_max,_val,_min;
|
||||||
|
public SliderPreference(Context ctx,AttributeSet a){
|
||||||
|
super(ctx,a); _ctx=ctx;
|
||||||
|
_suf=gStr(a,NS,"text",""); _def=gInt(a,NS,"defaultValue",0);
|
||||||
|
_max=gInt(a,NS,"max",100); _min=gInt(a,null,"min",0);
|
||||||
|
setDefaultValue(_def);
|
||||||
|
}
|
||||||
|
@Override protected View onCreateDialogView(){
|
||||||
|
LinearLayout l=new LinearLayout(_ctx); l.setOrientation(LinearLayout.VERTICAL); l.setPadding(6,6,6,6);
|
||||||
|
_tv=new TextView(_ctx); _tv.setGravity(Gravity.CENTER_HORIZONTAL); _tv.setTextSize(32);
|
||||||
|
l.addView(_tv,new LinearLayout.LayoutParams(-1,-2));
|
||||||
|
_sb=new SeekBar(_ctx); _sb.setOnSeekBarChangeListener(this);
|
||||||
|
l.addView(_sb,new LinearLayout.LayoutParams(-1,-2));
|
||||||
|
if(shouldPersist())_val=getPersistedInt(_def);
|
||||||
|
_sb.setMax(_max); _sb.setProgress(_val); return l;
|
||||||
|
}
|
||||||
|
@Override protected void onSetInitialValue(boolean r,Object d){
|
||||||
|
super.onSetInitialValue(r,d);
|
||||||
|
_val=r?(shouldPersist()?getPersistedInt(_def):0):(Integer)d;
|
||||||
|
}
|
||||||
|
public void onProgressChanged(SeekBar s,int v,boolean f){
|
||||||
|
_val=v+_min; _tv.setText(_val+_suf);
|
||||||
|
if(shouldPersist())persistInt(_val); callChangeListener(Integer.valueOf(_val));
|
||||||
|
}
|
||||||
|
public void onStartTrackingTouch(SeekBar s){}
|
||||||
|
public void onStopTrackingTouch(SeekBar s){}
|
||||||
|
private int gInt(AttributeSet a,String ns,String n,int d){int id=a.getAttributeResourceValue(ns,n,0);return id!=0?getContext().getResources().getInteger(id):a.getAttributeIntValue(ns,n,d);}
|
||||||
|
private String gStr(AttributeSet a,String ns,String n,String d){int id=a.getAttributeResourceValue(ns,n,0);if(id!=0)return getContext().getResources().getString(id);String v=a.getAttributeValue(ns,n);return v!=null?v:d;}
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
|
||||||
|
Write-Stub "com\mojang\minecraftpe\MainMenuOptionsActivity.java" @"
|
||||||
|
package com.mojang.minecraftpe;
|
||||||
|
import android.app.Activity;
|
||||||
|
public class MainMenuOptionsActivity extends Activity {
|
||||||
|
public static final String Internal_Game_DifficultyPeaceful="internal_game_difficulty_peaceful";
|
||||||
|
public static final String Game_DifficultyLevel="game_difficulty";
|
||||||
|
public static final String Controls_Sensitivity="controls_sensitivity";
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
|
||||||
|
Write-Stub "com\mojang\minecraftpe\Minecraft_Market.java" @"
|
||||||
|
package com.mojang.minecraftpe;
|
||||||
|
import android.app.Activity; import android.content.Intent; import android.os.Bundle;
|
||||||
|
public class Minecraft_Market extends Activity {
|
||||||
|
@Override protected void onCreate(Bundle s){super.onCreate(s);startActivity(new Intent(this,MainActivity.class));finish();}
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
|
||||||
|
Write-Stub "com\mojang\minecraftpe\Minecraft_Market_Demo.java" @"
|
||||||
|
package com.mojang.minecraftpe;
|
||||||
|
import android.content.Intent; import android.net.Uri;
|
||||||
|
public class Minecraft_Market_Demo extends MainActivity {
|
||||||
|
@Override public void buyGame(){startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse("market://details?id=com.mojang.minecraftpe")));}
|
||||||
|
@Override protected boolean isDemo(){return true;}
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
|
||||||
|
Write-Stub "com\mojang\minecraftpe\GameModeButton.java" @"
|
||||||
|
package com.mojang.minecraftpe;
|
||||||
|
import com.mojang.android.StringValue;
|
||||||
|
import android.content.Context; import android.util.AttributeSet;
|
||||||
|
import android.view.View; import android.view.View.OnClickListener;
|
||||||
|
import android.widget.TextView; import android.widget.ToggleButton;
|
||||||
|
public class GameModeButton extends ToggleButton implements OnClickListener,StringValue {
|
||||||
|
static final int Creative=0,Survival=1;
|
||||||
|
private int _type=0; private boolean _attached=false;
|
||||||
|
public GameModeButton(Context c,AttributeSet a){super(c,a);setOnClickListener(this);}
|
||||||
|
public void onClick(View v){_update();}
|
||||||
|
@Override protected void onFinishInflate(){super.onFinishInflate();_update();}
|
||||||
|
@Override protected void onAttachedToWindow(){if(!_attached){_update();_attached=true;}}
|
||||||
|
private void _update(){_set(isChecked()?Survival:Creative);}
|
||||||
|
private void _set(int i){
|
||||||
|
_type=i<Creative?Creative:(i>Survival?Survival:i);
|
||||||
|
int id=_type==Survival?R.string.gamemode_survival_summary:R.string.gamemode_creative_summary;
|
||||||
|
String desc=getContext().getString(id);
|
||||||
|
View v=getRootView().findViewById(R.id.labelGameModeDesc);
|
||||||
|
if(desc!=null&&v instanceof TextView)((TextView)v).setText(desc);
|
||||||
|
}
|
||||||
|
public String getStringValue(){return new String[]{"creative","survival"}[_type];}
|
||||||
|
static public String getStringForType(int i){int c=i<Creative?Creative:(i>Survival?Survival:i);return new String[]{"creative","survival"}[c];}
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
|
||||||
|
Write-Host " stubs OK"
|
||||||
|
|
||||||
|
# ── 1. NDK build ─────────────────────────────────────────────
|
||||||
|
if (-not $NoCpp -and -not $NoBuild) {
|
||||||
|
Write-Step "NDK build (arm64-v8a)"
|
||||||
|
# NDK r14b on Windows hits the 32K CreateProcess limit with long paths.
|
||||||
|
# Work around it by building through a short junction C:\m -> repo root.
|
||||||
|
# Use forward slashes in the build paths to prevent the NDK toolchain from stripping backslashes.
|
||||||
|
$junctionBase = "C:/m"
|
||||||
|
if (-not (Test-Path "C:\m")) {
|
||||||
|
& cmd.exe /c "mklink /J `"C:\m`" `"$repo`"" | Out-Null
|
||||||
|
}
|
||||||
|
Push-Location "$junctionBase/project/android/jni"
|
||||||
|
$env:NDK_MODULE_PATH = "$junctionBase/project/lib_projects"
|
||||||
|
# run ndk-build and stream output directly to the console
|
||||||
|
$ndkCmd = Join-Path $ndk 'ndk-build.cmd'
|
||||||
|
$ndkArgs = "NDK_PROJECT_PATH=`"$junctionBase/project/android`" APP_BUILD_SCRIPT=`"$junctionBase/project/android/jni/Android.mk`""
|
||||||
|
|
||||||
|
$proc = Start-Process -FilePath $ndkCmd -ArgumentList $ndkArgs -NoNewWindow -Wait -PassThru
|
||||||
|
Pop-Location
|
||||||
|
if ($proc.ExitCode -ne 0) {
|
||||||
|
Write-Host "ndk-build failed (exit $($proc.ExitCode))" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
Copy-Item $libSrc $libDst -Force
|
||||||
|
Write-Host " .so -> $libDst"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 2. Java compile ──────────────────────────────────────────
|
||||||
|
if (-not $NoJava -and -not $NoBuild) {
|
||||||
|
Write-Step "Java compile"
|
||||||
|
|
||||||
|
New-Dir (Split-Path $rJava -Parent)
|
||||||
|
& "$sdkTools\aapt.exe" package -f -M $manifest -S $res -I $androidJar -J "$apkbuild\gen" -F "$apkbuild\_rgen.apk"
|
||||||
|
Assert-ExitCode "aapt R.java"
|
||||||
|
Remove-Item "$apkbuild\_rgen.apk" -ea SilentlyContinue
|
||||||
|
|
||||||
|
$srcs = @(
|
||||||
|
Get-ChildItem $javaSrc -Recurse -Filter "*.java" | Select-Object -Exp FullName
|
||||||
|
Get-ChildItem $stubsDir -Recurse -Filter "*.java" | Select-Object -Exp FullName
|
||||||
|
$rJava
|
||||||
|
)
|
||||||
|
|
||||||
|
Remove-Item $classesDir -Recurse -Force -ea SilentlyContinue
|
||||||
|
New-Dir $classesDir
|
||||||
|
|
||||||
|
& javac --release 8 -cp $androidJar -d $classesDir @srcs
|
||||||
|
if ($LASTEXITCODE -ne 0) { Write-Host 'javac failed' -ForegroundColor Red; exit 1 }
|
||||||
|
Write-Host " javac OK"
|
||||||
|
|
||||||
|
$classFiles = Get-ChildItem $classesDir -Recurse -Filter "*.class" | Select-Object -Exp FullName
|
||||||
|
& "$sdkTools\d8.bat" --min-api 21 --output $apkbuild $classFiles
|
||||||
|
Assert-ExitCode "d8"
|
||||||
|
Write-Host " d8 -> $dexOut"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 3. Package APK ───────────────────────────────────────────
|
||||||
|
Write-Step "Package APK"
|
||||||
|
Remove-Item $unsigned,$aligned,$signed -ea SilentlyContinue
|
||||||
|
|
||||||
|
& "$sdkTools\aapt.exe" package -f -M $manifest -S $res -I $androidJar -F $unsigned
|
||||||
|
Assert-ExitCode "aapt package"
|
||||||
|
|
||||||
|
$zip = [System.IO.Compression.ZipFile]::Open($unsigned, 'Update')
|
||||||
|
try {
|
||||||
|
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip,$dexOut,"classes.dex",[System.IO.Compression.CompressionLevel]::Fastest)|Out-Null
|
||||||
|
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip,$libDst,"lib/arm64-v8a/libminecraftpe.so",[System.IO.Compression.CompressionLevel]::NoCompression)|Out-Null
|
||||||
|
Get-ChildItem $dataDir -Recurse -File | ForEach-Object {
|
||||||
|
$rel=$_.FullName.Substring("$dataDir\".Length).Replace('\','/')
|
||||||
|
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip,$_.FullName,"assets/$rel",[System.IO.Compression.CompressionLevel]::NoCompression)|Out-Null
|
||||||
|
}
|
||||||
|
} finally { $zip.Dispose() }
|
||||||
|
Write-Host " APK assembled"
|
||||||
|
|
||||||
|
& "$sdkTools\zipalign.exe" -p 4 $unsigned $aligned; Assert-ExitCode "zipalign"
|
||||||
|
& "$sdkTools\apksigner.bat" sign --ks $keystore --ks-pass pass:android --key-pass pass:android --out $signed $aligned; Assert-ExitCode "apksigner"
|
||||||
|
Write-Host " signed -> $signed"
|
||||||
|
|
||||||
|
# ── 4. Install ───────────────────────────────────────────────
|
||||||
|
Write-Step "Install"
|
||||||
|
& $adb shell am force-stop $pkg
|
||||||
|
& $adb uninstall $pkg 2>$null
|
||||||
|
& $adb install --no-incremental $signed
|
||||||
|
Assert-ExitCode "adb install"
|
||||||
|
|
||||||
|
Write-Host "`nDone." -ForegroundColor Green
|
||||||
383
build.sh
Executable file
383
build.sh
Executable file
@@ -0,0 +1,383 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ============================================================
|
||||||
|
# Usage:
|
||||||
|
# ./build.sh # full build (NDK + Java + APK + install)
|
||||||
|
# ./build.sh --no-cpp # skip NDK rebuild (Java/assets changed)
|
||||||
|
# ./build.sh --no-java # skip Java recompile (C++ changed only)
|
||||||
|
# ./build.sh --no-build # repackage + install only (no recompile)
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# lets be strict cuz we are safe like that
|
||||||
|
# *thanos snap*
|
||||||
|
set -euo pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# configuration
|
||||||
|
########################################
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$SCRIPT_DIR"
|
||||||
|
|
||||||
|
# build output directory (similar to apkbuild in the PS script)
|
||||||
|
# maybe doing this in build.ps1 would be cleaner, than putting the apkbuild in C:
|
||||||
|
BUILD_DIR="$REPO_ROOT/build-apk"
|
||||||
|
|
||||||
|
# default Android/NDK/SDK paths (can be overridden by env vars)
|
||||||
|
ANDROID_NDK_PATH="${ANDROID_NDK_PATH:-$HOME/android-ndk-r14b}"
|
||||||
|
ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-$HOME/Android/Sdk}}"
|
||||||
|
ANDROID_BUILD_TOOLS_VERSION="${ANDROID_BUILD_TOOLS_VERSION:-}"
|
||||||
|
ANDROID_PLATFORM_API="${ANDROID_PLATFORM_API:-}"
|
||||||
|
|
||||||
|
function fail() {
|
||||||
|
echo "ERROR: $1" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function find_build_tools_dir() {
|
||||||
|
if [[ -n "$ANDROID_BUILD_TOOLS_VERSION" ]]; then
|
||||||
|
local candidate="$ANDROID_SDK_ROOT/build-tools/$ANDROID_BUILD_TOOLS_VERSION"
|
||||||
|
[[ -d "$candidate" ]] && echo "$candidate" && return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "$ANDROID_SDK_ROOT/build-tools" ]]; then
|
||||||
|
fail "Android build-tools not found under $ANDROID_SDK_ROOT/build-tools. Set ANDROID_SDK_ROOT or install Android SDK build-tools."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# picking the highest build tools version because its the easiest way rn
|
||||||
|
# i guess if it breaks then fuck you
|
||||||
|
local best
|
||||||
|
best=$(ls -1 "$ANDROID_SDK_ROOT/build-tools" | sort -V | tail -n 1)
|
||||||
|
[[ -n "$best" && -d "$ANDROID_SDK_ROOT/build-tools/$best" ]] || \
|
||||||
|
fail "No Android build-tools versions found under $ANDROID_SDK_ROOT/build-tools."
|
||||||
|
echo "$ANDROID_SDK_ROOT/build-tools/$best"
|
||||||
|
}
|
||||||
|
|
||||||
|
function find_android_platform_dir() {
|
||||||
|
if [[ -n "$ANDROID_PLATFORM_API" ]]; then
|
||||||
|
local candidate="$ANDROID_SDK_ROOT/platforms/android-$ANDROID_PLATFORM_API"
|
||||||
|
[[ -d "$candidate" ]] && echo "$candidate" && return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "$ANDROID_SDK_ROOT/platforms" ]]; then
|
||||||
|
fail "Android platforms not found under $ANDROID_SDK_ROOT/platforms. Install an Android platform."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# pick the highest api level installed for now
|
||||||
|
# ideally we should be able to build to any api level, but lets keep it simple for now and
|
||||||
|
# just pick the highest one available
|
||||||
|
local best
|
||||||
|
best=$(ls -1 "$ANDROID_SDK_ROOT/platforms" | grep -E '^android-[0-9]+' | sed 's/android-//' | sort -n | tail -n 1)
|
||||||
|
[[ -n "$best" ]] || fail "No Android platforms found under $ANDROID_SDK_ROOT/platforms."
|
||||||
|
echo "$ANDROID_SDK_ROOT/platforms/android-$best"
|
||||||
|
}
|
||||||
|
|
||||||
|
ANDROID_BUILD_TOOLS_DIR="$(find_build_tools_dir)"
|
||||||
|
ANDROID_PLATFORM_DIR="$(find_android_platform_dir)"
|
||||||
|
|
||||||
|
KEYSTORE_FILE="$BUILD_DIR/debug.keystore"
|
||||||
|
PACKAGE_NAME="com.mojang.minecraftpe"
|
||||||
|
|
||||||
|
# android tool binaries
|
||||||
|
AAPT="$ANDROID_BUILD_TOOLS_DIR/aapt"
|
||||||
|
ZIPALIGN="$ANDROID_BUILD_TOOLS_DIR/zipalign"
|
||||||
|
APKSIGNER="$ANDROID_BUILD_TOOLS_DIR/apksigner"
|
||||||
|
DEX_TOOL="$ANDROID_BUILD_TOOLS_DIR/d8"
|
||||||
|
ADB="${ADB:-$ANDROID_SDK_ROOT/platform-tools/adb}"
|
||||||
|
|
||||||
|
# java tool binaries
|
||||||
|
JAVA_HOME_DEFAULT="${JAVA_HOME:-}" # may be empty
|
||||||
|
|
||||||
|
# prefer javac from the jdk;
|
||||||
|
# on some systems /usr/lib/jvm/default points to a JRE only.
|
||||||
|
# If javac is missing, try to locate a JDK installation.
|
||||||
|
JAVAC_CMD=""
|
||||||
|
if command -v javac >/dev/null 2>&1; then
|
||||||
|
JAVAC_CMD="$(command -v javac)"
|
||||||
|
elif [[ -n "$JAVA_HOME_DEFAULT" && -x "$JAVA_HOME_DEFAULT/bin/javac" ]]; then
|
||||||
|
JAVAC_CMD="$JAVA_HOME_DEFAULT/bin/javac"
|
||||||
|
elif [[ -x "/usr/lib/jvm/java-8-openjdk/bin/javac" ]]; then
|
||||||
|
JAVAC_CMD="/usr/lib/jvm/java-8-openjdk/bin/javac"
|
||||||
|
elif [[ -x "/usr/lib/jvm/default/bin/javac" ]]; then
|
||||||
|
JAVAC_CMD="/usr/lib/jvm/default/bin/javac"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$JAVAC_CMD" ]]; then
|
||||||
|
fail "javac not found; install a JDK and ensure javac is on PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
KEYTOOL="" # will be detected later
|
||||||
|
|
||||||
|
# swource directories
|
||||||
|
JNI_DIR="$REPO_ROOT/project/android/jni"
|
||||||
|
JAVA_SRC_DIR="$REPO_ROOT/project/android_java/src"
|
||||||
|
ANDROID_MANIFEST="$REPO_ROOT/project/android_java/AndroidManifest.xml"
|
||||||
|
ANDROID_RES_DIR="$REPO_ROOT/project/android_java/res"
|
||||||
|
DATA_DIR="$REPO_ROOT/data"
|
||||||
|
|
||||||
|
# output files
|
||||||
|
APK_UNSIGNED="$BUILD_DIR/minecraftpe-unsigned.apk"
|
||||||
|
APK_ALIGNED="$BUILD_DIR/minecraftpe-aligned.apk"
|
||||||
|
APK_SIGNED="$BUILD_DIR/minecraftpe-debug.apk"
|
||||||
|
DEX_OUTPUT="$BUILD_DIR/classes.dex"
|
||||||
|
|
||||||
|
# flags parsed from CLI args
|
||||||
|
NO_CPP=false
|
||||||
|
NO_JAVA=false
|
||||||
|
NO_BUILD=false
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# helpers
|
||||||
|
########################################
|
||||||
|
function usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $0 [--no-cpp] [--no-java] [--no-build]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--no-cpp Skip the NDK (C++) build step
|
||||||
|
--no-java Skip the Java build step
|
||||||
|
--no-build Skip the compile steps; just package + install
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function log_step() {
|
||||||
|
echo -e "\n==> $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function fail() {
|
||||||
|
echo "ERROR: $1" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function require_cmd() {
|
||||||
|
if ! command -v "$1" >/dev/null 2>&1; then
|
||||||
|
fail "$1 not found; install it (e.g. 'sudo pacman -S $1')"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ensure required tools are available early
|
||||||
|
require_cmd zip
|
||||||
|
require_cmd unzip
|
||||||
|
|
||||||
|
function ensure_dir() {
|
||||||
|
mkdir -p "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function find_keytool() {
|
||||||
|
# first try JAVA_HOME if set
|
||||||
|
if [[ -n "$JAVA_HOME_DEFAULT" && -x "$JAVA_HOME_DEFAULT/bin/keytool" ]]; then
|
||||||
|
echo "$JAVA_HOME_DEFAULT/bin/keytool"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# try common install locations
|
||||||
|
if [[ -n "${JAVA_HOME:-}" && -x "${JAVA_HOME}/bin/keytool" ]]; then
|
||||||
|
echo "${JAVA_HOME}/bin/keytool"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v keytool >/dev/null 2>&1; then
|
||||||
|
command -v keytool
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
fail "keytool not found. Set JAVA_HOME or install a JDK."
|
||||||
|
}
|
||||||
|
|
||||||
|
function write_stub_file() {
|
||||||
|
local rel_path="$1"
|
||||||
|
local content="$2"
|
||||||
|
local full_path="$BUILD_DIR/stubs/$rel_path"
|
||||||
|
|
||||||
|
ensure_dir "$(dirname "$full_path")"
|
||||||
|
if [[ ! -f "$full_path" ]]; then
|
||||||
|
echo -e "$content" > "$full_path"
|
||||||
|
echo " stub: $rel_path"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# argument parsing
|
||||||
|
########################################
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--no-cpp) NO_CPP=true ;;
|
||||||
|
--no-java) NO_JAVA=true ;;
|
||||||
|
--no-build) NO_BUILD=true ;;
|
||||||
|
-h|--help) usage ;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1" >&2
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# validate required tools
|
||||||
|
########################################
|
||||||
|
KEYTOOL="$(find_keytool)"
|
||||||
|
|
||||||
|
if [[ ! -x "$AAPT" ]]; then
|
||||||
|
fail "aapt not found at $AAPT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -x "$ZIPALIGN" ]]; then
|
||||||
|
fail "zipalign not found at $ZIPALIGN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -x "$APKSIGNER" ]]; then
|
||||||
|
fail "apksigner not found at $APKSIGNER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -x "$DEX_TOOL" ]]; then
|
||||||
|
fail "d8 not found at $DEX_TOOL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -x "$ADB" ]]; then
|
||||||
|
fail "adb not found at $ADB"
|
||||||
|
fi
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# bootstrap
|
||||||
|
########################################
|
||||||
|
log_step "Bootstrap"
|
||||||
|
|
||||||
|
ensure_dir "$BUILD_DIR"
|
||||||
|
ensure_dir "$BUILD_DIR/lib/arm64-v8a"
|
||||||
|
ensure_dir "$BUILD_DIR/gen"
|
||||||
|
ensure_dir "$BUILD_DIR/stubs"
|
||||||
|
|
||||||
|
# create a debug keystore if it doesn't exist
|
||||||
|
if [[ ! -f "$KEYSTORE_FILE" ]]; then
|
||||||
|
echo " generating debug.keystore..."
|
||||||
|
"$KEYTOOL" -genkeypair \
|
||||||
|
-keystore "$KEYSTORE_FILE" -storepass android -keypass android \
|
||||||
|
-alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 \
|
||||||
|
-dname "CN=Android Debug,O=Android,C=US" >/dev/null 2>&1
|
||||||
|
echo " keystore created"
|
||||||
|
else
|
||||||
|
echo " keystore OK"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# why dont we just include the stubs lol
|
||||||
|
write_stub_file "com/mojang/android/StringValue.java" "package com.mojang.android;\npublic interface StringValue { String getStringValue(); }\n"
|
||||||
|
|
||||||
|
write_stub_file "com/mojang/android/licensing/LicenseCodes.java" "package com.mojang.android.licensing;\npublic class LicenseCodes { public static final int LICENSE_OK = 0; }\n"
|
||||||
|
|
||||||
|
write_stub_file "com/mojang/android/EditTextAscii.java" "package com.mojang.android;\nimport android.content.Context;\nimport android.text.Editable;\nimport android.text.TextWatcher;\nimport android.util.AttributeSet;\nimport android.widget.EditText;\npublic class EditTextAscii extends EditText implements TextWatcher {\n public EditTextAscii(Context c) { super(c); addTextChangedListener(this); }\n public EditTextAscii(Context c, AttributeSet a) { super(c,a); addTextChangedListener(this); }\n public EditTextAscii(Context c, AttributeSet a, int d) { super(c,a,d); addTextChangedListener(this); }\n @Override public void onTextChanged(CharSequence s,int st,int b,int co){}\n public void beforeTextChanged(CharSequence s,int st,int co,int aft){}\n public void afterTextChanged(Editable e){\n String s=e.toString(),san=sanitize(s);\n if(!s.equals(san))e.replace(0,e.length(),san);\n }\n static public String sanitize(String s){\n StringBuilder sb=new StringBuilder();\n for(int i=0;i<s.length();i++){char c=s.charAt(i);if(c<128)sb.append(c);}\n return sb.toString();\n }\n}\n"
|
||||||
|
|
||||||
|
write_stub_file "com/mojang/android/preferences/SliderPreference.java" "package com.mojang.android.preferences;\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.preference.DialogPreference;\nimport android.util.AttributeSet;\nimport android.view.Gravity;\nimport android.view.View;\nimport android.widget.LinearLayout;\nimport android.widget.SeekBar;\nimport android.widget.TextView;\npublic class SliderPreference extends DialogPreference implements SeekBar.OnSeekBarChangeListener {\n private static final String NS=\"http://schemas.android.com/apk/res/android\";\n private Context _ctx; private TextView _tv; private SeekBar _sb;\n private String _suf; private int _def,_max,_val,_min;\n public SliderPreference(Context ctx,AttributeSet a){\n super(ctx,a); _ctx=ctx;\n _suf=gStr(a,NS,\"text\",\"\"); _def=gInt(a,NS,\"defaultValue\",0);\n _max=gInt(a,NS,\"max\",100); _min=gInt(a,null,\"min\",0);\n setDefaultValue(_def);\n }\n @Override protected View onCreateDialogView(){\n LinearLayout l=new LinearLayout(_ctx); l.setOrientation(LinearLayout.VERTICAL); l.setPadding(6,6,6,6);\n _tv=new TextView(_ctx); _tv.setGravity(Gravity.CENTER_HORIZONTAL); _tv.setTextSize(32);\n l.addView(_tv,new LinearLayout.LayoutParams(-1,-2));\n _sb=new SeekBar(_ctx); _sb.setOnSeekBarChangeListener(this);\n l.addView(_sb,new LinearLayout.LayoutParams(-1,-2));\n if(shouldPersist())_val=getPersistedInt(_def);\n _sb.setMax(_max); _sb.setProgress(_val); return l;\n }\n @Override protected void onSetInitialValue(boolean r,Object d){\n super.onSetInitialValue(r,d);\n _val=r?(shouldPersist()?getPersistedInt(_def):0):(Integer)d;\n }\n public void onProgressChanged(SeekBar s,int v,boolean f){\n _val=v+_min; _tv.setText(_val+_suf);\n if(shouldPersist())persistInt(_val); callChangeListener(Integer.valueOf(_val));\n }\n public void onStartTrackingTouch(SeekBar s){}\n public void onStopTrackingTouch(SeekBar s){}\n private int gInt(AttributeSet a,String ns,String n,int d){int id=a.getAttributeResourceValue(ns,n,0);return id!=0?getContext().getResources().getInteger(id):a.getAttributeIntValue(ns,n,d);}\n private String gStr(AttributeSet a,String ns,String n,String d){int id=a.getAttributeResourceValue(ns,n,0);if(id!=0)return getContext().getResources().getString(id);String v=a.getAttributeValue(ns,n);return v!=null?v:d;}\n}\n"
|
||||||
|
|
||||||
|
write_stub_file "com/mojang/minecraftpe/MainMenuOptionsActivity.java" "package com.mojang.minecraftpe;\nimport android.app.Activity;\npublic class MainMenuOptionsActivity extends Activity {\n public static final String Internal_Game_DifficultyPeaceful=\"internal_game_difficulty_peaceful\";\n public static final String Game_DifficultyLevel=\"game_difficulty\";\n public static final String Controls_Sensitivity=\"controls_sensitivity\";\n}\n"
|
||||||
|
|
||||||
|
write_stub_file "com/mojang/minecraftpe/Minecraft_Market.java" "package com.mojang.minecraftpe;\nimport android.app.Activity; import android.content.Intent; import android.os.Bundle;\npublic class Minecraft_Market extends Activity {\n @Override protected void onCreate(Bundle s){super.onCreate(s);startActivity(new Intent(this,MainActivity.class));finish();}\n}\n"
|
||||||
|
|
||||||
|
write_stub_file "com/mojang/minecraftpe/Minecraft_Market_Demo.java" "package com.mojang.minecraftpe;\nimport android.content.Intent; import android.net.Uri;\npublic class Minecraft_Market_Demo extends MainActivity {\n @Override public void buyGame(){startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse(\"market://details?id=com.mojang.minecraftpe\")));}\n @Override protected boolean isDemo(){return true;}\n}\n"
|
||||||
|
|
||||||
|
write_stub_file "com/mojang/minecraftpe/GameModeButton.java" "package com.mojang.minecraftpe;\nimport com.mojang.android.StringValue;\nimport android.content.Context; import android.util.AttributeSet;\nimport android.view.View; import android.view.View.OnClickListener;\nimport android.widget.TextView; import android.widget.ToggleButton;\npublic class GameModeButton extends ToggleButton implements OnClickListener,StringValue {\n static final int Creative=0,Survival=1;\n private int _type=0; private boolean _attached=false;\n public GameModeButton(Context c,AttributeSet a){super(c,a);setOnClickListener(this);}\n public void onClick(View v){_update();}\n @Override protected void onFinishInflate(){super.onFinishInflate();_update();}\n @Override protected void onAttachedToWindow(){if(!_attached){_update();_attached=true;}}\n private void _update(){_set(isChecked()?Survival:Creative);}\n private void _set(int i){\n _type=i<Creative?Creative:(i>Survival?Survival:i);\n int id=_type==Survival?R.string.gamemode_survival_summary:R.string.gamemode_creative_summary;\n String desc=getContext().getString(id);\n View v=getRootView().findViewById(R.id.labelGameModeDesc);\n if(desc!=null&&v instanceof TextView)((TextView)v).setText(desc);\n }\n public String getStringValue(){return new String[]{\"creative\",\"survival\"}[_type];}\n static public String getStringForType(int i){int c=i<Creative?Creative:(i>Survival?Survival:i);return new String[]{\"creative\",\"survival\"}[c];}\n}\n"
|
||||||
|
|
||||||
|
echo " stubs OK"
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# ndk build
|
||||||
|
########################################
|
||||||
|
if [[ "$NO_CPP" == false && "$NO_BUILD" == false ]]; then
|
||||||
|
log_step "NDK build (arm64-v8a)"
|
||||||
|
|
||||||
|
# the original windows build script used a junction to avoid long paths here
|
||||||
|
# on linux, path lengths are *usually* fine, but we still keep things simple
|
||||||
|
pushd "$JNI_DIR" >/dev/null
|
||||||
|
|
||||||
|
export NDK_MODULE_PATH="$REPO_ROOT/project/lib_projects"
|
||||||
|
|
||||||
|
# run ndk-build and show output in case of failure
|
||||||
|
if ! "$ANDROID_NDK_PATH/ndk-build" NDK_PROJECT_PATH="$REPO_ROOT/project/android" APP_BUILD_SCRIPT="$JNI_DIR/Android.mk" 2>&1 | tee "$BUILD_DIR/ndk-build.log"; then
|
||||||
|
echo "NDK build failed. See $BUILD_DIR/ndk-build.log" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
popd >/dev/null
|
||||||
|
|
||||||
|
# copy the compiled library to the APK staging folder
|
||||||
|
cp -v "$REPO_ROOT/project/android/libs/arm64-v8a/libminecraftpe.so" "$BUILD_DIR/lib/arm64-v8a/"
|
||||||
|
|
||||||
|
echo " .so -> $BUILD_DIR/lib/arm64-v8a/libminecraftpe.so"
|
||||||
|
fi
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# java compile
|
||||||
|
########################################
|
||||||
|
if [[ "$NO_JAVA" == false && "$NO_BUILD" == false ]]; then
|
||||||
|
log_step "Java compile"
|
||||||
|
|
||||||
|
ensure_dir "$(dirname "$BUILD_DIR/gen/R.java")"
|
||||||
|
|
||||||
|
# generate R.java
|
||||||
|
"$AAPT" package -f -M "$ANDROID_MANIFEST" -S "$ANDROID_RES_DIR" -I "$ANDROID_PLATFORM_DIR/android.jar" -J "$BUILD_DIR/gen" -F "$BUILD_DIR/_rgen.apk"
|
||||||
|
rm -f "$BUILD_DIR/_rgen.apk"
|
||||||
|
|
||||||
|
# collect all source files (project + stubs + generated R.java)
|
||||||
|
JAVA_SOURCES=(
|
||||||
|
$(find "$JAVA_SRC_DIR" -name "*.java" -print)
|
||||||
|
$(find "$BUILD_DIR/stubs" -name "*.java" -print)
|
||||||
|
"$BUILD_DIR/gen/R.java"
|
||||||
|
)
|
||||||
|
|
||||||
|
rm -rf "$BUILD_DIR/classes"
|
||||||
|
ensure_dir "$BUILD_DIR/classes"
|
||||||
|
|
||||||
|
# Some JDK versions (<=8) don’t support --release.
|
||||||
|
JAVAC_ARGS=(--release 8)
|
||||||
|
if "$JAVAC_CMD" -version 2>&1 | grep -qE '^javac 1\.'; then
|
||||||
|
JAVAC_ARGS=(-source 1.8 -target 1.8)
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$JAVAC_CMD" "${JAVAC_ARGS[@]}" -cp "$ANDROID_PLATFORM_DIR/android.jar" -d "$BUILD_DIR/classes" "${JAVA_SOURCES[@]}"
|
||||||
|
echo " javac OK"
|
||||||
|
|
||||||
|
# convert class files into dex
|
||||||
|
JAVA_CLASS_FILES=( $(find "$BUILD_DIR/classes" -name "*.class" -print) )
|
||||||
|
"$DEX_TOOL" --min-api 21 --output "$BUILD_DIR" "${JAVA_CLASS_FILES[@]}"
|
||||||
|
echo " d8 -> $DEX_OUTPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# package apk
|
||||||
|
########################################
|
||||||
|
log_step "Package APK"
|
||||||
|
|
||||||
|
rm -f "$APK_UNSIGNED" "$APK_ALIGNED" "$APK_SIGNED"
|
||||||
|
|
||||||
|
"$AAPT" package -f -M "$ANDROID_MANIFEST" -S "$ANDROID_RES_DIR" -I "$ANDROID_PLATFORM_DIR/android.jar" -F "$APK_UNSIGNED"
|
||||||
|
|
||||||
|
# add classes.dex and native library into apk
|
||||||
|
pushd "$BUILD_DIR" >/dev/null
|
||||||
|
zip -q "$APK_UNSIGNED" "classes.dex"
|
||||||
|
zip -q "$APK_UNSIGNED" "lib/arm64-v8a/libminecraftpe.so"
|
||||||
|
popd >/dev/null
|
||||||
|
|
||||||
|
# add assets from data/ directory into the apk under assets/
|
||||||
|
TMP_ASSETS_DIR="$(mktemp -d)"
|
||||||
|
mkdir -p "$TMP_ASSETS_DIR/assets"
|
||||||
|
cp -r "$DATA_DIR/." "$TMP_ASSETS_DIR/assets/"
|
||||||
|
pushd "$TMP_ASSETS_DIR" >/dev/null
|
||||||
|
zip -q -r "$APK_UNSIGNED" assets
|
||||||
|
popd >/dev/null
|
||||||
|
rm -rf "$TMP_ASSETS_DIR"
|
||||||
|
|
||||||
|
"$ZIPALIGN" -p 4 "$APK_UNSIGNED" "$APK_ALIGNED"
|
||||||
|
"$APKSIGNER" sign --ks "$KEYSTORE_FILE" --ks-pass pass:android --key-pass pass:android --out "$APK_SIGNED" "$APK_ALIGNED"
|
||||||
|
|
||||||
|
echo " signed -> $APK_SIGNED"
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# install
|
||||||
|
########################################
|
||||||
|
log_step "Install"
|
||||||
|
|
||||||
|
"$ADB" shell am force-stop "$PACKAGE_NAME" || true
|
||||||
|
"$ADB" uninstall "$PACKAGE_NAME" || true
|
||||||
|
"$ADB" install --no-incremental "$APK_SIGNED"
|
||||||
|
|
||||||
|
echo -e "\nDone. Enjoy MCPE 0.6.1 on your device!"
|
||||||
BIN
data/images/gui/logo/github.png
Normal file
BIN
data/images/gui/logo/github.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 111 KiB |
@@ -144,6 +144,17 @@ options.fov.max=Quake Pro
|
|||||||
options.gamma=Brightness
|
options.gamma=Brightness
|
||||||
options.gamma.min=Moody
|
options.gamma.min=Moody
|
||||||
options.gamma.max=Bright
|
options.gamma.max=Bright
|
||||||
|
options.group.mojang=Login
|
||||||
|
options.group.general=General
|
||||||
|
options.group.game=Game
|
||||||
|
options.group.controls=Controls
|
||||||
|
options.group.graphics=Graphics
|
||||||
|
options.group.tweaks=Tweaks
|
||||||
|
options.allowSprint=Allow sprint
|
||||||
|
options.barOnTop=HUD above inventory
|
||||||
|
options.autojump=Auto Jump
|
||||||
|
options.thirdperson=Third Person
|
||||||
|
options.servervisible=Server Visible
|
||||||
options.sensitivity=Sensitivity
|
options.sensitivity=Sensitivity
|
||||||
options.sensitivity.min=*yawn*
|
options.sensitivity.min=*yawn*
|
||||||
options.sensitivity.max=HYPERSPEED!!!
|
options.sensitivity.max=HYPERSPEED!!!
|
||||||
@@ -156,6 +167,8 @@ options.viewBobbing=View Bobbing
|
|||||||
options.ao=Smooth Lighting
|
options.ao=Smooth Lighting
|
||||||
options.anaglyph=3D Anaglyph
|
options.anaglyph=3D Anaglyph
|
||||||
options.framerateLimit=Performance
|
options.framerateLimit=Performance
|
||||||
|
options.limitFramerate=Limit Framerate
|
||||||
|
options.vsync=VSync
|
||||||
options.difficulty=Difficulty
|
options.difficulty=Difficulty
|
||||||
options.difficulty.peaceful=Peaceful
|
options.difficulty.peaceful=Peaceful
|
||||||
options.difficulty.easy=Easy
|
options.difficulty.easy=Easy
|
||||||
@@ -170,6 +183,7 @@ options.guiScale.auto=Auto
|
|||||||
options.guiScale.small=Small
|
options.guiScale.small=Small
|
||||||
options.guiScale.normal=Normal
|
options.guiScale.normal=Normal
|
||||||
options.guiScale.large=Large
|
options.guiScale.large=Large
|
||||||
|
options.guiScale.larger=Larger
|
||||||
options.advancedOpengl=Advanced OpenGL
|
options.advancedOpengl=Advanced OpenGL
|
||||||
options.renderClouds=Clouds
|
options.renderClouds=Clouds
|
||||||
options.farWarning1=A 64 bit Java installation is recommended
|
options.farWarning1=A 64 bit Java installation is recommended
|
||||||
@@ -178,6 +192,15 @@ options.particles=Particles
|
|||||||
options.particles.all=All
|
options.particles.all=All
|
||||||
options.particles.decreased=Decreased
|
options.particles.decreased=Decreased
|
||||||
options.particles.minimal=Minimal
|
options.particles.minimal=Minimal
|
||||||
|
options.username=Username
|
||||||
|
options.smoothCamera=Smooth camera
|
||||||
|
options.destroyVibration=Destroy vibration
|
||||||
|
options.isLeftHanded=Left handed
|
||||||
|
options.useTouchscreen=Use touchscreen
|
||||||
|
options.fancyGraphics=Fancy graphics
|
||||||
|
options.renderDebug=Debug render
|
||||||
|
options.anaglyph3d=3D anaglyph
|
||||||
|
|
||||||
|
|
||||||
performance.max=Max FPS
|
performance.max=Max FPS
|
||||||
performance.balanced=Balanced
|
performance.balanced=Balanced
|
||||||
@@ -185,21 +208,21 @@ performance.powersaver=Power saver
|
|||||||
|
|
||||||
controls.title=Controls
|
controls.title=Controls
|
||||||
|
|
||||||
key.forward=Forward
|
options.key.forward=Forward
|
||||||
key.left=Left
|
options.key.left=Left
|
||||||
key.back=Back
|
options.key.back=Back
|
||||||
key.right=Right
|
options.key.right=Right
|
||||||
key.jump=Jump
|
options.key.jump=Jump
|
||||||
key.inventory=Inventory
|
options.key.inventory=Inventory
|
||||||
key.drop=Drop
|
options.key.drop=Drop
|
||||||
key.chat=Chat
|
options.key.chat=Chat
|
||||||
key.fog=Toggle Fog
|
options.key.fog=Toggle Fog
|
||||||
key.sneak=Sneak
|
options.key.sneak=Sneak
|
||||||
key.playerlist=List Players
|
options.key.playerlist=List Players
|
||||||
key.attack=Attack
|
options.key.attack=Attack
|
||||||
key.use=Use Item
|
options.key.use=Use Item
|
||||||
key.pickItem=Pick Block
|
options.key.pickItem=Pick Block
|
||||||
key.mouseButton=Button %1$s
|
options.key.mouseButton=Button %1$s
|
||||||
|
|
||||||
texturePack.openFolder=Open texture pack folder
|
texturePack.openFolder=Open texture pack folder
|
||||||
texturePack.title=Select Texture Pack
|
texturePack.title=Select Texture Pack
|
||||||
|
|||||||
0
glad/include/KHR/khrplatform.h
Executable file → Normal file
0
glad/include/KHR/khrplatform.h
Executable file → Normal file
2941
glad/include/glad/glad.h
Executable file → Normal file
2941
glad/include/glad/glad.h
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
1393
glad/src/glad.c
Executable file → Normal file
1393
glad/src/glad.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
143
misc/web/index.html
Normal file
143
misc/web/index.html
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-us">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>Emscripten-Generated Code</title>
|
||||||
|
<style>
|
||||||
|
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||||
|
textarea.emscripten { font-family: monospace; width: 80%; }
|
||||||
|
div.emscripten { text-align: center; }
|
||||||
|
div.emscripten_border { border: 1px solid black; }
|
||||||
|
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
|
||||||
|
canvas.emscripten { border: 0px none; background-color: black; }
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
margin: 0px auto;
|
||||||
|
-webkit-animation: rotation .8s linear infinite;
|
||||||
|
-moz-animation: rotation .8s linear infinite;
|
||||||
|
-o-animation: rotation .8s linear infinite;
|
||||||
|
animation: rotation 0.8s linear infinite;
|
||||||
|
border-left: 10px solid rgb(0,150,240);
|
||||||
|
border-right: 10px solid rgb(0,150,240);
|
||||||
|
border-bottom: 10px solid rgb(0,150,240);
|
||||||
|
border-top: 10px solid rgb(100,0,200);
|
||||||
|
border-radius: 100%;
|
||||||
|
background-color: rgb(200,100,250);
|
||||||
|
}
|
||||||
|
@-webkit-keyframes rotation {
|
||||||
|
from {-webkit-transform: rotate(0deg);}
|
||||||
|
to {-webkit-transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
@-moz-keyframes rotation {
|
||||||
|
from {-moz-transform: rotate(0deg);}
|
||||||
|
to {-moz-transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
@-o-keyframes rotation {
|
||||||
|
from {-o-transform: rotate(0deg);}
|
||||||
|
to {-o-transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
@keyframes rotation {
|
||||||
|
from {transform: rotate(0deg);}
|
||||||
|
to {transform: rotate(360deg);}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<hr/>
|
||||||
|
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>emscripten</strong></center></figure>
|
||||||
|
<div class="emscripten" id="status">Downloading...</div>
|
||||||
|
<div class="emscripten">
|
||||||
|
<progress value="0" max="100" id="progress" hidden=1></progress>
|
||||||
|
</div>
|
||||||
|
<div class="emscripten_border">
|
||||||
|
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
<div class="emscripten">
|
||||||
|
<input type="checkbox" id="resize">Resize canvas
|
||||||
|
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
|
||||||
|
|
||||||
|
<input type="button" value="Fullscreen" onclick="Module.requestFullscreen(document.getElementById('pointerLock').checked,
|
||||||
|
document.getElementById('resize').checked)">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
<textarea class="emscripten" id="output" rows="8"></textarea>
|
||||||
|
<hr>
|
||||||
|
<script type='text/javascript'>
|
||||||
|
var statusElement = document.getElementById('status');
|
||||||
|
var progressElement = document.getElementById('progress');
|
||||||
|
var spinnerElement = document.getElementById('spinner');
|
||||||
|
var canvasElement = document.getElementById('canvas');
|
||||||
|
var outputElement = document.getElementById('output');
|
||||||
|
if (outputElement) outputElement.value = ''; // clear browser cache
|
||||||
|
|
||||||
|
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
||||||
|
// application robust, you may want to override this behavior before shipping!
|
||||||
|
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
|
||||||
|
canvasElement.addEventListener("webglcontextlost", (e) => {
|
||||||
|
alert('WebGL context lost. You will need to reload the page.');
|
||||||
|
e.preventDefault();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
function setStatus(text) {
|
||||||
|
if (!setStatus.last) setStatus.last = { time: Date.now(), text: '' };
|
||||||
|
if (text === setStatus.last.text) return;
|
||||||
|
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
||||||
|
var now = Date.now();
|
||||||
|
if (m && now - setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon
|
||||||
|
setStatus.last.time = now;
|
||||||
|
setStatus.last.text = text;
|
||||||
|
if (m) {
|
||||||
|
text = m[1];
|
||||||
|
progressElement.value = parseInt(m[2])*100;
|
||||||
|
progressElement.max = parseInt(m[4])*100;
|
||||||
|
progressElement.hidden = false;
|
||||||
|
spinnerElement.hidden = false;
|
||||||
|
} else {
|
||||||
|
progressElement.value = null;
|
||||||
|
progressElement.max = null;
|
||||||
|
progressElement.hidden = true;
|
||||||
|
if (!text) spinnerElement.hidden = true;
|
||||||
|
}
|
||||||
|
statusElement.innerHTML = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
var Module = {
|
||||||
|
print(...args) {
|
||||||
|
// These replacements are necessary if you render to raw HTML
|
||||||
|
//text = text.replace(/&/g, "&");
|
||||||
|
//text = text.replace(/</g, "<");
|
||||||
|
//text = text.replace(/>/g, ">");
|
||||||
|
//text = text.replace('\n', '<br>', 'g');
|
||||||
|
console.log(...args);
|
||||||
|
if (outputElement) {
|
||||||
|
var text = args.join(' ');
|
||||||
|
outputElement.value += text + "\n";
|
||||||
|
outputElement.scrollTop = outputElement.scrollHeight; // focus on bottom
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canvas: canvasElement,
|
||||||
|
setStatus: setStatus,
|
||||||
|
totalDependencies: 0,
|
||||||
|
monitorRunDependencies(left) {
|
||||||
|
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||||
|
setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setStatus('Downloading...');
|
||||||
|
window.onerror = () => {
|
||||||
|
setStatus('Exception thrown, see JavaScript console');
|
||||||
|
spinnerElement.style.display = 'none';
|
||||||
|
setStatus = (text) => {
|
||||||
|
if (text) console.error('[post-exception status] ' + text);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="MinecraftPE.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.mojang.minecraftpe"
|
package="com.mojang.minecraftpe"
|
||||||
android:versionCode="6006"
|
android:versionCode="6010"
|
||||||
android:versionName="0.6.0"
|
android:versionName="0.6.1-alpha-0.0.3"
|
||||||
android:installLocation="preferExternal">
|
android:installLocation="preferExternal">
|
||||||
|
|
||||||
<!-- This is the platform API where NativeActivity was introduced. -->
|
<!-- This is the platform API where NativeActivity was introduced. -->
|
||||||
<uses-sdk android:minSdkVersion="9"
|
<uses-sdk android:minSdkVersion="24"
|
||||||
android:targetSdkVersion="9" />
|
android:targetSdkVersion="24" />
|
||||||
|
|
||||||
<!-- uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="true"/ -->
|
<!-- uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="true"/ -->
|
||||||
|
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ options.guiScale.auto=Auto
|
|||||||
options.guiScale.small=Small
|
options.guiScale.small=Small
|
||||||
options.guiScale.normal=Normal
|
options.guiScale.normal=Normal
|
||||||
options.guiScale.large=Large
|
options.guiScale.large=Large
|
||||||
|
options.guiScale.larger=Larger
|
||||||
options.advancedOpengl=Advanced OpenGL
|
options.advancedOpengl=Advanced OpenGL
|
||||||
options.renderClouds=Clouds
|
options.renderClouds=Clouds
|
||||||
options.farWarning1=A 64 bit Java installation is recommended
|
options.farWarning1=A 64 bit Java installation is recommended
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
# Convert Windows backslashes to forward slashes so NDK toolchain doesn’t treat them as escapes.
|
||||||
|
LOCAL_PATH := $(subst \,/,$(LOCAL_PATH))
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_MODULE := minecraftpe
|
LOCAL_MODULE := minecraftpe
|
||||||
LOCAL_SRC_FILES := ../../../src/main.cpp \
|
LOCAL_SRC_FILES := ../../../src/main.cpp \
|
||||||
../../../src/main_android.cpp \
|
../../../src/main_android_java.cpp \
|
||||||
../../../src/platform/audio/SoundSystemSL.cpp \
|
../../../src/platform/audio/SoundSystemSL.cpp \
|
||||||
../../../src/platform/input/Controller.cpp \
|
../../../src/platform/input/Controller.cpp \
|
||||||
../../../src/platform/input/Keyboard.cpp \
|
../../../src/platform/input/Keyboard.cpp \
|
||||||
@@ -12,6 +14,7 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
|
|||||||
../../../src/platform/input/Multitouch.cpp \
|
../../../src/platform/input/Multitouch.cpp \
|
||||||
../../../src/platform/time.cpp \
|
../../../src/platform/time.cpp \
|
||||||
../../../src/platform/CThread.cpp \
|
../../../src/platform/CThread.cpp \
|
||||||
|
../../../src/platform/HttpClient.cpp \
|
||||||
../../../src/NinecraftApp.cpp \
|
../../../src/NinecraftApp.cpp \
|
||||||
../../../src/Performance.cpp \
|
../../../src/Performance.cpp \
|
||||||
../../../src/SharedConstants.cpp \
|
../../../src/SharedConstants.cpp \
|
||||||
@@ -21,6 +24,7 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
|
|||||||
../../../src/client/Options.cpp \
|
../../../src/client/Options.cpp \
|
||||||
../../../src/client/OptionsFile.cpp \
|
../../../src/client/OptionsFile.cpp \
|
||||||
../../../src/client/OptionStrings.cpp \
|
../../../src/client/OptionStrings.cpp \
|
||||||
|
../../../src/client/Option.cpp \
|
||||||
../../../src/client/gamemode/GameMode.cpp \
|
../../../src/client/gamemode/GameMode.cpp \
|
||||||
../../../src/client/gamemode/CreativeMode.cpp \
|
../../../src/client/gamemode/CreativeMode.cpp \
|
||||||
../../../src/client/gamemode/SurvivalMode.cpp \
|
../../../src/client/gamemode/SurvivalMode.cpp \
|
||||||
@@ -34,13 +38,14 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
|
|||||||
../../../src/client/gui/components/NinePatch.cpp \
|
../../../src/client/gui/components/NinePatch.cpp \
|
||||||
../../../src/client/gui/components/OptionsGroup.cpp \
|
../../../src/client/gui/components/OptionsGroup.cpp \
|
||||||
../../../src/client/gui/components/OptionsItem.cpp \
|
../../../src/client/gui/components/OptionsItem.cpp \
|
||||||
../../../src/client/gui/components/OptionsPane.cpp \
|
../../../src/client/gui/components/KeyOption.cpp \
|
||||||
|
../../../src/client/gui/components/TextOption.cpp \
|
||||||
../../../src/client/gui/components/RolledSelectionListH.cpp \
|
../../../src/client/gui/components/RolledSelectionListH.cpp \
|
||||||
../../../src/client/gui/components/RolledSelectionListV.cpp \
|
../../../src/client/gui/components/RolledSelectionListV.cpp \
|
||||||
../../../src/client/gui/components/ScrolledSelectionList.cpp \
|
../../../src/client/gui/components/ScrolledSelectionList.cpp \
|
||||||
../../../src/client/gui/components/ScrollingPane.cpp \
|
../../../src/client/gui/components/ScrollingPane.cpp \
|
||||||
../../../src/client/gui/components/Slider.cpp \
|
../../../src/client/gui/components/Slider.cpp \
|
||||||
../../../src/client/gui/components/SmallButton.cpp \
|
../../../src/client/gui/components/TextBox.cpp \
|
||||||
../../../src/client/gui/Font.cpp \
|
../../../src/client/gui/Font.cpp \
|
||||||
../../../src/client/gui/Gui.cpp \
|
../../../src/client/gui/Gui.cpp \
|
||||||
../../../src/client/gui/GuiComponent.cpp \
|
../../../src/client/gui/GuiComponent.cpp \
|
||||||
@@ -48,6 +53,10 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
|
|||||||
../../../src/client/gui/screens/ScreenChooser.cpp \
|
../../../src/client/gui/screens/ScreenChooser.cpp \
|
||||||
../../../src/client/gui/screens/ArmorScreen.cpp \
|
../../../src/client/gui/screens/ArmorScreen.cpp \
|
||||||
../../../src/client/gui/screens/ChatScreen.cpp \
|
../../../src/client/gui/screens/ChatScreen.cpp \
|
||||||
|
../../../src/client/gui/screens/ChooseLevelScreen.cpp \
|
||||||
|
../../../src/client/gui/screens/SimpleChooseLevelScreen.cpp \
|
||||||
|
../../../src/client/gui/screens/ConsoleScreen.cpp \
|
||||||
|
../../../src/client/gui/screens/UsernameScreen.cpp \
|
||||||
../../../src/client/gui/screens/ConfirmScreen.cpp \
|
../../../src/client/gui/screens/ConfirmScreen.cpp \
|
||||||
../../../src/client/gui/screens/ChestScreen.cpp \
|
../../../src/client/gui/screens/ChestScreen.cpp \
|
||||||
../../../src/client/gui/screens/DeathScreen.cpp \
|
../../../src/client/gui/screens/DeathScreen.cpp \
|
||||||
@@ -56,12 +65,14 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
|
|||||||
../../../src/client/gui/screens/IngameBlockSelectionScreen.cpp \
|
../../../src/client/gui/screens/IngameBlockSelectionScreen.cpp \
|
||||||
../../../src/client/gui/screens/JoinGameScreen.cpp \
|
../../../src/client/gui/screens/JoinGameScreen.cpp \
|
||||||
../../../src/client/gui/screens/OptionsScreen.cpp \
|
../../../src/client/gui/screens/OptionsScreen.cpp \
|
||||||
|
../../../src/client/gui/screens/CreditsScreen.cpp \
|
||||||
../../../src/client/gui/screens/PauseScreen.cpp \
|
../../../src/client/gui/screens/PauseScreen.cpp \
|
||||||
../../../src/client/gui/screens/ProgressScreen.cpp \
|
../../../src/client/gui/screens/ProgressScreen.cpp \
|
||||||
../../../src/client/gui/screens/RenameMPLevelScreen.cpp \
|
../../../src/client/gui/screens/RenameMPLevelScreen.cpp \
|
||||||
../../../src/client/gui/screens/SelectWorldScreen.cpp \
|
../../../src/client/gui/screens/SelectWorldScreen.cpp \
|
||||||
../../../src/client/gui/screens/StartMenuScreen.cpp \
|
../../../src/client/gui/screens/StartMenuScreen.cpp \
|
||||||
../../../src/client/gui/screens/TextEditScreen.cpp \
|
../../../src/client/gui/screens/TextEditScreen.cpp \
|
||||||
|
../../../src/client/gui/screens/JoinByIPScreen.cpp \
|
||||||
../../../src/client/gui/screens/touch/TouchIngameBlockSelectionScreen.cpp \
|
../../../src/client/gui/screens/touch/TouchIngameBlockSelectionScreen.cpp \
|
||||||
../../../src/client/gui/screens/touch/TouchJoinGameScreen.cpp \
|
../../../src/client/gui/screens/touch/TouchJoinGameScreen.cpp \
|
||||||
../../../src/client/gui/screens/touch/TouchSelectWorldScreen.cpp \
|
../../../src/client/gui/screens/touch/TouchSelectWorldScreen.cpp \
|
||||||
@@ -245,7 +256,10 @@ LOCAL_SRC_FILES := ../../../src/main.cpp \
|
|||||||
../../../src/world/level/tile/entity/FurnaceTileEntity.cpp \
|
../../../src/world/level/tile/entity/FurnaceTileEntity.cpp \
|
||||||
../../../src/world/phys/HitResult.cpp
|
../../../src/world/phys/HitResult.cpp
|
||||||
|
|
||||||
LOCAL_CFLAGS := -Wno-psabi $(LOCAL_CFLAGS)
|
LOCAL_CFLAGS := -DPLATFORM_ANDROID -DPRE_ANDROID23 -Wno-narrowing $(LOCAL_CFLAGS)
|
||||||
|
LOCAL_CPPFLAGS := -std=c++14 -frtti
|
||||||
|
LOCAL_CPPFLAGS += -frtti
|
||||||
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../src
|
||||||
|
|
||||||
#LOCAL_CFLAGS := -DANDROID_PUBLISH -DDEMO_MODE $(LOCAL_CFLAGS)
|
#LOCAL_CFLAGS := -DANDROID_PUBLISH -DDEMO_MODE $(LOCAL_CFLAGS)
|
||||||
#LOCAL_CFLAGS := -DANDROID_PUBLISH $(LOCAL_CFLAGS)
|
#LOCAL_CFLAGS := -DANDROID_PUBLISH $(LOCAL_CFLAGS)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
APP_PLATFORM := android-9
|
APP_PLATFORM := android-21
|
||||||
APP_STL := stlport_static
|
APP_STL := gnustl_static
|
||||||
APP_OPTIM := release
|
APP_OPTIM := release
|
||||||
APP_ABI := armeabi-v7a
|
APP_ABI := arm64-v8a
|
||||||
|
APP_SHORT_COMMANDS := true
|
||||||
|
APP_CPPFLAGS += -frtti -fexceptions
|
||||||
#APP_ABI := armeabi-v7a x86
|
#APP_ABI := armeabi-v7a x86
|
||||||
|
|||||||
@@ -468,17 +468,16 @@ public class MainActivity extends NativeActivity {
|
|||||||
|
|
||||||
_userInputStatus = 1;
|
_userInputStatus = 1;
|
||||||
InputMethodManager inputManager = (InputMethodManager)getSystemService("input_method");
|
InputMethodManager inputManager = (InputMethodManager)getSystemService("input_method");
|
||||||
boolean result = inputManager.showSoftInput(this.getCurrentFocus(), InputMethodManager.SHOW_IMPLICIT);
|
View focused = this.getCurrentFocus();
|
||||||
|
if (focused != null) {
|
||||||
|
boolean result = inputManager.showSoftInput(focused, InputMethodManager.SHOW_IMPLICIT);
|
||||||
|
} else {
|
||||||
|
// fallback: try to show using decor view token
|
||||||
|
View decor = getWindow().getDecorView();
|
||||||
|
if (decor != null) {
|
||||||
|
inputManager.showSoftInput(decor, InputMethodManager.SHOW_IMPLICIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onStart() {
|
|
||||||
//System.out.println("onStart");
|
|
||||||
super.onStart();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onResume() {
|
|
||||||
//System.out.println("onResume");
|
|
||||||
super.onResume();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
|
|||||||
@@ -1,30 +1,39 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.mojang.minecraftpe"
|
package="com.mojang.minecraftpe"
|
||||||
android:versionCode="4000"
|
android:versionCode="6010"
|
||||||
android:versionName="0.4.0"
|
android:versionName="0.6.1-alpha-0.0.3">
|
||||||
>
|
|
||||||
<!-- android:installLocation="preferExternal" -->
|
|
||||||
|
|
||||||
<uses-sdk android:targetSdkVersion="8" android:minSdkVersion="7"/>
|
<uses-sdk
|
||||||
|
android:minSdkVersion="24"
|
||||||
|
android:targetSdkVersion="28"/>
|
||||||
|
|
||||||
<uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="true"/>
|
<uses-feature
|
||||||
|
android:name="android.hardware.touchscreen.multitouch"
|
||||||
|
android:required="true"/>
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||||
|
|
||||||
<application android:icon="@drawable/icon"
|
<application
|
||||||
|
android:icon="@drawable/icon"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
>
|
android:hardwareAccelerated="true"
|
||||||
|
android:extractNativeLibs="true"
|
||||||
|
android:requestLegacyExternalStorage="true">
|
||||||
|
|
||||||
<activity android:name="com.mojang.minecraftpe.Minecraft_Market"
|
<activity
|
||||||
|
android:name="com.mojang.minecraftpe.Minecraft_Market"
|
||||||
android:label="@string/app_name_short"
|
android:label="@string/app_name_short"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden|screenSize|uiMode"
|
||||||
android:screenOrientation="landscape"
|
android:screenOrientation="landscape"
|
||||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||||
|
android:exported="true">
|
||||||
|
|
||||||
<meta-data android:name="android.app.lib_name"
|
<meta-data
|
||||||
|
android:name="android.app.lib_name"
|
||||||
android:value="minecraftpe"/>
|
android:value="minecraftpe"/>
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@@ -32,13 +41,34 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="com.mojang.minecraftpe.MainMenuOptionsActivity"></activity>
|
|
||||||
|
|
||||||
<meta-data android:name="xperiaplayoptimized_content" android:resource="@string/xperiaplayoptimized_content" />
|
<activity
|
||||||
<meta-data android:name="game_display_name" android:resource="@string/app_name" />
|
android:name="com.mojang.minecraftpe.MainActivity"
|
||||||
<meta-data android:name="game_icon" android:resource="@drawable/iconx" />
|
android:configChanges="orientation|keyboardHidden|screenSize|uiMode"
|
||||||
|
android:screenOrientation="landscape"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||||
|
android:exported="false"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.mojang.minecraftpe.MainMenuOptionsActivity"
|
||||||
|
android:exported="false"/>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="xperiaplayoptimized_content"
|
||||||
|
android:resource="@string/xperiaplayoptimized_content"/>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="game_display_name"
|
||||||
|
android:resource="@string/app_name"/>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="game_icon"
|
||||||
|
android:resource="@drawable/iconx"/>
|
||||||
|
|
||||||
|
<uses-library
|
||||||
|
android:name="xperiaplaycertified"
|
||||||
|
android:required="false"/>
|
||||||
|
|
||||||
<uses-library android:name="xperiaplaycertified" android:required="false"/>
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -31,6 +31,8 @@ import android.content.Intent;
|
|||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Build;
|
||||||
import android.graphics.Bitmap.CompressFormat;
|
import android.graphics.Bitmap.CompressFormat;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
@@ -40,7 +42,6 @@ import android.os.Vibrator;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Display;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
@@ -55,9 +56,12 @@ import com.mojang.minecraftpe.sound.SoundPlayer;
|
|||||||
|
|
||||||
public class MainActivity extends Activity {
|
public class MainActivity extends Activity {
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
|
private static final int PERMISSION_REQUEST_CODE = 123;
|
||||||
|
|
||||||
private GLView _glView;
|
private GLView _glView;
|
||||||
public float invScale = 1.0f;// / 1.5f;
|
public float invScale = 1.0f;// / 1.5f;
|
||||||
|
private int _screenWidth = 0;
|
||||||
|
private int _screenHeight = 0;
|
||||||
|
|
||||||
Vector<MotionEvent> _touchEvents = new Vector<MotionEvent>();
|
Vector<MotionEvent> _touchEvents = new Vector<MotionEvent>();
|
||||||
Vector<KeyEvent> _keyEvents = new Vector<KeyEvent>();
|
Vector<KeyEvent> _keyEvents = new Vector<KeyEvent>();
|
||||||
@@ -68,7 +72,12 @@ public class MainActivity extends Activity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
nativeRegisterThis();
|
nativeRegisterThis();
|
||||||
|
|
||||||
nativeOnCreate();
|
// Cache screen dimensions once to avoid re-entrant getDisplayMetrics() callbacks
|
||||||
|
android.util.DisplayMetrics _dm = getResources().getDisplayMetrics();
|
||||||
|
_screenWidth = Math.max(_dm.widthPixels, _dm.heightPixels);
|
||||||
|
_screenHeight = Math.min(_dm.widthPixels, _dm.heightPixels);
|
||||||
|
|
||||||
|
nativeOnCreate(_screenWidth, _screenHeight);
|
||||||
|
|
||||||
_glView = new GLView(getApplication(), this);
|
_glView = new GLView(getApplication(), this);
|
||||||
//_glView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
|
//_glView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
|
||||||
@@ -102,19 +111,69 @@ public class MainActivity extends Activity {
|
|||||||
setContentView(_glView);
|
setContentView(_glView);
|
||||||
|
|
||||||
_soundPlayer = new SoundPlayer(this, AudioManager.STREAM_MUSIC);
|
_soundPlayer = new SoundPlayer(this, AudioManager.STREAM_MUSIC);
|
||||||
|
|
||||||
|
// request dangerous permissions at runtime if necessary
|
||||||
|
checkAndRequestPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAndRequestPermissions() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
boolean needRequest = false;
|
||||||
|
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
needRequest = true;
|
||||||
|
}
|
||||||
|
if (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
needRequest = true;
|
||||||
|
}
|
||||||
|
if (needRequest) {
|
||||||
|
requestPermissions(new String[] {
|
||||||
|
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
|
android.Manifest.permission.READ_EXTERNAL_STORAGE
|
||||||
|
}, PERMISSION_REQUEST_CODE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||||
|
if (requestCode == PERMISSION_REQUEST_CODE) {
|
||||||
|
boolean granted = true;
|
||||||
|
for (int r : grantResults) {
|
||||||
|
if (r != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
granted = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!granted) {
|
||||||
|
// user denied; you might want to warn or close the app
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
// method required by native code to detect touchscreen support
|
||||||
|
public boolean supportsTouchscreen() {
|
||||||
|
return true; // all devices using this build are touch-capable
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTouchscreen() { return true; }
|
|
||||||
static public boolean isXperiaPlay() { return false; }
|
static public boolean isXperiaPlay() { return false; }
|
||||||
|
|
||||||
static private boolean _isPowerVr = false;
|
static private boolean _isPowerVr = false;
|
||||||
public void setIsPowerVR(boolean status) { MainActivity._isPowerVr = status; }
|
public void setIsPowerVR(boolean status) { MainActivity._isPowerVr = status; }
|
||||||
static public boolean isPowerVR() { return _isPowerVr; }
|
static public boolean isPowerVR() { return _isPowerVr; }
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public void vibrate(int milliSeconds) {
|
public void vibrate(int milliSeconds) {
|
||||||
Vibrator v = (Vibrator)this.getSystemService(VIBRATOR_SERVICE);
|
Vibrator v = (Vibrator) getSystemService(VIBRATOR_SERVICE);
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= 26) {
|
||||||
|
v.vibrate(android.os.VibrationEffect.createOneShot(milliSeconds,
|
||||||
|
android.os.VibrationEffect.DEFAULT_AMPLITUDE));
|
||||||
|
} else {
|
||||||
v.vibrate(milliSeconds);
|
v.vibrate(milliSeconds);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createAlertDialog(boolean hasOkButton, boolean hasCancelButton, boolean preventBackKey) {
|
private void createAlertDialog(boolean hasOkButton, boolean hasCancelButton, boolean preventBackKey) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
@@ -144,9 +203,16 @@ public class MainActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWindowFocusChanged(boolean hasFocus) {
|
public void onWindowFocusChanged(boolean hasFocus) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
//System.out.println("Focus has changed. Has Focus? " + hasFocus);
|
|
||||||
super.onWindowFocusChanged(hasFocus);
|
super.onWindowFocusChanged(hasFocus);
|
||||||
|
if (hasFocus) {
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(
|
||||||
|
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||||
|
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||||
|
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||||
|
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
|
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||||
|
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -184,9 +250,12 @@ public class MainActivity extends Activity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.getAction() == KeyEvent.ACTION_DOWN)
|
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
nativeOnKeyDown(keyCode);
|
nativeOnKeyDown(keyCode);
|
||||||
else if (event.getAction() == KeyEvent.ACTION_UP)
|
int unicodeChar = event.getUnicodeChar(event.getMetaState());
|
||||||
|
if (unicodeChar > 0)
|
||||||
|
nativeTextChar(unicodeChar);
|
||||||
|
} else if (event.getAction() == KeyEvent.ACTION_UP)
|
||||||
nativeOnKeyUp(keyCode);
|
nativeOnKeyUp(keyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,22 +416,15 @@ public class MainActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getScreenWidth() {
|
public int getScreenWidth() {
|
||||||
Display display = ((WindowManager)this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
return _screenWidth;
|
||||||
int out = Math.max(display.getWidth(), display.getHeight());
|
|
||||||
//System.out.println("getwidth: " + out);
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getScreenHeight() {
|
public int getScreenHeight() {
|
||||||
Display display = ((WindowManager)this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
return _screenHeight;
|
||||||
int out = Math.min(display.getWidth(), display.getHeight());
|
|
||||||
//System.out.println("getheight: " + out);
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getPixelsPerMillimeter() {
|
public float getPixelsPerMillimeter() {
|
||||||
DisplayMetrics metrics = new DisplayMetrics();
|
android.util.DisplayMetrics metrics = getResources().getDisplayMetrics();
|
||||||
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
|
||||||
return (metrics.xdpi + metrics.ydpi) * 0.5f / 25.4f;
|
return (metrics.xdpi + metrics.ydpi) * 0.5f / 25.4f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,8 +527,8 @@ public class MainActivity extends Activity {
|
|||||||
|
|
||||||
MainActivity.this.mDialog.show();
|
MainActivity.this.mDialog.show();
|
||||||
MainActivity.this.mDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
MainActivity.this.mDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
MainActivity.this.mDialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
MainActivity.this.mDialog.getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||||
//MainActivity.this.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
//MainActivity.this.getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -516,6 +578,20 @@ public class MainActivity extends Activity {
|
|||||||
|
|
||||||
public void buyGame() {}
|
public void buyGame() {}
|
||||||
|
|
||||||
|
public int getKeyFromKeyCode(int keyCode, int metaState, int deviceId) {
|
||||||
|
android.view.KeyCharacterMap kcm = android.view.KeyCharacterMap.load(deviceId);
|
||||||
|
return kcm.get(keyCode, metaState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openURL(String url) {
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, android.net.Uri.parse(url));
|
||||||
|
startActivity(intent);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getPlatformStringVar(int id) {
|
public String getPlatformStringVar(int id) {
|
||||||
if (id == 0) return android.os.Build.MODEL;
|
if (id == 0) return android.os.Build.MODEL;
|
||||||
return null;
|
return null;
|
||||||
@@ -604,10 +680,11 @@ public class MainActivity extends Activity {
|
|||||||
//
|
//
|
||||||
native void nativeRegisterThis();
|
native void nativeRegisterThis();
|
||||||
native void nativeUnregisterThis();
|
native void nativeUnregisterThis();
|
||||||
native static void nativeOnCreate();
|
native static void nativeOnCreate(int screenWidth, int screenHeight);
|
||||||
native static void nativeOnDestroy();
|
native static void nativeOnDestroy();
|
||||||
native static void nativeOnKeyDown(int key);
|
native static void nativeOnKeyDown(int key);
|
||||||
native static void nativeOnKeyUp(int key);
|
native static void nativeOnKeyUp(int key);
|
||||||
|
native static void nativeTextChar(int unicodeChar);
|
||||||
native static boolean nativeHandleBack(boolean isDown);
|
native static boolean nativeHandleBack(boolean isDown);
|
||||||
native static void nativeMouseDown(int pointerId, int buttonId, float x, float y);
|
native static void nativeMouseDown(int pointerId, int buttonId, float x, float y);
|
||||||
native static void nativeMouseUp(int pointerId, int buttonId, float x, float y);
|
native static void nativeMouseUp(int pointerId, int buttonId, float x, float y);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.7)
|
cmake_minimum_required(VERSION 3.5.0)
|
||||||
find_package (Threads)
|
find_package (Threads)
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/../lib_projects/raknet/jni/RaknetSources")
|
include_directories("${PROJECT_SOURCE_DIR}/../lib_projects/raknet/jni/RaknetSources")
|
||||||
add_subdirectory("${PROJECT_SOURCE_DIR}/../lib_projects/raknet/jni" "${CMAKE_CURRENT_BINARY_DIR}/raknet")
|
add_subdirectory("${PROJECT_SOURCE_DIR}/../lib_projects/raknet/jni" "${CMAKE_CURRENT_BINARY_DIR}/raknet")
|
||||||
@@ -19,6 +19,7 @@ set(CompileFiles ../../src/main.cpp
|
|||||||
../../src/client/IConfigListener.cpp
|
../../src/client/IConfigListener.cpp
|
||||||
../../src/client/Minecraft.cpp
|
../../src/client/Minecraft.cpp
|
||||||
../../src/client/Options.cpp
|
../../src/client/Options.cpp
|
||||||
|
../../src/client/Option.cpp
|
||||||
../../src/client/OptionsFile.cpp
|
../../src/client/OptionsFile.cpp
|
||||||
../../src/client/OptionStrings.cpp
|
../../src/client/OptionStrings.cpp
|
||||||
../../src/client/gamemode/GameMode.cpp
|
../../src/client/gamemode/GameMode.cpp
|
||||||
@@ -151,6 +152,9 @@ set(CompileFiles ../../src/main.cpp
|
|||||||
../../src/world/level/tile/entity/TileEntity.cpp
|
../../src/world/level/tile/entity/TileEntity.cpp
|
||||||
../../src/world/level/tile/entity/FurnaceTileEntity.cpp
|
../../src/world/level/tile/entity/FurnaceTileEntity.cpp
|
||||||
../../src/world/phys/HitResult.cpp)
|
../../src/world/phys/HitResult.cpp)
|
||||||
message(${CMAKE_LIBRARY_ARCHITECTURE})
|
|
||||||
add_executable(mcpe_server ${CompileFiles})
|
add_executable(mcpe_server ${CompileFiles})
|
||||||
target_link_libraries(mcpe_server raknet ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(mcpe_server raknet ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
target_include_directories(mcpe_server PUBLIC
|
||||||
|
"../../src/"
|
||||||
|
)
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ include $(CLEAR_VARS)
|
|||||||
|
|
||||||
LOCAL_MODULE := RakNet
|
LOCAL_MODULE := RakNet
|
||||||
|
|
||||||
MY_PREFIX := $(LOCAL_PATH)/RakNetSources/
|
MY_PREFIX := $(LOCAL_PATH)/RaknetSources/
|
||||||
MY_SOURCES := $(wildcard $(MY_PREFIX)*.cpp)
|
MY_SOURCES := $(wildcard $(MY_PREFIX)*.cpp)
|
||||||
LOCAL_SRC_FILES += $(MY_SOURCES:$(MY_PREFIX)%=RakNetSources/%)
|
LOCAL_SRC_FILES += $(MY_SOURCES:$(MY_PREFIX)%=RaknetSources/%)
|
||||||
|
|
||||||
LOCAL_CFLAGS := -Wno-psabi $(LOCAL_CFLAGS)
|
LOCAL_CFLAGS := -Wno-psabi $(LOCAL_CFLAGS)
|
||||||
|
LOCAL_CPPFLAGS += -frtti
|
||||||
|
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|||||||
@@ -5,13 +5,13 @@
|
|||||||
#include <stdio.h> // RAKNET_DEBUG_PRINTF
|
#include <stdio.h> // RAKNET_DEBUG_PRINTF
|
||||||
#include "RakAssert.h"
|
#include "RakAssert.h"
|
||||||
#if defined(ANDROID)
|
#if defined(ANDROID)
|
||||||
#include <asm/io.h>
|
// <asm/io.h> not needed and unavailable on arm64
|
||||||
#elif defined(_WIN32) || defined(__CYGWIN__)
|
#elif defined(_WIN32) || defined(__CYGWIN__)
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
|
|
||||||
#elif !defined ( __APPLE__ ) && !defined ( __APPLE_CC__ ) && !defined ( __PPC__ ) && !defined ( __FreeBSD__ ) && !defined ( __S3E__ )
|
// #elif !defined ( __APPLE__ ) && !defined ( __APPLE_CC__ ) && !defined ( __PPC__ ) && !defined ( __FreeBSD__ ) && !defined ( __S3E__ )
|
||||||
#include <sys/io.h>
|
// #include <sys/io.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ static const unsigned int MAX_OFFLINE_DATA_LENGTH=400; // I set this because I l
|
|||||||
#pragma warning(disable:4309) // 'initializing' : truncation of constant value
|
#pragma warning(disable:4309) // 'initializing' : truncation of constant value
|
||||||
#endif
|
#endif
|
||||||
// Make sure highest bit is 0, so isValid in DatagramHeaderFormat is false
|
// Make sure highest bit is 0, so isValid in DatagramHeaderFormat is false
|
||||||
static const char OFFLINE_MESSAGE_DATA_ID[16]={0x00,0xFF,0xFF,0x00,0xFE,0xFE,0xFE,0xFE,0xFD,0xFD,0xFD,0xFD,0x12,0x34,0x56,0x78};
|
static const unsigned char OFFLINE_MESSAGE_DATA_ID[16]={0x00,0xFF,0xFF,0x00,0xFE,0xFE,0xFE,0xFE,0xFD,0xFD,0xFD,0xFD,0x12,0x34,0x56,0x78};
|
||||||
|
|
||||||
struct PacketFollowedByData
|
struct PacketFollowedByData
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ public:
|
|||||||
|
|
||||||
virtual void saveScreenshot(const std::string& filename, int glWidth, int glHeight) {}
|
virtual void saveScreenshot(const std::string& filename, int glWidth, int glHeight) {}
|
||||||
virtual TextureData loadTexture(const std::string& filename_, bool textureFolder) { return TextureData(); }
|
virtual TextureData loadTexture(const std::string& filename_, bool textureFolder) { return TextureData(); }
|
||||||
|
virtual TextureData loadTextureFromMemory(const unsigned char* data, size_t size) { return TextureData(); }
|
||||||
|
|
||||||
virtual void playSound(const std::string& fn, float volume, float pitch) {}
|
virtual void playSound(const std::string& fn, float volume, float pitch) {}
|
||||||
|
|
||||||
@@ -96,9 +97,6 @@ public:
|
|||||||
virtual std::string getDateString(int s) { return ""; }
|
virtual std::string getDateString(int s) { return ""; }
|
||||||
//virtual void createUserInputScreen(const char* types) {}
|
//virtual void createUserInputScreen(const char* types) {}
|
||||||
|
|
||||||
virtual int checkLicense() { return 0; }
|
|
||||||
virtual bool hasBuyButtonWhenInvalidLicense() { return false; }
|
|
||||||
|
|
||||||
virtual void uploadPlatformDependentData(int id, void* data) {}
|
virtual void uploadPlatformDependentData(int id, void* data) {}
|
||||||
virtual BinaryBlob readAssetFile(const std::string& filename) { return BinaryBlob(); }
|
virtual BinaryBlob readAssetFile(const std::string& filename) { return BinaryBlob(); }
|
||||||
virtual void _tick() {}
|
virtual void _tick() {}
|
||||||
@@ -117,7 +115,7 @@ public:
|
|||||||
virtual bool isSuperFast() = 0;
|
virtual bool isSuperFast() = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual void buyGame() {}
|
virtual void openURL(const std::string& url) {}
|
||||||
|
|
||||||
virtual void finish() {}
|
virtual void finish() {}
|
||||||
|
|
||||||
|
|||||||
@@ -68,9 +68,6 @@ public:
|
|||||||
|
|
||||||
_methodGetDateString(0),
|
_methodGetDateString(0),
|
||||||
|
|
||||||
_methodCheckLicense(0),
|
|
||||||
_methodHasBuyButton(0),
|
|
||||||
_methodBuyGame(0),
|
|
||||||
_methodVibrate(0),
|
_methodVibrate(0),
|
||||||
_methodSupportsTouchscreen(0),
|
_methodSupportsTouchscreen(0),
|
||||||
_methodSetIsPowerVR(0),
|
_methodSetIsPowerVR(0),
|
||||||
@@ -104,6 +101,7 @@ public:
|
|||||||
|
|
||||||
int getScreenWidth() { return _screenWidth; }
|
int getScreenWidth() { return _screenWidth; }
|
||||||
int getScreenHeight() { return _screenHeight; }
|
int getScreenHeight() { return _screenHeight; }
|
||||||
|
void setScreenDimensions(int w, int h) { _screenWidth = w; _screenHeight = h; }
|
||||||
|
|
||||||
// Note, this has to be called from the main thread (e.g. do it from JNI_onLoad)
|
// Note, this has to be called from the main thread (e.g. do it from JNI_onLoad)
|
||||||
// Somewhere between calling this, and calling the AppPlatform methods,
|
// Somewhere between calling this, and calling the AppPlatform methods,
|
||||||
@@ -146,10 +144,6 @@ public:
|
|||||||
|
|
||||||
_methodGetDateString = env->GetMethodID( _activityClass, "getDateString", "(I)Ljava/lang/String;");
|
_methodGetDateString = env->GetMethodID( _activityClass, "getDateString", "(I)Ljava/lang/String;");
|
||||||
|
|
||||||
_methodCheckLicense = env->GetMethodID( _activityClass, "checkLicense", "()I");
|
|
||||||
_methodHasBuyButton = env->GetMethodID( _activityClass, "hasBuyButtonWhenInvalidLicense", "()Z");
|
|
||||||
_methodBuyGame = env->GetMethodID( _activityClass, "buyGame", "()V");
|
|
||||||
|
|
||||||
_methodVibrate = env->GetMethodID( _activityClass, "vibrate", "(I)V");
|
_methodVibrate = env->GetMethodID( _activityClass, "vibrate", "(I)V");
|
||||||
_methodSupportsTouchscreen = env->GetMethodID( _activityClass, "supportsTouchscreen", "()Z");
|
_methodSupportsTouchscreen = env->GetMethodID( _activityClass, "supportsTouchscreen", "()Z");
|
||||||
_methodSetIsPowerVR = env->GetMethodID( _activityClass, "setIsPowerVR", "(Z)V");
|
_methodSetIsPowerVR = env->GetMethodID( _activityClass, "setIsPowerVR", "(Z)V");
|
||||||
@@ -157,6 +151,8 @@ public:
|
|||||||
|
|
||||||
_methodGetPixelsPerMillimeter = env->GetMethodID( _activityClass, "getPixelsPerMillimeter", "()F");
|
_methodGetPixelsPerMillimeter = env->GetMethodID( _activityClass, "getPixelsPerMillimeter", "()F");
|
||||||
_methodGetPlatformStringVar = env->GetMethodID( _activityClass, "getPlatformStringVar", "(I)Ljava/lang/String;");
|
_methodGetPlatformStringVar = env->GetMethodID( _activityClass, "getPlatformStringVar", "(I)Ljava/lang/String;");
|
||||||
|
// custom helper to launch external URLs
|
||||||
|
_methodOpenURL = env->GetMethodID(_activityClass, "openURL", "(Ljava/lang/String;)V");
|
||||||
|
|
||||||
_classWindow = (jclass)env->NewGlobalRef(env->FindClass("android/view/Window"));
|
_classWindow = (jclass)env->NewGlobalRef(env->FindClass("android/view/Window"));
|
||||||
_classContext = (jclass)env->NewGlobalRef(env->FindClass("android/content/Context"));
|
_classContext = (jclass)env->NewGlobalRef(env->FindClass("android/content/Context"));
|
||||||
@@ -192,14 +188,20 @@ public:
|
|||||||
// be rewritten later on anyway
|
// be rewritten later on anyway
|
||||||
int initConsts() {
|
int initConsts() {
|
||||||
|
|
||||||
|
LOGI("initConsts: start\n");
|
||||||
JVMAttacher ta(_vm);
|
JVMAttacher ta(_vm);
|
||||||
JNIEnv* env = ta.getEnv();
|
JNIEnv* env = ta.getEnv();
|
||||||
|
|
||||||
|
LOGI("initConsts: getting method IDs\n");
|
||||||
jmethodID fWidth = env->GetMethodID( _activityClass, "getScreenWidth", "()I");
|
jmethodID fWidth = env->GetMethodID( _activityClass, "getScreenWidth", "()I");
|
||||||
|
LOGI("initConsts: got fWidth=%p\n", fWidth);
|
||||||
jmethodID fHeight = env->GetMethodID( _activityClass, "getScreenHeight", "()I");
|
jmethodID fHeight = env->GetMethodID( _activityClass, "getScreenHeight", "()I");
|
||||||
|
LOGI("initConsts: got fHeight=%p, calling getScreenWidth\n", fHeight);
|
||||||
|
|
||||||
_screenWidth = env->CallIntMethod(instance, fWidth);
|
_screenWidth = env->CallIntMethod(instance, fWidth);
|
||||||
|
LOGI("initConsts: screenWidth=%d, calling getScreenHeight\n", _screenWidth);
|
||||||
_screenHeight = env->CallIntMethod(instance, fHeight);
|
_screenHeight = env->CallIntMethod(instance, fHeight);
|
||||||
|
LOGI("initConsts: screenHeight=%d, done\n", _screenHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tick() {
|
void tick() {
|
||||||
@@ -376,8 +378,9 @@ public:
|
|||||||
JVMAttacher ta(_vm);
|
JVMAttacher ta(_vm);
|
||||||
JNIEnv* env = ta.getEnv();
|
JNIEnv* env = ta.getEnv();
|
||||||
|
|
||||||
|
std::string path = textureFolder ? "images/" + filename : filename;
|
||||||
jintArray arr = (jintArray)env->CallObjectMethod(
|
jintArray arr = (jintArray)env->CallObjectMethod(
|
||||||
instance, _getImageData, env->NewStringUTF(filename.c_str()));
|
instance, _getImageData, env->NewStringUTF(path.c_str()));
|
||||||
|
|
||||||
if (!arr)
|
if (!arr)
|
||||||
return TextureData();
|
return TextureData();
|
||||||
@@ -464,37 +467,15 @@ public:
|
|||||||
env->ReleaseStringUTFChars(stringVar, str);
|
env->ReleaseStringUTFChars(stringVar, str);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
// Opens a webpage using an Android intent. Called from native code.
|
||||||
int checkLicense() {
|
virtual void openURL(const std::string& url) {
|
||||||
if (!_isInited) return -2;
|
if (!_isInited || !_methodOpenURL) return;
|
||||||
if (!_methodCheckLicense) return -2;
|
|
||||||
|
|
||||||
JVMAttacher ta(_vm);
|
JVMAttacher ta(_vm);
|
||||||
JNIEnv* env = ta.getEnv();
|
JNIEnv* env = ta.getEnv();
|
||||||
|
jstring jurl = env->NewStringUTF(url.c_str());
|
||||||
return env->CallIntMethod(instance, _methodCheckLicense);
|
env->CallVoidMethod(instance, _methodOpenURL, jurl);
|
||||||
|
env->DeleteLocalRef(jurl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasBuyButtonWhenInvalidLicense() {
|
|
||||||
if (!_isInited) return false;
|
|
||||||
if (!_methodHasBuyButton) return false;
|
|
||||||
|
|
||||||
JVMAttacher ta(_vm);
|
|
||||||
JNIEnv* env = ta.getEnv();
|
|
||||||
|
|
||||||
return JNI_TRUE == env->CallBooleanMethod(instance, _methodHasBuyButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
void buyGame() {
|
|
||||||
if (!_isInited) return;
|
|
||||||
if (!_methodBuyGame) return;
|
|
||||||
|
|
||||||
JVMAttacher ta(_vm);
|
|
||||||
JNIEnv* env = ta.getEnv();
|
|
||||||
|
|
||||||
env->CallVoidMethod(instance, _methodBuyGame);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void finish() {
|
virtual void finish() {
|
||||||
if (!_isInited) return;
|
if (!_isInited) return;
|
||||||
if (!_methodFinish) return;
|
if (!_methodFinish) return;
|
||||||
@@ -636,10 +617,6 @@ private:
|
|||||||
|
|
||||||
jmethodID _methodGetDateString;
|
jmethodID _methodGetDateString;
|
||||||
|
|
||||||
jmethodID _methodCheckLicense;
|
|
||||||
jmethodID _methodHasBuyButton;
|
|
||||||
jmethodID _methodBuyGame;
|
|
||||||
|
|
||||||
jmethodID _getScreenWidth;
|
jmethodID _getScreenWidth;
|
||||||
jmethodID _getScreenHeight;
|
jmethodID _getScreenHeight;
|
||||||
jmethodID _methodGetPixelsPerMillimeter;
|
jmethodID _methodGetPixelsPerMillimeter;
|
||||||
@@ -649,6 +626,7 @@ private:
|
|||||||
jmethodID _methodIsNetworkEnabled;
|
jmethodID _methodIsNetworkEnabled;
|
||||||
|
|
||||||
jmethodID _methodGetPlatformStringVar;
|
jmethodID _methodGetPlatformStringVar;
|
||||||
|
jmethodID _methodOpenURL; // new JNI method for launching browser
|
||||||
|
|
||||||
jclass _classWindow;
|
jclass _classWindow;
|
||||||
jclass _classContext;
|
jclass _classContext;
|
||||||
|
|||||||
0
src/AppPlatform_glfw.cpp
Executable file → Normal file
0
src/AppPlatform_glfw.cpp
Executable file → Normal file
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "AppPlatform.h"
|
#include "AppPlatform.h"
|
||||||
#include "platform/log.h"
|
#include "platform/log.h"
|
||||||
|
#include "platform/HttpClient.h"
|
||||||
|
#include "platform/PngLoader.h"
|
||||||
#include "client/renderer/gles.h"
|
#include "client/renderer/gles.h"
|
||||||
#include "world/level/storage/FolderMethods.h"
|
#include "world/level/storage/FolderMethods.h"
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
@@ -10,6 +12,13 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <ctime>
|
||||||
|
#include "util/StringUtils.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <shellapi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static void png_funcReadFile(png_structp pngPtr, png_bytep data, png_size_t length) {
|
static void png_funcReadFile(png_structp pngPtr, png_bytep data, png_size_t length) {
|
||||||
((std::istream*)png_get_io_ptr(pngPtr))->read((char*)data, length);
|
((std::istream*)png_get_io_ptr(pngPtr))->read((char*)data, length);
|
||||||
@@ -22,7 +31,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryBlob readAssetFile(const std::string& filename) {
|
BinaryBlob readAssetFile(const std::string& filename) override {
|
||||||
FILE* fp = fopen(("data/" + filename).c_str(), "r");
|
FILE* fp = fopen(("data/" + filename).c_str(), "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return BinaryBlob();
|
return BinaryBlob();
|
||||||
@@ -39,7 +48,7 @@ public:
|
|||||||
return blob;
|
return blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveScreenshot(const std::string& filename, int glWidth, int glHeight) {
|
void saveScreenshot(const std::string& filename, int glWidth, int glHeight) override {
|
||||||
//@todo
|
//@todo
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,8 +56,17 @@ public:
|
|||||||
return (p & 0xff00ff00) | ((p >> 16) & 0xff) | ((p << 16) & 0xff0000);
|
return (p & 0xff00ff00) | ((p >> 16) & 0xff) | ((p << 16) & 0xff0000);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureData loadTexture(const std::string& filename_, bool textureFolder)
|
TextureData loadTexture(const std::string& filename_, bool textureFolder) override
|
||||||
{
|
{
|
||||||
|
// Support fetching PNG textures via HTTP/HTTPS (for skins, etc)
|
||||||
|
if (Util::startsWith(filename_, "http://") || Util::startsWith(filename_, "https://")) {
|
||||||
|
std::vector<unsigned char> body;
|
||||||
|
if (HttpClient::download(filename_, body) && !body.empty()) {
|
||||||
|
return loadTextureFromMemory(body.data(), body.size());
|
||||||
|
}
|
||||||
|
return TextureData();
|
||||||
|
}
|
||||||
|
|
||||||
TextureData out;
|
TextureData out;
|
||||||
|
|
||||||
std::string filename = textureFolder? "data/images/" + filename_
|
std::string filename = textureFolder? "data/images/" + filename_
|
||||||
@@ -101,29 +119,37 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getDateString(int s) {
|
TextureData loadTextureFromMemory(const unsigned char* data, size_t size) override {
|
||||||
std::stringstream ss;
|
return loadPngFromMemory(data, size);
|
||||||
ss << s << " s (UTC)";
|
|
||||||
return ss.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int checkLicense() {
|
virtual std::string getDateString(int s) override {
|
||||||
static int _z = 0;//20;
|
time_t tm = s;
|
||||||
_z--;
|
|
||||||
if (_z < 0) return 0;
|
char mbstr[100];
|
||||||
//if (_z < 0) return 107;
|
std::strftime(mbstr, sizeof(mbstr), "%F %T", std::localtime(&tm));
|
||||||
return -2;
|
|
||||||
|
return std::string(mbstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int getScreenWidth() { return 854; };
|
virtual int getScreenWidth() override { return 854; };
|
||||||
virtual int getScreenHeight() { return 480; };
|
virtual int getScreenHeight() override { return 480; };
|
||||||
|
|
||||||
virtual float getPixelsPerMillimeter();
|
virtual float getPixelsPerMillimeter() override;
|
||||||
|
|
||||||
virtual bool supportsTouchscreen() { return true; }
|
virtual bool supportsTouchscreen() override { return true; }
|
||||||
virtual bool hasBuyButtonWhenInvalidLicense() { return false; }
|
|
||||||
|
virtual void openURL(const std::string& url) override {
|
||||||
|
#ifdef _WIN32
|
||||||
|
ShellExecuteA(NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
#elif __linux__
|
||||||
|
std::string command = "xdg-open " + url;
|
||||||
|
system(command.c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWwindow* window;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*APPPLATFORM_GLFW_H__*/
|
#endif /*APPPLATFORM_GLFW_H__*/
|
||||||
|
|||||||
@@ -41,17 +41,6 @@ public:
|
|||||||
|
|
||||||
std::string getDateString(int s);
|
std::string getDateString(int s);
|
||||||
|
|
||||||
virtual int checkLicense() {
|
|
||||||
return 0;
|
|
||||||
static int _z = 20;
|
|
||||||
_z--;
|
|
||||||
if (_z < 0) return 0;
|
|
||||||
//if (_z < 0) return 107;
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void buyGame();
|
|
||||||
|
|
||||||
virtual int getScreenWidth();
|
virtual int getScreenWidth();
|
||||||
virtual int getScreenHeight();
|
virtual int getScreenHeight();
|
||||||
virtual float getPixelsPerMillimeter();
|
virtual float getPixelsPerMillimeter();
|
||||||
|
|||||||
@@ -175,10 +175,6 @@ BinaryBlob AppPlatform_iOS::readAssetFile(const std::string& filename_) {
|
|||||||
return BinaryBlob(bytes, numBytes);
|
return BinaryBlob(bytes, numBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppPlatform_iOS::buyGame() {
|
|
||||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=479516143&mt=8"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string AppPlatform_iOS::getDateString(int s) {
|
std::string AppPlatform_iOS::getDateString(int s) {
|
||||||
|
|
||||||
NSDate* date = [NSDate dateWithTimeIntervalSince1970:s];
|
NSDate* date = [NSDate dateWithTimeIntervalSince1970:s];
|
||||||
|
|||||||
@@ -14,4 +14,3 @@ float AppPlatform_win32::getPixelsPerMillimeter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AppPlatform_win32::supportsTouchscreen() { return true; }
|
bool AppPlatform_win32::supportsTouchscreen() { return true; }
|
||||||
bool AppPlatform_win32::hasBuyButtonWhenInvalidLicense() { return true; }
|
|
||||||
|
|||||||
@@ -3,12 +3,17 @@
|
|||||||
|
|
||||||
#include "AppPlatform.h"
|
#include "AppPlatform.h"
|
||||||
#include "platform/log.h"
|
#include "platform/log.h"
|
||||||
|
#include "platform/HttpClient.h"
|
||||||
|
#include "platform/PngLoader.h"
|
||||||
#include "client/renderer/gles.h"
|
#include "client/renderer/gles.h"
|
||||||
#include "world/level/storage/FolderMethods.h"
|
#include "world/level/storage/FolderMethods.h"
|
||||||
|
#include "util/StringUtils.h"
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <shellapi.h>
|
||||||
|
|
||||||
static void png_funcReadFile(png_structp pngPtr, png_bytep data, png_size_t length) {
|
static void png_funcReadFile(png_structp pngPtr, png_bytep data, png_size_t length) {
|
||||||
((std::istream*)png_get_io_ptr(pngPtr))->read((char*)data, length);
|
((std::istream*)png_get_io_ptr(pngPtr))->read((char*)data, length);
|
||||||
@@ -48,6 +53,15 @@ public:
|
|||||||
|
|
||||||
TextureData loadTexture(const std::string& filename_, bool textureFolder)
|
TextureData loadTexture(const std::string& filename_, bool textureFolder)
|
||||||
{
|
{
|
||||||
|
// Support fetching PNG textures via HTTP/HTTPS (for skins, etc).
|
||||||
|
if (Util::startsWith(filename_, "http://") || Util::startsWith(filename_, "https://")) {
|
||||||
|
std::vector<unsigned char> body;
|
||||||
|
if (HttpClient::download(filename_, body) && !body.empty()) {
|
||||||
|
return loadTextureFromMemory(body.data(), body.size());
|
||||||
|
}
|
||||||
|
return TextureData();
|
||||||
|
}
|
||||||
|
|
||||||
TextureData out;
|
TextureData out;
|
||||||
|
|
||||||
std::string filename = textureFolder? "data/images/" + filename_
|
std::string filename = textureFolder? "data/images/" + filename_
|
||||||
@@ -100,18 +114,15 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getDateString(int s) {
|
TextureData loadTextureFromMemory(const unsigned char* data, size_t size) override {
|
||||||
std::stringstream ss;
|
return loadPngFromMemory(data, size);
|
||||||
ss << s << " s (UTC)";
|
|
||||||
return ss.str();
|
|
||||||
}
|
}
|
||||||
|
time_t tm = s;
|
||||||
|
|
||||||
virtual int checkLicense() {
|
char mbstr[100];
|
||||||
static int _z = 0;//20;
|
std::strftime(mbstr, sizeof(mbstr), "%F %T", std::localtime(&tm));
|
||||||
_z--;
|
|
||||||
if (_z < 0) return 0;
|
return std::string(mbstr);
|
||||||
//if (_z < 0) return 107;
|
|
||||||
return -2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int getScreenWidth();
|
virtual int getScreenWidth();
|
||||||
@@ -120,7 +131,10 @@ public:
|
|||||||
virtual float getPixelsPerMillimeter();
|
virtual float getPixelsPerMillimeter();
|
||||||
|
|
||||||
virtual bool supportsTouchscreen();
|
virtual bool supportsTouchscreen();
|
||||||
virtual bool hasBuyButtonWhenInvalidLicense();
|
|
||||||
|
virtual void openURL(const std::string& url) {
|
||||||
|
ShellExecuteA(NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
//#include "world/level/storage/FolderMethods.h"
|
//#include "world/level/storage/FolderMethods.h"
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
#include "client/gui/screens/StartMenuScreen.h"
|
#include "client/gui/screens/StartMenuScreen.h"
|
||||||
|
#include "client/gui/screens/UsernameScreen.h"
|
||||||
#endif
|
#endif
|
||||||
#include "client/player/LocalPlayer.h"
|
#include "client/player/LocalPlayer.h"
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
@@ -110,8 +111,12 @@ void NinecraftApp::init()
|
|||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
LOGI("This: %p\n", this);
|
LOGI("This: %p\n", this);
|
||||||
screenChooser.setScreen(SCREEN_STARTMENU);
|
screenChooser.setScreen(SCREEN_STARTMENU);
|
||||||
|
|
||||||
|
if (options.getBooleanValue(OPTIONS_FIRST_LAUNCH)) {
|
||||||
|
options.toggle(OPTIONS_FIRST_LAUNCH);
|
||||||
|
setScreen(new UsernameScreen());
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
user->name = "Server";
|
|
||||||
hostMultiplayer();
|
hostMultiplayer();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -240,8 +245,9 @@ void NinecraftApp::initGLStates()
|
|||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
glEnable2(GL_TEXTURE_2D);
|
glEnable2(GL_TEXTURE_2D);
|
||||||
|
#ifndef _EMSCRIPTEN_
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||||
|
#endif
|
||||||
// Both updates isPowerVR flag in java and returns if the graphics chip is PowerVR SGX or not
|
// Both updates isPowerVR flag in java and returns if the graphics chip is PowerVR SGX or not
|
||||||
_powerVr = platform()->isPowerVR();
|
_powerVr = platform()->isPowerVR();
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|||||||
@@ -4,7 +4,13 @@ namespace Common {
|
|||||||
|
|
||||||
std::string getGameVersionString(const std::string& versionSuffix /* = "" */)
|
std::string getGameVersionString(const std::string& versionSuffix /* = "" */)
|
||||||
{
|
{
|
||||||
return std::string("v0.6.1") + versionSuffix + " alpha";
|
std::string result = std::string("v0.6.1") + versionSuffix;
|
||||||
|
// append 64-bit port marker only on Android 64‑bit targets
|
||||||
|
#if defined(ANDROID) && (defined(__aarch64__) || defined(__x86_64__))
|
||||||
|
result += " (64-bit port)";
|
||||||
|
#endif
|
||||||
|
result += " alpha";
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
#ifndef NET_MINECRAFT_CLIENT__KeyMapping_H__
|
|
||||||
#define NET_MINECRAFT_CLIENT__KeyMapping_H__
|
|
||||||
|
|
||||||
//package net.minecraft.client;
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class KeyMapping
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string name;
|
|
||||||
int key;
|
|
||||||
|
|
||||||
KeyMapping() {}
|
|
||||||
|
|
||||||
KeyMapping(const std::string& name_, int key_)
|
|
||||||
: name(name_),
|
|
||||||
key(key_)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT__KeyMapping_H__*/
|
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
#include "Minecraft.h"
|
#include "Minecraft.h"
|
||||||
|
#include "client/Options.h"
|
||||||
#include "client/player/input/IBuildInput.h"
|
#include "client/player/input/IBuildInput.h"
|
||||||
|
#include "platform/input/Keyboard.h"
|
||||||
|
#include "world/item/Item.h"
|
||||||
|
#include "world/item/ItemInstance.h"
|
||||||
|
#include <string>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#if defined(APPLE_DEMO_PROMOTION)
|
#if defined(APPLE_DEMO_PROMOTION)
|
||||||
#define NO_NETWORK
|
#define NO_NETWORK
|
||||||
@@ -8,88 +14,36 @@
|
|||||||
#if defined(RPI)
|
#if defined(RPI)
|
||||||
#define CREATORMODE
|
#define CREATORMODE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../network/RakNetInstance.h"
|
#include "../network/RakNetInstance.h"
|
||||||
#include "../network/ClientSideNetworkHandler.h"
|
#include "../network/ClientSideNetworkHandler.h"
|
||||||
#include "../network/ServerSideNetworkHandler.h"
|
#include "../network/ServerSideNetworkHandler.h"
|
||||||
//#include "../network/Packet.h"
|
//#include "../network/Packet.h"
|
||||||
#include "../world/entity/player/Inventory.h"
|
#include "../world/entity/player/Inventory.h"
|
||||||
#include "../world/level/chunk/ChunkCache.h"
|
|
||||||
#include "../world/level/tile/Tile.h"
|
#include "../world/level/tile/Tile.h"
|
||||||
#include "../world/level/storage/LevelStorageSource.h"
|
#include "../world/level/storage/LevelStorageSource.h"
|
||||||
#include "../world/level/storage/LevelStorage.h"
|
#include "../world/level/storage/LevelStorage.h"
|
||||||
#include "player/input/KeyboardInput.h"
|
#include "player/input/KeyboardInput.h"
|
||||||
|
#include "player/input/ControllerTurnInput.h"
|
||||||
|
#include "player/input/XperiaPlayInput.h"
|
||||||
|
#include "world/level/chunk/ChunkSource.h"
|
||||||
|
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
#include "player/input/touchscreen/TouchInputHolder.h"
|
#include "player/input/touchscreen/TouchInputHolder.h"
|
||||||
#endif
|
|
||||||
#include "player/LocalPlayer.h"
|
|
||||||
#include "gamemode/CreativeMode.h"
|
|
||||||
#include "gamemode/SurvivalMode.h"
|
|
||||||
#include "player/LocalPlayer.h"
|
|
||||||
#ifndef STANDALONE_SERVER
|
|
||||||
#include "particle/ParticleEngine.h"
|
#include "particle/ParticleEngine.h"
|
||||||
#include "gui/Screen.h"
|
#include "gui/Screen.h"
|
||||||
#include "gui/Font.h"
|
#include "gui/Font.h"
|
||||||
#include "gui/screens/RenameMPLevelScreen.h"
|
#include "gui/screens/RenameMPLevelScreen.h"
|
||||||
|
#include "gui/screens/ConsoleScreen.h"
|
||||||
|
#include "gui/screens/ChatScreen.h"
|
||||||
#include "sound/SoundEngine.h"
|
#include "sound/SoundEngine.h"
|
||||||
#endif
|
|
||||||
#include "../platform/CThread.h"
|
|
||||||
#include "../platform/input/Mouse.h"
|
|
||||||
#include "../AppPlatform.h"
|
|
||||||
#include "../Performance.h"
|
|
||||||
#include "../LicenseCodes.h"
|
|
||||||
#include "../util/PerfTimer.h"
|
|
||||||
#include "../util/PerfRenderer.h"
|
|
||||||
#include "player/input/MouseBuildInput.h"
|
|
||||||
|
|
||||||
#include "../world/Facing.h"
|
|
||||||
|
|
||||||
#include "../network/packet/PlaceBlockPacket.h"
|
|
||||||
|
|
||||||
#include "player/input/IInputHolder.h"
|
|
||||||
#ifndef STANDALONE_SERVER
|
|
||||||
#include "player/input/touchscreen/TouchscreenInput.h"
|
#include "player/input/touchscreen/TouchscreenInput.h"
|
||||||
|
#include "renderer/Chunk.h"
|
||||||
#include "player/input/ControllerTurnInput.h"
|
|
||||||
#include "player/input/XperiaPlayInput.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "player/input/MouseTurnInput.h"
|
|
||||||
#include "../world/entity/MobFactory.h"
|
|
||||||
#include "../world/level/MobSpawner.h"
|
|
||||||
#include "../util/Mth.h"
|
|
||||||
#include "../network/packet/InteractPacket.h"
|
|
||||||
#ifndef STANDALONE_SERVER
|
|
||||||
#include "gui/screens/PrerenderTilesScreen.h"
|
#include "gui/screens/PrerenderTilesScreen.h"
|
||||||
#include "renderer/Textures.h"
|
#include "renderer/Textures.h"
|
||||||
#include "gui/screens/DeathScreen.h"
|
#include "gui/screens/DeathScreen.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../network/packet/RespawnPacket.h"
|
|
||||||
#include "IConfigListener.h"
|
|
||||||
#include "../world/entity/MobCategory.h"
|
|
||||||
#ifndef STANDALONE_SERVER
|
|
||||||
#include "gui/screens/FurnaceScreen.h"
|
#include "gui/screens/FurnaceScreen.h"
|
||||||
#endif
|
|
||||||
#include "../world/Difficulty.h"
|
|
||||||
#include "../server/ServerLevel.h"
|
|
||||||
#ifdef CREATORMODE
|
|
||||||
#include "../server/CreatorLevel.h"
|
|
||||||
#endif
|
|
||||||
#include "../network/packet/AdventureSettingsPacket.h"
|
|
||||||
#include "../network/packet/SetSpawnPositionPacket.h"
|
|
||||||
#include "../network/command/CommandServer.h"
|
|
||||||
#include "gamemode/CreatorMode.h"
|
|
||||||
#ifndef STANDALONE_SERVER
|
|
||||||
#include "gui/screens/ArmorScreen.h"
|
#include "gui/screens/ArmorScreen.h"
|
||||||
#endif
|
|
||||||
#include "../world/level/levelgen/synth/ImprovedNoise.h"
|
|
||||||
#ifndef STANDALONE_SERVER
|
|
||||||
#include "renderer/tileentity/TileEntityRenderDispatcher.h"
|
#include "renderer/tileentity/TileEntityRenderDispatcher.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef STANDALONE_SERVER
|
|
||||||
#include "renderer/ptexture/DynamicTexture.h"
|
#include "renderer/ptexture/DynamicTexture.h"
|
||||||
#include "renderer/GameRenderer.h"
|
#include "renderer/GameRenderer.h"
|
||||||
#include "renderer/ItemInHandRenderer.h"
|
#include "renderer/ItemInHandRenderer.h"
|
||||||
@@ -99,8 +53,42 @@
|
|||||||
#include "gui/Font.h"
|
#include "gui/Font.h"
|
||||||
#include "gui/screens/RenameMPLevelScreen.h"
|
#include "gui/screens/RenameMPLevelScreen.h"
|
||||||
#include "sound/SoundEngine.h"
|
#include "sound/SoundEngine.h"
|
||||||
|
#endif // STANDALONE_SERVER
|
||||||
|
|
||||||
|
#include "player/LocalPlayer.h"
|
||||||
|
#include "gamemode/CreativeMode.h"
|
||||||
|
#include "gamemode/SurvivalMode.h"
|
||||||
|
#include "player/LocalPlayer.h"
|
||||||
|
#include "../platform/CThread.h"
|
||||||
|
#include "../platform/input/Mouse.h"
|
||||||
|
#include "../AppPlatform.h"
|
||||||
|
#include "../LicenseCodes.h"
|
||||||
|
#include "../util/PerfTimer.h"
|
||||||
|
#include "../util/PerfRenderer.h"
|
||||||
|
#include "player/input/MouseBuildInput.h"
|
||||||
|
|
||||||
|
#include "player/input/IInputHolder.h"
|
||||||
|
|
||||||
|
#include "player/input/MouseTurnInput.h"
|
||||||
|
#include "../world/entity/MobFactory.h"
|
||||||
|
#include "../world/level/MobSpawner.h"
|
||||||
|
#include "../util/Mth.h"
|
||||||
|
#include "../network/packet/InteractPacket.h"
|
||||||
|
#include "../network/packet/RespawnPacket.h"
|
||||||
|
#include "../network/packet/AdventureSettingsPacket.h"
|
||||||
|
#include "../network/packet/SetSpawnPositionPacket.h"
|
||||||
|
#include "IConfigListener.h"
|
||||||
|
#include "../world/entity/MobCategory.h"
|
||||||
|
#include "../world/Difficulty.h"
|
||||||
|
#include "../server/ServerLevel.h"
|
||||||
|
|
||||||
|
#ifdef CREATORMODE
|
||||||
|
#include "../server/CreatorLevel.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../network/command/CommandServer.h"
|
||||||
|
#include "gamemode/CreatorMode.h"
|
||||||
|
|
||||||
static void checkGlError(const char* tag) {
|
static void checkGlError(const char* tag) {
|
||||||
#ifdef GLDEBUG
|
#ifdef GLDEBUG
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -128,8 +116,7 @@ int Minecraft::customDebugId = Minecraft::CDI_NONE;
|
|||||||
|
|
||||||
bool Minecraft::useAmbientOcclusion = false;
|
bool Minecraft::useAmbientOcclusion = false;
|
||||||
|
|
||||||
Minecraft::Minecraft()
|
Minecraft::Minecraft() :
|
||||||
: user(NULL),
|
|
||||||
level(NULL),
|
level(NULL),
|
||||||
player(NULL),
|
player(NULL),
|
||||||
cameraTargetPlayer(NULL),
|
cameraTargetPlayer(NULL),
|
||||||
@@ -187,7 +174,7 @@ Minecraft::Minecraft()
|
|||||||
_powerVr(false),
|
_powerVr(false),
|
||||||
commandPort(4711),
|
commandPort(4711),
|
||||||
reserved_d1(0),reserved_d2(0),
|
reserved_d1(0),reserved_d2(0),
|
||||||
reserved_f1(0),reserved_f2(0)
|
reserved_f1(0),reserved_f2(0), options(this)
|
||||||
{
|
{
|
||||||
//#ifdef ANDROID
|
//#ifdef ANDROID
|
||||||
|
|
||||||
@@ -234,7 +221,6 @@ Minecraft::~Minecraft()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//delete player;
|
//delete player;
|
||||||
delete user;
|
|
||||||
delete inputHolder;
|
delete inputHolder;
|
||||||
|
|
||||||
delete storageSource;
|
delete storageSource;
|
||||||
@@ -349,6 +335,7 @@ void Minecraft::leaveGame(bool renameLevel /*=false*/)
|
|||||||
|
|
||||||
_running = false;
|
_running = false;
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
|
gui.clearMessages();
|
||||||
if (renameLevel) {
|
if (renameLevel) {
|
||||||
setScreen(new RenameMPLevelScreen(LevelStorageSource::TempLevelId));
|
setScreen(new RenameMPLevelScreen(LevelStorageSource::TempLevelId));
|
||||||
}
|
}
|
||||||
@@ -449,20 +436,21 @@ void Minecraft::update() {
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (pause && level != NULL) {
|
// If we're paused (local world / invisible server), freeze gameplay and
|
||||||
float lastA = timer.a;
|
// networking and only keep UI responsive.
|
||||||
timer.advanceTime();
|
bool freezeGame = pause;
|
||||||
timer.a = lastA;
|
|
||||||
} else {
|
if (!freezeGame) {
|
||||||
timer.advanceTime();
|
timer.advanceTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raknetInstance) {
|
if (raknetInstance && !freezeGame) {
|
||||||
raknetInstance->runEvents(netCallback);
|
raknetInstance->runEvents(netCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMER_PUSH("tick");
|
TIMER_PUSH("tick");
|
||||||
int toTick = timer.ticks;
|
int toTick = freezeGame ? 1 : timer.ticks;
|
||||||
|
if (!freezeGame) timer.ticks = 0;
|
||||||
for (int i = 0; i < toTick; ++i, ++ticks)
|
for (int i = 0; i < toTick; ++i, ++ticks)
|
||||||
tick(i, toTick-1);
|
tick(i, toTick-1);
|
||||||
|
|
||||||
@@ -489,16 +477,15 @@ void Minecraft::update() {
|
|||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
checkGlError("Update finished");
|
checkGlError("Update finished");
|
||||||
|
|
||||||
if (options.renderDebug) {
|
if (options.getBooleanValue(OPTIONS_RENDER_DEBUG)) {
|
||||||
|
#ifndef PLATFORM_DESKTOP
|
||||||
if (!PerfTimer::enabled) {
|
if (!PerfTimer::enabled) {
|
||||||
PerfTimer::reset();
|
PerfTimer::reset();
|
||||||
PerfTimer::enabled = true;
|
PerfTimer::enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TIMER_PUSH("debugfps");
|
|
||||||
_perfRenderer->renderFpsMeter(1);
|
_perfRenderer->renderFpsMeter(1);
|
||||||
checkGlError("render debug");
|
checkGlError("render debug");
|
||||||
//TIMER_POP();
|
#endif
|
||||||
} else {
|
} else {
|
||||||
PerfTimer::enabled = false;
|
PerfTimer::enabled = false;
|
||||||
}
|
}
|
||||||
@@ -558,7 +545,7 @@ void Minecraft::tick(int nTick, int maxTick) {
|
|||||||
TIMER_POP_PUSH("levelRenderer");
|
TIMER_POP_PUSH("levelRenderer");
|
||||||
levelRenderer->tick();
|
levelRenderer->tick();
|
||||||
#endif
|
#endif
|
||||||
level->difficulty = options.difficulty;
|
level->difficulty = options.getIntValue(OPTIONS_DIFFICULTY);
|
||||||
if (level->isClientSide) level->difficulty = Difficulty::EASY;
|
if (level->isClientSide) level->difficulty = Difficulty::EASY;
|
||||||
|
|
||||||
TIMER_POP_PUSH("level");
|
TIMER_POP_PUSH("level");
|
||||||
@@ -588,7 +575,9 @@ void Minecraft::tick(int nTick, int maxTick) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
TIMER_POP_PUSH("particles");
|
TIMER_POP_PUSH("particles");
|
||||||
|
if (!pause) {
|
||||||
particleEngine->tick();
|
particleEngine->tick();
|
||||||
|
}
|
||||||
if (screen) {
|
if (screen) {
|
||||||
screenMutex = true;
|
screenMutex = true;
|
||||||
screen->tick();
|
screen->tick();
|
||||||
@@ -664,11 +653,21 @@ void Minecraft::tickInput() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e.action == MouseAction::ACTION_WHEEL) {
|
if (e.action == MouseAction::ACTION_WHEEL) {
|
||||||
|
// If chat/console is open, use the wheel to scroll through chat history.
|
||||||
|
if (screen && (dynamic_cast<ChatScreen*>(screen) || dynamic_cast<ConsoleScreen*>(screen))) {
|
||||||
|
gui.scrollChat(e.dy);
|
||||||
|
} else {
|
||||||
Inventory* v = player->inventory;
|
Inventory* v = player->inventory;
|
||||||
int numSlots = gui.getNumSlots() - 1;
|
|
||||||
|
int numSlots = gui.getNumSlots();
|
||||||
|
#ifndef PLATFORM_DESKTOP
|
||||||
|
numSlots--;
|
||||||
|
#endif
|
||||||
|
|
||||||
int slot = (v->selected - e.dy + numSlots) % numSlots;
|
int slot = (v->selected - e.dy + numSlots) % numSlots;
|
||||||
v->selectSlot(slot);
|
v->selectSlot(slot);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
if (mouseDiggable && options.useMouseForDigging) {
|
if (mouseDiggable && options.useMouseForDigging) {
|
||||||
if (Mouse::getEventButton() == MouseAction::ACTION_LEFT && Mouse::getEventButtonState()) {
|
if (Mouse::getEventButton() == MouseAction::ACTION_LEFT && Mouse::getEventButtonState()) {
|
||||||
@@ -692,12 +691,12 @@ void Minecraft::tickInput() {
|
|||||||
if (isPressed) {
|
if (isPressed) {
|
||||||
gui.handleKeyPressed(key);
|
gui.handleKeyPressed(key);
|
||||||
|
|
||||||
#if defined(WIN32) || defined(RPI)//|| defined(_DEBUG) || defined(DEBUG)
|
#if defined(WIN32) || defined(RPI) || defined (PLATFORM_DESKTOP)//|| defined(_DEBUG) || defined(DEBUG)
|
||||||
if (key >= '0' && key <= '9') {
|
if (key >= '0' && key <= '9') {
|
||||||
int digit = key - '0';
|
int digit = key - '0';
|
||||||
int slot = digit - 1;
|
int slot = digit - 1;
|
||||||
|
|
||||||
if (slot >= 0 && slot < gui.getNumSlots()-1)
|
if (slot >= 0 && slot < gui.getNumSlots())
|
||||||
player->inventory->selectSlot(slot);
|
player->inventory->selectSlot(slot);
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
@@ -717,21 +716,24 @@ void Minecraft::tickInput() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PLATFORM_DESKTOP)
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
if (key == Keyboard::KEY_LEFT_CTRL) {
|
||||||
|
player->setSprinting(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (key == Keyboard::KEY_E) {
|
if (key == Keyboard::KEY_E) {
|
||||||
screenChooser.setScreen(SCREEN_BLOCKSELECTION);
|
screenChooser.setScreen(SCREEN_BLOCKSELECTION);
|
||||||
}
|
}
|
||||||
if (!screen && key == Keyboard::KEY_O || key == 250) {
|
|
||||||
releaseMouse();
|
if (!screen && key == Keyboard::KEY_T && level) {
|
||||||
}
|
setScreen(new ConsoleScreen());
|
||||||
#endif
|
|
||||||
#if defined(WIN32)
|
|
||||||
if (key == Keyboard::KEY_F) {
|
|
||||||
options.isFlying = !options.isFlying;
|
|
||||||
player->noPhysics = options.isFlying;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == Keyboard::KEY_T) {
|
if (key == Keyboard::KEY_F3) {
|
||||||
options.thirdPersonView = !options.thirdPersonView;
|
options.toggle(OPTIONS_RENDER_DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == Keyboard::KEY_F5) {
|
||||||
|
options.toggle(OPTIONS_THIRD_PERSON_VIEW);
|
||||||
/*
|
/*
|
||||||
ImprovedNoise noise;
|
ImprovedNoise noise;
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i)
|
||||||
@@ -739,15 +741,15 @@ void Minecraft::tickInput() {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == Keyboard::KEY_O) {
|
if (!screen && key == Keyboard::KEY_O || key == 250) {
|
||||||
useAmbientOcclusion = !useAmbientOcclusion;
|
releaseMouse();
|
||||||
options.ambientOcclusion = useAmbientOcclusion;
|
|
||||||
levelRenderer->allChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == Keyboard::KEY_L)
|
if (key == Keyboard::KEY_F) {
|
||||||
options.viewDistance = (options.viewDistance + 1) % 4;
|
int dst = options.getIntValue(OPTIONS_VIEW_DISTANCE);
|
||||||
|
options.set(OPTIONS_VIEW_DISTANCE, (dst + 1) % 4);
|
||||||
|
}
|
||||||
|
#ifdef CHEATS
|
||||||
if (key == Keyboard::KEY_U) {
|
if (key == Keyboard::KEY_U) {
|
||||||
onGraphicsReset();
|
onGraphicsReset();
|
||||||
player->heal(100);
|
player->heal(100);
|
||||||
@@ -816,21 +818,20 @@ void Minecraft::tickInput() {
|
|||||||
if (player->inventory->getItem(i))
|
if (player->inventory->getItem(i))
|
||||||
player->inventory->dropSlot(i, false);
|
player->inventory->dropSlot(i, false);
|
||||||
}
|
}
|
||||||
if (key == Keyboard::KEY_F3) {
|
|
||||||
options.renderDebug = !options.renderDebug;
|
|
||||||
}
|
|
||||||
if (key == Keyboard::KEY_M) {
|
if (key == Keyboard::KEY_M) {
|
||||||
options.difficulty = (options.difficulty == Difficulty::PEACEFUL)?
|
Difficulty difficulty = (Difficulty)options.getIntValue(OPTIONS_DIFFICULTY);
|
||||||
Difficulty::NORMAL : Difficulty::PEACEFUL;
|
options.set(OPTIONS_DIFFICULTY, (difficulty == Difficulty::PEACEFUL)?
|
||||||
|
Difficulty::NORMAL : Difficulty::PEACEFUL);
|
||||||
//setIsCreativeMode( !isCreativeMode() );
|
//setIsCreativeMode( !isCreativeMode() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.renderDebug) {
|
if (options.getBooleanValue(OPTIONS_RENDER_DEBUG)) {
|
||||||
if (key >= '0' && key <= '9') {
|
if (key >= '0' && key <= '9') {
|
||||||
_perfRenderer->debugFpsMeterKeyPress(key - '0');
|
_perfRenderer->debugFpsMeterKeyPress(key - '0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PLATFORM_DESKTOP
|
#ifndef PLATFORM_DESKTOP
|
||||||
if (key == 82)
|
if (key == 82)
|
||||||
@@ -861,7 +862,18 @@ void Minecraft::tickInput() {
|
|||||||
|
|
||||||
static bool prevMouseDownLeft = false;
|
static bool prevMouseDownLeft = false;
|
||||||
|
|
||||||
// Destroy and attack is on same button
|
if (Mouse::getButtonState(MouseAction::ACTION_LEFT) == 0) {
|
||||||
|
gameMode->stopDestroyBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useTouchscreen()) {
|
||||||
|
// Touch: gesture recognizer classifies the action type (turn/destroy/build)
|
||||||
|
BuildActionIntention bai;
|
||||||
|
if (inputHolder && inputHolder->getBuildInput()->tickBuild(player, &bai)) {
|
||||||
|
handleBuildAction(&bai);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Desktop: left mouse = destroy/attack
|
||||||
if (Mouse::isButtonDown(MouseAction::ACTION_LEFT)) {
|
if (Mouse::isButtonDown(MouseAction::ACTION_LEFT)) {
|
||||||
auto baiFlags = BuildActionIntention::BAI_REMOVE | BuildActionIntention::BAI_ATTACK;
|
auto baiFlags = BuildActionIntention::BAI_REMOVE | BuildActionIntention::BAI_ATTACK;
|
||||||
|
|
||||||
@@ -874,10 +886,20 @@ void Minecraft::tickInput() {
|
|||||||
prevMouseDownLeft = Mouse::isButtonDown(MouseAction::ACTION_LEFT);
|
prevMouseDownLeft = Mouse::isButtonDown(MouseAction::ACTION_LEFT);
|
||||||
|
|
||||||
// Build and use/interact is on same button
|
// Build and use/interact is on same button
|
||||||
|
// USPESHNO spizheno
|
||||||
|
static int buildHoldTicks = 0;
|
||||||
if (Mouse::isButtonDown(MouseAction::ACTION_RIGHT)) {
|
if (Mouse::isButtonDown(MouseAction::ACTION_RIGHT)) {
|
||||||
|
if (buildHoldTicks >= 5) buildHoldTicks = 0;
|
||||||
|
|
||||||
|
if (++buildHoldTicks == 1) {
|
||||||
BuildActionIntention bai(BuildActionIntention::BAI_BUILD | BuildActionIntention::BAI_INTERACT);
|
BuildActionIntention bai(BuildActionIntention::BAI_BUILD | BuildActionIntention::BAI_INTERACT);
|
||||||
handleBuildAction(&bai);
|
handleBuildAction(&bai);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
buildHoldTicks = 0;
|
||||||
|
gameMode->releaseUsingItem(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lastTickTime = getTimeMs();
|
lastTickTime = getTimeMs();
|
||||||
|
|
||||||
@@ -992,6 +1014,17 @@ bool Minecraft::isOnline()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Minecraft::pauseGame(bool isBackPaused) {
|
void Minecraft::pauseGame(bool isBackPaused) {
|
||||||
|
// Only freeze gameplay when running a local server and it is not accepting
|
||||||
|
// incoming connections (invisible server), which includes typical single-
|
||||||
|
// player/lobby mode. If the server is visible, the game should keep ticking.
|
||||||
|
bool canFreeze = false;
|
||||||
|
if (raknetInstance && raknetInstance->isServer() && netCallback) {
|
||||||
|
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) netCallback;
|
||||||
|
if (!ss->allowsIncomingConnections())
|
||||||
|
canFreeze = true;
|
||||||
|
}
|
||||||
|
pause = canFreeze;
|
||||||
|
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
if (screen != NULL) return;
|
if (screen != NULL) return;
|
||||||
screenChooser.setScreen(isBackPaused? SCREEN_PAUSEPREV : SCREEN_PAUSE);
|
screenChooser.setScreen(isBackPaused? SCREEN_PAUSEPREV : SCREEN_PAUSE);
|
||||||
@@ -1044,6 +1077,8 @@ void Minecraft::setScreen( Screen* screen )
|
|||||||
|
|
||||||
//noRender = false;
|
//noRender = false;
|
||||||
} else {
|
} else {
|
||||||
|
// Closing a screen and returning to the game should unpause.
|
||||||
|
pause = false;
|
||||||
grabMouse();
|
grabMouse();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1077,21 +1112,19 @@ bool Minecraft::useTouchscreen() {
|
|||||||
#ifdef RPI
|
#ifdef RPI
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
return options.useTouchScreen || !_supportsNonTouchscreen;
|
return options.getBooleanValue(OPTIONS_USE_TOUCHSCREEN) || !_supportsNonTouchscreen;
|
||||||
}
|
}
|
||||||
bool Minecraft::supportNonTouchScreen() {
|
bool Minecraft::supportNonTouchScreen() {
|
||||||
return _supportsNonTouchscreen;
|
return _supportsNonTouchscreen;
|
||||||
}
|
}
|
||||||
void Minecraft::init()
|
void Minecraft::init()
|
||||||
{
|
{
|
||||||
options.minecraft = this;
|
|
||||||
options.initDefaultValues();
|
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
checkGlError("Init enter");
|
checkGlError("Init enter");
|
||||||
|
|
||||||
_supportsNonTouchscreen = !platform()->supportsTouchscreen();
|
_supportsNonTouchscreen = !platform()->supportsTouchscreen();
|
||||||
|
|
||||||
LOGI("IS TOUCHSCREEN? %d\n", options.useTouchScreen);
|
LOGI("IS TOUCHSCREEN? %d\n", options.getBooleanValue(OPTIONS_USE_TOUCHSCREEN));
|
||||||
|
|
||||||
textures = new Textures(&options, platform());
|
textures = new Textures(&options, platform());
|
||||||
textures->addDynamicTexture(new WaterTexture());
|
textures->addDynamicTexture(new WaterTexture());
|
||||||
@@ -1110,10 +1143,8 @@ void Minecraft::init()
|
|||||||
checkGlError("Init complete");
|
checkGlError("Init complete");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
user = new User("TestUser", "");
|
|
||||||
setIsCreativeMode(false); // false means it's Survival Mode
|
setIsCreativeMode(false); // false means it's Survival Mode
|
||||||
reloadOptions();
|
reloadOptions();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Minecraft::setSize(int w, int h) {
|
void Minecraft::setSize(int w, int h) {
|
||||||
@@ -1123,6 +1154,20 @@ void Minecraft::setSize(int w, int h) {
|
|||||||
width = w;
|
width = w;
|
||||||
height = h;
|
height = h;
|
||||||
|
|
||||||
|
int guiScale = options.getIntValue(OPTIONS_GUI_SCALE);
|
||||||
|
|
||||||
|
// determine gui scale, optionally overriding auto
|
||||||
|
if (guiScale != 0) {
|
||||||
|
// manual selection: 1->small, 2->normal, 3->large, 4->larger
|
||||||
|
switch (guiScale) {
|
||||||
|
case 1: Gui::GuiScale = 2.0f; break;
|
||||||
|
case 2: Gui::GuiScale = 3.0f; break;
|
||||||
|
case 3: Gui::GuiScale = 4.0f; break;
|
||||||
|
case 4: Gui::GuiScale = 5.0f; break; // bigger than large
|
||||||
|
default: Gui::GuiScale = 1.0f; break; // auto
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// auto compute from resolution
|
||||||
if (width >= 1000) {
|
if (width >= 1000) {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
Gui::GuiScale = (width > 2000)? 8.0f : 4.0f;
|
Gui::GuiScale = (width > 2000)? 8.0f : 4.0f;
|
||||||
@@ -1141,16 +1186,17 @@ void Minecraft::setSize(int w, int h) {
|
|||||||
Gui::GuiScale = 2.0f;
|
Gui::GuiScale = 2.0f;
|
||||||
else
|
else
|
||||||
Gui::GuiScale = 1.0f;
|
Gui::GuiScale = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
Gui::InvGuiScale = 1.0f / Gui::GuiScale;
|
Gui::InvGuiScale = 1.0f / Gui::GuiScale;
|
||||||
int screenWidth = (int)(width * Gui::InvGuiScale);
|
int screenWidth = (int)(width * Gui::InvGuiScale);
|
||||||
int screenHeight = (int)(height * Gui::InvGuiScale);
|
int screenHeight = (int)(height * Gui::InvGuiScale);
|
||||||
|
|
||||||
if (platform()) {
|
// if (platform()) {
|
||||||
float pixelsPerMillimeter = options.getProgressValue(&Options::Option::PIXELS_PER_MILLIMETER);
|
// float pixelsPerMillimeter = options.getProgressValue(&Options::Option::PIXELS_PER_MILLIMETER);
|
||||||
pixelCalc.setPixelsPerMillimeter(pixelsPerMillimeter);
|
// pixelCalc.setPixelsPerMillimeter(pixelsPerMillimeter);
|
||||||
pixelCalcUi.setPixelsPerMillimeter(pixelsPerMillimeter * Gui::InvGuiScale);
|
// pixelCalcUi.setPixelsPerMillimeter(pixelsPerMillimeter * Gui::InvGuiScale);
|
||||||
}
|
// }
|
||||||
|
|
||||||
Config config = createConfig(this);
|
Config config = createConfig(this);
|
||||||
gui.onConfigChanged(config);
|
gui.onConfigChanged(config);
|
||||||
@@ -1171,16 +1217,16 @@ void Minecraft::setSize(int w, int h) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Minecraft::reloadOptions() {
|
void Minecraft::reloadOptions() {
|
||||||
options.update();
|
|
||||||
options.save();
|
options.save();
|
||||||
bool wasTouchscreen = options.useTouchScreen;
|
bool wasTouchscreen = options.getBooleanValue(OPTIONS_USE_TOUCHSCREEN);
|
||||||
options.useTouchScreen = useTouchscreen();
|
options.set(OPTIONS_USE_TOUCHSCREEN, useTouchscreen());
|
||||||
options.save();
|
options.save();
|
||||||
|
|
||||||
if ((wasTouchscreen != options.useTouchScreen) || (inputHolder == 0))
|
if ((wasTouchscreen != useTouchscreen()) || (inputHolder == 0))
|
||||||
_reloadInput();
|
_reloadInput();
|
||||||
|
|
||||||
user->name = options.username;
|
// TODO:
|
||||||
|
// user->name = options.username;
|
||||||
|
|
||||||
LOGI("Reloading-options\n");
|
LOGI("Reloading-options\n");
|
||||||
|
|
||||||
@@ -1193,7 +1239,12 @@ void Minecraft::_reloadInput() {
|
|||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
delete inputHolder;
|
delete inputHolder;
|
||||||
|
|
||||||
if (useTouchscreen() && !PLATFORM_DESKTOP) {
|
#ifdef PLATFORM_DESKTOP
|
||||||
|
const bool useTouchHolder = false;
|
||||||
|
#else
|
||||||
|
const bool useTouchHolder = useTouchscreen();
|
||||||
|
#endif
|
||||||
|
if (useTouchHolder) {
|
||||||
inputHolder = new TouchInputHolder(this, &options);
|
inputHolder = new TouchInputHolder(this, &options);
|
||||||
} else {
|
} else {
|
||||||
#if defined(ANDROID) || defined(__APPLE__)
|
#if defined(ANDROID) || defined(__APPLE__)
|
||||||
@@ -1245,6 +1296,31 @@ bool Minecraft::joinMultiplayer( const PingedCompatibleServer& server )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Minecraft::joinMultiplayerFromString( const std::string& server )
|
||||||
|
{
|
||||||
|
std::string ip = "";
|
||||||
|
std::string port = "19132";
|
||||||
|
|
||||||
|
size_t pos = server.find(":");
|
||||||
|
|
||||||
|
if (pos != std::string::npos) {
|
||||||
|
ip = server.substr(0, pos);
|
||||||
|
port = server.substr(pos + 1);
|
||||||
|
} else {
|
||||||
|
ip = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s \n", port.c_str());
|
||||||
|
|
||||||
|
if (isLookingForMultiplayer && netCallback) {
|
||||||
|
isLookingForMultiplayer = false;
|
||||||
|
printf("test");
|
||||||
|
int portNum = atoi(port.c_str());
|
||||||
|
return raknetInstance->connect(ip.c_str(), portNum);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Minecraft::hostMultiplayer(int port) {
|
void Minecraft::hostMultiplayer(int port) {
|
||||||
// Tear down last instance
|
// Tear down last instance
|
||||||
raknetInstance->disconnect();
|
raknetInstance->disconnect();
|
||||||
@@ -1254,9 +1330,9 @@ void Minecraft::hostMultiplayer(int port) {
|
|||||||
#if !defined(NO_NETWORK)
|
#if !defined(NO_NETWORK)
|
||||||
netCallback = new ServerSideNetworkHandler(this, raknetInstance);
|
netCallback = new ServerSideNetworkHandler(this, raknetInstance);
|
||||||
#ifdef STANDALONE_SERVER
|
#ifdef STANDALONE_SERVER
|
||||||
raknetInstance->host(user->name, port, 16);
|
raknetInstance->host("Server", port, 16);
|
||||||
#else
|
#else
|
||||||
raknetInstance->host(user->name, port);
|
raknetInstance->host(options.getStringValue(OPTIONS_USERNAME), port);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1313,8 +1389,10 @@ void Minecraft::_levelGenerated()
|
|||||||
|
|
||||||
this->cameraTargetPlayer = player;
|
this->cameraTargetPlayer = player;
|
||||||
|
|
||||||
|
std::string serverName = options.getStringValue(OPTIONS_USERNAME) + " - " + level->getLevelData()->levelName;
|
||||||
|
|
||||||
if (raknetInstance->isServer())
|
if (raknetInstance->isServer())
|
||||||
raknetInstance->announceServer(user->name);
|
raknetInstance->announceServer(serverName);
|
||||||
|
|
||||||
if (netCallback) {
|
if (netCallback) {
|
||||||
netCallback->levelGenerated(level);
|
netCallback->levelGenerated(level);
|
||||||
@@ -1412,11 +1490,11 @@ LevelStorageSource* Minecraft::getLevelSource()
|
|||||||
return storageSource;
|
return storageSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Minecraft::getLicenseId() {
|
// int Minecraft::getLicenseId() {
|
||||||
if (!LicenseCodes::isReady(_licenseId))
|
// if (!LicenseCodes::isReady(_licenseId))
|
||||||
_licenseId = platform()->checkLicense();
|
// _licenseId = platform()->checkLicense();
|
||||||
return _licenseId;
|
// return _licenseId;
|
||||||
}
|
// }
|
||||||
|
|
||||||
void Minecraft::audioEngineOn() {
|
void Minecraft::audioEngineOn() {
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
@@ -1486,22 +1564,25 @@ ICreator* Minecraft::getCreator()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Minecraft::optionUpdated( const Options::Option* option, bool value ) {
|
void Minecraft::optionUpdated(OptionId option, bool value ) {
|
||||||
if(netCallback != NULL && option == &Options::Option::SERVER_VISIBLE) {
|
if(netCallback != NULL && option == OPTIONS_SERVER_VISIBLE) {
|
||||||
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) netCallback;
|
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) netCallback;
|
||||||
ss->allowIncomingConnections(value);
|
ss->allowIncomingConnections(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Minecraft::optionUpdated( const Options::Option* option, float value ) {
|
void Minecraft::optionUpdated(OptionId option, float value ) {
|
||||||
#ifndef STANDALONE_SERVER
|
// #ifndef STANDALONE_SERVER
|
||||||
if(option == &Options::Option::PIXELS_PER_MILLIMETER) {
|
// if(option == OPTIONS_PIXELS_PER_MILLIMETER) {
|
||||||
pixelCalcUi.setPixelsPerMillimeter(value * Gui::InvGuiScale);
|
// pixelCalcUi.setPixelsPerMillimeter(value * Gui::InvGuiScale);
|
||||||
pixelCalc.setPixelsPerMillimeter(value);
|
// pixelCalc.setPixelsPerMillimeter(value);
|
||||||
}
|
// }
|
||||||
#endif
|
// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Minecraft::optionUpdated( const Options::Option* option, int value ) {
|
void Minecraft::optionUpdated(OptionId option, int value ) {
|
||||||
|
if(option == OPTIONS_GUI_SCALE) {
|
||||||
|
// reapply screen scaling using current window size
|
||||||
|
setSize(width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,15 @@
|
|||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
#include "MouseHandler.h"
|
#include "MouseHandler.h"
|
||||||
#endif
|
|
||||||
#include "Timer.h"
|
|
||||||
#include "player/input/ITurnInput.h"
|
|
||||||
#ifndef STANDALONE_SERVER
|
|
||||||
#include "gui/Gui.h"
|
#include "gui/Gui.h"
|
||||||
#include "gui/screens/ScreenChooser.h"
|
#include "gui/screens/ScreenChooser.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "Timer.h"
|
||||||
|
|
||||||
//#include "../network/RakNetInstance.h"
|
//#include "../network/RakNetInstance.h"
|
||||||
#include "../world/phys/HitResult.h"
|
#include "../world/phys/HitResult.h"
|
||||||
|
|
||||||
class User;
|
|
||||||
class Level;
|
class Level;
|
||||||
class LocalPlayer;
|
class LocalPlayer;
|
||||||
class IInputHolder;
|
class IInputHolder;
|
||||||
@@ -80,6 +78,7 @@ public:
|
|||||||
void locateMultiplayer();
|
void locateMultiplayer();
|
||||||
void cancelLocateMultiplayer();
|
void cancelLocateMultiplayer();
|
||||||
bool joinMultiplayer(const PingedCompatibleServer& server);
|
bool joinMultiplayer(const PingedCompatibleServer& server);
|
||||||
|
bool joinMultiplayerFromString(const std::string& server);
|
||||||
void hostMultiplayer(int port=19132);
|
void hostMultiplayer(int port=19132);
|
||||||
Player* respawnPlayer(int playerId);
|
Player* respawnPlayer(int playerId);
|
||||||
void respawnPlayer();
|
void respawnPlayer();
|
||||||
@@ -109,7 +108,6 @@ public:
|
|||||||
void onGraphicsReset();
|
void onGraphicsReset();
|
||||||
|
|
||||||
bool isLevelGenerated();
|
bool isLevelGenerated();
|
||||||
int getLicenseId();
|
|
||||||
|
|
||||||
void audioEngineOn();
|
void audioEngineOn();
|
||||||
void audioEngineOff();
|
void audioEngineOff();
|
||||||
@@ -117,9 +115,9 @@ public:
|
|||||||
bool isPowerVR() { return _powerVr; }
|
bool isPowerVR() { return _powerVr; }
|
||||||
bool isKindleFire(int kindleVersion);
|
bool isKindleFire(int kindleVersion);
|
||||||
bool transformResolution(int* w, int* h);
|
bool transformResolution(int* w, int* h);
|
||||||
void optionUpdated(const Options::Option* option, bool value);
|
void optionUpdated(OptionId option, bool value);
|
||||||
void optionUpdated(const Options::Option* option, float value);
|
void optionUpdated(OptionId option, float value);
|
||||||
void optionUpdated(const Options::Option* option, int value);
|
void optionUpdated(OptionId option, int value);
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
bool _isSuperFast;
|
bool _isSuperFast;
|
||||||
bool isSuperFast() { return _isSuperFast; }
|
bool isSuperFast() { return _isSuperFast; }
|
||||||
@@ -166,7 +164,6 @@ public:
|
|||||||
int lastTickTime;
|
int lastTickTime;
|
||||||
float ticksSinceLastUpdate;
|
float ticksSinceLastUpdate;
|
||||||
|
|
||||||
User* user;
|
|
||||||
Level* level;
|
Level* level;
|
||||||
|
|
||||||
LocalPlayer* player;
|
LocalPlayer* player;
|
||||||
|
|||||||
52
src/client/Option.cpp
Normal file
52
src/client/Option.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include "Option.h"
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
Option::~Option() {}
|
||||||
|
|
||||||
|
bool Option::parse_bool_like(const std::string& value, bool& out) {
|
||||||
|
if (value == "true" || value == "YES") {
|
||||||
|
out = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == "false" || value == "NO") {
|
||||||
|
out = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OptionFloat::parse(const std::string& value) {
|
||||||
|
bool b;
|
||||||
|
|
||||||
|
if (parse_bool_like(value, b)) {
|
||||||
|
m_value = b ? 1.f : 0.f;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sscanf(value.c_str(), "%f", &m_value) == 1;
|
||||||
|
}
|
||||||
|
bool OptionInt::parse(const std::string& value) {
|
||||||
|
bool b;
|
||||||
|
if (parse_bool_like(value, b)) {
|
||||||
|
m_value = b ? 1 : 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sscanf(value.c_str(), "%d", &m_value) == 1;
|
||||||
|
}
|
||||||
|
bool OptionBool::parse(const std::string& value) {
|
||||||
|
if (value == "0") {
|
||||||
|
m_value = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == "1") {
|
||||||
|
m_value = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parse_bool_like(value, m_value);
|
||||||
|
}
|
||||||
107
src/client/Option.h
Normal file
107
src/client/Option.h
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <sstream>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <util/Mth.h>
|
||||||
|
/*
|
||||||
|
template<typename T>
|
||||||
|
struct is_option_type : std::false_type {};
|
||||||
|
|
||||||
|
template<> struct is_option_type<bool> : std::true_type {};
|
||||||
|
template<> struct is_option_type<int> : std::true_type {};
|
||||||
|
template<> struct is_option_type<float> : std::true_type {};
|
||||||
|
template<> struct is_option_type<std::string> : std::true_type {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_min_max_option : std::false_type {};
|
||||||
|
|
||||||
|
template<> struct is_min_max_option<int> : std::true_type {};
|
||||||
|
template<> struct is_min_max_option<float> : std::true_type {};
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Option {
|
||||||
|
public:
|
||||||
|
Option(const std::string& key) : m_key("options." + key) {}
|
||||||
|
virtual ~Option();
|
||||||
|
|
||||||
|
const std::string& getStringId() { return m_key; }
|
||||||
|
|
||||||
|
virtual bool parse(const std::string& value) { return false; }
|
||||||
|
virtual std::string serialize() { return m_key + ":"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string m_key;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::string serialize_value(const T& value) const {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << m_key << ":" << value;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parse_bool_like(const std::string& value, bool& out);
|
||||||
|
};
|
||||||
|
|
||||||
|
class OptionFloat : public Option {
|
||||||
|
public:
|
||||||
|
OptionFloat(const std::string& key, float value = 0.f, float min = 0.f, float max = 1.f) :
|
||||||
|
Option(key), m_value(value), m_min(min), m_max(max) {}
|
||||||
|
|
||||||
|
float get() { return m_value; }
|
||||||
|
void set(float value) { m_value = Mth::clamp(value, m_min, m_max); }
|
||||||
|
|
||||||
|
float getMin() { return m_min; }
|
||||||
|
float getMax() { return m_max; }
|
||||||
|
|
||||||
|
virtual bool parse(const std::string& value);
|
||||||
|
virtual std::string serialize() { return serialize_value(m_value); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_value, m_min, m_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OptionInt : public Option {
|
||||||
|
public:
|
||||||
|
OptionInt(const std::string& key, int value = 0, int min = -999999, int max = 999999) :
|
||||||
|
Option(key), m_value(value), m_min(min), m_max(max) {}
|
||||||
|
|
||||||
|
int get() { return m_value; }
|
||||||
|
void set(int value) { m_value = Mth::clamp(value, m_min, m_max); }
|
||||||
|
|
||||||
|
int getMin() { return m_min; }
|
||||||
|
int getMax() { return m_max; }
|
||||||
|
|
||||||
|
virtual bool parse(const std::string& value);
|
||||||
|
virtual std::string serialize() { return serialize_value(m_value); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_value, m_min, m_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OptionBool : public Option {
|
||||||
|
public:
|
||||||
|
OptionBool(const std::string& key, bool value = false) : Option(key), m_value(value) {}
|
||||||
|
|
||||||
|
bool get() { return m_value; }
|
||||||
|
void set(int value) { m_value = value; }
|
||||||
|
void toggle() { m_value = !m_value; }
|
||||||
|
|
||||||
|
virtual bool parse(const std::string& value);
|
||||||
|
virtual std::string serialize() { return serialize_value(m_value); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OptionString : public Option {
|
||||||
|
public:
|
||||||
|
OptionString(const std::string& key, const std::string& str = "") : Option(key), m_value(str) {}
|
||||||
|
|
||||||
|
const std::string& get() { return m_value; }
|
||||||
|
void set(const std::string& value) { m_value = value; }
|
||||||
|
|
||||||
|
virtual bool parse(const std::string& value) { m_value = value; return true; }
|
||||||
|
virtual std::string serialize() { return m_key + ":" + m_value; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_value;
|
||||||
|
};
|
||||||
@@ -5,12 +5,20 @@ const char* OptionStrings::Multiplayer_ServerVisible = "mp_server_visible_defa
|
|||||||
|
|
||||||
const char* OptionStrings::Graphics_Fancy = "gfx_fancygraphics";
|
const char* OptionStrings::Graphics_Fancy = "gfx_fancygraphics";
|
||||||
const char* OptionStrings::Graphics_LowQuality = "gfx_lowquality";
|
const char* OptionStrings::Graphics_LowQuality = "gfx_lowquality";
|
||||||
|
const char* OptionStrings::Graphics_Vsync = "gfx_vsync";
|
||||||
|
const char* OptionStrings::Graphics_GUIScale = "gfx_guiscale";
|
||||||
|
const char* OptionStrings::Graphics_SmoothLightning = "gfx_smoothlightning";
|
||||||
|
const char* OptionStrings::Graphics_Anaglyph = "gfx_anaglyph";
|
||||||
|
const char* OptionStrings::Graphics_ViewBobbing = "gfx_viewbobbing";
|
||||||
|
|
||||||
const char* OptionStrings::Controls_Sensitivity = "ctrl_sensitivity";
|
const char* OptionStrings::Controls_Sensitivity = "ctrl_sensitivity";
|
||||||
const char* OptionStrings::Controls_InvertMouse = "ctrl_invertmouse";
|
const char* OptionStrings::Controls_InvertMouse = "ctrl_invertmouse";
|
||||||
const char* OptionStrings::Controls_UseTouchScreen = "ctrl_usetouchscreen";
|
const char* OptionStrings::Controls_UseTouchScreen = "ctrl_usetouchscreen";
|
||||||
const char* OptionStrings::Controls_UseTouchJoypad = "ctrl_usetouchjoypad";
|
const char* OptionStrings::Controls_UseTouchJoypad = "ctrl_usetouchjoypad";
|
||||||
const char* OptionStrings::Controls_IsLefthanded = "ctrl_islefthanded";
|
const char* OptionStrings::Controls_IsLefthanded = "ctrl_islefthanded";
|
||||||
|
// why it isnt ctrl_feedback_vibration? i dont want touch it because compatibility with older versions
|
||||||
const char* OptionStrings::Controls_FeedbackVibration = "feedback_vibration";
|
const char* OptionStrings::Controls_FeedbackVibration = "feedback_vibration";
|
||||||
|
const char* OptionStrings::Controls_AutoJump = "ctrl_autojump";
|
||||||
|
|
||||||
const char* OptionStrings::Game_DifficultyLevel = "game_difficulty";
|
const char* OptionStrings::Game_DifficultyLevel = "game_difficulty";
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ public:
|
|||||||
|
|
||||||
static const char* Graphics_Fancy;
|
static const char* Graphics_Fancy;
|
||||||
static const char* Graphics_LowQuality;
|
static const char* Graphics_LowQuality;
|
||||||
|
static const char* Graphics_GUIScale;
|
||||||
|
static const char* Graphics_Vsync;
|
||||||
|
static const char* Graphics_SmoothLightning;
|
||||||
|
static const char* Graphics_Anaglyph;
|
||||||
|
static const char* Graphics_ViewBobbing;
|
||||||
|
|
||||||
static const char* Controls_Sensitivity;
|
static const char* Controls_Sensitivity;
|
||||||
static const char* Controls_InvertMouse;
|
static const char* Controls_InvertMouse;
|
||||||
@@ -15,8 +20,17 @@ public:
|
|||||||
static const char* Controls_UseTouchJoypad;
|
static const char* Controls_UseTouchJoypad;
|
||||||
static const char* Controls_IsLefthanded;
|
static const char* Controls_IsLefthanded;
|
||||||
static const char* Controls_FeedbackVibration;
|
static const char* Controls_FeedbackVibration;
|
||||||
|
static const char* Controls_AutoJump;
|
||||||
|
|
||||||
|
static const char* Audio_Music;
|
||||||
|
static const char* Audio_Sound;
|
||||||
|
|
||||||
|
|
||||||
static const char* Game_DifficultyLevel;
|
static const char* Game_DifficultyLevel;
|
||||||
|
|
||||||
|
static const char* Tweaks_Sprint;
|
||||||
|
static const char* Tweaks_BarOnTop;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT__OptionsStrings_H__*/
|
#endif /*NET_MINECRAFT_CLIENT__OptionsStrings_H__*/
|
||||||
|
|||||||
@@ -4,457 +4,293 @@
|
|||||||
#include "../platform/log.h"
|
#include "../platform/log.h"
|
||||||
#include "../world/Difficulty.h"
|
#include "../world/Difficulty.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <sstream>
|
|
||||||
/*static*/
|
#include <memory>
|
||||||
|
|
||||||
bool Options::debugGl = false;
|
bool Options::debugGl = false;
|
||||||
|
|
||||||
void Options::initDefaultValues() {
|
// OPTIONS TABLE
|
||||||
difficulty = Difficulty::NORMAL;
|
|
||||||
hideGui = false;
|
|
||||||
thirdPersonView = false;
|
|
||||||
renderDebug = false;
|
|
||||||
isFlying = false;
|
|
||||||
smoothCamera = true;
|
|
||||||
fixedCamera = false;
|
|
||||||
flySpeed = 1;
|
|
||||||
cameraSpeed = 1;
|
|
||||||
guiScale = 0;
|
|
||||||
|
|
||||||
useMouseForDigging = false;
|
OptionInt difficulty("difficulty", Difficulty::NORMAL, 0, Difficulty::COUNT);
|
||||||
destroyVibration = true;
|
OptionBool hidegui("hidegui", false);
|
||||||
isLeftHanded = false;
|
OptionBool thirdPersonView("thirdperson", false);
|
||||||
|
OptionBool renderDebug("renderDebug", false);
|
||||||
|
OptionBool smoothCamera("smoothCamera", false);
|
||||||
|
OptionBool fixedCamera("fixedCamera", false);
|
||||||
|
OptionBool isFlying("isflying", false);
|
||||||
|
OptionBool barOnTop("barOnTop", false);
|
||||||
|
OptionBool allowSprint("allowSprint", true);
|
||||||
|
OptionBool autoJump("autoJump", true);
|
||||||
|
|
||||||
isJoyTouchArea = false;
|
|
||||||
|
|
||||||
music = 1;
|
OptionFloat flySpeed("flySpeed", 1.f);
|
||||||
sound = 1;
|
OptionFloat cameraSpeed("cameraSpeed", 1.f);
|
||||||
sensitivity = 0.5f;
|
|
||||||
invertYMouse = false;
|
|
||||||
viewDistance = 2;
|
|
||||||
bobView = true;
|
|
||||||
anaglyph3d = false;
|
|
||||||
limitFramerate = false;
|
|
||||||
fancyGraphics = true;//false;
|
|
||||||
ambientOcclusion = false;
|
|
||||||
if(minecraft->supportNonTouchScreen())
|
|
||||||
useTouchScreen = false;
|
|
||||||
else
|
|
||||||
useTouchScreen = true;
|
|
||||||
pixelsPerMillimeter = minecraft->platform()->getPixelsPerMillimeter();
|
|
||||||
//useMouseForDigging = true;
|
|
||||||
|
|
||||||
//skin = "Default";
|
OptionInt guiScale("guiScale", 0, 0, 5);
|
||||||
username = "Steve";
|
|
||||||
serverVisible = true;
|
|
||||||
|
|
||||||
keyUp = KeyMapping("key.forward", Keyboard::KEY_W);
|
OptionString skin("skin", "Default");
|
||||||
keyLeft = KeyMapping("key.left", Keyboard::KEY_A);
|
|
||||||
keyDown = KeyMapping("key.back", Keyboard::KEY_S);
|
#ifdef RPI
|
||||||
keyRight = KeyMapping("key.right", Keyboard::KEY_D);
|
OptionString username("username", "StevePi");
|
||||||
keyJump = KeyMapping("key.jump", Keyboard::KEY_SPACE);
|
#else
|
||||||
keyBuild = KeyMapping("key.inventory", Keyboard::KEY_E);
|
OptionString username("username", "Steve");
|
||||||
keySneak = KeyMapping("key.sneak", Keyboard::KEY_LSHIFT);
|
|
||||||
#ifndef RPI
|
|
||||||
keyCraft = KeyMapping("key.crafting", Keyboard::KEY_Q);
|
|
||||||
keyDrop = KeyMapping("key.drop", Keyboard::KEY_Q);
|
|
||||||
keyChat = KeyMapping("key.chat", Keyboard::KEY_T);
|
|
||||||
keyFog = KeyMapping("key.fog", Keyboard::KEY_F);
|
|
||||||
keyDestroy=KeyMapping("key.destroy", 88); // @todo @fix
|
|
||||||
keyUse = KeyMapping("key.use", Keyboard::KEY_U);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//const int Unused = 99999;
|
OptionBool destroyVibration("destroyVibration", true);
|
||||||
keyMenuNext = KeyMapping("key.menu.next", 40);
|
OptionBool isLeftHanded("isLeftHanded", false);
|
||||||
keyMenuPrevious = KeyMapping("key.menu.previous", 38);
|
OptionBool isJoyTouchArea("isJoyTouchArea", false);
|
||||||
keyMenuOk = KeyMapping("key.menu.ok", 13);
|
|
||||||
keyMenuCancel = KeyMapping("key.menu.cancel", 8);
|
|
||||||
|
|
||||||
int k = 0;
|
OptionFloat musicVolume("music", 1.f, MUSIC_MIN_VALUE, MUSIC_MAX_VALUE);
|
||||||
keyMappings[k++] = &keyUp;
|
OptionFloat soundVolume("sound", 1.f, SOUND_MIN_VALUE, SOUND_MAX_VALUE);
|
||||||
keyMappings[k++] = &keyLeft;
|
|
||||||
keyMappings[k++] = &keyDown;
|
|
||||||
keyMappings[k++] = &keyRight;
|
|
||||||
keyMappings[k++] = &keyJump;
|
|
||||||
keyMappings[k++] = &keySneak;
|
|
||||||
keyMappings[k++] = &keyDrop;
|
|
||||||
keyMappings[k++] = &keyBuild;
|
|
||||||
keyMappings[k++] = &keyChat;
|
|
||||||
keyMappings[k++] = &keyFog;
|
|
||||||
keyMappings[k++] = &keyDestroy;
|
|
||||||
keyMappings[k++] = &keyUse;
|
|
||||||
|
|
||||||
keyMappings[k++] = &keyMenuNext;
|
OptionFloat sensitivityOpt("sensitivity", 0.5f, SENSITIVITY_MIN_VALUE, SENSITIVITY_MAX_VALUE);
|
||||||
keyMappings[k++] = &keyMenuPrevious;
|
|
||||||
keyMappings[k++] = &keyMenuOk;
|
|
||||||
keyMappings[k++] = &keyMenuCancel;
|
|
||||||
|
|
||||||
// "Polymorphism" at it's worst. At least it's better to have it here
|
OptionBool invertYMouse("invertMouse", false);
|
||||||
// for now, then to have it spread all around the game code (even if
|
OptionInt viewDistance("renderDistance", 2, 0, 4);
|
||||||
// it would be slightly better performance with it inlined. Should
|
|
||||||
// probably create separate subclasses (or read from file). @fix @todo.
|
|
||||||
#if defined(ANDROID) || defined(__APPLE__) || defined(RPI)
|
|
||||||
viewDistance = 2;
|
|
||||||
thirdPersonView = false;
|
|
||||||
useMouseForDigging = false;
|
|
||||||
fancyGraphics = false;
|
|
||||||
|
|
||||||
//renderDebug = true;
|
OptionBool anaglyph3d("anaglyph3d", false);
|
||||||
#if !defined(RPI)
|
OptionBool limitFramerate("limitFramerate", false);
|
||||||
keyUp.key = 19;
|
OptionBool vsync("vsync", true);
|
||||||
keyDown.key = 20;
|
OptionBool fancyGraphics("fancyGraphics", true);
|
||||||
keyLeft.key = 21;
|
OptionBool viewBobbing("viewBobbing", true);
|
||||||
keyRight.key = 22;
|
OptionBool ambientOcclusion("ao", false);
|
||||||
keyJump.key = 23;
|
|
||||||
keyUse.key = 103;
|
|
||||||
keyDestroy.key = 102;
|
|
||||||
keyCraft.key = 109;
|
|
||||||
|
|
||||||
keyMenuNext.key = 20;
|
OptionBool useTouchscreen("useTouchscreen", true);
|
||||||
keyMenuPrevious.key = 19;
|
|
||||||
keyMenuOk.key = 23;
|
|
||||||
keyMenuCancel.key = 4;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(RPI)
|
OptionBool serverVisible("servervisible", true);
|
||||||
username = "StevePi";
|
|
||||||
|
OptionInt keyForward("key.forward", Keyboard::KEY_W);
|
||||||
|
OptionInt keyLeft("key.left", Keyboard::KEY_A);
|
||||||
|
OptionInt keyBack("key.back", Keyboard::KEY_S);
|
||||||
|
OptionInt keyRight("key.right", Keyboard::KEY_D);
|
||||||
|
OptionInt keyJump("key.jump", Keyboard::KEY_SPACE);
|
||||||
|
OptionInt keyInventory("key.inventory", Keyboard::KEY_E);
|
||||||
|
OptionInt keySneak("key.sneak", Keyboard::KEY_LSHIFT);
|
||||||
|
OptionInt keyDrop("key.drop", Keyboard::KEY_Q);
|
||||||
|
OptionInt keyChat("key.chat", Keyboard::KEY_T);
|
||||||
|
OptionInt keyFog("key.fog", Keyboard::KEY_F);
|
||||||
|
OptionInt keyUse("key.use", Keyboard::KEY_U);
|
||||||
|
|
||||||
|
// TODO: make human readable keycodes here
|
||||||
|
OptionInt keyMenuNext("key.menu.next", 40);
|
||||||
|
OptionInt keyMenuPrev("key.menu.previous", 38);
|
||||||
|
OptionInt keyMenuOk("key.menu.ok", 13);
|
||||||
|
OptionInt keyMenuCancel("key.menu.cancel", 8);
|
||||||
|
|
||||||
|
OptionBool firstLaunch("firstLaunch", true);
|
||||||
|
|
||||||
|
OptionString lastIp("lastip");
|
||||||
|
|
||||||
|
void Options::initTable() {
|
||||||
|
m_options[OPTIONS_DIFFICULTY] = &difficulty;
|
||||||
|
m_options[OPTIONS_HIDEGUI] = &hidegui;
|
||||||
|
m_options[OPTIONS_THIRD_PERSON_VIEW] = &thirdPersonView;
|
||||||
|
m_options[OPTIONS_RENDER_DEBUG] = &renderDebug;
|
||||||
|
m_options[OPTIONS_SMOOTH_CAMERA] = &smoothCamera;
|
||||||
|
m_options[OPTIONS_FIXED_CAMERA] = &fixedCamera;
|
||||||
|
m_options[OPTIONS_IS_FLYING] = &isFlying;
|
||||||
|
|
||||||
|
m_options[OPTIONS_FLY_SPEED] = &flySpeed;
|
||||||
|
m_options[OPTIONS_CAMERA_SPEED] = &cameraSpeed;
|
||||||
|
|
||||||
|
m_options[OPTIONS_GUI_SCALE] = &guiScale;
|
||||||
|
|
||||||
|
m_options[OPTIONS_DESTROY_VIBRATION] = &destroyVibration;
|
||||||
|
|
||||||
|
m_options[OPTIONS_IS_LEFT_HANDED] = &isLeftHanded;
|
||||||
|
m_options[OPTIONS_IS_JOY_TOUCH_AREA] = &isJoyTouchArea;
|
||||||
|
|
||||||
|
m_options[OPTIONS_MUSIC_VOLUME] = &musicVolume;
|
||||||
|
m_options[OPTIONS_SOUND_VOLUME] = &soundVolume;
|
||||||
|
|
||||||
|
#if defined(PLATFORM_DESKTOP) || defined(RPI)
|
||||||
|
float sensitivity = sensitivityOpt.get();
|
||||||
sensitivity *= 0.4f;
|
sensitivity *= 0.4f;
|
||||||
useMouseForDigging = true;
|
sensitivityOpt.set(sensitivity);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
m_options[OPTIONS_GUI_SCALE] = &guiScale;
|
||||||
|
|
||||||
|
m_options[OPTIONS_SKIN] = &skin;
|
||||||
|
m_options[OPTIONS_USERNAME] = &username;
|
||||||
|
|
||||||
|
m_options[OPTIONS_DESTROY_VIBRATION] = &destroyVibration;
|
||||||
|
m_options[OPTIONS_IS_LEFT_HANDED] = &isLeftHanded;
|
||||||
|
|
||||||
|
m_options[OPTIONS_MUSIC_VOLUME] = &musicVolume;
|
||||||
|
m_options[OPTIONS_SOUND_VOLUME] = &soundVolume;
|
||||||
|
|
||||||
|
m_options[OPTIONS_SENSITIVITY] = &sensitivityOpt;
|
||||||
|
|
||||||
|
m_options[OPTIONS_INVERT_Y_MOUSE] = &invertYMouse;
|
||||||
|
m_options[OPTIONS_VIEW_DISTANCE] = &viewDistance;
|
||||||
|
|
||||||
|
m_options[OPTIONS_ANAGLYPH_3D] = &anaglyph3d;
|
||||||
|
m_options[OPTIONS_LIMIT_FRAMERATE] = &limitFramerate;
|
||||||
|
m_options[OPTIONS_VSYNC] = &vsync;
|
||||||
|
m_options[OPTIONS_FANCY_GRAPHICS] = &fancyGraphics;
|
||||||
|
m_options[OPTIONS_VIEW_BOBBING] = &viewBobbing;
|
||||||
|
m_options[OPTIONS_AMBIENT_OCCLUSION] = &ambientOcclusion;
|
||||||
|
|
||||||
|
m_options[OPTIONS_USE_TOUCHSCREEN] = &useTouchscreen;
|
||||||
|
|
||||||
|
m_options[OPTIONS_SERVER_VISIBLE] = &serverVisible;
|
||||||
|
|
||||||
|
m_options[OPTIONS_KEY_FORWARD] = &keyForward;
|
||||||
|
m_options[OPTIONS_KEY_LEFT] = &keyLeft;
|
||||||
|
m_options[OPTIONS_KEY_BACK] = &keyBack;
|
||||||
|
m_options[OPTIONS_KEY_RIGHT] = &keyRight;
|
||||||
|
m_options[OPTIONS_KEY_JUMP] = &keyJump;
|
||||||
|
m_options[OPTIONS_KEY_INVENTORY] = &keyInventory;
|
||||||
|
m_options[OPTIONS_KEY_SNEAK] = &keySneak;
|
||||||
|
m_options[OPTIONS_KEY_DROP] = &keyDrop;
|
||||||
|
m_options[OPTIONS_KEY_CHAT] = &keyChat;
|
||||||
|
m_options[OPTIONS_KEY_FOG] = &keyFog;
|
||||||
|
m_options[OPTIONS_KEY_USE] = &keyUse;
|
||||||
|
|
||||||
|
m_options[OPTIONS_KEY_MENU_NEXT] = &keyMenuNext;
|
||||||
|
m_options[OPTIONS_KEY_MENU_PREV] = &keyMenuPrev;
|
||||||
|
m_options[OPTIONS_KEY_MENU_OK] = &keyMenuOk;
|
||||||
|
m_options[OPTIONS_KEY_MENU_CANCEL] = &keyMenuCancel;
|
||||||
|
|
||||||
|
m_options[OPTIONS_FIRST_LAUNCH] = &firstLaunch;
|
||||||
|
|
||||||
|
m_options[OPTIONS_BAR_ON_TOP] = &barOnTop;
|
||||||
|
m_options[OPTIONS_ALLOW_SPRINT] = &allowSprint;
|
||||||
|
|
||||||
|
m_options[OPTIONS_AUTOJUMP] = &autoJump;
|
||||||
|
m_options[OPTIONS_LAST_IP] = &lastIp;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Options::Option
|
void Options::set(OptionId key, const std::string& value) {
|
||||||
Options::Option::MUSIC (0, "options.music", true, false),
|
auto option = opt<OptionString>(key);
|
||||||
Options::Option::SOUND (1, "options.sound", true, false),
|
|
||||||
Options::Option::INVERT_MOUSE (2, "options.invertMouse", false, true),
|
|
||||||
Options::Option::SENSITIVITY (3, "options.sensitivity", true, false),
|
|
||||||
Options::Option::RENDER_DISTANCE (4, "options.renderDistance",false, false),
|
|
||||||
Options::Option::VIEW_BOBBING (5, "options.viewBobbing", false, true),
|
|
||||||
Options::Option::ANAGLYPH (6, "options.anaglyph", false, true),
|
|
||||||
Options::Option::LIMIT_FRAMERATE (7, "options.limitFramerate",false, true),
|
|
||||||
Options::Option::DIFFICULTY (8, "options.difficulty", false, false),
|
|
||||||
Options::Option::GRAPHICS (9, "options.graphics", false, false),
|
|
||||||
Options::Option::AMBIENT_OCCLUSION (10, "options.ao", false, true),
|
|
||||||
Options::Option::GUI_SCALE (11, "options.guiScale", false, false),
|
|
||||||
Options::Option::THIRD_PERSON (12, "options.thirdperson", false, true),
|
|
||||||
Options::Option::HIDE_GUI (13, "options.hidegui", false, true),
|
|
||||||
Options::Option::SERVER_VISIBLE (14, "options.servervisible", false, true),
|
|
||||||
Options::Option::LEFT_HANDED (15, "options.lefthanded", false, true),
|
|
||||||
Options::Option::USE_TOUCHSCREEN (16, "options.usetouchscreen", false, true),
|
|
||||||
Options::Option::USE_TOUCH_JOYPAD (17, "options.usetouchpad", false, true),
|
|
||||||
Options::Option::DESTROY_VIBRATION (18, "options.destroyvibration", false, true),
|
|
||||||
Options::Option::PIXELS_PER_MILLIMETER(19, "options.pixelspermilimeter", true, false);
|
|
||||||
|
|
||||||
/* private */
|
if (option) {
|
||||||
const float Options::SOUND_MIN_VALUE = 0.0f;
|
option->set(value);
|
||||||
const float Options::SOUND_MAX_VALUE = 1.0f;
|
notifyOptionUpdate(key, value);
|
||||||
const float Options::MUSIC_MIN_VALUE = 0.0f;
|
}
|
||||||
const float Options::MUSIC_MAX_VALUE = 1.0f;
|
}
|
||||||
const float Options::SENSITIVITY_MIN_VALUE = 0.0f;
|
|
||||||
const float Options::SENSITIVITY_MAX_VALUE = 1.0f;
|
|
||||||
const float Options::PIXELS_PER_MILLIMETER_MIN_VALUE = 3.0f;
|
|
||||||
const float Options::PIXELS_PER_MILLIMETER_MAX_VALUE = 4.0f;
|
|
||||||
const int DIFFICULY_LEVELS[] = {
|
|
||||||
Difficulty::PEACEFUL,
|
|
||||||
Difficulty::NORMAL
|
|
||||||
};
|
|
||||||
|
|
||||||
/*private*/
|
void Options::set(OptionId key, float value) {
|
||||||
const char* Options::RENDER_DISTANCE_NAMES[] = {
|
auto option = opt<OptionFloat>(key);
|
||||||
"options.renderDistance.far",
|
|
||||||
"options.renderDistance.normal",
|
|
||||||
"options.renderDistance.short",
|
|
||||||
"options.renderDistance.tiny"
|
|
||||||
};
|
|
||||||
|
|
||||||
/*private*/
|
if (option) {
|
||||||
const char* Options::DIFFICULTY_NAMES[] = {
|
option->set(value);
|
||||||
"options.difficulty.peaceful",
|
notifyOptionUpdate(key, value);
|
||||||
"options.difficulty.easy",
|
}
|
||||||
"options.difficulty.normal",
|
}
|
||||||
"options.difficulty.hard"
|
|
||||||
};
|
|
||||||
|
|
||||||
/*private*/
|
void Options::set(OptionId key, int value) {
|
||||||
const char* Options::GUI_SCALE[] = {
|
auto option = opt<OptionInt>(key);
|
||||||
"options.guiScale.auto",
|
|
||||||
"options.guiScale.small",
|
|
||||||
"options.guiScale.normal",
|
|
||||||
"options.guiScale.large"
|
|
||||||
};
|
|
||||||
|
|
||||||
void Options::update()
|
if (option) {
|
||||||
{
|
option->set(value);
|
||||||
viewDistance = 2;
|
notifyOptionUpdate(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Options::toggle(OptionId key) {
|
||||||
|
auto option = opt<OptionBool>(key);
|
||||||
|
|
||||||
|
if (option) {
|
||||||
|
option->toggle();
|
||||||
|
notifyOptionUpdate(key, option->get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Options::load() {
|
||||||
StringVector optionStrings = optionsFile.getOptionStrings();
|
StringVector optionStrings = optionsFile.getOptionStrings();
|
||||||
for (unsigned int i = 0; i < optionStrings.size(); i += 2) {
|
|
||||||
|
for (auto i = 0; i < optionStrings.size(); i += 2) {
|
||||||
const std::string& key = optionStrings[i];
|
const std::string& key = optionStrings[i];
|
||||||
const std::string& value = optionStrings[i+1];
|
const std::string& value = optionStrings[i+1];
|
||||||
|
|
||||||
//LOGI("reading key: %s (%s)\n", key.c_str(), value.c_str());
|
// FIXME: woah this is so slow
|
||||||
|
auto opt = std::find_if(m_options.begin(), m_options.end(), [&](auto& it) {
|
||||||
|
return it != nullptr && it->getStringId() == key;
|
||||||
|
});
|
||||||
|
|
||||||
// Multiplayer
|
if (opt == m_options.end()) continue;
|
||||||
if (key == OptionStrings::Multiplayer_Username) username = value;
|
|
||||||
if (key == OptionStrings::Multiplayer_ServerVisible) readBool(value, serverVisible);
|
|
||||||
|
|
||||||
// Controls
|
(*opt)->parse(value);
|
||||||
if (key == OptionStrings::Controls_Sensitivity) {
|
/*
|
||||||
float sens;
|
// //LOGI("reading key: %s (%s)\n", key.c_str(), value.c_str());
|
||||||
if (readFloat(value, sens)) {
|
|
||||||
// sens is in range [0,1] with default/center at 0.5 (for aesthetics)
|
|
||||||
// We wanna map it to something like [0.3, 0.9] BUT keep 0.5 @ ~0.5...
|
|
||||||
sensitivity = 0.3f + std::pow(1.1f * sens, 1.3f) * 0.42f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (key == OptionStrings::Controls_InvertMouse) {
|
|
||||||
readBool(value, invertYMouse);
|
|
||||||
}
|
|
||||||
if (key == OptionStrings::Controls_IsLefthanded) {
|
|
||||||
readBool(value, isLeftHanded);
|
|
||||||
}
|
|
||||||
if (key == OptionStrings::Controls_UseTouchJoypad) {
|
|
||||||
readBool(value, isJoyTouchArea);
|
|
||||||
if (!minecraft->useTouchscreen())
|
|
||||||
isJoyTouchArea = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Feedback
|
// // Multiplayer
|
||||||
if (key == OptionStrings::Controls_FeedbackVibration)
|
// // if (key == OptionStrings::Multiplayer_Username) username = value;
|
||||||
readBool(value, destroyVibration);
|
// if (key == OptionStrings::Multiplayer_ServerVisible) {
|
||||||
|
// m_options[OPTIONS_SERVER_VISIBLE] = readBool(value);
|
||||||
// Graphics
|
|
||||||
if (key == OptionStrings::Graphics_Fancy) {
|
|
||||||
readBool(value, fancyGraphics);
|
|
||||||
}
|
|
||||||
if (key == OptionStrings::Graphics_LowQuality) {
|
|
||||||
bool isLow;
|
|
||||||
readBool(value, isLow);
|
|
||||||
if (isLow) {
|
|
||||||
viewDistance = 3;
|
|
||||||
fancyGraphics = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Game
|
|
||||||
if (key == OptionStrings::Game_DifficultyLevel) {
|
|
||||||
readInt(value, difficulty);
|
|
||||||
// Only support peaceful and normal right now
|
|
||||||
if (difficulty != Difficulty::PEACEFUL && difficulty != Difficulty::NORMAL)
|
|
||||||
difficulty = Difficulty::NORMAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
// if (minecraft->isSuperFast()) {
|
|
||||||
// viewDistance = (viewDistance>0)? --viewDistance : 0;
|
|
||||||
// }
|
// }
|
||||||
// LOGI("Is this card super fast?: %d\n", viewDistance);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//LOGI("Lefty is: %d\n", isLeftHanded);
|
// // Controls
|
||||||
|
// if (key == OptionStrings::Controls_Sensitivity) {
|
||||||
|
// float sens = readFloat(value);
|
||||||
|
|
||||||
|
// // sens is in range [0,1] with default/center at 0.5 (for aesthetics)
|
||||||
|
// // We wanna map it to something like [0.3, 0.9] BUT keep 0.5 @ ~0.5...
|
||||||
|
// m_options[OPTIONS_SENSITIVITY] = 0.3f + std::pow(1.1f * sens, 1.3f) * 0.42f;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (key == OptionStrings::Controls_InvertMouse) {
|
||||||
|
// m_options[OPTIONS_INVERT_Y_MOUSE] = readBool(value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (key == OptionStrings::Controls_IsLefthanded) {
|
||||||
|
// m_options[OPTIONS_IS_LEFT_HANDED] = readBool(value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (key == OptionStrings::Controls_UseTouchJoypad) {
|
||||||
|
// m_options[OPTIONS_IS_JOY_TOUCH_AREA] = readBool(value) && minecraft->useTouchscreen();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Feedback
|
||||||
|
// if (key == OptionStrings::Controls_FeedbackVibration) {
|
||||||
|
// m_options[OPTIONS_DESTROY_VIBRATION] = readBool(value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Graphics
|
||||||
|
// if (key == OptionStrings::Graphics_Fancy) {
|
||||||
|
// m_options[OPTIONS_FANCY_GRAPHICS] = readBool(value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Graphics extras
|
||||||
|
// if (key == OptionStrings::Graphics_Vsync) {
|
||||||
|
// m_options[OPTIONS_VSYNC] = readBool(value);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (key == OptionStrings::Graphics_GUIScale) {
|
||||||
|
// m_options[OPTIONS_GUI_SCALE] = readInt(value) % 5;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Game
|
||||||
|
// if (key == OptionStrings::Game_DifficultyLevel) {
|
||||||
|
// readInt(value, difficulty);
|
||||||
|
// // Only support peaceful and normal right now
|
||||||
|
// if (difficulty != Difficulty::PEACEFUL && difficulty != Difficulty::NORMAL)
|
||||||
|
// difficulty = Difficulty::NORMAL;
|
||||||
|
// }*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Options::load()
|
void Options::save() {
|
||||||
{
|
|
||||||
int a = 0;
|
|
||||||
//try {
|
|
||||||
// if (!optionsFile.exists()) return;
|
|
||||||
// BufferedReader br = /*new*/ BufferedReader(/*new*/ FileReader(optionsFile));
|
|
||||||
// std::string line = "";
|
|
||||||
// while ((line = br.readLine()) != NULL) {
|
|
||||||
// std::string[] cmds = line.split(":");
|
|
||||||
// if (cmds[0].equals("music")) music = readFloat(cmds[1]);
|
|
||||||
// if (cmds[0].equals("sound")) sound = readFloat(cmds[1]);
|
|
||||||
// if (cmds[0].equals("mouseSensitivity")) sensitivity = readFloat(cmds[1]);
|
|
||||||
// if (cmds[0].equals("invertYMouse")) invertYMouse = cmds[1].equals("true");
|
|
||||||
// if (cmds[0].equals("viewDistance")) viewDistance = Integer.parseInt(cmds[1]);
|
|
||||||
// if (cmds[0].equals("guiScale")) guiScale = Integer.parseInt(cmds[1]);
|
|
||||||
// if (cmds[0].equals("bobView")) bobView = cmds[1].equals("true");
|
|
||||||
// if (cmds[0].equals("anaglyph3d")) anaglyph3d = cmds[1].equals("true");
|
|
||||||
// if (cmds[0].equals("limitFramerate")) limitFramerate = cmds[1].equals("true");
|
|
||||||
// if (cmds[0].equals("difficulty")) difficulty = Integer.parseInt(cmds[1]);
|
|
||||||
// if (cmds[0].equals("fancyGraphics")) fancyGraphics = cmds[1].equals("true");
|
|
||||||
// if (cmds[0].equals("ao")) ambientOcclusion = cmds[1].equals("true");
|
|
||||||
// if (cmds[0].equals("skin")) skin = cmds[1];
|
|
||||||
// if (cmds[0].equals("lastServer") && cmds.length >= 2) lastMpIp = cmds[1];
|
|
||||||
|
|
||||||
// for (int i = 0; i < keyMappings.length; i++) {
|
|
||||||
// if (cmds[0].equals("key_" + keyMappings[i].name)) {
|
|
||||||
// keyMappings[i].key = Integer.parseInt(cmds[1]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// br.close();
|
|
||||||
//} catch (Exception e) {
|
|
||||||
// System.out.println("Failed to load options");
|
|
||||||
// e.printStackTrace();
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Options::save()
|
|
||||||
{
|
|
||||||
StringVector stringVec;
|
StringVector stringVec;
|
||||||
// Game
|
|
||||||
addOptionToSaveOutput(stringVec, OptionStrings::Multiplayer_ServerVisible, serverVisible);
|
|
||||||
addOptionToSaveOutput(stringVec, OptionStrings::Game_DifficultyLevel, difficulty);
|
|
||||||
|
|
||||||
// Input
|
for (auto& it : m_options) {
|
||||||
addOptionToSaveOutput(stringVec, OptionStrings::Controls_InvertMouse, invertYMouse);
|
if (it) stringVec.push_back(it->serialize());
|
||||||
addOptionToSaveOutput(stringVec, OptionStrings::Controls_Sensitivity, sensitivity);
|
|
||||||
addOptionToSaveOutput(stringVec, OptionStrings::Controls_IsLefthanded, isLeftHanded);
|
|
||||||
addOptionToSaveOutput(stringVec, OptionStrings::Controls_UseTouchScreen, useTouchScreen);
|
|
||||||
addOptionToSaveOutput(stringVec, OptionStrings::Controls_UseTouchJoypad, isJoyTouchArea);
|
|
||||||
addOptionToSaveOutput(stringVec, OptionStrings::Controls_FeedbackVibration, destroyVibration);
|
|
||||||
//
|
|
||||||
// static const Option MUSIC;
|
|
||||||
// static const Option SOUND;
|
|
||||||
// static const Option INVERT_MOUSE;
|
|
||||||
// static const Option SENSITIVITY;
|
|
||||||
// static const Option RENDER_DISTANCE;
|
|
||||||
// static const Option VIEW_BOBBING;
|
|
||||||
// static const Option ANAGLYPH;
|
|
||||||
// static const Option LIMIT_FRAMERATE;
|
|
||||||
// static const Option DIFFICULTY;
|
|
||||||
// static const Option GRAPHICS;
|
|
||||||
// static const Option AMBIENT_OCCLUSION;
|
|
||||||
// static const Option GUI_SCALE;
|
|
||||||
//
|
|
||||||
// static const Option THIRD_PERSON;
|
|
||||||
// static const Option HIDE_GUI;
|
|
||||||
//try {
|
|
||||||
// PrintWriter pw = /*new*/ PrintWriter(/*new*/ FileWriter(optionsFile));
|
|
||||||
|
|
||||||
// pw.println("music:" + music);
|
|
||||||
// pw.println("sound:" + sound);
|
|
||||||
// pw.println("invertYMouse:" + invertYMouse);
|
|
||||||
// pw.println("mouseSensitivity:" + sensitivity);
|
|
||||||
// pw.println("viewDistance:" + viewDistance);
|
|
||||||
// pw.println("guiScale:" + guiScale);
|
|
||||||
// pw.println("bobView:" + bobView);
|
|
||||||
// pw.println("anaglyph3d:" + anaglyph3d);
|
|
||||||
// pw.println("limitFramerate:" + limitFramerate);
|
|
||||||
// pw.println("difficulty:" + difficulty);
|
|
||||||
// pw.println("fancyGraphics:" + fancyGraphics);
|
|
||||||
// pw.println("ao:" + ambientOcclusion);
|
|
||||||
// pw.println("skin:" + skin);
|
|
||||||
// pw.println("lastServer:" + lastMpIp);
|
|
||||||
|
|
||||||
// for (int i = 0; i < keyMappings.length; i++) {
|
|
||||||
// pw.println("key_" + keyMappings[i].name + ":" + keyMappings[i].key);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pw.close();
|
|
||||||
//} catch (Exception e) {
|
|
||||||
// System.out.println("Failed to save options");
|
|
||||||
// e.printStackTrace();
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
void Options::addOptionToSaveOutput(StringVector& stringVector, std::string name, bool boolValue) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << name << ":" << boolValue;
|
|
||||||
stringVector.push_back(ss.str());
|
|
||||||
}
|
|
||||||
void Options::addOptionToSaveOutput(StringVector& stringVector, std::string name, float floatValue) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << name << ":" << floatValue;
|
|
||||||
stringVector.push_back(ss.str());
|
|
||||||
}
|
|
||||||
void Options::addOptionToSaveOutput(StringVector& stringVector, std::string name, int intValue) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << name << ":" << intValue;
|
|
||||||
stringVector.push_back(ss.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Options::getMessage( const Option* item )
|
optionsFile.save(stringVec);
|
||||||
{
|
|
||||||
return "Options::getMessage - Not implemented";
|
|
||||||
|
|
||||||
//Language language = Language.getInstance();
|
|
||||||
//std::string caption = language.getElement(item.getCaptionId()) + ": ";
|
|
||||||
|
|
||||||
//if (item.isProgress()) {
|
|
||||||
// float progressValue = getProgressValue(item);
|
|
||||||
|
|
||||||
// if (item == Option.SENSITIVITY) {
|
|
||||||
// if (progressValue == 0) {
|
|
||||||
// return caption + language.getElement("options.sensitivity.min");
|
|
||||||
// }
|
|
||||||
// if (progressValue == 1) {
|
|
||||||
// return caption + language.getElement("options.sensitivity.max");
|
|
||||||
// }
|
|
||||||
// return caption + (int) (progressValue * 200) + "%";
|
|
||||||
// } else {
|
|
||||||
// if (progressValue == 0) {
|
|
||||||
// return caption + language.getElement("options.off");
|
|
||||||
// }
|
|
||||||
// return caption + (int) (progressValue * 100) + "%";
|
|
||||||
// }
|
|
||||||
//} else if (item.isBoolean()) {
|
|
||||||
|
|
||||||
// bool booleanValue = getBooleanValue(item);
|
|
||||||
// if (booleanValue) {
|
|
||||||
// return caption + language.getElement("options.on");
|
|
||||||
// }
|
|
||||||
// return caption + language.getElement("options.off");
|
|
||||||
//} else if (item == Option.RENDER_DISTANCE) {
|
|
||||||
// return caption + language.getElement(RENDER_DISTANCE_NAMES[viewDistance]);
|
|
||||||
//} else if (item == Option.DIFFICULTY) {
|
|
||||||
// return caption + language.getElement(DIFFICULTY_NAMES[difficulty]);
|
|
||||||
//} else if (item == Option.GUI_SCALE) {
|
|
||||||
// return caption + language.getElement(GUI_SCALE[guiScale]);
|
|
||||||
//} else if (item == Option.GRAPHICS) {
|
|
||||||
// if (fancyGraphics) {
|
|
||||||
// return caption + language.getElement("options.graphics.fancy");
|
|
||||||
// }
|
|
||||||
// return caption + language.getElement("options.graphics.fast");
|
|
||||||
//}
|
|
||||||
|
|
||||||
//return caption;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/
|
void Options::notifyOptionUpdate(OptionId key, bool value) {
|
||||||
bool Options::readFloat(const std::string& string, float& value) {
|
minecraft->optionUpdated(key, value);
|
||||||
if (string == "true" || string == "YES") { value = 1; return true; }
|
|
||||||
if (string == "false" || string == "NO") { value = 0; return true; }
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (sscanf_s(string.c_str(), "%f", &value))
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
if (sscanf(string.c_str(), "%f", &value))
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/
|
void Options::notifyOptionUpdate(OptionId key, float value) {
|
||||||
bool Options::readInt(const std::string& string, int& value) {
|
minecraft->optionUpdated(key, value);
|
||||||
if (string == "true" || string == "YES") { value = 1; return true; }
|
|
||||||
if (string == "false" || string == "NO") { value = 0; return true; }
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (sscanf_s(string.c_str(), "%d", &value))
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
if (sscanf(string.c_str(), "%d", &value))
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/
|
void Options::notifyOptionUpdate(OptionId key, int value) {
|
||||||
bool Options::readBool(const std::string& string, bool& value) {
|
minecraft->optionUpdated(key, value);
|
||||||
std::string s = Util::stringTrim(string);
|
|
||||||
if (string == "true" || string == "1" || string == "YES") { value = true; return true; }
|
|
||||||
if (string == "false" || string == "0" || string == "NO") { value = false; return true; }
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Options::notifyOptionUpdate( const Option* option, bool value ) {
|
|
||||||
minecraft->optionUpdated(option, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Options::notifyOptionUpdate( const Option* option, float value ) {
|
|
||||||
minecraft->optionUpdated(option, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Options::notifyOptionUpdate( const Option* option, int value ) {
|
|
||||||
minecraft->optionUpdated(option, value);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,328 +1,166 @@
|
|||||||
#ifndef NET_MINECRAFT_CLIENT__Options_H__
|
#ifndef NET_MINECRAFT_CLIENT__Options_H__
|
||||||
#define NET_MINECRAFT_CLIENT__Options_H__
|
#define NET_MINECRAFT_CLIENT__Options_H__
|
||||||
|
|
||||||
|
#define SOUND_MIN_VALUE 0.0f
|
||||||
|
#define SOUND_MAX_VALUE 1.0f
|
||||||
|
#define MUSIC_MIN_VALUE 0.0f
|
||||||
|
#define MUSIC_MAX_VALUE 1.0f
|
||||||
|
#define SENSITIVITY_MIN_VALUE 0.0f
|
||||||
|
#define SENSITIVITY_MAX_VALUE 1.0f
|
||||||
|
#define PIXELS_PER_MILLIMETER_MIN_VALUE 3.0f
|
||||||
|
#define PIXELS_PER_MILLIMETER_MAX_VALUE 4.0f
|
||||||
|
|
||||||
//package net.minecraft.client;
|
//package net.minecraft.client;
|
||||||
|
|
||||||
//#include "locale/Language.h"
|
//#include "locale/Language.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include "KeyMapping.h"
|
|
||||||
#include "../platform/input/Keyboard.h"
|
#include "../platform/input/Keyboard.h"
|
||||||
#include "../util/StringUtils.h"
|
#include "../util/StringUtils.h"
|
||||||
#include "OptionsFile.h"
|
#include "OptionsFile.h"
|
||||||
|
#include "Option.h"
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
enum OptionId {
|
||||||
|
// General
|
||||||
|
OPTIONS_DIFFICULTY,
|
||||||
|
OPTIONS_HIDEGUI,
|
||||||
|
OPTIONS_THIRD_PERSON_VIEW,
|
||||||
|
OPTIONS_GUI_SCALE,
|
||||||
|
OPTIONS_DESTROY_VIBRATION,
|
||||||
|
OPTIONS_MUSIC_VOLUME,
|
||||||
|
OPTIONS_SOUND_VOLUME,
|
||||||
|
OPTIONS_SKIN,
|
||||||
|
OPTIONS_USERNAME,
|
||||||
|
OPTIONS_SERVER_VISIBLE,
|
||||||
|
OPTIONS_BAR_ON_TOP,
|
||||||
|
OPTIONS_ALLOW_SPRINT,
|
||||||
|
OPTIONS_AUTOJUMP,
|
||||||
|
|
||||||
|
// Graphics
|
||||||
|
OPTIONS_RENDER_DEBUG,
|
||||||
|
OPTIONS_SMOOTH_CAMERA,
|
||||||
|
OPTIONS_FIXED_CAMERA,
|
||||||
|
OPTIONS_VIEW_DISTANCE,
|
||||||
|
OPTIONS_VIEW_BOBBING,
|
||||||
|
OPTIONS_AMBIENT_OCCLUSION,
|
||||||
|
OPTIONS_ANAGLYPH_3D,
|
||||||
|
OPTIONS_LIMIT_FRAMERATE,
|
||||||
|
OPTIONS_VSYNC,
|
||||||
|
OPTIONS_FANCY_GRAPHICS,
|
||||||
|
|
||||||
|
// Cheats / debug
|
||||||
|
OPTIONS_FLY_SPEED,
|
||||||
|
OPTIONS_CAMERA_SPEED,
|
||||||
|
OPTIONS_IS_FLYING,
|
||||||
|
|
||||||
|
// Control
|
||||||
|
OPTIONS_USE_MOUSE_FOR_DIGGING,
|
||||||
|
OPTIONS_IS_LEFT_HANDED,
|
||||||
|
OPTIONS_IS_JOY_TOUCH_AREA,
|
||||||
|
OPTIONS_SENSITIVITY,
|
||||||
|
OPTIONS_INVERT_Y_MOUSE,
|
||||||
|
OPTIONS_USE_TOUCHSCREEN,
|
||||||
|
|
||||||
|
OPTIONS_KEY_FORWARD,
|
||||||
|
OPTIONS_KEY_LEFT,
|
||||||
|
OPTIONS_KEY_BACK,
|
||||||
|
OPTIONS_KEY_RIGHT,
|
||||||
|
OPTIONS_KEY_JUMP,
|
||||||
|
OPTIONS_KEY_INVENTORY,
|
||||||
|
OPTIONS_KEY_SNEAK,
|
||||||
|
OPTIONS_KEY_DROP,
|
||||||
|
OPTIONS_KEY_CHAT,
|
||||||
|
OPTIONS_KEY_FOG,
|
||||||
|
OPTIONS_KEY_USE,
|
||||||
|
|
||||||
|
OPTIONS_KEY_MENU_NEXT,
|
||||||
|
OPTIONS_KEY_MENU_PREV,
|
||||||
|
OPTIONS_KEY_MENU_OK,
|
||||||
|
OPTIONS_KEY_MENU_CANCEL,
|
||||||
|
|
||||||
|
OPTIONS_FIRST_LAUNCH,
|
||||||
|
OPTIONS_LAST_IP,
|
||||||
|
|
||||||
|
// Should be last!
|
||||||
|
OPTIONS_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
class Minecraft;
|
class Minecraft;
|
||||||
typedef std::vector<std::string> StringVector;
|
typedef std::vector<std::string> StringVector;
|
||||||
|
|
||||||
class Options
|
class Options
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
class Option
|
|
||||||
{
|
|
||||||
const bool _isProgress;
|
|
||||||
const bool _isBoolean;
|
|
||||||
const std::string _captionId;
|
|
||||||
const int _ordinal;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const Option MUSIC;
|
|
||||||
static const Option SOUND;
|
|
||||||
static const Option INVERT_MOUSE;
|
|
||||||
static const Option SENSITIVITY;
|
|
||||||
static const Option RENDER_DISTANCE;
|
|
||||||
static const Option VIEW_BOBBING;
|
|
||||||
static const Option ANAGLYPH;
|
|
||||||
static const Option LIMIT_FRAMERATE;
|
|
||||||
static const Option DIFFICULTY;
|
|
||||||
static const Option GRAPHICS;
|
|
||||||
static const Option AMBIENT_OCCLUSION;
|
|
||||||
static const Option GUI_SCALE;
|
|
||||||
|
|
||||||
static const Option THIRD_PERSON;
|
|
||||||
static const Option HIDE_GUI;
|
|
||||||
static const Option SERVER_VISIBLE;
|
|
||||||
static const Option LEFT_HANDED;
|
|
||||||
static const Option USE_TOUCHSCREEN;
|
|
||||||
static const Option USE_TOUCH_JOYPAD;
|
|
||||||
static const Option DESTROY_VIBRATION;
|
|
||||||
|
|
||||||
static const Option PIXELS_PER_MILLIMETER;
|
|
||||||
|
|
||||||
/*
|
|
||||||
static Option* getItem(int id) {
|
|
||||||
for (Option item : Option.values()) {
|
|
||||||
if (item.getId() == id) {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Option(int ordinal, const std::string& captionId, bool hasProgress, bool isBoolean)
|
|
||||||
: _captionId(captionId),
|
|
||||||
_isProgress(hasProgress),
|
|
||||||
_isBoolean(isBoolean),
|
|
||||||
_ordinal(ordinal)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool isProgress() const {
|
|
||||||
return _isProgress;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isBoolean() const {
|
|
||||||
return _isBoolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isInt() const {
|
|
||||||
return (!_isBoolean && !_isProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getId() {
|
|
||||||
return _ordinal;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getCaptionId() const {
|
|
||||||
return _captionId;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const float SOUND_MIN_VALUE;
|
|
||||||
static const float SOUND_MAX_VALUE;
|
|
||||||
static const float MUSIC_MIN_VALUE;
|
|
||||||
static const float MUSIC_MAX_VALUE;
|
|
||||||
static const float SENSITIVITY_MIN_VALUE;
|
|
||||||
static const float SENSITIVITY_MAX_VALUE;
|
|
||||||
static const float PIXELS_PER_MILLIMETER_MIN_VALUE;
|
|
||||||
static const float PIXELS_PER_MILLIMETER_MAX_VALUE;
|
|
||||||
static const char* RENDER_DISTANCE_NAMES[];
|
|
||||||
static const char* DIFFICULTY_NAMES[];
|
|
||||||
static const char* GUI_SCALE[];
|
|
||||||
static const int DIFFICULY_LEVELS[];
|
|
||||||
public:
|
public:
|
||||||
static bool debugGl;
|
static bool debugGl;
|
||||||
|
|
||||||
float music;
|
Options(Minecraft* minecraft, const std::string& workingDirectory = "")
|
||||||
float sound;
|
: minecraft(minecraft) {
|
||||||
//note: sensitivity is transformed in Options::update
|
// elements werent initialized so i was getting a garbage pointer and a crash
|
||||||
float sensitivity;
|
m_options.fill(nullptr);
|
||||||
bool invertYMouse;
|
initTable();
|
||||||
int viewDistance;
|
|
||||||
bool bobView;
|
|
||||||
bool anaglyph3d;
|
|
||||||
bool limitFramerate;
|
|
||||||
bool fancyGraphics;
|
|
||||||
bool ambientOcclusion;
|
|
||||||
bool useMouseForDigging;
|
|
||||||
bool isLeftHanded;
|
|
||||||
bool destroyVibration;
|
|
||||||
//std::string skin;
|
|
||||||
|
|
||||||
KeyMapping keyUp;
|
|
||||||
KeyMapping keyLeft;
|
|
||||||
KeyMapping keyDown;
|
|
||||||
KeyMapping keyRight;
|
|
||||||
KeyMapping keyJump;
|
|
||||||
KeyMapping keyBuild;
|
|
||||||
KeyMapping keyDrop;
|
|
||||||
KeyMapping keyChat;
|
|
||||||
KeyMapping keyFog;
|
|
||||||
KeyMapping keySneak;
|
|
||||||
KeyMapping keyCraft;
|
|
||||||
KeyMapping keyDestroy;
|
|
||||||
KeyMapping keyUse;
|
|
||||||
|
|
||||||
KeyMapping keyMenuNext;
|
|
||||||
KeyMapping keyMenuPrevious;
|
|
||||||
KeyMapping keyMenuOk;
|
|
||||||
KeyMapping keyMenuCancel;
|
|
||||||
|
|
||||||
KeyMapping* keyMappings[16];
|
|
||||||
|
|
||||||
/*protected*/ Minecraft* minecraft;
|
|
||||||
///*private*/ File optionsFile;
|
|
||||||
|
|
||||||
int difficulty;
|
|
||||||
bool hideGui;
|
|
||||||
bool thirdPersonView;
|
|
||||||
bool renderDebug;
|
|
||||||
|
|
||||||
bool isFlying;
|
|
||||||
bool smoothCamera;
|
|
||||||
bool fixedCamera;
|
|
||||||
float flySpeed;
|
|
||||||
float cameraSpeed;
|
|
||||||
int guiScale;
|
|
||||||
std::string username;
|
|
||||||
|
|
||||||
bool serverVisible;
|
|
||||||
bool isJoyTouchArea;
|
|
||||||
bool useTouchScreen;
|
|
||||||
float pixelsPerMillimeter;
|
|
||||||
Options(Minecraft* minecraft, const std::string& workingDirectory)
|
|
||||||
: minecraft(minecraft)
|
|
||||||
{
|
|
||||||
//optionsFile = /*new*/ File(workingDirectory, "options.txt");
|
|
||||||
initDefaultValues();
|
|
||||||
|
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
Options()
|
void initTable();
|
||||||
: minecraft(NULL)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
void set(OptionId key, int value);
|
||||||
|
void set(OptionId key, float value);
|
||||||
|
void set(OptionId key, const std::string& value);
|
||||||
|
void toggle(OptionId key);
|
||||||
|
|
||||||
|
int getIntValue(OptionId key) {
|
||||||
|
auto option = opt<OptionInt>(key);
|
||||||
|
return (option)? option->get() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initDefaultValues();
|
std::string getStringValue(OptionId key) {
|
||||||
|
auto option = opt<OptionString>(key);
|
||||||
std::string getKeyDescription(int i) {
|
return (option)? option->get() : "";
|
||||||
//Language language = Language.getInstance();
|
|
||||||
//return language.getElement(keyMappings[i].name);
|
|
||||||
return "Options::getKeyDescription not implemented";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getKeyMessage(int i) {
|
float getProgressValue(OptionId key) {
|
||||||
//return Keyboard.getKeyName(keyMappings[i].key);
|
auto option = opt<OptionFloat>(key);
|
||||||
return "Options::getKeyMessage not implemented";
|
return (option)? option->get() : 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setKey(int i, int key) {
|
bool getBooleanValue(OptionId key) {
|
||||||
keyMappings[i]->key = key;
|
auto option = opt<OptionBool>(key);
|
||||||
save();
|
return (option)? option->get() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(const Option* item, float value) {
|
float getProgrssMin(OptionId key) {
|
||||||
if (item == &Option::MUSIC) {
|
auto option = opt<OptionFloat>(key);
|
||||||
music = value;
|
return (option)? option->getMin() : 0.f;
|
||||||
//minecraft.soundEngine.updateOptions();
|
|
||||||
} else if (item == &Option::SOUND) {
|
|
||||||
sound = value;
|
|
||||||
//minecraft.soundEngine.updateOptions();
|
|
||||||
} else if (item == &Option::SENSITIVITY) {
|
|
||||||
sensitivity = value;
|
|
||||||
} else if (item == &Option::PIXELS_PER_MILLIMETER) {
|
|
||||||
pixelsPerMillimeter = value;
|
|
||||||
}
|
|
||||||
notifyOptionUpdate(item, value);
|
|
||||||
}
|
|
||||||
void set(const Option* item, int value) {
|
|
||||||
if(item == &Option::DIFFICULTY) {
|
|
||||||
difficulty = value;
|
|
||||||
}
|
|
||||||
notifyOptionUpdate(item, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggle(const Option* option, int dir) {
|
float getProgrssMax(OptionId key) {
|
||||||
if (option == &Option::INVERT_MOUSE) invertYMouse = !invertYMouse;
|
auto option = opt<OptionFloat>(key);
|
||||||
if (option == &Option::RENDER_DISTANCE) viewDistance = (viewDistance + dir) & 3;
|
return (option)? option->getMax() : 0.f;
|
||||||
if (option == &Option::GUI_SCALE) guiScale = (guiScale + dir) & 3;
|
|
||||||
if (option == &Option::VIEW_BOBBING) bobView = !bobView;
|
|
||||||
if (option == &Option::THIRD_PERSON) thirdPersonView = !thirdPersonView;
|
|
||||||
if (option == &Option::HIDE_GUI) hideGui = !hideGui;
|
|
||||||
if (option == &Option::SERVER_VISIBLE) serverVisible = !serverVisible;
|
|
||||||
if (option == &Option::LEFT_HANDED) isLeftHanded = !isLeftHanded;
|
|
||||||
if (option == &Option::USE_TOUCHSCREEN) useTouchScreen = !useTouchScreen;
|
|
||||||
if (option == &Option::USE_TOUCH_JOYPAD) isJoyTouchArea = !isJoyTouchArea;
|
|
||||||
if (option == &Option::DESTROY_VIBRATION) destroyVibration = !destroyVibration;
|
|
||||||
if (option == &Option::ANAGLYPH) {
|
|
||||||
anaglyph3d = !anaglyph3d;
|
|
||||||
//minecraft->textures.reloadAll();
|
|
||||||
}
|
|
||||||
if (option == &Option::LIMIT_FRAMERATE) limitFramerate = !limitFramerate;
|
|
||||||
if (option == &Option::DIFFICULTY) difficulty = (difficulty + dir) & 3;
|
|
||||||
if (option == &Option::GRAPHICS) {
|
|
||||||
fancyGraphics = !fancyGraphics;
|
|
||||||
//minecraft->levelRenderer.allChanged();
|
|
||||||
}
|
|
||||||
if (option == &Option::AMBIENT_OCCLUSION) {
|
|
||||||
ambientOcclusion = !ambientOcclusion;
|
|
||||||
//minecraft->levelRenderer.allChanged();
|
|
||||||
}
|
|
||||||
notifyOptionUpdate(option, getBooleanValue(option));
|
|
||||||
save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int getIntValue(const Option* item) {
|
Option* getOpt(OptionId id) { return m_options[id]; }
|
||||||
if(item == &Option::DIFFICULTY) return difficulty;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getProgressValue(const Option* item) {
|
|
||||||
if (item == &Option::MUSIC) return music;
|
|
||||||
if (item == &Option::SOUND) return sound;
|
|
||||||
if (item == &Option::SENSITIVITY) return sensitivity;
|
|
||||||
if (item == &Option::PIXELS_PER_MILLIMETER) return pixelsPerMillimeter;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getBooleanValue(const Option* item) {
|
|
||||||
if (item == &Option::INVERT_MOUSE)
|
|
||||||
return invertYMouse;
|
|
||||||
if (item == &Option::VIEW_BOBBING)
|
|
||||||
return bobView;
|
|
||||||
if (item == &Option::ANAGLYPH)
|
|
||||||
return anaglyph3d;
|
|
||||||
if (item == &Option::LIMIT_FRAMERATE)
|
|
||||||
return limitFramerate;
|
|
||||||
if (item == &Option::AMBIENT_OCCLUSION)
|
|
||||||
return ambientOcclusion;
|
|
||||||
if (item == &Option::THIRD_PERSON)
|
|
||||||
return thirdPersonView;
|
|
||||||
if (item == &Option::HIDE_GUI)
|
|
||||||
return hideGui;
|
|
||||||
if (item == &Option::THIRD_PERSON)
|
|
||||||
return thirdPersonView;
|
|
||||||
if (item == &Option::SERVER_VISIBLE)
|
|
||||||
return serverVisible;
|
|
||||||
if (item == &Option::LEFT_HANDED)
|
|
||||||
return isLeftHanded;
|
|
||||||
if (item == &Option::USE_TOUCHSCREEN)
|
|
||||||
return useTouchScreen;
|
|
||||||
if (item == &Option::USE_TOUCH_JOYPAD)
|
|
||||||
return isJoyTouchArea;
|
|
||||||
if (item == &Option::DESTROY_VIBRATION)
|
|
||||||
return destroyVibration;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getProgrssMin(const Option* item) {
|
|
||||||
if (item == &Option::MUSIC) return MUSIC_MIN_VALUE;
|
|
||||||
if (item == &Option::SOUND) return SOUND_MIN_VALUE;
|
|
||||||
if (item == &Option::SENSITIVITY) return SENSITIVITY_MIN_VALUE;
|
|
||||||
if (item == &Option::PIXELS_PER_MILLIMETER) return PIXELS_PER_MILLIMETER_MIN_VALUE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getProgrssMax(const Option* item) {
|
|
||||||
if (item == &Option::MUSIC) return MUSIC_MAX_VALUE;
|
|
||||||
if (item == &Option::SOUND) return SOUND_MAX_VALUE;
|
|
||||||
if (item == &Option::SENSITIVITY) return SENSITIVITY_MAX_VALUE;
|
|
||||||
if (item == &Option::PIXELS_PER_MILLIMETER) return PIXELS_PER_MILLIMETER_MAX_VALUE;
|
|
||||||
return 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getMessage(const Option* item);
|
|
||||||
|
|
||||||
void update();
|
|
||||||
void load();
|
void load();
|
||||||
void save();
|
void save();
|
||||||
void addOptionToSaveOutput(StringVector& stringVector, std::string name, bool boolValue);
|
|
||||||
void addOptionToSaveOutput(StringVector& stringVector, std::string name, float floatValue);
|
void notifyOptionUpdate(OptionId key, bool value);
|
||||||
void addOptionToSaveOutput(StringVector& stringVector, std::string name, int intValue);
|
void notifyOptionUpdate(OptionId key, float value);
|
||||||
void notifyOptionUpdate(const Option* option, bool value);
|
void notifyOptionUpdate(OptionId key, int value);
|
||||||
void notifyOptionUpdate(const Option* option, float value);
|
void notifyOptionUpdate(OptionId key, const std::string& value) {}
|
||||||
void notifyOptionUpdate(const Option* option, int value);
|
|
||||||
private:
|
|
||||||
static bool readFloat(const std::string& string, float& value);
|
|
||||||
static bool readInt(const std::string& string, int& value);
|
|
||||||
static bool readBool(const std::string& string, bool& value);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template<typename T>
|
||||||
|
T* opt(OptionId key) {
|
||||||
|
if (m_options[key] == nullptr) return nullptr;
|
||||||
|
return dynamic_cast<T*>(m_options[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<Option*, OPTIONS_COUNT> m_options;
|
||||||
OptionsFile optionsFile;
|
OptionsFile optionsFile;
|
||||||
|
|
||||||
|
Minecraft* minecraft;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT__Options_H__*/
|
#endif /*NET_MINECRAFT_CLIENT__Options_H__*/
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "OptionsFile.h"
|
#include "OptionsFile.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <platform/log.h>
|
||||||
|
|
||||||
OptionsFile::OptionsFile() {
|
OptionsFile::OptionsFile() {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@@ -19,19 +20,32 @@ void OptionsFile::save(const StringVector& settings) {
|
|||||||
fprintf(pFile, "%s\n", it->c_str());
|
fprintf(pFile, "%s\n", it->c_str());
|
||||||
}
|
}
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
|
} else {
|
||||||
|
LOGI("OptionsFile::save failed to open '%s' for writing: %s", settingsPath.c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringVector OptionsFile::getOptionStrings() {
|
StringVector OptionsFile::getOptionStrings() {
|
||||||
StringVector returnVector;
|
StringVector returnVector;
|
||||||
FILE* pFile = fopen(settingsPath.c_str(), "w");
|
FILE* pFile = fopen(settingsPath.c_str(), "r");
|
||||||
if(pFile != NULL) {
|
if(pFile != NULL) {
|
||||||
char lineBuff[128];
|
char lineBuff[128];
|
||||||
while(fgets(lineBuff, sizeof lineBuff, pFile)) {
|
while(fgets(lineBuff, sizeof lineBuff, pFile)) {
|
||||||
if(strlen(lineBuff) > 2)
|
// Strip trailing newline
|
||||||
returnVector.push_back(std::string(lineBuff));
|
size_t len = strlen(lineBuff);
|
||||||
|
while(len > 0 && (lineBuff[len-1] == '\n' || lineBuff[len-1] == '\r'))
|
||||||
|
lineBuff[--len] = '\0';
|
||||||
|
if(len < 3) continue;
|
||||||
|
// Split "key:value" into two separate entries to match update() pairing
|
||||||
|
char* colon = strchr(lineBuff, ':');
|
||||||
|
if(colon) {
|
||||||
|
returnVector.push_back(std::string(lineBuff, colon - lineBuff));
|
||||||
|
returnVector.push_back(std::string(colon + 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
|
} else {
|
||||||
|
LOGI("OptionsFile::getOptionStrings failed to open '%s' for reading: %s", settingsPath.c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
return returnVector;
|
return returnVector;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
#ifndef NET_MINECRAFT_CLIENT__User_H__
|
|
||||||
#define NET_MINECRAFT_CLIENT__User_H__
|
|
||||||
|
|
||||||
//package net.minecraft.client;
|
|
||||||
|
|
||||||
#include "../world/level/tile/Tile.h"
|
|
||||||
|
|
||||||
class User
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//static List<Tile> allowedTiles = /*new*/ ArrayList<Tile>();
|
|
||||||
|
|
||||||
//static {
|
|
||||||
// allowedTiles.push_back(Tile::rock);
|
|
||||||
// allowedTiles.push_back(Tile::stoneBrick);
|
|
||||||
// allowedTiles.push_back(Tile::redBrick);
|
|
||||||
// allowedTiles.push_back(Tile::dirt);
|
|
||||||
// allowedTiles.push_back(Tile::wood);
|
|
||||||
// allowedTiles.push_back(Tile::treeTrunk);
|
|
||||||
// allowedTiles.push_back(Tile::leaves);
|
|
||||||
// allowedTiles.push_back(Tile::torch);
|
|
||||||
// allowedTiles.push_back(Tile::stoneSlabHalf);
|
|
||||||
|
|
||||||
// allowedTiles.push_back(Tile::glass);
|
|
||||||
// allowedTiles.push_back(Tile::mossStone);
|
|
||||||
// allowedTiles.push_back(Tile::sapling);
|
|
||||||
// allowedTiles.push_back(Tile::flower);
|
|
||||||
// allowedTiles.push_back(Tile::rose);
|
|
||||||
// allowedTiles.push_back(Tile::mushroom1);
|
|
||||||
// allowedTiles.push_back(Tile::mushroom2);
|
|
||||||
// allowedTiles.push_back(Tile::sand);
|
|
||||||
// allowedTiles.push_back(Tile::gravel);
|
|
||||||
// allowedTiles.push_back(Tile::sponge);
|
|
||||||
|
|
||||||
// allowedTiles.push_back(Tile::cloth);
|
|
||||||
// allowedTiles.push_back(Tile::coalOre);
|
|
||||||
// allowedTiles.push_back(Tile::ironOre);
|
|
||||||
// allowedTiles.push_back(Tile::goldOre);
|
|
||||||
// allowedTiles.push_back(Tile::ironBlock);
|
|
||||||
// allowedTiles.push_back(Tile::goldBlock);
|
|
||||||
// allowedTiles.push_back(Tile::bookshelf);
|
|
||||||
// allowedTiles.push_back(Tile::tnt);
|
|
||||||
// allowedTiles.push_back(Tile::obsidian);
|
|
||||||
|
|
||||||
// // System.out.println(allowedTiles.size());
|
|
||||||
//}
|
|
||||||
|
|
||||||
static bool isTileAllowed(const Tile& tile) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
std::string sessionId;
|
|
||||||
//std::string mpPassword;
|
|
||||||
|
|
||||||
User(const std::string& name, const std::string& sessionId) {
|
|
||||||
this->name = name;
|
|
||||||
this->sessionId = sessionId;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT__User_H__*/
|
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
#include "../../network/packet/RemoveBlockPacket.h"
|
#include "../../network/packet/RemoveBlockPacket.h"
|
||||||
#include "../../world/entity/player/Abilities.h"
|
#include "../../world/entity/player/Abilities.h"
|
||||||
|
|
||||||
static const int DestructionTickDelay = 10;
|
static const int DestructionTickDelay = 5;
|
||||||
|
|
||||||
CreativeMode::CreativeMode(Minecraft* minecraft)
|
CreativeMode::CreativeMode(Minecraft* minecraft)
|
||||||
: super(minecraft)
|
: super(minecraft)
|
||||||
@@ -29,12 +29,8 @@ void CreativeMode::startDestroyBlock(int x, int y, int z, int face) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CreativeMode::creativeDestroyBlock(int x, int y, int z, int face) {
|
void CreativeMode::creativeDestroyBlock(int x, int y, int z, int face) {
|
||||||
//if (!
|
minecraft->level->extinguishFire(x, y, z, face);
|
||||||
minecraft->level->extinguishFire(x, y, z, face)
|
|
||||||
//{
|
|
||||||
;
|
|
||||||
destroyBlock(x, y, z, face);
|
destroyBlock(x, y, z, face);
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreativeMode::continueDestroyBlock(int x, int y, int z, int face) {
|
void CreativeMode::continueDestroyBlock(int x, int y, int z, int face) {
|
||||||
@@ -46,6 +42,7 @@ void CreativeMode::continueDestroyBlock(int x, int y, int z, int face) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CreativeMode::stopDestroyBlock() {
|
void CreativeMode::stopDestroyBlock() {
|
||||||
|
destroyDelay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreativeMode::initAbilities( Abilities& abilities ) {
|
void CreativeMode::initAbilities( Abilities& abilities ) {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "../../network/packet/RemoveBlockPacket.h"
|
#include "../../network/packet/RemoveBlockPacket.h"
|
||||||
#include "../../world/entity/player/Abilities.h"
|
#include "../../world/entity/player/Abilities.h"
|
||||||
|
|
||||||
static const int DestructionTickDelay = 10;
|
static const int DestructionTickDelay = 5;
|
||||||
|
|
||||||
class Creator: public ICreator {
|
class Creator: public ICreator {
|
||||||
//virtual void getEvents();
|
//virtual void getEvents();
|
||||||
@@ -60,12 +60,8 @@ void CreatorMode::startDestroyBlock(int x, int y, int z, int face) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CreatorMode::CreatorDestroyBlock(int x, int y, int z, int face) {
|
void CreatorMode::CreatorDestroyBlock(int x, int y, int z, int face) {
|
||||||
//if (!
|
minecraft->level->extinguishFire(x, y, z, face);
|
||||||
minecraft->level->extinguishFire(x, y, z, face)
|
|
||||||
//{
|
|
||||||
;
|
|
||||||
destroyBlock(x, y, z, face);
|
destroyBlock(x, y, z, face);
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatorMode::continueDestroyBlock(int x, int y, int z, int face) {
|
void CreatorMode::continueDestroyBlock(int x, int y, int z, int face) {
|
||||||
@@ -83,6 +79,7 @@ bool CreatorMode::useItemOn( Player* player, Level* level, ItemInstance* item, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CreatorMode::stopDestroyBlock() {
|
void CreatorMode::stopDestroyBlock() {
|
||||||
|
destroyDelay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatorMode::initAbilities( Abilities& abilities ) {
|
void CreatorMode::initAbilities( Abilities& abilities ) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "../../world/level/Level.h"
|
#include "../../world/level/Level.h"
|
||||||
#include "../../world/item/ItemInstance.h"
|
#include "../../world/item/ItemInstance.h"
|
||||||
#include "../player/LocalPlayer.h"
|
#include "../player/LocalPlayer.h"
|
||||||
|
#include "client/Options.h"
|
||||||
#ifndef STANDALONE_SERVER
|
#ifndef STANDALONE_SERVER
|
||||||
#include "../sound/SoundEngine.h"
|
#include "../sound/SoundEngine.h"
|
||||||
#include "../particle/ParticleEngine.h"
|
#include "../particle/ParticleEngine.h"
|
||||||
@@ -27,7 +28,7 @@ GameMode::GameMode( Minecraft* minecraft)
|
|||||||
|
|
||||||
/*virtual*/
|
/*virtual*/
|
||||||
Player* GameMode::createPlayer(Level* level) {
|
Player* GameMode::createPlayer(Level* level) {
|
||||||
return new LocalPlayer(minecraft, level, minecraft->user, level->dimension->id, isCreativeType());
|
return new LocalPlayer(minecraft, level, minecraft->options.getStringValue(OPTIONS_USERNAME), level->dimension->id, isCreativeType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*virtual*/
|
/*virtual*/
|
||||||
@@ -74,7 +75,7 @@ bool GameMode::destroyBlock(int x, int y, int z, int face) {
|
|||||||
minecraft->soundEngine->play(oldTile->soundType->getBreakSound(), x + 0.5f, y + 0.5f, z + 0.5f, (oldTile->soundType->getVolume() + 1) / 2, oldTile->soundType->getPitch() * 0.8f);
|
minecraft->soundEngine->play(oldTile->soundType->getBreakSound(), x + 0.5f, y + 0.5f, z + 0.5f, (oldTile->soundType->getVolume() + 1) / 2, oldTile->soundType->getPitch() * 0.8f);
|
||||||
#endif
|
#endif
|
||||||
oldTile->destroy(level, x, y, z, data);
|
oldTile->destroy(level, x, y, z, data);
|
||||||
if (minecraft->options.destroyVibration) minecraft->platform()->vibrate(24);
|
if (minecraft->options.getBooleanValue(OPTIONS_DESTROY_VIBRATION)) minecraft->platform()->vibrate(24);
|
||||||
|
|
||||||
if (minecraft->isOnline()) {
|
if (minecraft->isOnline()) {
|
||||||
RemoveBlockPacket packet(minecraft->player, x, y, z);
|
RemoveBlockPacket packet(minecraft->player, x, y, z);
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
#include "Gui.h"
|
#include "Gui.h"
|
||||||
#include "Font.h"
|
#include "Font.h"
|
||||||
|
#include "client/Options.h"
|
||||||
|
#include "platform/input/Keyboard.h"
|
||||||
#include "screens/IngameBlockSelectionScreen.h"
|
#include "screens/IngameBlockSelectionScreen.h"
|
||||||
|
#include "screens/ChatScreen.h"
|
||||||
|
#include "screens/ConsoleScreen.h"
|
||||||
#include "../Minecraft.h"
|
#include "../Minecraft.h"
|
||||||
#include "../player/LocalPlayer.h"
|
#include "../player/LocalPlayer.h"
|
||||||
#include "../renderer/Tesselator.h"
|
#include "../renderer/Tesselator.h"
|
||||||
@@ -20,6 +24,10 @@
|
|||||||
#include "../../platform/input/Mouse.h"
|
#include "../../platform/input/Mouse.h"
|
||||||
#include "../../world/level/Level.h"
|
#include "../../world/level/Level.h"
|
||||||
#include "../../world/PosTranslator.h"
|
#include "../../world/PosTranslator.h"
|
||||||
|
#include "../../platform/time.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
float Gui::InvGuiScale = 1.0f / 3.0f;
|
float Gui::InvGuiScale = 1.0f / 3.0f;
|
||||||
float Gui::GuiScale = 1.0f / Gui::InvGuiScale;
|
float Gui::GuiScale = 1.0f / Gui::InvGuiScale;
|
||||||
@@ -33,6 +41,7 @@ Gui::Gui(Minecraft* minecraft)
|
|||||||
progress(0),
|
progress(0),
|
||||||
overlayMessageTime(0),
|
overlayMessageTime(0),
|
||||||
animateOverlayMessageColor(false),
|
animateOverlayMessageColor(false),
|
||||||
|
chatScrollOffset(0),
|
||||||
tbr(1),
|
tbr(1),
|
||||||
_inventoryNeedsUpdate(true),
|
_inventoryNeedsUpdate(true),
|
||||||
_flashSlotId(-1),
|
_flashSlotId(-1),
|
||||||
@@ -84,6 +93,7 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) {
|
|||||||
// F: 3
|
// F: 3
|
||||||
int ySlot = screenHeight - 16 - 3;
|
int ySlot = screenHeight - 16 - 3;
|
||||||
|
|
||||||
|
if (!minecraft->options.getBooleanValue(OPTIONS_HIDEGUI)) {
|
||||||
if (minecraft->gameMode->canHurtPlayer()) {
|
if (minecraft->gameMode->canHurtPlayer()) {
|
||||||
minecraft->textures->loadAndBindTexture("gui/icons.png");
|
minecraft->textures->loadAndBindTexture("gui/icons.png");
|
||||||
Tesselator& t = Tesselator::instance;
|
Tesselator& t = Tesselator::instance;
|
||||||
@@ -93,6 +103,7 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) {
|
|||||||
renderBubbles();
|
renderBubbles();
|
||||||
t.endOverrideAndDraw();
|
t.endOverrideAndDraw();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(minecraft->player->getSleepTimer() > 0) {
|
if(minecraft->player->getSleepTimer() > 0) {
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
@@ -103,18 +114,22 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) {
|
|||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
if (!minecraft->options.getBooleanValue(OPTIONS_HIDEGUI)) {
|
||||||
renderToolBar(a, ySlot, screenWidth);
|
renderToolBar(a, ySlot, screenWidth);
|
||||||
|
|
||||||
|
|
||||||
//font->drawShadow(APP_NAME, 2, 2, 0xffffffff);
|
|
||||||
//font->drawShadow("This is a demo, not the finished product", 2, 10 + 2, 0xffffffff);
|
|
||||||
#ifdef APPLE_DEMO_PROMOTION
|
|
||||||
font->drawShadow("Demo version", 2, 0 + 2, 0xffffffff);
|
|
||||||
#endif /*APPLE_DEMO_PROMOTION*/
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
bool isChatting = (minecraft->screen && (dynamic_cast<ChatScreen*>(minecraft->screen) || dynamic_cast<ConsoleScreen*>(minecraft->screen)));
|
||||||
unsigned int max = 10;
|
unsigned int max = 10;
|
||||||
bool isChatting = false;
|
if (isChatting) {
|
||||||
|
int lineHeight = 9;
|
||||||
|
max = (screenHeight - 48) / lineHeight;
|
||||||
|
if (max < 1) max = 1;
|
||||||
|
int maxScroll = (int)guiMessages.size() - (int)max;
|
||||||
|
if (maxScroll < 0) maxScroll = 0;
|
||||||
|
if (chatScrollOffset > maxScroll) chatScrollOffset = maxScroll;
|
||||||
|
} else {
|
||||||
|
chatScrollOffset = 0;
|
||||||
|
}
|
||||||
renderChatMessages(screenHeight, max, isChatting, font);
|
renderChatMessages(screenHeight, max, isChatting, font);
|
||||||
#if !defined(RPI)
|
#if !defined(RPI)
|
||||||
renderOnSelectItemNameText(screenWidth, font, ySlot);
|
renderOnSelectItemNameText(screenWidth, font, ySlot);
|
||||||
@@ -123,9 +138,14 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) {
|
|||||||
renderDebugInfo();
|
renderDebugInfo();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// glPopMatrix2();
|
if (Keyboard::isKeyDown(Keyboard::KEY_TAB)) {
|
||||||
//
|
renderPlayerList(font, screenWidth, screenHeight);
|
||||||
// glEnable(GL_ALPHA_TEST);
|
}
|
||||||
|
|
||||||
|
if (minecraft->options.getBooleanValue(OPTIONS_RENDER_DEBUG))
|
||||||
|
renderDebugInfo();
|
||||||
|
}
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glEnable2(GL_ALPHA_TEST);
|
glEnable2(GL_ALPHA_TEST);
|
||||||
}
|
}
|
||||||
@@ -188,11 +208,13 @@ void Gui::handleClick(int button, int x, int y) {
|
|||||||
int slot = getSlotIdAt(x, y);
|
int slot = getSlotIdAt(x, y);
|
||||||
if (slot != -1)
|
if (slot != -1)
|
||||||
{
|
{
|
||||||
|
#ifndef PLATFORM_DESKTOP
|
||||||
if (slot == (getNumSlots()-1))
|
if (slot == (getNumSlots()-1))
|
||||||
{
|
{
|
||||||
minecraft->screenChooser.setScreen(SCREEN_BLOCKSELECTION);
|
minecraft->screenChooser.setScreen(SCREEN_BLOCKSELECTION);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
minecraft->player->inventory->selectSlot(slot);
|
minecraft->player->inventory->selectSlot(slot);
|
||||||
itemNameOverlayTime = 0;
|
itemNameOverlayTime = 0;
|
||||||
@@ -202,6 +224,33 @@ void Gui::handleClick(int button, int x, int y) {
|
|||||||
|
|
||||||
void Gui::handleKeyPressed(int key)
|
void Gui::handleKeyPressed(int key)
|
||||||
{
|
{
|
||||||
|
bool isChatting = (minecraft->screen && (dynamic_cast<ChatScreen*>(minecraft->screen) || dynamic_cast<ConsoleScreen*>(minecraft->screen)));
|
||||||
|
if (isChatting) {
|
||||||
|
// Allow scrolling the chat history with the mouse/keyboard when chat is open
|
||||||
|
if (key == 38) { // VK_UP
|
||||||
|
scrollChat(1);
|
||||||
|
return;
|
||||||
|
} else if (key == 40) { // VK_DOWN
|
||||||
|
scrollChat(-1);
|
||||||
|
return;
|
||||||
|
} else if (key == 33) { // VK_PRIOR (Page Up)
|
||||||
|
// Scroll by a page
|
||||||
|
int screenHeight = (int)(minecraft->height * InvGuiScale);
|
||||||
|
int maxVisible = (screenHeight - 48) / 9;
|
||||||
|
scrollChat(maxVisible);
|
||||||
|
return;
|
||||||
|
} else if (key == 34) { // VK_NEXT (Page Down)
|
||||||
|
int screenHeight = (int)(minecraft->height * InvGuiScale);
|
||||||
|
int maxVisible = (screenHeight - 48) / 9;
|
||||||
|
scrollChat(-maxVisible);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == Keyboard::KEY_F1) {
|
||||||
|
minecraft->options.toggle(OPTIONS_HIDEGUI);
|
||||||
|
}
|
||||||
|
|
||||||
if (key == 99)
|
if (key == 99)
|
||||||
{
|
{
|
||||||
if (minecraft->player->inventory->selected > 0)
|
if (minecraft->player->inventory->selected > 0)
|
||||||
@@ -220,6 +269,27 @@ void Gui::handleKeyPressed(int key)
|
|||||||
{
|
{
|
||||||
minecraft->screenChooser.setScreen(SCREEN_BLOCKSELECTION);
|
minecraft->screenChooser.setScreen(SCREEN_BLOCKSELECTION);
|
||||||
}
|
}
|
||||||
|
else if (key == minecraft->options.getIntValue(OPTIONS_KEY_DROP))
|
||||||
|
{
|
||||||
|
minecraft->player->inventory->dropSlot(minecraft->player->inventory->selected, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gui::scrollChat(int delta) {
|
||||||
|
if (delta == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int screenHeight = (int)(minecraft->height * InvGuiScale);
|
||||||
|
int maxVisible = (screenHeight - 48) / 9;
|
||||||
|
if (maxVisible <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int maxScroll = (int)guiMessages.size() - maxVisible;
|
||||||
|
if (maxScroll < 0) maxScroll = 0;
|
||||||
|
int desired = chatScrollOffset + delta;
|
||||||
|
if (desired < 0) desired = 0;
|
||||||
|
if (desired > maxScroll) desired = maxScroll;
|
||||||
|
chatScrollOffset = desired;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gui::tick() {
|
void Gui::tick() {
|
||||||
@@ -252,9 +322,22 @@ void Gui::addMessage(const std::string& _string) {
|
|||||||
message.message = string;
|
message.message = string;
|
||||||
message.ticks = 0;
|
message.ticks = 0;
|
||||||
guiMessages.insert(guiMessages.begin(), message);
|
guiMessages.insert(guiMessages.begin(), message);
|
||||||
while (guiMessages.size() > 30) {
|
|
||||||
|
// Keep a larger history so users can scroll through the full chat
|
||||||
|
const unsigned int MaxHistoryLines = 200;
|
||||||
|
while (guiMessages.size() > MaxHistoryLines) {
|
||||||
guiMessages.pop_back();
|
guiMessages.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the user has scrolled up, keep their window fixed (new messages shift older ones down)
|
||||||
|
if (chatScrollOffset > 0) {
|
||||||
|
chatScrollOffset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gui::clearMessages() {
|
||||||
|
guiMessages.clear();
|
||||||
|
chatScrollOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gui::setNowPlaying(const std::string& string) {
|
void Gui::setNowPlaying(const std::string& string) {
|
||||||
@@ -395,10 +478,11 @@ void Gui::onConfigChanged( const Config& c ) {
|
|||||||
//LOGI("x,y: %f, %f\n", xx, yy);
|
//LOGI("x,y: %f, %f\n", xx, yy);
|
||||||
}
|
}
|
||||||
rcFeedbackInner = t.end(true, rcFeedbackInner.vboId);
|
rcFeedbackInner = t.end(true, rcFeedbackInner.vboId);
|
||||||
|
|
||||||
if (c.minecraft->useTouchscreen()) {
|
if (c.minecraft->useTouchscreen()) {
|
||||||
// I'll bump this up to 6.
|
// I'll bump this up to 6.
|
||||||
int num = 6; // without "..." dots
|
int num = 6; // without "..." dots
|
||||||
if (!c.minecraft->options.isJoyTouchArea && c.width > 480) {
|
if (!c.minecraft->options.getBooleanValue(OPTIONS_IS_JOY_TOUCH_AREA) && c.width > 480) {
|
||||||
while (num < Inventory::MAX_SELECTION_SIZE - 1) {
|
while (num < Inventory::MAX_SELECTION_SIZE - 1) {
|
||||||
int x0, x1, y;
|
int x0, x1, y;
|
||||||
getSlotPos(0, x0, y);
|
getSlotPos(0, x0, y);
|
||||||
@@ -452,9 +536,16 @@ void Gui::tickItemDrop()
|
|||||||
// Handle item drop
|
// Handle item drop
|
||||||
static bool isCurrentlyActive = false;
|
static bool isCurrentlyActive = false;
|
||||||
isCurrentlyActive = false;
|
isCurrentlyActive = false;
|
||||||
|
|
||||||
|
int slots = getNumSlots();
|
||||||
|
|
||||||
|
#ifndef PLATFORM_DESKTOP
|
||||||
|
slots--;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (Mouse::isButtonDown(MouseAction::ACTION_LEFT)) {
|
if (Mouse::isButtonDown(MouseAction::ACTION_LEFT)) {
|
||||||
int slot = getSlotIdAt(Mouse::getX(), Mouse::getY());
|
int slot = getSlotIdAt(Mouse::getX(), Mouse::getY());
|
||||||
if (slot >= 0 && slot < getNumSlots()-1) {
|
if (slot >= 0 && slot < slots) {
|
||||||
if (slot != _currentDropSlot) {
|
if (slot != _currentDropSlot) {
|
||||||
_currentDropTicks = 0;
|
_currentDropTicks = 0;
|
||||||
_currentDropSlot = slot;
|
_currentDropSlot = slot;
|
||||||
@@ -505,7 +596,8 @@ void Gui::renderProgressIndicator( const bool isTouchInterface, const int screen
|
|||||||
ItemInstance* currentItem = minecraft->player->inventory->getSelected();
|
ItemInstance* currentItem = minecraft->player->inventory->getSelected();
|
||||||
bool bowEquipped = currentItem != NULL ? currentItem->getItem() == Item::bow : false;
|
bool bowEquipped = currentItem != NULL ? currentItem->getItem() == Item::bow : false;
|
||||||
bool itemInUse = currentItem != NULL ? currentItem->getItem() == minecraft->player->getUseItem()->getItem() : false;
|
bool itemInUse = currentItem != NULL ? currentItem->getItem() == minecraft->player->getUseItem()->getItem() : false;
|
||||||
if (!isTouchInterface || minecraft->options.isJoyTouchArea || (bowEquipped && itemInUse)) {
|
if ((!isTouchInterface || minecraft->options.getBooleanValue(OPTIONS_IS_JOY_TOUCH_AREA)
|
||||||
|
|| (bowEquipped && itemInUse)) && !minecraft->options.getBooleanValue(OPTIONS_HIDEGUI)) {
|
||||||
minecraft->textures->loadAndBindTexture("gui/icons.png");
|
minecraft->textures->loadAndBindTexture("gui/icons.png");
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc2(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR);
|
glBlendFunc2(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR);
|
||||||
@@ -574,11 +666,14 @@ void Gui::renderHearts() {
|
|||||||
int oh = minecraft->player->lastHealth;
|
int oh = minecraft->player->lastHealth;
|
||||||
random.setSeed(tickCount * 312871);
|
random.setSeed(tickCount * 312871);
|
||||||
|
|
||||||
int xx = 2;//screenWidth / 2 - getNumSlots() * 10;
|
int screenWidth = (int)(minecraft->width * InvGuiScale);
|
||||||
|
int screenHeight = (int)(minecraft->height * InvGuiScale);
|
||||||
|
|
||||||
|
int xx = (minecraft->options.getBooleanValue(OPTIONS_BAR_ON_TOP)) ? screenWidth / 2 - getNumSlots() * 10 - 1 : 2;
|
||||||
|
|
||||||
int armor = minecraft->player->getArmorValue();
|
int armor = minecraft->player->getArmorValue();
|
||||||
for (int i = 0; i < Player::MAX_HEALTH / 2; i++) {
|
for (int i = 0; i < Player::MAX_HEALTH / 2; i++) {
|
||||||
int yo = 2;
|
int yo = (minecraft->options.getBooleanValue(OPTIONS_BAR_ON_TOP)) ? screenHeight - 32 : 2;
|
||||||
int ip2 = i + i + 1;
|
int ip2 = i + i + 1;
|
||||||
|
|
||||||
if (armor > 0) {
|
if (armor > 0) {
|
||||||
@@ -606,11 +701,15 @@ void Gui::renderHearts() {
|
|||||||
|
|
||||||
void Gui::renderBubbles() {
|
void Gui::renderBubbles() {
|
||||||
if (minecraft->player->isUnderLiquid(Material::water)) {
|
if (minecraft->player->isUnderLiquid(Material::water)) {
|
||||||
int yo = 12;
|
int screenWidth = (int)(minecraft->width * InvGuiScale);
|
||||||
|
int screenHeight = (int)(minecraft->height * InvGuiScale);
|
||||||
|
|
||||||
|
int xx = (minecraft->options.getBooleanValue(OPTIONS_BAR_ON_TOP)) ? screenWidth / 2 - getNumSlots() * 10 - 1 : 2;
|
||||||
|
int yo = (minecraft->options.getBooleanValue(OPTIONS_BAR_ON_TOP)) ? screenHeight - 42 : 12;
|
||||||
int count = (int) std::ceil((minecraft->player->airSupply - 2) * 10.0f / Player::TOTAL_AIR_SUPPLY);
|
int count = (int) std::ceil((minecraft->player->airSupply - 2) * 10.0f / Player::TOTAL_AIR_SUPPLY);
|
||||||
int extra = (int) std::ceil((minecraft->player->airSupply) * 10.0f / Player::TOTAL_AIR_SUPPLY) - count;
|
int extra = (int) std::ceil((minecraft->player->airSupply) * 10.0f / Player::TOTAL_AIR_SUPPLY) - count;
|
||||||
for (int i = 0; i < count + extra; i++) {
|
for (int i = 0; i < count + extra; i++) {
|
||||||
int xo = i * 8 + 2;
|
int xo = i * 8 + xx;
|
||||||
if (i < count) blit(xo, yo, 16, 9 * 2, 9, 9);
|
if (i < count) blit(xo, yo, 16, 9 * 2, 9, 9);
|
||||||
else blit(xo, yo, 16 + 9, 9 * 2, 9, 9);
|
else blit(xo, yo, 16 + 9, 9 * 2, 9, 9);
|
||||||
}
|
}
|
||||||
@@ -626,20 +725,169 @@ void Gui::onLevelGenerated() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Gui::renderDebugInfo() {
|
void Gui::renderDebugInfo() {
|
||||||
static char buf[256];
|
// FPS counter (updates once per second)
|
||||||
float xx = minecraft->player->x;
|
static float fps = 0.0f;
|
||||||
float yy = minecraft->player->y - minecraft->player->heightOffset;
|
static float fpsLastTime = 0.0f;
|
||||||
float zz = minecraft->player->z;
|
static int fpsFrames = 0;
|
||||||
posTranslator.to(xx, yy, zz);
|
float now = getTimeS();
|
||||||
sprintf(buf, "pos: %3.1f, %3.1f, %3.1f\n", xx, yy, zz);
|
fpsFrames++;
|
||||||
|
if (now - fpsLastTime >= 1.0f) {
|
||||||
|
fps = fpsFrames / (now - fpsLastTime);
|
||||||
|
fpsFrames = 0;
|
||||||
|
fpsLastTime = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalPlayer* p = minecraft->player;
|
||||||
|
Level* lvl = minecraft->level;
|
||||||
|
|
||||||
|
// Position
|
||||||
|
float px = p->x, py = p->y - p->heightOffset, pz = p->z;
|
||||||
|
posTranslator.to(px, py, pz);
|
||||||
|
int bx = (int)floorf(px), by = (int)floorf(py), bz = (int)floorf(pz);
|
||||||
|
int cx = bx >> 4, cz = bz >> 4;
|
||||||
|
|
||||||
|
// Facing direction
|
||||||
|
float yMod = fmodf(p->yRot, 360.0f);
|
||||||
|
if (yMod < 0) yMod += 360.0f;
|
||||||
|
const char* facing;
|
||||||
|
const char* axis;
|
||||||
|
if (yMod < 45 || yMod >= 315) { facing = "South"; axis = "+Z"; }
|
||||||
|
else if (yMod < 135) { facing = "West"; axis = "-X"; }
|
||||||
|
else if (yMod < 225) { facing = "North"; axis = "-Z"; }
|
||||||
|
else { facing = "East"; axis = "+X"; }
|
||||||
|
|
||||||
|
// Biome
|
||||||
|
const char* biomeName = "unknown";
|
||||||
|
if (lvl) {
|
||||||
|
Biome* biome = lvl->getBiome(bx, bz);
|
||||||
|
if (biome) biomeName = biome->name.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time
|
||||||
|
long worldTime = lvl ? lvl->getTime() : 0;
|
||||||
|
long dayTime = worldTime % Level::TICKS_PER_DAY;
|
||||||
|
long day = worldTime / Level::TICKS_PER_DAY;
|
||||||
|
long seed = lvl ? lvl->getSeed() : 0;
|
||||||
|
|
||||||
|
// Build lines (NULL entry = blank gap)
|
||||||
|
static char ln[8][96];
|
||||||
|
sprintf(ln[0], "Minecraft PE 0.6.1 alpha (mcpe64)");
|
||||||
|
sprintf(ln[1], "%.1f fps", fps);
|
||||||
|
ln[2][0] = '\0'; // blank separator
|
||||||
|
sprintf(ln[3], "XYZ: %.3f / %.3f / %.3f", px, py, pz);
|
||||||
|
sprintf(ln[4], "Block: %d %d %d Chunk: %d %d", bx, by, bz, cx, cz);
|
||||||
|
sprintf(ln[5], "Facing: %s (%s) (%.1f / %.1f)", facing, axis, p->yRot, p->xRot);
|
||||||
|
sprintf(ln[6], "Biome: %s", biomeName);
|
||||||
|
sprintf(ln[7], "Day %ld Time: %ld Seed: %ld", day, dayTime, seed);
|
||||||
|
|
||||||
|
const int N = 8;
|
||||||
|
const float LH = (float)Font::DefaultLineHeight; // 10 font-pixels
|
||||||
|
const float MGN = 2.0f; // left/top margin in font-pixels
|
||||||
|
const float PAD = 2.0f; // horizontal padding for background
|
||||||
|
Font* font = minecraft->font;
|
||||||
|
|
||||||
|
// 1) Draw semi-transparent background boxes behind each line
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
if (ln[i][0] == '\0') continue;
|
||||||
|
float w = (float)font->width(ln[i]);
|
||||||
|
float x0 = MGN - PAD;
|
||||||
|
float y0 = MGN + i * LH - 1.0f;
|
||||||
|
float x1 = MGN + w + PAD;
|
||||||
|
float y1 = MGN + (i + 1) * LH - 1.0f;
|
||||||
|
fill(x0, y0, x1, y1, 0x90000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Draw text (no extra scale — font coords are in GUI units, same as fill)
|
||||||
Tesselator& t = Tesselator::instance;
|
Tesselator& t = Tesselator::instance;
|
||||||
t.beginOverride();
|
t.beginOverride();
|
||||||
t.scale2d(InvGuiScale, InvGuiScale);
|
for (int i = 0; i < N; i++) {
|
||||||
minecraft->font->draw(buf, 2, 2, 0xffffff);
|
if (ln[i][0] == '\0') continue;
|
||||||
t.resetScale();
|
float y = MGN + i * LH;
|
||||||
|
int col = (i == 0) ? 0xffFFFF55 : 0xffffffff; // title yellow, rest white
|
||||||
|
font->draw(ln[i], MGN, y, col);
|
||||||
|
}
|
||||||
t.endOverrideAndDraw();
|
t.endOverrideAndDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gui::renderPlayerList(Font* font, int screenWidth, int screenHeight) {
|
||||||
|
// only show when in game, no other screen
|
||||||
|
// if (!minecraft->level) return;
|
||||||
|
|
||||||
|
// only show the overlay while connected to a multiplayer server
|
||||||
|
Level* level = minecraft->level;
|
||||||
|
if (!level) return;
|
||||||
|
if (!level->isClientSide) return;
|
||||||
|
|
||||||
|
std::vector<std::string> playerNames;
|
||||||
|
playerNames.reserve(level->players.size());
|
||||||
|
|
||||||
|
for (Player* player : level->players) {
|
||||||
|
if (!player) continue;
|
||||||
|
playerNames.push_back(player->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// is this check needed? if there are no players, the box won't render at all since height will be 0,
|
||||||
|
// but maybe we want to skip rendering entirely in that case
|
||||||
|
// if (playerNames.empty())
|
||||||
|
// return;
|
||||||
|
|
||||||
|
std::sort(playerNames.begin(), playerNames.end());
|
||||||
|
|
||||||
|
float maxNameWidth = 0.0f;
|
||||||
|
// find the longest name so we can size the box accordingly
|
||||||
|
for (const std::string& name : playerNames) {
|
||||||
|
float nameWidth = font->width(name);
|
||||||
|
if (nameWidth > maxNameWidth)
|
||||||
|
maxNameWidth = nameWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// player count title
|
||||||
|
std::ostringstream titleStream;
|
||||||
|
titleStream << "Players (" << playerNames.size() << ")";
|
||||||
|
std::string titleText = titleStream.str();
|
||||||
|
float titleWidth = font->width(titleText);
|
||||||
|
|
||||||
|
if (titleWidth > maxNameWidth)
|
||||||
|
maxNameWidth = titleWidth;
|
||||||
|
|
||||||
|
const float padding = 4.0f;
|
||||||
|
const float lineHeight = (float)Font::DefaultLineHeight;
|
||||||
|
|
||||||
|
const float boxWidth = maxNameWidth + padding * 2;
|
||||||
|
const float boxHeight = (playerNames.size() + 1) * lineHeight + padding * 2;
|
||||||
|
|
||||||
|
const float boxLeft = (screenWidth - boxWidth) / 2.0f;
|
||||||
|
const float boxTop = 10.0f;
|
||||||
|
const float boxRight = boxLeft + boxWidth;
|
||||||
|
const float boxBottom = boxTop + boxHeight;
|
||||||
|
|
||||||
|
fill(boxLeft, boxTop, boxRight, boxBottom, 0x90000000);
|
||||||
|
|
||||||
|
float titleX = (screenWidth - titleWidth) / 2.0f;
|
||||||
|
float titleY = boxTop + padding;
|
||||||
|
|
||||||
|
// scale the text down slightly
|
||||||
|
// i think the gl scaling is the best for this
|
||||||
|
// oh my god this looks really bad OH GOD
|
||||||
|
//const float textScale = 0.8f;
|
||||||
|
//const float invTextScale = 1.0f / textScale;
|
||||||
|
//glPushMatrix2();
|
||||||
|
//glScalef2(textScale, textScale, 1);
|
||||||
|
|
||||||
|
// draw title
|
||||||
|
//font->draw(titleText, titleX * invTextScale, titleY * invTextScale, 0xFFFFFFFF);
|
||||||
|
font->draw(titleText, titleX, titleY, 0xFFFFFFFF);
|
||||||
|
|
||||||
|
// draw player names
|
||||||
|
// we should add ping icons here eventually, but for now just show names
|
||||||
|
float currentY = boxTop + padding + lineHeight;
|
||||||
|
for (const std::string& name : playerNames) {
|
||||||
|
font->draw(name, (boxLeft + padding), currentY, 0xFFDDDDDD);
|
||||||
|
currentY += lineHeight;
|
||||||
|
}
|
||||||
|
//glPopMatrix2();
|
||||||
|
}
|
||||||
|
|
||||||
void Gui::renderSleepAnimation( const int screenWidth, const int screenHeight ) {
|
void Gui::renderSleepAnimation( const int screenWidth, const int screenHeight ) {
|
||||||
int timer = minecraft->player->getSleepTimer();
|
int timer = minecraft->player->getSleepTimer();
|
||||||
float amount = (float) timer / (float) Player::SLEEP_DURATION;
|
float amount = (float) timer / (float) Player::SLEEP_DURATION;
|
||||||
@@ -670,6 +918,70 @@ void Gui::renderOnSelectItemNameText( const int screenWidth, Font* font, int ySl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// helper structure used by drawColoredString
|
||||||
|
struct ColorSegment {
|
||||||
|
std::string text;
|
||||||
|
uint32_t color;
|
||||||
|
};
|
||||||
|
|
||||||
|
// parse [tag] and [/tag] markers; tags may contain a color name (gold, green, etc.)
|
||||||
|
static void parseColorTags(const std::string& in, std::vector<ColorSegment>& out) {
|
||||||
|
uint32_t curColor = 0xffffff;
|
||||||
|
size_t pos = 0;
|
||||||
|
while (pos < in.size()) {
|
||||||
|
size_t open = in.find('[', pos);
|
||||||
|
if (open == std::string::npos) {
|
||||||
|
out.push_back({in.substr(pos), curColor});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (open > pos) {
|
||||||
|
out.push_back({in.substr(pos, open - pos), curColor});
|
||||||
|
}
|
||||||
|
size_t close = in.find(']', open);
|
||||||
|
if (close == std::string::npos) {
|
||||||
|
out.push_back({in.substr(open), curColor});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::string tag = in.substr(open + 1, close - open - 1);
|
||||||
|
if (!tag.empty() && tag[0] == '/') {
|
||||||
|
curColor = 0xffffff;
|
||||||
|
} else {
|
||||||
|
std::string lower;
|
||||||
|
lower.resize(tag.size());
|
||||||
|
std::transform(tag.begin(), tag.end(), lower.begin(), ::tolower);
|
||||||
|
if (lower.find("gold") != std::string::npos) curColor = 0xffd700;
|
||||||
|
else if (lower.find("green") != std::string::npos) curColor = 0x00ff00;
|
||||||
|
else if (lower.find("yellow") != std::string::npos) curColor = 0xffff00;
|
||||||
|
else if (lower.find("red") != std::string::npos) curColor = 0xff0000;
|
||||||
|
else if (lower.find("blue") != std::string::npos) curColor = 0x0000ff;
|
||||||
|
}
|
||||||
|
pos = close + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gui::drawColoredString(Font* font, const std::string& text, float x, float y, int alpha) {
|
||||||
|
std::vector<ColorSegment> segs;
|
||||||
|
parseColorTags(text, segs);
|
||||||
|
float cx = x;
|
||||||
|
for (auto &s : segs) {
|
||||||
|
int color = s.color + (alpha << 24);
|
||||||
|
font->drawShadow(s.text, cx, y, color);
|
||||||
|
cx += font->width(s.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float Gui::getColoredWidth(Font* font, const std::string& text) {
|
||||||
|
std::vector<ColorSegment> segs;
|
||||||
|
parseColorTags(text, segs);
|
||||||
|
float w = 0;
|
||||||
|
for (auto &s : segs) {
|
||||||
|
w += font->width(s.text);
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
void Gui::renderChatMessages( const int screenHeight, unsigned int max, bool isChatting, Font* font ) {
|
void Gui::renderChatMessages( const int screenHeight, unsigned int max, bool isChatting, Font* font ) {
|
||||||
// if (minecraft.screen instanceof ChatScreen) {
|
// if (minecraft.screen instanceof ChatScreen) {
|
||||||
// max = 20;
|
// max = 20;
|
||||||
@@ -685,9 +997,16 @@ void Gui::renderChatMessages( const int screenHeight, unsigned int max, bool isC
|
|||||||
// // glScalef2(1.0f / ssc.scale, 1.0f / ssc.scale, 1);
|
// // glScalef2(1.0f / ssc.scale, 1.0f / ssc.scale, 1);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
int baseY = screenHeight - 48;
|
int baseY = screenHeight - 48;
|
||||||
for (unsigned int i = 0; i < guiMessages.size() && i < max; i++) {
|
int start = chatScrollOffset;
|
||||||
if (guiMessages.at(i).ticks < 20 * 10 || isChatting) {
|
if (start < 0) start = 0;
|
||||||
float t = guiMessages.at(i).ticks / (20 * 10.0f);
|
for (unsigned int i = 0; i < max; i++) {
|
||||||
|
unsigned int msgIdx = (unsigned int)start + i;
|
||||||
|
if (msgIdx >= guiMessages.size())
|
||||||
|
break;
|
||||||
|
|
||||||
|
GuiMessage& message = guiMessages.at(msgIdx);
|
||||||
|
if (message.ticks < 20 * 10 || isChatting) {
|
||||||
|
float t = message.ticks / (20 * 10.0f);
|
||||||
t = 1 - t;
|
t = 1 - t;
|
||||||
t = t * 10;
|
t = t * 10;
|
||||||
if (t < 0) t = 0;
|
if (t < 0) t = 0;
|
||||||
@@ -699,11 +1018,18 @@ void Gui::renderChatMessages( const int screenHeight, unsigned int max, bool isC
|
|||||||
if (alpha > 0) {
|
if (alpha > 0) {
|
||||||
const float x = 2;
|
const float x = 2;
|
||||||
const float y = (float)(baseY - i * 9);
|
const float y = (float)(baseY - i * 9);
|
||||||
std::string msg = guiMessages.at(i).message;
|
std::string msg = message.message;
|
||||||
this->fill(x, y - 1, x + MAX_MESSAGE_WIDTH, y + 8, (alpha / 2) << 24);
|
this->fill(x, y - 1, x + MAX_MESSAGE_WIDTH, y + 8, (alpha / 2) << 24);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
font->drawShadow(msg, x, y, 0xffffff + (alpha << 24));
|
// special-case join/leave announcements
|
||||||
|
int baseColor = 0xffffff;
|
||||||
|
if (msg.find(" joined the game") != std::string::npos ||
|
||||||
|
msg.find(" left the game") != std::string::npos) {
|
||||||
|
baseColor = 0xffff00; // yellow
|
||||||
|
}
|
||||||
|
// replace previous logic; allow full colour tags now
|
||||||
|
Gui::drawColoredString(font, msg, x, y, alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -756,20 +1082,24 @@ void Gui::renderToolBar( float a, int ySlot, const int screenWidth ) {
|
|||||||
t.beginOverride();
|
t.beginOverride();
|
||||||
|
|
||||||
float x = baseItemX;
|
float x = baseItemX;
|
||||||
for (int i = 0; i < getNumSlots()-1; i++) {
|
|
||||||
|
int slots = getNumSlots();
|
||||||
|
|
||||||
|
// TODO: if using touchscreen
|
||||||
|
|
||||||
|
#ifndef PLATFORM_DESKTOP
|
||||||
|
slots--;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 0; i < slots; i++) {
|
||||||
renderSlot(i, (int)x, ySlot, a);
|
renderSlot(i, (int)x, ySlot, a);
|
||||||
x += 20;
|
x += 20;
|
||||||
}
|
}
|
||||||
_inventoryNeedsUpdate = false;
|
_inventoryNeedsUpdate = false;
|
||||||
//_inventoryRc = t.end(_inventoryRc.vboId);
|
|
||||||
|
|
||||||
//drawArrayVTC(_inventoryRc.vboId, _inventoryRc.vertexCount);
|
#ifndef PLATFORM_DESKTOP
|
||||||
|
|
||||||
//renderSlotWatch.stop();
|
|
||||||
//renderSlotWatch.printEvery(100, "Render slots:");
|
|
||||||
|
|
||||||
//int x = screenWidth / 2 + getNumSlots() * 10 + (getNumSlots()-1) * 20 + 2;
|
|
||||||
blit(screenWidth / 2 + 10 * getNumSlots() - 20 + 4, ySlot + 6, 242, 252, 14, 4, 14, 4);
|
blit(screenWidth / 2 + 10 * getNumSlots() - 20 + 4, ySlot + 6, 242, 252, 14, 4, 14, 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
minecraft->textures->loadAndBindTexture("gui/gui_blocks.png");
|
minecraft->textures->loadAndBindTexture("gui/gui_blocks.png");
|
||||||
t.endOverrideAndDraw();
|
t.endOverrideAndDraw();
|
||||||
@@ -779,7 +1109,7 @@ void Gui::renderToolBar( float a, int ySlot, const int screenWidth ) {
|
|||||||
glDisable2(GL_TEXTURE_2D);
|
glDisable2(GL_TEXTURE_2D);
|
||||||
t.beginOverride();
|
t.beginOverride();
|
||||||
x = baseItemX;
|
x = baseItemX;
|
||||||
for (int i = 0; i < getNumSlots()-1; i++) {
|
for (int i = 0; i < slots; i++) {
|
||||||
ItemRenderer::renderGuiItemDecorations(minecraft->player->inventory->getItem(i), x, (float)ySlot);
|
ItemRenderer::renderGuiItemDecorations(minecraft->player->inventory->getItem(i), x, (float)ySlot);
|
||||||
x += 20;
|
x += 20;
|
||||||
}
|
}
|
||||||
@@ -799,7 +1129,7 @@ void Gui::renderToolBar( float a, int ySlot, const int screenWidth ) {
|
|||||||
t.beginOverride();
|
t.beginOverride();
|
||||||
if (minecraft->gameMode->isSurvivalType()) {
|
if (minecraft->gameMode->isSurvivalType()) {
|
||||||
x = baseItemX;
|
x = baseItemX;
|
||||||
for (int i = 0; i < getNumSlots()-1; i++) {
|
for (int i = 0; i < slots; i++) {
|
||||||
ItemInstance* item = minecraft->player->inventory->getItem(i);
|
ItemInstance* item = minecraft->player->inventory->getItem(i);
|
||||||
if (item && item->count >= 0)
|
if (item && item->count >= 0)
|
||||||
renderSlotText(item, k*x, k*ySlot + 1, true, true);
|
renderSlotText(item, k*x, k*ySlot + 1, true, true);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public:
|
|||||||
|
|
||||||
void handleClick(int button, int x, int y);
|
void handleClick(int button, int x, int y);
|
||||||
void handleKeyPressed( int key );
|
void handleKeyPressed( int key );
|
||||||
|
void scrollChat(int delta);
|
||||||
|
|
||||||
void tick();
|
void tick();
|
||||||
void render(float a, bool mouseFree, int xMouse, int yMouse);
|
void render(float a, bool mouseFree, int xMouse, int yMouse);
|
||||||
@@ -47,6 +48,12 @@ public:
|
|||||||
|
|
||||||
void renderChatMessages( const int screenHeight, unsigned int max, bool isChatting, Font* font );
|
void renderChatMessages( const int screenHeight, unsigned int max, bool isChatting, Font* font );
|
||||||
|
|
||||||
|
// draw a string containing simple [color]...[/color] tags; color names are matched
|
||||||
|
// case-insensitively and default to white. alpha is applied to each segment.
|
||||||
|
// draw tagged string (ignores simple [color]…[/color] tags)
|
||||||
|
static void drawColoredString(Font* font, const std::string& text, float x, float y, int alpha);
|
||||||
|
static float getColoredWidth(Font* font, const std::string& text);
|
||||||
|
|
||||||
void renderOnSelectItemNameText( const int screenWidth, Font* font, int ySlot );
|
void renderOnSelectItemNameText( const int screenWidth, Font* font, int ySlot );
|
||||||
|
|
||||||
void renderSleepAnimation( const int screenWidth, const int screenHeight );
|
void renderSleepAnimation( const int screenWidth, const int screenHeight );
|
||||||
@@ -54,10 +61,12 @@ public:
|
|||||||
void renderBubbles();
|
void renderBubbles();
|
||||||
void renderHearts();
|
void renderHearts();
|
||||||
void renderDebugInfo();
|
void renderDebugInfo();
|
||||||
|
void renderPlayerList(Font* font, int screenWidth, int screenHeight);
|
||||||
|
|
||||||
void renderProgressIndicator( const bool isTouchInterface, const int screenWidth, const int screenHeight, float a );
|
void renderProgressIndicator( const bool isTouchInterface, const int screenWidth, const int screenHeight, float a );
|
||||||
|
|
||||||
void addMessage(const std::string& string);
|
void addMessage(const std::string& string);
|
||||||
|
void clearMessages();
|
||||||
void postError(int errCode);
|
void postError(int errCode);
|
||||||
|
|
||||||
void onGraphicsReset();
|
void onGraphicsReset();
|
||||||
@@ -90,6 +99,7 @@ private:
|
|||||||
int MAX_MESSAGE_WIDTH;
|
int MAX_MESSAGE_WIDTH;
|
||||||
//ItemRenderer itemRenderer;
|
//ItemRenderer itemRenderer;
|
||||||
GuiMessageList guiMessages;
|
GuiMessageList guiMessages;
|
||||||
|
int chatScrollOffset;
|
||||||
Random random;
|
Random random;
|
||||||
|
|
||||||
Minecraft* minecraft;
|
Minecraft* minecraft;
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ void Screen::render( int xm, int ym, float a )
|
|||||||
Button* button = buttons[i];
|
Button* button = buttons[i];
|
||||||
button->render(minecraft, xm, ym);
|
button->render(minecraft, xm, ym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// render any text boxes after buttons
|
||||||
|
for (unsigned int i = 0; i < textBoxes.size(); i++) {
|
||||||
|
TextBox* textbox = textBoxes[i];
|
||||||
|
textbox->render(minecraft, xm, ym);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::init( Minecraft* minecraft, int width, int height )
|
void Screen::init( Minecraft* minecraft, int width, int height )
|
||||||
@@ -72,6 +78,14 @@ void Screen::updateEvents()
|
|||||||
void Screen::mouseEvent()
|
void Screen::mouseEvent()
|
||||||
{
|
{
|
||||||
const MouseAction& e = Mouse::getEvent();
|
const MouseAction& e = Mouse::getEvent();
|
||||||
|
// forward wheel events to subclasses
|
||||||
|
if (e.action == MouseAction::ACTION_WHEEL) {
|
||||||
|
int xm = e.x * width / minecraft->width;
|
||||||
|
int ym = e.y * height / minecraft->height - 1;
|
||||||
|
mouseWheel(e.dx, e.dy, xm, ym);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!e.isButton())
|
if (!e.isButton())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -98,7 +112,7 @@ void Screen::keyboardEvent()
|
|||||||
}
|
}
|
||||||
void Screen::keyboardTextEvent()
|
void Screen::keyboardTextEvent()
|
||||||
{
|
{
|
||||||
keyboardNewChar(Keyboard::getChar());
|
charPressed(Keyboard::getChar());
|
||||||
}
|
}
|
||||||
void Screen::renderBackground()
|
void Screen::renderBackground()
|
||||||
{
|
{
|
||||||
@@ -157,6 +171,12 @@ void Screen::keyPressed( int eventKey )
|
|||||||
minecraft->setScreen(NULL);
|
minecraft->setScreen(NULL);
|
||||||
//minecraft->grabMouse();
|
//minecraft->grabMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pass key events to any text boxes first
|
||||||
|
for (auto& textbox : textBoxes) {
|
||||||
|
textbox->keyPressed(minecraft, eventKey);
|
||||||
|
}
|
||||||
|
|
||||||
if (minecraft->useTouchscreen())
|
if (minecraft->useTouchscreen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -166,11 +186,11 @@ void Screen::keyPressed( int eventKey )
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Options& o = minecraft->options;
|
Options& o = minecraft->options;
|
||||||
if (eventKey == o.keyMenuNext.key)
|
if (eventKey == o.getIntValue(OPTIONS_KEY_MENU_NEXT))
|
||||||
if (++tabButtonIndex == tabButtonCount) tabButtonIndex = 0;
|
if (++tabButtonIndex == tabButtonCount) tabButtonIndex = 0;
|
||||||
if (eventKey == o.keyMenuPrevious.key)
|
if (eventKey == o.getIntValue(OPTIONS_KEY_MENU_PREV))
|
||||||
if (--tabButtonIndex == -1) tabButtonIndex = tabButtonCount-1;
|
if (--tabButtonIndex == -1) tabButtonIndex = tabButtonCount-1;
|
||||||
if (eventKey == o.keyMenuOk.key) {
|
if (eventKey == o.getIntValue(OPTIONS_KEY_MENU_OK)) {
|
||||||
Button* button = tabButtons[tabButtonIndex];
|
Button* button = tabButtons[tabButtonIndex];
|
||||||
if (button->active) {
|
if (button->active) {
|
||||||
minecraft->soundEngine->playUI("random.click", 1, 1);
|
minecraft->soundEngine->playUI("random.click", 1, 1);
|
||||||
@@ -181,6 +201,12 @@ void Screen::keyPressed( int eventKey )
|
|||||||
updateTabButtonSelection();
|
updateTabButtonSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Screen::charPressed(char inputChar) {
|
||||||
|
for (auto& textbox : textBoxes) {
|
||||||
|
textbox->charPressed(minecraft, inputChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Screen::updateTabButtonSelection()
|
void Screen::updateTabButtonSelection()
|
||||||
{
|
{
|
||||||
if (minecraft->useTouchscreen())
|
if (minecraft->useTouchscreen())
|
||||||
@@ -210,6 +236,11 @@ void Screen::mouseClicked( int x, int y, int buttonNum )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let textboxes see the click regardless
|
||||||
|
for (auto& textbox : textBoxes) {
|
||||||
|
textbox->mouseClicked(minecraft, x, y, buttonNum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::mouseReleased( int x, int y, int buttonNum )
|
void Screen::mouseReleased( int x, int y, int buttonNum )
|
||||||
|
|||||||
@@ -57,8 +57,11 @@ protected:
|
|||||||
virtual void mouseClicked(int x, int y, int buttonNum);
|
virtual void mouseClicked(int x, int y, int buttonNum);
|
||||||
virtual void mouseReleased(int x, int y, int buttonNum);
|
virtual void mouseReleased(int x, int y, int buttonNum);
|
||||||
|
|
||||||
|
// mouse wheel movement (dx/dy are wheel deltas, xm/ym are GUI coords)
|
||||||
|
virtual void mouseWheel(int dx, int dy, int xm, int ym) {}
|
||||||
|
|
||||||
virtual void keyPressed(int eventKey);
|
virtual void keyPressed(int eventKey);
|
||||||
virtual void keyboardNewChar(char inputChar) {}
|
virtual void charPressed(char inputChar);
|
||||||
public:
|
public:
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|||||||
@@ -9,13 +9,20 @@ class GuiElement : public GuiComponent {
|
|||||||
public:
|
public:
|
||||||
GuiElement(bool active=false, bool visible=true, int x = 0, int y = 0, int width=24, int height=24);
|
GuiElement(bool active=false, bool visible=true, int x = 0, int y = 0, int width=24, int height=24);
|
||||||
virtual ~GuiElement() {}
|
virtual ~GuiElement() {}
|
||||||
|
|
||||||
virtual void tick(Minecraft* minecraft) {}
|
virtual void tick(Minecraft* minecraft) {}
|
||||||
virtual void render(Minecraft* minecraft, int xm, int ym) { }
|
virtual void render(Minecraft* minecraft, int xm, int ym) { }
|
||||||
virtual void setupPositions() {}
|
virtual void setupPositions() {}
|
||||||
|
|
||||||
virtual void mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum) {}
|
virtual void mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum) {}
|
||||||
virtual void mouseReleased(Minecraft* minecraft, int x, int y, int buttonNum) {}
|
virtual void mouseReleased(Minecraft* minecraft, int x, int y, int buttonNum) {}
|
||||||
|
virtual void keyPressed(Minecraft* minecraft, int key) {}
|
||||||
|
virtual void charPressed(Minecraft* minecraft, char key) {}
|
||||||
|
|
||||||
virtual bool pointInside(int x, int y);
|
virtual bool pointInside(int x, int y);
|
||||||
|
|
||||||
void setVisible(bool visible);
|
void setVisible(bool visible);
|
||||||
|
|
||||||
bool active;
|
bool active;
|
||||||
bool visible;
|
bool visible;
|
||||||
int x;
|
int x;
|
||||||
|
|||||||
@@ -52,3 +52,15 @@ void GuiElementContainer::mouseReleased( Minecraft* minecraft, int x, int y, int
|
|||||||
(*it)->mouseReleased(minecraft, x, y, buttonNum);
|
(*it)->mouseReleased(minecraft, x, y, buttonNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GuiElementContainer::keyPressed(Minecraft* minecraft, int key) {
|
||||||
|
for(std::vector<GuiElement*>::iterator it = children.begin(); it != children.end(); ++it) {
|
||||||
|
(*it)->keyPressed(minecraft, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiElementContainer::charPressed(Minecraft* minecraft, char key) {
|
||||||
|
for(std::vector<GuiElement*>::iterator it = children.begin(); it != children.end(); ++it) {
|
||||||
|
(*it)->charPressed(minecraft, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,8 +17,9 @@ public:
|
|||||||
virtual void tick( Minecraft* minecraft );
|
virtual void tick( Minecraft* minecraft );
|
||||||
|
|
||||||
virtual void mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum );
|
virtual void mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum );
|
||||||
|
|
||||||
virtual void mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum );
|
virtual void mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum );
|
||||||
|
virtual void keyPressed(Minecraft* minecraft, int key);
|
||||||
|
virtual void charPressed(Minecraft* minecraft, char key);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<GuiElement*> children;
|
std::vector<GuiElement*> children;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "../../../platform/log.h"
|
#include "../../../platform/log.h"
|
||||||
#include "../../../util/Mth.h"
|
#include "../../../util/Mth.h"
|
||||||
#include "../../renderer/Textures.h"
|
#include "../../renderer/Textures.h"
|
||||||
|
#include <client/Option.h>
|
||||||
|
|
||||||
|
|
||||||
ImageButton::ImageButton(int id, const std::string& msg)
|
ImageButton::ImageButton(int id, const std::string& msg)
|
||||||
@@ -112,43 +113,17 @@ void ImageButton::render(Minecraft* minecraft, int xm, int ym) {
|
|||||||
//
|
//
|
||||||
// A toggleable Button
|
// A toggleable Button
|
||||||
//
|
//
|
||||||
OptionButton::OptionButton(const Options::Option* option)
|
OptionButton::OptionButton(OptionId option) : m_optId(option), super(ButtonId, "") {}
|
||||||
: _option(option),
|
|
||||||
_isFloat(false),
|
|
||||||
super(ButtonId, "")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionButton::OptionButton(const Options::Option* option, float onValue, float offValue)
|
|
||||||
: _option(option),
|
|
||||||
_isFloat(true),
|
|
||||||
_onValue(onValue),
|
|
||||||
_offValue(offValue),
|
|
||||||
super(ButtonId, "")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OptionButton::isSecondImage(bool hovered) {
|
|
||||||
return _secondImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionButton::toggle(Options* options) {
|
void OptionButton::toggle(Options* options) {
|
||||||
if (_isFloat) {
|
options->toggle(m_optId);
|
||||||
options->set(_option, (Mth::abs(_current - _onValue) < 0.01f) ? _offValue : _onValue);
|
|
||||||
} else {
|
|
||||||
options->toggle(_option, 1);
|
|
||||||
}
|
|
||||||
// Update graphics here
|
// Update graphics here
|
||||||
updateImage(options);
|
updateImage(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionButton::updateImage(Options* options) {
|
void OptionButton::updateImage(Options* options) {
|
||||||
if (_isFloat) {
|
_secondImage = options->getBooleanValue(m_optId);
|
||||||
_current = options->getProgressValue(_option);
|
|
||||||
_secondImage = Mth::abs(_current - _onValue) < 0.01f;
|
|
||||||
} else {
|
|
||||||
_secondImage = options->getBooleanValue(_option);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionButton::mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum ) {
|
void OptionButton::mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum ) {
|
||||||
|
|||||||
@@ -77,28 +77,20 @@ class OptionButton: public ImageButton
|
|||||||
{
|
{
|
||||||
typedef ImageButton super;
|
typedef ImageButton super;
|
||||||
public:
|
public:
|
||||||
OptionButton(const Options::Option* option);
|
OptionButton(OptionId optId);
|
||||||
OptionButton(const Options::Option* option, float onValue, float offValue);
|
|
||||||
|
|
||||||
void toggle(Options* options);
|
void toggle(Options* options);
|
||||||
void updateImage(Options* options);
|
void updateImage(Options* options);
|
||||||
|
|
||||||
static const int ButtonId = 9999999;
|
static const int ButtonId = 9999999;
|
||||||
protected:
|
protected:
|
||||||
bool isSecondImage(bool hovered);
|
bool isSecondImage(bool hovered) { return _secondImage; }
|
||||||
|
|
||||||
virtual void mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum );
|
virtual void mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
OptionId m_optId;
|
||||||
const Options::Option* _option;
|
|
||||||
bool _secondImage;
|
bool _secondImage;
|
||||||
|
|
||||||
// If not float, it's considered to be a boolean value
|
|
||||||
bool _isFloat;
|
|
||||||
float _onValue;
|
|
||||||
float _offValue;
|
|
||||||
float _current;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
22
src/client/gui/components/KeyOption.cpp
Normal file
22
src/client/gui/components/KeyOption.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "KeyOption.h"
|
||||||
|
#include <client/Minecraft.h>
|
||||||
|
|
||||||
|
KeyOption::KeyOption(Minecraft* minecraft, OptionId optId)
|
||||||
|
: Touch::TButton((int)optId, Keyboard::getKeyName(minecraft->options.getIntValue(optId))) {}
|
||||||
|
|
||||||
|
|
||||||
|
void KeyOption::mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum) {
|
||||||
|
selected = isInside(x, y);
|
||||||
|
msg = (selected)? "..." : Keyboard::getKeyName(minecraft->options.getIntValue((OptionId)id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyOption::keyPressed(Minecraft* minecraft, int key) {
|
||||||
|
if (!selected) return;
|
||||||
|
|
||||||
|
if (key != Keyboard::KEY_ESCAPE) {
|
||||||
|
minecraft->options.set((OptionId)id, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
selected = false;
|
||||||
|
msg = Keyboard::getKeyName(minecraft->options.getIntValue((OptionId)id));
|
||||||
|
}
|
||||||
14
src/client/gui/components/KeyOption.h
Normal file
14
src/client/gui/components/KeyOption.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Button.h"
|
||||||
|
#include <client/Options.h>
|
||||||
|
|
||||||
|
class KeyOption : public Touch::TButton {
|
||||||
|
public:
|
||||||
|
KeyOption(Minecraft* minecraft, OptionId optId);
|
||||||
|
|
||||||
|
virtual void mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum);
|
||||||
|
virtual void released(int mx, int my) {}
|
||||||
|
virtual void keyPressed(Minecraft* minecraft, int key);
|
||||||
|
protected:
|
||||||
|
bool m_captureMode;
|
||||||
|
};
|
||||||
@@ -4,13 +4,16 @@
|
|||||||
#include "OptionsItem.h"
|
#include "OptionsItem.h"
|
||||||
#include "Slider.h"
|
#include "Slider.h"
|
||||||
#include "../../../locale/I18n.h"
|
#include "../../../locale/I18n.h"
|
||||||
|
#include "TextOption.h"
|
||||||
|
#include "KeyOption.h"
|
||||||
|
|
||||||
OptionsGroup::OptionsGroup( std::string labelID ) {
|
OptionsGroup::OptionsGroup( std::string labelID ) {
|
||||||
label = I18n::get(labelID);
|
label = I18n::get(labelID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsGroup::setupPositions() {
|
void OptionsGroup::setupPositions() {
|
||||||
// First we write the header and then we add the items
|
// First we write the header and then we add the items
|
||||||
int curY = y + 10;
|
int curY = y + 18;
|
||||||
for(std::vector<GuiElement*>::iterator it = children.begin(); it != children.end(); ++it) {
|
for(std::vector<GuiElement*>::iterator it = children.begin(); it != children.end(); ++it) {
|
||||||
(*it)->width = width - 5;
|
(*it)->width = width - 5;
|
||||||
|
|
||||||
@@ -23,46 +26,90 @@ void OptionsGroup::setupPositions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OptionsGroup::render( Minecraft* minecraft, int xm, int ym ) {
|
void OptionsGroup::render( Minecraft* minecraft, int xm, int ym ) {
|
||||||
minecraft->font->draw(label, (float)x + 2, (float)y, 0xffffffff, false);
|
float padX = 10.0f;
|
||||||
|
float padY = 5.0f;
|
||||||
|
|
||||||
|
minecraft->font->draw(label, (float)x + padX, (float)y + padY, 0xffffffff, false);
|
||||||
|
|
||||||
super::render(minecraft, xm, ym);
|
super::render(minecraft, xm, ym);
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionsGroup& OptionsGroup::addOptionItem( const Options::Option* option, Minecraft* minecraft ) {
|
OptionsGroup& OptionsGroup::addOptionItem(OptionId optId, Minecraft* minecraft ) {
|
||||||
if(option->isBoolean())
|
auto option = minecraft->options.getOpt(optId);
|
||||||
createToggle(option, minecraft);
|
|
||||||
else if(option->isProgress())
|
if (option == nullptr) return *this;
|
||||||
createProgressSlider(option, minecraft);
|
|
||||||
else if(option->isInt())
|
// TODO: do a options key class to check it faster via dynamic_cast
|
||||||
createStepSlider(option, minecraft);
|
if (option->getStringId().find("options.key") != std::string::npos) createKey(optId, minecraft);
|
||||||
|
else if (dynamic_cast<OptionBool*>(option)) createToggle(optId, minecraft);
|
||||||
|
else if (dynamic_cast<OptionFloat*>(option)) createProgressSlider(optId, minecraft);
|
||||||
|
else if (dynamic_cast<OptionInt*>(option)) createStepSlider(optId, minecraft);
|
||||||
|
else if (dynamic_cast<OptionString*>(option)) createTextbox(optId, minecraft);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsGroup::createToggle( const Options::Option* option, Minecraft* minecraft ) {
|
// TODO: wrap this copypaste shit into templates
|
||||||
|
|
||||||
|
void OptionsGroup::createToggle(OptionId optId, Minecraft* minecraft ) {
|
||||||
ImageDef def;
|
ImageDef def;
|
||||||
|
|
||||||
def.setSrc(IntRectangle(160, 206, 39, 20));
|
def.setSrc(IntRectangle(160, 206, 39, 20));
|
||||||
def.name = "gui/touchgui.png";
|
def.name = "gui/touchgui.png";
|
||||||
def.width = 39 * 0.7f;
|
def.width = 39 * 0.7f;
|
||||||
def.height = 20 * 0.7f;
|
def.height = 20 * 0.7f;
|
||||||
OptionButton* element = new OptionButton(option);
|
|
||||||
|
OptionButton* element = new OptionButton(optId);
|
||||||
element->setImageDef(def, true);
|
element->setImageDef(def, true);
|
||||||
std::string itemLabel = I18n::get(option->getCaptionId());
|
element->updateImage(&minecraft->options);
|
||||||
|
|
||||||
|
std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId());
|
||||||
|
|
||||||
|
OptionsItem* item = new OptionsItem(itemLabel, element);
|
||||||
|
|
||||||
|
addChild(item);
|
||||||
|
setupPositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsGroup::createProgressSlider(OptionId optId, Minecraft* minecraft ) {
|
||||||
|
Slider* element = new SliderFloat(minecraft, optId);
|
||||||
|
element->width = 100;
|
||||||
|
element->height = 20;
|
||||||
|
|
||||||
|
std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId());
|
||||||
OptionsItem* item = new OptionsItem(itemLabel, element);
|
OptionsItem* item = new OptionsItem(itemLabel, element);
|
||||||
addChild(item);
|
addChild(item);
|
||||||
setupPositions();
|
setupPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsGroup::createProgressSlider( const Options::Option* option, Minecraft* minecraft ) {
|
void OptionsGroup::createStepSlider(OptionId optId, Minecraft* minecraft ) {
|
||||||
Slider* element = new Slider(minecraft,
|
Slider* element = new SliderInt(minecraft, optId);
|
||||||
option,
|
|
||||||
minecraft->options.getProgrssMin(option),
|
|
||||||
minecraft->options.getProgrssMax(option));
|
|
||||||
element->width = 100;
|
element->width = 100;
|
||||||
element->height = 20;
|
element->height = 20;
|
||||||
OptionsItem* item = new OptionsItem(label, element);
|
std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId());
|
||||||
|
OptionsItem* item = new OptionsItem(itemLabel, element);
|
||||||
addChild(item);
|
addChild(item);
|
||||||
setupPositions();
|
setupPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsGroup::createStepSlider( const Options::Option* option, Minecraft* minecraft ) {
|
void OptionsGroup::createTextbox(OptionId optId, Minecraft* minecraft) {
|
||||||
|
TextBox* element = new TextOption(minecraft, optId);
|
||||||
|
element->width = 100;
|
||||||
|
element->height = 20;
|
||||||
|
|
||||||
|
std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId());
|
||||||
|
OptionsItem* item = new OptionsItem(itemLabel, element);
|
||||||
|
addChild(item);
|
||||||
|
setupPositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsGroup::createKey(OptionId optId, Minecraft* minecraft) {
|
||||||
|
KeyOption* element = new KeyOption(minecraft, optId);
|
||||||
|
element->width = 50;
|
||||||
|
element->height = 20;
|
||||||
|
|
||||||
|
std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId());
|
||||||
|
OptionsItem* item = new OptionsItem(itemLabel, element);
|
||||||
|
addChild(item);
|
||||||
|
setupPositions();
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "GuiElementContainer.h"
|
#include "GuiElementContainer.h"
|
||||||
|
#include "ScrollingPane.h"
|
||||||
#include "../../Options.h"
|
#include "../../Options.h"
|
||||||
|
|
||||||
class Font;
|
class Font;
|
||||||
@@ -16,11 +17,15 @@ public:
|
|||||||
OptionsGroup(std::string labelID);
|
OptionsGroup(std::string labelID);
|
||||||
virtual void setupPositions();
|
virtual void setupPositions();
|
||||||
virtual void render(Minecraft* minecraft, int xm, int ym);
|
virtual void render(Minecraft* minecraft, int xm, int ym);
|
||||||
virtual OptionsGroup& addOptionItem(const Options::Option* option, Minecraft* minecraft);
|
OptionsGroup& addOptionItem(OptionId optId, Minecraft* minecraft);
|
||||||
protected:
|
protected:
|
||||||
virtual void createToggle(const Options::Option* option, Minecraft* minecraft);
|
|
||||||
virtual void createProgressSlider(const Options::Option* option, Minecraft* minecraft);
|
void createToggle(OptionId optId, Minecraft* minecraft);
|
||||||
virtual void createStepSlider(const Options::Option* option, Minecraft* minecraft);
|
void createProgressSlider(OptionId optId, Minecraft* minecraft);
|
||||||
|
void createStepSlider(OptionId optId, Minecraft* minecraft);
|
||||||
|
void createTextbox(OptionId optId, Minecraft* minecraft);
|
||||||
|
void createKey(OptionId optId, Minecraft* minecraft);
|
||||||
|
|
||||||
std::string label;
|
std::string label;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
#include "OptionsPane.h"
|
|
||||||
#include "OptionsGroup.h"
|
|
||||||
#include "OptionsItem.h"
|
|
||||||
#include "ImageButton.h"
|
|
||||||
#include "Slider.h"
|
|
||||||
#include "../../Minecraft.h"
|
|
||||||
|
|
||||||
OptionsPane::OptionsPane() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsPane::setupPositions() {
|
|
||||||
int currentHeight = y + 1;
|
|
||||||
for(std::vector<GuiElement*>::iterator it = children.begin(); it != children.end(); ++it ) {
|
|
||||||
(*it)->width = width;
|
|
||||||
(*it)->y = currentHeight;
|
|
||||||
(*it)->x = x;
|
|
||||||
currentHeight += (*it)->height + 1;
|
|
||||||
}
|
|
||||||
height = currentHeight;
|
|
||||||
super::setupPositions();
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionsGroup& OptionsPane::createOptionsGroup( std::string label ) {
|
|
||||||
OptionsGroup* newGroup = new OptionsGroup(label);
|
|
||||||
children.push_back(newGroup);
|
|
||||||
// create and return a new group index
|
|
||||||
return *newGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsPane::createToggle( unsigned int group, std::string label, const Options::Option* option ) {
|
|
||||||
// if(group > children.size()) return;
|
|
||||||
// ImageDef def;
|
|
||||||
// def.setSrc(IntRectangle(160, 206, 39, 20));
|
|
||||||
// def.name = "gui/touchgui.png";
|
|
||||||
// def.width = 39 * 0.7f;
|
|
||||||
// def.height = 20 * 0.7f;
|
|
||||||
// OptionButton* element = new OptionButton(option);
|
|
||||||
// element->setImageDef(def, true);
|
|
||||||
// OptionsItem* item = new OptionsItem(label, element);
|
|
||||||
// ((OptionsGroup*)children[group])->addChild(item);
|
|
||||||
// setupPositions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsPane::createProgressSlider( Minecraft* minecraft, unsigned int group, std::string label, const Options::Option* option, float progressMin/*=1.0f*/, float progressMax/*=1.0f */ ) {
|
|
||||||
// if(group > children.size()) return;
|
|
||||||
// Slider* element = new Slider(minecraft, option, progressMin, progressMax);
|
|
||||||
// element->width = 100;
|
|
||||||
// element->height = 20;
|
|
||||||
// OptionsItem* item = new OptionsItem(label, element);
|
|
||||||
// ((OptionsGroup*)children[group])->addChild(item);
|
|
||||||
// setupPositions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OptionsPane::createStepSlider( Minecraft* minecraft, unsigned int group, std::string label, const Options::Option* option, const std::vector<int>& stepVec ) {
|
|
||||||
// if(group > children.size()) return;
|
|
||||||
// Slider* element = new Slider(minecraft, option, stepVec);
|
|
||||||
// element->width = 100;
|
|
||||||
// element->height = 20;
|
|
||||||
// sliders.push_back(element);
|
|
||||||
// OptionsItem* item = new OptionsItem(label, element);
|
|
||||||
// ((OptionsGroup*)children[group])->addChild(item);
|
|
||||||
// setupPositions();
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#ifndef ITEMPANE_H__
|
|
||||||
#define ITEMPANE_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include "GuiElementContainer.h"
|
|
||||||
#include "../../../world/item/ItemInstance.h"
|
|
||||||
#include "../../../client/Options.h"
|
|
||||||
class Font;
|
|
||||||
class Textures;
|
|
||||||
class NinePatchLayer;
|
|
||||||
class ItemPane;
|
|
||||||
class OptionButton;
|
|
||||||
class Button;
|
|
||||||
class OptionsGroup;
|
|
||||||
class Slider;
|
|
||||||
class Minecraft;
|
|
||||||
class OptionsPane: public GuiElementContainer
|
|
||||||
{
|
|
||||||
typedef GuiElementContainer super;
|
|
||||||
public:
|
|
||||||
OptionsPane();
|
|
||||||
OptionsGroup& createOptionsGroup( std::string label );
|
|
||||||
void createToggle( unsigned int group, std::string label, const Options::Option* option );
|
|
||||||
void createProgressSlider(Minecraft* minecraft, unsigned int group, std::string label, const Options::Option* option, float progressMin=1.0f, float progressMax=1.0f );
|
|
||||||
void createStepSlider(Minecraft* minecraft, unsigned int group, std::string label, const Options::Option* option, const std::vector<int>& stepVec );
|
|
||||||
void setupPositions();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*ITEMPANE_H__*/
|
|
||||||
@@ -548,6 +548,14 @@ void ScrollingPane::stepThroughDecelerationAnimation(bool noAnimation) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScrollingPane::scrollBy(float dx, float dy) {
|
||||||
|
// adjust the translation offsets fpx/fpy by the requested amount
|
||||||
|
float nfpx = fpx + dx;
|
||||||
|
float nfpy = fpy + dy;
|
||||||
|
// convert back to content offset (fpx = -contentOffset.x)
|
||||||
|
setContentOffset(Vec3(-nfpx, -nfpy, 0));
|
||||||
|
}
|
||||||
|
|
||||||
void ScrollingPane::setContentOffset(float x, float y) {
|
void ScrollingPane::setContentOffset(float x, float y) {
|
||||||
this->setContentOffsetWithAnimation(Vec3(x, y, 0), false);
|
this->setContentOffsetWithAnimation(Vec3(x, y, 0), false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ public:
|
|||||||
void tick();
|
void tick();
|
||||||
void render(int xm, int ym, float alpha);
|
void render(int xm, int ym, float alpha);
|
||||||
|
|
||||||
|
// scroll the content by the given amount (dx horizontal, dy vertical)
|
||||||
|
// positive values move content downward/rightward
|
||||||
|
void scrollBy(float dx, float dy);
|
||||||
|
|
||||||
bool getGridItemFor_slow(int itemIndex, GridItem& out);
|
bool getGridItemFor_slow(int itemIndex, GridItem& out);
|
||||||
|
|
||||||
void setSelected(int id, bool selected);
|
void setSelected(int id, bool selected);
|
||||||
|
|||||||
@@ -5,35 +5,8 @@
|
|||||||
#include "../../../util/Mth.h"
|
#include "../../../util/Mth.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
Slider::Slider(Minecraft* minecraft, const Options::Option* option, float progressMin, float progressMax)
|
|
||||||
: sliderType(SliderProgress), mouseDownOnElement(false), option(option), numSteps(0), progressMin(progressMin), progressMax(progressMax) {
|
|
||||||
if(option != NULL) {
|
|
||||||
percentage = (minecraft->options.getProgressValue(option) - progressMin) / (progressMax - progressMin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Slider::Slider(Minecraft* minecraft, const Options::Option* option, const std::vector<int>& stepVec )
|
Slider::Slider(OptionId optId) : m_mouseDownOnElement(false), m_optId(optId), m_numSteps(0) {}
|
||||||
: sliderType(SliderStep),
|
|
||||||
curStepValue(0),
|
|
||||||
curStep(0),
|
|
||||||
sliderSteps(stepVec),
|
|
||||||
mouseDownOnElement(false),
|
|
||||||
option(option),
|
|
||||||
percentage(0),
|
|
||||||
progressMin(0.0f),
|
|
||||||
progressMax(1.0) {
|
|
||||||
assert(stepVec.size() > 1);
|
|
||||||
numSteps = sliderSteps.size();
|
|
||||||
if(option != NULL) {
|
|
||||||
curStepValue;
|
|
||||||
int curStep;
|
|
||||||
curStepValue = minecraft->options.getIntValue(option);
|
|
||||||
std::vector<int>::iterator currentItem = std::find(sliderSteps.begin(), sliderSteps.end(), curStepValue);
|
|
||||||
if(currentItem != sliderSteps.end()) {
|
|
||||||
curStep = currentItem - sliderSteps.begin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Slider::render( Minecraft* minecraft, int xm, int ym ) {
|
void Slider::render( Minecraft* minecraft, int xm, int ym ) {
|
||||||
int xSliderStart = x + 5;
|
int xSliderStart = x + 5;
|
||||||
@@ -45,56 +18,71 @@ void Slider::render( Minecraft* minecraft, int xm, int ym ) {
|
|||||||
int barWidth = xSliderEnd - xSliderStart;
|
int barWidth = xSliderEnd - xSliderStart;
|
||||||
//fill(x, y + 8, x + (int)(width * percentage), y + height, 0xffff00ff);
|
//fill(x, y + 8, x + (int)(width * percentage), y + height, 0xffff00ff);
|
||||||
fill(xSliderStart, ySliderStart, xSliderEnd, ySliderEnd, 0xff606060);
|
fill(xSliderStart, ySliderStart, xSliderEnd, ySliderEnd, 0xff606060);
|
||||||
if(sliderType == SliderStep) {
|
|
||||||
int stepDistance = barWidth / (numSteps -1);
|
if (m_numSteps > 2) {
|
||||||
for(int a = 0; a <= numSteps - 1; ++a) {
|
int stepDistance = barWidth / (m_numSteps-1);
|
||||||
|
for(int a = 0; a <= m_numSteps; ++a) {
|
||||||
int renderSliderStepPosX = xSliderStart + a * stepDistance + 1;
|
int renderSliderStepPosX = xSliderStart + a * stepDistance + 1;
|
||||||
fill(renderSliderStepPosX - 1, ySliderStart - 2, renderSliderStepPosX + 1, ySliderEnd + 2, 0xff606060);
|
fill(renderSliderStepPosX - 1, ySliderStart - 2, renderSliderStepPosX + 1, ySliderEnd + 2, 0xff606060);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
minecraft->textures->loadAndBindTexture("gui/touchgui.png");
|
minecraft->textures->loadAndBindTexture("gui/touchgui.png");
|
||||||
blit(xSliderStart + (int)(percentage * barWidth) - handleSizeX / 2, y, 226, 126, handleSizeX, handleSizeY, handleSizeX, handleSizeY);
|
blit(xSliderStart + (int)(m_percentage * barWidth) - handleSizeX / 2, y, 226, 126, handleSizeX, handleSizeY, handleSizeX, handleSizeY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Slider::mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum ) {
|
void Slider::mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum ) {
|
||||||
if(pointInside(x, y)) {
|
if(pointInside(x, y)) {
|
||||||
mouseDownOnElement = true;
|
m_mouseDownOnElement = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Slider::mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum ) {
|
void Slider::mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum ) {
|
||||||
mouseDownOnElement = false;
|
m_mouseDownOnElement = false;
|
||||||
if(sliderType == SliderStep) {
|
|
||||||
curStep = Mth::floor((percentage * (numSteps-1) + 0.5f));
|
|
||||||
curStepValue = sliderSteps[Mth::Min(curStep, numSteps-1)];
|
|
||||||
percentage = float(curStep) / (numSteps - 1);
|
|
||||||
setOption(minecraft);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Slider::tick(Minecraft* minecraft) {
|
void Slider::tick(Minecraft* minecraft) {
|
||||||
if(minecraft->screen != NULL) {
|
if(minecraft->screen != NULL) {
|
||||||
int xm = Mouse::getX();
|
int xm = Mouse::getX();
|
||||||
int ym = Mouse::getY();
|
int ym = Mouse::getY();
|
||||||
|
|
||||||
minecraft->screen->toGUICoordinate(xm, ym);
|
minecraft->screen->toGUICoordinate(xm, ym);
|
||||||
if(mouseDownOnElement) {
|
|
||||||
percentage = float(xm - x) / float(width);
|
if(m_mouseDownOnElement) {
|
||||||
percentage = Mth::clamp(percentage, 0.0f, 1.0f);
|
m_percentage = float(xm - x) / float(width);
|
||||||
setOption(minecraft);
|
m_percentage = Mth::clamp(m_percentage, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Slider::setOption( Minecraft* minecraft ) {
|
SliderFloat::SliderFloat(Minecraft* minecraft, OptionId option)
|
||||||
if(option != NULL) {
|
: Slider(option), m_option(dynamic_cast<OptionFloat*>(minecraft->options.getOpt(option)))
|
||||||
if(sliderType == SliderStep) {
|
{
|
||||||
if(minecraft->options.getIntValue(option) != curStepValue) {
|
m_percentage = Mth::clamp((m_option->get() - m_option->getMin()) / (m_option->getMax() - m_option->getMin()), 0.f, 1.f);
|
||||||
minecraft->options.set(option, curStepValue);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if(minecraft->options.getProgressValue(option) != percentage * (progressMax - progressMin) + progressMin) {
|
SliderInt::SliderInt(Minecraft* minecraft, OptionId option)
|
||||||
minecraft->options.set(option, percentage * (progressMax - progressMin) + progressMin);
|
: Slider(option), m_option(dynamic_cast<OptionInt*>(minecraft->options.getOpt(option)))
|
||||||
|
{
|
||||||
|
m_numSteps = m_option->getMax() - m_option->getMin();
|
||||||
|
m_percentage = float(m_option->get() - m_option->getMin()) / (m_numSteps-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SliderInt::mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum ) {
|
||||||
|
Slider::mouseReleased(minecraft, x, y, buttonNum);
|
||||||
|
|
||||||
|
if (pointInside(x, y)) {
|
||||||
|
int curStep = Mth::floor(m_percentage * (m_numSteps-1));
|
||||||
|
m_percentage = float(curStep - m_option->getMin()) / (m_numSteps-1);
|
||||||
|
|
||||||
|
minecraft->options.set(m_optId, curStep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SliderFloat::mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum ) {
|
||||||
|
Slider::mouseReleased(minecraft, x, y, buttonNum);
|
||||||
|
|
||||||
|
if (pointInside(x, y)) {
|
||||||
|
minecraft->options.set(m_optId, m_percentage * (m_option->getMax() - m_option->getMin()) + m_option->getMin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,38 +3,45 @@
|
|||||||
|
|
||||||
#include "GuiElement.h"
|
#include "GuiElement.h"
|
||||||
#include "../../../client/Options.h"
|
#include "../../../client/Options.h"
|
||||||
enum SliderType {
|
#include <client/Option.h>
|
||||||
SliderProgress, // Sets slider between {0..1}
|
|
||||||
SliderStep // Uses the closest step
|
|
||||||
};
|
|
||||||
class Slider : public GuiElement {
|
class Slider : public GuiElement {
|
||||||
typedef GuiElement super;
|
typedef GuiElement super;
|
||||||
public:
|
public:
|
||||||
// Creates a progress slider with no steps
|
|
||||||
Slider(Minecraft* minecraft, const Options::Option* option, float progressMin, float progressMax);
|
|
||||||
Slider(Minecraft* minecraft, const Options::Option* option, const std::vector<int>& stepVec);
|
|
||||||
virtual void render( Minecraft* minecraft, int xm, int ym );
|
virtual void render( Minecraft* minecraft, int xm, int ym );
|
||||||
|
|
||||||
virtual void mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum );
|
virtual void mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum );
|
||||||
|
|
||||||
virtual void mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum );
|
virtual void mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum );
|
||||||
|
|
||||||
virtual void tick(Minecraft* minecraft);
|
virtual void tick(Minecraft* minecraft);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
virtual void setOption(Minecraft* minecraft);
|
Slider(OptionId optId);
|
||||||
|
|
||||||
private:
|
OptionId m_optId;
|
||||||
SliderType sliderType;
|
|
||||||
std::vector<int> sliderSteps;
|
bool m_mouseDownOnElement;
|
||||||
bool mouseDownOnElement;
|
float m_percentage;
|
||||||
float percentage;
|
int m_numSteps;
|
||||||
int curStepValue;
|
};
|
||||||
int curStep;
|
|
||||||
int numSteps;
|
class SliderFloat : public Slider {
|
||||||
float progressMin;
|
public:
|
||||||
float progressMax;
|
SliderFloat(Minecraft* minecraft, OptionId option);
|
||||||
const Options::Option* option;
|
|
||||||
|
virtual void mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum ) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
OptionFloat* m_option;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SliderInt : public Slider {
|
||||||
|
public:
|
||||||
|
SliderInt(Minecraft* minecraft, OptionId option);
|
||||||
|
|
||||||
|
virtual void mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum ) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
OptionInt* m_option;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT_GUI_COMPONENTS__Slider_H__*/
|
#endif /*NET_MINECRAFT_CLIENT_GUI_COMPONENTS__Slider_H__*/
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
#include "SmallButton.h"
|
|
||||||
|
|
||||||
SmallButton::SmallButton( int id, int x, int y, const std::string& msg )
|
|
||||||
: super(id, x, y, 150, 20, msg),
|
|
||||||
option(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallButton::SmallButton( int id, int x, int y, int width, int height, const std::string& msg )
|
|
||||||
: super(id, x, y, width, height, msg),
|
|
||||||
option(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallButton::SmallButton( int id, int x, int y, Options::Option* item, const std::string& msg )
|
|
||||||
: super(id, x, y, 150, 20, msg),
|
|
||||||
option(item)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Options::Option* SmallButton::getOption()
|
|
||||||
{
|
|
||||||
return option;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#ifndef NET_MINECRAFT_CLIENT_GUI_COMPONENTS__SmallButton_H__
|
|
||||||
#define NET_MINECRAFT_CLIENT_GUI_COMPONENTS__SmallButton_H__
|
|
||||||
|
|
||||||
//package net.minecraft.client.gui;
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "Button.h"
|
|
||||||
#include "../../Options.h"
|
|
||||||
|
|
||||||
class SmallButton: public Button
|
|
||||||
{
|
|
||||||
typedef Button super;
|
|
||||||
public:
|
|
||||||
SmallButton(int id, int x, int y, const std::string& msg);
|
|
||||||
SmallButton(int id, int x, int y, int width, int height, const std::string& msg);
|
|
||||||
SmallButton(int id, int x, int y, Options::Option* item, const std::string& msg);
|
|
||||||
|
|
||||||
Options::Option* getOption();
|
|
||||||
private:
|
|
||||||
Options::Option* option;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT_GUI_COMPONENTS__SmallButton_H__*/
|
|
||||||
@@ -1,37 +1,102 @@
|
|||||||
#include "TextBox.h"
|
#include "TextBox.h"
|
||||||
|
#include "../Gui.h"
|
||||||
#include "../../Minecraft.h"
|
#include "../../Minecraft.h"
|
||||||
#include "../../../AppPlatform.h"
|
#include "../../../AppPlatform.h"
|
||||||
TextBox::TextBox( int id, const std::string& msg )
|
#include "../../../platform/input/Mouse.h"
|
||||||
: id(0), w(0), h(0), x(0), y(0), text(msg), focused(false) {
|
|
||||||
|
|
||||||
|
// delegate constructors
|
||||||
|
TextBox::TextBox(int id, const std::string& msg)
|
||||||
|
: TextBox(id, 0, 0, msg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TextBox::TextBox(int id, int x, int y, const std::string& msg)
|
TextBox::TextBox(int id, int x, int y, const std::string& msg)
|
||||||
: id(id), w(0), h(0), x(x), y(y), text(msg), focused(false) {
|
: TextBox(id, x, y, 24, Font::DefaultLineHeight + 4, msg)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TextBox::TextBox(int id, int x, int y, int w, int h, const std::string& msg)
|
TextBox::TextBox(int id, int x, int y, int w, int h, const std::string& msg)
|
||||||
: id(id), w(w), h(h), x(x), y(y), text(msg) {
|
: GuiElement(true, true, x, y, w, h),
|
||||||
|
id(id), hint(msg), focused(false), blink(false), blinkTicks(0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::setFocus(Minecraft* minecraft) {
|
void TextBox::setFocus(Minecraft* minecraft) {
|
||||||
if (!focused) {
|
if (!focused) {
|
||||||
minecraft->platform()->showKeyboard();
|
minecraft->platform()->showKeyboard();
|
||||||
focused = true;
|
focused = true;
|
||||||
|
blinkTicks = 0;
|
||||||
|
blink = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextBox::loseFocus(Minecraft* minecraft) {
|
bool TextBox::loseFocus(Minecraft* minecraft) {
|
||||||
if (focused) {
|
if (focused) {
|
||||||
minecraft->platform()->showKeyboard();
|
minecraft->platform()->hideKeyboard();
|
||||||
focused = false;
|
focused = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::render( Minecraft* minecraft, int xm, int ym ) {
|
void TextBox::mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum) {
|
||||||
|
if (buttonNum == MouseAction::ACTION_LEFT) {
|
||||||
|
if (pointInside(x, y)) {
|
||||||
|
setFocus(minecraft);
|
||||||
|
} else {
|
||||||
|
loseFocus(minecraft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBox::charPressed(Minecraft* minecraft, char c) {
|
||||||
|
if (focused && c >= 32 && c < 127 && (int)text.size() < 256) {
|
||||||
|
text.push_back(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBox::keyPressed(Minecraft* minecraft, int key) {
|
||||||
|
if (focused && key == Keyboard::KEY_BACKSPACE && !text.empty()) {
|
||||||
|
text.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBox::tick(Minecraft* minecraft) {
|
||||||
|
blinkTicks++;
|
||||||
|
if (blinkTicks >= 5) {
|
||||||
|
blink = !blink;
|
||||||
|
blinkTicks = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBox::render(Minecraft* minecraft, int xm, int ym) {
|
||||||
|
// textbox like in beta 1.7.3
|
||||||
|
// change appearance when focused so the user can tell it's active
|
||||||
|
// active background darker gray with a subtle border
|
||||||
|
uint32_t bgColor = focused ? 0xffa0a0a0 : 0xffa0a0a0;
|
||||||
|
uint32_t borderColor = focused ? 0xff000000 : 0xff000000;
|
||||||
|
fill(x, y, x + width, y + height, bgColor);
|
||||||
|
fill(x + 1, y + 1, x + width - 1, y + height - 1, borderColor);
|
||||||
|
|
||||||
|
glEnable2(GL_SCISSOR_TEST);
|
||||||
|
glScissor(
|
||||||
|
Gui::GuiScale * (x + 2),
|
||||||
|
minecraft->height - Gui::GuiScale * (y + height - 2),
|
||||||
|
Gui::GuiScale * (width - 2),
|
||||||
|
Gui::GuiScale * (height - 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
int _y = y + (height - Font::DefaultLineHeight) / 2;
|
||||||
|
|
||||||
|
if (text.empty() && !focused) {
|
||||||
|
drawString(minecraft->font, hint, x + 2, _y, 0xff5e5e5e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (focused && blink) text.push_back('_');
|
||||||
|
|
||||||
|
drawString(minecraft->font, text, x + 2, _y, 0xffffffff);
|
||||||
|
|
||||||
|
if (focused && blink) text.pop_back();
|
||||||
|
|
||||||
|
glDisable2(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,31 +4,41 @@
|
|||||||
//package net.minecraft.client.gui;
|
//package net.minecraft.client.gui;
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../GuiComponent.h"
|
#include "GuiElement.h"
|
||||||
#include "../../Options.h"
|
#include "../../Options.h"
|
||||||
|
#include "../../../platform/input/Mouse.h"
|
||||||
|
#include "../../../platform/input/Keyboard.h"
|
||||||
|
|
||||||
class Font;
|
class Font;
|
||||||
class Minecraft;
|
class Minecraft;
|
||||||
|
|
||||||
class TextBox: public GuiComponent
|
class TextBox: public GuiElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextBox(int id, const std::string& msg);
|
TextBox(int id, const std::string& msg);
|
||||||
TextBox(int id, int x, int y, const std::string& msg);
|
TextBox(int id, int x, int y, const std::string& msg);
|
||||||
TextBox(int id, int x, int y, int w, int h, const std::string& msg);
|
TextBox(int id, int x, int y, int w, int h, const std::string& msg);
|
||||||
|
|
||||||
|
virtual void mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum);
|
||||||
|
|
||||||
virtual void setFocus(Minecraft* minecraft);
|
virtual void setFocus(Minecraft* minecraft);
|
||||||
virtual bool loseFocus(Minecraft* minecraft);
|
virtual bool loseFocus(Minecraft* minecraft);
|
||||||
|
|
||||||
virtual void render(Minecraft* minecraft, int xm, int ym);
|
virtual void render(Minecraft* minecraft, int xm, int ym);
|
||||||
|
|
||||||
public:
|
virtual void keyPressed(Minecraft* minecraft, int key);
|
||||||
int w, h;
|
virtual void charPressed(Minecraft* minecraft, char c);
|
||||||
int x, y;
|
virtual void tick(Minecraft* minecraft);
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string hint;
|
||||||
std::string text;
|
std::string text;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
|
int blinkTicks;
|
||||||
|
|
||||||
bool focused;
|
bool focused;
|
||||||
|
bool blink;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT_GUI_COMPONENTS__TextBox_H__*/
|
#endif /*NET_MINECRAFT_CLIENT_GUI_COMPONENTS__TextBox_H__*/
|
||||||
|
|||||||
17
src/client/gui/components/TextOption.cpp
Normal file
17
src/client/gui/components/TextOption.cpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include "TextOption.h"
|
||||||
|
#include <client/Minecraft.h>
|
||||||
|
|
||||||
|
TextOption::TextOption(Minecraft* minecraft, OptionId optId)
|
||||||
|
: TextBox((int)optId, minecraft->options.getOpt(optId)->getStringId())
|
||||||
|
{
|
||||||
|
text = minecraft->options.getStringValue(optId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextOption::loseFocus(Minecraft* minecraft) {
|
||||||
|
if (TextBox::loseFocus(minecraft)) {
|
||||||
|
minecraft->options.set((OptionId)id, text);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
10
src/client/gui/components/TextOption.h
Normal file
10
src/client/gui/components/TextOption.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "TextBox.h"
|
||||||
|
#include <client/Options.h>
|
||||||
|
|
||||||
|
class TextOption : public TextBox {
|
||||||
|
public:
|
||||||
|
TextOption(Minecraft* minecraft, OptionId optId);
|
||||||
|
|
||||||
|
virtual bool loseFocus(Minecraft* minecraft);
|
||||||
|
};
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__BuyGameScreen_H__
|
|
||||||
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__BuyGameScreen_H__
|
|
||||||
|
|
||||||
#include "../Screen.h"
|
|
||||||
#include "../components/Button.h"
|
|
||||||
|
|
||||||
class BuyGameScreen: public Screen
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BuyGameScreen() {}
|
|
||||||
virtual ~BuyGameScreen() {}
|
|
||||||
|
|
||||||
void init();
|
|
||||||
|
|
||||||
void render(int xm, int ym, float a);
|
|
||||||
|
|
||||||
void buttonClicked(Button* button) {
|
|
||||||
//if (button->id == bQuit.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
//Button bQuit;
|
|
||||||
//Button bBuyGame;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__BuyGameScreen_H__*/
|
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
//package net.minecraft.client.gui;
|
//package net.minecraft.client.gui;
|
||||||
|
|
||||||
#include "../Screen.h"
|
#include "../Screen.h"
|
||||||
#include "../components/SmallButton.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class ConfirmScreen: public Screen
|
class ConfirmScreen: public Screen
|
||||||
|
|||||||
223
src/client/gui/screens/ConsoleScreen.cpp
Normal file
223
src/client/gui/screens/ConsoleScreen.cpp
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
#include "ConsoleScreen.h"
|
||||||
|
#include "../Gui.h"
|
||||||
|
#include "../../Minecraft.h"
|
||||||
|
#include "../../player/LocalPlayer.h"
|
||||||
|
#include "../../../platform/input/Keyboard.h"
|
||||||
|
#include "../../../world/level/Level.h"
|
||||||
|
#include "../../../network/RakNetInstance.h"
|
||||||
|
#include "../../../network/ServerSideNetworkHandler.h"
|
||||||
|
#include "../../../network/packet/ChatPacket.h"
|
||||||
|
#include "../../../platform/log.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
ConsoleScreen::ConsoleScreen()
|
||||||
|
: _input(""),
|
||||||
|
_cursorBlink(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleScreen::init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleScreen::tick()
|
||||||
|
{
|
||||||
|
_cursorBlink++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConsoleScreen::handleBackEvent(bool /*isDown*/)
|
||||||
|
{
|
||||||
|
minecraft->setScreen(NULL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleScreen::keyPressed(int eventKey)
|
||||||
|
{
|
||||||
|
if (eventKey == Keyboard::KEY_ESCAPE) {
|
||||||
|
minecraft->setScreen(NULL);
|
||||||
|
} else if (eventKey == Keyboard::KEY_RETURN) {
|
||||||
|
execute();
|
||||||
|
} else if (eventKey == Keyboard::KEY_BACKSPACE) {
|
||||||
|
if (!_input.empty())
|
||||||
|
_input.erase(_input.size() - 1, 1);
|
||||||
|
} else {
|
||||||
|
super::keyPressed(eventKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleScreen::charPressed(char inputChar)
|
||||||
|
{
|
||||||
|
if (inputChar >= 32 && inputChar < 127)
|
||||||
|
_input += inputChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// execute: run _input as a command, print result, close screen
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
void ConsoleScreen::execute()
|
||||||
|
{
|
||||||
|
if (_input.empty()) {
|
||||||
|
minecraft->setScreen(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_input[0] == '/') {
|
||||||
|
// Command
|
||||||
|
std::string result = processCommand(_input);
|
||||||
|
if (!result.empty())
|
||||||
|
minecraft->gui.addMessage(result);
|
||||||
|
} else {
|
||||||
|
// Chat message: <name> message
|
||||||
|
std::string msg = std::string("<") + minecraft->player->name + "> " + _input;
|
||||||
|
if (minecraft->netCallback && minecraft->raknetInstance->isServer()) {
|
||||||
|
// Hosting a LAN game: displayGameMessage shows locally + broadcasts MessagePacket to clients
|
||||||
|
static_cast<ServerSideNetworkHandler*>(minecraft->netCallback)->displayGameMessage(msg);
|
||||||
|
} else if (minecraft->netCallback) {
|
||||||
|
// Connected client: send ChatPacket to server; server echoes it back as MessagePacket
|
||||||
|
ChatPacket chatPkt(msg);
|
||||||
|
minecraft->raknetInstance->send(chatPkt);
|
||||||
|
} else {
|
||||||
|
// Singleplayer: show locally only
|
||||||
|
minecraft->gui.addMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
minecraft->setScreen(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// processCommand
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
static std::string trim(const std::string& s) {
|
||||||
|
size_t a = s.find_first_not_of(" \t");
|
||||||
|
if (a == std::string::npos) return "";
|
||||||
|
size_t b = s.find_last_not_of(" \t");
|
||||||
|
return s.substr(a, b - a + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ConsoleScreen::processCommand(const std::string& raw)
|
||||||
|
{
|
||||||
|
// strip leading '/'
|
||||||
|
std::string line = raw;
|
||||||
|
if (!line.empty() && line[0] == '/') line = line.substr(1);
|
||||||
|
line = trim(line);
|
||||||
|
|
||||||
|
// tokenise
|
||||||
|
std::vector<std::string> args;
|
||||||
|
{
|
||||||
|
std::istringstream ss(line);
|
||||||
|
std::string tok;
|
||||||
|
while (ss >> tok) args.push_back(tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.empty()) return "";
|
||||||
|
|
||||||
|
Level* level = minecraft->level;
|
||||||
|
if (!level) return "No level loaded.";
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// /time ...
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
if (args[0] == "time") {
|
||||||
|
if (args.size() < 2)
|
||||||
|
return "Usage: /time <add|set|query> ...";
|
||||||
|
|
||||||
|
const std::string& sub = args[1];
|
||||||
|
|
||||||
|
// -- time add <value> -----------------------------------------------
|
||||||
|
if (sub == "add") {
|
||||||
|
if (args.size() < 3) return "Usage: /time add <value>";
|
||||||
|
long delta = std::atol(args[2].c_str());
|
||||||
|
long newTime = level->getTime() + delta;
|
||||||
|
level->setTime(newTime);
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "Set the time to " << (newTime % Level::TICKS_PER_DAY);
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- time set <value|day|night|noon|midnight> -----------------------
|
||||||
|
if (sub == "set") {
|
||||||
|
if (args.size() < 3) return "Usage: /time set <value|day|night|noon|midnight>";
|
||||||
|
const std::string& val = args[2];
|
||||||
|
|
||||||
|
long t = -1;
|
||||||
|
if (val == "day") t = 1000;
|
||||||
|
else if (val == "noon") t = 6000;
|
||||||
|
else if (val == "night") t = 13000;
|
||||||
|
else if (val == "midnight") t = 18000;
|
||||||
|
else {
|
||||||
|
// numeric — accept positive integers only
|
||||||
|
bool numeric = true;
|
||||||
|
for (char c : val)
|
||||||
|
if (!std::isdigit((unsigned char)c)) { numeric = false; break; }
|
||||||
|
if (!numeric) return std::string("Unknown value: ") + val;
|
||||||
|
t = std::atol(val.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preserve the total day count so only the time-of-day changes
|
||||||
|
long dayCount = level->getTime() / Level::TICKS_PER_DAY;
|
||||||
|
long newTime = dayCount * Level::TICKS_PER_DAY + (t % Level::TICKS_PER_DAY);
|
||||||
|
level->setTime(newTime);
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "Set the time to " << t;
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- time query <daytime|gametime|day> ------------------------------
|
||||||
|
if (sub == "query") {
|
||||||
|
if (args.size() < 3) return "Usage: /time query <daytime|gametime|day>";
|
||||||
|
const std::string& what = args[2];
|
||||||
|
|
||||||
|
long total = level->getTime();
|
||||||
|
long daytime = total % Level::TICKS_PER_DAY;
|
||||||
|
long day = total / Level::TICKS_PER_DAY;
|
||||||
|
|
||||||
|
std::ostringstream out;
|
||||||
|
if (what == "daytime") { out << "The time of day is " << daytime; }
|
||||||
|
else if (what == "gametime") { out << "The game time is " << total; }
|
||||||
|
else if (what == "day") { out << "The day is " << day; }
|
||||||
|
else return std::string("Unknown query: ") + what;
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown sub-command. Usage: /time <add|set|query> ...";
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string("Unknown command: /") + args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// render
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
void ConsoleScreen::render(int /*xm*/, int /*ym*/, float /*a*/)
|
||||||
|
{
|
||||||
|
// Dim the game world slightly
|
||||||
|
fillGradient(0, 0, width, height, 0x00000000, 0x40000000);
|
||||||
|
|
||||||
|
const int boxH = 12;
|
||||||
|
const int boxY = height - boxH - 2;
|
||||||
|
const int boxX0 = 2;
|
||||||
|
const int boxX1 = width - 2;
|
||||||
|
|
||||||
|
// Input box background
|
||||||
|
fill(boxX0, boxY, boxX1, boxY + boxH, 0xc0000000);
|
||||||
|
// Border
|
||||||
|
fill(boxX0, boxY, boxX1, boxY + 1, 0xff808080);
|
||||||
|
fill(boxX0, boxY + boxH - 1, boxX1, boxY + boxH, 0xff808080);
|
||||||
|
fill(boxX0, boxY, boxX0 + 1, boxY + boxH, 0xff808080);
|
||||||
|
fill(boxX1 - 1, boxY, boxX1, boxY + boxH, 0xff808080);
|
||||||
|
|
||||||
|
// Input text + blinking cursor
|
||||||
|
std::string displayed = _input;
|
||||||
|
if ((_cursorBlink / 10) % 2 == 0)
|
||||||
|
displayed += '_';
|
||||||
|
|
||||||
|
// Placeholder hint when empty
|
||||||
|
if (_input.empty() && (_cursorBlink / 10) % 2 != 0)
|
||||||
|
font->drawShadow("Type a message or /command", (float)(boxX0 + 2), (float)(boxY + 2), 0xff606060);
|
||||||
|
else
|
||||||
|
font->drawShadow(displayed, (float)(boxX0 + 2), (float)(boxY + 2), 0xffffffff);
|
||||||
|
}
|
||||||
34
src/client/gui/screens/ConsoleScreen.h
Normal file
34
src/client/gui/screens/ConsoleScreen.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__ConsoleScreen_H__
|
||||||
|
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__ConsoleScreen_H__
|
||||||
|
|
||||||
|
#include "../Screen.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class ConsoleScreen: public Screen
|
||||||
|
{
|
||||||
|
typedef Screen super;
|
||||||
|
public:
|
||||||
|
ConsoleScreen();
|
||||||
|
virtual ~ConsoleScreen() {}
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void render(int xm, int ym, float a);
|
||||||
|
void tick();
|
||||||
|
|
||||||
|
virtual bool renderGameBehind() { return true; }
|
||||||
|
virtual bool isInGameScreen() { return true; }
|
||||||
|
virtual bool isPauseScreen() { return false; }
|
||||||
|
|
||||||
|
virtual void keyPressed(int eventKey);
|
||||||
|
virtual void charPressed(char inputChar);
|
||||||
|
virtual bool handleBackEvent(bool isDown);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void execute();
|
||||||
|
std::string processCommand(const std::string& cmd);
|
||||||
|
|
||||||
|
std::string _input;
|
||||||
|
int _cursorBlink; // tick counter for cursor blink
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__ConsoleScreen_H__*/
|
||||||
129
src/client/gui/screens/CreditsScreen.cpp
Normal file
129
src/client/gui/screens/CreditsScreen.cpp
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
#include "CreditsScreen.h"
|
||||||
|
#include "StartMenuScreen.h"
|
||||||
|
#include "OptionsScreen.h"
|
||||||
|
#include "../../Minecraft.h"
|
||||||
|
#include "../components/Button.h"
|
||||||
|
#include "../components/ImageButton.h"
|
||||||
|
#include "platform/input/Mouse.h"
|
||||||
|
|
||||||
|
CreditsScreen::CreditsScreen()
|
||||||
|
: bHeader(NULL), btnBack(NULL)
|
||||||
|
{}
|
||||||
|
CreditsScreen::~CreditsScreen() {
|
||||||
|
if (bHeader) delete bHeader;
|
||||||
|
if (btnBack) delete btnBack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreditsScreen::init() {
|
||||||
|
bHeader = new Touch::THeader(0, "Credits");
|
||||||
|
btnBack = new ImageButton(1, "");
|
||||||
|
{
|
||||||
|
ImageDef def;
|
||||||
|
def.name = "gui/touchgui.png";
|
||||||
|
def.width = 34;
|
||||||
|
def.height = 26;
|
||||||
|
def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height));
|
||||||
|
btnBack->setImageDef(def, true);
|
||||||
|
}
|
||||||
|
buttons.push_back(bHeader);
|
||||||
|
buttons.push_back(btnBack);
|
||||||
|
|
||||||
|
// prepare text lines
|
||||||
|
_lines.clear();
|
||||||
|
_lines.push_back("Minecraft: Pocket Edition");
|
||||||
|
_lines.push_back("Original game by Mojang");
|
||||||
|
_lines.push_back("");
|
||||||
|
_lines.push_back("Programmers:");
|
||||||
|
_lines.push_back("mschiller890");
|
||||||
|
_lines.push_back("InviseDivine");
|
||||||
|
_lines.push_back("Kolyah35");
|
||||||
|
_lines.push_back("karson");
|
||||||
|
_lines.push_back("deepfriedwaffles");
|
||||||
|
_lines.push_back("");
|
||||||
|
// avoid color tags around the URL so it isn't mangled by the parser please
|
||||||
|
_lines.push_back("Join our Discord server: https://discord.gg/c58YesBxve");
|
||||||
|
_scrollSpeed = 0.5f;
|
||||||
|
_scrollY = height; // start below screen
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreditsScreen::setupPositions() {
|
||||||
|
int buttonHeight = btnBack->height;
|
||||||
|
btnBack->x = width - btnBack->width;
|
||||||
|
btnBack->y = 0;
|
||||||
|
if (bHeader) {
|
||||||
|
bHeader->x = 0;
|
||||||
|
bHeader->y = 0;
|
||||||
|
bHeader->width = width - btnBack->width;
|
||||||
|
bHeader->height = btnBack->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset scroll starting position when screen size changes
|
||||||
|
_scrollY = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreditsScreen::tick() {
|
||||||
|
// move text upward
|
||||||
|
_scrollY -= _scrollSpeed;
|
||||||
|
// if text has scrolled off the top, restart
|
||||||
|
float totalHeight = _lines.size() * (minecraft->font->lineHeight + 8);
|
||||||
|
if (_scrollY + totalHeight < 0) {
|
||||||
|
_scrollY = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Mouse::isButtonDown(MouseAction::ACTION_LEFT)) {
|
||||||
|
_scrollSpeed = 1.5f;
|
||||||
|
} else {
|
||||||
|
_scrollSpeed = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreditsScreen::render(int xm, int ym, float a) {
|
||||||
|
renderBackground();
|
||||||
|
int w = width;
|
||||||
|
Font* font = minecraft->font;
|
||||||
|
float y = _scrollY;
|
||||||
|
const float lineHeight = font->lineHeight + 8;
|
||||||
|
for (size_t i = 0; i < _lines.size(); ++i) {
|
||||||
|
const std::string& line = _lines[i];
|
||||||
|
// use color-tag-aware drawing, centre by total width
|
||||||
|
float lineWidth = Gui::getColoredWidth(font, line);
|
||||||
|
Gui::drawColoredString(font, line, w/2 - lineWidth/2, (int)y, 255);
|
||||||
|
// underline hyperlink lines manually
|
||||||
|
if (line.find("http") != std::string::npos || line.find("discord.gg") != std::string::npos) {
|
||||||
|
float x0 = w/2 - lineWidth/2;
|
||||||
|
float y0 = y + font->lineHeight - 1;
|
||||||
|
this->fill(x0, y0, x0 + lineWidth, y0 + 1, 0xffffffff);
|
||||||
|
}
|
||||||
|
y += lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
super::render(xm, ym, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreditsScreen::buttonClicked(Button* button) {
|
||||||
|
if (button->id == 1) {
|
||||||
|
minecraft->setScreen(new OptionsScreen());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreditsScreen::mouseClicked(int x, int y, int buttonNum) {
|
||||||
|
// map click to a line in the scrolling text
|
||||||
|
const float lineHeight = minecraft->font->lineHeight + 8;
|
||||||
|
for (size_t i = 0; i < _lines.size(); ++i) {
|
||||||
|
float lineY = _scrollY + i * lineHeight;
|
||||||
|
if (y >= lineY && y < lineY + lineHeight) {
|
||||||
|
const std::string& line = _lines[i];
|
||||||
|
size_t start = line.find("http");
|
||||||
|
if (start == std::string::npos)
|
||||||
|
start = line.find("discord.gg");
|
||||||
|
if (start != std::string::npos) {
|
||||||
|
// extract until space
|
||||||
|
size_t end = line.find(' ', start);
|
||||||
|
std::string url = line.substr(start, (end == std::string::npos) ? std::string::npos : end - start);
|
||||||
|
minecraft->platform()->openURL(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super::mouseClicked(x, y, buttonNum);
|
||||||
|
}
|
||||||
32
src/client/gui/screens/CreditsScreen.h
Normal file
32
src/client/gui/screens/CreditsScreen.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__CreditsScreen_H__
|
||||||
|
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__CreditsScreen_H__
|
||||||
|
|
||||||
|
#include "../Screen.h"
|
||||||
|
#include "../components/Button.h"
|
||||||
|
|
||||||
|
class ImageButton;
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class CreditsScreen: public Screen {
|
||||||
|
public:
|
||||||
|
typedef Screen super;
|
||||||
|
CreditsScreen();
|
||||||
|
virtual ~CreditsScreen();
|
||||||
|
void init();
|
||||||
|
void setupPositions();
|
||||||
|
virtual void tick();
|
||||||
|
void render(int xm, int ym, float a);
|
||||||
|
void buttonClicked(Button* button);
|
||||||
|
virtual void mouseClicked(int x, int y, int buttonNum);
|
||||||
|
private:
|
||||||
|
Touch::THeader* bHeader;
|
||||||
|
ImageButton* btnBack;
|
||||||
|
|
||||||
|
std::vector<std::string> _lines;
|
||||||
|
float _scrollY;
|
||||||
|
float _scrollSpeed;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* NET_MINECRAFT_CLIENT_GUI_SCREENS__CreditsScreen_H__ */
|
||||||
@@ -169,19 +169,19 @@ void IngameBlockSelectionScreen::keyPressed(int eventKey)
|
|||||||
int tmpSelectedSlot = selectedItem;
|
int tmpSelectedSlot = selectedItem;
|
||||||
|
|
||||||
Options& o = minecraft->options;
|
Options& o = minecraft->options;
|
||||||
if (eventKey == o.keyLeft.key && selX > 0)
|
if (eventKey == o.getIntValue(OPTIONS_KEY_LEFT) && selX > 0)
|
||||||
{
|
{
|
||||||
tmpSelectedSlot -= 1;
|
tmpSelectedSlot -= 1;
|
||||||
}
|
}
|
||||||
else if (eventKey == o.keyRight.key && selX < (InventoryCols - 1))
|
else if (eventKey == o.getIntValue(OPTIONS_KEY_RIGHT) && selX < (InventoryCols - 1))
|
||||||
{
|
{
|
||||||
tmpSelectedSlot += 1;
|
tmpSelectedSlot += 1;
|
||||||
}
|
}
|
||||||
else if (eventKey == o.keyDown.key && selY < (InventoryRows - 1))
|
else if (eventKey == o.getIntValue(OPTIONS_KEY_BACK) && selY < (InventoryRows - 1))
|
||||||
{
|
{
|
||||||
tmpSelectedSlot += InventoryCols;
|
tmpSelectedSlot += InventoryCols;
|
||||||
}
|
}
|
||||||
else if (eventKey == o.keyUp.key && selY > 0)
|
else if (eventKey == o.getIntValue(OPTIONS_KEY_FORWARD) && selY > 0)
|
||||||
{
|
{
|
||||||
tmpSelectedSlot -= InventoryCols;
|
tmpSelectedSlot -= InventoryCols;
|
||||||
}
|
}
|
||||||
@@ -189,19 +189,38 @@ void IngameBlockSelectionScreen::keyPressed(int eventKey)
|
|||||||
if (isAllowed(tmpSelectedSlot))
|
if (isAllowed(tmpSelectedSlot))
|
||||||
selectedItem = tmpSelectedSlot;
|
selectedItem = tmpSelectedSlot;
|
||||||
|
|
||||||
if (eventKey == o.keyMenuOk.key)
|
if (eventKey == o.getIntValue(OPTIONS_KEY_MENU_OK))
|
||||||
selectSlotAndClose();
|
selectSlotAndClose();
|
||||||
|
|
||||||
#ifdef RPI
|
#ifdef RPI
|
||||||
if (eventKey == o.keyMenuCancel.key
|
if (eventKey == o.getIntValue(OPTIONS_KEY_MENU_CANCEL)
|
||||||
|| eventKey == Keyboard::KEY_ESCAPE)
|
|| eventKey == Keyboard::KEY_ESCAPE)
|
||||||
minecraft->setScreen(NULL);
|
minecraft->setScreen(NULL);
|
||||||
#else
|
#else
|
||||||
if (eventKey == o.keyMenuCancel.key)
|
if (eventKey == o.getIntValue(OPTIONS_KEY_MENU_CANCEL))
|
||||||
minecraft->setScreen(NULL);
|
minecraft->setScreen(NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// wheel support for creative inventory; scroll moves selection vertically
|
||||||
|
void IngameBlockSelectionScreen::mouseWheel(int dx, int dy, int xm, int ym)
|
||||||
|
{
|
||||||
|
if (dy == 0) return;
|
||||||
|
// just move selection up/down one row; desktop UI doesn't have a pane
|
||||||
|
int cols = InventoryCols;
|
||||||
|
int maxIndex = InventorySize - 1;
|
||||||
|
int idx = selectedItem;
|
||||||
|
if (dy > 0) {
|
||||||
|
// wheel up -> previous row
|
||||||
|
if (idx >= cols) idx -= cols;
|
||||||
|
} else {
|
||||||
|
// wheel down -> next row
|
||||||
|
if (idx + cols <= maxIndex) idx += cols;
|
||||||
|
}
|
||||||
|
selectedItem = idx;
|
||||||
|
}
|
||||||
|
|
||||||
int IngameBlockSelectionScreen::getSelectedSlot(int x, int y)
|
int IngameBlockSelectionScreen::getSelectedSlot(int x, int y)
|
||||||
{
|
{
|
||||||
int left = width / 2 - InventoryCols * 10;
|
int left = width / 2 - InventoryCols * 10;
|
||||||
|
|||||||
@@ -12,18 +12,21 @@ public:
|
|||||||
IngameBlockSelectionScreen();
|
IngameBlockSelectionScreen();
|
||||||
virtual ~IngameBlockSelectionScreen() {}
|
virtual ~IngameBlockSelectionScreen() {}
|
||||||
|
|
||||||
virtual void init();
|
virtual void init() override;
|
||||||
virtual void removed();
|
virtual void removed() override;
|
||||||
|
|
||||||
void render(int xm, int ym, float a);
|
void render(int xm, int ym, float a) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void mouseClicked(int x, int y, int buttonNum);
|
virtual void mouseClicked(int x, int y, int buttonNum) override;
|
||||||
virtual void mouseReleased(int x, int y, int buttonNum);
|
virtual void mouseReleased(int x, int y, int buttonNum) override;
|
||||||
|
|
||||||
virtual void buttonClicked(Button* button);
|
virtual void buttonClicked(Button* button) override;
|
||||||
|
|
||||||
virtual void keyPressed(int eventKey);
|
// wheel input for creative inventory scrolling
|
||||||
|
virtual void mouseWheel(int dx, int dy, int xm, int ym) override;
|
||||||
|
|
||||||
|
virtual void keyPressed(int eventKey) override;
|
||||||
private:
|
private:
|
||||||
void renderSlots();
|
void renderSlots();
|
||||||
void renderSlot(int slot, int x, int y, float a);
|
void renderSlot(int slot, int x, int y, float a);
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__InvalidLicenseScreen_H__
|
|
||||||
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__InvalidLicenseScreen_H__
|
|
||||||
|
|
||||||
#include "../Screen.h"
|
|
||||||
#include "../components/Button.h"
|
|
||||||
#include "../../Minecraft.h"
|
|
||||||
#include "../../../LicenseCodes.h"
|
|
||||||
|
|
||||||
class InvalidLicenseScreen: public Screen
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InvalidLicenseScreen(int id, bool hasBuyButton)
|
|
||||||
: _id(id),
|
|
||||||
_hasBuyButton(hasBuyButton),
|
|
||||||
_baseY(0),
|
|
||||||
bOk(0),
|
|
||||||
bBuy(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~InvalidLicenseScreen() {
|
|
||||||
delete bOk;
|
|
||||||
delete bBuy;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
if (minecraft->useTouchscreen()) {
|
|
||||||
bOk = new Touch::TButton(1, "Ok");
|
|
||||||
bBuy = new Touch::TButton(2, "Buy");
|
|
||||||
} else {
|
|
||||||
bOk = new Button(1, "Ok");
|
|
||||||
bBuy = new Button(2, "Buy");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_hasBuyButton)
|
|
||||||
bOk->msg = "Quit";
|
|
||||||
|
|
||||||
if (!LicenseCodes::isOk(_id)) {
|
|
||||||
char buf[20] = {0};
|
|
||||||
sprintf(buf, "%d", _id);
|
|
||||||
|
|
||||||
desc1 = "License verification failed (error ";
|
|
||||||
desc1 += buf;
|
|
||||||
desc1 += ")";
|
|
||||||
desc2 = "Try again later.";
|
|
||||||
hint = "You need to be connected to the internet\n";
|
|
||||||
hint += "once while you start the game.";
|
|
||||||
}
|
|
||||||
|
|
||||||
buttons.push_back(bOk);
|
|
||||||
tabButtons.push_back(bOk);
|
|
||||||
|
|
||||||
if (_hasBuyButton) {
|
|
||||||
buttons.push_back(bBuy);
|
|
||||||
tabButtons.push_back(bBuy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setupPositions() {
|
|
||||||
_baseY = height/5 + 6;
|
|
||||||
//if (_hasBuyButton)
|
|
||||||
_baseY -= 24;
|
|
||||||
|
|
||||||
bOk->width = bBuy->width = 200;
|
|
||||||
bOk->x = bBuy->x = (width - bOk->width) / 2;
|
|
||||||
bBuy->y = _baseY + 84;
|
|
||||||
bOk->y = bBuy->y + bBuy->height + 4;
|
|
||||||
|
|
||||||
if (!_hasBuyButton)
|
|
||||||
bOk->y -= 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tick() {}
|
|
||||||
|
|
||||||
//void keyPressed(int eventKey) {}
|
|
||||||
|
|
||||||
void render(int xm, int ym, float a) {
|
|
||||||
renderDirtBackground(0);
|
|
||||||
drawCenteredString(minecraft->font, desc1, width/2, _baseY, 0xffffff);
|
|
||||||
drawCenteredString(minecraft->font, desc2, width/2, _baseY + 24, 0xffffff);
|
|
||||||
|
|
||||||
drawCenteredString(minecraft->font, hint, width/2, _baseY + 60, 0xffffff);
|
|
||||||
|
|
||||||
Screen::render(xm, ym, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
void buttonClicked(Button* button) {
|
|
||||||
if (button->id == bOk->id) {
|
|
||||||
minecraft->quit();
|
|
||||||
}
|
|
||||||
if (button->id == bBuy->id) {
|
|
||||||
minecraft->platform()->buyGame();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private:
|
|
||||||
int _id;
|
|
||||||
std::string desc1;
|
|
||||||
std::string desc2;
|
|
||||||
std::string hint;
|
|
||||||
|
|
||||||
Button* bOk;
|
|
||||||
Button* bBuy;
|
|
||||||
bool _hasBuyButton;
|
|
||||||
int _baseY;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__InvalidLicenseScreen_H__*/
|
|
||||||
124
src/client/gui/screens/JoinByIPScreen.cpp
Normal file
124
src/client/gui/screens/JoinByIPScreen.cpp
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
#include "JoinByIPScreen.h"
|
||||||
|
|
||||||
|
#include "JoinGameScreen.h"
|
||||||
|
#include "StartMenuScreen.h"
|
||||||
|
#include "ProgressScreen.h"
|
||||||
|
#include "../Font.h"
|
||||||
|
#include "../../../network/RakNetInstance.h"
|
||||||
|
#include "client/Options.h"
|
||||||
|
#include "client/gui/Screen.h"
|
||||||
|
#include "client/gui/components/TextBox.h"
|
||||||
|
#include "network/ClientSideNetworkHandler.h"
|
||||||
|
|
||||||
|
JoinByIPScreen::JoinByIPScreen() :
|
||||||
|
tIP(0, "Server IP"),
|
||||||
|
bHeader(1, "Join on server"),
|
||||||
|
bJoin( 2, "Join Game"),
|
||||||
|
bBack( 3, "")
|
||||||
|
{
|
||||||
|
bJoin.active = false;
|
||||||
|
//gamesList->yInertia = 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
JoinByIPScreen::~JoinByIPScreen()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoinByIPScreen::buttonClicked(Button* button)
|
||||||
|
{
|
||||||
|
if (button->id == bJoin.id)
|
||||||
|
{
|
||||||
|
minecraft->isLookingForMultiplayer = true;
|
||||||
|
minecraft->netCallback = new ClientSideNetworkHandler(minecraft, minecraft->raknetInstance);
|
||||||
|
|
||||||
|
minecraft->joinMultiplayerFromString(tIP.text);
|
||||||
|
{
|
||||||
|
minecraft->options.set(OPTIONS_LAST_IP, tIP.text);
|
||||||
|
bJoin.active = false;
|
||||||
|
bBack.active = false;
|
||||||
|
minecraft->setScreen(new ProgressScreen());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (button->id == bBack.id)
|
||||||
|
{
|
||||||
|
minecraft->cancelLocateMultiplayer();
|
||||||
|
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JoinByIPScreen::handleBackEvent(bool isDown)
|
||||||
|
{
|
||||||
|
if (!isDown)
|
||||||
|
{
|
||||||
|
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoinByIPScreen::tick()
|
||||||
|
{
|
||||||
|
Screen::tick();
|
||||||
|
bJoin.active = !tIP.text.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoinByIPScreen::init()
|
||||||
|
{
|
||||||
|
ImageDef def;
|
||||||
|
def.name = "gui/touchgui.png";
|
||||||
|
def.width = 34;
|
||||||
|
def.height = 26;
|
||||||
|
|
||||||
|
def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height));
|
||||||
|
bBack.setImageDef(def, true);
|
||||||
|
|
||||||
|
buttons.push_back(&bJoin);
|
||||||
|
buttons.push_back(&bBack);
|
||||||
|
buttons.push_back(&bHeader);
|
||||||
|
|
||||||
|
textBoxes.push_back(&tIP);
|
||||||
|
#ifdef ANDROID
|
||||||
|
tabButtons.push_back(&bJoin);
|
||||||
|
tabButtons.push_back(&bBack);
|
||||||
|
tabButtons.push_back(&bHeader);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tIP.text = minecraft->options.getStringValue(OPTIONS_LAST_IP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoinByIPScreen::setupPositions() {
|
||||||
|
int tIpDiff = 40;
|
||||||
|
|
||||||
|
bJoin.y = height * 2 / 3;
|
||||||
|
bBack.y = 0;
|
||||||
|
bHeader.y = 0;
|
||||||
|
|
||||||
|
// Center buttons
|
||||||
|
//bJoin.x = width / 2 - 4 - bJoin.w;
|
||||||
|
bBack.x = width - bBack.width;//width / 2 + 4;
|
||||||
|
|
||||||
|
bJoin.x = (width - bJoin.width) / 2;
|
||||||
|
|
||||||
|
bHeader.x = 0;
|
||||||
|
bHeader.width = width - bBack.width;
|
||||||
|
|
||||||
|
tIP.width = bJoin.width + tIpDiff;
|
||||||
|
tIP.height = 16;
|
||||||
|
tIP.x = bJoin.x - tIpDiff / 2;
|
||||||
|
tIP.y = ((height - bJoin.height) / 2) - tIP.height - 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoinByIPScreen::render( int xm, int ym, float a )
|
||||||
|
{
|
||||||
|
renderBackground();
|
||||||
|
Screen::render(xm, ym, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoinByIPScreen::keyPressed(int eventKey)
|
||||||
|
{
|
||||||
|
if (eventKey == Keyboard::KEY_ESCAPE) {
|
||||||
|
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// let base class handle navigation and text box keys
|
||||||
|
Screen::keyPressed(eventKey);
|
||||||
|
}
|
||||||
28
src/client/gui/screens/JoinByIPScreen.h
Normal file
28
src/client/gui/screens/JoinByIPScreen.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
#include "../Screen.h"
|
||||||
|
#include "../components/Button.h"
|
||||||
|
#include "../../Minecraft.h"
|
||||||
|
#include "client/gui/components/ImageButton.h"
|
||||||
|
#include "client/gui/components/TextBox.h"
|
||||||
|
|
||||||
|
class JoinByIPScreen: public Screen
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
JoinByIPScreen();
|
||||||
|
virtual ~JoinByIPScreen();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void setupPositions();
|
||||||
|
|
||||||
|
virtual void tick();
|
||||||
|
void render(int xm, int ym, float a);
|
||||||
|
|
||||||
|
virtual void keyPressed(int eventKey);
|
||||||
|
void buttonClicked(Button* button);
|
||||||
|
virtual bool handleBackEvent(bool isDown);
|
||||||
|
private:
|
||||||
|
TextBox tIP;
|
||||||
|
Touch::THeader bHeader;
|
||||||
|
Touch::TButton bJoin;
|
||||||
|
ImageButton bBack;
|
||||||
|
};
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "../Screen.h"
|
#include "../Screen.h"
|
||||||
#include "../components/Button.h"
|
#include "../components/Button.h"
|
||||||
#include "../components/SmallButton.h"
|
|
||||||
#include "../components/ScrolledSelectionList.h"
|
#include "../components/ScrolledSelectionList.h"
|
||||||
#include "../../Minecraft.h"
|
#include "../../Minecraft.h"
|
||||||
#include "../../../network/RakNetInstance.h"
|
#include "../../../network/RakNetInstance.h"
|
||||||
|
|||||||
@@ -1,46 +1,63 @@
|
|||||||
#include "OptionsScreen.h"
|
#include "OptionsScreen.h"
|
||||||
|
|
||||||
#include "StartMenuScreen.h"
|
#include "StartMenuScreen.h"
|
||||||
|
#include "UsernameScreen.h"
|
||||||
#include "DialogDefinitions.h"
|
#include "DialogDefinitions.h"
|
||||||
#include "../../Minecraft.h"
|
#include "../../Minecraft.h"
|
||||||
#include "../../../AppPlatform.h"
|
#include "../../../AppPlatform.h"
|
||||||
|
#include "CreditsScreen.h"
|
||||||
|
|
||||||
#include "../components/OptionsPane.h"
|
|
||||||
#include "../components/ImageButton.h"
|
#include "../components/ImageButton.h"
|
||||||
#include "../components/OptionsGroup.h"
|
#include "../components/OptionsGroup.h"
|
||||||
|
#include "platform/input/Keyboard.h"
|
||||||
|
|
||||||
OptionsScreen::OptionsScreen()
|
OptionsScreen::OptionsScreen()
|
||||||
: btnClose(NULL),
|
: btnClose(NULL),
|
||||||
bHeader(NULL),
|
bHeader(NULL),
|
||||||
|
btnCredits(NULL),
|
||||||
selectedCategory(0) {
|
selectedCategory(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionsScreen::~OptionsScreen() {
|
OptionsScreen::~OptionsScreen() {
|
||||||
|
|
||||||
if (btnClose != NULL) {
|
if (btnClose != NULL) {
|
||||||
delete btnClose;
|
delete btnClose;
|
||||||
btnClose = NULL;
|
btnClose = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bHeader != NULL) {
|
if (bHeader != NULL) {
|
||||||
delete bHeader,
|
delete bHeader;
|
||||||
bHeader = NULL;
|
bHeader = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (btnCredits != NULL) {
|
||||||
|
delete btnCredits;
|
||||||
|
btnCredits = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
|
for (std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
|
||||||
if (*it != NULL) {
|
if (*it != NULL) {
|
||||||
delete* it;
|
delete* it;
|
||||||
*it = NULL;
|
*it = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(std::vector<OptionsPane*>::iterator it = optionPanes.begin(); it != optionPanes.end(); ++it) {
|
|
||||||
|
for (std::vector<OptionsGroup*>::iterator it = optionPanes.begin(); it != optionPanes.end(); ++it) {
|
||||||
if (*it != NULL) {
|
if (*it != NULL) {
|
||||||
delete* it;
|
delete* it;
|
||||||
*it = NULL;
|
*it = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
categoryButtons.clear();
|
categoryButtons.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsScreen::init() {
|
void OptionsScreen::init() {
|
||||||
|
|
||||||
bHeader = new Touch::THeader(0, "Options");
|
bHeader = new Touch::THeader(0, "Options");
|
||||||
|
|
||||||
btnClose = new ImageButton(1, "");
|
btnClose = new ImageButton(1, "");
|
||||||
|
|
||||||
ImageDef def;
|
ImageDef def;
|
||||||
def.name = "gui/touchgui.png";
|
def.name = "gui/touchgui.png";
|
||||||
def.width = 34;
|
def.width = 34;
|
||||||
@@ -49,133 +66,204 @@ void OptionsScreen::init() {
|
|||||||
def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height));
|
def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height));
|
||||||
btnClose->setImageDef(def, true);
|
btnClose->setImageDef(def, true);
|
||||||
|
|
||||||
categoryButtons.push_back(new Touch::TButton(2, "Login"));
|
categoryButtons.push_back(new Touch::TButton(2, "General"));
|
||||||
categoryButtons.push_back(new Touch::TButton(3, "Game"));
|
categoryButtons.push_back(new Touch::TButton(3, "Game"));
|
||||||
categoryButtons.push_back(new Touch::TButton(4, "Controls"));
|
categoryButtons.push_back(new Touch::TButton(4, "Controls"));
|
||||||
categoryButtons.push_back(new Touch::TButton(5, "Graphics"));
|
categoryButtons.push_back(new Touch::TButton(5, "Graphics"));
|
||||||
|
categoryButtons.push_back(new Touch::TButton(6, "Tweaks"));
|
||||||
|
|
||||||
|
btnCredits = new Touch::TButton(11, "Credits");
|
||||||
|
|
||||||
buttons.push_back(bHeader);
|
buttons.push_back(bHeader);
|
||||||
buttons.push_back(btnClose);
|
buttons.push_back(btnClose);
|
||||||
|
buttons.push_back(btnCredits);
|
||||||
|
|
||||||
for (std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
|
for (std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
|
||||||
buttons.push_back(*it);
|
buttons.push_back(*it);
|
||||||
tabButtons.push_back(*it);
|
tabButtons.push_back(*it);
|
||||||
}
|
}
|
||||||
generateOptionScreens();
|
|
||||||
|
|
||||||
|
generateOptionScreens();
|
||||||
|
// start with first category selected
|
||||||
|
selectCategory(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsScreen::setupPositions() {
|
void OptionsScreen::setupPositions() {
|
||||||
|
|
||||||
int buttonHeight = btnClose->height;
|
int buttonHeight = btnClose->height;
|
||||||
|
|
||||||
btnClose->x = width - btnClose->width;
|
btnClose->x = width - btnClose->width;
|
||||||
btnClose->y = 0;
|
btnClose->y = 0;
|
||||||
|
|
||||||
int offsetNum = 1;
|
int offsetNum = 1;
|
||||||
|
|
||||||
for (std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
|
for (std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
|
||||||
|
|
||||||
(*it)->x = 0;
|
(*it)->x = 0;
|
||||||
(*it)->y = offsetNum * buttonHeight;
|
(*it)->y = offsetNum * buttonHeight;
|
||||||
(*it)->selected = false;
|
(*it)->selected = false;
|
||||||
|
|
||||||
offsetNum++;
|
offsetNum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bHeader->x = 0;
|
bHeader->x = 0;
|
||||||
bHeader->y = 0;
|
bHeader->y = 0;
|
||||||
bHeader->width = width - btnClose->width;
|
bHeader->width = width - btnClose->width;
|
||||||
bHeader->height = btnClose->height;
|
bHeader->height = btnClose->height;
|
||||||
for(std::vector<OptionsPane*>::iterator it = optionPanes.begin(); it != optionPanes.end(); ++it) {
|
|
||||||
|
// Credits button (bottom-right)
|
||||||
|
if (btnCredits != NULL) {
|
||||||
|
btnCredits->x = width - btnCredits->width;
|
||||||
|
btnCredits->y = height - btnCredits->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::vector<OptionsGroup*>::iterator it = optionPanes.begin(); it != optionPanes.end(); ++it) {
|
||||||
|
|
||||||
if (categoryButtons.size() > 0 && categoryButtons[0] != NULL) {
|
if (categoryButtons.size() > 0 && categoryButtons[0] != NULL) {
|
||||||
|
|
||||||
(*it)->x = categoryButtons[0]->width;
|
(*it)->x = categoryButtons[0]->width;
|
||||||
(*it)->y = bHeader->height;
|
(*it)->y = bHeader->height;
|
||||||
(*it)->width = width - categoryButtons[0]->width;
|
(*it)->width = width - categoryButtons[0]->width;
|
||||||
|
|
||||||
(*it)->setupPositions();
|
(*it)->setupPositions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selectCategory(0);
|
|
||||||
|
// don't override user selection on resize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OptionsScreen::render(int xm, int ym, float a) {
|
void OptionsScreen::render(int xm, int ym, float a) {
|
||||||
|
|
||||||
renderBackground();
|
renderBackground();
|
||||||
super::render(xm, ym, a);
|
|
||||||
int xmm = xm * width / minecraft->width;
|
int xmm = xm * width / minecraft->width;
|
||||||
int ymm = ym * height / minecraft->height - 1;
|
int ymm = ym * height / minecraft->height - 1;
|
||||||
if(currentOptionPane != NULL)
|
|
||||||
currentOptionPane->render(minecraft, xmm, ymm);
|
if (currentOptionsGroup != NULL)
|
||||||
|
currentOptionsGroup->render(minecraft, xmm, ymm);
|
||||||
|
|
||||||
|
super::render(xm, ym, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsScreen::removed()
|
void OptionsScreen::removed() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsScreen::buttonClicked(Button* button) {
|
void OptionsScreen::buttonClicked(Button* button) {
|
||||||
|
|
||||||
if (button == btnClose) {
|
if (button == btnClose) {
|
||||||
minecraft->reloadOptions();
|
minecraft->options.save();
|
||||||
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
||||||
} else if(button->id > 1 && button->id < 7) {
|
}
|
||||||
// This is a category button
|
else if (button->id > 1 && button->id < 7) {
|
||||||
int categoryButton = button->id - categoryButtons[0]->id;
|
int categoryButton = button->id - categoryButtons[0]->id;
|
||||||
selectCategory(categoryButton);
|
selectCategory(categoryButton);
|
||||||
}
|
}
|
||||||
|
else if (button == btnCredits) {
|
||||||
|
minecraft->setScreen(new CreditsScreen());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsScreen::selectCategory(int index) {
|
void OptionsScreen::selectCategory(int index) {
|
||||||
|
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
|
|
||||||
for (std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
|
for (std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
|
||||||
if(index == currentIndex) {
|
|
||||||
|
if (index == currentIndex)
|
||||||
(*it)->selected = true;
|
(*it)->selected = true;
|
||||||
} else {
|
else
|
||||||
(*it)->selected = false;
|
(*it)->selected = false;
|
||||||
}
|
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < (int)optionPanes.size())
|
if (index < (int)optionPanes.size())
|
||||||
currentOptionPane = optionPanes[index];
|
currentOptionsGroup = optionPanes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsScreen::generateOptionScreens() {
|
void OptionsScreen::generateOptionScreens() {
|
||||||
optionPanes.push_back(new OptionsPane());
|
// how the fuck it works
|
||||||
optionPanes.push_back(new OptionsPane());
|
|
||||||
optionPanes.push_back(new OptionsPane());
|
optionPanes.push_back(new OptionsGroup("options.group.general"));
|
||||||
optionPanes.push_back(new OptionsPane());
|
optionPanes.push_back(new OptionsGroup("options.group.game"));
|
||||||
// Mojang Pane
|
optionPanes.push_back(new OptionsGroup("options.group.controls"));
|
||||||
optionPanes[0]->createOptionsGroup("options.group.mojang")
|
optionPanes.push_back(new OptionsGroup("options.group.graphics"));
|
||||||
//.addOptionItem(&Options::Option::THIRD_PERSON, minecraft);
|
optionPanes.push_back(new OptionsGroup("options.group.tweaks"));
|
||||||
.addOptionItem(&Options::Option::SENSITIVITY, minecraft);
|
|
||||||
// int mojangGroup = optionPanes[0]->createOptionsGroup("Mojang");
|
// General Pane
|
||||||
// static const int arr[] = {5,4,3,15};
|
optionPanes[0]->addOptionItem(OPTIONS_USERNAME, minecraft)
|
||||||
// std::vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
|
.addOptionItem(OPTIONS_SENSITIVITY, minecraft);
|
||||||
// optionPanes[0]->createStepSlider(minecraft, mojangGroup, "This works?", &Options::Option::DIFFICULTY, vec);
|
|
||||||
//
|
// Game Pane
|
||||||
// // Game Pane
|
optionPanes[1]->addOptionItem(OPTIONS_DIFFICULTY, minecraft)
|
||||||
// int gameGroup = optionPanes[1]->createOptionsGroup("Game");
|
.addOptionItem(OPTIONS_SERVER_VISIBLE, minecraft)
|
||||||
// optionPanes[1]->createToggle(gameGroup, "Third person camera", &Options::Option::THIRD_PERSON);
|
.addOptionItem(OPTIONS_THIRD_PERSON_VIEW, minecraft)
|
||||||
// optionPanes[1]->createToggle(gameGroup, "Server visible", &Options::Option::SERVER_VISIBLE);
|
.addOptionItem(OPTIONS_GUI_SCALE, minecraft)
|
||||||
//
|
.addOptionItem(OPTIONS_SENSITIVITY, minecraft)
|
||||||
// // Input Pane
|
.addOptionItem(OPTIONS_MUSIC_VOLUME, minecraft)
|
||||||
// int controlsGroup = optionPanes[2]->createOptionsGroup("Controls");
|
.addOptionItem(OPTIONS_SOUND_VOLUME, minecraft)
|
||||||
// optionPanes[2]->createToggle(controlsGroup, "Invert X-axis", &Options::Option::INVERT_MOUSE);
|
.addOptionItem(OPTIONS_SMOOTH_CAMERA, minecraft)
|
||||||
// optionPanes[2]->createToggle(controlsGroup, "Lefty", &Options::Option::LEFT_HANDED);
|
.addOptionItem(OPTIONS_DESTROY_VIBRATION, minecraft)
|
||||||
// optionPanes[2]->createToggle(controlsGroup, "Use touch screen", &Options::Option::USE_TOUCHSCREEN);
|
.addOptionItem(OPTIONS_IS_LEFT_HANDED, minecraft);
|
||||||
// optionPanes[2]->createToggle(controlsGroup, "Split touch controls", &Options::Option::USE_TOUCH_JOYPAD);
|
|
||||||
// int feedBackGroup = optionPanes[2]->createOptionsGroup("Feedback");
|
// // Controls Pane
|
||||||
// optionPanes[2]->createToggle(feedBackGroup, "Vibrate on destroy", &Options::Option::DESTROY_VIBRATION);
|
optionPanes[2]->addOptionItem(OPTIONS_INVERT_Y_MOUSE, minecraft)
|
||||||
//
|
.addOptionItem(OPTIONS_USE_TOUCHSCREEN, minecraft);
|
||||||
// int graphicsGroup = optionPanes[3]->createOptionsGroup("Graphics");
|
|
||||||
// optionPanes[3]->createProgressSlider(minecraft, graphicsGroup, "Gui Scale", &Options::Option::PIXELS_PER_MILLIMETER, 3, 4);
|
for (int i = OPTIONS_KEY_FORWARD; i <= OPTIONS_KEY_USE; i++) {
|
||||||
// optionPanes[3]->createToggle(graphicsGroup, "Fancy Graphics", &Options::Option::INVERT_MOUSE);
|
optionPanes[2]->addOptionItem((OptionId)i, minecraft);
|
||||||
// optionPanes[3]->createToggle(graphicsGroup, "Fancy Skies", &Options::Option::INVERT_MOUSE);
|
}
|
||||||
// optionPanes[3]->createToggle(graphicsGroup, "Animated water", &Options::Option::INVERT_MOUSE);
|
|
||||||
// int experimentalGraphicsGroup = optionPanes[3]->createOptionsGroup("Experimental graphics");
|
// // Graphics Pane
|
||||||
// optionPanes[3]->createToggle(experimentalGraphicsGroup, "Soft shadows", &Options::Option::INVERT_MOUSE);
|
optionPanes[3]->addOptionItem(OPTIONS_FANCY_GRAPHICS, minecraft)
|
||||||
|
.addOptionItem(OPTIONS_LIMIT_FRAMERATE, minecraft)
|
||||||
|
.addOptionItem(OPTIONS_VSYNC, minecraft)
|
||||||
|
.addOptionItem(OPTIONS_RENDER_DEBUG, minecraft)
|
||||||
|
.addOptionItem(OPTIONS_ANAGLYPH_3D, minecraft)
|
||||||
|
.addOptionItem(OPTIONS_VIEW_BOBBING, minecraft)
|
||||||
|
.addOptionItem(OPTIONS_AMBIENT_OCCLUSION, minecraft);
|
||||||
|
|
||||||
|
optionPanes[4]->addOptionItem(OPTIONS_ALLOW_SPRINT, minecraft)
|
||||||
|
.addOptionItem(OPTIONS_BAR_ON_TOP, minecraft);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsScreen::mouseClicked(int x, int y, int buttonNum) {
|
void OptionsScreen::mouseClicked(int x, int y, int buttonNum) {
|
||||||
if(currentOptionPane != NULL)
|
|
||||||
currentOptionPane->mouseClicked(minecraft, x, y, buttonNum);
|
if (currentOptionsGroup != NULL)
|
||||||
|
currentOptionsGroup->mouseClicked(minecraft, x, y, buttonNum);
|
||||||
|
|
||||||
super::mouseClicked(x, y, buttonNum);
|
super::mouseClicked(x, y, buttonNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsScreen::mouseReleased(int x, int y, int buttonNum) {
|
void OptionsScreen::mouseReleased(int x, int y, int buttonNum) {
|
||||||
if(currentOptionPane != NULL)
|
|
||||||
currentOptionPane->mouseReleased(minecraft, x, y, buttonNum);
|
if (currentOptionsGroup != NULL)
|
||||||
|
currentOptionsGroup->mouseReleased(minecraft, x, y, buttonNum);
|
||||||
|
|
||||||
super::mouseReleased(x, y, buttonNum);
|
super::mouseReleased(x, y, buttonNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OptionsScreen::keyPressed(int eventKey) {
|
||||||
|
if (currentOptionsGroup != NULL)
|
||||||
|
currentOptionsGroup->keyPressed(minecraft, eventKey);
|
||||||
|
if (eventKey == Keyboard::KEY_ESCAPE)
|
||||||
|
minecraft->options.save();
|
||||||
|
|
||||||
|
super::keyPressed(eventKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsScreen::charPressed(char inputChar) {
|
||||||
|
if (currentOptionsGroup != NULL)
|
||||||
|
currentOptionsGroup->charPressed(minecraft, inputChar);
|
||||||
|
|
||||||
|
super::keyPressed(inputChar);
|
||||||
|
}
|
||||||
|
|
||||||
void OptionsScreen::tick() {
|
void OptionsScreen::tick() {
|
||||||
if(currentOptionPane != NULL)
|
|
||||||
currentOptionPane->tick(minecraft);
|
if (currentOptionsGroup != NULL)
|
||||||
|
currentOptionsGroup->tick(minecraft);
|
||||||
|
|
||||||
super::tick();
|
super::tick();
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "../Screen.h"
|
#include "../Screen.h"
|
||||||
#include "../components/Button.h"
|
#include "../components/Button.h"
|
||||||
|
#include "../components/OptionsGroup.h"
|
||||||
|
|
||||||
class ImageButton;
|
class ImageButton;
|
||||||
class OptionsPane;
|
class OptionsPane;
|
||||||
@@ -10,13 +11,14 @@ class OptionsPane;
|
|||||||
class OptionsScreen: public Screen
|
class OptionsScreen: public Screen
|
||||||
{
|
{
|
||||||
typedef Screen super;
|
typedef Screen super;
|
||||||
void init();
|
|
||||||
|
|
||||||
|
void init();
|
||||||
void generateOptionScreens();
|
void generateOptionScreens();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OptionsScreen();
|
OptionsScreen();
|
||||||
~OptionsScreen();
|
~OptionsScreen();
|
||||||
|
|
||||||
void setupPositions();
|
void setupPositions();
|
||||||
void buttonClicked(Button* button);
|
void buttonClicked(Button* button);
|
||||||
void render(int xm, int ym, float a);
|
void render(int xm, int ym, float a);
|
||||||
@@ -25,13 +27,22 @@ public:
|
|||||||
|
|
||||||
virtual void mouseClicked(int x, int y, int buttonNum);
|
virtual void mouseClicked(int x, int y, int buttonNum);
|
||||||
virtual void mouseReleased(int x, int y, int buttonNum);
|
virtual void mouseReleased(int x, int y, int buttonNum);
|
||||||
|
virtual void keyPressed(int eventKey);
|
||||||
|
virtual void charPressed(char inputChar);
|
||||||
|
|
||||||
virtual void tick();
|
virtual void tick();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Touch::THeader* bHeader;
|
Touch::THeader* bHeader;
|
||||||
ImageButton* btnClose;
|
ImageButton* btnClose;
|
||||||
|
|
||||||
|
Button* btnCredits; // <-- ADD THIS
|
||||||
|
|
||||||
std::vector<Touch::TButton*> categoryButtons;
|
std::vector<Touch::TButton*> categoryButtons;
|
||||||
std::vector<OptionsPane*> optionPanes;
|
std::vector<OptionsGroup*> optionPanes;
|
||||||
OptionsPane* currentOptionPane;
|
|
||||||
|
OptionsGroup* currentOptionsGroup;
|
||||||
|
|
||||||
int selectedCategory;
|
int selectedCategory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ PauseScreen::PauseScreen(bool wasBackPaused)
|
|||||||
bServerVisibility(0),
|
bServerVisibility(0),
|
||||||
// bThirdPerson(0),
|
// bThirdPerson(0),
|
||||||
wasBackPaused(wasBackPaused),
|
wasBackPaused(wasBackPaused),
|
||||||
bSound(&Options::Option::SOUND, 1, 0),
|
// bSound(OPTIONS_SOUND_VOLUME, 1, 0),
|
||||||
bThirdPerson(&Options::Option::THIRD_PERSON),
|
bThirdPerson(OPTIONS_THIRD_PERSON_VIEW),
|
||||||
bHideGui(&Options::Option::HIDE_GUI)
|
bHideGui(OPTIONS_HIDEGUI)
|
||||||
{
|
{
|
||||||
ImageDef def;
|
ImageDef def;
|
||||||
def.setSrc(IntRectangle(160, 144, 39, 31));
|
def.setSrc(IntRectangle(160, 144, 39, 31));
|
||||||
@@ -27,7 +27,7 @@ PauseScreen::PauseScreen(bool wasBackPaused)
|
|||||||
def.width = defSrc.w * 0.666667f;
|
def.width = defSrc.w * 0.666667f;
|
||||||
def.height = defSrc.h * 0.666667f;
|
def.height = defSrc.h * 0.666667f;
|
||||||
|
|
||||||
bSound.setImageDef(def, true);
|
// bSound.setImageDef(def, true);
|
||||||
defSrc.y += defSrc.h;
|
defSrc.y += defSrc.h;
|
||||||
bThirdPerson.setImageDef(def, true);
|
bThirdPerson.setImageDef(def, true);
|
||||||
bHideGui.setImageDef(def, true);
|
bHideGui.setImageDef(def, true);
|
||||||
@@ -60,10 +60,10 @@ void PauseScreen::init() {
|
|||||||
buttons.push_back(bContinue);
|
buttons.push_back(bContinue);
|
||||||
buttons.push_back(bQuit);
|
buttons.push_back(bQuit);
|
||||||
|
|
||||||
bSound.updateImage(&minecraft->options);
|
// bSound.updateImage(&minecraft->options);
|
||||||
bThirdPerson.updateImage(&minecraft->options);
|
bThirdPerson.updateImage(&minecraft->options);
|
||||||
bHideGui.updateImage(&minecraft->options);
|
bHideGui.updateImage(&minecraft->options);
|
||||||
buttons.push_back(&bSound);
|
// buttons.push_back(&bSound);
|
||||||
buttons.push_back(&bThirdPerson);
|
buttons.push_back(&bThirdPerson);
|
||||||
//buttons.push_back(&bHideGui);
|
//buttons.push_back(&bHideGui);
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ void PauseScreen::init() {
|
|||||||
// buttons.push_back(bThirdPerson);
|
// buttons.push_back(bThirdPerson);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < buttons.size(); ++i) {
|
for (unsigned int i = 0; i < buttons.size(); ++i) {
|
||||||
if (buttons[i] == &bSound) continue;
|
// if (buttons[i] == &bSound) continue;
|
||||||
if (buttons[i] == &bThirdPerson) continue;
|
if (buttons[i] == &bThirdPerson) continue;
|
||||||
if (buttons[i] == &bHideGui) continue;
|
if (buttons[i] == &bHideGui) continue;
|
||||||
tabButtons.push_back(buttons[i]);
|
tabButtons.push_back(buttons[i]);
|
||||||
@@ -115,10 +115,10 @@ void PauseScreen::setupPositions() {
|
|||||||
bQuitAndSaveLocally->x = bServerVisibility->x = (width - bQuitAndSaveLocally->width) / 2;
|
bQuitAndSaveLocally->x = bServerVisibility->x = (width - bQuitAndSaveLocally->width) / 2;
|
||||||
bQuitAndSaveLocally->y = bServerVisibility->y = yBase + 32 * 3;
|
bQuitAndSaveLocally->y = bServerVisibility->y = yBase + 32 * 3;
|
||||||
|
|
||||||
bSound.y = bThirdPerson.y = 8;
|
// bSound.y = bThirdPerson.y = 8;
|
||||||
bSound.x = 4;
|
// bSound.x = 4;
|
||||||
bThirdPerson.x = bSound.x + 4 + bSound.width;
|
// bThirdPerson.x = bSound.x + 4 + bSound.width;
|
||||||
bHideGui.x = bThirdPerson.x + 4 + bThirdPerson.width;
|
// bHideGui.x = bThirdPerson.x + 4 + bThirdPerson.width;
|
||||||
|
|
||||||
//bThirdPerson->x = (width - bThirdPerson->w) / 2;
|
//bThirdPerson->x = (width - bThirdPerson->w) / 2;
|
||||||
//bThirdPerson->y = yBase + 32 * 4;
|
//bThirdPerson->y = yBase + 32 * 4;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ private:
|
|||||||
Button* bServerVisibility;
|
Button* bServerVisibility;
|
||||||
// Button* bThirdPerson;
|
// Button* bThirdPerson;
|
||||||
|
|
||||||
OptionButton bSound;
|
// OptionButton bSound;
|
||||||
OptionButton bThirdPerson;
|
OptionButton bThirdPerson;
|
||||||
OptionButton bHideGui;
|
OptionButton bHideGui;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "PauseScreen.h"
|
#include "PauseScreen.h"
|
||||||
#include "RenameMPLevelScreen.h"
|
#include "RenameMPLevelScreen.h"
|
||||||
#include "IngameBlockSelectionScreen.h"
|
#include "IngameBlockSelectionScreen.h"
|
||||||
|
#include "JoinByIPScreen.h"
|
||||||
#include "touch/TouchStartMenuScreen.h"
|
#include "touch/TouchStartMenuScreen.h"
|
||||||
#include "touch/TouchSelectWorldScreen.h"
|
#include "touch/TouchSelectWorldScreen.h"
|
||||||
#include "touch/TouchJoinGameScreen.h"
|
#include "touch/TouchJoinGameScreen.h"
|
||||||
@@ -12,6 +13,8 @@
|
|||||||
|
|
||||||
#include "../../Minecraft.h"
|
#include "../../Minecraft.h"
|
||||||
|
|
||||||
|
#include <client/gui/screens/UsernameScreen.h>
|
||||||
|
|
||||||
Screen* ScreenChooser::createScreen( ScreenId id )
|
Screen* ScreenChooser::createScreen( ScreenId id )
|
||||||
{
|
{
|
||||||
Screen* screen = NULL;
|
Screen* screen = NULL;
|
||||||
@@ -24,7 +27,7 @@ Screen* ScreenChooser::createScreen( ScreenId id )
|
|||||||
case SCREEN_PAUSE: screen = new PauseScreen(false); break;
|
case SCREEN_PAUSE: screen = new PauseScreen(false); break;
|
||||||
case SCREEN_PAUSEPREV: screen = new PauseScreen(true); break;
|
case SCREEN_PAUSEPREV: screen = new PauseScreen(true); break;
|
||||||
case SCREEN_BLOCKSELECTION: screen = new Touch::IngameBlockSelectionScreen(); break;
|
case SCREEN_BLOCKSELECTION: screen = new Touch::IngameBlockSelectionScreen(); break;
|
||||||
|
case SCREEN_JOINBYIP: screen = new JoinByIPScreen(); break;
|
||||||
case SCREEN_NONE:
|
case SCREEN_NONE:
|
||||||
default:
|
default:
|
||||||
// Do nothing
|
// Do nothing
|
||||||
@@ -38,6 +41,7 @@ Screen* ScreenChooser::createScreen( ScreenId id )
|
|||||||
case SCREEN_PAUSE: screen = new PauseScreen(false); break;
|
case SCREEN_PAUSE: screen = new PauseScreen(false); break;
|
||||||
case SCREEN_PAUSEPREV: screen = new PauseScreen(true); break;
|
case SCREEN_PAUSEPREV: screen = new PauseScreen(true); break;
|
||||||
case SCREEN_BLOCKSELECTION: screen = new IngameBlockSelectionScreen(); break;
|
case SCREEN_BLOCKSELECTION: screen = new IngameBlockSelectionScreen(); break;
|
||||||
|
case SCREEN_JOINBYIP: screen = new JoinByIPScreen(); break;
|
||||||
|
|
||||||
case SCREEN_NONE:
|
case SCREEN_NONE:
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ enum ScreenId {
|
|||||||
SCREEN_PAUSE,
|
SCREEN_PAUSE,
|
||||||
SCREEN_PAUSEPREV,
|
SCREEN_PAUSEPREV,
|
||||||
SCREEN_SELECTWORLD,
|
SCREEN_SELECTWORLD,
|
||||||
SCREEN_BLOCKSELECTION
|
SCREEN_BLOCKSELECTION,
|
||||||
|
SCREEN_JOINBYIP
|
||||||
};
|
};
|
||||||
|
|
||||||
class Screen;
|
class Screen;
|
||||||
|
|||||||
@@ -230,7 +230,6 @@ SelectWorldScreen::SelectWorldScreen()
|
|||||||
bBack (3, "Back"),
|
bBack (3, "Back"),
|
||||||
bWorldView(4, ""),
|
bWorldView(4, ""),
|
||||||
worldsList(NULL),
|
worldsList(NULL),
|
||||||
_state(_STATE_DEFAULT),
|
|
||||||
_hasStartedLevel(false)
|
_hasStartedLevel(false)
|
||||||
{
|
{
|
||||||
bDelete.active = false;
|
bDelete.active = false;
|
||||||
@@ -244,16 +243,10 @@ SelectWorldScreen::~SelectWorldScreen()
|
|||||||
void SelectWorldScreen::buttonClicked(Button* button)
|
void SelectWorldScreen::buttonClicked(Button* button)
|
||||||
{
|
{
|
||||||
if (button->id == bCreate.id) {
|
if (button->id == bCreate.id) {
|
||||||
//minecraft->setScreen( new CreateWorldScreen() );
|
// open in-game world-creation screen instead of using platform dialog
|
||||||
//minecraft->locateMultiplayer();
|
if (!_hasStartedLevel) {
|
||||||
//minecraft->setScreen(new JoinGameScreen());
|
std::string name = getUniqueLevelName("world");
|
||||||
|
minecraft->setScreen(new SimpleChooseLevelScreen(name));
|
||||||
//minecraft->hostMultiplayer();
|
|
||||||
//minecraft->setScreen(new ProgressScreen());
|
|
||||||
|
|
||||||
if (_state == _STATE_DEFAULT && !_hasStartedLevel) {
|
|
||||||
minecraft->platform()->createUserInput(DialogDefinitions::DIALOG_CREATE_NEW_WORLD);
|
|
||||||
_state = _STATE_CREATEWORLD;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (button->id == bDelete.id) {
|
if (button->id == bDelete.id) {
|
||||||
@@ -294,70 +287,6 @@ static char ILLEGAL_FILE_CHARACTERS[] = {
|
|||||||
|
|
||||||
void SelectWorldScreen::tick()
|
void SelectWorldScreen::tick()
|
||||||
{
|
{
|
||||||
if (_state == _STATE_CREATEWORLD) {
|
|
||||||
#if defined(RPI)
|
|
||||||
std::string levelId = getUniqueLevelName("world");
|
|
||||||
LevelSettings settings(getEpochTimeS(), GameType::Creative);
|
|
||||||
minecraft->selectLevel(levelId, levelId, settings);
|
|
||||||
minecraft->hostMultiplayer();
|
|
||||||
minecraft->setScreen(new ProgressScreen());
|
|
||||||
_hasStartedLevel = true;
|
|
||||||
#elif defined(WIN32)
|
|
||||||
std::string name = getUniqueLevelName("perf");
|
|
||||||
minecraft->setScreen(new SimpleChooseLevelScreen(name));
|
|
||||||
#else
|
|
||||||
int status = minecraft->platform()->getUserInputStatus();
|
|
||||||
if (status > -1) {
|
|
||||||
if (status == 1) {
|
|
||||||
StringVector sv = minecraft->platform()->getUserInput();
|
|
||||||
|
|
||||||
// Read the level name.
|
|
||||||
// 1) Trim name 2) Remove all bad chars 3) Append '-' chars 'til the name is unique
|
|
||||||
std::string levelName = Util::stringTrim(sv[0]);
|
|
||||||
std::string levelId = levelName;
|
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(ILLEGAL_FILE_CHARACTERS) / sizeof(char); ++i)
|
|
||||||
levelId = Util::stringReplace(levelId, std::string(1, ILLEGAL_FILE_CHARACTERS[i]), "");
|
|
||||||
if ((int)levelId.length() == 0) {
|
|
||||||
levelId = "no_name";
|
|
||||||
}
|
|
||||||
levelId = getUniqueLevelName(levelId);
|
|
||||||
|
|
||||||
// Read the seed
|
|
||||||
int seed = getEpochTimeS();
|
|
||||||
if (sv.size() >= 2) {
|
|
||||||
std::string seedString = Util::stringTrim(sv[1]);
|
|
||||||
if (seedString.length() > 0) {
|
|
||||||
int tmpSeed;
|
|
||||||
// Try to read it as an integer
|
|
||||||
if (sscanf(seedString.c_str(), "%d", &tmpSeed) > 0) {
|
|
||||||
seed = tmpSeed;
|
|
||||||
} // Hash the "seed"
|
|
||||||
else {
|
|
||||||
seed = Util::hashCode(seedString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Read the game mode
|
|
||||||
bool isCreative = true;
|
|
||||||
if (sv.size() >= 3 && sv[2] == "survival")
|
|
||||||
isCreative = false;
|
|
||||||
|
|
||||||
// Start a new level with the given name and seed
|
|
||||||
LevelSettings settings(seed, isCreative? GameType::Creative : GameType::Survival);
|
|
||||||
LOGI("Creating a level with id '%s', name '%s' and seed '%d'\n", levelId.c_str(), levelName.c_str(), seed);
|
|
||||||
minecraft->selectLevel(levelId, levelName, settings);
|
|
||||||
minecraft->hostMultiplayer();
|
|
||||||
minecraft->setScreen(new ProgressScreen());
|
|
||||||
_hasStartedLevel = true;
|
|
||||||
}
|
|
||||||
_state = _STATE_DEFAULT;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
worldsList->tick();
|
worldsList->tick();
|
||||||
|
|
||||||
if (worldsList->hasPickedLevel) {
|
if (worldsList->hasPickedLevel) {
|
||||||
@@ -425,13 +354,23 @@ void SelectWorldScreen::render( int xm, int ym, float a )
|
|||||||
//Performance::watches.get("sws-worlds").start();
|
//Performance::watches.get("sws-worlds").start();
|
||||||
|
|
||||||
worldsList->setComponentSelected(bWorldView.selected);
|
worldsList->setComponentSelected(bWorldView.selected);
|
||||||
|
// #ifdef PLATFORM_DESKTOP
|
||||||
|
|
||||||
|
// desktop: render the list normally (mouse wheel handled separately below)
|
||||||
if (_mouseHasBeenUp)
|
if (_mouseHasBeenUp)
|
||||||
worldsList->render(xm, ym, a);
|
worldsList->render(xm, ym, a);
|
||||||
else {
|
else {
|
||||||
worldsList->render(0, 0, a);
|
worldsList->render(0, 0, a);
|
||||||
_mouseHasBeenUp = !Mouse::getButtonState(MouseAction::ACTION_LEFT);
|
_mouseHasBeenUp = !Mouse::getButtonState(MouseAction::ACTION_LEFT);
|
||||||
}
|
}
|
||||||
|
// #else
|
||||||
|
// if (_mouseHasBeenUp)
|
||||||
|
// worldsList->render(xm, ym, a);
|
||||||
|
// else {
|
||||||
|
// worldsList->render(0, 0, a);
|
||||||
|
// _mouseHasBeenUp = !Mouse::getButtonState(MouseAction::ACTION_LEFT);
|
||||||
|
// }
|
||||||
|
// #endif
|
||||||
|
|
||||||
//Performance::watches.get("sws-worlds").stop();
|
//Performance::watches.get("sws-worlds").stop();
|
||||||
//Performance::watches.get("sws-screen").start();
|
//Performance::watches.get("sws-screen").start();
|
||||||
@@ -473,12 +412,34 @@ std::string SelectWorldScreen::getUniqueLevelName( const std::string& level )
|
|||||||
|
|
||||||
bool SelectWorldScreen::isInGameScreen() { return true; }
|
bool SelectWorldScreen::isInGameScreen() { return true; }
|
||||||
|
|
||||||
|
void SelectWorldScreen::mouseWheel(int dx, int dy, int xm, int ym)
|
||||||
|
{
|
||||||
|
if (!worldsList)
|
||||||
|
return;
|
||||||
|
if (dy == 0)
|
||||||
|
return;
|
||||||
|
int num = worldsList->getNumberOfItems();
|
||||||
|
int idx = worldsList->selectedItem;
|
||||||
|
if (dy > 0) {
|
||||||
|
if (idx > 0) {
|
||||||
|
idx--;
|
||||||
|
worldsList->stepLeft();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (idx < num - 1) {
|
||||||
|
idx++;
|
||||||
|
worldsList->stepRight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
worldsList->selectedItem = idx;
|
||||||
|
}
|
||||||
|
|
||||||
void SelectWorldScreen::keyPressed( int eventKey )
|
void SelectWorldScreen::keyPressed( int eventKey )
|
||||||
{
|
{
|
||||||
if (bWorldView.selected) {
|
if (bWorldView.selected) {
|
||||||
if (eventKey == minecraft->options.keyLeft.key)
|
if (eventKey == minecraft->options.getIntValue(OPTIONS_KEY_RIGHT))
|
||||||
worldsList->stepLeft();
|
worldsList->stepLeft();
|
||||||
if (eventKey == minecraft->options.keyRight.key)
|
if (eventKey == minecraft->options.getIntValue(OPTIONS_KEY_LEFT))
|
||||||
worldsList->stepRight();
|
worldsList->stepRight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "../Screen.h"
|
#include "../Screen.h"
|
||||||
#include "../TweenData.h"
|
#include "../TweenData.h"
|
||||||
#include "../components/Button.h"
|
#include "../components/Button.h"
|
||||||
#include "../components/SmallButton.h"
|
|
||||||
#include "../components/RolledSelectionListH.h"
|
#include "../components/RolledSelectionListH.h"
|
||||||
#include "../../Minecraft.h"
|
#include "../../Minecraft.h"
|
||||||
#include "../../../world/level/storage/LevelStorageSource.h"
|
#include "../../../world/level/storage/LevelStorageSource.h"
|
||||||
@@ -90,6 +89,9 @@ public:
|
|||||||
|
|
||||||
void render(int xm, int ym, float a);
|
void render(int xm, int ym, float a);
|
||||||
|
|
||||||
|
// mouse wheel scroll (new in desktop implementation)
|
||||||
|
virtual void mouseWheel(int dx, int dy, int xm, int ym);
|
||||||
|
|
||||||
bool isInGameScreen();
|
bool isInGameScreen();
|
||||||
private:
|
private:
|
||||||
void loadLevelSource();
|
void loadLevelSource();
|
||||||
@@ -104,9 +106,6 @@ private:
|
|||||||
|
|
||||||
bool _mouseHasBeenUp;
|
bool _mouseHasBeenUp;
|
||||||
bool _hasStartedLevel;
|
bool _hasStartedLevel;
|
||||||
int _state;
|
|
||||||
static const int _STATE_DEFAULT = 0;
|
|
||||||
static const int _STATE_CREATEWORLD = 1;
|
|
||||||
//LevelStorageSource* levels;
|
//LevelStorageSource* levels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,55 +2,145 @@
|
|||||||
#include "ProgressScreen.h"
|
#include "ProgressScreen.h"
|
||||||
#include "ScreenChooser.h"
|
#include "ScreenChooser.h"
|
||||||
#include "../components/Button.h"
|
#include "../components/Button.h"
|
||||||
|
#include "../components/ImageButton.h"
|
||||||
#include "../../Minecraft.h"
|
#include "../../Minecraft.h"
|
||||||
#include "../../../world/level/LevelSettings.h"
|
#include "../../../world/level/LevelSettings.h"
|
||||||
#include "../../../platform/time.h"
|
#include "../../../platform/time.h"
|
||||||
|
#include "../../../platform/input/Keyboard.h"
|
||||||
|
#include "../../../platform/log.h"
|
||||||
|
|
||||||
SimpleChooseLevelScreen::SimpleChooseLevelScreen(const std::string& levelName)
|
SimpleChooseLevelScreen::SimpleChooseLevelScreen(const std::string& levelName)
|
||||||
: bCreative(0),
|
: bHeader(0),
|
||||||
bSurvival(0),
|
bGamemode(0),
|
||||||
|
bCheats(0),
|
||||||
bBack(0),
|
bBack(0),
|
||||||
|
bCreate(0),
|
||||||
levelName(levelName),
|
levelName(levelName),
|
||||||
hasChosen(false)
|
hasChosen(false),
|
||||||
|
gamemode(GameType::Survival),
|
||||||
|
cheatsEnabled(false),
|
||||||
|
tLevelName(0, "World name"),
|
||||||
|
tSeed(1, "World seed")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleChooseLevelScreen::~SimpleChooseLevelScreen()
|
SimpleChooseLevelScreen::~SimpleChooseLevelScreen()
|
||||||
{
|
{
|
||||||
delete bCreative;
|
if (bHeader) delete bHeader;
|
||||||
delete bSurvival;
|
delete bGamemode;
|
||||||
|
delete bCheats;
|
||||||
delete bBack;
|
delete bBack;
|
||||||
|
delete bCreate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleChooseLevelScreen::init()
|
void SimpleChooseLevelScreen::init()
|
||||||
{
|
{
|
||||||
if (minecraft->useTouchscreen()) {
|
// make sure the base class loads the existing level list; the
|
||||||
bCreative = new Touch::TButton(1, "Creative mode");
|
// derived screen uses ChooseLevelScreen::getUniqueLevelName(), which
|
||||||
bSurvival = new Touch::TButton(2, "Survival mode");
|
// depends on `levels` being populated. omitting this used to result
|
||||||
bBack = new Touch::TButton(3, "Back");
|
// in duplicate IDs ("creating the second world would load the
|
||||||
} else {
|
// first") when the name already existed.
|
||||||
bCreative = new Button(1, "Creative mode");
|
ChooseLevelScreen::init();
|
||||||
bSurvival = new Button(2, "Survival mode");
|
|
||||||
bBack = new Button(3, "Back");
|
|
||||||
}
|
|
||||||
buttons.push_back(bCreative);
|
|
||||||
buttons.push_back(bSurvival);
|
|
||||||
buttons.push_back(bBack);
|
|
||||||
|
|
||||||
tabButtons.push_back(bCreative);
|
tLevelName.text = "New world";
|
||||||
tabButtons.push_back(bSurvival);
|
|
||||||
|
// header + close button
|
||||||
|
bHeader = new Touch::THeader(0, "Create World");
|
||||||
|
// create the back/X button as ImageButton like CreditsScreen
|
||||||
|
bBack = new ImageButton(2, "");
|
||||||
|
{
|
||||||
|
ImageDef def;
|
||||||
|
def.name = "gui/touchgui.png";
|
||||||
|
def.width = 34;
|
||||||
|
def.height = 26;
|
||||||
|
def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height));
|
||||||
|
bBack->setImageDef(def, true);
|
||||||
|
}
|
||||||
|
if (minecraft->useTouchscreen()) {
|
||||||
|
bGamemode = new Touch::TButton(1, "Survival mode");
|
||||||
|
bCheats = new Touch::TButton(4, "Cheats: Off");
|
||||||
|
bCreate = new Touch::TButton(3, "Create");
|
||||||
|
} else {
|
||||||
|
bGamemode = new Button(1, "Survival mode");
|
||||||
|
bCheats = new Button(4, "Cheats: Off");
|
||||||
|
bCreate = new Button(3, "Create");
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons.push_back(bHeader);
|
||||||
|
buttons.push_back(bBack);
|
||||||
|
buttons.push_back(bGamemode);
|
||||||
|
buttons.push_back(bCheats);
|
||||||
|
buttons.push_back(bCreate);
|
||||||
|
|
||||||
|
tabButtons.push_back(bGamemode);
|
||||||
|
tabButtons.push_back(bCheats);
|
||||||
tabButtons.push_back(bBack);
|
tabButtons.push_back(bBack);
|
||||||
|
tabButtons.push_back(bCreate);
|
||||||
|
|
||||||
|
textBoxes.push_back(&tLevelName);
|
||||||
|
textBoxes.push_back(&tSeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleChooseLevelScreen::setupPositions()
|
void SimpleChooseLevelScreen::setupPositions()
|
||||||
{
|
{
|
||||||
bCreative->width = bSurvival->width = bBack->width = 120;
|
int buttonHeight = bBack->height;
|
||||||
bCreative->x = (width - bCreative->width) / 2;
|
|
||||||
bCreative->y = height/3 - 40;
|
// position back button in upper-right
|
||||||
bSurvival->x = (width - bSurvival->width) / 2;
|
bBack->x = width - bBack->width;
|
||||||
bSurvival->y = 2*height/3 - 40;
|
bBack->y = 0;
|
||||||
bBack->x = bSurvival->x + bSurvival->width - bBack->width;
|
|
||||||
bBack->y = height - 40;
|
// header occupies remaining top bar
|
||||||
|
if (bHeader) {
|
||||||
|
bHeader->x = 0;
|
||||||
|
bHeader->y = 0;
|
||||||
|
bHeader->width = width - bBack->width;
|
||||||
|
bHeader->height = buttonHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// layout the form elements below the header
|
||||||
|
int centerX = width / 2;
|
||||||
|
const int padding = 5;
|
||||||
|
|
||||||
|
tLevelName.width = tSeed.width = 200;
|
||||||
|
tLevelName.x = centerX - tLevelName.width / 2;
|
||||||
|
tLevelName.y = buttonHeight + 20;
|
||||||
|
|
||||||
|
tSeed.x = tLevelName.x;
|
||||||
|
tSeed.y = tLevelName.y + 30;
|
||||||
|
|
||||||
|
const int buttonWidth = 120;
|
||||||
|
const int buttonSpacing = 10;
|
||||||
|
const int totalButtonWidth = buttonWidth * 2 + buttonSpacing;
|
||||||
|
|
||||||
|
bGamemode->width = buttonWidth;
|
||||||
|
bCheats->width = buttonWidth;
|
||||||
|
|
||||||
|
bGamemode->x = centerX - totalButtonWidth / 2;
|
||||||
|
bCheats->x = bGamemode->x + buttonWidth + buttonSpacing;
|
||||||
|
|
||||||
|
// compute vertical centre for buttons in remaining space
|
||||||
|
{
|
||||||
|
int bottomPad = 20;
|
||||||
|
int availTop = buttonHeight + 20 + 30 + 10; // just below seed
|
||||||
|
int availBottom = height - bottomPad - bCreate->height - 10; // leave some gap before create
|
||||||
|
int availHeight = availBottom - availTop;
|
||||||
|
if (availHeight < 0) availHeight = 0;
|
||||||
|
int y = availTop + (availHeight - bGamemode->height) / 2;
|
||||||
|
bGamemode->y = y;
|
||||||
|
bCheats->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
bCreate->width = 100;
|
||||||
|
bCreate->x = centerX - bCreate->width / 2;
|
||||||
|
int bottomPadding = 20;
|
||||||
|
bCreate->y = height - bottomPadding - bCreate->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimpleChooseLevelScreen::tick()
|
||||||
|
{
|
||||||
|
// let any textboxes handle their own blinking/input
|
||||||
|
for (auto* tb : textBoxes)
|
||||||
|
tb->tick(minecraft);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleChooseLevelScreen::render( int xm, int ym, float a )
|
void SimpleChooseLevelScreen::render( int xm, int ym, float a )
|
||||||
@@ -58,36 +148,109 @@ void SimpleChooseLevelScreen::render( int xm, int ym, float a )
|
|||||||
renderDirtBackground(0);
|
renderDirtBackground(0);
|
||||||
glEnable2(GL_BLEND);
|
glEnable2(GL_BLEND);
|
||||||
|
|
||||||
drawCenteredString(minecraft->font, "Mobs, health and gather resources", width/2, bSurvival->y + bSurvival->height + 4, 0xffcccccc);
|
const char* modeDesc = NULL;
|
||||||
drawCenteredString(minecraft->font, "Unlimited resources and flying", width/2, bCreative->y + bCreative->height + 4, 0xffcccccc);
|
if (gamemode == GameType::Survival) {
|
||||||
|
modeDesc = "Mobs, health and gather resources";
|
||||||
|
} else if (gamemode == GameType::Creative) {
|
||||||
|
modeDesc = "Unlimited resources and flying";
|
||||||
|
}
|
||||||
|
if (modeDesc) {
|
||||||
|
drawCenteredString(minecraft->font, modeDesc, width / 2, bGamemode->y + bGamemode->height + 4, 0xffcccccc);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawString(minecraft->font, "World name:", tLevelName.x, tLevelName.y - Font::DefaultLineHeight - 2, 0xffcccccc);
|
||||||
|
drawString(minecraft->font, "World seed:", tSeed.x, tSeed.y - Font::DefaultLineHeight - 2, 0xffcccccc);
|
||||||
|
|
||||||
Screen::render(xm, ym, a);
|
Screen::render(xm, ym, a);
|
||||||
glDisable2(GL_BLEND);
|
glDisable2(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mouse clicks should also manage textbox focus explicitly
|
||||||
|
void SimpleChooseLevelScreen::mouseClicked(int x, int y, int buttonNum)
|
||||||
|
{
|
||||||
|
if (buttonNum == MouseAction::ACTION_LEFT) {
|
||||||
|
// determine if the click landed on either textbox or its label above
|
||||||
|
int lvlTop = tLevelName.y - (Font::DefaultLineHeight + 4);
|
||||||
|
int lvlBottom = tLevelName.y + tLevelName.height;
|
||||||
|
int lvlLeft = tLevelName.x;
|
||||||
|
int lvlRight = tLevelName.x + tLevelName.width;
|
||||||
|
bool clickedLevel = x >= lvlLeft && x < lvlRight && y >= lvlTop && y < lvlBottom;
|
||||||
|
|
||||||
|
int seedTop = tSeed.y - (Font::DefaultLineHeight + 4);
|
||||||
|
int seedBottom = tSeed.y + tSeed.height;
|
||||||
|
int seedLeft = tSeed.x;
|
||||||
|
int seedRight = tSeed.x + tSeed.width;
|
||||||
|
bool clickedSeed = x >= seedLeft && x < seedRight && y >= seedTop && y < seedBottom;
|
||||||
|
|
||||||
|
if (clickedLevel) {
|
||||||
|
LOGI("SimpleChooseLevelScreen: level textbox clicked (%d,%d)\n", x, y);
|
||||||
|
tLevelName.setFocus(minecraft);
|
||||||
|
tSeed.loseFocus(minecraft);
|
||||||
|
} else if (clickedSeed) {
|
||||||
|
LOGI("SimpleChooseLevelScreen: seed textbox clicked (%d,%d)\n", x, y);
|
||||||
|
tSeed.setFocus(minecraft);
|
||||||
|
tLevelName.loseFocus(minecraft);
|
||||||
|
} else {
|
||||||
|
// click outside both fields -> blur both
|
||||||
|
tLevelName.loseFocus(minecraft);
|
||||||
|
tSeed.loseFocus(minecraft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow normal button and textbox handling too
|
||||||
|
Screen::mouseClicked(x, y, buttonNum);
|
||||||
|
}
|
||||||
|
|
||||||
void SimpleChooseLevelScreen::buttonClicked( Button* button )
|
void SimpleChooseLevelScreen::buttonClicked( Button* button )
|
||||||
{
|
{
|
||||||
if (button == bBack) {
|
|
||||||
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (hasChosen)
|
if (hasChosen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int gameType;
|
if (button == bGamemode) {
|
||||||
|
gamemode ^= 1;
|
||||||
|
bGamemode->msg = (gamemode == GameType::Survival) ? "Survival mode" : "Creative mode";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (button == bCreative)
|
if (button == bCheats) {
|
||||||
gameType = GameType::Creative;
|
cheatsEnabled = !cheatsEnabled;
|
||||||
|
bCheats->msg = cheatsEnabled ? "Cheats: On" : "Cheats: Off";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (button == bSurvival)
|
if (button == bCreate && !tLevelName.text.empty()) {
|
||||||
gameType = GameType::Survival;
|
int seed = getEpochTimeS();
|
||||||
|
if (!tSeed.text.empty()) {
|
||||||
std::string levelId = getUniqueLevelName(levelName);
|
std::string seedString = Util::stringTrim(tSeed.text);
|
||||||
LevelSettings settings(getEpochTimeS(), gameType);
|
int tmpSeed;
|
||||||
|
if (sscanf(seedString.c_str(), "%d", &tmpSeed) > 0) {
|
||||||
|
seed = tmpSeed;
|
||||||
|
} else {
|
||||||
|
seed = Util::hashCode(seedString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string levelId = getUniqueLevelName(tLevelName.text);
|
||||||
|
LevelSettings settings(seed, gamemode, cheatsEnabled);
|
||||||
minecraft->selectLevel(levelId, levelId, settings);
|
minecraft->selectLevel(levelId, levelId, settings);
|
||||||
minecraft->hostMultiplayer();
|
minecraft->hostMultiplayer();
|
||||||
minecraft->setScreen(new ProgressScreen());
|
minecraft->setScreen(new ProgressScreen());
|
||||||
hasChosen = true;
|
hasChosen = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button == bBack) {
|
||||||
|
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimpleChooseLevelScreen::keyPressed(int eventKey)
|
||||||
|
{
|
||||||
|
if (eventKey == Keyboard::KEY_ESCAPE) {
|
||||||
|
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// let base class handle navigation and text box keys
|
||||||
|
Screen::keyPressed(eventKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SimpleChooseLevelScreen::handleBackEvent(bool isDown) {
|
bool SimpleChooseLevelScreen::handleBackEvent(bool isDown) {
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__DemoChooseLevelScreen_H__
|
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__DemoChooseLevelScreen_H__
|
||||||
|
|
||||||
#include "ChooseLevelScreen.h"
|
#include "ChooseLevelScreen.h"
|
||||||
|
#include "../components/TextBox.h"
|
||||||
|
#include "../components/Button.h" // for Touch::THeader
|
||||||
class Button;
|
class Button;
|
||||||
|
class ImageButton;
|
||||||
|
|
||||||
class SimpleChooseLevelScreen: public ChooseLevelScreen
|
class SimpleChooseLevelScreen: public ChooseLevelScreen
|
||||||
{
|
{
|
||||||
@@ -12,21 +15,30 @@ public:
|
|||||||
virtual ~SimpleChooseLevelScreen();
|
virtual ~SimpleChooseLevelScreen();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void setupPositions();
|
void setupPositions();
|
||||||
|
void tick();
|
||||||
|
|
||||||
void render(int xm, int ym, float a);
|
void render(int xm, int ym, float a);
|
||||||
|
|
||||||
void buttonClicked(Button* button);
|
void buttonClicked(Button* button);
|
||||||
bool handleBackEvent(bool isDown);
|
bool handleBackEvent(bool isDown);
|
||||||
|
virtual void keyPressed(int eventKey);
|
||||||
|
virtual void mouseClicked(int x, int y, int buttonNum);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Button* bCreative;
|
Touch::THeader* bHeader;
|
||||||
Button* bSurvival;
|
Button* bGamemode;
|
||||||
Button* bBack;
|
Button* bCheats;
|
||||||
|
ImageButton* bBack;
|
||||||
|
Button* bCreate;
|
||||||
bool hasChosen;
|
bool hasChosen;
|
||||||
|
|
||||||
std::string levelName;
|
std::string levelName;
|
||||||
|
int gamemode;
|
||||||
|
bool cheatsEnabled;
|
||||||
|
|
||||||
|
TextBox tLevelName;
|
||||||
|
TextBox tSeed;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__DemoChooseLevelScreen_H__*/
|
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__DemoChooseLevelScreen_H__*/
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
#include "StartMenuScreen.h"
|
#include "StartMenuScreen.h"
|
||||||
|
#include "UsernameScreen.h"
|
||||||
#include "SelectWorldScreen.h"
|
#include "SelectWorldScreen.h"
|
||||||
#include "ProgressScreen.h"
|
#include "ProgressScreen.h"
|
||||||
#include "JoinGameScreen.h"
|
#include "JoinGameScreen.h"
|
||||||
#include "OptionsScreen.h"
|
#include "OptionsScreen.h"
|
||||||
#include "PauseScreen.h"
|
#include "PauseScreen.h"
|
||||||
#include "InvalidLicenseScreen.h"
|
|
||||||
#include "PrerenderTilesScreen.h" // test button
|
#include "PrerenderTilesScreen.h" // test button
|
||||||
//#include "BuyGameScreen.h"
|
#include "../components/ImageButton.h"
|
||||||
|
|
||||||
#include "../../../util/Mth.h"
|
#include "../../../util/Mth.h"
|
||||||
|
|
||||||
#include "../Font.h"
|
#include "../Font.h"
|
||||||
#include "../components/SmallButton.h"
|
|
||||||
#include "../components/ScrolledSelectionList.h"
|
#include "../components/ScrolledSelectionList.h"
|
||||||
|
|
||||||
#include "../../Minecraft.h"
|
#include "../../Minecraft.h"
|
||||||
@@ -26,9 +25,8 @@
|
|||||||
StartMenuScreen::StartMenuScreen()
|
StartMenuScreen::StartMenuScreen()
|
||||||
: bHost( 2, 0, 0, 160, 24, "Start Game"),
|
: bHost( 2, 0, 0, 160, 24, "Start Game"),
|
||||||
bJoin( 3, 0, 0, 160, 24, "Join Game"),
|
bJoin( 3, 0, 0, 160, 24, "Join Game"),
|
||||||
bOptions( 4, 0, 0, 78, 22, "Options"),
|
bOptions( 4, 0, 0, 160, 24, "Options"),
|
||||||
bBuy( 5, 0, 0, 78, 22, "Buy"),
|
bQuit( 5, "")
|
||||||
bTest( 999, 0, 0, 78, 22, "Create")
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +36,12 @@ StartMenuScreen::~StartMenuScreen()
|
|||||||
|
|
||||||
void StartMenuScreen::init()
|
void StartMenuScreen::init()
|
||||||
{
|
{
|
||||||
|
bJoin.active = bHost.active = bOptions.active = true;
|
||||||
|
|
||||||
|
if (minecraft->options.getStringValue(OPTIONS_USERNAME).empty()) {
|
||||||
|
return; // tick() will redirect to UsernameScreen
|
||||||
|
}
|
||||||
|
|
||||||
buttons.push_back(&bHost);
|
buttons.push_back(&bHost);
|
||||||
buttons.push_back(&bJoin);
|
buttons.push_back(&bJoin);
|
||||||
//buttons.push_back(&bTest);
|
//buttons.push_back(&bTest);
|
||||||
@@ -50,18 +54,28 @@ void StartMenuScreen::init()
|
|||||||
tabButtons.push_back(&bOptions);
|
tabButtons.push_back(&bOptions);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEMO_MODE
|
// add quit button (top right X icon) – match OptionsScreen style
|
||||||
buttons.push_back(&bBuy);
|
{
|
||||||
tabButtons.push_back(&bBuy);
|
ImageDef def;
|
||||||
#endif
|
def.name = "gui/touchgui.png";
|
||||||
|
def.width = 34;
|
||||||
|
def.height = 26;
|
||||||
|
def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height));
|
||||||
|
bQuit.setImageDef(def, true);
|
||||||
|
bQuit.scaleWhenPressed = false;
|
||||||
|
buttons.push_back(&bQuit);
|
||||||
|
// don't include in tab navigation
|
||||||
|
}
|
||||||
|
|
||||||
copyright = "\xffMojang AB";//. Do not distribute!";
|
copyright = "\xffMojang AB";//. Do not distribute!";
|
||||||
|
|
||||||
#ifdef PRE_ANDROID23
|
// always show base version string, suffix was previously added for Android builds
|
||||||
std::string versionString = Common::getGameVersionString("j");
|
|
||||||
#else
|
|
||||||
std::string versionString = Common::getGameVersionString();
|
std::string versionString = Common::getGameVersionString();
|
||||||
#endif
|
|
||||||
|
std::string _username = minecraft->options.getStringValue(OPTIONS_USERNAME);
|
||||||
|
if (_username.empty()) _username = "unknown";
|
||||||
|
|
||||||
|
username = "Username: " + _username;
|
||||||
|
|
||||||
#ifdef DEMO_MODE
|
#ifdef DEMO_MODE
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@@ -76,37 +90,26 @@ void StartMenuScreen::init()
|
|||||||
version = versionString;
|
version = versionString;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bJoin.active = bHost.active = bOptions.active = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartMenuScreen::setupPositions() {
|
void StartMenuScreen::setupPositions() {
|
||||||
int yBase = height / 2 + 25;
|
int yBase = height / 2;
|
||||||
|
|
||||||
//#ifdef ANDROID
|
bHost.y = yBase;
|
||||||
bHost.y = yBase - 28;
|
bJoin.y = bHost.y + 24 + 4;
|
||||||
#ifdef RPI
|
bOptions.y = bJoin.y + 24 + 4;
|
||||||
bJoin.y = yBase + 4;
|
|
||||||
#else
|
|
||||||
bJoin.y = yBase;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bOptions.y = yBase + 28 + 2;
|
|
||||||
bTest.y = bBuy.y = bOptions.y;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
// Center buttons
|
// Center buttons
|
||||||
bHost.x = (width - bHost.width) / 2;
|
bHost.x = (width - bHost.width) / 2;
|
||||||
bJoin.x = (width - bJoin.width) / 2;
|
bJoin.x = (width - bJoin.width) / 2;
|
||||||
bOptions.x = (width - bJoin.width) / 2;
|
bOptions.x = (width - bOptions.width) / 2;
|
||||||
bTest.x = bBuy.x = bOptions.x + bOptions.width + 4;
|
|
||||||
|
|
||||||
copyrightPosX = width - minecraft->font->width(copyright) - 1;
|
// position quit icon at top-right (use image-defined size)
|
||||||
versionPosX = (width - minecraft->font->width(version)) / 2;// - minecraft->font->width(version) - 2;
|
bQuit.x = width - bQuit.width;
|
||||||
|
bQuit.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartMenuScreen::tick() {
|
void StartMenuScreen::tick() {
|
||||||
_updateLicense();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartMenuScreen::buttonClicked(Button* button) {
|
void StartMenuScreen::buttonClicked(Button* button) {
|
||||||
@@ -128,15 +131,9 @@ void StartMenuScreen::buttonClicked(Button* button) {
|
|||||||
{
|
{
|
||||||
minecraft->setScreen(new OptionsScreen());
|
minecraft->setScreen(new OptionsScreen());
|
||||||
}
|
}
|
||||||
if (button->id == bTest.id)
|
if (button == &bQuit)
|
||||||
{
|
{
|
||||||
//minecraft->setScreen(new PauseScreen());
|
minecraft->quit();
|
||||||
//minecraft->setScreen(new PrerenderTilesScreen());
|
|
||||||
}
|
|
||||||
if (button->id == bBuy.id)
|
|
||||||
{
|
|
||||||
minecraft->platform()->buyGame();
|
|
||||||
//minecraft->setScreen(new BuyGameScreen());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +143,9 @@ void StartMenuScreen::render( int xm, int ym, float a )
|
|||||||
{
|
{
|
||||||
renderBackground();
|
renderBackground();
|
||||||
|
|
||||||
|
// Show current username in the top-left corner
|
||||||
|
drawString(font, username, 2, 2, 0xffffffff);
|
||||||
|
|
||||||
#if defined(RPI)
|
#if defined(RPI)
|
||||||
TextureId id = minecraft->textures->loadTexture("gui/pi_title.png");
|
TextureId id = minecraft->textures->loadTexture("gui/pi_title.png");
|
||||||
#else
|
#else
|
||||||
@@ -157,7 +157,7 @@ void StartMenuScreen::render( int xm, int ym, float a )
|
|||||||
minecraft->textures->bind(id);
|
minecraft->textures->bind(id);
|
||||||
|
|
||||||
const float x = (float)width / 2;
|
const float x = (float)width / 2;
|
||||||
const float y = 4;
|
const float y = height/16;
|
||||||
//const float scale = Mth::Min(
|
//const float scale = Mth::Min(
|
||||||
const float wh = Mth::Min((float)width/2.0f, (float)data->w / 2);
|
const float wh = Mth::Min((float)width/2.0f, (float)data->w / 2);
|
||||||
const float scale = 2.0f * wh / (float)data->w;
|
const float scale = 2.0f * wh / (float)data->w;
|
||||||
@@ -179,27 +179,35 @@ void StartMenuScreen::render( int xm, int ym, float a )
|
|||||||
blit(0, height - 12, 0, 0, 43, 12, 256, 72+72);
|
blit(0, height - 12, 0, 0, 43, 12, 256, 72+72);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
drawString(font, version, versionPosX, 62, /*50,*/ 0xffcccccc);//0x666666);
|
drawString(font, version, width - font->width(version) - 2, height - 10, 0xffcccccc);//0x666666);
|
||||||
drawString(font, copyright, copyrightPosX, height - 10, 0xffffff);
|
drawString(font, copyright, 2, height - 20, 0xffffff);
|
||||||
|
glEnable2(GL_BLEND);
|
||||||
|
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glColor4f2(1, 1, 1, 1);
|
||||||
|
if (Textures::isTextureIdValid(minecraft->textures->loadAndBindTexture("gui/logo/github.png")))
|
||||||
|
blit(2, height - 10, 0, 0, 8, 8, 256, 256);
|
||||||
|
{
|
||||||
|
std::string txt = "Kolyah35/minecraft-pe-0.6.1";
|
||||||
|
float wtxt = font->width(txt);
|
||||||
|
Gui::drawColoredString(font, txt, 12, height - 10, 255);
|
||||||
|
// underline link
|
||||||
|
float y0 = height - 10 + font->lineHeight - 1;
|
||||||
|
this->fill(12, (int)y0, 12 + (int)wtxt, (int)(y0 + 1), 0xffffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Screen::render(xm, ym, a);
|
Screen::render(xm, ym, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartMenuScreen::_updateLicense()
|
void StartMenuScreen::mouseClicked(int x, int y, int buttonNum) {
|
||||||
{
|
const int logoX = 2;
|
||||||
int id = minecraft->getLicenseId();
|
const int logoW = 8 + 2 + font->width("Kolyah35/minecraft-pe-0.6.1");
|
||||||
if (LicenseCodes::isReady(id))
|
const int logoY = height - 10;
|
||||||
{
|
const int logoH = 10;
|
||||||
if (LicenseCodes::isOk(id))
|
if (x >= logoX && x <= logoX + logoW && y >= logoY && y <= logoY + logoH)
|
||||||
bJoin.active = bHost.active = bOptions.active = true;
|
minecraft->platform()->openURL("https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1");
|
||||||
else
|
else
|
||||||
{
|
Screen::mouseClicked(x, y, buttonNum);
|
||||||
bool hasBuyButton = minecraft->platform()->hasBuyButtonWhenInvalidLicense();
|
|
||||||
minecraft->setScreen(new InvalidLicenseScreen(id, hasBuyButton));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bJoin.active = bHost.active = bOptions.active = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartMenuScreen::handleBackEvent( bool isDown ) {
|
bool StartMenuScreen::handleBackEvent( bool isDown ) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "../Screen.h"
|
#include "../Screen.h"
|
||||||
#include "../components/Button.h"
|
#include "../components/Button.h"
|
||||||
|
#include "../components/ImageButton.h"
|
||||||
|
|
||||||
class StartMenuScreen: public Screen
|
class StartMenuScreen: public Screen
|
||||||
{
|
{
|
||||||
@@ -17,22 +18,23 @@ public:
|
|||||||
void render(int xm, int ym, float a);
|
void render(int xm, int ym, float a);
|
||||||
|
|
||||||
void buttonClicked(Button* button);
|
void buttonClicked(Button* button);
|
||||||
|
virtual void mouseClicked(int x, int y, int buttonNum);
|
||||||
bool handleBackEvent(bool isDown);
|
bool handleBackEvent(bool isDown);
|
||||||
bool isInGameScreen();
|
bool isInGameScreen();
|
||||||
private:
|
private:
|
||||||
void _updateLicense();
|
|
||||||
|
|
||||||
Button bHost;
|
Button bHost;
|
||||||
Button bJoin;
|
Button bJoin;
|
||||||
Button bOptions;
|
Button bOptions;
|
||||||
Button bTest;
|
ImageButton bQuit; // X button in top-right corner
|
||||||
Button bBuy;
|
|
||||||
|
|
||||||
std::string copyright;
|
std::string copyright;
|
||||||
int copyrightPosX;
|
int copyrightPosX;
|
||||||
|
|
||||||
std::string version;
|
std::string version;
|
||||||
int versionPosX;
|
int versionPosX;
|
||||||
|
|
||||||
|
std::string username;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__StartMenuScreen_H__*/
|
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__StartMenuScreen_H__*/
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ void TextEditScreen::keyPressed( int eventKey ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditScreen::keyboardNewChar( char inputChar ) {
|
void TextEditScreen::charPressed( char inputChar ) {
|
||||||
std::string fullstring = sign->messages[line] + inputChar;
|
std::string fullstring = sign->messages[line] + inputChar;
|
||||||
if(fullstring.length() < 16) {
|
if(fullstring.length() < 16) {
|
||||||
sign->messages[line] = fullstring;
|
sign->messages[line] = fullstring;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user