Compare commits
36 Commits
78e17d8c18
...
ed9bef8492
Author | SHA1 | Date | |
---|---|---|---|
ed9bef8492 | |||
c4e26c5be2 | |||
0c82db4116 | |||
ce168c1c16 | |||
93eb7807aa | |||
12074e15d9 | |||
010aaa89e3 | |||
0e32fd36c8 | |||
6c89e64f8b | |||
9fe6a2fb39 | |||
c87a6fa3c0 | |||
69d3832815 | |||
67002006f3 | |||
eb96d80e5a | |||
968001897d | |||
68519f06fd | |||
b3b935dd1d | |||
006243d02f | |||
3c1bce876c | |||
484d3e7f90 | |||
23df63abb7 | |||
126c3d618d | |||
3937f88084 | |||
4bd2fecfa2 | |||
b539491713 | |||
ea4c5c77a1 | |||
e506dbb1bb | |||
699d83c61b | |||
329f92c0a4 | |||
bfa0567ac9 | |||
a94708a1ae | |||
905a569c09 | |||
53f602403a | |||
2f64552926 | |||
2b920f50ba | |||
d859a16b5a |
27
.gitignore
vendored
27
.gitignore
vendored
@ -1,14 +1,15 @@
|
||||
out
|
||||
debian/tmp
|
||||
.vscode
|
||||
build
|
||||
CMakeLists.txt.user
|
||||
/out
|
||||
/debian/tmp
|
||||
/.vscode
|
||||
/build*
|
||||
/CMakeLists.txt.user
|
||||
*.autosave
|
||||
AppImageBuilder.yml
|
||||
appimage-builder-cache
|
||||
appimage-build
|
||||
AppDir
|
||||
*.zsync
|
||||
*.AppImage
|
||||
core*
|
||||
qemu_*
|
||||
/AppImageBuilder.yml
|
||||
/appimage-builder-cache
|
||||
/appimage-build
|
||||
/AppDir
|
||||
/*.zsync
|
||||
/*.AppImage
|
||||
/core*
|
||||
/qemu_*
|
||||
/cmake/.prebuilt-armhf-toolchain
|
||||
|
7
.gitmodules
vendored
7
.gitmodules
vendored
@ -2,11 +2,14 @@
|
||||
path = dependencies/libpng/src
|
||||
url = https://github.com/glennrp/libpng.git
|
||||
[submodule "dependencies/zlib/src"]
|
||||
path = dependencies/zlib/src
|
||||
path = dependencies/libpng/zlib/src
|
||||
url = https://github.com/madler/zlib.git
|
||||
[submodule "dependencies/glfw/src"]
|
||||
path = dependencies/glfw/src
|
||||
path = media-layer/core/dependencies/glfw/src
|
||||
url = https://github.com/glfw/glfw.git
|
||||
[submodule "dependencies/zenity/src"]
|
||||
path = dependencies/zenity/src
|
||||
url = https://gitea.thebrokenrail.com/TheBrokenRail/zenity.git
|
||||
[submodule "launcher/dependencies/patchelf/src"]
|
||||
path = launcher/dependencies/patchelf/src
|
||||
url = https://github.com/NixOS/patchelf.git
|
||||
|
108
CMakeLists.txt
108
CMakeLists.txt
@ -1,25 +1,38 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
|
||||
# Build Mode
|
||||
set(MCPI_BUILD_MODE "native" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code")
|
||||
set_property(CACHE MCPI_BUILD_MODE PROPERTY STRINGS "arm" "native")
|
||||
if(MCPI_BUILD_MODE STREQUAL "arm")
|
||||
set(BUILD_ARM_COMPONENTS TRUE)
|
||||
set(BUILD_NATIVE_COMPONENTS FALSE)
|
||||
elseif(MCPI_BUILD_MODE STREQUAL "native")
|
||||
set(BUILD_ARM_COMPONENTS FALSE)
|
||||
set(BUILD_NATIVE_COMPONENTS TRUE)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid Mode")
|
||||
endif()
|
||||
|
||||
# Specify Options
|
||||
option(MCPI_IS_MIXED_BUILD "Whether The Architecture-Independent And ARM Code Are Different Architecture" FALSE)
|
||||
set(MCPI_BUILD_MODE "both" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code; \"both\" = Build All Code As ARM")
|
||||
set_property(CACHE MCPI_BUILD_MODE PROPERTY STRINGS "both" "arm" "native")
|
||||
option(MCPI_OPEN_SOURCE_ONLY "Only Install Open-Source Code (Will Result In Broken Install)" FALSE)
|
||||
option(MCPI_IS_APPIMAGE_BUILD "AppImage Build" FALSE)
|
||||
|
||||
# Server/Headless Builds
|
||||
option(MCPI_SERVER_MODE "Server Mode" FALSE)
|
||||
option(MCPI_HEADLESS_MODE "Headless Mode" ${MCPI_SERVER_MODE})
|
||||
# ARMHF Sysroot
|
||||
option(MCPI_BUNDLE_ARMHF_SYSROOT "Whether To Include An ARMHF Sysroot" ${MCPI_IS_MIXED_BUILD})
|
||||
set(MCPI_CUSTOM_BUNDLED_ARMHF_SYSROOT "" CACHE PATH "Custom Bundled ARMHF Sysroot")
|
||||
|
||||
# Media Layer
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
option(MCPI_USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" ${MCPI_IS_MIXED_BUILD})
|
||||
option(MCPI_USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" TRUE)
|
||||
if(MCPI_HEADLESS_MODE)
|
||||
set(DEFAULT_USE_MEDIA_LAYER_PROXY FALSE)
|
||||
else()
|
||||
set(MCPI_USE_MEDIA_LAYER_PROXY FALSE)
|
||||
set(MCPI_USE_GLES1_COMPATIBILITY_LAYER FALSE)
|
||||
set(DEFAULT_USE_MEDIA_LAYER_PROXY ${MCPI_IS_MIXED_BUILD})
|
||||
endif()
|
||||
option(MCPI_USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" ${DEFAULT_USE_MEDIA_LAYER_PROXY})
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
option(MCPI_USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" TRUE)
|
||||
endif()
|
||||
|
||||
# App ID
|
||||
set(DEFAULT_APP_ID "com.thebrokenrail.MCPIReborn")
|
||||
if(MCPI_SERVER_MODE)
|
||||
@ -28,6 +41,7 @@ else()
|
||||
string(APPEND DEFAULT_APP_ID "Client")
|
||||
endif()
|
||||
set(MCPI_APP_ID "${DEFAULT_APP_ID}" CACHE STRING "App ID")
|
||||
|
||||
# App Title
|
||||
set(DEFAULT_APP_TITLE "Minecraft: Pi Edition: Reborn")
|
||||
if(MCPI_SERVER_MODE)
|
||||
@ -37,26 +51,6 @@ else()
|
||||
endif()
|
||||
set(MCPI_APP_TITLE "${DEFAULT_APP_TITLE}" CACHE STRING "App Title")
|
||||
|
||||
# Configure Build Mode
|
||||
if(MCPI_BUILD_MODE STREQUAL "arm")
|
||||
set(USE_ARM32_TOOLCHAIN TRUE)
|
||||
set(BUILD_ARM_COMPONENTS TRUE)
|
||||
set(BUILD_NATIVE_COMPONENTS FALSE)
|
||||
elseif(MCPI_BUILD_MODE STREQUAL "native")
|
||||
set(USE_ARM32_TOOLCHAIN FALSE)
|
||||
set(BUILD_ARM_COMPONENTS FALSE)
|
||||
set(BUILD_NATIVE_COMPONENTS TRUE)
|
||||
elseif(MCPI_BUILD_MODE STREQUAL "both")
|
||||
set(USE_ARM32_TOOLCHAIN TRUE)
|
||||
set(BUILD_ARM_COMPONENTS TRUE)
|
||||
set(BUILD_NATIVE_COMPONENTS TRUE)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid Mode")
|
||||
endif()
|
||||
|
||||
# Utility Functions
|
||||
include(cmake/util.cmake)
|
||||
|
||||
# Specify Variant Name
|
||||
set(MCPI_VARIANT_NAME "minecraft-pi-reborn")
|
||||
if(MCPI_SERVER_MODE)
|
||||
@ -67,30 +61,58 @@ endif()
|
||||
|
||||
# Specify Installation Paths
|
||||
set(MCPI_INSTALL_DIR "lib/${MCPI_VARIANT_NAME}")
|
||||
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
|
||||
set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin")
|
||||
set(MCPI_LEGAL_DIR "${MCPI_INSTALL_DIR}/legal") # For Software Licenses
|
||||
set(MCPI_SDK_DIR "${MCPI_INSTALL_DIR}/sdk")
|
||||
set(MCPI_SDK_LIB_DIR "${MCPI_SDK_DIR}/lib")
|
||||
set(MCPI_SDK_INCLUDE_DIR "${MCPI_SDK_DIR}/include")
|
||||
|
||||
# Library Directory
|
||||
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
string(APPEND MCPI_LIB_DIR "/arm")
|
||||
elseif(BUILD_NATIVE_COMPONENTS)
|
||||
string(APPEND MCPI_LIB_DIR "/native")
|
||||
endif()
|
||||
|
||||
# Share Directory
|
||||
set(MCPI_SHARE_DIR "share")
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
string(PREPEND MCPI_SHARE_DIR "usr/")
|
||||
endif()
|
||||
|
||||
# Build Mode
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
endif()
|
||||
|
||||
# Prebuilt ARMHF Toolchain
|
||||
option(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN "Whether To Use A Prebuilt ARMHF Toolchain For Building ARM Components" ${MCPI_IS_MIXED_BUILD})
|
||||
if(BUILD_ARM_COMPONENTS AND MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
|
||||
include(cmake/prebuilt-armhf-toolchain.cmake)
|
||||
endif()
|
||||
|
||||
# Start Project
|
||||
project(minecraft-pi-reborn)
|
||||
|
||||
# Sanity Check
|
||||
# Utility Functions
|
||||
include(cmake/util.cmake)
|
||||
|
||||
# Sanity Checks
|
||||
if(BUILD_NATIVE_COMPONENTS AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" AND NOT MCPI_IS_MIXED_BUILD)
|
||||
message(FATAL_ERROR "Project is configured as a mixed-buld, but MCPI_IS_MIXED_BUILD is disabled.")
|
||||
endif()
|
||||
|
||||
# Require ARM Compilation
|
||||
if(USE_ARM32_TOOLCHAIN AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
|
||||
if(BUILD_ARM_COMPONENTS AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
|
||||
message(FATAL_ERROR "ARM-Targeting Compiler Required")
|
||||
endif()
|
||||
|
||||
# Specify Default Installation Prefix
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "" FORCE)
|
||||
set(DEFAULT_PREFIX "/usr")
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
set(DEFAULT_PREFIX "/")
|
||||
endif()
|
||||
set(CMAKE_INSTALL_PREFIX "${DEFAULT_PREFIX}" CACHE PATH "" FORCE)
|
||||
endif()
|
||||
|
||||
# Optimizations
|
||||
@ -116,9 +138,14 @@ add_subdirectory(dependencies)
|
||||
|
||||
# Warnings
|
||||
add_compile_options(-Wall -Wextra -Werror -Wpointer-arith -Wshadow -Wnull-dereference)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 10.0)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
# Prevents False Positives
|
||||
add_compile_options(-Wno-stringop-overflow)
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 10.0)
|
||||
add_compile_options(-Wno-stringop-overflow)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 11.0)
|
||||
add_compile_options(-Wno-array-bounds -Wno-stringop-overread)
|
||||
endif()
|
||||
endif()
|
||||
add_link_options(-Wl,--no-undefined)
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
@ -159,3 +186,8 @@ endif()
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
add_subdirectory(images)
|
||||
endif()
|
||||
|
||||
# Install SDK
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(EXPORT sdk DESTINATION "${MCPI_SDK_DIR}" EXPORT_LINK_INTERFACE_LIBRARIES)
|
||||
endif()
|
||||
|
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -22,6 +22,8 @@ pipeline {
|
||||
stage('Publish') {
|
||||
steps {
|
||||
sh 'apt-get update && apt-get install -y docker.io'
|
||||
sh 'rm -rf ./out/server-amd64'
|
||||
sh './scripts/build.sh server amd64'
|
||||
sh 'docker build --no-cache --tag thebrokenrail/minecraft-pi-reborn-server .'
|
||||
withCredentials([usernamePassword(credentialsId: 'docker_hub_login', usernameVariable: 'DOCKER_HUB_USERNAME', passwordVariable: 'DOCKER_HUB_PASSWORD')]) {
|
||||
sh 'docker login -u "${DOCKER_HUB_USERNAME}" -p "${DOCKER_HUB_PASSWORD}"'
|
||||
|
@ -1,15 +0,0 @@
|
||||
# Setup Toolchain
|
||||
macro(setup_toolchain target)
|
||||
# Use ARM Cross-Compiler
|
||||
set(CMAKE_C_COMPILER "${target}-gcc")
|
||||
set(CMAKE_CXX_COMPILER "${target}-g++")
|
||||
# Extra
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
# Custom Search Paths
|
||||
if(NOT DEFINED ENV{MCPI_TOOLCHAIN_USE_DEFAULT_SEARCH_PATHS})
|
||||
# Find Root
|
||||
set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}")
|
||||
# pkg-config
|
||||
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/${target}/pkgconfig:/usr/${target}/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig")
|
||||
endif()
|
||||
endmacro()
|
78
cmake/prebuilt-armhf-toolchain.cmake
Normal file
78
cmake/prebuilt-armhf-toolchain.cmake
Normal file
@ -0,0 +1,78 @@
|
||||
# Locations
|
||||
set(toolchain_dir "${CMAKE_CURRENT_LIST_DIR}/.prebuilt-armhf-toolchain")
|
||||
set(sysroot_dir "${CMAKE_CURRENT_BINARY_DIR}/bundled-armhf-sysroot")
|
||||
|
||||
# Force Toolchain
|
||||
set(CMAKE_C_COMPILER "${toolchain_dir}/bin/arm-none-linux-gnueabihf-gcc")
|
||||
set(CMAKE_CXX_COMPILER "${toolchain_dir}/bin/arm-none-linux-gnueabihf-g++")
|
||||
set(CMAKE_SYSTEM_NAME "Linux")
|
||||
set(CMAKE_SYSTEM_PROCESSOR "arm")
|
||||
unset(CMAKE_TOOLCHAIN_FILE CACHE)
|
||||
|
||||
# Download If Needed
|
||||
if(NOT EXISTS "${CMAKE_C_COMPILER}")
|
||||
# Pick URL
|
||||
execute_process(COMMAND uname -m OUTPUT_VARIABLE arch OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(arch STREQUAL "x86_64")
|
||||
set(toolchain_url "https://developer.arm.com/-/media/Files/downloads/gnu/11.2-2022.02/binrel/gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf.tar.xz")
|
||||
set(toolchain_sha256 "c254f7199261fe76c32ef42187502839bda7efad0a66646cf739d074eff45fad")
|
||||
elseif(arch STREQUAL "aarch64" OR arch STREQUAL "armv8b" OR arch STREQUAL "armv8l")
|
||||
set(toolchain_url "https://developer.arm.com/-/media/Files/downloads/gnu/11.2-2022.02/binrel/gcc-arm-11.2-2022.02-aarch64-arm-none-linux-gnueabihf.tar.xz")
|
||||
set(toolchain_sha256 "c5603772af016008ddacb7e475dc226d0cccdf069925dfded43e452a59774fc3")
|
||||
else()
|
||||
message(FATAL_ERROR "Unable To Download Prebuilt ARMHF Toolchain")
|
||||
endif()
|
||||
|
||||
# Download
|
||||
message(STATUS "Downloading Prebuilt ARMHF Toolchain...")
|
||||
file(REMOVE_RECURSE "${toolchain_dir}")
|
||||
include(FetchContent)
|
||||
set(FETCHCONTENT_QUIET FALSE)
|
||||
FetchContent_Declare(
|
||||
prebuilt-armhf-toolchain
|
||||
URL "${toolchain_url}"
|
||||
URL_HASH "SHA256=${toolchain_sha256}"
|
||||
SOURCE_DIR "${toolchain_dir}"
|
||||
)
|
||||
FetchContent_Populate(prebuilt-armhf-toolchain)
|
||||
|
||||
# Force Sysroot Rebuild
|
||||
file(REMOVE_RECURSE "${sysroot_dir}")
|
||||
endif()
|
||||
|
||||
# Build Sysroot
|
||||
if(NOT EXISTS "${sysroot_dir}")
|
||||
# Create Directory
|
||||
file(MAKE_DIRECTORY "${sysroot_dir}")
|
||||
|
||||
# Copy Files From Toolchain
|
||||
file(
|
||||
COPY "${toolchain_dir}/arm-none-linux-gnueabihf/libc/"
|
||||
DESTINATION "${sysroot_dir}"
|
||||
USE_SOURCE_PERMISSIONS
|
||||
FILES_MATCHING
|
||||
PATTERN "*.so*"
|
||||
)
|
||||
|
||||
# Delete Unneeded Files
|
||||
file(REMOVE_RECURSE "${sysroot_dir}/usr/lib/audit")
|
||||
file(REMOVE_RECURSE "${sysroot_dir}/usr/lib/gconv")
|
||||
|
||||
# Strip Files
|
||||
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE "${sysroot_dir}/*")
|
||||
foreach(file IN LISTS files)
|
||||
execute_process(COMMAND "${toolchain_dir}/bin/arm-none-linux-gnueabihf-strip" "${file}" RESULT_VARIABLE ret)
|
||||
# Check Result
|
||||
if(NOT ret EQUAL 0)
|
||||
# Delete Invalid Files
|
||||
file(REMOVE "${file}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Install Sysroot (Skipping Empty Directories)
|
||||
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE RELATIVE "${sysroot_dir}" "${sysroot_dir}/*")
|
||||
foreach(file IN LISTS files)
|
||||
get_filename_component(parent "${file}" DIRECTORY)
|
||||
install(PROGRAMS "${sysroot_dir}/${file}" DESTINATION "${MCPI_INSTALL_DIR}/sysroot/${parent}")
|
||||
endforeach()
|
38
cmake/toolchain/base-toolchain.cmake
Normal file
38
cmake/toolchain/base-toolchain.cmake
Normal file
@ -0,0 +1,38 @@
|
||||
# Setup Toolchain
|
||||
macro(setup_toolchain target)
|
||||
# Target Variants
|
||||
set(target_variants "${target}")
|
||||
macro(add_target_variant value)
|
||||
string(REPLACE "-linux" "-${value}-linux" target_variant "${target}")
|
||||
list(APPEND target_variants "${target_variant}")
|
||||
endmacro()
|
||||
add_target_variant(unknown)
|
||||
add_target_variant(none)
|
||||
add_target_variant(pc)
|
||||
# Find Compiler
|
||||
macro(find_compiler output name)
|
||||
set(possible_names "")
|
||||
foreach(possible_target IN LISTS target_variants)
|
||||
list(APPEND possible_names "${possible_target}-${name}")
|
||||
endforeach()
|
||||
find_program(
|
||||
"${output}"
|
||||
NAMES ${possible_names}
|
||||
NO_CACHE
|
||||
)
|
||||
if("${${output}}" STREQUAL "${output}-NOTFOUND")
|
||||
message(FATAL_ERROR "Unable To Find ${name}")
|
||||
endif()
|
||||
endmacro()
|
||||
find_compiler(CMAKE_C_COMPILER "gcc")
|
||||
find_compiler(CMAKE_CXX_COMPILER "g++")
|
||||
# Extra
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
# Custom Search Paths
|
||||
if(NOT DEFINED ENV{MCPI_TOOLCHAIN_USE_DEFAULT_SEARCH_PATHS})
|
||||
# Find Root
|
||||
set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}")
|
||||
# pkg-config
|
||||
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/${target}/pkgconfig:/usr/${target}/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig")
|
||||
endif()
|
||||
endmacro()
|
@ -1,19 +1,10 @@
|
||||
# Symlink Function
|
||||
function(install_symlink target link)
|
||||
install(CODE "\
|
||||
# Prepare\n \
|
||||
set(file \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${link}\")\n \
|
||||
\
|
||||
# Create Directory\n \
|
||||
get_filename_component(dir \"\${file}\" DIRECTORY)\n \
|
||||
file(MAKE_DIRECTORY \${dir})\n \
|
||||
\
|
||||
# Create Symlink\n \
|
||||
if(NOT EXISTS \"\${file}\")\n \
|
||||
execute_process(COMMAND \${CMAKE_COMMAND} -E create_symlink ${target} \"\${file}\")\n \
|
||||
message(\"-- Installing: \${file}\")\n \
|
||||
else()\n \
|
||||
message(\"-- Up-to-date: \${file}\")\n \
|
||||
endif() \
|
||||
")
|
||||
get_filename_component(parent "${link}" DIRECTORY)
|
||||
if(parent STREQUAL "")
|
||||
set(parent ".")
|
||||
endif()
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/symlink/${parent}")
|
||||
file(CREATE_LINK "${target}" "${CMAKE_BINARY_DIR}/symlink/${link}" SYMBOLIC)
|
||||
install(FILES "${CMAKE_BINARY_DIR}/symlink/${link}" DESTINATION "${parent}")
|
||||
endfunction()
|
||||
|
16
dependencies/CMakeLists.txt
vendored
16
dependencies/CMakeLists.txt
vendored
@ -1,22 +1,14 @@
|
||||
project(dependencies)
|
||||
|
||||
# ZLib (Needed By libpng)
|
||||
add_subdirectory(zlib)
|
||||
# LibPNG
|
||||
add_subdirectory(libpng)
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
add_subdirectory(libpng)
|
||||
endif()
|
||||
# Minecraft: Pi Edition
|
||||
if(BUILD_ARM_COMPONENTS AND NOT MCPI_OPEN_SOURCE_ONLY)
|
||||
add_subdirectory(minecraft-pi)
|
||||
endif()
|
||||
# GLFW
|
||||
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
|
||||
add_subdirectory(glfw)
|
||||
endif()
|
||||
# Zenity (Minimal Build)
|
||||
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
|
||||
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_SERVER_MODE)
|
||||
add_subdirectory(zenity)
|
||||
endif()
|
||||
# Sysroot
|
||||
if(BUILD_ARM_COMPONENTS AND MCPI_BUNDLE_ARMHF_SYSROOT)
|
||||
add_subdirectory(armhf-sysroot)
|
||||
endif()
|
||||
|
113
dependencies/armhf-sysroot/CMakeLists.txt
vendored
113
dependencies/armhf-sysroot/CMakeLists.txt
vendored
@ -1,113 +0,0 @@
|
||||
project(armhf-sysroot)
|
||||
|
||||
# Check If Using Custom Sysroot
|
||||
if(MCPI_CUSTOM_BUNDLED_ARMHF_SYSROOT)
|
||||
# Custom Sysroot
|
||||
set(SYSROOT_DIR "${MCPI_CUSTOM_BUNDLED_ARMHF_SYSROOT}")
|
||||
else()
|
||||
# Download From APT
|
||||
set(APT_PACKAGES "libc6" "libstdc++6")
|
||||
|
||||
# Copy To Binary Directory
|
||||
set(APT_DIR "${CMAKE_CURRENT_BINARY_DIR}/apt")
|
||||
file(REMOVE_RECURSE "${APT_DIR}")
|
||||
file(MAKE_DIRECTORY "${APT_DIR}")
|
||||
# Make Directories
|
||||
file(MAKE_DIRECTORY "${APT_DIR}/apt.conf.d")
|
||||
file(MAKE_DIRECTORY "${APT_DIR}/preferences.d")
|
||||
file(MAKE_DIRECTORY "${APT_DIR}/keys")
|
||||
file(MAKE_DIRECTORY "${APT_DIR}/dpkg")
|
||||
file(TOUCH "${APT_DIR}/dpkg/status")
|
||||
|
||||
# Create APT Sources
|
||||
execute_process(
|
||||
COMMAND "${CMAKE_SOURCE_DIR}/scripts/tools/get-apt-sources.sh"
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
OUTPUT_VARIABLE APT_SOURCES
|
||||
RESULT_VARIABLE APT_SOURCES_RESULT
|
||||
)
|
||||
if(NOT APT_SOURCES_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Unable To Get APT Sources For ARMHF Sysroot")
|
||||
endif()
|
||||
file(WRITE "${APT_DIR}/sources.list" "${APT_SOURCES}")
|
||||
|
||||
# Create APT Config
|
||||
string(CONCAT APT_CONFIG
|
||||
"Dir \"${APT_DIR}\";\n"
|
||||
"Dir::State \"${APT_DIR}\";\n"
|
||||
"Dir::Cache \"${APT_DIR}\";\n"
|
||||
"Dir::Etc::Main \"${APT_DIR}/apt.conf\";\n"
|
||||
"Dir::Etc::Parts \"${APT_DIR}/apt.conf.d\";\n"
|
||||
"Dir::Etc::SourceList \"${APT_DIR}/sources.list\";\n"
|
||||
"Dir::Etc::SourceListParts \"${APT_DIR}/sources.list.d\";\n"
|
||||
"Dir::Etc::PreferencesParts \"${APT_DIR}/preferences.d\";\n"
|
||||
"Dir::Etc::TrustedParts \"${APT_DIR}/keys\";\n"
|
||||
"Dir::State::status \"${APT_DIR}/dpkg/status\";\n"
|
||||
"Dir::Ignore-Files-Silently \"False\";\n"
|
||||
"APT::Install-Recommends \"False\";\n"
|
||||
"APT::Install-Suggests \"False\";\n"
|
||||
"APT::Immediate-Configure \"False\";\n"
|
||||
"APT::Architecture \"armhf\";\n"
|
||||
"APT::Architectures { \"armhf\"; }\n"
|
||||
"Acquire::Languages \"none\";\n"
|
||||
"APT::Get::AllowUnauthenticated \"True\";\n"
|
||||
"Acquire::AllowInsecureRepositories \"True\";\n"
|
||||
)
|
||||
file(WRITE "${APT_DIR}/apt.conf" "${APT_CONFIG}")
|
||||
|
||||
# Environment
|
||||
set(APT_ENV
|
||||
"${CMAKE_COMMAND}"
|
||||
-E env
|
||||
"DEBIAN_FRONTEND=noninteractive"
|
||||
"APT_CONFIG=${APT_DIR}/apt.conf"
|
||||
)
|
||||
|
||||
# Create Sysroot Directory
|
||||
set(SYSROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/sysroot")
|
||||
file(REMOVE_RECURSE "${SYSROOT_DIR}")
|
||||
file(MAKE_DIRECTORY "${SYSROOT_DIR}")
|
||||
|
||||
# Download
|
||||
add_custom_command(
|
||||
OUTPUT "${APT_DIR}/.update-stamp"
|
||||
COMMAND ${APT_ENV} apt-get update
|
||||
COMMAND "${CMAKE_COMMAND}" -E touch "${APT_DIR}/.update-stamp"
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT "${APT_DIR}/.download-stamp"
|
||||
DEPENDS "${APT_DIR}/.update-stamp"
|
||||
COMMAND ${APT_ENV} apt-get install -y --no-install-recommends --download-only ${APT_PACKAGES}
|
||||
COMMAND "${CMAKE_COMMAND}" -E touch "${APT_DIR}/.download-stamp"
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT "${APT_DIR}/.extract-stamp"
|
||||
DEPENDS "${APT_DIR}/.download-stamp"
|
||||
COMMAND ${APT_ENV} find "${APT_DIR}/archives" -maxdepth 1 -type f -name "*.deb" -exec dpkg -x {} "${SYSROOT_DIR}" ";"
|
||||
COMMAND "${CMAKE_COMMAND}" -E touch "${APT_DIR}/.extract-stamp"
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(armhf-sysroot ALL DEPENDS "${APT_DIR}/.extract-stamp")
|
||||
endif()
|
||||
|
||||
# Install
|
||||
install(
|
||||
DIRECTORY "${SYSROOT_DIR}/"
|
||||
DESTINATION "${MCPI_INSTALL_DIR}/sysroot"
|
||||
USE_SOURCE_PERMISSIONS
|
||||
REGEX "usr/lib/arm-linux-gnueabihf/gconv" EXCLUDE
|
||||
REGEX "usr/lib/arm-linux-gnueabihf/audit" EXCLUDE
|
||||
REGEX "usr/share/man" EXCLUDE
|
||||
REGEX "usr/share/doc/.*/README\..*" EXCLUDE
|
||||
REGEX "usr/share/doc/.*/changelog\..*" EXCLUDE
|
||||
REGEX "usr/share/doc/.*/NEWS\..*" EXCLUDE
|
||||
REGEX "usr/share/doc/.*/TODO\..*" EXCLUDE
|
||||
REGEX "usr/share/lintian" EXCLUDE
|
||||
REGEX "usr/share/gcc" EXCLUDE
|
||||
REGEX "usr/share/gdb" EXCLUDE
|
||||
REGEX "usr/share/locale" EXCLUDE
|
||||
REGEX "usr/share/help" EXCLUDE
|
||||
REGEX "etc" EXCLUDE
|
||||
)
|
1
dependencies/glfw/src
vendored
1
dependencies/glfw/src
vendored
@ -1 +0,0 @@
|
||||
Subproject commit da6713cd096a40a4512f468b34c189017e73f987
|
58
dependencies/libpng/CMakeLists.txt
vendored
58
dependencies/libpng/CMakeLists.txt
vendored
@ -1,5 +1,8 @@
|
||||
project(libpng)
|
||||
|
||||
# ZLib (Needed By libpng)
|
||||
add_subdirectory(zlib)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w)
|
||||
|
||||
@ -7,46 +10,35 @@ add_compile_options(-w)
|
||||
|
||||
# Options
|
||||
set(PNG_TESTS FALSE CACHE BOOL "" FORCE)
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
set(PNG_NO_STDIO FALSE CACHE BOOL "" FORCE)
|
||||
else()
|
||||
set(PNG_NO_STDIO TRUE CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
set(PNG_STATIC FALSE CACHE BOOL "" FORCE)
|
||||
set(PNG_SHARED TRUE CACHE BOOL "" FORCE)
|
||||
else()
|
||||
set(PNG_STATIC TRUE CACHE BOOL "" FORCE)
|
||||
set(PNG_SHARED FALSE CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
set(PNG_NO_STDIO FALSE CACHE BOOL "" FORCE)
|
||||
set(PNG_STATIC FALSE CACHE BOOL "" FORCE)
|
||||
set(PNG_SHARED TRUE CACHE BOOL "" FORCE)
|
||||
|
||||
# Download
|
||||
set(ZLIB_LIBRARY zlibstatic)
|
||||
set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/src" "${CMAKE_CURRENT_BINARY_DIR}/../zlib/src")
|
||||
set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/zlib/src")
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0054 OLD) # Silence Warning
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0003 NEW) # Silence Warning
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0022 NEW) # Fix Error
|
||||
set(M_LIBRARY m) # No Full Paths!
|
||||
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0054 NEW) # Re-Enable New Behavior
|
||||
if(TARGET png12)
|
||||
set_target_properties(png12 PROPERTIES LINK_OPTIONS "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libpng.vers") # Use Symbol Versioning
|
||||
set_target_properties(png12 PROPERTIES DEBUG_POSTFIX "") # Fix LibPNG Suffix In Debug Mode
|
||||
target_include_directories(png12 PUBLIC src)
|
||||
endif()
|
||||
if(TARGET png12_static)
|
||||
find_library(M_LIBRARY NAMES m REQUIRED)
|
||||
target_link_libraries(png12_static "${ZLIB_LIBRARY}" "${M_LIBRARY}")
|
||||
target_include_directories(png12_static PUBLIC src)
|
||||
else()
|
||||
add_library(png12_static ALIAS png12)
|
||||
endif()
|
||||
|
||||
# Setup Target
|
||||
set_target_properties(png12 PROPERTIES LINK_OPTIONS "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libpng.vers") # Use Symbol Versioning
|
||||
set_target_properties(png12 PROPERTIES DEBUG_POSTFIX "") # Fix LibPNG Suffix In Debug Mode
|
||||
target_include_directories(png12 PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>")
|
||||
foreach(zlib_include_dir IN ITEMS "${ZLIB_INCLUDE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/zlib/src")
|
||||
target_include_directories(png12 PUBLIC "$<BUILD_INTERFACE:${zlib_include_dir}>")
|
||||
endforeach()
|
||||
|
||||
# Ensure Build
|
||||
if(TARGET png12)
|
||||
add_custom_target(png12-build ALL DEPENDS png12)
|
||||
endif()
|
||||
if(TARGET png12_static)
|
||||
add_custom_target(png12_static-build ALL DEPENDS png12_static)
|
||||
endif()
|
||||
add_custom_target(png12-build ALL DEPENDS png12)
|
||||
# Install
|
||||
if(TARGET png12)
|
||||
install(TARGETS png12 DESTINATION "${MCPI_LIB_DIR}")
|
||||
install(TARGETS png12 DESTINATION "${MCPI_LIB_DIR}")
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS png12 zlibstatic EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
endif()
|
||||
|
||||
# License
|
||||
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/libpng")
|
||||
|
@ -6,7 +6,11 @@ add_compile_options(-w)
|
||||
## zlib
|
||||
|
||||
# Download
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0022 NEW) # Fix Error
|
||||
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||
|
||||
# Ensure Build
|
||||
add_custom_target(zlib-build ALL DEPENDS zlibstatic)
|
||||
|
||||
# License
|
||||
install(FILES src/README DESTINATION "${MCPI_LEGAL_DIR}/zlib")
|
3
dependencies/zenity/CMakeLists.txt
vendored
3
dependencies/zenity/CMakeLists.txt
vendored
@ -13,3 +13,6 @@ add_custom_target(zenity-build ALL DEPENDS zenity)
|
||||
|
||||
# Install
|
||||
install(TARGETS zenity DESTINATION "${MCPI_BIN_DIR}")
|
||||
|
||||
# License
|
||||
install(FILES src/COPYING DESTINATION "${MCPI_LEGAL_DIR}/zenity")
|
||||
|
@ -2,6 +2,11 @@
|
||||
|
||||
## Launch Sequence
|
||||
|
||||
### Common
|
||||
1. The launcher forks itself
|
||||
1. The child process continues the launch sequence.
|
||||
2. The original process monitors the child process for crashes.
|
||||
|
||||
### Client
|
||||
1. The launcher is started by the user
|
||||
1. The launcher starts several Zenity dialogs to configure MCPI-Reborn
|
||||
@ -34,12 +39,11 @@ The Media Layer handles MCPI's graphics calls and user input. It replaces MCPI's
|
||||
This sub-component re-implements a subset of SDL 1.2 calls with GLFW. It also provides a few utility functions that are used internally by MCPI-Reborn.
|
||||
|
||||
The utility functions include:
|
||||
* Taking Screenshots
|
||||
* Fullscreen
|
||||
* Audio
|
||||
* Etc
|
||||
|
||||
This is always compiled for the host system's architecture.
|
||||
This is always compiled for the host system's architecture unless the Media Layer Proxy is disabled.
|
||||
|
||||
This was created because SDL 1.2 has numerous bugs and is in-general unsupported.
|
||||
|
||||
@ -60,21 +64,13 @@ It is made of two parts:
|
||||
|
||||
While proxying all Media Layer Core API calls across UNIX pipes does hurt performance, it is better than emulating the entire graphics stack.
|
||||
|
||||
Using this in server-mode is redundant (and disallowed).
|
||||
Using this in server-mode is redundant.
|
||||
|
||||
#### Extras
|
||||
This sub-component contains code that must always be linked directly to MCPI.
|
||||
|
||||
This is always compiled for ARM.
|
||||
|
||||
#### Stubs
|
||||
This sub-component implements stubs for various redundant libraries used by MCPI to silence linker errors.
|
||||
|
||||
This is always compiled for ARM.
|
||||
|
||||
##### What To Stub And What To Patch?
|
||||
Most libraries (like ``bcm_host``) can just be replaced with stubs, because they don't need to do anything and aren't used by anything else. However, some libraries (like EGL and X11) might be used by some of MCPI-Reborn's dependencies (like GLFW) so instead of being replaced by a stub, each call is manually patched out from MCPI. A stub is still generated just in case that library isn't present on the system to silence linker errors, but it is only loaded if no other version is available.
|
||||
|
||||
#### Headers
|
||||
This sub-component includes headers for SDL, GLES, and EGL allowing easy (cross-)compilation.
|
||||
|
||||
|
@ -1,21 +1,11 @@
|
||||
# Building
|
||||
|
||||
## Build Dependencies
|
||||
* Common
|
||||
* ARM Compiler
|
||||
* Host Compiler
|
||||
* CMake
|
||||
* Host Architecture Dependencies
|
||||
* Client Mode Only
|
||||
* OpenAL
|
||||
## Dependencies
|
||||
|
||||
## Runtime Dependencies
|
||||
* Non-ARM Host Architectures
|
||||
* QEMU User-Mode
|
||||
* Host Architecture Dependencies
|
||||
* Client Mode Only
|
||||
* OpenGL ES 2.0
|
||||
* OpenAL
|
||||
### Debian/Ubuntu
|
||||
```sh
|
||||
./scripts/install-dependencies.sh
|
||||
```
|
||||
|
||||
## Instructions
|
||||
```sh
|
||||
@ -29,4 +19,4 @@
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
- ``MCPI_TOOLCHAIN_USE_DEFAULT_SEARCH_PATHS``: Use Default CMake Search Paths Rather Than Guessing
|
||||
* ``MCPI_TOOLCHAIN_USE_DEFAULT_SEARCH_PATHS``: Use Default CMake Search Paths Rather Than Guessing
|
||||
|
@ -1,5 +1,20 @@
|
||||
# Changelog
|
||||
|
||||
**2.4.0**
|
||||
* [Modding SDK](../example-mods/README.md)
|
||||
* Cache Blacklist/Whitelist
|
||||
* More Reliable AppImages
|
||||
* CMake Refactors
|
||||
* Disable Broken Touchscreen-Specific Block Outline Behavior
|
||||
* Add ``Remove Forced GUI Lag (Can Break Joining Servers)`` Feature Flag (Disabled By Default)
|
||||
* Add ``Add Buckets`` Feature Flag (Enabled By Default)
|
||||
* Add ``Classic HUD`` Feature Flag (Enabled By Default)
|
||||
* Add ``Translucent Toolbar`` Feature Flag (Enabled By Default)
|
||||
* Fix Sound Pitch/Volume/Attenuation
|
||||
* Fix Holding Left-Click When Attacking
|
||||
* Don't Force EGL (Should Fix Some NVIDIA Systems)
|
||||
* Performance Fixes
|
||||
|
||||
**2.3.13**
|
||||
* Fix Texture Bug
|
||||
|
||||
|
@ -14,6 +14,9 @@ TRUE This Flag Is On By Default
|
||||
FALSE This Flag Is Off By Default
|
||||
```
|
||||
|
||||
### ``--default`` (Client Mode Only)
|
||||
If you run MCPI-Reborn with ``--default``, it will skip the startup configuration dialogs and just use the default values.
|
||||
|
||||
### ``--only-generate`` (Server Mode Only)
|
||||
If you run MCPI-Reborn with ``--only-generate``, it will immediately exit once world generation has completed. This is mainly used for automatically testing MCPI-Reborn.
|
||||
|
||||
@ -25,18 +28,18 @@ The world used will always be re-created on start and uses a hard-coded seed.
|
||||
## Environmental Variables
|
||||
|
||||
### ``MCPI_DEBUG``
|
||||
This enables debug logging if you set it to any non-zero-length value.
|
||||
This enables debug logging if it is set.
|
||||
|
||||
### Client Mode Only
|
||||
If a value isn't set for any of the following variables, a GUI will open that allows you to select one.
|
||||
If any of the following variables aren't set, one configuration dialog will open on startup for each unset variable.
|
||||
|
||||
### ``MCPI_FEATURE_FLAGS``
|
||||
#### ``MCPI_FEATURE_FLAGS``
|
||||
This corresponds to ``--print-available-feature-flags``. This is just a list of all enabled feature flags separated by ``|``.
|
||||
|
||||
For instance, the string ``Feature A|Feature B`` would enable both ``Feature A`` and ``Feature B`` and *disable every other available feature flag*.
|
||||
|
||||
### ``MCPI_RENDER_DISTANCE``
|
||||
#### ``MCPI_RENDER_DISTANCE``
|
||||
This is the render distance. The possible values are: ``Far``, ``Normal``, ``Short``, and ``Tiny``.
|
||||
|
||||
### ``MCPI_USERNAME``
|
||||
#### ``MCPI_USERNAME``
|
||||
This is the username.
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Dedicated Server
|
||||
The dedicated server is a version of Minecraft: Pi Edition modified to run in a headless environment. It loads settings from a ``server.properties`` file.
|
||||
|
||||
This server is also compatible with MCPE Alpha v0.6.1.
|
||||
This server is also compatible with MCPE Alpha v0.6.1[^1].
|
||||
|
||||
## Setup
|
||||
|
||||
@ -15,3 +15,5 @@ An official Docker image is also provided: [thebrokenrail/minecraft-pi-reborn-se
|
||||
* Player data is not saved because of limitations with MCPE LAN worlds
|
||||
* An easy workaround is to place your inventory in a chest before logging off
|
||||
* Survival Mode servers are incompatible with unmodded MCPI
|
||||
|
||||
[^1]: The exception to this is buckets, those will crash MCPE players.
|
||||
|
@ -1,21 +1,27 @@
|
||||
# Installation
|
||||
|
||||
## AppImage
|
||||
Download packages [here](https://jenkins.thebrokenrail.com/job/minecraft-pi-reborn/job/master/lastSuccessfulBuild/artifact/out/).
|
||||
|
||||
## Picking A Package
|
||||
### System Requirements
|
||||
* Debian Buster/Ubuntu 18.04 Or Higher
|
||||
* QEMU User-Mode
|
||||
* Debian/Ubuntu: ``sudo apt install qemu-user``
|
||||
* Arch: ``sudo pacman -Sy qemu-user``
|
||||
* Client-Only Dependencies
|
||||
* Graphics Drivers
|
||||
* GTK+ 3
|
||||
* Debian/Ubuntu: ``sudo apt install libgtk-3-0``
|
||||
* Arch: ``sudo pacman -Sy gtk3``
|
||||
* OpenAL
|
||||
* Debian/Ubuntu: ``sudo apt install libopenal1``
|
||||
* Arch: ``sudo pacman -Sy openal``
|
||||
|
||||
### Name Format
|
||||
```
|
||||
minecraft-pi-reborn-<Variant>_X.Y.Z_<Architecture>
|
||||
```
|
||||
|
||||
### Picking A Variant
|
||||
* ``client``: Client mode, use this if you want to play MCPI.
|
||||
* ``server``: Server mode, use this if you want to host a dedicated MCPI server.
|
||||
|
||||
### Picking An Architecture
|
||||
* ``amd64``: x86_64, use this if you are using a device with an AMD or Intel processor.
|
||||
* ``armhf``: ARM 32-Bit, use this if you are using an ARM device (like a Raspberry Pi).
|
||||
* ``arm64``: ARM 64-Bit, ``armhf`` but for 64-bit devices.
|
||||
|
||||
## Running
|
||||
### Running
|
||||
Follow [these](https://docs.appimage.org/introduction/quickstart.html#how-to-run-an-appimage) instructions.
|
||||
|
||||
## Flatpak
|
||||
<a href="https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn"><img width="240" alt="Download On Flathub" src="https://flathub.org/assets/badges/flathub-badge-en.svg" /></a>
|
||||
|
||||
### Note
|
||||
Game data is stored in ``~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi`` instead of ``~/.minecraft-pi``.
|
||||
|
19
example-mods/README.md
Normal file
19
example-mods/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Example Mods
|
||||
This is an example of a mod that cane be built using the modding SDK.
|
||||
|
||||
* **Expanded Creative Mod**: This specific mod adds even more items and blocks to the Creative Inventory. It was originally by [@Bigjango13](https://github.com/bigjango13).
|
||||
* **Chat Commands Mod**: This specific mod makes an chat message starting with a ``/`` handled by the MCPI API.
|
||||
* **Recipes Mod**: This specific mod demos custom recipes.
|
||||
|
||||
## The SDK
|
||||
The modding SDK is a collection of exported CMake targets that allows anyone to create their own MCPI mod!
|
||||
|
||||
The SDK is copied to ``~/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cmake`` whenever MCPI-Reborn is started.
|
||||
|
||||
## How do I use this?
|
||||
```sh
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cp libexpanded-creative.so ~/.minecraft-pi/mods
|
||||
```
|
15
example-mods/chat-commands/.gitignore
vendored
Normal file
15
example-mods/chat-commands/.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/out
|
||||
/debian/tmp
|
||||
/.vscode
|
||||
/build*
|
||||
/CMakeLists.txt.user
|
||||
*.autosave
|
||||
/AppImageBuilder.yml
|
||||
/appimage-builder-cache
|
||||
/appimage-build
|
||||
/AppDir
|
||||
/*.zsync
|
||||
/*.AppImage
|
||||
/core*
|
||||
/qemu_*
|
||||
/cmake/.prebuilt-armhf-toolchain
|
15
example-mods/chat-commands/CMakeLists.txt
Normal file
15
example-mods/chat-commands/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
|
||||
# Build For ARM
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
||||
|
||||
# Start Project
|
||||
project(chat-commands)
|
||||
|
||||
# Include SDK
|
||||
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cmake")
|
||||
|
||||
# Build
|
||||
add_library(chat-commands SHARED chat-commands.cpp)
|
||||
target_link_libraries(chat-commands mods-headers reborn-patch symbols chat misc)
|
25
example-mods/chat-commands/chat-commands.cpp
Normal file
25
example-mods/chat-commands/chat-commands.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Headers
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
#include <mods/chat/chat.h>
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
// The Actual Mod
|
||||
HOOK(chat_handle_packet_send, void, (unsigned char *minecraft, unsigned char *packet)) {
|
||||
// Get Message
|
||||
char *message = *(char **) (packet + ChatPacket_message_property_offset);
|
||||
if (message[0] == '/') {
|
||||
// API Command
|
||||
unsigned char *gui = minecraft + Minecraft_gui_property_offset;
|
||||
std::string out = chat_send_api_command(minecraft, &message[1]);
|
||||
if (out.length() > 0 && out[out.length() - 1] == '\n') {
|
||||
out[out.length() - 1] = '\0';
|
||||
}
|
||||
misc_add_message(gui, out.c_str());
|
||||
} else {
|
||||
// Call Original Method
|
||||
ensure_chat_handle_packet_send();
|
||||
(*real_chat_handle_packet_send)(minecraft, packet);
|
||||
}
|
||||
}
|
15
example-mods/expanded-creative/.gitignore
vendored
Normal file
15
example-mods/expanded-creative/.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/out
|
||||
/debian/tmp
|
||||
/.vscode
|
||||
/build*
|
||||
/CMakeLists.txt.user
|
||||
*.autosave
|
||||
/AppImageBuilder.yml
|
||||
/appimage-builder-cache
|
||||
/appimage-build
|
||||
/AppDir
|
||||
/*.zsync
|
||||
/*.AppImage
|
||||
/core*
|
||||
/qemu_*
|
||||
/cmake/.prebuilt-armhf-toolchain
|
15
example-mods/expanded-creative/CMakeLists.txt
Normal file
15
example-mods/expanded-creative/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
|
||||
# Build For ARM
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
||||
|
||||
# Start Project
|
||||
project(expanded-creative)
|
||||
|
||||
# Include SDK
|
||||
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cmake")
|
||||
|
||||
# Build
|
||||
add_library(expanded-creative SHARED expanded-creative.cpp)
|
||||
target_link_libraries(expanded-creative mods-headers reborn-patch symbols misc)
|
638
example-mods/expanded-creative/expanded-creative.cpp
Normal file
638
example-mods/expanded-creative/expanded-creative.cpp
Normal file
@ -0,0 +1,638 @@
|
||||
// Headers
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
// The Actual Mod
|
||||
|
||||
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(unsigned char *filling_container) {
|
||||
ItemInstance *fire_instance = new ItemInstance;
|
||||
ALLOC_CHECK(fire_instance);
|
||||
fire_instance->count = 255;
|
||||
fire_instance->auxiliary = 0;
|
||||
fire_instance->id = 51;
|
||||
(*FillingContainer_addItem)(filling_container, fire_instance);
|
||||
|
||||
ItemInstance *mushroomStew_instance = new ItemInstance;
|
||||
ALLOC_CHECK(mushroomStew_instance);
|
||||
mushroomStew_instance->count = 255;
|
||||
mushroomStew_instance->auxiliary = 0;
|
||||
mushroomStew_instance->id = 282;
|
||||
(*FillingContainer_addItem)(filling_container, mushroomStew_instance);
|
||||
|
||||
ItemInstance *steak_instance = new ItemInstance;
|
||||
ALLOC_CHECK(steak_instance);
|
||||
steak_instance->count = 255;
|
||||
steak_instance->auxiliary = 0;
|
||||
steak_instance->id = 364;
|
||||
(*FillingContainer_addItem)(filling_container, steak_instance);
|
||||
|
||||
ItemInstance *cookedChicken_instance = new ItemInstance;
|
||||
ALLOC_CHECK(cookedChicken_instance);
|
||||
cookedChicken_instance->count = 255;
|
||||
cookedChicken_instance->auxiliary = 0;
|
||||
cookedChicken_instance->id = 366;
|
||||
(*FillingContainer_addItem)(filling_container, cookedChicken_instance);
|
||||
|
||||
ItemInstance *porkCooked_instance = new ItemInstance;
|
||||
ALLOC_CHECK(porkCooked_instance);
|
||||
porkCooked_instance->count = 255;
|
||||
porkCooked_instance->auxiliary = 0;
|
||||
porkCooked_instance->id = 320;
|
||||
(*FillingContainer_addItem)(filling_container, porkCooked_instance);
|
||||
|
||||
ItemInstance *apple_instance = new ItemInstance;
|
||||
ALLOC_CHECK(apple_instance);
|
||||
apple_instance->count = 255;
|
||||
apple_instance->auxiliary = 0;
|
||||
apple_instance->id = 260;
|
||||
(*FillingContainer_addItem)(filling_container, apple_instance);
|
||||
|
||||
ItemInstance *tallGrass_instance = new ItemInstance;
|
||||
ALLOC_CHECK(tallGrass_instance);
|
||||
tallGrass_instance->count = 255;
|
||||
tallGrass_instance->auxiliary = 0;
|
||||
tallGrass_instance->id = 31;
|
||||
(*FillingContainer_addItem)(filling_container, tallGrass_instance);
|
||||
|
||||
ItemInstance *crops_instance = new ItemInstance;
|
||||
ALLOC_CHECK(crops_instance);
|
||||
crops_instance->count = 255;
|
||||
crops_instance->auxiliary = 0;
|
||||
crops_instance->id = 59;
|
||||
(*FillingContainer_addItem)(filling_container, crops_instance);
|
||||
|
||||
ItemInstance *farmland_instance = new ItemInstance;
|
||||
ALLOC_CHECK(farmland_instance);
|
||||
farmland_instance->count = 255;
|
||||
farmland_instance->auxiliary = 0;
|
||||
farmland_instance->id = 60;
|
||||
(*FillingContainer_addItem)(filling_container, farmland_instance);
|
||||
|
||||
ItemInstance *activeFurnace_instance = new ItemInstance;
|
||||
ALLOC_CHECK(activeFurnace_instance);
|
||||
activeFurnace_instance->count = 255;
|
||||
activeFurnace_instance->auxiliary = 0;
|
||||
activeFurnace_instance->id = 62;
|
||||
(*FillingContainer_addItem)(filling_container, activeFurnace_instance);
|
||||
|
||||
ItemInstance *ironDoor_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironDoor_instance);
|
||||
ironDoor_instance->count = 255;
|
||||
ironDoor_instance->auxiliary = 0;
|
||||
ironDoor_instance->id = 330;
|
||||
(*FillingContainer_addItem)(filling_container, ironDoor_instance);
|
||||
|
||||
ItemInstance *activeRedstoneOre_instance = new ItemInstance;
|
||||
ALLOC_CHECK(activeRedstoneOre_instance);
|
||||
activeRedstoneOre_instance->count = 255;
|
||||
activeRedstoneOre_instance->auxiliary = 0;
|
||||
activeRedstoneOre_instance->id = 74;
|
||||
(*FillingContainer_addItem)(filling_container, activeRedstoneOre_instance);
|
||||
|
||||
ItemInstance *pumkinStem_instance = new ItemInstance;
|
||||
ALLOC_CHECK(pumkinStem_instance);
|
||||
pumkinStem_instance->count = 255;
|
||||
pumkinStem_instance->auxiliary = 0;
|
||||
pumkinStem_instance->id = 105;
|
||||
(*FillingContainer_addItem)(filling_container, pumkinStem_instance);
|
||||
|
||||
ItemInstance *newGrass_instance = new ItemInstance;
|
||||
ALLOC_CHECK(newGrass_instance);
|
||||
newGrass_instance->count = 255;
|
||||
newGrass_instance->auxiliary = 0;
|
||||
newGrass_instance->id = 253;
|
||||
(*FillingContainer_addItem)(filling_container, newGrass_instance);
|
||||
|
||||
ItemInstance *reserved6_instance = new ItemInstance;
|
||||
ALLOC_CHECK(reserved6_instance);
|
||||
reserved6_instance->count = 255;
|
||||
reserved6_instance->auxiliary = 0;
|
||||
reserved6_instance->id = 1;
|
||||
(*FillingContainer_addItem)(filling_container, reserved6_instance);
|
||||
|
||||
ItemInstance *doubleStoneSlab_instance = new ItemInstance;
|
||||
ALLOC_CHECK(doubleStoneSlab_instance);
|
||||
doubleStoneSlab_instance->count = 255;
|
||||
doubleStoneSlab_instance->auxiliary = 0;
|
||||
doubleStoneSlab_instance->id = 43;
|
||||
(*FillingContainer_addItem)(filling_container, doubleStoneSlab_instance);
|
||||
|
||||
ItemInstance *arrow_instance = new ItemInstance;
|
||||
ALLOC_CHECK(arrow_instance);
|
||||
arrow_instance->count = 255;
|
||||
arrow_instance->auxiliary = 0;
|
||||
arrow_instance->id = 262;
|
||||
(*FillingContainer_addItem)(filling_container, arrow_instance);
|
||||
|
||||
ItemInstance *coal_instance = new ItemInstance;
|
||||
ALLOC_CHECK(coal_instance);
|
||||
coal_instance->count = 255;
|
||||
coal_instance->auxiliary = 0;
|
||||
coal_instance->id = 263;
|
||||
(*FillingContainer_addItem)(filling_container, coal_instance);
|
||||
|
||||
ItemInstance *diamond_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamond_instance);
|
||||
diamond_instance->count = 255;
|
||||
diamond_instance->auxiliary = 0;
|
||||
diamond_instance->id = 264;
|
||||
(*FillingContainer_addItem)(filling_container, diamond_instance);
|
||||
|
||||
ItemInstance *ironIngot_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironIngot_instance);
|
||||
ironIngot_instance->count = 255;
|
||||
ironIngot_instance->auxiliary = 0;
|
||||
ironIngot_instance->id = 265;
|
||||
(*FillingContainer_addItem)(filling_container, ironIngot_instance);
|
||||
|
||||
ItemInstance *goldIngot_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldIngot_instance);
|
||||
goldIngot_instance->count = 255;
|
||||
goldIngot_instance->auxiliary = 0;
|
||||
goldIngot_instance->id = 266;
|
||||
(*FillingContainer_addItem)(filling_container, goldIngot_instance);
|
||||
|
||||
ItemInstance *woodSword_instance = new ItemInstance;
|
||||
ALLOC_CHECK(woodSword_instance);
|
||||
woodSword_instance->count = 255;
|
||||
woodSword_instance->auxiliary = 0;
|
||||
woodSword_instance->id = 268;
|
||||
(*FillingContainer_addItem)(filling_container, woodSword_instance);
|
||||
|
||||
ItemInstance *woodShovel_instance = new ItemInstance;
|
||||
ALLOC_CHECK(woodShovel_instance);
|
||||
woodShovel_instance->count = 255;
|
||||
woodShovel_instance->auxiliary = 0;
|
||||
woodShovel_instance->id = 269;
|
||||
(*FillingContainer_addItem)(filling_container, woodShovel_instance);
|
||||
|
||||
ItemInstance *woodPickaxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(woodPickaxe_instance);
|
||||
woodPickaxe_instance->count = 255;
|
||||
woodPickaxe_instance->auxiliary = 0;
|
||||
woodPickaxe_instance->id = 270;
|
||||
(*FillingContainer_addItem)(filling_container, woodPickaxe_instance);
|
||||
|
||||
ItemInstance *woodAxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(woodAxe_instance);
|
||||
woodAxe_instance->count = 255;
|
||||
woodAxe_instance->auxiliary = 0;
|
||||
woodAxe_instance->id = 271;
|
||||
(*FillingContainer_addItem)(filling_container, woodAxe_instance);
|
||||
|
||||
ItemInstance *stoneSword_instance = new ItemInstance;
|
||||
ALLOC_CHECK(stoneSword_instance);
|
||||
stoneSword_instance->count = 255;
|
||||
stoneSword_instance->auxiliary = 0;
|
||||
stoneSword_instance->id = 272;
|
||||
(*FillingContainer_addItem)(filling_container, stoneSword_instance);
|
||||
|
||||
ItemInstance *stoneShovel_instance = new ItemInstance;
|
||||
ALLOC_CHECK(stoneShovel_instance);
|
||||
stoneShovel_instance->count = 255;
|
||||
stoneShovel_instance->auxiliary = 0;
|
||||
stoneShovel_instance->id = 273;
|
||||
(*FillingContainer_addItem)(filling_container, stoneShovel_instance);
|
||||
|
||||
ItemInstance *stonePickaxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(stonePickaxe_instance);
|
||||
stonePickaxe_instance->count = 255;
|
||||
stonePickaxe_instance->auxiliary = 0;
|
||||
stonePickaxe_instance->id = 274;
|
||||
(*FillingContainer_addItem)(filling_container, stonePickaxe_instance);
|
||||
|
||||
ItemInstance *stoneAxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(stoneAxe_instance);
|
||||
stoneAxe_instance->count = 255;
|
||||
stoneAxe_instance->auxiliary = 0;
|
||||
stoneAxe_instance->id = 275;
|
||||
(*FillingContainer_addItem)(filling_container, stoneAxe_instance);
|
||||
|
||||
ItemInstance *shovelIron_instance = new ItemInstance;
|
||||
ALLOC_CHECK(shovelIron_instance);
|
||||
shovelIron_instance->count = 255;
|
||||
shovelIron_instance->auxiliary = 0;
|
||||
shovelIron_instance->id = 256;
|
||||
(*FillingContainer_addItem)(filling_container, shovelIron_instance);
|
||||
|
||||
ItemInstance *ironPick_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironPick_instance);
|
||||
ironPick_instance->count = 255;
|
||||
ironPick_instance->auxiliary = 0;
|
||||
ironPick_instance->id = 257;
|
||||
(*FillingContainer_addItem)(filling_container, ironPick_instance);
|
||||
|
||||
ItemInstance *ironAxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironAxe_instance);
|
||||
ironAxe_instance->count = 255;
|
||||
ironAxe_instance->auxiliary = 0;
|
||||
ironAxe_instance->id = 258;
|
||||
(*FillingContainer_addItem)(filling_container, ironAxe_instance);
|
||||
|
||||
ItemInstance *diamondSword_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondSword_instance);
|
||||
diamondSword_instance->count = 255;
|
||||
diamondSword_instance->auxiliary = 0;
|
||||
diamondSword_instance->id = 276;
|
||||
(*FillingContainer_addItem)(filling_container, diamondSword_instance);
|
||||
|
||||
ItemInstance *diamondShovel_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondShovel_instance);
|
||||
diamondShovel_instance->count = 255;
|
||||
diamondShovel_instance->auxiliary = 0;
|
||||
diamondShovel_instance->id = 277;
|
||||
(*FillingContainer_addItem)(filling_container, diamondShovel_instance);
|
||||
|
||||
ItemInstance *diamondPickaxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondPickaxe_instance);
|
||||
diamondPickaxe_instance->count = 255;
|
||||
diamondPickaxe_instance->auxiliary = 0;
|
||||
diamondPickaxe_instance->id = 278;
|
||||
(*FillingContainer_addItem)(filling_container, diamondPickaxe_instance);
|
||||
|
||||
ItemInstance *diamondAxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondAxe_instance);
|
||||
diamondAxe_instance->count = 255;
|
||||
diamondAxe_instance->auxiliary = 0;
|
||||
diamondAxe_instance->id = 279;
|
||||
(*FillingContainer_addItem)(filling_container, diamondAxe_instance);
|
||||
|
||||
ItemInstance *magicWand_instance = new ItemInstance;
|
||||
ALLOC_CHECK(magicWand_instance);
|
||||
magicWand_instance->count = 255;
|
||||
magicWand_instance->auxiliary = 0;
|
||||
magicWand_instance->id = 280;
|
||||
(*FillingContainer_addItem)(filling_container, magicWand_instance);
|
||||
|
||||
ItemInstance *bowl_instance = new ItemInstance;
|
||||
ALLOC_CHECK(bowl_instance);
|
||||
bowl_instance->count = 255;
|
||||
bowl_instance->auxiliary = 0;
|
||||
bowl_instance->id = 281;
|
||||
(*FillingContainer_addItem)(filling_container, bowl_instance);
|
||||
|
||||
ItemInstance *goldSword_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldSword_instance);
|
||||
goldSword_instance->count = 255;
|
||||
goldSword_instance->auxiliary = 0;
|
||||
goldSword_instance->id = 283;
|
||||
(*FillingContainer_addItem)(filling_container, goldSword_instance);
|
||||
|
||||
ItemInstance *goldShovel_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldShovel_instance);
|
||||
goldShovel_instance->count = 255;
|
||||
goldShovel_instance->auxiliary = 0;
|
||||
goldShovel_instance->id = 284;
|
||||
(*FillingContainer_addItem)(filling_container, goldShovel_instance);
|
||||
|
||||
ItemInstance *goldPickaxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldPickaxe_instance);
|
||||
goldPickaxe_instance->count = 255;
|
||||
goldPickaxe_instance->auxiliary = 0;
|
||||
goldPickaxe_instance->id = 285;
|
||||
(*FillingContainer_addItem)(filling_container, goldPickaxe_instance);
|
||||
|
||||
ItemInstance *goldAxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldAxe_instance);
|
||||
goldAxe_instance->count = 255;
|
||||
goldAxe_instance->auxiliary = 0;
|
||||
goldAxe_instance->id = 286;
|
||||
(*FillingContainer_addItem)(filling_container, goldAxe_instance);
|
||||
|
||||
ItemInstance *string_instance = new ItemInstance;
|
||||
ALLOC_CHECK(string_instance);
|
||||
string_instance->count = 255;
|
||||
string_instance->auxiliary = 0;
|
||||
string_instance->id = 287;
|
||||
(*FillingContainer_addItem)(filling_container, string_instance);
|
||||
|
||||
ItemInstance *feather_instance = new ItemInstance;
|
||||
ALLOC_CHECK(feather_instance);
|
||||
feather_instance->count = 255;
|
||||
feather_instance->auxiliary = 0;
|
||||
feather_instance->id = 288;
|
||||
(*FillingContainer_addItem)(filling_container, feather_instance);
|
||||
|
||||
ItemInstance *gunpowder_instance = new ItemInstance;
|
||||
ALLOC_CHECK(gunpowder_instance);
|
||||
gunpowder_instance->count = 255;
|
||||
gunpowder_instance->auxiliary = 0;
|
||||
gunpowder_instance->id = 289;
|
||||
(*FillingContainer_addItem)(filling_container, gunpowder_instance);
|
||||
|
||||
ItemInstance *woodHoe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(woodHoe_instance);
|
||||
woodHoe_instance->count = 255;
|
||||
woodHoe_instance->auxiliary = 0;
|
||||
woodHoe_instance->id = 290;
|
||||
(*FillingContainer_addItem)(filling_container, woodHoe_instance);
|
||||
|
||||
ItemInstance *stoneHoe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(stoneHoe_instance);
|
||||
stoneHoe_instance->count = 255;
|
||||
stoneHoe_instance->auxiliary = 0;
|
||||
stoneHoe_instance->id = 291;
|
||||
(*FillingContainer_addItem)(filling_container, stoneHoe_instance);
|
||||
|
||||
ItemInstance *flint1_instance = new ItemInstance;
|
||||
ALLOC_CHECK(flint1_instance);
|
||||
flint1_instance->count = 255;
|
||||
flint1_instance->auxiliary = 0;
|
||||
flint1_instance->id = 292;
|
||||
(*FillingContainer_addItem)(filling_container, flint1_instance);
|
||||
|
||||
ItemInstance *diamondHoe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondHoe_instance);
|
||||
diamondHoe_instance->count = 255;
|
||||
diamondHoe_instance->auxiliary = 0;
|
||||
diamondHoe_instance->id = 293;
|
||||
(*FillingContainer_addItem)(filling_container, diamondHoe_instance);
|
||||
|
||||
ItemInstance *goldHoe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldHoe_instance);
|
||||
goldHoe_instance->count = 255;
|
||||
goldHoe_instance->auxiliary = 0;
|
||||
goldHoe_instance->id = 294;
|
||||
(*FillingContainer_addItem)(filling_container, goldHoe_instance);
|
||||
|
||||
ItemInstance *seeds_instance = new ItemInstance;
|
||||
ALLOC_CHECK(seeds_instance);
|
||||
seeds_instance->count = 255;
|
||||
seeds_instance->auxiliary = 0;
|
||||
seeds_instance->id = 295;
|
||||
(*FillingContainer_addItem)(filling_container, seeds_instance);
|
||||
|
||||
ItemInstance *wheat_instance = new ItemInstance;
|
||||
ALLOC_CHECK(wheat_instance);
|
||||
wheat_instance->count = 255;
|
||||
wheat_instance->auxiliary = 0;
|
||||
wheat_instance->id = 296;
|
||||
(*FillingContainer_addItem)(filling_container, wheat_instance);
|
||||
|
||||
ItemInstance *bread_instance = new ItemInstance;
|
||||
ALLOC_CHECK(bread_instance);
|
||||
bread_instance->count = 255;
|
||||
bread_instance->auxiliary = 0;
|
||||
bread_instance->id = 297;
|
||||
(*FillingContainer_addItem)(filling_container, bread_instance);
|
||||
|
||||
ItemInstance *diamondHelm_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondHelm_instance);
|
||||
diamondHelm_instance->count = 255;
|
||||
diamondHelm_instance->auxiliary = 0;
|
||||
diamondHelm_instance->id = 310;
|
||||
(*FillingContainer_addItem)(filling_container, diamondHelm_instance);
|
||||
|
||||
ItemInstance *diamondChest_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondChest_instance);
|
||||
diamondChest_instance->count = 255;
|
||||
diamondChest_instance->auxiliary = 0;
|
||||
diamondChest_instance->id = 311;
|
||||
(*FillingContainer_addItem)(filling_container, diamondChest_instance);
|
||||
|
||||
ItemInstance *diamondLeg_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondLeg_instance);
|
||||
diamondLeg_instance->count = 255;
|
||||
diamondLeg_instance->auxiliary = 0;
|
||||
diamondLeg_instance->id = 312;
|
||||
(*FillingContainer_addItem)(filling_container, diamondLeg_instance);
|
||||
|
||||
ItemInstance *diamondBoot_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondBoot_instance);
|
||||
diamondBoot_instance->count = 255;
|
||||
diamondBoot_instance->auxiliary = 0;
|
||||
diamondBoot_instance->id = 313;
|
||||
(*FillingContainer_addItem)(filling_container, diamondBoot_instance);
|
||||
|
||||
ItemInstance *leatherCap_instance = new ItemInstance;
|
||||
ALLOC_CHECK(leatherCap_instance);
|
||||
leatherCap_instance->count = 255;
|
||||
leatherCap_instance->auxiliary = 0;
|
||||
leatherCap_instance->id = 298;
|
||||
(*FillingContainer_addItem)(filling_container, leatherCap_instance);
|
||||
|
||||
ItemInstance *leatherShirt_instance = new ItemInstance;
|
||||
ALLOC_CHECK(leatherShirt_instance);
|
||||
leatherShirt_instance->count = 255;
|
||||
leatherShirt_instance->auxiliary = 0;
|
||||
leatherShirt_instance->id = 299;
|
||||
(*FillingContainer_addItem)(filling_container, leatherShirt_instance);
|
||||
|
||||
ItemInstance *leatherPants_instance = new ItemInstance;
|
||||
ALLOC_CHECK(leatherPants_instance);
|
||||
leatherPants_instance->count = 255;
|
||||
leatherPants_instance->auxiliary = 0;
|
||||
leatherPants_instance->id = 300;
|
||||
(*FillingContainer_addItem)(filling_container, leatherPants_instance);
|
||||
|
||||
ItemInstance *leatherBoots_instance = new ItemInstance;
|
||||
ALLOC_CHECK(leatherBoots_instance);
|
||||
leatherBoots_instance->count = 255;
|
||||
leatherBoots_instance->auxiliary = 0;
|
||||
leatherBoots_instance->id = 301;
|
||||
(*FillingContainer_addItem)(filling_container, leatherBoots_instance);
|
||||
|
||||
ItemInstance *chainHelm_instance = new ItemInstance;
|
||||
ALLOC_CHECK(chainHelm_instance);
|
||||
chainHelm_instance->count = 255;
|
||||
chainHelm_instance->auxiliary = 0;
|
||||
chainHelm_instance->id = 302;
|
||||
(*FillingContainer_addItem)(filling_container, chainHelm_instance);
|
||||
|
||||
ItemInstance *chainShirt_instance = new ItemInstance;
|
||||
ALLOC_CHECK(chainShirt_instance);
|
||||
chainShirt_instance->count = 255;
|
||||
chainShirt_instance->auxiliary = 0;
|
||||
chainShirt_instance->id = 303;
|
||||
(*FillingContainer_addItem)(filling_container, chainShirt_instance);
|
||||
|
||||
ItemInstance *chainLegs_instance = new ItemInstance;
|
||||
ALLOC_CHECK(chainLegs_instance);
|
||||
chainLegs_instance->count = 255;
|
||||
chainLegs_instance->auxiliary = 0;
|
||||
chainLegs_instance->id = 304;
|
||||
(*FillingContainer_addItem)(filling_container, chainLegs_instance);
|
||||
|
||||
ItemInstance *chainBoots_instance = new ItemInstance;
|
||||
ALLOC_CHECK(chainBoots_instance);
|
||||
chainBoots_instance->count = 255;
|
||||
chainBoots_instance->auxiliary = 0;
|
||||
chainBoots_instance->id = 305;
|
||||
(*FillingContainer_addItem)(filling_container, chainBoots_instance);
|
||||
|
||||
ItemInstance *goldHelm_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldHelm_instance);
|
||||
goldHelm_instance->count = 255;
|
||||
goldHelm_instance->auxiliary = 0;
|
||||
goldHelm_instance->id = 314;
|
||||
(*FillingContainer_addItem)(filling_container, goldHelm_instance);
|
||||
|
||||
ItemInstance *goldChest_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldChest_instance);
|
||||
goldChest_instance->count = 255;
|
||||
goldChest_instance->auxiliary = 0;
|
||||
goldChest_instance->id = 315;
|
||||
(*FillingContainer_addItem)(filling_container, goldChest_instance);
|
||||
|
||||
ItemInstance *goldLegs_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldLegs_instance);
|
||||
goldLegs_instance->count = 255;
|
||||
goldLegs_instance->auxiliary = 0;
|
||||
goldLegs_instance->id = 316;
|
||||
(*FillingContainer_addItem)(filling_container, goldLegs_instance);
|
||||
|
||||
ItemInstance *goldBoots_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldBoots_instance);
|
||||
goldBoots_instance->count = 255;
|
||||
goldBoots_instance->auxiliary = 0;
|
||||
goldBoots_instance->id = 317;
|
||||
(*FillingContainer_addItem)(filling_container, goldBoots_instance);
|
||||
|
||||
ItemInstance *ironHelm_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironHelm_instance);
|
||||
ironHelm_instance->count = 255;
|
||||
ironHelm_instance->auxiliary = 0;
|
||||
ironHelm_instance->id = 306;
|
||||
(*FillingContainer_addItem)(filling_container, ironHelm_instance);
|
||||
|
||||
ItemInstance *ironChest_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironChest_instance);
|
||||
ironChest_instance->count = 255;
|
||||
ironChest_instance->auxiliary = 0;
|
||||
ironChest_instance->id = 307;
|
||||
(*FillingContainer_addItem)(filling_container, ironChest_instance);
|
||||
|
||||
ItemInstance *ironLegs_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironLegs_instance);
|
||||
ironLegs_instance->count = 255;
|
||||
ironLegs_instance->auxiliary = 0;
|
||||
ironLegs_instance->id = 308;
|
||||
(*FillingContainer_addItem)(filling_container, ironLegs_instance);
|
||||
|
||||
ItemInstance *ironBoots_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironBoots_instance);
|
||||
ironBoots_instance->count = 255;
|
||||
ironBoots_instance->auxiliary = 0;
|
||||
ironBoots_instance->id = 309;
|
||||
(*FillingContainer_addItem)(filling_container, ironBoots_instance);
|
||||
|
||||
ItemInstance *flint2_instance = new ItemInstance;
|
||||
ALLOC_CHECK(flint2_instance);
|
||||
flint2_instance->count = 255;
|
||||
flint2_instance->auxiliary = 0;
|
||||
flint2_instance->id = 318;
|
||||
(*FillingContainer_addItem)(filling_container, flint2_instance);
|
||||
|
||||
ItemInstance *porkRaw_instance = new ItemInstance;
|
||||
ALLOC_CHECK(porkRaw_instance);
|
||||
porkRaw_instance->count = 255;
|
||||
porkRaw_instance->auxiliary = 0;
|
||||
porkRaw_instance->id = 319;
|
||||
(*FillingContainer_addItem)(filling_container, porkRaw_instance);
|
||||
|
||||
ItemInstance *leather_instance = new ItemInstance;
|
||||
ALLOC_CHECK(leather_instance);
|
||||
leather_instance->count = 255;
|
||||
leather_instance->auxiliary = 0;
|
||||
leather_instance->id = 334;
|
||||
(*FillingContainer_addItem)(filling_container, leather_instance);
|
||||
|
||||
ItemInstance *clayBrick_instance = new ItemInstance;
|
||||
ALLOC_CHECK(clayBrick_instance);
|
||||
clayBrick_instance->count = 255;
|
||||
clayBrick_instance->auxiliary = 0;
|
||||
clayBrick_instance->id = 336;
|
||||
(*FillingContainer_addItem)(filling_container, clayBrick_instance);
|
||||
|
||||
ItemInstance *clay_instance = new ItemInstance;
|
||||
ALLOC_CHECK(clay_instance);
|
||||
clay_instance->count = 255;
|
||||
clay_instance->auxiliary = 0;
|
||||
clay_instance->id = 337;
|
||||
(*FillingContainer_addItem)(filling_container, clay_instance);
|
||||
|
||||
ItemInstance *notepad_instance = new ItemInstance;
|
||||
ALLOC_CHECK(notepad_instance);
|
||||
notepad_instance->count = 255;
|
||||
notepad_instance->auxiliary = 0;
|
||||
notepad_instance->id = 339;
|
||||
(*FillingContainer_addItem)(filling_container, notepad_instance);
|
||||
|
||||
ItemInstance *book_instance = new ItemInstance;
|
||||
ALLOC_CHECK(book_instance);
|
||||
book_instance->count = 255;
|
||||
book_instance->auxiliary = 0;
|
||||
book_instance->id = 340;
|
||||
(*FillingContainer_addItem)(filling_container, book_instance);
|
||||
|
||||
ItemInstance *slimeball_instance = new ItemInstance;
|
||||
ALLOC_CHECK(slimeball_instance);
|
||||
slimeball_instance->count = 255;
|
||||
slimeball_instance->auxiliary = 0;
|
||||
slimeball_instance->id = 341;
|
||||
(*FillingContainer_addItem)(filling_container, slimeball_instance);
|
||||
|
||||
ItemInstance *compass_instance = new ItemInstance;
|
||||
ALLOC_CHECK(compass_instance);
|
||||
compass_instance->count = 255;
|
||||
compass_instance->auxiliary = 0;
|
||||
compass_instance->id = 345;
|
||||
(*FillingContainer_addItem)(filling_container, compass_instance);
|
||||
|
||||
ItemInstance *clock_instance = new ItemInstance;
|
||||
ALLOC_CHECK(clock_instance);
|
||||
clock_instance->count = 255;
|
||||
clock_instance->auxiliary = 0;
|
||||
clock_instance->id = 347;
|
||||
(*FillingContainer_addItem)(filling_container, clock_instance);
|
||||
|
||||
ItemInstance *glowDust_instance = new ItemInstance;
|
||||
ALLOC_CHECK(glowDust_instance);
|
||||
glowDust_instance->count = 255;
|
||||
glowDust_instance->auxiliary = 0;
|
||||
glowDust_instance->id = 348;
|
||||
(*FillingContainer_addItem)(filling_container, glowDust_instance);
|
||||
|
||||
ItemInstance *bone_instance = new ItemInstance;
|
||||
ALLOC_CHECK(bone_instance);
|
||||
bone_instance->count = 255;
|
||||
bone_instance->auxiliary = 0;
|
||||
bone_instance->id = 352;
|
||||
(*FillingContainer_addItem)(filling_container, bone_instance);
|
||||
|
||||
ItemInstance *sugar_instance = new ItemInstance;
|
||||
ALLOC_CHECK(sugar_instance);
|
||||
sugar_instance->count = 255;
|
||||
sugar_instance->auxiliary = 0;
|
||||
sugar_instance->id = 353;
|
||||
(*FillingContainer_addItem)(filling_container, sugar_instance);
|
||||
|
||||
ItemInstance *melon_instance = new ItemInstance;
|
||||
ALLOC_CHECK(melon_instance);
|
||||
melon_instance->count = 255;
|
||||
melon_instance->auxiliary = 0;
|
||||
melon_instance->id = 360;
|
||||
(*FillingContainer_addItem)(filling_container, melon_instance);
|
||||
|
||||
ItemInstance *beefRaw_instance = new ItemInstance;
|
||||
ALLOC_CHECK(beefRaw_instance);
|
||||
beefRaw_instance->count = 255;
|
||||
beefRaw_instance->auxiliary = 0;
|
||||
beefRaw_instance->id = 363;
|
||||
(*FillingContainer_addItem)(filling_container, beefRaw_instance);
|
||||
|
||||
ItemInstance *chickenRaw_instance = new ItemInstance;
|
||||
ALLOC_CHECK(chickenRaw_instance);
|
||||
chickenRaw_instance->count = 255;
|
||||
chickenRaw_instance->auxiliary = 0;
|
||||
chickenRaw_instance->id = 365;
|
||||
(*FillingContainer_addItem)(filling_container, chickenRaw_instance);
|
||||
}
|
||||
|
||||
// Init
|
||||
__attribute__((constructor)) static void init_expanded_creative() {
|
||||
INFO("Loading Expanded Creative Mod");
|
||||
misc_run_on_creative_inventory_setup(Inventory_setupDefault_FillingContainer_addItem_call_injection);
|
||||
}
|
15
example-mods/recipes/.gitignore
vendored
Normal file
15
example-mods/recipes/.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/out
|
||||
/debian/tmp
|
||||
/.vscode
|
||||
/build*
|
||||
/CMakeLists.txt.user
|
||||
*.autosave
|
||||
/AppImageBuilder.yml
|
||||
/appimage-builder-cache
|
||||
/appimage-build
|
||||
/AppDir
|
||||
/*.zsync
|
||||
/*.AppImage
|
||||
/core*
|
||||
/qemu_*
|
||||
/cmake/.prebuilt-armhf-toolchain
|
15
example-mods/recipes/CMakeLists.txt
Normal file
15
example-mods/recipes/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
|
||||
# Build For ARM
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
||||
|
||||
# Start Project
|
||||
project(recipes)
|
||||
|
||||
# Include SDK
|
||||
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cmake")
|
||||
|
||||
# Build
|
||||
add_library(recipes SHARED recipes.cpp)
|
||||
target_link_libraries(recipes mods-headers reborn-util symbols misc)
|
52
example-mods/recipes/recipes.cpp
Normal file
52
example-mods/recipes/recipes.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
// Headers
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
// Custom Crafting Recipes
|
||||
static void Recipes_injection(unsigned char *recipes) {
|
||||
// Add
|
||||
Recipes_Type type1 = {
|
||||
.item = 0,
|
||||
.tile = 0,
|
||||
.instance = {
|
||||
.count = 1,
|
||||
.id = 12,
|
||||
.auxiliary = 0
|
||||
},
|
||||
.letter = 'a'
|
||||
};
|
||||
Recipes_Type type2 = {
|
||||
.item = 0,
|
||||
.tile = 0,
|
||||
.instance = {
|
||||
.count = 1,
|
||||
.id = 13,
|
||||
.auxiliary = 0
|
||||
},
|
||||
.letter = 'b'
|
||||
};
|
||||
ItemInstance result = {
|
||||
.count = 1,
|
||||
.id = 344,
|
||||
.auxiliary = 0
|
||||
};
|
||||
(*Recipes_addShapelessRecipe)(recipes, result, {type1, type2});
|
||||
}
|
||||
|
||||
// Custom Furnace Recipes
|
||||
static void FurnaceRecipes_injection(unsigned char *recipes) {
|
||||
// Add
|
||||
(*FurnaceRecipes_addFurnaceRecipe)(recipes, 49, {.count = 1, .id = 246, .auxiliary = 0});
|
||||
}
|
||||
|
||||
// Init
|
||||
__attribute__((constructor)) static void init_recipes() {
|
||||
// Log
|
||||
INFO("Loading Custom Recipes");
|
||||
|
||||
// Setup
|
||||
misc_run_on_recipes_setup(Recipes_injection);
|
||||
misc_run_on_furnace_recipes_setup(FurnaceRecipes_injection);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
project(images)
|
||||
|
||||
# Title Background
|
||||
if(NOT MCPI_SERVER_MODE)
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
install(
|
||||
FILES "background.png"
|
||||
DESTINATION "${MCPI_INSTALL_DIR}/data/images/gui"
|
||||
@ -12,6 +12,12 @@ endif()
|
||||
# Icon
|
||||
install(
|
||||
FILES "icon.png"
|
||||
DESTINATION "share/icons/hicolor/scalable/apps"
|
||||
DESTINATION "${MCPI_SHARE_DIR}/icons/hicolor/scalable/apps"
|
||||
RENAME "${MCPI_APP_ID}.png"
|
||||
)
|
||||
|
||||
# AppImage
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
install_symlink("${MCPI_SHARE_DIR}/icons/hicolor/scalable/apps/${MCPI_APP_ID}.png" "${MCPI_APP_ID}.png")
|
||||
install_symlink("${MCPI_APP_ID}.png" ".DirIcon")
|
||||
endif()
|
||||
|
BIN
images/start.png
BIN
images/start.png
Binary file not shown.
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 156 KiB |
@ -1,23 +1,30 @@
|
||||
project(launcher)
|
||||
|
||||
# Dependencies
|
||||
add_subdirectory(dependencies)
|
||||
|
||||
# Launcher
|
||||
add_executable(launcher src/bootstrap.c src/patchelf.c src/crash-report.c)
|
||||
if(MCPI_SERVER_MODE)
|
||||
target_sources(launcher PRIVATE src/server/launcher.c)
|
||||
else()
|
||||
target_sources(launcher PRIVATE src/client/launcher.cpp)
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/available-feature-flags.c"
|
||||
COMMAND xxd -i available-feature-flags "${CMAKE_CURRENT_BINARY_DIR}/available-feature-flags.c"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/client/available-feature-flags"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src/client"
|
||||
VERBATIM
|
||||
)
|
||||
target_sources(launcher PRIVATE src/client/launcher.cpp "${CMAKE_CURRENT_BINARY_DIR}/available-feature-flags.c")
|
||||
endif()
|
||||
target_link_libraries(launcher reborn-util)
|
||||
# RPath
|
||||
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
|
||||
|
||||
# Install
|
||||
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")
|
||||
install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_VARIANT_NAME}")
|
||||
|
||||
# Install Available Feature Flags List
|
||||
if(NOT MCPI_SERVER_MODE)
|
||||
install(FILES "src/client/available-feature-flags" DESTINATION "${MCPI_INSTALL_DIR}")
|
||||
endif()
|
||||
|
||||
# Install Desktop Entry
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
|
||||
"[Desktop Entry]\n"
|
||||
@ -42,7 +49,7 @@ else()
|
||||
endif()
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
|
||||
DESTINATION "share/applications"
|
||||
DESTINATION "${MCPI_SHARE_DIR}/applications"
|
||||
RENAME "${MCPI_APP_ID}.desktop"
|
||||
)
|
||||
|
||||
@ -105,6 +112,12 @@ file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
|
||||
)
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
|
||||
DESTINATION "share/metainfo"
|
||||
DESTINATION "${MCPI_SHARE_DIR}/metainfo"
|
||||
RENAME "${MCPI_APP_ID}.appdata.xml"
|
||||
)
|
||||
|
||||
# AppImage
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
install_symlink("bin/${MCPI_VARIANT_NAME}" "AppRun")
|
||||
install_symlink("${MCPI_SHARE_DIR}/applications/${MCPI_APP_ID}.desktop" "${MCPI_APP_ID}.desktop")
|
||||
endif()
|
||||
|
4
launcher/dependencies/CMakeLists.txt
Normal file
4
launcher/dependencies/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
project(launcher-dependencies)
|
||||
|
||||
# PatchELF
|
||||
add_subdirectory(patchelf)
|
17
launcher/dependencies/patchelf/CMakeLists.txt
Normal file
17
launcher/dependencies/patchelf/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
project(patchelf)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w)
|
||||
|
||||
## PatchELF
|
||||
|
||||
# Build
|
||||
add_executable(patchelf src/src/patchelf.cc)
|
||||
target_compile_definitions(patchelf PRIVATE -D_FILE_OFFSET_BITS=64)
|
||||
set_target_properties(patchelf PROPERTIES CXX_STANDARD 17)
|
||||
|
||||
# Install
|
||||
install(TARGETS patchelf DESTINATION "${MCPI_BIN_DIR}")
|
||||
|
||||
# License
|
||||
install(FILES src/COPYING DESTINATION "${MCPI_LEGAL_DIR}/patchelf")
|
1
launcher/dependencies/patchelf/src
Submodule
1
launcher/dependencies/patchelf/src
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 734daa3d0f79cf1a0c81f927d846ace5d6a2c8e1
|
@ -15,13 +15,6 @@
|
||||
#include "crash-report.h"
|
||||
|
||||
// Set Environmental Variable
|
||||
#define PRESERVE_ENVIRONMENTAL_VARIABLE(name) \
|
||||
{ \
|
||||
char *original_env_value = getenv(name); \
|
||||
if (original_env_value != NULL) { \
|
||||
setenv("ORIGINAL_" name, original_env_value, 1); \
|
||||
} \
|
||||
}
|
||||
static void trim(char **value) {
|
||||
// Remove Trailing Colon
|
||||
int length = strlen(*value);
|
||||
@ -45,19 +38,6 @@ void set_and_print_env(const char *name, char *value) {
|
||||
// Set The Value
|
||||
setenv(name, value, 1);
|
||||
}
|
||||
#ifndef __ARM_ARCH
|
||||
#define PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU(name) \
|
||||
{ \
|
||||
char *old_value = getenv("QEMU_SET_ENV"); \
|
||||
char *new_value = NULL; \
|
||||
/* Pass Variable */ \
|
||||
safe_asprintf(&new_value, "%s%s%s=%s", old_value == NULL ? "" : old_value, old_value == NULL ? "" : ",", name, getenv(name)); \
|
||||
setenv("QEMU_SET_ENV", new_value, 1); \
|
||||
free(new_value); \
|
||||
/* Reset Variable */ \
|
||||
RESET_ENVIRONMENTAL_VARIABLE(name); \
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get Environmental Variable
|
||||
static char *get_env_safe(const char *name) {
|
||||
@ -98,14 +78,14 @@ static void load(char **ld_preload, char *folder) {
|
||||
// Add Terminator
|
||||
name[total_length] = '\0';
|
||||
|
||||
// Check If File Is Executable
|
||||
// Check If File Is Accessible
|
||||
int result = access(name, R_OK);
|
||||
if (result == 0) {
|
||||
// Add To LD_PRELOAD
|
||||
string_append(ld_preload, ":%s", name);
|
||||
string_append(ld_preload, "%s%s", *ld_preload == NULL ? "" : ":", name);
|
||||
} else if (result == -1 && errno != 0) {
|
||||
// Fail
|
||||
INFO("Unable To Acesss: %s: %s", name, strerror(errno));
|
||||
WARN("Unable To Acesss: %s: %s", name, strerror(errno));
|
||||
errno = 0;
|
||||
}
|
||||
}
|
||||
@ -169,12 +149,14 @@ void pre_bootstrap(int argc, char *argv[]) {
|
||||
#endif
|
||||
|
||||
// Debug Zenity
|
||||
#ifndef MCPI_SERVER_MODE
|
||||
{
|
||||
const char *is_debug = getenv("MCPI_DEBUG");
|
||||
if (is_debug != NULL && strlen(is_debug) > 0) {
|
||||
set_and_print_env("ZENITY_DEBUG", "1");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// AppImage
|
||||
#ifdef MCPI_IS_APPIMAGE_BUILD
|
||||
@ -225,6 +207,48 @@ void pre_bootstrap(int argc, char *argv[]) {
|
||||
sigaction(SIGTERM, &act_sigterm, NULL);
|
||||
}
|
||||
|
||||
// Copy SDK Into ~/.minecraft-pi
|
||||
static void run_simple_command(const char *const command[], const char *error) {
|
||||
int status = 0;
|
||||
char *output = run_command(command, &status);
|
||||
if (output != NULL) {
|
||||
free(output);
|
||||
}
|
||||
if (!is_exit_status_success(status)) {
|
||||
ERR("%s", error);
|
||||
}
|
||||
}
|
||||
static void copy_sdk(char *binary_directory) {
|
||||
// Output Directory
|
||||
char *output = NULL;
|
||||
safe_asprintf(&output, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk/" MCPI_SDK_DIR, getenv("HOME"));
|
||||
// Source Directory
|
||||
char *source = NULL;
|
||||
safe_asprintf(&source, "%s/sdk/.", binary_directory);
|
||||
|
||||
// Clean
|
||||
{
|
||||
const char *const command[] = {"rm", "-rf", output, NULL};
|
||||
run_simple_command(command, "Unable To Clean SDK Output Directory");
|
||||
}
|
||||
|
||||
// Make Directory
|
||||
{
|
||||
const char *const command[] = {"mkdir", "-p", output, NULL};
|
||||
run_simple_command(command, "Unable To Create SDK Output Directory");
|
||||
}
|
||||
|
||||
// Copy
|
||||
{
|
||||
const char *const command[] = {"cp", "-ar", source, output, NULL};
|
||||
run_simple_command(command, "Unable To Copy SDK");
|
||||
}
|
||||
|
||||
// Free
|
||||
free(output);
|
||||
free(source);
|
||||
}
|
||||
|
||||
// Bootstrap
|
||||
void bootstrap(int argc, char *argv[]) {
|
||||
INFO("Configuring Game...");
|
||||
@ -232,6 +256,9 @@ void bootstrap(int argc, char *argv[]) {
|
||||
// Get Binary Directory
|
||||
char *binary_directory = get_binary_directory();
|
||||
|
||||
// Copy SDK
|
||||
copy_sdk(binary_directory);
|
||||
|
||||
// Set MCPI_REBORN_ASSETS_PATH
|
||||
{
|
||||
char *assets_path = realpath("/proc/self/exe", NULL);
|
||||
@ -265,7 +292,7 @@ void bootstrap(int argc, char *argv[]) {
|
||||
// Find Linker
|
||||
char *linker = NULL;
|
||||
// Select Linker
|
||||
#ifdef MCPI_BUNDLE_ARMHF_SYSROOT
|
||||
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
||||
// Use ARM Sysroot Linker
|
||||
safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory);
|
||||
#else
|
||||
@ -303,22 +330,17 @@ void bootstrap(int argc, char *argv[]) {
|
||||
// Free Resolved Path
|
||||
free(resolved_path);
|
||||
|
||||
// Configure LD_LIBRARY_PATH
|
||||
// Configure Library Search Path
|
||||
char *library_path = NULL;
|
||||
{
|
||||
// Log
|
||||
DEBUG("Setting Linker Search Paths...");
|
||||
|
||||
// Preserve
|
||||
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH");
|
||||
// Prepare
|
||||
char *new_ld_path = NULL;
|
||||
|
||||
// Add Library Directory
|
||||
safe_asprintf(&new_ld_path, "%s/lib", binary_directory);
|
||||
|
||||
// Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System)
|
||||
#ifdef MCPI_BUNDLE_ARMHF_SYSROOT
|
||||
string_append(&new_ld_path, ":%s/sysroot/lib:%s/sysroot/lib/arm-linux-gnueabihf:%s/sysroot/usr/lib:%s/sysroot/usr/lib/arm-linux-gnueabihf", binary_directory, binary_directory, binary_directory, binary_directory);
|
||||
#endif
|
||||
// Add Native Library Directory
|
||||
safe_asprintf(&new_ld_path, "%s/lib/native", binary_directory);
|
||||
|
||||
// Add LD_LIBRARY_PATH
|
||||
{
|
||||
@ -328,27 +350,38 @@ void bootstrap(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
// Set And Free
|
||||
// Set LD_LIBRARY_PATH (Used For Everything Except MCPI)
|
||||
set_and_print_env("LD_LIBRARY_PATH", new_ld_path);
|
||||
|
||||
// Add ARM Library Directory
|
||||
// (This Overrides LD_LIBRARY_PATH Using ld.so's --library-path Option)
|
||||
safe_asprintf(&library_path, "%s/lib/arm", binary_directory);
|
||||
|
||||
// Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System)
|
||||
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
||||
string_append(&library_path, ":%s/sysroot/lib:%s/sysroot/lib/arm-linux-gnueabihf:%s/sysroot/usr/lib:%s/sysroot/usr/lib/arm-linux-gnueabihf", binary_directory, binary_directory, binary_directory, binary_directory);
|
||||
#endif
|
||||
|
||||
// Add Remaining LD_LIBRARY_PATH
|
||||
string_append(&library_path, ":%s", new_ld_path);
|
||||
|
||||
// Free LD_LIBRARY_PATH
|
||||
free(new_ld_path);
|
||||
}
|
||||
|
||||
// Configure LD_PRELOAD
|
||||
// Configure MCPI's Preloaded Objects
|
||||
char *preload = NULL;
|
||||
{
|
||||
// Log
|
||||
DEBUG("Locating Mods...");
|
||||
|
||||
// Preserve
|
||||
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_PRELOAD");
|
||||
char *new_ld_preload = NULL;
|
||||
|
||||
// ~/.minecraft-pi/mods
|
||||
{
|
||||
// Get Mods Folder
|
||||
char *mods_folder = NULL;
|
||||
safe_asprintf(&mods_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA "/mods/", getenv("HOME"));
|
||||
// Load Mods From ./mods
|
||||
load(&new_ld_preload, mods_folder);
|
||||
load(&preload, mods_folder);
|
||||
// Free Mods Folder
|
||||
free(mods_folder);
|
||||
}
|
||||
@ -359,7 +392,7 @@ void bootstrap(int argc, char *argv[]) {
|
||||
char *mods_folder = NULL;
|
||||
safe_asprintf(&mods_folder, "%s/mods/", binary_directory);
|
||||
// Load Mods From ./mods
|
||||
load(&new_ld_preload, mods_folder);
|
||||
load(&preload, mods_folder);
|
||||
// Free Mods Folder
|
||||
free(mods_folder);
|
||||
}
|
||||
@ -368,13 +401,9 @@ void bootstrap(int argc, char *argv[]) {
|
||||
{
|
||||
char *value = get_env_safe("LD_PRELOAD");
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&new_ld_preload, ":%s", value);
|
||||
string_append(&preload, ":%s", value);
|
||||
}
|
||||
}
|
||||
|
||||
// Set LD_PRELOAD
|
||||
set_and_print_env("LD_PRELOAD", new_ld_preload);
|
||||
free(new_ld_preload);
|
||||
}
|
||||
|
||||
// Free Binary Directory
|
||||
@ -385,26 +414,28 @@ void bootstrap(int argc, char *argv[]) {
|
||||
|
||||
// Arguments
|
||||
int argv_start = 1; // argv = &new_args[argv_start]
|
||||
const char *new_args[argv_start /* 1 Potential Prefix Argument (QEMU) */ + argc + 1 /* NULL-Terminator */]; //
|
||||
int real_argv_start = argv_start + 5; // ld.so Arguments
|
||||
const char *new_args[real_argv_start /* 1 Potential Prefix Argument (QEMU) */ + argc + 1 /* NULL-Terminator */]; //
|
||||
|
||||
// Copy Existing Arguments
|
||||
for (int i = 1; i < argc; i++) {
|
||||
new_args[i + argv_start] = argv[i];
|
||||
new_args[i + real_argv_start] = argv[i];
|
||||
}
|
||||
// NULL-Terminator
|
||||
new_args[argv_start + argc] = NULL;
|
||||
new_args[real_argv_start + argc] = NULL;
|
||||
|
||||
// Set Executable Argument
|
||||
new_args[argv_start] = new_mcpi_exe_path;
|
||||
new_args[argv_start] = patch_get_interpreter(new_mcpi_exe_path);
|
||||
new_args[argv_start + 1] = "--preload";
|
||||
new_args[argv_start + 2] = preload;
|
||||
new_args[argv_start + 3] = "--library-path";
|
||||
new_args[argv_start + 4] = library_path;
|
||||
new_args[real_argv_start] = new_mcpi_exe_path;
|
||||
|
||||
// Non-ARM Systems Need QEMU
|
||||
#ifndef __ARM_ARCH
|
||||
argv_start--;
|
||||
new_args[argv_start] = QEMU_BINARY;
|
||||
|
||||
// Prevent QEMU From Being Modded
|
||||
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_LIBRARY_PATH");
|
||||
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_PRELOAD");
|
||||
#endif
|
||||
|
||||
// Run
|
||||
|
@ -37,3 +37,7 @@ TRUE Improved Title Background
|
||||
TRUE Force Touch GUI Button Behavior
|
||||
TRUE Improved Button Hover Behavior
|
||||
TRUE Implement Create World Dialog
|
||||
FALSE Remove Forced GUI Lag (Can Break Joining Servers)
|
||||
TRUE Add Buckets
|
||||
TRUE Classic HUD
|
||||
TRUE Translucent Toolbar
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <sys/wait.h>
|
||||
@ -36,46 +36,44 @@ static std::string strip_feature_flag_default(std::string flag, bool *default_re
|
||||
}
|
||||
|
||||
// Load Available Feature Flags
|
||||
extern unsigned char available_feature_flags[];
|
||||
extern unsigned int available_feature_flags_len;
|
||||
static void load_available_feature_flags(std::function<void(std::string)> callback) {
|
||||
// Get Path
|
||||
char *binary_directory = get_binary_directory();
|
||||
std::string path = std::string(binary_directory) + "/available-feature-flags";
|
||||
free(binary_directory);
|
||||
// Load File
|
||||
std::ifstream stream(path);
|
||||
if (stream && stream.good()) {
|
||||
std::vector<std::string> lines;
|
||||
// Read File
|
||||
{
|
||||
std::string line;
|
||||
while (std::getline(stream, line)) {
|
||||
if (line.length() > 0) {
|
||||
// Verify Line
|
||||
if (line.find('|') == std::string::npos) {
|
||||
lines.push_back(line);
|
||||
} else {
|
||||
// Invalid Line
|
||||
ERR("Feature Flag Contains Invalid '|'");
|
||||
}
|
||||
std::string data(available_feature_flags, available_feature_flags + available_feature_flags_len);
|
||||
std::stringstream stream(data);
|
||||
// Store Lines
|
||||
std::vector<std::string> lines;
|
||||
// Read File
|
||||
{
|
||||
std::string line;
|
||||
while (std::getline(stream, line)) {
|
||||
if (line.length() > 0) {
|
||||
// Verify Line
|
||||
if (line.find('|') == std::string::npos) {
|
||||
lines.push_back(line);
|
||||
} else {
|
||||
// Invalid Line
|
||||
ERR("Feature Flag Contains Invalid '|'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sort
|
||||
std::sort(lines.begin(), lines.end(), [](std::string a, std::string b) {
|
||||
// Strip Defaults
|
||||
std::string stripped_a = strip_feature_flag_default(a, NULL);
|
||||
std::string stripped_b = strip_feature_flag_default(b, NULL);
|
||||
// Sort
|
||||
std::sort(lines.begin(), lines.end(), [](std::string a, std::string b) {
|
||||
// Strip Defaults
|
||||
std::string stripped_a = strip_feature_flag_default(a, NULL);
|
||||
std::string stripped_b = strip_feature_flag_default(b, NULL);
|
||||
// Sort
|
||||
return stripped_a < stripped_b;
|
||||
});
|
||||
// Run Callbacks
|
||||
for (std::string line : lines) {
|
||||
callback(line);
|
||||
}
|
||||
// Close File
|
||||
stream.close();
|
||||
} else {
|
||||
ERR("Unable To Load Available Feature Flags");
|
||||
return stripped_a < stripped_b;
|
||||
});
|
||||
// Run Callbacks
|
||||
for (std::string &line : lines) {
|
||||
callback(line);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,6 +124,20 @@ static void run_zenity_and_set_env(const char *env_name, std::vector<std::string
|
||||
run_command_and_set_env(env_name, full_command_array);
|
||||
}
|
||||
|
||||
// Set Variable If Not Already Set
|
||||
static void set_env_if_unset(const char *env_name, std::function<std::string()> callback) {
|
||||
if (getenv(env_name) == NULL) {
|
||||
char *value = strdup(callback().c_str());
|
||||
ALLOC_CHECK(value);
|
||||
set_and_print_env(env_name, value);
|
||||
free(value);
|
||||
}
|
||||
}
|
||||
|
||||
// Defaults
|
||||
#define DEFAULT_USERNAME "StevePi"
|
||||
#define DEFAULT_RENDER_DISTANCE "Short"
|
||||
|
||||
// Launch
|
||||
#define LIST_DIALOG_SIZE "400"
|
||||
int main(int argc, char *argv[]) {
|
||||
@ -149,6 +161,37 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
// --default
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--default") == 0) {
|
||||
// Use Default Feature Flags
|
||||
set_env_if_unset("MCPI_FEATURE_FLAGS", []() {
|
||||
std::string feature_flags = "";
|
||||
load_available_feature_flags([&feature_flags](std::string flag) {
|
||||
bool default_value;
|
||||
// Strip Default Value
|
||||
std::string stripped_flag = strip_feature_flag_default(flag, &default_value);
|
||||
// Specify Default Value
|
||||
if (default_value) {
|
||||
// Enabled By Default
|
||||
feature_flags += stripped_flag + '|';
|
||||
}
|
||||
});
|
||||
if (feature_flags.length() > 0 && feature_flags[feature_flags.length() - 1] == '|') {
|
||||
feature_flags.pop_back();
|
||||
}
|
||||
return feature_flags;
|
||||
});
|
||||
set_env_if_unset("MCPI_RENDER_DISTANCE", []() {
|
||||
return DEFAULT_RENDER_DISTANCE;
|
||||
});
|
||||
set_env_if_unset("MCPI_USERNAME", []() {
|
||||
return DEFAULT_USERNAME;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create ~/.minecraft-pi If Needed
|
||||
// Minecraft Folder
|
||||
{
|
||||
@ -215,14 +258,11 @@ int main(int argc, char *argv[]) {
|
||||
command.push_back("Selected");
|
||||
command.push_back("--column");
|
||||
command.push_back("Name");
|
||||
command.push_back("FALSE");
|
||||
command.push_back("Far");
|
||||
command.push_back("FALSE");
|
||||
command.push_back("Normal");
|
||||
command.push_back("TRUE");
|
||||
command.push_back("Short");
|
||||
command.push_back("FALSE");
|
||||
command.push_back("Tiny");
|
||||
std::string render_distances[] = {"Far", "Normal", "Short", "Tiny"};
|
||||
for (std::string &render_distance : render_distances) {
|
||||
command.push_back(render_distance.compare(DEFAULT_RENDER_DISTANCE) == 0 ? "TRUE" : "FALSE");
|
||||
command.push_back(render_distance);
|
||||
}
|
||||
// Run
|
||||
run_zenity_and_set_env("MCPI_RENDER_DISTANCE", command);
|
||||
}
|
||||
@ -233,7 +273,7 @@ int main(int argc, char *argv[]) {
|
||||
command.push_back("--text");
|
||||
command.push_back("Enter Minecraft Username:");
|
||||
command.push_back("--entry-text");
|
||||
command.push_back("StevePi");
|
||||
command.push_back(DEFAULT_USERNAME);
|
||||
// Run
|
||||
run_zenity_and_set_env("MCPI_USERNAME", command);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <signal.h>
|
||||
#include <poll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
@ -44,6 +45,7 @@ static void exit_handler(__attribute__((unused)) int signal) {
|
||||
// Setup
|
||||
#define PIPE_READ 0
|
||||
#define PIPE_WRITE 1
|
||||
#define MCPI_LOGS_DIR "/tmp/.minecraft-pi-logs"
|
||||
void setup_crash_report() {
|
||||
// Store Output
|
||||
int output_pipe[2];
|
||||
@ -100,8 +102,21 @@ void setup_crash_report() {
|
||||
#define BUFFER_SIZE 1024
|
||||
char buf[BUFFER_SIZE];
|
||||
|
||||
// Ensure Temporary Directory
|
||||
{
|
||||
// Check If It Exists
|
||||
struct stat tmp_stat;
|
||||
int exists = stat(MCPI_LOGS_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode);
|
||||
if (!exists) {
|
||||
// Doesn't Exist
|
||||
if (mkdir(MCPI_LOGS_DIR, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
|
||||
ERR("Unable To Create Temporary Folder: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create Temporary File
|
||||
char log_filename[] = "/tmp/.minecraft-pi-log-XXXXXX";
|
||||
char log_filename[] = MCPI_LOGS_DIR "/XXXXXX";
|
||||
int log_file_fd = mkstemp(log_filename);
|
||||
if (log_file_fd == -1) {
|
||||
ERR("Unable To Create Log File: %s", strerror(errno));
|
||||
|
@ -72,7 +72,9 @@ static void duplicate_mcpi_executable(const char *original_path, char *new_path)
|
||||
"--remove-needed", "libbcm_host.so", \
|
||||
"--remove-needed", "libX11.so.6", \
|
||||
"--remove-needed", "libEGL.so", \
|
||||
"--replace-needed", "libGLESv2.so", "libGLESv1_CM.so.1", \
|
||||
"--remove-needed", "libGLESv2.so", \
|
||||
"--remove-needed", "libSDL-1.2.so.0", \
|
||||
"--add-needed", "libmedia-layer-core.so", \
|
||||
new_path, \
|
||||
NULL \
|
||||
}; \
|
||||
|
@ -5,8 +5,22 @@ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/libreborn")
|
||||
configure_file(include/libreborn/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/libreborn/config.h" ESCAPE_QUOTES @ONLY)
|
||||
|
||||
# Util
|
||||
add_library(reborn-util STATIC src/util/elf.c src/util/exec.c src/util/string.c src/util/util.c)
|
||||
target_include_directories(reborn-util PUBLIC include PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/include")
|
||||
add_library(reborn-util SHARED src/util/elf.c src/util/exec.c src/util/string.c src/util/util.c)
|
||||
target_include_directories(
|
||||
reborn-util
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/libreborn>"
|
||||
)
|
||||
# Install
|
||||
install(TARGETS reborn-util DESTINATION "${MCPI_LIB_DIR}")
|
||||
# SDK
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS reborn-util EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
install(DIRECTORY "include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/libreborn")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/libreborn")
|
||||
endif()
|
||||
|
||||
# Patch
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
@ -15,4 +29,6 @@ if(BUILD_ARM_COMPONENTS)
|
||||
target_compile_definitions(reborn-patch PUBLIC -DREBORN_HAS_PATCH_CODE)
|
||||
# Install
|
||||
install(TARGETS reborn-patch DESTINATION "${MCPI_LIB_DIR}")
|
||||
# SDK
|
||||
install(TARGETS reborn-patch EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
endif()
|
||||
|
@ -3,7 +3,8 @@
|
||||
#cmakedefine MCPI_SERVER_MODE
|
||||
#cmakedefine MCPI_HEADLESS_MODE
|
||||
#cmakedefine MCPI_IS_APPIMAGE_BUILD
|
||||
#cmakedefine MCPI_BUNDLE_ARMHF_SYSROOT
|
||||
#cmakedefine MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
||||
#cmakedefine MCPI_USE_GLES1_COMPATIBILITY_LAYER
|
||||
#cmakedefine MCPI_APP_TITLE "@MCPI_APP_TITLE@"
|
||||
#cmakedefine MCPI_VERSION "@MCPI_VERSION@"
|
||||
#cmakedefine MCPI_SDK_DIR "@MCPI_SDK_DIR@"
|
||||
|
@ -6,6 +6,6 @@
|
||||
// Logging
|
||||
#define INFO(format, ...) { fprintf(stderr, "[INFO]: " format "\n", ##__VA_ARGS__); }
|
||||
#define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", ##__VA_ARGS__); }
|
||||
#define DEBUG(format, ...) { const char *debug = getenv("MCPI_DEBUG"); if (debug != NULL && strlen(debug) > 0) { fprintf(stderr, "[DEBUG]: " format "\n", ##__VA_ARGS__); } }
|
||||
#define DEBUG(format, ...) { const char *debug = getenv("MCPI_DEBUG"); if (debug != NULL) { fprintf(stderr, "[DEBUG]: " format "\n", ##__VA_ARGS__); } }
|
||||
#define ERR(format, ...) { fprintf(stderr, "[ERR]: (%s:%i): " format "\n", __FILE__, __LINE__, ##__VA_ARGS__); exit(EXIT_FAILURE); }
|
||||
#define IMPOSSIBLE() ERR("This Should Never Be Called")
|
||||
|
@ -14,6 +14,8 @@ void _overwrite_call(const char *file, int line, void *start, void *target);
|
||||
void _overwrite_calls(const char *file, int line, void *start, void *target);
|
||||
#define overwrite_calls(start, target) _overwrite_calls(__FILE__, __LINE__, start, target);
|
||||
|
||||
void *extract_from_bl_instruction(unsigned char *from);
|
||||
|
||||
void _overwrite(const char *file, int line, void *start, void *target);
|
||||
#define overwrite(start, target) _overwrite(__FILE__, __LINE__, start, target);
|
||||
|
||||
|
@ -32,17 +32,6 @@
|
||||
\
|
||||
__attribute__((__used__)) return_type name args
|
||||
|
||||
// Macro To Reset Environmental Variables To Pre-MCPI State
|
||||
#define RESET_ENVIRONMENTAL_VARIABLE(name) \
|
||||
{ \
|
||||
char *original_env_value = getenv("ORIGINAL_" name); \
|
||||
if (original_env_value != NULL) { \
|
||||
setenv(name, original_env_value, 1); \
|
||||
} else { \
|
||||
unsetenv(name); \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -72,6 +72,12 @@ static unsigned char *code_block = NULL;
|
||||
#define CODE_SIZE 8
|
||||
static int code_block_remaining = CODE_BLOCK_SIZE;
|
||||
|
||||
static void _long_overwrite(void *start, void *target) {
|
||||
unsigned char patch_data[4] = {0x04, 0xf0, 0x1f, 0xe5}; // "ldr pc, [pc, #-0x4]"
|
||||
|
||||
_patch(NULL, -1, start, patch_data);
|
||||
_patch_address(NULL, -1, (void *) (((unsigned char *) start) + 4), target);
|
||||
}
|
||||
static void update_code_block(void *target) {
|
||||
// BL Instructions Can Only Access A Limited Portion of Memory, So This Allocates Memory Closer To The Original Instruction, That When Run, Will Jump Into The Actual Target
|
||||
if (code_block == NULL) {
|
||||
@ -84,28 +90,31 @@ static void update_code_block(void *target) {
|
||||
if (code_block_remaining < CODE_SIZE) {
|
||||
ERR("Maximum Amount Of overwrite_calls() Uses Reached");
|
||||
}
|
||||
_overwrite(NULL, -1, code_block, target);
|
||||
_long_overwrite(code_block, target);
|
||||
}
|
||||
static void increment_code_block() {
|
||||
code_block = code_block + CODE_SIZE;
|
||||
code_block_remaining = code_block_remaining - CODE_SIZE;
|
||||
}
|
||||
|
||||
// Overwrite Specific BL Instruction
|
||||
void _overwrite_call(const char *file, int line, void *start, void *target) {
|
||||
// Overwrite Specific B(L) Instruction
|
||||
static void _overwrite_call_internal(const char *file, int line, void *start, void *target, int use_b_instruction) {
|
||||
// Add New Target To Code Block
|
||||
update_code_block(target);
|
||||
|
||||
// Patch
|
||||
int use_b_instruction = ((unsigned char *) start)[3] == B_INSTRUCTION;
|
||||
uint32_t new_instruction = generate_bl_instruction(start, code_block, use_b_instruction);
|
||||
_patch(file, line, start, (unsigned char *) &new_instruction);
|
||||
|
||||
// Increment Code Block Position
|
||||
increment_code_block();
|
||||
}
|
||||
void _overwrite_call(const char *file, int line, void *start, void *target) {
|
||||
int use_b_instruction = ((unsigned char *) start)[3] == B_INSTRUCTION;
|
||||
_overwrite_call_internal(file, line, start, target, use_b_instruction);
|
||||
}
|
||||
|
||||
// Overwrite Function Calls
|
||||
// Overwrite All B(L) Intrusctions That Target The Specified Address
|
||||
void _overwrite_calls(const char *file, int line, void *start, void *target) {
|
||||
// Add New Target To Code Block
|
||||
update_code_block(target);
|
||||
@ -128,13 +137,24 @@ void _overwrite_calls(const char *file, int line, void *start, void *target) {
|
||||
}
|
||||
}
|
||||
|
||||
// Overwrite Function
|
||||
// NOTE: "start" Must Be At Least 8 Bytes Long
|
||||
void _overwrite(const char *file, int line, void *start, void *target) {
|
||||
unsigned char patch_data[4] = {0x04, 0xf0, 0x1f, 0xe5}; // "ldr pc, [pc, #-0x4]"
|
||||
// Extract Target Address From B(L) Instruction
|
||||
void *extract_from_bl_instruction(unsigned char *from) {
|
||||
unsigned char *pc = ((unsigned char *) from) + 8;
|
||||
|
||||
_patch(file, line, start, patch_data);
|
||||
_patch_address(file, line, (void *) (((unsigned char *) start) + 4), target);
|
||||
int32_t target = 0;
|
||||
unsigned char *target_array = (unsigned char *) ⌖
|
||||
target_array[0] = from[0];
|
||||
target_array[1] = from[1];
|
||||
target_array[2] = from[2];
|
||||
|
||||
int32_t offset = target << 2;
|
||||
|
||||
return (void *) (pc + offset);
|
||||
}
|
||||
|
||||
// Overwrite Function
|
||||
void _overwrite(const char *file, int line, void *start, void *target) {
|
||||
_overwrite_call_internal(file, line, start, target, 1);
|
||||
}
|
||||
|
||||
// Print Patch Debug Data
|
||||
|
@ -4,8 +4,17 @@
|
||||
|
||||
// Safe execvpe()
|
||||
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) {
|
||||
// Log
|
||||
DEBUG("Running Command:");
|
||||
for (int i = 0; argv[i] != NULL; i++) {
|
||||
DEBUG(" %s", argv[i]);
|
||||
}
|
||||
// Run
|
||||
int ret = execvpe(argv[0], (char *const *) argv, (char *const *) envp);
|
||||
if (ret == -1) {
|
||||
if (errno == ENOENT && strcmp(argv[0], "qemu-qrm")) {
|
||||
ERR("Unable to find QEMU! To install on Ubuntu/Debian, run \"sudo apt install qemu-user\". To install on Arch Linux, run \"sudo pacman -Sy qemu-user\".");
|
||||
}
|
||||
ERR("Unable To Execute Program: %s: %s", argv[0], strerror(errno));
|
||||
} else {
|
||||
IMPOSSIBLE();
|
||||
|
@ -1,23 +1,28 @@
|
||||
project(media-layer)
|
||||
|
||||
# Target Notes:
|
||||
# media-layer-core-real: Fully Built Media Layer Core
|
||||
# media-layer-core: Alias Target That Points To The Library MCPI Should Link To
|
||||
|
||||
# Add Headers
|
||||
add_library(media-layer-headers INTERFACE)
|
||||
target_include_directories(media-layer-headers INTERFACE include)
|
||||
target_include_directories(
|
||||
media-layer-headers
|
||||
INTERFACE
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/media-layer>"
|
||||
)
|
||||
# SDK
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS media-layer-headers EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
install(DIRECTORY "include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/media-layer")
|
||||
endif()
|
||||
|
||||
# Add GLESv1_CM Stubs Or Compatibility Layer
|
||||
add_subdirectory(gles)
|
||||
# Add Extras
|
||||
add_subdirectory(extras)
|
||||
|
||||
# Add Core
|
||||
add_subdirectory(core)
|
||||
if((BUILD_NATIVE_COMPONENTS AND MCPI_USE_MEDIA_LAYER_PROXY) OR (BUILD_ARM_COMPONENTS AND NOT MCPI_USE_MEDIA_LAYER_PROXY))
|
||||
add_subdirectory(core)
|
||||
endif()
|
||||
|
||||
# Add Proxy
|
||||
if(MCPI_USE_MEDIA_LAYER_PROXY)
|
||||
add_subdirectory(proxy)
|
||||
endif()
|
||||
|
||||
# Add Extras
|
||||
add_subdirectory(extras)
|
||||
|
@ -1,39 +1,32 @@
|
||||
project(media-layer-core)
|
||||
|
||||
# Dependencies
|
||||
add_subdirectory(dependencies)
|
||||
|
||||
# OpenGL
|
||||
add_subdirectory(gles)
|
||||
|
||||
# Configuration
|
||||
set(CORE_SRC src/base.cpp src/media.c src/screenshot.c) # SDL Re-Implementation Using GLFW
|
||||
set(CORE_SRC src/base.cpp src/media.c $<TARGET_OBJECTS:media-layer-extras>) # SDL Re-Implementation Using GLFW
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
list(APPEND CORE_SRC src/audio/api.cpp src/audio/engine.c src/audio/file.cpp)
|
||||
else()
|
||||
list(APPEND CORE_SRC src/audio/stubs.c)
|
||||
endif()
|
||||
|
||||
# Build
|
||||
if(MCPI_USE_MEDIA_LAYER_PROXY AND BUILD_NATIVE_COMPONENTS)
|
||||
# Build Media Layer Core Natively And Use Proxy
|
||||
add_library(media-layer-core-real OBJECT ${CORE_SRC}) # Dependencies Are Setup Later
|
||||
endif()
|
||||
if(NOT MCPI_USE_MEDIA_LAYER_PROXY AND BUILD_ARM_COMPONENTS)
|
||||
# Directly Link Media Layer Core To MCPI
|
||||
add_library(media-layer-core-real SHARED ${CORE_SRC}) # Dependencies Are Setup Later
|
||||
set_target_properties(media-layer-core-real PROPERTIES OUTPUT_NAME "media-layer-core")
|
||||
# Install
|
||||
install(TARGETS media-layer-core-real DESTINATION "${MCPI_LIB_DIR}")
|
||||
# Create Alias Target For Linking
|
||||
add_library(media-layer-core ALIAS media-layer-core-real)
|
||||
endif()
|
||||
|
||||
# Configure Media Layer Core If Built
|
||||
if(TARGET media-layer-core-real)
|
||||
# Link
|
||||
target_link_libraries(media-layer-core-real media-layer-headers reborn-util pthread dl)
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
# OpenAL
|
||||
find_library(OPENAL_LIBRARY NAMES openal REQUIRED)
|
||||
# Link
|
||||
target_link_libraries(media-layer-core-real png12_static "${OPENAL_LIBRARY}" m GLESv1_CM glfw)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Add Symlinks So MCPI Can Locate Libraries
|
||||
add_library(media-layer-core SHARED ${CORE_SRC}) # Dependencies Are Setup Later
|
||||
# Install
|
||||
install(TARGETS media-layer-core DESTINATION "${MCPI_LIB_DIR}")
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install_symlink("libmedia-layer-core.so" "${MCPI_LIB_DIR}/libSDL-1.2.so.0")
|
||||
install(TARGETS media-layer-core EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
endif()
|
||||
|
||||
# Link
|
||||
target_link_libraries(media-layer-core PUBLIC media-layer-headers PUBLIC reborn-util PUBLIC GLESv1_CM PUBLIC dl)
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
# OpenAL
|
||||
find_library(OPENAL_LIBRARY NAMES openal REQUIRED)
|
||||
# Link
|
||||
target_link_libraries(media-layer-core PRIVATE "${OPENAL_LIBRARY}" PRIVATE m PRIVATE glfw)
|
||||
endif()
|
||||
|
6
media-layer/core/dependencies/CMakeLists.txt
Normal file
6
media-layer/core/dependencies/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
project(media-layer-core-dependencies)
|
||||
|
||||
# GLFW
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
add_subdirectory(glfw)
|
||||
endif()
|
@ -6,7 +6,7 @@ add_compile_options(-w)
|
||||
## GLFW
|
||||
|
||||
# Download
|
||||
set(BUILD_SHARED_LIBS FALSE CACHE BOOL "" FORCE)
|
||||
set(BUILD_SHARED_LIBS TRUE CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_EXAMPLES FALSE CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_TESTS FALSE CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_DOCS FALSE CACHE BOOL "" FORCE)
|
||||
@ -15,8 +15,17 @@ set(GLFW_BUILD_WIN32 FALSE CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_COCOA FALSE CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_X11 TRUE CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_WAYLAND TRUE CACHE BOOL "" FORCE)
|
||||
set(GLFW_LIBRARY_TYPE "STATIC" CACHE BOOL "" FORCE)
|
||||
set(GLFW_LIBRARY_TYPE "SHARED" CACHE BOOL "" FORCE)
|
||||
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||
|
||||
# Ensure Build
|
||||
add_custom_target(glfw-build ALL DEPENDS glfw)
|
||||
|
||||
# Install
|
||||
install(TARGETS glfw DESTINATION "${MCPI_LIB_DIR}")
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS glfw EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
endif()
|
||||
|
||||
# License
|
||||
install(FILES src/LICENSE.md DESTINATION "${MCPI_LEGAL_DIR}/glfw")
|
1
media-layer/core/dependencies/glfw/src
Submodule
1
media-layer/core/dependencies/glfw/src
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c50d53160fa9b579dda0d0a4f9a7c2512940df8e
|
27
media-layer/core/gles/CMakeLists.txt
Normal file
27
media-layer/core/gles/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
||||
project(media-layer-gles)
|
||||
|
||||
# Build
|
||||
if(MCPI_HEADLESS_MODE)
|
||||
# Stubs For Headless Mode
|
||||
set(GLES_SRC src/stubs.c)
|
||||
elseif(MCPI_USE_GLES1_COMPATIBILITY_LAYER)
|
||||
# GLESv1_CM Compatibility Layer
|
||||
set(GLES_SRC src/compatibility-layer/state.c src/compatibility-layer/passthrough.c src/compatibility-layer/matrix.c src/compatibility-layer/draw.c src/compatibility-layer/buffer.cpp)
|
||||
else()
|
||||
# Passthrough To glfwGetProcAddress()
|
||||
set(GLES_SRC src/passthrough.c)
|
||||
endif()
|
||||
add_library(GLESv1_CM SHARED ${GLES_SRC})
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
target_link_libraries(GLESv1_CM PRIVATE glfw PUBLIC reborn-util PRIVATE dl PRIVATE m)
|
||||
endif()
|
||||
|
||||
# Common
|
||||
target_link_libraries(GLESv1_CM PUBLIC media-layer-headers)
|
||||
set_target_properties(GLESv1_CM PROPERTIES SOVERSION "1")
|
||||
# Install
|
||||
install(TARGETS GLESv1_CM DESTINATION "${MCPI_LIB_DIR}")
|
||||
# SDK
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS GLESv1_CM EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
endif()
|
35
media-layer/core/gles/src/compatibility-layer/buffer.cpp
Normal file
35
media-layer/core/gles/src/compatibility-layer/buffer.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#include "../passthrough.h"
|
||||
|
||||
// Store Buffers
|
||||
static std::unordered_map<GLuint, GLuint> buffers_map;
|
||||
// Get Buffer
|
||||
GL_FUNC(glGenBuffers, void, (GLsizei n, GLuint *buffers));
|
||||
static GLuint get_real_buffer(GLuint fake_buffer) {
|
||||
if (buffers_map.count(fake_buffer) > 0) {
|
||||
return buffers_map[fake_buffer];
|
||||
} else {
|
||||
GLuint new_buffer;
|
||||
real_glGenBuffers()(1, &new_buffer);
|
||||
buffers_map[fake_buffer] = new_buffer;
|
||||
return get_real_buffer(fake_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert Fake Buffers To Real Buffers When Calling GL
|
||||
GL_FUNC(glBindBuffer, void, (GLenum target, GLuint buffer));
|
||||
void glBindBuffer(GLenum target, GLuint buffer) {
|
||||
real_glBindBuffer()(target, get_real_buffer(buffer));
|
||||
}
|
||||
GL_FUNC(glDeleteBuffers, void, (GLsizei n, const GLuint *buffers));
|
||||
void glDeleteBuffers(GLsizei n, const GLuint *buffers) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (buffers_map.count(buffers[i]) > 0) {
|
||||
real_glDeleteBuffers()(1, &buffers_map[i]);
|
||||
buffers_map.erase(buffers[i]);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#include "state.h"
|
||||
#include "passthrough.h"
|
||||
#include "../passthrough.h"
|
||||
|
||||
#include <GLES/gl.h>
|
||||
|
||||
@ -157,6 +157,11 @@ static void use_shader(GLuint program) {
|
||||
|
||||
// Array Pointer Drawing
|
||||
GL_FUNC(glDrawArrays, void, (GLenum mode, GLint first, GLsizei count));
|
||||
#define lazy_uniform(name) \
|
||||
static GLint name##_handle = -1; \
|
||||
if (name##_handle == -1) { \
|
||||
name##_handle = real_glGetUniformLocation()(program, #name); \
|
||||
}
|
||||
void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
// Verify
|
||||
if (gl_state.array_pointers.vertex.size != 3 || !gl_state.array_pointers.vertex.enabled || gl_state.array_pointers.vertex.type != GL_FLOAT) {
|
||||
@ -178,30 +183,30 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
use_shader(program);
|
||||
|
||||
// Projection Matrix
|
||||
GLint u_projection_handle = real_glGetUniformLocation()(program, "u_projection");
|
||||
lazy_uniform(u_projection);
|
||||
matrix_t *p = &gl_state.matrix_stacks.projection.stack[gl_state.matrix_stacks.projection.i];
|
||||
real_glUniformMatrix4fv()(u_projection_handle, 1, 0, (GLfloat *) &p->data[0][0]);
|
||||
|
||||
// Model View Matrix
|
||||
GLint u_model_view_handle = real_glGetUniformLocation()(program, "u_model_view");
|
||||
lazy_uniform(u_model_view);
|
||||
p = &gl_state.matrix_stacks.model_view.stack[gl_state.matrix_stacks.model_view.i];
|
||||
real_glUniformMatrix4fv()(u_model_view_handle, 1, 0, (GLfloat *) &p->data[0][0]);
|
||||
|
||||
// Has Texture
|
||||
GLint u_has_texture_handle = real_glGetUniformLocation()(program, "u_has_texture"); \
|
||||
lazy_uniform(u_has_texture); \
|
||||
real_glUniform1i()(u_has_texture_handle, use_texture); \
|
||||
|
||||
// Texture Matrix
|
||||
GLint u_texture_handle = real_glGetUniformLocation()(program, "u_texture");
|
||||
lazy_uniform(u_texture);
|
||||
p = &gl_state.matrix_stacks.texture.stack[gl_state.matrix_stacks.texture.i];
|
||||
real_glUniformMatrix4fv()(u_texture_handle, 1, 0, (GLfloat *) &p->data[0][0]);
|
||||
|
||||
// Texture Unit
|
||||
GLint u_texture_unit_handle = real_glGetUniformLocation()(program, "u_texture_unit");
|
||||
lazy_uniform(u_texture_unit);
|
||||
real_glUniform1i()(u_texture_unit_handle, 0);
|
||||
|
||||
// Alpha Test
|
||||
GLint u_alpha_test_handle = real_glGetUniformLocation()(program, "u_alpha_test");
|
||||
lazy_uniform(u_alpha_test);
|
||||
real_glUniform1i()(u_alpha_test_handle, gl_state.alpha_test);
|
||||
|
||||
// Color
|
||||
@ -214,16 +219,16 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
}
|
||||
|
||||
// Fog
|
||||
GLint u_fog_handle = real_glGetUniformLocation()(program, "u_fog");
|
||||
lazy_uniform(u_fog);
|
||||
real_glUniform1i()(u_fog_handle, gl_state.fog.enabled);
|
||||
if (gl_state.fog.enabled) {
|
||||
GLint u_fog_color_handle = real_glGetUniformLocation()(program, "u_fog_color");
|
||||
lazy_uniform(u_fog_color);
|
||||
real_glUniform4f()(u_fog_color_handle, gl_state.fog.color[0], gl_state.fog.color[1], gl_state.fog.color[2], gl_state.fog.color[3]);
|
||||
GLint u_fog_is_linear_handle = real_glGetUniformLocation()(program, "u_fog_is_linear");
|
||||
lazy_uniform(u_fog_is_linear);
|
||||
real_glUniform1i()(u_fog_is_linear_handle, gl_state.fog.mode == GL_LINEAR);
|
||||
GLint u_fog_start_handle = real_glGetUniformLocation()(program, "u_fog_start");
|
||||
lazy_uniform(u_fog_start);
|
||||
real_glUniform1f()(u_fog_start_handle, gl_state.fog.start);
|
||||
GLint u_fog_end_handle = real_glGetUniformLocation()(program, "u_fog_end");
|
||||
lazy_uniform(u_fog_end);
|
||||
real_glUniform1f()(u_fog_end_handle, gl_state.fog.end);
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#include "state.h"
|
||||
#include "passthrough.h"
|
||||
|
||||
// Matrix Common
|
||||
static void matrix_copy(matrix_t *src, matrix_t *dst) {
|
@ -1,6 +1,6 @@
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#include "passthrough.h"
|
||||
#include "../passthrough.h"
|
||||
|
||||
// Simple v1.1 -> v2.0 Passthrough Functions
|
||||
GL_FUNC(glLineWidth, void, (GLfloat width));
|
||||
@ -43,10 +43,6 @@ GL_FUNC(glDepthFunc, void, (GLenum func));
|
||||
void glDepthFunc(GLenum func) {
|
||||
real_glDepthFunc()(func);
|
||||
}
|
||||
GL_FUNC(glBindBuffer, void, (GLenum target, GLuint buffer));
|
||||
void glBindBuffer(GLenum target, GLuint buffer) {
|
||||
real_glBindBuffer()(target, buffer);
|
||||
}
|
||||
GL_FUNC(glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
|
||||
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
|
||||
real_glClearColor()(red, green, blue, alpha);
|
||||
@ -61,10 +57,6 @@ void glHint(GLenum target, GLenum mode) {
|
||||
real_glHint()(target, mode);
|
||||
}
|
||||
}
|
||||
GL_FUNC(glDeleteBuffers, void, (GLsizei n, const GLuint *buffers));
|
||||
void glDeleteBuffers(GLsizei n, const GLuint *buffers) {
|
||||
real_glDeleteBuffers()(n, buffers);
|
||||
}
|
||||
GL_FUNC(glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha));
|
||||
void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
|
||||
real_glColorMask()(red, green, blue, alpha);
|
@ -1,7 +1,7 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#include "state.h"
|
||||
#include "passthrough.h"
|
||||
#include "../passthrough.h"
|
||||
|
||||
// GL State
|
||||
gl_state_t gl_state = {
|
204
media-layer/core/gles/src/passthrough.c
Normal file
204
media-layer/core/gles/src/passthrough.c
Normal file
@ -0,0 +1,204 @@
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#include "passthrough.h"
|
||||
|
||||
GL_FUNC(glFogfv, void, (GLenum pname, const GLfloat *params));
|
||||
void glFogfv(GLenum pname, const GLfloat *params) {
|
||||
real_glFogfv()(pname, params);
|
||||
}
|
||||
GL_FUNC(glVertexPointer, void, (GLint size, GLenum type, GLsizei stride, const void *pointer));
|
||||
void glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {
|
||||
real_glVertexPointer()(size, type, stride, pointer);
|
||||
}
|
||||
GL_FUNC(glLineWidth, void, (GLfloat width));
|
||||
void glLineWidth(GLfloat width) {
|
||||
real_glLineWidth()(width);
|
||||
}
|
||||
GL_FUNC(glBlendFunc, void, (GLenum sfactor, GLenum dfactor));
|
||||
void glBlendFunc(GLenum sfactor, GLenum dfactor) {
|
||||
real_glBlendFunc()(sfactor, dfactor);
|
||||
}
|
||||
GL_FUNC(glDrawArrays, void, (GLenum mode, GLint first, GLsizei count));
|
||||
void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
real_glDrawArrays()(mode, first, count);
|
||||
}
|
||||
GL_FUNC(glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha));
|
||||
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
|
||||
real_glColor4f()(red, green, blue, alpha);
|
||||
}
|
||||
GL_FUNC(glClear, void, (GLbitfield mask));
|
||||
void glClear(GLbitfield mask) {
|
||||
real_glClear()(mask);
|
||||
}
|
||||
GL_FUNC(glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage));
|
||||
void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) {
|
||||
real_glBufferData()(target, size, data, usage);
|
||||
}
|
||||
GL_FUNC(glFogx, void, (GLenum pname, GLfixed param));
|
||||
void glFogx(GLenum pname, GLfixed param) {
|
||||
real_glFogx()(pname, param);
|
||||
}
|
||||
GL_FUNC(glFogf, void, (GLenum pname, GLfloat param));
|
||||
void glFogf(GLenum pname, GLfloat param) {
|
||||
real_glFogf()(pname, param);
|
||||
}
|
||||
GL_FUNC(glMatrixMode, void, (GLenum mode));
|
||||
void glMatrixMode(GLenum mode) {
|
||||
real_glMatrixMode()(mode);
|
||||
}
|
||||
GL_FUNC(glColorPointer, void, (GLint size, GLenum type, GLsizei stride, const void *pointer));
|
||||
void glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {
|
||||
real_glColorPointer()(size, type, stride, pointer);
|
||||
}
|
||||
GL_FUNC(glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height));
|
||||
void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
real_glScissor()(x, y, width, height);
|
||||
}
|
||||
GL_FUNC(glTexParameteri, void, (GLenum target, GLenum pname, GLint param));
|
||||
void glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||
real_glTexParameteri()(target, pname, param);
|
||||
}
|
||||
GL_FUNC(glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels));
|
||||
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) {
|
||||
real_glTexImage2D()(target, level, internalformat, width, height, border, format, type, pixels);
|
||||
}
|
||||
GL_FUNC(glEnable, void, (GLenum cap));
|
||||
void glEnable(GLenum cap) {
|
||||
real_glEnable()(cap);
|
||||
}
|
||||
GL_FUNC(glEnableClientState, void, (GLenum array));
|
||||
void glEnableClientState(GLenum array) {
|
||||
real_glEnableClientState()(array);
|
||||
}
|
||||
GL_FUNC(glPolygonOffset, void, (GLfloat factor, GLfloat units));
|
||||
void glPolygonOffset(GLfloat factor, GLfloat units) {
|
||||
real_glPolygonOffset()(factor, units);
|
||||
}
|
||||
GL_FUNC(glDisableClientState, void, (GLenum array));
|
||||
void glDisableClientState(GLenum array) {
|
||||
real_glDisableClientState()(array);
|
||||
}
|
||||
GL_FUNC(glDepthRangef, void, (GLclampf near, GLclampf far));
|
||||
void glDepthRangef(GLclampf near, GLclampf far) {
|
||||
real_glDepthRangef()(near, far);
|
||||
}
|
||||
GL_FUNC(glDepthFunc, void, (GLenum func));
|
||||
void glDepthFunc(GLenum func) {
|
||||
real_glDepthFunc()(func);
|
||||
}
|
||||
GL_FUNC(glBindBuffer, void, (GLenum target, GLuint buffer));
|
||||
void glBindBuffer(GLenum target, GLuint buffer) {
|
||||
real_glBindBuffer()(target, buffer);
|
||||
}
|
||||
GL_FUNC(glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
|
||||
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
|
||||
real_glClearColor()(red, green, blue, alpha);
|
||||
}
|
||||
GL_FUNC(glPopMatrix, void, ());
|
||||
void glPopMatrix() {
|
||||
real_glPopMatrix()();
|
||||
}
|
||||
GL_FUNC(glLoadIdentity, void, ());
|
||||
void glLoadIdentity() {
|
||||
real_glLoadIdentity()();
|
||||
}
|
||||
GL_FUNC(glScalef, void, (GLfloat x, GLfloat y, GLfloat z));
|
||||
void glScalef(GLfloat x, GLfloat y, GLfloat z) {
|
||||
real_glScalef()(x, y, z);
|
||||
}
|
||||
GL_FUNC(glPushMatrix, void, ());
|
||||
void glPushMatrix() {
|
||||
real_glPushMatrix()();
|
||||
}
|
||||
GL_FUNC(glDepthMask, void, (GLboolean flag));
|
||||
void glDepthMask(GLboolean flag) {
|
||||
real_glDepthMask()(flag);
|
||||
}
|
||||
GL_FUNC(glHint, void, (GLenum target, GLenum mode));
|
||||
void glHint(GLenum target, GLenum mode) {
|
||||
real_glHint()(target, mode);
|
||||
}
|
||||
GL_FUNC(glMultMatrixf, void, (const GLfloat *m));
|
||||
void glMultMatrixf(const GLfloat *m) {
|
||||
real_glMultMatrixf()(m);
|
||||
}
|
||||
GL_FUNC(glTexCoordPointer, void, (GLint size, GLenum type, GLsizei stride, const void *pointer));
|
||||
void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {
|
||||
real_glTexCoordPointer()(size, type, stride, pointer);
|
||||
}
|
||||
GL_FUNC(glDeleteBuffers, void, (GLsizei n, const GLuint *buffers));
|
||||
void glDeleteBuffers(GLsizei n, const GLuint *buffers) {
|
||||
real_glDeleteBuffers()(n, buffers);
|
||||
}
|
||||
GL_FUNC(glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha));
|
||||
void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
|
||||
real_glColorMask()(red, green, blue, alpha);
|
||||
}
|
||||
GL_FUNC(glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels));
|
||||
void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) {
|
||||
real_glTexSubImage2D()(target, level, xoffset, yoffset, width, height, format, type, pixels);
|
||||
}
|
||||
GL_FUNC(glGenTextures, void, (GLsizei n, GLuint *textures));
|
||||
void glGenTextures(GLsizei n, GLuint *textures) {
|
||||
real_glGenTextures()(n, textures);
|
||||
}
|
||||
GL_FUNC(glDeleteTextures, void, (GLsizei n, const GLuint *textures));
|
||||
void glDeleteTextures(GLsizei n, const GLuint *textures) {
|
||||
real_glDeleteTextures()(n, textures);
|
||||
}
|
||||
GL_FUNC(glAlphaFunc, void, (GLenum func, GLclampf ref));
|
||||
void glAlphaFunc(GLenum func, GLclampf ref) {
|
||||
real_glAlphaFunc()(func, ref);
|
||||
}
|
||||
GL_FUNC(glGetFloatv, void, (GLenum pname, GLfloat *params));
|
||||
void glGetFloatv(GLenum pname, GLfloat *params) {
|
||||
real_glGetFloatv()(pname, params);
|
||||
}
|
||||
GL_FUNC(glBindTexture, void, (GLenum target, GLuint texture));
|
||||
void glBindTexture(GLenum target, GLuint texture) {
|
||||
real_glBindTexture()(target, texture);
|
||||
}
|
||||
GL_FUNC(glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z));
|
||||
void glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
|
||||
real_glTranslatef()(x, y, z);
|
||||
}
|
||||
GL_FUNC(glShadeModel, void, (GLenum mode));
|
||||
void glShadeModel(GLenum mode) {
|
||||
real_glShadeModel()(mode);
|
||||
}
|
||||
GL_FUNC(glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far));
|
||||
void glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far) {
|
||||
real_glOrthof()(left, right, bottom, top, near, far);
|
||||
}
|
||||
GL_FUNC(glDisable, void, (GLenum cap));
|
||||
void glDisable(GLenum cap) {
|
||||
real_glDisable()(cap);
|
||||
}
|
||||
GL_FUNC(glCullFace, void, (GLenum mode));
|
||||
void glCullFace(GLenum mode) {
|
||||
real_glCullFace()(mode);
|
||||
}
|
||||
GL_FUNC(glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z));
|
||||
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
|
||||
real_glRotatef()(angle, x, y, z);
|
||||
}
|
||||
GL_FUNC(glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height));
|
||||
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
real_glViewport()(x, y, width, height);
|
||||
}
|
||||
GL_FUNC(glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz));
|
||||
void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) {
|
||||
real_glNormal3f()(nx, ny, nz);
|
||||
}
|
||||
GL_FUNC(glIsEnabled, GLboolean, (GLenum cap));
|
||||
GLboolean glIsEnabled(GLenum cap) {
|
||||
return real_glIsEnabled()(cap);
|
||||
}
|
||||
GL_FUNC(glGetIntegerv, void, (GLenum pname, GLint *data));
|
||||
void glGetIntegerv(GLenum pname, GLint *data) {
|
||||
real_glGetIntegerv()(pname, data);
|
||||
}
|
||||
GL_FUNC(glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data));
|
||||
void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data) {
|
||||
real_glReadPixels()(x, y, width, height, format, type, data);
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
#define GL_FUNC(name, return_type, args) \
|
||||
typedef return_type (*real_##name##_t)args; \
|
||||
\
|
||||
__attribute__((__unused__)) static real_##name##_t real_##name() { \
|
||||
static real_##name##_t real_##name() { \
|
||||
static real_##name##_t func = NULL; \
|
||||
if (!func) { \
|
||||
func = (real_##name##_t) glfwGetProcAddress(#name); \
|
@ -45,7 +45,11 @@ void glDepthRangef(GLclampf near, GLclampf far) {
|
||||
}
|
||||
void glDepthFunc(GLenum func) {
|
||||
}
|
||||
static GLuint current_buffer = 0;
|
||||
void glBindBuffer(GLenum target, GLuint buffer) {
|
||||
if (target == GL_ARRAY_BUFFER) {
|
||||
current_buffer = buffer;
|
||||
}
|
||||
}
|
||||
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
|
||||
}
|
||||
@ -140,6 +144,10 @@ void glGetIntegerv(GLenum pname, GLint *data) {
|
||||
data[0] = current_texture;
|
||||
break;
|
||||
}
|
||||
case GL_ARRAY_BUFFER_BINDING: {
|
||||
data[0] = current_buffer;
|
||||
break;
|
||||
}
|
||||
case GL_UNPACK_ALIGNMENT: {
|
||||
data[0] = 1;
|
||||
break;
|
@ -8,12 +8,14 @@
|
||||
|
||||
#include "file.h"
|
||||
#include "engine.h"
|
||||
#include "api.h"
|
||||
|
||||
// Store Audio Sources
|
||||
static std::vector<ALuint> &get_sources() {
|
||||
static std::vector<ALuint> sources;
|
||||
return sources;
|
||||
}
|
||||
static std::vector<ALuint> sources;
|
||||
|
||||
// Store Idle Audio Sources
|
||||
#define MAX_IDLE_SOURCES 50
|
||||
static std::vector<ALuint> idle_sources;
|
||||
|
||||
// Error Checking
|
||||
#define AL_ERROR_CHECK() AL_ERROR_CHECK_MANUAL(alGetError())
|
||||
@ -25,6 +27,22 @@ static std::vector<ALuint> &get_sources() {
|
||||
} \
|
||||
}
|
||||
|
||||
// Delete Sources
|
||||
void _media_audio_delete_sources() {
|
||||
if (_media_audio_is_loaded()) {
|
||||
for (ALuint source : idle_sources) {
|
||||
alDeleteSources(1, &source);
|
||||
AL_ERROR_CHECK();
|
||||
}
|
||||
for (ALuint source : sources) {
|
||||
alDeleteSources(1, &source);
|
||||
AL_ERROR_CHECK();
|
||||
}
|
||||
}
|
||||
idle_sources.clear();
|
||||
sources.clear();
|
||||
}
|
||||
|
||||
// Update Listener
|
||||
void media_audio_update(float volume, float x, float y, float z, float yaw) {
|
||||
// Check
|
||||
@ -44,8 +62,8 @@ void media_audio_update(float volume, float x, float y, float z, float yaw) {
|
||||
AL_ERROR_CHECK();
|
||||
|
||||
// Clear Finished Sources
|
||||
std::vector<ALuint>::iterator it = get_sources().begin();
|
||||
while (it != get_sources().end()) {
|
||||
std::vector<ALuint>::iterator it = sources.begin();
|
||||
while (it != sources.end()) {
|
||||
ALuint source = *it;
|
||||
bool remove = false;
|
||||
// Check
|
||||
@ -57,8 +75,12 @@ void media_audio_update(float volume, float x, float y, float z, float yaw) {
|
||||
if (source_state != AL_PLAYING) {
|
||||
// Finished Playing
|
||||
remove = true;
|
||||
alDeleteSources(1, &source);
|
||||
AL_ERROR_CHECK();
|
||||
if (idle_sources.size() < MAX_IDLE_SOURCES) {
|
||||
idle_sources.push_back(source);
|
||||
} else {
|
||||
alDeleteSources(1, &source);
|
||||
AL_ERROR_CHECK();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not A Source
|
||||
@ -66,7 +88,7 @@ void media_audio_update(float volume, float x, float y, float z, float yaw) {
|
||||
}
|
||||
// Remove If Needed
|
||||
if (remove) {
|
||||
it = get_sources().erase(it);
|
||||
it = sources.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
@ -81,16 +103,23 @@ void media_audio_play(const char *source, const char *name, float x, float y, fl
|
||||
// Load Sound
|
||||
ALuint buffer = _media_audio_get_buffer(source, name);
|
||||
if (volume > 0.0f && buffer) {
|
||||
// Create Source
|
||||
// Get Source
|
||||
ALuint al_source;
|
||||
alGenSources(1, &al_source);
|
||||
// Special Out-Of-Memory Handling
|
||||
{
|
||||
ALenum err = alGetError();
|
||||
if (err == AL_OUT_OF_MEMORY) {
|
||||
return;
|
||||
} else {
|
||||
AL_ERROR_CHECK_MANUAL(err);
|
||||
if (idle_sources.size() > 0) {
|
||||
// Use Idle Source
|
||||
al_source = idle_sources.back();
|
||||
idle_sources.pop_back();
|
||||
} else {
|
||||
// Create Source
|
||||
alGenSources(1, &al_source);
|
||||
// Special Out-Of-Memory Handling
|
||||
{
|
||||
ALenum err = alGetError();
|
||||
if (err == AL_OUT_OF_MEMORY) {
|
||||
return;
|
||||
} else {
|
||||
AL_ERROR_CHECK_MANUAL(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,13 +138,13 @@ void media_audio_play(const char *source, const char *name, float x, float y, fl
|
||||
AL_ERROR_CHECK();
|
||||
|
||||
// Set Attenuation
|
||||
alSourcei(al_source, AL_DISTANCE_MODEL, AL_LINEAR_DISTANCE);
|
||||
alSourcei(al_source, AL_DISTANCE_MODEL, AL_LINEAR_DISTANCE_CLAMPED);
|
||||
AL_ERROR_CHECK();
|
||||
alSourcef(al_source, AL_MAX_DISTANCE, 16.0f);
|
||||
alSourcef(al_source, AL_MAX_DISTANCE, 22.0f);
|
||||
AL_ERROR_CHECK();
|
||||
alSourcef(al_source, AL_ROLLOFF_FACTOR, 1.0f);
|
||||
AL_ERROR_CHECK();
|
||||
alSourcef(al_source, AL_REFERENCE_DISTANCE, 0.0f);
|
||||
alSourcef(al_source, AL_REFERENCE_DISTANCE, 2.0f);
|
||||
AL_ERROR_CHECK();
|
||||
|
||||
// Set Buffer
|
||||
@ -125,7 +154,7 @@ void media_audio_play(const char *source, const char *name, float x, float y, fl
|
||||
// Play
|
||||
alSourcePlay(al_source);
|
||||
AL_ERROR_CHECK();
|
||||
get_sources().push_back(al_source);
|
||||
sources.push_back(al_source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
media-layer/core/src/audio/api.h
Normal file
11
media-layer/core/src/audio/api.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__attribute__((visibility("internal"))) void _media_audio_delete_sources();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "engine.h"
|
||||
#include "file.h"
|
||||
#include "api.h"
|
||||
|
||||
// Store Device
|
||||
static ALCdevice *device = NULL;
|
||||
@ -55,6 +56,9 @@ void _media_audio_init() {
|
||||
// De-Init
|
||||
void _media_audio_cleanup() {
|
||||
if (_media_audio_is_loaded()) {
|
||||
// Delete Audio Sources
|
||||
_media_audio_delete_sources();
|
||||
|
||||
// Delete Audio Buffers
|
||||
_media_audio_delete_buffers();
|
||||
|
||||
|
@ -229,7 +229,7 @@ ALuint _media_audio_get_buffer(const char *source, const char *name) {
|
||||
// Delete Buffers
|
||||
void _media_audio_delete_buffers() {
|
||||
if (_media_audio_is_loaded()) {
|
||||
for (auto it : buffers) {
|
||||
for (auto &it : buffers) {
|
||||
if (it.second && alIsBuffer(it.second)) {
|
||||
alDeleteBuffers(1, &it.second);
|
||||
}
|
||||
|
6
media-layer/core/src/audio/stubs.c
Normal file
6
media-layer/core/src/audio/stubs.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <media-layer/audio.h>
|
||||
|
||||
void media_audio_update(__attribute__((unused)) float volume, __attribute__((unused)) float x, __attribute__((unused)) float y, __attribute__((unused)) float z, __attribute__((unused)) float yaw) {
|
||||
}
|
||||
void media_audio_play(__attribute__((unused)) const char *source, __attribute__((unused)) const char *name, __attribute__((unused)) float x, __attribute__((unused)) float y, __attribute__((unused)) float z, __attribute__((unused)) float pitch, __attribute__((unused)) float volume, __attribute__((unused)) int is_ui) {
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
#include <cstdlib>
|
||||
#include <pthread.h>
|
||||
#include <vector>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
@ -15,7 +14,6 @@ int SDL_Init(__attribute__((unused)) uint32_t flags) {
|
||||
|
||||
// Event Queue
|
||||
|
||||
static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static std::vector<SDL_Event> queue;
|
||||
|
||||
int SDL_PollEvent(SDL_Event *event) {
|
||||
@ -23,7 +21,6 @@ int SDL_PollEvent(SDL_Event *event) {
|
||||
_media_handle_SDL_PollEvent();
|
||||
|
||||
// Poll Event
|
||||
pthread_mutex_lock(&queue_mutex);
|
||||
int ret;
|
||||
if (queue.size() > 0) {
|
||||
*event = queue[0];
|
||||
@ -32,14 +29,11 @@ int SDL_PollEvent(SDL_Event *event) {
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&queue_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDL_PushEvent(SDL_Event *event) {
|
||||
pthread_mutex_lock(&queue_mutex);
|
||||
queue.push_back(*event);
|
||||
pthread_mutex_unlock(&queue_mutex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -273,8 +273,6 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||||
#endif
|
||||
// Use EGL
|
||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
|
||||
// Extra Settings
|
||||
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_ALPHA_BITS, 0); // Fix Transparent Window On Wayland
|
||||
|
@ -1,11 +1,5 @@
|
||||
project(media-layer-extras)
|
||||
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
# Add Source To Media Core
|
||||
if(TARGET media-layer-core-real)
|
||||
set(TARGET media-layer-core-real)
|
||||
elseif(TARGET media-layer-proxy-server)
|
||||
set(TARGET media-layer-proxy-server)
|
||||
endif()
|
||||
target_sources("${TARGET}" PRIVATE src/SDL.c)
|
||||
endif()
|
||||
# Build
|
||||
add_library(media-layer-extras OBJECT src/SDL.c)
|
||||
target_link_libraries(media-layer-extras media-layer-headers reborn-util)
|
||||
|
@ -1,29 +0,0 @@
|
||||
project(media-layer-stubs)
|
||||
|
||||
# Stubs Only Needed For ARM
|
||||
if(MCPI_USE_GLES1_COMPATIBILITY_LAYER AND BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
|
||||
# GLESv1_CM Compatibility Layer
|
||||
set(GLES1_LINK_MODE "SHARED")
|
||||
if(MCPI_USE_MEDIA_LAYER_PROXY)
|
||||
# Link To Media Layer Proxy Client Statically
|
||||
# (This is so it doesn't interfere with the Media Layer Proxy Server's libGLESv1_CM.so.1 symlink.)
|
||||
set(GLES1_LINK_MODE "OBJECT")
|
||||
endif()
|
||||
add_library(GLESv1_CM "${GLES1_LINK_MODE}" src/compatibility-layer/state.c src/compatibility-layer/passthrough.c src/compatibility-layer/matrix.c src/compatibility-layer/draw.c)
|
||||
target_link_libraries(GLESv1_CM glfw reborn-util dl m)
|
||||
# Install
|
||||
if(NOT MCPI_USE_MEDIA_LAYER_PROXY)
|
||||
install(TARGETS GLESv1_CM DESTINATION "${MCPI_LIB_DIR}")
|
||||
endif()
|
||||
else()
|
||||
# Add GLESv1_CM Stubs For Linking
|
||||
add_library(GLESv1_CM SHARED src/stubs.c)
|
||||
# Install Fake GLESv1_CM Stubs In Server Mode
|
||||
if(MCPI_HEADLESS_MODE AND BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS GLESv1_CM DESTINATION "${MCPI_LIB_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Common
|
||||
target_link_libraries(GLESv1_CM media-layer-headers)
|
||||
set_target_properties(GLESv1_CM PROPERTIES SOVERSION "1")
|
@ -39,6 +39,7 @@ extern "C" {
|
||||
#define GL_FOG_END 0xb64
|
||||
#define GL_FOG_MODE 0xb65
|
||||
#define GL_FOG_COLOR 0xb66
|
||||
#define GL_BLEND 0xbe2
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
@ -4,15 +4,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MCPI_HEADLESS_MODE
|
||||
void media_audio_update(float volume, float x, float y, float z, float yaw);
|
||||
void media_audio_play(const char *source, const char *name, float x, float y, float z, float pitch, float volume, int is_ui);
|
||||
#else
|
||||
static inline void media_audio_update(__attribute__((unused)) float volume, __attribute__((unused)) float x, __attribute__((unused)) float y, __attribute__((unused)) float z, __attribute__((unused)) float yaw) {
|
||||
}
|
||||
static inline void media_audio_play(__attribute__((unused)) const char *source, __attribute__((unused)) const char *name, __attribute__((unused)) float x, __attribute__((unused)) float y, __attribute__((unused)) float z, __attribute__((unused)) float pitch, __attribute__((unused)) float volume, __attribute__((unused)) int is_ui) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ extern "C" {
|
||||
|
||||
void media_ensure_loaded();
|
||||
|
||||
void media_take_screenshot(char *home);
|
||||
void media_toggle_fullscreen();
|
||||
void media_swap_buffers();
|
||||
void media_cleanup();
|
||||
|
@ -7,21 +7,16 @@ set(MEDIA_LAYER_PROXY_SRC src/common/common.c src/media-layer-core.c src/GLESv1_
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
# Build Media Layer Proxy Client
|
||||
add_executable(media-layer-proxy-client src/client/client.cpp ${MEDIA_LAYER_PROXY_SRC})
|
||||
target_link_libraries(media-layer-proxy-client media-layer-headers reborn-util media-layer-core-real GLESv1_CM)
|
||||
target_link_libraries(media-layer-proxy-client media-layer-headers reborn-util media-layer-core GLESv1_CM)
|
||||
target_compile_definitions(media-layer-proxy-client PRIVATE -DMEDIA_LAYER_PROXY_CLIENT)
|
||||
# Install
|
||||
install(TARGETS media-layer-proxy-client DESTINATION "${MCPI_BIN_DIR}")
|
||||
endif()
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
elseif(BUILD_ARM_COMPONENTS)
|
||||
# Build Media Layer Proxy Server
|
||||
add_library(media-layer-proxy-server SHARED src/server/server.cpp ${MEDIA_LAYER_PROXY_SRC})
|
||||
target_link_libraries(media-layer-proxy-server media-layer-headers reborn-util)
|
||||
target_compile_definitions(media-layer-proxy-server PRIVATE -DMEDIA_LAYER_PROXY_SERVER)
|
||||
set_target_properties(media-layer-proxy-server PROPERTIES OUTPUT_NAME "media-layer-core")
|
||||
# Symlink GLESv1_CM To Media Layer Proxy Server
|
||||
install_symlink("libmedia-layer-core.so" "${MCPI_LIB_DIR}/libGLESv1_CM.so.1")
|
||||
add_library(media-layer-core SHARED src/server/server.cpp ${MEDIA_LAYER_PROXY_SRC} $<TARGET_OBJECTS:media-layer-extras>)
|
||||
target_link_libraries(media-layer-core media-layer-headers reborn-util)
|
||||
target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_PROXY_SERVER)
|
||||
# Install
|
||||
install(TARGETS media-layer-proxy-server DESTINATION "${MCPI_LIB_DIR}")
|
||||
# Create Alias Target For Linking
|
||||
add_library(media-layer-core ALIAS media-layer-proxy-server)
|
||||
install(TARGETS media-layer-core DESTINATION "${MCPI_LIB_DIR}")
|
||||
install(TARGETS media-layer-core EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
endif()
|
||||
|
@ -35,20 +35,45 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Track Bindings
|
||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||
static GLuint bound_buffer = 0;
|
||||
static GLuint bound_texture = 0;
|
||||
static unsigned char vertex_array_enabled = 0;
|
||||
static unsigned char color_array_enabled = 0;
|
||||
static unsigned char tex_coord_array_enabled = 0;
|
||||
static unsigned char *get_array_enabled_pointer(GLenum array) {
|
||||
switch (array) {
|
||||
case GL_VERTEX_ARRAY: {
|
||||
return &vertex_array_enabled;
|
||||
}
|
||||
case GL_COLOR_ARRAY: {
|
||||
return &color_array_enabled;
|
||||
}
|
||||
case GL_TEXTURE_COORD_ARRAY: {
|
||||
return &tex_coord_array_enabled;
|
||||
}
|
||||
default: {
|
||||
ERR("Unsupported Array Pointer: %i", array);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// 'pointer' Is Only Supported As An Integer, Not As An Actual Pointer
|
||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||
#define CALL_GL_POINTER(unique_id, name) \
|
||||
static int is_set_##name = 0; \
|
||||
CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) { \
|
||||
/* Check */ \
|
||||
static int last_set = 0; \
|
||||
static GLint last_size; \
|
||||
static GLenum last_type; \
|
||||
static GLsizei last_stride; \
|
||||
static const void *last_pointer; \
|
||||
if (last_set && last_size == size && last_type == type && last_stride == stride && last_pointer == pointer) { \
|
||||
if (is_set_##name && last_size == size && last_type == type && last_stride == stride && last_pointer == pointer) { \
|
||||
return; \
|
||||
} else { \
|
||||
last_set = 1; \
|
||||
is_set_##name = 1; \
|
||||
last_size = size; \
|
||||
last_type = type; \
|
||||
last_stride = stride; \
|
||||
@ -58,6 +83,7 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) {
|
||||
start_proxy_call(); \
|
||||
\
|
||||
/* Arguments */ \
|
||||
write_int(bound_buffer); \
|
||||
write_int((uint32_t) size); \
|
||||
write_int((uint32_t) type); \
|
||||
write_int((uint32_t) stride); \
|
||||
@ -69,10 +95,11 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) {
|
||||
#else
|
||||
#define CALL_GL_POINTER(unique_id, name) \
|
||||
CALL(unique_id, name, unused, unused) { \
|
||||
/* Setup Buffer Binding */ \
|
||||
GLuint bound_buffer = (GLuint) read_int(); \
|
||||
glBindBuffer(GL_ARRAY_BUFFER, bound_buffer); \
|
||||
/* Check State */ \
|
||||
GLint current_buffer = 0; \
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, ¤t_buffer); \
|
||||
if (current_buffer == 0) { \
|
||||
if (bound_buffer == 0) { \
|
||||
PROXY_ERR("gl*Pointer() Functions Are Only Supported When A Buffer Is Bound To GL_ARRAY_BUFFER"); \
|
||||
} \
|
||||
GLint size = (GLint) read_int(); \
|
||||
@ -122,31 +149,6 @@ CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor)) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Track Bindings
|
||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||
static GLuint bound_buffer = 0;
|
||||
static GLuint bound_texture = 0;
|
||||
static unsigned char vertex_array_enabled = 0;
|
||||
static unsigned char color_array_enabled = 0;
|
||||
static unsigned char tex_coord_array_enabled = 0;
|
||||
static unsigned char *get_array_enabled_pointer(GLenum array) {
|
||||
switch (array) {
|
||||
case GL_VERTEX_ARRAY: {
|
||||
return &vertex_array_enabled;
|
||||
}
|
||||
case GL_COLOR_ARRAY: {
|
||||
return &color_array_enabled;
|
||||
}
|
||||
case GL_TEXTURE_COORD_ARRAY: {
|
||||
return &tex_coord_array_enabled;
|
||||
}
|
||||
default: {
|
||||
ERR("Unsupported Array Pointer: %i", array);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) {
|
||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||
// Lock Proxy
|
||||
@ -524,6 +526,8 @@ CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) {
|
||||
#endif
|
||||
}
|
||||
|
||||
CALL_GL_POINTER(41, glTexCoordPointer)
|
||||
|
||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||
void glDisableClientState(GLenum array) {
|
||||
// Set
|
||||
@ -532,6 +536,23 @@ void glDisableClientState(GLenum array) {
|
||||
return;
|
||||
} else {
|
||||
*enabled = 0;
|
||||
// Not needed when using compatibility layer
|
||||
#ifndef MCPI_USE_GLES1_COMPATIBILITY_LAYER
|
||||
switch (array) {
|
||||
case GL_VERTEX_ARRAY: {
|
||||
is_set_glVertexPointer = 0;
|
||||
break;
|
||||
}
|
||||
case GL_COLOR_ARRAY: {
|
||||
is_set_glColorPointer = 0;
|
||||
break;
|
||||
}
|
||||
case GL_TEXTURE_COORD_ARRAY: {
|
||||
is_set_glTexCoordPointer = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -580,6 +601,12 @@ void glBindBuffer(GLenum target, GLuint buffer) {
|
||||
} else {
|
||||
PROXY_ERR("Unsupported Buffer Binding: %u", target);
|
||||
}
|
||||
// Not needed when using compatibility layer
|
||||
#ifndef MCPI_USE_GLES1_COMPATIBILITY_LAYER
|
||||
is_set_glVertexPointer = 0;
|
||||
is_set_glColorPointer = 0;
|
||||
is_set_glTexCoordPointer = 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -720,8 +747,6 @@ CALL(40, glMultMatrixf, void, (const GLfloat *m)) {
|
||||
#endif
|
||||
}
|
||||
|
||||
CALL_GL_POINTER(41, glTexCoordPointer)
|
||||
|
||||
CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers)) {
|
||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||
// Lock Proxy
|
||||
@ -1135,9 +1160,13 @@ CALL(58, glIsEnabled, GLboolean, (GLenum cap)) {
|
||||
static int get_glGetIntegerv_params_size(GLenum pname) {
|
||||
switch (pname) {
|
||||
case GL_TEXTURE_BINDING_2D:
|
||||
case GL_PACK_ALIGNMENT:
|
||||
case GL_UNPACK_ALIGNMENT: {
|
||||
return 1;
|
||||
}
|
||||
case GL_VIEWPORT: {
|
||||
return 4;
|
||||
}
|
||||
default: {
|
||||
PROXY_ERR("Unsupported glGetIntegerv Property: %u", pname);
|
||||
}
|
||||
@ -1173,3 +1202,43 @@ CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params)) {
|
||||
safe_write((void *) params, sizeof (GLint) * size);
|
||||
#endif
|
||||
}
|
||||
|
||||
CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data)) {
|
||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||
// Get Texture Size
|
||||
int size = get_texture_size(width, height, format, type);
|
||||
|
||||
// Lock Proxy
|
||||
start_proxy_call();
|
||||
|
||||
// Arguments
|
||||
write_int((uint32_t) x);
|
||||
write_int((uint32_t) y);
|
||||
write_int((uint32_t) width);
|
||||
write_int((uint32_t) height);
|
||||
write_int((uint32_t) format);
|
||||
write_int((uint32_t) type);
|
||||
|
||||
// Get Return Value
|
||||
safe_read((void *) data, size);
|
||||
|
||||
// Release Proxy
|
||||
end_proxy_call();
|
||||
#else
|
||||
GLint x = (GLint) read_int();
|
||||
GLint y = (GLint) read_int();
|
||||
GLsizei width = (GLsizei) read_int();
|
||||
GLsizei height = (GLsizei) read_int();
|
||||
GLenum format = (GLenum) read_int();
|
||||
GLenum type = (GLenum) read_int();
|
||||
int size = get_texture_size(width, height, format, type);
|
||||
void *pixels = malloc(size);
|
||||
ALLOC_CHECK(pixels);
|
||||
// Run
|
||||
glReadPixels(x, y, width, height, format, type, pixels);
|
||||
// Return Value
|
||||
safe_write((void *) pixels, (size_t) size);
|
||||
// Free
|
||||
free(pixels);
|
||||
#endif
|
||||
}
|
||||
|
@ -9,13 +9,14 @@
|
||||
#include "../common/common.h"
|
||||
|
||||
// Store Handlers
|
||||
static std::vector<proxy_handler_t> handlers;
|
||||
#define MAX_HANDLERS 100
|
||||
static proxy_handler_t handlers[MAX_HANDLERS];
|
||||
void _add_handler(unsigned char unique_id, proxy_handler_t handler) {
|
||||
if (handlers.size() > unique_id && handlers[unique_id] != NULL) {
|
||||
PROXY_ERR("Duplicate ID: %i", (int) unique_id);
|
||||
if (unique_id >= MAX_HANDLERS) {
|
||||
PROXY_ERR("ID Too Big: %i", (int) unique_id);
|
||||
}
|
||||
if (handlers.size() <= unique_id) {
|
||||
handlers.resize(unique_id + 1);
|
||||
if (handlers[unique_id] != NULL) {
|
||||
PROXY_ERR("Duplicate ID: %i", (int) unique_id);
|
||||
}
|
||||
handlers[unique_id] = handler;
|
||||
}
|
||||
@ -78,7 +79,7 @@ int main(int argc, char *argv[]) {
|
||||
int running = is_connection_open();
|
||||
while (running && !exit_requested) {
|
||||
unsigned char unique_id = read_byte();
|
||||
if (handlers.size() > unique_id && handlers[unique_id] != NULL) {
|
||||
if (handlers[unique_id] != NULL) {
|
||||
// Run Method
|
||||
handlers[unique_id]();
|
||||
// Check If Connection Is Still Open
|
||||
|
@ -56,6 +56,7 @@ void safe_read(void *buf, size_t len) {
|
||||
// Read Remaining Data
|
||||
size_t to_read_to_cache = 0;
|
||||
while (to_read_to_cache < 1) {
|
||||
CHECK_CONNECTION();
|
||||
int bytes_available;
|
||||
if (ioctl(get_connection_read(), FIONREAD, &bytes_available) == -1) {
|
||||
bytes_available = 0;
|
||||
|
@ -176,25 +176,6 @@ CALL(6, SDL_ShowCursor, int, (int32_t toggle)) {
|
||||
#endif
|
||||
}
|
||||
|
||||
CALL(7, media_take_screenshot, void, (char *home)) {
|
||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||
// Lock Proxy
|
||||
start_proxy_call();
|
||||
|
||||
// Arguments
|
||||
write_string(home);
|
||||
|
||||
// Release Proxy
|
||||
end_proxy_call();
|
||||
#else
|
||||
char *home = read_string();
|
||||
// Run
|
||||
media_take_screenshot(home);
|
||||
// Free
|
||||
free(home);
|
||||
#endif
|
||||
}
|
||||
|
||||
CALL(8, media_swap_buffers, void, ()) {
|
||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||
// Lock Proxy
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <csignal>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
@ -65,10 +64,6 @@ static void start_media_layer_proxy_client(int read, int write) {
|
||||
} else if (ret == 0) {
|
||||
// Child Process
|
||||
|
||||
// Prepare Environment
|
||||
RESET_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH");
|
||||
RESET_ENVIRONMENTAL_VARIABLE("LD_PRELOAD");
|
||||
|
||||
// Prepare Arguments
|
||||
char *read_str = NULL;
|
||||
safe_asprintf(&read_str, "%i", read);
|
||||
@ -160,16 +155,12 @@ unsigned char _get_unique_id(const char *name) {
|
||||
return get_unique_ids()[name]; // Assume ID Exists
|
||||
}
|
||||
|
||||
// The Proxy Is Single-Threaded
|
||||
static pthread_mutex_t proxy_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
// Proxy Call Functions
|
||||
void _start_proxy_call(unsigned char call_id) {
|
||||
// Lock Proxy
|
||||
pthread_mutex_lock(&proxy_mutex);
|
||||
// Start Call
|
||||
write_byte(call_id);
|
||||
}
|
||||
void end_proxy_call() {
|
||||
// Flush Write Cache
|
||||
flush_write_cache();
|
||||
// Release Proxy
|
||||
pthread_mutex_unlock(&proxy_mutex);
|
||||
}
|
||||
|
@ -1,85 +1,114 @@
|
||||
project(mods)
|
||||
|
||||
## Headers
|
||||
add_library(mods-headers INTERFACE)
|
||||
target_include_directories(
|
||||
mods-headers
|
||||
INTERFACE
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/mods>"
|
||||
)
|
||||
# SDK
|
||||
install(TARGETS mods-headers EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
install(DIRECTORY "include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/mods")
|
||||
|
||||
## Mods
|
||||
|
||||
add_library(compat SHARED src/compat/compat.c src/compat/egl.c src/compat/x11.c src/compat/bcm_host.c)
|
||||
target_link_libraries(compat reborn-patch media-layer-core)
|
||||
target_link_libraries(compat mods-headers reborn-patch media-layer-core)
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
target_link_libraries(compat screenshot)
|
||||
endif()
|
||||
if(NOT MCPI_SERVER_MODE)
|
||||
target_link_libraries(compat input sign chat home dl)
|
||||
endif()
|
||||
|
||||
add_library(readdir SHARED src/readdir/readdir.c)
|
||||
|
||||
add_library(feature SHARED src/feature/feature.c)
|
||||
target_link_libraries(feature reborn-patch)
|
||||
target_link_libraries(feature mods-headers reborn-patch)
|
||||
|
||||
add_library(version SHARED src/version/version.cpp)
|
||||
target_link_libraries(version reborn-patch symbols)
|
||||
target_link_libraries(version mods-headers reborn-patch symbols)
|
||||
|
||||
add_library(chat SHARED src/chat/chat.cpp src/chat/ui.c)
|
||||
target_link_libraries(chat reborn-patch symbols feature)
|
||||
target_link_libraries(chat mods-headers reborn-patch symbols feature)
|
||||
if(NOT MCPI_SERVER_MODE)
|
||||
target_link_libraries(chat input media-layer-core pthread)
|
||||
endif()
|
||||
|
||||
add_library(creative SHARED src/creative/creative.cpp)
|
||||
target_link_libraries(creative reborn-patch symbols feature)
|
||||
target_link_libraries(creative mods-headers reborn-patch symbols feature misc)
|
||||
|
||||
add_library(game-mode SHARED src/game-mode/game-mode.c src/game-mode/ui.cpp)
|
||||
target_link_libraries(game-mode reborn-patch symbols feature)
|
||||
target_link_libraries(game-mode mods-headers reborn-patch symbols feature)
|
||||
if(NOT MCPI_SERVER_MODE)
|
||||
target_link_libraries(game-mode pthread media-layer-core)
|
||||
endif()
|
||||
|
||||
if(MCPI_SERVER_MODE)
|
||||
add_library(server SHARED src/server/server.cpp src/server/server_properties.cpp)
|
||||
target_link_libraries(server reborn-patch symbols feature home misc compat dl media-layer-core pthread)
|
||||
target_link_libraries(server mods-headers reborn-patch symbols feature home misc compat dl media-layer-core pthread)
|
||||
else()
|
||||
target_link_libraries(compat input sign chat home dl)
|
||||
|
||||
target_link_libraries(chat input media-layer-core pthread)
|
||||
|
||||
target_link_libraries(game-mode pthread media-layer-core)
|
||||
|
||||
add_library(multiplayer SHARED src/multiplayer/multiplayer.cpp)
|
||||
target_link_libraries(multiplayer reborn-patch symbols home feature)
|
||||
target_link_libraries(multiplayer mods-headers reborn-patch symbols home feature)
|
||||
|
||||
add_library(sound SHARED src/sound/sound.cpp src/sound/repository.cpp)
|
||||
target_link_libraries(sound reborn-patch symbols feature override media-layer-core)
|
||||
target_link_libraries(sound mods-headers reborn-patch symbols feature override media-layer-core)
|
||||
|
||||
add_library(camera SHARED src/camera/camera.cpp)
|
||||
target_link_libraries(camera reborn-patch symbols media-layer-core feature home)
|
||||
target_link_libraries(camera mods-headers reborn-patch symbols feature home)
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
target_link_libraries(camera screenshot)
|
||||
endif()
|
||||
|
||||
add_library(input SHARED src/input/input.cpp src/input/bow.c src/input/attack.c src/input/toggle.c src/input/misc.c src/input/drop.cpp)
|
||||
target_link_libraries(input reborn-patch symbols creative feature media-layer-core)
|
||||
target_link_libraries(input mods-headers reborn-patch symbols creative feature misc media-layer-core)
|
||||
|
||||
add_library(sign SHARED src/sign/sign.cpp)
|
||||
target_link_libraries(sign reborn-patch symbols feature input)
|
||||
target_link_libraries(sign mods-headers reborn-patch symbols feature input)
|
||||
|
||||
add_library(touch SHARED src/touch/touch.cpp)
|
||||
target_link_libraries(touch reborn-patch symbols feature)
|
||||
|
||||
add_library(override SHARED src/override/override.c)
|
||||
target_link_libraries(override reborn-patch symbols dl home)
|
||||
target_link_libraries(touch mods-headers reborn-patch symbols feature)
|
||||
|
||||
add_library(textures SHARED src/textures/textures.cpp)
|
||||
target_link_libraries(textures reborn-patch symbols media-layer-core feature misc)
|
||||
target_link_libraries(textures mods-headers reborn-patch symbols media-layer-core feature misc)
|
||||
|
||||
add_library(atlas SHARED src/atlas/atlas.cpp)
|
||||
target_link_libraries(atlas reborn-patch symbols feature GLESv1_CM)
|
||||
target_link_libraries(atlas mods-headers reborn-patch symbols feature media-layer-core)
|
||||
|
||||
add_library(benchmark SHARED src/benchmark/benchmark.cpp)
|
||||
target_link_libraries(benchmark reborn-patch symbols compat misc media-layer-core)
|
||||
target_link_libraries(benchmark mods-headers reborn-patch symbols compat misc media-layer-core)
|
||||
endif()
|
||||
|
||||
add_library(death SHARED src/death/death.cpp)
|
||||
target_link_libraries(death reborn-patch symbols feature)
|
||||
add_library(override SHARED src/override/override.c)
|
||||
target_link_libraries(override mods-headers reborn-patch symbols dl home)
|
||||
|
||||
add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp src/misc/logging.cpp)
|
||||
target_link_libraries(misc reborn-patch symbols media-layer-core feature GLESv1_CM)
|
||||
add_library(death SHARED src/death/death.cpp)
|
||||
target_link_libraries(death mods-headers reborn-patch symbols feature)
|
||||
|
||||
add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp src/misc/logging.cpp src/misc/api.cpp)
|
||||
target_link_libraries(misc mods-headers reborn-patch symbols media-layer-core feature)
|
||||
|
||||
add_library(options SHARED src/options/options.c src/options/options.cpp)
|
||||
target_link_libraries(options reborn-patch symbols feature home)
|
||||
target_link_libraries(options mods-headers reborn-patch symbols feature home)
|
||||
|
||||
add_library(bucket SHARED src/bucket/bucket.cpp)
|
||||
target_link_libraries(bucket mods-headers reborn-patch symbols feature misc)
|
||||
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
add_library(screenshot SHARED src/screenshot/screenshot.c)
|
||||
target_link_libraries(screenshot mods-headers reborn-util media-layer-core png12)
|
||||
endif()
|
||||
|
||||
add_library(home SHARED src/home/home.c)
|
||||
target_link_libraries(home reborn-patch symbols)
|
||||
target_link_libraries(home mods-headers reborn-patch symbols)
|
||||
|
||||
add_library(test SHARED src/test/test.c)
|
||||
target_link_libraries(test reborn-patch home)
|
||||
target_link_libraries(test mods-headers reborn-patch home)
|
||||
|
||||
add_library(init SHARED src/init/init.c)
|
||||
target_link_libraries(init compat game-mode misc death options chat creative home version test media-layer-core)
|
||||
target_link_libraries(init mods-headers compat game-mode misc death options chat creative bucket home version test media-layer-core)
|
||||
if(MCPI_SERVER_MODE)
|
||||
target_link_libraries(init server)
|
||||
else()
|
||||
@ -87,9 +116,15 @@ else()
|
||||
endif()
|
||||
|
||||
## Install Mods
|
||||
install(TARGETS init compat readdir feature game-mode misc death options chat creative home version test DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||
set(MODS_TO_INSTALL init compat readdir feature game-mode misc override death options chat creative bucket home version test)
|
||||
if(MCPI_SERVER_MODE)
|
||||
install(TARGETS server DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||
list(APPEND MODS_TO_INSTALL server)
|
||||
else()
|
||||
install(TARGETS multiplayer sound override camera input sign touch textures atlas benchmark DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||
list(APPEND MODS_TO_INSTALL multiplayer sound camera input sign touch textures atlas benchmark)
|
||||
endif()
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
list(APPEND MODS_TO_INSTALL screenshot)
|
||||
endif()
|
||||
install(TARGETS ${MODS_TO_INSTALL} DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||
# SDK
|
||||
install(TARGETS ${MODS_TO_INSTALL} EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
|
26
mods/include/mods/chat/chat.h
Normal file
26
mods/include/mods/chat/chat.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
// Send API Command
|
||||
std::string chat_send_api_command(unsigned char *minecraft, char *str);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MCPI_SERVER_MODE
|
||||
void chat_open();
|
||||
unsigned int chat_get_counter();
|
||||
#endif
|
||||
|
||||
// Override using the HOOK() macro to provide customized chat behavior.
|
||||
void chat_send_message(unsigned char *server_side_network_handler, char *username, char *message);
|
||||
void chat_handle_packet_send(unsigned char *minecraft, unsigned char *packet);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -27,6 +27,7 @@ void init_misc();
|
||||
void init_death();
|
||||
void init_options();
|
||||
void init_chat();
|
||||
void init_bucket();
|
||||
void init_home();
|
||||
#ifndef MCPI_SERVER_MODE
|
||||
void init_benchmark();
|
@ -17,12 +17,6 @@ void input_set_is_left_click(int val);
|
||||
|
||||
void input_set_mouse_grab_state(int state);
|
||||
|
||||
__attribute__((visibility("internal"))) void _init_attack();
|
||||
__attribute__((visibility("internal"))) void _init_bow();
|
||||
__attribute__((visibility("internal"))) void _init_misc();
|
||||
__attribute__((visibility("internal"))) void _init_toggle();
|
||||
__attribute__((visibility("internal"))) void _init_drop();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
27
mods/include/mods/misc/misc.h
Normal file
27
mods/include/mods/misc/misc.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t misc_get_real_selected_slot(unsigned char *player);
|
||||
|
||||
typedef void (*misc_update_function_t)(unsigned char *obj);
|
||||
void misc_run_on_update(misc_update_function_t function); // obj == Minecraft *
|
||||
void misc_run_on_tick(misc_update_function_t function); // obj == Minecraft *
|
||||
void misc_run_on_recipes_setup(misc_update_function_t function); // obj == Recipes *
|
||||
void misc_run_on_furnace_recipes_setup(misc_update_function_t function); // obj == FurnaceRecipes *
|
||||
void misc_run_on_creative_inventory_setup(misc_update_function_t function); // obj == FillingContainer *
|
||||
void misc_run_on_tiles_setup(misc_update_function_t function); // obj == NULL
|
||||
void misc_run_on_items_setup(misc_update_function_t function); // obj == NULL
|
||||
|
||||
void Level_saveLevelData_injection(unsigned char *level);
|
||||
|
||||
// Use this instead of directly calling Gui::addMessage(), it has proper logging!
|
||||
void misc_add_message(unsigned char *gui, const char *text);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
11
mods/include/mods/screenshot/screenshot.h
Normal file
11
mods/include/mods/screenshot/screenshot.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void screenshot_take(char *home);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user