Expand Debug Info
This commit is contained in:
parent
66f4f11a68
commit
661cfd02ad
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
extern double fps;
|
||||
extern double tps;
|
@ -1,6 +1,7 @@
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <cmath>
|
||||
|
||||
#include <symbols/minecraft.h>
|
||||
#include <libreborn/libreborn.h>
|
||||
@ -18,20 +19,34 @@ static std::string to_string_with_precision(const double x, const int precision)
|
||||
stream << std::fixed << std::setprecision(precision) << x;
|
||||
return stream.str();
|
||||
}
|
||||
static float wrap_degrees(float x) {
|
||||
x = std::fmod(x, 360);
|
||||
if (x >= 180) {
|
||||
x -= 360;
|
||||
}
|
||||
if (x < -180) {
|
||||
x += 360;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
static int debug_precision = 3;
|
||||
static std::vector<std::string> get_debug_info(const Minecraft *minecraft) {
|
||||
static std::vector<std::string> get_debug_info_left(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));
|
||||
// Seed
|
||||
// Level Information
|
||||
if (minecraft->level) {
|
||||
info.push_back("");
|
||||
info.push_back("Seed: " + std::to_string(minecraft->level->data.seed));
|
||||
info.push_back("Time: " + std::to_string(minecraft->level->data.time));
|
||||
info.push_back("Entities: " + std::to_string(minecraft->level->entities.size()));
|
||||
info.push_back("Players: " + std::to_string(minecraft->level->players.size()));
|
||||
}
|
||||
// X/Y/Z
|
||||
// Player Information
|
||||
if (minecraft->player) {
|
||||
// X/Y/Z
|
||||
info.push_back("");
|
||||
float x = minecraft->player->x;
|
||||
float y = minecraft->player->y - minecraft->player->height_offset;
|
||||
@ -40,6 +55,93 @@ static std::vector<std::string> get_debug_info(const Minecraft *minecraft) {
|
||||
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));
|
||||
// Rotation
|
||||
info.push_back("");
|
||||
const float yaw = wrap_degrees(minecraft->player->yaw);
|
||||
info.push_back("Yaw: " + to_string_with_precision(yaw, debug_precision));
|
||||
const float pitch = wrap_degrees(minecraft->player->pitch);
|
||||
info.push_back("Pitch: " + to_string_with_precision(pitch, debug_precision));
|
||||
// Facing
|
||||
char axis[3] = {};
|
||||
bool is_positive_on_axis;
|
||||
std::string direction;
|
||||
if (const float abs_yaw = std::abs(yaw); abs_yaw < 45 || abs_yaw > 135) {
|
||||
// Z-Axis
|
||||
axis[1] = 'Z';
|
||||
is_positive_on_axis = abs_yaw < 90;
|
||||
direction = is_positive_on_axis ? "South" : "North";
|
||||
} else {
|
||||
// X-Axis
|
||||
axis[1] = 'X';
|
||||
is_positive_on_axis = yaw < 0;
|
||||
direction = is_positive_on_axis ? "East" : "West";
|
||||
}
|
||||
axis[0] = is_positive_on_axis ? '+' : '-';
|
||||
info.push_back("Facing: " + direction + " (" + axis + ")");
|
||||
}
|
||||
// Return
|
||||
return info;
|
||||
}
|
||||
static std::vector<std::string> get_debug_info_right(const Minecraft *minecraft) {
|
||||
std::vector<std::string> info;
|
||||
// TPS
|
||||
info.push_back("TPS: " + to_string_with_precision(tps, debug_precision));
|
||||
// Target Information
|
||||
const HitResult &target = minecraft->hit_result;
|
||||
if (target.type != 2) {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
std::string type;
|
||||
std::vector<std::string> type_info;
|
||||
int xyz_precision;
|
||||
if (target.type == 0) {
|
||||
// Tile
|
||||
x = float(target.x);
|
||||
y = float(target.y);
|
||||
z = float(target.z);
|
||||
type = "Tile";
|
||||
if (minecraft->level) {
|
||||
const int id = minecraft->level->getTile(x, y, z);
|
||||
std::string id_info = "ID: " + std::to_string(id);
|
||||
if (Tile *tile = Tile::tiles[id]) {
|
||||
const std::string description_id = tile->getDescriptionId();
|
||||
std::string name = description_id + ".name";
|
||||
if (I18n::_strings.contains(name)) {
|
||||
name = I18n::_strings[name];
|
||||
} else {
|
||||
name = description_id;
|
||||
}
|
||||
if (!name.empty()) {
|
||||
id_info += " (" + name + ')';
|
||||
}
|
||||
}
|
||||
type_info.push_back(id_info);
|
||||
type_info.push_back("Data: " + std::to_string(minecraft->level->getData(x, y, z)));
|
||||
}
|
||||
xyz_precision = 0;
|
||||
} else {
|
||||
// Entity
|
||||
Entity *entity = target.entity;
|
||||
x = entity->x;
|
||||
y = entity->y;
|
||||
z = entity->z;
|
||||
type = "Entity";
|
||||
type_info.push_back("Type ID: " + std::to_string(entity->getEntityTypeId())); // TODO: Specify name when RJ PR is merged
|
||||
type_info.push_back("ID: " + std::to_string(entity->id));
|
||||
if (entity->isMob()) {
|
||||
Mob *mob = (Mob *) entity;
|
||||
type_info.push_back("Health: " + std::to_string(mob->health) + '/' + std::to_string(mob->getMaxHealth()));
|
||||
}
|
||||
xyz_precision = debug_precision;
|
||||
}
|
||||
info.push_back("");
|
||||
info.push_back("Target X: " + to_string_with_precision(x, xyz_precision));
|
||||
info.push_back("Target Y: " + to_string_with_precision(y, xyz_precision));
|
||||
info.push_back("Target Z: " + to_string_with_precision(z, xyz_precision));
|
||||
info.push_back("");
|
||||
info.push_back("Target Type: " + type);
|
||||
info.insert(info.end(), type_info.begin(), type_info.end());
|
||||
}
|
||||
// Return
|
||||
return info;
|
||||
@ -48,12 +150,16 @@ static std::vector<std::string> get_debug_info(const Minecraft *minecraft) {
|
||||
// Render Text With Background
|
||||
static constexpr uint32_t debug_background_color = 0x90505050;
|
||||
static constexpr int debug_text_color = 0xe0e0e0;
|
||||
static void render_debug_line(Gui *gui, std::string &line, const int x, const int y) {
|
||||
static void render_debug_line(Gui *gui, const std::string &line, int x, const int y, const bool right_aligned) {
|
||||
// Draw Background
|
||||
const int width = gui->minecraft->font->width(line);
|
||||
if (width == 0) {
|
||||
return;
|
||||
}
|
||||
if (right_aligned) {
|
||||
const int screen_width = int(float(gui->minecraft->screen_width) * Gui::InvGuiScale);
|
||||
x = screen_width - x - width + 1;
|
||||
}
|
||||
int x1 = x - 1;
|
||||
int y1 = y - 1;
|
||||
int x2 = x + width;
|
||||
@ -66,15 +172,18 @@ static void render_debug_line(Gui *gui, std::string &line, const int x, const in
|
||||
static bool debug_info_shown = false;
|
||||
static constexpr int debug_margin = 2;
|
||||
static constexpr int debug_line_padding = 1;
|
||||
static void render_debug_info(Gui *self, const std::vector<std::string> &info, const bool right_aligned) {
|
||||
int y = debug_margin;
|
||||
for (const std::string &line : info) {
|
||||
render_debug_line(self, line, debug_margin, y, right_aligned);
|
||||
y += line_height;
|
||||
y += debug_line_padding;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
render_debug_info(self, get_debug_info_left(self->minecraft), false);
|
||||
render_debug_info(self, get_debug_info_right(self->minecraft), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,32 +16,65 @@ static long long int get_time() {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// Tracker
|
||||
struct Tracker {
|
||||
// State
|
||||
long long int counter = 0;
|
||||
long long int last_time = get_time();
|
||||
// Properties
|
||||
double &out;
|
||||
const std::function<void()> callback;
|
||||
// Constructor
|
||||
Tracker(double &out_, const std::function<void()> &callback_):
|
||||
out(out_),
|
||||
callback(callback_) {}
|
||||
// Update
|
||||
void update() {
|
||||
// Update Counter
|
||||
counter++;
|
||||
// Get Delta
|
||||
const long long int time = get_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) {
|
||||
out = double(counter) / delta_seconds;
|
||||
counter = 0;
|
||||
last_time = time;
|
||||
// Callback
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Track FPS
|
||||
static bool log_fps;
|
||||
double fps = 0;
|
||||
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);
|
||||
}
|
||||
static void fps_callback() {
|
||||
// Log
|
||||
if (log_fps) {
|
||||
INFO("FPS: %f", fps);
|
||||
}
|
||||
}
|
||||
static Tracker fps_tracker(fps, fps_callback);
|
||||
static void update_fps() {
|
||||
fps_tracker.update();
|
||||
}
|
||||
|
||||
// Track TPS
|
||||
double tps = 0;
|
||||
static Tracker tps_tracker(tps, nullptr);
|
||||
static void update_tps(__attribute__((unused)) Minecraft *minecraft) {
|
||||
tps_tracker.update();
|
||||
}
|
||||
|
||||
// Init
|
||||
void init_fps() {
|
||||
misc_run_on_swap_buffers(update_fps);
|
||||
log_fps = feature_has("Log FPS", server_disabled);
|
||||
if (!reborn_is_headless()) {
|
||||
misc_run_on_swap_buffers(update_fps);
|
||||
log_fps = feature_has("Log FPS", server_disabled);
|
||||
}
|
||||
misc_run_on_tick(update_tps);
|
||||
}
|
||||
|
@ -24,8 +24,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();
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
@ -21,6 +20,7 @@
|
||||
#include <mods/compat/compat.h>
|
||||
#include <mods/misc/misc.h>
|
||||
#include <mods/game-mode/game-mode.h>
|
||||
#include <mods/fps/fps.h>
|
||||
|
||||
// --only-generate: Ony Generate World And Then Exit
|
||||
static bool only_generate = false;
|
||||
@ -207,29 +207,6 @@ static void list_callback(Minecraft *minecraft, const std::string &username, Pla
|
||||
INFO(" - %s (%s)", username.c_str(), get_player_ip(minecraft, player));
|
||||
}
|
||||
|
||||
// Track TPS
|
||||
#define NANOSECONDS_IN_SECOND 1000000000ll
|
||||
static long long int get_time() {
|
||||
timespec ts = {};
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||
const long long int a = (long long int) ts.tv_nsec;
|
||||
const long long int b = ((long long int) ts.tv_sec) * NANOSECONDS_IN_SECOND;
|
||||
return a + b;
|
||||
}
|
||||
static bool is_last_tick_time_set = false;
|
||||
static long long int last_tick_time;
|
||||
static double tps = 0;
|
||||
static void Minecraft_tick_injection(__attribute__((unused)) const Minecraft *minecraft) {
|
||||
const long long int time = get_time();
|
||||
if (is_last_tick_time_set) {
|
||||
const long long int tick_time = time - last_tick_time;
|
||||
tps = ((double) NANOSECONDS_IN_SECOND) / ((double) tick_time);
|
||||
} else {
|
||||
is_last_tick_time_set = true;
|
||||
}
|
||||
last_tick_time = time;
|
||||
}
|
||||
|
||||
// Get ServerSideNetworkHandler From Minecraft
|
||||
static ServerSideNetworkHandler *get_server_side_network_handler(const Minecraft *minecraft) {
|
||||
return (ServerSideNetworkHandler *) minecraft->network_handler;
|
||||
@ -612,9 +589,6 @@ static void server_init() {
|
||||
// Log IPs
|
||||
overwrite_call((void *) 0x75e54, (void *) ServerSideNetworkHandler_onReady_ClientGeneration_ServerSideNetworkHandler_popPendingPlayer_injection);
|
||||
|
||||
// Track TPS
|
||||
misc_run_on_tick(Minecraft_tick_injection);
|
||||
|
||||
// Start Reading STDIN
|
||||
pthread_create(&read_stdin_thread_obj, nullptr, read_stdin_thread, nullptr);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ virtual-method ItemInstance *getCarriedItem() = 0x1ac;
|
||||
virtual-method void updateAi() = 0x1cc;
|
||||
virtual-method float getWalkingSpeedModifier() = 0x1e8;
|
||||
virtual-method void aiStep() = 0x180;
|
||||
virtual-method int getMaxHealth() = 0x168;
|
||||
|
||||
method bool getSharedFlag(int flag) = 0x81fd8;
|
||||
method void setSharedFlag(int flag, bool value) = 0x81ef8;
|
||||
|
@ -48,6 +48,7 @@ virtual-method bool getSignal2(LevelSource *level, int x, int y, int z, int dire
|
||||
// Called by Level_hasDirectSignal
|
||||
virtual-method bool getDirectSignal(Level *level, int x, int y, int z, int direction) = 0xc8;
|
||||
virtual-method void entityInside(Level *level, int x, int y, int z, Entity *entity) = 0xcc;
|
||||
virtual-method std::string getName() = 0xd8;
|
||||
virtual-method std::string getDescriptionId() = 0xdc;
|
||||
virtual-method Tile *setDescriptionId(const std::string &description_id) = 0xe0;
|
||||
virtual-method Tile *setSoundType(const Tile_SoundType &sound_type) = 0xe8;
|
||||
|
Loading…
Reference in New Issue
Block a user