diff --git a/levels/chapter_01.json b/levels/chapter_01.json index 796b325..2ceca82 100644 --- a/levels/chapter_01.json +++ b/levels/chapter_01.json @@ -77,10 +77,7 @@ "id": "increment_input", "name": "Incrementer", "description": "Add one to each input number", - "init_board": { - "grid": " \n\n\n o\n 5\n\n *|\n A2\n\n\n\n", - "comments": [] - }, + "init_board": " \n o \n 5 \n \n *+ \n M2 \n \n \n \n", "stages": [{ "input": [93, 47, 71], "output": [94, 48, 72] diff --git a/src/editor.rs b/src/editor.rs index c8506b0..ef4af7f 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -601,7 +601,7 @@ impl Editor { } } - pub fn draw(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals) { + pub fn draw(&mut self, d: &mut RaylibDrawHandle, textures: &Textures, globals: &mut Globals) { d.clear_background(BG_WORLD); if self.draw_overlay && self.zoom >= 0.5 { @@ -618,13 +618,13 @@ impl Editor { } } - self.draw_board(d, &globals.textures); - self.board_overlay(d, &globals.textures); - self.draw_bottom_bar(d, globals); - self.draw_top_bar(d, &globals.textures); + self.draw_board(d, textures); + self.board_overlay(d, textures); + self.draw_bottom_bar(d, textures, globals); + self.draw_top_bar(d, textures); if self.active_tool == Tool::Blueprint { - self.draw_blueprint_sidebar(d, &globals.textures); + self.draw_blueprint_sidebar(d, textures); } self.mouse.update(d); @@ -642,7 +642,7 @@ impl Editor { match self.popup { Popup::Success | Popup::Failure => { - self.draw_end_popup(d, &globals.textures); + self.draw_end_popup(d, textures); } Popup::LevelInfo => { let bounds = screen_centered_rect_dyn(d, 100, 100); @@ -994,7 +994,12 @@ impl Editor { } } - fn draw_bottom_bar(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals) { + fn draw_bottom_bar( + &mut self, + d: &mut RaylibDrawHandle, + textures: &Textures, + globals: &mut Globals, + ) { let height = d.get_screen_height(); let footer_top = (height - FOOTER_HEIGHT) as f32; // background @@ -1030,13 +1035,13 @@ impl Editor { { self.active_tool = Tool::SelectArea(Selection::default()); } - draw_scaled_texture(d, globals.get_tex("cancel"), 104, y + 4, 2.); + draw_scaled_texture(d, textures.get("cancel"), 104, y + 4, 2.); self.tooltip.add(144, y, 40, 40, "Save blueprint"); if simple_button((d, &self.mouse), 144, y, 40, 40) { self.save_blueprint(selection); } - draw_scaled_texture(d, globals.get_tex("save"), 148, y + 4, 2.); + draw_scaled_texture(d, textures.get("save"), 148, y + 4, 2.); self.tooltip.add(188, y, 40, 40, "Copy"); if simple_button((d, &self.mouse), 188, y, 40, 40) || globals.is_pressed(ActionId::Copy) @@ -1050,7 +1055,7 @@ impl Editor { self.pasting_board = Some(board); } } - draw_scaled_texture(d, globals.get_tex("copy"), 192, y + 4, 2.); + draw_scaled_texture(d, textures.get("copy"), 192, y + 4, 2.); self.tooltip.add(232, y, 40, 40, "Delete"); if simple_button((d, &self.mouse), 232, y, 40, 40) { @@ -1062,7 +1067,7 @@ impl Editor { )); self.set_area(min, board); } - draw_scaled_texture(d, globals.get_tex("eraser"), 236, y + 4, 2.); + draw_scaled_texture(d, textures.get("eraser"), 236, y + 4, 2.); } let mut tool_button = @@ -1082,7 +1087,7 @@ impl Editor { scrollable_texture_option_button( (d, &self.mouse), pos, - globals.get_tex(texture), + textures.get(texture), tool_option, &mut self.active_tool, border, diff --git a/src/lib.rs b/src/lib.rs index 2de043b..3464583 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,47 +10,19 @@ pub mod theme; pub mod ui; pub mod util; -use std::fs; - use arboard::Clipboard; use config::Config; use input::ActionId; -use raylib::{texture::Texture2D, RaylibHandle}; -use util::{userdata_dir, Textures}; +use raylib::RaylibHandle; // use util::MouseInput; -pub const CONFIG_FILE_NAME: &str = "config.json"; - pub struct Globals { pub clipboard: Option, pub config: Config, - textures: Textures, // pub mouse: MouseInput, } impl Globals { - pub fn new(rl: &mut RaylibHandle, thread: &raylib::prelude::RaylibThread) -> Self { - let mut textures = Textures::default(); - textures.load_dir("assets", rl, thread); - textures.load_dir("assets/tiles", rl, thread); - textures.load_dir("assets/digits", rl, thread); - - let config_path = userdata_dir().join(CONFIG_FILE_NAME); - let config = fs::read_to_string(config_path) - .ok() - .and_then(|s| serde_json::from_str(&s).ok()) - .unwrap_or_default(); - - Self { - clipboard: Clipboard::new() - .map_err(|e| eprintln!("System clipboard error: {e}")) - .ok(), - config, - textures, - // mouse: util::MouseInput::default() - } - } - pub fn update(&mut self, rl: &RaylibHandle) { self.config.input.update(rl); } @@ -66,8 +38,4 @@ impl Globals { pub fn is_released(&self, action: ActionId) -> bool { self.config.input.is_released(action) } - - pub fn get_tex(&self, name: &str) -> &Texture2D { - self.textures.get(name) - } } diff --git a/src/main.rs b/src/main.rs index 9659834..4ebec62 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,10 @@ use std::{ collections::HashMap, - fs::{read_dir, read_to_string, File}, + fs::{self, read_dir, read_to_string, File}, io::Write, }; +use arboard::Clipboard; use raylib::prelude::*; use marble_machinations::*; @@ -16,12 +17,14 @@ use ui::{simple_option_button, tex32_button, text_button, text_input, ShapedText use util::*; const TITLE_TEXT: &str = concat!("Marble Machinations v", env!("CARGO_PKG_VERSION")); +const CONFIG_FILE_NAME: &str = "config.json"; struct Game { levels: Vec, level_scroll: usize, solutions: HashMap>, open_editor: Option, + textures: Textures, selected_level: usize, selected_solution: usize, delete_solution: Option, @@ -52,20 +55,37 @@ fn main() { impl Game { fn new(rl: &mut RaylibHandle, thread: &RaylibThread) -> Self { + let mut textures = Textures::default(); + textures.load_dir("assets", rl, thread); + textures.load_dir("assets/tiles", rl, thread); + textures.load_dir("assets/digits", rl, thread); + let levels = get_levels(); let solutions = get_solutions(); + let config_path = userdata_dir().join(CONFIG_FILE_NAME); + let config = fs::read_to_string(config_path) + .ok() + .and_then(|s| serde_json::from_str(&s).ok()) + .unwrap_or_default(); Self { levels, level_scroll: 0, solutions, open_editor: None, + textures, selected_level: 0, selected_solution: 0, delete_solution: None, editing_solution_name: false, level_desc_text: ShapedText::new(20), - globals: Globals::new(rl, thread), + globals: Globals { + clipboard: Clipboard::new() + .map_err(|e| eprintln!("System clipboard error: {e}")) + .ok(), + config, + // mouse: util::MouseInput::default() + }, show_settings: false, mouse: MouseInput::default(), } @@ -78,7 +98,7 @@ impl Game { self.mouse.update(&d); if let Some(editor) = &mut self.open_editor { editor.update(&d, &mut self.globals); - editor.draw(&mut d, &mut self.globals); + editor.draw(&mut d, &self.textures, &mut self.globals); match editor.get_exit_state() { ExitState::Dont => (), ExitState::ExitAndSave => { @@ -250,7 +270,7 @@ impl Game { if tex32_button( (d, &self.mouse), (level_list_width + entry_width + 15, solution_y + 4), - self.globals.get_tex("cancel"), + self.textures.get("cancel"), (&mut tooltip, "delete"), ) { self.delete_solution = Some(solution_index); @@ -335,6 +355,7 @@ impl Game { fn save_config(&self) { let path = userdata_dir().join(CONFIG_FILE_NAME); + // todo save more than just input let json = serde_json::to_string_pretty(&self.globals.config).unwrap(); let mut f = File::create(path).unwrap(); f.write_all(json.as_bytes()).unwrap(); diff --git a/src/marble_engine/grid.rs b/src/marble_engine/grid.rs index 30a04cb..a958be1 100644 --- a/src/marble_engine/grid.rs +++ b/src/marble_engine/grid.rs @@ -255,7 +255,7 @@ 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 + // TODO: some in-game option to show power direction if let Tile::Powerable(_, state) = &tile { for dir in Direction::ALL { if state.get_dir(dir) { diff --git a/src/ui.rs b/src/ui.rs index e211105..3a9bc42 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -38,6 +38,7 @@ impl ShapedText { } self.max_width = width; self.lines.clear(); + // todo remove leading space on broken lines // todo fix splitting very long words let mut line_start = 0; let mut line_end = 0;