2.2.0
This commit is contained in:
parent
a762654e35
commit
d851a8f3e1
@ -115,6 +115,11 @@ if(BUILD_NATIVE_COMPONENTS)
|
|||||||
add_subdirectory(launcher)
|
add_subdirectory(launcher)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Include Symbols
|
||||||
|
if(BUILD_ARM_COMPONENTS)
|
||||||
|
add_subdirectory(symbols)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Build Mods
|
# Build Mods
|
||||||
if(BUILD_ARM_COMPONENTS)
|
if(BUILD_ARM_COMPONENTS)
|
||||||
add_subdirectory(mods)
|
add_subdirectory(mods)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
FROM debian:bullseye
|
FROM debian:bullseye-slim
|
||||||
|
|
||||||
# Copy DEB
|
# Copy DEB
|
||||||
ADD ./out/minecraft-pi-reborn-server_*~bullseye_amd64.deb /root
|
ADD ./out/minecraft-pi-reborn-server_*_amd64.deb /root
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
RUN \
|
RUN \
|
||||||
|
2
debian/client-arm
vendored
2
debian/client-arm
vendored
@ -4,4 +4,4 @@ Maintainer: TheBrokenRail <connor24nolan@live.com>
|
|||||||
Description: Fun with Blocks
|
Description: Fun with Blocks
|
||||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||||
Architecture: armhf
|
Architecture: armhf
|
||||||
Depends: libc6, libstdc++6, zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3
|
Depends: libc6, libstdc++6, zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3, libopenal1
|
||||||
|
2
debian/client-arm64
vendored
2
debian/client-arm64
vendored
@ -4,4 +4,4 @@ Maintainer: TheBrokenRail <connor24nolan@live.com>
|
|||||||
Description: Fun with Blocks
|
Description: Fun with Blocks
|
||||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||||
Architecture: arm64
|
Architecture: arm64
|
||||||
Depends: libc6, libstdc++6, libc6:armhf, libstdc++6:armhf, zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3
|
Depends: libc6, libstdc++6, libc6:armhf, libstdc++6:armhf, zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3, libopenal1
|
||||||
|
2
debian/client-x86_64
vendored
2
debian/client-x86_64
vendored
@ -4,4 +4,4 @@ Maintainer: TheBrokenRail <connor24nolan@live.com>
|
|||||||
Description: Fun with Blocks
|
Description: Fun with Blocks
|
||||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Depends: libc6, libstdc++6, libc6-armhf-cross, libstdc++6-armhf-cross, zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3, qemu-user-static
|
Depends: libc6, libstdc++6, libc6-armhf-cross, libstdc++6-armhf-cross, zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3, libopenal1, qemu-user-static
|
||||||
|
@ -36,6 +36,7 @@ This sub-component re-implements a subset of SDL 1.2 calls with GLFW. It also pr
|
|||||||
The utility functions include:
|
The utility functions include:
|
||||||
* Taking Screenshots
|
* Taking Screenshots
|
||||||
* Fullscreen
|
* Fullscreen
|
||||||
|
* Audio
|
||||||
* Etc
|
* Etc
|
||||||
|
|
||||||
This is always compiled for the host system's architecture.
|
This is always compiled for the host system's architecture.
|
||||||
@ -87,17 +88,20 @@ This component contains various utility functions including:
|
|||||||
|
|
||||||
* Code Patching (ARM Only)
|
* Code Patching (ARM Only)
|
||||||
* Logging
|
* Logging
|
||||||
* MCPI Symbols
|
|
||||||
* Etc
|
* Etc
|
||||||
|
|
||||||
The code patching is ARM only because it relies on hard-coded ARM instructions. However, this is irrelevant since code patching is only needed in ARM code (to patch MCPI).
|
The code patching is ARM only because it relies on hard-coded ARM instructions. However, this is irrelevant since code patching is only needed in ARM code (to patch MCPI).
|
||||||
|
|
||||||
|
### ``symbols``
|
||||||
|
This component contains all MCPI symbols.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
MCPI-Reborn has several dependencies:
|
MCPI-Reborn has several dependencies:
|
||||||
* MCPI (Bundled)
|
* MCPI (Bundled)
|
||||||
* GLFW (Only In Client Mode)
|
* GLFW (Only In Client Mode)
|
||||||
* Open GL ES 1.1
|
* Open GL ES 1.1
|
||||||
* EGL
|
* EGL
|
||||||
|
* OpenAL (Only In Client Mode)
|
||||||
* ZLib (Required By LibPNG; Bundled)
|
* ZLib (Required By LibPNG; Bundled)
|
||||||
* LibPNG (Bundled)
|
* LibPNG (Bundled)
|
||||||
* FreeImage (Only In Client Mode)
|
* FreeImage (Only In Client Mode)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
* Client Mode Only
|
* Client Mode Only
|
||||||
* GLFW
|
* GLFW
|
||||||
* FreeImage
|
* FreeImage
|
||||||
|
* OpenAL
|
||||||
|
|
||||||
## Runtime Dependencies
|
## Runtime Dependencies
|
||||||
* Non-ARM Host Architectures
|
* Non-ARM Host Architectures
|
||||||
@ -33,6 +34,7 @@
|
|||||||
* OpenGL ES 1.1
|
* OpenGL ES 1.1
|
||||||
* GLFW
|
* GLFW
|
||||||
* FreeImage
|
* FreeImage
|
||||||
|
* OpenAL
|
||||||
* Zenity
|
* Zenity
|
||||||
|
|
||||||
## Two-Step Build
|
## Two-Step Build
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
**2.2.0**
|
||||||
|
* Sound Support
|
||||||
|
* Split Off "Allow Joining Survival Servers" From Game-Mode Mod
|
||||||
|
* Separate Headless Code From Server Code
|
||||||
|
* Fix Bug Where `RakNetInstance` Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
|
||||||
|
* Clean-Up Code
|
||||||
|
* Remove Support For Debian Buster
|
||||||
|
|
||||||
**2.1.8**
|
**2.1.8**
|
||||||
* Fix Crash On ARM Systems
|
* Fix Crash On ARM Systems
|
||||||
|
|
||||||
|
@ -1,25 +1,21 @@
|
|||||||
# Manual Installation
|
# Manual Installation
|
||||||
[Download Packages Here](https://jenkins.thebrokenrail.com/job/minecraft-pi-reborn/job/master/lastSuccessfulBuild/artifact/out/)
|
[Download Packages Here](https://jenkins.thebrokenrail.com/job/minecraft-pi-reborn/job/master/lastSuccessfulBuild/artifact/out/)
|
||||||
|
|
||||||
|
## Supported Distributions
|
||||||
|
* Ubuntu 20.04+
|
||||||
|
* Debian Bullseye+
|
||||||
|
|
||||||
## Picking A Package
|
## Picking A Package
|
||||||
|
|
||||||
### Name Format
|
### Name Format
|
||||||
```
|
```
|
||||||
minecraft-pi-reborn-<Variant>_X.Y.Z~<Distribution>_<Architecture>
|
minecraft-pi-reborn-<Variant>_X.Y.Z_<Architecture>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Picking A Variant
|
### Picking A Variant
|
||||||
* ``client``: Client mode, use this if you want to play MCPI
|
* ``client``: Client mode, use this if you want to play MCPI
|
||||||
* ``server``: Server mode, use this if you want to host a dedicated MCPI server
|
* ``server``: Server mode, use this if you want to host a dedicated MCPI server
|
||||||
|
|
||||||
### Picking A Distribution
|
|
||||||
This specifies which version of Debian MCPI-Reborn was built against. Which one you should use depends on your current distribution. If your distribution supports it, you should use ``bullseye`` for better mouse sensitivity.
|
|
||||||
|
|
||||||
* Ubuntu 20.04+: ``bullseye``
|
|
||||||
* Raspberry Pi OS Buster: ``buster``
|
|
||||||
* Debian Bullseye+: ``bullseye``
|
|
||||||
* Debian Buster: ``buster``
|
|
||||||
|
|
||||||
### Picking An Architecture
|
### Picking An Architecture
|
||||||
* ``amd64``: x86_64, use this if you are using a device with an AMD or Intel processor
|
* ``amd64``: x86_64, use this if you are using a device with an AMD or Intel processor
|
||||||
* ``armhf``: ARM 32-Bit, use this if you are using an ARM device (like a Raspberry Pi)
|
* ``armhf``: ARM 32-Bit, use this if you are using an ARM device (like a Raspberry Pi)
|
||||||
|
@ -8,4 +8,5 @@
|
|||||||
* [View Architecture](ARCHITECTURE.md)
|
* [View Architecture](ARCHITECTURE.md)
|
||||||
* [View Command Line Arguments](COMMAND_LINE.md)
|
* [View Command Line Arguments](COMMAND_LINE.md)
|
||||||
* [View Multiplayer](MULTIPLAYER.md)
|
* [View Multiplayer](MULTIPLAYER.md)
|
||||||
|
* [View Sound](SOUND.md)
|
||||||
* [View Changelog](CHANGELOG.md)
|
* [View Changelog](CHANGELOG.md)
|
||||||
|
7
docs/SOUND.md
Normal file
7
docs/SOUND.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Sound
|
||||||
|
One of MCPI-Reborn's main modifications is a sound-engine since MCPI doesn't include one by default[^1]. However, it can't be used out-of-box because MCPI doesn't contain any sound data and MCPI-Reborn can't include it because of copyright.
|
||||||
|
|
||||||
|
MCPE's sound data can be extracted from any MCPE v0.6.1[^2] APK file, just place its `libminecraftpe.so` into `~/.minecraft-pi/overrides` and you should have sound!
|
||||||
|
|
||||||
|
[^1]: The mute button is just leftover code from MCPE, it doesn't actually do anything in un-modded MCPI, however it is connected to MCPI-Reborn's sound-engine.
|
||||||
|
[^2]: This isn't a hard limit, an MCPE v0.8.1 APK would probably work, but don't rely on it.
|
@ -2,6 +2,7 @@
|
|||||||
| Name | Description |
|
| Name | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| MCPI | Shorthand for Minecraft: Pi Edition |
|
| MCPI | Shorthand for Minecraft: Pi Edition |
|
||||||
|
| MCPE | Shorthand for Minecraft: Pocket Edition |
|
||||||
| Host Architecture | The native architecture of the CPU that MCPi-Reborn will be running on |
|
| Host Architecture | The native architecture of the CPU that MCPi-Reborn will be running on |
|
||||||
| Native Component | A component that *can* be compiled for the host architecture |
|
| Native Component | A component that *can* be compiled for the host architecture |
|
||||||
| ARM Component | A component that *must* be compiled for ARM |
|
| ARM Component | A component that *must* be compiled for ARM |
|
||||||
|
BIN
images/start.png
BIN
images/start.png
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@ -25,3 +25,4 @@ TRUE Bind Common Toggleable Options To Function Keys
|
|||||||
TRUE Render Selected Item Text
|
TRUE Render Selected Item Text
|
||||||
TRUE External Server Support
|
TRUE External Server Support
|
||||||
TRUE Load Language Files
|
TRUE Load Language Files
|
||||||
|
TRUE Implement Sound Engine
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#define FORCE_PROC_FOR_ROOT_PATH
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
#include "bootstrap.h"
|
#include "bootstrap.h"
|
||||||
@ -190,14 +189,6 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
setenv("QEMU_LD_PREFIX", "/usr/arm-linux-gnueabihf", 1);
|
setenv("QEMU_LD_PREFIX", "/usr/arm-linux-gnueabihf", 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Select Executable Interpreter
|
|
||||||
#ifdef __ARM_ARCH
|
|
||||||
#define EXE_INTERPRETER "/lib/ld-linux-armhf.so.3"
|
|
||||||
#else
|
|
||||||
// Use Static QEMU So It Isn't Affected By LD_* Variables
|
|
||||||
#define EXE_INTERPRETER "qemu-arm-static"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Create Full Path
|
// Create Full Path
|
||||||
char *full_path = NULL;
|
char *full_path = NULL;
|
||||||
safe_asprintf(&full_path, "%s/" MCPI_NAME, binary_directory);
|
safe_asprintf(&full_path, "%s/" MCPI_NAME, binary_directory);
|
||||||
@ -205,6 +196,14 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
// Free Binary Directory
|
// Free Binary Directory
|
||||||
free(binary_directory);
|
free(binary_directory);
|
||||||
|
|
||||||
|
#ifdef __ARM_ARCH
|
||||||
|
// Mark argc As Used
|
||||||
|
(void) argc;
|
||||||
|
// Run
|
||||||
|
safe_execvpe(full_path, argv, environ);
|
||||||
|
#else
|
||||||
|
// Use Static QEMU So It Isn't Affected By LD_* Variables
|
||||||
|
#define EXE_INTERPRETER "qemu-arm-static"
|
||||||
// Create Arguments List
|
// Create Arguments List
|
||||||
char *new_argv[argc + 2];
|
char *new_argv[argc + 2];
|
||||||
for (int i = 1; i <= argc; i++) {
|
for (int i = 1; i <= argc; i++) {
|
||||||
@ -214,4 +213,5 @@ void bootstrap(int argc, char *argv[]) {
|
|||||||
new_argv[1] = full_path; // Path To MCPI
|
new_argv[1] = full_path; // Path To MCPI
|
||||||
// Run
|
// Run
|
||||||
safe_execvpe(EXE_INTERPRETER, new_argv, environ);
|
safe_execvpe(EXE_INTERPRETER, new_argv, environ);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ target_include_directories(reborn-headers INTERFACE include)
|
|||||||
if(BUILD_ARM_COMPONENTS)
|
if(BUILD_ARM_COMPONENTS)
|
||||||
add_library(reborn SHARED src/reborn.c)
|
add_library(reborn SHARED src/reborn.c)
|
||||||
target_link_libraries(reborn dl reborn-headers)
|
target_link_libraries(reborn dl reborn-headers)
|
||||||
|
target_compile_definitions(reborn PUBLIC -DREBORN_HAS_COMPILED_CODE)
|
||||||
# Install
|
# Install
|
||||||
install(TARGETS reborn DESTINATION "${MCPI_LIB_DIR}")
|
install(TARGETS reborn DESTINATION "${MCPI_LIB_DIR}")
|
||||||
endif()
|
endif()
|
||||||
|
@ -4,53 +4,46 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
|
#include <link.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
|
|
||||||
// Find And Iterate Over All .text Sections In Current Binary
|
// Find And Iterate Over All .text Sections In Current Binary
|
||||||
typedef void (*text_section_callback_t)(Elf32_Addr section, Elf32_Word size, void *data);
|
typedef void (*text_section_callback_t)(ElfW(Addr) section, ElfW(Word) size, void *data);
|
||||||
static inline void iterate_text_sections(text_section_callback_t callback, void *data) {
|
static inline void iterate_text_sections(text_section_callback_t callback, void *data) {
|
||||||
// Find Main Binary
|
|
||||||
char *real_path = NULL;
|
|
||||||
{
|
|
||||||
char *binary_directory = get_binary_directory();
|
|
||||||
safe_asprintf(&real_path, "%s/minecraft-pi", binary_directory);
|
|
||||||
free(binary_directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load Main Binary
|
// Load Main Binary
|
||||||
FILE *file_obj = fopen(real_path, "rb");
|
FILE *file_obj = fopen("/proc/self/exe", "rb");
|
||||||
|
|
||||||
// Verify Binary
|
// Verify Binary
|
||||||
if (!file_obj) {
|
if (!file_obj) {
|
||||||
ERR("Unable To Open Binary: %s", real_path);
|
ERR("%s", "Unable To Open Current Binary");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get File Size
|
// Get File Size
|
||||||
fseek(file_obj, 0L, SEEK_END);
|
fseek(file_obj, 0L, SEEK_END);
|
||||||
long int size = ftell(file_obj);
|
long int file_size = ftell(file_obj);
|
||||||
fseek(file_obj, 0L, SEEK_SET);
|
fseek(file_obj, 0L, SEEK_SET);
|
||||||
|
|
||||||
// Map File To Pointer
|
// Map File To Pointer
|
||||||
unsigned char *file_map = (unsigned char *) mmap(0, size, PROT_READ, MAP_PRIVATE, fileno(file_obj), 0);
|
unsigned char *file_map = (unsigned char *) mmap(0, file_size, PROT_READ, MAP_PRIVATE, fileno(file_obj), 0);
|
||||||
|
|
||||||
// Parse ELF
|
// Parse ELF
|
||||||
Elf32_Ehdr *elf_header = (Elf32_Ehdr *) file_map;
|
ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_map;
|
||||||
Elf32_Shdr *elf_section_headers = (Elf32_Shdr *) (file_map + elf_header->e_shoff);
|
ElfW(Shdr) *elf_section_headers = (ElfW(Shdr) *) (file_map + elf_header->e_shoff);
|
||||||
int elf_section_header_count = elf_header->e_shnum;
|
int elf_section_header_count = elf_header->e_shnum;
|
||||||
|
|
||||||
// Locate Section Names
|
// Locate Section Names
|
||||||
Elf32_Shdr elf_strtab = elf_section_headers[elf_header->e_shstrndx];
|
ElfW(Shdr) elf_shstrtab = elf_section_headers[elf_header->e_shstrndx];
|
||||||
unsigned char *elf_strtab_p = file_map + elf_strtab.sh_offset;
|
unsigned char *elf_shstrtab_p = file_map + elf_shstrtab.sh_offset;
|
||||||
|
|
||||||
// Track .text Sections
|
// Track .text Sections
|
||||||
int text_sections = 0;
|
int text_sections = 0;
|
||||||
|
|
||||||
// Iterate Sections
|
// Iterate Sections
|
||||||
for (int i = 0; i < elf_section_header_count; ++i) {
|
for (int i = 0; i < elf_section_header_count; ++i) {
|
||||||
Elf32_Shdr header = elf_section_headers[i];
|
ElfW(Shdr) header = elf_section_headers[i];
|
||||||
char *name = (char *) (elf_strtab_p + header.sh_name);
|
char *name = (char *) (elf_shstrtab_p + header.sh_name);
|
||||||
// Check Section Type
|
// Check Section Type
|
||||||
if (strcmp(name, ".text") == 0) {
|
if (strcmp(name, ".text") == 0) {
|
||||||
// .text Section
|
// .text Section
|
||||||
@ -61,13 +54,10 @@ static inline void iterate_text_sections(text_section_callback_t callback, void
|
|||||||
|
|
||||||
// Ensure At Least .text Section Was Scanned
|
// Ensure At Least .text Section Was Scanned
|
||||||
if (text_sections < 1) {
|
if (text_sections < 1) {
|
||||||
ERR("Unable To Find .text Sectons On: %s", real_path);
|
ERR("%s", "Unable To Find .text Sectons");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free Binary Path
|
|
||||||
free(real_path);
|
|
||||||
|
|
||||||
// Unmap And Close File
|
// Unmap And Close File
|
||||||
munmap(file_map, size);
|
munmap(file_map, file_size);
|
||||||
fclose(file_obj);
|
fclose(file_obj);
|
||||||
}
|
}
|
||||||
|
@ -21,15 +21,6 @@ __attribute__((noreturn)) static inline void safe_execvpe(const char *pathname,
|
|||||||
}
|
}
|
||||||
// Get Binary Directory (Remember To Free)
|
// Get Binary Directory (Remember To Free)
|
||||||
static inline char *get_binary_directory() {
|
static inline char *get_binary_directory() {
|
||||||
#ifndef FORCE_PROC_FOR_ROOT_PATH
|
|
||||||
{
|
|
||||||
// Check Environment
|
|
||||||
char *specified_root = getenv("MCPI_ROOT_PATH");
|
|
||||||
if (specified_root != NULL) {
|
|
||||||
return strdup(specified_root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// Get Path To Current Executable
|
// Get Path To Current Executable
|
||||||
char *exe = realpath("/proc/self/exe", NULL);
|
char *exe = realpath("/proc/self/exe", NULL);
|
||||||
ALLOC_CHECK(exe);
|
ALLOC_CHECK(exe);
|
||||||
@ -43,9 +34,6 @@ static inline char *get_binary_directory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Environment
|
|
||||||
setenv("MCPI_ROOT_PATH", exe, 1);
|
|
||||||
|
|
||||||
// Return
|
// Return
|
||||||
return exe;
|
return exe;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ extern "C" {
|
|||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
|
||||||
#ifdef __arm__
|
#ifdef REBORN_HAS_COMPILED_CODE
|
||||||
|
|
||||||
// Patching Functions
|
// Patching Functions
|
||||||
|
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
// Logging
|
// Logging
|
||||||
#define INFO(format, ...) { fprintf(stderr, "[INFO]: " format "\n", __VA_ARGS__); }
|
#define INFO(format, ...) { fprintf(stderr, "[INFO]: " format "\n", __VA_ARGS__); }
|
||||||
#define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", __VA_ARGS__); }
|
#define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", __VA_ARGS__); }
|
||||||
#define ERR(format, ...) { fprintf(stderr, "[ERR]: " format "\n", __VA_ARGS__); exit(EXIT_FAILURE); }
|
#define ERR(format, ...) { fprintf(stderr, "[ERR]: (%s:%i): " format "\n", __FILE__, __LINE__, __VA_ARGS__); exit(EXIT_FAILURE); }
|
||||||
#define IMPOSSIBLE() ERR("(%s:%i) This Should Never Be Called", __FILE__, __LINE__)
|
#define IMPOSSIBLE() ERR("%s", "This Should Never Be Called")
|
||||||
|
@ -44,7 +44,7 @@ struct overwrite_data {
|
|||||||
void *replacement;
|
void *replacement;
|
||||||
int found;
|
int found;
|
||||||
};
|
};
|
||||||
static void overwrite_calls_callback(Elf32_Addr section_addr, Elf32_Word size, void *data) {
|
static void overwrite_calls_callback(ElfW(Addr) section_addr, ElfW(Word) size, void *data) {
|
||||||
struct overwrite_data *args = (struct overwrite_data *) data;
|
struct overwrite_data *args = (struct overwrite_data *) data;
|
||||||
void *section = (void *) section_addr;
|
void *section = (void *) section_addr;
|
||||||
|
|
||||||
@ -122,12 +122,14 @@ void _overwrite_calls(const char *file, int line, void *start, void *target) {
|
|||||||
// Increment Code Block Position
|
// Increment Code Block Position
|
||||||
increment_code_block();
|
increment_code_block();
|
||||||
|
|
||||||
|
// Check
|
||||||
if (data.found < 1) {
|
if (data.found < 1) {
|
||||||
ERR("(%s:%i) Unable To Find Callsites For 0x%08x", file, line, (uint32_t) start);
|
ERR("(%s:%i) Unable To Find Callsites For 0x%08x", file, line, (uint32_t) start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overwrite Function
|
// Overwrite Function
|
||||||
|
// NOTE: "start" Must Be At Least 8 Bytes Long
|
||||||
void _overwrite(const char *file, int line, void *start, void *target) {
|
void _overwrite(const char *file, int line, void *start, void *target) {
|
||||||
unsigned char patch_data[4] = {0x04, 0xf0, 0x1f, 0xe5}; // "ldr pc, [pc, #-0x4]"
|
unsigned char patch_data[4] = {0x04, 0xf0, 0x1f, 0xe5}; // "ldr pc, [pc, #-0x4]"
|
||||||
|
|
||||||
|
@ -2,6 +2,9 @@ project(media-layer-core)
|
|||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
set(CORE_SRC src/base.cpp src/media.c src/screenshot.c) # SDL Re-Implementation Using GLFW
|
set(CORE_SRC src/base.cpp src/media.c src/screenshot.c) # SDL Re-Implementation Using GLFW
|
||||||
|
if(NOT MCPI_HEADLESS_MODE)
|
||||||
|
list(APPEND CORE_SRC src/audio/api.cpp src/audio/engine.c src/audio/file.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
if(MCPI_USE_MEDIA_LAYER_PROXY AND BUILD_NATIVE_COMPONENTS)
|
if(MCPI_USE_MEDIA_LAYER_PROXY AND BUILD_NATIVE_COMPONENTS)
|
||||||
@ -23,8 +26,10 @@ if(TARGET media-layer-core)
|
|||||||
find_package(glfw3 3.3 REQUIRED)
|
find_package(glfw3 3.3 REQUIRED)
|
||||||
# Find FreeImage
|
# Find FreeImage
|
||||||
find_library(FREEIMAGE_LIBRARY NAMES freeimage libfreeimage.so.3 REQUIRED)
|
find_library(FREEIMAGE_LIBRARY NAMES freeimage libfreeimage.so.3 REQUIRED)
|
||||||
# Not Needed In Server Mode
|
# OpenAL
|
||||||
target_link_libraries(media-layer-core "${FREEIMAGE_LIBRARY}" GLESv1_CM glfw)
|
find_library(OPENAL_LIBRARY NAMES openal REQUIRED)
|
||||||
|
# Link
|
||||||
|
target_link_libraries(media-layer-core "${FREEIMAGE_LIBRARY}" "${OPENAL_LIBRARY}" m GLESv1_CM glfw)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
104
media-layer/core/src/audio/api.cpp
Normal file
104
media-layer/core/src/audio/api.cpp
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
|
||||||
|
#include <media-layer/audio.h>
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "file.h"
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
|
// Store Audio Sources
|
||||||
|
static std::vector<ALuint> &get_sources() {
|
||||||
|
static std::vector<ALuint> sources;
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define AL_ERROR_CHECK() \
|
||||||
|
{ \
|
||||||
|
ALenum err = alGetError(); \
|
||||||
|
if (err != AL_NO_ERROR) { \
|
||||||
|
ERR("OpenAL Error: %s", alGetString(err)); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Listener
|
||||||
|
void media_audio_update(float volume, float x, float y, float z, float yaw) {
|
||||||
|
// Update Listener Volume
|
||||||
|
alListenerf(AL_GAIN, volume);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
|
||||||
|
// Update Listener Position
|
||||||
|
alListener3f(AL_POSITION, x, y, z);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
|
||||||
|
// Update Listener Orientation
|
||||||
|
float radian_yaw = yaw * (M_PI / 180);
|
||||||
|
ALfloat orientation[] = {-sinf(radian_yaw), 0.0f, cosf(radian_yaw), 0.0f, 1.0f, 0.0f};
|
||||||
|
alListenerfv(AL_ORIENTATION, orientation);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
|
||||||
|
// Clear Finished Sources
|
||||||
|
std::vector<ALuint>::iterator it = get_sources().begin();
|
||||||
|
while (it != get_sources().end()) {
|
||||||
|
ALuint source = *it;
|
||||||
|
// Check
|
||||||
|
ALint source_state;
|
||||||
|
alGetSourcei(source, AL_SOURCE_STATE, &source_state);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
if (source_state != AL_PLAYING) {
|
||||||
|
// Finished
|
||||||
|
it = get_sources().erase(it);
|
||||||
|
alDeleteSources(1, &source);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
} else {
|
||||||
|
// Still Playing
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void media_audio_play(const char *source, const char *name, float x, float y, float z, float pitch, float volume, int is_ui) {
|
||||||
|
// Load Sound
|
||||||
|
ALuint buffer = _media_audio_get_buffer(source, name);
|
||||||
|
if (buffer) {
|
||||||
|
// Create Source
|
||||||
|
ALuint al_source;
|
||||||
|
alGenSources(1, &al_source);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
|
||||||
|
// Set Properties
|
||||||
|
alSourcef(al_source, AL_PITCH, pitch);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
alSourcef(al_source, AL_GAIN, volume);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
alSource3f(al_source, AL_POSITION, x, y, z);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
alSource3f(al_source, AL_VELOCITY, 0, 0, 0);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
alSourcei(al_source, AL_LOOPING, AL_FALSE);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
alSourcei(al_source, AL_SOURCE_RELATIVE, is_ui ? AL_TRUE : AL_FALSE);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
|
||||||
|
// Set Attenuation
|
||||||
|
alSourcei(al_source, AL_DISTANCE_MODEL, AL_LINEAR_DISTANCE);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
alSourcef(al_source, AL_MAX_DISTANCE, 16.0f);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
alSourcef(al_source, AL_ROLLOFF_FACTOR, 1.0f);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
alSourcef(al_source, AL_REFERENCE_DISTANCE, 0.0f);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
|
||||||
|
// Set Buffer
|
||||||
|
alSourcei(al_source, AL_BUFFER, buffer);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
|
||||||
|
// Play
|
||||||
|
alSourcePlay(al_source);
|
||||||
|
AL_ERROR_CHECK();
|
||||||
|
get_sources().push_back(al_source);
|
||||||
|
}
|
||||||
|
}
|
85
media-layer/core/src/audio/engine.c
Normal file
85
media-layer/core/src/audio/engine.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
#include <AL/alext.h>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "engine.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
// Store Device
|
||||||
|
static ALCdevice *device = NULL;
|
||||||
|
static ALCcontext *context = NULL;
|
||||||
|
|
||||||
|
// Store State
|
||||||
|
static int is_loaded = 0;
|
||||||
|
int _media_audio_is_loaded() {
|
||||||
|
return is_loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init
|
||||||
|
void _media_audio_init() {
|
||||||
|
// Open Device
|
||||||
|
device = alcOpenDevice(NULL);
|
||||||
|
if (!device) {
|
||||||
|
WARN("%s", "Unable To Load Audio Engine");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Context
|
||||||
|
context = alcCreateContext(device, NULL);
|
||||||
|
ALCenum err = alcGetError(device);
|
||||||
|
if (err != ALC_NO_ERROR) {
|
||||||
|
ERR("Unable To Open Audio Context: %s", alcGetString(device, err));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select Context
|
||||||
|
alcMakeContextCurrent(context);
|
||||||
|
err = alcGetError(device);
|
||||||
|
if (err != ALC_NO_ERROR) {
|
||||||
|
ERR("Unable To Select Audio Context: %s", alcGetString(device, err));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable AL_SOURCE_DISTANCE_MODEL
|
||||||
|
alEnable(AL_SOURCE_DISTANCE_MODEL);
|
||||||
|
ALenum al_err = alGetError();
|
||||||
|
if (al_err != AL_NO_ERROR) {
|
||||||
|
ERR("Unable To Enable AL_SOURCE_DISTANCE_MODEL: %s", alGetString(al_err));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log
|
||||||
|
INFO("%s", "Loaded Audio Engine");
|
||||||
|
is_loaded = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Init
|
||||||
|
void _media_audio_cleanup() {
|
||||||
|
if (_media_audio_is_loaded()) {
|
||||||
|
// Delete Audio Buffers
|
||||||
|
_media_audio_delete_buffers();
|
||||||
|
|
||||||
|
// Deselect Context
|
||||||
|
alcMakeContextCurrent(NULL);
|
||||||
|
ALCenum err = alcGetError(device);
|
||||||
|
if (err != ALC_NO_ERROR) {
|
||||||
|
ERR("Unable To Deselect Audio Context: %s", alcGetString(device, err));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy Context
|
||||||
|
alcDestroyContext(context);
|
||||||
|
err = alcGetError(device);
|
||||||
|
if (err != ALC_NO_ERROR) {
|
||||||
|
ERR("Unable To Destroy Audio Context: %s", alcGetString(device, err));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close Device
|
||||||
|
alcCloseDevice(device);
|
||||||
|
err = alcGetError(device);
|
||||||
|
if (err != ALC_NO_ERROR) {
|
||||||
|
ERR("Unable To Close Audio Device: %s", alcGetString(device, err));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log
|
||||||
|
INFO("%s", "Unloaded Audio Engine");
|
||||||
|
}
|
||||||
|
}
|
15
media-layer/core/src/audio/engine.h
Normal file
15
media-layer/core/src/audio/engine.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__attribute__((visibility("internal"))) void _media_audio_init();
|
||||||
|
__attribute__((visibility("internal"))) void _media_audio_cleanup();
|
||||||
|
__attribute__((visibility("internal"))) int _media_audio_is_loaded();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
241
media-layer/core/src/audio/file.cpp
Normal file
241
media-layer/core/src/audio/file.cpp
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <elf.h>
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "file.h"
|
||||||
|
#include "engine.h"
|
||||||
|
|
||||||
|
// Load Symbol From ELF File
|
||||||
|
static void load_symbol(const char *source, const char *name, std::function<void(unsigned char *, uint32_t)> callback) {
|
||||||
|
// File Data
|
||||||
|
FILE *file_obj = NULL;
|
||||||
|
unsigned char *file_map = NULL;
|
||||||
|
long int file_size = 0;
|
||||||
|
|
||||||
|
// Code
|
||||||
|
{
|
||||||
|
// Load Main Binary
|
||||||
|
file_obj = fopen(source, "rb");
|
||||||
|
|
||||||
|
// Verify Binary
|
||||||
|
if (!file_obj) {
|
||||||
|
WARN("Unable To Open: %s", source);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get File Size
|
||||||
|
fseek(file_obj, 0L, SEEK_END);
|
||||||
|
file_size = ftell(file_obj);
|
||||||
|
fseek(file_obj, 0L, SEEK_SET);
|
||||||
|
|
||||||
|
// Map File To Pointer
|
||||||
|
file_map = (unsigned char *) mmap(0, file_size, PROT_READ, MAP_PRIVATE, fileno(file_obj), 0);
|
||||||
|
|
||||||
|
// Check ELF Magic
|
||||||
|
if (file_map[EI_MAG0] != ELFMAG0 || file_map[EI_MAG1] != ELFMAG1 || file_map[EI_MAG2] != ELFMAG2 || file_map[EI_MAG3] != ELFMAG3) {
|
||||||
|
WARN("Not An ELF File: %s", source);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (file_map[EI_CLASS] != ELFCLASS32) {
|
||||||
|
WARN("ELF File Isn't 32-Bit: %s", source);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (file_map[EI_DATA] != ELFDATA2LSB) {
|
||||||
|
WARN("ELF File Isn't Little-Endian: %s", source);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse ELF
|
||||||
|
Elf32_Ehdr *elf_header = (Elf32_Ehdr *) file_map;
|
||||||
|
Elf32_Shdr *elf_section_headers = (Elf32_Shdr *) (file_map + elf_header->e_shoff);
|
||||||
|
int elf_section_header_count = elf_header->e_shnum;
|
||||||
|
|
||||||
|
// Locate Section Names
|
||||||
|
Elf32_Shdr elf_shstrtab = elf_section_headers[elf_header->e_shstrndx];
|
||||||
|
unsigned char *elf_shstrtab_p = file_map + elf_shstrtab.sh_offset;
|
||||||
|
|
||||||
|
// Locate String Table
|
||||||
|
unsigned char *elf_strtab_p = NULL;
|
||||||
|
for (int i = 0; i < elf_section_header_count; ++i) {
|
||||||
|
Elf32_Shdr header = elf_section_headers[i];
|
||||||
|
// Check Section Type
|
||||||
|
if (header.sh_type == SHT_STRTAB) {
|
||||||
|
// Check Section Name
|
||||||
|
char *section_name = (char *) (elf_shstrtab_p + header.sh_name);
|
||||||
|
if (strcmp(section_name, ".dynstr") == 0) {
|
||||||
|
// Found
|
||||||
|
elf_strtab_p = file_map + header.sh_offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (elf_strtab_p == NULL) {
|
||||||
|
WARN("Unable To Find String Table In: %s", source);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locate Symbol Tables
|
||||||
|
Elf32_Sym *symbol = NULL;
|
||||||
|
for (int i = 0; i < elf_section_header_count; ++i) {
|
||||||
|
// Exit Loop If Finished
|
||||||
|
if (symbol != NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Get Section Header
|
||||||
|
Elf32_Shdr header = elf_section_headers[i];
|
||||||
|
// Check Section Type
|
||||||
|
if (header.sh_type == SHT_DYNSYM) {
|
||||||
|
// Symbol Table
|
||||||
|
Elf32_Sym *table = (Elf32_Sym *) (file_map + header.sh_offset);
|
||||||
|
for (int j = 0; (j * sizeof (Elf32_Sym)) < header.sh_size; j++) {
|
||||||
|
// Check Symbol Name
|
||||||
|
char *symbol_name = (char *) (elf_strtab_p + table[j].st_name);
|
||||||
|
if (strcmp(symbol_name, name) == 0) {
|
||||||
|
// Found
|
||||||
|
symbol = &table[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Symbol
|
||||||
|
if (symbol != NULL) {
|
||||||
|
// Convert Virtual Address To File Offset
|
||||||
|
Elf32_Shdr symbol_section_header = elf_section_headers[symbol->st_shndx];
|
||||||
|
int vaddr_to_offset = -symbol_section_header.sh_addr + symbol_section_header.sh_offset;
|
||||||
|
Elf32_Off symbol_offset = symbol->st_value + vaddr_to_offset;
|
||||||
|
// Access Symbol
|
||||||
|
unsigned char *value = file_map + symbol_offset;
|
||||||
|
uint32_t size = symbol->st_size;
|
||||||
|
callback(value, size);
|
||||||
|
} else {
|
||||||
|
// Unable To Find Symbol
|
||||||
|
WARN("Unable To Find Symbol: %s", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
// Unmap And Close File
|
||||||
|
if (file_map != NULL) {
|
||||||
|
munmap(file_map, file_size);
|
||||||
|
}
|
||||||
|
if (file_obj != NULL) {
|
||||||
|
fclose(file_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio Metadata
|
||||||
|
struct audio_metadata {
|
||||||
|
int32_t channels;
|
||||||
|
int32_t frame_size;
|
||||||
|
int32_t sample_rate;
|
||||||
|
int32_t frames;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Load Sound Symbol Into ALunit
|
||||||
|
static ALuint load_sound(const char *source, const char *name) {
|
||||||
|
// Check OpenAL
|
||||||
|
if (!_media_audio_is_loaded()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store Result
|
||||||
|
ALuint buffer = 0;
|
||||||
|
|
||||||
|
// Load Symbol
|
||||||
|
load_symbol(source, name, [name, &buffer](unsigned char *symbol, uint32_t size) {
|
||||||
|
// Load Metadata
|
||||||
|
if (size < sizeof (audio_metadata)) {
|
||||||
|
WARN("Symbol Too Small To Contain Audio Metadata: %s", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
audio_metadata *meta = (audio_metadata *) symbol;
|
||||||
|
|
||||||
|
// Check Frame Size
|
||||||
|
if (meta->frame_size != 1 && meta->frame_size != 2) {
|
||||||
|
WARN("Unsupported Frame Size: %s: %i", name, meta->frame_size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Audio Format
|
||||||
|
ALenum format = AL_NONE;
|
||||||
|
if (meta->channels == 1) {
|
||||||
|
format = meta->frame_size == 2 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8;
|
||||||
|
} else if (meta->channels == 2) {
|
||||||
|
format = meta->frame_size == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO8;
|
||||||
|
} else {
|
||||||
|
WARN("Unsupported Channel Count: %s: %i", name, meta->channels);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load Data
|
||||||
|
int remaining_size = size - sizeof (audio_metadata);
|
||||||
|
int data_size = meta->channels * meta->frames * meta->frame_size;
|
||||||
|
if (remaining_size < data_size) {
|
||||||
|
WARN("Symbol Too Small To Contain Specified Audio Data: %s", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsigned char *data = symbol + sizeof (audio_metadata);
|
||||||
|
|
||||||
|
// Create Buffer
|
||||||
|
alGenBuffers(1, &buffer);
|
||||||
|
alBufferData(buffer, format, data, data_size, meta->sample_rate);
|
||||||
|
|
||||||
|
// Check OpenAL Error
|
||||||
|
ALenum err = alGetError();
|
||||||
|
if (err != AL_NO_ERROR) {
|
||||||
|
WARN("Unable To Store Audio Buffer: %s", alGetString(err));
|
||||||
|
if (buffer && alIsBuffer(buffer)) {
|
||||||
|
alDeleteBuffers(1, &buffer);
|
||||||
|
}
|
||||||
|
buffer = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store Buffers
|
||||||
|
static std::unordered_map<std::string, ALuint> &get_buffers() {
|
||||||
|
static std::unordered_map<std::string, ALuint> buffers;
|
||||||
|
return buffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Buffer For Sound
|
||||||
|
ALuint _media_audio_get_buffer(const char *source, const char *name) {
|
||||||
|
// Check
|
||||||
|
if (_media_audio_is_loaded()) {
|
||||||
|
if (get_buffers().count(name) > 0) {
|
||||||
|
// Return
|
||||||
|
return get_buffers()[name];
|
||||||
|
} else {
|
||||||
|
// Load And Return
|
||||||
|
get_buffers()[name] = load_sound(source, name);
|
||||||
|
return _media_audio_get_buffer(source, name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete Buffers
|
||||||
|
void _media_audio_delete_buffers() {
|
||||||
|
if (_media_audio_is_loaded()) {
|
||||||
|
for (auto it : get_buffers()) {
|
||||||
|
if (it.second && alIsBuffer(it.second)) {
|
||||||
|
alDeleteBuffers(1, &it.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get_buffers().clear();
|
||||||
|
}
|
14
media-layer/core/src/audio/file.h
Normal file
14
media-layer/core/src/audio/file.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AL/al.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__attribute__((visibility("internal"))) ALuint _media_audio_get_buffer(const char *source, const char *name);
|
||||||
|
__attribute__((visibility("internal"))) void _media_audio_delete_buffers();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
#include <libreborn/media-layer/internal.h>
|
#include <media-layer/internal.h>
|
||||||
|
|
||||||
// SDL Is Replaced With GLFW
|
// SDL Is Replaced With GLFW
|
||||||
|
|
||||||
|
@ -9,10 +9,12 @@
|
|||||||
#endif // #ifndef MCPI_HEADLESS_MODE
|
#endif // #ifndef MCPI_HEADLESS_MODE
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
#include <libreborn/media-layer/internal.h>
|
#include <media-layer/internal.h>
|
||||||
|
|
||||||
// GLFW Code Not Needed In Server Mode
|
#include "audio/engine.h"
|
||||||
|
|
||||||
|
// GLFW Code Not Needed In Headless Mode
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
|
|
||||||
static GLFWwindow *glfw_window;
|
static GLFWwindow *glfw_window;
|
||||||
@ -196,10 +198,14 @@ static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute_
|
|||||||
|
|
||||||
#endif // #ifndef MCPI_HEADLESS_MODE
|
#endif // #ifndef MCPI_HEADLESS_MODE
|
||||||
|
|
||||||
// Init GLFW
|
// Track Media Layer State
|
||||||
|
static int is_running = 0;
|
||||||
|
|
||||||
|
// Init Media Layer
|
||||||
void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *icon) {
|
void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *icon) {
|
||||||
// Don't Enable GLFW In Server Mode
|
// Don't Enable GLFW In Headless Mode
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
|
// Init GLFW
|
||||||
glfwSetErrorCallback(glfw_error);
|
glfwSetErrorCallback(glfw_error);
|
||||||
|
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
@ -221,7 +227,7 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
|
|||||||
ERR("%s", "Unable To Create GLFW Window");
|
ERR("%s", "Unable To Create GLFW Window");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't Process Events In Server Mode
|
// Don't Process Events In Headless Mode
|
||||||
glfwSetKeyCallback(glfw_window, glfw_key);
|
glfwSetKeyCallback(glfw_window, glfw_key);
|
||||||
glfwSetCharCallback(glfw_window, glfw_char);
|
glfwSetCharCallback(glfw_window, glfw_char);
|
||||||
glfwSetCursorPosCallback(glfw_window, glfw_motion);
|
glfwSetCursorPosCallback(glfw_window, glfw_motion);
|
||||||
@ -229,9 +235,15 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
|
|||||||
glfwSetScrollCallback(glfw_window, glfw_scroll);
|
glfwSetScrollCallback(glfw_window, glfw_scroll);
|
||||||
|
|
||||||
glfwMakeContextCurrent(glfw_window);
|
glfwMakeContextCurrent(glfw_window);
|
||||||
|
|
||||||
|
// Init OpenAL
|
||||||
|
_media_audio_init();
|
||||||
#else // #ifndef MCPI_HEADLESS_MODE
|
#else // #ifndef MCPI_HEADLESS_MODE
|
||||||
(void) title; // Mark As Used
|
(void) title; // Mark As Used
|
||||||
#endif // #ifndef MCPI_HEADLESS_MODE
|
#endif // #ifndef MCPI_HEADLESS_MODE
|
||||||
|
|
||||||
|
// Set State
|
||||||
|
is_running = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void media_swap_buffers() {
|
void media_swap_buffers() {
|
||||||
@ -241,7 +253,7 @@ void media_swap_buffers() {
|
|||||||
#endif // #ifndef MCPI_HEADLESS_MODE
|
#endif // #ifndef MCPI_HEADLESS_MODE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fullscreen Not Needed In Server Mode
|
// Fullscreen Not Needed In Headless Mode
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
static int is_fullscreen = 0;
|
static int is_fullscreen = 0;
|
||||||
|
|
||||||
@ -278,7 +290,7 @@ void media_toggle_fullscreen() {
|
|||||||
|
|
||||||
// Intercept SDL Events
|
// Intercept SDL Events
|
||||||
void _media_handle_SDL_PollEvent() {
|
void _media_handle_SDL_PollEvent() {
|
||||||
// GLFW Is Disabled In Server Mode
|
// GLFW And Audio Are Disabled Disabled In Headless Mode
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
// Process GLFW Events
|
// Process GLFW Events
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
@ -293,13 +305,22 @@ void _media_handle_SDL_PollEvent() {
|
|||||||
#endif // #ifndef MCPI_HEADLESS_MODE
|
#endif // #ifndef MCPI_HEADLESS_MODE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terminate GLFW
|
// Cleanup Media Layer
|
||||||
void media_cleanup() {
|
void media_cleanup() {
|
||||||
// GLFW Is Disabled In Server Mode
|
if (is_running) {
|
||||||
|
// GLFW And Audio Are Disabled In Headless Mode
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
|
// Terminate GLFW
|
||||||
glfwDestroyWindow(glfw_window);
|
glfwDestroyWindow(glfw_window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
||||||
|
// Cleanup OpenAL
|
||||||
|
_media_audio_cleanup();
|
||||||
#endif // #ifndef MCPI_HEADLESS_MODE
|
#endif // #ifndef MCPI_HEADLESS_MODE
|
||||||
|
|
||||||
|
// Update State
|
||||||
|
is_running = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store Cursor State
|
// Store Cursor State
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Screenshot Code Is Useless In Server Mode
|
// Screenshot Code Is Useless In Headless Mode
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -14,7 +14,7 @@
|
|||||||
#include <GLES/gl.h>
|
#include <GLES/gl.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
|
|
||||||
// Ensure Screenshots Folder Exists
|
// Ensure Screenshots Folder Exists
|
||||||
static void ensure_screenshots_folder(char *screenshots) {
|
static void ensure_screenshots_folder(char *screenshots) {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
|
|
||||||
// SDL Stub
|
// SDL Stub
|
||||||
void *SDL_SetVideoMode(__attribute__((unused)) int width, __attribute__((unused)) int height, __attribute__((unused)) int bpp, __attribute__((unused)) uint32_t flags) {
|
void *SDL_SetVideoMode(__attribute__((unused)) int width, __attribute__((unused)) int height, __attribute__((unused)) int bpp, __attribute__((unused)) uint32_t flags) {
|
||||||
|
12
media-layer/include/media-layer/audio.h
Normal file
12
media-layer/include/media-layer/audio.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void media_audio_update(float volume, float x, float y, float z, float yaw);
|
||||||
|
void media_audio_play(const char *source, const char *name, float x, float y, float z, float pitch, float volume, int is_ui);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@ -135,7 +135,7 @@ char *read_string() {
|
|||||||
return strdup(str);
|
return strdup(str);
|
||||||
}
|
}
|
||||||
#define MAX_STRING_SIZE 256
|
#define MAX_STRING_SIZE 256
|
||||||
void write_string(char *str) {
|
void write_string(const char *str) {
|
||||||
unsigned char is_null = str == NULL;
|
unsigned char is_null = str == NULL;
|
||||||
write_byte(is_null);
|
write_byte(is_null);
|
||||||
if (!is_null) {
|
if (!is_null) {
|
||||||
|
@ -44,7 +44,7 @@ __attribute__((visibility("internal"))) void write_float(float x);
|
|||||||
|
|
||||||
// Read/Write Strings
|
// Read/Write Strings
|
||||||
__attribute__((visibility("internal"))) char *read_string(); // Remember To free()
|
__attribute__((visibility("internal"))) char *read_string(); // Remember To free()
|
||||||
__attribute__((visibility("internal"))) void write_string(char *str);
|
__attribute__((visibility("internal"))) void write_string(const char *str);
|
||||||
|
|
||||||
// Manipulate Connection
|
// Manipulate Connection
|
||||||
__attribute__((visibility("internal"))) void set_connection(int read, int write);
|
__attribute__((visibility("internal"))) void set_connection(int read, int write);
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
#include <libreborn/media-layer/internal.h>
|
#include <media-layer/audio.h>
|
||||||
|
#include <media-layer/internal.h>
|
||||||
|
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
|
|
||||||
@ -356,3 +357,62 @@ CALL(10, media_get_framebuffer_size, void, (int *width, int *height)) {
|
|||||||
write_int((uint32_t) height);
|
write_int((uint32_t) height);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CALL(59, media_audio_update, void, (float volume, float x, float y, float z, float yaw)) {
|
||||||
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
|
// Lock Proxy
|
||||||
|
start_proxy_call();
|
||||||
|
|
||||||
|
// Arguments
|
||||||
|
write_float(volume);
|
||||||
|
write_float(x);
|
||||||
|
write_float(y);
|
||||||
|
write_float(z);
|
||||||
|
write_float(yaw);
|
||||||
|
|
||||||
|
// Release Proxy
|
||||||
|
end_proxy_call();
|
||||||
|
#else
|
||||||
|
float volume = read_float();
|
||||||
|
float x = read_float();
|
||||||
|
float y = read_float();
|
||||||
|
float z = read_float();
|
||||||
|
float yaw = read_float();
|
||||||
|
// Run
|
||||||
|
media_audio_update(volume, x, y, z, yaw);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL(60, media_audio_play, void, (const char *source, const char *name, float x, float y, float z, float pitch, float volume, int is_ui)) {
|
||||||
|
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||||
|
// Lock Proxy
|
||||||
|
start_proxy_call();
|
||||||
|
|
||||||
|
// Arguments
|
||||||
|
write_string(source);
|
||||||
|
write_string(name);
|
||||||
|
write_float(x);
|
||||||
|
write_float(y);
|
||||||
|
write_float(z);
|
||||||
|
write_float(pitch);
|
||||||
|
write_float(volume);
|
||||||
|
write_int(is_ui);
|
||||||
|
|
||||||
|
// Release Proxy
|
||||||
|
end_proxy_call();
|
||||||
|
#else
|
||||||
|
char *source = read_string();
|
||||||
|
char *name = read_string();
|
||||||
|
float x = read_float();
|
||||||
|
float y = read_float();
|
||||||
|
float z = read_float();
|
||||||
|
float pitch = read_float();
|
||||||
|
float volume = read_float();
|
||||||
|
int is_ui = read_int();
|
||||||
|
// Run
|
||||||
|
media_audio_play(source, name, x, y, z, pitch, volume, is_ui);
|
||||||
|
// Free
|
||||||
|
free(source);
|
||||||
|
free(name);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@ add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
|
|||||||
## Mods
|
## Mods
|
||||||
|
|
||||||
add_library(compat SHARED src/compat/compat.c src/compat/egl.c src/compat/x11.c)
|
add_library(compat SHARED src/compat/compat.c src/compat/egl.c src/compat/x11.c)
|
||||||
target_link_libraries(compat feature input chat sign media-layer-core home dl)
|
target_link_libraries(compat reborn media-layer-core)
|
||||||
|
|
||||||
add_library(readdir SHARED src/readdir/readdir.c)
|
add_library(readdir SHARED src/readdir/readdir.c)
|
||||||
|
|
||||||
@ -16,73 +16,80 @@ add_library(feature SHARED src/feature/feature.c)
|
|||||||
target_link_libraries(feature reborn)
|
target_link_libraries(feature reborn)
|
||||||
|
|
||||||
add_library(version SHARED src/version/version.cpp)
|
add_library(version SHARED src/version/version.cpp)
|
||||||
target_link_libraries(version reborn)
|
target_link_libraries(version reborn symbols)
|
||||||
|
|
||||||
|
add_library(chat SHARED src/chat/chat.cpp src/chat/ui.c)
|
||||||
|
target_link_libraries(chat reborn symbols feature pthread)
|
||||||
|
|
||||||
if(MCPI_SERVER_MODE)
|
if(MCPI_SERVER_MODE)
|
||||||
add_library(server SHARED src/server/server.cpp src/server/server_properties.cpp)
|
add_library(server SHARED src/server/server.cpp src/server/server_properties.cpp)
|
||||||
target_link_libraries(server reborn feature home compat version dl media-layer-core pthread)
|
target_link_libraries(server reborn symbols feature home compat version dl media-layer-core pthread)
|
||||||
else()
|
else()
|
||||||
|
target_link_libraries(compat input sign chat home dl)
|
||||||
|
|
||||||
|
target_link_libraries(chat input)
|
||||||
|
|
||||||
add_library(multiplayer SHARED src/multiplayer/multiplayer.cpp)
|
add_library(multiplayer SHARED src/multiplayer/multiplayer.cpp)
|
||||||
target_link_libraries(multiplayer reborn home feature)
|
target_link_libraries(multiplayer reborn symbols home feature)
|
||||||
endif()
|
|
||||||
|
add_library(sound SHARED src/sound/sound.cpp src/sound/repository.cpp)
|
||||||
|
target_link_libraries(sound reborn symbols feature override media-layer-core)
|
||||||
|
|
||||||
add_library(camera SHARED src/camera/camera.cpp)
|
add_library(camera SHARED src/camera/camera.cpp)
|
||||||
target_link_libraries(camera reborn media-layer-core feature home)
|
target_link_libraries(camera reborn symbols media-layer-core feature home)
|
||||||
|
|
||||||
add_library(game-mode SHARED src/game-mode/game-mode.c src/game-mode/game-mode.cpp)
|
|
||||||
target_link_libraries(game-mode reborn feature)
|
|
||||||
|
|
||||||
add_library(input SHARED src/input/input.cpp src/input/bow.c src/input/attack.c src/input/toggle.c src/input/misc.c src/input/drop.cpp)
|
add_library(input SHARED src/input/input.cpp src/input/bow.c src/input/attack.c src/input/toggle.c src/input/misc.c src/input/drop.cpp)
|
||||||
target_link_libraries(input reborn feature media-layer-core)
|
target_link_libraries(input reborn symbols feature media-layer-core)
|
||||||
|
|
||||||
add_library(sign SHARED src/sign/sign.cpp)
|
add_library(sign SHARED src/sign/sign.cpp)
|
||||||
target_link_libraries(sign reborn feature input)
|
target_link_libraries(sign reborn symbols feature input)
|
||||||
|
|
||||||
add_library(death SHARED src/death/death.cpp)
|
|
||||||
target_link_libraries(death reborn feature)
|
|
||||||
|
|
||||||
add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp)
|
|
||||||
target_link_libraries(misc reborn feature)
|
|
||||||
|
|
||||||
add_library(creative SHARED src/creative/creative.cpp)
|
add_library(creative SHARED src/creative/creative.cpp)
|
||||||
target_link_libraries(creative reborn feature)
|
target_link_libraries(creative reborn symbols feature)
|
||||||
|
|
||||||
add_library(options SHARED src/options/options.c)
|
|
||||||
target_link_libraries(options reborn feature)
|
|
||||||
|
|
||||||
add_library(touch SHARED src/touch/touch.c)
|
add_library(touch SHARED src/touch/touch.c)
|
||||||
target_link_libraries(touch reborn feature)
|
target_link_libraries(touch reborn symbols feature)
|
||||||
|
|
||||||
add_library(override SHARED src/override/override.c)
|
add_library(override SHARED src/override/override.c)
|
||||||
target_link_libraries(override reborn dl home)
|
target_link_libraries(override reborn symbols dl home)
|
||||||
|
|
||||||
add_library(textures SHARED src/textures/textures.cpp)
|
add_library(textures SHARED src/textures/textures.cpp)
|
||||||
target_link_libraries(textures reborn feature)
|
target_link_libraries(textures reborn symbols feature)
|
||||||
|
|
||||||
add_library(atlas SHARED src/atlas/atlas.cpp)
|
add_library(atlas SHARED src/atlas/atlas.cpp)
|
||||||
target_link_libraries(atlas reborn feature GLESv1_CM)
|
target_link_libraries(atlas reborn symbols feature GLESv1_CM)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(chat SHARED src/chat/chat.cpp src/chat/ui.c)
|
add_library(game-mode SHARED src/game-mode/game-mode.c src/game-mode/game-mode.cpp)
|
||||||
target_link_libraries(chat reborn feature input pthread)
|
target_link_libraries(game-mode reborn symbols feature)
|
||||||
|
|
||||||
|
add_library(death SHARED src/death/death.cpp)
|
||||||
|
target_link_libraries(death reborn symbols feature)
|
||||||
|
|
||||||
|
add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp)
|
||||||
|
target_link_libraries(misc reborn symbols feature)
|
||||||
|
|
||||||
|
add_library(options SHARED src/options/options.c)
|
||||||
|
target_link_libraries(options reborn symbols feature)
|
||||||
|
|
||||||
add_library(home SHARED src/home/home.c)
|
add_library(home SHARED src/home/home.c)
|
||||||
target_link_libraries(home reborn)
|
target_link_libraries(home reborn symbols)
|
||||||
|
|
||||||
add_library(test SHARED src/test/test.c)
|
add_library(test SHARED src/test/test.c)
|
||||||
target_link_libraries(test reborn home)
|
target_link_libraries(test reborn home)
|
||||||
|
|
||||||
add_library(init SHARED src/init/init.c)
|
add_library(init SHARED src/init/init.c)
|
||||||
target_link_libraries(init compat game-mode camera input sign misc creative death options touch textures atlas chat home version test)
|
target_link_libraries(init compat game-mode misc death options chat home version test)
|
||||||
if(MCPI_SERVER_MODE)
|
if(MCPI_SERVER_MODE)
|
||||||
target_link_libraries(init server)
|
target_link_libraries(init server)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(init multiplayer)
|
target_link_libraries(init multiplayer sound camera input sign creative touch textures atlas)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
## Install Mods
|
## Install Mods
|
||||||
install(TARGETS init compat readdir feature override game-mode camera input sign misc creative death options touch textures atlas chat home version test DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
install(TARGETS init compat readdir feature game-mode misc death options chat home version test DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||||
if(MCPI_SERVER_MODE)
|
if(MCPI_SERVER_MODE)
|
||||||
install(TARGETS server DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
install(TARGETS server DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||||
else()
|
else()
|
||||||
install(TARGETS multiplayer DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
install(TARGETS multiplayer sound override camera input sign creative touch textures atlas DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||||
endif()
|
endif()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <GLES/gl.h>
|
#include <GLES/gl.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
#include "../home/home.h"
|
#include "../home/home.h"
|
||||||
|
@ -5,11 +5,13 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
#include "../input/input.h"
|
#include "../input/input.h"
|
||||||
|
#endif // #ifndef MCPI_SERVER_MODE
|
||||||
#include "chat.h"
|
#include "chat.h"
|
||||||
|
|
||||||
// Store If Chat is Enabled
|
// Store If Chat is Enabled
|
||||||
@ -19,6 +21,7 @@ int _chat_enabled = 0;
|
|||||||
#define MAX_CHAT_MESSAGE_LENGTH 512
|
#define MAX_CHAT_MESSAGE_LENGTH 512
|
||||||
|
|
||||||
// Send API Command
|
// Send API Command
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
static void send_api_command(unsigned char *minecraft, char *str) {
|
static void send_api_command(unsigned char *minecraft, char *str) {
|
||||||
struct ConnectedClient client;
|
struct ConnectedClient client;
|
||||||
client.sock = -1;
|
client.sock = -1;
|
||||||
@ -36,6 +39,7 @@ static void send_api_chat_command(unsigned char *minecraft, char *str) {
|
|||||||
send_api_command(minecraft, command);
|
send_api_command(minecraft, command);
|
||||||
free(command);
|
free(command);
|
||||||
}
|
}
|
||||||
|
#endif // #ifndef MCPI_SERVER_MODE
|
||||||
|
|
||||||
// Send Message To Players
|
// Send Message To Players
|
||||||
static void send_message(unsigned char *server_side_network_handler, char *username, char *message) {
|
static void send_message(unsigned char *server_side_network_handler, char *username, char *message) {
|
||||||
@ -76,6 +80,7 @@ static void ServerSideNetworkHandler_handle_ChatPacket_injection(unsigned char *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
// Message Queue
|
// Message Queue
|
||||||
static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static std::vector<std::string> queue;
|
static std::vector<std::string> queue;
|
||||||
@ -110,6 +115,7 @@ static void send_queued_messages(unsigned char *minecraft) {
|
|||||||
// Unlock
|
// Unlock
|
||||||
pthread_mutex_unlock(&queue_mutex);
|
pthread_mutex_unlock(&queue_mutex);
|
||||||
}
|
}
|
||||||
|
#endif // #ifndef MCPI_SERVER_MODE
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
void init_chat() {
|
void init_chat() {
|
||||||
@ -123,6 +129,8 @@ void init_chat() {
|
|||||||
// Re-Broadcast ChatPacket
|
// Re-Broadcast ChatPacket
|
||||||
patch_address(ServerSideNetworkHandler_handle_ChatPacket_vtable_addr, (void *) ServerSideNetworkHandler_handle_ChatPacket_injection);
|
patch_address(ServerSideNetworkHandler_handle_ChatPacket_vtable_addr, (void *) ServerSideNetworkHandler_handle_ChatPacket_injection);
|
||||||
// Send Messages On Input Tick
|
// Send Messages On Input Tick
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
input_run_on_tick(send_queued_messages);
|
input_run_on_tick(send_queued_messages);
|
||||||
|
#endif // #ifndef MCPI_SERVER_MODE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,15 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
void chat_open();
|
void chat_open();
|
||||||
unsigned int chat_get_counter();
|
unsigned int chat_get_counter();
|
||||||
|
#endif // #ifndef MCPI_SERVER_MODE
|
||||||
|
|
||||||
__attribute__((visibility("internal"))) extern int _chat_enabled;
|
__attribute__((visibility("internal"))) extern int _chat_enabled;
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
__attribute__((visibility("internal"))) void _chat_queue_message(char *message);
|
__attribute__((visibility("internal"))) void _chat_queue_message(char *message);
|
||||||
|
#endif // #ifndef MCPI_SERVER_MODE
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -86,3 +87,4 @@ void chat_open() {
|
|||||||
pthread_create(&thread, NULL, chat_thread, NULL);
|
pthread_create(&thread, NULL, chat_thread, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // #ifndef MCPI_SERVER_MODE
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "compat.h"
|
||||||
|
#include "../init/init.h"
|
||||||
|
|
||||||
|
#ifndef MCPI_SERVER_MODE
|
||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
#include <libreborn/media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
#include "../input/input.h"
|
#include "../input/input.h"
|
||||||
#include "../sign/sign.h"
|
#include "../sign/sign.h"
|
||||||
#include "../chat/chat.h"
|
#include "../chat/chat.h"
|
||||||
#include "../home/home.h"
|
#include "../home/home.h"
|
||||||
#include "../init/init.h"
|
|
||||||
#include "compat.h"
|
|
||||||
|
|
||||||
// Custom Title
|
// Custom Title
|
||||||
HOOK(SDL_WM_SetCaption, void, (__attribute__((unused)) const char *title, const char *icon)) {
|
HOOK(SDL_WM_SetCaption, void, (__attribute__((unused)) const char *title, const char *icon)) {
|
||||||
@ -29,7 +31,6 @@ HOOK(SDL_ShowCursor, int, (int toggle)) {
|
|||||||
// Intercept SDL Events
|
// Intercept SDL Events
|
||||||
HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
HOOK(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
|
||||||
#ifndef MCPI_SERVER_MODE
|
|
||||||
// Check If Exit Is Requested
|
// Check If Exit Is Requested
|
||||||
if (compat_check_exit_requested()) {
|
if (compat_check_exit_requested()) {
|
||||||
// Send SDL_QUIT
|
// Send SDL_QUIT
|
||||||
@ -37,7 +38,6 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
|||||||
new_event.type = SDL_QUIT;
|
new_event.type = SDL_QUIT;
|
||||||
SDL_PushEvent(&new_event);
|
SDL_PushEvent(&new_event);
|
||||||
}
|
}
|
||||||
#endif // #ifndef MCPI_SERVER_MODE
|
|
||||||
|
|
||||||
// Poll Events
|
// Poll Events
|
||||||
ensure_SDL_PollEvent();
|
ensure_SDL_PollEvent();
|
||||||
@ -106,6 +106,7 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif // #ifndef MCPI_SERVER_MODE
|
||||||
|
|
||||||
// Exit Handler
|
// Exit Handler
|
||||||
static void exit_handler(__attribute__((unused)) int data) {
|
static void exit_handler(__attribute__((unused)) int data) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
|
|
||||||
// Functions That Have Their Return Values Used
|
// Functions That Have Their Return Values Used
|
||||||
static EGLSurface eglCreateWindowSurface_injection(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) NativeWindowType native_window, __attribute__((unused)) EGLint const *attrib_list) {
|
static EGLSurface eglCreateWindowSurface_injection(__attribute__((unused)) EGLDisplay display, __attribute__((unused)) EGLConfig config, __attribute__((unused)) NativeWindowType native_window, __attribute__((unused)) EGLint const *attrib_list) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/media-layer/core.h>
|
#include <media-layer/core.h>
|
||||||
|
|
||||||
// Functions That Have Their Return Values Used
|
// Functions That Have Their Return Values Used
|
||||||
static int XTranslateCoordinates_injection(__attribute__((unused)) void *display, __attribute__((unused)) XID src_w, __attribute__((unused)) XID dest_w, int src_x, int src_y, int *dest_x_return, int *dest_y_return, __attribute__((unused)) XID *child_return) {
|
static int XTranslateCoordinates_injection(__attribute__((unused)) void *display, __attribute__((unused)) XID src_w, __attribute__((unused)) XID dest_w, int src_x, int src_y, int *dest_x_return, int *dest_y_return, __attribute__((unused)) XID *child_return) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
static int is_survival = -1;
|
static int is_survival = -1;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "game-mode.h"
|
#include "game-mode.h"
|
||||||
|
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
// Get Minecraft From Screen
|
// Get Minecraft From Screen
|
||||||
static unsigned char *get_minecraft_from_screen(unsigned char *screen) {
|
static unsigned char *get_minecraft_from_screen(unsigned char *screen) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "home.h"
|
#include "home.h"
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
|
@ -7,18 +7,19 @@ __attribute__((constructor)) static void init() {
|
|||||||
init_server();
|
init_server();
|
||||||
#else
|
#else
|
||||||
init_multiplayer();
|
init_multiplayer();
|
||||||
#endif
|
init_sound();
|
||||||
init_game_mode();
|
|
||||||
init_input();
|
init_input();
|
||||||
init_sign();
|
init_sign();
|
||||||
init_misc();
|
|
||||||
init_creative();
|
init_creative();
|
||||||
init_death();
|
|
||||||
init_camera();
|
init_camera();
|
||||||
init_options();
|
|
||||||
init_touch();
|
init_touch();
|
||||||
init_textures();
|
init_textures();
|
||||||
init_atlas();
|
init_atlas();
|
||||||
|
#endif
|
||||||
|
init_game_mode();
|
||||||
|
init_misc();
|
||||||
|
init_death();
|
||||||
|
init_options();
|
||||||
init_chat();
|
init_chat();
|
||||||
init_home();
|
init_home();
|
||||||
init_version();
|
init_version();
|
||||||
|
@ -10,18 +10,19 @@ void init_compat();
|
|||||||
void init_server();
|
void init_server();
|
||||||
#else
|
#else
|
||||||
void init_multiplayer();
|
void init_multiplayer();
|
||||||
#endif
|
void init_sound();
|
||||||
void init_game_mode();
|
|
||||||
void init_input();
|
void init_input();
|
||||||
void init_sign();
|
void init_sign();
|
||||||
void init_misc();
|
|
||||||
void init_creative();
|
void init_creative();
|
||||||
void init_death();
|
|
||||||
void init_camera();
|
void init_camera();
|
||||||
void init_options();
|
|
||||||
void init_touch();
|
void init_touch();
|
||||||
void init_textures();
|
void init_textures();
|
||||||
void init_atlas();
|
void init_atlas();
|
||||||
|
#endif
|
||||||
|
void init_game_mode();
|
||||||
|
void init_misc();
|
||||||
|
void init_death();
|
||||||
|
void init_options();
|
||||||
void init_chat();
|
void init_chat();
|
||||||
void init_home();
|
void init_home();
|
||||||
void init_version();
|
void init_version();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
@ -107,6 +107,16 @@ static RakNet_StartupResult RakNetInstance_host_RakNet_RakPeer_Startup_injection
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix Bug Where RakNetInstance Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
|
||||||
|
static unsigned char *RakNetInstance_injection(unsigned char *rak_net_instance) {
|
||||||
|
// Call Original Method
|
||||||
|
unsigned char *result = (*RakNetInstance)(rak_net_instance);
|
||||||
|
// Fix
|
||||||
|
*(unsigned char *) (rak_net_instance + RakNetInstance_pinging_for_hosts_property_offset) = 0;
|
||||||
|
// Return
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
void init_misc() {
|
void init_misc() {
|
||||||
if (feature_has("Remove Invalid Item Background", 0)) {
|
if (feature_has("Remove Invalid Item Background", 0)) {
|
||||||
@ -131,6 +141,9 @@ void init_misc() {
|
|||||||
// Print Error Message If RakNet Startup Fails
|
// Print Error Message If RakNet Startup Fails
|
||||||
overwrite_call((void *) 0x73778, (void *) RakNetInstance_host_RakNet_RakPeer_Startup_injection);
|
overwrite_call((void *) 0x73778, (void *) RakNetInstance_host_RakNet_RakPeer_Startup_injection);
|
||||||
|
|
||||||
|
// Fix Bug Where RakNetInstance Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
|
||||||
|
overwrite_calls((void *) RakNetInstance, (void *) RakNetInstance_injection);
|
||||||
|
|
||||||
// Init C++
|
// Init C++
|
||||||
_init_misc_cpp();
|
_init_misc_cpp();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../home/home.h"
|
#include "../home/home.h"
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
@ -110,8 +110,9 @@ static void iterate_servers(std::function<void(const char *address, int port)> c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ping External Servers
|
||||||
static void RakNetInstance_pingForHosts_injection(unsigned char *rak_net_instance, int32_t base_port) {
|
static void RakNetInstance_pingForHosts_injection(unsigned char *rak_net_instance, int32_t base_port) {
|
||||||
// Call Original
|
// Call Original Method
|
||||||
(*RakNetInstance_pingForHosts)(rak_net_instance, base_port);
|
(*RakNetInstance_pingForHosts)(rak_net_instance, base_port);
|
||||||
|
|
||||||
// Get RakNet::RakPeer
|
// Get RakNet::RakPeer
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
|
@ -14,23 +14,35 @@ static int starts_with(const char *s, const char *t) {
|
|||||||
return strncmp(s, t, strlen(t)) == 0;
|
return strncmp(s, t, strlen(t)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_override_path(const char *filename) {
|
char *override_get_path(const char *filename) {
|
||||||
// Get MCPI Home Path
|
// Get MCPI Home Path
|
||||||
char *home_path = home_get();
|
char *home_path = home_get();
|
||||||
// Get Asset Override Path
|
// Get Asset Override Path
|
||||||
char *overrides = NULL;
|
char *overrides = NULL;
|
||||||
safe_asprintf(&overrides, "%s/overrides", home_path);
|
safe_asprintf(&overrides, "%s/overrides", home_path);
|
||||||
|
|
||||||
// Get Data Path
|
// Get Data Path
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
char *cwd = getcwd(NULL, 0);
|
char *binary_directory = get_binary_directory();
|
||||||
safe_asprintf(&data, "%s/data", cwd);
|
safe_asprintf(&data, "%s/data", binary_directory);
|
||||||
free(cwd);
|
free(binary_directory);
|
||||||
|
int data_length = strlen(data);
|
||||||
|
|
||||||
// Get Full Path
|
// Get Full Path
|
||||||
|
char *full_path;
|
||||||
|
if (strlen(filename) > 0 && filename[0] == '/') {
|
||||||
|
// Absolute Path
|
||||||
|
full_path = strdup(filename);
|
||||||
|
} else {
|
||||||
|
// Relative Path
|
||||||
|
full_path = realpath(filename, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check For Override
|
||||||
char *new_path = NULL;
|
char *new_path = NULL;
|
||||||
char *full_path = realpath(filename, NULL);
|
|
||||||
if (full_path != NULL) {
|
if (full_path != NULL) {
|
||||||
if (starts_with(full_path, data)) {
|
if (starts_with(full_path, data)) {
|
||||||
safe_asprintf(&new_path, "%s%s", overrides, &full_path[strlen(data)]);
|
safe_asprintf(&new_path, "%s%s", overrides, &full_path[data_length]);
|
||||||
if (access(new_path, F_OK) == -1) {
|
if (access(new_path, F_OK) == -1) {
|
||||||
free(new_path);
|
free(new_path);
|
||||||
new_path = NULL;
|
new_path = NULL;
|
||||||
@ -38,15 +50,17 @@ static char *get_override_path(const char *filename) {
|
|||||||
}
|
}
|
||||||
free(full_path);
|
free(full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free Variables
|
// Free Variables
|
||||||
free(overrides);
|
free(overrides);
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
// Return
|
// Return
|
||||||
return new_path;
|
return new_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
HOOK(fopen, FILE *, (const char *filename, const char *mode)) {
|
HOOK(fopen, FILE *, (const char *filename, const char *mode)) {
|
||||||
char *new_path = get_override_path(filename);
|
char *new_path = override_get_path(filename);
|
||||||
// Open File
|
// Open File
|
||||||
ensure_fopen();
|
ensure_fopen();
|
||||||
FILE *file = (*real_fopen)(new_path != NULL ? new_path : filename, mode);
|
FILE *file = (*real_fopen)(new_path != NULL ? new_path : filename, mode);
|
||||||
@ -59,7 +73,7 @@ HOOK(fopen, FILE *, (const char *filename, const char *mode)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HOOK(fopen64, FILE *, (const char *filename, const char *mode)) {
|
HOOK(fopen64, FILE *, (const char *filename, const char *mode)) {
|
||||||
char *new_path = get_override_path(filename);
|
char *new_path = override_get_path(filename);
|
||||||
// Open File
|
// Open File
|
||||||
ensure_fopen64();
|
ensure_fopen64();
|
||||||
FILE *file = (*real_fopen64)(new_path != NULL ? new_path : filename, mode);
|
FILE *file = (*real_fopen64)(new_path != NULL ? new_path : filename, mode);
|
||||||
|
11
mods/src/override/override.h
Normal file
11
mods/src/override/override.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *override_get_path(const char *filename);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@ -25,7 +25,7 @@
|
|||||||
#include "../compat/compat.h"
|
#include "../compat/compat.h"
|
||||||
#include "../version/version.h"
|
#include "../version/version.h"
|
||||||
|
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
// --only-generate: Ony Generate World And Then Exit
|
// --only-generate: Ony Generate World And Then Exit
|
||||||
static bool only_generate = false;
|
static bool only_generate = false;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
|
2
mods/src/sound/README.md
Normal file
2
mods/src/sound/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# ``sound`` Mod
|
||||||
|
This mod implements a sound engine.
|
335
mods/src/sound/repository.cpp
Normal file
335
mods/src/sound/repository.cpp
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "sound.h"
|
||||||
|
|
||||||
|
// Sound Repository Extracted From MCPE 0.6.1 APK
|
||||||
|
static std::unordered_map<std::string, std::vector<std::string>> repository = {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"step.cloth",
|
||||||
|
{
|
||||||
|
"PCM_cloth1",
|
||||||
|
"PCM_cloth2",
|
||||||
|
"PCM_cloth3",
|
||||||
|
"PCM_cloth4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step.grass",
|
||||||
|
{
|
||||||
|
"PCM_grass1",
|
||||||
|
"PCM_grass2",
|
||||||
|
"PCM_grass3",
|
||||||
|
"PCM_grass4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step.gravel",
|
||||||
|
{
|
||||||
|
"PCM_gravel1",
|
||||||
|
"PCM_gravel2",
|
||||||
|
"PCM_gravel3",
|
||||||
|
"PCM_gravel4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step.sand",
|
||||||
|
{
|
||||||
|
"PCM_sand1",
|
||||||
|
"PCM_sand2",
|
||||||
|
"PCM_sand3",
|
||||||
|
"PCM_sand4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step.stone",
|
||||||
|
{
|
||||||
|
"PCM_stone1",
|
||||||
|
"PCM_stone2",
|
||||||
|
"PCM_stone3",
|
||||||
|
"PCM_stone4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step.wood",
|
||||||
|
{
|
||||||
|
"PCM_wood1",
|
||||||
|
"PCM_wood2",
|
||||||
|
"PCM_wood3",
|
||||||
|
"PCM_wood4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.splash",
|
||||||
|
{
|
||||||
|
"PCM_splash"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.explode",
|
||||||
|
{
|
||||||
|
"PCM_explode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.click",
|
||||||
|
{
|
||||||
|
"PCM_click"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.door_open",
|
||||||
|
{
|
||||||
|
"PCM_door_open"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.door_close",
|
||||||
|
{
|
||||||
|
"PCM_door_close"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.pop",
|
||||||
|
{
|
||||||
|
"PCM_pop"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.pop2",
|
||||||
|
{
|
||||||
|
"PCM_pop2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.hurt",
|
||||||
|
{
|
||||||
|
"PCM_hurt"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.glass",
|
||||||
|
{
|
||||||
|
"PCM_glass1",
|
||||||
|
"PCM_glass2",
|
||||||
|
"PCM_glass3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.sheep",
|
||||||
|
{
|
||||||
|
"PCM_sheep1",
|
||||||
|
"PCM_sheep2",
|
||||||
|
"PCM_sheep3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.pig",
|
||||||
|
{
|
||||||
|
"PCM_pig1",
|
||||||
|
"PCM_pig2",
|
||||||
|
"PCM_pig3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.pigdeath",
|
||||||
|
{
|
||||||
|
"PCM_pigdeath"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.cow",
|
||||||
|
{
|
||||||
|
"PCM_cow1",
|
||||||
|
"PCM_cow2",
|
||||||
|
"PCM_cow3",
|
||||||
|
"PCM_cow4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.cowhurt",
|
||||||
|
{
|
||||||
|
"PCM_cowhurt1",
|
||||||
|
"PCM_cowhurt2",
|
||||||
|
"PCM_cowhurt3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.chicken",
|
||||||
|
{
|
||||||
|
"PCM_chicken2",
|
||||||
|
"PCM_chicken3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.chickenhurt",
|
||||||
|
{
|
||||||
|
"PCM_chickenhurt1",
|
||||||
|
"PCM_chickenhurt2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.zombie",
|
||||||
|
{
|
||||||
|
"PCM_zombie1",
|
||||||
|
"PCM_zombie2",
|
||||||
|
"PCM_zombie3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.zombiedeath",
|
||||||
|
{
|
||||||
|
"PCM_zombiedeath"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.zombiehurt",
|
||||||
|
{
|
||||||
|
"PCM_zombiehurt1",
|
||||||
|
"PCM_zombiehurt2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.skeleton",
|
||||||
|
{
|
||||||
|
"PCM_skeleton1",
|
||||||
|
"PCM_skeleton2",
|
||||||
|
"PCM_skeleton3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.skeletonhurt",
|
||||||
|
{
|
||||||
|
"PCM_skeletonhurt1",
|
||||||
|
"PCM_skeletonhurt2",
|
||||||
|
"PCM_skeletonhurt3",
|
||||||
|
"PCM_skeletonhurt4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.spider",
|
||||||
|
{
|
||||||
|
"PCM_spider1",
|
||||||
|
"PCM_spider2",
|
||||||
|
"PCM_spider3",
|
||||||
|
"PCM_spider4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.spiderdeath",
|
||||||
|
{
|
||||||
|
"PCM_spiderdeath"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.zombiepig.zpig",
|
||||||
|
{
|
||||||
|
"PCM_zpig1",
|
||||||
|
"PCM_zpig2",
|
||||||
|
"PCM_zpig3",
|
||||||
|
"PCM_zpig4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.zombiepig.zpigangry",
|
||||||
|
{
|
||||||
|
"PCM_zpigangry1",
|
||||||
|
"PCM_zpigangry2",
|
||||||
|
"PCM_zpigangry3",
|
||||||
|
"PCM_zpigangry4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.zombiepig.zpigdeath",
|
||||||
|
{
|
||||||
|
"PCM_zpigdeath"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.zombiepig.zpighurt",
|
||||||
|
{
|
||||||
|
"PCM_zpighurt1",
|
||||||
|
"PCM_zpighurt2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"damage.fallbig",
|
||||||
|
{
|
||||||
|
"PCM_fallbig1",
|
||||||
|
"PCM_fallbig2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"damage.fallsmall",
|
||||||
|
{
|
||||||
|
"PCM_fallsmall"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.bow",
|
||||||
|
{
|
||||||
|
"PCM_bow"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.bowhit",
|
||||||
|
{
|
||||||
|
"PCM_bowhit1",
|
||||||
|
"PCM_bowhit2",
|
||||||
|
"PCM_bowhit3",
|
||||||
|
"PCM_bowhit4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.creeper",
|
||||||
|
{
|
||||||
|
"PCM_creeper1",
|
||||||
|
"PCM_creeper2",
|
||||||
|
"PCM_creeper3",
|
||||||
|
"PCM_creeper4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mob.creeperdeath",
|
||||||
|
{
|
||||||
|
"PCM_creeperdeath"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.eat",
|
||||||
|
{
|
||||||
|
"PCM_eat1",
|
||||||
|
"PCM_eat2",
|
||||||
|
"PCM_eat3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random.fuse",
|
||||||
|
{
|
||||||
|
"PCM_fuse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set rand() Seed
|
||||||
|
__attribute__((constructor)) static void init_rand_seed() {
|
||||||
|
srand(time(NULL));
|
||||||
|
}
|
||||||
|
// Pick Sound
|
||||||
|
std::string _sound_pick(std::string sound) {
|
||||||
|
if (repository.count(sound) > 0) {
|
||||||
|
// Sound Exists
|
||||||
|
std::vector<std::string> &options = repository[sound];
|
||||||
|
return options[rand() % options.size()];
|
||||||
|
} else {
|
||||||
|
// Invalid Sound
|
||||||
|
ERR("Invalid Sound: %s", sound.c_str());
|
||||||
|
}
|
||||||
|
}
|
119
mods/src/sound/sound.cpp
Normal file
119
mods/src/sound/sound.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
#include <symbols/minecraft.h>
|
||||||
|
#include <media-layer/audio.h>
|
||||||
|
|
||||||
|
#include "sound.h"
|
||||||
|
#include "../feature/feature.h"
|
||||||
|
#include "../override/override.h"
|
||||||
|
#include "../init/init.h"
|
||||||
|
|
||||||
|
// Resolve Source File Path
|
||||||
|
#define SOURCE_FILE_BASE "data/libminecraftpe.so"
|
||||||
|
static std::string get_source_file() {
|
||||||
|
static bool source_loaded = false;
|
||||||
|
static std::string source;
|
||||||
|
|
||||||
|
// Check
|
||||||
|
if (source_loaded) {
|
||||||
|
// Already Resolved
|
||||||
|
return source;
|
||||||
|
} else {
|
||||||
|
// Resolve
|
||||||
|
|
||||||
|
// Get Binary Directory
|
||||||
|
char *binary_directory = get_binary_directory();
|
||||||
|
|
||||||
|
// Get Full Path
|
||||||
|
char *full_path = NULL;
|
||||||
|
safe_asprintf(&full_path, "%s/" SOURCE_FILE_BASE, binary_directory);
|
||||||
|
|
||||||
|
// Free Binary Directory
|
||||||
|
free(binary_directory);
|
||||||
|
|
||||||
|
// Handle Overrides
|
||||||
|
char *overridden_full_path = override_get_path(full_path);
|
||||||
|
if (overridden_full_path != NULL) {
|
||||||
|
free(full_path);
|
||||||
|
full_path = overridden_full_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check If Sound Exists
|
||||||
|
if (access(full_path, F_OK) == -1) {
|
||||||
|
// Fail
|
||||||
|
WARN("%s", "Audio Source File Doesn't Exists: " SOURCE_FILE_BASE);
|
||||||
|
source.assign("");
|
||||||
|
} else {
|
||||||
|
// Set
|
||||||
|
source.assign(full_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free
|
||||||
|
free(full_path);
|
||||||
|
|
||||||
|
// Mark As Loaded
|
||||||
|
source_loaded = true;
|
||||||
|
|
||||||
|
// Return
|
||||||
|
return get_source_file();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Resolve On Startup
|
||||||
|
__attribute__((constructor)) static void resolve_source_file() {
|
||||||
|
get_source_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play Sound
|
||||||
|
// The pitch value is unsued because it causes glitchy sounds, it is seemingly unused in MCPE as well.
|
||||||
|
static void SoundEngine_playUI_injection(__attribute__((unused)) unsigned char *sound_engine, std::string const& name, __attribute__((unused)) float pitch, float volume) {
|
||||||
|
std::string source = get_source_file();
|
||||||
|
if (source.size() > 0) {
|
||||||
|
media_audio_play(source.c_str(), _sound_pick(name).c_str(), 0.0f, 0.0f, 0.0f, 1.0f, volume, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void SoundEngine_play_injection(__attribute__((unused)) unsigned char *sound_engine, std::string const& name, float x, float y, float z, __attribute__((unused)) float pitch, float volume) {
|
||||||
|
std::string source = get_source_file();
|
||||||
|
if (source.size() > 0) {
|
||||||
|
media_audio_play(source.c_str(), _sound_pick(name).c_str(), x, y, z, 1.0f, volume, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh Data
|
||||||
|
static void SoundEngine_update_injection(unsigned char *sound_engine, unsigned char *listener_mob, __attribute__((unused)) float listener_angle) {
|
||||||
|
// Variables
|
||||||
|
static float volume = 0;
|
||||||
|
static float x = 0;
|
||||||
|
static float y = 0;
|
||||||
|
static float z = 0;
|
||||||
|
static float yaw = 0;
|
||||||
|
|
||||||
|
// SoundEngine Properties
|
||||||
|
unsigned char *options = *(unsigned char **) (sound_engine + SoundEngine_options_property_offset);
|
||||||
|
|
||||||
|
// Volume
|
||||||
|
int32_t sound_enabled = *(int32_t *) (options + Options_sound_property_offset);
|
||||||
|
volume = sound_enabled ? 1 : 0;
|
||||||
|
|
||||||
|
// Position And Rotation
|
||||||
|
if (listener_mob != NULL) {
|
||||||
|
// Values
|
||||||
|
x = *(float *) (listener_mob + Entity_x_property_offset);
|
||||||
|
y = *(float *) (listener_mob + Entity_y_property_offset);
|
||||||
|
z = *(float *) (listener_mob + Entity_z_property_offset);
|
||||||
|
yaw = *(float *) (listener_mob + Entity_yaw_property_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log
|
||||||
|
media_audio_update(volume, x, y, z, yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init
|
||||||
|
void init_sound() {
|
||||||
|
// Implement Sound Engine
|
||||||
|
if (feature_has("Implement Sound Engine", 0)) {
|
||||||
|
overwrite_calls((void *) SoundEngine_playUI, (void *) SoundEngine_playUI_injection);
|
||||||
|
overwrite_calls((void *) SoundEngine_play, (void *) SoundEngine_play_injection);
|
||||||
|
overwrite_calls((void *) SoundEngine_update, (void *) SoundEngine_update_injection);
|
||||||
|
}
|
||||||
|
}
|
5
mods/src/sound/sound.h
Normal file
5
mods/src/sound/sound.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
__attribute__((visibility("internal"))) std::string _sound_pick(std::string sound);
|
@ -1,5 +1,5 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "../feature/feature.h"
|
#include "../feature/feature.h"
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
|
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
// Enable Touch GUI
|
// Enable Touch GUI
|
||||||
static int32_t Minecraft_isTouchscreen_injection(__attribute__((unused)) unsigned char *minecraft) {
|
static int32_t Minecraft_isTouchscreen_injection(__attribute__((unused)) unsigned char *minecraft) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
#include <libreborn/minecraft.h>
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "../init/init.h"
|
#include "../init/init.h"
|
||||||
|
@ -31,6 +31,7 @@ sudo apt-get install --no-install-recommends -y \
|
|||||||
libfreeimage3 libfreeimage-dev \
|
libfreeimage3 libfreeimage-dev \
|
||||||
crossbuild-essential-armhf \
|
crossbuild-essential-armhf \
|
||||||
crossbuild-essential-arm64 \
|
crossbuild-essential-arm64 \
|
||||||
|
libopenal-dev \
|
||||||
qemu-user-static
|
qemu-user-static
|
||||||
|
|
||||||
# Install ARM Dependencies
|
# Install ARM Dependencies
|
||||||
@ -38,7 +39,9 @@ if [ ! -z "${ARM_PACKAGES_SUPPORTED}" ]; then
|
|||||||
sudo apt-get install --no-install-recommends -y \
|
sudo apt-get install --no-install-recommends -y \
|
||||||
libglfw3:armhf libglfw3-dev:armhf \
|
libglfw3:armhf libglfw3-dev:armhf \
|
||||||
libfreeimage3:armhf \
|
libfreeimage3:armhf \
|
||||||
|
libopenal-dev:armhf \
|
||||||
libglfw3:arm64 libglfw3-dev:arm64 \
|
libglfw3:arm64 libglfw3-dev:arm64 \
|
||||||
libfreeimage3:arm64
|
libfreeimage3:arm64 \
|
||||||
|
libopenal-dev:arm64
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ package() {
|
|||||||
cp "debian/$1" "${dir}/DEBIAN/control"
|
cp "debian/$1" "${dir}/DEBIAN/control"
|
||||||
|
|
||||||
# Format DEBIAN/control
|
# Format DEBIAN/control
|
||||||
sed -i "s/\${VERSION}/${VERSION}~$(lsb_release -cs)/g" "${dir}/DEBIAN/control"
|
sed -i "s/\${VERSION}/${VERSION}/g" "${dir}/DEBIAN/control"
|
||||||
|
|
||||||
# Fix Permissions On Jenkins
|
# Fix Permissions On Jenkins
|
||||||
chmod -R g-s "${dir}"
|
chmod -R g-s "${dir}"
|
||||||
|
4
symbols/CMakeLists.txt
Normal file
4
symbols/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
project(symbols)
|
||||||
|
|
||||||
|
add_library(symbols INTERFACE)
|
||||||
|
target_include_directories(symbols INTERFACE include)
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
// bool In C
|
// bool In C
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
typedef uint32_t bool;
|
typedef unsigned char bool;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
@ -182,6 +182,7 @@ static uint32_t Options_ambient_occlusion_property_offset = 0x18; // unsigned ch
|
|||||||
static uint32_t Options_hide_gui_property_offset = 0xec; // unsigned char / bool
|
static uint32_t Options_hide_gui_property_offset = 0xec; // unsigned char / bool
|
||||||
static uint32_t Options_third_person_property_offset = 0xed; // unsigned char / bool
|
static uint32_t Options_third_person_property_offset = 0xed; // unsigned char / bool
|
||||||
static uint32_t Options_render_distance_property_offset = 0x10; // int32_t
|
static uint32_t Options_render_distance_property_offset = 0x10; // int32_t
|
||||||
|
static uint32_t Options_sound_property_offset = 0x4; // int32_t
|
||||||
|
|
||||||
// MouseBuildInput
|
// MouseBuildInput
|
||||||
|
|
||||||
@ -221,6 +222,15 @@ static uint32_t Player_inventory_property_offset = 0xbe0; // Inventory *
|
|||||||
typedef void (*Entity_die_t)(unsigned char *entity, unsigned char *cause);
|
typedef void (*Entity_die_t)(unsigned char *entity, unsigned char *cause);
|
||||||
static uint32_t Entity_die_vtable_offset = 0x130;
|
static uint32_t Entity_die_vtable_offset = 0x130;
|
||||||
|
|
||||||
|
static uint32_t Entity_x_property_offset = 0x4; // float
|
||||||
|
static uint32_t Entity_y_property_offset = 0x8; // float
|
||||||
|
static uint32_t Entity_z_property_offset = 0xc; // float
|
||||||
|
static uint32_t Entity_yaw_property_offset = 0x40; // float
|
||||||
|
static uint32_t Entity_old_x_property_offset = 0x28; // float
|
||||||
|
static uint32_t Entity_old_y_property_offset = 0x2c; // float
|
||||||
|
static uint32_t Entity_old_z_property_offset = 0x30; // float
|
||||||
|
static uint32_t Entity_old_yaw_property_offset = 0x48; // float
|
||||||
|
|
||||||
// Mob
|
// Mob
|
||||||
|
|
||||||
typedef void (*Mob_actuallyHurt_t)(unsigned char *entity, int32_t damage);
|
typedef void (*Mob_actuallyHurt_t)(unsigned char *entity, int32_t damage);
|
||||||
@ -389,7 +399,11 @@ static RakNetInstance_pingForHosts_t RakNetInstance_pingForHosts = (RakNetInstan
|
|||||||
static uint32_t RakNetInstance_pingForHosts_vtable_offset = 0x14;
|
static uint32_t RakNetInstance_pingForHosts_vtable_offset = 0x14;
|
||||||
static void *RakNetInstance_pingForHosts_vtable_addr = (void *) 0x109afc;
|
static void *RakNetInstance_pingForHosts_vtable_addr = (void *) 0x109afc;
|
||||||
|
|
||||||
|
typedef unsigned char *(*RakNetInstance_t)(unsigned char *rak_net_instance);
|
||||||
|
static RakNetInstance_t RakNetInstance = (RakNetInstance_t) 0x73b20;
|
||||||
|
|
||||||
static uint32_t RakNetInstance_peer_property_offset = 0x4; // RakNet::RakPeer *
|
static uint32_t RakNetInstance_peer_property_offset = 0x4; // RakNet::RakPeer *
|
||||||
|
static uint32_t RakNetInstance_pinging_for_hosts_property_offset = 0x24; // unsigned char
|
||||||
|
|
||||||
// RakNet::RakPeer
|
// RakNet::RakPeer
|
||||||
|
|
||||||
@ -483,6 +497,17 @@ static Tesselator_colorABGR_t Tesselator_colorABGR = (Tesselator_colorABGR_t) 0x
|
|||||||
typedef void (*Tesselator_color_t)(unsigned char *tesselator, int32_t r, int32_t g, int32_t b, int32_t a);
|
typedef void (*Tesselator_color_t)(unsigned char *tesselator, int32_t r, int32_t g, int32_t b, int32_t a);
|
||||||
static Tesselator_color_t Tesselator_color = (Tesselator_color_t) 0x52a48;
|
static Tesselator_color_t Tesselator_color = (Tesselator_color_t) 0x52a48;
|
||||||
|
|
||||||
|
// SoundEngine
|
||||||
|
|
||||||
|
typedef void (*SoundEngine_enable_t)(unsigned char *sound_engine, bool state);
|
||||||
|
static SoundEngine_enable_t SoundEngine_enable = (SoundEngine_enable_t) 0x6776c;
|
||||||
|
|
||||||
|
typedef void (*SoundEngine_update_t)(unsigned char *sound_engine, unsigned char *listener_mob, float listener_angle);
|
||||||
|
static SoundEngine_update_t SoundEngine_update = (SoundEngine_update_t) 0x67778;
|
||||||
|
|
||||||
|
static uint32_t SoundEngine_minecraft_property_offset = 0xa08; // Minecraft *
|
||||||
|
static uint32_t SoundEngine_options_property_offset = 0x4; // Options *
|
||||||
|
|
||||||
// Method That Require C++ Types
|
// Method That Require C++ Types
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
@ -550,6 +575,14 @@ static SelectWorldScreen_getUniqueLevelName_t SelectWorldScreen_getUniqueLevelNa
|
|||||||
|
|
||||||
static SelectWorldScreen_getUniqueLevelName_t Touch_SelectWorldScreen_getUniqueLevelName = (SelectWorldScreen_getUniqueLevelName_t) 0x3d82c;
|
static SelectWorldScreen_getUniqueLevelName_t Touch_SelectWorldScreen_getUniqueLevelName = (SelectWorldScreen_getUniqueLevelName_t) 0x3d82c;
|
||||||
|
|
||||||
|
// SoundEngine
|
||||||
|
|
||||||
|
typedef void (*SoundEngine_playUI_t)(unsigned char *sound_engine, std::string const& name, float pitch, float volume);
|
||||||
|
static SoundEngine_playUI_t SoundEngine_playUI = (SoundEngine_playUI_t) 0x67864;
|
||||||
|
|
||||||
|
typedef void (*SoundEngine_play_t)(unsigned char *sound_engine, std::string const& name, float x, float y, float z, float pitch, float volume);
|
||||||
|
static SoundEngine_play_t SoundEngine_play = (SoundEngine_play_t) 0x67860;
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
|
|
||||||
typedef std::string (*Common_getGameVersionString_t)(std::string const& version_suffix);
|
typedef std::string (*Common_getGameVersionString_t)(std::string const& version_suffix);
|
Loading…
Reference in New Issue
Block a user