Refactor Launcher
This commit is contained in:
parent
d7616419bc
commit
4d54a9d28c
@ -77,3 +77,6 @@ mcpi_option(APP_TITLE "App Title" STRING "${DEFAULT_APP_TITLE}")
|
|||||||
|
|
||||||
# Skin Server
|
# Skin Server
|
||||||
mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data")
|
mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data")
|
||||||
|
|
||||||
|
# Discord Invite
|
||||||
|
mcpi_option(DISCORD_INVITE "Discord Invite URL" STRING "https://discord.gg/mcpi-revival-740287937727561779")
|
2
dependencies/qemu/CMakeLists.txt
vendored
2
dependencies/qemu/CMakeLists.txt
vendored
@ -30,7 +30,7 @@ ExternalProject_Add(qemu
|
|||||||
"--cross-prefix="
|
"--cross-prefix="
|
||||||
"--cc=${CMAKE_C_COMPILER}"
|
"--cc=${CMAKE_C_COMPILER}"
|
||||||
"--cxx=${CMAKE_CXX_COMPILER}"
|
"--cxx=${CMAKE_CXX_COMPILER}"
|
||||||
"--extra-ldflags=-ldl"
|
"--extra-ldflags=-ldl -Wl,-rpath=$ORIGIN/../lib/native -Wl,--disable-new-dtags"
|
||||||
"--disable-debug-info"
|
"--disable-debug-info"
|
||||||
"--target-list=arm-linux-user"
|
"--target-list=arm-linux-user"
|
||||||
"--without-default-features"
|
"--without-default-features"
|
||||||
|
@ -2,19 +2,19 @@ project(launcher)
|
|||||||
|
|
||||||
# Launcher
|
# Launcher
|
||||||
add_executable(launcher
|
add_executable(launcher
|
||||||
src/bootstrap.c
|
src/bootstrap.cpp
|
||||||
src/patchelf.cpp
|
src/patchelf.cpp
|
||||||
src/util.c
|
src/util.c
|
||||||
src/crash-report.c
|
src/crash-report.c
|
||||||
src/sdk.c
|
src/sdk.cpp
|
||||||
src/mods.c
|
src/mods.cpp
|
||||||
|
src/options/parser.cpp
|
||||||
|
src/main.cpp
|
||||||
)
|
)
|
||||||
if(MCPI_SERVER_MODE)
|
if(NOT MCPI_SERVER_MODE)
|
||||||
target_sources(launcher PRIVATE src/server/launcher.c)
|
|
||||||
else()
|
|
||||||
embed_resource(launcher src/client/available-feature-flags)
|
embed_resource(launcher src/client/available-feature-flags)
|
||||||
target_sources(launcher PRIVATE
|
target_sources(launcher PRIVATE
|
||||||
src/client/launcher.cpp
|
src/client/configuration.cpp
|
||||||
src/client/cache.cpp
|
src/client/cache.cpp
|
||||||
src/client/available-feature-flags # Show In IDE
|
src/client/available-feature-flags # Show In IDE
|
||||||
)
|
)
|
||||||
@ -22,6 +22,7 @@ endif()
|
|||||||
target_link_libraries(launcher reborn-util LIB_LIEF)
|
target_link_libraries(launcher reborn-util LIB_LIEF)
|
||||||
# RPath
|
# RPath
|
||||||
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
|
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
|
||||||
|
target_link_options(launcher PRIVATE "LINKER:--disable-new-dtags")
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")
|
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")
|
||||||
|
@ -1,361 +0,0 @@
|
|||||||
#define _FILE_OFFSET_BITS 64
|
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
#include "bootstrap.h"
|
|
||||||
#include "patchelf.h"
|
|
||||||
#include "crash-report.h"
|
|
||||||
|
|
||||||
#define MCPI_BINARY "minecraft-pi"
|
|
||||||
#define QEMU_BINARY "qemu-arm"
|
|
||||||
|
|
||||||
#define REQUIRED_PAGE_SIZE 4096
|
|
||||||
#define _STR(x) #x
|
|
||||||
#define STR(x) _STR(x)
|
|
||||||
|
|
||||||
// Exit Handler
|
|
||||||
static void exit_handler(__attribute__((unused)) int signal_id) {
|
|
||||||
// Pass Signal To Child
|
|
||||||
murder_children();
|
|
||||||
while (wait(NULL) > 0) {}
|
|
||||||
_exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug Information
|
|
||||||
static void run_debug_command(const char *const command[], const char *prefix) {
|
|
||||||
int status = 0;
|
|
||||||
char *output = run_command(command, &status, NULL);
|
|
||||||
if (output != NULL) {
|
|
||||||
// Remove Newline
|
|
||||||
size_t length = strlen(output);
|
|
||||||
if (length > 0 && output[length - 1] == '\n') {
|
|
||||||
output[length - 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print
|
|
||||||
DEBUG("%s: %s", prefix, output);
|
|
||||||
free(output);
|
|
||||||
}
|
|
||||||
if (!is_exit_status_success(status)) {
|
|
||||||
ERR("Unable To Gather Debug Information");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void print_debug_information() {
|
|
||||||
// System Information
|
|
||||||
const char *const command[] = {"uname", "-a", NULL};
|
|
||||||
run_debug_command(command, "System Information");
|
|
||||||
|
|
||||||
// Version
|
|
||||||
DEBUG("Reborn Version: v%s", MCPI_VERSION);
|
|
||||||
|
|
||||||
// Architecture
|
|
||||||
const char *arch = "Unknown";
|
|
||||||
#ifdef __x86_64__
|
|
||||||
arch = "AMD64";
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
arch = "ARM64";
|
|
||||||
#elif defined(__arm__)
|
|
||||||
arch = "ARM32";
|
|
||||||
#endif
|
|
||||||
DEBUG("Reborn Target Architecture: %s", arch);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pre-Bootstrap
|
|
||||||
void pre_bootstrap(int argc, char *argv[]) {
|
|
||||||
// Set Debug Tag
|
|
||||||
reborn_debug_tag = "(Launcher) ";
|
|
||||||
|
|
||||||
// Disable stdout Buffering
|
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
|
||||||
|
|
||||||
// Print Version
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0) {
|
|
||||||
// Print
|
|
||||||
printf("Reborn v%s\n", MCPI_VERSION);
|
|
||||||
fflush(stdout);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Logging
|
|
||||||
setup_log_file();
|
|
||||||
|
|
||||||
// --debug
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
if (strcmp(argv[i], "--debug") == 0) {
|
|
||||||
set_and_print_env("MCPI_DEBUG", "1");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// GTK Dark Mode
|
|
||||||
#ifndef MCPI_SERVER_MODE
|
|
||||||
set_and_print_env("GTK_THEME", "Adwaita:dark");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Configure PATH
|
|
||||||
{
|
|
||||||
// Get Binary Directory
|
|
||||||
char *binary_directory = get_binary_directory();
|
|
||||||
|
|
||||||
// Add Library Directory
|
|
||||||
char *new_path = NULL;
|
|
||||||
safe_asprintf(&new_path, "%s/bin", binary_directory);
|
|
||||||
// Add Existing PATH
|
|
||||||
{
|
|
||||||
char *value = getenv("PATH");
|
|
||||||
if (value != NULL && strlen(value) > 0) {
|
|
||||||
string_append(&new_path, ":%s", value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Set And Free
|
|
||||||
set_and_print_env("PATH", new_path);
|
|
||||||
free(new_path);
|
|
||||||
|
|
||||||
// Free Binary Directory
|
|
||||||
free(binary_directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --copy-sdk
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
if (strcmp(argv[i], "--copy-sdk") == 0) {
|
|
||||||
char *binary_directory = get_binary_directory();
|
|
||||||
copy_sdk(binary_directory, 0);
|
|
||||||
free(binary_directory);
|
|
||||||
fflush(stdout);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Crash Reports
|
|
||||||
setup_crash_report();
|
|
||||||
|
|
||||||
// AppImage
|
|
||||||
#ifdef MCPI_IS_APPIMAGE_BUILD
|
|
||||||
{
|
|
||||||
char *owd = getenv("OWD");
|
|
||||||
if (owd != NULL && chdir(owd) != 0) {
|
|
||||||
ERR("AppImage: Unable To Fix Current Directory: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Install Signal Handlers
|
|
||||||
struct sigaction act_sigint;
|
|
||||||
memset((void *) &act_sigint, 0, sizeof (struct sigaction));
|
|
||||||
act_sigint.sa_flags = SA_RESTART;
|
|
||||||
act_sigint.sa_handler = &exit_handler;
|
|
||||||
sigaction(SIGINT, &act_sigint, NULL);
|
|
||||||
struct sigaction act_sigterm;
|
|
||||||
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
|
|
||||||
act_sigterm.sa_flags = SA_RESTART;
|
|
||||||
act_sigterm.sa_handler = &exit_handler;
|
|
||||||
sigaction(SIGTERM, &act_sigterm, NULL);
|
|
||||||
|
|
||||||
// Check Page Size (Not Needed When Using QEMU)
|
|
||||||
#ifndef MCPI_USE_QEMU
|
|
||||||
long page_size = sysconf(_SC_PAGESIZE);
|
|
||||||
if (page_size != REQUIRED_PAGE_SIZE) {
|
|
||||||
ERR("Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Debug Information
|
|
||||||
print_debug_information();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bootstrap
|
|
||||||
void bootstrap(int argc, char *argv[]) {
|
|
||||||
INFO("Configuring Game...");
|
|
||||||
|
|
||||||
// Get Binary Directory
|
|
||||||
char *binary_directory = get_binary_directory();
|
|
||||||
DEBUG("Binary Directory: %s", binary_directory);
|
|
||||||
|
|
||||||
// Copy SDK
|
|
||||||
copy_sdk(binary_directory, 1);
|
|
||||||
|
|
||||||
// Set MCPI_REBORN_ASSETS_PATH
|
|
||||||
{
|
|
||||||
char *assets_path = realpath("/proc/self/exe", NULL);
|
|
||||||
ALLOC_CHECK(assets_path);
|
|
||||||
chop_last_component(&assets_path);
|
|
||||||
string_append(&assets_path, "/data");
|
|
||||||
set_and_print_env("MCPI_REBORN_ASSETS_PATH", assets_path);
|
|
||||||
free(assets_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve Binary Path & Set MCPI_DIRECTORY
|
|
||||||
char *resolved_path = NULL;
|
|
||||||
{
|
|
||||||
// Log
|
|
||||||
DEBUG("Resolving File Paths...");
|
|
||||||
|
|
||||||
// Resolve Full Binary Path
|
|
||||||
char *full_path = NULL;
|
|
||||||
safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory);
|
|
||||||
resolved_path = realpath(full_path, NULL);
|
|
||||||
ALLOC_CHECK(resolved_path);
|
|
||||||
free(full_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix MCPI Dependencies
|
|
||||||
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
|
|
||||||
{
|
|
||||||
// Log
|
|
||||||
DEBUG("Patching ELF Dependencies...");
|
|
||||||
|
|
||||||
// Find Linker
|
|
||||||
char *linker = NULL;
|
|
||||||
// Select Linker
|
|
||||||
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
|
||||||
// Use ARM Sysroot Linker
|
|
||||||
safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory);
|
|
||||||
#else
|
|
||||||
// Use Current Linker
|
|
||||||
linker = patch_get_interpreter();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Patch
|
|
||||||
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker);
|
|
||||||
|
|
||||||
// Free Linker Path
|
|
||||||
if (linker != NULL) {
|
|
||||||
free(linker);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify
|
|
||||||
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
|
|
||||||
IMPOSSIBLE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set MCPI_VANILLA_ASSETS_PATH
|
|
||||||
{
|
|
||||||
char *assets_path = strdup(resolved_path);
|
|
||||||
ALLOC_CHECK(assets_path);
|
|
||||||
chop_last_component(&assets_path);
|
|
||||||
string_append(&assets_path, "/data");
|
|
||||||
set_and_print_env("MCPI_VANILLA_ASSETS_PATH", assets_path);
|
|
||||||
free(assets_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free Resolved Path
|
|
||||||
free(resolved_path);
|
|
||||||
|
|
||||||
// Configure Library Search Path
|
|
||||||
{
|
|
||||||
// Log
|
|
||||||
DEBUG("Setting Linker Search Paths...");
|
|
||||||
|
|
||||||
// Prepare
|
|
||||||
char *transitive_ld_path = NULL;
|
|
||||||
char *mcpi_ld_path = NULL;
|
|
||||||
|
|
||||||
// Library Search Path For Native Components
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set
|
|
||||||
set_and_print_env("MCPI_ARM_LD_LIBRARY_PATH", mcpi_ld_path);
|
|
||||||
free(mcpi_ld_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure Preloaded Objects
|
|
||||||
{
|
|
||||||
// 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
|
|
||||||
bootstrap_mods(binary_directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free Binary Directory
|
|
||||||
free(binary_directory);
|
|
||||||
|
|
||||||
// Start Game
|
|
||||||
INFO("Starting Game...");
|
|
||||||
|
|
||||||
// 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 */]; //
|
|
||||||
|
|
||||||
// Copy Existing Arguments
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
new_args[i + argv_start] = argv[i];
|
|
||||||
}
|
|
||||||
// NULL-Terminator
|
|
||||||
new_args[argv_start + argc] = NULL;
|
|
||||||
|
|
||||||
// Set Executable Argument
|
|
||||||
new_args[argv_start] = new_mcpi_exe_path;
|
|
||||||
|
|
||||||
// Non-ARM Systems Need QEMU
|
|
||||||
#ifdef MCPI_USE_QEMU
|
|
||||||
argv_start--;
|
|
||||||
new_args[argv_start] = QEMU_BINARY;
|
|
||||||
// Use 4k Page Size
|
|
||||||
set_and_print_env("QEMU_PAGESIZE", STR(REQUIRED_PAGE_SIZE));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup Environment
|
|
||||||
setup_exec_environment(1);
|
|
||||||
|
|
||||||
// Pass LD_* Variables Through QEMU
|
|
||||||
#ifdef MCPI_USE_QEMU
|
|
||||||
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);
|
|
||||||
}
|
|
226
launcher/src/bootstrap.cpp
Normal file
226
launcher/src/bootstrap.cpp
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "bootstrap.h"
|
||||||
|
#include "patchelf.h"
|
||||||
|
|
||||||
|
#define MCPI_BINARY "minecraft-pi"
|
||||||
|
#define QEMU_BINARY "qemu-arm"
|
||||||
|
|
||||||
|
#define REQUIRED_PAGE_SIZE 4096
|
||||||
|
#define _STR(x) #x
|
||||||
|
#define STR(x) _STR(x)
|
||||||
|
|
||||||
|
// Debug Information
|
||||||
|
static void run_debug_command(const char *const command[], const char *prefix) {
|
||||||
|
int status = 0;
|
||||||
|
char *output = run_command(command, &status, nullptr);
|
||||||
|
if (output != nullptr) {
|
||||||
|
// Remove Newline
|
||||||
|
size_t length = strlen(output);
|
||||||
|
if (length > 0 && output[length - 1] == '\n') {
|
||||||
|
output[length - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print
|
||||||
|
DEBUG("%s: %s", prefix, output);
|
||||||
|
free(output);
|
||||||
|
}
|
||||||
|
if (!is_exit_status_success(status)) {
|
||||||
|
ERR("Unable To Gather Debug Information");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void print_debug_information() {
|
||||||
|
// System Information
|
||||||
|
const char *const command[] = {"uname", "-a", nullptr};
|
||||||
|
run_debug_command(command, "System Information");
|
||||||
|
|
||||||
|
// Version
|
||||||
|
DEBUG("Reborn Version: v%s", MCPI_VERSION);
|
||||||
|
|
||||||
|
// Architecture
|
||||||
|
const char *arch = "Unknown";
|
||||||
|
#ifdef __x86_64__
|
||||||
|
arch = "AMD64";
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
arch = "ARM64";
|
||||||
|
#elif defined(__arm__)
|
||||||
|
arch = "ARM32";
|
||||||
|
#endif
|
||||||
|
DEBUG("Reborn Target Architecture: %s", arch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bootstrap
|
||||||
|
void bootstrap() {
|
||||||
|
// Debug Information
|
||||||
|
print_debug_information();
|
||||||
|
|
||||||
|
// Check Page Size (Not Needed When Using QEMU)
|
||||||
|
#ifndef MCPI_USE_QEMU
|
||||||
|
long page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
if (page_size != REQUIRED_PAGE_SIZE) {
|
||||||
|
ERR("Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
set_and_print_env("QEMU_PAGESIZE", STR(REQUIRED_PAGE_SIZE));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get Binary Directory
|
||||||
|
char *binary_directory_raw = get_binary_directory();
|
||||||
|
const std::string binary_directory = binary_directory_raw;
|
||||||
|
free(binary_directory_raw);
|
||||||
|
DEBUG("Binary Directory: %s", binary_directory.c_str());
|
||||||
|
|
||||||
|
// Copy SDK
|
||||||
|
copy_sdk(binary_directory, true);
|
||||||
|
|
||||||
|
// Set MCPI_REBORN_ASSETS_PATH
|
||||||
|
{
|
||||||
|
char *assets_path = realpath("/proc/self/exe", nullptr);
|
||||||
|
ALLOC_CHECK(assets_path);
|
||||||
|
chop_last_component(&assets_path);
|
||||||
|
string_append(&assets_path, "/data");
|
||||||
|
set_and_print_env("MCPI_REBORN_ASSETS_PATH", assets_path);
|
||||||
|
free(assets_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve Binary Path & Set MCPI_DIRECTORY
|
||||||
|
char *resolved_path = nullptr;
|
||||||
|
{
|
||||||
|
// Log
|
||||||
|
DEBUG("Resolving File Paths...");
|
||||||
|
|
||||||
|
// Resolve Full Binary Path
|
||||||
|
const std::string full_path = binary_directory + ("/" MCPI_BINARY);
|
||||||
|
resolved_path = realpath(full_path.c_str(), nullptr);
|
||||||
|
ALLOC_CHECK(resolved_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix MCPI Dependencies
|
||||||
|
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
|
||||||
|
{
|
||||||
|
// Log
|
||||||
|
DEBUG("Patching ELF Dependencies...");
|
||||||
|
|
||||||
|
// Find Linker
|
||||||
|
char *linker = nullptr;
|
||||||
|
// Select Linker
|
||||||
|
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
||||||
|
// Use ARM Sysroot Linker
|
||||||
|
safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory.c_str());
|
||||||
|
#else
|
||||||
|
// Use Current Linker
|
||||||
|
linker = patch_get_interpreter();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Patch
|
||||||
|
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker);
|
||||||
|
|
||||||
|
// Free Linker Path
|
||||||
|
if (linker != nullptr) {
|
||||||
|
free(linker);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
|
||||||
|
IMPOSSIBLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set MCPI_VANILLA_ASSETS_PATH
|
||||||
|
{
|
||||||
|
char *assets_path = strdup(resolved_path);
|
||||||
|
ALLOC_CHECK(assets_path);
|
||||||
|
chop_last_component(&assets_path);
|
||||||
|
string_append(&assets_path, "/data");
|
||||||
|
set_and_print_env("MCPI_VANILLA_ASSETS_PATH", assets_path);
|
||||||
|
free(assets_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free Resolved Path
|
||||||
|
free(resolved_path);
|
||||||
|
|
||||||
|
// Configure Library Search Path
|
||||||
|
{
|
||||||
|
// Log
|
||||||
|
DEBUG("Setting Linker Search Paths...");
|
||||||
|
|
||||||
|
// Prepare
|
||||||
|
std::string mcpi_ld_path = "";
|
||||||
|
|
||||||
|
// Library Search Path For ARM Components
|
||||||
|
{
|
||||||
|
// Add ARM Library Directory
|
||||||
|
mcpi_ld_path += binary_directory + "/lib/arm:";
|
||||||
|
|
||||||
|
// Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System)
|
||||||
|
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
||||||
|
mcpi_ld_path += binary_directory + "/sysroot/lib:";
|
||||||
|
mcpi_ld_path += binary_directory + "/sysroot/lib/arm-linux-gnueabihf:";
|
||||||
|
mcpi_ld_path += binary_directory + "/sysroot/usr/lib:";
|
||||||
|
mcpi_ld_path += binary_directory + "/sysroot/usr/lib/arm-linux-gnueabihf:";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Add Host LD_LIBRARY_PATH
|
||||||
|
{
|
||||||
|
char *value = getenv("LD_LIBRARY_PATH");
|
||||||
|
if (value != nullptr && strlen(value) > 0) {
|
||||||
|
mcpi_ld_path += value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set
|
||||||
|
set_and_print_env(MCPI_LD_VARIABLE_PREFIX "LD_LIBRARY_PATH", mcpi_ld_path.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure Preloaded Objects
|
||||||
|
{
|
||||||
|
// Log
|
||||||
|
DEBUG("Locating Mods...");
|
||||||
|
|
||||||
|
// ARM Components
|
||||||
|
bootstrap_mods(binary_directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start Game
|
||||||
|
INFO("Starting Game...");
|
||||||
|
|
||||||
|
// Arguments
|
||||||
|
std::vector<std::string> args;
|
||||||
|
// Non-ARM Systems Need QEMU
|
||||||
|
#ifdef MCPI_USE_QEMU
|
||||||
|
args.insert(args.begin(), QEMU_BINARY);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Preserve Existing LD_* Variables
|
||||||
|
#define preserve_variable(name) set_and_print_env(MCPI_ORIGINAL_LD_VARIABLE_PREFIX name, getenv(name))
|
||||||
|
for_each_special_environmental_variable(preserve_variable);
|
||||||
|
set_and_print_env(MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV, "1");
|
||||||
|
// Setup Environment
|
||||||
|
setup_exec_environment(1);
|
||||||
|
|
||||||
|
// Pass LD_* Variables Through QEMU
|
||||||
|
#ifdef MCPI_USE_QEMU
|
||||||
|
#define pass_variable_through_qemu(name) args.push_back("-E"); args.push_back(std::string(name) + "=" + getenv(name))
|
||||||
|
for_each_special_environmental_variable(pass_variable_through_qemu);
|
||||||
|
// Treat QEMU Itself As A Native Component
|
||||||
|
setup_exec_environment(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Specify MCPI Binary
|
||||||
|
args.push_back(new_mcpi_exe_path);
|
||||||
|
|
||||||
|
// Run
|
||||||
|
const char *new_argv[args.size() + 1];
|
||||||
|
for (std::vector<std::string>::size_type i = 0; i < args.size(); i++) {
|
||||||
|
new_argv[i] = args[i].c_str();
|
||||||
|
}
|
||||||
|
new_argv[args.size()] = nullptr;
|
||||||
|
safe_execvpe(new_argv, environ);
|
||||||
|
}
|
@ -1,14 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#include <string>
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void pre_bootstrap(int argc, char *argv[]);
|
void bootstrap();
|
||||||
void bootstrap(int argc, char *argv[]);
|
void copy_sdk(const std::string &binary_directory, bool log_with_debug);
|
||||||
void copy_sdk(char *binary_directory, int log_with_debug);
|
void bootstrap_mods(const std::string &binary_directory);
|
||||||
void bootstrap_mods(char *binary_directory);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
#include "launcher.h"
|
#include "configuration.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
// Get Cache Path
|
// Get Cache Path
|
||||||
|
@ -10,25 +10,24 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
#include "../bootstrap.h"
|
#include "configuration.h"
|
||||||
#include "launcher.h"
|
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
// Strip Feature Flag Default
|
// Strip Feature Flag Default
|
||||||
std::string strip_feature_flag_default(std::string flag, bool *default_ret) {
|
std::string strip_feature_flag_default(const std::string &flag, bool *default_ret) {
|
||||||
// Valid Values
|
// Valid Values
|
||||||
std::string true_str = "TRUE ";
|
std::string true_str = "TRUE ";
|
||||||
std::string false_str = "FALSE ";
|
std::string false_str = "FALSE ";
|
||||||
// Test
|
// Test
|
||||||
if (flag.rfind(true_str, 0) == 0) {
|
if (flag.rfind(true_str, 0) == 0) {
|
||||||
// Enabled By Default
|
// Enabled By Default
|
||||||
if (default_ret != NULL) {
|
if (default_ret != nullptr) {
|
||||||
*default_ret = true;
|
*default_ret = true;
|
||||||
}
|
}
|
||||||
return flag.substr(true_str.length(), std::string::npos);
|
return flag.substr(true_str.length(), std::string::npos);
|
||||||
} else if (flag.rfind(false_str, 0) == 0) {
|
} else if (flag.rfind(false_str, 0) == 0) {
|
||||||
// Disabled By Default
|
// Disabled By Default
|
||||||
if (default_ret != NULL) {
|
if (default_ret != nullptr) {
|
||||||
*default_ret = false;
|
*default_ret = false;
|
||||||
}
|
}
|
||||||
return flag.substr(false_str.length(), std::string::npos);
|
return flag.substr(false_str.length(), std::string::npos);
|
||||||
@ -41,7 +40,7 @@ std::string strip_feature_flag_default(std::string flag, bool *default_ret) {
|
|||||||
// Load Available Feature Flags
|
// Load Available Feature Flags
|
||||||
extern unsigned char available_feature_flags[];
|
extern unsigned char available_feature_flags[];
|
||||||
extern size_t available_feature_flags_len;
|
extern size_t available_feature_flags_len;
|
||||||
void load_available_feature_flags(std::function<void(std::string)> callback) {
|
void load_available_feature_flags(const std::function<void(std::string)> &callback) {
|
||||||
// Get Path
|
// Get Path
|
||||||
char *binary_directory = get_binary_directory();
|
char *binary_directory = get_binary_directory();
|
||||||
std::string path = std::string(binary_directory) + "/available-feature-flags";
|
std::string path = std::string(binary_directory) + "/available-feature-flags";
|
||||||
@ -55,7 +54,7 @@ void load_available_feature_flags(std::function<void(std::string)> callback) {
|
|||||||
{
|
{
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(stream, line)) {
|
while (std::getline(stream, line)) {
|
||||||
if (line.length() > 0) {
|
if (!line.empty()) {
|
||||||
// Verify Line
|
// Verify Line
|
||||||
if (line.find('|') == std::string::npos) {
|
if (line.find('|') == std::string::npos) {
|
||||||
lines.push_back(line);
|
lines.push_back(line);
|
||||||
@ -67,15 +66,15 @@ void load_available_feature_flags(std::function<void(std::string)> callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sort
|
// Sort
|
||||||
std::sort(lines.begin(), lines.end(), [](std::string a, std::string b) {
|
std::sort(lines.begin(), lines.end(), [](const std::string &a, const std::string &b) {
|
||||||
// Strip Defaults
|
// Strip Defaults
|
||||||
std::string stripped_a = strip_feature_flag_default(a, NULL);
|
std::string stripped_a = strip_feature_flag_default(a, nullptr);
|
||||||
std::string stripped_b = strip_feature_flag_default(b, NULL);
|
std::string stripped_b = strip_feature_flag_default(b, nullptr);
|
||||||
// Sort
|
// Sort
|
||||||
return stripped_a < stripped_b;
|
return stripped_a < stripped_b;
|
||||||
});
|
});
|
||||||
// Run Callbacks
|
// Run Callbacks
|
||||||
for (std::string &line : lines) {
|
for (const std::string &line : lines) {
|
||||||
callback(line);
|
callback(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,11 +82,11 @@ void load_available_feature_flags(std::function<void(std::string)> callback) {
|
|||||||
// Run Command And Set Environmental Variable
|
// Run Command And Set Environmental Variable
|
||||||
static void run_command_and_set_env(const char *env_name, const char *command[]) {
|
static void run_command_and_set_env(const char *env_name, const char *command[]) {
|
||||||
// Only Run If Environmental Variable Is NULL
|
// Only Run If Environmental Variable Is NULL
|
||||||
if (getenv(env_name) == NULL) {
|
if (getenv(env_name) == nullptr) {
|
||||||
// Run
|
// Run
|
||||||
int return_code;
|
int return_code;
|
||||||
char *output = run_command(command, &return_code, NULL);
|
char *output = run_command(command, &return_code, nullptr);
|
||||||
if (output != NULL) {
|
if (output != nullptr) {
|
||||||
// Trim
|
// Trim
|
||||||
int length = strlen(output);
|
int length = strlen(output);
|
||||||
if (output[length - 1] == '\n') {
|
if (output[length - 1] == '\n') {
|
||||||
@ -122,14 +121,14 @@ static void run_zenity_and_set_env(const char *env_name, std::vector<std::string
|
|||||||
for (std::vector<std::string>::size_type i = 0; i < full_command.size(); i++) {
|
for (std::vector<std::string>::size_type i = 0; i < full_command.size(); i++) {
|
||||||
full_command_array[i] = full_command[i].c_str();
|
full_command_array[i] = full_command[i].c_str();
|
||||||
}
|
}
|
||||||
full_command_array[full_command.size()] = NULL;
|
full_command_array[full_command.size()] = nullptr;
|
||||||
// Run
|
// Run
|
||||||
run_command_and_set_env(env_name, full_command_array);
|
run_command_and_set_env(env_name, full_command_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Variable If Not Already Set
|
// Set Variable If Not Already Set
|
||||||
static void set_env_if_unset(const char *env_name, std::function<std::string()> callback) {
|
static void set_env_if_unset(const char *env_name, const std::function<std::string()> &callback) {
|
||||||
if (getenv(env_name) == NULL) {
|
if (getenv(env_name) == nullptr) {
|
||||||
char *value = strdup(callback().c_str());
|
char *value = strdup(callback().c_str());
|
||||||
ALLOC_CHECK(value);
|
ALLOC_CHECK(value);
|
||||||
set_and_print_env(env_name, value);
|
set_and_print_env(env_name, value);
|
||||||
@ -137,76 +136,50 @@ static void set_env_if_unset(const char *env_name, std::function<std::string()>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Launch
|
// Handle Non-Launch Commands
|
||||||
#define LIST_DIALOG_SIZE "400"
|
void handle_non_launch_client_only_commands(const options_t &options) {
|
||||||
int main(int argc, char *argv[]) {
|
// Print Available Feature Flags
|
||||||
// Don't Run As Root
|
if (options.print_available_feature_flags) {
|
||||||
if (getenv("_MCPI_SKIP_ROOT_CHECK") == NULL && (getuid() == 0 || geteuid() == 0)) {
|
load_available_feature_flags([](const std::string &line) {
|
||||||
ERR("Don't Run As Root");
|
printf("%s\n", line.c_str());
|
||||||
|
fflush(stdout);
|
||||||
|
});
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure HOME
|
// Check Environment
|
||||||
if (getenv("HOME") == NULL) {
|
void check_environment_client() {
|
||||||
ERR("$HOME Isn't Set");
|
// Don't Run As Root
|
||||||
|
if (getenv("_MCPI_SKIP_ROOT_CHECK") == nullptr && (getuid() == 0 || geteuid() == 0)) {
|
||||||
|
ERR("Don't Run As Root");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check For Display
|
// Check For Display
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
if (getenv("DISPLAY") == NULL && getenv("WAYLAND_DISPLAY") == NULL) {
|
if (getenv("DISPLAY") == nullptr && getenv("WAYLAND_DISPLAY") == nullptr) {
|
||||||
ERR("No display attached! Make sure $DISPLAY or $WAYLAND_DISPLAY is set.");
|
ERR("No display attached! Make sure $DISPLAY or $WAYLAND_DISPLAY is set.");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Print Features
|
// Configure Client Options
|
||||||
for (int i = 1; i < argc; i++) {
|
#define LIST_DIALOG_SIZE "400"
|
||||||
if (strcmp(argv[i], "--print-available-feature-flags") == 0) {
|
void configure_client(const options_t &options) {
|
||||||
// Print Available Feature Flags
|
// Wipe Cache If Needed
|
||||||
load_available_feature_flags([](std::string line) {
|
if (options.wipe_cache) {
|
||||||
printf("%s\n", line.c_str());
|
|
||||||
fflush(stdout);
|
|
||||||
});
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pre-Bootstrap
|
|
||||||
pre_bootstrap(argc, argv);
|
|
||||||
|
|
||||||
// Create ~/.minecraft-pi If Needed
|
|
||||||
{
|
|
||||||
char *minecraft_folder = NULL;
|
|
||||||
safe_asprintf(&minecraft_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA, getenv("HOME"));
|
|
||||||
const char *const command[] = {"mkdir", "-p", minecraft_folder, NULL};
|
|
||||||
run_simple_command(command, "Unable To Create Data Directory");
|
|
||||||
free(minecraft_folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --wipe-cache
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
if (strcmp(argv[i], "--wipe-cache") == 0) {
|
|
||||||
wipe_cache();
|
wipe_cache();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --no-cache
|
|
||||||
bool no_cache = false;
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
if (strcmp(argv[i], "--no-cache") == 0) {
|
|
||||||
no_cache = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Load Cache
|
// Load Cache
|
||||||
launcher_cache cache = no_cache ? empty_cache : load_cache();
|
launcher_cache cache = options.no_cache ? empty_cache : load_cache();
|
||||||
|
|
||||||
// --default
|
// --default
|
||||||
for (int i = 1; i < argc; i++) {
|
if (options.use_default) {
|
||||||
if (strcmp(argv[i], "--default") == 0) {
|
|
||||||
// Use Default Feature Flags
|
// Use Default Feature Flags
|
||||||
set_env_if_unset("MCPI_FEATURE_FLAGS", [&cache]() {
|
set_env_if_unset("MCPI_FEATURE_FLAGS", [&cache]() {
|
||||||
std::string feature_flags = "";
|
std::string feature_flags = "";
|
||||||
load_available_feature_flags([&feature_flags, &cache](std::string flag) {
|
load_available_feature_flags([&feature_flags, &cache](const std::string &flag) {
|
||||||
bool value;
|
bool value;
|
||||||
// Strip Default Value
|
// Strip Default Value
|
||||||
std::string stripped_flag = strip_feature_flag_default(flag, &value);
|
std::string stripped_flag = strip_feature_flag_default(flag, &value);
|
||||||
@ -220,7 +193,7 @@ int main(int argc, char *argv[]) {
|
|||||||
feature_flags += stripped_flag + '|';
|
feature_flags += stripped_flag + '|';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (feature_flags.length() > 0 && feature_flags[feature_flags.length() - 1] == '|') {
|
if (!feature_flags.empty() && feature_flags[feature_flags.length() - 1] == '|') {
|
||||||
feature_flags.pop_back();
|
feature_flags.pop_back();
|
||||||
}
|
}
|
||||||
return feature_flags;
|
return feature_flags;
|
||||||
@ -231,8 +204,6 @@ int main(int argc, char *argv[]) {
|
|||||||
set_env_if_unset("MCPI_USERNAME", [&cache]() {
|
set_env_if_unset("MCPI_USERNAME", [&cache]() {
|
||||||
return cache.username;
|
return cache.username;
|
||||||
});
|
});
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup MCPI_FEATURE_FLAGS
|
// Setup MCPI_FEATURE_FLAGS
|
||||||
@ -248,7 +219,7 @@ int main(int argc, char *argv[]) {
|
|||||||
command.push_back("Enabled");
|
command.push_back("Enabled");
|
||||||
command.push_back("--column");
|
command.push_back("--column");
|
||||||
command.push_back("Feature");
|
command.push_back("Feature");
|
||||||
load_available_feature_flags([&command, &cache](std::string flag) {
|
load_available_feature_flags([&command, &cache](const std::string &flag) {
|
||||||
bool value;
|
bool value;
|
||||||
// Strip Default Value
|
// Strip Default Value
|
||||||
std::string stripped_flag = strip_feature_flag_default(flag, &value);
|
std::string stripped_flag = strip_feature_flag_default(flag, &value);
|
||||||
@ -287,7 +258,7 @@ int main(int argc, char *argv[]) {
|
|||||||
command.push_back("Name");
|
command.push_back("Name");
|
||||||
std::string render_distances[] = {"Far", "Normal", "Short", "Tiny"};
|
std::string render_distances[] = {"Far", "Normal", "Short", "Tiny"};
|
||||||
for (std::string &render_distance : render_distances) {
|
for (std::string &render_distance : render_distances) {
|
||||||
command.push_back(render_distance.compare(cache.render_distance) == 0 ? "TRUE" : "FALSE");
|
command.push_back(render_distance == cache.render_distance ? "TRUE" : "FALSE");
|
||||||
command.push_back(render_distance);
|
command.push_back(render_distance);
|
||||||
}
|
}
|
||||||
// Run
|
// Run
|
||||||
@ -306,10 +277,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save Cache
|
// Save Cache
|
||||||
if (!no_cache) {
|
if (!options.no_cache) {
|
||||||
save_cache();
|
save_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bootstrap
|
|
||||||
bootstrap(argc, argv);
|
|
||||||
}
|
}
|
23
launcher/src/client/configuration.h
Normal file
23
launcher/src/client/configuration.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "../options/parser.h"
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
#define DEFAULT_USERNAME "StevePi"
|
||||||
|
#define DEFAULT_RENDER_DISTANCE "Short"
|
||||||
|
|
||||||
|
// Feature Flags
|
||||||
|
std::string strip_feature_flag_default(const std::string& flag, bool *default_ret);
|
||||||
|
void load_available_feature_flags(const std::function<void(std::string)> &callback);
|
||||||
|
|
||||||
|
// Handle Non-Launch Commands
|
||||||
|
void handle_non_launch_client_only_commands(const options_t &options);
|
||||||
|
|
||||||
|
// Check Environment
|
||||||
|
void check_environment_client();
|
||||||
|
|
||||||
|
// Configure Client Options
|
||||||
|
void configure_client(const options_t &options);
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
// Defaults
|
|
||||||
#define DEFAULT_USERNAME "StevePi"
|
|
||||||
#define DEFAULT_RENDER_DISTANCE "Short"
|
|
||||||
|
|
||||||
// Feature Flags
|
|
||||||
std::string strip_feature_flag_default(std::string flag, bool *default_ret);
|
|
||||||
void load_available_feature_flags(std::function<void(std::string)> callback);
|
|
@ -34,7 +34,7 @@ static void show_report(const char *log_filename) {
|
|||||||
"--width", CRASH_REPORT_DIALOG_WIDTH,
|
"--width", CRASH_REPORT_DIALOG_WIDTH,
|
||||||
"--height", CRASH_REPORT_DIALOG_HEIGHT,
|
"--height", CRASH_REPORT_DIALOG_HEIGHT,
|
||||||
"--text-info",
|
"--text-info",
|
||||||
"--text", MCPI_APP_BASE_TITLE " has crashed!\n\nNeed help? Consider asking on the <a href=\"https://discord.com/invite/aDqejQGMMy\">Discord server</a>! <i>If you believe this is a problem with " MCPI_APP_BASE_TITLE " itself, please upload this crash report to the #bugs Discord channel.</i>",
|
"--text", MCPI_APP_BASE_TITLE " has crashed!\n\nNeed help? Consider asking on the <a href=\"" MCPI_DISCORD_INVITE "\">Discord server</a>! <i>If you believe this is a problem with " MCPI_APP_BASE_TITLE " itself, please upload this crash report to the #bugs Discord channel.</i>",
|
||||||
"--filename", log_filename,
|
"--filename", log_filename,
|
||||||
"--no-wrap",
|
"--no-wrap",
|
||||||
"--font", "Monospace",
|
"--font", "Monospace",
|
||||||
@ -121,13 +121,11 @@ void setup_crash_report() {
|
|||||||
track_child(ret);
|
track_child(ret);
|
||||||
|
|
||||||
// Install Signal Handlers
|
// Install Signal Handlers
|
||||||
struct sigaction act_sigint;
|
struct sigaction act_sigint = {0};
|
||||||
memset((void *) &act_sigint, 0, sizeof (struct sigaction));
|
|
||||||
act_sigint.sa_flags = SA_RESTART;
|
act_sigint.sa_flags = SA_RESTART;
|
||||||
act_sigint.sa_handler = &exit_handler;
|
act_sigint.sa_handler = &exit_handler;
|
||||||
sigaction(SIGINT, &act_sigint, NULL);
|
sigaction(SIGINT, &act_sigint, NULL);
|
||||||
struct sigaction act_sigterm;
|
struct sigaction act_sigterm = {0};
|
||||||
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
|
|
||||||
act_sigterm.sa_flags = SA_RESTART;
|
act_sigterm.sa_flags = SA_RESTART;
|
||||||
act_sigterm.sa_handler = &exit_handler;
|
act_sigterm.sa_handler = &exit_handler;
|
||||||
sigaction(SIGTERM, &act_sigterm, NULL);
|
sigaction(SIGTERM, &act_sigterm, NULL);
|
||||||
|
154
launcher/src/main.cpp
Normal file
154
launcher/src/main.cpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
#include <cstdlib>
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "bootstrap.h"
|
||||||
|
#include "options/parser.h"
|
||||||
|
#include "crash-report.h"
|
||||||
|
#include "util.h"
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
|
#include "client/configuration.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Bind Options To Environmental Variable
|
||||||
|
static void bind_to_env(const char *env, const bool value) {
|
||||||
|
const bool force = env[0] == '_';
|
||||||
|
if (force || value) {
|
||||||
|
set_and_print_env(env, value ? "1" : nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void setup_environment(const options_t &options) {
|
||||||
|
// Passthrough Options To Game
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
|
bind_to_env("_MCPI_BENCHMARK", options.benchmark);
|
||||||
|
#else
|
||||||
|
bind_to_env("_MCPI_ONLY_GENERATE", options.only_generate);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// GTK Dark Mode
|
||||||
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
|
set_and_print_env("GTK_THEME", "Adwaita:dark");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Configure PATH
|
||||||
|
{
|
||||||
|
// Get Binary Directory
|
||||||
|
char *binary_directory = get_binary_directory();
|
||||||
|
std::string new_path = std::string(binary_directory) + "/bin";
|
||||||
|
free(binary_directory);
|
||||||
|
// Add Existing PATH
|
||||||
|
{
|
||||||
|
char *value = getenv("PATH");
|
||||||
|
if (value != nullptr && strlen(value) > 0) {
|
||||||
|
new_path += std::string(":") + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Set And Free
|
||||||
|
set_and_print_env("PATH", new_path.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-Launch Commands
|
||||||
|
static void handle_non_launch_commands(const options_t &options) {
|
||||||
|
if (options.copy_sdk) {
|
||||||
|
char *binary_directory = get_binary_directory();
|
||||||
|
copy_sdk(binary_directory, false);
|
||||||
|
free(binary_directory);
|
||||||
|
fflush(stdout);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit Handler
|
||||||
|
static void exit_handler(__attribute__((unused)) int signal_id) {
|
||||||
|
// Pass Signal To Child
|
||||||
|
murder_children();
|
||||||
|
while (wait(nullptr) > 0) {}
|
||||||
|
_exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start The Game
|
||||||
|
static void start_game(const options_t &options) {
|
||||||
|
// Disable stdout Buffering
|
||||||
|
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||||
|
|
||||||
|
// Environemntal Variable Options
|
||||||
|
setup_environment(options);
|
||||||
|
|
||||||
|
// Setup Crash Reporting
|
||||||
|
if (!options.disable_crash_report) {
|
||||||
|
setup_log_file();
|
||||||
|
setup_crash_report();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install Signal Handlers
|
||||||
|
struct sigaction act_sigint = {};
|
||||||
|
act_sigint.sa_flags = SA_RESTART;
|
||||||
|
act_sigint.sa_handler = &exit_handler;
|
||||||
|
sigaction(SIGINT, &act_sigint, nullptr);
|
||||||
|
struct sigaction act_sigterm = {};
|
||||||
|
act_sigterm.sa_flags = SA_RESTART;
|
||||||
|
act_sigterm.sa_handler = &exit_handler;
|
||||||
|
sigaction(SIGTERM, &act_sigterm, nullptr);
|
||||||
|
|
||||||
|
// Setup Home
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
|
// Ensure $HOME
|
||||||
|
const char *home = getenv("HOME");
|
||||||
|
if (home == nullptr) {
|
||||||
|
ERR("$HOME Isn't Set");
|
||||||
|
}
|
||||||
|
// Create If Needed
|
||||||
|
{
|
||||||
|
std::string minecraft_folder = std::string(home) + HOME_SUBDIRECTORY_FOR_GAME_DATA;
|
||||||
|
struct stat tmp_stat = {};
|
||||||
|
bool exists = stat(minecraft_folder.c_str(), &tmp_stat) != 0 ? false : S_ISDIR(tmp_stat.st_mode);
|
||||||
|
if (!exists) {
|
||||||
|
// Doesn't Exist
|
||||||
|
if (mkdir(minecraft_folder.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
|
||||||
|
ERR("Unable To Create Data Directory: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Set Home To Current Directory, So World Data Is Stored There
|
||||||
|
char *launch_directory = getcwd(NULL, 0);
|
||||||
|
set_and_print_env("HOME", launch_directory);
|
||||||
|
free(launch_directory);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Configure Client Options
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
|
configure_client(options);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Bootstrap
|
||||||
|
bootstrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
// Parse Options
|
||||||
|
options_t options = parse_options(argc, argv);
|
||||||
|
|
||||||
|
// Set Debug Tag
|
||||||
|
reborn_debug_tag = "(Launcher) ";
|
||||||
|
|
||||||
|
// Debug Logging
|
||||||
|
bind_to_env(MCPI_DEBUG_ENV, options.debug);
|
||||||
|
|
||||||
|
// Handle Non-Launch Commands (Copy SDK, Print Feature Flags, Etc)
|
||||||
|
handle_non_launch_commands(options);
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
|
handle_non_launch_client_only_commands(options);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Check Environment
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
|
// Code After This Can Safely Open A Window
|
||||||
|
check_environment_client();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Start The Game
|
||||||
|
start_game(options);
|
||||||
|
}
|
@ -1,110 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "bootstrap.h"
|
|
||||||
|
|
||||||
// Get All Mods In Folder
|
|
||||||
static void load(char **ld_preload, const char *folder) {
|
|
||||||
int folder_name_length = strlen(folder);
|
|
||||||
// Open Folder
|
|
||||||
DIR *dp = opendir(folder);
|
|
||||||
if (dp != NULL) {
|
|
||||||
// Loop Through Folder
|
|
||||||
struct dirent *entry = NULL;
|
|
||||||
errno = 0;
|
|
||||||
while (1) {
|
|
||||||
errno = 0;
|
|
||||||
entry = readdir(dp);
|
|
||||||
if (entry != NULL) {
|
|
||||||
// Check If File Is Regular
|
|
||||||
if (entry->d_type == DT_REG) {
|
|
||||||
// Get Full Name
|
|
||||||
int name_length = strlen(entry->d_name);
|
|
||||||
int total_length = folder_name_length + name_length;
|
|
||||||
char name[total_length + 1];
|
|
||||||
|
|
||||||
// Concatenate Folder Name And File Name
|
|
||||||
for (int i = 0; i < folder_name_length; i++) {
|
|
||||||
name[i] = folder[i];
|
|
||||||
}
|
|
||||||
for (int i = 0; i < name_length; i++) {
|
|
||||||
name[folder_name_length + i] = entry->d_name[i];
|
|
||||||
}
|
|
||||||
// Add Terminator
|
|
||||||
name[total_length] = '\0';
|
|
||||||
|
|
||||||
// Check If File Is Accessible
|
|
||||||
int result = access(name, R_OK);
|
|
||||||
if (result == 0) {
|
|
||||||
// Add To LD_PRELOAD
|
|
||||||
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));
|
|
||||||
errno = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (errno != 0) {
|
|
||||||
// Error Reading Contents Of Folder
|
|
||||||
ERR("Error Reading Directory: %s: %s", folder, strerror(errno));
|
|
||||||
} else {
|
|
||||||
// Done!
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Close Folder
|
|
||||||
closedir(dp);
|
|
||||||
} else if (errno == ENOENT) {
|
|
||||||
// Folder Doesn't Exist
|
|
||||||
} else {
|
|
||||||
// Unable To Open Folder
|
|
||||||
ERR("Error Opening Directory: %s: %s", folder, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bootstrap Mods
|
|
||||||
void bootstrap_mods(char *binary_directory) {
|
|
||||||
// Prepare
|
|
||||||
char *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(&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 = 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);
|
|
||||||
}
|
|
86
launcher/src/mods.cpp
Normal file
86
launcher/src/mods.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#include <dirent.h>
|
||||||
|
#include <cerrno>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "bootstrap.h"
|
||||||
|
|
||||||
|
// Get All Mods In Folder
|
||||||
|
static void load(std::string &ld_preload, const std::string &folder) {
|
||||||
|
// Open Folder
|
||||||
|
DIR *dp = opendir(folder.c_str());
|
||||||
|
if (dp != nullptr) {
|
||||||
|
// Loop Through Folder
|
||||||
|
while (true) {
|
||||||
|
errno = 0;
|
||||||
|
dirent *entry = readdir(dp);
|
||||||
|
if (entry != nullptr) {
|
||||||
|
// Check If File Is Regular
|
||||||
|
if (entry->d_type == DT_REG) {
|
||||||
|
// Get Full Name
|
||||||
|
std::string name = folder + entry->d_name;
|
||||||
|
|
||||||
|
// Check If File Is Accessible
|
||||||
|
int result = access(name.c_str(), R_OK);
|
||||||
|
if (result == 0) {
|
||||||
|
// Add To LD_PRELOAD
|
||||||
|
ld_preload += name + ":";
|
||||||
|
} else if (result == -1 && errno != 0) {
|
||||||
|
// Fail
|
||||||
|
WARN("Unable To Access: %s: %s", name.c_str(), strerror(errno));
|
||||||
|
errno = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (errno != 0) {
|
||||||
|
// Error Reading Contents Of Folder
|
||||||
|
ERR("Error Reading Directory: %s: %s", folder.c_str(), strerror(errno));
|
||||||
|
} else {
|
||||||
|
// Done!
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Close Folder
|
||||||
|
closedir(dp);
|
||||||
|
} else if (errno == ENOENT) {
|
||||||
|
// Folder Doesn't Exist
|
||||||
|
} else {
|
||||||
|
// Unable To Open Folder
|
||||||
|
ERR("Error Opening Directory: %s: %s", folder.c_str(), strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bootstrap Mods
|
||||||
|
#define SUBDIRECTORY_FOR_MODS "/mods/"
|
||||||
|
void bootstrap_mods(const std::string &binary_directory) {
|
||||||
|
// Prepare
|
||||||
|
std::string preload = "";
|
||||||
|
|
||||||
|
// ~/.minecraft-pi/mods
|
||||||
|
{
|
||||||
|
// Get Mods Folder
|
||||||
|
std::string mods_folder = std::string(getenv("HOME")) + HOME_SUBDIRECTORY_FOR_GAME_DATA SUBDIRECTORY_FOR_MODS;
|
||||||
|
// Load Mods From ./mods
|
||||||
|
load(preload, mods_folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Built-In Mods
|
||||||
|
{
|
||||||
|
// Get Mods Folder
|
||||||
|
std::string mods_folder = binary_directory + SUBDIRECTORY_FOR_MODS;
|
||||||
|
// Load Mods From ./mods
|
||||||
|
load(preload, mods_folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add LD_PRELOAD
|
||||||
|
{
|
||||||
|
const char *value = getenv("LD_PRELOAD");
|
||||||
|
if (value != nullptr && strlen(value) > 0) {
|
||||||
|
preload += value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set
|
||||||
|
set_and_print_env(MCPI_LD_VARIABLE_PREFIX "LD_PRELOAD", preload.c_str());
|
||||||
|
}
|
12
launcher/src/options/option-list.h
Normal file
12
launcher/src/options/option-list.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
OPTION(debug, "debug", 'd', "Enable Debug Logging (" MCPI_DEBUG_ENV ")")
|
||||||
|
OPTION(copy_sdk, "copy-sdk", -2, "Extract Modding SDK And Exit")
|
||||||
|
OPTION(disable_crash_report, "disable-crash-report", -1, "Disable Crash Report Dialog")
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
|
OPTION(use_default, "default", -3, "Skip Configuration Dialogs")
|
||||||
|
OPTION(no_cache, "no-cache", -4, "Disable Configuration Cache")
|
||||||
|
OPTION(wipe_cache, "wipe-cache", -5, "Wipe Cached Configuration")
|
||||||
|
OPTION(print_available_feature_flags, "print-available-feature-flags", -6, "Print Available Feature Flags")
|
||||||
|
OPTION(benchmark, "benchmark", -7, "Run Benchmark")
|
||||||
|
#else
|
||||||
|
OPTION(only_generate, "only-generate", -8, "Generate World And Exit")
|
||||||
|
#endif
|
38
launcher/src/options/parser.cpp
Normal file
38
launcher/src/options/parser.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include <argp.h>
|
||||||
|
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
const char *argp_program_version = "Reborn v" MCPI_VERSION;
|
||||||
|
const char *argp_program_bug_address = "<" MCPI_DISCORD_INVITE ">";
|
||||||
|
static char doc[] = "Minecraft: Pi Edition Modding Project";
|
||||||
|
|
||||||
|
// Options
|
||||||
|
#define OPTION(ignored, name, key, doc) {name, key, nullptr, 0, doc, 0},
|
||||||
|
static argp_option options_data[] = {
|
||||||
|
#include "option-list.h"
|
||||||
|
{nullptr, 0, nullptr, 0, nullptr, 0}
|
||||||
|
};
|
||||||
|
#undef OPTION
|
||||||
|
|
||||||
|
// Parse Options
|
||||||
|
#define OPTION(name, ignored, key, ...) \
|
||||||
|
case key: \
|
||||||
|
options->name = true; \
|
||||||
|
break;
|
||||||
|
static error_t parse_opt(int key, __attribute__((unused)) char *arg, argp_state *state) {
|
||||||
|
options_t *options = (options_t *) state->input;
|
||||||
|
switch (key) {
|
||||||
|
#include "option-list.h"
|
||||||
|
default:
|
||||||
|
return ARGP_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#undef OPTION
|
||||||
|
static argp argp = {options_data, parse_opt, nullptr, doc, nullptr, nullptr, nullptr};
|
||||||
|
options_t parse_options(int argc, char *argv[]) {
|
||||||
|
options_t options = {};
|
||||||
|
argp_parse(&argp, argc, argv, 0, nullptr, &options);
|
||||||
|
return options;
|
||||||
|
}
|
10
launcher/src/options/parser.h
Normal file
10
launcher/src/options/parser.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#define OPTION(name, ...) bool name;
|
||||||
|
struct options_t {
|
||||||
|
#include "option-list.h"
|
||||||
|
};
|
||||||
|
#undef OPTION
|
||||||
|
options_t parse_options(int argc, char *argv[]);
|
@ -1,67 +0,0 @@
|
|||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "bootstrap.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
// Log
|
|
||||||
#define LOG(is_debug, ...) \
|
|
||||||
{ \
|
|
||||||
if (is_debug) { \
|
|
||||||
DEBUG(__VA_ARGS__); \
|
|
||||||
} else { \
|
|
||||||
INFO(__VA_ARGS__); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy SDK Into ~/.minecraft-pi
|
|
||||||
#define HOME_SUBDIRECTORY_FOR_SDK HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk"
|
|
||||||
void copy_sdk(char *binary_directory, int log_with_debug) {
|
|
||||||
// Ensure SDK Directory
|
|
||||||
{
|
|
||||||
char *sdk_path = NULL;
|
|
||||||
safe_asprintf(&sdk_path, "%s" HOME_SUBDIRECTORY_FOR_SDK, getenv("HOME"));
|
|
||||||
const char *const command[] = {"mkdir", "-p", sdk_path, NULL};
|
|
||||||
run_simple_command(command, "Unable To Create SDK Directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lock File
|
|
||||||
char *lock_file_path = NULL;
|
|
||||||
safe_asprintf(&lock_file_path, "%s" HOME_SUBDIRECTORY_FOR_SDK "/.lock", getenv("HOME"));
|
|
||||||
int lock_file_fd = lock_file(lock_file_path);
|
|
||||||
|
|
||||||
// Output Directory
|
|
||||||
char *output = NULL;
|
|
||||||
safe_asprintf(&output, "%s" HOME_SUBDIRECTORY_FOR_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");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log
|
|
||||||
LOG(log_with_debug, "Copied SDK To: %s", output);
|
|
||||||
|
|
||||||
// Free
|
|
||||||
free(output);
|
|
||||||
free(source);
|
|
||||||
|
|
||||||
// Unlock File
|
|
||||||
unlock_file(lock_file_path, lock_file_fd);
|
|
||||||
free(lock_file_path);
|
|
||||||
}
|
|
59
launcher/src/sdk.cpp
Normal file
59
launcher/src/sdk.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "bootstrap.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
// Log
|
||||||
|
#define LOG(is_debug, ...) \
|
||||||
|
{ \
|
||||||
|
if (is_debug) { \
|
||||||
|
DEBUG(__VA_ARGS__); \
|
||||||
|
} else { \
|
||||||
|
INFO(__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy SDK Into ~/.minecraft-pi
|
||||||
|
#define HOME_SUBDIRECTORY_FOR_SDK HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk"
|
||||||
|
void copy_sdk(const std::string &binary_directory, const bool log_with_debug) {
|
||||||
|
// Ensure SDK Directory
|
||||||
|
std::string sdk_path;
|
||||||
|
{
|
||||||
|
sdk_path = std::string(getenv("HOME")) + HOME_SUBDIRECTORY_FOR_SDK;
|
||||||
|
const char *const command[] = {"mkdir", "-p", sdk_path.c_str(), nullptr};
|
||||||
|
run_simple_command(command, "Unable To Create SDK Directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock File
|
||||||
|
std::string lock_file_path = sdk_path + "/.lock";
|
||||||
|
int lock_file_fd = lock_file(lock_file_path.c_str());
|
||||||
|
|
||||||
|
// Output Directory
|
||||||
|
std::string output = sdk_path + "/" MCPI_SDK_DIR;
|
||||||
|
// Source Directory
|
||||||
|
std::string source = binary_directory + "/sdk/.";
|
||||||
|
|
||||||
|
// Clean
|
||||||
|
{
|
||||||
|
const char *const command[] = {"rm", "-rf", output.c_str(), nullptr};
|
||||||
|
run_simple_command(command, "Unable To Clean SDK Output Directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make Directory
|
||||||
|
{
|
||||||
|
const char *const command[] = {"mkdir", "-p", output.c_str(), nullptr};
|
||||||
|
run_simple_command(command, "Unable To Create SDK Output Directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy
|
||||||
|
{
|
||||||
|
const char *const command[] = {"cp", "-ar", source.c_str(), output.c_str(), nullptr};
|
||||||
|
run_simple_command(command, "Unable To Copy SDK");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log
|
||||||
|
LOG(log_with_debug, "Copied SDK To: %s", output.c_str());
|
||||||
|
|
||||||
|
// Unlock File
|
||||||
|
unlock_file(lock_file_path.c_str(), lock_file_fd);
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "../bootstrap.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
// Pre-Bootstrap
|
|
||||||
pre_bootstrap(argc, argv);
|
|
||||||
|
|
||||||
// Set Home To Current Directory, So World Data Is Stored There
|
|
||||||
char *launch_directory = getcwd(NULL, 0);
|
|
||||||
set_and_print_env("HOME", launch_directory);
|
|
||||||
free(launch_directory);
|
|
||||||
|
|
||||||
// Bootstrap
|
|
||||||
bootstrap(argc, argv);
|
|
||||||
}
|
|
@ -14,3 +14,4 @@
|
|||||||
#cmakedefine MCPI_SDK_DIR "@MCPI_SDK_DIR@"
|
#cmakedefine MCPI_SDK_DIR "@MCPI_SDK_DIR@"
|
||||||
#cmakedefine MCPI_SKIN_SERVER "@MCPI_SKIN_SERVER@"
|
#cmakedefine MCPI_SKIN_SERVER "@MCPI_SKIN_SERVER@"
|
||||||
#cmakedefine MCPI_USE_QEMU
|
#cmakedefine MCPI_USE_QEMU
|
||||||
|
#cmakedefine MCPI_DISCORD_INVITE "@MCPI_DISCORD_INVITE@"
|
||||||
|
@ -20,9 +20,12 @@ extern "C" {
|
|||||||
void set_and_print_env(const char *name, const char *value);
|
void set_and_print_env(const char *name, const char *value);
|
||||||
|
|
||||||
// Safe execvpe()
|
// Safe execvpe()
|
||||||
|
#define MCPI_LD_VARIABLE_PREFIX "_MCPI_"
|
||||||
|
#define MCPI_ORIGINAL_LD_VARIABLE_PREFIX MCPI_LD_VARIABLE_PREFIX "ORIGINAL_"
|
||||||
|
#define MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV MCPI_ORIGINAL_LD_VARIABLE_PREFIX "PRESERVED"
|
||||||
#define for_each_special_environmental_variable(handle) \
|
#define for_each_special_environmental_variable(handle) \
|
||||||
handle("LD_LIBRARY_PATH"); \
|
handle("LD_LIBRARY_PATH"); \
|
||||||
handle("LD_PRELOAD");
|
handle("LD_PRELOAD")
|
||||||
void setup_exec_environment(int is_arm_component);
|
void setup_exec_environment(int is_arm_component);
|
||||||
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]);
|
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]);
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
|
#define MCPI_DEBUG_ENV "MCPI_DEBUG"
|
||||||
extern const char *reborn_debug_tag;
|
extern const char *reborn_debug_tag;
|
||||||
int reborn_get_debug_fd();
|
int reborn_get_debug_fd();
|
||||||
|
|
||||||
|
@ -21,12 +21,14 @@ void set_and_print_env(const char *name, const char *value) {
|
|||||||
// Safe execvpe()
|
// Safe execvpe()
|
||||||
#define handle_environmental_variable(var) \
|
#define handle_environmental_variable(var) \
|
||||||
{ \
|
{ \
|
||||||
const char *full_var = is_arm_component ? "MCPI_ARM_" var : "MCPI_NATIVE_" var; \
|
const char *full_var = is_arm_component ? MCPI_LD_VARIABLE_PREFIX var : MCPI_ORIGINAL_LD_VARIABLE_PREFIX var; \
|
||||||
const char *var_value = getenv(full_var); \
|
const char *var_value = getenv(full_var); \
|
||||||
set_and_print_env(var, var_value); \
|
set_and_print_env(var, var_value); \
|
||||||
}
|
}
|
||||||
void setup_exec_environment(int is_arm_component) {
|
void setup_exec_environment(int is_arm_component) {
|
||||||
|
if (is_arm_component || getenv(MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV) != NULL) {
|
||||||
for_each_special_environmental_variable(handle_environmental_variable);
|
for_each_special_environmental_variable(handle_environmental_variable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) {
|
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) {
|
||||||
// Log
|
// Log
|
||||||
@ -89,7 +91,7 @@ char *run_command(const char *const command[], int *exit_status, size_t *output_
|
|||||||
char buf[BUFFER_SIZE];
|
char buf[BUFFER_SIZE];
|
||||||
size_t position = 0;
|
size_t position = 0;
|
||||||
ssize_t bytes_read = 0;
|
ssize_t bytes_read = 0;
|
||||||
while ((bytes_read = read(output_pipe[0], (void *) buf, BUFFER_SIZE)) > 0) {
|
while ((bytes_read = read(output_pipe[0], buf, BUFFER_SIZE)) > 0) {
|
||||||
// Grow Output If Needed
|
// Grow Output If Needed
|
||||||
size_t needed_size = position + bytes_read;
|
size_t needed_size = position + bytes_read;
|
||||||
if (needed_size > size) {
|
if (needed_size > size) {
|
||||||
|
@ -7,7 +7,7 @@ const char *reborn_debug_tag = "";
|
|||||||
|
|
||||||
// Debug FD
|
// Debug FD
|
||||||
int reborn_get_debug_fd() {
|
int reborn_get_debug_fd() {
|
||||||
if (getenv("MCPI_DEBUG") != NULL) {
|
if (getenv(MCPI_DEBUG_ENV) != NULL) {
|
||||||
return STDERR_FILENO;
|
return STDERR_FILENO;
|
||||||
} else {
|
} else {
|
||||||
static int debug_fd = -1;
|
static int debug_fd = -1;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
|
|
||||||
CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params))
|
CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pname, (uint32_t) params);
|
trampoline(pname, (uint32_t) params);
|
||||||
#else
|
#else
|
||||||
GLenum pname = next_int();
|
GLenum pname = next_int();
|
||||||
@ -17,7 +17,7 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params))
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 'pointer' Is Only Supported As An Integer, Not As An Actual Pointer
|
// 'pointer' Is Only Supported As An Integer, Not As An Actual Pointer
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
#define CALL_GL_POINTER(unique_id, name) \
|
#define CALL_GL_POINTER(unique_id, name) \
|
||||||
CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) \
|
CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) \
|
||||||
trampoline(size, type, stride, (uint32_t) pointer); \
|
trampoline(size, type, stride, (uint32_t) pointer); \
|
||||||
@ -37,7 +37,7 @@ CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params))
|
|||||||
CALL_GL_POINTER(12, glVertexPointer)
|
CALL_GL_POINTER(12, glVertexPointer)
|
||||||
|
|
||||||
CALL(13, glLineWidth, void, (GLfloat width))
|
CALL(13, glLineWidth, void, (GLfloat width))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, width));
|
trampoline(pun_to(uint32_t, width));
|
||||||
#else
|
#else
|
||||||
GLfloat width = next_float();
|
GLfloat width = next_float();
|
||||||
@ -47,7 +47,7 @@ CALL(13, glLineWidth, void, (GLfloat width))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor))
|
CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(sfactor, dfactor);
|
trampoline(sfactor, dfactor);
|
||||||
#else
|
#else
|
||||||
GLenum sfactor = next_int();
|
GLenum sfactor = next_int();
|
||||||
@ -58,7 +58,7 @@ CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count))
|
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(mode, first, count);
|
trampoline(mode, first, count);
|
||||||
#else
|
#else
|
||||||
GLenum mode = next_int();
|
GLenum mode = next_int();
|
||||||
@ -70,7 +70,7 @@ CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha))
|
CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, red), pun_to(uint32_t, green), pun_to(uint32_t, blue), pun_to(uint32_t, alpha));
|
trampoline(pun_to(uint32_t, red), pun_to(uint32_t, green), pun_to(uint32_t, blue), pun_to(uint32_t, alpha));
|
||||||
#else
|
#else
|
||||||
GLfloat red = next_float();
|
GLfloat red = next_float();
|
||||||
@ -83,7 +83,7 @@ CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alp
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(17, glClear, void, (GLbitfield mask))
|
CALL(17, glClear, void, (GLbitfield mask))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(mask);
|
trampoline(mask);
|
||||||
#else
|
#else
|
||||||
GLbitfield mask = next_int();
|
GLbitfield mask = next_int();
|
||||||
@ -93,7 +93,7 @@ CALL(17, glClear, void, (GLbitfield mask))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage))
|
CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, size, (uint32_t) data, usage);
|
trampoline(target, size, (uint32_t) data, usage);
|
||||||
#else
|
#else
|
||||||
GLenum target = next_int();
|
GLenum target = next_int();
|
||||||
@ -106,7 +106,7 @@ CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(19, glFogx, void, (GLenum pname, GLfixed param))
|
CALL(19, glFogx, void, (GLenum pname, GLfixed param))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pname, param);
|
trampoline(pname, param);
|
||||||
#else
|
#else
|
||||||
GLenum pname = next_int();
|
GLenum pname = next_int();
|
||||||
@ -117,7 +117,7 @@ CALL(19, glFogx, void, (GLenum pname, GLfixed param))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(20, glFogf, void, (GLenum pname, GLfloat param))
|
CALL(20, glFogf, void, (GLenum pname, GLfloat param))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pname, pun_to(uint32_t, param));
|
trampoline(pname, pun_to(uint32_t, param));
|
||||||
#else
|
#else
|
||||||
GLenum pname = next_int();
|
GLenum pname = next_int();
|
||||||
@ -128,7 +128,7 @@ CALL(20, glFogf, void, (GLenum pname, GLfloat param))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(21, glMatrixMode, void, (GLenum mode))
|
CALL(21, glMatrixMode, void, (GLenum mode))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(mode);
|
trampoline(mode);
|
||||||
#else
|
#else
|
||||||
GLenum mode = next_int();
|
GLenum mode = next_int();
|
||||||
@ -140,7 +140,7 @@ CALL(21, glMatrixMode, void, (GLenum mode))
|
|||||||
CALL_GL_POINTER(22, glColorPointer)
|
CALL_GL_POINTER(22, glColorPointer)
|
||||||
|
|
||||||
CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(x, y, width, height);
|
trampoline(x, y, width, height);
|
||||||
#else
|
#else
|
||||||
GLint x = next_int();
|
GLint x = next_int();
|
||||||
@ -153,7 +153,7 @@ CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param))
|
CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, pname, param);
|
trampoline(target, pname, param);
|
||||||
#else
|
#else
|
||||||
GLenum target = next_int();
|
GLenum target = next_int();
|
||||||
@ -165,7 +165,7 @@ CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels))
|
CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, level, internalformat, width, height, border, format, type, (uint32_t) pixels);
|
trampoline(target, level, internalformat, width, height, border, format, type, (uint32_t) pixels);
|
||||||
#else
|
#else
|
||||||
GLenum target = next_int();
|
GLenum target = next_int();
|
||||||
@ -183,7 +183,7 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(26, glEnable, void, (GLenum cap))
|
CALL(26, glEnable, void, (GLenum cap))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(cap);
|
trampoline(cap);
|
||||||
#else
|
#else
|
||||||
GLenum cap = next_int();
|
GLenum cap = next_int();
|
||||||
@ -193,7 +193,7 @@ CALL(26, glEnable, void, (GLenum cap))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(27, glEnableClientState, void, (GLenum array))
|
CALL(27, glEnableClientState, void, (GLenum array))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(array);
|
trampoline(array);
|
||||||
#else
|
#else
|
||||||
GLenum array = next_int();
|
GLenum array = next_int();
|
||||||
@ -203,7 +203,7 @@ CALL(27, glEnableClientState, void, (GLenum array))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units))
|
CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, factor), pun_to(uint32_t, units));
|
trampoline(pun_to(uint32_t, factor), pun_to(uint32_t, units));
|
||||||
#else
|
#else
|
||||||
GLfloat factor = next_float();
|
GLfloat factor = next_float();
|
||||||
@ -216,7 +216,7 @@ CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units))
|
|||||||
CALL_GL_POINTER(41, glTexCoordPointer)
|
CALL_GL_POINTER(41, glTexCoordPointer)
|
||||||
|
|
||||||
CALL(29, glDisableClientState, void, (GLenum array))
|
CALL(29, glDisableClientState, void, (GLenum array))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(array);
|
trampoline(array);
|
||||||
#else
|
#else
|
||||||
GLenum array = next_int();
|
GLenum array = next_int();
|
||||||
@ -226,7 +226,7 @@ CALL(29, glDisableClientState, void, (GLenum array))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far))
|
CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, near), pun_to(uint32_t, far));
|
trampoline(pun_to(uint32_t, near), pun_to(uint32_t, far));
|
||||||
#else
|
#else
|
||||||
GLclampf near = next_float();
|
GLclampf near = next_float();
|
||||||
@ -237,7 +237,7 @@ CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(31, glDepthFunc, void, (GLenum func))
|
CALL(31, glDepthFunc, void, (GLenum func))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(func);
|
trampoline(func);
|
||||||
#else
|
#else
|
||||||
GLenum func2 = next_int();
|
GLenum func2 = next_int();
|
||||||
@ -247,7 +247,7 @@ CALL(31, glDepthFunc, void, (GLenum func))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer))
|
CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, buffer);
|
trampoline(target, buffer);
|
||||||
#else
|
#else
|
||||||
GLenum target = next_int();
|
GLenum target = next_int();
|
||||||
@ -258,7 +258,7 @@ CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha))
|
CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, red), pun_to(uint32_t, green), pun_to(uint32_t, blue), pun_to(uint32_t, alpha));
|
trampoline(pun_to(uint32_t, red), pun_to(uint32_t, green), pun_to(uint32_t, blue), pun_to(uint32_t, alpha));
|
||||||
#else
|
#else
|
||||||
GLclampf red = next_float();
|
GLclampf red = next_float();
|
||||||
@ -271,7 +271,7 @@ CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLcla
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(34, glPopMatrix, void, ())
|
CALL(34, glPopMatrix, void, ())
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline();
|
trampoline();
|
||||||
#else
|
#else
|
||||||
// Run
|
// Run
|
||||||
@ -280,7 +280,7 @@ CALL(34, glPopMatrix, void, ())
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(35, glLoadIdentity, void, ())
|
CALL(35, glLoadIdentity, void, ())
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline();
|
trampoline();
|
||||||
#else
|
#else
|
||||||
// Run
|
// Run
|
||||||
@ -289,7 +289,7 @@ CALL(35, glLoadIdentity, void, ())
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z))
|
CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z));
|
trampoline(pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z));
|
||||||
#else
|
#else
|
||||||
GLfloat x = next_float();
|
GLfloat x = next_float();
|
||||||
@ -301,7 +301,7 @@ CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(37, glPushMatrix, void, ())
|
CALL(37, glPushMatrix, void, ())
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline();
|
trampoline();
|
||||||
#else
|
#else
|
||||||
// Run
|
// Run
|
||||||
@ -310,7 +310,7 @@ CALL(37, glPushMatrix, void, ())
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(38, glDepthMask, void, (GLboolean flag))
|
CALL(38, glDepthMask, void, (GLboolean flag))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(flag);
|
trampoline(flag);
|
||||||
#else
|
#else
|
||||||
GLboolean flag = next_int();
|
GLboolean flag = next_int();
|
||||||
@ -320,7 +320,7 @@ CALL(38, glDepthMask, void, (GLboolean flag))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(39, glHint, void, (GLenum target, GLenum mode))
|
CALL(39, glHint, void, (GLenum target, GLenum mode))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, mode);
|
trampoline(target, mode);
|
||||||
#else
|
#else
|
||||||
GLenum target = next_int();
|
GLenum target = next_int();
|
||||||
@ -331,7 +331,7 @@ CALL(39, glHint, void, (GLenum target, GLenum mode))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(40, glMultMatrixf, void, (const GLfloat *m))
|
CALL(40, glMultMatrixf, void, (const GLfloat *m))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline((uint32_t) m);
|
trampoline((uint32_t) m);
|
||||||
#else
|
#else
|
||||||
GLfloat *m = next_ptr();
|
GLfloat *m = next_ptr();
|
||||||
@ -341,7 +341,7 @@ CALL(40, glMultMatrixf, void, (const GLfloat *m))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers))
|
CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(n, (uint32_t) buffers);
|
trampoline(n, (uint32_t) buffers);
|
||||||
#else
|
#else
|
||||||
GLsizei n = next_int();
|
GLsizei n = next_int();
|
||||||
@ -352,7 +352,7 @@ CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha))
|
CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(red, green, blue, alpha);
|
trampoline(red, green, blue, alpha);
|
||||||
#else
|
#else
|
||||||
GLboolean red = next_int();
|
GLboolean red = next_int();
|
||||||
@ -365,7 +365,7 @@ CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLb
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels))
|
CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, level, xoffset, yoffset, width, height, format, type, (uint32_t) pixels);
|
trampoline(target, level, xoffset, yoffset, width, height, format, type, (uint32_t) pixels);
|
||||||
#else
|
#else
|
||||||
GLenum target = next_int();
|
GLenum target = next_int();
|
||||||
@ -383,7 +383,7 @@ CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLin
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures))
|
CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(n, (uint32_t) textures);
|
trampoline(n, (uint32_t) textures);
|
||||||
#else
|
#else
|
||||||
GLsizei n = next_int();
|
GLsizei n = next_int();
|
||||||
@ -394,7 +394,7 @@ CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures))
|
CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(n, (uint32_t) textures);
|
trampoline(n, (uint32_t) textures);
|
||||||
#else
|
#else
|
||||||
GLsizei n = next_int();
|
GLsizei n = next_int();
|
||||||
@ -405,7 +405,7 @@ CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref))
|
CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(func, pun_to(uint32_t, ref));
|
trampoline(func, pun_to(uint32_t, ref));
|
||||||
#else
|
#else
|
||||||
GLenum func2 = next_int();
|
GLenum func2 = next_int();
|
||||||
@ -416,7 +416,7 @@ CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params))
|
CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pname, (uint32_t) params);
|
trampoline(pname, (uint32_t) params);
|
||||||
#else
|
#else
|
||||||
GLenum pname = next_int();
|
GLenum pname = next_int();
|
||||||
@ -427,7 +427,7 @@ CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(49, glBindTexture, void, (GLenum target, GLuint texture))
|
CALL(49, glBindTexture, void, (GLenum target, GLuint texture))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(target, texture);
|
trampoline(target, texture);
|
||||||
#else
|
#else
|
||||||
GLenum target = next_int();
|
GLenum target = next_int();
|
||||||
@ -438,7 +438,7 @@ CALL(49, glBindTexture, void, (GLenum target, GLuint texture))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
|
CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z));
|
trampoline(pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z));
|
||||||
#else
|
#else
|
||||||
GLfloat x = next_float();
|
GLfloat x = next_float();
|
||||||
@ -450,7 +450,7 @@ CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(51, glShadeModel, void, (GLenum mode))
|
CALL(51, glShadeModel, void, (GLenum mode))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(mode);
|
trampoline(mode);
|
||||||
#else
|
#else
|
||||||
GLenum mode = next_int();
|
GLenum mode = next_int();
|
||||||
@ -460,7 +460,7 @@ CALL(51, glShadeModel, void, (GLenum mode))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far))
|
CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, left), pun_to(uint32_t, right), pun_to(uint32_t, bottom), pun_to(uint32_t, top), pun_to(uint32_t, near), pun_to(uint32_t, far));
|
trampoline(pun_to(uint32_t, left), pun_to(uint32_t, right), pun_to(uint32_t, bottom), pun_to(uint32_t, top), pun_to(uint32_t, near), pun_to(uint32_t, far));
|
||||||
#else
|
#else
|
||||||
GLfloat left = next_float();
|
GLfloat left = next_float();
|
||||||
@ -475,7 +475,7 @@ CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat t
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(53, glDisable, void, (GLenum cap))
|
CALL(53, glDisable, void, (GLenum cap))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(cap);
|
trampoline(cap);
|
||||||
#else
|
#else
|
||||||
GLenum cap = next_int();
|
GLenum cap = next_int();
|
||||||
@ -485,7 +485,7 @@ CALL(53, glDisable, void, (GLenum cap))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(54, glCullFace, void, (GLenum mode))
|
CALL(54, glCullFace, void, (GLenum mode))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(mode);
|
trampoline(mode);
|
||||||
#else
|
#else
|
||||||
GLenum mode = next_int();
|
GLenum mode = next_int();
|
||||||
@ -495,7 +495,7 @@ CALL(54, glCullFace, void, (GLenum mode))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
|
CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, angle), pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z));
|
trampoline(pun_to(uint32_t, angle), pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z));
|
||||||
#else
|
#else
|
||||||
GLfloat angle = next_float();
|
GLfloat angle = next_float();
|
||||||
@ -508,7 +508,7 @@ CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(x, y, width, height);
|
trampoline(x, y, width, height);
|
||||||
#else
|
#else
|
||||||
GLint x = next_int();
|
GLint x = next_int();
|
||||||
@ -521,7 +521,7 @@ CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz))
|
CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, nx), pun_to(uint32_t, ny), pun_to(uint32_t, nz));
|
trampoline(pun_to(uint32_t, nx), pun_to(uint32_t, ny), pun_to(uint32_t, nz));
|
||||||
#else
|
#else
|
||||||
GLfloat nx = next_float();
|
GLfloat nx = next_float();
|
||||||
@ -533,7 +533,7 @@ CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(58, glIsEnabled, GLboolean, (GLenum cap))
|
CALL(58, glIsEnabled, GLboolean, (GLenum cap))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
return trampoline(cap);
|
return trampoline(cap);
|
||||||
#else
|
#else
|
||||||
GLenum cap = next_int();
|
GLenum cap = next_int();
|
||||||
@ -543,7 +543,7 @@ CALL(58, glIsEnabled, GLboolean, (GLenum cap))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params))
|
CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pname, (uint32_t) params);
|
trampoline(pname, (uint32_t) params);
|
||||||
#else
|
#else
|
||||||
GLenum pname = next_int();
|
GLenum pname = next_int();
|
||||||
@ -554,7 +554,7 @@ CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data))
|
CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(x, y, width, height, format, type, (uint32_t) data);
|
trampoline(x, y, width, height, format, type, (uint32_t) data);
|
||||||
#else
|
#else
|
||||||
GLint x = next_int();
|
GLint x = next_int();
|
||||||
@ -570,7 +570,7 @@ CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, G
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(67, glGenBuffers, void, (GLsizei n, GLuint *buffers))
|
CALL(67, glGenBuffers, void, (GLsizei n, GLuint *buffers))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(n, (uint32_t) buffers);
|
trampoline(n, (uint32_t) buffers);
|
||||||
#else
|
#else
|
||||||
GLsizei n = next_int();
|
GLsizei n = next_int();
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// SDL Functions
|
// SDL Functions
|
||||||
|
|
||||||
CALL(0, SDL_Init, int, (uint32_t flags))
|
CALL(0, SDL_Init, int, (uint32_t flags))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
return trampoline(flags);
|
return trampoline(flags);
|
||||||
#else
|
#else
|
||||||
uint32_t flags = next_int();
|
uint32_t flags = next_int();
|
||||||
@ -21,7 +21,7 @@ CALL(0, SDL_Init, int, (uint32_t flags))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(1, SDL_PollEvent, int, (SDL_Event *event))
|
CALL(1, SDL_PollEvent, int, (SDL_Event *event))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
return trampoline((uint32_t) event);
|
return trampoline((uint32_t) event);
|
||||||
#else
|
#else
|
||||||
SDL_Event *event = next_ptr();
|
SDL_Event *event = next_ptr();
|
||||||
@ -31,7 +31,7 @@ CALL(1, SDL_PollEvent, int, (SDL_Event *event))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(2, SDL_PushEvent, int, (SDL_Event *event))
|
CALL(2, SDL_PushEvent, int, (SDL_Event *event))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
return trampoline((uint32_t) event);
|
return trampoline((uint32_t) event);
|
||||||
#else
|
#else
|
||||||
SDL_Event *event = next_ptr();
|
SDL_Event *event = next_ptr();
|
||||||
@ -41,7 +41,7 @@ CALL(2, SDL_PushEvent, int, (SDL_Event *event))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(3, SDL_WM_SetCaption, void, (const char *title, const char *icon))
|
CALL(3, SDL_WM_SetCaption, void, (const char *title, const char *icon))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline((uint32_t) title, (uint32_t) icon);
|
trampoline((uint32_t) title, (uint32_t) icon);
|
||||||
#else
|
#else
|
||||||
char *title = next_ptr();
|
char *title = next_ptr();
|
||||||
@ -52,7 +52,7 @@ CALL(3, SDL_WM_SetCaption, void, (const char *title, const char *icon))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(4, media_toggle_fullscreen, void, ())
|
CALL(4, media_toggle_fullscreen, void, ())
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline();
|
trampoline();
|
||||||
#else
|
#else
|
||||||
// Run
|
// Run
|
||||||
@ -61,7 +61,7 @@ CALL(4, media_toggle_fullscreen, void, ())
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode))
|
CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
return trampoline(mode);
|
return trampoline(mode);
|
||||||
#else
|
#else
|
||||||
SDL_GrabMode mode = next_int();
|
SDL_GrabMode mode = next_int();
|
||||||
@ -71,7 +71,7 @@ CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(6, SDL_ShowCursor, int, (int32_t toggle))
|
CALL(6, SDL_ShowCursor, int, (int32_t toggle))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
return trampoline(toggle);
|
return trampoline(toggle);
|
||||||
#else
|
#else
|
||||||
int mode = next_int();
|
int mode = next_int();
|
||||||
@ -81,7 +81,7 @@ CALL(6, SDL_ShowCursor, int, (int32_t toggle))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(8, media_swap_buffers, void, ())
|
CALL(8, media_swap_buffers, void, ())
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline();
|
trampoline();
|
||||||
#else
|
#else
|
||||||
// Run
|
// Run
|
||||||
@ -90,7 +90,7 @@ CALL(8, media_swap_buffers, void, ())
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(9, media_cleanup, void, ())
|
CALL(9, media_cleanup, void, ())
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline();
|
trampoline();
|
||||||
#else
|
#else
|
||||||
// Run
|
// Run
|
||||||
@ -99,7 +99,7 @@ CALL(9, media_cleanup, void, ())
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(10, media_get_framebuffer_size, void, (int *width, int *height))
|
CALL(10, media_get_framebuffer_size, void, (int *width, int *height))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline((uint32_t) width, (uint32_t) height);
|
trampoline((uint32_t) width, (uint32_t) height);
|
||||||
#else
|
#else
|
||||||
int *width = next_ptr();
|
int *width = next_ptr();
|
||||||
@ -110,7 +110,7 @@ CALL(10, media_get_framebuffer_size, void, (int *width, int *height))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(59, media_audio_update, void, (float volume, float x, float y, float z, float yaw))
|
CALL(59, media_audio_update, void, (float volume, float x, float y, float z, float yaw))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(pun_to(uint32_t, volume), pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z), pun_to(uint32_t, yaw));
|
trampoline(pun_to(uint32_t, volume), pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z), pun_to(uint32_t, yaw));
|
||||||
#else
|
#else
|
||||||
float volume = next_float();
|
float volume = next_float();
|
||||||
@ -124,7 +124,7 @@ CALL(59, media_audio_update, void, (float volume, float x, float y, float z, flo
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(60, media_audio_play, void, (const char *source, const char *name, float x, float y, float z, float pitch, float volume, int is_ui))
|
CALL(60, media_audio_play, void, (const char *source, const char *name, float x, float y, float z, float pitch, float volume, int is_ui))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline((uint32_t) source, (uint32_t) name, pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z), pun_to(uint32_t, pitch), pun_to(uint32_t, volume), is_ui);
|
trampoline((uint32_t) source, (uint32_t) name, pun_to(uint32_t, x), pun_to(uint32_t, y), pun_to(uint32_t, z), pun_to(uint32_t, pitch), pun_to(uint32_t, volume), is_ui);
|
||||||
#else
|
#else
|
||||||
char *source = next_ptr();
|
char *source = next_ptr();
|
||||||
@ -141,7 +141,7 @@ CALL(60, media_audio_play, void, (const char *source, const char *name, float x,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(62, media_set_interactable, void, (int is_interactable))
|
CALL(62, media_set_interactable, void, (int is_interactable))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(is_interactable);
|
trampoline(is_interactable);
|
||||||
#else
|
#else
|
||||||
int is_interactable = next_int();
|
int is_interactable = next_int();
|
||||||
@ -151,7 +151,7 @@ CALL(62, media_set_interactable, void, (int is_interactable))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(63, media_disable_vsync, void, ())
|
CALL(63, media_disable_vsync, void, ())
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline();
|
trampoline();
|
||||||
#else
|
#else
|
||||||
// Run
|
// Run
|
||||||
@ -160,7 +160,7 @@ CALL(63, media_disable_vsync, void, ())
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled))
|
CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled))
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline(enabled);
|
trampoline(enabled);
|
||||||
#else
|
#else
|
||||||
int enabled = next_int();
|
int enabled = next_int();
|
||||||
@ -170,7 +170,7 @@ CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled))
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(66, media_force_egl, void, ())
|
CALL(66, media_force_egl, void, ())
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline();
|
trampoline();
|
||||||
#else
|
#else
|
||||||
// Run
|
// Run
|
||||||
@ -179,7 +179,7 @@ CALL(66, media_force_egl, void, ())
|
|||||||
}
|
}
|
||||||
|
|
||||||
CALL(68, media_ensure_loaded, void, ())
|
CALL(68, media_ensure_loaded, void, ())
|
||||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||||
trampoline();
|
trampoline();
|
||||||
#else
|
#else
|
||||||
// Run
|
// Run
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void run_tests();
|
void run_tests();
|
||||||
void init_version();
|
void init_version();
|
||||||
@ -10,7 +8,7 @@ void init_compat();
|
|||||||
void init_server();
|
void init_server();
|
||||||
#else
|
#else
|
||||||
void init_multiplayer();
|
void init_multiplayer();
|
||||||
void init_benchmark(int argc, char *argv[]);
|
void init_benchmark();
|
||||||
#endif
|
#endif
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
void init_sound();
|
void init_sound();
|
||||||
|
@ -158,17 +158,9 @@ static void Minecraft_update_injection(Minecraft *minecraft) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init Benchmark
|
// Init Benchmark
|
||||||
void init_benchmark(int argc, char *argv[]) {
|
void init_benchmark() {
|
||||||
// --benchmark: Activate Benchmark
|
// --benchmark: Activate Benchmark
|
||||||
bool active = false;
|
bool active = getenv("_MCPI_BENCHMARK") != nullptr;
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
// Check Argument
|
|
||||||
if (strcmp(argv[i], "--benchmark") == 0) {
|
|
||||||
// Enabled
|
|
||||||
active = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (active) {
|
if (active) {
|
||||||
misc_run_on_update(Minecraft_update_injection);
|
misc_run_on_update(Minecraft_update_injection);
|
||||||
// Track Ticks
|
// Track Ticks
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
#include <symbols/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
__attribute__((constructor)) static void init(int argc, char *argv[]) {
|
__attribute__((constructor)) static void init() {
|
||||||
media_ensure_loaded();
|
media_ensure_loaded();
|
||||||
reborn_init_patch();
|
reborn_init_patch();
|
||||||
run_tests();
|
run_tests();
|
||||||
@ -37,9 +37,6 @@ __attribute__((constructor)) static void init(int argc, char *argv[]) {
|
|||||||
init_cake();
|
init_cake();
|
||||||
init_home();
|
init_home();
|
||||||
#ifndef MCPI_SERVER_MODE
|
#ifndef MCPI_SERVER_MODE
|
||||||
init_benchmark(argc, argv);
|
init_benchmark();
|
||||||
#else
|
|
||||||
(void) argc;
|
|
||||||
(void) argv;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ CUSTOM_VTABLE(info_screen, Screen) {
|
|||||||
self->handleBackEvent(false);
|
self->handleBackEvent(false);
|
||||||
} else if (button->id == DISCORD_ID) {
|
} else if (button->id == DISCORD_ID) {
|
||||||
// Open Discord Invite
|
// Open Discord Invite
|
||||||
open_url("https://discord.gg/mcpi-revival-740287937727561779");
|
open_url(MCPI_DISCORD_INVITE);
|
||||||
} else if (button->id >= INFO_ID_START) {
|
} else if (button->id >= INFO_ID_START) {
|
||||||
// Open Info URL
|
// Open Info URL
|
||||||
int i = button->id - INFO_ID_START;
|
int i = button->id - INFO_ID_START;
|
||||||
|
@ -31,16 +31,8 @@
|
|||||||
|
|
||||||
// --only-generate: Ony Generate World And Then Exit
|
// --only-generate: Ony Generate World And Then Exit
|
||||||
static bool only_generate = false;
|
static bool only_generate = false;
|
||||||
__attribute__((constructor)) static void _init_only_generate(int argc, char *argv[]) {
|
__attribute__((constructor)) static void _init_only_generate() {
|
||||||
// Iterate Arguments
|
only_generate = getenv("_MCPI_ONLY_GENERATE") != nullptr;
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
// Check Argument
|
|
||||||
if (strcmp(argv[i], "--only-generate") == 0) {
|
|
||||||
// Enabled
|
|
||||||
only_generate = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server Properties
|
// Server Properties
|
||||||
|
Loading…
Reference in New Issue
Block a user