From a20bb4c9211a65227bbf674b2c923cff53fa6c58 Mon Sep 17 00:00:00 2001 From: dani <> Date: Fri, 11 Aug 2023 03:58:43 +0000 Subject: [PATCH] create map button in map edit --- examples/basic/gfx.gif | Bin 28446 -> 29133 bytes src/gsa.rs | 23 ++- src/mapedit.rs | 431 ++++++++++++++++++++++++++++++++--------- 3 files changed, 360 insertions(+), 94 deletions(-) diff --git a/examples/basic/gfx.gif b/examples/basic/gfx.gif index 47b5ae877a4f49a266c1bfde579bca5ec2426845..cec71effa79fc4abe3d6800eb7b291197ad102d1 100644 GIT binary patch delta 12006 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 bool { - self.maps.maps.contains_key(&map) + self.maps.maps.contains_key(&map) } /// Checks if any of given buttons currently held down diff --git a/src/mapedit.rs b/src/mapedit.rs index 3d1b373..ed1fa9b 100644 --- a/src/mapedit.rs +++ b/src/mapedit.rs @@ -11,6 +11,7 @@ use crate::tileset::*; use crate::*; use clap::crate_version; use glam::IVec2; +use winit::event::ElementState; use winit::{ dpi::LogicalSize, event::{Event, VirtualKeyCode, WindowEvent}, @@ -21,14 +22,28 @@ use winit::{ const SPR_CURSOR: usize = 0x01; const TILE_CURSOR: u16 = 0x7110; const TILE_MARKER: u16 = 0x7210; -//const TILE_BG: u16 = 0x730a; +const TILE_FRT: u16 = 0x7018; +const TILE_FRB: u16 = 0x7118; +const TILE_FRL: u16 = 0x7218; +const TILE_FRR: u16 = 0x7219; +const TILE_FRTL: u16 = 0x7019; +const TILE_FRTR: u16 = 0x701A; +const TILE_FRBL: u16 = 0x7119; +const TILE_FRBR: u16 = 0x711A; +const TILE_FRBG: u16 = 0x721A; +const TILE_INPUT: u16 = 0x7318; + +const TILE_BUT_YES: u16 = 0x7311; +const TILE_BUT_NO: u16 = 0x7312; +const TILE_BUT_CREATE: u16 = 0x7213; 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; +const BUT_CREATE: usize = 1; +const BUT_LAYER1: usize = 3; +const BUT_LAYER2: usize = 4; +const BUT_LAYER3: usize = 5; +const BUT_LAYERS: usize = 6; +const BUT_EXIT: usize = 8; struct Surface<'a> { pub data: &'a mut [u8], @@ -49,27 +64,165 @@ impl<'a> Surface<'a> { } } +#[derive(Copy, Clone)] enum State { Edit, SelectTile, + NewMapDialog, } -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; +fn key_to_num(key: VirtualKeyCode) -> u16 { + match key { + VirtualKeyCode::Key0 => 0x0, + VirtualKeyCode::Key1 => 0x1, + VirtualKeyCode::Key2 => 0x2, + VirtualKeyCode::Key3 => 0x3, + VirtualKeyCode::Key4 => 0x4, + VirtualKeyCode::Key5 => 0x5, + VirtualKeyCode::Key6 => 0x6, + VirtualKeyCode::Key7 => 0x7, + VirtualKeyCode::Key8 => 0x8, + VirtualKeyCode::Key9 => 0x9, + VirtualKeyCode::A => 0xa, + VirtualKeyCode::B => 0xb, + VirtualKeyCode::C => 0xc, + VirtualKeyCode::D => 0xd, + VirtualKeyCode::E => 0xe, + VirtualKeyCode::F => 0xf, + _ => 0x0, } } +impl Background { + fn draw_frame(&mut self, pos: IVec2, size: IVec2) { + let px1 = pos.x as usize; + let py1 = pos.y as usize; + let sx = size.x as usize; + let sy = size.y as usize; + let px2 = px1 + sx - 1; + let py2 = py1 + sy - 1; + + self.tiles[px1][py1] = TILE_FRTL; + self.tiles[px1][py2] = TILE_FRBL; + self.tiles[px2][py1] = TILE_FRTR; + self.tiles[px2][py2] = TILE_FRBR; + + for x in (px1 + 1)..px2 { + self.tiles[x][py1] = TILE_FRT; + self.tiles[x][py2] = TILE_FRB; + } + + for y in (py1 + 1)..py2 { + self.tiles[px1][y] = TILE_FRL; + self.tiles[px2][y] = TILE_FRR; + } + for x in (px1 + 1)..px2 { + for y in (py1 + 1)..py2 { + self.tiles[x][y] = TILE_FRBG; + } + } + } +} + +fn draw_input_window(gsa: &mut Gsa, pos: IVec2, caption: &str) { + gsa.bgs[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.bgs[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.bgs[2].tiles[pos.x as usize + 5][pos.y as usize + 3] = TILE_BUT_NO; + gsa.write_string( + 3, + IVec2 { + x: pos.x * 2 + 2, + y: pos.y * 2 + 1, + }, + caption, + ); + gsa.write_string( + 3, + IVec2 { + x: pos.x * 2 + 3, + y: pos.y * 2 + 3, + }, + "ID:0000", + ); +} + +fn update_input_window(gsa: &mut Gsa, pos: IVec2, val: u16) { + gsa.write_string( + 3, + IVec2 { + x: pos.x * 2 + 6, + y: pos.y * 2 + 3, + }, + &format!("{:04x}", val), + ); +} + +fn set_state(state: State, gsa1: &mut Gsa, gsa2: &mut Gsa, current_layer: usize, all_layers: bool) { + match state { + State::Edit => { + //update editing layers + if all_layers { + gsa1.bgs[0].active = true; + gsa1.bgs[1].active = true; + gsa1.bgs[2].active = true; + } else { + gsa1.bgs[0].active = current_layer == 0; + gsa1.bgs[1].active = current_layer == 1; + gsa1.bgs[2].active = current_layer == 2; + } + gsa2.clear_bg(2); + gsa2.clear_bg(3); + draw_toolbar(gsa1, gsa2, current_layer, all_layers); + + gsa2.bgs[0].active = false; + gsa2.bgs[1].active = false; + gsa1.sprites[SPR_CURSOR].priority = 3; + gsa1.sprites[SPR_CURSOR].tile = TILE_CURSOR; + gsa2.sprites[SPR_CURSOR].tile = EMPTY_TILE; + } + State::SelectTile => { + draw_toolbar(gsa1, gsa2, current_layer, all_layers); + gsa1.bgs[0].active = false; + gsa1.bgs[1].active = false; + gsa1.bgs[2].active = false; + gsa2.bgs[0].active = true; + gsa2.bgs[1].active = true; + gsa1.sprites[SPR_CURSOR].tile = EMPTY_TILE; + gsa2.sprites[SPR_CURSOR].tile = TILE_CURSOR; + } + State::NewMapDialog => { + gsa1.bgs[0].active = false; + gsa1.bgs[1].active = false; + gsa1.bgs[2].active = false; + gsa2.bgs[0].active = false; + gsa2.bgs[1].active = false; + gsa1.sprites[SPR_CURSOR].tile = EMPTY_TILE; + gsa2.sprites[SPR_CURSOR].tile = EMPTY_TILE; + 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) { + for y in 0..BACKGROUND_MAX_SIZE { + gsa2.bgs[2].tiles[0][y] = 0x7010; + } + gsa2.bgs[2].tiles[0][BUT_SAVE] = 0x7211; + gsa2.bgs[2].tiles[0][BUT_CREATE] = TILE_BUT_CREATE; + gsa2.bgs[2].tiles[0][BUT_EXIT] = 0x7212; + + //layer buttons + gsa2.bgs[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.bgs[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.bgs[2].size = IVec2 { x: 120, y: 68 }; //enough to cover 4k monitors? <_< + gsa2.bgs[3].size = IVec2 { x: 240, y: 136 }; +} + pub(crate) fn run_mapedit() { println!("running map edit"); @@ -83,7 +236,7 @@ pub(crate) fn run_mapedit() { Maps::default() }; - let mut gsa = Gsa { + let mut gsa1 = Gsa { sprites: [Sprite::default(); MAX_SPRITES], palette, bgs: Default::default(), @@ -94,22 +247,20 @@ pub(crate) fn run_mapedit() { maps, }; - gsa.reset_bgs(); - gsa.reset_sprites(); + gsa1.reset_bgs(); + gsa1.reset_sprites(); - if gsa.map_exists(1337) { - gsa.load_map(1337); + if gsa1.map_exists(0) { + gsa1.load_map(0); } for i in 0..3 { - gsa.bgs[i].scroll = IVec2 { + gsa1.bgs[i].scroll = IVec2 { x: -16 - 32, y: -32, }; } - gsa.sprites[SPR_CURSOR].tile = TILE_CURSOR; - gsa.sprites[SPR_CURSOR].priority = 3; let mut gsa2 = Gsa { sprites: [Sprite::default(); MAX_SPRITES], palette, @@ -134,17 +285,7 @@ pub(crate) fn run_mapedit() { gsa2.bgs[0].tiles[x][y] = (x + (y << 8)) as u16; } } - gsa2.bgs[0].active = false; - gsa2.bgs[1].active = false; - gsa2.bgs[2].active = true; - gsa2.bgs[2].size = IVec2 { x: 120, y: 68 }; //enough to cover 4k monitors? <_< - - for y in 0..BACKGROUND_MAX_SIZE { - gsa2.bgs[2].tiles[0][y] = 0x7010; - } - gsa2.bgs[2].tiles[0][BUT_SAVE] = 0x7211; - // layer buttons set up later - gsa2.bgs[2].tiles[0][BUT_EXIT] = 0x7212; + //draw_input_window(&mut gsa2, IVec2 { x: 5, y: 3 }, "Create Map"); let event_loop = EventLoop::new(); let size = LogicalSize::new(1280, 720); @@ -168,10 +309,13 @@ pub(crate) fn run_mapedit() { let mut right_down = false; let mut selected_tile = IVec2::ZERO; 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); + let mut state = State::Edit; + let mut input_buf = 0u16; + let mut current_map = 0; + set_state(State::Edit, &mut gsa1, &mut gsa2, current_layer, all_layers); + event_loop.run(move |event, _, control_flow| { let mouse_pos = &mut mouse_pos; let tile_pos = &mut tile_pos; @@ -181,76 +325,183 @@ pub(crate) fn run_mapedit() { let right_down = &mut right_down; let selected_tile = &mut selected_tile; let state = &mut state; - let current_layer = &mut current_layer; - let all_layers = &mut all_layers; + let current_layer = &mut current_layer; + let all_layers = &mut all_layers; + let input_buf = &mut input_buf; + let current_map = &mut current_map; match event { Event::WindowEvent { event, .. } => match event { WindowEvent::KeyboardInput { input, .. } => { - match ( - input.state, - input.virtual_keycode.unwrap_or(VirtualKeyCode::F24), - ) { - (winit::event::ElementState::Pressed, VirtualKeyCode::Escape) => { - *control_flow = ControlFlow::Exit; + let vk = input.virtual_keycode.unwrap_or(VirtualKeyCode::F24); + match vk { + VirtualKeyCode::Escape => { + //*control_flow = ControlFlow::Exit; } - (winit::event::ElementState::Pressed, VirtualKeyCode::LShift) => { - gsa.bgs[0].active = false; - gsa.bgs[1].active = false; - gsa.bgs[2].active = false; - gsa2.bgs[0].active = true; - gsa2.bgs[1].active = true; - gsa.sprites[SPR_CURSOR].tile = EMPTY_TILE; - gsa2.sprites[SPR_CURSOR].tile = TILE_CURSOR; - *state = State::SelectTile; + VirtualKeyCode::LShift => { + if input.state == ElementState::Pressed { + *state = State::SelectTile; + set_state( + *state, + &mut gsa1, + &mut gsa2, + *current_layer, + *all_layers, + ); + } else { + *state = State::Edit; + set_state( + *state, + &mut gsa1, + &mut gsa2, + *current_layer, + *all_layers, + ); + } } - (winit::event::ElementState::Released, VirtualKeyCode::LShift) => { - gsa.bgs[0].active = true; - gsa.bgs[1].active = true; - gsa.bgs[2].active = true; - gsa2.bgs[0].active = false; - gsa2.bgs[1].active = false; - gsa.sprites[SPR_CURSOR].tile = TILE_CURSOR; - gsa2.sprites[SPR_CURSOR].tile = EMPTY_TILE; - *state = State::Edit; + VirtualKeyCode::Key0 + | VirtualKeyCode::Key1 + | VirtualKeyCode::Key2 + | VirtualKeyCode::Key3 + | VirtualKeyCode::Key4 + | VirtualKeyCode::Key5 + | VirtualKeyCode::Key6 + | VirtualKeyCode::Key7 + | VirtualKeyCode::Key8 + | VirtualKeyCode::Key9 + | VirtualKeyCode::A + | VirtualKeyCode::B + | VirtualKeyCode::C + | VirtualKeyCode::D + | VirtualKeyCode::E + | VirtualKeyCode::F => { + if input.state == ElementState::Pressed { + *input_buf = ((*input_buf & 0xFFF) << 4) | key_to_num(vk); + update_input_window(&mut gsa2, IVec2 { x: 15, y: 9 }, *input_buf); + } } _ => {} } } - WindowEvent::MouseInput { state, button, .. } => match (state, button) { + WindowEvent::MouseInput { + state: but_state, + button, + .. + } => match (but_state, button) { (winit::event::ElementState::Pressed, winit::event::MouseButton::Left) => { 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])]); + gsa1.store_map(*current_map); fs::write( maps_path, - postcard::to_allocvec(&gsa.maps).unwrap(), + postcard::to_allocvec(&gsa1.maps).unwrap(), ) .unwrap(); } + BUT_CREATE => { + *state = State::NewMapDialog; + *input_buf = *current_map; + set_state( + *state, + &mut gsa1, + &mut gsa2, + *current_layer, + *all_layers, + ); + update_input_window( + &mut gsa2, + IVec2 { x: 15, y: 9 }, + *input_buf, + ); + } BUT_LAYER1 => { *current_layer = 0; + set_state( + *state, + &mut gsa1, + &mut gsa2, + *current_layer, + *all_layers, + ); } BUT_LAYER2 => { *current_layer = 1; + set_state( + *state, + &mut gsa1, + &mut gsa2, + *current_layer, + *all_layers, + ); } BUT_LAYER3 => { *current_layer = 2; + set_state( + *state, + &mut gsa1, + &mut gsa2, + *current_layer, + *all_layers, + ); + } + BUT_LAYERS => { + *all_layers = !*all_layers; + set_state( + *state, + &mut gsa1, + &mut gsa2, + *current_layer, + *all_layers, + ); } - 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; + match *state { + State::NewMapDialog => { + //todo: not hardcode? + if mouse_pos.y / 16 == 12 { + if mouse_pos.x / 16 == 16 { + println!("yes"); + gsa1.store_map(*current_map); + *current_map = *input_buf; + if gsa1.map_exists(*current_map) { + gsa1.load_map(*current_map); + } else { + //todo: not reset scrolling + gsa1.reset_bgs(); + } + *state = State::Edit; + set_state( + *state, + &mut gsa1, + &mut gsa2, + *current_layer, + *all_layers, + ); + } else if mouse_pos.x / 16 == 20 { + println!("no"); + *state = State::Edit; + set_state( + *state, + &mut gsa1, + &mut gsa2, + *current_layer, + *all_layers, + ); + } + } + } + _ => { + *left_down = true; + } + } } } (winit::event::ElementState::Released, winit::event::MouseButton::Left) => { @@ -280,9 +531,9 @@ pub(crate) fn run_mapedit() { match *state { State::Edit => { // normal mode - gsa.bgs[0].scroll -= delta; - gsa.bgs[1].scroll -= delta; - gsa.bgs[2].scroll -= delta; + gsa1.bgs[0].scroll -= delta; + gsa1.bgs[1].scroll -= delta; + gsa1.bgs[2].scroll -= delta; } State::SelectTile => { // tile select mode @@ -295,16 +546,16 @@ pub(crate) fn run_mapedit() { } *mouse_pos = new_pos; *tile_pos = IVec2 { - x: (new_pos.x + gsa.bgs[0].scroll.x).div_euclid(TILE_SIZE as i32), - y: (new_pos.y + gsa.bgs[0].scroll.y).div_euclid(TILE_SIZE as i32), + x: (new_pos.x + gsa1.bgs[0].scroll.x).div_euclid(TILE_SIZE as i32), + y: (new_pos.y + gsa1.bgs[0].scroll.y).div_euclid(TILE_SIZE as i32), }; *tile_pos2 = IVec2 { x: (new_pos.x + gsa2.bgs[0].scroll.x).div_euclid(TILE_SIZE as i32), y: (new_pos.y + gsa2.bgs[0].scroll.y).div_euclid(TILE_SIZE as i32), }; - let cursor_pos = *tile_pos * TILE_SIZE as i32 - gsa.bgs[0].scroll; + let cursor_pos = *tile_pos * TILE_SIZE as i32 - gsa1.bgs[0].scroll; let cursor_pos2 = *tile_pos2 * TILE_SIZE as i32 - gsa2.bgs[0].scroll; - gsa.sprites[SPR_CURSOR].pos = cursor_pos; + gsa1.sprites[SPR_CURSOR].pos = cursor_pos; gsa2.sprites[SPR_CURSOR].pos = cursor_pos2; } _ => {} @@ -320,7 +571,8 @@ pub(crate) fn run_mapedit() { && tile_pos.y < BACKGROUND_MAX_SIZE as i32 { let tile = (selected_tile.x + (selected_tile.y << 8)) as u16; - gsa.bgs[*current_layer].tiles[tile_pos.x as usize][tile_pos.y as usize] = tile; + gsa1.bgs[*current_layer].tiles[tile_pos.x as usize] + [tile_pos.y as usize] = tile; } } else if *right_down { if tile_pos.x >= 0 @@ -328,8 +580,8 @@ pub(crate) fn run_mapedit() { && tile_pos.x < BACKGROUND_MAX_SIZE as i32 && tile_pos.y < BACKGROUND_MAX_SIZE as i32 { - gsa.bgs[*current_layer].tiles[tile_pos.x as usize][tile_pos.y as usize] = - EMPTY_TILE; + gsa1.bgs[*current_layer].tiles[tile_pos.x as usize] + [tile_pos.y as usize] = EMPTY_TILE; } } } @@ -348,6 +600,7 @@ pub(crate) fn run_mapedit() { } } } + _ => {} }; // render @@ -365,7 +618,7 @@ pub(crate) fn run_mapedit() { x: size.width as i32 / 2, y: size.height as i32 / 2, }; - render_to_screen(&mut screen_buffer, &gsa, &tileset, screen_size); + render_to_screen(&mut screen_buffer, &gsa1, &tileset, screen_size); render_to_screen(&mut screen_buffer, &gsa2, &tileset, screen_size); let mut screen = Surface { data: &mut screen_buffer, @@ -373,10 +626,10 @@ pub(crate) fn run_mapedit() { }; match *state { State::Edit => { - let xs = -gsa.bgs[0].scroll.x - 1; - let ys = -gsa.bgs[0].scroll.y - 1; - let xe = xs + gsa.bgs[0].size.x * TILE_SIZE as i32 + 1; - let ye = ys + gsa.bgs[0].size.y * TILE_SIZE as i32 + 1; + let xs = -gsa1.bgs[0].scroll.x - 1; + let ys = -gsa1.bgs[0].scroll.y - 1; + let xe = xs + gsa1.bgs[0].size.x * TILE_SIZE as i32 + 1; + let ye = ys + gsa1.bgs[0].size.y * TILE_SIZE as i32 + 1; if xs >= 16 && xs < screen_size.x { let starty = (ys + 1).max(0); let len = ye.min(screen_size.y) - starty;