diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 36b4d46..46d9eea 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -101,8 +101,15 @@ jobs: ${{github.workspace}}/build/MinecraftPE-server build-android: # pray to god - name: Build Android APK + name: Build Android APK (${{ matrix.abi }}) runs-on: ubuntu-latest + + strategy: + # keep going with the other ABI if one fails so you at least get something useful + fail-fast: false + matrix: + abi: [ arm64-v8a, armeabi-v7a ] + env: ANDROID_SDK_ROOT: ${{ github.workspace }}/android-sdk # ANDROID_NDK_PATH: ${{ env.ANDROID_NDK_PATH }} @@ -110,6 +117,9 @@ jobs: ANDROID_BUILD_TOOLS_VERSION: 36.0.0 ADB: /bin/true # JAVA_HOME: ${{ env.JAVA_HOME }} + # build.sh reads MATRIX_ABI to decide which ABI to build when no --abi flag is passed + MATRIX_ABI: ${{ matrix.abi }} + steps: - name: Checkout repository uses: actions/checkout@v4 @@ -166,6 +176,7 @@ jobs: echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT" echo "ANDROID_NDK_PATH=$ANDROID_NDK_PATH" echo "JAVA_HOME=$JAVA_HOME" + echo "MATRIX_ABI=$MATRIX_ABI" $ANDROID_SDK_ROOT/platform-tools/adb version || true java -version javac -version @@ -178,8 +189,9 @@ jobs: - name: Upload APK uses: actions/upload-artifact@v4 with: - name: minecraftpe-apk - path: ${{ github.workspace }}/build-apk/minecraftpe-debug.apk + # artifact name is ABI-specific so both matrix legs can upload without clobbering each other + name: minecraftpe-apk-${{ matrix.abi }} + path: ${{ github.workspace }}/build-apk/minecraftpe-*-debug.apk publish: name: Publish @@ -217,11 +229,17 @@ jobs: files: mcpe-linux/MinecraftPE-server dest: minecraftpe-server-${{ steps.ref.outputs.hash }}.zip - - name: Zip Android Artifact + - name: Zip Android arm64-v8a Artifact uses: vimtor/action-zip@v1.2 with: - files: mcpe-apk/minecraftpe-debug.apk - dest: minecraftpe-${{ steps.ref.outputs.hash }}-android.zip + files: minecraftpe-apk-arm64-v8a/minecraftpe-v8a-debug.apk + dest: minecraftpe-${{ steps.ref.outputs.hash }}-android-arm64-v8a.zip + + - name: Zip Android armeabi-v7a Artifact + uses: vimtor/action-zip@v1.2 + with: + files: minecraftpe-apk-armeabi-v7a/minecraftpe-v7a-debug.apk + dest: minecraftpe-${{ steps.ref.outputs.hash }}-android-armeabi-v7a.zip - name: Update Development Release uses: andelf/nightly-release@main @@ -236,4 +254,5 @@ jobs: ./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 \ No newline at end of file + ./minecraftpe-${{ steps.ref.outputs.hash }}-android-arm64-v8a.zip + ./minecraftpe-${{ steps.ref.outputs.hash }}-android-armeabi-v7a.zip \ No newline at end of file diff --git a/build.sh b/build.sh index c9fd016..1a8797f 100755 --- a/build.sh +++ b/build.sh @@ -5,6 +5,11 @@ # ./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) +# +# ABI targeting: +# ./build.sh --abi arm64-v8a # build for arm64 only (default) +# ./build.sh --abi armeabi-v7a # build for ARMv7 only +# ./build.sh --abi all # build for both ABIs (fat APK) # ============================================================ # lets be strict cuz we are safe like that @@ -28,6 +33,11 @@ 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:-}" +# ABI selection: can be set via --abi flag or MATRIX_ABI env var. +# Supported values: arm64-v8a, armeabi-v7a, all +# MATRIX_ABI takes precedence over the default but is overridden by --abi on the CLI. +TARGET_ABI="${MATRIX_ABI:-arm64-v8a}" + function fail() { echo "ERROR: $1" >&2 exit 1 @@ -114,10 +124,11 @@ 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" +# output files: APK names are derived after argument parsing once TARGET_ABI is final. +# see the "resolve APK output filenames" block below. +APK_UNSIGNED="" +APK_ALIGNED="" +APK_SIGNED="" DEX_OUTPUT="$BUILD_DIR/classes.dex" # flags parsed from CLI args @@ -130,12 +141,14 @@ NO_BUILD=false ######################################## function usage() { cat <] 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 + --no-cpp Skip the NDK (C++) build step + --no-java Skip the Java build step + --no-build Skip the compile steps; just package + install + --abi Target ABI: arm64-v8a (default), armeabi-v7a, or all + Can also be set via MATRIX_ABI env var for CI matrix builds. EOF exit 1 } @@ -196,6 +209,33 @@ function write_stub_file() { fi } +function build_ndk_abi() { + local abi="$1" + + # armeabi-v7a needs a few extra NDK flags to get hardware FPU support + # without APP_ABI the default would be whatever Android.mk says, so we + # always pass it explicitly so the same Android.mk works for both targets + local -a extra_flags=( "APP_ABI=$abi" ) + if [[ "$abi" == "armeabi-v7a" ]]; then + # enable hardware FPU + NEON like the old Minecraft ARMv7 builds used to + extra_flags+=( "APP_ARM_MODE=arm" "APP_ARM_NEON=true" ) + fi + + echo " ndk-build for $abi..." + if ! "$ANDROID_NDK_PATH/ndk-build" \ + NDK_PROJECT_PATH="$REPO_ROOT/project/android" \ + APP_BUILD_SCRIPT="$JNI_DIR/Android.mk" \ + "${extra_flags[@]}" \ + 2>&1 | tee "$BUILD_DIR/ndk-build-${abi}.log"; then + echo "NDK build failed for $abi. See $BUILD_DIR/ndk-build-${abi}.log" >&2 + exit 1 + fi + + ensure_dir "$BUILD_DIR/lib/$abi" + cp -v "$REPO_ROOT/project/android/libs/$abi/libminecraftpe.so" "$BUILD_DIR/lib/$abi/" + echo " .so -> $BUILD_DIR/lib/$abi/libminecraftpe.so" +} + ######################################## # argument parsing ######################################## @@ -204,6 +244,11 @@ while [[ $# -gt 0 ]]; do --no-cpp) NO_CPP=true ;; --no-java) NO_JAVA=true ;; --no-build) NO_BUILD=true ;; + --abi) + shift + [[ $# -gt 0 ]] || fail "--abi requires a value (arm64-v8a, armeabi-v7a, all)" + TARGET_ABI="$1" + ;; -h|--help) usage ;; *) echo "Unknown option: $1" >&2 @@ -213,6 +258,27 @@ while [[ $# -gt 0 ]]; do shift done +# validate the ABI value now that all args are parsed +case "$TARGET_ABI" in + arm64-v8a|armeabi-v7a|all) ;; + *) fail "Unknown ABI '$TARGET_ABI'. Supported values: arm64-v8a, armeabi-v7a, all" ;; +esac + +echo " TARGET_ABI=$TARGET_ABI" + +# resolve APK output filenames now that TARGET_ABI is final. +# arm64-v8a -> minecraftpe-v8a-debug.apk +# armeabi-v7a -> minecraftpe-v7a-debug.apk +# all -> minecraftpe-all-debug.apk (fat APK containing both ABIs) +case "$TARGET_ABI" in + arm64-v8a) APK_SUFFIX="v8a" ;; + armeabi-v7a) APK_SUFFIX="v7a" ;; + *) APK_SUFFIX="$TARGET_ABI" ;; +esac +APK_UNSIGNED="$BUILD_DIR/minecraftpe-${APK_SUFFIX}-unsigned.apk" +APK_ALIGNED="$BUILD_DIR/minecraftpe-${APK_SUFFIX}-aligned.apk" +APK_SIGNED="$BUILD_DIR/minecraftpe-${APK_SUFFIX}-debug.apk" + ######################################## # validate required tools ######################################## @@ -245,6 +311,7 @@ log_step "Bootstrap" ensure_dir "$BUILD_DIR" ensure_dir "$BUILD_DIR/lib/arm64-v8a" +ensure_dir "$BUILD_DIR/lib/armeabi-v7a" ensure_dir "$BUILD_DIR/gen" ensure_dir "$BUILD_DIR/stubs" @@ -283,7 +350,7 @@ echo " stubs OK" # ndk build ######################################## if [[ "$NO_CPP" == false && "$NO_BUILD" == false ]]; then - log_step "NDK build (arm64-v8a)" + log_step "NDK build ($TARGET_ABI)" # 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 @@ -291,18 +358,15 @@ if [[ "$NO_CPP" == false && "$NO_BUILD" == false ]]; then 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 + # build each requested ABI by delegating to build_ndk_abi() + if [[ "$TARGET_ABI" == "all" ]]; then + build_ndk_abi "arm64-v8a" + build_ndk_abi "armeabi-v7a" + else + build_ndk_abi "$TARGET_ABI" 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 ######################################## @@ -327,7 +391,7 @@ if [[ "$NO_JAVA" == false && "$NO_BUILD" == false ]]; then rm -rf "$BUILD_DIR/classes" ensure_dir "$BUILD_DIR/classes" - # Some JDK versions (<=8) don’t support --release. + # 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) @@ -351,10 +415,18 @@ 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 +# add classes.dex and native library/libraries into apk. +# when building for "all" we pack both ABIs into the same APK so Android can +# pick the right one at install time (fat APK). for a single-ABI build we +# only include the one .so that was actually compiled. pushd "$BUILD_DIR" >/dev/null zip -q "$APK_UNSIGNED" "classes.dex" -zip -q "$APK_UNSIGNED" "lib/arm64-v8a/libminecraftpe.so" +if [[ "$TARGET_ABI" == "all" ]]; then + zip -q "$APK_UNSIGNED" "lib/arm64-v8a/libminecraftpe.so" + zip -q "$APK_UNSIGNED" "lib/armeabi-v7a/libminecraftpe.so" +else + zip -q "$APK_UNSIGNED" "lib/$TARGET_ABI/libminecraftpe.so" +fi popd >/dev/null # add assets from data/ directory into the apk under assets/ @@ -380,4 +452,4 @@ log_step "Install" "$ADB" uninstall "$PACKAGE_NAME" || true "$ADB" install --no-incremental "$APK_SIGNED" -echo -e "\nDone. Enjoy MCPE 0.6.1 on your device!" +echo -e "\nDone. Enjoy MCPE 0.6.1 on your device!" \ No newline at end of file diff --git a/project/android/AndroidManifest.xml b/project/android/AndroidManifest.xml index 0dfca86..7b97a02 100755 --- a/project/android/AndroidManifest.xml +++ b/project/android/AndroidManifest.xml @@ -6,8 +6,8 @@ android:installLocation="preferExternal"> - + diff --git a/project/android/jni/Application.mk b/project/android/jni/Application.mk index 2ea6b29..b3d73ad 100755 --- a/project/android/jni/Application.mk +++ b/project/android/jni/Application.mk @@ -1,4 +1,4 @@ -APP_PLATFORM := android-21 +APP_PLATFORM := android-19 APP_STL := gnustl_static APP_OPTIM := release APP_ABI := arm64-v8a diff --git a/project/android_java/AndroidManifest.xml b/project/android_java/AndroidManifest.xml index 7127054..3859e3c 100755 --- a/project/android_java/AndroidManifest.xml +++ b/project/android_java/AndroidManifest.xml @@ -5,8 +5,8 @@ android:versionName="0.6.1-alpha-0.0.3"> + android:minSdkVersion="19" + android:targetSdkVersion="36"/> CallIntMethod(instance, fHeight); LOGI("initConsts: screenHeight=%d, done\n", _screenHeight); + + return 1; } void tick() { @@ -536,7 +538,7 @@ public: static __inline bool isSquare(int n) { int L = n & 0xf; - if ((1 << L) & 0x213 == 0) return false; + if (((1 << L) & 0x213) == 0) return false; int t = (int) sqrt((double) n) + 0.5; return t*t == n; diff --git a/src/client/OptionsFile.cpp b/src/client/OptionsFile.cpp index a227471..3bd9a4a 100755 --- a/src/client/OptionsFile.cpp +++ b/src/client/OptionsFile.cpp @@ -1,6 +1,7 @@ #include "OptionsFile.h" #include #include +#include #include OptionsFile::OptionsFile() { diff --git a/src/client/gui/Gui.cpp b/src/client/gui/Gui.cpp index 21be996..cf1ab58 100755 --- a/src/client/gui/Gui.cpp +++ b/src/client/gui/Gui.cpp @@ -430,9 +430,9 @@ void Gui::onConfigChanged( const Config& c ) { // Create outer feedback circle // #ifdef ANDROID - const float mm = 12; + const float mm = 50; //20 #else - const float mm = 12; + const float mm = 50; //20 #endif const float maxRadius = minecraft->pixelCalcUi.millimetersToPixels(mm); const float radius = Mth::Min(80.0f/2, maxRadius); diff --git a/src/client/player/LocalPlayer.cpp b/src/client/player/LocalPlayer.cpp index 5c7f65e..c048801 100755 --- a/src/client/player/LocalPlayer.cpp +++ b/src/client/player/LocalPlayer.cpp @@ -24,12 +24,14 @@ #include "../../platform/HttpClient.h" #include "../../platform/CThread.h" #include "../../util/StringUtils.h" +#include "client/Options.h" #if defined(_WIN32) #include #else #include #include +#include #endif #ifndef STANDALONE_SERVER @@ -328,12 +330,12 @@ LocalPlayer::LocalPlayer(Minecraft* minecraft, Level* level, const std::string& { this->dimension = dimension; _init(); - #ifndef STANDALONE_SERVER - printf("%s \n", name.c_str()); - if (!name.empty()) { - this->name = name; + if (minecraft->options.getStringValue(OPTIONS_USERNAME).size() != 0) { + textureName = "mob/char.png"; + + this->name = minecraft->options.getStringValue(OPTIONS_USERNAME); printf("test \n"); // Fetch user skin and cape from Mojang servers in the background (avoids blocking the main thread) // TODO: Fix this memory leak diff --git a/src/client/player/input/touchscreen/TouchscreenInput.cpp b/src/client/player/input/touchscreen/TouchscreenInput.cpp index d997f76..bf9fb46 100755 --- a/src/client/player/input/touchscreen/TouchscreenInput.cpp +++ b/src/client/player/input/touchscreen/TouchscreenInput.cpp @@ -126,8 +126,8 @@ void TouchscreenInput_TestFps::onConfigChanged(const Config& c) { // If too large (like playing on Tablet) PixelCalc& pc = _minecraft->pixelCalc; - if (pc.pixelsToMillimeters(Bw) > 14) { - Bw = Bh = pc.millimetersToPixels(14); + if (pc.pixelsToMillimeters(Bw) > 200) { //14 + Bw = Bh = pc.millimetersToPixels(200); //14 } // temp data float xx; diff --git a/src/main_android_java.cpp b/src/main_android_java.cpp index 28ed165..e6d91df 100755 --- a/src/main_android_java.cpp +++ b/src/main_android_java.cpp @@ -7,8 +7,7 @@ //#include "main_android_java.h" #include "platform/input/Multitouch.h" #include -#include -#define gettid() ((int)syscall(SYS_gettid)) +#include // Horrible, I know. / A #ifndef MAIN_CLASS @@ -145,7 +144,7 @@ Java_com_mojang_minecraftpe_GLRenderer_nativeOnSurfaceCreated(JNIEnv* env) { JNIEXPORT void JNICALL Java_com_mojang_minecraftpe_GLRenderer_nativeOnSurfaceChanged(JNIEnv* env, jclass cls, jint w, jint h) { - LOGI("@nativeOnSurfaceChanged: %p\n", pthread_self()); + LOGI("@nativeOnSurfaceChanged: %lu\n", (unsigned long)pthread_self()); if (gApp) { gApp->setSize(w, h);