add config options to show/hide timing debug info and power directions

This commit is contained in:
Crispy 2025-04-21 00:23:19 +02:00
parent 440cd7a759
commit c8fc484e9c
7 changed files with 115 additions and 64 deletions

View file

@ -2,7 +2,11 @@
Game store page: https://crispypin.itch.io/marble-machinations Game store page: https://crispypin.itch.io/marble-machinations
## [unreleased] ## [unreleased]
### added
- option to display power direction while overlay is enabled
### changed ### changed
- hide tick timing numbers by default
- when multiple I/O silos (or multiple directions of one) are activated in the same tick, they will all output the same value instead of pulling input in an arbitrary order - when multiple I/O silos (or multiple directions of one) are activated in the same tick, they will all output the same value instead of pulling input in an arbitrary order
### fixed ### fixed

View file

@ -16,7 +16,6 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble
- packet routing? - packet routing?
- game of life sim (width;height;steps;grid -> grid) - game of life sim (width;height;steps;grid -> grid)
- show level name in end popup - show level name in end popup
- hide timing debug info by default
- shrink button - shrink button
#### 0.4.0 #### 0.4.0
- UI layout engine - UI layout engine

View file

@ -1,11 +1,21 @@
use raylib::prelude::*; use raylib::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{input::Input, theme::FG_CHAPTER_TITLE, ui::text_button, util::Scroll, Globals}; use crate::{
input::Input,
theme::FG_CHAPTER_TITLE,
ui::{text_button, toggle_button},
util::Scroll,
Globals,
};
#[derive(Default, Debug, Clone, Serialize, Deserialize)] #[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct Config { pub struct Config {
pub input: Input, pub input: Input,
#[serde(default)]
pub show_debug_timing: bool,
#[serde(default)]
pub show_power_direction: bool,
#[serde(skip)] #[serde(skip)]
scroll_offset: u32, scroll_offset: u32,
} }
@ -25,19 +35,29 @@ impl Config {
Some(Scroll::Up) => self.scroll_offset = self.scroll_offset.saturating_sub(64), Some(Scroll::Up) => self.scroll_offset = self.scroll_offset.saturating_sub(64),
None => (), None => (),
} }
let y = -(self.scroll_offset as i32); let mut y = -(self.scroll_offset as i32) + 15;
d.draw_text("Settings", 16, y, 30, FG_CHAPTER_TITLE);
y += 40;
d.draw_text("Settings", 16, y + 16, 30, FG_CHAPTER_TITLE); if text_button(d, &globals.mouse, 10, y, 80, "apply") {
if text_button(d, &globals.mouse, 10, y + 60, 80, "apply") {
return MenuReturn::StaySave; return MenuReturn::StaySave;
} }
if text_button(d, &globals.mouse, 100, y + 60, 80, "done") { if text_button(d, &globals.mouse, 100, y, 80, "done") {
return MenuReturn::ReturnSave; return MenuReturn::ReturnSave;
} }
if text_button(d, &globals.mouse, 190, y + 60, 80, "cancel") { if text_button(d, &globals.mouse, 190, y, 80, "cancel") {
return MenuReturn::ReturnCancel; return MenuReturn::ReturnCancel;
} }
y += 40;
let mut toggle = |value, text| {
toggle_button((d, &globals.mouse), 10, y, 30, 30, value);
d.draw_text(text, 50, y + 5, 20, Color::WHITE);
y += 40;
};
toggle(&mut self.show_power_direction, "show power directions");
toggle(&mut self.show_debug_timing, "show debug timing");
// self.input.update(d); // self.input.update(d);
self.input.draw_edit(d, globals, y); self.input.draw_edit(d, globals, y);

View file

@ -74,8 +74,8 @@ pub struct Editor {
undo_history: Vec<Action>, undo_history: Vec<Action>,
undo_index: usize, undo_index: usize,
// debug/profiling // debug/profiling
step_time: u128, step_time: usize,
max_step_time: u128, max_step_time: usize,
start_time: Instant, start_time: Instant,
} }
@ -472,8 +472,8 @@ impl Editor {
.as_micros() .as_micros()
.checked_div(steps_taken) .checked_div(steps_taken)
.unwrap_or_default(); .unwrap_or_default();
self.step_time = avg_step_time; self.step_time = avg_step_time as usize;
self.max_step_time = avg_step_time.max(self.max_step_time); self.max_step_time = self.step_time.max(self.max_step_time);
} }
if globals.is_pressed(ActionId::StepSim) { if globals.is_pressed(ActionId::StepSim) {
self.step_pressed() self.step_pressed()
@ -575,20 +575,33 @@ impl Editor {
} }
fn draw_board(&self, d: &mut RaylibDrawHandle, globals: &Globals) { fn draw_board(&self, d: &mut RaylibDrawHandle, globals: &Globals) {
let draw_power = globals.config.show_power_direction && self.draw_overlay;
if self.sim_state == SimState::Editing { if self.sim_state == SimState::Editing {
self.source_board self.source_board.grid.draw(
.grid d,
.draw(d, &globals.textures, self.view_offset, self.zoom); &globals.textures,
self.view_offset,
self.zoom,
draw_power,
);
} else { } else {
if self.machine.debug_subticks.is_empty() { if self.machine.debug_subticks.is_empty() {
self.machine self.machine.grid().draw(
.grid() d,
.draw(d, &globals.textures, self.view_offset, self.zoom); &globals.textures,
self.view_offset,
self.zoom,
draw_power,
);
} else { } else {
let subframe = &self.machine.debug_subticks[self.machine.subtick_index]; let subframe = &self.machine.debug_subticks[self.machine.subtick_index];
subframe subframe.grid.draw(
.grid d,
.draw(d, &globals.textures, self.view_offset, self.zoom); &globals.textures,
self.view_offset,
self.zoom,
draw_power,
);
if let Some(pos) = subframe.pos { if let Some(pos) = subframe.pos {
let p = self.pos_to_screen(pos.to_vec()); let p = self.pos_to_screen(pos.to_vec());
d.draw_texture_ex( d.draw_texture_ex(
@ -961,34 +974,22 @@ impl Editor {
draw_usize(d, &globals.textures, total_steps, (420, 44), 9, 2); draw_usize(d, &globals.textures, total_steps, (420, 44), 9, 2);
} }
draw_usize( if globals.config.show_debug_timing {
d, draw_usize(d, &globals.textures, self.step_time, (260, 42), 9, 1);
&globals.textures, draw_usize(d, &globals.textures, self.max_step_time, (260, 60), 9, 1);
self.step_time as usize, #[cfg(debug_assertions)]
(260, 42), {
9, draw_usize(
1, d,
); &globals.textures,
draw_usize( self.machine.subtick_index,
d, (260, 80),
&globals.textures, 9,
self.max_step_time as usize, 1,
(260, 60), );
9, let subtick_count = self.machine.debug_subticks.len();
1, draw_usize(d, &globals.textures, subtick_count, (260, 100), 9, 1);
); }
#[cfg(debug_assertions)]
{
draw_usize(
d,
&globals.textures,
self.machine.subtick_index,
(260, 80),
9,
1,
);
let subtick_count = self.machine.debug_subticks.len();
draw_usize(d, &globals.textures, subtick_count, (260, 100), 9, 1);
} }
d.draw_text("input:", 603, 8, 10, Color::WHITE); d.draw_text("input:", 603, 8, 10, Color::WHITE);
@ -1380,7 +1381,9 @@ impl Editor {
offset.x -= offset.x.rem(tile_size); offset.x -= offset.x.rem(tile_size);
offset.y -= offset.y.rem(tile_size); offset.y -= offset.y.rem(tile_size);
offset += view_offset; offset += view_offset;
board.grid.draw(d, &globals.textures, offset, self.zoom); board
.grid
.draw(d, &globals.textures, offset, self.zoom, false);
board.draw_comments(d, offset, self.zoom); board.draw_comments(d, offset, self.zoom);
if self.mouse.left_click() { if self.mouse.left_click() {
let tile_pos = (self.mouse.pos() - self.view_offset) / tile_size; let tile_pos = (self.mouse.pos() - self.view_offset) / tile_size;
@ -1517,7 +1520,9 @@ impl Editor {
offset.x -= offset.x.rem(tile_size); offset.x -= offset.x.rem(tile_size);
offset.y -= offset.y.rem(tile_size); offset.y -= offset.y.rem(tile_size);
offset += view_offset; offset += view_offset;
bp.board.grid.draw(d, &globals.textures, offset, self.zoom); bp.board
.grid
.draw(d, &globals.textures, offset, self.zoom, false);
bp.board.draw_comments(d, offset, self.zoom); bp.board.draw_comments(d, offset, self.zoom);
} }
if self.mouse.pos().x < SIDEBAR_WIDTH as f32 { if self.mouse.pos().x < SIDEBAR_WIDTH as f32 {

View file

@ -132,8 +132,7 @@ enum BindingEdit {
} }
impl Input { impl Input {
pub fn draw_edit(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals, y: i32) { pub fn draw_edit(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals, mut y: i32) {
let mut y = y + 96;
if self.editing_binding.is_some() { if self.editing_binding.is_some() {
globals.mouse.clear(); globals.mouse.clear();
} }

View file

@ -285,7 +285,7 @@ impl Grid {
out out
} }
pub fn draw(&self, d: &mut RaylibDrawHandle, textures: &Textures, offset: Vector2, scale: f32) { pub fn draw(&self, d: &mut RaylibDrawHandle, textures: &Textures, offset: Vector2, scale: f32, power_directions: bool) {
let tile_size = (TILE_TEXTURE_SIZE * scale) as i32; let tile_size = (TILE_TEXTURE_SIZE * scale) as i32;
let start_x = (-offset.x as i32) / tile_size - 1; let start_x = (-offset.x as i32) / tile_size - 1;
@ -304,14 +304,14 @@ impl Grid {
} }
let texture = textures.get(texname); let texture = textures.get(texname);
draw_scaled_texture(d, texture, px, py, scale); draw_scaled_texture(d, texture, px, py, scale);
#[cfg(debug_assertions)] if power_directions
// todo some in-game option to show power direction {
if let Tile::Powerable(_, state) = &tile { if let Tile::Powerable(_, state) = &tile {
for dir in Direction::ALL { for dir in Direction::ALL {
if state.get_dir(dir) { if state.get_dir(dir) {
let texture = textures.get(dir.debug_arrow_texture_name()); let texture = textures.get(dir.debug_arrow_texture_name());
draw_scaled_texture(d, texture, px, py, scale); draw_scaled_texture(d, texture, px, py, scale);
} }}
} }
} }
} else { } else {

View file

@ -2,7 +2,7 @@ use std::ops::Range;
use crate::{ use crate::{
theme::*, theme::*,
util::{draw_scaled_texture, MouseInput, Scroll, Textures}, util::{draw_scaled_texture, rect, MouseInput, Scroll, Textures},
Globals, Globals,
}; };
use raylib::prelude::*; use raylib::prelude::*;
@ -160,6 +160,35 @@ impl Tooltip {
} }
} }
pub fn toggle_button(
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
x: i32,
y: i32,
width: i32,
height: i32,
val: &mut bool,
) {
let margin = 5;
let mouse_pos = mouse.pos();
let bounds = rect(x, y, width, height);
let hover = bounds.check_collision_point_rec(mouse_pos);
d.draw_rectangle(x, y, width, height, widget_bg(hover));
let pressed = hover && mouse.left_click();
if pressed {
*val = !*val;
}
if *val {
d.draw_rectangle(
x + margin,
y + margin,
width - margin * 2,
height - margin * 2,
Color::WHITE,
);
}
}
pub fn simple_button( pub fn simple_button(
(d, mouse): (&mut RaylibDrawHandle, &MouseInput), (d, mouse): (&mut RaylibDrawHandle, &MouseInput),
x: i32, x: i32,
@ -168,12 +197,7 @@ pub fn simple_button(
height: i32, height: i32,
) -> bool { ) -> bool {
let mouse_pos = mouse.pos(); let mouse_pos = mouse.pos();
let bounds = Rectangle { let bounds = rect(x, y, width, height);
x: x as f32,
y: y as f32,
width: width as f32,
height: height as f32,
};
let hover = bounds.check_collision_point_rec(mouse_pos); let hover = bounds.check_collision_point_rec(mouse_pos);
let pressed = hover && mouse.left_click(); let pressed = hover && mouse.left_click();
d.draw_rectangle(x, y, width, height, widget_bg(hover)); d.draw_rectangle(x, y, width, height, widget_bg(hover));