This commit is contained in:
Bigjango13 2024-07-06 17:10:31 -07:00
commit 8cd674004f
29 changed files with 206 additions and 91 deletions

View File

@ -16,7 +16,7 @@
* Add `Optimized Chunk Sorting` Feature Flag (Enabled By Default)
* Add `Add Cake` Feature Flag (Enabled By Default)
* Add `Add Reborn Info To Options` Feature Flag (Enabled By Default)
* Add `Track FPS` Feature Flag (Disabled By Default)
* Add `Log FPS` Feature Flag (Disabled By Default)
* Split Up `Remove Creative Mode Restrictions` Feature Flag
* `Remove Creative Mode Restrictions` (Disabled By Default)
* `Display Slot Count In Creative Mode` (Disabled By Default)

View File

@ -56,17 +56,15 @@ static void print_debug_information() {
}
// Bootstrap
void bootstrap() {
void bootstrap(const options_t &options) {
// Debug Information
print_debug_information();
// Check Page Size (Not Needed When Using QEMU)
#ifndef MCPI_RUNTIME_IS_QEMU
long page_size = sysconf(_SC_PAGESIZE);
if (page_size != REQUIRED_PAGE_SIZE) {
ERR("Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
CONDITIONAL_ERR(!options.skip_pagesize_check, "Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
}
#endif
// Get Binary Directory
const std::string binary_directory = get_binary_directory();

View File

@ -2,6 +2,8 @@
#include <string>
void bootstrap();
#include "options/parser.h"
void bootstrap(const options_t &options);
void copy_sdk(const std::string &binary_directory, bool log_with_debug);
std::string bootstrap_mods(const std::string &binary_directory);

View File

@ -66,8 +66,9 @@ TRUE Display Date In Select World Screen
TRUE Optimized Chunk Sorting
TRUE Fix Held Item Caching
TRUE Add Reborn Info To Options
FALSE Track FPS
FALSE Log FPS
TRUE Add Welcome Screen
TRUE Add Missing Language Strings
TRUE Fix Pigmen Burning In The Sun
TRUE Fix Grass's Bottom Texture
TRUE Fix Grass's Bottom Texture
TRUE F3 Debug Information

View File

@ -90,7 +90,7 @@ static void start_game(const options_t &options) {
}
// Bootstrap
bootstrap();
bootstrap(options);
}
// Main

View File

@ -9,4 +9,5 @@ OPTION(benchmark, "benchmark", -7, "Run Client-Mode Benchmark")
OPTION(only_generate, "only-generate", -8, "Generate World And Exit (Server-Mode Only)")
OPTION(force_headless, "force-headless", -9, "Force Disable Game Rendering")
OPTION(force_non_headless, "force-non-headless", -10, "Force Enable Game Rendering")
OPTION(server_mode, "server", -11, "Run In Server-Mode")
OPTION(server_mode, "server", -11, "Run In Server-Mode")
OPTION(skip_pagesize_check, "skip-pagesize-check", -12, "Skip Page-Size Check (Not Recommended)")

View File

@ -21,6 +21,14 @@ int reborn_get_debug_fd();
#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 IMPOSSIBLE() ERR("This Should Never Be Called")
#define CONDITIONAL_ERR(is_error, ...) \
{ \
if ((is_error)) { \
ERR(__VA_ARGS__); \
} else { \
WARN(__VA_ARGS__); \
} \
}
#ifdef __cplusplus
}

View File

@ -15,6 +15,18 @@
} \
}
// 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; \
})
// Hook Library Function
#ifdef __cplusplus
#define hooked_function_setup extern "C"

View File

@ -107,6 +107,9 @@ static SDLKey glfw_key_to_sdl_key(const int key) {
// Screenshot
case GLFW_KEY_F2:
return SDLK_F2;
// Debug
case GLFW_KEY_F3:
return SDLK_F3;
// Hide GUI
case GLFW_KEY_F1:
return SDLK_F1;
@ -457,6 +460,9 @@ void media_cleanup() {
// Cleanup OpenAL
_media_audio_cleanup();
// Mark As Stopped
glfw_window = nullptr;
}
}
@ -558,4 +564,4 @@ void media_get_framebuffer_size(int *width, int *height) {
*width = DEFAULT_WIDTH;
*height = DEFAULT_HEIGHT;
}
}
}

View File

@ -35,12 +35,12 @@ typedef enum {
SDLK_LEFT = 276,
SDLK_F1 = 282,
SDLK_F2 = 283,
SDLK_F3 = 284,
SDLK_F5 = 286,
SDLK_F11 = 292,
SDLK_F12 = 293,
SDLK_RSHIFT = 303,
SDLK_LSHIFT = 304,
SDLK_WORLD_0 = 160 // Used For Controller Crafting Button
SDLK_LSHIFT = 304
} SDLKey;
typedef enum {

View File

@ -262,8 +262,7 @@ static int get_texture_size(const GLsizei width, const GLsizei height, const GLe
int alignment;
glGetIntegerv(is_upload ? GL_UNPACK_ALIGNMENT : GL_PACK_ALIGNMENT, &alignment);
// Round
int diff = line_size % alignment;
line_size = line_size + (alignment - diff);
line_size = ALIGN_UP(line_size, alignment);
}
// Return
return line_size * height;
@ -718,7 +717,7 @@ CALL(65, glReadPixels, void, (GLint x, GLint y, GLsizei width, GLsizei height, G
GLsizei height = args.next<GLsizei>();
GLenum format = args.next<GLenum>();
GLenum type = args.next<GLenum>();
int data_size = get_texture_size(width, height, format, type, false);
const int data_size = get_texture_size(width, height, format, type, false);
unsigned char *data = new unsigned char[data_size];
func(x, y, width, height, format, type, data);
writer(args.next<uint32_t>(), data, data_size);

View File

@ -87,6 +87,8 @@ set(SRC
src/benchmark/benchmark.cpp
# init
src/init/init.cpp
# f3
src/f3/f3.cpp
)
# Install Splashes
install(

View File

@ -28,4 +28,5 @@ void init_cake();
void init_home();
void init_override();
void init_screenshot();
void init_f3();
}

View File

@ -5,6 +5,7 @@ KEY(LEFT, 0x25)
KEY(RIGHT, 0x27)
KEY(F1, 0x70)
KEY(F2, 0x71)
KEY(F3, 0x72)
KEY(F5, 0x74)
KEY(F11, 0x7a)
KEY(RETURN, 0xd)

View File

@ -9,9 +9,6 @@ extern "C" {
int32_t misc_get_real_selected_slot(Player *player);
void misc_render_background(int color, Minecraft *minecraft, int x, int y, int width, int height);
typedef void (*misc_update_function_FillingContainer_t)(FillingContainer *obj);
void misc_run_on_creative_inventory_setup(misc_update_function_FillingContainer_t function); // obj == FillingContainer *
extern bool is_in_chat;
}
@ -24,3 +21,5 @@ void misc_run_on_items_setup(const std::function<void()> &func);
void misc_run_on_language_setup(const std::function<void()> &func);
void misc_run_on_game_key_press(const std::function<bool(Minecraft *, int)> &func);
void misc_run_on_key_press(const std::function<bool(Minecraft *, int)> &func);
void misc_run_on_creative_inventory_setup(const std::function<void(FillingContainer *)> &function);
void misc_run_on_swap_buffers(const std::function<void()> &function);

View File

@ -48,9 +48,7 @@ static void start_world(Minecraft *minecraft) {
// Track Frames
static unsigned long long int frames = 0;
HOOK(media_swap_buffers, void, ()) {
ensure_media_swap_buffers();
real_media_swap_buffers();
static void handle_swap_buffers() {
frames++;
}
@ -64,8 +62,8 @@ static void Minecraft_tick_injection(__attribute__((unused)) Minecraft *minecraf
static long long int get_time() {
timespec ts = {};
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
long long int a = (long long int) ts.tv_nsec;
long long int b = ((long long int) ts.tv_sec) * NANOSECONDS_IN_SECOND;
const long long int a = ts.tv_nsec;
const long long int b = ((long long int) ts.tv_sec) * NANOSECONDS_IN_SECOND;
return a + b;
}
@ -161,6 +159,8 @@ void init_benchmark() {
bool active = getenv(_MCPI_BENCHMARK_ENV) != nullptr;
if (active) {
misc_run_on_update(Minecraft_update_injection);
// Track Frames
misc_run_on_swap_buffers(handle_swap_buffers);
// Track Ticks
misc_run_on_tick(Minecraft_tick_injection);
// Disable Interaction

2
mods/src/f3/README.md Normal file
View File

@ -0,0 +1,2 @@
# `f3` Mod
This mod add a proper F3 debug screen.

87
mods/src/f3/f3.cpp Normal file
View File

@ -0,0 +1,87 @@
#include <vector>
#include <iomanip>
#include <sstream>
#include <symbols/minecraft.h>
#include <libreborn/libreborn.h>
#include <mods/misc/misc.h>
#include <mods/feature/feature.h>
#include <mods/input/input.h>
#include <mods/version/version.h>
#include <mods/fps/fps.h>
#include <mods/init/init.h>
// Get Debug Information
static std::string to_string_with_precision(const double x, const int precision) {
std::stringstream stream;
stream << std::fixed << std::setprecision(precision) << x;
return stream.str();
}
static int debug_precision = 3;
static std::vector<std::string> get_debug_info(const Minecraft *minecraft) {
std::vector<std::string> info;
// Version
info.push_back(std::string("MCPI ") + version_get());
// FPS
info.push_back("FPS: " + to_string_with_precision(fps, debug_precision));
// X/Y/Z
if (minecraft->player) {
info.push_back("");
float x = minecraft->player->x;
float y = minecraft->player->y - minecraft->player->height_offset;
float z = minecraft->player->z;
minecraft->command_server->pos_translator.to(&x, &y, &z);
info.push_back("X: " + to_string_with_precision(x, debug_precision));
info.push_back("Y: " + to_string_with_precision(y, debug_precision));
info.push_back("Z: " + to_string_with_precision(z, debug_precision));
}
// Return
return info;
}
// Render Text With Background
static uint32_t debug_background_color = 0x90505050;
static int debug_text_color = 0xe0e0e0;
static int debug_background_padding = 1;
static int line_height = 8;
static void render_debug_line(Gui *gui, std::string &line, const int x, const int y) {
// Draw Background
int width = gui->minecraft->font->width(&line);
if (width == 0) {
return;
}
gui->fill(x - debug_background_padding, y - debug_background_padding, x + width + debug_background_padding, y + line_height, debug_background_color);
// Draw Text
gui->minecraft->font->draw(&line, float(x), float(y), debug_text_color);
}
// Draw Debug Information
static bool debug_info_shown = false;
static int debug_margin = 2;
static int debug_line_padding = 1;
static void Gui_renderDebugInfo_injection(__attribute__((unused)) Gui_renderDebugInfo_t original, Gui *self) {
if (debug_info_shown) {
std::vector<std::string> info = get_debug_info(self->minecraft);
int y = debug_margin;
for (std::string &line : info) {
render_debug_line(self, line, debug_margin, y);
y += line_height;
y += debug_line_padding;
}
}
}
// Init
void init_f3() {
if (feature_has("F3 Debug Information", server_disabled)) {
overwrite_calls(Gui_renderDebugInfo, Gui_renderDebugInfo_injection);
misc_run_on_game_key_press([](__attribute__((unused)) Minecraft *minecraft, int key) {
if (key == MC_KEY_F3) {
debug_info_shown = !debug_info_shown;
return true;
} else {
return false;
}
});
}
}

View File

@ -6,49 +6,42 @@
#include <mods/feature/feature.h>
#include <mods/fps/fps.h>
// Track FPS
// Get Time
#define NANOSECONDS_IN_SECOND 1000000000ll
static long long int get_time() {
timespec ts = {};
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
long long int a = (long long int) ts.tv_nsec;
long long int b = ((long long int) ts.tv_sec) * NANOSECONDS_IN_SECOND;
const long long int a = ts.tv_nsec;
const long long int b = ((long long int) ts.tv_sec) * NANOSECONDS_IN_SECOND;
return a + b;
}
// Track FPS
static bool log_fps;
double fps = 0;
static void update_fps(__attribute__((unused)) Minecraft *minecraft) {
static bool is_last_update_time_set = false;
static long long int last_update_time;
long long int time = get_time();
if (is_last_update_time_set) {
long long int update_time = time - last_update_time;
fps = ((double) NANOSECONDS_IN_SECOND) / ((double) update_time);
} else {
is_last_update_time_set = true;
}
last_update_time = time;
}
// Print FPS
static void print_fps(__attribute__((unused)) Minecraft *minecraft) {
// Track Ticks
static int ticks = 0;
ticks++;
if (ticks == 20) {
// One Second Has Passed, Reset
ticks = 0;
}
// Print
if (ticks == 0) {
INFO("FPS: %f", fps);
static void update_fps() {
// Track Frames
static long long int frames = 0;
frames++;
// Get Delta
const long long int time = get_time();
static long long int last_time = time;
const long long int delta = time - last_time;
const double delta_seconds = double(delta) / double(NANOSECONDS_IN_SECOND);
// Calculate FPS
if (delta_seconds >= 1) {
fps = double(frames) / delta_seconds;
frames = 0;
last_time = time;
// Log
if (log_fps) {
INFO("FPS: %f", fps);
}
}
}
// Init
void init_fps() {
if (feature_has("Track FPS", server_disabled)) {
misc_run_on_update(update_fps);
misc_run_on_tick(print_fps);
}
misc_run_on_swap_buffers(update_fps);
log_fps = feature_has("Log FPS", server_disabled);
}

View File

@ -23,8 +23,8 @@ __attribute__((constructor)) static void init() {
init_title_screen();
if (!reborn_is_headless()) {
init_skin();
init_fps();
}
init_fps();
init_touch();
init_textures();
init_creative();
@ -42,5 +42,6 @@ __attribute__((constructor)) static void init() {
}
if (!reborn_is_headless()) {
init_screenshot();
init_f3();
}
}

View File

@ -1,4 +1,3 @@
#include <utility>
#include <vector>
#include <libreborn/libreborn.h>
@ -9,31 +8,43 @@
#include "misc-internal.h"
// Callbacks
#define STORE_CALLBACK(name, type) \
static std::vector<misc_update_function_##type##_t> &get_misc_##name##_functions() { \
static std::vector<misc_update_function_##type##_t> functions; \
template <typename... Args>
struct Callbacks {
std::vector<std::function<void(Args...)>> functions;
void run(Args... args) {
for (const std::function<void(Args...)> &func : functions) {
func(args...);
}
}
};
// Callbacks
#define SETUP_CALLBACK(name, ...) \
static Callbacks<__VA_ARGS__> &get_misc_##name##_functions() { \
static Callbacks<__VA_ARGS__> functions; \
return functions; \
} \
void misc_run_on_##name(misc_update_function_##type##_t function) { \
get_misc_##name##_functions().push_back(function); \
}
#define SETUP_CALLBACK(name, type) \
STORE_CALLBACK(name, type) \
static void handle_misc_##name(type *obj) { \
for (misc_update_function_##type##_t function : get_misc_##name##_functions()) { \
function(obj); \
} \
void misc_run_on_##name(const std::function<void(__VA_ARGS__)> &function) { \
get_misc_##name##_functions().functions.push_back(function); \
}
// Run Functions On Creative Inventory Setup
SETUP_CALLBACK(creative_inventory_setup, FillingContainer);
SETUP_CALLBACK(creative_inventory_setup, FillingContainer *);
// Handle Custom Creative Inventory Setup Behavior
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(FillingContainer *filling_container, ItemInstance *item_instance) {
// Call Original Method
filling_container->addItem(item_instance);
// Run Functions
handle_misc_creative_inventory_setup(filling_container);
get_misc_creative_inventory_setup_functions().run(filling_container);
}
// Track Frames
SETUP_CALLBACK(swap_buffers);
HOOK(media_swap_buffers, void, ()) {
get_misc_swap_buffers_functions().run();
ensure_media_swap_buffers();
real_media_swap_buffers();
}
// API

View File

@ -251,14 +251,6 @@ static const char *RAKNET_ERROR_NAMES[] = {
"Couldn't Generate GUID",
"Unknown"
};
#define CONDITIONAL_ERR(is_error, ...) \
{ \
if ((is_error)) { \
ERR(__VA_ARGS__); \
} else { \
WARN(__VA_ARGS__); \
} \
}
static RakNet_StartupResult RakNetInstance_host_RakNet_RakPeer_Startup_injection(RakNet_RakPeer *rak_peer, unsigned short maxConnections, unsigned char *socketDescriptors, uint32_t socketDescriptorCount, int32_t threadPriority) {
// Call Original Method
RakNet_StartupResult result = rak_peer->Startup(maxConnections, socketDescriptors, socketDescriptorCount, threadPriority);

View File

@ -78,10 +78,7 @@ void screenshot_take(Gui *gui) {
int alignment;
glGetIntegerv(GL_PACK_ALIGNMENT, &alignment);
// Round
int diff = line_size % alignment;
if (diff > 0) {
line_size = line_size + (alignment - diff);
}
line_size = ALIGN_UP(line_size, alignment);
}
int size = height * line_size;

View File

@ -92,10 +92,7 @@ static int get_line_size(int width) {
int alignment;
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
// Round
int diff = line_size % alignment;
if (diff > 0) {
line_size = line_size + (alignment - diff);
}
line_size = ALIGN_UP(line_size, alignment);
}
return line_size;
}

View File

@ -1,4 +1,5 @@
method void from(int *x, int *y, int *z) = 0x27c98;
method void to(float *x, float *y, float *z) = 0x27be0;
property float x = 0x4;
property float y = 0x8;

View File

@ -1 +1,2 @@
method int width(std::string *string) = 0x24d4c;
method void draw(std::string *string, float x, float y, uint color) = 0x250e0;

View File

@ -14,6 +14,7 @@ method void renderSlot(int slot, int x, int y, float alpha) = 0x25cc0;
method void renderSlotText(ItemInstance *item, float x, float y, bool finite, bool shadow) = 0x25df8;
method void handleKeyPressed(int key) = 0x25a08;
method void renderHearts() = 0x2641c;
method void renderDebugInfo() = 0x26958;
property Minecraft *minecraft = 0x9f4;
property float selected_item_text_timer = 0x9fc;

View File

@ -7,4 +7,6 @@ method void blit(int x_dest, int y_dest, int x_src, int y_src, int width_dest, i
method void drawCenteredString(Font *font, std::string *text, int x, int y, uint color) = 0x2821c;
method void drawString(Font *font, std::string *text, int x, int y, uint color) = 0x28284;
method void fill(int x1, int y1, int x2, int y2, uint color) = 0x285f0;
method void fillGradient(int x1, int y1, int x2, int y2, int color1, int color2) = 0x287c0;
method void fillGradient(int x1, int y1, int x2, int y2, int color1, int color2) = 0x287c0;
property float z = 0x4;

View File

@ -2,7 +2,7 @@ method void begin(int mode) = 0x529d4;
method void draw() = 0x52e08;
method void colorABGR(int color) = 0x52b54;
method void color(int r, int g, int b, int a) = 0x52a48;
method void vertex(float x, float y, float z) = 052bc0;
method void vertex(float x, float y, float z) = 0x52bc0;
method void vertexUV(float x, float y, float z, float u, float v) = 0x52d40;
method void addOffset(float x, float y, float z) = 0x52d90;