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
|
||||
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="
|
||||
"--cc=${CMAKE_C_COMPILER}"
|
||||
"--cxx=${CMAKE_CXX_COMPILER}"
|
||||
"--extra-ldflags=-ldl"
|
||||
"--extra-ldflags=-ldl -Wl,-rpath=$ORIGIN/../lib/native -Wl,--disable-new-dtags"
|
||||
"--disable-debug-info"
|
||||
"--target-list=arm-linux-user"
|
||||
"--without-default-features"
|
||||
|
@ -2,19 +2,19 @@ project(launcher)
|
||||
|
||||
# Launcher
|
||||
add_executable(launcher
|
||||
src/bootstrap.c
|
||||
src/bootstrap.cpp
|
||||
src/patchelf.cpp
|
||||
src/util.c
|
||||
src/crash-report.c
|
||||
src/sdk.c
|
||||
src/mods.c
|
||||
src/sdk.cpp
|
||||
src/mods.cpp
|
||||
src/options/parser.cpp
|
||||
src/main.cpp
|
||||
)
|
||||
if(MCPI_SERVER_MODE)
|
||||
target_sources(launcher PRIVATE src/server/launcher.c)
|
||||
else()
|
||||
if(NOT MCPI_SERVER_MODE)
|
||||
embed_resource(launcher src/client/available-feature-flags)
|
||||
target_sources(launcher PRIVATE
|
||||
src/client/launcher.cpp
|
||||
src/client/configuration.cpp
|
||||
src/client/cache.cpp
|
||||
src/client/available-feature-flags # Show In IDE
|
||||
)
|
||||
@ -22,6 +22,7 @@ endif()
|
||||
target_link_libraries(launcher reborn-util LIB_LIEF)
|
||||
# RPath
|
||||
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
|
||||
target_link_options(launcher PRIVATE "LINKER:--disable-new-dtags")
|
||||
|
||||
# Install
|
||||
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
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
void pre_bootstrap(int argc, char *argv[]);
|
||||
void bootstrap(int argc, char *argv[]);
|
||||
void copy_sdk(char *binary_directory, int log_with_debug);
|
||||
void bootstrap_mods(char *binary_directory);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
void bootstrap();
|
||||
void copy_sdk(const std::string &binary_directory, bool log_with_debug);
|
||||
void bootstrap_mods(const std::string &binary_directory);
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#include "launcher.h"
|
||||
#include "configuration.h"
|
||||
#include "cache.h"
|
||||
|
||||
// Get Cache Path
|
||||
|
@ -10,25 +10,24 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#include "../util.h"
|
||||
#include "../bootstrap.h"
|
||||
#include "launcher.h"
|
||||
#include "configuration.h"
|
||||
#include "cache.h"
|
||||
|
||||
// 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
|
||||
std::string true_str = "TRUE ";
|
||||
std::string false_str = "FALSE ";
|
||||
// Test
|
||||
if (flag.rfind(true_str, 0) == 0) {
|
||||
// Enabled By Default
|
||||
if (default_ret != NULL) {
|
||||
if (default_ret != nullptr) {
|
||||
*default_ret = true;
|
||||
}
|
||||
return flag.substr(true_str.length(), std::string::npos);
|
||||
} else if (flag.rfind(false_str, 0) == 0) {
|
||||
// Disabled By Default
|
||||
if (default_ret != NULL) {
|
||||
if (default_ret != nullptr) {
|
||||
*default_ret = false;
|
||||
}
|
||||
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
|
||||
extern unsigned char available_feature_flags[];
|
||||
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
|
||||
char *binary_directory = get_binary_directory();
|
||||
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;
|
||||
while (std::getline(stream, line)) {
|
||||
if (line.length() > 0) {
|
||||
if (!line.empty()) {
|
||||
// Verify Line
|
||||
if (line.find('|') == std::string::npos) {
|
||||
lines.push_back(line);
|
||||
@ -67,15 +66,15 @@ void load_available_feature_flags(std::function<void(std::string)> callback) {
|
||||
}
|
||||
}
|
||||
// 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
|
||||
std::string stripped_a = strip_feature_flag_default(a, NULL);
|
||||
std::string stripped_b = strip_feature_flag_default(b, NULL);
|
||||
std::string stripped_a = strip_feature_flag_default(a, nullptr);
|
||||
std::string stripped_b = strip_feature_flag_default(b, nullptr);
|
||||
// Sort
|
||||
return stripped_a < stripped_b;
|
||||
});
|
||||
// Run Callbacks
|
||||
for (std::string &line : lines) {
|
||||
for (const std::string &line : lines) {
|
||||
callback(line);
|
||||
}
|
||||
}
|
||||
@ -83,11 +82,11 @@ void load_available_feature_flags(std::function<void(std::string)> callback) {
|
||||
// Run Command And Set Environmental Variable
|
||||
static void run_command_and_set_env(const char *env_name, const char *command[]) {
|
||||
// Only Run If Environmental Variable Is NULL
|
||||
if (getenv(env_name) == NULL) {
|
||||
if (getenv(env_name) == nullptr) {
|
||||
// Run
|
||||
int return_code;
|
||||
char *output = run_command(command, &return_code, NULL);
|
||||
if (output != NULL) {
|
||||
char *output = run_command(command, &return_code, nullptr);
|
||||
if (output != nullptr) {
|
||||
// Trim
|
||||
int length = strlen(output);
|
||||
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++) {
|
||||
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_command_and_set_env(env_name, full_command_array);
|
||||
}
|
||||
|
||||
// Set Variable If Not Already Set
|
||||
static void set_env_if_unset(const char *env_name, std::function<std::string()> callback) {
|
||||
if (getenv(env_name) == NULL) {
|
||||
static void set_env_if_unset(const char *env_name, const std::function<std::string()> &callback) {
|
||||
if (getenv(env_name) == nullptr) {
|
||||
char *value = strdup(callback().c_str());
|
||||
ALLOC_CHECK(value);
|
||||
set_and_print_env(env_name, value);
|
||||
@ -137,102 +136,74 @@ static void set_env_if_unset(const char *env_name, std::function<std::string()>
|
||||
}
|
||||
}
|
||||
|
||||
// Launch
|
||||
#define LIST_DIALOG_SIZE "400"
|
||||
int main(int argc, char *argv[]) {
|
||||
// Don't Run As Root
|
||||
if (getenv("_MCPI_SKIP_ROOT_CHECK") == NULL && (getuid() == 0 || geteuid() == 0)) {
|
||||
ERR("Don't Run As Root");
|
||||
// Handle Non-Launch Commands
|
||||
void handle_non_launch_client_only_commands(const options_t &options) {
|
||||
// Print Available Feature Flags
|
||||
if (options.print_available_feature_flags) {
|
||||
load_available_feature_flags([](const std::string &line) {
|
||||
printf("%s\n", line.c_str());
|
||||
fflush(stdout);
|
||||
});
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure HOME
|
||||
if (getenv("HOME") == NULL) {
|
||||
ERR("$HOME Isn't Set");
|
||||
// Check Environment
|
||||
void check_environment_client() {
|
||||
// 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
|
||||
#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.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Print Features
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--print-available-feature-flags") == 0) {
|
||||
// Print Available Feature Flags
|
||||
load_available_feature_flags([](std::string line) {
|
||||
printf("%s\n", line.c_str());
|
||||
fflush(stdout);
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
// Configure Client Options
|
||||
#define LIST_DIALOG_SIZE "400"
|
||||
void configure_client(const options_t &options) {
|
||||
// Wipe Cache If Needed
|
||||
if (options.wipe_cache) {
|
||||
wipe_cache();
|
||||
}
|
||||
|
||||
// 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();
|
||||
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
|
||||
launcher_cache cache = no_cache ? empty_cache : load_cache();
|
||||
launcher_cache cache = options.no_cache ? empty_cache : load_cache();
|
||||
|
||||
// --default
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--default") == 0) {
|
||||
// Use Default Feature Flags
|
||||
set_env_if_unset("MCPI_FEATURE_FLAGS", [&cache]() {
|
||||
std::string feature_flags = "";
|
||||
load_available_feature_flags([&feature_flags, &cache](std::string flag) {
|
||||
bool value;
|
||||
// Strip Default Value
|
||||
std::string stripped_flag = strip_feature_flag_default(flag, &value);
|
||||
// Use Cache
|
||||
if (cache.feature_flags.count(stripped_flag) > 0) {
|
||||
value = cache.feature_flags[stripped_flag];
|
||||
}
|
||||
// Specify Default Value
|
||||
if (value) {
|
||||
// Enabled By Default
|
||||
feature_flags += stripped_flag + '|';
|
||||
}
|
||||
});
|
||||
if (feature_flags.length() > 0 && feature_flags[feature_flags.length() - 1] == '|') {
|
||||
feature_flags.pop_back();
|
||||
if (options.use_default) {
|
||||
// Use Default Feature Flags
|
||||
set_env_if_unset("MCPI_FEATURE_FLAGS", [&cache]() {
|
||||
std::string feature_flags = "";
|
||||
load_available_feature_flags([&feature_flags, &cache](const std::string &flag) {
|
||||
bool value;
|
||||
// Strip Default Value
|
||||
std::string stripped_flag = strip_feature_flag_default(flag, &value);
|
||||
// Use Cache
|
||||
if (cache.feature_flags.count(stripped_flag) > 0) {
|
||||
value = cache.feature_flags[stripped_flag];
|
||||
}
|
||||
// Specify Default Value
|
||||
if (value) {
|
||||
// Enabled By Default
|
||||
feature_flags += stripped_flag + '|';
|
||||
}
|
||||
return feature_flags;
|
||||
});
|
||||
set_env_if_unset("MCPI_RENDER_DISTANCE", [&cache]() {
|
||||
return cache.render_distance;
|
||||
});
|
||||
set_env_if_unset("MCPI_USERNAME", [&cache]() {
|
||||
return cache.username;
|
||||
});
|
||||
break;
|
||||
}
|
||||
if (!feature_flags.empty() && feature_flags[feature_flags.length() - 1] == '|') {
|
||||
feature_flags.pop_back();
|
||||
}
|
||||
return feature_flags;
|
||||
});
|
||||
set_env_if_unset("MCPI_RENDER_DISTANCE", [&cache]() {
|
||||
return cache.render_distance;
|
||||
});
|
||||
set_env_if_unset("MCPI_USERNAME", [&cache]() {
|
||||
return cache.username;
|
||||
});
|
||||
}
|
||||
|
||||
// Setup MCPI_FEATURE_FLAGS
|
||||
@ -248,7 +219,7 @@ int main(int argc, char *argv[]) {
|
||||
command.push_back("Enabled");
|
||||
command.push_back("--column");
|
||||
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;
|
||||
// Strip Default 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");
|
||||
std::string render_distances[] = {"Far", "Normal", "Short", "Tiny"};
|
||||
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);
|
||||
}
|
||||
// Run
|
||||
@ -306,10 +277,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
// Save Cache
|
||||
if (!no_cache) {
|
||||
if (!options.no_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,
|
||||
"--height", CRASH_REPORT_DIALOG_HEIGHT,
|
||||
"--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,
|
||||
"--no-wrap",
|
||||
"--font", "Monospace",
|
||||
@ -121,13 +121,11 @@ void setup_crash_report() {
|
||||
track_child(ret);
|
||||
|
||||
// Install Signal Handlers
|
||||
struct sigaction act_sigint;
|
||||
memset((void *) &act_sigint, 0, sizeof (struct sigaction));
|
||||
struct sigaction act_sigint = {0};
|
||||
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));
|
||||
struct sigaction act_sigterm = {0};
|
||||
act_sigterm.sa_flags = SA_RESTART;
|
||||
act_sigterm.sa_handler = &exit_handler;
|
||||
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_SKIN_SERVER "@MCPI_SKIN_SERVER@"
|
||||
#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);
|
||||
|
||||
// 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) \
|
||||
handle("LD_LIBRARY_PATH"); \
|
||||
handle("LD_PRELOAD");
|
||||
handle("LD_PRELOAD")
|
||||
void setup_exec_environment(int is_arm_component);
|
||||
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]);
|
||||
|
||||
|
@ -8,6 +8,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// Debug
|
||||
#define MCPI_DEBUG_ENV "MCPI_DEBUG"
|
||||
extern const char *reborn_debug_tag;
|
||||
int reborn_get_debug_fd();
|
||||
|
||||
|
@ -21,12 +21,14 @@ void set_and_print_env(const char *name, const char *value) {
|
||||
// Safe execvpe()
|
||||
#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); \
|
||||
set_and_print_env(var, var_value); \
|
||||
}
|
||||
void setup_exec_environment(int is_arm_component) {
|
||||
for_each_special_environmental_variable(handle_environmental_variable);
|
||||
if (is_arm_component || getenv(MCPI_ORIGINAL_LD_VARIABLES_PRESERVED_ENV) != NULL) {
|
||||
for_each_special_environmental_variable(handle_environmental_variable);
|
||||
}
|
||||
}
|
||||
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]) {
|
||||
// Log
|
||||
@ -89,7 +91,7 @@ char *run_command(const char *const command[], int *exit_status, size_t *output_
|
||||
char buf[BUFFER_SIZE];
|
||||
size_t position = 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
|
||||
size_t needed_size = position + bytes_read;
|
||||
if (needed_size > size) {
|
||||
|
@ -7,7 +7,7 @@ const char *reborn_debug_tag = "";
|
||||
|
||||
// Debug FD
|
||||
int reborn_get_debug_fd() {
|
||||
if (getenv("MCPI_DEBUG") != NULL) {
|
||||
if (getenv(MCPI_DEBUG_ENV) != NULL) {
|
||||
return STDERR_FILENO;
|
||||
} else {
|
||||
static int debug_fd = -1;
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "common/common.h"
|
||||
|
||||
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);
|
||||
#else
|
||||
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
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
#define CALL_GL_POINTER(unique_id, name) \
|
||||
CALL(unique_id, name, void, (GLint size, GLenum type, GLsizei stride, const void *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(13, glLineWidth, void, (GLfloat width))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(pun_to(uint32_t, width));
|
||||
#else
|
||||
GLfloat width = next_float();
|
||||
@ -47,7 +47,7 @@ CALL(13, glLineWidth, void, (GLfloat width))
|
||||
}
|
||||
|
||||
CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(sfactor, dfactor);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(mode, first, count);
|
||||
#else
|
||||
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))
|
||||
#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));
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(mask);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(target, size, (uint32_t) data, usage);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(pname, param);
|
||||
#else
|
||||
GLenum pname = next_int();
|
||||
@ -117,7 +117,7 @@ CALL(19, glFogx, void, (GLenum pname, GLfixed 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));
|
||||
#else
|
||||
GLenum pname = next_int();
|
||||
@ -128,7 +128,7 @@ CALL(20, glFogf, void, (GLenum pname, GLfloat param))
|
||||
}
|
||||
|
||||
CALL(21, glMatrixMode, void, (GLenum mode))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(mode);
|
||||
#else
|
||||
GLenum mode = next_int();
|
||||
@ -140,7 +140,7 @@ CALL(21, glMatrixMode, void, (GLenum mode))
|
||||
CALL_GL_POINTER(22, glColorPointer)
|
||||
|
||||
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);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(target, pname, param);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(target, level, internalformat, width, height, border, format, type, (uint32_t) pixels);
|
||||
#else
|
||||
GLenum target = next_int();
|
||||
@ -183,7 +183,7 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat,
|
||||
}
|
||||
|
||||
CALL(26, glEnable, void, (GLenum cap))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(cap);
|
||||
#else
|
||||
GLenum cap = next_int();
|
||||
@ -193,7 +193,7 @@ CALL(26, glEnable, void, (GLenum cap))
|
||||
}
|
||||
|
||||
CALL(27, glEnableClientState, void, (GLenum array))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(array);
|
||||
#else
|
||||
GLenum array = next_int();
|
||||
@ -203,7 +203,7 @@ CALL(27, glEnableClientState, void, (GLenum array))
|
||||
}
|
||||
|
||||
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));
|
||||
#else
|
||||
GLfloat factor = next_float();
|
||||
@ -216,7 +216,7 @@ CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units))
|
||||
CALL_GL_POINTER(41, glTexCoordPointer)
|
||||
|
||||
CALL(29, glDisableClientState, void, (GLenum array))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(array);
|
||||
#else
|
||||
GLenum array = next_int();
|
||||
@ -226,7 +226,7 @@ CALL(29, glDisableClientState, void, (GLenum array))
|
||||
}
|
||||
|
||||
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));
|
||||
#else
|
||||
GLclampf near = next_float();
|
||||
@ -237,7 +237,7 @@ CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far))
|
||||
}
|
||||
|
||||
CALL(31, glDepthFunc, void, (GLenum func))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(func);
|
||||
#else
|
||||
GLenum func2 = next_int();
|
||||
@ -247,7 +247,7 @@ CALL(31, glDepthFunc, void, (GLenum func))
|
||||
}
|
||||
|
||||
CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(target, buffer);
|
||||
#else
|
||||
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))
|
||||
#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));
|
||||
#else
|
||||
GLclampf red = next_float();
|
||||
@ -271,7 +271,7 @@ CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLcla
|
||||
}
|
||||
|
||||
CALL(34, glPopMatrix, void, ())
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline();
|
||||
#else
|
||||
// Run
|
||||
@ -280,7 +280,7 @@ CALL(34, glPopMatrix, void, ())
|
||||
}
|
||||
|
||||
CALL(35, glLoadIdentity, void, ())
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline();
|
||||
#else
|
||||
// Run
|
||||
@ -289,7 +289,7 @@ CALL(35, glLoadIdentity, void, ())
|
||||
}
|
||||
|
||||
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));
|
||||
#else
|
||||
GLfloat x = next_float();
|
||||
@ -301,7 +301,7 @@ CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z))
|
||||
}
|
||||
|
||||
CALL(37, glPushMatrix, void, ())
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline();
|
||||
#else
|
||||
// Run
|
||||
@ -310,7 +310,7 @@ CALL(37, glPushMatrix, void, ())
|
||||
}
|
||||
|
||||
CALL(38, glDepthMask, void, (GLboolean flag))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(flag);
|
||||
#else
|
||||
GLboolean flag = next_int();
|
||||
@ -320,7 +320,7 @@ CALL(38, glDepthMask, void, (GLboolean flag))
|
||||
}
|
||||
|
||||
CALL(39, glHint, void, (GLenum target, GLenum mode))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(target, mode);
|
||||
#else
|
||||
GLenum target = next_int();
|
||||
@ -331,7 +331,7 @@ CALL(39, glHint, void, (GLenum target, GLenum mode))
|
||||
}
|
||||
|
||||
CALL(40, glMultMatrixf, void, (const GLfloat *m))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline((uint32_t) m);
|
||||
#else
|
||||
GLfloat *m = next_ptr();
|
||||
@ -341,7 +341,7 @@ CALL(40, glMultMatrixf, void, (const GLfloat *m))
|
||||
}
|
||||
|
||||
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);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(red, green, blue, alpha);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(target, level, xoffset, yoffset, width, height, format, type, (uint32_t) pixels);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(n, (uint32_t) textures);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(n, (uint32_t) textures);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(func, pun_to(uint32_t, ref));
|
||||
#else
|
||||
GLenum func2 = next_int();
|
||||
@ -416,7 +416,7 @@ CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref))
|
||||
}
|
||||
|
||||
CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(pname, (uint32_t) params);
|
||||
#else
|
||||
GLenum pname = next_int();
|
||||
@ -427,7 +427,7 @@ CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params))
|
||||
}
|
||||
|
||||
CALL(49, glBindTexture, void, (GLenum target, GLuint texture))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(target, texture);
|
||||
#else
|
||||
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))
|
||||
#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));
|
||||
#else
|
||||
GLfloat x = next_float();
|
||||
@ -450,7 +450,7 @@ CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
|
||||
}
|
||||
|
||||
CALL(51, glShadeModel, void, (GLenum mode))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(mode);
|
||||
#else
|
||||
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))
|
||||
#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));
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(cap);
|
||||
#else
|
||||
GLenum cap = next_int();
|
||||
@ -485,7 +485,7 @@ CALL(53, glDisable, void, (GLenum cap))
|
||||
}
|
||||
|
||||
CALL(54, glCullFace, void, (GLenum mode))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(mode);
|
||||
#else
|
||||
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))
|
||||
#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));
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(x, y, width, height);
|
||||
#else
|
||||
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))
|
||||
#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));
|
||||
#else
|
||||
GLfloat nx = next_float();
|
||||
@ -533,7 +533,7 @@ CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz))
|
||||
}
|
||||
|
||||
CALL(58, glIsEnabled, GLboolean, (GLenum cap))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
return trampoline(cap);
|
||||
#else
|
||||
GLenum cap = next_int();
|
||||
@ -543,7 +543,7 @@ CALL(58, glIsEnabled, GLboolean, (GLenum cap))
|
||||
}
|
||||
|
||||
CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(pname, (uint32_t) params);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(x, y, width, height, format, type, (uint32_t) data);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(n, (uint32_t) buffers);
|
||||
#else
|
||||
GLsizei n = next_int();
|
||||
|
@ -11,7 +11,7 @@
|
||||
// SDL Functions
|
||||
|
||||
CALL(0, SDL_Init, int, (uint32_t flags))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
return trampoline(flags);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
return trampoline((uint32_t) event);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
return trampoline((uint32_t) event);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline((uint32_t) title, (uint32_t) icon);
|
||||
#else
|
||||
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, ())
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline();
|
||||
#else
|
||||
// Run
|
||||
@ -61,7 +61,7 @@ CALL(4, media_toggle_fullscreen, void, ())
|
||||
}
|
||||
|
||||
CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
return trampoline(mode);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
return trampoline(toggle);
|
||||
#else
|
||||
int mode = next_int();
|
||||
@ -81,7 +81,7 @@ CALL(6, SDL_ShowCursor, int, (int32_t toggle))
|
||||
}
|
||||
|
||||
CALL(8, media_swap_buffers, void, ())
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline();
|
||||
#else
|
||||
// Run
|
||||
@ -90,7 +90,7 @@ CALL(8, media_swap_buffers, void, ())
|
||||
}
|
||||
|
||||
CALL(9, media_cleanup, void, ())
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline();
|
||||
#else
|
||||
// Run
|
||||
@ -99,7 +99,7 @@ CALL(9, media_cleanup, void, ())
|
||||
}
|
||||
|
||||
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);
|
||||
#else
|
||||
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))
|
||||
#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));
|
||||
#else
|
||||
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))
|
||||
#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);
|
||||
#else
|
||||
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))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(is_interactable);
|
||||
#else
|
||||
int is_interactable = next_int();
|
||||
@ -151,7 +151,7 @@ CALL(62, media_set_interactable, void, (int is_interactable))
|
||||
}
|
||||
|
||||
CALL(63, media_disable_vsync, void, ())
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline();
|
||||
#else
|
||||
// Run
|
||||
@ -160,7 +160,7 @@ CALL(63, media_disable_vsync, void, ())
|
||||
}
|
||||
|
||||
CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled))
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(enabled);
|
||||
#else
|
||||
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, ())
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline();
|
||||
#else
|
||||
// Run
|
||||
@ -179,7 +179,7 @@ CALL(66, media_force_egl, void, ())
|
||||
}
|
||||
|
||||
CALL(68, media_ensure_loaded, void, ())
|
||||
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline();
|
||||
#else
|
||||
// Run
|
||||
|
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
extern "C" {
|
||||
void run_tests();
|
||||
void init_version();
|
||||
@ -10,7 +8,7 @@ void init_compat();
|
||||
void init_server();
|
||||
#else
|
||||
void init_multiplayer();
|
||||
void init_benchmark(int argc, char *argv[]);
|
||||
void init_benchmark();
|
||||
#endif
|
||||
#ifndef MCPI_HEADLESS_MODE
|
||||
void init_sound();
|
||||
|
@ -158,17 +158,9 @@ static void Minecraft_update_injection(Minecraft *minecraft) {
|
||||
}
|
||||
|
||||
// Init Benchmark
|
||||
void init_benchmark(int argc, char *argv[]) {
|
||||
void init_benchmark() {
|
||||
// --benchmark: Activate Benchmark
|
||||
bool active = false;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
// Check Argument
|
||||
if (strcmp(argv[i], "--benchmark") == 0) {
|
||||
// Enabled
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool active = getenv("_MCPI_BENCHMARK") != nullptr;
|
||||
if (active) {
|
||||
misc_run_on_update(Minecraft_update_injection);
|
||||
// Track Ticks
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <media-layer/core.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
__attribute__((constructor)) static void init(int argc, char *argv[]) {
|
||||
__attribute__((constructor)) static void init() {
|
||||
media_ensure_loaded();
|
||||
reborn_init_patch();
|
||||
run_tests();
|
||||
@ -37,9 +37,6 @@ __attribute__((constructor)) static void init(int argc, char *argv[]) {
|
||||
init_cake();
|
||||
init_home();
|
||||
#ifndef MCPI_SERVER_MODE
|
||||
init_benchmark(argc, argv);
|
||||
#else
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
init_benchmark();
|
||||
#endif
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ CUSTOM_VTABLE(info_screen, Screen) {
|
||||
self->handleBackEvent(false);
|
||||
} else if (button->id == DISCORD_ID) {
|
||||
// Open Discord Invite
|
||||
open_url("https://discord.gg/mcpi-revival-740287937727561779");
|
||||
open_url(MCPI_DISCORD_INVITE);
|
||||
} else if (button->id >= INFO_ID_START) {
|
||||
// Open Info URL
|
||||
int i = button->id - INFO_ID_START;
|
||||
|
@ -31,16 +31,8 @@
|
||||
|
||||
// --only-generate: Ony Generate World And Then Exit
|
||||
static bool only_generate = false;
|
||||
__attribute__((constructor)) static void _init_only_generate(int argc, char *argv[]) {
|
||||
// Iterate Arguments
|
||||
for (int i = 1; i < argc; i++) {
|
||||
// Check Argument
|
||||
if (strcmp(argv[i], "--only-generate") == 0) {
|
||||
// Enabled
|
||||
only_generate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
__attribute__((constructor)) static void _init_only_generate() {
|
||||
only_generate = getenv("_MCPI_ONLY_GENERATE") != nullptr;
|
||||
}
|
||||
|
||||
// Server Properties
|
||||
|
Loading…
Reference in New Issue
Block a user