layer system for map edit
This commit is contained in:
parent
8f78bbdca1
commit
aff0311484
|
@ -13,7 +13,7 @@ keywords = ["gamedev"]
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glam = "0.24.0"
|
glam = {version = "0.24.0", features = ["serde"]}
|
||||||
ascii = "1.1.0"
|
ascii = "1.1.0"
|
||||||
gilrs = "0.10.2"
|
gilrs = "0.10.2"
|
||||||
winit = "0.28.6"
|
winit = "0.28.6"
|
||||||
|
@ -22,7 +22,8 @@ gif = "0.12.0"
|
||||||
clap = {version = "4.3.8", features = ["derive", "cargo"]}
|
clap = {version = "4.3.8", features = ["derive", "cargo"]}
|
||||||
dunce = "1.0.4"
|
dunce = "1.0.4"
|
||||||
path-slash = "0.2.1"
|
path-slash = "0.2.1"
|
||||||
serde = "1.0.181"
|
serde = {version = "1.0.181", features = ["derive"]}
|
||||||
|
postcard = {version = "1.0.6", features = ["alloc"]}
|
||||||
|
|
||||||
[profile.release-dani]
|
[profile.release-dani]
|
||||||
inherits = "release"
|
inherits = "release"
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 28 KiB |
|
@ -8,6 +8,7 @@ fn init(gsa: &mut Gsa) -> Game {
|
||||||
gsa.sprites[1].tile = 0x0200;
|
gsa.sprites[1].tile = 0x0200;
|
||||||
gsa.bgs[0].tiles[1][1] = 0x0300;
|
gsa.bgs[0].tiles[1][1] = 0x0300;
|
||||||
gsa.bgs[1].half_tile = true;
|
gsa.bgs[1].half_tile = true;
|
||||||
|
gsa.load_map(1337);
|
||||||
gsa.write_string(1, IVec2::ONE, "Hello world nyaa~");
|
gsa.write_string(1, IVec2::ONE, "Hello world nyaa~");
|
||||||
Game {}
|
Game {}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +16,7 @@ fn init(gsa: &mut Gsa) -> 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[0].pos.x = (gsa.sprites[0].pos.x + 1) % 300;
|
||||||
gsa.sprites[1].pos += gsa.input_dir();
|
gsa.sprites[1].pos += gsa.input_dir();
|
||||||
gsa.bgs[1].scroll.x += 1;
|
//gsa.bgs[1].scroll.x += 1;
|
||||||
if gsa.button_pressed(FACE_DOWN) {
|
if gsa.button_pressed(FACE_DOWN) {
|
||||||
gsa.sprites[1].tile += 1;
|
gsa.sprites[1].tile += 1;
|
||||||
}
|
}
|
||||||
|
|
19
src/gsa.rs
19
src/gsa.rs
|
@ -1,4 +1,5 @@
|
||||||
use crate::background::Background;
|
use crate::background::Background;
|
||||||
|
use crate::maps::Maps;
|
||||||
use crate::rgb::Rgb;
|
use crate::rgb::Rgb;
|
||||||
use crate::sprite::Sprite;
|
use crate::sprite::Sprite;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -27,6 +28,7 @@ pub struct Gsa {
|
||||||
pub(crate) pressed: Buttons,
|
pub(crate) pressed: Buttons,
|
||||||
pub(crate) released: Buttons,
|
pub(crate) released: Buttons,
|
||||||
pub(crate) down: Buttons,
|
pub(crate) down: Buttons,
|
||||||
|
pub(crate) maps: Maps,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gsa {
|
impl Gsa {
|
||||||
|
@ -64,6 +66,23 @@ impl Gsa {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loads tilemap into backgrounds
|
||||||
|
pub fn load_map(&mut self, map: u16) {
|
||||||
|
for (i, map) in self.maps.maps[&map].iter().enumerate() {
|
||||||
|
self.bgs[i].size = map.size;
|
||||||
|
for y in 0..map.size.y 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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Does a tilemap with this id exist?
|
||||||
|
pub fn map_exists(&mut self, map: u16) -> bool {
|
||||||
|
self.maps.maps.contains_key(&map)
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if any of given buttons currently held down
|
/// Checks if any of given buttons currently held down
|
||||||
pub fn button_down(&self, button: Buttons) -> bool {
|
pub fn button_down(&self, button: Buttons) -> bool {
|
||||||
self.down & button != 0
|
self.down & button != 0
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::usize;
|
use std::usize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Background, Gsa, Rgb, BACKGROUND_MAX_SIZE, EMPTY_TILE, HALF_TILE_SIZE, MAX_BACKGROUNDS,
|
Background, Gsa, Rgb, EMPTY_TILE, HALF_TILE_SIZE, MAX_BACKGROUNDS, TILESET_SIZE, TILE_SIZE,
|
||||||
SCREEN_HEIGHT, SCREEN_WIDTH, TILESET_SIZE, TILE_SIZE, TRANSPARENT,
|
TRANSPARENT,
|
||||||
};
|
};
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use softbuffer::Buffer;
|
use softbuffer::Buffer;
|
||||||
|
|
|
@ -43,9 +43,11 @@ mod background;
|
||||||
mod buttons;
|
mod buttons;
|
||||||
mod gsa;
|
mod gsa;
|
||||||
mod gsa_render_to_screen;
|
mod gsa_render_to_screen;
|
||||||
|
mod maps;
|
||||||
mod rgb;
|
mod rgb;
|
||||||
mod run;
|
mod run;
|
||||||
mod sprite;
|
mod sprite;
|
||||||
|
mod tilemap;
|
||||||
mod tileset;
|
mod tileset;
|
||||||
|
|
||||||
pub use crate::background::*;
|
pub use crate::background::*;
|
||||||
|
|
|
@ -3,9 +3,11 @@ mod buttons;
|
||||||
mod gsa;
|
mod gsa;
|
||||||
mod gsa_render_to_screen;
|
mod gsa_render_to_screen;
|
||||||
mod mapedit;
|
mod mapedit;
|
||||||
|
mod maps;
|
||||||
mod rgb;
|
mod rgb;
|
||||||
mod run;
|
mod run;
|
||||||
mod sprite;
|
mod sprite;
|
||||||
|
mod tilemap;
|
||||||
mod tileset;
|
mod tileset;
|
||||||
|
|
||||||
//todo: figure out how to not repeat all the lib.rs stuff :(
|
//todo: figure out how to not repeat all the lib.rs stuff :(
|
||||||
|
|
254
src/mapedit.rs
254
src/mapedit.rs
|
@ -4,22 +4,31 @@ use std::num::NonZeroU32;
|
||||||
use crate::gsa::Gsa;
|
use crate::gsa::Gsa;
|
||||||
use crate::gsa_render_to_screen::render_to_screen;
|
use crate::gsa_render_to_screen::render_to_screen;
|
||||||
use crate::gsa_render_to_screen::render_to_window;
|
use crate::gsa_render_to_screen::render_to_window;
|
||||||
|
use crate::maps::Maps;
|
||||||
use crate::sprite::Sprite;
|
use crate::sprite::Sprite;
|
||||||
|
use crate::tilemap::Tilemap;
|
||||||
use crate::tileset::*;
|
use crate::tileset::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use clap::crate_version;
|
use clap::crate_version;
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use winit::{
|
use winit::{
|
||||||
dpi::LogicalSize,
|
dpi::LogicalSize,
|
||||||
event::{Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
event::{Event, VirtualKeyCode, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
window::WindowBuilder,
|
window::WindowBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SPR_CURSOR: usize = 0x01;
|
const SPR_CURSOR: usize = 0x01;
|
||||||
const TILE_CURSOR: u16 = 0x7308;
|
const TILE_CURSOR: u16 = 0x7110;
|
||||||
const TILE_MARKER: u16 = 0x7309;
|
const TILE_MARKER: u16 = 0x7210;
|
||||||
const TILE_BG: u16 = 0x730a;
|
//const TILE_BG: u16 = 0x730a;
|
||||||
|
|
||||||
|
const BUT_SAVE: usize = 0;
|
||||||
|
const BUT_LAYER1: usize = 2;
|
||||||
|
const BUT_LAYER2: usize = 3;
|
||||||
|
const BUT_LAYER3: usize = 4;
|
||||||
|
const BUT_LAYERS: usize = 5;
|
||||||
|
const BUT_EXIT: usize = 7;
|
||||||
|
|
||||||
struct Surface<'a> {
|
struct Surface<'a> {
|
||||||
pub data: &'a mut [u8],
|
pub data: &'a mut [u8],
|
||||||
|
@ -40,12 +49,40 @@ impl<'a> Surface<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
Edit,
|
||||||
|
SelectTile,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_layer_state(gsa: &mut Gsa, gsa2: &mut Gsa, layer: usize, all: bool) {
|
||||||
|
gsa2.bgs[2].tiles[0][BUT_LAYER1] = if layer == 0 {0x7111} else {0x7011};
|
||||||
|
gsa2.bgs[2].tiles[0][BUT_LAYER2] = if layer == 1 {0x7112} else {0x7012};
|
||||||
|
gsa2.bgs[2].tiles[0][BUT_LAYER3] = if layer == 2 {0x7113} else {0x7013};
|
||||||
|
gsa2.bgs[2].tiles[0][BUT_LAYERS] = if all {0x7114} else {0x7014};
|
||||||
|
if all {
|
||||||
|
gsa.bgs[0].active = true;
|
||||||
|
gsa.bgs[1].active = true;
|
||||||
|
gsa.bgs[2].active = true;
|
||||||
|
} else {
|
||||||
|
gsa.bgs[0].active = layer == 0;
|
||||||
|
gsa.bgs[1].active = layer == 1;
|
||||||
|
gsa.bgs[2].active = layer == 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn run_mapedit() {
|
pub(crate) fn run_mapedit() {
|
||||||
println!("running map edit");
|
println!("running map edit");
|
||||||
|
|
||||||
let tileset_path = "examples/basic/gfx.gif";
|
let tileset_path = "examples/basic/gfx.gif";
|
||||||
let (tileset, palette) = load_tileset(&fs::read(tileset_path).unwrap());
|
let (tileset, palette) = load_tileset(&fs::read(tileset_path).unwrap());
|
||||||
|
|
||||||
|
let maps_path = "examples/basic/maps.dat";
|
||||||
|
let maps = if Path::new(maps_path).exists() {
|
||||||
|
postcard::from_bytes(&fs::read(maps_path).unwrap()).unwrap()
|
||||||
|
} else {
|
||||||
|
Maps::default()
|
||||||
|
};
|
||||||
|
|
||||||
let mut gsa = Gsa {
|
let mut gsa = Gsa {
|
||||||
sprites: [Sprite::default(); MAX_SPRITES],
|
sprites: [Sprite::default(); MAX_SPRITES],
|
||||||
palette,
|
palette,
|
||||||
|
@ -54,15 +91,25 @@ pub(crate) fn run_mapedit() {
|
||||||
pressed: 0,
|
pressed: 0,
|
||||||
released: 0,
|
released: 0,
|
||||||
down: 0,
|
down: 0,
|
||||||
|
maps,
|
||||||
};
|
};
|
||||||
|
|
||||||
gsa.reset_bgs();
|
gsa.reset_bgs();
|
||||||
gsa.reset_sprites();
|
gsa.reset_sprites();
|
||||||
|
|
||||||
|
if gsa.map_exists(1337) {
|
||||||
|
gsa.load_map(1337);
|
||||||
|
}
|
||||||
|
|
||||||
for i in 0..3 {
|
for i in 0..3 {
|
||||||
gsa.bgs[i].scroll = IVec2 { x: -16, y: 0 };
|
gsa.bgs[i].scroll = IVec2 {
|
||||||
|
x: -16 - 32,
|
||||||
|
y: -32,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
gsa.sprites[SPR_CURSOR].tile = TILE_CURSOR;
|
gsa.sprites[SPR_CURSOR].tile = TILE_CURSOR;
|
||||||
|
gsa.sprites[SPR_CURSOR].priority = 3;
|
||||||
let mut gsa2 = Gsa {
|
let mut gsa2 = Gsa {
|
||||||
sprites: [Sprite::default(); MAX_SPRITES],
|
sprites: [Sprite::default(); MAX_SPRITES],
|
||||||
palette,
|
palette,
|
||||||
|
@ -71,11 +118,15 @@ pub(crate) fn run_mapedit() {
|
||||||
pressed: 0,
|
pressed: 0,
|
||||||
released: 0,
|
released: 0,
|
||||||
down: 0,
|
down: 0,
|
||||||
|
maps: Maps::default(),
|
||||||
};
|
};
|
||||||
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 { x: -16, y: 0 };
|
gsa2.bgs[i].scroll = IVec2 {
|
||||||
|
x: -16 - 32,
|
||||||
|
y: -32,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
for y in 0..TILESET_SIZE {
|
for y in 0..TILESET_SIZE {
|
||||||
|
@ -89,10 +140,11 @@ pub(crate) fn run_mapedit() {
|
||||||
gsa2.bgs[2].size = IVec2 { x: 120, y: 68 }; //enough to cover 4k monitors? <_<
|
gsa2.bgs[2].size = IVec2 { x: 120, y: 68 }; //enough to cover 4k monitors? <_<
|
||||||
|
|
||||||
for y in 0..BACKGROUND_MAX_SIZE {
|
for y in 0..BACKGROUND_MAX_SIZE {
|
||||||
gsa2.bgs[2].tiles[0][y] = 0x7408;
|
gsa2.bgs[2].tiles[0][y] = 0x7010;
|
||||||
}
|
}
|
||||||
gsa2.bgs[2].tiles[0][0] = 0x7409;
|
gsa2.bgs[2].tiles[0][BUT_SAVE] = 0x7211;
|
||||||
gsa2.bgs[2].tiles[0][2] = 0x740a;
|
// layer buttons set up later
|
||||||
|
gsa2.bgs[2].tiles[0][BUT_EXIT] = 0x7212;
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let size = LogicalSize::new(1280, 720);
|
let size = LogicalSize::new(1280, 720);
|
||||||
|
@ -116,6 +168,10 @@ pub(crate) fn run_mapedit() {
|
||||||
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.bgs[1].tiles[0][0] = TILE_MARKER;
|
||||||
|
let mut state = State::Edit;
|
||||||
|
let mut current_layer = 0usize;
|
||||||
|
let mut all_layers = true;
|
||||||
|
update_layer_state(&mut gsa, &mut gsa2, current_layer, all_layers);
|
||||||
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;
|
||||||
let tile_pos = &mut tile_pos;
|
let tile_pos = &mut tile_pos;
|
||||||
|
@ -124,6 +180,9 @@ pub(crate) fn run_mapedit() {
|
||||||
let middle_down = &mut middle_down;
|
let middle_down = &mut middle_down;
|
||||||
let right_down = &mut right_down;
|
let right_down = &mut right_down;
|
||||||
let selected_tile = &mut selected_tile;
|
let selected_tile = &mut selected_tile;
|
||||||
|
let state = &mut state;
|
||||||
|
let current_layer = &mut current_layer;
|
||||||
|
let all_layers = &mut all_layers;
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent { event, .. } => match event {
|
Event::WindowEvent { event, .. } => match event {
|
||||||
|
@ -143,6 +202,7 @@ pub(crate) fn run_mapedit() {
|
||||||
gsa2.bgs[1].active = true;
|
gsa2.bgs[1].active = true;
|
||||||
gsa.sprites[SPR_CURSOR].tile = EMPTY_TILE;
|
gsa.sprites[SPR_CURSOR].tile = EMPTY_TILE;
|
||||||
gsa2.sprites[SPR_CURSOR].tile = TILE_CURSOR;
|
gsa2.sprites[SPR_CURSOR].tile = TILE_CURSOR;
|
||||||
|
*state = State::SelectTile;
|
||||||
}
|
}
|
||||||
(winit::event::ElementState::Released, VirtualKeyCode::LShift) => {
|
(winit::event::ElementState::Released, VirtualKeyCode::LShift) => {
|
||||||
gsa.bgs[0].active = true;
|
gsa.bgs[0].active = true;
|
||||||
|
@ -152,13 +212,46 @@ pub(crate) fn run_mapedit() {
|
||||||
gsa2.bgs[1].active = false;
|
gsa2.bgs[1].active = false;
|
||||||
gsa.sprites[SPR_CURSOR].tile = TILE_CURSOR;
|
gsa.sprites[SPR_CURSOR].tile = TILE_CURSOR;
|
||||||
gsa2.sprites[SPR_CURSOR].tile = EMPTY_TILE;
|
gsa2.sprites[SPR_CURSOR].tile = EMPTY_TILE;
|
||||||
|
*state = State::Edit;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WindowEvent::MouseInput { state, button, .. } => match (state, button) {
|
WindowEvent::MouseInput { state, button, .. } => match (state, button) {
|
||||||
(winit::event::ElementState::Pressed, winit::event::MouseButton::Left) => {
|
(winit::event::ElementState::Pressed, winit::event::MouseButton::Left) => {
|
||||||
*left_down = true;
|
if mouse_pos.x < 16 {
|
||||||
|
match (mouse_pos.y / 16) as usize {
|
||||||
|
BUT_SAVE => {
|
||||||
|
println!("saving");
|
||||||
|
gsa.maps.maps.insert(1337, [Tilemap::from_bg(&gsa.bgs[0]), Tilemap::from_bg(&gsa.bgs[1]), Tilemap::from_bg(&gsa.bgs[2])]);
|
||||||
|
fs::write(
|
||||||
|
maps_path,
|
||||||
|
postcard::to_allocvec(&gsa.maps).unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
BUT_LAYER1 => {
|
||||||
|
*current_layer = 0;
|
||||||
|
}
|
||||||
|
BUT_LAYER2 => {
|
||||||
|
*current_layer = 1;
|
||||||
|
}
|
||||||
|
BUT_LAYER3 => {
|
||||||
|
*current_layer = 2;
|
||||||
|
}
|
||||||
|
BUT_LAYERS => {
|
||||||
|
*all_layers = !*all_layers;
|
||||||
|
}
|
||||||
|
BUT_EXIT => {
|
||||||
|
println!("exit");
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
update_layer_state(&mut gsa, &mut gsa2, *current_layer, *all_layers);
|
||||||
|
} else {
|
||||||
|
*left_down = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(winit::event::ElementState::Released, winit::event::MouseButton::Left) => {
|
(winit::event::ElementState::Released, winit::event::MouseButton::Left) => {
|
||||||
*left_down = false;
|
*left_down = false;
|
||||||
|
@ -184,16 +277,20 @@ pub(crate) fn run_mapedit() {
|
||||||
};
|
};
|
||||||
let delta = new_pos - *mouse_pos;
|
let delta = new_pos - *mouse_pos;
|
||||||
if *middle_down {
|
if *middle_down {
|
||||||
if gsa.bgs[0].active {
|
match *state {
|
||||||
// normal mode
|
State::Edit => {
|
||||||
gsa.bgs[0].scroll -= delta;
|
// normal mode
|
||||||
gsa.bgs[1].scroll -= delta;
|
gsa.bgs[0].scroll -= delta;
|
||||||
gsa.bgs[2].scroll -= delta;
|
gsa.bgs[1].scroll -= delta;
|
||||||
} else {
|
gsa.bgs[2].scroll -= delta;
|
||||||
// tile select mode
|
}
|
||||||
gsa2.bgs[0].scroll -= delta;
|
State::SelectTile => {
|
||||||
gsa2.bgs[1].scroll -= delta;
|
// tile select mode
|
||||||
//gsa2.bgs[2].scroll -= delta;
|
gsa2.bgs[0].scroll -= delta;
|
||||||
|
gsa2.bgs[1].scroll -= delta;
|
||||||
|
//gsa2.bgs[2].scroll -= delta;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*mouse_pos = new_pos;
|
*mouse_pos = new_pos;
|
||||||
|
@ -214,42 +311,44 @@ pub(crate) fn run_mapedit() {
|
||||||
},
|
},
|
||||||
|
|
||||||
Event::MainEventsCleared => {
|
Event::MainEventsCleared => {
|
||||||
if gsa.bgs[0].active {
|
match *state {
|
||||||
// normal mode
|
State::Edit => {
|
||||||
if *left_down {
|
if *left_down {
|
||||||
if tile_pos.x >= 0
|
if tile_pos.x >= 0
|
||||||
&& tile_pos.y >= 0
|
&& tile_pos.y >= 0
|
||||||
&& 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
|
||||||
{
|
{
|
||||||
let tile = (selected_tile.x + (selected_tile.y << 8)) as u16;
|
let tile = (selected_tile.x + (selected_tile.y << 8)) as u16;
|
||||||
gsa.bgs[0].tiles[tile_pos.x as usize][tile_pos.y as usize] = tile;
|
gsa.bgs[*current_layer].tiles[tile_pos.x as usize][tile_pos.y as usize] = tile;
|
||||||
}
|
}
|
||||||
} else if *right_down {
|
} else if *right_down {
|
||||||
if tile_pos.x >= 0
|
if tile_pos.x >= 0
|
||||||
&& tile_pos.y >= 0
|
&& tile_pos.y >= 0
|
||||||
&& 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
|
||||||
{
|
{
|
||||||
gsa.bgs[0].tiles[tile_pos.x as usize][tile_pos.y as usize] = EMPTY_TILE;
|
gsa.bgs[*current_layer].tiles[tile_pos.x as usize][tile_pos.y as usize] =
|
||||||
|
EMPTY_TILE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
State::SelectTile => {
|
||||||
// tile select mode
|
if *left_down {
|
||||||
if *left_down {
|
if tile_pos2.x >= 0
|
||||||
if tile_pos2.x >= 0
|
&& tile_pos2.y >= 0
|
||||||
&& tile_pos2.y >= 0
|
&& 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.bgs[1].tiles[selected_tile.x as usize][selected_tile.y as usize] =
|
[selected_tile.y as usize] = EMPTY_TILE;
|
||||||
EMPTY_TILE;
|
*selected_tile = *tile_pos2;
|
||||||
*selected_tile = *tile_pos2;
|
gsa2.bgs[1].tiles[selected_tile.x as usize]
|
||||||
gsa2.bgs[1].tiles[selected_tile.x as usize][selected_tile.y as usize] =
|
[selected_tile.y as usize] = TILE_MARKER;
|
||||||
TILE_MARKER;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// render
|
// render
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
|
@ -272,31 +371,34 @@ pub(crate) fn run_mapedit() {
|
||||||
data: &mut screen_buffer,
|
data: &mut screen_buffer,
|
||||||
size: screen_size,
|
size: screen_size,
|
||||||
};
|
};
|
||||||
if gsa.bgs[0].active {
|
match *state {
|
||||||
let xs = -gsa.bgs[0].scroll.x - 1;
|
State::Edit => {
|
||||||
let ys = -gsa.bgs[0].scroll.y - 1;
|
let xs = -gsa.bgs[0].scroll.x - 1;
|
||||||
let xe = xs + gsa.bgs[0].size.x * TILE_SIZE as i32 + 1;
|
let ys = -gsa.bgs[0].scroll.y - 1;
|
||||||
let ye = ys + gsa.bgs[0].size.y * TILE_SIZE as i32 + 1;
|
let xe = xs + gsa.bgs[0].size.x * TILE_SIZE as i32 + 1;
|
||||||
if xs >= 16 && xs < screen_size.x {
|
let ye = ys + gsa.bgs[0].size.y * TILE_SIZE as i32 + 1;
|
||||||
let starty = (ys + 1).max(0);
|
if xs >= 16 && xs < screen_size.x {
|
||||||
let len = ye.min(screen_size.y) - starty;
|
let starty = (ys + 1).max(0);
|
||||||
screen.draw_vline(IVec2 { x: xs, y: starty }, len, 0xfc);
|
let len = ye.min(screen_size.y) - starty;
|
||||||
}
|
screen.draw_vline(IVec2 { x: xs, y: starty }, len, 0xfc);
|
||||||
if xe >= 16 && xe < screen_size.x {
|
}
|
||||||
let starty = (ys + 1).max(0);
|
if xe >= 16 && xe < screen_size.x {
|
||||||
let len = ye.min(screen_size.y) - starty;
|
let starty = (ys + 1).max(0);
|
||||||
screen.draw_vline(IVec2 { x: xe, y: starty }, len, 0xfc);
|
let len = ye.min(screen_size.y) - starty;
|
||||||
}
|
screen.draw_vline(IVec2 { x: xe, y: starty }, len, 0xfc);
|
||||||
if ys >= 0 && ys < screen_size.y {
|
}
|
||||||
let startx = (xs + 1).max(16);
|
if ys >= 0 && ys < screen_size.y {
|
||||||
let len = xe.min(screen_size.x) - startx;
|
let startx = (xs + 1).max(16);
|
||||||
screen.draw_hline(IVec2 { x: startx, y: ys }, len, 0xfc);
|
let len = xe.min(screen_size.x) - startx;
|
||||||
}
|
screen.draw_hline(IVec2 { x: startx, y: ys }, len, 0xfc);
|
||||||
if ye >= 0 && ye < screen_size.y {
|
}
|
||||||
let startx = (xs + 1).max(16);
|
if ye >= 0 && ye < screen_size.y {
|
||||||
let len = xe.min(screen_size.x) - startx;
|
let startx = (xs + 1).max(16);
|
||||||
screen.draw_hline(IVec2 { x: startx, y: ye }, len, 0xfc);
|
let len = xe.min(screen_size.x) - startx;
|
||||||
|
screen.draw_hline(IVec2 { x: startx, y: ye }, len, 0xfc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
render_to_window(
|
render_to_window(
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::tilemap::Tilemap;
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize, Serialize)]
|
||||||
|
pub(crate) struct Maps {
|
||||||
|
pub(crate) maps: HashMap<u16, [Tilemap; 3]>,
|
||||||
|
}
|
10
src/run.rs
10
src/run.rs
|
@ -1,5 +1,6 @@
|
||||||
use crate::buttons::{button_from_gilrs, button_from_scancode};
|
use crate::buttons::{button_from_gilrs, button_from_scancode};
|
||||||
use crate::gsa_render_to_screen::{render_to_screen, render_to_window};
|
use crate::gsa_render_to_screen::{render_to_screen, render_to_window};
|
||||||
|
use crate::maps::Maps;
|
||||||
use crate::tileset::load_tileset;
|
use crate::tileset::load_tileset;
|
||||||
use crate::{
|
use crate::{
|
||||||
Buttons, Gsa, Sprite, FONT_BOLD, MAX_SPRITES, SCREEN_HEIGHT, SCREEN_WIDTH, TRANSPARENT,
|
Buttons, Gsa, Sprite, FONT_BOLD, MAX_SPRITES, SCREEN_HEIGHT, SCREEN_WIDTH, TRANSPARENT,
|
||||||
|
@ -27,7 +28,12 @@ use winit::window::WindowBuilder;
|
||||||
macro_rules! run {
|
macro_rules! run {
|
||||||
($init: ident, $update: ident) => {
|
($init: ident, $update: ident) => {
|
||||||
fn main() {
|
fn main() {
|
||||||
run($init, $update, include_bytes!("gfx.gif"));
|
run(
|
||||||
|
$init,
|
||||||
|
$update,
|
||||||
|
include_bytes!("gfx.gif"),
|
||||||
|
include_bytes!("maps.dat"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -37,6 +43,7 @@ pub fn run<TGame: 'static>(
|
||||||
init_fn: fn(gsa: &mut Gsa) -> TGame,
|
init_fn: fn(gsa: &mut Gsa) -> TGame,
|
||||||
update_fn: fn(game: &mut TGame, gsa: &mut Gsa),
|
update_fn: fn(game: &mut TGame, gsa: &mut Gsa),
|
||||||
image_data: &[u8],
|
image_data: &[u8],
|
||||||
|
maps_data: &[u8],
|
||||||
) {
|
) {
|
||||||
let (tileset, palette) = load_tileset(image_data);
|
let (tileset, palette) = load_tileset(image_data);
|
||||||
|
|
||||||
|
@ -48,6 +55,7 @@ pub fn run<TGame: 'static>(
|
||||||
pressed: 0,
|
pressed: 0,
|
||||||
released: 0,
|
released: 0,
|
||||||
down: 0,
|
down: 0,
|
||||||
|
maps: postcard::from_bytes(maps_data).unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
gsa.reset_bgs();
|
gsa.reset_bgs();
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
use glam::IVec2;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::Background;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub(crate) struct Tilemap {
|
||||||
|
pub(crate) data: Vec<u16>,
|
||||||
|
pub(crate) size: IVec2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tilemap {
|
||||||
|
pub(crate) fn from_bg(bg: &Background) -> Self {
|
||||||
|
let mut data = vec![0u16; (bg.size.x * bg.size.y) as usize];
|
||||||
|
for y in 0..bg.size.y as usize {
|
||||||
|
for x in 0..bg.size.x as usize {
|
||||||
|
data[x + y * bg.size.x as usize] = bg.tiles[x][y];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
data,
|
||||||
|
size: bg.size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue