Merge and add requested changes

This commit is contained in:
Bigjango13 2024-10-22 16:42:45 -07:00
commit 375c4be7ae
84 changed files with 1842 additions and 1022 deletions

@ -1 +1 @@
Subproject commit 16962f2f36a51b2acefad9cec3622f6de5730aa3 Subproject commit bae887e095d87e756d1bf4aa4f95a97693a97b62

View File

@ -48,6 +48,9 @@
* `Click Buttons On Mouse Down` (Enabled By Default) * `Click Buttons On Mouse Down` (Enabled By Default)
* `3D Dropped Items` (Enabled By Default) * `3D Dropped Items` (Enabled By Default)
* `Render Entity Shadows` (Enabled By Default) * `Render Entity Shadows` (Enabled By Default)
* `Render Vignette` (Enabled By Default)
* `Increase Render Chunk Size` (Enabled By Default)
* `Proper Entity Shading` (Enabled By Default)
* Existing Functionality (All Enabled By Default) * Existing Functionality (All Enabled By Default)
* `Fix Screen Rendering When Hiding HUD` * `Fix Screen Rendering When Hiding HUD`
* `Sanitize Usernames` * `Sanitize Usernames`

View File

@ -101,22 +101,57 @@ void bootstrap(const options_t &options) {
} }
} }
// Fix MCPI Dependencies // Configure Preloaded Objects
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX"; std::vector<std::string> mcpi_ld_preload;
std::string linker;
{ {
// Log // Log
DEBUG("Patching ELF Dependencies..."); DEBUG("Locating Mods...");
// ARM Components
mcpi_ld_preload = bootstrap_mods(binary_directory);
}
// Configure Library Search Path
std::vector<std::string> mcpi_ld_path;
{
// Log
DEBUG("Setting Linker Search Paths...");
// Library Search Path For ARM Components
{
// Add ARM Library Directory
mcpi_ld_path.push_back("lib/arm");
// Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System)
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
mcpi_ld_path.push_back("sysroot/lib");
mcpi_ld_path.push_back("sysroot/lib/arm-linux-gnueabihf");
mcpi_ld_path.push_back("sysroot/usr/lib");
mcpi_ld_path.push_back("sysroot/usr/lib/arm-linux-gnueabihf");
#endif
// Fix Paths
for (std::string &path : mcpi_ld_path) {
path = binary_directory + '/' + path;
}
}
}
// Fix MCPI Dependencies
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
{
// Log
DEBUG("Patching ELF...");
// Find Linker // Find Linker
linker = "/lib/ld-linux-armhf.so.3"; std::string linker = "/lib/ld-linux-armhf.so.3";
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN #ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
// Use ARM Sysroot Linker // Use ARM Sysroot Linker
linker = binary_directory + "/sysroot" + linker; linker = binary_directory + "/sysroot" + linker;
#endif #endif
// Patch // Patch
patch_mcpi_elf_dependencies(game_binary.c_str(), new_mcpi_exe_path); patch_mcpi_elf_dependencies(game_binary, new_mcpi_exe_path, linker, mcpi_ld_path, mcpi_ld_preload);
// Verify // Verify
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) { if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
@ -132,37 +167,6 @@ void bootstrap(const options_t &options) {
set_and_print_env(_MCPI_VANILLA_ASSETS_PATH_ENV, assets_path.c_str()); set_and_print_env(_MCPI_VANILLA_ASSETS_PATH_ENV, assets_path.c_str());
} }
// Configure Library Search Path
std::string mcpi_ld_path = "";
{
// Log
DEBUG("Setting Linker Search Paths...");
// 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
}
}
// Configure Preloaded Objects
std::string mcpi_ld_preload;
{
// Log
DEBUG("Locating Mods...");
// ARM Components
mcpi_ld_preload = bootstrap_mods(binary_directory);
}
// Start Game // Start Game
INFO("Starting Game..."); INFO("Starting Game...");
@ -178,13 +182,6 @@ void bootstrap(const options_t &options) {
args.push_back("0x40000"); // Arbitrary Value (Aligns To 4k And 16k Page Sizes) args.push_back("0x40000"); // Arbitrary Value (Aligns To 4k And 16k Page Sizes)
#endif #endif
// Setup Linker
args.push_back(linker);
args.push_back("--library-path");
args.push_back(mcpi_ld_path);
args.push_back("--preload");
args.push_back(mcpi_ld_preload);
// Specify MCPI Binary // Specify MCPI Binary
args.push_back(new_mcpi_exe_path); args.push_back(new_mcpi_exe_path);

View File

@ -1,9 +1,10 @@
#pragma once #pragma once
#include <string> #include <string>
#include <vector>
#include "options/parser.h" #include "options/parser.h"
void bootstrap(const options_t &options); void bootstrap(const options_t &options);
void copy_sdk(const std::string &binary_directory, bool log_with_debug); void copy_sdk(const std::string &binary_directory, bool log_with_debug);
std::string bootstrap_mods(const std::string &binary_directory); std::vector<std::string> bootstrap_mods(const std::string &binary_directory);

View File

@ -113,3 +113,5 @@ TRUE 3D Dropped Items
TRUE Render Entity Shadows TRUE Render Entity Shadows
TRUE Render Vignette TRUE Render Vignette
TRUE Implement RaspberryJuice API TRUE Implement RaspberryJuice API
TRUE Increase Render Chunk Size
TRUE Proper Entity Shading

View File

@ -8,14 +8,14 @@
#include "bootstrap.h" #include "bootstrap.h"
// Get All Mods In Folder // Get All Mods In Folder
static void load(std::string &ld_preload, const std::string &folder, int recursion_limit = 128); static void load(std::vector<std::string> &ld_preload, const std::string &folder, int recursion_limit = 128);
static void handle_file(std::string &ld_preload, const std::string &file, const int recursion_limit) { static void handle_file(std::vector<std::string> &ld_preload, const std::string &file, const int recursion_limit) {
// Check Type // Check Type
struct stat file_stat = {}; struct stat file_stat = {};
lstat(file.c_str(), &file_stat); lstat(file.c_str(), &file_stat);
if (S_ISDIR(file_stat.st_mode)) { if (S_ISDIR(file_stat.st_mode)) {
// Recurse Into Directory // Recurse Into Directory
load(ld_preload, std::string(file) + "/", recursion_limit - 1); load(ld_preload, std::string(file) + '/', recursion_limit - 1);
} else if (S_ISLNK(file_stat.st_mode)) { } else if (S_ISLNK(file_stat.st_mode)) {
// Resolve Symlink // Resolve Symlink
char *resolved_file = realpath(file.c_str(), nullptr); char *resolved_file = realpath(file.c_str(), nullptr);
@ -27,7 +27,8 @@ static void handle_file(std::string &ld_preload, const std::string &file, const
const int result = access(file.c_str(), R_OK); const int result = access(file.c_str(), R_OK);
if (result == 0) { if (result == 0) {
// Add To LD_PRELOAD // Add To LD_PRELOAD
ld_preload += file + ":"; DEBUG("Found Mod: %s", file.c_str());
ld_preload.push_back(file);
} else if (result == -1 && errno != 0) { } else if (result == -1 && errno != 0) {
// Fail // Fail
WARN("Unable To Access: %s: %s", file.c_str(), strerror(errno)); WARN("Unable To Access: %s: %s", file.c_str(), strerror(errno));
@ -35,7 +36,7 @@ static void handle_file(std::string &ld_preload, const std::string &file, const
} }
} }
} }
static void load(std::string &ld_preload, const std::string &folder, const int recursion_limit) { static void load(std::vector<std::string> &ld_preload, const std::string &folder, const int recursion_limit) {
// Check Recursion // Check Recursion
if (recursion_limit <= 0) { if (recursion_limit <= 0) {
ERR("Reached Recursion Limit While Loading Mods"); ERR("Reached Recursion Limit While Loading Mods");
@ -74,9 +75,9 @@ static void load(std::string &ld_preload, const std::string &folder, const int r
// Bootstrap Mods // Bootstrap Mods
#define SUBDIRECTORY_FOR_MODS "/mods/" #define SUBDIRECTORY_FOR_MODS "/mods/"
std::string bootstrap_mods(const std::string &binary_directory) { std::vector<std::string> bootstrap_mods(const std::string &binary_directory) {
// Prepare // Prepare
std::string preload = ""; std::vector<std::string> preload;
// ~/.minecraft-pi/mods // ~/.minecraft-pi/mods
{ {

View File

@ -1,5 +1,6 @@
#include <cstdlib> #include <cstdlib>
#include <sys/stat.h> #include <sys/stat.h>
#include <ranges>
#include <LIEF/ELF.hpp> #include <LIEF/ELF.hpp>
@ -16,7 +17,7 @@ static void duplicate_mcpi_executable(char *new_path) {
ensure_directory(MCPI_PATCHED_DIR); ensure_directory(MCPI_PATCHED_DIR);
// Generate New File // Generate New File
int new_file_fd = mkstemp(new_path); const int new_file_fd = mkstemp(new_path);
if (new_file_fd == -1) { if (new_file_fd == -1) {
ERR("Unable To Create Temporary File: %s", strerror(errno)); ERR("Unable To Create Temporary File: %s", strerror(errno));
} }
@ -24,34 +25,72 @@ static void duplicate_mcpi_executable(char *new_path) {
} }
// Fix MCPI Dependencies // Fix MCPI Dependencies
static const char *libraries_to_remove[] = { static std::vector<std::string> needed_libraries = {
"libbcm_host.so", "libmedia-layer-core.so",
"libX11.so.6", "libpng12.so.0",
"libEGL.so", "libstdc++.so.6",
"libGLESv2.so", "libm.so.6",
"libSDL-1.2.so.0" "libgcc_s.so.1",
"libc.so.6",
"libpthread.so.0"
}; };
static const char *libraries_to_add[] = { static std::vector<std::string> function_prefixes_to_patch = {
"libmedia-layer-core.so" "SDL_",
"gl"
}; };
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path) { void patch_mcpi_elf_dependencies(const std::string &original_path, char *new_path, const std::string &interpreter, const std::vector<std::string> &rpath, const std::vector<std::string> &mods) {
// Duplicate MCPI executable into /tmp so it can be modified. // Duplicate MCPI executable into /tmp so it can be modified.
duplicate_mcpi_executable(new_path); duplicate_mcpi_executable(new_path);
// Patch File // Load Binary
{ std::unique_ptr<LIEF::ELF::Binary> binary = LIEF::ELF::Parser::parse(original_path);
std::unique_ptr<LIEF::ELF::Binary> binary = LIEF::ELF::Parser::parse(original_path);
for (size_t i = 0; i < (sizeof (libraries_to_remove) / sizeof (const char *)); i++) { // Set Interpreter
binary->remove_library(libraries_to_remove[i]); if (!interpreter.empty()) {
} binary->interpreter(interpreter);
for (size_t i = 0; i < (sizeof (libraries_to_add) / sizeof (const char *)); i++) {
binary->add_library(libraries_to_add[i]);
}
LIEF::ELF::Builder builder{*binary};
builder.build();
builder.write(new_path);
} }
// Remove Existing Needed Libraries
std::vector<std::string> to_remove;
for (const LIEF::ELF::DynamicEntry &entry : binary->dynamic_entries()) {
const LIEF::ELF::DynamicEntryLibrary *library = dynamic_cast<const LIEF::ELF::DynamicEntryLibrary *>(&entry);
if (library) {
to_remove.push_back(library->name());
}
}
for (const std::string &library : to_remove) {
binary->remove_library(library);
}
// Setup RPath
binary->add(LIEF::ELF::DynamicEntryRpath(rpath));
// Add Libraries
std::vector<std::string> all_libraries;
for (const std::vector<std::string> &list : {mods, needed_libraries}) {
all_libraries.insert(all_libraries.end(), list.begin(), list.end());
}
for (const std::string &library : all_libraries | std::views::reverse) {
binary->add_library(library);
}
// Fix Symbol Names
for (LIEF::ELF::Symbol &symbol : binary->dynamic_symbols()) {
if (symbol.is_function()) {
for (const std::string &prefix : function_prefixes_to_patch) {
if (symbol.name().rfind(prefix, 0) == 0) {
symbol.name("media_" + symbol.name());
break;
}
}
}
}
// Write Binary
LIEF::ELF::Builder builder{*binary};
builder.build();
builder.write(new_path);
// Fix Permissions // Fix Permissions
if (chmod(new_path, S_IRUSR | S_IXUSR) != 0) { if (chmod(new_path, S_IRUSR | S_IXUSR) != 0) {
ERR("Unable To Set File Permissions: %s: %s", new_path, strerror(errno)); ERR("Unable To Set File Permissions: %s: %s", new_path, strerror(errno));

View File

@ -1,13 +1,8 @@
#pragma once #pragma once
#ifdef __cplusplus #include <string>
extern "C" { #include <vector>
#endif
#define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched" #define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched"
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path); void patch_mcpi_elf_dependencies(const std::string &original_path, char *new_path, const std::string &interpreter, const std::vector<std::string> &rpath, const std::vector<std::string> &mods);
#ifdef __cplusplus
}
#endif

View File

@ -10,7 +10,7 @@
void reborn_init_patch(); void reborn_init_patch();
// Replace Call Located At start With A Call To target // Replace Call Located At start With A Call To target
void overwrite_call(void *start, void *target); void overwrite_call(void *start, void *target, bool force_b_instruction = false);
// Replace All Calls To Method start With target // Replace All Calls To Method start With target
void *overwrite_calls_manual(void *start, void *target, bool allow_no_callsites = false); void *overwrite_calls_manual(void *start, void *target, bool allow_no_callsites = false);

View File

@ -21,8 +21,8 @@ static void _overwrite_call_internal(void *start, void *target, const bool use_b
// Increment Code Block Position // Increment Code Block Position
increment_code_block(); increment_code_block();
} }
void overwrite_call(void *start, void *target) { void overwrite_call(void *start, void *target, const bool force_b_instruction) {
const bool use_b_instruction = ((unsigned char *) start)[3] == B_INSTRUCTION; const bool use_b_instruction = force_b_instruction || ((unsigned char *) start)[3] == B_INSTRUCTION;
_overwrite_call_internal(start, target, use_b_instruction); _overwrite_call_internal(start, target, use_b_instruction);
} }

View File

@ -19,9 +19,6 @@ if(BUILD_ARM_COMPONENTS)
) )
endif() endif()
# Add Extras
add_subdirectory(extras)
# Add Core # Add Core
if(BUILD_MEDIA_LAYER_CORE) if(BUILD_MEDIA_LAYER_CORE)
add_subdirectory(gles) add_subdirectory(gles)

View File

@ -4,10 +4,12 @@ project(media-layer-core)
set(CORE_SRC set(CORE_SRC
src/base.cpp src/base.cpp
src/media.cpp src/media.cpp
src/cursor.cpp
src/util.cpp
src/events.cpp
src/audio/api.cpp src/audio/api.cpp
src/audio/engine.c src/audio/engine.c
src/audio/file.cpp src/audio/file.cpp
$<TARGET_OBJECTS:media-layer-extras>
) )
# Build # Build

View File

@ -2,13 +2,14 @@
#include <SDL/SDL.h> #include <SDL/SDL.h>
#include <media-layer/internal.h>
#include <media-layer/core.h> #include <media-layer/core.h>
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#include "media.h"
// SDL Is Replaced With GLFW // SDL Is Replaced With GLFW
int SDL_Init(__attribute__((unused)) uint32_t flags) { int media_SDL_Init(__attribute__((unused)) uint32_t flags) {
return 0; return 0;
} }
@ -16,9 +17,9 @@ int SDL_Init(__attribute__((unused)) uint32_t flags) {
static std::vector<SDL_Event> queue; static std::vector<SDL_Event> queue;
int SDL_PollEvent(SDL_Event *event) { int media_SDL_PollEvent(SDL_Event *event) {
// Handle External Events // Handle External Events
_media_handle_SDL_PollEvent(); _media_handle_media_SDL_PollEvent();
// Poll Event // Poll Event
int ret; int ret;
@ -32,7 +33,7 @@ int SDL_PollEvent(SDL_Event *event) {
return ret; return ret;
} }
int SDL_PushEvent(SDL_Event *event) { int media_SDL_PushEvent(SDL_Event *event) {
queue.push_back(*event); queue.push_back(*event);
return 1; return 1;
} }

View File

@ -0,0 +1,108 @@
#include "media.h"
// Enable/Disable Raw Mouse Motion
bool raw_mouse_motion_enabled = true;
void media_set_raw_mouse_motion_enabled(const int enabled) {
raw_mouse_motion_enabled = enabled;
if (glfw_window) {
glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE);
}
if (!raw_mouse_motion_enabled) {
WARN("Raw mouse motion has been DISABLED, this IS NOT recommended, and should only ever be used on systems that don't support or have broken raw mouse motion.");
}
}
// Store Cursor State
static bool cursor_grabbed = false;
static bool cursor_visible = true;
// Ignore Relative Cursor Motion
bool ignore_relative_motion = false;
// Update GLFW Cursor State (Client Only)
void _media_update_cursor() {
if (glfw_window) {
// Get New State
const bool new_cursor_visible = is_interactable ? cursor_visible : true;
const bool new_cursor_grabbed = is_interactable ? cursor_grabbed : false;
// Store Old Mode
const int old_mode = glfwGetInputMode(glfw_window, GLFW_CURSOR);
// Handle Cursor Visibility
int new_mode;
if (!new_cursor_visible) {
if (new_cursor_grabbed) {
new_mode = GLFW_CURSOR_DISABLED;
} else {
new_mode = GLFW_CURSOR_HIDDEN;
}
} else {
new_mode = GLFW_CURSOR_NORMAL;
}
if (new_mode != old_mode) {
// Ignore Relative Cursor Motion When Locking
if (new_mode == GLFW_CURSOR_DISABLED && old_mode != GLFW_CURSOR_DISABLED) {
ignore_relative_motion = true;
}
// Set New Mode
glfwSetInputMode(glfw_window, GLFW_CURSOR, new_mode);
// Handle Cursor Lock/Unlock
if ((new_mode == GLFW_CURSOR_DISABLED && old_mode != GLFW_CURSOR_DISABLED) || (new_mode != GLFW_CURSOR_DISABLED && old_mode == GLFW_CURSOR_DISABLED)) {
// Use Raw Mouse Motion
if (raw_mouse_motion_enabled) {
glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, new_mode == GLFW_CURSOR_DISABLED ? GLFW_TRUE : GLFW_FALSE);
}
// Request Focus
glfwRequestWindowAttention(glfw_window);
}
// Reset Mouse Position When Unlocking
if (new_mode != GLFW_CURSOR_DISABLED && old_mode == GLFW_CURSOR_DISABLED) {
double cursor_x;
double cursor_y;
glfwGetCursorPos(glfw_window, &cursor_x, &cursor_y);
_media_glfw_motion(glfw_window, cursor_x, cursor_y);
}
}
}
}
// Fix SDL Cursor Visibility/Grabbing
SDL_GrabMode media_SDL_WM_GrabInput(const SDL_GrabMode mode) {
if (mode == SDL_GRAB_QUERY) {
// Query
return cursor_grabbed ? SDL_GRAB_ON : SDL_GRAB_OFF;
} else if (mode == SDL_GRAB_ON) {
// Store State
cursor_grabbed = true;
} else if (mode == SDL_GRAB_OFF) {
// Store State
cursor_grabbed = false;
}
// Update Cursor GLFW State (Client Only)
_media_update_cursor();
// Return
return mode;
}
// Stub SDL Cursor Visibility
int media_SDL_ShowCursor(const int toggle) {
if (toggle == SDL_QUERY) {
// Query
return cursor_visible ? SDL_ENABLE : SDL_DISABLE;
} else if (toggle == SDL_ENABLE) {
// Store State
cursor_visible = true;
} else if (toggle == SDL_DISABLE) {
// Store State
cursor_visible = false;
}
// Update Cursor GLFW State (Client Only)
_media_update_cursor();
// Return
return toggle;
}

View File

@ -0,0 +1,275 @@
#include "media.h"
// Convert GLFW Key To SDL Key
static SDLKey glfw_key_to_sdl_key(const int key) {
switch (key) {
// Movement
case GLFW_KEY_W:
return SDLK_w;
case GLFW_KEY_A:
return SDLK_a;
case GLFW_KEY_S:
return SDLK_s;
case GLFW_KEY_D:
return SDLK_d;
case GLFW_KEY_SPACE:
return SDLK_SPACE;
case GLFW_KEY_LEFT_SHIFT:
return SDLK_LSHIFT;
case GLFW_KEY_RIGHT_SHIFT:
return SDLK_RSHIFT;
// Inventory
case GLFW_KEY_E:
return SDLK_e;
// Drop Item
case GLFW_KEY_Q:
return SDLK_q;
// Toolbar
case GLFW_KEY_1:
return SDLK_1;
case GLFW_KEY_2:
return SDLK_2;
case GLFW_KEY_3:
return SDLK_3;
case GLFW_KEY_4:
return SDLK_4;
case GLFW_KEY_5:
return SDLK_5;
case GLFW_KEY_6:
return SDLK_6;
case GLFW_KEY_7:
return SDLK_7;
case GLFW_KEY_8:
return SDLK_8;
case GLFW_KEY_9:
return SDLK_9;
case GLFW_KEY_0:
return SDLK_0;
// UI Control
case GLFW_KEY_ESCAPE:
return SDLK_ESCAPE;
case GLFW_KEY_UP:
return SDLK_UP;
case GLFW_KEY_DOWN:
return SDLK_DOWN;
case GLFW_KEY_LEFT:
return SDLK_LEFT;
case GLFW_KEY_RIGHT:
return SDLK_RIGHT;
case GLFW_KEY_TAB:
return SDLK_TAB;
case GLFW_KEY_ENTER:
return SDLK_RETURN;
case GLFW_KEY_BACKSPACE:
return SDLK_BACKSPACE;
case GLFW_KEY_DELETE:
return SDLK_DELETE;
// Fullscreen
case GLFW_KEY_F11:
return SDLK_F11;
// Screenshot
case GLFW_KEY_F2:
return SDLK_F2;
// Debug
case GLFW_KEY_F3:
return SDLK_F3;
// Hide GUI
case GLFW_KEY_F1:
return SDLK_F1;
// Third Person
case GLFW_KEY_F5:
return SDLK_F5;
// Chat
case GLFW_KEY_T:
return SDLK_t;
// Unknown
default:
return SDLK_UNKNOWN;
}
}
// Convert GLFW Key Modifier To SDL Key Modifier
static SDLMod glfw_modifier_to_sdl_modifier(const int mods) {
int ret = KMOD_NONE;
// Control
if ((mods & GLFW_MOD_CONTROL) != 0) {
ret |= KMOD_CTRL;
}
// Shift
if ((mods & GLFW_MOD_SHIFT) != 0) {
ret |= KMOD_SHIFT;
}
// Alt
if ((mods & GLFW_MOD_ALT) != 0) {
ret |= KMOD_ALT;
}
// Return
return SDLMod(ret);
}
// Pass Key Presses To SDL
static void glfw_key_raw(int key, int scancode, int action, int mods) {
SDL_Event event1;
bool up = action == GLFW_RELEASE;
event1.type = up ? SDL_KEYUP : SDL_KEYDOWN;
event1.key.state = up ? SDL_RELEASED : SDL_PRESSED;
event1.key.keysym.scancode = scancode;
event1.key.keysym.mod = glfw_modifier_to_sdl_modifier(mods);
event1.key.keysym.sym = glfw_key_to_sdl_key(key);
media_SDL_PushEvent(&event1);
// Allow MCPI To Access Original GLFW Keycode
SDL_Event event2;
event2.type = SDL_USEREVENT;
event2.user.code = USER_EVENT_REAL_KEY;
event2.user.data1 = event1.key.state;
event2.user.data2 = key;
media_SDL_PushEvent(&event2);
}
static void glfw_key(__attribute__((unused)) GLFWwindow *window, const int key, const int scancode, const int action, const int mods) {
if (is_interactable) {
glfw_key_raw(key, scancode, action, mods);
}
}
// Pass Text To Minecraft
static void character_event(char c) {
if (!is_interactable) {
return;
}
// SDL_UserEvent Is Never Used In MCPI, So It Is Repurposed For Character Events
SDL_Event event;
event.type = SDL_USEREVENT;
event.user.code = USER_EVENT_CHARACTER;
event.user.data1 = (int) c;
media_SDL_PushEvent(&event);
}
static void codepoint_to_utf8(unsigned char *const buffer, const unsigned int code) {
// https://stackoverflow.com/a/42013433/16198887
if (code <= 0x7f) {
buffer[0] = code;
} else if (code <= 0x7ff) {
buffer[0] = 0xc0 | (code >> 6); // 110xxxxx
buffer[1] = 0x80 | (code & 0x3f); // 10xxxxxx
} else if (code <= 0xffff) {
buffer[0] = 0xe0 | (code >> 12); // 1110xxxx
buffer[1] = 0x80 | ((code >> 6) & 0x3f); // 10xxxxxx
buffer[2] = 0x80 | (code & 0x3f); // 10xxxxxx
} else if (code <= 0x10ffff) {
buffer[0] = 0xf0 | (code >> 18); // 11110xxx
buffer[1] = 0x80 | ((code >> 12) & 0x3f); // 10xxxxxx
buffer[2] = 0x80 | ((code >> 6) & 0x3f); // 10xxxxxx
buffer[3] = 0x80 | (code & 0x3f); // 10xxxxxx
}
}
static void glfw_char(__attribute__((unused)) GLFWwindow *window, const unsigned int codepoint) {
// Convert
size_t str_size = 4 /* Maximum UTF-8 character size */ + 1 /* NULL-terminator */;
char str[str_size] = {};
codepoint_to_utf8((unsigned char *) str, codepoint);
char *cp437_str = to_cp437(str);
// Send Event
for (int i = 0; cp437_str[i] != '\0'; i++) {
character_event(cp437_str[i]);
}
// Free
free(cp437_str);
}
// Convert Screen Coordinates To Pixels
static void convert_to_pixels(GLFWwindow *window, double *xpos, double *ypos) {
// Skip If Cursor Is Grabbed
if (media_SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON && raw_mouse_motion_enabled) {
return;
}
// Get Window Size
int window_width;
int window_height;
glfwGetWindowSize(window, &window_width, &window_height);
// Get Framebuffer Size
int framebuffer_width;
int framebuffer_height;
glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
// Calculate Ratios
const double width_ratio = ((double) framebuffer_width) / ((double) window_width);
const double height_ratio = ((double) framebuffer_height) / ((double) window_height);
// Multiply
*xpos *= width_ratio;
*ypos *= height_ratio;
}
// Last Mouse Location
static double last_mouse_x = 0;
static double last_mouse_y = 0;
// Pass Mouse Movement To SDL
void _media_glfw_motion(__attribute__((unused)) GLFWwindow *window, double xpos, double ypos) {
convert_to_pixels(window, &xpos, &ypos);
if (is_interactable) {
SDL_Event event;
event.type = SDL_MOUSEMOTION;
event.motion.x = uint16_t(xpos);
event.motion.y = uint16_t(ypos);
event.motion.xrel = !ignore_relative_motion ? (xpos - last_mouse_x) : 0;
event.motion.yrel = !ignore_relative_motion ? (ypos - last_mouse_y) : 0;
media_SDL_PushEvent(&event);
}
ignore_relative_motion = false;
last_mouse_x = xpos;
last_mouse_y = ypos;
}
// Create And Push SDL Mouse Click Event
static void click_event(int button, bool up) {
SDL_Event event;
event.type = up ? SDL_MOUSEBUTTONUP : SDL_MOUSEBUTTONDOWN;
event.button.x = uint16_t(last_mouse_x);
event.button.y = uint16_t(last_mouse_y);
event.button.state = up ? SDL_RELEASED : SDL_PRESSED;
event.button.button = button;
media_SDL_PushEvent(&event);
}
// Pass Mouse Click To SDL
static void glfw_click_raw(const int button, const int action) {
const bool up = action == GLFW_RELEASE;
const int sdl_button = button == GLFW_MOUSE_BUTTON_RIGHT ? SDL_BUTTON_RIGHT : (button == GLFW_MOUSE_BUTTON_LEFT ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE);
click_event(sdl_button, up);
}
static void glfw_click(__attribute__((unused)) GLFWwindow *window, const int button, const int action, __attribute__((unused)) int mods) {
if (is_interactable) {
glfw_click_raw(button, action);
}
}
// Pass Mouse Scroll To SDL
static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute__((unused)) double xoffset, double yoffset) {
if (is_interactable && yoffset != 0) {
const int sdl_button = yoffset > 0 ? SDL_BUTTON_WHEELUP : SDL_BUTTON_WHEELDOWN;
click_event(sdl_button, false);
click_event(sdl_button, true);
}
}
// Intercept SDL Events
void _media_handle_media_SDL_PollEvent() {
if (glfw_window) {
// Process GLFW Events
glfwPollEvents();
// Close Window
if (glfwWindowShouldClose(glfw_window)) {
SDL_Event event;
event.type = SDL_QUIT;
media_SDL_PushEvent(&event);
glfwSetWindowShouldClose(glfw_window, GLFW_FALSE);
}
}
}
// Register Event Listeners
void _media_register_event_listeners() {
glfwSetKeyCallback(glfw_window, glfw_key);
glfwSetCharCallback(glfw_window, glfw_char);
glfwSetCursorPosCallback(glfw_window, _media_glfw_motion);
glfwSetMouseButtonCallback(glfw_window, glfw_click);
glfwSetScrollCallback(glfw_window, glfw_scroll);
}

View File

@ -1,309 +1,21 @@
#include <ctime> #include <ctime>
#include <unistd.h> #include <unistd.h>
#include <SDL/SDL.h> #include "media.h"
#include <libreborn/libreborn.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <media-layer/core.h>
#include <media-layer/internal.h>
#include "audio/engine.h" #include "audio/engine.h"
// Allow Disabling Interaction
static void update_cursor();
static int is_interactable = 1;
void media_set_interactable(const int toggle) {
if (bool(toggle) != is_interactable) {
is_interactable = toggle;
update_cursor();
}
}
// Store Cursor State
static bool cursor_grabbed = false;
static bool cursor_visible = true;
// Track If Raw Mouse Motion Is Enabled
static bool raw_mouse_motion_enabled = true;
// Window // Window
static GLFWwindow *glfw_window = nullptr; GLFWwindow *glfw_window = nullptr;
// Handle GLFW Error // Handle GLFW Error
static void glfw_error(__attribute__((unused)) int error, const char *description) { static void glfw_error(__attribute__((unused)) int error, const char *description) {
WARN("GLFW Error: %s", description); WARN("GLFW Error: %s", description);
} }
// Convert GLFW Key To SDL Key
static SDLKey glfw_key_to_sdl_key(const int key) {
switch (key) {
// Movement
case GLFW_KEY_W:
return SDLK_w;
case GLFW_KEY_A:
return SDLK_a;
case GLFW_KEY_S:
return SDLK_s;
case GLFW_KEY_D:
return SDLK_d;
case GLFW_KEY_SPACE:
return SDLK_SPACE;
case GLFW_KEY_LEFT_SHIFT:
return SDLK_LSHIFT;
case GLFW_KEY_RIGHT_SHIFT:
return SDLK_RSHIFT;
// Inventory
case GLFW_KEY_E:
return SDLK_e;
// Drop Item
case GLFW_KEY_Q:
return SDLK_q;
// Toolbar
case GLFW_KEY_1:
return SDLK_1;
case GLFW_KEY_2:
return SDLK_2;
case GLFW_KEY_3:
return SDLK_3;
case GLFW_KEY_4:
return SDLK_4;
case GLFW_KEY_5:
return SDLK_5;
case GLFW_KEY_6:
return SDLK_6;
case GLFW_KEY_7:
return SDLK_7;
case GLFW_KEY_8:
return SDLK_8;
case GLFW_KEY_9:
return SDLK_9;
case GLFW_KEY_0:
return SDLK_0;
// UI Control
case GLFW_KEY_ESCAPE:
return SDLK_ESCAPE;
case GLFW_KEY_UP:
return SDLK_UP;
case GLFW_KEY_DOWN:
return SDLK_DOWN;
case GLFW_KEY_LEFT:
return SDLK_LEFT;
case GLFW_KEY_RIGHT:
return SDLK_RIGHT;
case GLFW_KEY_TAB:
return SDLK_TAB;
case GLFW_KEY_ENTER:
return SDLK_RETURN;
case GLFW_KEY_BACKSPACE:
return SDLK_BACKSPACE;
case GLFW_KEY_DELETE:
return SDLK_DELETE;
// Fullscreen
case GLFW_KEY_F11:
return SDLK_F11;
// Screenshot
case GLFW_KEY_F2:
return SDLK_F2;
// Debug
case GLFW_KEY_F3:
return SDLK_F3;
// Hide GUI
case GLFW_KEY_F1:
return SDLK_F1;
// Third Person
case GLFW_KEY_F5:
return SDLK_F5;
// Chat
case GLFW_KEY_T:
return SDLK_t;
// Unknown
default:
return SDLK_UNKNOWN;
}
}
// Convert GLFW Key Modifier To SDL Key Modifier
static SDLMod glfw_modifier_to_sdl_modifier(const int mods) {
int ret = KMOD_NONE;
// Control
if ((mods & GLFW_MOD_CONTROL) != 0) {
ret |= KMOD_CTRL;
}
// Shift
if ((mods & GLFW_MOD_SHIFT) != 0) {
ret |= KMOD_SHIFT;
}
// Alt
if ((mods & GLFW_MOD_ALT) != 0) {
ret |= KMOD_ALT;
}
// Return
return SDLMod(ret);
}
// Pass Key Presses To SDL
static void glfw_key_raw(int key, int scancode, int action, int mods) {
SDL_Event event1;
bool up = action == GLFW_RELEASE;
event1.type = up ? SDL_KEYUP : SDL_KEYDOWN;
event1.key.state = up ? SDL_RELEASED : SDL_PRESSED;
event1.key.keysym.scancode = scancode;
event1.key.keysym.mod = glfw_modifier_to_sdl_modifier(mods);
event1.key.keysym.sym = glfw_key_to_sdl_key(key);
SDL_PushEvent(&event1);
// Allow MCPI To Access Original GLFW Keycode
SDL_Event event2;
event2.type = SDL_USEREVENT;
event2.user.code = USER_EVENT_REAL_KEY;
event2.user.data1 = event1.key.state;
event2.user.data2 = key;
SDL_PushEvent(&event2);
}
static void glfw_key(__attribute__((unused)) GLFWwindow *window, const int key, const int scancode, const int action, const int mods) {
if (is_interactable) {
glfw_key_raw(key, scancode, action, mods);
}
}
// Pass Text To Minecraft
static void character_event(char c) {
if (!is_interactable) {
return;
}
// SDL_UserEvent Is Never Used In MCPI, So It Is Repurposed For Character Events
SDL_Event event;
event.type = SDL_USEREVENT;
event.user.code = USER_EVENT_CHARACTER;
event.user.data1 = (int) c;
SDL_PushEvent(&event);
}
static void codepoint_to_utf8(unsigned char *const buffer, const unsigned int code) {
// https://stackoverflow.com/a/42013433/16198887
if (code <= 0x7f) {
buffer[0] = code;
} else if (code <= 0x7ff) {
buffer[0] = 0xc0 | (code >> 6); // 110xxxxx
buffer[1] = 0x80 | (code & 0x3f); // 10xxxxxx
} else if (code <= 0xffff) {
buffer[0] = 0xe0 | (code >> 12); // 1110xxxx
buffer[1] = 0x80 | ((code >> 6) & 0x3f); // 10xxxxxx
buffer[2] = 0x80 | (code & 0x3f); // 10xxxxxx
} else if (code <= 0x10ffff) {
buffer[0] = 0xf0 | (code >> 18); // 11110xxx
buffer[1] = 0x80 | ((code >> 12) & 0x3f); // 10xxxxxx
buffer[2] = 0x80 | ((code >> 6) & 0x3f); // 10xxxxxx
buffer[3] = 0x80 | (code & 0x3f); // 10xxxxxx
}
}
static void glfw_char(__attribute__((unused)) GLFWwindow *window, const unsigned int codepoint) {
// Convert
size_t str_size = 4 /* Maximum UTF-8 character size */ + 1 /* NULL-terminator */;
char str[str_size] = {};
codepoint_to_utf8((unsigned char *) str, codepoint);
char *cp437_str = to_cp437(str);
// Send Event
for (int i = 0; cp437_str[i] != '\0'; i++) {
character_event(cp437_str[i]);
}
// Free
free(cp437_str);
}
// Last Mouse Location
static double last_mouse_x = 0;
static double last_mouse_y = 0;
// Ignore Relative Cursor Motion
static bool ignore_relative_motion = false;
// Convert Screen Coordinates To Pixels
static void convert_to_pixels(GLFWwindow *window, double *xpos, double *ypos) {
// Skip If Cursor Is Grabbed
if (cursor_grabbed && raw_mouse_motion_enabled) {
return;
}
// Get Window Size
int window_width;
int window_height;
glfwGetWindowSize(window, &window_width, &window_height);
// Get Framebuffer Size
int framebuffer_width;
int framebuffer_height;
glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
// Calculate Ratios
const double width_ratio = ((double) framebuffer_width) / ((double) window_width);
const double height_ratio = ((double) framebuffer_height) / ((double) window_height);
// Multiply
*xpos *= width_ratio;
*ypos *= height_ratio;
}
// Pass Mouse Movement To SDL
static void glfw_motion(__attribute__((unused)) GLFWwindow *window, double xpos, double ypos) {
convert_to_pixels(window, &xpos, &ypos);
if (is_interactable) {
SDL_Event event;
event.type = SDL_MOUSEMOTION;
event.motion.x = xpos;
event.motion.y = ypos;
event.motion.xrel = !ignore_relative_motion ? (xpos - last_mouse_x) : 0;
event.motion.yrel = !ignore_relative_motion ? (ypos - last_mouse_y) : 0;
SDL_PushEvent(&event);
}
ignore_relative_motion = false;
last_mouse_x = xpos;
last_mouse_y = ypos;
}
// Create And Push SDL Mouse Click Event
static void click_event(int button, bool up) {
SDL_Event event;
event.type = up ? SDL_MOUSEBUTTONUP : SDL_MOUSEBUTTONDOWN;
event.button.x = last_mouse_x;
event.button.y = last_mouse_y;
event.button.state = up ? SDL_RELEASED : SDL_PRESSED;
event.button.button = button;
SDL_PushEvent(&event);
}
// Pass Mouse Click To SDL
static void glfw_click_raw(const int button, const int action) {
const bool up = action == GLFW_RELEASE;
const int sdl_button = button == GLFW_MOUSE_BUTTON_RIGHT ? SDL_BUTTON_RIGHT : (button == GLFW_MOUSE_BUTTON_LEFT ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE);
click_event(sdl_button, up);
}
static void glfw_click(__attribute__((unused)) GLFWwindow *window, const int button, const int action, __attribute__((unused)) int mods) {
if (is_interactable) {
glfw_click_raw(button, action);
}
}
// Pass Mouse Scroll To SDL
static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute__((unused)) double xoffset, double yoffset) {
if (is_interactable && yoffset != 0) {
const int sdl_button = yoffset > 0 ? SDL_BUTTON_WHEELUP : SDL_BUTTON_WHEELDOWN;
click_event(sdl_button, false);
click_event(sdl_button, true);
}
}
// Enable/Disable Raw Mouse Motion
void media_set_raw_mouse_motion_enabled(const int enabled) {
raw_mouse_motion_enabled = enabled;
if (glfw_window) {
glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE);
}
if (!raw_mouse_motion_enabled) {
WARN("Raw mouse motion has been DISABLED, this IS NOT recommended, and should only ever be used on systems that don't support or have broken raw mouse motion.");
}
}
// Disable V-Sync // Disable V-Sync
static int disable_vsync = 0; static bool disable_vsync = false;
void media_disable_vsync() { void media_disable_vsync() {
disable_vsync = 1; disable_vsync = true;
if (glfw_window) { if (glfw_window) {
glfwSwapInterval(0); glfwSwapInterval(0);
} }
@ -321,7 +33,7 @@ void media_force_egl() {
// Init Media Layer // Init Media Layer
#define GL_VERSION 0x1f02 #define GL_VERSION 0x1f02
typedef const char *(*glGetString_t)(unsigned int name); typedef const char *(*glGetString_t)(unsigned int name);
void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *icon) { void media_SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *icon) {
// Disable In Headless Mode // Disable In Headless Mode
if (reborn_is_headless()) { if (reborn_is_headless()) {
return; return;
@ -356,11 +68,7 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
} }
// Event Handlers // Event Handlers
glfwSetKeyCallback(glfw_window, glfw_key); _media_register_event_listeners();
glfwSetCharCallback(glfw_window, glfw_char);
glfwSetCursorPosCallback(glfw_window, glfw_motion);
glfwSetMouseButtonCallback(glfw_window, glfw_click);
glfwSetScrollCallback(glfw_window, glfw_scroll);
// Make Window Context Current // Make Window Context Current
glfwMakeContextCurrent(glfw_window); glfwMakeContextCurrent(glfw_window);
@ -373,7 +81,7 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
_media_audio_init(); _media_audio_init();
// Update State // Update State
update_cursor(); _media_update_cursor();
if (disable_vsync) { if (disable_vsync) {
media_disable_vsync(); media_disable_vsync();
} }
@ -382,58 +90,6 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
atexit(media_cleanup); atexit(media_cleanup);
} }
void media_swap_buffers() {
if (glfw_window) {
glfwSwapBuffers(glfw_window);
}
}
// Track Fullscreen
static bool is_fullscreen = false;
// Old Size And Position To Use When Exiting Fullscreen
static int old_width = -1;
static int old_height = -1;
static int old_x = -1;
static int old_y = -1;
// Toggle Fullscreen
void media_toggle_fullscreen() {
if (glfw_window) {
if (is_fullscreen) {
glfwSetWindowMonitor(glfw_window, nullptr, old_x, old_y, old_width, old_height, GLFW_DONT_CARE);
old_width = -1;
old_height = -1;
old_x = -1;
old_y = -1;
} else {
glfwGetWindowSize(glfw_window, &old_width, &old_height);
glfwGetWindowPos(glfw_window, &old_x, &old_y);
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
glfwSetWindowMonitor(glfw_window, monitor, 0, 0, mode->width, mode->height, GLFW_DONT_CARE);
}
is_fullscreen = !is_fullscreen;
}
}
// Intercept SDL Events
void _media_handle_SDL_PollEvent() {
if (glfw_window) {
// Process GLFW Events
glfwPollEvents();
// Close Window
if (glfwWindowShouldClose(glfw_window)) {
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
glfwSetWindowShouldClose(glfw_window, GLFW_FALSE);
}
}
}
// Cleanup Media Layer // Cleanup Media Layer
void media_cleanup() { void media_cleanup() {
if (glfw_window) { if (glfw_window) {
@ -450,113 +106,4 @@ void media_cleanup() {
// Mark As Stopped // Mark As Stopped
glfw_window = nullptr; glfw_window = nullptr;
} }
}
// Update GLFW Cursor State (Client Only)
static void update_cursor() {
if (glfw_window) {
// Get New State
const bool new_cursor_visible = is_interactable ? cursor_visible : true;
const bool new_cursor_grabbed = is_interactable ? cursor_grabbed : false;
// Store Old Mode
const int old_mode = glfwGetInputMode(glfw_window, GLFW_CURSOR);
// Handle Cursor Visibility
int new_mode;
if (!new_cursor_visible) {
if (new_cursor_grabbed) {
new_mode = GLFW_CURSOR_DISABLED;
} else {
new_mode = GLFW_CURSOR_HIDDEN;
}
} else {
new_mode = GLFW_CURSOR_NORMAL;
}
if (new_mode != old_mode) {
// Ignore Relative Cursor Motion When Locking
if (new_mode == GLFW_CURSOR_DISABLED && old_mode != GLFW_CURSOR_DISABLED) {
ignore_relative_motion = true;
}
// Set New Mode
glfwSetInputMode(glfw_window, GLFW_CURSOR, new_mode);
// Handle Cursor Lock/Unlock
if ((new_mode == GLFW_CURSOR_DISABLED && old_mode != GLFW_CURSOR_DISABLED) || (new_mode != GLFW_CURSOR_DISABLED && old_mode == GLFW_CURSOR_DISABLED)) {
// Use Raw Mouse Motion
if (raw_mouse_motion_enabled) {
glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, new_mode == GLFW_CURSOR_DISABLED ? GLFW_TRUE : GLFW_FALSE);
}
// Request Focus
if (!glfwGetWindowAttrib(glfw_window, GLFW_FOCUSED)) {
glfwRequestWindowAttention(glfw_window);
}
}
// Reset Mouse Position When Unlocking
if (new_mode != GLFW_CURSOR_DISABLED && old_mode == GLFW_CURSOR_DISABLED) {
double cursor_x;
double cursor_y;
glfwGetCursorPos(glfw_window, &cursor_x, &cursor_y);
glfw_motion(glfw_window, cursor_x, cursor_y);
}
}
}
}
// Fix SDL Cursor Visibility/Grabbing
SDL_GrabMode SDL_WM_GrabInput(const SDL_GrabMode mode) {
if (mode == SDL_GRAB_QUERY) {
// Query
return cursor_grabbed ? SDL_GRAB_ON : SDL_GRAB_OFF;
} else if (mode == SDL_GRAB_ON) {
// Store State
cursor_grabbed = true;
} else if (mode == SDL_GRAB_OFF) {
// Store State
cursor_grabbed = false;
}
// Update Cursor GLFW State (Client Only)
update_cursor();
// Return
return mode;
}
// Stub SDL Cursor Visibility
int SDL_ShowCursor(const int toggle) {
if (toggle == SDL_QUERY) {
// Query
return cursor_visible ? SDL_ENABLE : SDL_DISABLE;
} else if (toggle == SDL_ENABLE) {
// Store State
cursor_visible = true;
} else if (toggle == SDL_DISABLE) {
// Store State
cursor_visible = false;
}
// Update Cursor GLFW State (Client Only)
update_cursor();
// Return
return toggle;
}
// Get Framebuffer Size
void media_get_framebuffer_size(int *width, int *height) {
if (glfw_window) {
glfwGetFramebufferSize(glfw_window, width, height);
} else {
*width = DEFAULT_WIDTH;
*height = DEFAULT_HEIGHT;
}
}
// Check OpenGL Extension
int media_has_extension(const char *name) {
if (glfw_window) {
return glfwExtensionSupported(name);
} else {
return 0;
}
} }

View File

@ -0,0 +1,25 @@
#pragma once
#include <SDL/SDL.h>
#include <libreborn/libreborn.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <media-layer/core.h>
// Interactivity
__attribute__((visibility("internal"))) extern bool is_interactable;
// Window
__attribute__((visibility("internal"))) extern GLFWwindow *glfw_window;
// Cursor
__attribute__((visibility("internal"))) void _media_update_cursor();
__attribute__((visibility("internal"))) extern bool ignore_relative_motion;
__attribute__((visibility("internal"))) extern bool raw_mouse_motion_enabled;
// Events
__attribute__((visibility("internal"))) void _media_register_event_listeners();
__attribute__((visibility("internal"))) void _media_handle_media_SDL_PollEvent();
__attribute__((visibility("internal"))) void _media_glfw_motion(GLFWwindow *window, double xpos, double ypos);

View File

@ -0,0 +1,67 @@
#include "media.h"
// Allow Disabling Interaction
bool is_interactable = true;
void media_set_interactable(const int toggle) {
if (bool(toggle) != is_interactable) {
is_interactable = toggle;
_media_update_cursor();
}
}
// Get Framebuffer Size
void media_get_framebuffer_size(int *width, int *height) {
if (glfw_window) {
glfwGetFramebufferSize(glfw_window, width, height);
} else {
*width = DEFAULT_WIDTH;
*height = DEFAULT_HEIGHT;
}
}
// Check OpenGL Extension
int media_has_extension(const char *name) {
if (glfw_window) {
return glfwExtensionSupported(name);
} else {
return 0;
}
}
// Swap Buffers
void media_swap_buffers() {
if (glfw_window) {
glfwSwapBuffers(glfw_window);
}
}
// Toggle Fullscreen
void media_toggle_fullscreen() {
// Track Fullscreen
static bool is_fullscreen = false;
// Old Size And Position To Use When Exiting Fullscreen
static int old_width = -1;
static int old_height = -1;
static int old_x = -1;
static int old_y = -1;
// Run
if (glfw_window) {
if (is_fullscreen) {
glfwSetWindowMonitor(glfw_window, nullptr, old_x, old_y, old_width, old_height, GLFW_DONT_CARE);
old_width = -1;
old_height = -1;
old_x = -1;
old_y = -1;
} else {
glfwGetWindowSize(glfw_window, &old_width, &old_height);
glfwGetWindowPos(glfw_window, &old_x, &old_y);
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
glfwSetWindowMonitor(glfw_window, monitor, 0, 0, mode->width, mode->height, GLFW_DONT_CARE);
}
is_fullscreen = !is_fullscreen;
}
}

View File

@ -1,5 +0,0 @@
project(media-layer-extras)
# Build
add_library(media-layer-extras OBJECT src/SDL.c)
target_link_libraries(media-layer-extras media-layer-headers reborn-util)

View File

@ -1,36 +0,0 @@
#include <SDL/SDL.h>
#include <SDL/SDL_syswm.h>
#include <sys/wait.h>
#include <libreborn/libreborn.h>
#include <media-layer/core.h>
// SDL Stub
void *SDL_SetVideoMode(__attribute__((unused)) int width, __attribute__((unused)) int height, __attribute__((unused)) int bpp, __attribute__((unused)) uint32_t flags) {
// Return Value Is Only Used For A NULL-Check
return (void *) 1;
}
static void x11_nop() {
// NOP
}
int SDL_GetWMInfo(SDL_SysWMinfo *info) {
// Return Fake Lock Functions Since XLib Isn't Directly Used
SDL_SysWMinfo ret;
ret.info.x11.lock_func = x11_nop;
ret.info.x11.unlock_func = x11_nop;
ret.info.x11.display = NULL;
ret.info.x11.window = 0;
ret.info.x11.wmwindow = ret.info.x11.window;
*info = ret;
return 1;
}
// Quit
void SDL_Quit() {
// Cleanup Media Layer
media_cleanup();
// Exit
INFO("Stopped");
}

View File

@ -17,214 +17,230 @@ static void *gl_dlsysm(__attribute__((unused)) void *handle, __attribute__((unus
// Passthrough Functions // Passthrough Functions
GL_FUNC(glFogfv, void, (GLenum pname, const GLfloat *params)) GL_FUNC(glFogfv, void, (GLenum pname, const GLfloat *params))
void glFogfv(const GLenum pname, const GLfloat *params) { void media_glFogfv(const GLenum pname, const GLfloat *params) {
real_glFogfv()(pname, params); real_glFogfv()(pname, params);
} }
GL_FUNC(glVertexPointer, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) GL_FUNC(glVertexPointer, void, (GLint size, GLenum type, GLsizei stride, const void *pointer))
void glVertexPointer(const GLint size, const GLenum type, const GLsizei stride, const void *pointer) { void media_glVertexPointer(const GLint size, const GLenum type, const GLsizei stride, const void *pointer) {
real_glVertexPointer()(size, type, stride, pointer); real_glVertexPointer()(size, type, stride, pointer);
} }
GL_FUNC(glLineWidth, void, (GLfloat width)) GL_FUNC(glLineWidth, void, (GLfloat width))
void glLineWidth(const GLfloat width) { void media_glLineWidth(const GLfloat width) {
real_glLineWidth()(width); real_glLineWidth()(width);
} }
GL_FUNC(glBlendFunc, void, (GLenum sfactor, GLenum dfactor)) GL_FUNC(glBlendFunc, void, (GLenum sfactor, GLenum dfactor))
void glBlendFunc(const GLenum sfactor, const GLenum dfactor) { void media_glBlendFunc(const GLenum sfactor, const GLenum dfactor) {
real_glBlendFunc()(sfactor, dfactor); real_glBlendFunc()(sfactor, dfactor);
} }
GL_FUNC(glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) GL_FUNC(glDrawArrays, void, (GLenum mode, GLint first, GLsizei count))
void glDrawArrays(const GLenum mode, const GLint first, const GLsizei count) { void media_glDrawArrays(const GLenum mode, const GLint first, const GLsizei count) {
real_glDrawArrays()(mode, first, count); real_glDrawArrays()(mode, first, count);
} }
GL_FUNC(glMultiDrawArraysEXT, void, (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount)) GL_FUNC(glMultiDrawArraysEXT, void, (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount))
void glMultiDrawArrays(const GLenum mode, const GLint *first, const GLsizei *count, const GLsizei drawcount) { void media_glMultiDrawArrays(const GLenum mode, const GLint *first, const GLsizei *count, const GLsizei drawcount) {
real_glMultiDrawArraysEXT()(mode, first, count, drawcount); real_glMultiDrawArraysEXT()(mode, first, count, drawcount);
} }
GL_FUNC(glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) GL_FUNC(glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha))
void glColor4f(const GLfloat red, const GLfloat green, const GLfloat blue, const GLfloat alpha) { void media_glColor4f(const GLfloat red, const GLfloat green, const GLfloat blue, const GLfloat alpha) {
real_glColor4f()(red, green, blue, alpha); real_glColor4f()(red, green, blue, alpha);
} }
GL_FUNC(glClear, void, (GLbitfield mask)) GL_FUNC(glClear, void, (GLbitfield mask))
void glClear(const GLbitfield mask) { void media_glClear(const GLbitfield mask) {
real_glClear()(mask); real_glClear()(mask);
} }
GL_FUNC(glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage)) GL_FUNC(glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage))
void glBufferData(const GLenum target, const GLsizeiptr size, const void *data, const GLenum usage) { void media_glBufferData(const GLenum target, const GLsizeiptr size, const void *data, const GLenum usage) {
real_glBufferData()(target, size, data, usage); real_glBufferData()(target, size, data, usage);
} }
GL_FUNC(glBufferSubData, void, (GLenum target, GLintptr offset, GLsizeiptr size, const void *data)) GL_FUNC(glBufferSubData, void, (GLenum target, GLintptr offset, GLsizeiptr size, const void *data))
void glBufferSubData(const GLenum target, const GLintptr offset, const GLsizeiptr size, const void *data) { void media_glBufferSubData(const GLenum target, const GLintptr offset, const GLsizeiptr size, const void *data) {
real_glBufferSubData()(target, offset, size, data); real_glBufferSubData()(target, offset, size, data);
} }
GL_FUNC(glFogi, void, (GLenum pname, GLint param)) GL_FUNC(glFogi, void, (GLenum pname, GLint param))
void glFogx(const GLenum pname, const GLfixed param) { void media_glFogx(const GLenum pname, const GLfixed param) {
real_glFogi()(pname, param); real_glFogi()(pname, param);
} }
GL_FUNC(glFogf, void, (GLenum pname, GLfloat param)) GL_FUNC(glFogf, void, (GLenum pname, GLfloat param))
void glFogf(const GLenum pname, const GLfloat param) { void media_glFogf(const GLenum pname, const GLfloat param) {
real_glFogf()(pname, param); real_glFogf()(pname, param);
} }
GL_FUNC(glMatrixMode, void, (GLenum mode)) GL_FUNC(glMatrixMode, void, (GLenum mode))
void glMatrixMode(const GLenum mode) { void media_glMatrixMode(const GLenum mode) {
real_glMatrixMode()(mode); real_glMatrixMode()(mode);
} }
GL_FUNC(glColorPointer, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) GL_FUNC(glColorPointer, void, (GLint size, GLenum type, GLsizei stride, const void *pointer))
void glColorPointer(const GLint size, const GLenum type, const GLsizei stride, const void *pointer) { void media_glColorPointer(const GLint size, const GLenum type, const GLsizei stride, const void *pointer) {
real_glColorPointer()(size, type, stride, pointer); real_glColorPointer()(size, type, stride, pointer);
} }
GL_FUNC(glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height)) GL_FUNC(glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
void glScissor(const GLint x, const GLint y, const GLsizei width, const GLsizei height) { void media_glScissor(const GLint x, const GLint y, const GLsizei width, const GLsizei height) {
real_glScissor()(x, y, width, height); real_glScissor()(x, y, width, height);
} }
GL_FUNC(glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) GL_FUNC(glTexParameteri, void, (GLenum target, GLenum pname, GLint param))
void glTexParameteri(const GLenum target, const GLenum pname, const GLint param) { void media_glTexParameteri(const GLenum target, const GLenum pname, const GLint param) {
real_glTexParameteri()(target, pname, param); real_glTexParameteri()(target, pname, param);
} }
GL_FUNC(glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) GL_FUNC(glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels))
void glTexImage2D(const GLenum target, const GLint level, const GLint internalformat, const GLsizei width, const GLsizei height, const GLint border, const GLenum format, const GLenum type, const void *pixels) { void media_glTexImage2D(const GLenum target, const GLint level, const GLint internalformat, const GLsizei width, const GLsizei height, const GLint border, const GLenum format, const GLenum type, const void *pixels) {
real_glTexImage2D()(target, level, internalformat, width, height, border, format, type, pixels); real_glTexImage2D()(target, level, internalformat, width, height, border, format, type, pixels);
} }
GL_FUNC(glEnable, void, (GLenum cap)) GL_FUNC(glEnable, void, (GLenum cap))
void glEnable(const GLenum cap) { void media_glEnable(const GLenum cap) {
real_glEnable()(cap); real_glEnable()(cap);
} }
GL_FUNC(glEnableClientState, void, (GLenum array)) GL_FUNC(glEnableClientState, void, (GLenum array))
void glEnableClientState(const GLenum array) { void media_glEnableClientState(const GLenum array) {
real_glEnableClientState()(array); real_glEnableClientState()(array);
} }
GL_FUNC(glPolygonOffset, void, (GLfloat factor, GLfloat units)) GL_FUNC(glPolygonOffset, void, (GLfloat factor, GLfloat units))
void glPolygonOffset(const GLfloat factor, const GLfloat units) { void media_glPolygonOffset(const GLfloat factor, const GLfloat units) {
real_glPolygonOffset()(factor, units); real_glPolygonOffset()(factor, units);
} }
GL_FUNC(glDisableClientState, void, (GLenum array)) GL_FUNC(glDisableClientState, void, (GLenum array))
void glDisableClientState(const GLenum array) { void media_glDisableClientState(const GLenum array) {
real_glDisableClientState()(array); real_glDisableClientState()(array);
} }
GL_FUNC(glDepthRange, void, (GLclampd near, GLclampd far)) GL_FUNC(glDepthRange, void, (GLclampd near, GLclampd far))
void glDepthRangef(const GLclampf near, const GLclampf far) { void media_glDepthRangef(const GLclampf near, const GLclampf far) {
real_glDepthRange()(near, far); real_glDepthRange()(near, far);
} }
GL_FUNC(glDepthFunc, void, (GLenum func)) GL_FUNC(glDepthFunc, void, (GLenum func))
void glDepthFunc(const GLenum func) { void media_glDepthFunc(const GLenum func) {
real_glDepthFunc()(func); real_glDepthFunc()(func);
} }
GL_FUNC(glBindBuffer, void, (GLenum target, GLuint buffer)) GL_FUNC(glBindBuffer, void, (GLenum target, GLuint buffer))
void glBindBuffer(const GLenum target, const GLuint buffer) { void media_glBindBuffer(const GLenum target, const GLuint buffer) {
real_glBindBuffer()(target, buffer); real_glBindBuffer()(target, buffer);
} }
GL_FUNC(glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) GL_FUNC(glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha))
void glClearColor(const GLclampf red, const GLclampf green, const GLclampf blue, const GLclampf alpha) { void media_glClearColor(const GLclampf red, const GLclampf green, const GLclampf blue, const GLclampf alpha) {
real_glClearColor()(red, green, blue, alpha); real_glClearColor()(red, green, blue, alpha);
} }
GL_FUNC(glPopMatrix, void, ()) GL_FUNC(glPopMatrix, void, ())
void glPopMatrix() { void media_glPopMatrix() {
real_glPopMatrix()(); real_glPopMatrix()();
} }
GL_FUNC(glLoadIdentity, void, ()) GL_FUNC(glLoadIdentity, void, ())
void glLoadIdentity() { void media_glLoadIdentity() {
real_glLoadIdentity()(); real_glLoadIdentity()();
} }
GL_FUNC(glScalef, void, (GLfloat x, GLfloat y, GLfloat z)) GL_FUNC(glScalef, void, (GLfloat x, GLfloat y, GLfloat z))
void glScalef(const GLfloat x, const GLfloat y, const GLfloat z) { void media_glScalef(const GLfloat x, const GLfloat y, const GLfloat z) {
real_glScalef()(x, y, z); real_glScalef()(x, y, z);
} }
GL_FUNC(glPushMatrix, void, ()) GL_FUNC(glPushMatrix, void, ())
void glPushMatrix() { void media_glPushMatrix() {
real_glPushMatrix()(); real_glPushMatrix()();
} }
GL_FUNC(glDepthMask, void, (GLboolean flag)) GL_FUNC(glDepthMask, void, (GLboolean flag))
void glDepthMask(const GLboolean flag) { void media_glDepthMask(const GLboolean flag) {
real_glDepthMask()(flag); real_glDepthMask()(flag);
} }
GL_FUNC(glHint, void, (GLenum target, GLenum mode)) GL_FUNC(glHint, void, (GLenum target, GLenum mode))
void glHint(const GLenum target, const GLenum mode) { void media_glHint(const GLenum target, const GLenum mode) {
real_glHint()(target, mode); real_glHint()(target, mode);
} }
GL_FUNC(glMultMatrixf, void, (const GLfloat *m)) GL_FUNC(glMultMatrixf, void, (const GLfloat *m))
void glMultMatrixf(const GLfloat *m) { void media_glMultMatrixf(const GLfloat *m) {
real_glMultMatrixf()(m); real_glMultMatrixf()(m);
} }
GL_FUNC(glTexCoordPointer, void, (GLint size, GLenum type, GLsizei stride, const void *pointer)) GL_FUNC(glTexCoordPointer, void, (GLint size, GLenum type, GLsizei stride, const void *pointer))
void glTexCoordPointer(const GLint size, const GLenum type, const GLsizei stride, const void *pointer) { void media_glTexCoordPointer(const GLint size, const GLenum type, const GLsizei stride, const void *pointer) {
real_glTexCoordPointer()(size, type, stride, pointer); real_glTexCoordPointer()(size, type, stride, pointer);
} }
GL_FUNC(glDeleteBuffers, void, (GLsizei n, const GLuint *buffers)) GL_FUNC(glDeleteBuffers, void, (GLsizei n, const GLuint *buffers))
void glDeleteBuffers(const GLsizei n, const GLuint *buffers) { void media_glDeleteBuffers(const GLsizei n, const GLuint *buffers) {
real_glDeleteBuffers()(n, buffers); real_glDeleteBuffers()(n, buffers);
} }
GL_FUNC(glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) GL_FUNC(glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha))
void glColorMask(const GLboolean red, const GLboolean green, const GLboolean blue, const GLboolean alpha) { void media_glColorMask(const GLboolean red, const GLboolean green, const GLboolean blue, const GLboolean alpha) {
real_glColorMask()(red, green, blue, alpha); real_glColorMask()(red, green, blue, alpha);
} }
GL_FUNC(glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)) GL_FUNC(glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels))
void glTexSubImage2D(const GLenum target, const GLint level, const GLint xoffset, const GLint yoffset, const GLsizei width, const GLsizei height, const GLenum format, const GLenum type, const void *pixels) { void media_glTexSubImage2D(const GLenum target, const GLint level, const GLint xoffset, const GLint yoffset, const GLsizei width, const GLsizei height, const GLenum format, const GLenum type, const void *pixels) {
real_glTexSubImage2D()(target, level, xoffset, yoffset, width, height, format, type, pixels); real_glTexSubImage2D()(target, level, xoffset, yoffset, width, height, format, type, pixels);
} }
GL_FUNC(glGenTextures, void, (GLsizei n, GLuint *textures)) GL_FUNC(glGenTextures, void, (GLsizei n, GLuint *textures))
void glGenTextures(const GLsizei n, GLuint *textures) { void media_glGenTextures(const GLsizei n, GLuint *textures) {
real_glGenTextures()(n, textures); real_glGenTextures()(n, textures);
} }
GL_FUNC(glDeleteTextures, void, (GLsizei n, const GLuint *textures)) GL_FUNC(glDeleteTextures, void, (GLsizei n, const GLuint *textures))
void glDeleteTextures(const GLsizei n, const GLuint *textures) { void media_glDeleteTextures(const GLsizei n, const GLuint *textures) {
real_glDeleteTextures()(n, textures); real_glDeleteTextures()(n, textures);
} }
GL_FUNC(glAlphaFunc, void, (GLenum func, GLclampf ref)) GL_FUNC(glAlphaFunc, void, (GLenum func, GLclampf ref))
void glAlphaFunc(const GLenum func, const GLclampf ref) { void media_glAlphaFunc(const GLenum func, const GLclampf ref) {
real_glAlphaFunc()(func, ref); real_glAlphaFunc()(func, ref);
} }
GL_FUNC(glGetFloatv, void, (GLenum pname, GLfloat *params)) GL_FUNC(glGetFloatv, void, (GLenum pname, GLfloat *params))
void glGetFloatv(const GLenum pname, GLfloat *params) { void media_glGetFloatv(const GLenum pname, GLfloat *params) {
real_glGetFloatv()(pname, params); real_glGetFloatv()(pname, params);
} }
GL_FUNC(glBindTexture, void, (GLenum target, GLuint texture)) GL_FUNC(glBindTexture, void, (GLenum target, GLuint texture))
void glBindTexture(const GLenum target, const GLuint texture) { void media_glBindTexture(const GLenum target, const GLuint texture) {
real_glBindTexture()(target, texture); real_glBindTexture()(target, texture);
} }
GL_FUNC(glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z)) GL_FUNC(glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
void glTranslatef(const GLfloat x, const GLfloat y, const GLfloat z) { void media_glTranslatef(const GLfloat x, const GLfloat y, const GLfloat z) {
real_glTranslatef()(x, y, z); real_glTranslatef()(x, y, z);
} }
GL_FUNC(glShadeModel, void, (GLenum mode)) GL_FUNC(glShadeModel, void, (GLenum mode))
void glShadeModel(const GLenum mode) { void media_glShadeModel(const GLenum mode) {
real_glShadeModel()(mode); real_glShadeModel()(mode);
} }
GL_FUNC(glOrtho, void, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)) GL_FUNC(glOrtho, void, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far))
void glOrthof(const GLfloat left, const GLfloat right, const GLfloat bottom, const GLfloat top, const GLfloat near, const GLfloat far) { void media_glOrthof(const GLfloat left, const GLfloat right, const GLfloat bottom, const GLfloat top, const GLfloat near, const GLfloat far) {
real_glOrtho()(left, right, bottom, top, near, far); real_glOrtho()(left, right, bottom, top, near, far);
} }
GL_FUNC(glDisable, void, (GLenum cap)) GL_FUNC(glDisable, void, (GLenum cap))
void glDisable(const GLenum cap) { void media_glDisable(const GLenum cap) {
real_glDisable()(cap); real_glDisable()(cap);
} }
GL_FUNC(glCullFace, void, (GLenum mode)) GL_FUNC(glCullFace, void, (GLenum mode))
void glCullFace(const GLenum mode) { void media_glCullFace(const GLenum mode) {
real_glCullFace()(mode); real_glCullFace()(mode);
} }
GL_FUNC(glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) GL_FUNC(glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
void glRotatef(const GLfloat angle, const GLfloat x, const GLfloat y, const GLfloat z) { void media_glRotatef(const GLfloat angle, const GLfloat x, const GLfloat y, const GLfloat z) {
real_glRotatef()(angle, x, y, z); real_glRotatef()(angle, x, y, z);
} }
GL_FUNC(glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height)) GL_FUNC(glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height))
void glViewport(const GLint x, const GLint y, const GLsizei width, const GLsizei height) { void media_glViewport(const GLint x, const GLint y, const GLsizei width, const GLsizei height) {
real_glViewport()(x, y, width, height); real_glViewport()(x, y, width, height);
} }
GL_FUNC(glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz)) GL_FUNC(glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz))
void glNormal3f(const GLfloat nx, const GLfloat ny, const GLfloat nz) { void media_glNormal3f(const GLfloat nx, const GLfloat ny, const GLfloat nz) {
real_glNormal3f()(nx, ny, nz); real_glNormal3f()(nx, ny, nz);
} }
GL_FUNC(glIsEnabled, GLboolean, (GLenum cap)) GL_FUNC(glIsEnabled, GLboolean, (GLenum cap))
GLboolean glIsEnabled(const GLenum cap) { GLboolean media_glIsEnabled(const GLenum cap) {
return real_glIsEnabled()(cap); return real_glIsEnabled()(cap);
} }
GL_FUNC(glGetIntegerv, void, (GLenum pname, GLint *data)) GL_FUNC(glGetIntegerv, void, (GLenum pname, GLint *data))
void glGetIntegerv(const GLenum pname, GLint *data) { void media_glGetIntegerv(const GLenum pname, GLint *data) {
real_glGetIntegerv()(pname, data); real_glGetIntegerv()(pname, data);
} }
GL_FUNC(glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data)) GL_FUNC(glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data))
void glReadPixels(const GLint x, const GLint y, const GLsizei width, const GLsizei height, const GLenum format, const GLenum type, void *data) { void media_glReadPixels(const GLint x, const GLint y, const GLsizei width, const GLsizei height, const GLenum format, const GLenum type, void *data) {
real_glReadPixels()(x, y, width, height, format, type, data); real_glReadPixels()(x, y, width, height, format, type, data);
} }
GL_FUNC(glGenBuffers, void, (GLsizei n, GLuint *buffers)) GL_FUNC(glGenBuffers, void, (GLsizei n, GLuint *buffers))
void glGenBuffers(const GLsizei n, GLuint *buffers) { void media_glGenBuffers(const GLsizei n, GLuint *buffers) {
real_glGenBuffers()(n, buffers); real_glGenBuffers()(n, buffers);
} }
GL_FUNC(glNormalPointer, void, (GLenum type, GLsizei stride, const void *pointer))
void media_glNormalPointer(const GLenum type, const GLsizei stride, const void *pointer) {
real_glNormalPointer()(type, stride, pointer);
}
GL_FUNC(glLightfv, void, (GLenum light, GLenum pname, const GLfloat *params))
void media_glLightfv(const GLenum light, const GLenum pname, const GLfloat *params) {
real_glLightfv()(light, pname, params);
}
GL_FUNC(glColorMaterial, void, (GLenum face, GLenum mode))
void media_glColorMaterial(const GLenum face, const GLenum mode) {
real_glColorMaterial()(face, mode);
}
GL_FUNC(glLightModelfv, void, (GLenum pname, const GLfloat *params))
void media_glLightModelfv(const GLenum pname, const GLfloat *params) {
real_glLightModelfv()(pname, params);
}

View File

@ -23,18 +23,6 @@ typedef XID EGLNativeWindowType;
typedef EGLNativeWindowType NativeWindowType; typedef EGLNativeWindowType NativeWindowType;
typedef EGLNativeDisplayType NativeDisplayType; typedef EGLNativeDisplayType NativeDisplayType;
EGLDisplay eglGetDisplay(NativeDisplayType native_display);
EGLBoolean eglInitialize(EGLDisplay display, EGLint *major, EGLint *minor);
EGLBoolean eglChooseConfig(EGLDisplay display, EGLint const *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
EGLBoolean eglBindAPI(EGLenum api);
EGLContext eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, EGLint const *attrib_list);
EGLSurface eglCreateWindowSurface(EGLDisplay display, EGLConfig config, NativeWindowType native_window, EGLint const *attrib_list);
EGLBoolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context);
EGLBoolean eglDestroySurface(EGLDisplay display, EGLSurface surface);
EGLBoolean eglDestroyContext(EGLDisplay display, EGLContext context);
EGLBoolean eglTerminate(EGLDisplay display);
EGLBoolean eglSwapBuffers(EGLDisplay display, EGLSurface surface);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -30,6 +30,7 @@ extern "C" {
#define GL_VERTEX_ARRAY 0x8074 #define GL_VERTEX_ARRAY 0x8074
#define GL_COLOR_ARRAY 0x8076 #define GL_COLOR_ARRAY 0x8076
#define GL_TEXTURE_COORD_ARRAY 0x8078 #define GL_TEXTURE_COORD_ARRAY 0x8078
#define GL_NORMAL_ARRAY 0x8075
#define GL_GREATER 0x204 #define GL_GREATER 0x204
#define GL_ALPHA_TEST 0xbc0 #define GL_ALPHA_TEST 0xbc0
#define GL_TEXTURE_2D 0xde1 #define GL_TEXTURE_2D 0xde1
@ -47,6 +48,7 @@ extern "C" {
#define GL_TRIANGLES 0x4 #define GL_TRIANGLES 0x4
#define GL_TRIANGLE_STRIP 0x5 #define GL_TRIANGLE_STRIP 0x5
#define GL_TRIANGLE_FAN 0x6 #define GL_TRIANGLE_FAN 0x6
#define GL_QUADS 0x7
#define GL_FASTEST 0x1101 #define GL_FASTEST 0x1101
#define GL_BACK 0x405 #define GL_BACK 0x405
#define GL_CULL_FACE 0xb44 #define GL_CULL_FACE 0xb44
@ -86,6 +88,17 @@ extern "C" {
#define GL_ALPHA 0x1906 #define GL_ALPHA 0x1906
#define GL_NONE 0 #define GL_NONE 0
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846e #define GL_ALIASED_LINE_WIDTH_RANGE 0x846e
#define GL_LIGHTING 0xb50
#define GL_LIGHT0 0x4000
#define GL_LIGHT1 0x4001
#define GL_RESCALE_NORMAL 0x803a
#define GL_POSITION 0x1203
#define GL_DIFFUSE 0x1201
#define GL_AMBIENT 0x1200
#define GL_SPECULAR 0x1202
#define GL_FRONT_AND_BACK 0x408
#define GL_AMBIENT_AND_DIFFUSE 0x1602
#define GL_LIGHT_MODEL_AMBIENT 0xb53
typedef float GLfloat; typedef float GLfloat;
typedef float GLclampf; typedef float GLclampf;
@ -103,61 +116,65 @@ typedef unsigned int GLenum;
typedef char GLchar; typedef char GLchar;
typedef void GLvoid; typedef void GLvoid;
void glFogfv(GLenum pname, const GLfloat *params); void media_glFogfv(GLenum pname, const GLfloat *params);
void glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); void media_glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);
void glLineWidth(GLfloat width); void media_glLineWidth(GLfloat width);
void glBlendFunc(GLenum sfactor, GLenum dfactor); void media_glBlendFunc(GLenum sfactor, GLenum dfactor);
void glDrawArrays(GLenum mode, GLint first, GLsizei count); void media_glDrawArrays(GLenum mode, GLint first, GLsizei count);
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void media_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
void glClear(GLbitfield mask); void media_glClear(GLbitfield mask);
void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage); void media_glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage);
void glFogx(GLenum pname, GLfixed param); void media_glFogx(GLenum pname, GLfixed param);
void glFogf(GLenum pname, GLfloat param); void media_glFogf(GLenum pname, GLfloat param);
void glMatrixMode(GLenum mode); void media_glMatrixMode(GLenum mode);
void glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); void media_glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);
void glScissor(GLint x, GLint y, GLsizei width, GLsizei height); void media_glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
void glTexParameteri(GLenum target, GLenum pname, GLint param); void media_glTexParameteri(GLenum target, GLenum pname, GLint param);
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); void media_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
void glEnable(GLenum cap); void media_glEnable(GLenum cap);
void glEnableClientState(GLenum array); void media_glEnableClientState(GLenum array);
void glPolygonOffset(GLfloat factor, GLfloat units); void media_glPolygonOffset(GLfloat factor, GLfloat units);
void glDisableClientState(GLenum array); void media_glDisableClientState(GLenum array);
void glDepthRangef(GLclampf near, GLclampf far); void media_glDepthRangef(GLclampf near, GLclampf far);
void glDepthFunc(GLenum func); void media_glDepthFunc(GLenum func);
void glBindBuffer(GLenum target, GLuint buffer); void media_glBindBuffer(GLenum target, GLuint buffer);
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); void media_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
void glPopMatrix(); void media_glPopMatrix();
void glLoadIdentity(); void media_glLoadIdentity();
void glScalef(GLfloat x, GLfloat y, GLfloat z); void media_glScalef(GLfloat x, GLfloat y, GLfloat z);
void glPushMatrix(); void media_glPushMatrix();
void glDepthMask(GLboolean flag); void media_glDepthMask(GLboolean flag);
void glHint(GLenum target, GLenum mode); void media_glHint(GLenum target, GLenum mode);
void glMultMatrixf(const GLfloat *m); void media_glMultMatrixf(const GLfloat *m);
void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); void media_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer);
void glDeleteBuffers(GLsizei n, const GLuint *buffers); void media_glDeleteBuffers(GLsizei n, const GLuint *buffers);
void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void media_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); void media_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
void glGenTextures(GLsizei n, GLuint *textures); void media_glGenTextures(GLsizei n, GLuint *textures);
void glDeleteTextures(GLsizei n, const GLuint *textures); void media_glDeleteTextures(GLsizei n, const GLuint *textures);
void glAlphaFunc(GLenum func, GLclampf ref); void media_glAlphaFunc(GLenum func, GLclampf ref);
void glGetFloatv(GLenum pname, GLfloat *params); void media_glGetFloatv(GLenum pname, GLfloat *params);
void glBindTexture(GLenum target, GLuint texture); void media_glBindTexture(GLenum target, GLuint texture);
void glTranslatef(GLfloat x, GLfloat y, GLfloat z); void media_glTranslatef(GLfloat x, GLfloat y, GLfloat z);
void glShadeModel(GLenum mode); void media_glShadeModel(GLenum mode);
void glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far); void media_glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far);
void glDisable(GLenum cap); void media_glDisable(GLenum cap);
void glCullFace(GLenum mode); void media_glCullFace(GLenum mode);
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); void media_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height); void media_glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz); void media_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz);
GLboolean glIsEnabled(GLenum cap); GLboolean media_glIsEnabled(GLenum cap);
void glGetIntegerv(GLenum pname, GLint *data); void media_glGetIntegerv(GLenum pname, GLint *data);
void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data); void media_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data);
void glGenBuffers(GLsizei n, GLuint *buffers); void media_glGenBuffers(GLsizei n, GLuint *buffers);
GLenum glGetError(); GLenum media_glGetError();
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data); void media_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
void glPixelStorei(GLenum pname, GLint param); void media_glPixelStorei(GLenum pname, GLint param);
void glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); void media_glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);
void media_glNormalPointer(GLenum type, GLsizei stride, const void *pointer);
void media_glLightfv(GLenum light, GLenum pname, const GLfloat *params);
void media_glColorMaterial(GLenum face, GLenum mode);
void media_glLightModelfv(GLenum pname, const GLfloat *params);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -11,10 +11,10 @@ extern "C" {
#include "SDL_syswm.h" #include "SDL_syswm.h"
#include "SDL_version.h" #include "SDL_version.h"
int SDL_Init(uint32_t flags); int media_SDL_Init(uint32_t flags);
int SDL_PollEvent(SDL_Event *event); int media_SDL_PollEvent(SDL_Event *event);
int SDL_PushEvent(SDL_Event *event); int media_SDL_PushEvent(SDL_Event *event);
void SDL_WM_SetCaption(const char *title, const char *icon); void media_SDL_WM_SetCaption(const char *title, const char *icon);
typedef enum { typedef enum {
SDL_GRAB_QUERY = -1, SDL_GRAB_QUERY = -1,
@ -22,17 +22,13 @@ typedef enum {
SDL_GRAB_ON = 1, SDL_GRAB_ON = 1,
SDL_GRAB_FULLSCREEN SDL_GRAB_FULLSCREEN
} SDL_GrabMode; } SDL_GrabMode;
SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode); SDL_GrabMode media_SDL_WM_GrabInput(SDL_GrabMode mode);
#define SDL_QUERY -1 #define SDL_QUERY (-1)
#define SDL_IGNORE 0 #define SDL_IGNORE 0
#define SDL_DISABLE 0 #define SDL_DISABLE 0
#define SDL_ENABLE 1 #define SDL_ENABLE 1
int SDL_ShowCursor(int toggle); int media_SDL_ShowCursor(int toggle);
void *SDL_SetVideoMode(int width, int height, int bpp, uint32_t flags);
int SDL_GetWMInfo(SDL_SysWMinfo *info);
void SDL_Quit();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -4,8 +4,6 @@
extern "C" { extern "C" {
#endif #endif
#include <stdint.h>
typedef unsigned long XID; typedef unsigned long XID;
typedef struct { typedef struct {
@ -32,9 +30,6 @@ typedef struct {
void *screen; void *screen;
} XWindowAttributes; } XWindowAttributes;
int XTranslateCoordinates(void *display, XID src_w, XID dest_w, int src_x, int src_y, int *dest_x_return, int *dest_y_return, XID *child_return);
int XGetWindowAttributes(void *display, XID w, XWindowAttributes *window_attributes_return);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,12 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// Internal Methods
__attribute__((visibility("internal"))) void _media_handle_SDL_PollEvent();
#ifdef __cplusplus
}
#endif

View File

@ -13,7 +13,7 @@ if(BUILD_NATIVE_COMPONENTS)
install(TARGETS media-layer-trampoline DESTINATION "${MCPI_LIB_DIR}") install(TARGETS media-layer-trampoline DESTINATION "${MCPI_LIB_DIR}")
elseif(BUILD_ARM_COMPONENTS) elseif(BUILD_ARM_COMPONENTS)
# Guest Component # Guest Component
add_library(media-layer-core SHARED src/guest/guest.cpp ${MEDIA_LAYER_TRAMPOLINE_SRC} $<TARGET_OBJECTS:media-layer-extras>) add_library(media-layer-core SHARED src/guest/guest.cpp ${MEDIA_LAYER_TRAMPOLINE_SRC})
target_link_libraries(media-layer-core PUBLIC media-layer-headers PRIVATE reborn-util PRIVATE trampoline-headers PRIVATE rt) target_link_libraries(media-layer-core PUBLIC media-layer-headers PRIVATE reborn-util PRIVATE trampoline-headers PRIVATE rt)
target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_TRAMPOLINE_GUEST) target_compile_definitions(media-layer-core PRIVATE -DMEDIA_LAYER_TRAMPOLINE_GUEST)
# Install # Install

View File

@ -10,7 +10,7 @@ static int get_glFogfv_params_length(const GLenum pname) {
return pname == GL_FOG_COLOR ? 4 : 1; return pname == GL_FOG_COLOR ? 4 : 1;
} }
#endif #endif
CALL(11, glFogfv, void, (GLenum pname, const GLfloat *params)) CALL(11, media_glFogfv, void, (GLenum pname, const GLfloat *params))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, pname, copy_array(get_glFogfv_params_length(pname), params)); trampoline(true, pname, copy_array(get_glFogfv_params_length(pname), params));
#else #else
@ -30,9 +30,10 @@ struct gl_array_details_t {
}; };
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
struct { struct {
gl_array_details_t glVertexPointer; gl_array_details_t media_glVertexPointer;
gl_array_details_t glColorPointer; gl_array_details_t media_glColorPointer;
gl_array_details_t glTexCoordPointer; gl_array_details_t media_glTexCoordPointer;
gl_array_details_t media_glNormalPointer;
} gl_array_details; } gl_array_details;
#endif #endif
struct gl_state_t { struct gl_state_t {
@ -41,6 +42,7 @@ struct gl_state_t {
bool vertex_array_enabled = false; bool vertex_array_enabled = false;
bool color_array_enabled = false; bool color_array_enabled = false;
bool tex_coord_array_enabled = false; bool tex_coord_array_enabled = false;
bool normal_array_enabled = false;
// Update State // Update State
bool &get_array_enabled(const GLenum array) { bool &get_array_enabled(const GLenum array) {
switch (array) { switch (array) {
@ -53,6 +55,9 @@ struct gl_state_t {
case GL_TEXTURE_COORD_ARRAY: { case GL_TEXTURE_COORD_ARRAY: {
return tex_coord_array_enabled; return tex_coord_array_enabled;
} }
case GL_NORMAL_ARRAY: {
return normal_array_enabled;
}
default: { default: {
ERR("Unsupported Array Type: %i", array); ERR("Unsupported Array Type: %i", array);
} }
@ -62,17 +67,18 @@ struct gl_state_t {
void send_array_to_driver(const GLenum array) { void send_array_to_driver(const GLenum array) {
const bool state = get_array_enabled(array); const bool state = get_array_enabled(array);
if (state) { if (state) {
glEnableClientState(array); media_glEnableClientState(array);
} else { } else {
glDisableClientState(array); media_glDisableClientState(array);
} }
} }
void send_to_driver() { void send_to_driver() {
send_array_to_driver(GL_VERTEX_ARRAY); send_array_to_driver(GL_VERTEX_ARRAY);
send_array_to_driver(GL_COLOR_ARRAY); send_array_to_driver(GL_COLOR_ARRAY);
send_array_to_driver(GL_TEXTURE_COORD_ARRAY); send_array_to_driver(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, bound_array_buffer); send_array_to_driver(GL_NORMAL_ARRAY);
glBindTexture(GL_TEXTURE_2D, bound_texture); media_glBindBuffer(GL_ARRAY_BUFFER, bound_array_buffer);
media_glBindTexture(GL_TEXTURE_2D, bound_texture);
} }
#endif #endif
}; };
@ -96,16 +102,16 @@ static gl_state_t gl_state;
#else #else
#define CALL_GL_POINTER(unique_id, name) \ #define CALL_GL_POINTER(unique_id, name) \
CALL(unique_id, name, unused, ()) \ CALL(unique_id, name, unused, ()) \
glBindBuffer(GL_ARRAY_BUFFER, args.next<GLuint>()); \ media_glBindBuffer(GL_ARRAY_BUFFER, args.next<GLuint>()); \
gl_array_details_t state = args.next<gl_array_details_t>(); \ gl_array_details_t state = args.next<gl_array_details_t>(); \
func(state.size, state.type, state.stride, (const void *) uintptr_t(state.pointer)); \ func(state.size, state.type, state.stride, (const void *) uintptr_t(state.pointer)); \
return 0; \ return 0; \
} }
#endif #endif
CALL_GL_POINTER(12, glVertexPointer) CALL_GL_POINTER(12, media_glVertexPointer)
CALL(13, glLineWidth, void, (GLfloat width)) CALL(13, media_glLineWidth, void, (GLfloat width))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, width); trampoline(true, width);
#else #else
@ -114,7 +120,7 @@ CALL(13, glLineWidth, void, (GLfloat width))
#endif #endif
} }
CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor)) CALL(14, media_glBlendFunc, void, (GLenum sfactor, GLenum dfactor))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, sfactor, dfactor); trampoline(true, sfactor, dfactor);
#else #else
@ -125,7 +131,7 @@ CALL(14, glBlendFunc, void, (GLenum sfactor, GLenum dfactor))
#endif #endif
} }
CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count)) CALL(15, media_glDrawArrays, void, (GLenum mode, GLint first, GLsizei count))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, gl_state, mode, first, count); trampoline(true, gl_state, mode, first, count);
#else #else
@ -139,7 +145,7 @@ CALL(15, glDrawArrays, void, (GLenum mode, GLint first, GLsizei count))
#endif #endif
} }
CALL(70, glMultiDrawArrays, void, (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount)) CALL(70, media_glMultiDrawArrays, void, (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, gl_state, mode, copy_array(drawcount, first), copy_array(drawcount, count)); trampoline(true, gl_state, mode, copy_array(drawcount, first), copy_array(drawcount, count));
#else #else
@ -154,7 +160,7 @@ CALL(70, glMultiDrawArrays, void, (GLenum mode, const GLint *first, const GLsize
#endif #endif
} }
CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) CALL(16, media_glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, red, green, blue, alpha); trampoline(true, red, green, blue, alpha);
#else #else
@ -167,7 +173,7 @@ CALL(16, glColor4f, void, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alp
#endif #endif
} }
CALL(17, glClear, void, (GLbitfield mask)) CALL(17, media_glClear, void, (GLbitfield mask))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, mask); trampoline(true, mask);
#else #else
@ -176,11 +182,11 @@ CALL(17, glClear, void, (GLbitfield mask))
#endif #endif
} }
CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage)) CALL(18, media_glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, gl_state.bound_array_buffer, target, int32_t(size), copy_array(size, (unsigned char *) data), usage); trampoline(true, gl_state.bound_array_buffer, target, int32_t(size), copy_array(size, (unsigned char *) data), usage);
#else #else
glBindBuffer(GL_ARRAY_BUFFER, args.next<GLuint>()); media_glBindBuffer(GL_ARRAY_BUFFER, args.next<GLuint>());
GLenum target = args.next<GLenum>(); GLenum target = args.next<GLenum>();
int32_t size = args.next<int32_t>(); int32_t size = args.next<int32_t>();
const unsigned char *data = args.next_arr<unsigned char>(); const unsigned char *data = args.next_arr<unsigned char>();
@ -190,7 +196,7 @@ CALL(18, glBufferData, void, (GLenum target, GLsizeiptr size, const void *data,
#endif #endif
} }
CALL(19, glFogx, void, (GLenum pname, GLfixed param)) CALL(19, media_glFogx, void, (GLenum pname, GLfixed param))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, pname, param); trampoline(true, pname, param);
#else #else
@ -201,7 +207,7 @@ CALL(19, glFogx, void, (GLenum pname, GLfixed param))
#endif #endif
} }
CALL(20, glFogf, void, (GLenum pname, GLfloat param)) CALL(20, media_glFogf, void, (GLenum pname, GLfloat param))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, pname, param); trampoline(true, pname, param);
#else #else
@ -212,7 +218,7 @@ CALL(20, glFogf, void, (GLenum pname, GLfloat param))
#endif #endif
} }
CALL(21, glMatrixMode, void, (GLenum mode)) CALL(21, media_glMatrixMode, void, (GLenum mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, mode); trampoline(true, mode);
#else #else
@ -221,9 +227,9 @@ CALL(21, glMatrixMode, void, (GLenum mode))
#endif #endif
} }
CALL_GL_POINTER(22, glColorPointer) CALL_GL_POINTER(22, media_glColorPointer)
CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height)) CALL(23, media_glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, x, y, width, height); trampoline(true, x, y, width, height);
#else #else
@ -236,11 +242,11 @@ CALL(23, glScissor, void, (GLint x, GLint y, GLsizei width, GLsizei height))
#endif #endif
} }
CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) CALL(24, media_glTexParameteri, void, (GLenum target, GLenum pname, GLint param))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, gl_state.bound_texture, target, pname, param); trampoline(true, gl_state.bound_texture, target, pname, param);
#else #else
glBindTexture(GL_TEXTURE_2D, args.next<GLuint>()); media_glBindTexture(GL_TEXTURE_2D, args.next<GLuint>());
GLenum target = args.next<GLenum>(); GLenum target = args.next<GLenum>();
GLenum pname = args.next<GLenum>(); GLenum pname = args.next<GLenum>();
GLint param = args.next<GLint>(); GLint param = args.next<GLint>();
@ -276,7 +282,7 @@ static int get_texture_size(const GLsizei width, const GLsizei height, const GLe
{ {
// Handle Alignment // Handle Alignment
int alignment; int alignment;
glGetIntegerv(is_upload ? GL_UNPACK_ALIGNMENT : GL_PACK_ALIGNMENT, &alignment); media_glGetIntegerv(is_upload ? GL_UNPACK_ALIGNMENT : GL_PACK_ALIGNMENT, &alignment);
// Round // Round
line_size = ALIGN_UP(line_size, alignment); line_size = ALIGN_UP(line_size, alignment);
} }
@ -284,11 +290,11 @@ static int get_texture_size(const GLsizei width, const GLsizei height, const GLe
return line_size * height; return line_size * height;
} }
CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) CALL(25, media_glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, gl_state.bound_texture, target, level, internalformat, width, height, border, format, type, copy_array(get_texture_size(width, height, format, type, true), (const unsigned char *) pixels)); trampoline(true, gl_state.bound_texture, target, level, internalformat, width, height, border, format, type, copy_array(get_texture_size(width, height, format, type, true), (const unsigned char *) pixels));
#else #else
glBindTexture(GL_TEXTURE_2D, args.next<GLuint>()); media_glBindTexture(GL_TEXTURE_2D, args.next<GLuint>());
GLenum target = args.next<GLenum>(); GLenum target = args.next<GLenum>();
GLint level = args.next<GLint>(); GLint level = args.next<GLint>();
GLint internalformat = args.next<GLint>(); GLint internalformat = args.next<GLint>();
@ -303,7 +309,7 @@ CALL(25, glTexImage2D, void, (GLenum target, GLint level, GLint internalformat,
#endif #endif
} }
CALL(26, glEnable, void, (GLenum cap)) CALL(26, media_glEnable, void, (GLenum cap))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, cap); trampoline(true, cap);
#else #else
@ -313,12 +319,12 @@ CALL(26, glEnable, void, (GLenum cap))
} }
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
void glEnableClientState(const GLenum array) { void media_glEnableClientState(const GLenum array) {
gl_state.get_array_enabled(array) = true; gl_state.get_array_enabled(array) = true;
} }
#endif #endif
CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units)) CALL(28, media_glPolygonOffset, void, (GLfloat factor, GLfloat units))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, factor, units); trampoline(true, factor, units);
#else #else
@ -329,29 +335,33 @@ CALL(28, glPolygonOffset, void, (GLfloat factor, GLfloat units))
#endif #endif
} }
CALL_GL_POINTER(41, glTexCoordPointer) CALL_GL_POINTER(41, media_glTexCoordPointer)
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
void glDisableClientState(const GLenum array) { void media_glDisableClientState(const GLenum array) {
gl_state.get_array_enabled(array) = false; gl_state.get_array_enabled(array) = false;
switch (array) { switch (array) {
case GL_VERTEX_ARRAY: { case GL_VERTEX_ARRAY: {
gl_array_details.glVertexPointer.size = -1; gl_array_details.media_glVertexPointer.size = -1;
break; break;
} }
case GL_COLOR_ARRAY: { case GL_COLOR_ARRAY: {
gl_array_details.glColorPointer.size = -1; gl_array_details.media_glColorPointer.size = -1;
break; break;
} }
case GL_TEXTURE_COORD_ARRAY: { case GL_TEXTURE_COORD_ARRAY: {
gl_array_details.glTexCoordPointer.size = -1; gl_array_details.media_glTexCoordPointer.size = -1;
break;
}
case GL_NORMAL_ARRAY: {
gl_array_details.media_glNormalPointer.size = -1;
break; break;
} }
} }
} }
#endif #endif
CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far)) CALL(30, media_glDepthRangef, void, (GLclampf near, GLclampf far))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, near, far); trampoline(true, near, far);
#else #else
@ -362,7 +372,7 @@ CALL(30, glDepthRangef, void, (GLclampf near, GLclampf far))
#endif #endif
} }
CALL(31, glDepthFunc, void, (GLenum func)) CALL(31, media_glDepthFunc, void, (GLenum func))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, func); trampoline(true, func);
#else #else
@ -372,19 +382,20 @@ CALL(31, glDepthFunc, void, (GLenum func))
} }
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
void glBindBuffer(const GLenum target, const GLuint buffer) { void media_glBindBuffer(const GLenum target, const GLuint buffer) {
if (target == GL_ARRAY_BUFFER) { if (target == GL_ARRAY_BUFFER) {
gl_state.bound_array_buffer = buffer; gl_state.bound_array_buffer = buffer;
} else { } else {
ERR("Unsupported Buffer Binding: %u", target); ERR("Unsupported Buffer Binding: %u", target);
} }
gl_array_details.glVertexPointer.size = -1; gl_array_details.media_glVertexPointer.size = -1;
gl_array_details.glColorPointer.size = -1; gl_array_details.media_glColorPointer.size = -1;
gl_array_details.glTexCoordPointer.size = -1; gl_array_details.media_glTexCoordPointer.size = -1;
gl_array_details.media_glNormalPointer.size = -1;
} }
#endif #endif
CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) CALL(33, media_glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, red, green, blue, alpha); trampoline(true, red, green, blue, alpha);
#else #else
@ -397,7 +408,7 @@ CALL(33, glClearColor, void, (GLclampf red, GLclampf green, GLclampf blue, GLcla
#endif #endif
} }
CALL(34, glPopMatrix, void, ()) CALL(34, media_glPopMatrix, void, ())
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true); trampoline(true);
#else #else
@ -406,7 +417,7 @@ CALL(34, glPopMatrix, void, ())
#endif #endif
} }
CALL(35, glLoadIdentity, void, ()) CALL(35, media_glLoadIdentity, void, ())
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true); trampoline(true);
#else #else
@ -415,7 +426,7 @@ CALL(35, glLoadIdentity, void, ())
#endif #endif
} }
CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z)) CALL(36, media_glScalef, void, (GLfloat x, GLfloat y, GLfloat z))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, x, y, z); trampoline(true, x, y, z);
#else #else
@ -427,7 +438,7 @@ CALL(36, glScalef, void, (GLfloat x, GLfloat y, GLfloat z))
#endif #endif
} }
CALL(37, glPushMatrix, void, ()) CALL(37, media_glPushMatrix, void, ())
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true); trampoline(true);
#else #else
@ -436,7 +447,7 @@ CALL(37, glPushMatrix, void, ())
#endif #endif
} }
CALL(38, glDepthMask, void, (GLboolean flag)) CALL(38, media_glDepthMask, void, (GLboolean flag))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, flag); trampoline(true, flag);
#else #else
@ -445,7 +456,7 @@ CALL(38, glDepthMask, void, (GLboolean flag))
#endif #endif
} }
CALL(39, glHint, void, (GLenum target, GLenum mode)) CALL(39, media_glHint, void, (GLenum target, GLenum mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, target, mode); trampoline(true, target, mode);
#else #else
@ -461,7 +472,7 @@ static int get_glMultMatrixf_size() {
return 16; return 16;
} }
#endif #endif
CALL(40, glMultMatrixf, void, (const GLfloat *m)) CALL(40, media_glMultMatrixf, void, (const GLfloat *m))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, copy_array(get_glMultMatrixf_size(), m)); trampoline(true, copy_array(get_glMultMatrixf_size(), m));
#else #else
@ -470,7 +481,7 @@ CALL(40, glMultMatrixf, void, (const GLfloat *m))
#endif #endif
} }
CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers)) CALL(42, media_glDeleteBuffers, void, (GLsizei n, const GLuint *buffers))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, copy_array(n, buffers)); trampoline(true, copy_array(n, buffers));
#else #else
@ -481,7 +492,7 @@ CALL(42, glDeleteBuffers, void, (GLsizei n, const GLuint *buffers))
#endif #endif
} }
CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) CALL(43, media_glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, red, green, blue, alpha); trampoline(true, red, green, blue, alpha);
#else #else
@ -494,11 +505,11 @@ CALL(43, glColorMask, void, (GLboolean red, GLboolean green, GLboolean blue, GLb
#endif #endif
} }
CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)) CALL(44, media_glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, gl_state.bound_texture, target, level, xoffset, yoffset, width, height, format, type, copy_array(get_texture_size(width, height, format, type, true), (const unsigned char *) pixels)); trampoline(true, gl_state.bound_texture, target, level, xoffset, yoffset, width, height, format, type, copy_array(get_texture_size(width, height, format, type, true), (const unsigned char *) pixels));
#else #else
glBindTexture(GL_TEXTURE_2D, args.next<GLuint>()); media_glBindTexture(GL_TEXTURE_2D, args.next<GLuint>());
GLenum target = args.next<GLenum>(); GLenum target = args.next<GLenum>();
GLint level = args.next<GLint>(); GLint level = args.next<GLint>();
GLint xoffset = args.next<GLint>(); GLint xoffset = args.next<GLint>();
@ -513,7 +524,7 @@ CALL(44, glTexSubImage2D, void, (GLenum target, GLint level, GLint xoffset, GLin
#endif #endif
} }
CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures)) CALL(45, media_glGenTextures, void, (GLsizei n, GLuint *textures))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(false, n, uint32_t(textures)); trampoline(false, n, uint32_t(textures));
#else #else
@ -526,7 +537,7 @@ CALL(45, glGenTextures, void, (GLsizei n, GLuint *textures))
#endif #endif
} }
CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures)) CALL(46, media_glDeleteTextures, void, (GLsizei n, const GLuint *textures))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, copy_array(n, textures)); trampoline(true, copy_array(n, textures));
#else #else
@ -537,7 +548,7 @@ CALL(46, glDeleteTextures, void, (GLsizei n, const GLuint *textures))
#endif #endif
} }
CALL(47, glAlphaFunc, void, (GLenum func, GLclampf ref)) CALL(47, media_glAlphaFunc, void, (GLenum func, GLclampf ref))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, func, ref); trampoline(true, func, ref);
#else #else
@ -559,12 +570,12 @@ static int get_glGetFloatv_params_size(GLenum pname) {
return 2; return 2;
} }
default: { default: {
ERR("Unsupported glGetFloatv Property: %u", pname); ERR("Unsupported media_glGetFloatv Property: %u", pname);
} }
} }
} }
#endif #endif
CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params)) CALL(48, media_glGetFloatv, void, (GLenum pname, GLfloat *params))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(false, pname, uint32_t(params)); trampoline(false, pname, uint32_t(params));
#else #else
@ -579,7 +590,7 @@ CALL(48, glGetFloatv, void, (GLenum pname, GLfloat *params))
} }
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
void glBindTexture(const GLenum target, const GLuint texture) { void media_glBindTexture(const GLenum target, const GLuint texture) {
if (target == GL_TEXTURE_2D) { if (target == GL_TEXTURE_2D) {
gl_state.bound_texture = texture; gl_state.bound_texture = texture;
} else { } else {
@ -588,7 +599,7 @@ void glBindTexture(const GLenum target, const GLuint texture) {
} }
#endif #endif
CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z)) CALL(50, media_glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, x, y, z); trampoline(true, x, y, z);
#else #else
@ -600,7 +611,7 @@ CALL(50, glTranslatef, void, (GLfloat x, GLfloat y, GLfloat z))
#endif #endif
} }
CALL(51, glShadeModel, void, (GLenum mode)) CALL(51, media_glShadeModel, void, (GLenum mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, mode); trampoline(true, mode);
#else #else
@ -609,7 +620,7 @@ CALL(51, glShadeModel, void, (GLenum mode))
#endif #endif
} }
CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far)) CALL(52, media_glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, left, right, bottom, top, near, far); trampoline(true, left, right, bottom, top, near, far);
#else #else
@ -624,7 +635,7 @@ CALL(52, glOrthof, void, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat t
#endif #endif
} }
CALL(53, glDisable, void, (GLenum cap)) CALL(53, media_glDisable, void, (GLenum cap))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, cap); trampoline(true, cap);
#else #else
@ -633,7 +644,7 @@ CALL(53, glDisable, void, (GLenum cap))
#endif #endif
} }
CALL(54, glCullFace, void, (GLenum mode)) CALL(54, media_glCullFace, void, (GLenum mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, mode); trampoline(true, mode);
#else #else
@ -642,7 +653,7 @@ CALL(54, glCullFace, void, (GLenum mode))
#endif #endif
} }
CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) CALL(55, media_glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, angle, x, y, z); trampoline(true, angle, x, y, z);
#else #else
@ -655,7 +666,7 @@ CALL(55, glRotatef, void, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
#endif #endif
} }
CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height)) CALL(56, media_glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, x, y, width, height); trampoline(true, x, y, width, height);
#else #else
@ -668,13 +679,19 @@ CALL(56, glViewport, void, (GLint x, GLint y, GLsizei width, GLsizei height))
#endif #endif
} }
CALL(57, media_glNormal3f, void, (GLfloat nx, GLfloat ny, GLfloat nz))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
void glNormal3f(__attribute__((unused)) GLfloat nx, __attribute__((unused)) GLfloat ny, __attribute__((unused)) GLfloat nz) { trampoline(true, nx, ny, nz);
// Do Nothing #else
} GLfloat nx = args.next<GLfloat>();
GLfloat ny = args.next<GLfloat>();
GLfloat nz = args.next<GLfloat>();
func(nx, ny, nz);
return 0;
#endif #endif
}
CALL(58, glIsEnabled, GLboolean, (GLenum cap)) CALL(58, media_glIsEnabled, GLboolean, (GLenum cap))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
return trampoline(false, cap); return trampoline(false, cap);
#else #else
@ -694,12 +711,12 @@ static int get_glGetIntegerv_params_size(GLenum pname) {
return 4; return 4;
} }
default: { default: {
ERR("Unsupported glGetIntegerv Property: %u", pname); ERR("Unsupported media_glGetIntegerv Property: %u", pname);
} }
} }
} }
#endif #endif
CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params)) CALL(61, media_glGetIntegerv, void, (GLenum pname, GLint *params))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
if (pname == GL_TEXTURE_BINDING_2D) { if (pname == GL_TEXTURE_BINDING_2D) {
params[0] = gl_state.bound_texture; params[0] = gl_state.bound_texture;
@ -717,7 +734,7 @@ CALL(61, glGetIntegerv, void, (GLenum pname, GLint *params))
#endif #endif
} }
CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data)) CALL(65, media_glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(false, x, y, width, height, format, type, uint32_t(data)); trampoline(false, x, y, width, height, format, type, uint32_t(data));
#else #else
@ -736,7 +753,7 @@ CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, G
#endif #endif
} }
CALL(67, glGenBuffers, void, (GLsizei n, GLuint *buffers)) CALL(67, media_glGenBuffers, void, (GLsizei n, GLuint *buffers))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(false, n, uint32_t(buffers)); trampoline(false, n, uint32_t(buffers));
#else #else
@ -749,11 +766,11 @@ CALL(67, glGenBuffers, void, (GLsizei n, GLuint *buffers))
#endif #endif
} }
CALL(69, glBufferSubData, void, (GLenum target, GLintptr offset, GLsizeiptr size, const void *data)) CALL(69, media_glBufferSubData, void, (GLenum target, GLintptr offset, GLsizeiptr size, const void *data))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, gl_state.bound_array_buffer, target, int32_t(offset), int32_t(size), copy_array(size, (unsigned char *) data)); trampoline(true, gl_state.bound_array_buffer, target, int32_t(offset), int32_t(size), copy_array(size, (unsigned char *) data));
#else #else
glBindBuffer(GL_ARRAY_BUFFER, args.next<GLuint>()); media_glBindBuffer(GL_ARRAY_BUFFER, args.next<GLuint>());
GLenum target = args.next<GLenum>(); GLenum target = args.next<GLenum>();
int32_t offset = args.next<int32_t>(); int32_t offset = args.next<int32_t>();
int32_t size = args.next<int32_t>(); int32_t size = args.next<int32_t>();
@ -761,4 +778,56 @@ CALL(69, glBufferSubData, void, (GLenum target, GLintptr offset, GLsizeiptr size
func(target, offset, size, data); func(target, offset, size, data);
return 0; return 0;
#endif #endif
}
CALL(72, media_glNormalPointer, void, (GLenum type, GLsizei stride, const void *pointer))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
gl_array_details_t &state = gl_array_details.media_glNormalPointer;
if (state.size == -1 || state.type != type || state.stride != stride || state.pointer != uint32_t(pointer)) {
state.size = 0;
state.type = type;
state.stride = stride;
state.pointer = uint32_t(pointer);
trampoline(true, gl_state.bound_array_buffer, state);
}
#else
media_glBindBuffer(GL_ARRAY_BUFFER, args.next<GLuint>());
gl_array_details_t state = args.next<gl_array_details_t>();
func(state.type, state.stride, (const void *) uintptr_t(state.pointer));
return 0;
#endif
}
CALL(73, media_glLightfv, void, (GLenum light, GLenum pname, const GLfloat *params))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, light, pname, copy_array(4, params));
#else
GLenum light = args.next<GLenum>();
GLenum pname = args.next<GLenum>();
const GLfloat *params = args.next_arr<GLfloat>();
func(light, pname, params);
return 0;
#endif
}
CALL(74, media_glColorMaterial, void, (GLenum face, GLenum mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, face, mode);
#else
GLenum face = args.next<GLenum>();
GLenum mode = args.next<GLenum>();
func(face, mode);
return 0;
#endif
}
CALL(75, media_glLightModelfv, void, (GLenum pname, const GLfloat *params))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, pname, copy_array(4, params));
#else
GLenum pname = args.next<GLenum>();
const GLfloat *params = args.next_arr<GLfloat>();
func(pname, params);
return 0;
#endif
} }

View File

@ -11,7 +11,7 @@
// SDL Functions // SDL Functions
CALL(0, SDL_Init, int, (uint32_t flags)) CALL(0, media_SDL_Init, int, (uint32_t flags))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
return trampoline(false, flags); return trampoline(false, flags);
#else #else
@ -20,7 +20,7 @@ CALL(0, SDL_Init, int, (uint32_t flags))
#endif #endif
} }
CALL(1, SDL_PollEvent, int, (SDL_Event *event)) CALL(1, media_SDL_PollEvent, int, (SDL_Event *event))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
return trampoline(false, uint32_t(event)); return trampoline(false, uint32_t(event));
#else #else
@ -31,7 +31,7 @@ CALL(1, SDL_PollEvent, int, (SDL_Event *event))
#endif #endif
} }
CALL(2, SDL_PushEvent, int, (SDL_Event *event)) CALL(2, media_SDL_PushEvent, int, (SDL_Event *event))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
return trampoline(false, *event); return trampoline(false, *event);
#else #else
@ -40,7 +40,7 @@ CALL(2, SDL_PushEvent, int, (SDL_Event *event))
#endif #endif
} }
CALL(3, SDL_WM_SetCaption, void, (const char *title, const char *icon)) CALL(3, media_SDL_WM_SetCaption, void, (const char *title, const char *icon))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
trampoline(true, copy_array(title), copy_array(icon)); trampoline(true, copy_array(title), copy_array(icon));
#else #else
@ -60,7 +60,7 @@ CALL(4, media_toggle_fullscreen, void, ())
#endif #endif
} }
CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode)) CALL(5, media_SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
return (SDL_GrabMode) trampoline(false, mode); return (SDL_GrabMode) trampoline(false, mode);
#else #else
@ -68,7 +68,7 @@ CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode))
#endif #endif
} }
CALL(6, SDL_ShowCursor, int, (int32_t toggle)) CALL(6, media_SDL_ShowCursor, int, (int32_t toggle))
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST #ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
return trampoline(false, toggle); return trampoline(false, toggle);
#else #else

View File

@ -7,6 +7,7 @@ set(SRC
src/compat/egl.cpp src/compat/egl.cpp
src/compat/x11.cpp src/compat/x11.cpp
src/compat/bcm_host.cpp src/compat/bcm_host.cpp
src/compat/sdl.cpp
# readdir # readdir
src/readdir/readdir.cpp src/readdir/readdir.cpp
# feature # feature
@ -101,6 +102,11 @@ set(SRC
src/classic-ui/classic-ui.cpp src/classic-ui/classic-ui.cpp
# api # api
src/api/api.cpp src/api/api.cpp
# shading
src/shading/init.cpp
src/shading/tesselator.cpp
src/shading/lighting.cpp
src/shading/normals.cpp
) )
# Install Splashes # Install Splashes
install( install(

View File

@ -12,4 +12,6 @@ std::string chat_send_api_command(const Minecraft *minecraft, const std::string
// Override using the HOOK() macro to provide customized chat behavior. // Override using the HOOK() macro to provide customized chat behavior.
void chat_send_message(ServerSideNetworkHandler *server_side_network_handler, const char *username, const char *message); void chat_send_message(ServerSideNetworkHandler *server_side_network_handler, const char *username, const char *message);
void chat_handle_packet_send(const Minecraft *minecraft, ChatPacket *packet); void chat_handle_packet_send(const Minecraft *minecraft, ChatPacket *packet);
bool is_sending_to_chat();
} }

View File

@ -32,4 +32,5 @@ void init_f3();
void init_multidraw(); void init_multidraw();
void init_classic_ui(); void init_classic_ui();
void init_api(); void init_api();
void init_shading();
} }

View File

@ -2,6 +2,7 @@
#include <symbols/minecraft.h> #include <symbols/minecraft.h>
extern int multidraw_vertex_size;
extern "C" { extern "C" {
void LevelRenderer_renderSameAsLast(LevelRenderer *self, float delta); void LevelRenderer_renderSameAsLast(LevelRenderer *self, float delta);
} }

View File

@ -3,5 +3,5 @@
#include <GLES/gl.h> #include <GLES/gl.h>
extern "C" { extern "C" {
void glTexSubImage2D_with_scaling(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei normal_texture_width, GLsizei normal_texture_height, GLenum format, GLenum type, const void *pixels); void media_glTexSubImage2D_with_scaling(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei normal_texture_width, GLsizei normal_texture_height, GLenum format, GLenum type, const void *pixels);
} }

View File

@ -17,11 +17,15 @@ This includes:
- Removes all entities of a type, and returns how many were removed - Removes all entities of a type, and returns how many were removed
- [x] `events.chat.posts() -> {"0", message}[]` - [x] `events.chat.posts() -> {"0", message}[]`
- Gets a list of chat messages, see the limitations section down below to see why it has a zero - Gets a list of chat messages, see the limitations section down below to see why it has a zero
- When compatibility mode is enabled, `|` in the chat messages is replaced with `\`
- When compatibility mode is disabled, `|` in the chat messages is replaced with `\|`
- When compatibility mode is disabled, the first "0" is removed, so the return value is just the message
- The messages are not cleared - The messages are not cleared
- [x] `events.projectile.hits() -> {x: int, y: int, z: int, "1", owner: string, target: int}` - [x] `events.projectile.hits() -> {x: int, y: int, z: int, "1", owner: string, target: int}`
- Returns a list of projectile hit events, the list is cleared each time it is read by this call - Returns a list of projectile hit events, the list is cleared each time it is read by this call
- When target id is not 0, it means the projectile hit an entity and (x, y, z) is the entity's position - When target id is not 0, it means the projectile hit an entity and (x, y, z) is the entity's position
- When target id is 0, it means the projectile hit a block and (x, y, z) is the block's position - When target id is 0, it means the projectile hit a block and (x, y, z) is the block's position
- When compatibility mode is disabled, the constant "1" is removed in the return value, leaving just the useful information
- Unlike RaspberryJuice, the last argument is the hit entity id, not the entity's name. This shouldn't break anything, and indeed should be more useful. - Unlike RaspberryJuice, the last argument is the hit entity id, not the entity's name. This shouldn't break anything, and indeed should be more useful.
- [x] `player.setDirection(x: float, y: float, z: float)` - [x] `player.setDirection(x: float, y: float, z: float)`
- sets rotation as if the player was at 0, 0, 0 and looking towards (x, y, z) - sets rotation as if the player was at 0, 0, 0 and looking towards (x, y, z)
@ -69,9 +73,11 @@ This includes:
- [x] `world.spawnEntity(x: int, y: int, z: int, type: int) -> int` - [x] `world.spawnEntity(x: int, y: int, z: int, type: int) -> int`
- Spawns an entity of `type` at the given position - Spawns an entity of `type` at the given position
- Entities with a type of 0 cannot be spawned - Entities with a type of 0 cannot be spawned
- The list of entity types can be found by running the command below, or on the [wiki](https://mcpirevival.miraheze.org/wiki/Minecraft:_Pi_Edition_Complete_Entity_List). - The list of entity types for RaspberryJuice can be found [here](https://github.com/zhuowei/RaspberryJuice/blob/master/src/main/resources/mcpi/api/python/modded/mcpi/entity.py). This list is used when compatibility mode is enabled.
- The list of entity types can be found by running the command below, or on the [wiki](https://mcpirevival.miraheze.org/wiki/Minecraft:_Pi_Edition_Complete_Entity_List). This list is used when compatibility mode is disabled.
- [x] `world.getEntityTypes() -> {type: int, name: str}` - [x] `world.getEntityTypes() -> {type: int, name: str}`
- Returns a list of known entity types, if there are modded entities this list may be incorrect - Returns a list of known entity types, if there are modded entities this list may be incorrect
- The ids return depend on if compatibility mode is enabled, see `world.spawnEntity` for more
- [x] `player.getAbsPos() -> {x: int, y: int, z: int}` - [x] `player.getAbsPos() -> {x: int, y: int, z: int}`
- Gets the absolute position of the player, aka, without passing it through `OffsetPosTranslator` - Gets the absolute position of the player, aka, without passing it through `OffsetPosTranslator`
- [x] `player.setAbsPos(x: int, y: int, z: int)` - [x] `player.setAbsPos(x: int, y: int, z: int)`
@ -93,8 +99,7 @@ Egdecases:
Extras: Extras:
- [x] `reborn.enableDangerMode` and `reborn.disableDangerMode` - Compatibility mode, this is enabled by default, and can be changed with `reborn.disableCompatMode` or `reborn.enableCompatMode`.
- With "danger mode" enabled, chat messages will have `|` turned into `\`
## How does it work? ## How does it work?

View File

@ -9,9 +9,11 @@
#include <mods/init/init.h> #include <mods/init/init.h>
#include <mods/misc/misc.h> #include <mods/misc/misc.h>
#include <mods/chat/chat.h>
#include <mods/server/server.h> #include <mods/server/server.h>
#include <mods/feature/feature.h> #include <mods/feature/feature.h>
bool compat_mode = true;
static std::string getBlocks(CommandServer *commandserver, Vec3 start, Vec3 end) { static std::string getBlocks(CommandServer *commandserver, Vec3 start, Vec3 end) {
int startx = start.x, starty = start.y, startz = start.z; int startx = start.x, starty = start.y, startz = start.z;
int endx = end.x, endy = end.y, endz = end.z; int endx = end.x, endy = end.y, endz = end.z;
@ -74,6 +76,15 @@ static std::string getEntityData(CommandServer *commandserver, Entity *entity) {
std::to_string(z); std::to_string(z);
} }
static std::string replace(std::string str, std::string s1, std::string s2) {
size_t i = str.find(s1, 0);
while (i != std::string::npos) {
str.replace(i, s1.length(), s2);
i = str.find(s1, i + s2.length());
}
return str;
}
static float distance_between(Entity *e1, Entity *e2) { static float distance_between(Entity *e1, Entity *e2) {
if (e1 == NULL || e2 == NULL) return 0; if (e1 == NULL || e2 == NULL) return 0;
float dx = e2->x - e1->x; float dx = e2->x - e1->x;
@ -92,37 +103,68 @@ struct ProjectileHitEvent {
commandserver->pos_translator.to(nx, ny, nz); commandserver->pos_translator.to(nx, ny, nz);
return std::to_string((int) nx) + "," return std::to_string((int) nx) + ","
+ std::to_string((int) ny) + "," + std::to_string((int) ny) + ","
+ std::to_string((int) nz) + ",1," + std::to_string((int) nz) + ","
+ (compat_mode ? "1," : "")
+ owner + "," + std::to_string(targetId); + owner + "," + std::to_string(targetId);
} }
}; };
constexpr size_t EVENT_SIZE = 50; struct ChatEvent {
static int event_at = 0, event_start = 0; std::string message = "";
static ProjectileHitEvent hitEvents[EVENT_SIZE]; bool from_player = false;
static void addProjectile(ProjectileHitEvent event) { std::string toString() {
hitEvents[event_at] = event; return message;
event_at++; }
event_at %= EVENT_SIZE; };
if (event_at == event_start) {
event_start++; constexpr int EVENT_SIZE = 50;
event_start %= EVENT_SIZE; static int hit_events_at = 0, hit_events_start = 0;
static ProjectileHitEvent hitEvents[EVENT_SIZE];
static int chat_events_at = 0, chat_events_start = 0;
static ChatEvent chatEvents[EVENT_SIZE];
template <typename T>
static void push_circular_queue(T event, T events[], int &start, int &at) {
events[at] = event;
at++;
at %= EVENT_SIZE;
if (at == start) {
start++;
start %= EVENT_SIZE;
} }
} }
static ProjectileHitEvent popProjectile() { template <typename T>
if (event_start == event_at) { static T pop_circular_queue(T events[], int &start, int &at) {
if (start == at) {
ERR("Over popped projectile hit events!"); ERR("Over popped projectile hit events!");
} }
ProjectileHitEvent ret = hitEvents[event_start]; T ret = events[start];
event_start++; start++;
event_start %= EVENT_SIZE; start %= EVENT_SIZE;
return ret; return ret;
} }
static const std::string fail = "Fail\n"; static const std::string fail = "Fail\n";
bool safe_mode = true; std::unordered_map<int, int> modern_entity_id_mapping = {
{93, 10}, /* Chicken */
{92, 11}, /* Cow */
{90, 12}, /* Pig */
{91, 13}, /* Sheep */
{54, 32}, /* Zombie */
{50, 33}, /* Creeper */
{51, 34}, /* Skeleton */
{52, 35}, /* Spider */
{57, 36}, /* PigZombie */
/* ItemEntity isn't available */
{20, 65}, /* PrimedTnt */
/* FallingTile isn't available */
{10, 80}, /* Arrow */
{11, 81}, /* Snowball */
{7, 82}, /* Egg */
{9, 83}, /* Painting */
};
std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServer *commandserver, ConnectedClient &client, const std::string &command) { std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServer *commandserver, ConnectedClient &client, const std::string &command) {
size_t arg_start = command.find("("); size_t arg_start = command.find("(");
if (arg_start == std::string::npos) return fail; if (arg_start == std::string::npos) return fail;
@ -199,17 +241,32 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
return std::to_string(removed) + "\n"; return std::to_string(removed) + "\n";
} else if (cmd == "events.chat.posts") { } else if (cmd == "events.chat.posts") {
std::string ret = ""; std::string ret = "";
for (GuiMessage gm : commandserver->minecraft->gui.messages) { while (chat_events_at != chat_events_start) {
std::string message = gm.message; ChatEvent ce = pop_circular_queue(chatEvents, chat_events_start, chat_events_at);
if (safe_mode) std::replace(message.begin(), message.end(), '|', '\\'); std::string message = ce.toString();
ret += "0," + message + "|"; if (compat_mode) std::replace(message.begin(), message.end(), '|', '\\');
else replace(message, "|", "\\|");
ret += (compat_mode ? "0," : "") + message + "|";
}
if (ret.size() > 1) ret.pop_back();
return ret + "\n";
} else if (cmd == "player.events.chat.posts") {
std::string ret = "";
while (chat_events_at != chat_events_start) {
ChatEvent ce = pop_circular_queue(chatEvents, chat_events_start, chat_events_at);
if (ce.from_player) {
std::string message = ce.toString();
if (compat_mode) std::replace(message.begin(), message.end(), '|', '\\');
else replace(message, "|", "\\|");
ret += (compat_mode ? "0," : "") + message + "|";
}
} }
if (ret.size() > 1) ret.pop_back(); if (ret.size() > 1) ret.pop_back();
return ret + "\n"; return ret + "\n";
} else if (cmd == "events.projectile.hits") { } else if (cmd == "events.projectile.hits") {
std::string result = ""; std::string result = "";
while (event_at != event_start) { while (hit_events_at != hit_events_start) {
result += popProjectile().toString(commandserver) + "|"; result += pop_circular_queue(hitEvents, hit_events_start, hit_events_at).toString(commandserver) + "|";
} }
if (result.size() > 1) result.pop_back(); if (result.size() > 1) result.pop_back();
return result + "\n"; return result + "\n";
@ -387,6 +444,7 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
x += ix - ix1; x += ix - ix1;
y += iy - iy1; y += iy - iy1;
z += iz - iz1; z += iz - iz1;
if (compat_mode && modern_entity_id_mapping.find(id) != modern_entity_id_mapping.end()) id = modern_entity_id_mapping[id];
// Spawn // Spawn
Entity *entity = NULL; Entity *entity = NULL;
if (id < 0x40) { if (id < 0x40) {
@ -401,7 +459,9 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
} else if (cmd == "world.getEntityTypes") { } else if (cmd == "world.getEntityTypes") {
std::string result = ""; std::string result = "";
for (auto &i : misc_get_entity_names()) { for (auto &i : misc_get_entity_names()) {
result += std::to_string(i.first) + "," + i.second + "|"; if (compat_mode && modern_entity_id_mapping.find(i.first) != modern_entity_id_mapping.end()) result += std::to_string(modern_entity_id_mapping[i.first]);
else result += std::to_string(i.first);
result += "," + i.second + "|";
} }
if (result.size() > 1) result.pop_back(); if (result.size() > 1) result.pop_back();
return result + "\n"; return result + "\n";
@ -414,10 +474,10 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ
return std::to_string(commandserver->minecraft->player->x) + "," return std::to_string(commandserver->minecraft->player->x) + ","
+ std::to_string(commandserver->minecraft->player->y) + "," + std::to_string(commandserver->minecraft->player->y) + ","
+ std::to_string(commandserver->minecraft->player->z) + "\n"; + std::to_string(commandserver->minecraft->player->z) + "\n";
} else if (cmd == "reborn.enableDangerMode") { } else if (cmd == "reborn.disableCompatMode") {
safe_mode = false; compat_mode = false;
} else if (cmd == "reborn.disableDangerMode") { } else if (cmd == "reborn.enableCompatMode") {
safe_mode = true; compat_mode = true;
} else { } else {
// Either invalid or a vanilla command, either way hand it off to the orignal handler // Either invalid or a vanilla command, either way hand it off to the orignal handler
return old(commandserver, client, command); return old(commandserver, client, command);
@ -438,13 +498,13 @@ static HitResult *Arrow_tick_HitResult_constructor_injection(HitResult *self, En
self->exact.z = target->z; self->exact.z = target->z;
// Add event // Add event
if (shooter && shooter->isPlayer()) { if (shooter && shooter->isPlayer()) {
addProjectile(ProjectileHitEvent{ push_circular_queue(ProjectileHitEvent{
.x = (int) target->x, .x = (int) target->x,
.y = (int) target->y, .y = (int) target->y,
.z = (int) target->z, .z = (int) target->z,
.owner = misc_get_player_username((Player *) shooter), .owner = misc_get_player_username((Player *) shooter),
.targetId = target->id .targetId = target->id
}); }, hitEvents, hit_events_start, hit_events_at);
} }
return self; return self;
} }
@ -457,13 +517,13 @@ static void Arrow_tick_injection(Arrow_tick_t old, Arrow *self) {
if (self && !self->pending_removal && self->grounded && oldFlightTime != self->flight_time) { if (self && !self->pending_removal && self->grounded && oldFlightTime != self->flight_time) {
if (shooter && shooter->isPlayer()) { if (shooter && shooter->isPlayer()) {
// Hit! Get the data // Hit! Get the data
addProjectile(ProjectileHitEvent{ push_circular_queue(ProjectileHitEvent{
.x = self->hit_x, .x = self->hit_x,
.y = self->hit_y, .y = self->hit_y,
.z = self->hit_z, .z = self->hit_z,
.owner = misc_get_player_username((Player *) shooter), .owner = misc_get_player_username((Player *) shooter),
.targetId = 0 .targetId = 0
}); }, hitEvents, hit_events_start, hit_events_at);
} }
} }
} }
@ -493,15 +553,24 @@ static void Throwable_tick_Throwable_onHit_injection(Throwable *self, HitResult
.targetId = 0 .targetId = 0
}; };
} }
addProjectile(event); push_circular_queue(event, hitEvents, hit_events_start, hit_events_at);
self->onHit(res); self->onHit(res);
} }
static void Gui_addMessage_injection(Gui_addMessage_t original, Gui *gui, const std::string &text) {
push_circular_queue(ChatEvent{
text,
is_sending_to_chat()
}, chatEvents, chat_events_start, chat_events_at);
original(gui, text);
}
void init_api() { void init_api() {
if (feature_has("Implement RaspberryJuice API", server_enabled)) { if (feature_has("Implement RaspberryJuice API", server_enabled)) {
overwrite_calls(CommandServer_parse, CommandServer_parse_injection); overwrite_calls(CommandServer_parse, CommandServer_parse_injection);
overwrite_calls(Arrow_tick, Arrow_tick_injection); overwrite_calls(Arrow_tick, Arrow_tick_injection);
overwrite_call((void *) 0x8b1e8, (void *) Arrow_tick_HitResult_constructor_injection); overwrite_call((void *) 0x8b1e8, (void *) Arrow_tick_HitResult_constructor_injection);
overwrite_call((void *) 0x8c5a4, (void *) Throwable_tick_Throwable_onHit_injection); overwrite_call((void *) 0x8c5a4, (void *) Throwable_tick_Throwable_onHit_injection);
overwrite_calls(Gui_addMessage, Gui_addMessage_injection);
} }
} }

View File

@ -24,15 +24,15 @@ static void ItemRenderer_renderGuiItemCorrect_injection_one(ItemRenderer_renderG
} }
// Fix Toolbar Rendering // Fix Toolbar Rendering
const GLboolean depth_test_was_enabled = glIsEnabled(GL_DEPTH_TEST); const GLboolean depth_test_was_enabled = media_glIsEnabled(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST); media_glDisable(GL_DEPTH_TEST);
// Call Original Method // Call Original Method
original(font, textures, use_carried ? &carried_item_instance : item_instance, param_1, param_2); original(font, textures, use_carried ? &carried_item_instance : item_instance, param_1, param_2);
// Revert GL State Changes // Revert GL State Changes
if (depth_test_was_enabled) { if (depth_test_was_enabled) {
glEnable(GL_DEPTH_TEST); media_glEnable(GL_DEPTH_TEST);
} }
} }
@ -98,10 +98,10 @@ static void ItemRenderer_renderGuiItem_two_injection_two(ItemRenderer_renderGuiI
original(font, textures, item_instance, x, y, w, h, param_5); original(font, textures, item_instance, x, y, w, h, param_5);
} }
static void ItemRenderer_renderGuiItemCorrect_injection_two(ItemRenderer_renderGuiItemCorrect_t original, Font *font, Textures *textures, const ItemInstance *item_instance, __attribute__((unused)) int x, __attribute__((unused)) int y) { static void ItemRenderer_renderGuiItemCorrect_injection_two(ItemRenderer_renderGuiItemCorrect_t original, Font *font, Textures *textures, const ItemInstance *item_instance, __attribute__((unused)) int x, __attribute__((unused)) int y) {
glPushMatrix(); media_glPushMatrix();
glTranslatef(target_x, target_y, 0); media_glTranslatef(target_x, target_y, 0);
original(font, textures, item_instance, 0, 0); original(font, textures, item_instance, 0, 0);
glPopMatrix();; media_glPopMatrix();;
} }
// Init // Init

View File

@ -126,7 +126,7 @@ static void Minecraft_update_injection(Minecraft *minecraft) {
event.motion.y = 0; event.motion.y = 0;
event.motion.xrel = (rotation_diff > INT16_MAX) ? INT16_MAX : int16_t(rotation_diff); event.motion.xrel = (rotation_diff > INT16_MAX) ? INT16_MAX : int16_t(rotation_diff);
event.motion.yrel = 0; event.motion.yrel = 0;
SDL_PushEvent(&event); media_SDL_PushEvent(&event);
// Reset Rotation Timer // Reset Rotation Timer
rotation_so_far += event.motion.xrel; rotation_so_far += event.motion.xrel;
} }

View File

@ -76,8 +76,14 @@ static void ServerSideNetworkHandler_handle_ChatPacket_injection(ServerSideNetwo
} }
// Send Message // Send Message
static bool _is_sending_to_chat = false;
bool is_sending_to_chat() {
return _is_sending_to_chat;
}
void _chat_send_message(const Minecraft *minecraft, const char *message) { void _chat_send_message(const Minecraft *minecraft, const char *message) {
_is_sending_to_chat= true;
send_api_chat_command(minecraft, message); send_api_chat_command(minecraft, message);
_is_sending_to_chat = false;
} }
// Allow Reading Longer ChatPacket Messages // Allow Reading Longer ChatPacket Messages

View File

@ -3,3 +3,4 @@
__attribute__((visibility("internal"))) void _patch_egl_calls(); __attribute__((visibility("internal"))) void _patch_egl_calls();
__attribute__((visibility("internal"))) void _patch_x11_calls(); __attribute__((visibility("internal"))) void _patch_x11_calls();
__attribute__((visibility("internal"))) void _patch_bcm_host_calls(); __attribute__((visibility("internal"))) void _patch_bcm_host_calls();
__attribute__((visibility("internal"))) void _patch_sdl_calls();

View File

@ -16,29 +16,29 @@
#include <mods/sign/sign.h> #include <mods/sign/sign.h>
// Custom Title // Custom Title
HOOK(SDL_WM_SetCaption, void, (__attribute__((unused)) const char *title, const char *icon)) { HOOK(media_SDL_WM_SetCaption, void, (__attribute__((unused)) const char *title, const char *icon)) {
real_SDL_WM_SetCaption()(MCPI_APP_TITLE, icon); real_media_SDL_WM_SetCaption()(MCPI_APP_TITLE, icon);
} }
// Mouse Cursor Is Always Invisible In Vanilla MCPI // Mouse Cursor Is Always Invisible In Vanilla MCPI
// Because In Vanilla MCPI, The GPU Overlay Covered The Normal Mouse Cursor // Because In Vanilla MCPI, The GPU Overlay Covered The Normal Mouse Cursor
HOOK(SDL_ShowCursor, int, (int toggle)) { HOOK(media_SDL_ShowCursor, int, (int toggle)) {
return real_SDL_ShowCursor()(toggle == SDL_QUERY ? SDL_QUERY : SDL_DISABLE); return real_media_SDL_ShowCursor()(toggle == SDL_QUERY ? SDL_QUERY : SDL_DISABLE);
} }
// Intercept SDL Events // Intercept SDL Events
HOOK(SDL_PollEvent, int, (SDL_Event *event)) { HOOK(media_SDL_PollEvent, int, (SDL_Event *event)) {
// In Server Mode, Exit Requests Are Handled In src/server/server.cpp // In Server Mode, Exit Requests Are Handled In src/server/server.cpp
// Check If Exit Is Requested // Check If Exit Is Requested
if (!reborn_is_server() && compat_check_exit_requested()) { if (!reborn_is_server() && compat_check_exit_requested()) {
// Send SDL_QUIT // Send SDL_QUIT
SDL_Event new_event; SDL_Event new_event;
new_event.type = SDL_QUIT; new_event.type = SDL_QUIT;
SDL_PushEvent(&new_event); media_SDL_PushEvent(&new_event);
} }
// Poll Events // Poll Events
int ret = real_SDL_PollEvent()(event); int ret = real_media_SDL_PollEvent()(event);
// Handle Events // Handle Events
if (ret == 1 && event != nullptr) { if (ret == 1 && event != nullptr) {
@ -73,7 +73,7 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
} }
if (handled) { if (handled) {
// Event Was Handled // Event Was Handled
return SDL_PollEvent(event); return media_SDL_PollEvent(event);
} }
} }
@ -99,6 +99,7 @@ void init_compat() {
_patch_egl_calls(); _patch_egl_calls();
_patch_x11_calls(); _patch_x11_calls();
_patch_bcm_host_calls(); _patch_bcm_host_calls();
_patch_sdl_calls();
} }
// Store Exit Requests // Store Exit Requests

43
mods/src/compat/sdl.cpp Normal file
View File

@ -0,0 +1,43 @@
#include <SDL/SDL.h>
#include <media-layer/core.h>
#include <libreborn/libreborn.h>
#include "compat-internal.h"
// SDL Stub
static void *SDL_SetVideoMode_injection(__attribute__((unused)) int width, __attribute__((unused)) int height, __attribute__((unused)) int bpp, __attribute__((unused)) uint32_t flags) {
// Return Value Is Only Used For A NULL-Check
return (void *) 1;
}
// Window Information
static void x11_nop() {
// NOP
}
static int SDL_GetWMInfo_injection(SDL_SysWMinfo *info) {
// Return Fake Lock Functions Since XLib Isn't Directly Used
SDL_SysWMinfo ret;
ret.info.x11.lock_func = x11_nop;
ret.info.x11.unlock_func = x11_nop;
ret.info.x11.display = NULL;
ret.info.x11.window = 0;
ret.info.x11.wmwindow = ret.info.x11.window;
*info = ret;
return 1;
}
// Quit
static void SDL_Quit_injection() {
// Cleanup Media Layer
media_cleanup();
// Exit
INFO("Stopped");
}
// Patch SDL Calls
void _patch_sdl_calls() {
// Disable SDL Calls
overwrite_call((void *) 0xe020, (void *) SDL_SetVideoMode_injection);
overwrite_call((void *) 0x13284, (void *) SDL_GetWMInfo_injection);
overwrite_call((void *) 0x12410, (void *) SDL_Quit_injection);
}

View File

@ -71,7 +71,7 @@ static bool Mob_hurt_injection(Mob_hurt_t original, Mob *mob, Entity *source, co
// Death Message Logic // Death Message Logic
template <typename Self, typename ParentSelf> template <typename Self, typename ParentSelf>
static void Player_die_injection(std::function<void(ParentSelf *, Entity *)> original, Self *player, Entity *cause) { static void Player_die_injection(const std::function<void(ParentSelf *, Entity *)> &original, Self *player, Entity *cause) {
// Call Original Method // Call Original Method
original((ParentSelf *) player, cause); original((ParentSelf *) player, cause);
@ -88,7 +88,7 @@ static void Player_die_injection(std::function<void(ParentSelf *, Entity *)> ori
} }
} }
template <typename OriginalSelf, typename Self> template <typename OriginalSelf, typename Self>
static void Player_actuallyHurt_injection(std::function<void(OriginalSelf *, int)> original, Self *player, int32_t damage) { static void Player_actuallyHurt_injection(const std::function<void(OriginalSelf *, int)> &original, Self *player, int32_t damage) {
// Store Old Health // Store Old Health
int32_t old_health = player->health; int32_t old_health = player->health;

View File

@ -16,6 +16,7 @@ __attribute__((constructor)) static void init() {
init_multiplayer(); init_multiplayer();
if (!reborn_is_headless()) { if (!reborn_is_headless()) {
init_sound(); init_sound();
init_shading();
} }
init_input(); init_input();
init_sign(); init_sign();

View File

@ -49,7 +49,7 @@ static bool InBedScreen_handleBackEvent_injection(InBedScreen *screen, const boo
// Block UI Interaction When Mouse Is Locked // Block UI Interaction When Mouse Is Locked
static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(Minecraft *minecraft) { static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(Minecraft *minecraft) {
const bool is_in_game = minecraft->screen == nullptr || minecraft->screen->vtable == (Screen_vtable *) Touch_IngameBlockSelectionScreen_vtable_base; const bool is_in_game = minecraft->screen == nullptr || minecraft->screen->vtable == (Screen_vtable *) Touch_IngameBlockSelectionScreen_vtable_base;
if (!enable_misc || (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF && is_in_game)) { if (!enable_misc || (media_SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF && is_in_game)) {
// Call Original Method // Call Original Method
return creative_is_restricted() && minecraft->isCreativeMode(); return creative_is_restricted() && minecraft->isCreativeMode();
} else { } else {
@ -60,7 +60,7 @@ static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(Minecraft *
// Block UI Interaction When Mouse Is Locked // Block UI Interaction When Mouse Is Locked
static void Gui_handleClick_injection(Gui_handleClick_t original, Gui *gui, const int32_t param_2, const int32_t param_3, const int32_t param_4) { static void Gui_handleClick_injection(Gui_handleClick_t original, Gui *gui, const int32_t param_2, const int32_t param_3, const int32_t param_4) {
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) { if (media_SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
// Call Original Method // Call Original Method
original(gui, param_2, param_3, param_4); original(gui, param_2, param_3, param_4);
} }

View File

@ -112,7 +112,7 @@ void misc_run_on_key_press(const std::function<bool(Minecraft *, int)> &func) {
// Render Fancy Background // Render Fancy Background
void misc_render_background(int color, const Minecraft *minecraft, const int x, const int y, const int width, const int height) { void misc_render_background(int color, const Minecraft *minecraft, const int x, const int y, const int width, const int height) {
// https://github.com/ReMinecraftPE/mcpe/blob/f0d65eaecec1b3fe9c2f2b251e114a890c54ab77/source/client/gui/components/RolledSelectionList.cpp#L169-L179 // https://github.com/ReMinecraftPE/mcpe/blob/f0d65eaecec1b3fe9c2f2b251e114a890c54ab77/source/client/gui/components/RolledSelectionList.cpp#L169-L179
glColor4f(1, 1, 1, 1); media_glColor4f(1, 1, 1, 1);
minecraft->textures->loadAndBindTexture("gui/background.png"); minecraft->textures->loadAndBindTexture("gui/background.png");
Tesselator *t = &Tesselator::instance; Tesselator *t = &Tesselator::instance;
t->begin(7); t->begin(7);

View File

@ -14,14 +14,14 @@
// Properly Generate Buffers // Properly Generate Buffers
static void anGenBuffers_injection(__attribute__((unused)) Common_anGenBuffers_t original, const int32_t count, uint32_t *buffers) { static void anGenBuffers_injection(__attribute__((unused)) Common_anGenBuffers_t original, const int32_t count, uint32_t *buffers) {
if (!reborn_is_headless()) { if (!reborn_is_headless()) {
glGenBuffers(count, buffers); media_glGenBuffers(count, buffers);
} }
} }
// Custom Outline Color // Custom Outline Color
static void LevelRenderer_render_AABB_glColor4f_injection(__attribute__((unused)) GLfloat red, __attribute__((unused)) GLfloat green, __attribute__((unused)) GLfloat blue, __attribute__((unused)) GLfloat alpha) { static void LevelRenderer_render_AABB_glColor4f_injection(__attribute__((unused)) GLfloat red, __attribute__((unused)) GLfloat green, __attribute__((unused)) GLfloat blue, __attribute__((unused)) GLfloat alpha) {
// Set Color // Set Color
glColor4f(0, 0, 0, 0.4); media_glColor4f(0, 0, 0, 0.4);
// Find Line Width // Find Line Width
const char *custom_line_width = getenv(MCPI_BLOCK_OUTLINE_WIDTH_ENV); const char *custom_line_width = getenv(MCPI_BLOCK_OUTLINE_WIDTH_ENV);
@ -35,14 +35,14 @@ static void LevelRenderer_render_AABB_glColor4f_injection(__attribute__((unused)
} }
// Clamp Line Width // Clamp Line Width
float range[2]; float range[2];
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range); media_glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
if (range[1] < line_width) { if (range[1] < line_width) {
line_width = range[1]; line_width = range[1];
} else if (range[0] > line_width) { } else if (range[0] > line_width) {
line_width = range[0]; line_width = range[0];
} }
// Set Line Width // Set Line Width
glLineWidth(line_width); media_glLineWidth(line_width);
} }
// Java Light Ramp // Java Light Ramp
@ -100,10 +100,10 @@ static void render_fire(EntityRenderer *self, Entity *entity, const float x, flo
const int texture = Tile::fire->texture; const int texture = Tile::fire->texture;
const int xt = (texture & 0xf) << 4; const int xt = (texture & 0xf) << 4;
const int yt = texture & 0xf0; const int yt = texture & 0xf0;
glPushMatrix(); media_glPushMatrix();
glTranslatef(x, y, z); media_glTranslatef(x, y, z);
const float s = entity->hitbox_width * 1.4f; const float s = entity->hitbox_width * 1.4f;
glScalef(s, s, s); media_glScalef(s, s, s);
self->bindTexture("terrain.png"); self->bindTexture("terrain.png");
Tesselator &t = Tesselator::instance; Tesselator &t = Tesselator::instance;
float r = 0.5f; float r = 0.5f;
@ -114,9 +114,9 @@ static void render_fire(EntityRenderer *self, Entity *entity, const float x, flo
// Handle Front-Facing // Handle Front-Facing
player_rot_y -= 180.f; player_rot_y -= 180.f;
} }
glRotatef(-player_rot_y, 0, 1, 0); media_glRotatef(-player_rot_y, 0, 1, 0);
glTranslatef(0, 0, -0.3f + float(int(h)) * 0.02f); media_glTranslatef(0, 0, -0.3f + float(int(h)) * 0.02f);
glColor4f(1, 1, 1, 1); media_glColor4f(1, 1, 1, 1);
float zo = 0; float zo = 0;
int ss = 0; int ss = 0;
t.begin(7); t.begin(7);
@ -151,7 +151,7 @@ static void render_fire(EntityRenderer *self, Entity *entity, const float x, flo
ss++; ss++;
} }
t.draw(); t.draw();
glPopMatrix(); media_glPopMatrix();
} }
// Entity Shadows // Entity Shadows
@ -181,7 +181,7 @@ static void render_shadow_tile(Tile *tile, const float x, const float y, const f
t.vertexUV(x1, y0, z1, u1, v1); t.vertexUV(x1, y0, z1, u1, v1);
t.vertexUV(x1, y0, z0, u1, v0); t.vertexUV(x1, y0, z0, u1, v0);
} }
static void render_shadow(const EntityRenderer *self, Entity *entity, float x, float y, float z, const float a) { static void render_shadow(const EntityRenderer *self, Entity *entity, const float x, const float y, const float z, const float a) {
// Calculate Power // Calculate Power
float pow = 0; float pow = 0;
if (self->shadow_radius > 0) { if (self->shadow_radius > 0) {
@ -192,15 +192,21 @@ static void render_shadow(const EntityRenderer *self, Entity *entity, float x, f
return; return;
} }
// Render // Render
glEnable(GL_BLEND); media_glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); media_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Textures *textures = EntityRenderer::entityRenderDispatcher->textures; Textures *textures = EntityRenderer::entityRenderDispatcher->textures;
textures->loadAndBindTexture("misc/shadow.png"); textures->loadAndBindTexture("misc/shadow.png");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); media_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); media_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Level *level = EntityRenderer::entityRenderDispatcher->level; Level *level = EntityRenderer::entityRenderDispatcher->level;
glDepthMask(false); media_glDepthMask(false);
const float r = self->shadow_radius; float r = self->shadow_radius;
if (entity->isMob()) {
Mob *mob = (Mob *) entity;
if (mob->isBaby()) {
r *= 0.5f;
}
}
const float ex = entity->old_x + (entity->x - entity->old_x) * a; const float ex = entity->old_x + (entity->x - entity->old_x) * a;
float ey = entity->old_y + (entity->y - entity->old_y) * a + entity->getShadowHeightOffs() - entity->height_offset; float ey = entity->old_y + (entity->y - entity->old_y) * a + entity->getShadowHeightOffs() - entity->height_offset;
const float ez = entity->old_z + (entity->z - entity->old_z) * a; const float ez = entity->old_z + (entity->z - entity->old_z) * a;
@ -232,9 +238,9 @@ static void render_shadow(const EntityRenderer *self, Entity *entity, float x, f
} }
} }
tt.draw(); tt.draw();
glColor4f(1, 1, 1, 1); media_glColor4f(1, 1, 1, 1);
glDisable(GL_BLEND); media_glDisable(GL_BLEND);
glDepthMask(true); media_glDepthMask(true);
} }
static void EntityRenderDispatcher_assign_injection(EntityRenderDispatcher_assign_t original, EntityRenderDispatcher *self, const uchar entity_id, EntityRenderer *renderer) { static void EntityRenderDispatcher_assign_injection(EntityRenderDispatcher_assign_t original, EntityRenderDispatcher *self, const uchar entity_id, EntityRenderer *renderer) {
// Modify Shadow Size // Modify Shadow Size
@ -276,10 +282,22 @@ static void EntityRenderDispatcher_render_EntityRenderer_render_injection(Entity
} }
// Render Fire // Render Fire
if (should_render_fire) { if (should_render_fire) {
const bool was_lighting_enabled = media_glIsEnabled(GL_LIGHTING);
media_glDisable(GL_LIGHTING);
render_fire(self, entity, x, y, z); render_fire(self, entity, x, y, z);
if (was_lighting_enabled) {
media_glEnable(GL_LIGHTING);
}
} }
} }
// Hide Shadow In Armor Screen
static void ArmorScreen_renderPlayer_injection(ArmorScreen_renderPlayer_t original, ArmorScreen *self, float param_1, float param_2) {
should_render_shadows = false;
original(self, param_1, param_2);
should_render_shadows = true;
}
// Nicer Water Rendering // Nicer Water Rendering
static bool game_render_anaglyph_color_mask[4]; static bool game_render_anaglyph_color_mask[4];
static void GameRenderer_render_glColorMask_injection(const bool red, const bool green, const bool blue, const bool alpha) { static void GameRenderer_render_glColorMask_injection(const bool red, const bool green, const bool blue, const bool alpha) {
@ -287,14 +305,14 @@ static void GameRenderer_render_glColorMask_injection(const bool red, const bool
game_render_anaglyph_color_mask[1] = green; game_render_anaglyph_color_mask[1] = green;
game_render_anaglyph_color_mask[2] = blue; game_render_anaglyph_color_mask[2] = blue;
game_render_anaglyph_color_mask[3] = alpha; game_render_anaglyph_color_mask[3] = alpha;
glColorMask(red, green, blue, alpha); media_glColorMask(red, green, blue, alpha);
} }
static int GameRenderer_render_LevelRenderer_render_injection(LevelRenderer *self, Mob *mob, int param_1, float delta) { static int GameRenderer_render_LevelRenderer_render_injection(LevelRenderer *self, Mob *mob, int param_1, float delta) {
glColorMask(false, false, false, false); media_glColorMask(false, false, false, false);
const int water_chunks = self->render(mob, param_1, delta); const int water_chunks = self->render(mob, param_1, delta);
glColorMask(true, true, true, true); media_glColorMask(true, true, true, true);
if (self->minecraft->options.anaglyph_3d) { if (self->minecraft->options.anaglyph_3d) {
glColorMask(game_render_anaglyph_color_mask[0], game_render_anaglyph_color_mask[1], game_render_anaglyph_color_mask[2], game_render_anaglyph_color_mask[3]); media_glColorMask(game_render_anaglyph_color_mask[0], game_render_anaglyph_color_mask[1], game_render_anaglyph_color_mask[2], game_render_anaglyph_color_mask[3]);
} }
if (water_chunks > 0) { if (water_chunks > 0) {
LevelRenderer_renderSameAsLast(self, delta); LevelRenderer_renderSameAsLast(self, delta);
@ -346,14 +364,13 @@ static void ModelPart_render_injection(ModelPart *model_part, float scale) {
// Stop // Stop
is_rendering_chest = false; is_rendering_chest = false;
} }
static void Tesselator_vertexUV_injection(Tesselator_vertexUV_t original, Tesselator *tesselator, const float x, const float y, const float z, const float u, float v) { static void Tesselator_vertexUV_injection(Tesselator *self, const float x, const float y, const float z, const float u, float v) {
// Fix Chest Texture // Fix Chest Texture
if (is_rendering_chest) { if (is_rendering_chest) {
v /= 2; v /= 2;
} }
// Call Original Method // Call Original Method
original(tesselator, x, y, z, u, v); self->vertexUV(x, y, z, u, v);
} }
static bool ChestTileEntity_shouldSave_injection(__attribute__((unused)) ChestTileEntity_shouldSave_t original, __attribute__((unused)) ChestTileEntity *tile_entity) { static bool ChestTileEntity_shouldSave_injection(__attribute__((unused)) ChestTileEntity_shouldSave_t original, __attribute__((unused)) ChestTileEntity *tile_entity) {
return true; return true;
@ -391,10 +408,10 @@ static ContainerMenu *ContainerMenu_destructor_injection(ContainerMenu_destructo
static bool disable_hand_positioning = false; static bool disable_hand_positioning = false;
static void ItemInHandRenderer_renderItem_glTranslatef_injection(const float x, const float y, const float z) { static void ItemInHandRenderer_renderItem_glTranslatef_injection(const float x, const float y, const float z) {
if (disable_hand_positioning) { if (disable_hand_positioning) {
glPopMatrix(); media_glPopMatrix();
glPushMatrix(); media_glPushMatrix();
} else { } else {
glTranslatef(x, y, z); media_glTranslatef(x, y, z);
} }
} }
static void ItemRenderer_render_injection(ItemRenderer_render_t original, ItemRenderer *self, Entity *entity, const float x, const float y, const float z, const float a, const float b) { static void ItemRenderer_render_injection(ItemRenderer_render_t original, ItemRenderer *self, Entity *entity, const float x, const float y, const float z, const float a, const float b) {
@ -408,7 +425,7 @@ static void ItemRenderer_render_injection(ItemRenderer_render_t original, ItemRe
} else { } else {
// 3D Item // 3D Item
self->random.setSeed(187); self->random.setSeed(187);
glPushMatrix(); media_glPushMatrix();
// Count // Count
int count; int count;
@ -425,14 +442,14 @@ static void ItemRenderer_render_injection(ItemRenderer_render_t original, ItemRe
// Bob // Bob
const float age = float(item_entity->age) + b; const float age = float(item_entity->age) + b;
const float bob = (Mth::sin((age / 10.0f) + item_entity->bob_offset) * 0.1f) + 0.1f; const float bob = (Mth::sin((age / 10.0f) + item_entity->bob_offset) * 0.1f) + 0.1f;
glTranslatef(x, y + bob, z); media_glTranslatef(x, y + bob, z);
// Scale // Scale
glScalef(0.5f, 0.5f, 0.5f); media_glScalef(0.5f, 0.5f, 0.5f);
// Spin // Spin
const float spin = ((age / 20.0f) + item_entity->bob_offset) * float(180.0f / M_PI); const float spin = ((age / 20.0f) + item_entity->bob_offset) * float(180.0f / M_PI);
glRotatef(spin, 0, 1, 0); media_glRotatef(spin, 0, 1, 0);
// Position // Position
constexpr float xo = 0.5f; constexpr float xo = 0.5f;
@ -440,33 +457,42 @@ static void ItemRenderer_render_injection(ItemRenderer_render_t original, ItemRe
constexpr float width = 1 / 16.0f; constexpr float width = 1 / 16.0f;
constexpr float margin = 0.35f / 16.0f; constexpr float margin = 0.35f / 16.0f;
constexpr float zo = width + margin; constexpr float zo = width + margin;
glTranslatef(-xo, -yo, -((zo * float(count)) / 2)); media_glTranslatef(-xo, -yo, -((zo * float(count)) / 2));
// Draw // Draw
disable_hand_positioning = true; disable_hand_positioning = true;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
glTranslatef(0, 0, zo); media_glTranslatef(0, 0, zo);
EntityRenderer::entityRenderDispatcher->item_renderer->renderItem(nullptr, &item); EntityRenderer::entityRenderDispatcher->item_renderer->renderItem(nullptr, &item);
} }
disable_hand_positioning = false; disable_hand_positioning = false;
// Finish // Finish
glPopMatrix(); media_glPopMatrix();
} }
} }
// Vignette // Vignette
static void Gui_renderProgressIndicator_injection(Gui_renderProgressIndicator_t original, Gui *self, const bool is_touch, int width, int height, float a) { static void Gui_renderProgressIndicator_injection(Gui_renderProgressIndicator_t original, Gui *self, const bool is_touch, int width, int height, float a) {
// Render // Render
glEnable(GL_BLEND); media_glEnable(GL_BLEND);
self->minecraft->textures->blur = true; self->minecraft->textures->blur = true;
self->renderVignette(self->minecraft->player->getBrightness(a), width, height); self->renderVignette(self->minecraft->player->getBrightness(a), width, height);
self->minecraft->textures->blur = false; self->minecraft->textures->blur = false;
glDisable(GL_BLEND); media_glDisable(GL_BLEND);
// Call Original Method // Call Original Method
original(self, is_touch, width, height, a); original(self, is_touch, width, height, a);
} }
// Increase Render Chunk Size
static void adjust_mov_shift(void *addr, const uint32_t new_shift) {
uint32_t instruction = *(uint32_t *) addr;
instruction &= ~0x00000f80;
instruction |= (new_shift << 7);
unsigned char *x = (unsigned char *) &instruction;
patch(addr, x);
}
// Init // Init
void _init_misc_graphics() { void _init_misc_graphics() {
// Disable V-Sync // Disable V-Sync
@ -519,6 +545,7 @@ void _init_misc_graphics() {
should_render_shadows = feature_has("Render Entity Shadows", server_disabled); should_render_shadows = feature_has("Render Entity Shadows", server_disabled);
if (should_render_shadows) { if (should_render_shadows) {
overwrite_calls(EntityRenderDispatcher_assign, EntityRenderDispatcher_assign_injection); overwrite_calls(EntityRenderDispatcher_assign, EntityRenderDispatcher_assign_injection);
overwrite_calls(ArmorScreen_renderPlayer, ArmorScreen_renderPlayer_injection);
} }
// Slightly Nicer Water Rendering // Slightly Nicer Water Rendering
@ -546,7 +573,7 @@ void _init_misc_graphics() {
overwrite_call((void *) 0x6655c, (void *) ModelPart_render_injection); overwrite_call((void *) 0x6655c, (void *) ModelPart_render_injection);
overwrite_call((void *) 0x66568, (void *) ModelPart_render_injection); overwrite_call((void *) 0x66568, (void *) ModelPart_render_injection);
overwrite_call((void *) 0x66574, (void *) ModelPart_render_injection); overwrite_call((void *) 0x66574, (void *) ModelPart_render_injection);
overwrite_calls(Tesselator_vertexUV, Tesselator_vertexUV_injection); overwrite_call((void *) 0x4278c, (void *) Tesselator_vertexUV_injection);
unsigned char chest_model_patch[4] = {0x13, 0x20, 0xa0, 0xe3}; // "mov r2, #0x13" unsigned char chest_model_patch[4] = {0x13, 0x20, 0xa0, 0xe3}; // "mov r2, #0x13"
patch((void *) 0x66fc8, chest_model_patch); patch((void *) 0x66fc8, chest_model_patch);
unsigned char chest_color_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop" unsigned char chest_color_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
@ -571,6 +598,51 @@ void _init_misc_graphics() {
overwrite_calls(Gui_renderProgressIndicator, Gui_renderProgressIndicator_injection); overwrite_calls(Gui_renderProgressIndicator, Gui_renderProgressIndicator_injection);
} }
// Increase Render Chunk Size
if (feature_has("Increase Render Chunk Size", server_disabled)) {
constexpr int chunk_size = 16;
// LevelRenderer::LevelRenderer
int a = 512 / chunk_size + 1;
a = a * a * (128 / chunk_size) * 3;
patch_address((void *) 0x4e748, (void *) a);
a *= sizeof(int);
patch_address((void *) 0x4e74c, (void *) a);
// LevelRenderer::allChanged
constexpr int b = 128 / chunk_size;
unsigned char render_chunk_patch_one[] = {(unsigned char) b, 0x20, 0xa0, 0xe3}; // "mov r2, #b"
patch((void *) 0x4fbec, render_chunk_patch_one);
adjust_mov_shift((void *) 0x4fbfc, std::log2(b));
const int c = std::log2(chunk_size);
adjust_mov_shift((void *) 0x4fbf0, c);
adjust_mov_shift((void *) 0x4fc74, c);
adjust_mov_shift((void *) 0x4fd60, c);
adjust_mov_shift((void *) 0x4fd40, c);
unsigned char render_chunk_patch_two[] = {(unsigned char) chunk_size, 0x20, 0xa0, 0xe3}; // "mov r2, #chunk_size"
patch((void *) 0x4fc80, render_chunk_patch_two);
// LevelRenderer::resortChunks
adjust_mov_shift((void *) 0x4f534, c);
constexpr int d = chunk_size / 2;
unsigned char render_chunk_patch_three[] = {(unsigned char) d, 0x10, 0x61, 0xe2}; // "rsb r1, r1, #d"
patch((void *) 0x4f548, render_chunk_patch_three);
adjust_mov_shift((void *) 0x4f58c, c);
unsigned char render_chunk_patch_four[] = {(unsigned char) d, 0x90, 0x63, 0xe2}; // "rsb r9, r3, #d"
patch((void *) 0x4f5d0, render_chunk_patch_four);
adjust_mov_shift((void *) 0x4f5f4, c);
adjust_mov_shift((void *) 0x4f638, c);
unsigned char render_chunk_patch_five[] = {(unsigned char) chunk_size, 0x90, 0x89, 0xe2}; // "add r9, r9, #chunk_size"
patch((void *) 0x4f6c0, render_chunk_patch_five);
unsigned char render_chunk_patch_six[] = {(unsigned char) chunk_size, 0x30, 0x83, 0xe2}; // "add r3, r3, #chunk_size"
patch((void *) 0x4f6ec, render_chunk_patch_six);
// LevelRenderer::setDirty
unsigned char render_chunk_patch_seven[] = {(unsigned char) chunk_size, 0x10, 0xa0, 0xe3}; // "mov r1, #chunk_size"
patch((void *) 0x4f1bc, render_chunk_patch_seven);
patch((void *) 0x4f1cc, render_chunk_patch_seven);
patch((void *) 0x4f1dc, render_chunk_patch_seven);
patch((void *) 0x4f1ec, render_chunk_patch_seven);
patch((void *) 0x4f1fc, render_chunk_patch_seven);
patch((void *) 0x4f20c, render_chunk_patch_seven);
}
// Don't Render Game In Headless Mode // Don't Render Game In Headless Mode
if (reborn_is_headless()) { if (reborn_is_headless()) {
overwrite_calls(GameRenderer_render, nop<GameRenderer_render_t, GameRenderer *, float>); overwrite_calls(GameRenderer_render, nop<GameRenderer_render_t, GameRenderer *, float>);

View File

@ -8,33 +8,19 @@
#include <mods/feature/feature.h> #include <mods/feature/feature.h>
// Print Chat To Log // Print Chat To Log
static bool Gui_addMessage_recursing = false;
static void Gui_addMessage_injection(Gui_addMessage_t original, Gui *gui, const std::string &text) { static void Gui_addMessage_injection(Gui_addMessage_t original, Gui *gui, const std::string &text) {
// Sanitize Message // Sanitize Message
char *new_message = strdup(text.c_str()); char *new_message = strdup(text.c_str());
ALLOC_CHECK(new_message); ALLOC_CHECK(new_message);
sanitize_string(new_message, -1, 1); sanitize_string(new_message, -1, 1);
const std::string cpp_str = new_message;
// Process Message // Print Log Message
if (!Gui_addMessage_recursing) { char *safe_message = from_cp437(new_message);
// Start Recursing fprintf(stderr, "[CHAT]: %s\n", safe_message);
Gui_addMessage_recursing = true; free(safe_message);
// Print Log Message // Call Original Method
char *safe_message = from_cp437(new_message); original(gui, text);
fprintf(stderr, "[CHAT]: %s\n", safe_message);
free(safe_message);
// Call Original Method
original(gui, cpp_str);
// End Recursing
Gui_addMessage_recursing = false;
} else {
// Call Original Method
original(gui, cpp_str);
}
// Free // Free
free(new_message); free(new_message);

View File

@ -406,7 +406,7 @@ static void set_on_fire(Mob *mob, const int seconds) {
} }
} }
template <typename Self> template <typename Self>
static void Monster_aiStep_injection(__attribute__((unused)) std::function<void(Self *)> original, Self *self) { static void Monster_aiStep_injection(__attribute__((unused)) const std::function<void(Self *)> &original, Self *self) {
// Fire! // Fire!
Level *level = self->level; Level *level = self->level;
if (level->isDay() && !level->is_client_side) { if (level->isDay() && !level->is_client_side) {

View File

@ -7,10 +7,12 @@
// Change Grass Color // Change Grass Color
static int32_t get_color(LevelSource *level_source, int32_t x, int32_t z) { static int32_t get_color(LevelSource *level_source, int32_t x, int32_t z) {
// Get Biome
const Biome *biome = level_source->getBiome(x, z); const Biome *biome = level_source->getBiome(x, z);
if (biome == nullptr) { if (biome == nullptr) {
return 0; return 0;
} }
// Return
return biome->color; return biome->color;
} }
#define BIOME_BLEND_SIZE 7 #define BIOME_BLEND_SIZE 7
@ -46,7 +48,7 @@ static int32_t TallGrass_getColor_injection(TallGrass_getColor_t original, TallG
// No Block Tinting // No Block Tinting
template <typename T> template <typename T>
static int32_t Tile_getColor_injection(__attribute__((unused)) std::function<int(T *, LevelSource *, int, int, int)> original, __attribute__((unused)) T *self, __attribute__((unused)) LevelSource *level_source, __attribute__((unused)) int x, __attribute__((unused)) int y, __attribute__((unused)) int z) { static int32_t Tile_getColor_injection(__attribute__((unused)) const std::function<int(T *, LevelSource *, int, int, int)> &original, __attribute__((unused)) T *self, __attribute__((unused)) LevelSource *level_source, __attribute__((unused)) int x, __attribute__((unused)) int y, __attribute__((unused)) int z) {
return 0xffffff; return 0xffffff;
} }

View File

@ -77,7 +77,7 @@ static void Gui_renderChatMessages_injection(Gui_renderChatMessages_t original,
// Render Selected Item Text // Render Selected Item Text
if (render_selected_item_text && !disable_fading) { if (render_selected_item_text && !disable_fading) {
// Fix GL Mode // Fix GL Mode
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); media_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Calculate Selected Item Text Scale // Calculate Selected Item Text Scale
const Minecraft *minecraft = gui->minecraft; const Minecraft *minecraft = gui->minecraft;
const int32_t screen_width = minecraft->screen_width; const int32_t screen_width = minecraft->screen_width;
@ -113,20 +113,20 @@ static void Inventory_selectSlot_injection(Inventory_selectSlot_t original, Inve
// Translucent Toolbar // Translucent Toolbar
static void Gui_renderToolBar_injection(Gui_renderToolBar_t original, Gui *gui, const float param_1, const int32_t param_2, const int32_t param_3) { static void Gui_renderToolBar_injection(Gui_renderToolBar_t original, Gui *gui, const float param_1, const int32_t param_2, const int32_t param_3) {
// Call Original Method // Call Original Method
glEnable(GL_BLEND); media_glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); media_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
original(gui, param_1, param_2, param_3); original(gui, param_1, param_2, param_3);
glDisable(GL_BLEND); media_glDisable(GL_BLEND);
} }
static void Gui_renderToolBar_glColor4f_injection(const GLfloat red, const GLfloat green, const GLfloat blue, __attribute__((unused)) GLfloat alpha) { static void Gui_renderToolBar_glColor4f_injection(const GLfloat red, const GLfloat green, const GLfloat blue, __attribute__((unused)) GLfloat alpha) {
// Fix Alpha // Fix Alpha
glColor4f(red, green, blue, 1.0f); media_glColor4f(red, green, blue, 1.0f);
} }
// Fix Screen Rendering When GUI is Hidden // Fix Screen Rendering When GUI is Hidden
static void Screen_render_injection(Screen_render_t original, Screen *screen, const int32_t param_1, const int32_t param_2, const float param_3) { static void Screen_render_injection(Screen_render_t original, Screen *screen, const int32_t param_1, const int32_t param_2, const float param_3) {
// Fix // Fix
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); media_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Call Original Method // Call Original Method
original(screen, param_1, param_2, param_3); original(screen, param_1, param_2, param_3);
} }
@ -150,9 +150,9 @@ static void GameRenderer_render_injection(GameRenderer_render_t original, GameRe
original(game_renderer, param_1); original(game_renderer, param_1);
// Check If Cursor Should Render // Check If Cursor Should Render
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) { if (media_SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
// Fix GL Mode // Fix GL Mode
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); media_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Get X And Y // Get X And Y
float x = Mouse::getX() * Gui::InvGuiScale; float x = Mouse::getX() * Gui::InvGuiScale;
float y = Mouse::getY() * Gui::InvGuiScale; float y = Mouse::getY() * Gui::InvGuiScale;

View File

@ -8,15 +8,15 @@ Buffer::Buffer(const ssize_t size) {
client_side_data = new unsigned char[size]; client_side_data = new unsigned char[size];
// Server-Side Data // Server-Side Data
server_side_data = 0; server_side_data = 0;
glGenBuffers(1, &server_side_data); media_glGenBuffers(1, &server_side_data);
glBindBuffer(GL_ARRAY_BUFFER, server_side_data); media_glBindBuffer(GL_ARRAY_BUFFER, server_side_data);
glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_DYNAMIC_DRAW); media_glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_DYNAMIC_DRAW);
} }
Buffer::~Buffer() { Buffer::~Buffer() {
// Client-Side Data // Client-Side Data
delete[] client_side_data; delete[] client_side_data;
// Server-Side Data // Server-Side Data
glDeleteBuffers(1, &server_side_data); media_glDeleteBuffers(1, &server_side_data);
} }
// Upload Data // Upload Data
@ -24,6 +24,6 @@ void Buffer::upload(const intptr_t offset, const ssize_t size, const void *data)
// Client-Side Data // Client-Side Data
memcpy(client_side_data + offset, data, size); memcpy(client_side_data + offset, data, size);
// Server-Side Data // Server-Side Data
glBindBuffer(GL_ARRAY_BUFFER, server_side_data); media_glBindBuffer(GL_ARRAY_BUFFER, server_side_data);
glBufferSubData(GL_ARRAY_BUFFER, offset, size, data); media_glBufferSubData(GL_ARRAY_BUFFER, offset, size, data);
} }

View File

@ -22,35 +22,35 @@ static void setup_multidraw(const int chunks, GLuint *buffers) {
buffers[i] = i + MULTIDRAW_BASE; buffers[i] = i + MULTIDRAW_BASE;
} }
} }
HOOK(glDeleteBuffers, void, (GLsizei n, const GLuint *buffers)) { HOOK(media_glDeleteBuffers, void, (GLsizei n, const GLuint *buffers)) {
if (buffers[0] >= MULTIDRAW_BASE) { if (buffers[0] >= MULTIDRAW_BASE) {
delete storage; delete storage;
} else { } else {
real_glDeleteBuffers()(n, buffers); real_media_glDeleteBuffers()(n, buffers);
} }
} }
// Setup Fake OpenGL Buffers // Setup Fake OpenGL Buffers
static int current_chunk = -1; static int current_chunk = -1;
HOOK(glBindBuffer, void, (const GLenum target, GLuint buffer)) { HOOK(media_glBindBuffer, void, (const GLenum target, GLuint buffer)) {
if (target == GL_ARRAY_BUFFER && buffer >= MULTIDRAW_BASE && storage != nullptr) { if (target == GL_ARRAY_BUFFER && buffer >= MULTIDRAW_BASE && storage != nullptr) {
current_chunk = int(buffer - MULTIDRAW_BASE); current_chunk = int(buffer - MULTIDRAW_BASE);
buffer = storage->buffer->server_side_data; buffer = storage->buffer->server_side_data;
} else { } else {
current_chunk = -1; current_chunk = -1;
} }
real_glBindBuffer()(target, buffer); real_media_glBindBuffer()(target, buffer);
} }
HOOK(glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage)) { HOOK(media_glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage)) {
if (target == GL_ARRAY_BUFFER && current_chunk >= 0 && storage != nullptr) { if (target == GL_ARRAY_BUFFER && current_chunk >= 0 && storage != nullptr) {
storage->upload(current_chunk, size, data); storage->upload(current_chunk, size, data);
} else { } else {
real_glBufferData()(target, size, data, usage); real_media_glBufferData()(target, size, data, usage);
} }
} }
// Render // Render
#define VERTEX_SIZE 24 int multidraw_vertex_size = 24;
#define MAX_RENDER_CHUNKS 4096 #define MAX_RENDER_CHUNKS 4096
static bool supports_multidraw() { static bool supports_multidraw() {
static int ret = -1; static int ret = -1;
@ -68,31 +68,31 @@ static void multidraw_renderSameAsLast(const LevelRenderer *self, const float b)
const float x = camera->old_x + ((camera->x - camera->old_x) * b); const float x = camera->old_x + ((camera->x - camera->old_x) * b);
const float y = camera->old_y + ((camera->y - camera->old_y) * b); const float y = camera->old_y + ((camera->y - camera->old_y) * b);
const float z = camera->old_z + ((camera->z - camera->old_z) * b); const float z = camera->old_z + ((camera->z - camera->old_z) * b);
glPushMatrix(); media_glPushMatrix();
glTranslatef(-x, -y, -z); media_glTranslatef(-x, -y, -z);
// Setup OpenGL // Setup OpenGL
glEnableClientState(GL_VERTEX_ARRAY); media_glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY); media_glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); media_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, storage->buffer->server_side_data); media_glBindBuffer(GL_ARRAY_BUFFER, storage->buffer->server_side_data);
glVertexPointer(3, GL_FLOAT, VERTEX_SIZE, (void *) 0); media_glVertexPointer(3, GL_FLOAT, multidraw_vertex_size, (void *) 0);
glTexCoordPointer(2, GL_FLOAT, VERTEX_SIZE, (void *) 0xc); media_glTexCoordPointer(2, GL_FLOAT, multidraw_vertex_size, (void *) 0xc);
glColorPointer(4, GL_UNSIGNED_BYTE, VERTEX_SIZE, (void *) 0x14); media_glColorPointer(4, GL_UNSIGNED_BYTE, multidraw_vertex_size, (void *) 0x14);
// Draw // Draw
if (supports_multidraw()) { if (supports_multidraw()) {
glMultiDrawArrays(GL_TRIANGLES, multidraw_firsts, multidraw_counts, multidraw_total); media_glMultiDrawArrays(GL_TRIANGLES, multidraw_firsts, multidraw_counts, multidraw_total);
} else { } else {
for (int i = 0; i < multidraw_total; i++) { for (int i = 0; i < multidraw_total; i++) {
glDrawArrays(GL_TRIANGLES, multidraw_firsts[i], multidraw_counts[i]); media_glDrawArrays(GL_TRIANGLES, multidraw_firsts[i], multidraw_counts[i]);
} }
} }
// Cleanup // Cleanup
glDisableClientState(GL_COLOR_ARRAY); media_glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); media_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix(); media_glPopMatrix();
} }
static int LevelRenderer_renderChunks_injection(__attribute__((unused)) LevelRenderer_renderChunks_t original, LevelRenderer *self, const int start, const int end, const int a, const float b) { static int LevelRenderer_renderChunks_injection(__attribute__((unused)) LevelRenderer_renderChunks_t original, LevelRenderer *self, const int start, const int end, const int a, const float b) {
// Batch // Batch
@ -110,7 +110,7 @@ static int LevelRenderer_renderChunks_injection(__attribute__((unused)) LevelRen
} }
// Queue // Queue
const int j = multidraw_total++; const int j = multidraw_total++;
multidraw_firsts[j] = block->offset / VERTEX_SIZE; multidraw_firsts[j] = block->offset / multidraw_vertex_size;
multidraw_counts[j] = render_chunk->vertices; multidraw_counts[j] = render_chunk->vertices;
} }
} }

View File

@ -66,7 +66,7 @@ void screenshot_take(Gui *gui) {
// Get Image Size // Get Image Size
GLint viewport[4]; GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport); media_glGetIntegerv(GL_VIEWPORT, viewport);
const int x = viewport[0]; const int x = viewport[0];
const int y = viewport[1]; const int y = viewport[1];
const int width = viewport[2]; const int width = viewport[2];
@ -77,7 +77,7 @@ void screenshot_take(Gui *gui) {
{ {
// Handle Alignment // Handle Alignment
int alignment; int alignment;
glGetIntegerv(GL_PACK_ALIGNMENT, &alignment); media_glGetIntegerv(GL_PACK_ALIGNMENT, &alignment);
// Round // Round
line_size = ALIGN_UP(line_size, alignment); line_size = ALIGN_UP(line_size, alignment);
} }
@ -86,7 +86,7 @@ void screenshot_take(Gui *gui) {
// Read Pixels // Read Pixels
unsigned char *pixels = (unsigned char *) malloc(size); unsigned char *pixels = (unsigned char *) malloc(size);
ALLOC_CHECK(pixels); ALLOC_CHECK(pixels);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); media_glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Save Image // Save Image
if (save_png(file.c_str(), pixels, line_size, width, height)) { if (save_png(file.c_str(), pixels, line_size, width, height)) {

View File

@ -239,7 +239,7 @@ static void handle_server_stop(Minecraft *minecraft) {
// Stop Game // Stop Game
SDL_Event event; SDL_Event event;
event.type = SDL_QUIT; event.type = SDL_QUIT;
SDL_PushEvent(&event); media_SDL_PushEvent(&event);
} }
} }

13
mods/src/shading/init.cpp Normal file
View File

@ -0,0 +1,13 @@
#include <mods/init/init.h>
#include <mods/feature/feature.h>
#include "shading-internal.h"
// Init
void init_shading() {
if (feature_has("Proper Entity Shading", server_disabled)) {
_init_custom_tesselator();
_init_normals();
_init_lighting();
}
}

View File

@ -0,0 +1,127 @@
#include <GLES/gl.h>
#include <symbols/minecraft.h>
#include <libreborn/libreborn.h>
#include "shading-internal.h"
// OpenGL Lighting
static float *get_buffer(const float a, const float b, const float c, const float d) {
static float buffer[4];
buffer[0] = a;
buffer[1] = b;
buffer[2] = c;
buffer[3] = d;
return buffer;
}
static void lighting_turn_on() {
media_glEnable(GL_LIGHTING);
media_glEnable(GL_LIGHT0);
media_glEnable(GL_LIGHT1);
media_glEnable(GL_COLOR_MATERIAL);
media_glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
constexpr float a = 0.4f;
constexpr float d = 0.6f;
constexpr float s = 0.0f;
Vec3 l = Vec3(0.2f, 1.0f, -0.7f).normalized();
media_glLightfv(GL_LIGHT0, GL_POSITION, get_buffer(l.x, l.y, l.z, 0));
media_glLightfv(GL_LIGHT0, GL_DIFFUSE, get_buffer(d, d, d, 1));
media_glLightfv(GL_LIGHT0, GL_AMBIENT, get_buffer(0, 0, 0, 1));
media_glLightfv(GL_LIGHT0, GL_SPECULAR, get_buffer(s, s, s, 1.0f));
l = Vec3(-0.2f, 1.0f, 0.7f).normalized();
media_glLightfv(GL_LIGHT1, GL_POSITION, get_buffer(l.x, l.y, l.z, 0));
media_glLightfv(GL_LIGHT1, GL_DIFFUSE, get_buffer(d, d, d, 1));
media_glLightfv(GL_LIGHT1, GL_AMBIENT, get_buffer(0, 0, 0, 1));
media_glLightfv(GL_LIGHT1, GL_SPECULAR, get_buffer(s, s, s, 1.0f));
media_glShadeModel(GL_FLAT);
media_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, get_buffer(a, a, a, 1));
}
static void lighting_turn_off() {
media_glDisable(GL_LIGHTING);
media_glDisable(GL_LIGHT0);
media_glDisable(GL_LIGHT1);
media_glDisable(GL_COLOR_MATERIAL);
}
// Entity Rendering
static void LevelRenderer_renderEntities_injection(LevelRenderer_renderEntities_t original, LevelRenderer *self, Vec3 pos, void *unknown, float a) {
lighting_turn_on();
original(self, pos, unknown, a);
lighting_turn_off();
}
// Held Items
static void ItemInHandRenderer_render_glPopMatrix_injection() {
lighting_turn_on();
media_glPopMatrix();
media_glEnable(GL_RESCALE_NORMAL);
}
static void ItemInHandRenderer_render_injection(ItemInHandRenderer_render_t original, ItemInHandRenderer *self, float a) {
original(self, a);
lighting_turn_off();
media_glDisable(GL_RESCALE_NORMAL);
}
// GL_RESCALE_NORMAL
static void enable_rescale_normal() {
media_glPushMatrix();
media_glEnable(GL_RESCALE_NORMAL);
}
static void disable_rescale_normal() {
media_glPopMatrix();
media_glDisable(GL_RESCALE_NORMAL);
}
template <typename Self>
static void EntityRenderer_render_injection(const std::function<void(Self *, Entity *, float, float, float, float, float)> &original, Self *self, Entity *entity, float x, float y, float z, float rot, float a) {
media_glEnable(GL_RESCALE_NORMAL);
original(self, entity, x, y, z, rot, a);
media_glDisable(GL_RESCALE_NORMAL);
}
// Fix Falling Tile Rendering
static void FallingTileRenderer_render_TileRenderer_renderBlock_injection(TileRenderer *self, Tile *tile, LevelSource *level, int x, int y, int z) {
media_glDisable(GL_LIGHTING);
self->renderBlock(tile, level, x, y, z);
media_glEnable(GL_LIGHTING);
}
static void TntRenderer_render_TileRenderer_renderTile_injection(TileRenderer *self, Tile *tile, int data) {
media_glDisable(GL_LIGHTING);
self->renderTile(tile, data);
media_glEnable(GL_LIGHTING);
}
// Fix Names
static void MobRenderer_renderNameTag_injection(MobRenderer_renderNameTag_t original, MobRenderer *self, Mob *mob, const std::string &name, const float x, const float y, const float z, const int param_1) {
media_glDisable(GL_LIGHTING);
original(self, mob, name, x, y, z, param_1);
media_glEnable(GL_LIGHTING);
}
// Armor Screen
static void ArmorScreen_renderPlayer_injection(ArmorScreen_renderPlayer_t original, ArmorScreen *self, float param_1, float param_2) {
original(self, param_1, param_2);
lighting_turn_off();
}
static void ArmorScreen_renderPlayer_glRotatef_injection(float angle, float x, float y, float z) {
lighting_turn_on();
media_glRotatef(angle, x, y, z);
}
// Init
void _init_lighting() {
overwrite_calls(LevelRenderer_renderEntities, LevelRenderer_renderEntities_injection);
overwrite_call((void *) 0x4c04c, (void *) ItemInHandRenderer_render_glPopMatrix_injection);
overwrite_calls(ItemInHandRenderer_render, ItemInHandRenderer_render_injection);
overwrite_call((void *) 0x4bedc, (void *) enable_rescale_normal);
overwrite_call((void *) 0x4bf70, (void *) disable_rescale_normal);
overwrite_calls(ItemRenderer_render, EntityRenderer_render_injection<ItemRenderer>);
overwrite_calls(ArrowRenderer_render, EntityRenderer_render_injection<ArrowRenderer>);
overwrite_calls(ItemSpriteRenderer_render, EntityRenderer_render_injection<ItemSpriteRenderer>);
overwrite_calls(PaintingRenderer_render, EntityRenderer_render_injection<PaintingRenderer>);
overwrite_call((void *) 0x641ec, (void *) enable_rescale_normal);
overwrite_call((void *) 0x647a0, (void *) disable_rescale_normal);
overwrite_call((void *) 0x62b08, (void *) FallingTileRenderer_render_TileRenderer_renderBlock_injection);
overwrite_call((void *) 0x65754, (void *) TntRenderer_render_TileRenderer_renderTile_injection);
overwrite_calls(MobRenderer_renderNameTag, MobRenderer_renderNameTag_injection);
overwrite_calls(ArmorScreen_renderPlayer, ArmorScreen_renderPlayer_injection);
overwrite_call((void *) 0x29d88, (void *) ArmorScreen_renderPlayer_glRotatef_injection);
}

View File

@ -0,0 +1,102 @@
#include <symbols/minecraft.h>
#include <libreborn/libreborn.h>
#include "shading-internal.h"
// PolygonQuad
Vec3 vector_to(const Vec3 &a, const Vec3 &b) {
return Vec3(a.x - b.x, a.y - b.y, a.z - b.z);
}
Vec3 vector_cross(const Vec3 &a, const Vec3 &b) {
return Vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
}
static void PolygonQuad_render_injection(PolygonQuad_render_t original, PolygonQuad *self, Tesselator &t, const float scale, const int buffer) {
// Set Normal
const Vec3 v0 = vector_to(self->vertices[1].pos, self->vertices[0].pos);
const Vec3 v1 = vector_to(self->vertices[1].pos, self->vertices[2].pos);
const Vec3 n = vector_cross(v1, v0).normalized();
t.normal(n.x, n.y, n.z);
// Call Original Method
original(self, t, scale, buffer);
}
// Specify Normal Before Vertex
#define add_normal_before(type, name) \
template <int nx, int ny, int nz> \
static decltype(auto) type##_##name##_injection(type *self, auto... args) { \
Tesselator::instance.normal(nx, ny, nz); \
return self->name(std::forward<decltype(args)>(args)...); \
} \
template <int nx, int ny, int nz> \
static void add_normal_before_##name(uint32_t addr) { \
std::remove_pointer_t<decltype(type##_##name)>::ptr_type func = type##_##name##_injection<nx, ny, nz>; \
overwrite_call((void *) addr, (void *) func); \
}
add_normal_before(Tesselator, vertexUV)
add_normal_before(Tesselator, vertex)
add_normal_before(Tile, getTexture2)
add_normal_before(TileRenderer, tesselateCrossTexture)
add_normal_before(Tile, updateDefaultShape)
// Init
void _init_normals() {
// PolygonQuad::render
overwrite_calls(PolygonQuad_render, PolygonQuad_render_injection);
// ItemInHandRenderer::renderItem
add_normal_before_vertexUV<0, 0, 1>(0x4bb4c);
add_normal_before_vertexUV<0, 0, -1>(0x4bbbc);
add_normal_before_vertexUV<-1, 0, 0>(0x4bc50);
add_normal_before_vertexUV<1, 0, 0>(0x4bcf0);
add_normal_before_vertexUV<0, 1, 0>(0x4bd90);
add_normal_before_vertexUV<0, -1, 0>(0x4be28);
// TileRenderer::renderTile
add_normal_before_getTexture2<0, -1, 0>(0x5dd2c);
add_normal_before_getTexture2<0, 1, 0>(0x5dd60);
add_normal_before_getTexture2<0, 0, -1>(0x5dd94);
add_normal_before_getTexture2<0, 0, 1>(0x5ddc8);
add_normal_before_getTexture2<-1, 0, 0>(0x5ddfc);
add_normal_before_getTexture2<1, 0, 0>(0x5de30);
add_normal_before_tesselateCrossTexture<0, -1, 0>(0x5de7c);
add_normal_before_updateDefaultShape<0, -1, 0>(0x5dea0);
add_normal_before_getTexture2<0, -1, 0>(0x5df38);
add_normal_before_getTexture2<0, 1, 0>(0x5df68);
add_normal_before_getTexture2<0, 0, -1>(0x5dfac);
add_normal_before_getTexture2<0, 0, 1>(0x5e004);
add_normal_before_getTexture2<-1, 0, 0>(0x5e05c);
add_normal_before_getTexture2<1, 0, 0>(0x5e0b4);
add_normal_before_getTexture2<0, -1, 0>(0x5e1e4);
add_normal_before_getTexture2<0, 1, 0>(0x5e218);
add_normal_before_getTexture2<0, 0, -1>(0x5e248);
add_normal_before_getTexture2<0, 0, 1>(0x5e278);
add_normal_before_getTexture2<-1, 0, 0>(0x5e2a8);
add_normal_before_getTexture2<1, 0, 0>(0x5e2d8);
add_normal_before_getTexture2<0, -1, 0>(0x5e408);
add_normal_before_getTexture2<0, 1, 0>(0x5e43c);
add_normal_before_getTexture2<0, 0, -1>(0x5e46c);
add_normal_before_getTexture2<0, 0, 1>(0x5e49c);
add_normal_before_getTexture2<-1, 0, 0>(0x5e4cc);
add_normal_before_getTexture2<1, 0, 0>(0x5e4fc);
add_normal_before_getTexture2<0, -1, 0>(0x5e60c);
add_normal_before_getTexture2<0, 1, 0>(0x5e640);
add_normal_before_getTexture2<0, 0, -1>(0x5e670);
add_normal_before_getTexture2<0, 0, 1>(0x5e6a0);
add_normal_before_getTexture2<-1, 0, 0>(0x5e6d0);
add_normal_before_getTexture2<1, 0, 0>(0x5e700);
// ArrowRenderer::render
add_normal_before_vertexUV<1, 0, 0>(0x60184);
add_normal_before_vertexUV<-1, 0, 0>(0x601f4);
add_normal_before_vertexUV<0, 0, 1>(0x60288);
// ItemRenderer::render
add_normal_before_vertexUV<0, 1, 0>(0x63394);
// ItemSpriteRenderer::render
add_normal_before_vertexUV<0, 1, 0>(0x63fd0);
// MobRenderer::renderNameTag
add_normal_before_vertex<0, 1, 0>(0x64918);
// PaintingRenderer::renderPainting
add_normal_before_vertexUV<0, 0, -1>(0x64c94);
add_normal_before_vertexUV<0, 0, 1>(0x64d04);
add_normal_before_vertexUV<0, 1, 0>(0x64d74);
add_normal_before_vertexUV<0, -1, 0>(0x64de4);
add_normal_before_vertexUV<-1, 0, 0>(0x64e54);
add_normal_before_vertexUV<1, 0, 0>(0x64ec4);
}

View File

@ -0,0 +1,5 @@
#pragma once
__attribute__((visibility("internal"))) void _init_custom_tesselator();
__attribute__((visibility("internal"))) void _init_normals();
__attribute__((visibility("internal"))) void _init_lighting();

View File

@ -0,0 +1,203 @@
#include <optional>
#include <cstddef>
#include <algorithm>
#include <GLES/gl.h>
#include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#include <mods/multidraw/multidraw.h>
#include "shading-internal.h"
// Structures
struct UV {
float u;
float v;
};
struct CustomVertex {
Vec3 pos;
UV uv;
GLuint color;
GLuint normal;
};
struct CustomTesselator {
int vertex_count;
CustomVertex *vertices;
std::optional<uint32_t> normal;
int quad_to_triangle_tracker;
static CustomTesselator instance;
};
CustomTesselator CustomTesselator::instance;
// Setup Vertex Array
static void Tesselator_clear_injection(Tesselator_clear_t original, Tesselator *self) {
if (original) {
original(self);
}
CustomTesselator::instance.vertex_count = 0;
CustomTesselator::instance.quad_to_triangle_tracker = 0;
CustomTesselator::instance.normal.reset();
}
#define MAX_VERTICES 524288
static void Tesselator_init_injection(Tesselator_init_t original, Tesselator *self) {
original(self);
CustomTesselator::instance.vertices = new CustomVertex[MAX_VERTICES];
Tesselator_clear_injection(nullptr, nullptr);
}
// Handle Tesselation Start
static void Tesselator_begin_injection(Tesselator_begin_t original, Tesselator *self, const int mode) {
original(self, mode);
if (!self->void_begin_end) {
Tesselator_clear_injection(nullptr, nullptr);
}
}
// Drawing
static GLuint get_next_buffer() {
Tesselator::instance.next_buffer_id++;
Tesselator::instance.next_buffer_id %= Tesselator::instance.buffer_count;
const GLuint out = Tesselator::instance.buffers[Tesselator::instance.next_buffer_id];
return out;
}
static RenderChunk Tesselator_end_injection(Tesselator *self, const bool use_given_buffer, const int buffer) {
// Check
if (!self->active) {
IMPOSSIBLE();
}
RenderChunk out;
out.constructor();
if (self->void_begin_end) {
return out;
}
// Render
out.vertices = CustomTesselator::instance.vertex_count;
if (out.vertices > 0) {
out.buffer = use_given_buffer ? buffer : get_next_buffer();
media_glBindBuffer(GL_ARRAY_BUFFER, out.buffer);
media_glBufferData(GL_ARRAY_BUFFER, out.vertices * sizeof(CustomVertex), CustomTesselator::instance.vertices, GL_STATIC_DRAW);
}
// Finish
self->clear();
self->active = false;
return out;
}
static void Tesselator_draw_injection(Tesselator *self) {
// Check
if (!self->active) {
IMPOSSIBLE();
}
if (self->void_begin_end) {
return;
}
// Render
const int vertices = CustomTesselator::instance.vertex_count;
if (vertices > 0) {
const GLuint buffer = get_next_buffer();
media_glBindBuffer(GL_ARRAY_BUFFER, buffer);
media_glBufferData(GL_ARRAY_BUFFER, vertices * sizeof(CustomVertex), CustomTesselator::instance.vertices, GL_STATIC_DRAW);
if (self->has_texture) {
media_glTexCoordPointer(2, GL_FLOAT, sizeof(CustomVertex), (void *) offsetof(CustomVertex, uv));
media_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (self->has_color) {
media_glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(CustomVertex), (void *) offsetof(CustomVertex, color));
media_glEnableClientState(GL_COLOR_ARRAY);
}
if (CustomTesselator::instance.normal) {
media_glNormalPointer(GL_BYTE, sizeof(CustomVertex), (void *) offsetof(CustomVertex, normal));
media_glEnableClientState(GL_NORMAL_ARRAY);
}
media_glVertexPointer(3, GL_FLOAT, sizeof(CustomVertex), (void *) offsetof(CustomVertex, pos));
media_glEnableClientState(GL_VERTEX_ARRAY);
int mode = self->mode;
if (mode == GL_QUADS) {
mode = GL_TRIANGLES;
}
media_glDrawArrays(mode, 0, vertices);
media_glDisableClientState(GL_VERTEX_ARRAY);
if (self->has_texture) {
media_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (self->has_color) {
media_glDisableClientState(GL_COLOR_ARRAY);
}
if (CustomTesselator::instance.normal) {
media_glDisableClientState(GL_NORMAL_ARRAY);
}
}
// Finish
self->clear();
self->active = false;
}
static void drawArrayVT_injection(const int buffer, const int vertices, int vertex_size, const uint mode) {
vertex_size = sizeof(CustomVertex);
media_glBindBuffer(GL_ARRAY_BUFFER, buffer);
media_glTexCoordPointer(2, GL_FLOAT, vertex_size, (void *) offsetof(CustomVertex, uv));
media_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
media_glVertexPointer(3, GL_FLOAT, vertex_size, (void *) offsetof(CustomVertex, pos));
media_glEnableClientState(GL_VERTEX_ARRAY);
media_glNormalPointer(GL_BYTE, sizeof(CustomVertex), (void *) offsetof(CustomVertex, normal));
media_glEnableClientState(GL_NORMAL_ARRAY);
media_glDrawArrays(mode, 0, vertices);
media_glDisableClientState(GL_VERTEX_ARRAY);
media_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
media_glDisableClientState(GL_NORMAL_ARRAY);
}
// Add Vertex
static void Tesselator_vertex_injection(const Tesselator *self, const float x, const float y, const float z) {
CustomVertex &vertex = CustomTesselator::instance.vertices[CustomTesselator::instance.vertex_count++];
vertex.pos = {
(self->offset_x + x) * self->sx,
(self->offset_y + y) * self->sy,
self->offset_z + z
};
if (self->has_texture) {
vertex.uv = {self->u, self->v};
}
if (self->has_color) {
vertex.color = self->_color;
}
if (CustomTesselator::instance.normal) {
vertex.normal = *CustomTesselator::instance.normal;
}
// Convert To Triangles
if (self->mode == GL_QUADS) {
int &tracker = CustomTesselator::instance.quad_to_triangle_tracker;
if (tracker == 3) {
tracker = 0;
} else {
if (tracker == 2) {
const int last_vertex = CustomTesselator::instance.vertex_count - 1;
for (const int i : {-2, 0}) {
CustomTesselator::instance.vertices[CustomTesselator::instance.vertex_count++] = CustomTesselator::instance.vertices[last_vertex + i];
}
}
tracker++;
}
}
}
// Specify Normal
static void Tesselator_normal_injection(__attribute__((unused)) Tesselator *self, const float nx, const float ny, const float nz) {
const signed char xx = (signed char) (nx * 127);
const signed char yy = (signed char) (ny * 127);
const signed char zz = (signed char) (nz * 127);
CustomTesselator::instance.normal = xx | (yy << 8) | (zz << 16);
}
// Init
void _init_custom_tesselator() {
multidraw_vertex_size = sizeof(CustomVertex);
overwrite_calls(Tesselator_init, Tesselator_init_injection);
overwrite_calls(Tesselator_clear, Tesselator_clear_injection);
overwrite_calls(Tesselator_begin, Tesselator_begin_injection);
overwrite_call((void *) Tesselator_end->backup, (void *) Tesselator_end_injection, true);
overwrite_call((void *) Tesselator_draw->backup, (void *) Tesselator_draw_injection, true);
overwrite_call((void *) Tesselator_vertex->backup, (void *) Tesselator_vertex_injection, true);
overwrite_call((void *) Tesselator_normal->backup, (void *) Tesselator_normal_injection, true);
overwrite_call((void *) Common_drawArrayVT->backup, (void *) drawArrayVT_injection, true);
}

View File

@ -42,10 +42,10 @@ static void load_pending_skins(__attribute__((unused)) Minecraft *minecraft) {
// Load Texture // Load Texture
GLint last_texture; GLint last_texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); media_glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
glBindTexture(GL_TEXTURE_2D, skin.texture_id); media_glBindTexture(GL_TEXTURE_2D, skin.texture_id);
glTexSubImage2D_with_scaling(GL_TEXTURE_2D, 0, 0, 0, width, height, SKIN_WIDTH, SKIN_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, img); media_glTexSubImage2D_with_scaling(GL_TEXTURE_2D, 0, 0, 0, width, height, SKIN_WIDTH, SKIN_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, img);
glBindTexture(GL_TEXTURE_2D, last_texture); media_glBindTexture(GL_TEXTURE_2D, last_texture);
// Free // Free
stbi_image_free(img); stbi_image_free(img);

View File

@ -26,7 +26,7 @@ static void Minecraft_tick_injection(const Minecraft *minecraft) {
// Store Texture Sizes // Store Texture Sizes
struct texture_data { struct texture_data {
GLint id; GLuint id;
GLsizei width; GLsizei width;
GLsizei height; GLsizei height;
}; };
@ -34,21 +34,21 @@ static std::vector<texture_data> &get_texture_data() {
static std::vector<texture_data> data; static std::vector<texture_data> data;
return data; return data;
} }
HOOK(glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) { HOOK(media_glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) {
// Store // Store
texture_data data = {}; texture_data data = {};
glGetIntegerv(GL_TEXTURE_BINDING_2D, &data.id); media_glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &data.id);
data.width = width; data.width = width;
data.height = height; data.height = height;
get_texture_data().push_back(data); get_texture_data().push_back(data);
// Call Original Method // Call Original Method
real_glTexImage2D()(target, level, internalformat, width, height, border, format, type, pixels); real_media_glTexImage2D()(target, level, internalformat, width, height, border, format, type, pixels);
} }
HOOK(glDeleteTextures, void, (GLsizei n, const GLuint *textures)) { HOOK(media_glDeleteTextures, void, (GLsizei n, const GLuint *textures)) {
// Remove Old Data // Remove Old Data
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
const GLint id = textures[i]; const GLuint id = textures[i];
std::vector<texture_data>::iterator it = get_texture_data().begin(); std::vector<texture_data>::iterator it = get_texture_data().begin();
while (it != get_texture_data().end()) { while (it != get_texture_data().end()) {
const texture_data data = *it; const texture_data data = *it;
@ -61,9 +61,9 @@ HOOK(glDeleteTextures, void, (GLsizei n, const GLuint *textures)) {
} }
// Call Original Method // Call Original Method
real_glDeleteTextures()(n, textures); real_media_glDeleteTextures()(n, textures);
} }
static void get_texture_size(const GLint id, GLsizei *width, GLsizei *height) { static void get_texture_size(const GLuint id, GLsizei *width, GLsizei *height) {
// Iterate // Iterate
std::vector<texture_data>::iterator it = get_texture_data().begin(); std::vector<texture_data>::iterator it = get_texture_data().begin();
while (it != get_texture_data().end()) { while (it != get_texture_data().end()) {
@ -88,7 +88,7 @@ static int get_line_size(const int width) {
{ {
// Handle Alignment // Handle Alignment
int alignment; int alignment;
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); media_glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
// Round // Round
line_size = ALIGN_UP(line_size, alignment); line_size = ALIGN_UP(line_size, alignment);
} }
@ -123,10 +123,10 @@ static void *scale_texture(const unsigned char *src, const GLsizei old_width, co
} }
// Scale Animated Textures // Scale Animated Textures
void glTexSubImage2D_with_scaling(const GLenum target, const GLint level, const GLint xoffset, const GLint yoffset, const GLsizei width, const GLsizei height, const GLsizei normal_texture_width, const GLsizei normal_texture_height, const GLenum format, const GLenum type, const void *pixels) { void media_glTexSubImage2D_with_scaling(const GLenum target, const GLint level, const GLint xoffset, const GLint yoffset, const GLsizei width, const GLsizei height, const GLsizei normal_texture_width, const GLsizei normal_texture_height, const GLenum format, const GLenum type, const void *pixels) {
// Get Current Texture Size // Get Current Texture Size
GLint current_texture; GLint current_texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture); media_glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
GLsizei texture_width; GLsizei texture_width;
GLsizei texture_height; GLsizei texture_height;
get_texture_size(current_texture, &texture_width, &texture_height); get_texture_size(current_texture, &texture_width, &texture_height);
@ -138,7 +138,7 @@ void glTexSubImage2D_with_scaling(const GLenum target, const GLint level, const
// Only Scale If Needed // Only Scale If Needed
if (width_factor == 1.0f && height_factor == 1.0f) { if (width_factor == 1.0f && height_factor == 1.0f) {
// No Scaling // No Scaling
glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); media_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
} else { } else {
// Check // Check
if (format != GL_RGBA || type != GL_UNSIGNED_BYTE) { if (format != GL_RGBA || type != GL_UNSIGNED_BYTE) {
@ -154,14 +154,14 @@ void glTexSubImage2D_with_scaling(const GLenum target, const GLint level, const
// Call Original Method // Call Original Method
const GLint new_xoffset = xoffset * width_factor; const GLint new_xoffset = xoffset * width_factor;
const GLint new_yoffset = yoffset * height_factor; const GLint new_yoffset = yoffset * height_factor;
glTexSubImage2D(target, level, new_xoffset, new_yoffset, new_width, new_height, format, type, new_pixels); media_glTexSubImage2D(target, level, new_xoffset, new_yoffset, new_width, new_height, format, type, new_pixels);
// Free // Free
free(new_pixels); free(new_pixels);
} }
} }
static void Textures_tick_glTexSubImage2D_injection(const GLenum target, const GLint level, const GLint xoffset, const GLint yoffset, const GLsizei width, const GLsizei height, const GLenum format, const GLenum type, const void *pixels) { static void Textures_tick_glTexSubImage2D_injection(const GLenum target, const GLint level, const GLint xoffset, const GLint yoffset, const GLsizei width, const GLsizei height, const GLenum format, const GLenum type, const void *pixels) {
glTexSubImage2D_with_scaling(target, level, xoffset, yoffset, width, height, 256, 256, format, type, pixels); media_glTexSubImage2D_with_scaling(target, level, xoffset, yoffset, width, height, 256, 256, format, type, pixels);
} }
// Load Textures // Load Textures

View File

@ -107,24 +107,24 @@ static bool draw_splash(StartMenuScreen *screen, const float y_factor, const boo
splash_width *= multiplier; splash_width *= multiplier;
} }
// Position // Position
glPushMatrix(); media_glPushMatrix();
glTranslatef(x, y, 0.0f); media_glTranslatef(x, y, 0.0f);
// Rotate // Rotate
glRotatef(SplashLine::angle, 0.0f, 0.0f, 1.0f); media_glRotatef(SplashLine::angle, 0.0f, 0.0f, 1.0f);
// Oscillate // Oscillate
const float timeMS = float(Common::getTimeMs() % 1000) / 1000.0f; const float timeMS = float(Common::getTimeMs() % 1000) / 1000.0f;
const float oscillation = (scale / SplashLine::max_scale) * 0.1f; const float oscillation = (scale / SplashLine::max_scale) * 0.1f;
scale = scale - Mth::abs(oscillation * Mth::sin(2.0f * float(M_PI) * timeMS)); scale = scale - Mth::abs(oscillation * Mth::sin(2.0f * float(M_PI) * timeMS));
// Scale // Scale
glTranslatef(splash_width / 2.0f, 0, 0); media_glTranslatef(splash_width / 2.0f, 0, 0);
glScalef(scale, scale, 1); media_glScalef(scale, scale, 1);
glTranslatef(-text_width / 2.0f, 0, 0); media_glTranslatef(-text_width / 2.0f, 0, 0);
// Render // Render
float y_offset = float(-line_height) / 2.0f; float y_offset = float(-line_height) / 2.0f;
y_offset += 1; // Make It Look Vertically Centered y_offset += 1; // Make It Look Vertically Centered
screen->drawString(screen->font, current_splash, 0, y_offset, 0xffff00); screen->drawString(screen->font, current_splash, 0, y_offset, 0xffff00);
// Finish // Finish
glPopMatrix(); media_glPopMatrix();
return true; return true;
} }
static void StartMenuScreen_render_injection(StartMenuScreen_render_t original, StartMenuScreen *screen, const int mouse_x, const int mouse_y, const float param_1) { static void StartMenuScreen_render_injection(StartMenuScreen_render_t original, StartMenuScreen *screen, const int mouse_x, const int mouse_y, const float param_1) {

View File

@ -110,7 +110,7 @@ static void StartMenuScreen_render_Screen_renderBackground_injection(StartMenuSc
constexpr int w = modern_title_width / 2; constexpr int w = modern_title_width / 2;
constexpr int h = modern_title_height; constexpr int h = modern_title_height;
Tesselator& t = Tesselator::instance; Tesselator& t = Tesselator::instance;
glColor4f(1, 1, 1, 1); media_glColor4f(1, 1, 1, 1);
t.begin(7); t.begin(7);
t.vertexUV(x - w, y + h, self->z, 0, 1); t.vertexUV(x - w, y + h, self->z, 0, 1);
t.vertexUV(x + w, y + h, self->z, 1, 1); t.vertexUV(x + w, y + h, self->z, 1, 1);

View File

@ -68,7 +68,7 @@ run_build() {
# Test Dependencies # Test Dependencies
run_test() { run_test() {
sudo apt-get install --no-install-recommends -y \ install_pkg \
"libc6:$1" \ "libc6:$1" \
"libstdc++6:$1" \ "libstdc++6:$1" \
"libopenal1:$1" \ "libopenal1:$1" \

View File

@ -35,7 +35,7 @@ set(SRC
src/entity/EntityRenderer.def src/entity/EntityRenderer.def
src/entity/ItemSpriteRenderer.def src/entity/ItemSpriteRenderer.def
src/entity/PathfinderMob.def src/entity/PathfinderMob.def
src/entity/HumanoidModel.def src/entity/model/HumanoidModel.def
src/entity/TripodCameraRenderer.def src/entity/TripodCameraRenderer.def
src/entity/TripodCamera.def src/entity/TripodCamera.def
src/entity/MobFactory.def src/entity/MobFactory.def
@ -63,6 +63,8 @@ set(SRC
src/entity/Entity.def src/entity/Entity.def
src/entity/ItemEntity.def src/entity/ItemEntity.def
src/entity/Arrow.def src/entity/Arrow.def
src/entity/ArrowRenderer.def
src/entity/PaintingRenderer.def
src/entity/Throwable.def src/entity/Throwable.def
src/level/container/FillingContainer.def src/level/container/FillingContainer.def
src/level/container/Container.def src/level/container/Container.def
@ -125,6 +127,7 @@ set(SRC
src/gui/screens/Touch_SelectWorldScreen.def src/gui/screens/Touch_SelectWorldScreen.def
src/gui/screens/PaneCraftingScreen.def src/gui/screens/PaneCraftingScreen.def
src/gui/screens/ScreenChooser.def src/gui/screens/ScreenChooser.def
src/gui/screens/ArmorScreen.def
src/gui/Font.def src/gui/Font.def
src/gui/components/ImageButton.def src/gui/components/ImageButton.def
src/gui/components/OptionButton.def src/gui/components/OptionButton.def
@ -162,7 +165,9 @@ set(SRC
src/misc/Strings.def src/misc/Strings.def
src/misc/I18n.def src/misc/I18n.def
src/misc/SimpleFoodData.def src/misc/SimpleFoodData.def
src/entity/ModelPart.def src/entity/model/ModelPart.def
src/entity/model/PolygonQuad.def
src/entity/model/VertexPT.def
src/misc/Tesselator.def src/misc/Tesselator.def
src/misc/AABB.def src/misc/AABB.def
src/misc/Vec3.def src/misc/Vec3.def

View File

@ -0,0 +1,3 @@
extends EntityRenderer;
vtable 0x1075e0;

View File

@ -1,5 +1,7 @@
extends EntityRenderer; extends EntityRenderer;
vtable 0x107e18;
size 0x10; size 0x10;
constructor (int texture) = 0x64078; constructor (int texture) = 0x64078;

View File

@ -11,6 +11,7 @@ virtual-method void updateAi() = 0x1cc;
virtual-method float getWalkingSpeedModifier() = 0x1e8; virtual-method float getWalkingSpeedModifier() = 0x1e8;
virtual-method void aiStep() = 0x180; virtual-method void aiStep() = 0x180;
virtual-method int getMaxHealth() = 0x168; virtual-method int getMaxHealth() = 0x168;
virtual-method bool isBaby() = 0x1a8;
method bool getSharedFlag(int flag) = 0x81fd8; method bool getSharedFlag(int flag) = 0x81fd8;
method void setSharedFlag(int flag, bool value) = 0x81ef8; method void setSharedFlag(int flag, bool value) = 0x81ef8;

View File

@ -1 +1,5 @@
extends EntityRenderer; extends EntityRenderer;
vtable 0x107e58;
virtual-method void renderNameTag(Mob *mob, const std::string &name, float x, float y, float z, int param_1) = 0x34;

View File

@ -0,0 +1,3 @@
extends EntityRenderer;
vtable 0x107eb8;

View File

@ -0,0 +1,3 @@
method void render(Tesselator &t, float scale, int buffer) = 0x42744;
property VertexPT vertices[4] = 0x0;

View File

@ -0,0 +1,7 @@
size 0x14;
property Vec3 pos = 0x0;
property float u = 0xc;
property float v = 0x10;
mark-as-simple;

View File

@ -0,0 +1,3 @@
extends Screen;
method void renderPlayer(float param_1, float param_2) = 0x29cd0;

View File

@ -15,6 +15,7 @@ virtual-method float getCreatureProbability() = 0x20;
property int color = 0x2c; property int color = 0x2c;
property int leaf_color = 0x34; property int leaf_color = 0x34;
property std::string name = 0x28;
// This is a Biome*[64x64], temp x humidity // This is a Biome*[64x64], temp x humidity
static-property Biome *map[4096] = 0x17c970; static-property Biome *map[4096] = 0x17c970;

View File

@ -6,6 +6,7 @@ method void generateSky() = 0x4d0d4;
method void renderHitSelect(Player *player, const HitResult &hit_result, int i, void *vp, float f) = 0x4e318; method void renderHitSelect(Player *player, const HitResult &hit_result, int i, void *vp, float f) = 0x4e318;
method void renderHitOutline(Player *player, const HitResult &hit_result, int i, void *vp, float f) = 0x4dc14; method void renderHitOutline(Player *player, const HitResult &hit_result, int i, void *vp, float f) = 0x4dc14;
method int renderChunks(int start, int end, int a, float b) = 0x4f35c; method int renderChunks(int start, int end, int a, float b) = 0x4f35c;
method void renderEntities(Vec3 pos, void *unknown, float a) = 0x500ec;
property Minecraft *minecraft = 0xb4; property Minecraft *minecraft = 0xb4;
property RenderList render_list = 0x34; property RenderList render_list = 0x34;

View File

@ -1,7 +1,10 @@
size 0x18; size 0x18;
constructor () = 0x525ac;
property uint buffer = 0x0; property uint buffer = 0x0;
property int vertices = 0x4; property int vertices = 0x4;
property float x = 0xc; property int id = 0x8;
property float y = 0x10; property Vec3 pos = 0xc;
property float z = 0x14;
mark-as-simple;

View File

@ -7,3 +7,4 @@ static-method int sdl_key_to_minecraft_key(int sdl_key) = 0x1243c;
static-method void anGenBuffers(int count, uint *buffers) = 0x5f28c; static-method void anGenBuffers(int count, uint *buffers) = 0x5f28c;
static-method int getTimeMs() = 0x13cd4; static-method int getTimeMs() = 0x13cd4;
static-method int getEpochTimeS() = 0x13d00; static-method int getEpochTimeS() = 0x13d00;
static-method void drawArrayVT(int buffer, int vertices, int vertex_size, uint mode) = 0x5f2cc;

View File

@ -1,9 +1,53 @@
method void init() = 0x5289c;
method void clear() = 0x528ac;
method void begin(int mode) = 0x529d4; method void begin(int mode) = 0x529d4;
method void begin_quads() = 0x52a24;
method RenderChunk end(bool use_given_buffer, int buffer) = 0x528d4;
method void draw() = 0x52e08; method void draw() = 0x52e08;
method void voidBeginAndEndCalls(bool x) = 0x52f74;
method void colorABGR(int color) = 0x52b54; method void colorABGR(int color) = 0x52b54;
method void color(int r, int g, int b, int a) = 0x52a48; method void color(int r, int g, int b, int a) = 0x52a48;
method void noColor() = 0x52d54;
method void enableColor() = 0x52f7c;
method void vertex(float x, float y, float z) = 0x52bc0; method void vertex(float x, float y, float z) = 0x52bc0;
method void tex(float u, float v) = 0x52a2c;
method void vertexUV(float x, float y, float z, float u, float v) = 0x52d40; method void vertexUV(float x, float y, float z, float u, float v) = 0x52d40;
method void scale2d(float sx, float sy) = 0x52b94;
method void resetScale() = 0x52bb0;
method void normal(float nx, float ny, float nz) = 0x52d68;
method void offset(float x, float y, float z) = 0x52d80;
method void addOffset(float x, float y, float z) = 0x52d90; method void addOffset(float x, float y, float z) = 0x52d90;
method void offset_vec3(const Vec3 &x) = 0x52db8;
method void addOffset_vec3(const Vec3 &x) = 0x52dd4;
property bool active = 0x3c;
property int mode = 0x58;
property int next_buffer_id = 0x44;
property uint *buffers = 0x48;
property int buffer_count = 0x40;
property float offset_x = 0x8;
property float offset_y = 0xc;
property float offset_z = 0x10;
property bool has_texture = 0x2d;
property float u = 0x14;
property float v = 0x18;
property bool has_color = 0x2c;
property uint _color = 0x1c;
property float sx = 0x24;
property float sy = 0x28;
property bool void_begin_end = 0x30;
static-property Tesselator instance = 0x137538; static-property Tesselator instance = 0x137538;

View File

@ -1,5 +1,7 @@
size 0xc; size 0xc;
method Vec3 normalized() = 0x5eae4;
property float x = 0x0; property float x = 0x0;
property float y = 0x4; property float y = 0x4;
property float z = 0x8; property float z = 0x8;

View File

@ -1,6 +1,7 @@
method void tick(bool param_1) = 0x531c4; method void tick(bool param_1) = 0x531c4;
method int loadAndBindTexture(const std::string &name) = 0x539cc; method uint loadAndBindTexture(const std::string &name) = 0x539cc;
method int assignTexture(const std::string &name, uchar *data) = 0x5354c; method uint loadTexture(const std::string &name, bool param_1) = 0x53800;
method uint assignTexture(const std::string &name, uchar *data) = 0x5354c;
method void addDynamicTexture(DynamicTexture *texture) = 0x534f8; method void addDynamicTexture(DynamicTexture *texture) = 0x534f8;
method Texture *getTemporaryTextureData(uint id) = 0x53168; method Texture *getTemporaryTextureData(uint id) = 0x53168;

View File

@ -9,5 +9,7 @@ method bool tesselateInWorld(Tile *tile, int x, int y, int z) = 0x5e80c;
method void renderGuiTile(Tile *tile, int aux) = 0x5ad0c; method void renderGuiTile(Tile *tile, int aux) = 0x5ad0c;
method void renderTile(Tile *tile, int data) = 0x5dcb0; method void renderTile(Tile *tile, int data) = 0x5dcb0;
method void tesselateTorch(Tile *tile, float x, float y, float z, float top_x, float top_z) = 0x54254; method void tesselateTorch(Tile *tile, float x, float y, float z, float top_x, float top_z) = 0x54254;
method void tesselateCrossTexture(Tile *tile, int data, float x, float y, float z) = 0x547cc;
method void renderBlock(Tile *tile, LevelSource *level, int x, int y, int z) = 0x59540;
property LevelSource *level = 0x0; property LevelSource *level = 0x0;