1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-27 20:34:03 +00:00

Add HUD toggle (#452)

* A bunch of things

* Current progress

* Fix for ResAnimationContent

* Figure out Parts*

* Cleanup, just because

* New pane working!!!

* New null pane for hierarchy

* Success with parent pane

* Generate multiple panes

* Multiple panes, almost working text color

* MaterialColor test, but fails

* Forgot bitfield-struct

* Vtable for material. Fixes SetWhiteColor!

* Refactor color changing, change naming scheme

* Just Frame Advantage

* Merge

* Delete T_test.txt

* Delete set_txt_num_01.txt

* Delete libtraining_modpack.nro

* Format Rust code using rustfmt

* Ignore shell scripts in repo languages

* General refactor, add basis for quick menu

* Small refactor, fix ordering of submenu options

* Toggles, sliders

* Tons of progress...

* Correct dmg updater, remove old quick menu backend

* Fix damage percentage display

* Small QoL

* Format Rust code using rustfmt

* More edits. Use Quit Training button as Modpack Menu header

* Finish merge

* Format Rust code using rustfmt

* Use vanilla backgrounds for text options

* Format ui_hacks, also always do new percent display

* Fix merge

* That was the most awful merge ever

* Address clippy warnings

* Format Rust code using rustfmt

* Last impls for resources, small cleanup

* Use macro for pane names

* Format

* Add HUD toggle

* Small change

* Fix for reentering training mode

* Last cleanup

* Format Rust code using rustfmt

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
jugeeya 2022-12-30 15:56:35 -08:00 committed by GitHub
parent ed425d78e5
commit c1a6f6626d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 238 additions and 110 deletions

View file

@ -494,6 +494,20 @@ pub struct Window {
// TODO
}
impl Deref for Window {
type Target = Pane;
fn deref(&self) -> &Self::Target {
&self.pane
}
}
impl DerefMut for Window {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.pane
}
}
#[derive(Debug, Copy, Clone)]
pub struct PaneNode {
pub prev: *mut PaneNode,
@ -514,7 +528,7 @@ pub struct GroupContainer {}
pub struct Layout {
vtable: u64,
pub anim_trans_list: AnimTransformNode,
pub root_pane: *const Pane,
pub root_pane: *mut Pane,
group_container: u64,
layout_size: f64,
pub layout_name: *const skyline::libc::c_char,

View file

@ -1,3 +1,5 @@
use std::ops::{Deref, DerefMut};
// Maybe needs a vtable.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@ -197,6 +199,20 @@ pub struct ResTextBox {
*/
}
impl Deref for ResTextBox {
type Target = ResPane;
fn deref(&self) -> &Self::Target {
&self.pane
}
}
impl DerefMut for ResTextBox {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.pane
}
}
impl ResTextBox {
pub fn enable_shadow(&mut self) {
self.text_box_flag |= 0x1 << TextBoxFlag::ShadowEnabled as u8;
@ -221,6 +237,20 @@ pub struct ResPicture {
*/
}
impl Deref for ResPicture {
type Target = ResPane;
fn deref(&self) -> &Self::Target {
&self.pane
}
}
impl DerefMut for ResPicture {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.pane
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ResPictureWithTex<const TEX_COORD_COUNT: usize> {
@ -228,6 +258,20 @@ pub struct ResPictureWithTex<const TEX_COORD_COUNT: usize> {
tex_coords: [[ResVec2; TEX_COORD_COUNT]; 4],
}
impl<const TEX_COORD_COUNT: usize> Deref for ResPictureWithTex<TEX_COORD_COUNT> {
type Target = ResPane;
fn deref(&self) -> &Self::Target {
&self.picture
}
}
impl<const TEX_COORD_COUNT: usize> DerefMut for ResPictureWithTex<TEX_COORD_COUNT> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.picture
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ResParts {
@ -236,6 +280,20 @@ pub struct ResParts {
magnify: ResVec2,
}
impl Deref for ResParts {
type Target = ResPane;
fn deref(&self) -> &Self::Target {
&self.pane
}
}
impl DerefMut for ResParts {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.pane
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct ResPartsProperty {
@ -325,6 +383,20 @@ pub struct ResWindow {
*/
}
impl Deref for ResWindow {
type Target = ResPane;
fn deref(&self) -> &Self::Target {
&self.pane
}
}
impl DerefMut for ResWindow {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.pane
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ResWindowWithTexCoordsAndFrames<const TEX_COORD_COUNT: usize, const FRAME_COUNT: usize> {
@ -333,3 +405,21 @@ pub struct ResWindowWithTexCoordsAndFrames<const TEX_COORD_COUNT: usize, const F
frame_offset_table: [u32; FRAME_COUNT],
frames: [ResWindowFrame; FRAME_COUNT],
}
impl<const TEX_COORD_COUNT: usize, const FRAME_COUNT: usize> Deref
for ResWindowWithTexCoordsAndFrames<TEX_COORD_COUNT, FRAME_COUNT>
{
type Target = ResPane;
fn deref(&self) -> &Self::Target {
&self.window
}
}
impl<const TEX_COORD_COUNT: usize, const FRAME_COUNT: usize> DerefMut
for ResWindowWithTexCoordsAndFrames<TEX_COORD_COUNT, FRAME_COUNT>
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.window
}
}

View file

@ -1,8 +1,8 @@
use crate::common::get_player_dmg_digits;
use crate::common::{get_player_dmg_digits, is_ready_go, is_training_mode};
use crate::consts::FighterId;
use crate::training::ui::*;
use crate::{common::menu::QUICK_MENU_ACTIVE, training::combo::FRAME_ADVANTAGE};
use training_mod_consts::OnOff;
use training_mod_consts::{OnOff, MENU};
use training_mod_tui::gauge::GaugeState;
pub static NUM_DISPLAY_PANES: usize = 1;
@ -12,6 +12,36 @@ pub static NUM_MENU_TABS: usize = 3;
pub static mut HAS_SORTED_MENU_CHILDREN: bool = false;
macro_rules! menu_text_name_fmt {
($x:ident, $y:ident) => {
format!("trMod_menu_opt_{}_{}", $x, $y).as_str()
};
}
macro_rules! menu_text_check_fmt {
($x:ident, $y:ident) => {
format!("trMod_menu_check_{}_{}", $x, $y).as_str()
};
}
macro_rules! menu_text_bg_left_fmt {
($x:ident, $y:ident) => {
format!("trMod_menu_bg_left_{}_{}", $x, $y).as_str()
};
}
macro_rules! menu_text_bg_back_fmt {
($x:ident, $y:ident) => {
format!("trMod_menu_bg_back_{}_{}", $x, $y).as_str()
};
}
macro_rules! menu_text_slider_fmt {
($x:ident) => {
format!("trMod_menu_slider_{}", $x).as_str()
};
}
// Sort all panes in under menu pane such that text and check options
// are last
pub unsafe fn all_menu_panes_sorted(root_pane: &Pane) -> Vec<&mut Pane> {
@ -21,16 +51,16 @@ pub unsafe fn all_menu_panes_sorted(root_pane: &Pane) -> Vec<&mut Pane> {
let y = idx / 3;
[
root_pane
.find_pane_by_name_recursive(format!("trMod_menu_opt_{x}_{y}").as_str())
.find_pane_by_name_recursive(menu_text_name_fmt!(x, y))
.unwrap(),
root_pane
.find_pane_by_name_recursive(format!("trMod_menu_check_{x}_{y}").as_str())
.find_pane_by_name_recursive(menu_text_check_fmt!(x, y))
.unwrap(),
root_pane
.find_pane_by_name_recursive(format!("trMod_menu_bg_left_{x}_{y}").as_str())
.find_pane_by_name_recursive(menu_text_bg_left_fmt!(x, y))
.unwrap(),
root_pane
.find_pane_by_name_recursive(format!("trMod_menu_bg_back_{x}_{y}").as_str())
.find_pane_by_name_recursive(menu_text_bg_back_fmt!(x, y))
.unwrap(),
]
})
@ -40,7 +70,7 @@ pub unsafe fn all_menu_panes_sorted(root_pane: &Pane) -> Vec<&mut Pane> {
&mut (0..NUM_MENU_TEXT_SLIDERS)
.map(|idx| {
root_pane
.find_pane_by_name_recursive(format!("trMod_menu_slider_{idx}").as_str())
.find_pane_by_name_recursive(menu_text_slider_fmt!(idx))
.unwrap()
})
.collect::<Vec<&mut Pane>>(),
@ -60,10 +90,15 @@ pub unsafe fn all_menu_panes_sorted(root_pane: &Pane) -> Vec<&mut Pane> {
#[skyline::hook(offset = 0x4b620)]
pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64) {
let layout_name = skyline::from_c_str((*layout).layout_name);
let root_pane = &*(*layout).root_pane;
let root_pane = &mut *(*layout).root_pane;
if is_training_mode() && is_ready_go() && layout_name != "info_training" {
root_pane.flags |= 1 << PaneFlag::InfluencedAlpha as u8;
root_pane.set_visible(MENU.hud == OnOff::On);
}
// Update percentage display as soon as possible on death
if crate::common::is_training_mode() && layout_name == "info_melee" {
if is_training_mode() && is_ready_go() && layout_name == "info_melee" {
for player_name in &["p1", "p2"] {
if let Some(parent) = root_pane.find_pane_by_name_recursive(player_name) {
let _p1_layout_name =
@ -169,14 +204,17 @@ pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64)
if QUICK_MENU_ACTIVE {
quit_button.pos_y = 514.0;
}
if let Some(quit_txt) = quit_button.find_pane_by_name_recursive("set_txt_00") {
quit_txt.set_text_string(if QUICK_MENU_ACTIVE {
"Modpack Menu"
} else {
// Awkward. We should get the o.g. translation for non-english games
// Or create our own textbox here so we don't step on their toes.
"Quit Training"
});
for quit_txt_s in &["set_txt_00", "set_txt_01"] {
if let Some(quit_txt) = quit_button.find_pane_by_name_recursive(quit_txt_s) {
quit_txt.set_text_string(if QUICK_MENU_ACTIVE {
"Modpack Menu"
} else {
// Awkward. We should get the o.g. translation for non-english games
// Or create our own textbox here so we don't step on their toes.
"Quit Training"
});
}
}
}
@ -197,21 +235,21 @@ pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64)
let x = idx % 3;
let y = idx / 3;
root_pane
.find_pane_by_name_recursive(format!("trMod_menu_opt_{x}_{y}").as_str())
.find_pane_by_name_recursive(menu_text_name_fmt!(x, y))
.map(|text| text.set_visible(false));
root_pane
.find_pane_by_name_recursive(format!("trMod_menu_check_{x}_{y}").as_str())
.find_pane_by_name_recursive(menu_text_check_fmt!(x, y))
.map(|text| text.set_visible(false));
root_pane
.find_pane_by_name_recursive(format!("trMod_menu_bg_left_{x}_{y}").as_str())
.find_pane_by_name_recursive(menu_text_bg_left_fmt!(x, y))
.map(|text| text.set_visible(false));
root_pane
.find_pane_by_name_recursive(format!("trMod_menu_bg_back_{x}_{y}").as_str())
.find_pane_by_name_recursive(menu_text_bg_back_fmt!(x, y))
.map(|text| text.set_visible(false));
});
(0..NUM_MENU_TEXT_SLIDERS).for_each(|idx| {
root_pane
.find_pane_by_name_recursive(format!("trMod_menu_slider_{idx}").as_str())
.find_pane_by_name_recursive(menu_text_slider_fmt!(idx))
.map(|text| text.set_visible(false));
});
@ -247,19 +285,22 @@ pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64)
list_section,
list_idx,
root_pane
.find_pane_by_name_recursive(
format!("trMod_menu_opt_{list_section}_{list_idx}").as_str(),
)
.find_pane_by_name_recursive(menu_text_name_fmt!(
list_section,
list_idx
))
.unwrap(),
root_pane
.find_pane_by_name_recursive(
format!("trMod_menu_bg_left_{list_section}_{list_idx}").as_str(),
)
.find_pane_by_name_recursive(menu_text_bg_left_fmt!(
list_section,
list_idx
))
.unwrap(),
root_pane
.find_pane_by_name_recursive(
format!("trMod_menu_bg_back_{list_section}_{list_idx}").as_str(),
)
.find_pane_by_name_recursive(menu_text_bg_back_fmt!(
list_section,
list_idx
))
.unwrap(),
)
})
@ -294,9 +335,9 @@ pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64)
.enumerate()
.for_each(|(idx, (checked, name))| {
let is_selected = sub_menu_state.selected().filter(|s| *s == idx).is_some();
if let Some(text) = root_pane.find_pane_by_name_recursive(
format!("trMod_menu_opt_{list_section}_{idx}").as_str(),
) {
if let Some(text) = root_pane
.find_pane_by_name_recursive(menu_text_name_fmt!(list_section, idx))
{
let text = text.as_textbox();
text.set_text_string(name);
if is_selected {
@ -307,21 +348,21 @@ pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64)
text.set_visible(true);
}
if let Some(bg_left) = root_pane.find_pane_by_name_recursive(
format!("trMod_menu_bg_left_{list_section}_{idx}").as_str(),
) {
if let Some(bg_left) = root_pane
.find_pane_by_name_recursive(menu_text_bg_left_fmt!(list_section, idx))
{
bg_left.set_visible(true);
}
if let Some(bg_back) = root_pane.find_pane_by_name_recursive(
format!("trMod_menu_bg_back_{list_section}_{idx}").as_str(),
) {
if let Some(bg_back) = root_pane
.find_pane_by_name_recursive(menu_text_bg_back_fmt!(list_section, idx))
{
bg_back.set_visible(true);
}
if let Some(check) = root_pane.find_pane_by_name_recursive(
format!("trMod_menu_check_{list_section}_{idx}").as_str(),
) {
if let Some(check) = root_pane
.find_pane_by_name_recursive(menu_text_check_fmt!(list_section, idx))
{
if *checked {
let check = check.as_textbox();
@ -426,12 +467,9 @@ pub unsafe fn layout_build_parts_impl(
let block = block as *mut ResPictureWithTex<2>;
let mut pic_menu_block = *block;
pic_menu_block
.picture
.pane
.set_name(format!("trMod_menu_bg_left_{x}_{y}").as_str());
pic_menu_block.picture.pane.scale_x /= 1.5;
pic_menu_block.picture.pane.set_pos(ResVec3::new(
pic_menu_block.set_name(menu_text_bg_left_fmt!(x, y));
pic_menu_block.picture.scale_x /= 1.5;
pic_menu_block.picture.set_pos(ResVec3::new(
menu_pos.x - 400.0 - 195.0 + x_offset,
menu_pos.y - 50.0 - y_offset,
0.0,
@ -455,22 +493,18 @@ pub unsafe fn layout_build_parts_impl(
let block = block as *mut ResWindowWithTexCoordsAndFrames<1, 4>;
let mut pic_menu_block = *block;
pic_menu_block
.window
.pane
.set_name(format!("trMod_menu_bg_back_{x}_{y}").as_str());
pic_menu_block.window.pane.scale_x /= 2.0;
pic_menu_block.window.pane.set_pos(ResVec3::new(
let mut bg_block = *block;
bg_block.set_name(menu_text_bg_back_fmt!(x, y));
bg_block.scale_x /= 2.0;
bg_block.set_pos(ResVec3::new(
menu_pos.x - 400.0 + x_offset,
menu_pos.y - 50.0 - y_offset,
0.0,
));
let pic_menu_pane =
build!(pic_menu_block, ResWindowWithTexCoordsAndFrames<1,4>, kind, Window);
pic_menu_pane.pane.detach();
let bg_pane = build!(bg_block, ResWindowWithTexCoordsAndFrames<1,4>, kind, Window);
bg_pane.detach();
if MENU_PANE_PTR != 0 {
(*(MENU_PANE_PTR as *mut Pane)).append_child(&pic_menu_pane.pane);
(*(MENU_PANE_PTR as *mut Pane)).append_child(bg_pane);
HAS_CREATED_OPT_BG_BACK = true;
}
});
@ -500,8 +534,11 @@ pub unsafe fn layout_build_parts_impl(
let menu_pane = build!(menu_pane_block, ResPane, menu_pane_kind, Pane);
menu_pane.detach();
root_pane.append_child(menu_pane);
if MENU_PANE_PTR == 0 {
if MENU_PANE_PTR != menu_pane as *mut Pane as u64 {
MENU_PANE_PTR = menu_pane as *mut Pane as u64;
HAS_CREATED_OPT_BG = false;
HAS_CREATED_OPT_BG_BACK = false;
HAS_SORTED_MENU_CHILDREN = false;
}
}
@ -511,7 +548,7 @@ pub unsafe fn layout_build_parts_impl(
let block = block as *mut ResPictureWithTex<1>;
// For menu backing
let mut pic_menu_block = *block;
pic_menu_block.picture.pane.set_name("trMod_menu_footer_bg");
pic_menu_block.set_name("trMod_menu_footer_bg");
let pic_menu_pane = build!(pic_menu_block, ResPictureWithTex<1>, kind, Picture);
pic_menu_pane.detach();
@ -524,10 +561,10 @@ pub unsafe fn layout_build_parts_impl(
let block = data as *mut ResTextBox;
let mut text_block = *block;
text_block.pane.set_name("trMod_menu_footer_txt");
text_block.set_name("trMod_menu_footer_txt");
let text_pane = build!(text_block, ResTextBox, kind, TextBox);
text_pane.pane.set_text_string("Footer!");
text_pane.set_text_string("Footer!");
// Ensure Material Colors are not hardcoded so we can just use SetTextColor.
text_pane.set_default_material_colors();
text_pane.set_color(255, 255, 255, 255);
@ -545,24 +582,20 @@ pub unsafe fn layout_build_parts_impl(
text_block.text_alignment(TextAlignment::Center);
let x = txt_idx;
text_block
.pane
.set_name(format!("trMod_menu_tab_{x}").as_str());
text_block.set_name(format!("trMod_menu_tab_{x}").as_str());
let mut x_offset = x as f32 * 300.0;
// Center current tab since we don't have a help key
if x == 1 {
x_offset -= 25.0;
}
text_block.pane.set_pos(ResVec3::new(
text_block.set_pos(ResVec3::new(
menu_pos.x - 25.0 + x_offset,
menu_pos.y + 75.0,
0.0,
));
let text_pane = build!(text_block, ResTextBox, kind, TextBox);
text_pane
.pane
.set_text_string(format!("Tab {txt_idx}!").as_str());
text_pane.set_text_string(format!("Tab {txt_idx}!").as_str());
// Ensure Material Colors are not hardcoded so we can just use SetTextColor.
text_pane.set_default_material_colors();
text_pane.set_color(255, 255, 255, 255);
@ -577,18 +610,16 @@ pub unsafe fn layout_build_parts_impl(
help_block.font_idx = 2;
let x = txt_idx;
help_block
.pane
.set_name(format!("trMod_menu_tab_help_{x}").as_str());
help_block.set_name(format!("trMod_menu_tab_help_{x}").as_str());
let x_offset = x as f32 * 300.0;
help_block.pane.set_pos(ResVec3::new(
help_block.set_pos(ResVec3::new(
menu_pos.x - 250.0 + x_offset,
menu_pos.y + 75.0,
0.0,
));
let help_pane = build!(help_block, ResTextBox, kind, TextBox);
help_pane.pane.set_text_string("abcd");
help_pane.set_text_string("abcd");
let it = help_pane.m_text_buf as *mut u16;
match txt_idx {
// Left Tab: ZL
@ -630,21 +661,17 @@ pub unsafe fn layout_build_parts_impl(
text_block.enable_shadow();
text_block.text_alignment(TextAlignment::Center);
text_block
.pane
.set_name(format!("trMod_menu_opt_{x}_{y}").as_str());
text_block.set_name(menu_text_name_fmt!(x, y));
let x_offset = x as f32 * 500.0;
let y_offset = y as f32 * 85.0;
text_block.pane.set_pos(ResVec3::new(
text_block.set_pos(ResVec3::new(
menu_pos.x - 480.0 + x_offset,
menu_pos.y - 50.0 - y_offset,
0.0,
));
let text_pane = build!(text_block, ResTextBox, kind, TextBox);
text_pane
.pane
.set_text_string(format!("Opt {txt_idx}!").as_str());
text_pane.set_text_string(format!("Opt {txt_idx}!").as_str());
// Ensure Material Colors are not hardcoded so we can just use SetTextColor.
text_pane.set_default_material_colors();
text_pane.set_color(255, 255, 255, 255);
@ -655,18 +682,14 @@ pub unsafe fn layout_build_parts_impl(
// Font Idx 2 = nintendo64 which contains nice symbols
check_block.font_idx = 2;
check_block
.pane
.set_name(format!("trMod_menu_check_{x}_{y}").as_str());
check_block.pane.set_pos(ResVec3::new(
check_block.set_name(menu_text_check_fmt!(x, y));
check_block.set_pos(ResVec3::new(
menu_pos.x - 375.0 + x_offset,
menu_pos.y - 50.0 - y_offset,
0.0,
));
let check_pane = build!(check_block, ResTextBox, kind, TextBox);
check_pane
.pane
.set_text_string(format!("Check {txt_idx}!").as_str());
check_pane.set_text_string(format!("Check {txt_idx}!").as_str());
// Ensure Material Colors are not hardcoded so we can just use SetTextColor.
check_pane.set_default_material_colors();
check_pane.set_color(0, 0, 0, 255);
@ -685,20 +708,16 @@ pub unsafe fn layout_build_parts_impl(
text_block.enable_shadow();
text_block.text_alignment(TextAlignment::Center);
text_block
.pane
.set_name(format!("trMod_menu_slider_{idx}").as_str());
text_block.set_name(menu_text_slider_fmt!(idx));
let x_offset = idx as f32 * 250.0;
text_block.pane.set_pos(ResVec3::new(
text_block.set_pos(ResVec3::new(
menu_pos.x - 450.0 + x_offset,
menu_pos.y - 150.0,
0.0,
));
let text_pane = build!(text_block, ResTextBox, kind, TextBox);
text_pane
.pane
.set_text_string(format!("Slider {idx}!").as_str());
text_pane.set_text_string(format!("Slider {idx}!").as_str());
// Ensure Material Colors are not hardcoded so we can just use SetTextColor.
text_pane.set_default_material_colors();
text_pane.set_color(0, 0, 0, 255);
@ -718,8 +737,8 @@ pub unsafe fn layout_build_parts_impl(
if (*block).name_matches("pic_numbase_01") {
let block = block as *mut ResPictureWithTex<1>;
let mut pic_block = *block;
pic_block.picture.pane.set_name(pic_name.as_str());
pic_block.picture.pane.set_pos(ResVec3::default());
pic_block.set_name(pic_name.as_str());
pic_block.set_pos(ResVec3::default());
let pic_pane = build!(pic_block, ResPictureWithTex<1>, kind, Picture);
pic_pane.detach();
@ -740,12 +759,10 @@ pub unsafe fn layout_build_parts_impl(
let block = data as *mut ResTextBox;
let mut text_block = *block;
text_block.pane.set_name(txt_name.as_str());
text_block.pane.set_pos(ResVec3::new(-10.0, -25.0, 0.0));
text_block.set_name(txt_name.as_str());
text_block.set_pos(ResVec3::new(-10.0, -25.0, 0.0));
let text_pane = build!(text_block, ResTextBox, kind, TextBox);
text_pane
.pane
.set_text_string(format!("Pane {idx}!").as_str());
text_pane.set_text_string(format!("Pane {idx}!").as_str());
// Ensure Material Colors are not hardcoded so we can just use SetTextColor.
text_pane.set_default_material_colors();
text_pane.detach();
@ -759,12 +776,10 @@ pub unsafe fn layout_build_parts_impl(
let block = data as *mut ResTextBox;
let mut header_block = *block;
header_block.pane.set_name(header_name.as_str());
header_block.pane.set_pos(ResVec3::new(0.0, 25.0, 0.0));
header_block.set_name(header_name.as_str());
header_block.set_pos(ResVec3::new(0.0, 25.0, 0.0));
let header_pane = build!(header_block, ResTextBox, kind, TextBox);
header_pane
.pane
.set_text_string(format!("Header {idx}").as_str());
header_pane.set_text_string(format!("Header {idx}").as_str());
// Ensure Material Colors are not hardcoded so we can just use SetTextColor.
header_pane.set_default_material_colors();
// Header should be white text

View file

@ -1122,6 +1122,7 @@ pub struct TrainingModpackMenu {
pub frame_advantage: OnOff,
pub full_hop: BoolFlag,
pub hitbox_vis: OnOff,
pub hud: OnOff,
pub input_delay: Delay,
pub ledge_delay: LongDelay,
pub ledge_state: LedgeOption,
@ -1209,6 +1210,7 @@ pub static DEFAULTS_MENU: TrainingModpackMenu = TrainingModpackMenu {
frame_advantage: OnOff::Off,
full_hop: BoolFlag::TRUE,
hitbox_vis: OnOff::On,
hud: OnOff::On,
input_delay: Delay::D0,
ledge_delay: LongDelay::empty(),
ledge_state: LedgeOption::default(),
@ -1681,6 +1683,13 @@ pub unsafe fn get_menu() -> UiMenu<'static> {
true,
&(MENU.quick_menu as u32),
);
misc_tab.add_submenu_with_toggles::<OnOff>(
"HUD",
"hud",
"HUD: Turn UI on or off",
true,
&(MENU.hud as u32),
);
overall_menu.tabs.push(misc_tab);
overall_menu