add config options to show/hide timing debug info and power directions
This commit is contained in:
parent
440cd7a759
commit
c8fc484e9c
7 changed files with 115 additions and 64 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
38
src/ui.rs
38
src/ui.rs
|
@ -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));
|
||||||
|
|
Loading…
Add table
Reference in a new issue