84 lines
2.5 KiB
Rust
84 lines
2.5 KiB
Rust
use crate::rgb::Rgb;
|
|
use crate::sprite::Sprite;
|
|
use crate::tilemap::Tilemap;
|
|
use crate::{
|
|
Buttons, DPAD_DOWN, DPAD_LEFT, DPAD_RIGHT, DPAD_UP, MAX_SPRITES, MAX_TILEMAPS, TILEMAP_MAX_SIZE,
|
|
};
|
|
use ascii::{AsciiChar, AsciiStr};
|
|
use glam::IVec2;
|
|
|
|
/// Complete state of GSA
|
|
pub struct Gsa {
|
|
/// Sprites available
|
|
pub sprites: [Sprite; MAX_SPRITES],
|
|
|
|
/// Palette used to draw graphics, initially loaded from gfx.gif
|
|
pub palette: [Rgb; 256],
|
|
|
|
/// Tilemap layers available
|
|
pub maps: [Tilemap; MAX_TILEMAPS],
|
|
|
|
/// Currently selected font
|
|
///
|
|
/// Chosen as half-size tile index, extends 16x16 half tiles in x and y
|
|
pub font: u16,
|
|
|
|
pub(crate) pressed: Buttons,
|
|
pub(crate) released: Buttons,
|
|
pub(crate) down: Buttons,
|
|
}
|
|
|
|
impl Gsa {
|
|
/// Clears all tiles of given map to 0
|
|
pub fn clear_map(&mut self, map: usize) {
|
|
self.fill_map(map, 0);
|
|
}
|
|
|
|
/// Sets all tiles of map to val
|
|
pub fn fill_map(&mut self, map: usize, val: u16) {
|
|
for x in 0..TILEMAP_MAX_SIZE {
|
|
for y in 0..TILEMAP_MAX_SIZE {
|
|
self.maps[map].tiles[x][y] = val;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Checks if any of given buttons currently held down
|
|
pub fn button_down(&self, button: Buttons) -> bool {
|
|
self.down & button != 0
|
|
}
|
|
|
|
/// Checks if any of given buttons been pressed in the current frame
|
|
pub fn button_pressed(&self, button: Buttons) -> bool {
|
|
self.pressed & button != 0
|
|
}
|
|
|
|
/// Checks if any of given buttons been released in the current frame
|
|
pub fn button_released(&self, button: Buttons) -> bool {
|
|
self.released & button != 0
|
|
}
|
|
|
|
/// Directional vector (-1 to 1) from current dpad state
|
|
pub fn input_dir(&self) -> IVec2 {
|
|
IVec2 {
|
|
x: if self.button_down(DPAD_LEFT) { -1 } else { 0 }
|
|
+ if self.button_down(DPAD_RIGHT) { 1 } else { 0 },
|
|
y: if self.button_down(DPAD_UP) { -1 } else { 0 }
|
|
+ if self.button_down(DPAD_DOWN) { 1 } else { 0 },
|
|
}
|
|
}
|
|
|
|
/// Write given string on given map, at given position, with font [Gsa::font]
|
|
pub fn write_string(&mut self, map: usize, pos: IVec2, str: &str) {
|
|
let str = AsciiStr::from_ascii(str).unwrap();
|
|
for (i, ch) in str.into_iter().enumerate() {
|
|
self.maps[map].tiles[pos.x as usize + i][pos.y as usize] = self.get_char_tile(*ch);
|
|
}
|
|
}
|
|
|
|
fn get_char_tile(&self, ch: AsciiChar) -> u16 {
|
|
let ch = ch as u16;
|
|
self.font + (ch % 0x10) + (ch / 0x10) * 0x100
|
|
}
|
|
}
|