Trampoline
This commit is contained in:
parent
f15625ff79
commit
03c7c50d48
@ -23,21 +23,31 @@ endif()
|
|||||||
|
|
||||||
# Media Layer
|
# Media Layer
|
||||||
if(NOT MCPI_HEADLESS_MODE)
|
if(NOT MCPI_HEADLESS_MODE)
|
||||||
set(DEFAULT_USE_MEDIA_LAYER_PROXY FALSE)
|
set(DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE FALSE)
|
||||||
if(BUILD_NATIVE_COMPONENTS AND NOT IS_ARM_TARGETING)
|
if(BUILD_NATIVE_COMPONENTS AND NOT IS_ARM_TARGETING)
|
||||||
set(DEFAULT_USE_MEDIA_LAYER_PROXY TRUE)
|
set(DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE TRUE)
|
||||||
endif()
|
endif()
|
||||||
mcpi_option(USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" BOOL "${DEFAULT_USE_MEDIA_LAYER_PROXY}")
|
mcpi_option(USE_MEDIA_LAYER_TRAMPOLINE "Whether To Enable The Media Layer Trampoline (Requires QEMU)" BOOL "${DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE}")
|
||||||
mcpi_option(USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" BOOL TRUE)
|
mcpi_option(USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" BOOL TRUE)
|
||||||
else()
|
else()
|
||||||
set(MCPI_USE_MEDIA_LAYER_PROXY FALSE)
|
set(MCPI_USE_MEDIA_LAYER_TRAMPOLINE FALSE)
|
||||||
endif()
|
endif()
|
||||||
if(MCPI_USE_MEDIA_LAYER_PROXY)
|
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
|
||||||
set(BUILD_MEDIA_LAYER_CORE "${BUILD_NATIVE_COMPONENTS}")
|
set(BUILD_MEDIA_LAYER_CORE "${BUILD_NATIVE_COMPONENTS}")
|
||||||
else()
|
else()
|
||||||
set(BUILD_MEDIA_LAYER_CORE "${BUILD_ARM_COMPONENTS}")
|
set(BUILD_MEDIA_LAYER_CORE "${BUILD_ARM_COMPONENTS}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# QEMU
|
||||||
|
if(BUILD_NATIVE_COMPONENTS)
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
check_symbol_exists("__ARM_ARCH" "" MCPI_IS_ARM32_OR_ARM64_TARGETING)
|
||||||
|
set(MCPI_USE_QEMU TRUE)
|
||||||
|
if(MCPI_IS_ARM32_OR_ARM64_TARGETING AND NOT MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
|
||||||
|
set(MCPI_USE_QEMU FALSE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Specify Variant Name
|
# Specify Variant Name
|
||||||
set(MCPI_VARIANT_NAME "minecraft-pi-reborn")
|
set(MCPI_VARIANT_NAME "minecraft-pi-reborn")
|
||||||
if(MCPI_SERVER_MODE)
|
if(MCPI_SERVER_MODE)
|
||||||
@ -67,13 +77,3 @@ 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")
|
||||||
|
|
||||||
# QEMU
|
|
||||||
if(BUILD_NATIVE_COMPONENTS)
|
|
||||||
include(CheckSymbolExists)
|
|
||||||
check_symbol_exists("__ARM_ARCH" "" MCPI_IS_ARM32_OR_ARM64_TARGETING)
|
|
||||||
set(MCPI_USE_QEMU TRUE)
|
|
||||||
if(MCPI_IS_ARM32_OR_ARM64_TARGETING)
|
|
||||||
set(MCPI_USE_QEMU FALSE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
14
dependencies/qemu/trampoline.patch
vendored
14
dependencies/qemu/trampoline.patch
vendored
@ -8,22 +8,25 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "qemu/path.h"
|
#include "qemu/path.h"
|
||||||
@@ -9070,6 +9071,14 @@ _syscall5(int, sys_move_mount, int, __from_dfd, const char *, __from_pathname,
|
@@ -9070,6 +9071,17 @@ _syscall5(int, sys_move_mount, int, __from_dfd, const char *, __from_pathname,
|
||||||
int, __to_dfd, const char *, __to_pathname, unsigned int, flag)
|
int, __to_dfd, const char *, __to_pathname, unsigned int, flag)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
+// g2h For Trampoline
|
+// g2h For Trampoline
|
||||||
+static CPUState *_trampoline_g2h_cpu = NULL;
|
+static CPUState *_trampoline_g2h_cpu = NULL;
|
||||||
+static void *_trampoline_g2h(uint32_t guest_addr) {
|
+static void *_trampoline_g2h(uint32_t guest_addr) {
|
||||||
|
+ if (guest_addr == 0) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
+ return g2h(_trampoline_g2h_cpu, guest_addr);
|
+ return g2h(_trampoline_g2h_cpu, guest_addr);
|
||||||
+}
|
+}
|
||||||
+// Trampoline Function
|
+// Trampoline Function
|
||||||
+typedef uint32_t (*_trampoline_t)(typeof(_trampoline_g2h) g2h, uint32_t id, uint32_t *args);
|
+typedef void (*_trampoline_t)(typeof(_trampoline_g2h) *g2h, uint32_t id, uint32_t *args);
|
||||||
+
|
+
|
||||||
/* This is an internal helper for do_syscall so that it is easier
|
/* This is an internal helper for do_syscall so that it is easier
|
||||||
* to have a single return point, so that actions, such as logging
|
* to have a single return point, so that actions, such as logging
|
||||||
* of syscall results, can be performed.
|
* of syscall results, can be performed.
|
||||||
@@ -9095,6 +9104,26 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
|
@@ -9095,6 +9107,27 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
switch(num) {
|
switch(num) {
|
||||||
@ -32,7 +35,7 @@
|
|||||||
+ static _trampoline_t _trampoline = NULL;
|
+ static _trampoline_t _trampoline = NULL;
|
||||||
+ if (_trampoline == NULL) {
|
+ if (_trampoline == NULL) {
|
||||||
+ // Open Library
|
+ // Open Library
|
||||||
+ void *_trampoline_handle = dlopen("libmedia-layer-trampoline.so", RTLD_LAZY);
|
+ void *_trampoline_handle = dlopen("libmedia-layer-trampoline.so", RTLD_NOW);
|
||||||
+ // Load Function
|
+ // Load Function
|
||||||
+ if (_trampoline_handle != NULL) {
|
+ if (_trampoline_handle != NULL) {
|
||||||
+ _trampoline = dlsym(_trampoline_handle, "trampoline");
|
+ _trampoline = dlsym(_trampoline_handle, "trampoline");
|
||||||
@ -45,7 +48,8 @@
|
|||||||
+ }
|
+ }
|
||||||
+ // Call Trampoline
|
+ // Call Trampoline
|
||||||
+ _trampoline_g2h_cpu = cpu;
|
+ _trampoline_g2h_cpu = cpu;
|
||||||
+ return _trampoline(_trampoline_g2h, arg1, g2h(cpu, arg2));
|
+ _trampoline(_trampoline_g2h, arg1, g2h(cpu, arg2));
|
||||||
|
+ return 0;
|
||||||
+ }
|
+ }
|
||||||
case TARGET_NR_exit:
|
case TARGET_NR_exit:
|
||||||
/* In old applications this may be used to implement _exit(2).
|
/* In old applications this may be used to implement _exit(2).
|
||||||
|
@ -33,7 +33,7 @@ if(BUILD_MEDIA_LAYER_CORE)
|
|||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Add Proxy
|
# Add Trampoline
|
||||||
if(MCPI_USE_MEDIA_LAYER_PROXY OR BUILD_ARM_COMPONENTS)
|
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE OR BUILD_ARM_COMPONENTS)
|
||||||
add_subdirectory(proxy)
|
add_subdirectory(trampoline)
|
||||||
endif()
|
endif()
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#include <cstdlib>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
#include <media-layer/internal.h>
|
#include <media-layer/internal.h>
|
||||||
#include <media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
// SDL Is Replaced With GLFW
|
// SDL Is Replaced With GLFW
|
||||||
|
|
||||||
|
@ -435,6 +435,7 @@ static void glfw_controller_look(float x, float y) {
|
|||||||
verify_controller_axis_value(y, CONTROLLER_LOOK_AXIS_THRESHOLD);
|
verify_controller_axis_value(y, CONTROLLER_LOOK_AXIS_THRESHOLD);
|
||||||
|
|
||||||
// Send Event
|
// Send Event
|
||||||
|
if (is_interactable) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
event.type = SDL_MOUSEMOTION;
|
event.type = SDL_MOUSEMOTION;
|
||||||
event.motion.x = last_mouse_x;
|
event.motion.x = last_mouse_x;
|
||||||
@ -443,6 +444,7 @@ static void glfw_controller_look(float x, float y) {
|
|||||||
event.motion.yrel = y * CONTROLLER_LOOK_AXIS_SENSITIVITY;
|
event.motion.yrel = y * CONTROLLER_LOOK_AXIS_SENSITIVITY;
|
||||||
SDL_PushEvent(&event);
|
SDL_PushEvent(&event);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Controller Place/Mine Triggers
|
// Controller Place/Mine Triggers
|
||||||
|
@ -4,10 +4,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Internal Methods (Not Handled By Media Layer Proxy)
|
// Internal Methods
|
||||||
|
|
||||||
__attribute__((visibility("internal"))) void _media_handle_SDL_PollEvent();
|
__attribute__((visibility("internal"))) void _media_handle_SDL_PollEvent();
|
||||||
__attribute__((visibility("internal"))) void _media_handle_SDL_Quit();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
project(media-layer-proxy)
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
set(MEDIA_LAYER_PROXY_SRC src/common/common.c src/media-layer-core.c) # Media Layer Proxy Source
|
|
||||||
if(NOT MCPI_HEADLESS_MODE)
|
|
||||||
list(APPEND MEDIA_LAYER_PROXY_SRC src/GLESv1_CM.c)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Build
|
|
||||||
if(BUILD_NATIVE_COMPONENTS)
|
|
||||||
# Build Media Layer Proxy Client
|
|
||||||
add_executable(media-layer-proxy-client src/client/client.cpp ${MEDIA_LAYER_PROXY_SRC})
|
|
||||||
target_link_libraries(media-layer-proxy-client media-layer-headers reborn-util media-layer-core GLESv1_CM)
|
|
||||||
target_compile_definitions(media-layer-proxy-client PRIVATE -DMEDIA_LAYER_PROXY_CLIENT)
|
|
||||||
# Install
|
|
||||||
install(TARGETS media-layer-proxy-client DESTINATION "${MCPI_BIN_DIR}")
|
|
||||||
elseif(BUILD_ARM_COMPONENTS)
|
|
||||||
# Build Media Layer Proxy Server
|
|
||||||
add_library(media-layer-core SHARED src/server/server.cpp ${MEDIA_LAYER_PROXY_SRC} $<TARGET_OBJECTS:media-layer-extras>)
|
|
||||||
target_link_libraries(media-layer-core media-layer-headers reborn-util)
|
|
||||||
target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_PROXY_SERVER)
|
|
||||||
# Install
|
|
||||||
if(MCPI_USE_MEDIA_LAYER_PROXY)
|
|
||||||
install(TARGETS media-layer-core DESTINATION "${MCPI_LIB_DIR}")
|
|
||||||
endif()
|
|
||||||
install(TARGETS media-layer-core EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
|
||||||
endif()
|
|
File diff suppressed because it is too large
Load Diff
@ -1,107 +0,0 @@
|
|||||||
#include <vector>
|
|
||||||
#include <cerrno>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <cstring>
|
|
||||||
#include <sys/prctl.h>
|
|
||||||
#include <csignal>
|
|
||||||
#include <exception>
|
|
||||||
|
|
||||||
#include "../common/common.h"
|
|
||||||
|
|
||||||
// Store Handlers
|
|
||||||
#define MAX_HANDLERS 100
|
|
||||||
static proxy_handler_t handlers[MAX_HANDLERS];
|
|
||||||
void _add_handler(unsigned char unique_id, proxy_handler_t handler) {
|
|
||||||
if (unique_id >= MAX_HANDLERS) {
|
|
||||||
PROXY_ERR("ID Too Big: %i", (int) unique_id);
|
|
||||||
}
|
|
||||||
if (handlers[unique_id] != NULL) {
|
|
||||||
PROXY_ERR("Duplicate ID: %i", (int) unique_id);
|
|
||||||
}
|
|
||||||
handlers[unique_id] = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store Parent PID
|
|
||||||
static int parent_is_alive = 1;
|
|
||||||
static void sigusr1_handler(__attribute__((unused)) int sig) {
|
|
||||||
// Mark Parent As Dead
|
|
||||||
parent_is_alive = 0;
|
|
||||||
}
|
|
||||||
// Check State Of Proxy And Exit If Invalid
|
|
||||||
void _check_proxy_state() {
|
|
||||||
// Check Server State
|
|
||||||
if (!parent_is_alive) {
|
|
||||||
void_write_cache(); // Parent Is Dead, No Reason To Send A Dead Process Data
|
|
||||||
PROXY_ERR("Server Terminated");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exit Handler
|
|
||||||
static volatile int exit_requested = 0;
|
|
||||||
static void exit_handler(__attribute__((unused)) int signal_id) {
|
|
||||||
// Request Exit
|
|
||||||
exit_requested = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
// Set Debug Tag
|
|
||||||
reborn_debug_tag = PROXY_LOG_TAG;
|
|
||||||
|
|
||||||
// Install Signal Handlers
|
|
||||||
signal(SIGINT, SIG_IGN);
|
|
||||||
struct sigaction act_sigterm;
|
|
||||||
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
|
|
||||||
act_sigterm.sa_handler = &exit_handler;
|
|
||||||
sigaction(SIGTERM, &act_sigterm, NULL);
|
|
||||||
|
|
||||||
// Send Signal On Parent Death To Interrupt Connection Read/Write And Exit
|
|
||||||
prctl(PR_SET_PDEATHSIG, SIGUSR1);
|
|
||||||
struct sigaction sa;
|
|
||||||
memset((void *) &sa, 0, sizeof (struct sigaction));
|
|
||||||
sa.sa_flags = SA_NOCLDSTOP;
|
|
||||||
sa.sa_handler = &sigusr1_handler;
|
|
||||||
if (sigaction(SIGUSR1, &sa, NULL) == -1) {
|
|
||||||
PROXY_ERR("Unable To Install Signal Handler: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Connection
|
|
||||||
if (argc != 3) {
|
|
||||||
PROXY_ERR("Invalid Arguments");
|
|
||||||
}
|
|
||||||
char *read_str = argv[1];
|
|
||||||
char *write_str = argv[2];
|
|
||||||
set_connection(atoi(read_str), atoi(write_str));
|
|
||||||
PROXY_INFO("Connected");
|
|
||||||
|
|
||||||
// Send Connection Message
|
|
||||||
write_string((char *) CONNECTED_MSG);
|
|
||||||
flush_write_cache();
|
|
||||||
|
|
||||||
// Loop
|
|
||||||
int running = is_connection_open();
|
|
||||||
while (running && !exit_requested) {
|
|
||||||
unsigned char unique_id = read_byte();
|
|
||||||
if (handlers[unique_id] != NULL) {
|
|
||||||
// Run Method
|
|
||||||
handlers[unique_id]();
|
|
||||||
// Check If Connection Is Still Open
|
|
||||||
if (!is_connection_open()) {
|
|
||||||
// Exit
|
|
||||||
running = 0;
|
|
||||||
} else {
|
|
||||||
// Flush Write Cache
|
|
||||||
flush_write_cache();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PROXY_ERR("Invalid Method ID: %i", (int) unique_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_connection_open()) {
|
|
||||||
close_connection();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exit
|
|
||||||
PROXY_INFO("Stopped");
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define PROXY_LOG_TAG "(Media Layer Proxy Client) "
|
|
||||||
|
|
||||||
typedef void (*proxy_handler_t)();
|
|
||||||
__attribute__((visibility("internal"))) void _add_handler(unsigned char id, proxy_handler_t handler);
|
|
||||||
|
|
||||||
#define CALL(unique_id, name, return_type, args) \
|
|
||||||
static void _run_##name (); \
|
|
||||||
__attribute__((constructor)) static void _init_##name() { \
|
|
||||||
_add_handler(unique_id, _run_##name); \
|
|
||||||
} \
|
|
||||||
static void _run_##name ()
|
|
@ -1,245 +0,0 @@
|
|||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
// Safely Send/Receive Data From The Connection
|
|
||||||
#define CHECK_CONNECTION() \
|
|
||||||
{ \
|
|
||||||
_check_proxy_state(); \
|
|
||||||
if (!is_connection_open()) { \
|
|
||||||
PROXY_ERR("Attempting To Access Closed Connection"); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
// Buffer Reads
|
|
||||||
static void *_read_cache = NULL;
|
|
||||||
__attribute__((destructor)) static void _free_read_cache() {
|
|
||||||
if (_read_cache != NULL) {
|
|
||||||
free(_read_cache);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static size_t _read_cache_size = 0;
|
|
||||||
static size_t _read_cache_actual_size = 0;
|
|
||||||
static size_t _read_cache_position = 0;
|
|
||||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
|
||||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
|
||||||
void safe_read(void *buf, size_t len) {
|
|
||||||
// Check Data
|
|
||||||
if (buf == NULL) {
|
|
||||||
PROXY_ERR("Attempting To Read Into NULL Buffer");
|
|
||||||
}
|
|
||||||
// Setup
|
|
||||||
size_t to_read = len;
|
|
||||||
// Copy From Read Buffer
|
|
||||||
if (_read_cache != NULL && _read_cache_size > 0) {
|
|
||||||
char *read_cache = (void *) (((unsigned char *) _read_cache) + _read_cache_position);
|
|
||||||
size_t read_cache_size = _read_cache_size - _read_cache_position;
|
|
||||||
if (read_cache_size > 0) {
|
|
||||||
size_t to_copy = min(to_read, read_cache_size);
|
|
||||||
memcpy(buf, read_cache, to_copy);
|
|
||||||
to_read -= to_copy;
|
|
||||||
_read_cache_position += to_copy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check If Done
|
|
||||||
if (to_read < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_read_cache_position < _read_cache_size) {
|
|
||||||
IMPOSSIBLE();
|
|
||||||
}
|
|
||||||
// Flush Write Cache
|
|
||||||
flush_write_cache();
|
|
||||||
// Read Remaining Data
|
|
||||||
size_t to_read_to_cache = 0;
|
|
||||||
while (to_read_to_cache < 1) {
|
|
||||||
CHECK_CONNECTION();
|
|
||||||
int bytes_available;
|
|
||||||
if (ioctl(get_connection_read(), FIONREAD, &bytes_available) == -1) {
|
|
||||||
bytes_available = 0;
|
|
||||||
}
|
|
||||||
to_read_to_cache = max((size_t) bytes_available, to_read);
|
|
||||||
}
|
|
||||||
// Resize Buffer
|
|
||||||
_read_cache_position = 0;
|
|
||||||
_read_cache_size = to_read_to_cache;
|
|
||||||
if (_read_cache == NULL) {
|
|
||||||
_read_cache_actual_size = _read_cache_size;
|
|
||||||
_read_cache = malloc(_read_cache_actual_size);
|
|
||||||
} else if (_read_cache_size > _read_cache_actual_size) {
|
|
||||||
_read_cache_actual_size = _read_cache_size;
|
|
||||||
_read_cache = realloc(_read_cache, _read_cache_actual_size);
|
|
||||||
}
|
|
||||||
ALLOC_CHECK(_read_cache);
|
|
||||||
// Read Into Buffer
|
|
||||||
while (to_read_to_cache > 0) {
|
|
||||||
CHECK_CONNECTION();
|
|
||||||
ssize_t x = read(get_connection_read(), (void *) (((unsigned char *) _read_cache) + (_read_cache_size - to_read_to_cache)), to_read_to_cache);
|
|
||||||
if (x == -1 && errno != EINTR) {
|
|
||||||
PROXY_ERR("Failed Reading Data To Connection: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
to_read_to_cache -= x;
|
|
||||||
}
|
|
||||||
// Copy Remaining Data
|
|
||||||
safe_read((void *) (((unsigned char *) buf) + (len - to_read)), to_read);
|
|
||||||
}
|
|
||||||
// Buffer Writes
|
|
||||||
static void *_write_cache = NULL;
|
|
||||||
__attribute__((destructor)) static void _free_write_cache() {
|
|
||||||
if (_write_cache != NULL) {
|
|
||||||
free(_write_cache);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static size_t _write_cache_size = 0;
|
|
||||||
static size_t _write_cache_position = 0;
|
|
||||||
void safe_write(void *buf, size_t len) {
|
|
||||||
// Check Data
|
|
||||||
if (buf == NULL) {
|
|
||||||
PROXY_ERR("Attempting To Send NULL Data");
|
|
||||||
}
|
|
||||||
// Expand Write Cache If Needed
|
|
||||||
size_t needed_size = _write_cache_position + len;
|
|
||||||
if (_write_cache == NULL) {
|
|
||||||
_write_cache_size = needed_size;
|
|
||||||
_write_cache = malloc(_write_cache_size);
|
|
||||||
} else if (needed_size > _write_cache_size) {
|
|
||||||
_write_cache_size = needed_size;
|
|
||||||
_write_cache = realloc(_write_cache, _write_cache_size);
|
|
||||||
}
|
|
||||||
ALLOC_CHECK(_write_cache);
|
|
||||||
// Copy Data
|
|
||||||
memcpy((void *) (((unsigned char *) _write_cache) + _write_cache_position), buf, len);
|
|
||||||
// Advance Position
|
|
||||||
_write_cache_position += len;
|
|
||||||
}
|
|
||||||
// Flush Write Cache
|
|
||||||
void flush_write_cache() {
|
|
||||||
// Check Cache
|
|
||||||
if (_write_cache == NULL || _write_cache_position < 1) {
|
|
||||||
// Nothing To Write
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Check Connection
|
|
||||||
if (!is_connection_open()) {
|
|
||||||
// Connection Closed
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Write & Reset
|
|
||||||
size_t to_write = _write_cache_position;
|
|
||||||
size_t old_write_cache_position = _write_cache_position;
|
|
||||||
_write_cache_position = 0;
|
|
||||||
while (to_write > 0) {
|
|
||||||
CHECK_CONNECTION();
|
|
||||||
ssize_t x = write(get_connection_write(), (void *) (((unsigned char *) _write_cache) + (old_write_cache_position - to_write)), to_write);
|
|
||||||
if (x == -1 && errno != EINTR) {
|
|
||||||
PROXY_ERR("Failed Writing Data To Connection: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
to_write -= x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void void_write_cache() {
|
|
||||||
_write_cache_position = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read/Write 32-Bit Integers
|
|
||||||
uint32_t read_int() {
|
|
||||||
uint32_t ret = 0;
|
|
||||||
safe_read((void *) &ret, sizeof (ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
void write_int(uint32_t x) {
|
|
||||||
safe_write((void *) &x, sizeof (x));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read/Write Floats
|
|
||||||
float read_float() {
|
|
||||||
float ret = 0;
|
|
||||||
safe_read((void *) &ret, sizeof (ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
void write_float(float x) {
|
|
||||||
safe_write((void *) &x, sizeof (x));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read/Write Bytes
|
|
||||||
unsigned char read_byte() {
|
|
||||||
unsigned char ret = 0;
|
|
||||||
safe_read((void *) &ret, sizeof (ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
void write_byte(unsigned char x) {
|
|
||||||
safe_write((void *) &x, sizeof (x));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read/Write Strings
|
|
||||||
char *read_string() {
|
|
||||||
// Check NULL
|
|
||||||
unsigned char is_null = read_byte();
|
|
||||||
if (is_null) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
// Allocate String
|
|
||||||
unsigned char length = read_byte();
|
|
||||||
char *str = malloc((size_t) length + 1);
|
|
||||||
// Read String
|
|
||||||
safe_read((void *) str, length);
|
|
||||||
// Add Terminator
|
|
||||||
str[length] = '\0';
|
|
||||||
// Return String
|
|
||||||
return strdup(str);
|
|
||||||
}
|
|
||||||
#define MAX_STRING_SIZE 256
|
|
||||||
void write_string(const char *str) {
|
|
||||||
unsigned char is_null = str == NULL;
|
|
||||||
write_byte(is_null);
|
|
||||||
if (!is_null) {
|
|
||||||
int length = strlen(str);
|
|
||||||
if (length > MAX_STRING_SIZE) {
|
|
||||||
PROXY_ERR("Unable To Write String To Connection: Larger Than %i Bytes", MAX_STRING_SIZE);
|
|
||||||
}
|
|
||||||
write_byte((unsigned char) length);
|
|
||||||
safe_write((void *) str, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close Connection
|
|
||||||
void close_connection() {
|
|
||||||
// Flush Write Cache
|
|
||||||
flush_write_cache();
|
|
||||||
// Close
|
|
||||||
int state_changed = 0;
|
|
||||||
if (get_connection_read() != -1) {
|
|
||||||
close(get_connection_read());
|
|
||||||
state_changed = 1;
|
|
||||||
}
|
|
||||||
if (get_connection_write() != -1) {
|
|
||||||
close(get_connection_write());
|
|
||||||
state_changed = 1;
|
|
||||||
}
|
|
||||||
set_connection(-1, -1);
|
|
||||||
if (state_changed) {
|
|
||||||
PROXY_INFO("Connection Closed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check If Connection Is Open
|
|
||||||
int is_connection_open() {
|
|
||||||
return get_connection_read() != -1 && get_connection_write() != -1;
|
|
||||||
}
|
|
||||||
// Pipe
|
|
||||||
static int _read = -1;
|
|
||||||
static int _write = -1;
|
|
||||||
// Set Pipe
|
|
||||||
void set_connection(int read, int write) {
|
|
||||||
_read = read;
|
|
||||||
_write = write;
|
|
||||||
}
|
|
||||||
// Get Pipe
|
|
||||||
int get_connection_read() {
|
|
||||||
return _read;
|
|
||||||
}
|
|
||||||
int get_connection_write() {
|
|
||||||
return _write;
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __BYTE_ORDER != __LITTLE_ENDIAN
|
|
||||||
#error "Only Little Endian Is Supported"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
#include "../server/server.h"
|
|
||||||
#elif defined(MEDIA_LAYER_PROXY_CLIENT)
|
|
||||||
#include "../client/client.h"
|
|
||||||
#else
|
|
||||||
#error "Invalid Configuration"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CONNECTED_MSG "Connected"
|
|
||||||
|
|
||||||
#define PROXY_INFO(format, ...) RAW_DEBUG(PROXY_LOG_TAG, format, ##__VA_ARGS__);
|
|
||||||
#define PROXY_ERR(format, ...) { close_connection(); ERR(PROXY_LOG_TAG format, ##__VA_ARGS__); }
|
|
||||||
|
|
||||||
// Safely Send/Receive Data From The Connection
|
|
||||||
__attribute__((visibility("internal"))) void safe_read(void *buf, size_t len);
|
|
||||||
__attribute__((visibility("internal"))) void safe_write(void *buf, size_t len);
|
|
||||||
__attribute__((visibility("internal"))) void flush_write_cache();
|
|
||||||
__attribute__((visibility("internal"))) void void_write_cache();
|
|
||||||
|
|
||||||
// Read/Write 32-Bit Integers
|
|
||||||
__attribute__((visibility("internal"))) uint32_t read_int();
|
|
||||||
__attribute__((visibility("internal"))) void write_int(uint32_t x);
|
|
||||||
|
|
||||||
// Read/Write Bytes
|
|
||||||
__attribute__((visibility("internal"))) unsigned char read_byte();
|
|
||||||
__attribute__((visibility("internal"))) void write_byte(unsigned char x);
|
|
||||||
|
|
||||||
// Read/Write Floats
|
|
||||||
__attribute__((visibility("internal"))) float read_float();
|
|
||||||
__attribute__((visibility("internal"))) void write_float(float x);
|
|
||||||
|
|
||||||
// Read/Write Strings
|
|
||||||
__attribute__((visibility("internal"))) char *read_string(); // Remember To free()
|
|
||||||
__attribute__((visibility("internal"))) void write_string(const char *str);
|
|
||||||
|
|
||||||
// Manipulate Connection
|
|
||||||
__attribute__((visibility("internal"))) void set_connection(int read, int write);
|
|
||||||
__attribute__((visibility("internal"))) int get_connection_read();
|
|
||||||
__attribute__((visibility("internal"))) int get_connection_write();
|
|
||||||
__attribute__((visibility("internal"))) void close_connection();
|
|
||||||
__attribute__((visibility("internal"))) int is_connection_open();
|
|
||||||
|
|
||||||
// Check State Of Proxy And Exit If Invalid
|
|
||||||
__attribute__((visibility("internal"))) void _check_proxy_state();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,354 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <SDL/SDL.h>
|
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
#include <media-layer/core.h>
|
|
||||||
#include <media-layer/audio.h>
|
|
||||||
#include <media-layer/internal.h>
|
|
||||||
|
|
||||||
#include "common/common.h"
|
|
||||||
|
|
||||||
// SDL Functions
|
|
||||||
|
|
||||||
CALL(0, SDL_Init, int, (uint32_t flags)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// Arguments
|
|
||||||
write_int(flags);
|
|
||||||
|
|
||||||
// Get Return Value
|
|
||||||
int32_t ret = (int32_t) read_int();
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
|
|
||||||
// Return
|
|
||||||
return ret;
|
|
||||||
#else
|
|
||||||
uint32_t flags = read_int();
|
|
||||||
// Run
|
|
||||||
int ret = SDL_Init(flags);
|
|
||||||
// Return Values
|
|
||||||
write_int((uint32_t) ret);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(1, SDL_PollEvent, int, (SDL_Event *event)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// No Arguments
|
|
||||||
|
|
||||||
// Get Return Value
|
|
||||||
int32_t ret = (int32_t) read_int();
|
|
||||||
if (ret) {
|
|
||||||
safe_read((void *) event, sizeof (SDL_Event));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
|
|
||||||
// Return Value
|
|
||||||
return ret;
|
|
||||||
#else
|
|
||||||
SDL_Event event;
|
|
||||||
// Run
|
|
||||||
int ret = (int32_t) SDL_PollEvent(&event);
|
|
||||||
// Return Values
|
|
||||||
write_int(ret);
|
|
||||||
if (ret) {
|
|
||||||
safe_write((void *) &event, sizeof (SDL_Event));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(2, SDL_PushEvent, int, (SDL_Event *event)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// Arguments
|
|
||||||
safe_write((void *) event, sizeof (SDL_Event));
|
|
||||||
|
|
||||||
// Get Return Value
|
|
||||||
int32_t ret = (int32_t) read_int();
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
|
|
||||||
// Return Value
|
|
||||||
return ret;
|
|
||||||
#else
|
|
||||||
SDL_Event event;
|
|
||||||
safe_read((void *) &event, sizeof (SDL_Event));
|
|
||||||
// Run
|
|
||||||
int ret = SDL_PushEvent(&event);
|
|
||||||
// Return Value
|
|
||||||
write_int((uint32_t) ret);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(3, SDL_WM_SetCaption, void, (const char *title, const char *icon)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// Arguments
|
|
||||||
write_string((char *) title);
|
|
||||||
write_string((char *) icon);
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
char *title = read_string();
|
|
||||||
char *icon = read_string();
|
|
||||||
// Run
|
|
||||||
SDL_WM_SetCaption(title, icon);
|
|
||||||
// Free
|
|
||||||
free(title);
|
|
||||||
free(icon);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(4, media_toggle_fullscreen, void, ()) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
// Run
|
|
||||||
media_toggle_fullscreen();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// Arguments
|
|
||||||
write_int((uint32_t) mode);
|
|
||||||
|
|
||||||
// Get Return Value
|
|
||||||
SDL_GrabMode ret = (SDL_GrabMode) read_int();
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
|
|
||||||
// Return Value
|
|
||||||
return ret;
|
|
||||||
#else
|
|
||||||
SDL_GrabMode mode = (SDL_GrabMode) read_int();
|
|
||||||
// Run
|
|
||||||
SDL_GrabMode ret = SDL_WM_GrabInput(mode);
|
|
||||||
// Return Value
|
|
||||||
write_int((uint32_t) ret);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(6, SDL_ShowCursor, int, (int32_t toggle)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// Arguments
|
|
||||||
write_int((uint32_t) toggle);
|
|
||||||
|
|
||||||
// Get Return Value
|
|
||||||
int32_t ret = (int32_t) read_int();
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
|
|
||||||
// Return Value
|
|
||||||
return ret;
|
|
||||||
#else
|
|
||||||
int mode = (int) read_int();
|
|
||||||
// Run
|
|
||||||
int ret = SDL_ShowCursor(mode);
|
|
||||||
// Return Value
|
|
||||||
write_int((uint32_t) ret);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(8, media_swap_buffers, void, ()) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
flush_write_cache();
|
|
||||||
#else
|
|
||||||
// Run
|
|
||||||
media_swap_buffers();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// This Method May Be Called In A Situation Where The Proxy Is Disconnected
|
|
||||||
CALL(9, media_cleanup, void, ()) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Check Connection
|
|
||||||
if (is_connection_open()) {
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
// Block Until Cleanup Is Complete
|
|
||||||
flush_write_cache();
|
|
||||||
read_byte();
|
|
||||||
// Close The Connection
|
|
||||||
close_connection();
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Run
|
|
||||||
media_cleanup();
|
|
||||||
// Confirm Cleanup
|
|
||||||
write_byte(0);
|
|
||||||
// Close The Connection
|
|
||||||
close_connection();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(10, media_get_framebuffer_size, void, (int *width, int *height)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// Get Return Values
|
|
||||||
*width = (int) read_int();
|
|
||||||
*height = (int) read_int();
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
// Run
|
|
||||||
media_get_framebuffer_size(&width, &height);
|
|
||||||
// Return Values
|
|
||||||
write_int((uint32_t) width);
|
|
||||||
write_int((uint32_t) height);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(59, media_audio_update, void, (float volume, float x, float y, float z, float yaw)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// Arguments
|
|
||||||
write_float(volume);
|
|
||||||
write_float(x);
|
|
||||||
write_float(y);
|
|
||||||
write_float(z);
|
|
||||||
write_float(yaw);
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
float volume = read_float();
|
|
||||||
float x = read_float();
|
|
||||||
float y = read_float();
|
|
||||||
float z = read_float();
|
|
||||||
float yaw = read_float();
|
|
||||||
// Run
|
|
||||||
media_audio_update(volume, x, y, z, yaw);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
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_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// Arguments
|
|
||||||
write_string(source);
|
|
||||||
write_string(name);
|
|
||||||
write_float(x);
|
|
||||||
write_float(y);
|
|
||||||
write_float(z);
|
|
||||||
write_float(pitch);
|
|
||||||
write_float(volume);
|
|
||||||
write_int(is_ui);
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
char *source = read_string();
|
|
||||||
char *name = read_string();
|
|
||||||
float x = read_float();
|
|
||||||
float y = read_float();
|
|
||||||
float z = read_float();
|
|
||||||
float pitch = read_float();
|
|
||||||
float volume = read_float();
|
|
||||||
int is_ui = read_int();
|
|
||||||
// Run
|
|
||||||
media_audio_play(source, name, x, y, z, pitch, volume, is_ui);
|
|
||||||
// Free
|
|
||||||
free(source);
|
|
||||||
free(name);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(62, media_set_interactable, void, (int is_interactable)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// Arguments
|
|
||||||
write_int(is_interactable);
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
int is_interactable = read_int();
|
|
||||||
// Run
|
|
||||||
media_set_interactable(is_interactable);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(63, media_disable_vsync, void, ()) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
// Run
|
|
||||||
media_disable_vsync();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled)) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
|
|
||||||
// Arguments
|
|
||||||
write_int(enabled);
|
|
||||||
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
int enabled = read_int();
|
|
||||||
// Run
|
|
||||||
media_set_raw_mouse_motion_enabled(enabled);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL(66, media_force_egl, void, ()) {
|
|
||||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
|
||||||
// Lock Proxy
|
|
||||||
start_proxy_call();
|
|
||||||
// Release Proxy
|
|
||||||
end_proxy_call();
|
|
||||||
#else
|
|
||||||
// Run
|
|
||||||
media_force_egl();
|
|
||||||
#endif
|
|
||||||
}
|
|
@ -1,170 +0,0 @@
|
|||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <csignal>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include <media-layer/core.h>
|
|
||||||
|
|
||||||
#include "../common/common.h"
|
|
||||||
|
|
||||||
// Track Client State
|
|
||||||
static int _client_is_alive = 0;
|
|
||||||
static int _client_status = 0;
|
|
||||||
static void update_client_state(int is_alive, int status) {
|
|
||||||
_client_is_alive = is_alive;
|
|
||||||
_client_status = status;
|
|
||||||
}
|
|
||||||
// Check State Of Proxy And Exit If Invalid
|
|
||||||
void _check_proxy_state() {
|
|
||||||
// Check Client State
|
|
||||||
if (!_client_is_alive) {
|
|
||||||
void_write_cache(); // Child Is Dead, No Reason To Send A Dead Process Data
|
|
||||||
char *exit_status = NULL;
|
|
||||||
get_exit_status_string(_client_status, &exit_status);
|
|
||||||
PROXY_ERR("Client Terminated%s", exit_status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start Proxy Client
|
|
||||||
static pid_t _client_pid;
|
|
||||||
static void sigchld_handler(__attribute__((unused)) int sig) {
|
|
||||||
// Track
|
|
||||||
int status;
|
|
||||||
|
|
||||||
// Reap
|
|
||||||
int saved_errno = errno;
|
|
||||||
// Only waitpid() Proxy Client, Other Sub-Processes Are Handled By pclose()
|
|
||||||
if (waitpid(_client_pid, &status, WNOHANG) == _client_pid) {
|
|
||||||
// Handle Client Death
|
|
||||||
untrack_child(_client_pid);
|
|
||||||
update_client_state(0, status);
|
|
||||||
}
|
|
||||||
errno = saved_errno;
|
|
||||||
}
|
|
||||||
static void start_media_layer_proxy_client(int read, int write) {
|
|
||||||
// Reap Children
|
|
||||||
struct sigaction sa;
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
sa.sa_flags = SA_NOCLDSTOP;
|
|
||||||
sa.sa_handler = &sigchld_handler;
|
|
||||||
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
|
|
||||||
PROXY_ERR("Unable To Install Signal Handler: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fork And Start
|
|
||||||
pid_t ret = fork();
|
|
||||||
if (ret == -1) {
|
|
||||||
PROXY_ERR("Unable To Launch Client: %s", strerror(errno));
|
|
||||||
} else if (ret == 0) {
|
|
||||||
// Child Process
|
|
||||||
|
|
||||||
// Set Debug Tag
|
|
||||||
reborn_debug_tag = CHILD_PROCESS_TAG;
|
|
||||||
|
|
||||||
// Prepare Arguments
|
|
||||||
char *read_str = NULL;
|
|
||||||
safe_asprintf(&read_str, "%i", read);
|
|
||||||
char *write_str = NULL;
|
|
||||||
safe_asprintf(&write_str, "%i", write);
|
|
||||||
const char *argv[] = {"media-layer-proxy-client", read_str, write_str, NULL};
|
|
||||||
|
|
||||||
// Setup Environment
|
|
||||||
setup_exec_environment(0);
|
|
||||||
|
|
||||||
// Run
|
|
||||||
safe_execvpe(argv, (const char *const *) environ);
|
|
||||||
} else {
|
|
||||||
// Parent Process
|
|
||||||
_client_pid = ret;
|
|
||||||
track_child(_client_pid);
|
|
||||||
}
|
|
||||||
update_client_state(1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximize Pipe Buffer Size
|
|
||||||
static void maximize_pipe_fd_size(int fd) {
|
|
||||||
// Read Maximum Pipe Size
|
|
||||||
std::ifstream max_size_file("/proc/sys/fs/pipe-max-size");
|
|
||||||
if (!max_size_file.good()) {
|
|
||||||
PROXY_ERR("%s", "Unable To Open Maximum Pipe Size File");
|
|
||||||
}
|
|
||||||
// Read One Line
|
|
||||||
int max_size;
|
|
||||||
std::string line;
|
|
||||||
if (std::getline(max_size_file, line) && line.size() > 0) {
|
|
||||||
max_size = std::stoi(line);
|
|
||||||
} else {
|
|
||||||
PROXY_ERR("%s", "Unable To Read Maximum Pipe Size File");
|
|
||||||
}
|
|
||||||
// Close
|
|
||||||
max_size_file.close();
|
|
||||||
// Set Maximum Pipe Size
|
|
||||||
errno = 0;
|
|
||||||
if (fcntl(fd, F_SETPIPE_SZ, max_size) < max_size) {
|
|
||||||
PROXY_ERR("Unable To Set Maximum Pipe Size: %s", errno != 0 ? strerror(errno) : "Unknown Error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void maximize_pipe_size(int pipe[2]) {
|
|
||||||
maximize_pipe_fd_size(pipe[0]);
|
|
||||||
maximize_pipe_fd_size(pipe[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start Server
|
|
||||||
static int loaded = 0;
|
|
||||||
__attribute__((constructor)) void media_ensure_loaded() {
|
|
||||||
if (!loaded) {
|
|
||||||
loaded = 1;
|
|
||||||
|
|
||||||
// Log
|
|
||||||
PROXY_INFO("Starting...");
|
|
||||||
|
|
||||||
// Create Connection
|
|
||||||
int server_to_client_pipe[2];
|
|
||||||
safe_pipe2(server_to_client_pipe, 0);
|
|
||||||
maximize_pipe_size(server_to_client_pipe);
|
|
||||||
int client_to_server_pipe[2];
|
|
||||||
safe_pipe2(client_to_server_pipe, 0);
|
|
||||||
maximize_pipe_size(client_to_server_pipe);
|
|
||||||
// Set Connection
|
|
||||||
set_connection(client_to_server_pipe[0], server_to_client_pipe[1]);
|
|
||||||
|
|
||||||
// Start Client
|
|
||||||
start_media_layer_proxy_client(server_to_client_pipe[0], client_to_server_pipe[1]);
|
|
||||||
|
|
||||||
// Wait For Connection Message
|
|
||||||
char *str = read_string();
|
|
||||||
if (strcmp(str, CONNECTED_MSG) == 0) {
|
|
||||||
PROXY_INFO("Connected");
|
|
||||||
} else {
|
|
||||||
PROXY_ERR("Unable To Connect");
|
|
||||||
}
|
|
||||||
// Free
|
|
||||||
free(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign Unique ID To Function
|
|
||||||
static std::unordered_map<std::string, unsigned char> &get_unique_ids() {
|
|
||||||
static std::unordered_map<std::string, unsigned char> unique_ids;
|
|
||||||
return unique_ids;
|
|
||||||
}
|
|
||||||
void _assign_unique_id(const char *name, unsigned char id) {
|
|
||||||
get_unique_ids()[name] = id;
|
|
||||||
}
|
|
||||||
unsigned char _get_unique_id(const char *name) {
|
|
||||||
return get_unique_ids()[name]; // Assume ID Exists
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proxy Call Functions
|
|
||||||
void _start_proxy_call(unsigned char call_id) {
|
|
||||||
// Start Call
|
|
||||||
write_byte(call_id);
|
|
||||||
}
|
|
||||||
void end_proxy_call() {
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define PROXY_LOG_TAG "(Media Layer Proxy Server) "
|
|
||||||
|
|
||||||
// Assign Unique ID To Function
|
|
||||||
__attribute__((visibility("internal"))) void _assign_unique_id(const char *name, unsigned char id);
|
|
||||||
__attribute__((visibility("internal"))) unsigned char _get_unique_id(const char *name);
|
|
||||||
|
|
||||||
// Must Call After Every Call
|
|
||||||
__attribute__((visibility("internal"))) void _start_proxy_call(unsigned char call_id);
|
|
||||||
#define start_proxy_call() \
|
|
||||||
{ \
|
|
||||||
static int _loaded_id = 0; \
|
|
||||||
static unsigned char _call_id; \
|
|
||||||
if (!_loaded_id) { \
|
|
||||||
_loaded_id = 1; \
|
|
||||||
_call_id = _get_unique_id(__func__); \
|
|
||||||
} \
|
|
||||||
_start_proxy_call(_call_id); \
|
|
||||||
}
|
|
||||||
__attribute__((visibility("internal"))) void end_proxy_call();
|
|
||||||
|
|
||||||
#define CALL(unique_id, name, return_type, args) \
|
|
||||||
__attribute__((constructor)) static void _init_##name() { \
|
|
||||||
_assign_unique_id(#name, unique_id); \
|
|
||||||
} \
|
|
||||||
return_type name args
|
|
30
media-layer/trampoline/CMakeLists.txt
Normal file
30
media-layer/trampoline/CMakeLists.txt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
project(media-layer-trampoline)
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
set(MEDIA_LAYER_TRAMPOLINE_SRC src/media-layer-core.c) # Media Layer Trampoline Source
|
||||||
|
if(NOT MCPI_HEADLESS_MODE)
|
||||||
|
list(APPEND MEDIA_LAYER_TRAMPOLINE_SRC src/GLESv1_CM.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Build
|
||||||
|
if(BUILD_NATIVE_COMPONENTS)
|
||||||
|
# Host Component
|
||||||
|
add_library(media-layer-trampoline src/host/host.c ${MEDIA_LAYER_TRAMPOLINE_SRC})
|
||||||
|
target_link_libraries(media-layer-trampoline reborn-util media-layer-core)
|
||||||
|
if(NOT MCPI_HEADLESS_MODE)
|
||||||
|
target_link_libraries(media-layer-trampoline GLESv1_CM)
|
||||||
|
endif()
|
||||||
|
target_compile_definitions(media-layer-trampoline PRIVATE -DMEDIA_LAYER_TRAMPOLINE_HOST)
|
||||||
|
# Install
|
||||||
|
install(TARGETS media-layer-trampoline DESTINATION "${MCPI_LIB_DIR}")
|
||||||
|
elseif(BUILD_ARM_COMPONENTS)
|
||||||
|
# Guest Component
|
||||||
|
add_library(media-layer-core SHARED src/guest/guest.c ${MEDIA_LAYER_TRAMPOLINE_SRC} $<TARGET_OBJECTS:media-layer-extras>)
|
||||||
|
target_link_libraries(media-layer-core media-layer-headers reborn-util)
|
||||||
|
target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
# Install
|
||||||
|
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
|
||||||
|
install(TARGETS media-layer-core DESTINATION "${MCPI_LIB_DIR}")
|
||||||
|
endif()
|
||||||
|
install(TARGETS media-layer-core EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||||
|
endif()
|
581
media-layer/trampoline/src/GLESv1_CM.c
Normal file
581
media-layer/trampoline/src/GLESv1_CM.c
Normal file
@ -0,0 +1,581 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <GLES/gl.h>
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
|
CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(pname, (uint32_t) params);
|
||||||
|
#else
|
||||||
|
GLenum pname = next_int();
|
||||||
|
GLfloat *params = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(pname, params);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'pointer' Is Only Supported As An Integer, Not As An Actual Pointer
|
||||||
|
#if defined(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); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define CALL_GL_POINTER(unique_id, name) \
|
||||||
|
CALL(unique_id, name, unused, unused) \
|
||||||
|
GLint size = next_int(); \
|
||||||
|
GLenum type = next_int(); \
|
||||||
|
GLsizei stride = next_int(); \
|
||||||
|
const void *pointer = (const void *) (uint64_t) next_int(); \
|
||||||
|
/* Run */ \
|
||||||
|
func(size, type, stride, pointer); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CALL_GL_POINTER(12, glVertexPointer)
|
||||||
|
|
||||||
|
CALL(13, glLineWidth, void, (GLfloat width))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(pun_to(uint32_t, width));
|
||||||
|
#else
|
||||||
|
GLfloat width = next_float();
|
||||||
|
// Run
|
||||||
|
func(width);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(sfactor, dfactor);
|
||||||
|
#else
|
||||||
|
GLenum sfactor = next_int();
|
||||||
|
GLenum dfactor = next_int();
|
||||||
|
// Run
|
||||||
|
func(sfactor, dfactor);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(mode, first, count);
|
||||||
|
#else
|
||||||
|
GLenum mode = next_int();
|
||||||
|
GLint first = next_int();
|
||||||
|
GLsizei count = next_int();
|
||||||
|
// Run
|
||||||
|
func(mode, first, count);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha))
|
||||||
|
#if defined(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();
|
||||||
|
GLfloat green = next_float();
|
||||||
|
GLfloat blue = next_float();
|
||||||
|
GLfloat alpha = next_float();
|
||||||
|
// Run
|
||||||
|
func(red, green, blue, alpha);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(17, glClear, void, (GLbitfield mask))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(mask);
|
||||||
|
#else
|
||||||
|
GLbitfield mask = next_int();
|
||||||
|
// Run
|
||||||
|
func(mask);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(target, size, (uint32_t) data, usage);
|
||||||
|
#else
|
||||||
|
GLenum target = next_int();
|
||||||
|
GLsizeiptr size = next_int();
|
||||||
|
const void *data = next_ptr();
|
||||||
|
GLenum usage = next_int();
|
||||||
|
// Run
|
||||||
|
func(target, size, data, usage);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(19, glFogx, void, (GLenum pname, GLfixed param))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(pname, param);
|
||||||
|
#else
|
||||||
|
GLenum pname = next_int();
|
||||||
|
GLfixed param = next_int();
|
||||||
|
// Run
|
||||||
|
func(pname, param);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(20, glFogf, void, (GLenum pname, GLfloat param))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(pname, pun_to(uint32_t, param));
|
||||||
|
#else
|
||||||
|
GLenum pname = next_int();
|
||||||
|
GLfloat param = next_float();
|
||||||
|
// Run
|
||||||
|
func(pname, param);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(21, glMatrixMode, void, (GLenum mode))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(mode);
|
||||||
|
#else
|
||||||
|
GLenum mode = next_int();
|
||||||
|
// Run
|
||||||
|
func(mode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL_GL_POINTER(22, glColorPointer)
|
||||||
|
|
||||||
|
CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(x, y, width, height);
|
||||||
|
#else
|
||||||
|
GLint x = next_int();
|
||||||
|
GLint y = next_int();
|
||||||
|
GLsizei width = next_int();
|
||||||
|
GLsizei height = next_int();
|
||||||
|
// Run
|
||||||
|
func(x, y, width, height);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(target, pname, param);
|
||||||
|
#else
|
||||||
|
GLenum target = next_int();
|
||||||
|
GLenum pname = next_int();
|
||||||
|
GLint param = next_int();
|
||||||
|
// Run
|
||||||
|
func(target, pname, param);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
trampoline(target, level, internalformat, width, height, border, format, type, (uint32_t) pixels);
|
||||||
|
#else
|
||||||
|
GLenum target = next_int();
|
||||||
|
GLint level = next_int();
|
||||||
|
GLint internalformat = next_int();
|
||||||
|
GLsizei width = next_int();
|
||||||
|
GLsizei height = next_int();
|
||||||
|
GLint border = next_int();
|
||||||
|
GLenum format = next_int();
|
||||||
|
GLenum type = next_int();
|
||||||
|
const void *pixels = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(target, level, internalformat, width, height, border, format, type, pixels);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(26, glEnable, void, (GLenum cap))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(cap);
|
||||||
|
#else
|
||||||
|
GLenum cap = next_int();
|
||||||
|
// Run
|
||||||
|
func(cap);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(27, glEnableClientState, void, (GLenum array))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(array);
|
||||||
|
#else
|
||||||
|
GLenum array = next_int();
|
||||||
|
// Run
|
||||||
|
func(array);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(pun_to(uint32_t, factor), pun_to(uint32_t, units));
|
||||||
|
#else
|
||||||
|
GLfloat factor = next_float();
|
||||||
|
GLfloat units = next_float();
|
||||||
|
// Run
|
||||||
|
func(factor, units);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL_GL_POINTER(41, glTexCoordPointer)
|
||||||
|
|
||||||
|
CALL(29, glDisableClientState, void, (GLenum array))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(array);
|
||||||
|
#else
|
||||||
|
GLenum array = next_int();
|
||||||
|
// Run
|
||||||
|
func(array);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(pun_to(uint32_t, near), pun_to(uint32_t, far));
|
||||||
|
#else
|
||||||
|
GLclampf near = next_float();
|
||||||
|
GLclampf far = next_float();
|
||||||
|
// Run
|
||||||
|
func(near, far);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(31, glDepthFunc, void, (GLenum func))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(func);
|
||||||
|
#else
|
||||||
|
GLenum func2 = next_int();
|
||||||
|
// Run
|
||||||
|
func(func2);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(32, glBindBuffer, void, (GLenum target, GLuint buffer))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(target, buffer);
|
||||||
|
#else
|
||||||
|
GLenum target = next_int();
|
||||||
|
GLenum buffer = next_int();
|
||||||
|
// Run
|
||||||
|
func(target, buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha))
|
||||||
|
#if defined(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();
|
||||||
|
GLclampf green = next_float();
|
||||||
|
GLclampf blue = next_float();
|
||||||
|
GLclampf alpha = next_float();
|
||||||
|
// Run
|
||||||
|
func(red, green, blue, alpha);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(34, glPopMatrix, void, ())
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline();
|
||||||
|
#else
|
||||||
|
// Run
|
||||||
|
func();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(35, glLoadIdentity, void, ())
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline();
|
||||||
|
#else
|
||||||
|
// Run
|
||||||
|
func();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z))
|
||||||
|
#if defined(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();
|
||||||
|
GLfloat y = next_float();
|
||||||
|
GLfloat z = next_float();
|
||||||
|
// Run
|
||||||
|
func(x, y, z);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(37, glPushMatrix, void, ())
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline();
|
||||||
|
#else
|
||||||
|
// Run
|
||||||
|
func();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(38, glDepthMask, void, (GLboolean flag))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(flag);
|
||||||
|
#else
|
||||||
|
GLboolean flag = next_int();
|
||||||
|
// Run
|
||||||
|
func(flag);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(39, glHint, void, (GLenum target, GLenum mode))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(target, mode);
|
||||||
|
#else
|
||||||
|
GLenum target = next_int();
|
||||||
|
GLenum mode = next_int();
|
||||||
|
// Run
|
||||||
|
func(target, mode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(40, glMultMatrixf, void, (const GLfloat *m))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline((uint32_t) m);
|
||||||
|
#else
|
||||||
|
GLfloat *m = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(m);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(n, (uint32_t) buffers);
|
||||||
|
#else
|
||||||
|
GLsizei n = next_int();
|
||||||
|
GLuint *buffers = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(n, buffers);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(red, green, blue, alpha);
|
||||||
|
#else
|
||||||
|
GLboolean red = next_int();
|
||||||
|
GLboolean green = next_int();
|
||||||
|
GLboolean blue = next_int();
|
||||||
|
GLboolean alpha = next_int();
|
||||||
|
// Run
|
||||||
|
func(red, green, blue, alpha);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
trampoline(target, level, xoffset, yoffset, width, height, format, type, (uint32_t) pixels);
|
||||||
|
#else
|
||||||
|
GLenum target = next_int();
|
||||||
|
GLint level = next_int();
|
||||||
|
GLint xoffset = next_int();
|
||||||
|
GLint yoffset = next_int();
|
||||||
|
GLsizei width = next_int();
|
||||||
|
GLsizei height = next_int();
|
||||||
|
GLenum format = next_int();
|
||||||
|
GLenum type = next_int();
|
||||||
|
const void *pixels = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(target, level, xoffset, yoffset, width, height, format, type, pixels);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(n, (uint32_t) textures);
|
||||||
|
#else
|
||||||
|
GLsizei n = next_int();
|
||||||
|
GLuint *textures = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(n, textures);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(n, (uint32_t) textures);
|
||||||
|
#else
|
||||||
|
GLsizei n = next_int();
|
||||||
|
GLuint *textures = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(n, textures);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(func, pun_to(uint32_t, ref));
|
||||||
|
#else
|
||||||
|
GLenum func2 = next_int();
|
||||||
|
GLclampf ref = next_float();
|
||||||
|
// Run
|
||||||
|
func(func2, ref);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(pname, (uint32_t) params);
|
||||||
|
#else
|
||||||
|
GLenum pname = next_int();
|
||||||
|
GLfloat *params = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(pname, params);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(49, glBindTexture, void, (GLenum target, GLuint texture))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(target, texture);
|
||||||
|
#else
|
||||||
|
GLenum target = next_int();
|
||||||
|
GLuint texture = next_int();
|
||||||
|
// Run
|
||||||
|
func(target, texture);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
|
||||||
|
#if defined(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();
|
||||||
|
GLfloat y = next_float();
|
||||||
|
GLfloat z = next_float();
|
||||||
|
// Run
|
||||||
|
func(x, y, z);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(51, glShadeModel, void, (GLenum mode))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(mode);
|
||||||
|
#else
|
||||||
|
GLenum mode = next_int();
|
||||||
|
// Run
|
||||||
|
func(mode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far))
|
||||||
|
#if defined(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();
|
||||||
|
GLfloat right = next_float();
|
||||||
|
GLfloat bottom = next_float();
|
||||||
|
GLfloat top = next_float();
|
||||||
|
GLfloat near = next_float();
|
||||||
|
GLfloat far = next_float();
|
||||||
|
// Run
|
||||||
|
func(left, right, bottom, top, near, far);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(53, glDisable, void, (GLenum cap))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(cap);
|
||||||
|
#else
|
||||||
|
GLenum cap = next_int();
|
||||||
|
// Run
|
||||||
|
func(cap);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(54, glCullFace, void, (GLenum mode))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(mode);
|
||||||
|
#else
|
||||||
|
GLenum mode = next_int();
|
||||||
|
// Run
|
||||||
|
func(mode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
|
||||||
|
#if defined(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();
|
||||||
|
GLfloat x = next_float();
|
||||||
|
GLfloat y = next_float();
|
||||||
|
GLfloat z = next_float();
|
||||||
|
// Run
|
||||||
|
func(angle, x, y, z);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(x, y, width, height);
|
||||||
|
#else
|
||||||
|
GLint x = next_int();
|
||||||
|
GLint y = next_int();
|
||||||
|
GLsizei width = next_int();
|
||||||
|
GLsizei height = next_int();
|
||||||
|
// Run
|
||||||
|
func(x, y, width, height);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(57, glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz))
|
||||||
|
#if defined(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();
|
||||||
|
GLfloat ny = next_float();
|
||||||
|
GLfloat nz = next_float();
|
||||||
|
// Run
|
||||||
|
func(nx, ny, nz);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(58, glIsEnabled, GLboolean, (GLenum cap))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
return trampoline(cap);
|
||||||
|
#else
|
||||||
|
GLenum cap = next_int();
|
||||||
|
// Run
|
||||||
|
ret(func(cap));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(pname, (uint32_t) params);
|
||||||
|
#else
|
||||||
|
GLenum pname = next_int();
|
||||||
|
GLint *params = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(pname, params);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(x, y, width, height, format, type, (uint32_t) data);
|
||||||
|
#else
|
||||||
|
GLint x = next_int();
|
||||||
|
GLint y = next_int();
|
||||||
|
GLsizei width = next_int();
|
||||||
|
GLsizei height = next_int();
|
||||||
|
GLenum format = next_int();
|
||||||
|
GLenum type = next_int();
|
||||||
|
void *data = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(x, y, width, height, format, type, data);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(67, glGenBuffers, void, (GLsizei n, GLuint *buffers))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(n, (uint32_t) buffers);
|
||||||
|
#else
|
||||||
|
GLsizei n = next_int();
|
||||||
|
GLuint *buffers = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(n, buffers);
|
||||||
|
#endif
|
||||||
|
}
|
21
media-layer/trampoline/src/common/common.h
Normal file
21
media-layer/trampoline/src/common/common.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __BYTE_ORDER != __LITTLE_ENDIAN
|
||||||
|
#error "Only Little Endian Is Supported"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_HOST)
|
||||||
|
#include "../host/host.h"
|
||||||
|
#elif defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
#include "../guest/guest.h"
|
||||||
|
#else
|
||||||
|
#error "Invalid Configuration"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#define pun_to(type, x) (*(type *) &(x))
|
||||||
|
#define pun_to(type, x) \
|
||||||
|
({ \
|
||||||
|
union { typeof(x) a; type b; } _pun; \
|
||||||
|
_pun.a = x; \
|
||||||
|
_pun.b; \
|
||||||
|
})
|
15
media-layer/trampoline/src/guest/guest.c
Normal file
15
media-layer/trampoline/src/guest/guest.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "guest.h"
|
||||||
|
|
||||||
|
uint32_t _trampoline(uint32_t id, uint32_t *args) {
|
||||||
|
// Make Syscall
|
||||||
|
long ret = syscall(0x1337 /* See trampoline.patch */, id, args);
|
||||||
|
if (ret == -1) {
|
||||||
|
// Error
|
||||||
|
ERR("Trampoline Error: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
// Return
|
||||||
|
return args[0];
|
||||||
|
}
|
12
media-layer/trampoline/src/guest/guest.h
Normal file
12
media-layer/trampoline/src/guest/guest.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Trampoline Function
|
||||||
|
uint32_t _trampoline(uint32_t id, uint32_t *args);
|
||||||
|
#define trampoline(...) _trampoline(_id, (uint32_t[]){__VA_ARGS__})
|
||||||
|
|
||||||
|
// Macro
|
||||||
|
#define CALL(unique_id, name, return_type, args) \
|
||||||
|
return_type name args { \
|
||||||
|
static unsigned char _id = unique_id;
|
17
media-layer/trampoline/src/host/host.c
Normal file
17
media-layer/trampoline/src/host/host.c
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "host.h"
|
||||||
|
|
||||||
|
// Registration
|
||||||
|
static handler_t *handlers[256];
|
||||||
|
void _add_handler(unsigned char id, handler_t *handler) {
|
||||||
|
if (handlers[id]) {
|
||||||
|
ERR("Conflicting Trampolines For ID: %i", (int) id);
|
||||||
|
}
|
||||||
|
handlers[id] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trampoline
|
||||||
|
void trampoline(g2h_t g2h, uint32_t id, uint32_t *args) {
|
||||||
|
handlers[id](g2h, args);
|
||||||
|
}
|
27
media-layer/trampoline/src/host/host.h
Normal file
27
media-layer/trampoline/src/host/host.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Trampoline Function
|
||||||
|
typedef void *(*g2h_t)(uint32_t guest_addr);
|
||||||
|
void trampoline(g2h_t g2h, uint32_t id, uint32_t *args); // See trampoline.patch
|
||||||
|
|
||||||
|
// Macro
|
||||||
|
typedef void handler_t(g2h_t g2h, uint32_t *args);
|
||||||
|
__attribute__((visibility("internal"))) void _add_handler(unsigned char id, handler_t *handler);
|
||||||
|
#define CALL(unique_id, name, ignored1, ignored2) \
|
||||||
|
static handler_t _run_##name; \
|
||||||
|
__attribute__((constructor)) static void _init_##name() { \
|
||||||
|
_add_handler(unique_id, _run_##name); \
|
||||||
|
} \
|
||||||
|
static void _run_##name(__attribute__((unused)) g2h_t g2h, __attribute__((unused)) uint32_t *args) { \
|
||||||
|
__attribute__((unused)) int _current_arg = 0; \
|
||||||
|
static typeof(name) *func = name;
|
||||||
|
|
||||||
|
// Helper Macros
|
||||||
|
#define next_int() args[_current_arg++]
|
||||||
|
#define next_ptr() g2h(next_int())
|
||||||
|
#define next_float() pun_to(float, next_int())
|
||||||
|
#define ret(x) \
|
||||||
|
args[0] = x; \
|
||||||
|
return;
|
188
media-layer/trampoline/src/media-layer-core.c
Normal file
188
media-layer/trampoline/src/media-layer-core.c
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
#include <media-layer/core.h>
|
||||||
|
#include <media-layer/audio.h>
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
|
// SDL Functions
|
||||||
|
|
||||||
|
CALL(0, SDL_Init, int, (uint32_t flags))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
return trampoline(flags);
|
||||||
|
#else
|
||||||
|
uint32_t flags = next_int();
|
||||||
|
// Run
|
||||||
|
ret(func(flags));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(1, SDL_PollEvent, int, (SDL_Event *event))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
return trampoline((uint32_t) event);
|
||||||
|
#else
|
||||||
|
SDL_Event *event = next_ptr();
|
||||||
|
// Run
|
||||||
|
ret(func(event));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(2, SDL_PushEvent, int, (SDL_Event *event))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
return trampoline((uint32_t) event);
|
||||||
|
#else
|
||||||
|
SDL_Event *event = next_ptr();
|
||||||
|
// Run
|
||||||
|
ret(func(event));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(3, SDL_WM_SetCaption, void, (const char *title, const char *icon))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline((uint32_t) title, (uint32_t) icon);
|
||||||
|
#else
|
||||||
|
char *title = next_ptr();
|
||||||
|
char *icon = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(title, icon);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(4, media_toggle_fullscreen, void, ())
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline();
|
||||||
|
#else
|
||||||
|
// Run
|
||||||
|
func();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
return trampoline(mode);
|
||||||
|
#else
|
||||||
|
SDL_GrabMode mode = next_int();
|
||||||
|
// Run
|
||||||
|
ret(func(mode));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(6, SDL_ShowCursor, int, (int32_t toggle))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
return trampoline(toggle);
|
||||||
|
#else
|
||||||
|
int mode = next_int();
|
||||||
|
// Run
|
||||||
|
ret(func(mode));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(8, media_swap_buffers, void, ())
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline();
|
||||||
|
#else
|
||||||
|
// Run
|
||||||
|
func();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(9, media_cleanup, void, ())
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline();
|
||||||
|
#else
|
||||||
|
// Run
|
||||||
|
func();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(10, media_get_framebuffer_size, void, (int *width, int *height))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline((uint32_t) width, (uint32_t) height);
|
||||||
|
#else
|
||||||
|
int *width = next_ptr();
|
||||||
|
int *height = next_ptr();
|
||||||
|
// Run
|
||||||
|
func(width, height);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(59, media_audio_update, void, (float volume, float x, float y, float z, float yaw))
|
||||||
|
#if defined(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();
|
||||||
|
float x = next_float();
|
||||||
|
float y = next_float();
|
||||||
|
float z = next_float();
|
||||||
|
float yaw = next_float();
|
||||||
|
// Run
|
||||||
|
func(volume, x, y, z, yaw);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
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();
|
||||||
|
char *name = next_ptr();
|
||||||
|
float x = next_float();
|
||||||
|
float y = next_float();
|
||||||
|
float z = next_float();
|
||||||
|
float pitch = next_float();
|
||||||
|
float volume = next_float();
|
||||||
|
int is_ui = next_int();
|
||||||
|
// Run
|
||||||
|
func(source, name, x, y, z, pitch, volume, is_ui);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(62, media_set_interactable, void, (int is_interactable))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(is_interactable);
|
||||||
|
#else
|
||||||
|
int is_interactable = next_int();
|
||||||
|
// Run
|
||||||
|
func(is_interactable);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(63, media_disable_vsync, void, ())
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline();
|
||||||
|
#else
|
||||||
|
// Run
|
||||||
|
func();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled))
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline(enabled);
|
||||||
|
#else
|
||||||
|
int enabled = next_int();
|
||||||
|
// Run
|
||||||
|
func(enabled);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(66, media_force_egl, void, ())
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline();
|
||||||
|
#else
|
||||||
|
// Run
|
||||||
|
func();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(68, media_ensure_loaded, void, ())
|
||||||
|
#if defined(MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||||
|
trampoline();
|
||||||
|
#else
|
||||||
|
// Run
|
||||||
|
func();
|
||||||
|
#endif
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user