diff --git a/CHANGLOG.md b/CHANGLOG.md index 1ad587c..8a8624a 100644 --- a/CHANGLOG.md +++ b/CHANGLOG.md @@ -1,6 +1,7 @@ # 0.2.0 - - added README.md - renamed tilemaps to backgrounds to make space for... tilemaps +- tile idx 0xffff and palette idx 0xff are now transparent rather than 0x0000 # 0.1.0 - 2023-07-21 initial release \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 7270030..d3bb716 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "gsa" -version = "0.1.0" +version = "0.2.0" edition = "2021" description = "Game development library modelled after an imaginary console" license = "0BSD" diff --git a/src/gsa.rs b/src/gsa.rs index 1b24fdd..055c66b 100644 --- a/src/gsa.rs +++ b/src/gsa.rs @@ -2,8 +2,8 @@ use crate::background::Background; use crate::rgb::Rgb; use crate::sprite::Sprite; use crate::{ - Buttons, BACKGROUND_MAX_SIZE, DPAD_DOWN, DPAD_LEFT, DPAD_RIGHT, DPAD_UP, MAX_BACKGROUNDS, - MAX_SPRITES, + Buttons, BACKGROUND_MAX_SIZE, DPAD_DOWN, DPAD_LEFT, DPAD_RIGHT, DPAD_UP, EMPTY_TILE, + MAX_BACKGROUNDS, MAX_SPRITES, }; use ascii::{AsciiChar, AsciiStr}; use glam::IVec2; @@ -16,7 +16,7 @@ pub struct Gsa { /// Palette used to draw graphics, initially loaded from gfx.gif pub palette: [Rgb; 256], - /// Tilemap layers available + /// Tilemap layers available, layer 0 in the back, layer 3 in front; layer 3 defaults to half-tile mode pub bgs: [Background; MAX_BACKGROUNDS], /// Currently selected font @@ -30,16 +30,36 @@ pub struct Gsa { } impl Gsa { - /// Clears all tiles of given map to 0 - pub fn clear_map(&mut self, map: usize) { - self.fill_map(map, 0); + /// Clears all tiles of given bg + pub fn clear_bg(&mut self, bg: usize) { + self.fill_bg(bg, EMPTY_TILE); } - /// Sets all tiles of map to val - pub fn fill_map(&mut self, map: usize, val: u16) { + /// Resets all bg + pub fn reset_bgs(&mut self) { + for bg in 0..MAX_BACKGROUNDS { + self.clear_bg(bg); + self.bgs[bg].scroll = IVec2::ZERO; + self.bgs[bg].half_tile = false; + } + //todo: document ui layer defaulting to half tile + self.bgs[3].half_tile = true; + } + + /// Clears all sprites + pub fn reset_sprites(&mut self) { + for sprite in 0..MAX_SPRITES { + self.sprites[sprite].pos = IVec2::ZERO; + self.sprites[sprite].tile = EMPTY_TILE; + self.sprites[sprite].priority = 0; + } + } + + /// Sets all tiles of bg to val + pub fn fill_bg(&mut self, bg: usize, val: u16) { for x in 0..BACKGROUND_MAX_SIZE { for y in 0..BACKGROUND_MAX_SIZE { - self.bgs[map].tiles[x][y] = val; + self.bgs[bg].tiles[x][y] = val; } } } diff --git a/src/gsa_render_to_screen.rs b/src/gsa_render_to_screen.rs index 1509cf3..07fd445 100644 --- a/src/gsa_render_to_screen.rs +++ b/src/gsa_render_to_screen.rs @@ -40,7 +40,7 @@ fn render_map(target: &mut [u8], map: &Background, tileset: &[u8]) { for x in startx..endx { for y in starty..endy { let tile = map.tiles[x as usize][y as usize]; - if tile > EMPTY_TILE { + if tile != EMPTY_TILE { draw_tile( target, IVec2 { @@ -60,7 +60,7 @@ pub(crate) fn render_to_screen(target: &mut [u8], gsa: &Gsa, tileset: &[u8]) { for i in 0..MAX_BACKGROUNDS { render_map(target, &gsa.bgs[i], tileset); for sprite in &gsa.sprites { - if sprite.tile > 0 && sprite.priority == i as u8 { + if sprite.tile != EMPTY_TILE && sprite.priority == i as u8 { draw_tile(target, sprite.pos, sprite.tile, tileset, false); } } diff --git a/src/lib.rs b/src/lib.rs index 2411eb5..b4ba70c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,15 @@ //! - Sprites: 256 of size 16x16 (pondering allowing larger sprites) //! - Backgrounds: 4 of size 1024x1024, scrollable //! +//! ## Getting started +//! `cargo install gsa` +//! +//! `gsa new my_project` +//! +//! `cd my_project` +//! +//! `cargo run` +//! //! ## Features not yet implemented //! - Background effects //! - Rotation? Scaling? diff --git a/src/main.rs b/src/main.rs index 31f2bac..c145919 100644 --- a/src/main.rs +++ b/src/main.rs @@ -77,11 +77,12 @@ fn main() { Some(local) => { writeln!( cargo, - "{} = {{path = \"{}\"}}", + "{} = {{path = \"{}\"}}\nglam = \"0.24.0\"\n\n[profile.dev.package.{}]\nopt-level = 3", crate_name!(), canonicalize(local) .expect("couldn't find path") - .to_slash_lossy() + .to_slash_lossy(), + crate_name!() ) .unwrap(); } diff --git a/src/run.rs b/src/run.rs index 0defd77..479005c 100644 --- a/src/run.rs +++ b/src/run.rs @@ -1,7 +1,11 @@ use crate::buttons::{button_from_gilrs, button_from_scancode}; use crate::gsa_render_to_screen::{render_to_screen, render_to_window}; use crate::tileset::load_tileset; -use crate::{Buttons, Gsa, Sprite, FONT_BOLD, MAX_SPRITES, SCREEN_HEIGHT, SCREEN_WIDTH}; +use crate::{ + Buttons, Gsa, Sprite, FONT_BOLD, MAX_BACKGROUNDS, MAX_SPRITES, SCREEN_HEIGHT, SCREEN_WIDTH, + TRANSPARENT, +}; +use clap::crate_version; use gilrs::EventType; use glam::IVec2; use std::cmp::min; @@ -46,22 +50,17 @@ pub fn run( released: 0, down: 0, }; - let mut game = init_fn(&mut gsa); - /*let state = State:: { - gsa, - game, - tileset, - update_fn, - first: true, - gilrs: Gilrs::new().unwrap(), - }; - */ + gsa.reset_bgs(); + gsa.reset_sprites(); + + let mut game = init_fn(&mut gsa); let event_loop = EventLoop::new(); let size = LogicalSize::new(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32); + //todo: custom title let window = WindowBuilder::new() - .with_title("Game Skunk Advance v0.1") + .with_title(format!("Game Skunk Advance v{}", crate_version!())) .with_inner_size(size) .with_min_inner_size(size) .build(&event_loop) @@ -119,8 +118,6 @@ pub fn run( last_second += Duration::from_secs(1); } - let mut screen_buffer = [0u8; SCREEN_WIDTH * SCREEN_HEIGHT]; - match event { Event::WindowEvent { event: @@ -197,6 +194,7 @@ pub fn run( *off_x = (size.width as usize - SCREEN_WIDTH * *scale) / 2; *off_y = (size.height as usize - SCREEN_HEIGHT * *scale) / 2; + let mut screen_buffer = [TRANSPARENT; SCREEN_WIDTH * SCREEN_HEIGHT]; let mut window_buffer = surface.buffer_mut().unwrap(); render_to_screen(&mut screen_buffer, &gsa, &tileset); render_to_window(