Compare commits
No commits in common. "master" and "2.4.0" have entirely different histories.
@ -115,37 +115,30 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "${DEFAULT_PREFIX}" CACHE PATH "" FORCE)
|
||||
endif()
|
||||
|
||||
# Required Compile Flags
|
||||
string(CONCAT COMPILE_FLAGS_SETUP
|
||||
# Optimizations
|
||||
"if(CMAKE_BUILD_TYPE STREQUAL \"Release\")\n"
|
||||
" add_compile_options(-O3 -s)\n"
|
||||
"else()\n"
|
||||
" add_compile_options(-g)\n"
|
||||
"endif()\n"
|
||||
# Optimizations
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
add_compile_options(-O3 -s)
|
||||
else()
|
||||
add_compile_options(-g)
|
||||
endif()
|
||||
|
||||
# PIC
|
||||
"set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)\n"
|
||||
# Use LLD When Using Clang
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
add_link_options("-fuse-ld=lld")
|
||||
endif()
|
||||
|
||||
# Warnings
|
||||
"add_link_options(-Wl,--no-undefined)\n"
|
||||
|
||||
# C Standard
|
||||
"add_definitions(-D_GNU_SOURCE)\n"
|
||||
"set(CMAKE_C_STANDARD 99)\n"
|
||||
"set(CMAKE_CXX_STANDARD 11)\n"
|
||||
|
||||
# Skip RPath
|
||||
"set(CMAKE_SKIP_BUILD_RPATH TRUE)"
|
||||
)
|
||||
cmake_language(EVAL CODE "${COMPILE_FLAGS_SETUP}")
|
||||
# PIC
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
|
||||
|
||||
# Fast Math
|
||||
add_compile_options(-ffast-math)
|
||||
|
||||
# Buld Dependencies
|
||||
add_subdirectory(dependencies)
|
||||
|
||||
# Warnings
|
||||
add_compile_options(-Wall -Wextra -Werror -Wpointer-arith -Wshadow -Wnull-dereference)
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL \"GNU\")
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
# Prevents False Positives
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 10.0)
|
||||
add_compile_options(-Wno-stringop-overflow)
|
||||
@ -154,9 +147,10 @@ if(CMAKE_C_COMPILER_ID STREQUAL \"GNU\")
|
||||
add_compile_options(-Wno-array-bounds -Wno-stringop-overread)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Buld Dependencies
|
||||
add_subdirectory(dependencies)
|
||||
add_link_options(-Wl,--no-undefined)
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
# Version
|
||||
set_property(
|
||||
@ -195,15 +189,5 @@ endif()
|
||||
|
||||
# Install SDK
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(EXPORT sdk DESTINATION "${MCPI_SDK_DIR}" FILE "sdk-targets.cmake" EXPORT_LINK_INTERFACE_LIBRARIES)
|
||||
string(CONCAT SDK_SETUP
|
||||
# Compile Flags
|
||||
"${COMPILE_FLAGS_SETUP}\n"
|
||||
# Log
|
||||
"message(STATUS \"Using Reborn SDK v${MCPI_VERSION}\")\n"
|
||||
# Include Targets
|
||||
"include(\"\${CMAKE_CURRENT_LIST_DIR}/sdk-targets.cmake\")\n"
|
||||
)
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake" "${SDK_SETUP}")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake" DESTINATION "${MCPI_SDK_DIR}")
|
||||
install(EXPORT sdk DESTINATION "${MCPI_SDK_DIR}" EXPORT_LINK_INTERFACE_LIBRARIES)
|
||||
endif()
|
||||
|
@ -56,6 +56,7 @@ if(NOT EXISTS "${sysroot_dir}")
|
||||
|
||||
# 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}/*")
|
||||
@ -67,13 +68,6 @@ if(NOT EXISTS "${sysroot_dir}")
|
||||
file(REMOVE "${file}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Setup gconv
|
||||
file(
|
||||
COPY "${toolchain_dir}/arm-none-linux-gnueabihf/libc/usr/lib/gconv/gconv-modules"
|
||||
DESTINATION "${sysroot_dir}/usr/lib/gconv"
|
||||
USE_SOURCE_PERMISSIONS
|
||||
)
|
||||
endif()
|
||||
|
||||
# Install Sysroot (Skipping Empty Directories)
|
||||
|
@ -8,24 +8,3 @@ function(install_symlink target link)
|
||||
file(CREATE_LINK "${target}" "${CMAKE_BINARY_DIR}/symlink/${link}" SYMBOLIC)
|
||||
install(FILES "${CMAKE_BINARY_DIR}/symlink/${link}" DESTINATION "${parent}")
|
||||
endfunction()
|
||||
|
||||
# Embed Resources
|
||||
function(embed_resource target file)
|
||||
# Read Hex Data
|
||||
file(READ "${file}" data HEX)
|
||||
# Convert Hex Data For C Compatibility
|
||||
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," data "${data}")
|
||||
# Get C Name
|
||||
get_filename_component(name "${file}" NAME)
|
||||
string(MAKE_C_IDENTIFIER "${name}" name)
|
||||
# Write Data
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${name}.c" "#include <stddef.h>\nconst unsigned char ${name}[] = {${data}};\nconst size_t ${name}_len = sizeof (${name});\n")
|
||||
# Add To Target
|
||||
target_sources("${target}" PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
|
||||
# Mark Dependency
|
||||
set_property(
|
||||
DIRECTORY
|
||||
APPEND
|
||||
PROPERTY CMAKE_CONFIGURE_DEPENDS "${file}"
|
||||
)
|
||||
endfunction()
|
||||
|
@ -1,16 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
**2.4.3**
|
||||
* Fix Signs With CP-437
|
||||
|
||||
**2.4.2**
|
||||
* Fix Picking Up Lava
|
||||
* Fix Wayland App ID
|
||||
|
||||
**2.4.1**
|
||||
* Allow More Characters In Usernames And Chat
|
||||
* Fix Running On ARMHF Debian Buster
|
||||
|
||||
**2.4.0**
|
||||
* [Modding SDK](../example-mods/README.md)
|
||||
* Cache Blacklist/Whitelist
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Example Mods
|
||||
This is an example of a mod that can be built using the modding SDK.
|
||||
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.
|
||||
|
BIN
images/start.png
BIN
images/start.png
Binary file not shown.
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 156 KiB |
@ -8,8 +8,14 @@ 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()
|
||||
embed_resource(launcher src/client/available-feature-flags)
|
||||
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
|
||||
@ -38,7 +44,7 @@ else()
|
||||
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
|
||||
"Terminal=false\n"
|
||||
"StartupNotify=false\n"
|
||||
"StartupWMClass=${MCPI_APP_ID}\n"
|
||||
"StartupWMClass=${MCPI_APP_TITLE}\n"
|
||||
)
|
||||
endif()
|
||||
install(
|
||||
|
@ -14,6 +14,38 @@
|
||||
#include "patchelf.h"
|
||||
#include "crash-report.h"
|
||||
|
||||
// Set Environmental Variable
|
||||
static void trim(char **value) {
|
||||
// Remove Trailing Colon
|
||||
int length = strlen(*value);
|
||||
if ((*value)[length - 1] == ':') {
|
||||
(*value)[length - 1] = '\0';
|
||||
}
|
||||
if ((*value)[0] == ':') {
|
||||
*value = &(*value)[1];
|
||||
}
|
||||
}
|
||||
void set_and_print_env(const char *name, char *value) {
|
||||
// Set Variable With No Trailing Colon
|
||||
static const char *unmodified_name_prefix = "MCPI_";
|
||||
if (!starts_with(name, unmodified_name_prefix)) {
|
||||
trim(&value);
|
||||
}
|
||||
|
||||
// Print New Value
|
||||
DEBUG("Set %s = %s", name, value);
|
||||
|
||||
// Set The Value
|
||||
setenv(name, value, 1);
|
||||
}
|
||||
|
||||
// Get Environmental Variable
|
||||
static char *get_env_safe(const char *name) {
|
||||
// Get Variable Or Blank String If Not Set
|
||||
char *ret = getenv(name);
|
||||
return ret != NULL ? ret : "";
|
||||
}
|
||||
|
||||
// Get All Mods In Folder
|
||||
static void load(char **ld_preload, char *folder) {
|
||||
int folder_name_length = strlen(folder);
|
||||
@ -53,7 +85,7 @@ static void load(char **ld_preload, char *folder) {
|
||||
string_append(ld_preload, "%s%s", *ld_preload == NULL ? "" : ":", name);
|
||||
} else if (result == -1 && errno != 0) {
|
||||
// Fail
|
||||
WARN("Unable To Access: %s: %s", name, strerror(errno));
|
||||
WARN("Unable To Acesss: %s: %s", name, strerror(errno));
|
||||
errno = 0;
|
||||
}
|
||||
}
|
||||
@ -101,10 +133,6 @@ void pre_bootstrap(int argc, char *argv[]) {
|
||||
// Disable stdout Buffering
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
// Set Default Native Component Environment
|
||||
#define set_variable_default(name) set_and_print_env("MCPI_NATIVE_" name, getenv(name));
|
||||
for_each_special_environmental_variable(set_variable_default);
|
||||
|
||||
// Print Version
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0) {
|
||||
@ -146,12 +174,12 @@ void pre_bootstrap(int argc, char *argv[]) {
|
||||
// Configure PATH
|
||||
{
|
||||
// Add Library Directory
|
||||
char *new_path = NULL;
|
||||
char *new_path;
|
||||
safe_asprintf(&new_path, "%s/bin", binary_directory);
|
||||
// Add Existing PATH
|
||||
{
|
||||
char *value = getenv("PATH");
|
||||
if (value != NULL && strlen(value) > 0) {
|
||||
char *value = get_env_safe("PATH");
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&new_path, ":%s", value);
|
||||
}
|
||||
}
|
||||
@ -303,120 +331,78 @@ void bootstrap(int argc, char *argv[]) {
|
||||
free(resolved_path);
|
||||
|
||||
// Configure Library Search Path
|
||||
char *library_path = NULL;
|
||||
{
|
||||
// Log
|
||||
DEBUG("Setting Linker Search Paths...");
|
||||
|
||||
// Prepare
|
||||
char *transitive_ld_path = NULL;
|
||||
char *mcpi_ld_path = NULL;
|
||||
char *new_ld_path = NULL;
|
||||
|
||||
// Library Search Path For Native Components
|
||||
// Add Native Library Directory
|
||||
safe_asprintf(&new_ld_path, "%s/lib/native", binary_directory);
|
||||
|
||||
// Add LD_LIBRARY_PATH
|
||||
{
|
||||
// Add Native Library Directory
|
||||
safe_asprintf(&transitive_ld_path, "%s/lib/native", binary_directory);
|
||||
|
||||
// Add Host LD_LIBRARY_PATH
|
||||
{
|
||||
char *value = getenv("LD_LIBRARY_PATH");
|
||||
if (value != NULL && strlen(value) > 0) {
|
||||
string_append(&transitive_ld_path, ":%s", value);
|
||||
}
|
||||
char *value = get_env_safe("LD_LIBRARY_PATH");
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&new_ld_path, ":%s", value);
|
||||
}
|
||||
|
||||
// Set
|
||||
set_and_print_env("MCPI_NATIVE_LD_LIBRARY_PATH", transitive_ld_path);
|
||||
free(transitive_ld_path);
|
||||
}
|
||||
|
||||
// Library Search Path For ARM Components
|
||||
{
|
||||
// Add ARM Library Directory
|
||||
safe_asprintf(&mcpi_ld_path, "%s/lib/arm", binary_directory);
|
||||
// Set LD_LIBRARY_PATH (Used For Everything Except MCPI)
|
||||
set_and_print_env("LD_LIBRARY_PATH", new_ld_path);
|
||||
|
||||
// Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System)
|
||||
// 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(&mcpi_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);
|
||||
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 Host LD_LIBRARY_PATH
|
||||
{
|
||||
char *value = getenv("LD_LIBRARY_PATH");
|
||||
if (value != NULL && strlen(value) > 0) {
|
||||
string_append(&mcpi_ld_path, ":%s", value);
|
||||
}
|
||||
}
|
||||
// Add Remaining LD_LIBRARY_PATH
|
||||
string_append(&library_path, ":%s", new_ld_path);
|
||||
|
||||
// Set
|
||||
set_and_print_env("MCPI_ARM_LD_LIBRARY_PATH", mcpi_ld_path);
|
||||
free(mcpi_ld_path);
|
||||
}
|
||||
|
||||
// Setup iconv
|
||||
{
|
||||
// Native Components
|
||||
char *host_gconv_path = getenv("GCONV_PATH");
|
||||
set_and_print_env("MCPI_NATIVE_GCONV_PATH", host_gconv_path);
|
||||
|
||||
// ARM Components
|
||||
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
||||
char *gconv_path = NULL;
|
||||
safe_asprintf(&gconv_path, "%s/sysroot/usr/lib/gconv", binary_directory);
|
||||
set_and_print_env("MCPI_ARM_GCONV_PATH", gconv_path);
|
||||
free(gconv_path);
|
||||
#else
|
||||
set_and_print_env("MCPI_ARM_GCONV_PATH", host_gconv_path);
|
||||
#endif
|
||||
}
|
||||
// Free LD_LIBRARY_PATH
|
||||
free(new_ld_path);
|
||||
}
|
||||
|
||||
// Configure Preloaded Objects
|
||||
// Configure MCPI's Preloaded Objects
|
||||
char *preload = NULL;
|
||||
{
|
||||
// Log
|
||||
DEBUG("Locating Mods...");
|
||||
|
||||
// Native Components
|
||||
char *host_ld_preload = getenv("LD_PRELOAD");
|
||||
set_and_print_env("MCPI_NATIVE_LD_PRELOAD", host_ld_preload);
|
||||
|
||||
// ARM Components
|
||||
// ~/.minecraft-pi/mods
|
||||
{
|
||||
// Prepare
|
||||
char *preload = NULL;
|
||||
// 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(&preload, mods_folder);
|
||||
// Free Mods Folder
|
||||
free(mods_folder);
|
||||
}
|
||||
|
||||
// ~/.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(&preload, mods_folder);
|
||||
// Free Mods Folder
|
||||
free(mods_folder);
|
||||
// Built-In Mods
|
||||
{
|
||||
// Get Mods Folder
|
||||
char *mods_folder = NULL;
|
||||
safe_asprintf(&mods_folder, "%s/mods/", binary_directory);
|
||||
// Load Mods From ./mods
|
||||
load(&preload, mods_folder);
|
||||
// Free Mods Folder
|
||||
free(mods_folder);
|
||||
}
|
||||
|
||||
// Add LD_PRELOAD
|
||||
{
|
||||
char *value = get_env_safe("LD_PRELOAD");
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&preload, ":%s", value);
|
||||
}
|
||||
|
||||
// Built-In Mods
|
||||
{
|
||||
// Get Mods Folder
|
||||
char *mods_folder = NULL;
|
||||
safe_asprintf(&mods_folder, "%s/mods/", binary_directory);
|
||||
// Load Mods From ./mods
|
||||
load(&preload, mods_folder);
|
||||
// Free Mods Folder
|
||||
free(mods_folder);
|
||||
}
|
||||
|
||||
// Add LD_PRELOAD
|
||||
{
|
||||
char *value = getenv("LD_PRELOAD");
|
||||
if (value != NULL && strlen(value) > 0) {
|
||||
string_append(&preload, ":%s", value);
|
||||
}
|
||||
}
|
||||
|
||||
// Set
|
||||
set_and_print_env("MCPI_ARM_LD_PRELOAD", preload);
|
||||
free(preload);
|
||||
}
|
||||
}
|
||||
|
||||
@ -428,17 +414,23 @@ 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
|
||||
@ -446,20 +438,6 @@ void bootstrap(int argc, char *argv[]) {
|
||||
new_args[argv_start] = QEMU_BINARY;
|
||||
#endif
|
||||
|
||||
// Setup Environment
|
||||
setup_exec_environment(1);
|
||||
|
||||
// Pass LD_* Variables Through QEMU
|
||||
#ifndef __ARM_ARCH
|
||||
char *qemu_set_env = NULL;
|
||||
#define pass_variable_through_qemu(name) string_append(&qemu_set_env, "%s%s=%s", qemu_set_env == NULL ? "" : ",", name, getenv(name));
|
||||
for_each_special_environmental_variable(pass_variable_through_qemu);
|
||||
set_and_print_env("QEMU_SET_ENV", qemu_set_env);
|
||||
free(qemu_set_env);
|
||||
// Treat QEMU Itself As A Native Component
|
||||
setup_exec_environment(0);
|
||||
#endif
|
||||
|
||||
// Run
|
||||
const char **new_argv = &new_args[argv_start];
|
||||
safe_execvpe(new_argv, (const char *const *) environ);
|
||||
|
@ -4,6 +4,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void set_and_print_env(const char *name, char *value);
|
||||
|
||||
void pre_bootstrap(int argc, char *argv[]);
|
||||
void bootstrap(int argc, char *argv[]);
|
||||
|
||||
|
@ -37,7 +37,7 @@ static std::string strip_feature_flag_default(std::string flag, bool *default_re
|
||||
|
||||
// Load Available Feature Flags
|
||||
extern unsigned char available_feature_flags[];
|
||||
extern size_t available_feature_flags_len;
|
||||
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();
|
||||
@ -112,7 +112,7 @@ static void run_zenity_and_set_env(const char *env_name, std::vector<std::string
|
||||
full_command.push_back("--title");
|
||||
full_command.push_back(DIALOG_TITLE);
|
||||
full_command.push_back("--name");
|
||||
full_command.push_back(MCPI_APP_ID);
|
||||
full_command.push_back(MCPI_APP_TITLE);
|
||||
full_command.insert(full_command.end(), command.begin(), command.end());
|
||||
// Convert To C Array
|
||||
const char *full_command_array[full_command.size() + 1];
|
||||
|
@ -22,7 +22,7 @@ static void show_report(const char *log_filename) {
|
||||
const char *command[] = {
|
||||
"zenity",
|
||||
"--title", DIALOG_TITLE,
|
||||
"--name", MCPI_APP_ID,
|
||||
"--name", MCPI_APP_TITLE,
|
||||
"--width", CRASH_REPORT_DIALOG_WIDTH,
|
||||
"--height", CRASH_REPORT_DIALOG_HEIGHT,
|
||||
"--text-info",
|
||||
|
@ -1,8 +1,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#include "../bootstrap.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
@ -6,6 +6,5 @@
|
||||
#cmakedefine MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
||||
#cmakedefine MCPI_USE_GLES1_COMPATIBILITY_LAYER
|
||||
#cmakedefine MCPI_APP_TITLE "@MCPI_APP_TITLE@"
|
||||
#cmakedefine MCPI_APP_ID "@MCPI_APP_ID@"
|
||||
#cmakedefine MCPI_VERSION "@MCPI_VERSION@"
|
||||
#cmakedefine MCPI_SDK_DIR "@MCPI_SDK_DIR@"
|
||||
|
@ -16,15 +16,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Set Environmental Variable
|
||||
void set_and_print_env(const char *name, const char *value);
|
||||
|
||||
// Safe execvpe()
|
||||
#define for_each_special_environmental_variable(handle) \
|
||||
handle("LD_LIBRARY_PATH"); \
|
||||
handle("GCONV_PATH"); \
|
||||
handle("LD_PRELOAD");
|
||||
void setup_exec_environment(int is_arm_component);
|
||||
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]);
|
||||
|
||||
// Chop Off Last Component
|
||||
@ -32,6 +24,9 @@ void chop_last_component(char **str);
|
||||
// Get Binary Directory (Remember To Free)
|
||||
char *get_binary_directory();
|
||||
|
||||
// Safe execvpe() Relative To Binary
|
||||
__attribute__((noreturn)) void safe_execvpe_relative_to_binary(const char *const argv[], const char *const envp[]);
|
||||
|
||||
// Run Command And Get Output
|
||||
char *run_command(const char *const command[], int *exit_status);
|
||||
#define is_exit_status_success(status) (WIFEXITED(status) && WEXITSTATUS(status) == 0)
|
||||
|
@ -3,8 +3,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <iconv.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
@ -35,11 +33,6 @@ extern "C" {
|
||||
// Sanitize String
|
||||
void sanitize_string(char **str, int max_length, unsigned int allow_newlines);
|
||||
|
||||
// CP437
|
||||
void safe_iconv(iconv_t cd, char *input, size_t input_size, char *output, size_t output_size);
|
||||
char *to_cp437(const char *input);
|
||||
char *from_cp437(const char *input);
|
||||
|
||||
// Starts With
|
||||
int starts_with(const char *str, const char *prefix);
|
||||
|
||||
|
@ -2,32 +2,7 @@
|
||||
|
||||
#include <libreborn/exec.h>
|
||||
|
||||
// Set Environmental Variable
|
||||
static void setenv_safe(const char *name, const char *value) {
|
||||
if (value != NULL) {
|
||||
setenv(name, value, 1);
|
||||
} else {
|
||||
unsetenv(name);
|
||||
}
|
||||
}
|
||||
void set_and_print_env(const char *name, const char *value) {
|
||||
// Print New Value
|
||||
DEBUG("Set %s = %s", name, value != NULL ? value : "(unset)");
|
||||
|
||||
// Set The Value
|
||||
setenv_safe(name, value);
|
||||
}
|
||||
|
||||
// Safe execvpe()
|
||||
#define handle_environmental_variable(var) \
|
||||
{ \
|
||||
const char *full_var = is_arm_component ? "MCPI_ARM_" var : "MCPI_NATIVE_" var; \
|
||||
const char *var_value = getenv(full_var); \
|
||||
set_and_print_env(var, var_value); \
|
||||
}
|
||||
void setup_exec_environment(int is_arm_component) {
|
||||
for_each_special_environmental_variable(handle_environmental_variable);
|
||||
}
|
||||
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) {
|
||||
// Log
|
||||
DEBUG("Running Command:");
|
||||
@ -70,6 +45,29 @@ char *get_binary_directory() {
|
||||
return exe;
|
||||
}
|
||||
|
||||
// Safe execvpe() Relative To Binary
|
||||
__attribute__((noreturn)) void safe_execvpe_relative_to_binary(const char *const argv[], const char *const envp[]) {
|
||||
// Get Binary Directory
|
||||
char *binary_directory = get_binary_directory();
|
||||
// Create Full Path
|
||||
char *full_path = NULL;
|
||||
safe_asprintf(&full_path, "%s/%s", binary_directory, argv[0]);
|
||||
// Free Binary Directory
|
||||
free(binary_directory);
|
||||
|
||||
// Build New argv
|
||||
int argc;
|
||||
for (argc = 0; argv[argc] != NULL; argc++);
|
||||
const char *new_argv[argc + 1];
|
||||
for (int i = 1; i < argc; i++) {
|
||||
new_argv[i] = argv[i];
|
||||
}
|
||||
new_argv[0] = full_path;
|
||||
new_argv[argc] = NULL;
|
||||
// Run
|
||||
safe_execvpe(new_argv, envp);
|
||||
}
|
||||
|
||||
// Run Command And Get Output
|
||||
char *run_command(const char *const command[], int *exit_status) {
|
||||
// Store Output
|
||||
@ -87,9 +85,6 @@ char *run_command(const char *const command[], int *exit_status) {
|
||||
close(output_pipe[0]);
|
||||
close(output_pipe[1]);
|
||||
|
||||
// Setup Environment
|
||||
setup_exec_environment(0);
|
||||
|
||||
// Run
|
||||
safe_execvpe(command, (const char *const *) environ);
|
||||
} else {
|
||||
|
@ -1,9 +1,8 @@
|
||||
#include <iconv.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <libreborn/string.h>
|
||||
|
||||
// Sanitize String
|
||||
#define MINIMUM_SAFE_CHARACTER 32
|
||||
#define MAXIMUM_SAFE_CHARACTER 126
|
||||
void sanitize_string(char **str, int max_length, unsigned int allow_newlines) {
|
||||
// Store Message Length
|
||||
int length = strlen(*str);
|
||||
@ -13,135 +12,18 @@ void sanitize_string(char **str, int max_length, unsigned int allow_newlines) {
|
||||
length = max_length;
|
||||
}
|
||||
// Loop Through Message
|
||||
if (!allow_newlines) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if ((*str)[i] == '\n' || (*str)[i] == '\r') {
|
||||
// Replace Newline
|
||||
(*str)[i] = ' ';
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (allow_newlines && ((*str)[i] == '\n' || (*str)[i] == '\r')) {
|
||||
continue;
|
||||
}
|
||||
unsigned char c = (unsigned char) (*str)[i];
|
||||
if (c < MINIMUM_SAFE_CHARACTER || c > MAXIMUM_SAFE_CHARACTER) {
|
||||
// Replace Illegal Character
|
||||
(*str)[i] = '?';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Minecraft-Flavored CP437
|
||||
void safe_iconv(iconv_t cd, char *input, size_t input_size, char *output, size_t output_size) {
|
||||
iconv(cd, &input, &input_size, &output, &output_size);
|
||||
}
|
||||
#define CP437_CHARACTERS 256
|
||||
static const char *cp437_characters_map[CP437_CHARACTERS] = {
|
||||
"\0", "☺", "☻", "♥", "♦", "♣", "♠", "•", "◘", "○", "\n", "♂", "♀", "\r", "♫", "☼",
|
||||
"►", "◄", "↕", "‼", "¶", "§", "▬", "↨", "↑", "↓", "→", "←", "∟", "↔", "▲", "▼",
|
||||
" ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/",
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
|
||||
"@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
|
||||
"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_",
|
||||
"`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
|
||||
"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "⌂",
|
||||
"Ç", "ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å",
|
||||
"É", "æ", "Æ", "ô", "ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "₧", "ƒ",
|
||||
"á", "í", "ó", "ú", "ñ", "Ñ", "ª", "º", "¿", "⌐", "¬", "½", "¼", "¡", "«", "»",
|
||||
"░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣", "║", "╗", "╝", "╜", "╛", "┐",
|
||||
"└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠", "═", "╬", "╧",
|
||||
"╨", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀",
|
||||
"α", "ß", "Γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩",
|
||||
"≡", "±", "≥", "≤", "⌠", "⌡", "÷", "≈", "°", "∙", "·", "√", "ⁿ", "²", "■", "©"
|
||||
};
|
||||
static uint32_t *get_cp437_characters_codepoint_map() {
|
||||
static uint32_t map[CP437_CHARACTERS];
|
||||
static int is_setup = 0;
|
||||
if (!is_setup) {
|
||||
// Build Map
|
||||
iconv_t cd = iconv_open("UTF-32LE", "UTF-8");
|
||||
if (cd != (iconv_t) -1) {
|
||||
size_t str_size = 4;
|
||||
uint32_t *str = (uint32_t *) malloc(str_size);
|
||||
ALLOC_CHECK(str);
|
||||
for (int i = 0; i < CP437_CHARACTERS; i++) {
|
||||
// Convert to UTF-32, Then Extract Codepoint
|
||||
safe_iconv(cd, (char *) cp437_characters_map[i], strlen(cp437_characters_map[i]), (char *) str, str_size);
|
||||
// Extract
|
||||
map[i] = str[0];
|
||||
}
|
||||
// Free
|
||||
free(str);
|
||||
iconv_close(cd);
|
||||
} else {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
is_setup = 1;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
char *to_cp437(const char *input) {
|
||||
// Convert To UTF-32 For Easier Parsing
|
||||
size_t in_size = strlen(input);
|
||||
size_t utf32_str_size = in_size * 4;
|
||||
size_t real_utf32_str_size = utf32_str_size + 4 /* NULL-terminator */;
|
||||
uint32_t *utf32_str = (uint32_t *) malloc(real_utf32_str_size);
|
||||
ALLOC_CHECK(utf32_str);
|
||||
memset(utf32_str, 0, real_utf32_str_size);
|
||||
iconv_t cd = iconv_open("UTF-32LE", "UTF-8");
|
||||
if (cd != (iconv_t) -1) {
|
||||
safe_iconv(cd, (char *) input, in_size, (char *) utf32_str, utf32_str_size);
|
||||
iconv_close(cd);
|
||||
} else {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
// Allocate String
|
||||
size_t cp437_str_size;
|
||||
for (cp437_str_size = 0; utf32_str[cp437_str_size] != 0; cp437_str_size++);
|
||||
size_t real_cp437_str_size = cp437_str_size + 1 /* NULL-terminator */;
|
||||
char *cp437_str = (char *) malloc(real_cp437_str_size);
|
||||
ALLOC_CHECK(cp437_str);
|
||||
memset(cp437_str, 0, real_cp437_str_size);
|
||||
// Handle Characters
|
||||
for (size_t i = 0; utf32_str[i] != 0; i++) {
|
||||
uint32_t codepoint = utf32_str[i];
|
||||
for (int j = 0; j < CP437_CHARACTERS; j++) {
|
||||
uint32_t test_codepoint = get_cp437_characters_codepoint_map()[j];
|
||||
if (codepoint == test_codepoint) {
|
||||
cp437_str[i] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cp437_str[i] == '\0') {
|
||||
cp437_str[i] = '?';
|
||||
}
|
||||
}
|
||||
// Free
|
||||
free(utf32_str);
|
||||
// Return
|
||||
return cp437_str;
|
||||
}
|
||||
char *from_cp437(const char *input) {
|
||||
// Convert To UTF-32 For Easier Parsing
|
||||
size_t in_size = strlen(input);
|
||||
size_t utf32_str_size = in_size * 4;
|
||||
size_t real_utf32_str_size = utf32_str_size + 4 /* NULL-terminator */;
|
||||
uint32_t *utf32_str = (uint32_t *) malloc(real_utf32_str_size);
|
||||
ALLOC_CHECK(utf32_str);
|
||||
memset(utf32_str, 0, real_utf32_str_size);
|
||||
// Handle Characters
|
||||
for (size_t i = 0; input[i] != '\0'; i++) {
|
||||
utf32_str[i] = get_cp437_characters_codepoint_map()[(uint32_t) input[i]];
|
||||
}
|
||||
// Convert To UTF-8
|
||||
size_t out_size = utf32_str_size;
|
||||
size_t real_out_size = utf32_str_size + 1 /* NULL-terminator */;
|
||||
char *output = (char *) malloc(real_out_size);
|
||||
ALLOC_CHECK(output);
|
||||
memset(output, 0, real_out_size);
|
||||
iconv_t cd = iconv_open("UTF-8", "UTF-32LE");
|
||||
if (cd != (iconv_t) -1) {
|
||||
safe_iconv(cd, (char *) utf32_str, utf32_str_size, output, out_size);
|
||||
iconv_close(cd);
|
||||
} else {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
// Return
|
||||
return output;
|
||||
}
|
||||
|
||||
// Starts With
|
||||
int starts_with(const char *str, const char *prefix) {
|
||||
return strncmp(prefix, str, strlen(prefix)) == 0;
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c18851f52ec9704eb06464058a600845ec1eada1
|
||||
Subproject commit c50d53160fa9b579dda0d0a4f9a7c2512940df8e
|
@ -14,11 +14,6 @@ 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)
|
||||
# Shaders
|
||||
if(MCPI_USE_GLES1_COMPATIBILITY_LAYER)
|
||||
embed_resource(GLESv1_CM src/compatibility-layer/shaders/main.vert)
|
||||
embed_resource(GLESv1_CM src/compatibility-layer/shaders/main.frag)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Common
|
||||
|
@ -54,16 +54,16 @@ static void log_shader(GLuint shader, const char *name) {
|
||||
ERR("Failed To Compile %s Shader", name);
|
||||
}
|
||||
}
|
||||
static GLuint compile_shader(const char *vertex_shader_text, const int vertex_shader_length, const char *fragment_shader_text, const int fragment_shader_length) {
|
||||
static GLuint compile_shader(const char *vertex_shader_text, const char *fragment_shader_text) {
|
||||
// Vertex Shader
|
||||
const GLuint vertex_shader = real_glCreateShader()(REAL_GL_VERTEX_SHADER);
|
||||
real_glShaderSource()(vertex_shader, 1, &vertex_shader_text, &vertex_shader_length);
|
||||
real_glShaderSource()(vertex_shader, 1, &vertex_shader_text, NULL);
|
||||
real_glCompileShader()(vertex_shader);
|
||||
log_shader(vertex_shader, "Vertex");
|
||||
|
||||
// Fragment Shader
|
||||
const GLuint fragment_shader = real_glCreateShader()(REAL_GL_FRAGMENT_SHADER);
|
||||
real_glShaderSource()(fragment_shader, 1, &fragment_shader_text, &fragment_shader_length);
|
||||
real_glShaderSource()(fragment_shader, 1, &fragment_shader_text, NULL);
|
||||
real_glCompileShader()(fragment_shader);
|
||||
log_shader(fragment_shader, "Fragment");
|
||||
|
||||
@ -78,14 +78,70 @@ static GLuint compile_shader(const char *vertex_shader_text, const int vertex_sh
|
||||
}
|
||||
|
||||
// Shader
|
||||
extern unsigned char main_vert[];
|
||||
extern size_t main_vert_len;
|
||||
extern unsigned char main_frag[];
|
||||
extern size_t main_frag_len;
|
||||
static GLuint get_shader() {
|
||||
static GLuint program = 0;
|
||||
if (program == 0) {
|
||||
program = compile_shader((const char *) main_vert, main_vert_len, (const char *) main_frag, main_frag_len);
|
||||
static const char *vertex_shader_text =
|
||||
"#version 100\n"
|
||||
"precision mediump float;\n"
|
||||
// Matrices
|
||||
"uniform mat4 u_projection;\n"
|
||||
"uniform mat4 u_model_view;\n"
|
||||
"uniform mat4 u_texture;\n"
|
||||
// Texture
|
||||
"attribute vec3 a_vertex_coords;\n"
|
||||
"attribute vec2 a_texture_coords;\n"
|
||||
"varying vec4 v_texture_pos;\n"
|
||||
// Color
|
||||
"attribute vec4 a_color;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
// Fog
|
||||
"varying vec4 v_fog_eye_position;\n"
|
||||
// Main
|
||||
"void main() {\n"
|
||||
" v_texture_pos = u_texture * vec4(a_texture_coords.xy, 0.0, 1.0);\n"
|
||||
" gl_Position = u_projection * u_model_view * vec4(a_vertex_coords.xyz, 1.0);\n"
|
||||
" v_color = a_color;\n"
|
||||
" v_fog_eye_position = u_model_view * vec4(a_vertex_coords.xyz, 1.0);\n"
|
||||
"}";
|
||||
static const char *fragment_shader_text =
|
||||
"#version 100\n"
|
||||
"precision mediump float;\n"
|
||||
// Texture
|
||||
"uniform bool u_has_texture;"
|
||||
"uniform sampler2D u_texture_unit;\n"
|
||||
// Color
|
||||
"varying vec4 v_color;\n"
|
||||
"varying vec4 v_texture_pos;\n"
|
||||
// Alpha Test
|
||||
"uniform bool u_alpha_test;\n"
|
||||
// Fog
|
||||
"uniform bool u_fog;\n"
|
||||
"uniform vec4 u_fog_color;\n"
|
||||
"uniform bool u_fog_is_linear;\n"
|
||||
"uniform float u_fog_start;\n"
|
||||
"uniform float u_fog_end;\n"
|
||||
"varying vec4 v_fog_eye_position;\n"
|
||||
// Main
|
||||
"void main(void) {\n"
|
||||
" gl_FragColor = v_color;\n"
|
||||
" if (u_has_texture) {\n"
|
||||
" gl_FragColor *= texture2D(u_texture_unit, v_texture_pos.xy);\n"
|
||||
" }\n"
|
||||
" if (u_alpha_test && gl_FragColor.a <= 0.1) {\n"
|
||||
" discard;\n"
|
||||
" }\n"
|
||||
" if (u_fog) {\n"
|
||||
" float fog_factor;\n"
|
||||
" if (u_fog_is_linear) {\n"
|
||||
" fog_factor = (u_fog_end - length(v_fog_eye_position)) / (u_fog_end - u_fog_start);\n"
|
||||
" } else {\n"
|
||||
" fog_factor = exp(-u_fog_start * length(v_fog_eye_position));\n"
|
||||
" }\n"
|
||||
" gl_FragColor = mix(gl_FragColor, u_fog_color, 1.0 - clamp(fog_factor, 0.0, 1.0));\n"
|
||||
" }\n"
|
||||
"}";
|
||||
program = compile_shader(vertex_shader_text, fragment_shader_text);
|
||||
}
|
||||
return program;
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
#version 100
|
||||
precision mediump float;
|
||||
// Texture
|
||||
uniform bool u_has_texture;
|
||||
uniform sampler2D u_texture_unit;
|
||||
// Color
|
||||
varying vec4 v_color;
|
||||
varying vec4 v_texture_pos;
|
||||
// Alpha Test
|
||||
uniform bool u_alpha_test;
|
||||
// Fog
|
||||
uniform bool u_fog;
|
||||
uniform vec4 u_fog_color;
|
||||
uniform bool u_fog_is_linear;
|
||||
uniform float u_fog_start;
|
||||
uniform float u_fog_end;
|
||||
varying vec4 v_fog_eye_position;
|
||||
// Main
|
||||
void main(void) {
|
||||
gl_FragColor = v_color;
|
||||
// Texture
|
||||
if (u_has_texture) {
|
||||
gl_FragColor *= texture2D(u_texture_unit, v_texture_pos.xy);
|
||||
}
|
||||
// Alpha Test
|
||||
if (u_alpha_test && gl_FragColor.a <= 0.1) {
|
||||
discard;
|
||||
}
|
||||
// Fog
|
||||
if (u_fog) {
|
||||
float fog_factor;
|
||||
if (u_fog_is_linear) {
|
||||
fog_factor = (u_fog_end - length(v_fog_eye_position)) / (u_fog_end - u_fog_start);
|
||||
} else {
|
||||
fog_factor = exp(-u_fog_start * length(v_fog_eye_position));
|
||||
}
|
||||
gl_FragColor = mix(gl_FragColor, u_fog_color, 1.0 - clamp(fog_factor, 0.0, 1.0));
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#version 100
|
||||
precision mediump float;
|
||||
// Matrices
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_model_view;
|
||||
uniform mat4 u_texture;
|
||||
// Texture
|
||||
attribute vec3 a_vertex_coords;
|
||||
attribute vec2 a_texture_coords;
|
||||
varying vec4 v_texture_pos;
|
||||
// Color
|
||||
attribute vec4 a_color;
|
||||
varying vec4 v_color;
|
||||
// Fog
|
||||
varying vec4 v_fog_eye_position;
|
||||
// Main
|
||||
void main(void) {
|
||||
v_texture_pos = u_texture * vec4(a_texture_coords.xy, 0.0, 1.0);
|
||||
gl_Position = u_projection * u_model_view * vec4(a_vertex_coords.xyz, 1.0);
|
||||
v_color = a_color;
|
||||
v_fog_eye_position = u_model_view * vec4(a_vertex_coords.xyz, 1.0);
|
||||
}
|
@ -155,42 +155,16 @@ static void glfw_key(__attribute__((unused)) GLFWwindow *window, int key, int sc
|
||||
event.key.keysym.mod = glfw_modifier_to_sdl_modifier(mods);
|
||||
event.key.keysym.sym = glfw_key_to_sdl_key(key);
|
||||
SDL_PushEvent(&event);
|
||||
if (key == GLFW_KEY_BACKSPACE && !up) {
|
||||
character_event((char) '\b');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pass Text To Minecraft
|
||||
static void codepoint_to_utf8(unsigned char *const buffer, const unsigned int code) {
|
||||
// https://stackoverflow.com/a/42013433/16198887
|
||||
if (code <= 0x7f) {
|
||||
buffer[0] = code;
|
||||
} else if (code <= 0x7ff) {
|
||||
buffer[0] = 0xc0 | (code >> 6); // 110xxxxx
|
||||
buffer[1] = 0x80 | (code & 0x3f); // 10xxxxxx
|
||||
} else if (code <= 0xffff) {
|
||||
buffer[0] = 0xe0 | (code >> 12); // 1110xxxx
|
||||
buffer[1] = 0x80 | ((code >> 6) & 0x3f); // 10xxxxxx
|
||||
buffer[2] = 0x80 | (code & 0x3f); // 10xxxxxx
|
||||
} else if (code <= 0x10ffff) {
|
||||
buffer[0] = 0xf0 | (code >> 18); // 11110xxx
|
||||
buffer[1] = 0x80 | ((code >> 12) & 0x3f); // 10xxxxxx
|
||||
buffer[2] = 0x80 | ((code >> 6) & 0x3f); // 10xxxxxx
|
||||
buffer[3] = 0x80 | (code & 0x3f); // 10xxxxxx
|
||||
}
|
||||
}
|
||||
static void glfw_char(__attribute__((unused)) GLFWwindow *window, unsigned int codepoint) {
|
||||
if (is_interactable) {
|
||||
// Convert
|
||||
size_t str_size = 4 /* Maximum UTF-8 character size */ + 1 /* NULL-terminator */;
|
||||
char str[str_size];
|
||||
memset(str, 0, str_size);
|
||||
codepoint_to_utf8((unsigned char *) str, codepoint);
|
||||
char *cp437_str = to_cp437(str);
|
||||
// Send Event·
|
||||
for (int i = 0; cp437_str[i] != '\0'; i++) {
|
||||
character_event(cp437_str[i]);
|
||||
}
|
||||
// Free
|
||||
free(cp437_str);
|
||||
character_event((char) codepoint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -316,9 +290,6 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
|
||||
// Extra Settings
|
||||
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_ALPHA_BITS, 0); // Fix Transparent Window On Wayland
|
||||
// App ID
|
||||
glfwWindowHintString(GLFW_X11_CLASS_NAME, MCPI_APP_ID);
|
||||
glfwWindowHintString(GLFW_WAYLAND_APP_ID, MCPI_APP_ID);
|
||||
|
||||
// Create Window
|
||||
glfw_window = glfwCreateWindow(DEFAULT_WIDTH, DEFAULT_HEIGHT, title, NULL, NULL);
|
||||
|
@ -71,9 +71,6 @@ static void start_media_layer_proxy_client(int read, int write) {
|
||||
safe_asprintf(&write_str, "%i", write);
|
||||
const char *argv[] = {"media-layer-proxy-client", read_str, write_str, NULL};
|
||||
|
||||
// Setup Environment
|
||||
setup_exec_environment(0);
|
||||
|
||||
// Run
|
||||
safe_execvpe(argv, (const char *const *) environ);
|
||||
} else {
|
||||
|
@ -66,7 +66,7 @@ else()
|
||||
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 mods-headers reborn-patch symbols feature input media-layer-core)
|
||||
target_link_libraries(sign mods-headers reborn-patch symbols feature input)
|
||||
|
||||
add_library(touch SHARED src/touch/touch.cpp)
|
||||
target_link_libraries(touch mods-headers reborn-patch symbols feature)
|
||||
@ -108,7 +108,7 @@ add_library(test SHARED src/test/test.c)
|
||||
target_link_libraries(test mods-headers reborn-patch home)
|
||||
|
||||
add_library(init SHARED src/init/init.c)
|
||||
target_link_libraries(init mods-headers reborn-util compat game-mode misc death options chat creative bucket 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()
|
||||
|
@ -40,7 +40,7 @@ static int32_t BucketItem_useOn(__attribute__((unused)) unsigned char *item, Ite
|
||||
if (tile == *(int32_t *) (*Tile_calmWater + Tile_id_property_offset)) {
|
||||
new_auxiliary = *(int32_t *) (*Tile_water + Tile_id_property_offset);
|
||||
} else if (tile == *(int32_t *) (*Tile_calmLava + Tile_id_property_offset)) {
|
||||
new_auxiliary = *(int32_t *) (*Tile_lava + Tile_id_property_offset);
|
||||
new_auxiliary = *(int32_t *) (*Tile_water + Tile_id_property_offset);
|
||||
}
|
||||
if (new_auxiliary != 0) {
|
||||
// Valid
|
||||
@ -108,9 +108,6 @@ static int32_t BucketItem_useOn(__attribute__((unused)) unsigned char *item, Ite
|
||||
Material_isSolid_t Material_isSolid = *(Material_isSolid_t *) (material_vtable + Material_isSolid_vtable_offset);
|
||||
valid = !(*Material_isSolid)(material);
|
||||
}
|
||||
if (item_instance->auxiliary != *(int32_t *) (*Tile_water + Tile_id_property_offset) && item_instance->auxiliary != *(int32_t *) (*Tile_lava + Tile_id_property_offset)) {
|
||||
valid = false;
|
||||
}
|
||||
if (valid) {
|
||||
(*Level_setTileAndData)(level, x, y, z, item_instance->auxiliary, 0);
|
||||
item_instance->auxiliary = 0;
|
||||
|
@ -29,7 +29,7 @@ static void *chat_thread(__attribute__((unused)) void *nop) {
|
||||
const char *command[] = {
|
||||
"zenity",
|
||||
"--title", DIALOG_TITLE,
|
||||
"--name", MCPI_APP_ID,
|
||||
"--name", MCPI_APP_TITLE,
|
||||
"--entry",
|
||||
"--text", "Enter Chat Message:",
|
||||
NULL
|
||||
@ -48,9 +48,7 @@ static void *chat_thread(__attribute__((unused)) void *nop) {
|
||||
// Don't Allow Empty Strings
|
||||
if (length > 0) {
|
||||
// Submit
|
||||
char *safe_output = to_cp437(output);
|
||||
_chat_queue_message(safe_output);
|
||||
free(safe_output);
|
||||
_chat_queue_message(output);
|
||||
}
|
||||
}
|
||||
// Free Output
|
||||
|
@ -88,7 +88,7 @@ static void *create_world_thread(__attribute__((unused)) void *nop) {
|
||||
const char *command[] = {
|
||||
"zenity",
|
||||
"--title", DIALOG_TITLE,
|
||||
"--name", MCPI_APP_ID,
|
||||
"--name", MCPI_APP_TITLE,
|
||||
"--entry",
|
||||
"--text", "Enter World Name:",
|
||||
"--entry-text", DEFAULT_WORLD_NAME,
|
||||
@ -115,7 +115,7 @@ static void *create_world_thread(__attribute__((unused)) void *nop) {
|
||||
const char *command[] = {
|
||||
"zenity",
|
||||
"--title", DIALOG_TITLE,
|
||||
"--name", MCPI_APP_ID,
|
||||
"--name", MCPI_APP_TITLE,
|
||||
"--list",
|
||||
"--radiolist",
|
||||
"--width", GAME_MODE_DIALOG_SIZE,
|
||||
@ -148,7 +148,7 @@ static void *create_world_thread(__attribute__((unused)) void *nop) {
|
||||
const char *command[] = {
|
||||
"zenity",
|
||||
"--title", DIALOG_TITLE,
|
||||
"--name", MCPI_APP_ID,
|
||||
"--name", MCPI_APP_TITLE,
|
||||
"--entry",
|
||||
"--only-numerical",
|
||||
"--text", "Enter Seed (Leave Blank For Random):",
|
||||
@ -186,9 +186,7 @@ static void *create_world_thread(__attribute__((unused)) void *nop) {
|
||||
pthread_mutex_lock(&create_world_state_lock);
|
||||
reset_create_world_state();
|
||||
create_world_state.dialog_state = DIALOG_SUCCESS;
|
||||
char *safe_name = to_cp437(world_name);
|
||||
create_world_state.name = safe_name;
|
||||
free(world_name);
|
||||
create_world_state.name = world_name;
|
||||
create_world_state.game_mode = game_mode;
|
||||
create_world_state.seed = seed;
|
||||
pthread_mutex_unlock(&create_world_state_lock);
|
||||
|
@ -20,9 +20,7 @@ static void Gui_addMessage_injection(unsigned char *gui, std::string const& text
|
||||
Gui_addMessage_recursing = true;
|
||||
|
||||
// Print Log Message
|
||||
char *safe_message = from_cp437(new_message);
|
||||
fprintf(stderr, "[CHAT]: %s\n", safe_message);
|
||||
free(safe_message);
|
||||
fprintf(stderr, "[CHAT]: %s\n", new_message);
|
||||
|
||||
// Call Original Method
|
||||
(*Gui_addMessage)(gui, std::string(new_message));
|
||||
|
@ -39,10 +39,6 @@ static char *get_username() {
|
||||
}
|
||||
return username;
|
||||
}
|
||||
static char *safe_username = NULL;
|
||||
__attribute__((destructor)) static void _free_safe_username() {
|
||||
free(safe_username);
|
||||
}
|
||||
|
||||
static int anaglyph;
|
||||
static int render_distance;
|
||||
@ -106,8 +102,7 @@ void init_options() {
|
||||
if (strcmp(*default_username, "StevePi") != 0) {
|
||||
ERR("Default Username Is Invalid");
|
||||
}
|
||||
safe_username = to_cp437(username);
|
||||
patch_address((void *) default_username, (void *) safe_username);
|
||||
patch_address((void *) default_username, (void *) username);
|
||||
|
||||
// Disable Autojump By Default
|
||||
if (feature_has("Disable Autojump By Default", server_disabled)) {
|
||||
|
@ -64,11 +64,7 @@ static ServerProperties &get_server_properties() {
|
||||
|
||||
// Get World Name
|
||||
static std::string get_world_name() {
|
||||
std::string name = get_server_properties().get_string("world-name", DEFAULT_WORLD_NAME);
|
||||
char *safe_name_c = to_cp437(name.c_str());
|
||||
std::string safe_name = safe_name_c;
|
||||
free(safe_name_c);
|
||||
return safe_name;
|
||||
return get_server_properties().get_string("world-name", DEFAULT_WORLD_NAME);
|
||||
}
|
||||
|
||||
// Create/Start World
|
||||
@ -124,12 +120,8 @@ static std::vector<unsigned char *> get_players_in_level(unsigned char *level) {
|
||||
return *(std::vector<unsigned char *> *) (level + Level_players_property_offset);
|
||||
}
|
||||
// Get Player's Username
|
||||
static std::string get_player_username(unsigned char *player) {
|
||||
std::string *username = (std::string *) (player + Player_username_property_offset);
|
||||
char *safe_username_c = from_cp437(username->c_str());
|
||||
std::string safe_username = safe_username_c;
|
||||
free(safe_username_c);
|
||||
return safe_username;
|
||||
static std::string *get_player_username(unsigned char *player) {
|
||||
return (std::string *) (player + Player_username_property_offset);
|
||||
}
|
||||
// Get Level From Minecraft
|
||||
static unsigned char *get_level(unsigned char *minecraft) {
|
||||
@ -145,7 +137,7 @@ static void find_players(unsigned char *minecraft, std::string target_username,
|
||||
for (std::size_t i = 0; i < players.size(); i++) {
|
||||
// Iterate Players
|
||||
unsigned char *player = players[i];
|
||||
std::string username = get_player_username(player);
|
||||
std::string username = *get_player_username(player);
|
||||
if (all_players || username == target_username) {
|
||||
// Run Callback
|
||||
(*callback)(minecraft, username, player);
|
||||
@ -334,11 +326,8 @@ static void handle_commands(unsigned char *minecraft) {
|
||||
} else if (data.rfind(say_command, 0) == 0) {
|
||||
// Format Message
|
||||
std::string message = "[Server] " + data.substr(say_command.length());
|
||||
char *safe_message = to_cp437(message.c_str());
|
||||
// Post Message To Chat
|
||||
(*ServerSideNetworkHandler_displayGameMessage)(server_side_network_handler, safe_message);
|
||||
// Free
|
||||
free(safe_message);
|
||||
(*ServerSideNetworkHandler_displayGameMessage)(server_side_network_handler, message);
|
||||
} else if (data == list_command) {
|
||||
// List Players
|
||||
INFO("All Players:");
|
||||
@ -595,7 +584,7 @@ static void server_init() {
|
||||
// Init Server
|
||||
void init_server() {
|
||||
server_init();
|
||||
set_and_print_env("MCPI_FEATURE_FLAGS", get_features());
|
||||
set_and_print_env("MCPI_RENDER_DISTANCE", "Tiny");
|
||||
set_and_print_env("MCPI_USERNAME", get_motd().c_str());
|
||||
setenv("MCPI_FEATURE_FLAGS", get_features(), 1);
|
||||
setenv("MCPI_RENDER_DISTANCE", "Tiny", 1);
|
||||
setenv("MCPI_USERNAME", get_motd().c_str(), 1);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include <vector>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
@ -9,16 +8,6 @@
|
||||
#include <mods/input/input.h>
|
||||
#include <mods/sign/sign.h>
|
||||
|
||||
// Handle Backspace
|
||||
static int32_t sdl_key_to_minecraft_key_injection(int32_t sdl_key) {
|
||||
if (sdl_key == SDLK_BACKSPACE) {
|
||||
return 8;
|
||||
} else {
|
||||
// Call Original Method
|
||||
return (*sdl_key_to_minecraft_key)(sdl_key);
|
||||
}
|
||||
}
|
||||
|
||||
// Open Sign Screen
|
||||
static void LocalPlayer_openTextEdit_injection(unsigned char *local_player, unsigned char *sign) {
|
||||
if (*(int32_t *) (sign + TileEntity_id_property_offset) == 4) {
|
||||
@ -30,10 +19,18 @@ static void LocalPlayer_openTextEdit_injection(unsigned char *local_player, unsi
|
||||
}
|
||||
}
|
||||
|
||||
#define BACKSPACE_KEY 8
|
||||
|
||||
static int is_valid_key(char key) {
|
||||
return (key >= 32 && key <= 126) || key == BACKSPACE_KEY;
|
||||
}
|
||||
|
||||
// Store Text Input
|
||||
std::vector<char> input;
|
||||
void sign_key_press(char key) {
|
||||
input.push_back(key);
|
||||
if (is_valid_key(key)) {
|
||||
input.push_back(key);
|
||||
}
|
||||
}
|
||||
static void clear_input(__attribute__((unused)) unsigned char *minecraft) {
|
||||
input.clear();
|
||||
@ -44,11 +41,16 @@ static void TextEditScreen_updateEvents_injection(unsigned char *screen) {
|
||||
// Call Original Method
|
||||
(*Screen_updateEvents)(screen);
|
||||
|
||||
if (!*(bool *)(screen + Screen_passthrough_input_property_offset)) {
|
||||
if (*(char *)(screen + 4) == '\0') {
|
||||
unsigned char *vtable = *(unsigned char **) screen;
|
||||
for (char key : input) {
|
||||
// Handle Normal Key
|
||||
(*(Screen_keyboardNewChar_t *) (vtable + Screen_keyboardNewChar_vtable_offset))(screen, key);
|
||||
if (key == BACKSPACE_KEY) {
|
||||
// Handle Backspace
|
||||
(*(Screen_keyPressed_t *) (vtable + Screen_keyPressed_vtable_offset))(screen, BACKSPACE_KEY);
|
||||
} else {
|
||||
// Handle Normal Key
|
||||
(*(Screen_keyboardNewChar_t *) (vtable + Screen_keyboardNewChar_vtable_offset))(screen, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
clear_input(NULL);
|
||||
@ -57,12 +59,10 @@ static void TextEditScreen_updateEvents_injection(unsigned char *screen) {
|
||||
// Init
|
||||
void init_sign() {
|
||||
if (feature_has("Fix Sign Placement", server_disabled)) {
|
||||
// Handle Backspace
|
||||
overwrite_calls((void *) sdl_key_to_minecraft_key, (void *) sdl_key_to_minecraft_key_injection);
|
||||
// Fix Signs
|
||||
patch_address(LocalPlayer_openTextEdit_vtable_addr, (void *) LocalPlayer_openTextEdit_injection);
|
||||
patch_address(TextEditScreen_updateEvents_vtable_addr, (void *) TextEditScreen_updateEvents_injection);
|
||||
// Clear Input On Input Tick
|
||||
// Clear input On Input Tick
|
||||
input_run_on_tick(clear_input);
|
||||
}
|
||||
}
|
||||
|
@ -11,22 +11,20 @@ build() {
|
||||
cd "build/${MODE}-${ARCH}"
|
||||
|
||||
# Create Prefix
|
||||
if [ -z "${DESTDIR+x}" ]; then
|
||||
export DESTDIR="$(cd ../../; pwd)/out/${MODE}-${ARCH}"
|
||||
rm -rf "${DESTDIR}"
|
||||
mkdir -p "${DESTDIR}"
|
||||
fi
|
||||
local prefix="$(cd ../../; pwd)/out/${MODE}-${ARCH}"
|
||||
rm -rf "${prefix}"
|
||||
mkdir -p "${prefix}"
|
||||
|
||||
# Build ARM Components
|
||||
cd arm
|
||||
cmake --build .
|
||||
cmake --install .
|
||||
DESTDIR="${prefix}" cmake --install .
|
||||
cd ../
|
||||
|
||||
# Build Native Components
|
||||
cd native
|
||||
cmake --build .
|
||||
cmake --install .
|
||||
DESTDIR="${prefix}" cmake --install .
|
||||
cd ../
|
||||
|
||||
# Exit
|
||||
|
@ -30,7 +30,8 @@ run() {
|
||||
|
||||
# Host Dependencies Needed For Compile
|
||||
queue_pkg \
|
||||
libwayland-bin
|
||||
libwayland-bin \
|
||||
xxd
|
||||
|
||||
# Host Dependencies Needed For Running
|
||||
queue_pkg \
|
||||
|
@ -18,9 +18,6 @@ static renderCursor_t renderCursor = (renderCursor_t) 0x480c4;
|
||||
typedef void (*sleepMs_t)(int32_t x);
|
||||
static sleepMs_t sleepMs = (sleepMs_t) 0x13cf4;
|
||||
|
||||
typedef int32_t (*sdl_key_to_minecraft_key_t)(int32_t sdl_key);
|
||||
static sdl_key_to_minecraft_key_t sdl_key_to_minecraft_key = (sdl_key_to_minecraft_key_t) 0x1243c;
|
||||
|
||||
static char **default_path = (char **) 0xe264; // /.minecraft/
|
||||
static char **default_username = (char **) 0x18fd4; // StevePi
|
||||
static char **minecraft_pi_version = (char **) 0x39d94; // v0.1.1 alpha
|
||||
@ -557,7 +554,6 @@ static uint32_t Screen_rendered_buttons_property_offset = 0x18; // std::vector<B
|
||||
static uint32_t Screen_selectable_buttons_property_offset = 0x30; // std::vector<Button *>
|
||||
static uint32_t Screen_width_property_offset = 0x8; // int32_t
|
||||
static uint32_t Screen_height_property_offset = 0xc; // int32_t
|
||||
static uint32_t Screen_passthrough_input_property_offset = 0x10; // bool
|
||||
|
||||
// Button
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user