Compare commits

...

2 Commits

Author SHA1 Message Date
dani ba785f8525 refactor 2023-08-14 17:43:47 +00:00
dani 1c8a6bd391 switched bg rendering to iterate over pixels rather than over tiles 2023-08-14 17:43:05 +00:00
10 changed files with 227 additions and 133 deletions

View File

@ -1,5 +1,6 @@
# 0.3.0 # 0.3.0
- added size to backgrounds - added size to backgrounds
- refactored api, background functions are now methods to background rather than gsa
# 0.2.1 - 2023-07-27 # 0.2.1 - 2023-07-27
- fixed missing dependency in scaffolding - fixed missing dependency in scaffolding

View File

@ -24,6 +24,7 @@ dunce = "1.0.4"
path-slash = "0.2.1" path-slash = "0.2.1"
serde = {version = "1.0.181", features = ["derive"]} serde = {version = "1.0.181", features = ["derive"]}
postcard = {version = "1.0.6", features = ["alloc"]} postcard = {version = "1.0.6", features = ["alloc"]}
#rayon = "1.7.0"
[profile.release-dani] [profile.release-dani]
inherits = "release" inherits = "release"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -4,22 +4,11 @@ use gsa::{run, Gsa, FACE_DOWN};
struct Game {} struct Game {}
fn init(gsa: &mut Gsa) -> Game { fn init(gsa: &mut Gsa) -> Game {
gsa.sprites[0].tile = 0x0300; gsa.bg[0].fill(0x0101);
gsa.sprites[1].tile = 0x0200; //gsa.write_string(IVec2::ONE, "Hello world nyaa~");
gsa.bgs[0].tiles[1][1] = 0x0300;
gsa.bgs[1].half_tile = true;
gsa.load_map(1337);
gsa.write_string(1, IVec2::ONE, "Hello world nyaa~");
Game {} Game {}
} }
fn update(_game: &mut Game, gsa: &mut Gsa) { fn update(_game: &mut Game, gsa: &mut Gsa) {}
gsa.sprites[0].pos.x = (gsa.sprites[0].pos.x + 1) % 300;
gsa.sprites[1].pos += gsa.input_dir();
//gsa.bgs[1].scroll.x += 1;
if gsa.button_pressed(FACE_DOWN) {
gsa.sprites[1].tile += 1;
}
}
run!(init, update); run!(init, update);

View File

@ -4,13 +4,13 @@ use gsa::{run, Gsa};
struct Game {} struct Game {}
fn init(gsa: &mut Gsa) -> Game { fn init(gsa: &mut Gsa) -> Game {
gsa.sprites[0].tile = 0; gsa.sprite[0].tile = 0;
gsa.write_string(3, IVec2 { x: 10, y: 10 }, "Hello World, nyaa~"); gsa.write_string(3, IVec2 { x: 10, y: 10 }, "Hello World, nyaa~");
Game {} Game {}
} }
fn update(_game: &mut Game, gsa: &mut Gsa) { fn update(_game: &mut Game, gsa: &mut Gsa) {
gsa.sprites[0].pos += gsa.input_dir(); gsa.sprite[0].pos += gsa.input_dir();
} }
run!(init, update); run!(init, update);

View File

@ -1,4 +1,4 @@
use crate::BACKGROUND_MAX_SIZE; use crate::{BACKGROUND_MAX_SIZE, EMPTY_TILE};
use glam::IVec2; use glam::IVec2;
/// Tilemap which will be rendered on screen /// Tilemap which will be rendered on screen
@ -28,3 +28,19 @@ impl Default for Background {
} }
} }
} }
impl Background {
/// Clears all tiles of given bg
pub fn clear(&mut self) {
self.fill(EMPTY_TILE);
}
/// Sets all tiles to val
pub fn fill(&mut self, val: u16) {
for x in 0..BACKGROUND_MAX_SIZE {
for y in 0..BACKGROUND_MAX_SIZE {
self.tiles[x][y] = val;
}
}
}
}

View File

@ -13,19 +13,22 @@ use glam::IVec2;
/// Complete state of GSA /// Complete state of GSA
pub struct Gsa { pub struct Gsa {
/// Sprites available /// Sprites available
pub sprites: [Sprite; MAX_SPRITES], pub sprite: [Sprite; MAX_SPRITES],
/// Palette used to draw graphics, initially loaded from gfx.gif /// Palette used to draw graphics, initially loaded from gfx.gif
pub palette: [Rgb; 256], pub palette: [Rgb; 256],
/// Tilemap layers available, layer 0 in the back, layer 3 in front; layer 3 defaults to half-tile mode /// Tilemap layers available, layer 0 in the back, layer 3 in front; layer 3 defaults to half-tile mode
pub bgs: [Background; MAX_BACKGROUNDS], pub bg: [Background; MAX_BACKGROUNDS],
/// Currently selected font /// Currently selected font
/// ///
/// Chosen as half-size tile index, extends 16x16 half tiles in x and y /// Chosen as half-size tile index, extends 16x16 half tiles in x and y
pub font: u16, pub font: u16,
/// Target BG for string functions, defaults to layer 3
pub str_bg: usize,
pub(crate) pressed: Buttons, pub(crate) pressed: Buttons,
pub(crate) released: Buttons, pub(crate) released: Buttons,
pub(crate) down: Buttons, pub(crate) down: Buttons,
@ -33,47 +36,33 @@ pub struct Gsa {
} }
impl Gsa { impl Gsa {
/// Clears all tiles of given bg
pub fn clear_bg(&mut self, bg: usize) {
self.fill_bg(bg, EMPTY_TILE);
}
/// Resets all bg /// Resets all bg
pub fn reset_bgs(&mut self) { pub fn reset_bgs(&mut self) {
for bg in 0..MAX_BACKGROUNDS { for bg in 0..MAX_BACKGROUNDS {
self.clear_bg(bg); self.bg[bg].clear();
self.bgs[bg].scroll = IVec2::ZERO; self.bg[bg].scroll = IVec2::ZERO;
self.bgs[bg].half_tile = false; self.bg[bg].half_tile = false;
} }
//todo: document ui layer defaulting to half tile //todo: document ui layer defaulting to half tile
self.bgs[3].half_tile = true; self.bg[3].half_tile = true;
} }
/// Clears all sprites /// Clears all sprites
pub fn reset_sprites(&mut self) { pub fn reset_sprites(&mut self) {
for sprite in 0..MAX_SPRITES { for sprite in 0..MAX_SPRITES {
self.sprites[sprite].pos = IVec2::ZERO; self.sprite[sprite].pos = IVec2::ZERO;
self.sprites[sprite].tile = EMPTY_TILE; self.sprite[sprite].tile = EMPTY_TILE;
self.sprites[sprite].priority = 0; self.sprite[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[bg].tiles[x][y] = val;
}
} }
} }
/// Loads tilemap into backgrounds from id /// Loads tilemap into backgrounds from id
pub fn load_map(&mut self, map: u16) { pub fn load_map(&mut self, map: u16) {
for (i, map) in self.maps.maps[&map].iter().enumerate() { for (i, map) in self.maps.maps[&map].iter().enumerate() {
self.bgs[i].size = map.size; self.bg[i].size = map.size;
for y in 0..map.size.y as usize { for y in 0..map.size.y as usize {
for x in 0..map.size.x as usize { for x in 0..map.size.x as usize {
self.bgs[i].tiles[x][y] = map.data[x + y * map.size.x as usize] self.bg[i].tiles[x][y] = map.data[x + y * map.size.x as usize]
} }
} }
} }
@ -84,9 +73,9 @@ impl Gsa {
self.maps.maps.insert( self.maps.maps.insert(
map, map,
[ [
Tilemap::from_bg(&self.bgs[0]), Tilemap::from_bg(&self.bg[0]),
Tilemap::from_bg(&self.bgs[1]), Tilemap::from_bg(&self.bg[1]),
Tilemap::from_bg(&self.bgs[2]), Tilemap::from_bg(&self.bg[2]),
], ],
); );
} }
@ -122,10 +111,20 @@ impl Gsa {
} }
/// Write given string on given map, at given position, with font [Gsa::font] /// 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) { pub fn write_string(&mut self, pos: IVec2, str: &str) {
let str = AsciiStr::from_ascii(str).unwrap(); let str = AsciiStr::from_ascii(str).unwrap();
for (i, ch) in str.into_iter().enumerate() { for (i, ch) in str.into_iter().enumerate() {
self.bgs[map].tiles[pos.x as usize + i][pos.y as usize] = self.get_char_tile(*ch); self.bg[self.str_bg].tiles[pos.x as usize + i][pos.y as usize] =
self.get_char_tile(*ch);
}
}
/// Write given string vertically on given map, at given position, with font [Gsa::font]
pub fn write_string_vertical(&mut self, pos: IVec2, str: &str) {
let str = AsciiStr::from_ascii(str).unwrap();
for (i, ch) in str.into_iter().enumerate() {
self.bg[self.str_bg].tiles[pos.x as usize][pos.y as usize + i] =
self.get_char_tile(*ch);
} }
} }

View File

@ -1,4 +1,5 @@
use std::usize; use std::usize;
//use rayon::prelude::*;
use crate::{ use crate::{
Background, Gsa, Rgb, EMPTY_TILE, HALF_TILE_SIZE, MAX_BACKGROUNDS, TILESET_SIZE, TILE_SIZE, Background, Gsa, Rgb, EMPTY_TILE, HALF_TILE_SIZE, MAX_BACKGROUNDS, TILESET_SIZE, TILE_SIZE,
@ -32,7 +33,7 @@ fn draw_tile(
} }
} }
fn render_map(target: &mut [u8], map: &Background, tileset: &[u8], screen_size: IVec2) { fn render_bg(target: &mut [u8], map: &Background, tileset: &[u8], screen_size: IVec2) {
let tcmult = if map.half_tile { 2 } else { 1 }; let tcmult = if map.half_tile { 2 } else { 1 };
let tilesize = if map.half_tile { let tilesize = if map.half_tile {
HALF_TILE_SIZE HALF_TILE_SIZE
@ -71,12 +72,44 @@ fn render_map(target: &mut [u8], map: &Background, tileset: &[u8], screen_size:
} }
} }
fn render_bg2(target: &mut [u8], map: &Background, tileset: &[u8], screen_size: IVec2) {
let tilesize = if map.half_tile {
HALF_TILE_SIZE
} else {
TILE_SIZE
} as i32;
//target.par_chunks_exact_mut(screen_size.x as usize).enumerate().for_each({|(screeny, row)|
target.chunks_exact_mut(screen_size.x as usize).enumerate().for_each({|(screeny, row)|
for screenx in 0..screen_size.x {
let x = screenx + map.scroll.x;
let y = screeny as i32 + map.scroll.y;
let tilex = x / tilesize;
let tiley = y / tilesize;
let pixx = x % tilesize;
let pixy = y % tilesize;
let tile = if tilex >= 0 && tiley >= 0 && tilex < map.size.x && tiley < map.size.y {
map.tiles[tilex as usize][tiley as usize]
} else {
EMPTY_TILE
};
if tile != EMPTY_TILE {
let tilesetx = tile as usize % 0x100 * tilesize as usize + pixx as usize;
let tilesety = tile as usize / 0x100 * tilesize as usize + pixy as usize;
let p = tileset[tilesetx + tilesety * (TILESET_SIZE * TILE_SIZE)];
if p != TRANSPARENT {
row[x as usize] = p;
}
}
}
});
}
pub(crate) fn render_to_screen(target: &mut [u8], gsa: &Gsa, tileset: &[u8], screen_size: IVec2) { pub(crate) fn render_to_screen(target: &mut [u8], gsa: &Gsa, tileset: &[u8], screen_size: IVec2) {
for i in 0..MAX_BACKGROUNDS { for i in 0..MAX_BACKGROUNDS {
if gsa.bgs[i].active { if gsa.bg[i].active {
render_map(target, &gsa.bgs[i], tileset, screen_size); render_bg2(target, &gsa.bg[i], tileset, screen_size);
} }
for sprite in &gsa.sprites { for sprite in &gsa.sprite {
if sprite.tile != EMPTY_TILE && sprite.priority == i as u8 { if sprite.tile != EMPTY_TILE && sprite.priority == i as u8 {
draw_tile(target, sprite.pos, sprite.tile, tileset, false, screen_size); draw_tile(target, sprite.pos, sprite.tile, tileset, false, screen_size);
} }

View File

@ -125,13 +125,12 @@ impl Background {
} }
fn draw_input_window(gsa: &mut Gsa, pos: IVec2, caption: &str) { fn draw_input_window(gsa: &mut Gsa, pos: IVec2, caption: &str) {
gsa.bgs[2].draw_frame(pos, IVec2 { x: 7, y: 5 }); gsa.bg[2].draw_frame(pos, IVec2 { x: 7, y: 5 });
gsa.bgs[2].tiles[pos.x as usize + 3][pos.y as usize + 1] = TILE_INPUT; gsa.bg[2].tiles[pos.x as usize + 3][pos.y as usize + 1] = TILE_INPUT;
gsa.bgs[2].tiles[pos.x as usize + 4][pos.y as usize + 1] = TILE_INPUT; gsa.bg[2].tiles[pos.x as usize + 4][pos.y as usize + 1] = TILE_INPUT;
gsa.bgs[2].tiles[pos.x as usize + 1][pos.y as usize + 3] = TILE_BUT_YES; gsa.bg[2].tiles[pos.x as usize + 1][pos.y as usize + 3] = TILE_BUT_YES;
gsa.bgs[2].tiles[pos.x as usize + 5][pos.y as usize + 3] = TILE_BUT_NO; gsa.bg[2].tiles[pos.x as usize + 5][pos.y as usize + 3] = TILE_BUT_NO;
gsa.write_string( gsa.write_string(
3,
IVec2 { IVec2 {
x: pos.x * 2 + 2, x: pos.x * 2 + 2,
y: pos.y * 2 + 1, y: pos.y * 2 + 1,
@ -139,7 +138,6 @@ fn draw_input_window(gsa: &mut Gsa, pos: IVec2, caption: &str) {
caption, caption,
); );
gsa.write_string( gsa.write_string(
3,
IVec2 { IVec2 {
x: pos.x * 2 + 3, x: pos.x * 2 + 3,
y: pos.y * 2 + 3, y: pos.y * 2 + 3,
@ -150,7 +148,6 @@ fn draw_input_window(gsa: &mut Gsa, pos: IVec2, caption: &str) {
fn update_input_window(gsa: &mut Gsa, pos: IVec2, val: u16) { fn update_input_window(gsa: &mut Gsa, pos: IVec2, val: u16) {
gsa.write_string( gsa.write_string(
3,
IVec2 { IVec2 {
x: pos.x * 2 + 6, x: pos.x * 2 + 6,
y: pos.y * 2 + 3, y: pos.y * 2 + 3,
@ -159,68 +156,105 @@ fn update_input_window(gsa: &mut Gsa, pos: IVec2, val: u16) {
); );
} }
fn set_state(state: State, gsa1: &mut Gsa, gsa2: &mut Gsa, current_layer: usize, all_layers: bool) { fn set_state(
state: State,
gsa1: &mut Gsa,
gsa2: &mut Gsa,
current_layer: usize,
all_layers: bool,
current_map: u16,
) {
match state { match state {
State::Edit => { State::Edit => {
//update editing layers //update editing layers
if all_layers { if all_layers {
gsa1.bgs[0].active = true; gsa1.bg[0].active = true;
gsa1.bgs[1].active = true; gsa1.bg[1].active = true;
gsa1.bgs[2].active = true; gsa1.bg[2].active = true;
} else { } else {
gsa1.bgs[0].active = current_layer == 0; gsa1.bg[0].active = current_layer == 0;
gsa1.bgs[1].active = current_layer == 1; gsa1.bg[1].active = current_layer == 1;
gsa1.bgs[2].active = current_layer == 2; gsa1.bg[2].active = current_layer == 2;
} }
gsa2.clear_bg(2); gsa2.bg[2].clear();
gsa2.clear_bg(3); gsa2.bg[2].clear();
draw_toolbar(gsa1, gsa2, current_layer, all_layers); draw_toolbar(gsa1, gsa2, current_layer, all_layers, current_map);
gsa2.bgs[0].active = false; gsa2.bg[0].active = false;
gsa2.bgs[1].active = false; gsa2.bg[1].active = false;
gsa1.sprites[SPR_CURSOR].priority = 3; gsa1.sprite[SPR_CURSOR].priority = 3;
gsa1.sprites[SPR_CURSOR].tile = TILE_CURSOR; gsa1.sprite[SPR_CURSOR].tile = TILE_CURSOR;
gsa2.sprites[SPR_CURSOR].tile = EMPTY_TILE; gsa2.sprite[SPR_CURSOR].tile = EMPTY_TILE;
} }
State::SelectTile => { State::SelectTile => {
draw_toolbar(gsa1, gsa2, current_layer, all_layers); draw_toolbar(gsa1, gsa2, current_layer, all_layers, current_map);
gsa1.bgs[0].active = false; gsa1.bg[0].active = false;
gsa1.bgs[1].active = false; gsa1.bg[1].active = false;
gsa1.bgs[2].active = false; gsa1.bg[2].active = false;
gsa2.bgs[0].active = true; gsa2.bg[0].active = true;
gsa2.bgs[1].active = true; gsa2.bg[1].active = true;
gsa1.sprites[SPR_CURSOR].tile = EMPTY_TILE; gsa1.sprite[SPR_CURSOR].tile = EMPTY_TILE;
gsa2.sprites[SPR_CURSOR].tile = TILE_CURSOR; gsa2.sprite[SPR_CURSOR].tile = TILE_CURSOR;
} }
State::NewMapDialog => { State::NewMapDialog => {
gsa1.bgs[0].active = false; gsa1.bg[0].active = false;
gsa1.bgs[1].active = false; gsa1.bg[1].active = false;
gsa1.bgs[2].active = false; gsa1.bg[2].active = false;
gsa2.bgs[0].active = false; gsa2.bg[0].active = false;
gsa2.bgs[1].active = false; gsa2.bg[1].active = false;
gsa1.sprites[SPR_CURSOR].tile = EMPTY_TILE; gsa1.sprite[SPR_CURSOR].tile = EMPTY_TILE;
gsa2.sprites[SPR_CURSOR].tile = EMPTY_TILE; gsa2.sprite[SPR_CURSOR].tile = EMPTY_TILE;
draw_input_window(gsa2, IVec2 { x: 15, y: 9 }, "Create Map"); draw_input_window(gsa2, IVec2 { x: 15, y: 9 }, "Create Map");
} }
} }
} }
fn draw_toolbar(gsa1: &mut Gsa, gsa2: &mut Gsa, current_layer: usize, all_layers: bool) { fn draw_toolbar(
gsa1: &mut Gsa,
gsa2: &mut Gsa,
current_layer: usize,
all_layers: bool,
current_map: u16,
) {
for y in 0..BACKGROUND_MAX_SIZE { for y in 0..BACKGROUND_MAX_SIZE {
gsa2.bgs[2].tiles[0][y] = 0x7010; gsa2.bg[2].tiles[0][y] = 0x7010;
} }
gsa2.bgs[2].tiles[0][BUT_SAVE] = 0x7211; gsa2.bg[2].tiles[0][BUT_SAVE] = 0x7211;
gsa2.bgs[2].tiles[0][BUT_CREATE] = TILE_BUT_CREATE; gsa2.bg[2].tiles[0][BUT_CREATE] = TILE_BUT_CREATE;
gsa2.bgs[2].tiles[0][BUT_EXIT] = 0x7212; gsa2.bg[2].tiles[0][BUT_EXIT] = 0x7212;
//layer buttons //layer buttons
gsa2.bgs[2].tiles[0][BUT_LAYER1] = if current_layer == 0 { 0x7111 } else { 0x7011 }; gsa2.bg[2].tiles[0][BUT_LAYER1] = if current_layer == 0 { 0x7111 } else { 0x7011 };
gsa2.bgs[2].tiles[0][BUT_LAYER2] = if current_layer == 1 { 0x7112 } else { 0x7012 }; gsa2.bg[2].tiles[0][BUT_LAYER2] = if current_layer == 1 { 0x7112 } else { 0x7012 };
gsa2.bgs[2].tiles[0][BUT_LAYER3] = if current_layer == 2 { 0x7113 } else { 0x7013 }; gsa2.bg[2].tiles[0][BUT_LAYER3] = if current_layer == 2 { 0x7113 } else { 0x7013 };
gsa2.bgs[2].tiles[0][BUT_LAYERS] = if all_layers { 0x7114 } else { 0x7014 }; gsa2.bg[2].tiles[0][BUT_LAYERS] = if all_layers { 0x7114 } else { 0x7014 };
gsa2.bgs[2].size = IVec2 { x: 120, y: 68 }; //enough to cover 4k monitors? <_< gsa2.bg[2].size = IVec2 { x: 120, y: 68 }; //enough to cover 4k monitors? <_<
gsa2.bgs[3].size = IVec2 { x: 240, y: 136 }; gsa2.bg[3].size = IVec2 { x: 240, y: 136 };
gsa2.write_string_vertical(
IVec2 {
x: 0,
y: BUT_EXIT as i32 * 2 + 3,
},
&format!("MAP-{:04X}", current_map),
);
gsa2.write_string_vertical(
IVec2 {
x: 0,
y: BUT_EXIT as i32 * 2 + 12,
},
&format!("W-{}", gsa1.bg[0].size.x),
);
gsa2.write_string_vertical(
IVec2 {
x: 1,
y: BUT_EXIT as i32 * 2 + 12,
},
&format!("H-{}", gsa1.bg[0].size.y),
);
} }
pub(crate) fn run_mapedit() { pub(crate) fn run_mapedit() {
@ -237,14 +271,15 @@ pub(crate) fn run_mapedit() {
}; };
let mut gsa1 = Gsa { let mut gsa1 = Gsa {
sprites: [Sprite::default(); MAX_SPRITES], sprite: [Sprite::default(); MAX_SPRITES],
palette, palette,
bgs: Default::default(), bg: Default::default(),
font: FONT_BOLD, font: FONT_BOLD,
pressed: 0, pressed: 0,
released: 0, released: 0,
down: 0, down: 0,
maps, maps,
str_bg: 3,
}; };
gsa1.reset_bgs(); gsa1.reset_bgs();
@ -255,26 +290,27 @@ pub(crate) fn run_mapedit() {
} }
for i in 0..3 { for i in 0..3 {
gsa1.bgs[i].scroll = IVec2 { gsa1.bg[i].scroll = IVec2 {
x: -16 - 32, x: -16 - 32,
y: -32, y: -32,
}; };
} }
let mut gsa2 = Gsa { let mut gsa2 = Gsa {
sprites: [Sprite::default(); MAX_SPRITES], sprite: [Sprite::default(); MAX_SPRITES],
palette, palette,
bgs: Default::default(), bg: Default::default(),
font: FONT_BOLD, font: FONT_BOLD,
pressed: 0, pressed: 0,
released: 0, released: 0,
down: 0, down: 0,
maps: Maps::default(), maps: Maps::default(),
str_bg: 3,
}; };
gsa2.reset_bgs(); gsa2.reset_bgs();
gsa2.reset_sprites(); gsa2.reset_sprites();
for i in 0..2 { for i in 0..2 {
gsa2.bgs[i].scroll = IVec2 { gsa2.bg[i].scroll = IVec2 {
x: -16 - 32, x: -16 - 32,
y: -32, y: -32,
}; };
@ -282,7 +318,7 @@ pub(crate) fn run_mapedit() {
for y in 0..TILESET_SIZE { for y in 0..TILESET_SIZE {
for x in 0..TILESET_SIZE { for x in 0..TILESET_SIZE {
gsa2.bgs[0].tiles[x][y] = (x + (y << 8)) as u16; gsa2.bg[0].tiles[x][y] = (x + (y << 8)) as u16;
} }
} }
//draw_input_window(&mut gsa2, IVec2 { x: 5, y: 3 }, "Create Map"); //draw_input_window(&mut gsa2, IVec2 { x: 5, y: 3 }, "Create Map");
@ -308,13 +344,20 @@ pub(crate) fn run_mapedit() {
let mut middle_down = false; let mut middle_down = false;
let mut right_down = false; let mut right_down = false;
let mut selected_tile = IVec2::ZERO; let mut selected_tile = IVec2::ZERO;
gsa2.bgs[1].tiles[0][0] = TILE_MARKER; gsa2.bg[1].tiles[0][0] = TILE_MARKER;
let mut current_layer = 0usize; let mut current_layer = 0usize;
let mut all_layers = true; let mut all_layers = true;
let mut state = State::Edit; let mut state = State::Edit;
let mut input_buf = 0u16; let mut input_buf = 0u16;
let mut current_map = 0; let mut current_map = 0;
set_state(State::Edit, &mut gsa1, &mut gsa2, current_layer, all_layers); set_state(
State::Edit,
&mut gsa1,
&mut gsa2,
current_layer,
all_layers,
current_map,
);
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
let mouse_pos = &mut mouse_pos; let mouse_pos = &mut mouse_pos;
@ -347,6 +390,7 @@ pub(crate) fn run_mapedit() {
&mut gsa2, &mut gsa2,
*current_layer, *current_layer,
*all_layers, *all_layers,
*current_map,
); );
} else { } else {
*state = State::Edit; *state = State::Edit;
@ -356,6 +400,7 @@ pub(crate) fn run_mapedit() {
&mut gsa2, &mut gsa2,
*current_layer, *current_layer,
*all_layers, *all_layers,
*current_map,
); );
} }
} }
@ -409,6 +454,7 @@ pub(crate) fn run_mapedit() {
&mut gsa2, &mut gsa2,
*current_layer, *current_layer,
*all_layers, *all_layers,
*current_map,
); );
update_input_window( update_input_window(
&mut gsa2, &mut gsa2,
@ -424,6 +470,7 @@ pub(crate) fn run_mapedit() {
&mut gsa2, &mut gsa2,
*current_layer, *current_layer,
*all_layers, *all_layers,
*current_map,
); );
} }
BUT_LAYER2 => { BUT_LAYER2 => {
@ -434,6 +481,7 @@ pub(crate) fn run_mapedit() {
&mut gsa2, &mut gsa2,
*current_layer, *current_layer,
*all_layers, *all_layers,
*current_map,
); );
} }
BUT_LAYER3 => { BUT_LAYER3 => {
@ -444,6 +492,7 @@ pub(crate) fn run_mapedit() {
&mut gsa2, &mut gsa2,
*current_layer, *current_layer,
*all_layers, *all_layers,
*current_map,
); );
} }
BUT_LAYERS => { BUT_LAYERS => {
@ -454,6 +503,7 @@ pub(crate) fn run_mapedit() {
&mut gsa2, &mut gsa2,
*current_layer, *current_layer,
*all_layers, *all_layers,
*current_map,
); );
} }
BUT_EXIT => { BUT_EXIT => {
@ -484,6 +534,7 @@ pub(crate) fn run_mapedit() {
&mut gsa2, &mut gsa2,
*current_layer, *current_layer,
*all_layers, *all_layers,
*current_map,
); );
} else if mouse_pos.x / 16 == 20 { } else if mouse_pos.x / 16 == 20 {
println!("no"); println!("no");
@ -494,6 +545,7 @@ pub(crate) fn run_mapedit() {
&mut gsa2, &mut gsa2,
*current_layer, *current_layer,
*all_layers, *all_layers,
*current_map,
); );
} }
} }
@ -531,14 +583,14 @@ pub(crate) fn run_mapedit() {
match *state { match *state {
State::Edit => { State::Edit => {
// normal mode // normal mode
gsa1.bgs[0].scroll -= delta; gsa1.bg[0].scroll -= delta;
gsa1.bgs[1].scroll -= delta; gsa1.bg[1].scroll -= delta;
gsa1.bgs[2].scroll -= delta; gsa1.bg[2].scroll -= delta;
} }
State::SelectTile => { State::SelectTile => {
// tile select mode // tile select mode
gsa2.bgs[0].scroll -= delta; gsa2.bg[0].scroll -= delta;
gsa2.bgs[1].scroll -= delta; gsa2.bg[1].scroll -= delta;
//gsa2.bgs[2].scroll -= delta; //gsa2.bgs[2].scroll -= delta;
} }
_ => {} _ => {}
@ -546,17 +598,17 @@ pub(crate) fn run_mapedit() {
} }
*mouse_pos = new_pos; *mouse_pos = new_pos;
*tile_pos = IVec2 { *tile_pos = IVec2 {
x: (new_pos.x + gsa1.bgs[0].scroll.x).div_euclid(TILE_SIZE as i32), x: (new_pos.x + gsa1.bg[0].scroll.x).div_euclid(TILE_SIZE as i32),
y: (new_pos.y + gsa1.bgs[0].scroll.y).div_euclid(TILE_SIZE as i32), y: (new_pos.y + gsa1.bg[0].scroll.y).div_euclid(TILE_SIZE as i32),
}; };
*tile_pos2 = IVec2 { *tile_pos2 = IVec2 {
x: (new_pos.x + gsa2.bgs[0].scroll.x).div_euclid(TILE_SIZE as i32), x: (new_pos.x + gsa2.bg[0].scroll.x).div_euclid(TILE_SIZE as i32),
y: (new_pos.y + gsa2.bgs[0].scroll.y).div_euclid(TILE_SIZE as i32), y: (new_pos.y + gsa2.bg[0].scroll.y).div_euclid(TILE_SIZE as i32),
}; };
let cursor_pos = *tile_pos * TILE_SIZE as i32 - gsa1.bgs[0].scroll; let cursor_pos = *tile_pos * TILE_SIZE as i32 - gsa1.bg[0].scroll;
let cursor_pos2 = *tile_pos2 * TILE_SIZE as i32 - gsa2.bgs[0].scroll; let cursor_pos2 = *tile_pos2 * TILE_SIZE as i32 - gsa2.bg[0].scroll;
gsa1.sprites[SPR_CURSOR].pos = cursor_pos; gsa1.sprite[SPR_CURSOR].pos = cursor_pos;
gsa2.sprites[SPR_CURSOR].pos = cursor_pos2; gsa2.sprite[SPR_CURSOR].pos = cursor_pos2;
} }
_ => {} _ => {}
}, },
@ -571,7 +623,7 @@ pub(crate) fn run_mapedit() {
&& tile_pos.y < BACKGROUND_MAX_SIZE as i32 && tile_pos.y < BACKGROUND_MAX_SIZE as i32
{ {
let tile = (selected_tile.x + (selected_tile.y << 8)) as u16; let tile = (selected_tile.x + (selected_tile.y << 8)) as u16;
gsa1.bgs[*current_layer].tiles[tile_pos.x as usize] gsa1.bg[*current_layer].tiles[tile_pos.x as usize]
[tile_pos.y as usize] = tile; [tile_pos.y as usize] = tile;
} }
} else if *right_down { } else if *right_down {
@ -580,7 +632,7 @@ pub(crate) fn run_mapedit() {
&& tile_pos.x < BACKGROUND_MAX_SIZE as i32 && tile_pos.x < BACKGROUND_MAX_SIZE as i32
&& tile_pos.y < BACKGROUND_MAX_SIZE as i32 && tile_pos.y < BACKGROUND_MAX_SIZE as i32
{ {
gsa1.bgs[*current_layer].tiles[tile_pos.x as usize] gsa1.bg[*current_layer].tiles[tile_pos.x as usize]
[tile_pos.y as usize] = EMPTY_TILE; [tile_pos.y as usize] = EMPTY_TILE;
} }
} }
@ -592,10 +644,10 @@ pub(crate) fn run_mapedit() {
&& tile_pos2.x < BACKGROUND_MAX_SIZE as i32 && tile_pos2.x < BACKGROUND_MAX_SIZE as i32
&& tile_pos2.y < BACKGROUND_MAX_SIZE as i32 && tile_pos2.y < BACKGROUND_MAX_SIZE as i32
{ {
gsa2.bgs[1].tiles[selected_tile.x as usize] gsa2.bg[1].tiles[selected_tile.x as usize]
[selected_tile.y as usize] = EMPTY_TILE; [selected_tile.y as usize] = EMPTY_TILE;
*selected_tile = *tile_pos2; *selected_tile = *tile_pos2;
gsa2.bgs[1].tiles[selected_tile.x as usize] gsa2.bg[1].tiles[selected_tile.x as usize]
[selected_tile.y as usize] = TILE_MARKER; [selected_tile.y as usize] = TILE_MARKER;
} }
} }
@ -626,10 +678,10 @@ pub(crate) fn run_mapedit() {
}; };
match *state { match *state {
State::Edit => { State::Edit => {
let xs = -gsa1.bgs[0].scroll.x - 1; let xs = -gsa1.bg[0].scroll.x - 1;
let ys = -gsa1.bgs[0].scroll.y - 1; let ys = -gsa1.bg[0].scroll.y - 1;
let xe = xs + gsa1.bgs[0].size.x * TILE_SIZE as i32 + 1; let xe = xs + gsa1.bg[0].size.x * TILE_SIZE as i32 + 1;
let ye = ys + gsa1.bgs[0].size.y * TILE_SIZE as i32 + 1; let ye = ys + gsa1.bg[0].size.y * TILE_SIZE as i32 + 1;
if xs >= 16 && xs < screen_size.x { if xs >= 16 && xs < screen_size.x {
let starty = (ys + 1).max(0); let starty = (ys + 1).max(0);
let len = ye.min(screen_size.y) - starty; let len = ye.min(screen_size.y) - starty;

View File

@ -47,15 +47,18 @@ pub fn run<TGame: 'static>(
) { ) {
let (tileset, palette) = load_tileset(image_data); let (tileset, palette) = load_tileset(image_data);
//rayon::ThreadPoolBuilder::new().num_threads(32).build_global().unwrap();
let mut gsa = Gsa { let mut gsa = Gsa {
sprites: [Sprite::default(); MAX_SPRITES], sprite: [Sprite::default(); MAX_SPRITES],
bgs: Default::default(), bg: Default::default(),
palette, palette,
font: FONT_BOLD, font: FONT_BOLD,
pressed: 0, pressed: 0,
released: 0, released: 0,
down: 0, down: 0,
maps: postcard::from_bytes(maps_data).unwrap(), maps: postcard::from_bytes(maps_data).unwrap(),
str_bg: 3,
}; };
gsa.reset_bgs(); gsa.reset_bgs();
@ -97,7 +100,7 @@ pub fn run<TGame: 'static>(
let mut last_second = Instant::now(); let mut last_second = Instant::now();
let mut last_frame = last_second; let mut last_frame = last_second;
let target_frame_duration = Duration::from_secs(1).div_f64(60.0); let target_frame_duration = Duration::from_secs(1).div_f64(60000.0);
let mut scale = 1usize; let mut scale = 1usize;
let mut off_x = 0usize; let mut off_x = 0usize;