WIP UI Scale Slider
This commit is contained in:
parent
c531e7ba7d
commit
cfac7d0a12
@ -17,6 +17,57 @@ static std::string get_cache_path() {
|
||||
}
|
||||
|
||||
// Load
|
||||
static void read_cache(std::ifstream &stream, State &ret) {
|
||||
// Cache Version
|
||||
unsigned char cache_version;
|
||||
stream.read((char *) &cache_version, 1);
|
||||
if (stream.eof()) {
|
||||
// Unable To Read Version
|
||||
WARN("Unable To Read Launcher Cache Version");
|
||||
return;
|
||||
}
|
||||
|
||||
// Support Older Versions
|
||||
bool load_gui_scale = true;
|
||||
if (cache_version == 0) {
|
||||
// Pre-v3.0.0 Cache
|
||||
load_gui_scale = false;
|
||||
} else if (cache_version != (unsigned char) CACHE_VERSION) {
|
||||
// Invalid Version
|
||||
WARN("Invalid Launcher Cache Version (Expected: %i, Actual: %i)", CACHE_VERSION, (int) cache_version);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load Username And Render Distance
|
||||
State state;
|
||||
std::getline(stream, state.username, '\0');
|
||||
std::getline(stream, state.render_distance, '\0');
|
||||
if (load_gui_scale) {
|
||||
stream.read((char *) &state.gui_scale, sizeof(float));
|
||||
}
|
||||
|
||||
// Load Feature Flags
|
||||
std::unordered_map<std::string, bool> flags;
|
||||
std::string flag;
|
||||
while (!stream.eof() && std::getline(stream, flag, '\0')) {
|
||||
if (!flag.empty()) {
|
||||
bool is_enabled = false;
|
||||
stream.read((char *) &is_enabled, sizeof(bool));
|
||||
flags[flag] = is_enabled;
|
||||
}
|
||||
stream.peek();
|
||||
}
|
||||
state.flags.from_cache(flags);
|
||||
|
||||
// Check For Error
|
||||
if (!stream) {
|
||||
WARN("Failure While Loading Launcher Cache");
|
||||
return;
|
||||
}
|
||||
|
||||
// Success
|
||||
ret = state;
|
||||
}
|
||||
State load_cache() {
|
||||
// Log
|
||||
DEBUG("Loading Launcher Cache...");
|
||||
@ -35,42 +86,8 @@ State load_cache() {
|
||||
// Lock File
|
||||
int lock_fd = lock_file(get_cache_path().c_str());
|
||||
|
||||
// Check Version
|
||||
unsigned char cache_version;
|
||||
stream.read((char *) &cache_version, 1);
|
||||
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
|
||||
State state;
|
||||
std::getline(stream, state.username, '\0');
|
||||
std::getline(stream, state.render_distance, '\0');
|
||||
|
||||
// Load Feature Flags
|
||||
std::unordered_map<std::string, bool> flags;
|
||||
std::string flag;
|
||||
while (!stream.eof() && std::getline(stream, flag, '\0')) {
|
||||
if (!flag.empty()) {
|
||||
bool is_enabled = false;
|
||||
stream.read((char *) &is_enabled, sizeof(bool));
|
||||
flags[flag] = is_enabled;
|
||||
}
|
||||
stream.peek();
|
||||
}
|
||||
state.flags.from_cache(flags);
|
||||
|
||||
// Check For Error
|
||||
if (!stream) {
|
||||
WARN("Failure While Loading Launcher Cache");
|
||||
} else {
|
||||
// Success
|
||||
ret = state;
|
||||
}
|
||||
}
|
||||
// Load
|
||||
read_cache(stream, ret);
|
||||
|
||||
// Close
|
||||
stream.close();
|
||||
@ -84,9 +101,26 @@ State load_cache() {
|
||||
}
|
||||
|
||||
// Save
|
||||
static void write_env_to_stream(std::ofstream &stream, const std::string &value) {
|
||||
static void write_env_to_stream(std::ostream &stream, const std::string &value) {
|
||||
stream.write(value.c_str(), int(value.size()) + 1);
|
||||
}
|
||||
void write_cache(std::ostream &stream, const State &state) {
|
||||
// Save 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, state.username);
|
||||
write_env_to_stream(stream, state.render_distance);
|
||||
stream.write((const char *) &state.gui_scale, sizeof(float));
|
||||
|
||||
// Save Feature Flags
|
||||
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));
|
||||
}
|
||||
}
|
||||
void save_cache(const State &state) {
|
||||
// Log
|
||||
DEBUG("Saving Launcher Cache...");
|
||||
@ -98,22 +132,10 @@ void save_cache(const State &state) {
|
||||
WARN("Unable To Open Launcher Cache For Saving");
|
||||
} else {
|
||||
// Lock File
|
||||
int lock_fd = lock_file(get_cache_path().c_str());
|
||||
const int lock_fd = lock_file(get_cache_path().c_str());
|
||||
|
||||
// Save 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, state.username);
|
||||
write_env_to_stream(stream, state.render_distance);
|
||||
|
||||
// Save Feature Flags
|
||||
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));
|
||||
}
|
||||
// Write
|
||||
write_cache(stream, state);
|
||||
|
||||
// Finish
|
||||
stream.close();
|
||||
|
@ -1,13 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
|
||||
// Cache Version
|
||||
#define CACHE_VERSION 0
|
||||
#define CACHE_VERSION 1
|
||||
|
||||
// Load Cache
|
||||
struct State;
|
||||
State load_cache();
|
||||
|
||||
// Save Cache
|
||||
void write_cache(std::ostream &stream, const State &state);
|
||||
void save_cache(const State &state);
|
||||
|
||||
// Wipe Cache
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include <libreborn/env.h>
|
||||
|
||||
#include "../util/util.h"
|
||||
#include "configuration.h"
|
||||
#include "cache.h"
|
||||
|
||||
@ -8,17 +9,17 @@
|
||||
State::State(): flags("") {
|
||||
username = DEFAULT_USERNAME;
|
||||
render_distance = DEFAULT_RENDER_DISTANCE;
|
||||
gui_scale = AUTO_GUI_SCALE;
|
||||
flags = Flags::get();
|
||||
}
|
||||
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());
|
||||
set_and_print_env(env, obj_to_env_value(value).c_str());
|
||||
} else {
|
||||
const char *env_value = getenv(env);
|
||||
if (env_value != nullptr) {
|
||||
value = env_value;
|
||||
env_value_to_obj(value, env_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -26,11 +27,14 @@ 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);
|
||||
update_from_env(MCPI_GUI_SCALE_ENV, gui_scale, save);
|
||||
}
|
||||
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
|
||||
std::ostringstream one;
|
||||
write_cache(one, *this);
|
||||
std::ostringstream two;
|
||||
write_cache(two, other);
|
||||
return one.str() == two.str();
|
||||
}
|
||||
|
||||
// Handle Non-Launch Commands
|
||||
|
@ -11,6 +11,7 @@
|
||||
// Default Configuration
|
||||
#define DEFAULT_USERNAME "StevePi"
|
||||
#define DEFAULT_RENDER_DISTANCE "Short"
|
||||
#define AUTO_GUI_SCALE 0
|
||||
|
||||
// State
|
||||
struct State {
|
||||
@ -21,6 +22,7 @@ struct State {
|
||||
// Properties
|
||||
std::string username;
|
||||
std::string render_distance;
|
||||
float gui_scale;
|
||||
Flags flags;
|
||||
};
|
||||
|
||||
|
@ -16,9 +16,9 @@ static constexpr std::array render_distances = {
|
||||
};
|
||||
|
||||
// Tooltips/Text
|
||||
static constexpr std::string revert_text = "Revert";
|
||||
static constexpr std::string revert_tooltip_text = "Last Saved";
|
||||
static constexpr std::string make_tooltip(const std::string &text, const std::string &type) {
|
||||
static const char *revert_text = "Revert";
|
||||
static const char *revert_tooltip_text = "Last Saved";
|
||||
static std::string make_tooltip(const std::string &text, const std::string &type) {
|
||||
return "Use " + text + ' ' + type;
|
||||
}
|
||||
|
||||
@ -123,20 +123,35 @@ int ConfigurationUI::get_render_distance_index() const {
|
||||
}
|
||||
void ConfigurationUI::draw_main() const {
|
||||
const ImGuiStyle &style = ImGui::GetStyle();
|
||||
const char *labels[] = {"Username", "Render Distance"};
|
||||
const char *labels[] = {"Username", "Render Distance", "UI Scale"};
|
||||
// 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
|
||||
// Username
|
||||
ImGui::InputText(labels[0], &state.username);
|
||||
// Render Distance
|
||||
int render_distance_index = get_render_distance_index();
|
||||
if (ImGui::Combo(labels[1], &render_distance_index, render_distances.data(), int(render_distances.size()))) {
|
||||
state.render_distance = render_distances[render_distance_index];
|
||||
}
|
||||
// UI Scale
|
||||
std::string scale_format = "%i";
|
||||
scale_format += 'x';
|
||||
if (state.gui_scale <= AUTO_GUI_SCALE) {
|
||||
scale_format = "Auto";
|
||||
}
|
||||
int gui_scale_int = int(state.gui_scale);
|
||||
if (ImGui::SliderInt(labels[2], &gui_scale_int, 0, 8, scale_format.c_str())) {
|
||||
state.gui_scale = float(gui_scale_int);
|
||||
if (state.gui_scale < AUTO_GUI_SCALE) {
|
||||
state.gui_scale = AUTO_GUI_SCALE;
|
||||
}
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
// Launcher Cache
|
||||
ImGui::Checkbox("Save Settings On Launch", &save_settings);
|
||||
}
|
||||
|
||||
@ -193,7 +208,7 @@ void ConfigurationUI::draw_servers() {
|
||||
// Revert/Save
|
||||
int clicked_button = -1;
|
||||
ImGui::BeginDisabled(!are_servers_unsaved());
|
||||
draw_right_aligned_buttons({revert_text.c_str(), "Save"}, [&clicked_button](const int id, const bool was_clicked) {
|
||||
draw_right_aligned_buttons({revert_text, "Save"}, [&clicked_button](const int id, const bool was_clicked) {
|
||||
if (id == 0) {
|
||||
ImGui::SetItemTooltip("%s", make_tooltip(revert_tooltip_text, "Server List").c_str());
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#define ENV(name, ...) extern const char *const name##_ENV;
|
||||
#include "env-list.h"
|
||||
#undef ENV
|
||||
@ -9,3 +11,12 @@ void clear_internal_env_vars();
|
||||
|
||||
// Set Environmental Variable
|
||||
void set_and_print_env(const char *name, const char *value);
|
||||
|
||||
// Convert Variable To Value And Vice-Versa
|
||||
struct Flags;
|
||||
std::string obj_to_env_value(const std::string &obj);
|
||||
std::string obj_to_env_value(const float &obj);
|
||||
std::string obj_to_env_value(const Flags &obj);
|
||||
void env_value_to_obj(std::string &out, const char *value);
|
||||
void env_value_to_obj(float &out, const char *value);
|
||||
void env_value_to_obj(Flags &out, const char *value);
|
@ -36,8 +36,9 @@ 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);
|
||||
std::string to_string() const;
|
||||
void from_string(const std::string &str);
|
||||
bool operator==(const Flags &other) const;
|
||||
// To/From Cache
|
||||
[[nodiscard]] std::unordered_map<std::string, bool> to_cache() const;
|
||||
void from_cache(const std::unordered_map<std::string, bool> &cache);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <libreborn/env.h>
|
||||
#include <libreborn/exec.h>
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/flags.h>
|
||||
|
||||
// Define Constants
|
||||
#define ENV(name, ...) const char *const name##_ENV = #name;
|
||||
@ -36,3 +37,23 @@ void set_and_print_env(const char *name, const char *value) {
|
||||
// Print New Value
|
||||
DEBUG("Set %s = %s", name, value != NULL ? value : "(unset)");
|
||||
}
|
||||
|
||||
// Conversion
|
||||
std::string obj_to_env_value(const std::string &obj) {
|
||||
return obj;
|
||||
}
|
||||
std::string obj_to_env_value(const float &obj) {
|
||||
return std::to_string(obj);
|
||||
}
|
||||
std::string obj_to_env_value(const Flags &obj) {
|
||||
return obj.to_string();
|
||||
}
|
||||
void env_value_to_obj(std::string &out, const char *value) {
|
||||
out = value;
|
||||
}
|
||||
void env_value_to_obj(float &out, const char *value) {
|
||||
out = strtof(value, nullptr);
|
||||
}
|
||||
void env_value_to_obj(Flags &out, const char *value) {
|
||||
out.from_string(value);
|
||||
}
|
@ -62,7 +62,7 @@ Flags::Flags(const std::string &data) {
|
||||
}
|
||||
});
|
||||
}
|
||||
Flags::operator std::string() const {
|
||||
std::string Flags::to_string() const {
|
||||
std::string out;
|
||||
root.for_each_const([&out](const FlagNode &flag) {
|
||||
if (flag.value) {
|
||||
@ -74,7 +74,7 @@ Flags::operator std::string() const {
|
||||
});
|
||||
return out;
|
||||
}
|
||||
Flags &Flags::operator=(const std::string &str) {
|
||||
void Flags::from_string(const std::string &str) {
|
||||
// Find Flags To Enable
|
||||
std::unordered_set<std::string> to_enable;
|
||||
std::stringstream stream(str);
|
||||
@ -88,7 +88,9 @@ Flags &Flags::operator=(const std::string &str) {
|
||||
root.for_each([&to_enable](FlagNode &flag) {
|
||||
flag.value = to_enable.contains(flag.name);
|
||||
});
|
||||
return *this;
|
||||
}
|
||||
bool Flags::operator==(const Flags &other) const {
|
||||
return to_string() == other.to_string();
|
||||
}
|
||||
std::unordered_map<std::string, bool> Flags::to_cache() const {
|
||||
std::unordered_map<std::string, bool> out;
|
||||
|
@ -20,7 +20,7 @@ bool _feature_has(const char *name, const int server_default) {
|
||||
if (!loaded) {
|
||||
const char *env = getenv(MCPI_FEATURE_FLAGS_ENV);
|
||||
if (env) {
|
||||
flags = env;
|
||||
flags.from_string(env);
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
@ -15,9 +15,8 @@
|
||||
// Heart Food Overlay
|
||||
static int heal_amount = 0, heal_amount_drawing = 0;
|
||||
static void Gui_renderHearts_injection(Gui_renderHearts_t original, Gui *gui) {
|
||||
// Get heal_amount
|
||||
// Calculate heal_amount
|
||||
heal_amount = heal_amount_drawing = 0;
|
||||
|
||||
Inventory *inventory = gui->minecraft->player->inventory;
|
||||
const ItemInstance *held_ii = inventory->getSelected();
|
||||
if (held_ii) {
|
||||
@ -30,7 +29,7 @@ static void Gui_renderHearts_injection(Gui_renderHearts_t original, Gui *gui) {
|
||||
}
|
||||
}
|
||||
|
||||
// Call original
|
||||
// Call Original Method
|
||||
original(gui);
|
||||
}
|
||||
#define PINK_HEART_FULL 70
|
||||
@ -306,14 +305,17 @@ void _init_misc_ui() {
|
||||
// Custom GUI Scale
|
||||
const char *gui_scale_str = getenv(MCPI_GUI_SCALE_ENV);
|
||||
if (gui_scale_str != nullptr) {
|
||||
float gui_scale;
|
||||
env_value_to_obj(gui_scale, gui_scale_str);
|
||||
if (gui_scale > 0) {
|
||||
unsigned char nop_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
|
||||
patch((void *) 0x173e8, nop_patch);
|
||||
patch((void *) 0x173f0, nop_patch);
|
||||
const float gui_scale = strtof(gui_scale_str, nullptr);
|
||||
uint32_t gui_scale_raw;
|
||||
memcpy(&gui_scale_raw, &gui_scale, sizeof (gui_scale_raw));
|
||||
patch_address((void *) 0x17520, (void *) gui_scale_raw);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't Wrap Text On '\r' Or '\t' Because They Are Actual Characters In MCPI
|
||||
if (feature_has("Fix Text Wrapping", server_disabled)) {
|
||||
|
@ -103,7 +103,7 @@ static bool draw_splash(StartMenuScreen *screen, const float y_factor, const boo
|
||||
const int text_width = screen->font->width(current_splash);
|
||||
float splash_width = float(text_width) * scale;
|
||||
if (splash_width > float(max_width)) {
|
||||
const float multiplier = (float(max_width) / splash_width);
|
||||
const float multiplier = float(max_width) / splash_width;
|
||||
scale *= multiplier;
|
||||
splash_width *= multiplier;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user