diff --git a/CHANGELOG.md b/CHANGELOG.md index fee8542..47e2c19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,11 @@ Game store page: https://crispypin.itch.io/marble-machinations ## [unreleased] +### added +- option to display power direction while overlay is enabled + ### 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 ### fixed diff --git a/README.md b/README.md index 9d5b549..a78b159 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,6 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble - packet routing? - game of life sim (width;height;steps;grid -> grid) - show level name in end popup -- hide timing debug info by default - shrink button #### 0.4.0 - UI layout engine diff --git a/src/config.rs b/src/config.rs index cc5f45b..674611f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,11 +1,21 @@ use raylib::prelude::*; 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)] pub struct Config { pub input: Input, + #[serde(default)] + pub show_debug_timing: bool, + #[serde(default)] + pub show_power_direction: bool, #[serde(skip)] scroll_offset: u32, } @@ -25,19 +35,29 @@ impl Config { Some(Scroll::Up) => self.scroll_offset = self.scroll_offset.saturating_sub(64), 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 + 60, 80, "apply") { + if text_button(d, &globals.mouse, 10, y, 80, "apply") { 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; } - if text_button(d, &globals.mouse, 190, y + 60, 80, "cancel") { + if text_button(d, &globals.mouse, 190, y, 80, "cancel") { 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.draw_edit(d, globals, y); diff --git a/src/editor.rs b/src/editor.rs index 3dcf0ac..87f8581 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -74,8 +74,8 @@ pub struct Editor { undo_history: Vec, undo_index: usize, // debug/profiling - step_time: u128, - max_step_time: u128, + step_time: usize, + max_step_time: usize, start_time: Instant, } @@ -472,8 +472,8 @@ impl Editor { .as_micros() .checked_div(steps_taken) .unwrap_or_default(); - self.step_time = avg_step_time; - self.max_step_time = avg_step_time.max(self.max_step_time); + self.step_time = avg_step_time as usize; + self.max_step_time = self.step_time.max(self.max_step_time); } if globals.is_pressed(ActionId::StepSim) { self.step_pressed() @@ -575,20 +575,33 @@ impl Editor { } 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 { - self.source_board - .grid - .draw(d, &globals.textures, self.view_offset, self.zoom); + self.source_board.grid.draw( + d, + &globals.textures, + self.view_offset, + self.zoom, + draw_power, + ); } else { if self.machine.debug_subticks.is_empty() { - self.machine - .grid() - .draw(d, &globals.textures, self.view_offset, self.zoom); + self.machine.grid().draw( + d, + &globals.textures, + self.view_offset, + self.zoom, + draw_power, + ); } else { let subframe = &self.machine.debug_subticks[self.machine.subtick_index]; - subframe - .grid - .draw(d, &globals.textures, self.view_offset, self.zoom); + subframe.grid.draw( + d, + &globals.textures, + self.view_offset, + self.zoom, + draw_power, + ); if let Some(pos) = subframe.pos { let p = self.pos_to_screen(pos.to_vec()); 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, - self.step_time as usize, - (260, 42), - 9, - 1, - ); - draw_usize( - d, - &globals.textures, - self.max_step_time as usize, - (260, 60), - 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); + if globals.config.show_debug_timing { + draw_usize(d, &globals.textures, self.step_time, (260, 42), 9, 1); + draw_usize(d, &globals.textures, self.max_step_time, (260, 60), 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); @@ -1380,7 +1381,9 @@ impl Editor { offset.x -= offset.x.rem(tile_size); offset.y -= offset.y.rem(tile_size); 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); if self.mouse.left_click() { 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.y -= offset.y.rem(tile_size); 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); } if self.mouse.pos().x < SIDEBAR_WIDTH as f32 { diff --git a/src/input.rs b/src/input.rs index e092537..a769625 100644 --- a/src/input.rs +++ b/src/input.rs @@ -132,8 +132,7 @@ enum BindingEdit { } impl Input { - pub fn draw_edit(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals, y: i32) { - let mut y = y + 96; + pub fn draw_edit(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals, mut y: i32) { if self.editing_binding.is_some() { globals.mouse.clear(); } diff --git a/src/marble_engine/grid.rs b/src/marble_engine/grid.rs index 466a3a8..1a60af9 100644 --- a/src/marble_engine/grid.rs +++ b/src/marble_engine/grid.rs @@ -285,7 +285,7 @@ impl Grid { 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 start_x = (-offset.x as i32) / tile_size - 1; @@ -304,14 +304,14 @@ impl Grid { } let texture = textures.get(texname); draw_scaled_texture(d, texture, px, py, scale); - #[cfg(debug_assertions)] - // todo some in-game option to show power direction + if power_directions + { if let Tile::Powerable(_, state) = &tile { for dir in Direction::ALL { if state.get_dir(dir) { let texture = textures.get(dir.debug_arrow_texture_name()); draw_scaled_texture(d, texture, px, py, scale); - } + }} } } } else { diff --git a/src/ui.rs b/src/ui.rs index 47199b0..360e2ee 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -2,7 +2,7 @@ use std::ops::Range; use crate::{ theme::*, - util::{draw_scaled_texture, MouseInput, Scroll, Textures}, + util::{draw_scaled_texture, rect, MouseInput, Scroll, Textures}, Globals, }; 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( (d, mouse): (&mut RaylibDrawHandle, &MouseInput), x: i32, @@ -168,12 +197,7 @@ pub fn simple_button( height: i32, ) -> bool { let mouse_pos = mouse.pos(); - let bounds = Rectangle { - x: x as f32, - y: y as f32, - width: width as f32, - height: height as f32, - }; + let bounds = rect(x, y, width, height); let hover = bounds.check_collision_point_rec(mouse_pos); let pressed = hover && mouse.left_click(); d.draw_rectangle(x, y, width, height, widget_bg(hover));