Compare commits
28 Commits
871288ee12
...
b2c13c8257
Author | SHA1 | Date | |
---|---|---|---|
b2c13c8257 | |||
2eb6a1c5be | |||
ef3292c5e0 | |||
67ceb4ad00 | |||
e1d9fc492b | |||
acec86b9b5 | |||
66d2e43f55 | |||
596ff01f75 | |||
57aed4d0b3 | |||
fd26000fd4 | |||
454734ab68 | |||
d3b70878be | |||
7f9d1d843e | |||
900169a728 | |||
633b165af0 | |||
86e8c0dd67 | |||
332acd49fb | |||
c2750bbaec | |||
70ef421780 | |||
ed59e19c52 | |||
dd760cc6f2 | |||
00f90afc2a | |||
4a91937b0a | |||
a6cc0b88b5 | |||
0b542701c5 | |||
fc7ecd528a | |||
2785e3f138 | |||
386f52a85f |
7
.gitmodules
vendored
7
.gitmodules
vendored
@ -1,9 +1,6 @@
|
||||
[submodule "dependencies/glfw/src"]
|
||||
path = dependencies/glfw/src
|
||||
url = https://github.com/glfw/glfw.git
|
||||
[submodule "dependencies/zenity/src"]
|
||||
path = dependencies/zenity/src
|
||||
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/zenity.git
|
||||
[submodule "dependencies/LIEF/src"]
|
||||
path = dependencies/LIEF/src
|
||||
url = https://github.com/lief-project/LIEF.git
|
||||
@ -23,3 +20,7 @@
|
||||
[submodule "dependencies/runtime/src"]
|
||||
path = dependencies/runtime/src
|
||||
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/runtime.git
|
||||
[submodule "dependencies/imgui/src"]
|
||||
path = dependencies/imgui/src
|
||||
url = https://github.com/ocornut/imgui.git
|
||||
ignore = dirty
|
||||
|
@ -1,12 +1,9 @@
|
||||
# Read Hex Data
|
||||
file(READ "${EMBED_IN}" data HEX)
|
||||
|
||||
# Convert Hex Data For C Compatibility
|
||||
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," data "${data}")
|
||||
|
||||
# Get C Name
|
||||
cmake_path(GET EMBED_OUT STEM name)
|
||||
|
||||
# Write Data
|
||||
file(WRITE "${EMBED_OUT}"
|
||||
"#include <stddef.h>\n"
|
||||
|
@ -16,13 +16,17 @@ function(embed_resource target file)
|
||||
cmake_path(GET file FILENAME name)
|
||||
string(MAKE_C_IDENTIFIER "${name}" name)
|
||||
# Add Command
|
||||
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${name}.c"
|
||||
set(in "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
|
||||
set(out "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
|
||||
set(script "${util_list_dir}/embed-resource.cmake")
|
||||
add_custom_command(OUTPUT "${out}"
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
ARGS "-DEMBED_IN=${CMAKE_CURRENT_SOURCE_DIR}/${file}" "-DEMBED_OUT=${CMAKE_CURRENT_BINARY_DIR}/${name}.c" "-P" "${util_list_dir}/embed-resource.cmake"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${file}" "${util_list_dir}/embed-resource.cmake"
|
||||
ARGS "-DEMBED_IN=${in}" "-DEMBED_OUT=${out}" "-P" "${script}"
|
||||
DEPENDS "${in}" "${script}"
|
||||
VERBATIM
|
||||
)
|
||||
# Add To Target
|
||||
target_sources("${target}" PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
|
||||
target_sources("${target}" PRIVATE "${out}")
|
||||
endfunction()
|
||||
|
||||
# Nicer Output
|
||||
@ -31,3 +35,45 @@ function(message log_level)
|
||||
_message("${log_level}" ${ARGN})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Exporting Targets And Headers
|
||||
macro(_get_sdk_header_dir target)
|
||||
set(sdk_dir "${MCPI_SDK_INCLUDE_DIR}/${target}")
|
||||
endmacro()
|
||||
function(setup_header_dirs target)
|
||||
_get_sdk_header_dir("${target}")
|
||||
# Get Header Type
|
||||
set(header_type "PUBLIC")
|
||||
get_target_property(type "${target}" TYPE)
|
||||
if ("${type}" STREQUAL "INTERFACE_LIBRARY")
|
||||
set(header_type "INTERFACE")
|
||||
endif()
|
||||
# Loop
|
||||
foreach(dir IN LISTS ARGN)
|
||||
# Add To Target
|
||||
target_include_directories("${target}" "${header_type}" "$<BUILD_INTERFACE:${dir}>")
|
||||
# Add To SDK
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(
|
||||
DIRECTORY "${dir}/"
|
||||
DESTINATION "${sdk_dir}"
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
# Add SDK Headers To Target
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
target_include_directories("${target}" "${header_type}" "$<INSTALL_INTERFACE:${sdk_dir}>")
|
||||
endif()
|
||||
endfunction()
|
||||
function(setup_library target should_install should_export)
|
||||
# Install
|
||||
if(should_install)
|
||||
install(TARGETS "${target}" DESTINATION "${MCPI_LIB_DIR}")
|
||||
endif()
|
||||
# SDK
|
||||
if(should_export AND BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS "${target}" EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
endif()
|
||||
endfunction()
|
12
dependencies/CMakeLists.txt
vendored
12
dependencies/CMakeLists.txt
vendored
@ -8,10 +8,6 @@ endif()
|
||||
if(BUILD_ARM_COMPONENTS AND NOT MCPI_OPEN_SOURCE_ONLY)
|
||||
add_subdirectory(minecraft-pi)
|
||||
endif()
|
||||
# Zenity (Minimal Build)
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
add_subdirectory(zenity)
|
||||
endif()
|
||||
# LIEF
|
||||
if(BUILD_NATIVE_COMPONENTS OR BUILD_MEDIA_LAYER_CORE)
|
||||
add_subdirectory(LIEF)
|
||||
@ -19,12 +15,16 @@ endif()
|
||||
# Extra Runtime
|
||||
add_subdirectory(runtime)
|
||||
# GLFW
|
||||
if(BUILD_MEDIA_LAYER_CORE)
|
||||
if(BUILD_NATIVE_COMPONENTS OR BUILD_MEDIA_LAYER_CORE)
|
||||
add_subdirectory(glfw)
|
||||
endif()
|
||||
# ImGui
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
add_subdirectory(imgui)
|
||||
endif()
|
||||
# UTF8-CPP
|
||||
add_subdirectory(utf8cpp)
|
||||
# Symbol Prcoessor
|
||||
# Symbol Processor
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
add_subdirectory(symbol-processor)
|
||||
endif()
|
||||
|
5
dependencies/LIEF/CMakeLists.txt
vendored
5
dependencies/LIEF/CMakeLists.txt
vendored
@ -29,10 +29,7 @@ add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||
unset(MESSAGE_QUIET)
|
||||
|
||||
# Install
|
||||
install(TARGETS LIB_LIEF DESTINATION "${MCPI_LIB_DIR}")
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS LIB_LIEF EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
endif()
|
||||
setup_library(LIB_LIEF TRUE TRUE)
|
||||
|
||||
# License
|
||||
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/LIEF")
|
||||
|
4
dependencies/glfw/CMakeLists.txt
vendored
4
dependencies/glfw/CMakeLists.txt
vendored
@ -21,7 +21,7 @@ add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||
unset(MESSAGE_QUIET)
|
||||
|
||||
# Install
|
||||
install(TARGETS glfw DESTINATION "${MCPI_LIB_DIR}")
|
||||
setup_library(glfw TRUE FALSE)
|
||||
|
||||
# License
|
||||
install(FILES src/LICENSE.md DESTINATION "${MCPI_LEGAL_DIR}/glfw")
|
||||
install(FILES src/LICENSE.md DESTINATION "${MCPI_LEGAL_DIR}/GLFW")
|
||||
|
2
dependencies/glfw/src
vendored
2
dependencies/glfw/src
vendored
@ -1 +1 @@
|
||||
Subproject commit 7b6aead9fb88b3623e3b3725ebb42670cbe4c579
|
||||
Subproject commit b35641f4a3c62aa86a0b3c983d163bc0fe36026d
|
50
dependencies/imgui/CMakeLists.txt
vendored
Normal file
50
dependencies/imgui/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
project(imgui)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w)
|
||||
|
||||
## ImGui
|
||||
|
||||
# Build
|
||||
add_library(imgui SHARED
|
||||
src/imgui.cpp
|
||||
src/imgui_draw.cpp
|
||||
src/imgui_tables.cpp
|
||||
src/imgui_widgets.cpp
|
||||
src/misc/cpp/imgui_stdlib.cpp
|
||||
src/backends/imgui_impl_glfw.cpp
|
||||
src/backends/imgui_impl_opengl2.cpp
|
||||
)
|
||||
setup_header_dirs(imgui
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/backends"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/misc/cpp"
|
||||
)
|
||||
find_package(OpenGL REQUIRED)
|
||||
target_link_libraries(imgui PUBLIC glfw OpenGL::GL)
|
||||
|
||||
# Fonts
|
||||
embed_resource(imgui src/misc/fonts/Roboto-Medium.ttf)
|
||||
embed_resource(imgui src/misc/fonts/Cousine-Regular.ttf)
|
||||
|
||||
# Configure
|
||||
target_compile_definitions(imgui PUBLIC
|
||||
IMGUI_DISABLE_DEMO_WINDOWS
|
||||
IMGUI_DISABLE_DEBUG_TOOLS
|
||||
IMGUI_DISABLE_DEFAULT_FONT
|
||||
IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
)
|
||||
|
||||
# Patch
|
||||
execute_process(
|
||||
COMMAND "patch" "-p1" "--forward" "--reject-file=-"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/fix-hidpi.patch"
|
||||
OUTPUT_QUIET
|
||||
)
|
||||
|
||||
# Install
|
||||
setup_library(imgui TRUE TRUE)
|
||||
|
||||
# License
|
||||
install(FILES src/LICENSE.txt src/docs/FONTS.md DESTINATION "${MCPI_LEGAL_DIR}/ImGui")
|
55
dependencies/imgui/fix-hidpi.patch
vendored
Normal file
55
dependencies/imgui/fix-hidpi.patch
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
--- a/backends/imgui_impl_glfw.cpp
|
||||
+++ b/backends/imgui_impl_glfw.cpp
|
||||
@@ -422,6 +422,21 @@ void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
|
||||
io.AddFocusEvent(focused != 0);
|
||||
}
|
||||
|
||||
+static void ImGui_ImplGlfw_ScaleMousePos(GLFWwindow* window, double &x, double &y) {
|
||||
+ // Get Window Size
|
||||
+ int window_width, window_height;
|
||||
+ glfwGetWindowSize(window, &window_width, &window_height);
|
||||
+ if (window_width <= 0 || window_height <= 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Get Framebuffer Size
|
||||
+ int framebuffer_width, framebuffer_height;
|
||||
+ glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
|
||||
+ // Multiply
|
||||
+ x *= double(framebuffer_width) / double(window_width);
|
||||
+ y *= double(framebuffer_height) / double(window_height);
|
||||
+}
|
||||
+
|
||||
void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
@@ -429,6 +444,7 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
||||
bd->PrevUserCallbackCursorPos(window, x, y);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
+ ImGui_ImplGlfw_ScaleMousePos(window, x, y);
|
||||
io.AddMousePosEvent((float)x, (float)y);
|
||||
bd->LastValidMousePos = ImVec2((float)x, (float)y);
|
||||
}
|
||||
@@ -738,6 +754,7 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
{
|
||||
double mouse_x, mouse_y;
|
||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||
+ ImGui_ImplGlfw_ScaleMousePos(window, mouse_x, mouse_y);
|
||||
bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
|
||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||
}
|
||||
@@ -831,13 +848,9 @@ void ImGui_ImplGlfw_NewFrame()
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?");
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
- int w, h;
|
||||
int display_w, display_h;
|
||||
- glfwGetWindowSize(bd->Window, &w, &h);
|
||||
glfwGetFramebufferSize(bd->Window, &display_w, &display_h);
|
||||
- io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
- if (w > 0 && h > 0)
|
||||
- io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);
|
||||
+ io.DisplaySize = ImVec2((float)display_w, (float)display_h);
|
||||
|
||||
// Setup time step
|
||||
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
|
1
dependencies/imgui/src
vendored
Submodule
1
dependencies/imgui/src
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 551b6c4d662a3938f0cd197e79cc29922feec1ff
|
8
dependencies/runtime/CMakeLists.txt
vendored
8
dependencies/runtime/CMakeLists.txt
vendored
@ -10,4 +10,10 @@ if(NOT BUILD_NATIVE_COMPONENTS)
|
||||
endif()
|
||||
|
||||
# Build
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(src)
|
||||
|
||||
# RPath
|
||||
if(TARGET runtime)
|
||||
set_target_properties(runtime PROPERTIES INSTALL_RPATH "$ORIGIN/../lib/native")
|
||||
target_link_options(runtime PRIVATE "LINKER:--disable-new-dtags")
|
||||
endif()
|
2
dependencies/runtime/src
vendored
2
dependencies/runtime/src
vendored
@ -1 +1 @@
|
||||
Subproject commit b42021ba5d45c29e22cbdd887e2fae5a1c1334a1
|
||||
Subproject commit 043d926f32a3315d92bce1d9bbb0ccdcf99c11a2
|
16
dependencies/stb_image/CMakeLists.txt
vendored
16
dependencies/stb_image/CMakeLists.txt
vendored
@ -7,24 +7,12 @@ add_compile_options(-w)
|
||||
|
||||
# Build
|
||||
add_library(stb_image SHARED src/stb_image_impl.c)
|
||||
target_include_directories(
|
||||
stb_image
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/stb_image>"
|
||||
)
|
||||
target_link_libraries(stb_image PRIVATE m)
|
||||
target_compile_definitions(stb_image PUBLIC STBI_ONLY_PNG)
|
||||
setup_header_dirs(stb_image "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
||||
# Install
|
||||
install(TARGETS stb_image DESTINATION "${MCPI_LIB_DIR}")
|
||||
install(
|
||||
DIRECTORY "include/"
|
||||
DESTINATION "${MCPI_SDK_INCLUDE_DIR}/stb_image"
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
)
|
||||
install(TARGETS stb_image EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
setup_library(stb_image TRUE TRUE)
|
||||
|
||||
# License
|
||||
install(FILES include/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/stb_image")
|
||||
|
2
dependencies/utf8cpp/CMakeLists.txt
vendored
2
dependencies/utf8cpp/CMakeLists.txt
vendored
@ -9,4 +9,4 @@ add_compile_options(-w)
|
||||
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||
|
||||
# License
|
||||
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/utf8cpp")
|
||||
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/UTF8-CPP")
|
||||
|
20
dependencies/zenity/CMakeLists.txt
vendored
20
dependencies/zenity/CMakeLists.txt
vendored
@ -1,20 +0,0 @@
|
||||
project(zenity)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w)
|
||||
|
||||
## Zenity
|
||||
|
||||
# Download
|
||||
set(MESSAGE_QUIET TRUE)
|
||||
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||
unset(MESSAGE_QUIET)
|
||||
|
||||
# Ensure Build
|
||||
add_custom_target(zenity-build ALL DEPENDS zenity)
|
||||
|
||||
# Install
|
||||
install(TARGETS zenity DESTINATION "${MCPI_BIN_DIR}")
|
||||
|
||||
# License
|
||||
install(FILES src/COPYING DESTINATION "${MCPI_LEGAL_DIR}/zenity")
|
1
dependencies/zenity/src
vendored
1
dependencies/zenity/src
vendored
@ -1 +0,0 @@
|
||||
Subproject commit a7496461161c917878d58131711425e7c8e59436
|
@ -52,6 +52,7 @@
|
||||
* `Increase Render Chunk Size` (Enabled By Default)
|
||||
* `Proper Entity Shading` (Enabled By Default)
|
||||
* `Fix Sugar Position In Hand` (Enabled By Default)
|
||||
* `Fix Reloading Textures On Resize` (Enabled By Default)
|
||||
* Existing Functionality (All Enabled By Default)
|
||||
* `Fix Screen Rendering When Hiding HUD`
|
||||
* `Sanitize Usernames`
|
||||
@ -70,14 +71,31 @@
|
||||
* `Screenshot Support`
|
||||
* `Fix Camera Functionality`
|
||||
* `Property Scale Animated Textures`
|
||||
* `Enable Text Input`
|
||||
* `Update Default Options`
|
||||
* `Fix options.txt Loading/Saving`
|
||||
* `Extend Supported Keycodes`
|
||||
* Split Up `Remove Creative Mode Restrictions` Feature Flag
|
||||
* `Remove Creative Mode Restrictions` (Disabled By Default)
|
||||
* `Display Slot Count In Creative Mode` (Disabled By Default)
|
||||
* `Force Survival Mode Inventory UI` (Disabled By Default)
|
||||
* `Force Survival Mode Inventory Behavior` (Disabled By Default)
|
||||
* `Maximize Creative Mode Inventory Stack Size` (Disabled By Default)
|
||||
* Rename `Disable Buggy Held Item Caching` Feature Flag To `Fix Held Item Caching`
|
||||
* Rename `Disable 'gui_blocks' Atlas` Feature Flag To `Regenerate "gui_blocks" Atlas`
|
||||
* Split Up `Miscellaneous Input Fixes` Feature Flag
|
||||
* `Fix Escape Key Handling` (Enabled By Default)
|
||||
* `Stop Locked Mouse From Interacting With HUD` (Enabled By Default)
|
||||
* Rename Feature Flags
|
||||
* `Disable Buggy Held Item Caching` To `Fix Held Item Caching`
|
||||
* `Disable 'gui_blocks' Atlas` To `Regenerate "gui_blocks" Atlas`
|
||||
* `Fix Sign Placement` To `Enable Sign Screen`
|
||||
* `Force Touch GUI Inventory` To `Force Touch UI Inventory`
|
||||
* `Full Touch GUI` To `Full Touch UI`
|
||||
* `Force Touch GUI Button Behavior` To `Force Touch UI Button Behavior`
|
||||
* `Remove Forced GUI Lag (Can Break Joining Servers)` To `Remove Forced UI Lag (Can Break Joining Servers)`
|
||||
* `Hide Block Outline When GUI Is Hidden` To `Hide Block Outline When UI Is Hidden`
|
||||
* `Fix Camera Functionality` To `Add Camera Functionality`
|
||||
* `Fix Camera Rendering` To `Enable Camera Rendering`
|
||||
* `Fix Camera Legs` To `Render Camera Legs`
|
||||
* Add Milk Buckets
|
||||
* Included In The `Add Buckets` Feature Flag
|
||||
* Removed `Property Scale Animated Textures` Feature Flag
|
||||
|
@ -27,7 +27,7 @@ The AppImage requires Debian Bullseye or higher. This is equivalent to Ubuntu 20
|
||||
|
||||
It also requires some additional packages. To install them, run:
|
||||
```sh
|
||||
sudo apt install -y libfuse2 libgtk-3-0 libopenal1 libglib2.0-0
|
||||
sudo apt install -y libfuse2 libopenal1 libglib2.0-0
|
||||
```
|
||||
</details>
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
// Headers
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/patch.h>
|
||||
#include <libreborn/util.h>
|
||||
#include <libreborn/string.h>
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/chat/chat.h>
|
||||
#include <mods/misc/misc.h>
|
||||
#include <mods/server/server.h>
|
||||
|
@ -1,628 +1,540 @@
|
||||
// Headers
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/patch.h>
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
// The Actual Mod
|
||||
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(FillingContainer *filling_container) {
|
||||
ItemInstance *fire_instance = new ItemInstance;
|
||||
ALLOC_CHECK(fire_instance);
|
||||
fire_instance->count = 255;
|
||||
fire_instance->auxiliary = 0;
|
||||
fire_instance->id = 51;
|
||||
filling_container->addItem(fire_instance);
|
||||
|
||||
ItemInstance *mushroomStew_instance = new ItemInstance;
|
||||
ALLOC_CHECK(mushroomStew_instance);
|
||||
mushroomStew_instance->count = 255;
|
||||
mushroomStew_instance->auxiliary = 0;
|
||||
mushroomStew_instance->id = 282;
|
||||
filling_container->addItem(mushroomStew_instance);
|
||||
|
||||
ItemInstance *steak_instance = new ItemInstance;
|
||||
ALLOC_CHECK(steak_instance);
|
||||
steak_instance->count = 255;
|
||||
steak_instance->auxiliary = 0;
|
||||
steak_instance->id = 364;
|
||||
filling_container->addItem(steak_instance);
|
||||
|
||||
ItemInstance *cookedChicken_instance = new ItemInstance;
|
||||
ALLOC_CHECK(cookedChicken_instance);
|
||||
cookedChicken_instance->count = 255;
|
||||
cookedChicken_instance->auxiliary = 0;
|
||||
cookedChicken_instance->id = 366;
|
||||
filling_container->addItem(cookedChicken_instance);
|
||||
|
||||
ItemInstance *porkCooked_instance = new ItemInstance;
|
||||
ALLOC_CHECK(porkCooked_instance);
|
||||
porkCooked_instance->count = 255;
|
||||
porkCooked_instance->auxiliary = 0;
|
||||
porkCooked_instance->id = 320;
|
||||
filling_container->addItem(porkCooked_instance);
|
||||
|
||||
ItemInstance *apple_instance = new ItemInstance;
|
||||
ALLOC_CHECK(apple_instance);
|
||||
apple_instance->count = 255;
|
||||
apple_instance->auxiliary = 0;
|
||||
apple_instance->id = 260;
|
||||
filling_container->addItem(apple_instance);
|
||||
|
||||
ItemInstance *tallGrass_instance = new ItemInstance;
|
||||
ALLOC_CHECK(tallGrass_instance);
|
||||
tallGrass_instance->count = 255;
|
||||
tallGrass_instance->auxiliary = 0;
|
||||
tallGrass_instance->id = 31;
|
||||
filling_container->addItem(tallGrass_instance);
|
||||
|
||||
ItemInstance *crops_instance = new ItemInstance;
|
||||
ALLOC_CHECK(crops_instance);
|
||||
crops_instance->count = 255;
|
||||
crops_instance->auxiliary = 0;
|
||||
crops_instance->id = 59;
|
||||
filling_container->addItem(crops_instance);
|
||||
|
||||
ItemInstance *farmland_instance = new ItemInstance;
|
||||
ALLOC_CHECK(farmland_instance);
|
||||
farmland_instance->count = 255;
|
||||
farmland_instance->auxiliary = 0;
|
||||
farmland_instance->id = 60;
|
||||
filling_container->addItem(farmland_instance);
|
||||
|
||||
ItemInstance *activeFurnace_instance = new ItemInstance;
|
||||
ALLOC_CHECK(activeFurnace_instance);
|
||||
activeFurnace_instance->count = 255;
|
||||
activeFurnace_instance->auxiliary = 0;
|
||||
activeFurnace_instance->id = 62;
|
||||
filling_container->addItem(activeFurnace_instance);
|
||||
|
||||
ItemInstance *ironDoor_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironDoor_instance);
|
||||
ironDoor_instance->count = 255;
|
||||
ironDoor_instance->auxiliary = 0;
|
||||
ironDoor_instance->id = 330;
|
||||
filling_container->addItem(ironDoor_instance);
|
||||
|
||||
ItemInstance *activeRedstoneOre_instance = new ItemInstance;
|
||||
ALLOC_CHECK(activeRedstoneOre_instance);
|
||||
activeRedstoneOre_instance->count = 255;
|
||||
activeRedstoneOre_instance->auxiliary = 0;
|
||||
activeRedstoneOre_instance->id = 74;
|
||||
filling_container->addItem(activeRedstoneOre_instance);
|
||||
|
||||
ItemInstance *pumkinStem_instance = new ItemInstance;
|
||||
ALLOC_CHECK(pumkinStem_instance);
|
||||
pumkinStem_instance->count = 255;
|
||||
pumkinStem_instance->auxiliary = 0;
|
||||
pumkinStem_instance->id = 105;
|
||||
filling_container->addItem(pumkinStem_instance);
|
||||
|
||||
ItemInstance *newGrass_instance = new ItemInstance;
|
||||
ALLOC_CHECK(newGrass_instance);
|
||||
newGrass_instance->count = 255;
|
||||
newGrass_instance->auxiliary = 0;
|
||||
newGrass_instance->id = 253;
|
||||
filling_container->addItem(newGrass_instance);
|
||||
|
||||
ItemInstance *reserved6_instance = new ItemInstance;
|
||||
ALLOC_CHECK(reserved6_instance);
|
||||
reserved6_instance->count = 255;
|
||||
reserved6_instance->auxiliary = 0;
|
||||
reserved6_instance->id = 1;
|
||||
filling_container->addItem(reserved6_instance);
|
||||
|
||||
ItemInstance *doubleStoneSlab_instance = new ItemInstance;
|
||||
ALLOC_CHECK(doubleStoneSlab_instance);
|
||||
doubleStoneSlab_instance->count = 255;
|
||||
doubleStoneSlab_instance->auxiliary = 0;
|
||||
doubleStoneSlab_instance->id = 43;
|
||||
filling_container->addItem(doubleStoneSlab_instance);
|
||||
|
||||
ItemInstance *arrow_instance = new ItemInstance;
|
||||
ALLOC_CHECK(arrow_instance);
|
||||
arrow_instance->count = 255;
|
||||
arrow_instance->auxiliary = 0;
|
||||
arrow_instance->id = 262;
|
||||
filling_container->addItem(arrow_instance);
|
||||
|
||||
ItemInstance *coal_instance = new ItemInstance;
|
||||
ALLOC_CHECK(coal_instance);
|
||||
coal_instance->count = 255;
|
||||
coal_instance->auxiliary = 0;
|
||||
coal_instance->id = 263;
|
||||
filling_container->addItem(coal_instance);
|
||||
|
||||
ItemInstance *diamond_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamond_instance);
|
||||
diamond_instance->count = 255;
|
||||
diamond_instance->auxiliary = 0;
|
||||
diamond_instance->id = 264;
|
||||
filling_container->addItem(diamond_instance);
|
||||
|
||||
ItemInstance *ironIngot_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironIngot_instance);
|
||||
ironIngot_instance->count = 255;
|
||||
ironIngot_instance->auxiliary = 0;
|
||||
ironIngot_instance->id = 265;
|
||||
filling_container->addItem(ironIngot_instance);
|
||||
|
||||
ItemInstance *goldIngot_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldIngot_instance);
|
||||
goldIngot_instance->count = 255;
|
||||
goldIngot_instance->auxiliary = 0;
|
||||
goldIngot_instance->id = 266;
|
||||
filling_container->addItem(goldIngot_instance);
|
||||
|
||||
ItemInstance *woodSword_instance = new ItemInstance;
|
||||
ALLOC_CHECK(woodSword_instance);
|
||||
woodSword_instance->count = 255;
|
||||
woodSword_instance->auxiliary = 0;
|
||||
woodSword_instance->id = 268;
|
||||
filling_container->addItem(woodSword_instance);
|
||||
|
||||
ItemInstance *woodShovel_instance = new ItemInstance;
|
||||
ALLOC_CHECK(woodShovel_instance);
|
||||
woodShovel_instance->count = 255;
|
||||
woodShovel_instance->auxiliary = 0;
|
||||
woodShovel_instance->id = 269;
|
||||
filling_container->addItem(woodShovel_instance);
|
||||
|
||||
ItemInstance *woodPickaxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(woodPickaxe_instance);
|
||||
woodPickaxe_instance->count = 255;
|
||||
woodPickaxe_instance->auxiliary = 0;
|
||||
woodPickaxe_instance->id = 270;
|
||||
filling_container->addItem(woodPickaxe_instance);
|
||||
|
||||
ItemInstance *woodAxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(woodAxe_instance);
|
||||
woodAxe_instance->count = 255;
|
||||
woodAxe_instance->auxiliary = 0;
|
||||
woodAxe_instance->id = 271;
|
||||
filling_container->addItem(woodAxe_instance);
|
||||
|
||||
ItemInstance *stoneSword_instance = new ItemInstance;
|
||||
ALLOC_CHECK(stoneSword_instance);
|
||||
stoneSword_instance->count = 255;
|
||||
stoneSword_instance->auxiliary = 0;
|
||||
stoneSword_instance->id = 272;
|
||||
filling_container->addItem(stoneSword_instance);
|
||||
|
||||
ItemInstance *stoneShovel_instance = new ItemInstance;
|
||||
ALLOC_CHECK(stoneShovel_instance);
|
||||
stoneShovel_instance->count = 255;
|
||||
stoneShovel_instance->auxiliary = 0;
|
||||
stoneShovel_instance->id = 273;
|
||||
filling_container->addItem(stoneShovel_instance);
|
||||
|
||||
ItemInstance *stonePickaxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(stonePickaxe_instance);
|
||||
stonePickaxe_instance->count = 255;
|
||||
stonePickaxe_instance->auxiliary = 0;
|
||||
stonePickaxe_instance->id = 274;
|
||||
filling_container->addItem(stonePickaxe_instance);
|
||||
|
||||
ItemInstance *stoneAxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(stoneAxe_instance);
|
||||
stoneAxe_instance->count = 255;
|
||||
stoneAxe_instance->auxiliary = 0;
|
||||
stoneAxe_instance->id = 275;
|
||||
filling_container->addItem(stoneAxe_instance);
|
||||
|
||||
ItemInstance *shovelIron_instance = new ItemInstance;
|
||||
ALLOC_CHECK(shovelIron_instance);
|
||||
shovelIron_instance->count = 255;
|
||||
shovelIron_instance->auxiliary = 0;
|
||||
shovelIron_instance->id = 256;
|
||||
filling_container->addItem(shovelIron_instance);
|
||||
|
||||
ItemInstance *ironPick_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironPick_instance);
|
||||
ironPick_instance->count = 255;
|
||||
ironPick_instance->auxiliary = 0;
|
||||
ironPick_instance->id = 257;
|
||||
filling_container->addItem(ironPick_instance);
|
||||
|
||||
ItemInstance *ironAxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironAxe_instance);
|
||||
ironAxe_instance->count = 255;
|
||||
ironAxe_instance->auxiliary = 0;
|
||||
ironAxe_instance->id = 258;
|
||||
filling_container->addItem(ironAxe_instance);
|
||||
|
||||
ItemInstance *diamondSword_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondSword_instance);
|
||||
diamondSword_instance->count = 255;
|
||||
diamondSword_instance->auxiliary = 0;
|
||||
diamondSword_instance->id = 276;
|
||||
filling_container->addItem(diamondSword_instance);
|
||||
|
||||
ItemInstance *diamondShovel_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondShovel_instance);
|
||||
diamondShovel_instance->count = 255;
|
||||
diamondShovel_instance->auxiliary = 0;
|
||||
diamondShovel_instance->id = 277;
|
||||
filling_container->addItem(diamondShovel_instance);
|
||||
|
||||
ItemInstance *diamondPickaxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondPickaxe_instance);
|
||||
diamondPickaxe_instance->count = 255;
|
||||
diamondPickaxe_instance->auxiliary = 0;
|
||||
diamondPickaxe_instance->id = 278;
|
||||
filling_container->addItem(diamondPickaxe_instance);
|
||||
|
||||
ItemInstance *diamondAxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondAxe_instance);
|
||||
diamondAxe_instance->count = 255;
|
||||
diamondAxe_instance->auxiliary = 0;
|
||||
diamondAxe_instance->id = 279;
|
||||
filling_container->addItem(diamondAxe_instance);
|
||||
|
||||
ItemInstance *magicWand_instance = new ItemInstance;
|
||||
ALLOC_CHECK(magicWand_instance);
|
||||
magicWand_instance->count = 255;
|
||||
magicWand_instance->auxiliary = 0;
|
||||
magicWand_instance->id = 280;
|
||||
filling_container->addItem(magicWand_instance);
|
||||
|
||||
ItemInstance *bowl_instance = new ItemInstance;
|
||||
ALLOC_CHECK(bowl_instance);
|
||||
bowl_instance->count = 255;
|
||||
bowl_instance->auxiliary = 0;
|
||||
bowl_instance->id = 281;
|
||||
filling_container->addItem(bowl_instance);
|
||||
|
||||
ItemInstance *goldSword_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldSword_instance);
|
||||
goldSword_instance->count = 255;
|
||||
goldSword_instance->auxiliary = 0;
|
||||
goldSword_instance->id = 283;
|
||||
filling_container->addItem(goldSword_instance);
|
||||
|
||||
ItemInstance *goldShovel_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldShovel_instance);
|
||||
goldShovel_instance->count = 255;
|
||||
goldShovel_instance->auxiliary = 0;
|
||||
goldShovel_instance->id = 284;
|
||||
filling_container->addItem(goldShovel_instance);
|
||||
|
||||
ItemInstance *goldPickaxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldPickaxe_instance);
|
||||
goldPickaxe_instance->count = 255;
|
||||
goldPickaxe_instance->auxiliary = 0;
|
||||
goldPickaxe_instance->id = 285;
|
||||
filling_container->addItem(goldPickaxe_instance);
|
||||
|
||||
ItemInstance *goldAxe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldAxe_instance);
|
||||
goldAxe_instance->count = 255;
|
||||
goldAxe_instance->auxiliary = 0;
|
||||
goldAxe_instance->id = 286;
|
||||
filling_container->addItem(goldAxe_instance);
|
||||
|
||||
ItemInstance *string_instance = new ItemInstance;
|
||||
ALLOC_CHECK(string_instance);
|
||||
string_instance->count = 255;
|
||||
string_instance->auxiliary = 0;
|
||||
string_instance->id = 287;
|
||||
filling_container->addItem(string_instance);
|
||||
|
||||
ItemInstance *feather_instance = new ItemInstance;
|
||||
ALLOC_CHECK(feather_instance);
|
||||
feather_instance->count = 255;
|
||||
feather_instance->auxiliary = 0;
|
||||
feather_instance->id = 288;
|
||||
filling_container->addItem(feather_instance);
|
||||
|
||||
ItemInstance *gunpowder_instance = new ItemInstance;
|
||||
ALLOC_CHECK(gunpowder_instance);
|
||||
gunpowder_instance->count = 255;
|
||||
gunpowder_instance->auxiliary = 0;
|
||||
gunpowder_instance->id = 289;
|
||||
filling_container->addItem(gunpowder_instance);
|
||||
|
||||
ItemInstance *woodHoe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(woodHoe_instance);
|
||||
woodHoe_instance->count = 255;
|
||||
woodHoe_instance->auxiliary = 0;
|
||||
woodHoe_instance->id = 290;
|
||||
filling_container->addItem(woodHoe_instance);
|
||||
|
||||
ItemInstance *stoneHoe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(stoneHoe_instance);
|
||||
stoneHoe_instance->count = 255;
|
||||
stoneHoe_instance->auxiliary = 0;
|
||||
stoneHoe_instance->id = 291;
|
||||
filling_container->addItem(stoneHoe_instance);
|
||||
|
||||
ItemInstance *flint1_instance = new ItemInstance;
|
||||
ALLOC_CHECK(flint1_instance);
|
||||
flint1_instance->count = 255;
|
||||
flint1_instance->auxiliary = 0;
|
||||
flint1_instance->id = 292;
|
||||
filling_container->addItem(flint1_instance);
|
||||
|
||||
ItemInstance *diamondHoe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondHoe_instance);
|
||||
diamondHoe_instance->count = 255;
|
||||
diamondHoe_instance->auxiliary = 0;
|
||||
diamondHoe_instance->id = 293;
|
||||
filling_container->addItem(diamondHoe_instance);
|
||||
|
||||
ItemInstance *goldHoe_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldHoe_instance);
|
||||
goldHoe_instance->count = 255;
|
||||
goldHoe_instance->auxiliary = 0;
|
||||
goldHoe_instance->id = 294;
|
||||
filling_container->addItem(goldHoe_instance);
|
||||
|
||||
ItemInstance *seeds_instance = new ItemInstance;
|
||||
ALLOC_CHECK(seeds_instance);
|
||||
seeds_instance->count = 255;
|
||||
seeds_instance->auxiliary = 0;
|
||||
seeds_instance->id = 295;
|
||||
filling_container->addItem(seeds_instance);
|
||||
|
||||
ItemInstance *wheat_instance = new ItemInstance;
|
||||
ALLOC_CHECK(wheat_instance);
|
||||
wheat_instance->count = 255;
|
||||
wheat_instance->auxiliary = 0;
|
||||
wheat_instance->id = 296;
|
||||
filling_container->addItem(wheat_instance);
|
||||
|
||||
ItemInstance *bread_instance = new ItemInstance;
|
||||
ALLOC_CHECK(bread_instance);
|
||||
bread_instance->count = 255;
|
||||
bread_instance->auxiliary = 0;
|
||||
bread_instance->id = 297;
|
||||
filling_container->addItem(bread_instance);
|
||||
|
||||
ItemInstance *diamondHelm_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondHelm_instance);
|
||||
diamondHelm_instance->count = 255;
|
||||
diamondHelm_instance->auxiliary = 0;
|
||||
diamondHelm_instance->id = 310;
|
||||
filling_container->addItem(diamondHelm_instance);
|
||||
|
||||
ItemInstance *diamondChest_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondChest_instance);
|
||||
diamondChest_instance->count = 255;
|
||||
diamondChest_instance->auxiliary = 0;
|
||||
diamondChest_instance->id = 311;
|
||||
filling_container->addItem(diamondChest_instance);
|
||||
|
||||
ItemInstance *diamondLeg_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondLeg_instance);
|
||||
diamondLeg_instance->count = 255;
|
||||
diamondLeg_instance->auxiliary = 0;
|
||||
diamondLeg_instance->id = 312;
|
||||
filling_container->addItem(diamondLeg_instance);
|
||||
|
||||
ItemInstance *diamondBoot_instance = new ItemInstance;
|
||||
ALLOC_CHECK(diamondBoot_instance);
|
||||
diamondBoot_instance->count = 255;
|
||||
diamondBoot_instance->auxiliary = 0;
|
||||
diamondBoot_instance->id = 313;
|
||||
filling_container->addItem(diamondBoot_instance);
|
||||
|
||||
ItemInstance *leatherCap_instance = new ItemInstance;
|
||||
ALLOC_CHECK(leatherCap_instance);
|
||||
leatherCap_instance->count = 255;
|
||||
leatherCap_instance->auxiliary = 0;
|
||||
leatherCap_instance->id = 298;
|
||||
filling_container->addItem(leatherCap_instance);
|
||||
|
||||
ItemInstance *leatherShirt_instance = new ItemInstance;
|
||||
ALLOC_CHECK(leatherShirt_instance);
|
||||
leatherShirt_instance->count = 255;
|
||||
leatherShirt_instance->auxiliary = 0;
|
||||
leatherShirt_instance->id = 299;
|
||||
filling_container->addItem(leatherShirt_instance);
|
||||
|
||||
ItemInstance *leatherPants_instance = new ItemInstance;
|
||||
ALLOC_CHECK(leatherPants_instance);
|
||||
leatherPants_instance->count = 255;
|
||||
leatherPants_instance->auxiliary = 0;
|
||||
leatherPants_instance->id = 300;
|
||||
filling_container->addItem(leatherPants_instance);
|
||||
|
||||
ItemInstance *leatherBoots_instance = new ItemInstance;
|
||||
ALLOC_CHECK(leatherBoots_instance);
|
||||
leatherBoots_instance->count = 255;
|
||||
leatherBoots_instance->auxiliary = 0;
|
||||
leatherBoots_instance->id = 301;
|
||||
filling_container->addItem(leatherBoots_instance);
|
||||
|
||||
ItemInstance *chainHelm_instance = new ItemInstance;
|
||||
ALLOC_CHECK(chainHelm_instance);
|
||||
chainHelm_instance->count = 255;
|
||||
chainHelm_instance->auxiliary = 0;
|
||||
chainHelm_instance->id = 302;
|
||||
filling_container->addItem(chainHelm_instance);
|
||||
|
||||
ItemInstance *chainShirt_instance = new ItemInstance;
|
||||
ALLOC_CHECK(chainShirt_instance);
|
||||
chainShirt_instance->count = 255;
|
||||
chainShirt_instance->auxiliary = 0;
|
||||
chainShirt_instance->id = 303;
|
||||
filling_container->addItem(chainShirt_instance);
|
||||
|
||||
ItemInstance *chainLegs_instance = new ItemInstance;
|
||||
ALLOC_CHECK(chainLegs_instance);
|
||||
chainLegs_instance->count = 255;
|
||||
chainLegs_instance->auxiliary = 0;
|
||||
chainLegs_instance->id = 304;
|
||||
filling_container->addItem(chainLegs_instance);
|
||||
|
||||
ItemInstance *chainBoots_instance = new ItemInstance;
|
||||
ALLOC_CHECK(chainBoots_instance);
|
||||
chainBoots_instance->count = 255;
|
||||
chainBoots_instance->auxiliary = 0;
|
||||
chainBoots_instance->id = 305;
|
||||
filling_container->addItem(chainBoots_instance);
|
||||
|
||||
ItemInstance *goldHelm_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldHelm_instance);
|
||||
goldHelm_instance->count = 255;
|
||||
goldHelm_instance->auxiliary = 0;
|
||||
goldHelm_instance->id = 314;
|
||||
filling_container->addItem(goldHelm_instance);
|
||||
|
||||
ItemInstance *goldChest_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldChest_instance);
|
||||
goldChest_instance->count = 255;
|
||||
goldChest_instance->auxiliary = 0;
|
||||
goldChest_instance->id = 315;
|
||||
filling_container->addItem(goldChest_instance);
|
||||
|
||||
ItemInstance *goldLegs_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldLegs_instance);
|
||||
goldLegs_instance->count = 255;
|
||||
goldLegs_instance->auxiliary = 0;
|
||||
goldLegs_instance->id = 316;
|
||||
filling_container->addItem(goldLegs_instance);
|
||||
|
||||
ItemInstance *goldBoots_instance = new ItemInstance;
|
||||
ALLOC_CHECK(goldBoots_instance);
|
||||
goldBoots_instance->count = 255;
|
||||
goldBoots_instance->auxiliary = 0;
|
||||
goldBoots_instance->id = 317;
|
||||
filling_container->addItem(goldBoots_instance);
|
||||
|
||||
ItemInstance *ironHelm_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironHelm_instance);
|
||||
ironHelm_instance->count = 255;
|
||||
ironHelm_instance->auxiliary = 0;
|
||||
ironHelm_instance->id = 306;
|
||||
filling_container->addItem(ironHelm_instance);
|
||||
|
||||
ItemInstance *ironChest_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironChest_instance);
|
||||
ironChest_instance->count = 255;
|
||||
ironChest_instance->auxiliary = 0;
|
||||
ironChest_instance->id = 307;
|
||||
filling_container->addItem(ironChest_instance);
|
||||
|
||||
ItemInstance *ironLegs_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironLegs_instance);
|
||||
ironLegs_instance->count = 255;
|
||||
ironLegs_instance->auxiliary = 0;
|
||||
ironLegs_instance->id = 308;
|
||||
filling_container->addItem(ironLegs_instance);
|
||||
|
||||
ItemInstance *ironBoots_instance = new ItemInstance;
|
||||
ALLOC_CHECK(ironBoots_instance);
|
||||
ironBoots_instance->count = 255;
|
||||
ironBoots_instance->auxiliary = 0;
|
||||
ironBoots_instance->id = 309;
|
||||
filling_container->addItem(ironBoots_instance);
|
||||
|
||||
ItemInstance *flint2_instance = new ItemInstance;
|
||||
ALLOC_CHECK(flint2_instance);
|
||||
flint2_instance->count = 255;
|
||||
flint2_instance->auxiliary = 0;
|
||||
flint2_instance->id = 318;
|
||||
filling_container->addItem(flint2_instance);
|
||||
|
||||
ItemInstance *porkRaw_instance = new ItemInstance;
|
||||
ALLOC_CHECK(porkRaw_instance);
|
||||
porkRaw_instance->count = 255;
|
||||
porkRaw_instance->auxiliary = 0;
|
||||
porkRaw_instance->id = 319;
|
||||
filling_container->addItem(porkRaw_instance);
|
||||
|
||||
ItemInstance *leather_instance = new ItemInstance;
|
||||
ALLOC_CHECK(leather_instance);
|
||||
leather_instance->count = 255;
|
||||
leather_instance->auxiliary = 0;
|
||||
leather_instance->id = 334;
|
||||
filling_container->addItem(leather_instance);
|
||||
|
||||
ItemInstance *clayBrick_instance = new ItemInstance;
|
||||
ALLOC_CHECK(clayBrick_instance);
|
||||
clayBrick_instance->count = 255;
|
||||
clayBrick_instance->auxiliary = 0;
|
||||
clayBrick_instance->id = 336;
|
||||
filling_container->addItem(clayBrick_instance);
|
||||
|
||||
ItemInstance *clay_instance = new ItemInstance;
|
||||
ALLOC_CHECK(clay_instance);
|
||||
clay_instance->count = 255;
|
||||
clay_instance->auxiliary = 0;
|
||||
clay_instance->id = 337;
|
||||
filling_container->addItem(clay_instance);
|
||||
|
||||
ItemInstance *notepad_instance = new ItemInstance;
|
||||
ALLOC_CHECK(notepad_instance);
|
||||
notepad_instance->count = 255;
|
||||
notepad_instance->auxiliary = 0;
|
||||
notepad_instance->id = 339;
|
||||
filling_container->addItem(notepad_instance);
|
||||
|
||||
ItemInstance *book_instance = new ItemInstance;
|
||||
ALLOC_CHECK(book_instance);
|
||||
book_instance->count = 255;
|
||||
book_instance->auxiliary = 0;
|
||||
book_instance->id = 340;
|
||||
filling_container->addItem(book_instance);
|
||||
|
||||
ItemInstance *slimeball_instance = new ItemInstance;
|
||||
ALLOC_CHECK(slimeball_instance);
|
||||
slimeball_instance->count = 255;
|
||||
slimeball_instance->auxiliary = 0;
|
||||
slimeball_instance->id = 341;
|
||||
filling_container->addItem(slimeball_instance);
|
||||
|
||||
ItemInstance *compass_instance = new ItemInstance;
|
||||
ALLOC_CHECK(compass_instance);
|
||||
compass_instance->count = 255;
|
||||
compass_instance->auxiliary = 0;
|
||||
compass_instance->id = 345;
|
||||
filling_container->addItem(compass_instance);
|
||||
|
||||
ItemInstance *clock_instance = new ItemInstance;
|
||||
ALLOC_CHECK(clock_instance);
|
||||
clock_instance->count = 255;
|
||||
clock_instance->auxiliary = 0;
|
||||
clock_instance->id = 347;
|
||||
filling_container->addItem(clock_instance);
|
||||
|
||||
ItemInstance *glowDust_instance = new ItemInstance;
|
||||
ALLOC_CHECK(glowDust_instance);
|
||||
glowDust_instance->count = 255;
|
||||
glowDust_instance->auxiliary = 0;
|
||||
glowDust_instance->id = 348;
|
||||
filling_container->addItem(glowDust_instance);
|
||||
|
||||
ItemInstance *bone_instance = new ItemInstance;
|
||||
ALLOC_CHECK(bone_instance);
|
||||
bone_instance->count = 255;
|
||||
bone_instance->auxiliary = 0;
|
||||
bone_instance->id = 352;
|
||||
filling_container->addItem(bone_instance);
|
||||
|
||||
ItemInstance *sugar_instance = new ItemInstance;
|
||||
ALLOC_CHECK(sugar_instance);
|
||||
sugar_instance->count = 255;
|
||||
sugar_instance->auxiliary = 0;
|
||||
sugar_instance->id = 353;
|
||||
filling_container->addItem(sugar_instance);
|
||||
|
||||
ItemInstance *melon_instance = new ItemInstance;
|
||||
ALLOC_CHECK(melon_instance);
|
||||
melon_instance->count = 255;
|
||||
melon_instance->auxiliary = 0;
|
||||
melon_instance->id = 360;
|
||||
filling_container->addItem(melon_instance);
|
||||
|
||||
ItemInstance *beefRaw_instance = new ItemInstance;
|
||||
ALLOC_CHECK(beefRaw_instance);
|
||||
beefRaw_instance->count = 255;
|
||||
beefRaw_instance->auxiliary = 0;
|
||||
beefRaw_instance->id = 363;
|
||||
filling_container->addItem(beefRaw_instance);
|
||||
|
||||
ItemInstance *chickenRaw_instance = new ItemInstance;
|
||||
ALLOC_CHECK(chickenRaw_instance);
|
||||
chickenRaw_instance->count = 255;
|
||||
chickenRaw_instance->auxiliary = 0;
|
||||
chickenRaw_instance->id = 365;
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Headers
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/patch.h>
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
// Custom Crafting Recipes
|
||||
|
@ -9,16 +9,23 @@ add_executable(launcher
|
||||
src/bootstrap/debug.cpp
|
||||
src/util/util.cpp
|
||||
src/util/sdk.cpp
|
||||
src/util/env.cpp
|
||||
src/logger/logger.cpp
|
||||
src/logger/crash-report.cpp
|
||||
src/options/parser.cpp
|
||||
src/main.cpp
|
||||
src/ui/frame.cpp
|
||||
src/ui/color.cpp
|
||||
src/client/configuration.cpp
|
||||
src/client/cache.cpp
|
||||
src/client/available-feature-flags # Show In IDE
|
||||
src/client/ui.cpp
|
||||
)
|
||||
target_link_libraries(launcher
|
||||
reborn-util
|
||||
LIB_LIEF
|
||||
imgui
|
||||
trampoline-headers
|
||||
)
|
||||
embed_resource(launcher src/client/available-feature-flags)
|
||||
target_link_libraries(launcher reborn-util LIB_LIEF trampoline-headers)
|
||||
# RPath
|
||||
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
|
||||
target_link_options(launcher PRIVATE "LINKER:--disable-new-dtags")
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/env.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
#include "../util/util.h"
|
||||
|
@ -1,7 +1,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/env.h>
|
||||
#include <libreborn/config.h>
|
||||
#include <libreborn/exec.h>
|
||||
|
||||
#include "../util/util.h"
|
||||
#include "bootstrap.h"
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/exec.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
|
||||
|
@ -2,10 +2,13 @@
|
||||
#include <cerrno>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/util.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
#include "../util/util.h"
|
||||
|
||||
// Get All Mods In Folder
|
||||
static void load(std::vector<std::string> &ld_preload, const std::string &folder, int recursion_limit = 128);
|
||||
@ -18,10 +21,8 @@ static void handle_file(std::vector<std::string> &ld_preload, const std::string
|
||||
load(ld_preload, std::string(file) + '/', recursion_limit - 1);
|
||||
} else if (S_ISLNK(file_stat.st_mode)) {
|
||||
// Resolve Symlink
|
||||
char *resolved_file = realpath(file.c_str(), nullptr);
|
||||
ALLOC_CHECK(resolved_file);
|
||||
const std::string resolved_file = safe_realpath(file);
|
||||
handle_file(ld_preload, resolved_file, recursion_limit);
|
||||
free(resolved_file);
|
||||
} else if (S_ISREG(file_stat.st_mode)) {
|
||||
// Check If File Is Accessible
|
||||
const int result = access(file.c_str(), R_OK);
|
||||
@ -79,19 +80,13 @@ std::vector<std::string> bootstrap_mods(const std::string &binary_directory) {
|
||||
// Prepare
|
||||
std::vector<std::string> preload;
|
||||
|
||||
// ~/.minecraft-pi/mods
|
||||
{
|
||||
// Get Mods Folder
|
||||
const std::string mods_folder = std::string(getenv(_MCPI_HOME_ENV)) + get_home_subdirectory_for_game_data() + SUBDIRECTORY_FOR_MODS;
|
||||
// Load Mods From ./mods
|
||||
load(preload, mods_folder);
|
||||
}
|
||||
|
||||
// Built-In Mods
|
||||
{
|
||||
// Get Mods Folder
|
||||
const std::string mods_folder = binary_directory + SUBDIRECTORY_FOR_MODS;
|
||||
// Load Mods From ./mods
|
||||
// Load
|
||||
const std::vector folders = {
|
||||
home_get(),
|
||||
binary_directory
|
||||
};
|
||||
for (std::string mods_folder : folders) {
|
||||
mods_folder += SUBDIRECTORY_FOR_MODS;
|
||||
load(preload, mods_folder);
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,8 @@
|
||||
|
||||
#include <LIEF/ELF.hpp>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <link.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/util.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
#include "bootstrap.h"
|
||||
|
||||
|
@ -1,115 +0,0 @@
|
||||
FALSE Full Touch GUI
|
||||
TRUE Fix Bow & Arrow
|
||||
TRUE Fix Attacking
|
||||
FALSE Force Mob Spawning
|
||||
TRUE Disable Autojump By Default
|
||||
TRUE Display Nametags By Default
|
||||
TRUE Fix Sign Placement
|
||||
TRUE Show Block Outlines
|
||||
FALSE Expand Creative Mode Inventory
|
||||
FALSE Remove Creative Mode Restrictions
|
||||
FALSE Display Slot Count In Creative Mode
|
||||
FALSE Force Survival Mode Inventory UI
|
||||
FALSE Force Survival Mode Inventory Behavior
|
||||
FALSE Maximize Creative Mode Inventory Stack Size
|
||||
TRUE Animated Water
|
||||
TRUE Animated Lava
|
||||
TRUE Animated Fire
|
||||
TRUE Regenerate "gui_blocks" Atlas
|
||||
TRUE Fix Camera Rendering
|
||||
TRUE Implement Chat
|
||||
FALSE Hide Chat Messages
|
||||
TRUE Implement Death Messages
|
||||
TRUE Implement Game-Mode Switching
|
||||
TRUE Allow Joining Survival Mode Servers
|
||||
TRUE Miscellaneous Input Fixes
|
||||
TRUE Bind "Q" Key To Item Dropping
|
||||
TRUE Bind Common Toggleable Options To Function Keys
|
||||
TRUE Render Selected Item Text
|
||||
TRUE External Server Support
|
||||
TRUE Load Language Files
|
||||
TRUE Implement Sound Engine
|
||||
TRUE Close Current Screen On Death
|
||||
FALSE Disable Raw Mouse Motion (Not Recommended)
|
||||
TRUE Fix Furnace Not Checking Item Auxiliary
|
||||
TRUE Improved Cursor Rendering
|
||||
TRUE Disable V-Sync
|
||||
TRUE Fix Options Screen
|
||||
TRUE Force Touch GUI Inventory
|
||||
TRUE Fix Pause Menu
|
||||
TRUE Add Title Screen Background
|
||||
TRUE Force Touch GUI Button Behavior
|
||||
TRUE Improved Button Hover Behavior
|
||||
TRUE Implement Create World Dialog
|
||||
FALSE Remove Forced GUI Lag (Can Break Joining Servers)
|
||||
TRUE Add Buckets
|
||||
TRUE Classic HUD
|
||||
TRUE Translucent Toolbar
|
||||
FALSE Force EGL
|
||||
TRUE Improved Classic Title Screen
|
||||
FALSE Disable Speed Bridging
|
||||
FALSE Disable Creative Mode Mining Delay
|
||||
FALSE Add Biome Colors To Grass
|
||||
TRUE Generate Caves
|
||||
FALSE Disable Block Tinting
|
||||
TRUE Disable Hostile AI In Creative Mode
|
||||
TRUE Load Custom Skins
|
||||
TRUE 3D Chest Model
|
||||
TRUE Replace Block Highlight With Outline
|
||||
TRUE Add Cake
|
||||
TRUE Use Java Beta 1.3 Light Ramp
|
||||
TRUE Send Full Level When Hosting Game
|
||||
FALSE Food Overlay
|
||||
TRUE Add Splashes
|
||||
TRUE Display Date In Select World Screen
|
||||
TRUE Optimized Chunk Sorting
|
||||
TRUE Fix Held Item Caching
|
||||
TRUE Add Reborn Info To Options
|
||||
FALSE Log FPS
|
||||
TRUE Add Welcome Screen
|
||||
TRUE F3 Debug Information
|
||||
TRUE Multidraw Rendering
|
||||
TRUE Add Missing Language Strings
|
||||
TRUE Fix Pigmen Burning In The Sun
|
||||
TRUE Fix Carried Grass's Bottom Texture
|
||||
TRUE Hide Crosshair In Third-Person
|
||||
TRUE Fix Camera Legs
|
||||
TRUE Implement Crafting Remainders
|
||||
TRUE Fix Door Duplication
|
||||
TRUE Fix Cobweb Lighting
|
||||
TRUE Fix Sneaking Syncing
|
||||
TRUE Fix Fire Immunity
|
||||
TRUE Fix Fire Syncing
|
||||
TRUE Fix Sunlight Not Properly Setting Mobs On Fire
|
||||
TRUE Stop Creative Players From Burning
|
||||
TRUE Render Fire In Third-Person
|
||||
TRUE Improved Water Rendering
|
||||
TRUE Classic Item Count UI
|
||||
TRUE Fix Screen Rendering When Hiding HUD
|
||||
TRUE Sanitize Usernames
|
||||
TRUE Patch RakNet Security Bug
|
||||
TRUE Log RakNet Startup Errors
|
||||
TRUE Prevent Unnecessary Server Pinging
|
||||
TRUE Proper OpenGL Buffer Generation
|
||||
TRUE Fix Furnace Screen Visual Bug
|
||||
TRUE Fix Text Wrapping
|
||||
TRUE Fullscreen Support
|
||||
TRUE Always Save Chest Tile Entities
|
||||
TRUE Fix Transferring Durability When Using Items
|
||||
TRUE Fix Switching Perspective While Sneaking
|
||||
TRUE Log Chat Messages
|
||||
TRUE Log Game Status
|
||||
TRUE Screenshot Support
|
||||
TRUE Fix Camera Functionality
|
||||
TRUE Allow High-Resolution Title
|
||||
TRUE Improved Classic Title Positioning
|
||||
TRUE Use Updated Title
|
||||
TRUE Hide Block Outline When GUI Is Hidden
|
||||
TRUE Fix Crash When Generating Certain Seeds
|
||||
TRUE Click Buttons On Mouse Down
|
||||
TRUE 3D Dropped Items
|
||||
TRUE Render Entity Shadows
|
||||
TRUE Render Vignette
|
||||
TRUE Increase Render Chunk Size
|
||||
TRUE Proper Entity Shading
|
||||
TRUE Fix Sugar Position In Hand
|
@ -6,18 +6,15 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/util.h>
|
||||
|
||||
#include "configuration.h"
|
||||
#include "cache.h"
|
||||
#include "configuration.h"
|
||||
|
||||
// Get Cache Path
|
||||
static std::string get_cache_path() {
|
||||
const char *home = getenv(_MCPI_HOME_ENV);
|
||||
if (home == nullptr) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
return std::string(home) + get_home_subdirectory_for_game_data() + "/.launcher-cache";
|
||||
return home_get() + "/.launcher-cache";
|
||||
}
|
||||
|
||||
// Load
|
||||
@ -37,7 +34,7 @@ launcher_cache load_cache() {
|
||||
std::ifstream stream(get_cache_path(), std::ios::in | std::ios::binary);
|
||||
if (!stream) {
|
||||
// Fail
|
||||
struct stat s;
|
||||
struct stat s = {};
|
||||
// No Warning If File Doesn't Exist
|
||||
if (stat(get_cache_path().c_str(), &s) == 0) {
|
||||
WARN("Unable To Open Launcher Cache For Loading");
|
||||
@ -49,14 +46,12 @@ launcher_cache load_cache() {
|
||||
// Check Version
|
||||
unsigned char cache_version;
|
||||
stream.read((char *) &cache_version, 1);
|
||||
if (stream.eof() || cache_version != (unsigned char) CACHE_VERSION) {
|
||||
// Fail
|
||||
if (!stream.eof()) {
|
||||
WARN("Invalid Launcher Cache Version (Expected: %i, Actual: %i)", (int) CACHE_VERSION, (int) cache_version);
|
||||
} else {
|
||||
WARN("Unable To Read Launcher Cache Version");
|
||||
}
|
||||
stream.close();
|
||||
if (stream.eof()) {
|
||||
// Unable To Read Version
|
||||
WARN("Unable To Read Launcher Cache Version");
|
||||
} else if (cache_version != (unsigned char) CACHE_VERSION) {
|
||||
// Invalid Version
|
||||
WARN("Invalid Launcher Cache Version (Expected: %i, Actual: %i)", CACHE_VERSION, (int) cache_version);
|
||||
} else {
|
||||
// Load Username And Render Distance
|
||||
launcher_cache cache;
|
||||
@ -66,16 +61,15 @@ launcher_cache load_cache() {
|
||||
// Load Feature Flags
|
||||
std::string flag;
|
||||
while (!stream.eof() && std::getline(stream, flag, '\0')) {
|
||||
if (flag.length() > 0) {
|
||||
unsigned char is_enabled = 0;
|
||||
stream.read((char *) &is_enabled, 1);
|
||||
cache.feature_flags[flag] = is_enabled != (unsigned char) 0;
|
||||
if (!flag.empty()) {
|
||||
bool is_enabled = false;
|
||||
stream.read((char *) &is_enabled, sizeof(bool));
|
||||
cache.feature_flags[flag] = is_enabled;
|
||||
}
|
||||
stream.peek();
|
||||
}
|
||||
|
||||
// Finish
|
||||
stream.close();
|
||||
if (!stream) {
|
||||
// Fail
|
||||
WARN("Failure While Loading Launcher Cache");
|
||||
@ -85,6 +79,9 @@ launcher_cache load_cache() {
|
||||
}
|
||||
}
|
||||
|
||||
// Close
|
||||
stream.close();
|
||||
|
||||
// Unlock File
|
||||
unlock_file(get_cache_path().c_str(), lock_fd);
|
||||
}
|
||||
@ -94,15 +91,10 @@ launcher_cache load_cache() {
|
||||
}
|
||||
|
||||
// Save
|
||||
#define write_env_to_stream(stream, env) \
|
||||
{ \
|
||||
const char *env_value = getenv(env); \
|
||||
if (env == NULL) { \
|
||||
IMPOSSIBLE(); \
|
||||
} \
|
||||
stream.write(env_value, strlen(env_value) + 1); \
|
||||
}
|
||||
void save_cache() {
|
||||
static void write_env_to_stream(std::ofstream &stream, const std::string &value) {
|
||||
stream.write(value.c_str(), int(value.size()) + 1);
|
||||
}
|
||||
void save_cache(const State &state) {
|
||||
// Log
|
||||
DEBUG("Saving Launcher Cache...");
|
||||
|
||||
@ -116,41 +108,23 @@ void save_cache() {
|
||||
int lock_fd = lock_file(get_cache_path().c_str());
|
||||
|
||||
// Save Cache Version
|
||||
unsigned char cache_version = (unsigned char) CACHE_VERSION;
|
||||
constexpr unsigned char cache_version = CACHE_VERSION;
|
||||
stream.write((const char *) &cache_version, 1);
|
||||
|
||||
// Save Username And Render Distance
|
||||
write_env_to_stream(stream, MCPI_USERNAME_ENV);
|
||||
write_env_to_stream(stream, MCPI_RENDER_DISTANCE_ENV);
|
||||
write_env_to_stream(stream, state.username);
|
||||
write_env_to_stream(stream, state.render_distance);
|
||||
|
||||
// Save Feature Flags
|
||||
std::unordered_map<std::string, bool> flags;
|
||||
load_available_feature_flags([&flags](std::string flag) {
|
||||
std::string stripped_flag = strip_feature_flag_default(flag, nullptr);
|
||||
flags[stripped_flag] = false;
|
||||
});
|
||||
{
|
||||
const char *enabled_flags = getenv(MCPI_FEATURE_FLAGS_ENV);
|
||||
if (enabled_flags == nullptr) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
std::istringstream enabled_flags_stream(enabled_flags);
|
||||
std::string flag;
|
||||
while (std::getline(enabled_flags_stream, flag, '|')) {
|
||||
if (flag.length() > 0) {
|
||||
flags[flag] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto &it : flags) {
|
||||
stream.write(it.first.c_str(), it.first.size() + 1);
|
||||
unsigned char val = it.second ? (unsigned char) 1 : (unsigned char) 0;
|
||||
stream.write((const char *) &val, 1);
|
||||
const std::unordered_map<std::string, bool> flags_cache = state.flags.to_cache();
|
||||
for (const std::pair<const std::string, bool> &it : flags_cache) {
|
||||
stream.write(it.first.c_str(), int(it.first.size()) + 1);
|
||||
stream.write((const char *) &it.second, sizeof(bool));
|
||||
}
|
||||
|
||||
// Finish
|
||||
stream.close();
|
||||
if (!stream.good()) {
|
||||
if (!stream) {
|
||||
WARN("Failure While Saving Launcher Cache");
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,8 @@ extern launcher_cache empty_cache;
|
||||
launcher_cache load_cache();
|
||||
|
||||
// Save Cache
|
||||
void save_cache();
|
||||
struct State;
|
||||
void save_cache(const State &state);
|
||||
|
||||
// Wipe Cache
|
||||
void wipe_cache();
|
||||
|
@ -1,145 +1,45 @@
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/env.h>
|
||||
|
||||
#include "../util/util.h"
|
||||
#include "configuration.h"
|
||||
#include "cache.h"
|
||||
|
||||
// Strip Feature Flag Default
|
||||
std::string strip_feature_flag_default(const std::string &flag, bool *default_ret) {
|
||||
// Valid Values
|
||||
std::string true_str = "TRUE ";
|
||||
std::string false_str = "FALSE ";
|
||||
// Test
|
||||
if (flag.rfind(true_str, 0) == 0) {
|
||||
// Enabled By Default
|
||||
if (default_ret != nullptr) {
|
||||
*default_ret = true;
|
||||
}
|
||||
return flag.substr(true_str.length(), std::string::npos);
|
||||
} else if (flag.rfind(false_str, 0) == 0) {
|
||||
// Disabled By Default
|
||||
if (default_ret != nullptr) {
|
||||
*default_ret = false;
|
||||
}
|
||||
return flag.substr(false_str.length(), std::string::npos);
|
||||
// State
|
||||
State::State(const launcher_cache &cache): flags("") {
|
||||
username = cache.username;
|
||||
render_distance = cache.render_distance;
|
||||
flags = Flags::get();
|
||||
flags.from_cache(cache.feature_flags);
|
||||
}
|
||||
template <typename T>
|
||||
static void update_from_env(const char *env, T &value, const bool save) {
|
||||
if (save) {
|
||||
const std::string str = static_cast<std::string>(value);
|
||||
set_and_print_env(env, str.c_str());
|
||||
} else {
|
||||
// Invalid
|
||||
ERR("Invalid Feature Flag Default");
|
||||
}
|
||||
}
|
||||
|
||||
// Load Available Feature Flags
|
||||
extern unsigned char available_feature_flags[];
|
||||
extern size_t available_feature_flags_len;
|
||||
void load_available_feature_flags(const std::function<void(std::string)> &callback) {
|
||||
// Load Data
|
||||
const std::string data(available_feature_flags, available_feature_flags + available_feature_flags_len);
|
||||
std::stringstream stream(data);
|
||||
// Store Lines
|
||||
std::vector<std::string> lines;
|
||||
// Read File
|
||||
{
|
||||
std::string line;
|
||||
while (std::getline(stream, line)) {
|
||||
if (!line.empty()) {
|
||||
// Verify Line
|
||||
if (line.find('|') == std::string::npos) {
|
||||
lines.push_back(line);
|
||||
} else {
|
||||
// Invalid Line
|
||||
ERR("Feature Flag Contains Invalid '|'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sort
|
||||
std::sort(lines.begin(), lines.end(), [](const std::string &a, const std::string &b) {
|
||||
// Strip Defaults
|
||||
const std::string stripped_a = strip_feature_flag_default(a, nullptr);
|
||||
const std::string stripped_b = strip_feature_flag_default(b, nullptr);
|
||||
// Sort
|
||||
return stripped_a < stripped_b;
|
||||
});
|
||||
// Run Callbacks
|
||||
for (const std::string &line : lines) {
|
||||
callback(line);
|
||||
}
|
||||
}
|
||||
|
||||
// Run Command And Set Environmental Variable
|
||||
static void run_command_and_set_env(const char *env_name, const char *command[]) {
|
||||
// Only Run If Environmental Variable Is NULL
|
||||
if (getenv(env_name) == nullptr) {
|
||||
// Check $DISPLAY
|
||||
reborn_check_display();
|
||||
// Run
|
||||
int return_code;
|
||||
const std::vector<unsigned char> *output = run_command(command, &return_code);
|
||||
std::string output_str = (const char *) output->data();
|
||||
delete output;
|
||||
// Trim
|
||||
const std::string::size_type length = output_str.length();
|
||||
if (length > 0 && output_str[length - 1] == '\n') {
|
||||
output_str.pop_back();
|
||||
}
|
||||
// Set
|
||||
set_and_print_env(env_name, output_str.c_str());
|
||||
// Check Return Code
|
||||
if (!is_exit_status_success(return_code)) {
|
||||
// Launch Interrupted
|
||||
exit(EXIT_SUCCESS);
|
||||
const char *env_value = getenv(env);
|
||||
if (env_value != nullptr) {
|
||||
value = env_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use Zenity To Set Environmental Variable
|
||||
#define DIALOG_TITLE "Launcher"
|
||||
static void run_zenity_and_set_env(const char *env_name, std::vector<std::string> command) {
|
||||
// Create Full Command
|
||||
std::vector<std::string> full_command;
|
||||
full_command.push_back("zenity");
|
||||
full_command.push_back("--title");
|
||||
full_command.push_back(DIALOG_TITLE);
|
||||
full_command.push_back("--name");
|
||||
full_command.push_back(MCPI_APP_ID);
|
||||
full_command.insert(full_command.end(), command.begin(), command.end());
|
||||
// Convert To C Array
|
||||
const char *full_command_array[full_command.size() + 1];
|
||||
for (std::vector<std::string>::size_type i = 0; i < full_command.size(); i++) {
|
||||
full_command_array[i] = full_command[i].c_str();
|
||||
}
|
||||
full_command_array[full_command.size()] = nullptr;
|
||||
// Run
|
||||
run_command_and_set_env(env_name, full_command_array);
|
||||
void State::update(const bool save) {
|
||||
update_from_env(MCPI_FEATURE_FLAGS_ENV, flags, save);
|
||||
update_from_env(MCPI_USERNAME_ENV, username, save);
|
||||
update_from_env(MCPI_RENDER_DISTANCE_ENV, render_distance, save);
|
||||
}
|
||||
|
||||
// Set Variable If Not Already Set
|
||||
static void set_env_if_unset(const char *env_name, const std::function<std::string()> &callback) {
|
||||
if (getenv(env_name) == nullptr) {
|
||||
char *value = strdup(callback().c_str());
|
||||
ALLOC_CHECK(value);
|
||||
set_and_print_env(env_name, value);
|
||||
free(value);
|
||||
}
|
||||
bool State::operator==(const State &other) const {
|
||||
#define test(x) static_cast<std::string>(x) == static_cast<std::string>(other.x)
|
||||
return test(username) && test(render_distance) && test(flags);
|
||||
#undef test
|
||||
}
|
||||
|
||||
// Handle Non-Launch Commands
|
||||
void handle_non_launch_client_only_commands(const options_t &options) {
|
||||
// Print Available Feature Flags
|
||||
if (options.print_available_feature_flags) {
|
||||
load_available_feature_flags([](const std::string &line) {
|
||||
printf("%s\n", line.c_str());
|
||||
fflush(stdout);
|
||||
});
|
||||
const Flags flags = Flags::get();
|
||||
flags.print();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
// Wipe Cache If Needed
|
||||
@ -150,115 +50,31 @@ void handle_non_launch_client_only_commands(const options_t &options) {
|
||||
}
|
||||
|
||||
// Configure Client Options
|
||||
#define LIST_DIALOG_SIZE "400"
|
||||
void configure_client(const options_t &options) {
|
||||
// Load Cache
|
||||
launcher_cache cache = options.no_cache ? empty_cache : load_cache();
|
||||
const launcher_cache cache = options.no_cache ? empty_cache : load_cache();
|
||||
|
||||
// Setup State
|
||||
State state(cache);
|
||||
state.update(false);
|
||||
|
||||
// --default
|
||||
if (options.use_default) {
|
||||
// Use Default Feature Flags
|
||||
set_env_if_unset(MCPI_FEATURE_FLAGS_ENV, [&cache]() {
|
||||
std::string feature_flags;
|
||||
load_available_feature_flags([&feature_flags, &cache](const std::string &flag) {
|
||||
bool value;
|
||||
// Strip Default Value
|
||||
std::string stripped_flag = strip_feature_flag_default(flag, &value);
|
||||
// Use Cache
|
||||
if (cache.feature_flags.count(stripped_flag) > 0) {
|
||||
value = cache.feature_flags[stripped_flag];
|
||||
}
|
||||
// Specify Default Value
|
||||
if (value) {
|
||||
// Enabled By Default
|
||||
feature_flags += stripped_flag + '|';
|
||||
}
|
||||
});
|
||||
if (!feature_flags.empty() && feature_flags[feature_flags.length() - 1] == '|') {
|
||||
feature_flags.pop_back();
|
||||
}
|
||||
return feature_flags;
|
||||
});
|
||||
set_env_if_unset(MCPI_RENDER_DISTANCE_ENV, [&cache]() {
|
||||
return cache.render_distance;
|
||||
});
|
||||
set_env_if_unset(MCPI_USERNAME_ENV, [&cache]() {
|
||||
return cache.username;
|
||||
});
|
||||
}
|
||||
|
||||
// Setup MCPI_FEATURE_FLAGS
|
||||
{
|
||||
std::vector<std::string> command;
|
||||
command.push_back("--list");
|
||||
command.push_back("--checklist");
|
||||
command.push_back("--width");
|
||||
command.push_back(LIST_DIALOG_SIZE);
|
||||
command.push_back("--height");
|
||||
command.push_back(LIST_DIALOG_SIZE);
|
||||
command.push_back("--column");
|
||||
command.push_back("Enabled");
|
||||
command.push_back("--column");
|
||||
command.push_back("Feature");
|
||||
load_available_feature_flags([&command, &cache](const std::string &flag) {
|
||||
bool value;
|
||||
// Strip Default Value
|
||||
std::string stripped_flag = strip_feature_flag_default(flag, &value);
|
||||
// Use Cache
|
||||
if (cache.feature_flags.count(stripped_flag) > 0) {
|
||||
value = cache.feature_flags[stripped_flag];
|
||||
}
|
||||
// Specify Default Value
|
||||
if (value) {
|
||||
// Enabled By Default
|
||||
command.push_back("TRUE");
|
||||
} else {
|
||||
// Disabled By Default
|
||||
command.push_back("FALSE");
|
||||
}
|
||||
// Specify Name
|
||||
command.push_back(stripped_flag);
|
||||
});
|
||||
// Run
|
||||
run_zenity_and_set_env(MCPI_FEATURE_FLAGS_ENV, command);
|
||||
}
|
||||
// Setup MCPI_RENDER_DISTANCE
|
||||
{
|
||||
std::vector<std::string> command;
|
||||
command.push_back("--list");
|
||||
command.push_back("--radiolist");
|
||||
command.push_back("--width");
|
||||
command.push_back(LIST_DIALOG_SIZE);
|
||||
command.push_back("--height");
|
||||
command.push_back(LIST_DIALOG_SIZE);
|
||||
command.push_back("--text");
|
||||
command.push_back("Select Minecraft Render Distance:");
|
||||
command.push_back("--column");
|
||||
command.push_back("Selected");
|
||||
command.push_back("--column");
|
||||
command.push_back("Name");
|
||||
std::string render_distances[] = {"Far", "Normal", "Short", "Tiny"};
|
||||
for (std::string &render_distance : render_distances) {
|
||||
command.push_back(render_distance == cache.render_distance ? "TRUE" : "FALSE");
|
||||
command.push_back(render_distance);
|
||||
bool save_settings = !options.no_cache;
|
||||
if (!options.use_default) {
|
||||
// Show UI
|
||||
ConfigurationUI *ui = new ConfigurationUI(state, save_settings);
|
||||
const int ret = ui->run();
|
||||
delete ui;
|
||||
if (ret <= 0) {
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
// Run
|
||||
run_zenity_and_set_env(MCPI_RENDER_DISTANCE_ENV, command);
|
||||
}
|
||||
// Setup MCPI_USERNAME
|
||||
{
|
||||
std::vector<std::string> command;
|
||||
command.push_back("--entry");
|
||||
command.push_back("--text");
|
||||
command.push_back("Enter Minecraft Username:");
|
||||
command.push_back("--entry-text");
|
||||
command.push_back(cache.username);
|
||||
// Run
|
||||
run_zenity_and_set_env(MCPI_USERNAME_ENV, command);
|
||||
}
|
||||
|
||||
// Save Cache
|
||||
if (!options.no_cache) {
|
||||
save_cache();
|
||||
if (save_settings) {
|
||||
save_cache(state);
|
||||
}
|
||||
|
||||
// Update Environment
|
||||
state.update(true);
|
||||
}
|
||||
|
@ -1,17 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
#include "../options/parser.h"
|
||||
#include "cache.h"
|
||||
#include "../ui/frame.h"
|
||||
|
||||
// Defaults
|
||||
#include <libreborn/flags.h>
|
||||
|
||||
// Default Configuration
|
||||
#define DEFAULT_USERNAME "StevePi"
|
||||
#define DEFAULT_RENDER_DISTANCE "Short"
|
||||
|
||||
// Feature Flags
|
||||
std::string strip_feature_flag_default(const std::string& flag, bool *default_ret);
|
||||
void load_available_feature_flags(const std::function<void(std::string)> &callback);
|
||||
// State
|
||||
struct State {
|
||||
explicit State(const launcher_cache &cache);
|
||||
// Methods
|
||||
void update(bool save);
|
||||
bool operator==(const State &other) const;
|
||||
// Properties
|
||||
std::string username;
|
||||
std::string render_distance;
|
||||
Flags flags;
|
||||
};
|
||||
|
||||
// UI
|
||||
struct ConfigurationUI final : Frame {
|
||||
explicit ConfigurationUI(State &state_, bool &save_settings_);
|
||||
int render() override;
|
||||
private:
|
||||
void update_render_distance();
|
||||
int draw_bottom();
|
||||
void draw_main();
|
||||
void draw_advanced() const;
|
||||
static void draw_category(FlagNode &category);
|
||||
const State default_state;
|
||||
const State original_state;
|
||||
State &state;
|
||||
bool &save_settings;
|
||||
int render_distance_index;
|
||||
};
|
||||
|
||||
// Handle Non-Launch Commands
|
||||
void handle_non_launch_client_only_commands(const options_t &options);
|
||||
|
143
launcher/src/client/ui.cpp
Normal file
143
launcher/src/client/ui.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
#include <vector>
|
||||
|
||||
#include "configuration.h"
|
||||
#include "cache.h"
|
||||
|
||||
#include <imgui_stdlib.h>
|
||||
|
||||
// Render Distances
|
||||
static std::vector render_distances = {
|
||||
"Far",
|
||||
"Normal",
|
||||
"Short",
|
||||
"Tiny"
|
||||
};
|
||||
|
||||
// Construct
|
||||
static constexpr int size = 400;
|
||||
ConfigurationUI::ConfigurationUI(State &state_, bool &save_settings_):
|
||||
Frame("Launcher", size, size),
|
||||
default_state(empty_cache),
|
||||
original_state(state_),
|
||||
state(state_),
|
||||
save_settings(save_settings_) {
|
||||
update_render_distance();
|
||||
}
|
||||
void ConfigurationUI::update_render_distance() {
|
||||
render_distance_index = 0;
|
||||
for (std::vector<std::string>::size_type i = 0; i < render_distances.size(); i++) {
|
||||
if (std::string(render_distances[i]) == state.render_distance) {
|
||||
render_distance_index = int(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render
|
||||
int ConfigurationUI::render() {
|
||||
if (ImGui::BeginChild("Main", ImVec2(0, -ImGui::GetFrameHeightWithSpacing() /* Leave Room For Bottom Row */), ImGuiChildFlags_None, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
|
||||
// Tabs
|
||||
if (ImGui::BeginTabBar("TabBar")) {
|
||||
// Main Tab
|
||||
if (ImGui::BeginTabItem("General")) {
|
||||
draw_main();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
// Advanced Tab
|
||||
if (ImGui::BeginTabItem("Advanced")) {
|
||||
draw_advanced();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
// Bottom Row
|
||||
return draw_bottom();
|
||||
}
|
||||
|
||||
// Bottom Row
|
||||
int ConfigurationUI::draw_bottom() {
|
||||
// Reset All Settings
|
||||
std::vector<std::tuple<const char *, const char *, const State *>> reset_options = {
|
||||
{"Revert", "Last Saved", &original_state},
|
||||
{"Reset", "Default", &default_state}
|
||||
};
|
||||
for (const std::tuple<const char *, const char *, const State *> &option : reset_options) {
|
||||
const State &new_state = *std::get<2>(option);
|
||||
ImGui::BeginDisabled(state == new_state);
|
||||
if (ImGui::Button(std::get<0>(option))) {
|
||||
state = new_state;
|
||||
update_render_distance();
|
||||
}
|
||||
ImGui::SetItemTooltip("Use %s Settings", std::get<1>(option));
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
// Right-Align Buttons
|
||||
int ret = 0;
|
||||
draw_right_aligned_buttons({"Quit", "Launch"}, [&ret](const int id, const bool was_clicked) {
|
||||
if (id == 0) {
|
||||
// Quit
|
||||
if (was_clicked) {
|
||||
ret = -1;
|
||||
}
|
||||
ImGui::SetItemTooltip("Changes Will Not Be Saved!");
|
||||
} else if (was_clicked) {
|
||||
// Launch
|
||||
ret = 1;
|
||||
}
|
||||
});
|
||||
// Return
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Main Tab
|
||||
void ConfigurationUI::draw_main() {
|
||||
const ImGuiStyle &style = ImGui::GetStyle();
|
||||
const char *labels[] = {"Username", "Render Distance"};
|
||||
// Calculate Label Size
|
||||
float label_size = 0;
|
||||
for (const char *label : labels) {
|
||||
label_size = std::max(label_size, ImGui::CalcTextSize(label).x + style.ItemInnerSpacing.x);
|
||||
}
|
||||
ImGui::PushItemWidth(-label_size);
|
||||
// Options
|
||||
ImGui::InputText(labels[0], &state.username);
|
||||
ImGui::Combo(labels[1], &render_distance_index, render_distances.data(), int(render_distances.size()));
|
||||
state.render_distance = render_distances[render_distance_index];
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::Checkbox("Save Settings On Launch", &save_settings);
|
||||
}
|
||||
|
||||
// Advanced Tab
|
||||
static std::string get_label(const FlagNode &node) {
|
||||
return node.name + "##" + std::to_string(node.id);
|
||||
}
|
||||
void ConfigurationUI::draw_advanced() const {
|
||||
if (ImGui::BeginChild("Features", ImVec2(0, 0), ImGuiChildFlags_Borders, ImGuiWindowFlags_HorizontalScrollbar)) {
|
||||
// Categories
|
||||
for (FlagNode &category : state.flags.root.children) {
|
||||
std::string label = get_label(category);
|
||||
if (ImGui::CollapsingHeader(label.c_str())) {
|
||||
draw_category(category);
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
// Feature Categories
|
||||
void ConfigurationUI::draw_category(FlagNode &category) {
|
||||
for (FlagNode &child : category.children) {
|
||||
std::string label = get_label(child);
|
||||
if (!child.children.empty()) {
|
||||
if (ImGui::TreeNode(label.c_str())) {
|
||||
draw_category(child);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
} else {
|
||||
ImGui::Checkbox(label.c_str(), &child.value);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +1,92 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <fstream>
|
||||
|
||||
#include <libreborn/util.h>
|
||||
#include <libreborn/config.h>
|
||||
#include <libreborn/exec.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "../ui/frame.h"
|
||||
|
||||
// UI
|
||||
struct CrashReport final : Frame {
|
||||
explicit CrashReport(const char *filename): Frame("Crash Report", 640, 480) {
|
||||
// Open File
|
||||
std::ifstream stream(filename, std::ios_base::binary | std::ios_base::ate);
|
||||
if (stream) {
|
||||
// Read File
|
||||
const std::streamoff size = stream.tellg();
|
||||
stream.seekg(0, std::ifstream::beg);
|
||||
log.resize(size);
|
||||
stream.read(log.data(), size);
|
||||
// Close File
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
bool first_render = true;
|
||||
int render() override {
|
||||
// Text
|
||||
ImGui::TextWrapped("%s", MCPI_APP_TITLE " has crashed!");
|
||||
ImGui::Spacing();
|
||||
ImGui::TextWrapped("Need help? Consider asking on the Discord server!");
|
||||
ImGui::Spacing();
|
||||
ImGui::TextWrapped("If you believe this is a problem with " MCPI_APP_TITLE " itself, please upload this crash report to the #bugs Discord channel.");
|
||||
// Log
|
||||
if (ImGui::BeginChild("Log", ImVec2(0, -ImGui::GetFrameHeightWithSpacing() /* Leave Room For Bottom Row */), ImGuiChildFlags_Borders, ImGuiWindowFlags_HorizontalScrollbar)) {
|
||||
ImGui::PushFont(monospace);
|
||||
ImGui::TextUnformatted(log.data(), log.data() + log.size());
|
||||
ImGui::PopFont();
|
||||
if (first_render) {
|
||||
ImGui::SetScrollHereY(1.0f);
|
||||
first_render = false;
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
// Buttons
|
||||
if (ImGui::Button("Join Discord")) {
|
||||
open_url(MCPI_DISCORD_INVITE);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("View All Logs")) {
|
||||
open_url("file://" + get_logs_folder());
|
||||
}
|
||||
ImGui::SameLine();
|
||||
// Right-Aligned
|
||||
int ret = 0;
|
||||
const std::string &log_ref = log;
|
||||
draw_right_aligned_buttons({"Copy", "Quit"}, [&ret, &log_ref](const int id, const bool was_clicked) {
|
||||
if (was_clicked) {
|
||||
if (id == 0) {
|
||||
// Copy Log
|
||||
ImGui::SetClipboardText(log_ref.c_str());
|
||||
} else {
|
||||
// Exit
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
std::string log;
|
||||
};
|
||||
|
||||
// Show Crash Report Dialog
|
||||
#define DIALOG_TITLE "Crash Report"
|
||||
#define CRASH_REPORT_DIALOG_WIDTH "640"
|
||||
#define CRASH_REPORT_DIALOG_HEIGHT "480"
|
||||
static void redirect_file(FILE *file, const char *mode) {
|
||||
const FILE *ret = freopen("/dev/null", mode, file);
|
||||
if (!ret) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
}
|
||||
void show_report(const char *log_filename) {
|
||||
// Fork
|
||||
pid_t pid = fork();
|
||||
const pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
// Child
|
||||
setsid();
|
||||
ALLOC_CHECK(freopen("/dev/null", "w", stdout));
|
||||
ALLOC_CHECK(freopen("/dev/null", "w", stderr));
|
||||
ALLOC_CHECK(freopen("/dev/null", "r", stdin));
|
||||
const char *command[] = {
|
||||
"zenity",
|
||||
"--title", DIALOG_TITLE,
|
||||
"--name", MCPI_APP_ID,
|
||||
"--width", CRASH_REPORT_DIALOG_WIDTH,
|
||||
"--height", CRASH_REPORT_DIALOG_HEIGHT,
|
||||
"--text-info",
|
||||
"--text", MCPI_APP_TITLE " has crashed!\n\nNeed help? Consider asking on the <a href=\"" MCPI_DISCORD_INVITE "\">Discord server</a>! <i>If you believe this is a problem with " MCPI_APP_TITLE " itself, please upload this crash report to the #bugs Discord channel.</i>",
|
||||
"--filename", log_filename,
|
||||
"--no-wrap",
|
||||
"--font", "Monospace",
|
||||
"--save-filename", MCPI_VARIANT_NAME "-crash-report.log",
|
||||
"--ok-label", "Exit",
|
||||
nullptr
|
||||
};
|
||||
safe_execvpe(command, (const char *const *) environ);
|
||||
redirect_file(stdout, "w");
|
||||
redirect_file(stderr, "w");
|
||||
redirect_file(stdin, "r");
|
||||
CrashReport ui(log_filename);
|
||||
ui.run();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
@ -3,16 +3,16 @@
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <csignal>
|
||||
#include <poll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/exec.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/util.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
@ -26,12 +26,16 @@ static void exit_handler(__attribute__((unused)) int signal) {
|
||||
// Log File
|
||||
static std::string log_filename;
|
||||
static int log_fd;
|
||||
static void setup_log_file() {
|
||||
// Get Log Directory
|
||||
const std::string home = std::string(getenv(_MCPI_HOME_ENV)) + get_home_subdirectory_for_game_data();
|
||||
std::string get_logs_folder() {
|
||||
const std::string home = home_get();
|
||||
ensure_directory(home.c_str());
|
||||
const std::string logs = home + "/logs";
|
||||
ensure_directory(logs.c_str());
|
||||
return logs;
|
||||
}
|
||||
static void setup_log_file() {
|
||||
// Get Log Directory
|
||||
const std::string logs = get_logs_folder();
|
||||
|
||||
// Get Timestamp
|
||||
time_t raw_time;
|
||||
@ -129,7 +133,7 @@ void setup_logger() {
|
||||
|
||||
// Close Log File
|
||||
close(log_fd);
|
||||
unsetenv(_MCPI_LOG_FD_ENV);
|
||||
reborn_set_log(-1);
|
||||
|
||||
// Show Crash Log
|
||||
if (is_crash && !reborn_is_headless()) {
|
||||
|
@ -1,4 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string get_logs_folder();
|
||||
void setup_logger();
|
||||
void show_report(const char *log_filename);
|
@ -1,5 +1,8 @@
|
||||
#include <cstdlib>
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#include <libreborn/env.h>
|
||||
#include <libreborn/util.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
#include "bootstrap/bootstrap.h"
|
||||
#include "options/parser.h"
|
||||
@ -24,49 +27,13 @@ static void setup_environment(const options_t &options) {
|
||||
bind_to_env(_MCPI_FORCE_HEADLESS_ENV, options.force_headless);
|
||||
bind_to_env(_MCPI_FORCE_NON_HEADLESS_ENV, options.force_non_headless);
|
||||
|
||||
// GTK Dark Mode
|
||||
set_and_print_env("GTK_THEME", "Adwaita:dark");
|
||||
|
||||
// Configure PATH
|
||||
{
|
||||
// Get Binary Directory
|
||||
const std::string binary_directory = get_binary_directory();
|
||||
std::string new_path = binary_directory + "/bin";
|
||||
// Add Existing PATH
|
||||
{
|
||||
const char *value = getenv("PATH");
|
||||
if (value != nullptr && strlen(value) > 0) {
|
||||
new_path += std::string(":") + value;
|
||||
}
|
||||
}
|
||||
// Set And Free
|
||||
set_and_print_env("PATH", new_path.c_str());
|
||||
}
|
||||
setup_path();
|
||||
|
||||
// Setup MCPI_HOME
|
||||
const char *custom_profile_directory = getenv(MCPI_PROFILE_DIRECTORY_ENV);
|
||||
if (custom_profile_directory != nullptr) {
|
||||
// Custom Directory
|
||||
custom_profile_directory = realpath(custom_profile_directory, nullptr);
|
||||
ALLOC_CHECK(custom_profile_directory);
|
||||
set_and_print_env(_MCPI_HOME_ENV, custom_profile_directory);
|
||||
free((void *) custom_profile_directory);
|
||||
} else if (!reborn_is_server()) {
|
||||
// Ensure $HOME
|
||||
const char *home = getenv("HOME");
|
||||
if (home == nullptr) {
|
||||
ERR("$HOME Is Not Set");
|
||||
}
|
||||
set_and_print_env(_MCPI_HOME_ENV, home);
|
||||
} else {
|
||||
// Set Home To Current Directory, So World Data Is Stored There
|
||||
char *launch_directory = getcwd(nullptr, 0);
|
||||
ALLOC_CHECK(launch_directory);
|
||||
set_and_print_env(_MCPI_HOME_ENV, launch_directory);
|
||||
free(launch_directory);
|
||||
}
|
||||
setup_home();
|
||||
// Create If Needed
|
||||
const std::string minecraft_folder = std::string(getenv(_MCPI_HOME_ENV)) + get_home_subdirectory_for_game_data();
|
||||
const std::string minecraft_folder = home_get();
|
||||
ensure_directory(minecraft_folder.c_str());
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include <argp.h>
|
||||
|
||||
#include <libreborn/config.h>
|
||||
#include <libreborn/env.h>
|
||||
#include <trampoline/types.h>
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
// Globals
|
||||
|
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#define OPTION(name, ...) bool name;
|
||||
struct options_t {
|
||||
#include "option-list.h"
|
||||
|
83
launcher/src/ui/color.cpp
Normal file
83
launcher/src/ui/color.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
#include "frame.h"
|
||||
|
||||
// Calculate Perceived Brightness Of Color
|
||||
// See: https://en.wikipedia.org/w/index.php?title=Relative_luminance&useskin=vector
|
||||
static float compute_luma(const ImVec4 &color) {
|
||||
return (0.2126f * color.x) + (0.7152f * color.y) + (0.0722f * color.z);
|
||||
}
|
||||
|
||||
// Apply Luma To RGB
|
||||
static float clamp(const float value) {
|
||||
return std::max(0.0f, std::min(value, 1.0f));
|
||||
}
|
||||
static ImVec4 apply_luma_to_color(const float target_luma, const ImVec4 &color) {
|
||||
const float current_luma = compute_luma(color);
|
||||
const float luma_ratio = (current_luma != 0) ? target_luma / current_luma : 0;
|
||||
ImVec4 out = color;
|
||||
for (float *x : {&out.x, &out.y, &out.z}) {
|
||||
*x = clamp(*x * luma_ratio);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Blend Color
|
||||
static ImVec4 blend_color(const ImVec4 &top, const ImVec4 &bottom) {
|
||||
const float luma = compute_luma(bottom);
|
||||
ImVec4 out = apply_luma_to_color(luma, top);
|
||||
out.w = bottom.w;
|
||||
return out;
|
||||
}
|
||||
static ImVec4 blend_with_primary(const ImVec4 &color) {
|
||||
static constexpr ImVec4 primary_color = {1.0f, (69.0f / 255.0f), 0.0f, 1.0f};
|
||||
return blend_color(primary_color, color);
|
||||
}
|
||||
|
||||
// Modify Colors
|
||||
void Frame::patch_colors(ImGuiStyle &style) {
|
||||
// Blend Colors
|
||||
static int target_colors_blend[] = {
|
||||
ImGuiCol_FrameBg,
|
||||
ImGuiCol_FrameBgHovered,
|
||||
ImGuiCol_FrameBgActive,
|
||||
ImGuiCol_TitleBgActive,
|
||||
ImGuiCol_CheckMark,
|
||||
ImGuiCol_SliderGrab,
|
||||
ImGuiCol_SliderGrabActive,
|
||||
ImGuiCol_Button,
|
||||
ImGuiCol_ButtonHovered,
|
||||
ImGuiCol_ButtonActive,
|
||||
ImGuiCol_Header,
|
||||
ImGuiCol_HeaderHovered,
|
||||
ImGuiCol_HeaderActive,
|
||||
ImGuiCol_SeparatorHovered,
|
||||
ImGuiCol_SeparatorActive,
|
||||
ImGuiCol_ResizeGrip,
|
||||
ImGuiCol_ResizeGripHovered,
|
||||
ImGuiCol_ResizeGripActive,
|
||||
ImGuiCol_TabHovered,
|
||||
ImGuiCol_Tab,
|
||||
ImGuiCol_TabSelected,
|
||||
ImGuiCol_TabSelectedOverline,
|
||||
ImGuiCol_TabDimmed,
|
||||
ImGuiCol_TabDimmedSelected,
|
||||
ImGuiCol_TextLink,
|
||||
ImGuiCol_TextSelectedBg,
|
||||
ImGuiCol_NavCursor
|
||||
};
|
||||
for (const int target_color : target_colors_blend) {
|
||||
ImVec4 &color = style.Colors[target_color];
|
||||
color = blend_with_primary(color);
|
||||
}
|
||||
// Remove Blue Accent From Colors
|
||||
static int target_colors_modify[] = {
|
||||
ImGuiCol_Separator,
|
||||
ImGuiCol_Border,
|
||||
ImGuiCol_TableHeaderBg,
|
||||
ImGuiCol_TableBorderStrong,
|
||||
ImGuiCol_TableBorderLight
|
||||
};
|
||||
for (const int target_color : target_colors_modify) {
|
||||
ImVec4 &color = style.Colors[target_color];
|
||||
color.y = color.z = color.x;
|
||||
}
|
||||
}
|
113
launcher/src/ui/frame.cpp
Normal file
113
launcher/src/ui/frame.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "frame.h"
|
||||
|
||||
#include <imgui_impl_glfw.h>
|
||||
#include <imgui_impl_opengl2.h>
|
||||
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/glfw.h>
|
||||
#include <libreborn/util.h>
|
||||
|
||||
// Init/Cleanup
|
||||
Frame::Frame(const char *title, const int width, const int height) {
|
||||
// Create Window
|
||||
init_glfw();
|
||||
window = create_glfw_window(title, width, height);
|
||||
// Disable V-Sync
|
||||
// (On Wayland, This Fixes Issues With The Clipboard)
|
||||
glfwSwapInterval(0);
|
||||
// Setup ImGui Context
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
io.IniFilename = nullptr;
|
||||
io.LogFilename = nullptr;
|
||||
// Setup Platform/Renderer Backends
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplOpenGL2_Init();
|
||||
}
|
||||
Frame::~Frame() {
|
||||
// Shutdown ImGui
|
||||
ImGui_ImplOpenGL2_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
// Cleanup GLFW
|
||||
cleanup_glfw(window);
|
||||
}
|
||||
|
||||
// Run Loop
|
||||
int Frame::run() {
|
||||
int ret = 0;
|
||||
while (!glfwWindowShouldClose(window) && ret == 0) {
|
||||
glfwPollEvents();
|
||||
// Update Style
|
||||
static float last_scale = -1.0f;
|
||||
float scale;
|
||||
get_glfw_scale(window, &scale, nullptr);
|
||||
if (scale != last_scale) {
|
||||
last_scale = scale;
|
||||
setup_style(scale);
|
||||
}
|
||||
// Start Frame
|
||||
ImGui_ImplOpenGL2_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
// Main Window
|
||||
ImGui::SetNextWindowPos({0, 0});
|
||||
int width, height;
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
ImGui::SetNextWindowSize({float(width), float(height)});
|
||||
if (ImGui::Begin("###Frame", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoScrollWithMouse)) {
|
||||
ret = render();
|
||||
}
|
||||
ImGui::End();
|
||||
// Render To OpenGL
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Style
|
||||
EMBEDDED_RESOURCE(Roboto_Medium_ttf);
|
||||
EMBEDDED_RESOURCE(Cousine_Regular_ttf);
|
||||
void Frame::setup_style(const float scale) {
|
||||
// Fonts
|
||||
const ImGuiIO &io = ImGui::GetIO();
|
||||
io.Fonts->Clear();
|
||||
ImFontConfig font_cfg;
|
||||
font_cfg.FontDataOwnedByAtlas = false;
|
||||
io.Fonts->AddFontFromMemoryTTF(Roboto_Medium_ttf, int(Roboto_Medium_ttf_len), std::floor(20.0f * scale), &font_cfg);
|
||||
monospace = io.Fonts->AddFontFromMemoryTTF(Cousine_Regular_ttf, int(Cousine_Regular_ttf_len), std::floor(18.0f * scale), &font_cfg);
|
||||
// Style
|
||||
ImGuiStyle &style = ImGui::GetStyle();
|
||||
style = ImGuiStyle();
|
||||
style.WindowBorderSize = 0;
|
||||
ImGui::StyleColorsDark(&style);
|
||||
style.ScaleAllSizes(scale);
|
||||
patch_colors(style);
|
||||
}
|
||||
|
||||
// Right-Aligned Buttons
|
||||
void Frame::draw_right_aligned_buttons(const std::vector<const char *> &buttons, const std::function<void(int, bool)> &callback) {
|
||||
// Calculate Position
|
||||
const ImGuiStyle &style = ImGui::GetStyle();
|
||||
float width_needed = 0;
|
||||
for (const char *text : buttons) {
|
||||
if (width_needed > 0) {
|
||||
width_needed += style.ItemSpacing.x;
|
||||
}
|
||||
width_needed += ImGui::CalcTextSize(text).x + style.FramePadding.x * 2.0f;
|
||||
}
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - width_needed);
|
||||
// Draw
|
||||
for (std::vector<const char *>::size_type id = 0; id < buttons.size(); id++) {
|
||||
if (id > 0) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
callback(int(id), ImGui::Button(buttons[id]));
|
||||
}
|
||||
}
|
30
launcher/src/ui/frame.h
Normal file
30
launcher/src/ui/frame.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
// UI Frame
|
||||
struct Frame {
|
||||
Frame(const char *title, int width, int height);
|
||||
virtual ~Frame();
|
||||
// Prevent Copying
|
||||
Frame(const Frame &) = delete;
|
||||
Frame &operator=(const Frame &) = delete;
|
||||
// Run
|
||||
int run();
|
||||
virtual int render() = 0;
|
||||
protected:
|
||||
// API For Sub-Classes
|
||||
ImFont *monospace = nullptr;
|
||||
static void draw_right_aligned_buttons(const std::vector<const char *> &buttons, const std::function<void(int, bool)> &callback);
|
||||
private:
|
||||
// Properties
|
||||
GLFWwindow *window = nullptr;
|
||||
// Internal Methods
|
||||
float get_scale();
|
||||
void setup_style(float scale);
|
||||
static void patch_colors(ImGuiStyle &style);
|
||||
};
|
52
launcher/src/util/env.cpp
Normal file
52
launcher/src/util/env.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/env.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
// $PATH
|
||||
void setup_path() {
|
||||
// Get Binary Directory
|
||||
const std::string binary_directory = get_binary_directory();
|
||||
std::string new_path = binary_directory + "/bin";
|
||||
// Add Existing PATH
|
||||
const char *value = getenv("PATH");
|
||||
if (value != nullptr && strlen(value) > 0) {
|
||||
new_path += std::string(":") + value;
|
||||
}
|
||||
// Set And Free
|
||||
set_and_print_env("PATH", new_path.c_str());
|
||||
}
|
||||
|
||||
// Profile Directory
|
||||
void setup_home() {
|
||||
const char *custom_profile_directory = getenv(MCPI_PROFILE_DIRECTORY_ENV);
|
||||
std::string home;
|
||||
if (custom_profile_directory != nullptr) {
|
||||
// Custom Directory
|
||||
home = safe_realpath(custom_profile_directory);
|
||||
} else if (!reborn_is_server()) {
|
||||
// Ensure $HOME
|
||||
const char *value = getenv("HOME");
|
||||
if (value == nullptr) {
|
||||
ERR("$HOME Is Not Set");
|
||||
}
|
||||
home = value;
|
||||
// Flatpak
|
||||
#ifdef MCPI_IS_FLATPAK_BUILD
|
||||
home += "/.var/app/" MCPI_APP_ID;
|
||||
#endif
|
||||
} else {
|
||||
// Set Home To Current Directory, So World Data Is Stored There
|
||||
char *launch_directory = getcwd(nullptr, 0);
|
||||
if (launch_directory == nullptr) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
home = launch_directory;
|
||||
free(launch_directory);
|
||||
}
|
||||
// Set
|
||||
set_and_print_env(_MCPI_HOME_ENV, home.c_str());
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/util.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
#include "../bootstrap/bootstrap.h"
|
||||
#include "util.h"
|
||||
@ -14,12 +16,12 @@
|
||||
}
|
||||
|
||||
// Copy SDK Into ~/.minecraft-pi
|
||||
#define HOME_SUBDIRECTORY_FOR_SDK (std::string(get_home_subdirectory_for_game_data()) + "/sdk")
|
||||
#define HOME_SUBDIRECTORY_FOR_SDK "/sdk"
|
||||
void copy_sdk(const std::string &binary_directory, const bool log_with_debug) {
|
||||
// Ensure SDK Directory
|
||||
std::string sdk_path;
|
||||
{
|
||||
sdk_path = std::string(getenv(_MCPI_HOME_ENV)) + HOME_SUBDIRECTORY_FOR_SDK;
|
||||
sdk_path = home_get() + HOME_SUBDIRECTORY_FOR_SDK;
|
||||
const char *const command[] = {"mkdir", "-p", sdk_path.c_str(), nullptr};
|
||||
run_simple_command(command, "Unable To Create SDK Directory");
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/exec.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
|
@ -8,4 +8,7 @@ void chop_last_component(std::string &str);
|
||||
std::string safe_realpath(const std::string &path);
|
||||
std::string get_binary_directory();
|
||||
|
||||
void copy_sdk(const std::string &binary_directory, bool log_with_debug);
|
||||
void copy_sdk(const std::string &binary_directory, bool log_with_debug);
|
||||
|
||||
void setup_path();
|
||||
void setup_home();
|
@ -12,23 +12,22 @@ add_library(reborn-util SHARED
|
||||
src/util/log.cpp
|
||||
src/util/cp437.cpp
|
||||
src/util/env.cpp
|
||||
src/util/config.cpp
|
||||
src/util/flags/node.cpp
|
||||
src/util/flags/flags.cpp
|
||||
src/util/flags/available-feature-flags # Show In IDE
|
||||
)
|
||||
target_include_directories(
|
||||
reborn-util
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/libreborn>"
|
||||
)
|
||||
embed_resource(reborn-util src/util/flags/available-feature-flags)
|
||||
target_link_libraries(reborn-util PRIVATE utf8cpp)
|
||||
# Install
|
||||
install(TARGETS reborn-util DESTINATION "${MCPI_LIB_DIR}")
|
||||
# SDK
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS reborn-util EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
install(DIRECTORY "include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/libreborn")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/libreborn")
|
||||
if(TARGET glfw)
|
||||
target_sources(reborn-util PRIVATE src/util/glfw.cpp)
|
||||
target_link_libraries(reborn-util PRIVATE glfw)
|
||||
endif()
|
||||
setup_header_dirs(reborn-util
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/include"
|
||||
)
|
||||
setup_library(reborn-util TRUE TRUE)
|
||||
|
||||
# Patch
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
@ -39,11 +38,9 @@ if(BUILD_ARM_COMPONENTS)
|
||||
src/patch/instruction.cpp
|
||||
)
|
||||
target_link_libraries(reborn-patch dl pthread reborn-util)
|
||||
target_compile_definitions(reborn-patch PUBLIC -DREBORN_HAS_PATCH_CODE)
|
||||
target_compile_definitions(reborn-patch PUBLIC REBORN_HAS_PATCH_CODE)
|
||||
# Install
|
||||
install(TARGETS reborn-patch DESTINATION "${MCPI_LIB_DIR}")
|
||||
# SDK
|
||||
install(TARGETS reborn-patch EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
setup_library(reborn-patch TRUE TRUE)
|
||||
endif()
|
||||
|
||||
# Fake LibPNG To Satisfy Symbol Versioning Requirement
|
||||
@ -55,5 +52,5 @@ if(BUILD_ARM_COMPONENTS)
|
||||
)
|
||||
target_link_options(fake-libpng PRIVATE "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/fake-libpng/empty.vers")
|
||||
# Install
|
||||
install(TARGETS fake-libpng DESTINATION "${MCPI_LIB_DIR}")
|
||||
setup_library(fake-libpng TRUE FALSE)
|
||||
endif()
|
||||
|
@ -3,7 +3,6 @@
|
||||
#cmakedefine MCPI_IS_APPIMAGE_BUILD
|
||||
#cmakedefine MCPI_IS_FLATPAK_BUILD
|
||||
#cmakedefine MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
||||
#cmakedefine MCPI_APP_BASE_TITLE "@MCPI_APP_BASE_TITLE@"
|
||||
#cmakedefine MCPI_APP_TITLE "@MCPI_APP_TITLE@"
|
||||
#cmakedefine MCPI_APP_ID "@MCPI_APP_ID@"
|
||||
#cmakedefine MCPI_VERSION "@MCPI_VERSION@"
|
||||
@ -12,3 +11,8 @@
|
||||
#cmakedefine MCPI_SKIN_SERVER "@MCPI_SKIN_SERVER@"
|
||||
#cmakedefine MCPI_DISCORD_INVITE "@MCPI_DISCORD_INVITE@"
|
||||
#cmakedefine MCPI_DOCUMENTATION "@MCPI_DOCUMENTATION@"
|
||||
|
||||
// Access Configuration At Runtime
|
||||
const char *reborn_get_version();
|
||||
bool reborn_is_headless();
|
||||
bool reborn_is_server();
|
@ -20,12 +20,12 @@ void poll_fds(const std::vector<int> &fds, const std::function<void(int, size_t,
|
||||
// Safe execvpe()
|
||||
__attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char *const envp[]);
|
||||
|
||||
// Debug Tag
|
||||
#define CHILD_PROCESS_TAG "(Child Process) "
|
||||
|
||||
// Run Command And Get Output
|
||||
std::vector<unsigned char> *run_command(const char *const command[], int *exit_status);
|
||||
#define is_exit_status_success(status) (WIFEXITED(status) && WEXITSTATUS(status) == 0)
|
||||
bool is_exit_status_success(int status);
|
||||
|
||||
// Get Exit Status String
|
||||
std::string get_exit_status_string(int status);
|
||||
std::string get_exit_status_string(int status);
|
||||
|
||||
// Open URL
|
||||
void open_url(const std::string &url);
|
48
libreborn/include/libreborn/flags.h
Normal file
48
libreborn/include/libreborn/flags.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
// Seperator
|
||||
#define FLAG_SEPERATOR_CHAR '|'
|
||||
|
||||
// Flag
|
||||
struct FlagNode {
|
||||
private:
|
||||
explicit FlagNode(const std::string &name_);
|
||||
public:
|
||||
FlagNode();
|
||||
// Methods
|
||||
void sort();
|
||||
void for_each(const std::function<void(FlagNode &)> &callback);
|
||||
void for_each_const(const std::function<void(const FlagNode &)> &callback) const;
|
||||
void add_flag(std::string line);
|
||||
FlagNode &add_category(const std::string &new_name);
|
||||
// Properties
|
||||
std::string name;
|
||||
bool value;
|
||||
std::vector<FlagNode> children;
|
||||
int id;
|
||||
// Internal
|
||||
static bool handle_line_prefix(const std::string &prefix, std::string &line);
|
||||
static std::unordered_map<std::string, bool> flag_prefixes;
|
||||
static void reset_id_counter();
|
||||
};
|
||||
|
||||
// All Flags
|
||||
struct Flags {
|
||||
explicit Flags(const std::string &data);
|
||||
static Flags get();
|
||||
// To/From Strings
|
||||
explicit operator std::string() const;
|
||||
Flags &operator=(const std::string &str);
|
||||
// To/From Cache
|
||||
[[nodiscard]] std::unordered_map<std::string, bool> to_cache() const;
|
||||
void from_cache(const std::unordered_map<std::string, bool> &cache);
|
||||
// Print
|
||||
void print() const;
|
||||
// Properties
|
||||
FlagNode root;
|
||||
};
|
11
libreborn/include/libreborn/glfw.h
Normal file
11
libreborn/include/libreborn/glfw.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
// GLFW Helpers
|
||||
#ifndef GLFW_VERSION_MAJOR
|
||||
#error "Missing GLFW"
|
||||
#endif
|
||||
|
||||
void init_glfw();
|
||||
GLFWwindow *create_glfw_window(const char *title, int width, int height);
|
||||
void cleanup_glfw(GLFWwindow *window);
|
||||
void get_glfw_scale(GLFWwindow *window, float *x_scale, float *y_scale);
|
@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <libreborn/config.h>
|
||||
#include "env.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
#include "exec.h"
|
||||
#include "patch.h"
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
|
||||
// Log File
|
||||
int reborn_get_log_fd();
|
||||
@ -13,15 +14,18 @@ int reborn_get_debug_fd();
|
||||
// Logging
|
||||
#define INFO(format, ...) fprintf(stderr, "[INFO]: " format "\n", ##__VA_ARGS__)
|
||||
#define WARN(format, ...) fprintf(stderr, "[WARN]: " format "\n", ##__VA_ARGS__)
|
||||
#define RAW_DEBUG(tag, format, ...) dprintf(reborn_get_debug_fd(), "[DEBUG]: %s" format "\n", tag, ##__VA_ARGS__)
|
||||
#define DEBUG(format, ...) RAW_DEBUG(reborn_debug_tag, format, ##__VA_ARGS__)
|
||||
#define ERR(format, ...) { fprintf(stderr, "[ERR]: (%s:%i): " format "\n", __FILE__, __LINE__, ##__VA_ARGS__); _exit(EXIT_FAILURE); }
|
||||
#define DEBUG(format, ...) dprintf(reborn_get_debug_fd(), "[DEBUG]: %s" format "\n", reborn_debug_tag, ##__VA_ARGS__)
|
||||
#define ERR(format, ...) \
|
||||
({ \
|
||||
fprintf(stderr, "[ERR]: (%s:%i): " format "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
|
||||
_exit(EXIT_FAILURE); \
|
||||
})
|
||||
#define IMPOSSIBLE() ERR("This Should Never Be Called")
|
||||
#define CONDITIONAL_ERR(is_error, ...) \
|
||||
{ \
|
||||
({ \
|
||||
if ((is_error)) { \
|
||||
ERR(__VA_ARGS__); \
|
||||
} else { \
|
||||
WARN(__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
})
|
||||
|
@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "log.h"
|
||||
|
||||
// Patching Functions
|
||||
#if defined(REBORN_HAS_PATCH_CODE)
|
||||
#ifndef REBORN_HAS_PATCH_CODE
|
||||
#error "Missing Patching Functions"
|
||||
#endif
|
||||
|
||||
// Init
|
||||
void reborn_init_patch();
|
||||
@ -27,7 +29,7 @@ void *reborn_thunk_enabler(void *target, void *thunk);
|
||||
// Replace All Calls To start With target Within [to, from)
|
||||
void overwrite_calls_within_manual(void *from, void *to, void *start, void *target);
|
||||
template <typename T>
|
||||
void _overwrite_calls_within(void *from, void *to, T *start, typename T::ptr_type target) {
|
||||
void overwrite_calls_within(void *from, void *to, T *start, typename T::ptr_type target) {
|
||||
overwrite_calls_within_manual(from, to, (void *) start->get(), (void *) target);
|
||||
}
|
||||
|
||||
@ -49,6 +51,4 @@ void patch_vtable(const T *start, typename T::ptr_type target) {
|
||||
WARN("Use overwrite_calls() Instead!");
|
||||
}
|
||||
patch_address((void *) start->get_vtable_addr(), (void *) target);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
@ -1,35 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <dlfcn.h>
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
// Check Memory Allocation
|
||||
#define ALLOC_CHECK(obj) \
|
||||
{ \
|
||||
if ((obj) == nullptr) { \
|
||||
ERR("Memory Allocation Failed"); \
|
||||
} \
|
||||
}
|
||||
|
||||
// Align Number
|
||||
#define ALIGN_UP(x, alignment) \
|
||||
({ \
|
||||
int _align_x = (x); \
|
||||
int _align_alignment = (alignment); \
|
||||
int _align_diff = _align_x % _align_alignment; \
|
||||
if (_align_diff > 0) { \
|
||||
_align_x += (_align_alignment - _align_diff); \
|
||||
} \
|
||||
_align_x; \
|
||||
})
|
||||
int align_up(int x, int alignment);
|
||||
|
||||
// Hook Library Function
|
||||
#define EXTERNAL_FUNC(name, return_type, args) \
|
||||
#define HOOK(name, return_type, args) \
|
||||
typedef return_type (*real_##name##_t)args; \
|
||||
__attribute__((__unused__)) static real_##name##_t real_##name() { \
|
||||
static real_##name##_t func = NULL; \
|
||||
@ -41,9 +21,7 @@
|
||||
} \
|
||||
} \
|
||||
return func; \
|
||||
}
|
||||
#define HOOK(name, return_type, args) \
|
||||
EXTERNAL_FUNC(name, return_type, args) \
|
||||
} \
|
||||
extern "C" __attribute__((__used__)) return_type name args
|
||||
|
||||
// Safe Version Of pipe()
|
||||
@ -52,6 +30,7 @@ struct Pipe {
|
||||
const int read;
|
||||
const int write;
|
||||
};
|
||||
|
||||
// Check If Two Percentages Are Different Enough To Be Logged
|
||||
bool is_progress_difference_significant(int32_t new_val, int32_t old_val);
|
||||
|
||||
@ -59,11 +38,6 @@ bool is_progress_difference_significant(int32_t new_val, int32_t old_val);
|
||||
int lock_file(const char *file);
|
||||
void unlock_file(const char *file, int fd);
|
||||
|
||||
// Access Configuration At Runtime
|
||||
const char *reborn_get_version();
|
||||
bool reborn_is_headless();
|
||||
bool reborn_is_server();
|
||||
|
||||
// Check $DISPLAY
|
||||
void reborn_check_display();
|
||||
|
||||
@ -74,4 +48,12 @@ const char *get_home_subdirectory_for_game_data();
|
||||
void ensure_directory(const char *path);
|
||||
|
||||
// Safe write()
|
||||
void safe_write(int fd, const void *buf, size_t size);
|
||||
void safe_write(int fd, const void *buf, size_t size);
|
||||
|
||||
// embed_resource()
|
||||
#define EMBEDDED_RESOURCE(name) \
|
||||
extern unsigned char name[]; \
|
||||
extern size_t name##_len
|
||||
|
||||
// Profile Directory
|
||||
std::string home_get();
|
@ -1,6 +1,8 @@
|
||||
#include <sys/mman.h>
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/patch.h>
|
||||
#include "patch-internal.h"
|
||||
|
||||
// Limit Amount Of overwrite_calls() Calls
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/patch.h>
|
||||
#include "patch-internal.h"
|
||||
|
||||
// Check Instruction
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <cstdint>
|
||||
#include <cerrno>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/patch.h>
|
||||
#include "patch-internal.h"
|
||||
|
||||
// Overwrite Specific B(L) Instruction
|
||||
|
@ -1,10 +1,11 @@
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
#include <elf.h>
|
||||
#include <dlfcn.h>
|
||||
#include <link.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/patch.h>
|
||||
#include "patch-internal.h"
|
||||
|
||||
// Track Segments
|
||||
|
32
libreborn/src/util/config.cpp
Normal file
32
libreborn/src/util/config.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include <cstdlib>
|
||||
|
||||
#include <libreborn/config.h>
|
||||
#include <libreborn/env.h>
|
||||
|
||||
// Access Configuration At Runtime
|
||||
const char *reborn_get_version() {
|
||||
return MCPI_VERSION;
|
||||
}
|
||||
bool reborn_is_headless() {
|
||||
static bool ret;
|
||||
static bool is_set = false;
|
||||
if (!is_set) {
|
||||
ret = reborn_is_server();
|
||||
if (getenv(_MCPI_FORCE_HEADLESS_ENV)) {
|
||||
ret = true;
|
||||
} else if (getenv(_MCPI_FORCE_NON_HEADLESS_ENV)) {
|
||||
ret = false;
|
||||
}
|
||||
is_set = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool reborn_is_server() {
|
||||
static int ret;
|
||||
static bool is_set = false;
|
||||
if (!is_set) {
|
||||
ret = getenv(_MCPI_SERVER_MODE_ENV) != nullptr;
|
||||
is_set = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/poll.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <libreborn/util.h>
|
||||
#include <libreborn/log.h>
|
||||
@ -101,6 +102,10 @@ void poll_fds(const std::vector<int> &fds, const std::function<void(int, size_t,
|
||||
on_data(int(i), size_t(bytes_read), buf);
|
||||
} else {
|
||||
// File Descriptor No Longer Accessible
|
||||
if (poll_fd.fd == STDIN_FILENO) {
|
||||
// This Shouldn't Happen
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
poll_fd.events = 0;
|
||||
open_fds--;
|
||||
}
|
||||
@ -120,7 +125,7 @@ __attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char
|
||||
DEBUG(" %s", argv[i]);
|
||||
}
|
||||
// Run
|
||||
int ret = execvpe(argv[0], (char *const *) argv, (char *const *) envp);
|
||||
const int ret = execvpe(argv[0], (char *const *) argv, (char *const *) envp);
|
||||
if (ret == -1) {
|
||||
ERR("Unable To Execute Program: %s: %s", argv[0], strerror(errno));
|
||||
} else {
|
||||
@ -129,6 +134,7 @@ __attribute__((noreturn)) void safe_execvpe(const char *const argv[], const char
|
||||
}
|
||||
|
||||
// Run Command And Get Output
|
||||
#define CHILD_PROCESS_TAG "(Child Process) "
|
||||
std::vector<unsigned char> *run_command(const char *const command[], int *exit_status) {
|
||||
// Run
|
||||
const std::optional<Process> child = fork_with_stdio();
|
||||
@ -174,3 +180,26 @@ std::string get_exit_status_string(const int status) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// Check Exit Status
|
||||
bool is_exit_status_success(const int status) {
|
||||
if (WIFEXITED(status)) {
|
||||
return WEXITSTATUS(status) == 0;
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
const int signal_no = WTERMSIG(status);
|
||||
return signal_no == SIGINT || signal_no == SIGTERM;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Open URL
|
||||
void open_url(const std::string &url) {
|
||||
int return_code;
|
||||
const char *command[] = {"xdg-open", url.c_str(), nullptr};
|
||||
const std::vector<unsigned char> *output = run_command(command, &return_code);
|
||||
delete output;
|
||||
if (!is_exit_status_success(return_code)) {
|
||||
WARN("Unable To Open URL: %s", url.c_str());
|
||||
}
|
||||
}
|
145
libreborn/src/util/flags/available-feature-flags
Normal file
145
libreborn/src/util/flags/available-feature-flags
Normal file
@ -0,0 +1,145 @@
|
||||
CATEGORY Creative Mode
|
||||
CATEGORY Inventory
|
||||
FALSE Expand Creative Mode Inventory
|
||||
FALSE Maximize Creative Mode Inventory Stack Size
|
||||
FALSE Force Survival Mode Inventory UI
|
||||
FALSE Force Survival Mode Inventory Behavior
|
||||
FALSE Display Slot Count In Creative Mode
|
||||
FALSE Remove Creative Mode Restrictions
|
||||
TRUE Disable Hostile AI In Creative Mode
|
||||
TRUE Stop Creative Players From Burning
|
||||
CATEGORY User Interface
|
||||
CATEGORY Screens
|
||||
CATEGORY Title
|
||||
TRUE Add Title Screen Background
|
||||
TRUE Improved Classic Title Screen
|
||||
TRUE Add Splashes
|
||||
TRUE Allow High-Resolution Title
|
||||
TRUE Improved Classic Title Positioning
|
||||
TRUE Use Updated Title
|
||||
CATEGORY Options
|
||||
TRUE Fix Options Screen
|
||||
TRUE Add Reborn Info To Options
|
||||
TRUE Force Touch UI Inventory
|
||||
TRUE Fix Pause Menu
|
||||
TRUE Close Current Screen On Death
|
||||
TRUE Implement Create World Dialog
|
||||
TRUE Display Date In Select World Screen
|
||||
TRUE Add Welcome Screen
|
||||
TRUE Enable Sign Screen
|
||||
CATEGORY HUD
|
||||
TRUE Classic HUD
|
||||
TRUE Translucent Toolbar
|
||||
FALSE Food Overlay
|
||||
TRUE Render Selected Item Text
|
||||
TRUE F3 Debug Information
|
||||
TRUE Hide Crosshair In Third-Person
|
||||
CATEGORY Text
|
||||
TRUE Load Language Files
|
||||
TRUE Add Missing Language Strings
|
||||
FALSE Full Touch UI
|
||||
TRUE Force Touch UI Button Behavior
|
||||
TRUE Improved Cursor Rendering
|
||||
FALSE Remove Forced UI Lag (Can Break Joining Servers)
|
||||
TRUE Improved Button Hover Behavior
|
||||
TRUE Classic Item Count UI
|
||||
TRUE Click Buttons On Mouse Down
|
||||
CATEGORY Rendering
|
||||
CATEGORY Optimizations
|
||||
TRUE Optimized Chunk Sorting
|
||||
TRUE Multidraw Rendering
|
||||
TRUE Increase Render Chunk Size
|
||||
CATEGORY Camera
|
||||
TRUE Enable Camera Rendering
|
||||
TRUE Render Camera Legs
|
||||
CATEGORY Block Outline
|
||||
TRUE Show Block Outlines
|
||||
TRUE Replace Block Highlight With Outline
|
||||
TRUE Hide Block Outline When UI Is Hidden
|
||||
CATEGORY Block Tinting
|
||||
FALSE Add Biome Colors To Grass
|
||||
FALSE Disable Block Tinting
|
||||
TRUE Display Nametags By Default
|
||||
TRUE Disable V-Sync
|
||||
TRUE 3D Chest Model
|
||||
TRUE Use Java Beta 1.3 Light Ramp
|
||||
TRUE Render Fire In Third-Person
|
||||
TRUE Improved Water Rendering
|
||||
TRUE Proper OpenGL Buffer Generation
|
||||
TRUE 3D Dropped Items
|
||||
TRUE Render Entity Shadows
|
||||
TRUE Render Vignette
|
||||
TRUE Proper Entity Shading
|
||||
CATEGORY Textures
|
||||
TRUE Regenerate "gui_blocks" Atlas
|
||||
TRUE Animated Water
|
||||
TRUE Animated Lava
|
||||
TRUE Animated Fire
|
||||
CATEGORY Input
|
||||
TRUE Disable Autojump By Default
|
||||
TRUE Bind "Q" Key To Item Dropping
|
||||
TRUE Bind Common Toggleable Options To Function Keys
|
||||
FALSE Disable Raw Mouse Motion (Not Recommended)
|
||||
FALSE Disable Speed Bridging
|
||||
FALSE Disable Creative Mode Mining Delay
|
||||
TRUE Enable Text Input
|
||||
TRUE Extend Supported Keycodes
|
||||
CATEGORY Multiplayer
|
||||
CATEGORY Chat
|
||||
TRUE Implement Chat
|
||||
FALSE Hide Chat Messages
|
||||
TRUE Allow Joining Survival Mode Servers
|
||||
TRUE External Server Support
|
||||
TRUE Send Full Level When Hosting Game
|
||||
TRUE Sanitize Usernames
|
||||
CATEGORY Gameplay
|
||||
TRUE Implement Death Messages
|
||||
TRUE Implement Game-Mode Switching
|
||||
FALSE Force Mob Spawning
|
||||
TRUE Add Buckets
|
||||
TRUE Load Custom Skins
|
||||
TRUE Add Cake
|
||||
TRUE Implement Crafting Remainders
|
||||
TRUE Implement Sound Engine
|
||||
TRUE Generate Caves
|
||||
CATEGORY Bug Fixes
|
||||
CATEGORY Visual
|
||||
TRUE Fix Held Item Caching
|
||||
TRUE Fix Cobweb Lighting
|
||||
TRUE Fix Furnace Screen Visual Bug
|
||||
TRUE Fix Text Wrapping
|
||||
TRUE Fix Carried Grass's Bottom Texture
|
||||
TRUE Fix Screen Rendering When Hiding HUD
|
||||
TRUE Fix Sugar Position In Hand
|
||||
TRUE Fix Switching Perspective While Sneaking
|
||||
CATEGORY Network
|
||||
TRUE Patch RakNet Security Bug
|
||||
TRUE Prevent Unnecessary Server Pinging
|
||||
TRUE Fix Fire Syncing
|
||||
TRUE Fix Sneaking Syncing
|
||||
CATEGORY Input
|
||||
TRUE Fix Bow & Arrow
|
||||
TRUE Fix Attacking
|
||||
TRUE Fix Escape Key Handling
|
||||
TRUE Stop Locked Mouse From Interacting With HUD
|
||||
CATEGORY Gameplay
|
||||
TRUE Fix Furnace Not Checking Item Auxiliary
|
||||
TRUE Fix Pigmen Burning In The Sun
|
||||
TRUE Fix Door Duplication
|
||||
TRUE Fix Fire Immunity
|
||||
TRUE Fix Sunlight Not Properly Setting Mobs On Fire
|
||||
TRUE Fix Transferring Durability When Using Items
|
||||
TRUE Fix Crash When Generating Certain Seeds
|
||||
TRUE Fix Reloading Textures On Resize
|
||||
TRUE Fix options.txt Loading/Saving
|
||||
CATEGORY Logging
|
||||
FALSE Log FPS
|
||||
TRUE Log Chat Messages
|
||||
TRUE Log Game Status
|
||||
TRUE Log RakNet Startup Errors
|
||||
CATEGORY Miscellaneous
|
||||
TRUE Fullscreen Support
|
||||
TRUE Always Save Chest Tile Entities
|
||||
TRUE Screenshot Support
|
||||
TRUE Add Camera Functionality
|
||||
TRUE Update Default Options
|
128
libreborn/src/util/flags/flags.cpp
Normal file
128
libreborn/src/util/flags/flags.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/flags.h>
|
||||
#include <libreborn/util.h>
|
||||
|
||||
// All Flags
|
||||
static unsigned int find_indent_level(std::string &str) {
|
||||
constexpr unsigned int INDENT = 4;
|
||||
unsigned int count = 0;
|
||||
for (const char c : str) {
|
||||
if (c == ' ') {
|
||||
count++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
str = str.substr(count);
|
||||
return count / INDENT;
|
||||
}
|
||||
Flags::Flags(const std::string &data) {
|
||||
FlagNode::reset_id_counter();
|
||||
// Read Lines
|
||||
std::stringstream stream(data);
|
||||
std::string line;
|
||||
std::vector stack = {&root};
|
||||
while (std::getline(stream, line)) {
|
||||
if (!line.empty()) {
|
||||
// Get Parent
|
||||
const unsigned int indent = find_indent_level(line);
|
||||
if (indent >= stack.size()) {
|
||||
ERR("Bad Feature Flag Indent: %s", line.c_str());
|
||||
}
|
||||
stack.resize(indent + 1);
|
||||
FlagNode &parent = *stack.back();
|
||||
// Add New Node
|
||||
if (FlagNode::handle_line_prefix("CATEGORY", line)) {
|
||||
// New Category
|
||||
FlagNode &category = parent.add_category(line);
|
||||
stack.push_back(&category);
|
||||
} else {
|
||||
// Add Flag
|
||||
if (indent == 0) {
|
||||
ERR("Feature Flag Outside Of Category: %s", line.c_str());
|
||||
}
|
||||
parent.add_flag(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sort
|
||||
root.sort();
|
||||
// Check For Duplicates
|
||||
std::unordered_set<std::string> seen;
|
||||
root.for_each_const([&seen](const FlagNode &node) {
|
||||
const std::string &name = node.name;
|
||||
if (seen.contains(name)) {
|
||||
ERR("Duplicate Feature Flag: %s", name.c_str());
|
||||
} else {
|
||||
seen.insert(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
Flags::operator std::string() const {
|
||||
std::string out;
|
||||
root.for_each_const([&out](const FlagNode &flag) {
|
||||
if (flag.value) {
|
||||
if (!out.empty()) {
|
||||
out += FLAG_SEPERATOR_CHAR;
|
||||
}
|
||||
out += flag.name;
|
||||
}
|
||||
});
|
||||
return out;
|
||||
}
|
||||
Flags &Flags::operator=(const std::string &str) {
|
||||
// Find Flags To Enable
|
||||
std::unordered_set<std::string> to_enable;
|
||||
std::stringstream stream(str);
|
||||
std::string flag_name;
|
||||
while (std::getline(stream, flag_name, FLAG_SEPERATOR_CHAR)) {
|
||||
if (!flag_name.empty()) {
|
||||
to_enable.insert(flag_name);
|
||||
}
|
||||
}
|
||||
// Update Flags
|
||||
root.for_each([&to_enable](FlagNode &flag) {
|
||||
flag.value = to_enable.contains(flag.name);
|
||||
});
|
||||
return *this;
|
||||
}
|
||||
std::unordered_map<std::string, bool> Flags::to_cache() const {
|
||||
std::unordered_map<std::string, bool> out;
|
||||
root.for_each_const([&out](const FlagNode &flag) {
|
||||
out[flag.name] = flag.value;
|
||||
});
|
||||
return out;
|
||||
}
|
||||
void Flags::from_cache(const std::unordered_map<std::string, bool> &cache) {
|
||||
root.for_each([&cache](FlagNode &flag) {
|
||||
if (cache.contains(flag.name)) {
|
||||
flag.value = cache.at(flag.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
void Flags::print() const {
|
||||
root.for_each_const([](const FlagNode &flag) {
|
||||
std::string prefix;
|
||||
for (const std::pair<const std::string, bool> &it : FlagNode::flag_prefixes) {
|
||||
if (it.second == flag.value) {
|
||||
prefix = it.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (prefix.empty()) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
printf("%s %s\n", prefix.c_str(), flag.name.c_str());
|
||||
fflush(stdout);
|
||||
});
|
||||
}
|
||||
|
||||
// Instance
|
||||
EMBEDDED_RESOURCE(available_feature_flags);
|
||||
Flags Flags::get() {
|
||||
return Flags(std::string(available_feature_flags, available_feature_flags + available_feature_flags_len));
|
||||
}
|
89
libreborn/src/util/flags/node.cpp
Normal file
89
libreborn/src/util/flags/node.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/flags.h>
|
||||
|
||||
// Flag
|
||||
static int next_id;
|
||||
void FlagNode::reset_id_counter() {
|
||||
next_id = 1;
|
||||
}
|
||||
FlagNode::FlagNode(const std::string &name_) {
|
||||
name = name_;
|
||||
value = false;
|
||||
id = next_id++;
|
||||
}
|
||||
FlagNode::FlagNode(): FlagNode("Root") {}
|
||||
void FlagNode::sort() {
|
||||
// Sort
|
||||
std::ranges::sort(children, [](const FlagNode &a, const FlagNode &b) {
|
||||
// Place Categories Before Flags
|
||||
if (a.children.empty() != b.children.empty()) {
|
||||
return a.children.empty() < b.children.empty();
|
||||
} else {
|
||||
// Sort Alphabetically
|
||||
return a.name < b.name;
|
||||
}
|
||||
});
|
||||
// Recurse
|
||||
for (FlagNode &child : children) {
|
||||
child.sort();
|
||||
}
|
||||
}
|
||||
|
||||
// Iteration
|
||||
void FlagNode::for_each(const std::function<void(FlagNode &)> &callback) {
|
||||
for (FlagNode &child : children) {
|
||||
if (child.children.empty()) {
|
||||
callback(child);
|
||||
} else {
|
||||
child.for_each(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
void FlagNode::for_each_const(const std::function<void(const FlagNode &)> &callback) const {
|
||||
const_cast<FlagNode &>(*this).for_each(callback);
|
||||
}
|
||||
|
||||
// Parsing
|
||||
bool FlagNode::handle_line_prefix(const std::string &prefix, std::string &line) {
|
||||
const std::string full_prefix = prefix + ' ';
|
||||
if (line.starts_with(full_prefix)) {
|
||||
line = line.substr(full_prefix.size());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::unordered_map<std::string, bool> FlagNode::flag_prefixes = {
|
||||
{"TRUE", true},
|
||||
{"FALSE", false}
|
||||
};
|
||||
void FlagNode::add_flag(std::string line) {
|
||||
// Parse
|
||||
bool value_set = false;
|
||||
bool new_value = false;
|
||||
for (const std::pair<const std::string, bool> &it : flag_prefixes) {
|
||||
if (handle_line_prefix(it.first, line)) {
|
||||
new_value = it.second;
|
||||
value_set = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Check
|
||||
if (!value_set) {
|
||||
ERR("Invalid Feature Flag Line: %s", line.c_str());
|
||||
}
|
||||
if (line.rfind(FLAG_SEPERATOR_CHAR, 0) != std::string::npos) {
|
||||
ERR("Feature Flag Contains Invalid Character");
|
||||
}
|
||||
// Create
|
||||
FlagNode out(line);
|
||||
out.value = new_value;
|
||||
children.push_back(out);
|
||||
}
|
||||
FlagNode &FlagNode::add_category(const std::string &new_name) {
|
||||
const FlagNode out(new_name);
|
||||
children.push_back(out);
|
||||
return children.back();
|
||||
}
|
68
libreborn/src/util/glfw.cpp
Normal file
68
libreborn/src/util/glfw.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <libreborn/glfw.h>
|
||||
#include <libreborn/util.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
// Handle GLFW Error
|
||||
static void glfw_error(__attribute__((unused)) int error, const char *description) {
|
||||
WARN("GLFW Error: %s", description);
|
||||
}
|
||||
|
||||
// Init
|
||||
void init_glfw() {
|
||||
reborn_check_display();
|
||||
glfwSetErrorCallback(glfw_error);
|
||||
if (!glfwInit()) {
|
||||
ERR("Unable To Initialize GLFW");
|
||||
}
|
||||
}
|
||||
|
||||
// Create Window
|
||||
GLFWwindow *create_glfw_window(const char *title, const int width, const int height) {
|
||||
// App ID
|
||||
glfwWindowHintString(GLFW_X11_CLASS_NAME, MCPI_APP_ID);
|
||||
glfwWindowHintString(GLFW_WAYLAND_APP_ID, MCPI_APP_ID);
|
||||
// Create Window
|
||||
GLFWwindow *window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
||||
if (!window) {
|
||||
ERR("Unable To Create GLFW Window");
|
||||
}
|
||||
// Make Window Context Current
|
||||
glfwMakeContextCurrent(window);
|
||||
// Return
|
||||
return window;
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
void cleanup_glfw(GLFWwindow *window) {
|
||||
// Ignore GLFW Errors During Termination
|
||||
glfwSetErrorCallback(nullptr);
|
||||
// Terminate GLFW
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
// Framebuffer Scaling
|
||||
void get_glfw_scale(GLFWwindow *window, float *x_scale, float *y_scale) {
|
||||
// Get Window Size
|
||||
int window_width;
|
||||
int window_height;
|
||||
glfwGetWindowSize(window, &window_width, &window_height);
|
||||
if (window_width <= 0 || window_height <= 0) {
|
||||
return;
|
||||
}
|
||||
// Get Framebuffer Size
|
||||
int framebuffer_width;
|
||||
int framebuffer_height;
|
||||
glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
|
||||
// Calculate Scale
|
||||
if (x_scale) {
|
||||
*x_scale = float(framebuffer_width) / float(window_width);
|
||||
}
|
||||
if (y_scale) {
|
||||
*y_scale = float(framebuffer_height) / float(window_height);
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ int reborn_get_log_fd() {
|
||||
void reborn_set_log(const int fd) {
|
||||
// Set Variable
|
||||
log_fd = -1;
|
||||
set_and_print_env(_MCPI_LOG_FD_ENV, std::to_string(fd).c_str());
|
||||
set_and_print_env(_MCPI_LOG_FD_ENV, fd >= 0 ? std::to_string(fd).c_str() : nullptr);
|
||||
}
|
||||
|
||||
// Debug Logging
|
||||
|
@ -1,11 +1,21 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <libreborn/util.h>
|
||||
#include <libreborn/config.h>
|
||||
#include <libreborn/env.h>
|
||||
|
||||
// Align Number
|
||||
int align_up(int x, const int alignment) {
|
||||
const int diff = x % alignment;
|
||||
if (diff > 0) {
|
||||
x += (alignment - diff);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// Safe Version Of pipe()
|
||||
Pipe::Pipe(): read(-1), write(-1) {
|
||||
int out[2];
|
||||
@ -50,34 +60,6 @@ void unlock_file(const char *file, const int fd) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
// Access Configuration At Runtime
|
||||
const char *reborn_get_version() {
|
||||
return MCPI_VERSION;
|
||||
}
|
||||
bool reborn_is_headless() {
|
||||
static bool ret;
|
||||
static bool is_set = false;
|
||||
if (!is_set) {
|
||||
ret = reborn_is_server();
|
||||
if (getenv(_MCPI_FORCE_HEADLESS_ENV)) {
|
||||
ret = true;
|
||||
} else if (getenv(_MCPI_FORCE_NON_HEADLESS_ENV)) {
|
||||
ret = false;
|
||||
}
|
||||
is_set = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool reborn_is_server() {
|
||||
static int ret;
|
||||
static int is_set = 0;
|
||||
if (!is_set) {
|
||||
ret = getenv(_MCPI_SERVER_MODE_ENV) != nullptr;
|
||||
is_set = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check $DISPLAY
|
||||
void reborn_check_display() {
|
||||
if (!getenv("DISPLAY") && !getenv("WAYLAND_DISPLAY")) {
|
||||
@ -122,4 +104,13 @@ void safe_write(const int fd, const void *buf, const size_t size) {
|
||||
if (bytes_written < 0) {
|
||||
ERR("Unable To Write Data: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
// Get MCPI Home Directory
|
||||
std::string home_get() {
|
||||
const char *home = getenv(_MCPI_HOME_ENV);
|
||||
if (home == nullptr) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
return std::string(home) + std::string(get_home_subdirectory_for_game_data());
|
||||
}
|
@ -2,22 +2,8 @@ project(media-layer)
|
||||
|
||||
# Add Headers
|
||||
add_library(media-layer-headers INTERFACE)
|
||||
target_include_directories(
|
||||
media-layer-headers
|
||||
INTERFACE
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/media-layer>"
|
||||
)
|
||||
# SDK
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
install(TARGETS media-layer-headers EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
# Copy Headers
|
||||
set(GLES_HEADERS "include/GLES")
|
||||
install(
|
||||
DIRECTORY "include/"
|
||||
DESTINATION "${MCPI_SDK_INCLUDE_DIR}/media-layer"
|
||||
)
|
||||
endif()
|
||||
setup_header_dirs(media-layer-headers "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
setup_library(media-layer-headers FALSE TRUE)
|
||||
|
||||
# Add Core
|
||||
if(BUILD_MEDIA_LAYER_CORE)
|
||||
|
@ -1,7 +1,7 @@
|
||||
project(media-layer-core)
|
||||
|
||||
# SDL Re-Implementation Using GLFW
|
||||
set(CORE_SRC
|
||||
# Build
|
||||
add_library(media-layer-core-real SHARED
|
||||
src/base.cpp
|
||||
src/window/media.cpp
|
||||
src/window/cursor.cpp
|
||||
@ -14,14 +14,14 @@ set(CORE_SRC
|
||||
src/audio/file.cpp
|
||||
)
|
||||
|
||||
# Build
|
||||
add_library(media-layer-core-real SHARED ${CORE_SRC}) # Dependencies Are Setup Later
|
||||
# Set Name
|
||||
set_target_properties(media-layer-core-real PROPERTIES OUTPUT_NAME "media-layer-core")
|
||||
if(BUILD_NATIVE_COMPONENTS)
|
||||
add_library(media-layer-core ALIAS media-layer-core-real)
|
||||
endif()
|
||||
|
||||
# Install
|
||||
install(TARGETS media-layer-core-real DESTINATION "${MCPI_LIB_DIR}")
|
||||
setup_library(media-layer-core-real TRUE FALSE)
|
||||
|
||||
# Link
|
||||
find_library(OPENAL_LIBRARY NAMES openal REQUIRED)
|
||||
|
@ -4,11 +4,9 @@
|
||||
#include <AL/al.h>
|
||||
|
||||
#include <media-layer/audio.h>
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
|
||||
#include "file.h"
|
||||
#include "engine.h"
|
||||
#include "api.h"
|
||||
#include "audio.h"
|
||||
|
||||
// Store Audio Sources
|
||||
static std::vector<ALuint> sources;
|
||||
@ -18,7 +16,6 @@ static std::vector<ALuint> sources;
|
||||
static std::vector<ALuint> idle_sources;
|
||||
|
||||
// Error Checking
|
||||
#define AL_ERROR_CHECK() AL_ERROR_CHECK_MANUAL(alGetError())
|
||||
#define AL_ERROR_CHECK_MANUAL(val) \
|
||||
{ \
|
||||
ALenum __err = val; \
|
||||
@ -26,6 +23,7 @@ static std::vector<ALuint> idle_sources;
|
||||
ERR("OpenAL Error: %s", alGetString(__err)); \
|
||||
} \
|
||||
}
|
||||
#define AL_ERROR_CHECK() AL_ERROR_CHECK_MANUAL(alGetError())
|
||||
|
||||
// Delete Sources
|
||||
void _media_audio_delete_sources() {
|
||||
|
@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
__attribute__((visibility("internal"))) void _media_audio_delete_sources();
|
12
media-layer/core/src/audio/audio.h
Normal file
12
media-layer/core/src/audio/audio.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <AL/al.h>
|
||||
|
||||
__attribute__((visibility("internal"))) void _media_audio_delete_sources();
|
||||
|
||||
__attribute__((visibility("internal"))) void _media_audio_init();
|
||||
__attribute__((visibility("internal"))) void _media_audio_cleanup();
|
||||
__attribute__((visibility("internal"))) int _media_audio_is_loaded();
|
||||
|
||||
__attribute__((visibility("internal"))) ALuint _media_audio_get_buffer(const char *source, const char *name);
|
||||
__attribute__((visibility("internal"))) void _media_audio_delete_buffers();
|
@ -2,11 +2,9 @@
|
||||
#include <AL/alc.h>
|
||||
#include <AL/alext.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
|
||||
#include "engine.h"
|
||||
#include "file.h"
|
||||
#include "api.h"
|
||||
#include "audio.h"
|
||||
|
||||
// Store Device
|
||||
static ALCdevice *device = nullptr;
|
||||
|
@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <AL/al.h>
|
||||
|
||||
__attribute__((visibility("internal"))) void _media_audio_init();
|
||||
__attribute__((visibility("internal"))) void _media_audio_cleanup();
|
||||
__attribute__((visibility("internal"))) int _media_audio_is_loaded();
|
@ -6,10 +6,9 @@
|
||||
|
||||
#include <LIEF/ELF.hpp>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
|
||||
#include "file.h"
|
||||
#include "engine.h"
|
||||
#include "audio.h"
|
||||
|
||||
// Load Symbol From ELF File
|
||||
static void load_symbol(const char *source, const char *name, std::function<void(const unsigned char *, uint32_t)> callback) {
|
||||
@ -53,7 +52,7 @@ static ALuint load_sound(const char *source, const char *name) {
|
||||
WARN("Symbol Too Small To Contain Audio Metadata: %s", name);
|
||||
return;
|
||||
}
|
||||
audio_metadata *meta = (audio_metadata *) symbol;
|
||||
const audio_metadata *meta = (audio_metadata *) symbol;
|
||||
|
||||
// Check Frame Size
|
||||
if (meta->frame_size != 1 && meta->frame_size != 2) {
|
||||
@ -73,7 +72,7 @@ static ALuint load_sound(const char *source, const char *name) {
|
||||
}
|
||||
|
||||
// Load Data
|
||||
const int remaining_size = size - sizeof (audio_metadata);
|
||||
const int remaining_size = int(size - sizeof (audio_metadata));
|
||||
const 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);
|
||||
@ -107,7 +106,7 @@ static std::unordered_map<std::string, ALuint> buffers;
|
||||
ALuint _media_audio_get_buffer(const char *source, const char *name) {
|
||||
// Check
|
||||
if (_media_audio_is_loaded()) {
|
||||
if (buffers.count(name) > 0) {
|
||||
if (buffers.contains(name)) {
|
||||
// Return
|
||||
return buffers[name];
|
||||
} else {
|
||||
|
@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <AL/al.h>
|
||||
|
||||
__attribute__((visibility("internal"))) ALuint _media_audio_get_buffer(const char *source, const char *name);
|
||||
__attribute__((visibility("internal"))) void _media_audio_delete_buffers();
|
@ -2,8 +2,6 @@
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#include "window/media.h"
|
||||
|
||||
// SDL Is Replaced With GLFW
|
||||
|
@ -179,20 +179,13 @@ static void convert_to_pixels(GLFWwindow *window, double *xpos, double *ypos) {
|
||||
if (media_SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON && raw_mouse_motion_enabled) {
|
||||
return;
|
||||
}
|
||||
// Get Window Size
|
||||
int window_width;
|
||||
int window_height;
|
||||
glfwGetWindowSize(window, &window_width, &window_height);
|
||||
// Get Framebuffer Size
|
||||
int framebuffer_width;
|
||||
int framebuffer_height;
|
||||
glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
|
||||
// Calculate Ratios
|
||||
const double width_ratio = ((double) framebuffer_width) / ((double) window_width);
|
||||
const double height_ratio = ((double) framebuffer_height) / ((double) window_height);
|
||||
// Get Scale
|
||||
float x_scale = 1;
|
||||
float y_scale = 1;
|
||||
get_glfw_scale(window, &x_scale, &y_scale);
|
||||
// Multiply
|
||||
*xpos *= width_ratio;
|
||||
*ypos *= height_ratio;
|
||||
*xpos *= x_scale;
|
||||
*ypos *= y_scale;
|
||||
}
|
||||
|
||||
// Last Mouse Location
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
|
||||
#include "media.h"
|
||||
|
||||
|
@ -2,16 +2,11 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "media.h"
|
||||
#include "../audio/engine.h"
|
||||
#include "../audio/audio.h"
|
||||
|
||||
// Window
|
||||
GLFWwindow *glfw_window = nullptr;
|
||||
|
||||
// Handle GLFW Error
|
||||
static void glfw_error(__attribute__((unused)) int error, const char *description) {
|
||||
WARN("GLFW Error: %s", description);
|
||||
}
|
||||
|
||||
// Disable V-Sync
|
||||
static bool disable_vsync = false;
|
||||
void media_disable_vsync() {
|
||||
@ -21,15 +16,6 @@ void media_disable_vsync() {
|
||||
}
|
||||
}
|
||||
|
||||
// Force EGL
|
||||
static int force_egl = 0;
|
||||
void media_force_egl() {
|
||||
if (force_egl == -1) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
force_egl = 1;
|
||||
}
|
||||
|
||||
// Init Media Layer
|
||||
#define GL_VERSION 0x1f02
|
||||
typedef const char *(*glGetString_t)(unsigned int name);
|
||||
@ -40,39 +26,21 @@ void media_SDL_WM_SetCaption(const char *title, __attribute__((unused)) const ch
|
||||
}
|
||||
|
||||
// Init GLFW
|
||||
reborn_check_display();
|
||||
glfwSetErrorCallback(glfw_error);
|
||||
if (!glfwInit()) {
|
||||
ERR("Unable To Initialize GLFW");
|
||||
}
|
||||
init_glfw();
|
||||
|
||||
// Create OpenGL Context
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
|
||||
// Use EGL
|
||||
if (force_egl) {
|
||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
|
||||
}
|
||||
force_egl = -1;
|
||||
// Extra Settings
|
||||
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_ALPHA_BITS, 0); // Fix Transparent Window On Wayland
|
||||
// App ID
|
||||
glfwWindowHintString(GLFW_X11_CLASS_NAME, MCPI_APP_ID);
|
||||
glfwWindowHintString(GLFW_WAYLAND_APP_ID, MCPI_APP_ID);
|
||||
glfwWindowHint(GLFW_ALPHA_BITS, 0);
|
||||
|
||||
// Create Window
|
||||
glfw_window = glfwCreateWindow(DEFAULT_WIDTH, DEFAULT_HEIGHT, title, nullptr, nullptr);
|
||||
if (!glfw_window) {
|
||||
ERR("Unable To Create GLFW Window");
|
||||
}
|
||||
glfw_window = create_glfw_window(title, DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
||||
|
||||
// Event Handlers
|
||||
_media_register_event_listeners();
|
||||
|
||||
// Make Window Context Current
|
||||
glfwMakeContextCurrent(glfw_window);
|
||||
|
||||
// Debug
|
||||
const glGetString_t glGetString = (glGetString_t) glfwGetProcAddress("glGetString");
|
||||
DEBUG("Using OpenGL %s", (*glGetString)(GL_VERSION));
|
||||
@ -93,12 +61,8 @@ void media_SDL_WM_SetCaption(const char *title, __attribute__((unused)) const ch
|
||||
// Cleanup Media Layer
|
||||
void media_cleanup() {
|
||||
if (glfw_window) {
|
||||
// Ignore GLFW Errors During Termination
|
||||
glfwSetErrorCallback(nullptr);
|
||||
|
||||
// Terminate GLFW
|
||||
glfwDestroyWindow(glfw_window);
|
||||
glfwTerminate();
|
||||
cleanup_glfw(glfw_window);
|
||||
|
||||
// Cleanup OpenAL
|
||||
_media_audio_cleanup();
|
||||
|
@ -1,11 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/string.h>
|
||||
#include <libreborn/glfw.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
#include <media-layer/core.h>
|
||||
|
||||
// Interactivity
|
||||
|
@ -14,6 +14,7 @@ void media_begin_offscreen_render(const int width, const int height) {
|
||||
glfwWindowHint(GLFW_ALPHA_BITS, 8);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_ALPHA_BITS, 8);
|
||||
// Open Window
|
||||
offscreen_window = glfwCreateWindow(width, height, "Offscreen Rendering", nullptr, nullptr);
|
||||
if (!offscreen_window) {
|
||||
|
@ -16,9 +16,8 @@ void media_toggle_fullscreen();
|
||||
void media_swap_buffers();
|
||||
void media_cleanup();
|
||||
void media_get_framebuffer_size(int *width, int *height);
|
||||
void media_set_interactable(int is_interactable);
|
||||
void media_set_interactable(int toggle);
|
||||
void media_disable_vsync();
|
||||
void media_force_egl();
|
||||
void media_set_raw_mouse_motion_enabled(int enabled);
|
||||
int media_has_extension(const char *name);
|
||||
void media_begin_offscreen_render(int width, int height);
|
||||
|
@ -10,7 +10,7 @@ if(BUILD_NATIVE_COMPONENTS)
|
||||
target_link_libraries(media-layer-trampoline reborn-util media-layer-core trampoline-headers)
|
||||
target_compile_definitions(media-layer-trampoline PRIVATE MEDIA_LAYER_TRAMPOLINE_HOST)
|
||||
# Install
|
||||
install(TARGETS media-layer-trampoline DESTINATION "${MCPI_LIB_DIR}")
|
||||
setup_library(media-layer-trampoline TRUE TRUE)
|
||||
elseif(BUILD_ARM_COMPONENTS)
|
||||
# Guest Component
|
||||
add_library(media-layer-core SHARED src/guest/guest.cpp ${MEDIA_LAYER_TRAMPOLINE_SRC})
|
||||
@ -24,8 +24,5 @@ elseif(BUILD_ARM_COMPONENTS)
|
||||
)
|
||||
target_compile_definitions(media-layer-core PRIVATE MEDIA_LAYER_TRAMPOLINE_GUEST)
|
||||
# Install
|
||||
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
|
||||
install(TARGETS media-layer-core DESTINATION "${MCPI_LIB_DIR}")
|
||||
endif()
|
||||
install(TARGETS media-layer-core EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
setup_library(media-layer-core "${MCPI_USE_MEDIA_LAYER_TRAMPOLINE}" TRUE)
|
||||
endif()
|
||||
|
@ -1,7 +1,8 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include <GLES/gl.h>
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/util.h>
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
@ -301,7 +302,7 @@ static int get_texture_size(const GLsizei width, const GLsizei height, const GLe
|
||||
int alignment;
|
||||
media_glGetIntegerv(is_upload ? GL_UNPACK_ALIGNMENT : GL_PACK_ALIGNMENT, &alignment);
|
||||
// Round
|
||||
line_size = ALIGN_UP(line_size, alignment);
|
||||
line_size = align_up(line_size, alignment);
|
||||
}
|
||||
// Return
|
||||
return line_size * height;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <unistd.h>
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <string>
|
||||
#include <sys/mman.h>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/log.h>
|
||||
|
||||
#include "host.h"
|
||||
|
||||
|
@ -7,8 +7,6 @@
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
|
||||
// SDL Functions
|
||||
|
||||
CALL(0, media_SDL_Init, int, (uint32_t flags))
|
||||
@ -165,15 +163,6 @@ CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled))
|
||||
#endif
|
||||
}
|
||||
|
||||
CALL(66, media_force_egl, void, ())
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
trampoline(true);
|
||||
#else
|
||||
func();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
CALL(71, media_has_extension, int, (const char *name))
|
||||
#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST
|
||||
return trampoline(false, copy_array(name));
|
||||
|
@ -1,15 +1,15 @@
|
||||
project(mods)
|
||||
|
||||
# Common Sources
|
||||
set(SRC
|
||||
# Build
|
||||
add_library(mods SHARED
|
||||
# compat
|
||||
src/compat/compat.cpp
|
||||
src/compat/egl.cpp
|
||||
src/compat/x11.cpp
|
||||
src/compat/bcm_host.cpp
|
||||
src/compat/readdir.cpp
|
||||
src/compat/sdl.cpp
|
||||
# readdir
|
||||
src/readdir/readdir.cpp
|
||||
src/compat/stubs/egl.cpp
|
||||
src/compat/stubs/x11.cpp
|
||||
src/compat/stubs/bcm_host.cpp
|
||||
src/compat/stubs/sdl.cpp
|
||||
# feature
|
||||
src/feature/feature.cpp
|
||||
# version
|
||||
@ -33,6 +33,7 @@ set(SRC
|
||||
src/misc/graphics.cpp
|
||||
src/misc/ui.cpp
|
||||
src/misc/tinting.cpp
|
||||
src/misc/home.cpp
|
||||
# extend
|
||||
src/extend/Screen.cpp
|
||||
src/extend/DynamicTexture.cpp
|
||||
@ -44,15 +45,11 @@ set(SRC
|
||||
src/bucket/bucket.cpp
|
||||
# cake
|
||||
src/cake/cake.cpp
|
||||
# home
|
||||
src/home/home.cpp
|
||||
# touch
|
||||
src/touch/touch.cpp
|
||||
# text-input-box
|
||||
src/text-input-box/TextInputBox.cpp
|
||||
src/text-input-box/TextInputScreen.cpp
|
||||
# test
|
||||
src/test/test.cpp
|
||||
# sound
|
||||
src/sound/sound.cpp
|
||||
src/sound/repository.cpp
|
||||
@ -66,8 +63,6 @@ set(SRC
|
||||
src/input/misc.cpp
|
||||
src/input/drop.cpp
|
||||
src/input/keys.cpp
|
||||
# sign
|
||||
src/sign/sign.cpp
|
||||
# atlas
|
||||
src/atlas/atlas.cpp
|
||||
# title-screen
|
||||
@ -109,29 +104,30 @@ set(SRC
|
||||
src/shading/lighting.cpp
|
||||
src/shading/normals.cpp
|
||||
)
|
||||
|
||||
# Install Splashes
|
||||
install(
|
||||
FILES "src/title-screen/splashes.txt"
|
||||
DESTINATION "${MCPI_INSTALL_DIR}/data"
|
||||
)
|
||||
|
||||
# Build
|
||||
add_library(mods SHARED ${SRC})
|
||||
# Headers
|
||||
setup_header_dirs(mods "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
||||
# Install
|
||||
install(TARGETS mods DESTINATION "${MCPI_INSTALL_DIR}/mods")
|
||||
# SDK
|
||||
install(TARGETS mods EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
||||
set(old_lib_dir "${MCPI_LIB_DIR}")
|
||||
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/mods")
|
||||
setup_library(mods TRUE TRUE)
|
||||
set(MCPI_LIB_DIR "${old_lib_dir}")
|
||||
|
||||
# Dependencies
|
||||
target_link_libraries(mods symbols reborn-patch media-layer-core stb_image dl pthread)
|
||||
|
||||
# Headers
|
||||
target_include_directories(
|
||||
mods
|
||||
target_link_libraries(mods
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/mods>"
|
||||
symbols
|
||||
reborn-patch
|
||||
media-layer-core
|
||||
PRIVATE
|
||||
stb_image
|
||||
dl
|
||||
pthread
|
||||
)
|
||||
# SDK
|
||||
install(DIRECTORY "include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/mods")
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
extern "C" {
|
||||
|
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
int creative_is_restricted();
|
||||
bool creative_is_restricted();
|
||||
}
|
@ -41,7 +41,7 @@ template <typename Self, typename Data>
|
||||
Data *extend_get_data(Self *self) {
|
||||
return (Data *) (self + 1);
|
||||
}
|
||||
template <typename Self, typename Data>
|
||||
template <typename Data, typename Self = typename Data::_Self>
|
||||
auto extend_struct(auto&&... args) -> decltype(Self::allocate()) {
|
||||
constexpr size_t size = sizeof(Self) + sizeof(Data);
|
||||
Self *out = (Self *) ::operator new(size);
|
||||
@ -53,11 +53,12 @@ auto extend_struct(auto&&... args) -> decltype(Self::allocate()) {
|
||||
// Helpers
|
||||
#define CREATE_HELPER(name) \
|
||||
struct Custom##name { \
|
||||
using _Self = name; \
|
||||
explicit Custom##name(auto&&... args): self(((name *) this) - 1) { \
|
||||
self->constructor(std::forward<decltype(args)>(args)...); \
|
||||
self->vtable = get_vtable(); \
|
||||
} \
|
||||
name *const self; \
|
||||
_Self *const self; \
|
||||
static name##_vtable *get_vtable(); \
|
||||
private: \
|
||||
static void setup_vtable(name##_vtable *vtable); \
|
||||
|
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
const char *home_get();
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
void run_tests();
|
||||
void init_version();
|
||||
void init_compat();
|
||||
void init_server();
|
||||
@ -9,7 +8,6 @@ void init_multiplayer();
|
||||
void init_benchmark();
|
||||
void init_sound();
|
||||
void init_input();
|
||||
void init_sign();
|
||||
void init_camera();
|
||||
void init_atlas();
|
||||
void init_title_screen();
|
||||
@ -25,7 +23,6 @@ void init_options();
|
||||
void init_chat();
|
||||
void init_bucket();
|
||||
void init_cake();
|
||||
void init_home();
|
||||
void init_override();
|
||||
void init_screenshot();
|
||||
void init_f3();
|
||||
|
@ -2,8 +2,4 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#define CHANGELOG_FILE "CHANGELOG.md"
|
||||
|
||||
extern "C" {
|
||||
void open_url(const std::string &url);
|
||||
}
|
||||
#define CHANGELOG_FILE "CHANGELOG.md"
|
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
void sign_key_press(char key);
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/patch.h>
|
||||
#include <libreborn/util.h>
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <media-layer/core.h>
|
||||
|
||||
#include <mods/feature/feature.h>
|
||||
@ -127,7 +130,7 @@ static void generate_atlas(Minecraft *minecraft) {
|
||||
int alignment;
|
||||
media_glGetIntegerv(GL_PACK_ALIGNMENT, &alignment);
|
||||
// Round
|
||||
line_size = ALIGN_UP(line_size, alignment);
|
||||
line_size = align_up(line_size, alignment);
|
||||
}
|
||||
Texture texture;
|
||||
texture.width = atlas_texture_size;
|
||||
|
@ -1,6 +1,10 @@
|
||||
#include <ctime>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/patch.h>
|
||||
#include <libreborn/util.h>
|
||||
#include <libreborn/env.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <media-layer/core.h>
|
||||
@ -41,7 +45,6 @@ static void start_world(Minecraft *minecraft) {
|
||||
|
||||
// Open ProgressScreen
|
||||
ProgressScreen *screen = ProgressScreen::allocate();
|
||||
ALLOC_CHECK(screen);
|
||||
screen = screen->constructor();
|
||||
minecraft->setScreen((Screen *) screen);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <libreborn/patch.h>
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/feature/feature.h>
|
||||
@ -22,7 +23,7 @@ static std::string BucketItem_getDescriptionId(__attribute__((unused)) FoodItem
|
||||
return "item.bucket";
|
||||
}
|
||||
}
|
||||
static int32_t BucketItem_getIcon(__attribute__((unused)) FoodItem *item, int32_t auxiliary) {
|
||||
static int32_t BucketItem_getIcon(__attribute__((unused)) FoodItem *item, const int32_t auxiliary) {
|
||||
if (auxiliary == Tile::water->id) {
|
||||
return 75;
|
||||
} else if (auxiliary == Tile::lava->id) {
|
||||
@ -35,7 +36,7 @@ static int32_t BucketItem_getIcon(__attribute__((unused)) FoodItem *item, int32_
|
||||
}
|
||||
|
||||
// Filling
|
||||
static bool fill_bucket(ItemInstance *item_instance, Player *player, int new_auxiliary) {
|
||||
static bool fill_bucket(ItemInstance *item_instance, const Player *player, const int new_auxiliary) {
|
||||
bool success = false;
|
||||
if (item_instance->count == 1) {
|
||||
item_instance->auxiliary = new_auxiliary;
|
||||
@ -57,7 +58,7 @@ static bool fill_bucket(ItemInstance *item_instance, Player *player, int new_aux
|
||||
|
||||
|
||||
// Use Bucket
|
||||
static int32_t BucketItem_useOn(__attribute__((unused)) FoodItem *item, ItemInstance *item_instance, Player *player, Level *level, int32_t x, int32_t y, int32_t z, int32_t hit_side, __attribute__((unused)) float hit_x, __attribute__((unused)) float hit_y, __attribute__((unused)) float hit_z) {
|
||||
static int32_t BucketItem_useOn(__attribute__((unused)) FoodItem *item, ItemInstance *item_instance, Player *player, Level *level, int32_t x, int32_t y, int32_t z, const int32_t hit_side, __attribute__((unused)) float hit_x, __attribute__((unused)) float hit_y, __attribute__((unused)) float hit_z) {
|
||||
if (item_instance->count < 1 || item_instance->auxiliary == 1) {
|
||||
return 0;
|
||||
} else if (item_instance->auxiliary == 0) {
|
||||
@ -188,7 +189,6 @@ CUSTOM_VTABLE(bucket, FoodItem) {
|
||||
static FoodItem *create_bucket(const int32_t id, int32_t texture_x, int32_t texture_y, std::string name) {
|
||||
// Construct
|
||||
FoodItem *item = FoodItem::allocate();
|
||||
ALLOC_CHECK(item);
|
||||
Item_constructor->get(false)((Item *) item, id); // FoodItem's Constructor Was Inlined
|
||||
|
||||
// Set VTable
|
||||
@ -237,7 +237,6 @@ bool Cow_interact_injection(Cow_interact_t original, Cow *self, Player *player)
|
||||
// Creative Inventory
|
||||
static void inventory_add_item(FillingContainer *inventory, FoodItem *item, int32_t auxiliary) {
|
||||
ItemInstance *item_instance = new ItemInstance;
|
||||
ALLOC_CHECK(item_instance);
|
||||
item_instance = item_instance->constructor_item_extra((Item *) item, 1, auxiliary);
|
||||
inventory->addItem(item_instance);
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/feature/feature.h>
|
||||
@ -45,7 +44,7 @@ static int Cake_getTexture3(__attribute__((unused)) Tile *tile, LevelSource *lev
|
||||
// Rendering
|
||||
static bool Cake_isSolidRender(__attribute__((unused)) Tile *tile) {
|
||||
// Stop it from turning other blocks invisable
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int Cake_getRenderLayer(__attribute__((unused)) Tile *tile) {
|
||||
@ -70,7 +69,7 @@ static AABB *Cake_getAABB(Tile *tile, Level *level, int x, int y, int z) {
|
||||
// Get the size of the slices
|
||||
int data = level->getData(x, y, z);
|
||||
if (data >= 6) data = 0;
|
||||
const float slice_size = (1.0 / 7.0) * (float) data;
|
||||
const float slice_size = (1.0f / 7.0f) * (float) data;
|
||||
|
||||
// Corner 1
|
||||
AABB *aabb = &tile->aabb;
|
||||
@ -79,9 +78,9 @@ static AABB *Cake_getAABB(Tile *tile, Level *level, int x, int y, int z) {
|
||||
aabb->z1 = (float) z + CAKE_LEN;
|
||||
|
||||
// Corner 2
|
||||
aabb->x2 = (float) x + (1.0 - CAKE_LEN);
|
||||
aabb->y2 = (float) y + 0.5;
|
||||
aabb->z2 = (float) z + (1.0 - CAKE_LEN) - slice_size;
|
||||
aabb->x2 = (float) x + (1.0f - CAKE_LEN);
|
||||
aabb->y2 = (float) y + 0.5f;
|
||||
aabb->z2 = (float) z + (1.0f - CAKE_LEN) - slice_size;
|
||||
|
||||
return aabb;
|
||||
}
|
||||
@ -91,7 +90,7 @@ static void Cake_updateShape(Tile *tile, LevelSource *level, int x, int y, int z
|
||||
int data = level->getData(x, y, z);
|
||||
if (data >= 6) data = 0;
|
||||
// Get slice amount
|
||||
const float slice_size = (1.0 / 7.0) * (float) data;
|
||||
const float slice_size = (1.0f / 7.0f) * (float) data;
|
||||
tile->setShape(
|
||||
CAKE_LEN, 0.0, CAKE_LEN,
|
||||
1.0 - CAKE_LEN, 0.5, (1.0 - CAKE_LEN) - slice_size
|
||||
@ -118,14 +117,12 @@ static int Cake_use(__attribute__((unused)) Tile *tile, Level *level, int x, int
|
||||
static void make_cake() {
|
||||
// Construct
|
||||
cake = Tile::allocate();
|
||||
ALLOC_CHECK(cake);
|
||||
int texture = 122;
|
||||
cake->constructor(92, texture, Material::dirt);
|
||||
cake->texture = texture;
|
||||
|
||||
// Set VTable
|
||||
cake->vtable = extend_dup_vtable(Tile_vtable::base);
|
||||
ALLOC_CHECK(cake->vtable);
|
||||
|
||||
// Set shape
|
||||
cake->setShape(
|
||||
@ -161,7 +158,6 @@ static void Tile_initTiles_injection() {
|
||||
// Add cake to creative inventory
|
||||
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(FillingContainer *filling_container) {
|
||||
ItemInstance *cake_instance = new ItemInstance;
|
||||
ALLOC_CHECK(cake_instance);
|
||||
cake_instance->count = 255;
|
||||
cake_instance->auxiliary = 0;
|
||||
cake_instance->id = 92;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user