mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 16:21:33 +11:00
Something that seems like it is close to working
This commit is contained in:
parent
472875edac
commit
f785d65057
|
@ -587,7 +587,7 @@ impl<I: FixedWidthUnsignedInteger, const N: usize> From<Vector2D<I>> for Vector2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct Rect<T: Number> {
|
pub struct Rect<T: Number> {
|
||||||
pub position: Vector2D<T>,
|
pub position: Vector2D<T>,
|
||||||
pub size: Vector2D<T>,
|
pub size: Vector2D<T>,
|
||||||
|
@ -657,10 +657,10 @@ impl<T: FixedWidthUnsignedInteger> Rect<T> {
|
||||||
let mut y = self.position.y;
|
let mut y = self.position.y;
|
||||||
core::iter::from_fn(move || {
|
core::iter::from_fn(move || {
|
||||||
x = x + T::one();
|
x = x + T::one();
|
||||||
if x > self.position.x + self.size.x {
|
if x >= self.position.x + self.size.x {
|
||||||
x = self.position.x;
|
x = self.position.x;
|
||||||
y = y + T::one();
|
y = y + T::one();
|
||||||
if y > self.position.y + self.size.y {
|
if y >= self.position.y + self.size.y {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use agb::display::example_logo;
|
||||||
fn main(mut gba: agb::Gba) -> ! {
|
fn main(mut gba: agb::Gba) -> ! {
|
||||||
let mut gfx = gba.display.video.tiled0();
|
let mut gfx = gba.display.video.tiled0();
|
||||||
|
|
||||||
let mut map = gfx.background();
|
let mut map = gfx.background(agb::display::Priority::P0);
|
||||||
let mut vram = gfx.vram;
|
let mut vram = gfx.vram;
|
||||||
|
|
||||||
example_logo::display_logo(&mut map, &mut vram);
|
example_logo::display_logo(&mut map, &mut vram);
|
||||||
|
|
|
@ -19,7 +19,7 @@ struct BackCosines {
|
||||||
fn main(mut gba: agb::Gba) -> ! {
|
fn main(mut gba: agb::Gba) -> ! {
|
||||||
let mut gfx = gba.display.video.tiled0();
|
let mut gfx = gba.display.video.tiled0();
|
||||||
|
|
||||||
let mut background = gfx.background();
|
let mut background = gfx.background(agb::display::Priority::P0);
|
||||||
|
|
||||||
example_logo::display_logo(&mut background, &mut gfx.vram);
|
example_logo::display_logo(&mut background, &mut gfx.vram);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use alloc::vec;
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
use alloc::{boxed::Box, vec};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fixnum::Vector2D,
|
display,
|
||||||
|
fixnum::{Rect, Vector2D},
|
||||||
memory_mapped::{MemoryMapped, MemoryMapped1DArray},
|
memory_mapped::{MemoryMapped, MemoryMapped1DArray},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -267,14 +268,14 @@ pub struct RegularMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RegularMap {
|
impl RegularMap {
|
||||||
fn new(background_id: u8, screenblock: u8) -> Self {
|
fn new(background_id: u8, screenblock: u8, priority: Priority) -> Self {
|
||||||
Self {
|
Self {
|
||||||
background_id,
|
background_id,
|
||||||
|
|
||||||
screenblock,
|
screenblock,
|
||||||
x_scroll: 0,
|
x_scroll: 0,
|
||||||
y_scroll: 0,
|
y_scroll: 0,
|
||||||
priority: Priority::P0,
|
priority,
|
||||||
|
|
||||||
tiles: [Tile::default(); 32 * 32],
|
tiles: [Tile::default(); 32 * 32],
|
||||||
tiles_dirty: true,
|
tiles_dirty: true,
|
||||||
|
@ -335,13 +336,35 @@ impl RegularMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
let screenblock_memory = self.screenblock_memory();
|
let screenblock_memory = self.screenblock_memory();
|
||||||
for (i, tile) in self.tiles.iter().enumerate() {
|
|
||||||
screenblock_memory.set(i, tile.0);
|
let scroll_pos = self.get_scroll_pos();
|
||||||
|
let x_scroll = scroll_pos.x % display::WIDTH as u16;
|
||||||
|
let y_scroll = scroll_pos.y % display::HEIGHT as u16;
|
||||||
|
let start_x = x_scroll / 8;
|
||||||
|
let end_x = (x_scroll + display::WIDTH as u16 + 8 - 1) / 8; // divide by 8 rounding up
|
||||||
|
|
||||||
|
let start_y = y_scroll / 8;
|
||||||
|
let end_y = (y_scroll + display::HEIGHT as u16 + 8 - 1) / 8;
|
||||||
|
|
||||||
|
for y in start_y..end_y {
|
||||||
|
for x in start_x..end_x {
|
||||||
|
let id = y.rem_euclid(32) * 32 + x.rem_euclid(32);
|
||||||
|
screenblock_memory.set(id as usize, self.tiles[id as usize].0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tiles_dirty = false;
|
self.tiles_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_scroll_pos(&mut self, pos: Vector2D<u16>) {
|
||||||
|
self.x_scroll = pos.x;
|
||||||
|
self.y_scroll = pos.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_scroll_pos(&self) -> Vector2D<u16> {
|
||||||
|
(self.x_scroll, self.y_scroll).into()
|
||||||
|
}
|
||||||
|
|
||||||
const fn bg_control_register(&self) -> MemoryMapped<u16> {
|
const fn bg_control_register(&self) -> MemoryMapped<u16> {
|
||||||
unsafe { MemoryMapped::new(0x0400_0008 + 2 * self.background_id as usize) }
|
unsafe { MemoryMapped::new(0x0400_0008 + 2 * self.background_id as usize) }
|
||||||
}
|
}
|
||||||
|
@ -359,6 +382,174 @@ impl RegularMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct InfiniteScrolledMap {
|
||||||
|
map: RegularMap,
|
||||||
|
get_tile: Box<dyn Fn(Vector2D<i32>) -> (TileSetReference, TileSetting)>,
|
||||||
|
|
||||||
|
current_pos: Vector2D<i32>,
|
||||||
|
offset: Vector2D<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InfiniteScrolledMap {
|
||||||
|
pub fn new(
|
||||||
|
map: RegularMap,
|
||||||
|
get_tile: Box<dyn Fn(Vector2D<i32>) -> (TileSetReference, TileSetting)>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
map,
|
||||||
|
get_tile,
|
||||||
|
current_pos: (0, 0).into(),
|
||||||
|
offset: (0, 0).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(&mut self, vram: &mut VRamManager, pos: Vector2D<i32>) {
|
||||||
|
self.current_pos = pos;
|
||||||
|
|
||||||
|
let x_start = div_floor(self.current_pos.x, 8);
|
||||||
|
let y_start = div_floor(self.current_pos.y, 8);
|
||||||
|
|
||||||
|
let x_end = div_ceil(self.current_pos.x + display::WIDTH, 8);
|
||||||
|
let y_end = div_ceil(self.current_pos.y + display::HEIGHT, 8);
|
||||||
|
|
||||||
|
for (y_idx, y) in (y_start..y_end).enumerate() {
|
||||||
|
for (x_idx, x) in (x_start..x_end).enumerate() {
|
||||||
|
let pos = (x, y).into();
|
||||||
|
let (tile_set_ref, tile_setting) = (self.get_tile)(pos);
|
||||||
|
|
||||||
|
self.map.set_tile(
|
||||||
|
vram,
|
||||||
|
(x_idx as u16, y_idx as u16).into(),
|
||||||
|
tile_set_ref,
|
||||||
|
tile_setting,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let offset = self.current_pos - (x_start * 8, y_start * 8).into();
|
||||||
|
let offset_scroll = (
|
||||||
|
if offset.x < 0 {
|
||||||
|
(offset.x + 32 * 8) as u16
|
||||||
|
} else {
|
||||||
|
offset.x as u16
|
||||||
|
},
|
||||||
|
if offset.y < 0 {
|
||||||
|
(offset.y + 32 * 8) as u16
|
||||||
|
} else {
|
||||||
|
offset.y as u16
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into();
|
||||||
|
|
||||||
|
self.map.set_scroll_pos(offset_scroll);
|
||||||
|
self.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_pos(&mut self, vram: &mut VRamManager, new_pos: Vector2D<i32>) {
|
||||||
|
let old_pos = self.current_pos;
|
||||||
|
|
||||||
|
let difference = new_pos - old_pos;
|
||||||
|
|
||||||
|
if difference.x.abs() > 8 || difference.y.abs() > 8 {
|
||||||
|
self.init(vram, new_pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let is_new_y_mod_8 = new_pos.y % 8 == 0;
|
||||||
|
let is_new_x_mod_8 = new_pos.x % 8 == 0;
|
||||||
|
|
||||||
|
let top_bottom_rect: Rect<i32> = {
|
||||||
|
let top_bottom_height = difference.y.signum();
|
||||||
|
let new_tile_y = if top_bottom_height > 0 {
|
||||||
|
div_ceil(new_pos.y, 8) + if is_new_y_mod_8 { 20 } else { 22 }
|
||||||
|
} else {
|
||||||
|
div_floor(new_pos.y, 8)
|
||||||
|
};
|
||||||
|
|
||||||
|
Rect::new(
|
||||||
|
(div_floor(new_pos.x, 8), new_tile_y).into(),
|
||||||
|
(
|
||||||
|
if is_new_x_mod_8 { 30 } else { 32 },
|
||||||
|
top_bottom_height.abs(),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let left_right_rect: Rect<i32> = {
|
||||||
|
let left_right_width = difference.x.signum();
|
||||||
|
let new_tile_x = if left_right_width > 0 {
|
||||||
|
div_ceil(new_pos.x, 8) + if is_new_x_mod_8 { 30 } else { 32 }
|
||||||
|
} else {
|
||||||
|
div_floor(new_pos.x, 8)
|
||||||
|
};
|
||||||
|
|
||||||
|
Rect::new(
|
||||||
|
(new_tile_x, div_floor(new_pos.y, 8)).into(),
|
||||||
|
(left_right_width.abs(), if is_new_y_mod_8 { 20 } else { 22 }).into(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
self.offset += difference;
|
||||||
|
self.current_pos = new_pos;
|
||||||
|
let offset_block = self.offset / 8;
|
||||||
|
|
||||||
|
for (x, y) in top_bottom_rect.iter().chain(left_right_rect.iter()) {
|
||||||
|
let (tileset_ref, tile_setting) = (self.get_tile)((x, y).into());
|
||||||
|
|
||||||
|
let tile_pos = (
|
||||||
|
(x + offset_block.x).rem_euclid(32) as u16,
|
||||||
|
(y + offset_block.y).rem_euclid(32) as u16,
|
||||||
|
)
|
||||||
|
.into();
|
||||||
|
|
||||||
|
self.map.set_tile(vram, tile_pos, tileset_ref, tile_setting)
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_scroll = self.map.get_scroll_pos();
|
||||||
|
|
||||||
|
let new_scroll = (
|
||||||
|
(current_scroll.x as i32 + difference.x).rem_euclid(32 * 8) as u16,
|
||||||
|
(current_scroll.y as i32 + difference.y).rem_euclid(32 * 8) as u16,
|
||||||
|
)
|
||||||
|
.into();
|
||||||
|
|
||||||
|
self.map.set_scroll_pos(new_scroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn show(&mut self) {
|
||||||
|
self.map.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hide(&mut self) {
|
||||||
|
self.map.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn commit(&mut self) {
|
||||||
|
self.map.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn div_floor(x: i32, y: i32) -> i32 {
|
||||||
|
if x > 0 && y < 0 {
|
||||||
|
(x - 1) / y - 1
|
||||||
|
} else if x < 0 && y > 0 {
|
||||||
|
(x + 1) / y - 1
|
||||||
|
} else {
|
||||||
|
x / y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn div_ceil(x: i32, y: i32) -> i32 {
|
||||||
|
if x > 0 && y > 0 {
|
||||||
|
(x - 1) / y + 1
|
||||||
|
} else if x < 0 && y < 0 {
|
||||||
|
(x + 1) / y + 1
|
||||||
|
} else {
|
||||||
|
x / y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Tiled0<'a> {
|
pub struct Tiled0<'a> {
|
||||||
num_regular: u8,
|
num_regular: u8,
|
||||||
next_screenblock: u8,
|
next_screenblock: u8,
|
||||||
|
@ -379,12 +570,12 @@ impl Tiled0<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn background(&mut self) -> RegularMap {
|
pub fn background(&mut self, priority: Priority) -> RegularMap {
|
||||||
if self.num_regular == 4 {
|
if self.num_regular == 4 {
|
||||||
panic!("Can only create 4 backgrounds");
|
panic!("Can only create 4 backgrounds");
|
||||||
}
|
}
|
||||||
|
|
||||||
let bg = RegularMap::new(self.num_regular, self.next_screenblock);
|
let bg = RegularMap::new(self.num_regular, self.next_screenblock, priority);
|
||||||
|
|
||||||
self.num_regular += 1;
|
self.num_regular += 1;
|
||||||
self.next_screenblock += 1;
|
self.next_screenblock += 1;
|
||||||
|
|
|
@ -35,7 +35,7 @@ mod tests {
|
||||||
fn logo_display(gba: &mut crate::Gba) {
|
fn logo_display(gba: &mut crate::Gba) {
|
||||||
let mut gfx = gba.display.video.tiled0();
|
let mut gfx = gba.display.video.tiled0();
|
||||||
|
|
||||||
let mut map = gfx.background();
|
let mut map = gfx.background(crate::display::Priority::P0);
|
||||||
|
|
||||||
display_logo(&mut map, &mut gfx.vram);
|
display_logo(&mut map, &mut gfx.vram);
|
||||||
|
|
||||||
|
|
43
examples/the-purple-night/Cargo.lock
generated
43
examples/the-purple-night/Cargo.lock
generated
|
@ -24,6 +24,7 @@ dependencies = [
|
||||||
"agb_sound_converter",
|
"agb_sound_converter",
|
||||||
"bare-metal",
|
"bare-metal",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -65,6 +66,17 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -94,9 +106,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.7.3"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f"
|
checksum = "0e851ca7c24871e7336801608a4797d7376545b6928a10d32d75685687141ead"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
|
@ -160,6 +172,15 @@ dependencies = [
|
||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hound"
|
name = "hound"
|
||||||
version = "3.4.0"
|
version = "3.4.0"
|
||||||
|
@ -250,10 +271,16 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "png"
|
name = "once_cell"
|
||||||
version = "0.17.4"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02cd7d51cea7e2fa6bbcb8af5fbcad15b871451bfc2d20ed72dff2f4ae072a84"
|
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "png"
|
||||||
|
version = "0.17.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
|
@ -394,6 +421,12 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.10.2+wasi-snapshot-preview1"
|
version = "0.10.2+wasi-snapshot-preview1"
|
||||||
|
|
|
@ -45,8 +45,8 @@ fn main() {
|
||||||
pub const CLOUD_MAP: &[u16] = &[#(#cloud_tiles),*];
|
pub const CLOUD_MAP: &[u16] = &[#(#cloud_tiles),*];
|
||||||
pub const BACKGROUND_MAP: &[u16] = &[#(#background_tiles),*];
|
pub const BACKGROUND_MAP: &[u16] = &[#(#background_tiles),*];
|
||||||
pub const FOREGROUND_MAP: &[u16] = &[#(#foreground_tiles),*];
|
pub const FOREGROUND_MAP: &[u16] = &[#(#foreground_tiles),*];
|
||||||
pub const WIDTH: u32 = #width;
|
pub const WIDTH: i32 = #width as i32;
|
||||||
pub const HEIGHT: u32 = #height;
|
pub const HEIGHT: i32 = #height as i32;
|
||||||
|
|
||||||
pub const SLIME_SPAWNS_X: &[u16] = &[#(#slimes_x),*];
|
pub const SLIME_SPAWNS_X: &[u16] = &[#(#slimes_x),*];
|
||||||
pub const SLIME_SPAWNS_Y: &[u16] = &[#(#slimes_y),*];
|
pub const SLIME_SPAWNS_Y: &[u16] = &[#(#slimes_y),*];
|
||||||
|
|
|
@ -8,13 +8,13 @@ mod sfx;
|
||||||
|
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
|
|
||||||
use rng::get_random;
|
use rng::get_random;
|
||||||
|
|
||||||
use agb::{
|
use agb::{
|
||||||
display::{
|
display::{
|
||||||
background::{BackgroundDistributor, BackgroundRegular},
|
background::{InfiniteScrolledMap, TileFormat, TileSet, TileSetting, VRamManager},
|
||||||
object::{ObjectControl, ObjectStandard},
|
object::{ObjectControl, ObjectStandard},
|
||||||
Priority, HEIGHT, WIDTH,
|
Priority, HEIGHT, WIDTH,
|
||||||
},
|
},
|
||||||
|
@ -29,9 +29,9 @@ agb::include_gfx!("gfx/background.toml");
|
||||||
type Number = FixedNum<8>;
|
type Number = FixedNum<8>;
|
||||||
|
|
||||||
struct Level {
|
struct Level {
|
||||||
background: BackgroundRegular<'static>,
|
background: InfiniteScrolledMap,
|
||||||
foreground: BackgroundRegular<'static>,
|
foreground: InfiniteScrolledMap,
|
||||||
clouds: BackgroundRegular<'static>,
|
clouds: InfiniteScrolledMap,
|
||||||
|
|
||||||
slime_spawns: Vec<(u16, u16)>,
|
slime_spawns: Vec<(u16, u16)>,
|
||||||
bat_spawns: Vec<(u16, u16)>,
|
bat_spawns: Vec<(u16, u16)>,
|
||||||
|
@ -40,33 +40,14 @@ struct Level {
|
||||||
|
|
||||||
impl Level {
|
impl Level {
|
||||||
fn load_level(
|
fn load_level(
|
||||||
mut backdrop: BackgroundRegular<'static>,
|
mut backdrop: InfiniteScrolledMap,
|
||||||
mut foreground: BackgroundRegular<'static>,
|
mut foreground: InfiniteScrolledMap,
|
||||||
mut clouds: BackgroundRegular<'static>,
|
mut clouds: InfiniteScrolledMap,
|
||||||
|
vram: &mut VRamManager,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
backdrop.set_position(Vector2D::new(0, 0));
|
backdrop.init(vram, (8, 8).into());
|
||||||
backdrop.set_map(agb::display::background::Map::new(
|
foreground.init(vram, (8, 8).into());
|
||||||
tilemap::BACKGROUND_MAP,
|
clouds.init(vram, (2, 2).into());
|
||||||
Vector2D::new(tilemap::WIDTH, tilemap::HEIGHT),
|
|
||||||
0,
|
|
||||||
));
|
|
||||||
backdrop.set_priority(Priority::P2);
|
|
||||||
|
|
||||||
foreground.set_position(Vector2D::new(0, 0));
|
|
||||||
foreground.set_map(agb::display::background::Map::new(
|
|
||||||
tilemap::FOREGROUND_MAP,
|
|
||||||
Vector2D::new(tilemap::WIDTH, tilemap::HEIGHT),
|
|
||||||
0,
|
|
||||||
));
|
|
||||||
foreground.set_priority(Priority::P0);
|
|
||||||
|
|
||||||
clouds.set_position(Vector2D::new(0, -5));
|
|
||||||
clouds.set_map(agb::display::background::Map::new(
|
|
||||||
tilemap::CLOUD_MAP,
|
|
||||||
Vector2D::new(tilemap::WIDTH, tilemap::HEIGHT),
|
|
||||||
0,
|
|
||||||
));
|
|
||||||
clouds.set_priority(Priority::P3);
|
|
||||||
|
|
||||||
backdrop.commit();
|
backdrop.commit();
|
||||||
foreground.commit();
|
foreground.commit();
|
||||||
|
@ -1804,8 +1785,6 @@ struct Game<'a> {
|
||||||
boss: BossState<'a>,
|
boss: BossState<'a>,
|
||||||
move_state: MoveState,
|
move_state: MoveState,
|
||||||
fade_count: u16,
|
fade_count: u16,
|
||||||
|
|
||||||
background_distributor: &'a mut BackgroundDistributor,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MoveState {
|
enum MoveState {
|
||||||
|
@ -1826,6 +1805,7 @@ impl<'a> Game<'a> {
|
||||||
fn advance_frame(
|
fn advance_frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
object_controller: &'a ObjectControl,
|
object_controller: &'a ObjectControl,
|
||||||
|
vram: &mut VRamManager,
|
||||||
sfx: &mut sfx::Sfx,
|
sfx: &mut sfx::Sfx,
|
||||||
) -> GameStatus {
|
) -> GameStatus {
|
||||||
let mut state = GameStatus::Continue;
|
let mut state = GameStatus::Continue;
|
||||||
|
@ -1845,7 +1825,7 @@ impl<'a> Game<'a> {
|
||||||
self.offset.x = (tilemap::WIDTH as i32 * 8 - 248).into();
|
self.offset.x = (tilemap::WIDTH as i32 * 8 - 248).into();
|
||||||
}
|
}
|
||||||
MoveState::FollowingPlayer => {
|
MoveState::FollowingPlayer => {
|
||||||
Game::update_sunrise(self.background_distributor, self.sunrise_timer);
|
Game::update_sunrise(vram, self.sunrise_timer);
|
||||||
if self.sunrise_timer < 120 {
|
if self.sunrise_timer < 120 {
|
||||||
self.sunrise_timer += 1;
|
self.sunrise_timer += 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1867,7 +1847,7 @@ impl<'a> Game<'a> {
|
||||||
if boss.gone {
|
if boss.gone {
|
||||||
self.fade_count += 1;
|
self.fade_count += 1;
|
||||||
self.fade_count = self.fade_count.min(600);
|
self.fade_count = self.fade_count.min(600);
|
||||||
Game::update_fade_out(self.background_distributor, self.fade_count);
|
Game::update_fade_out(vram, self.fade_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1969,15 +1949,11 @@ impl<'a> Game<'a> {
|
||||||
self.player.commit(this_frame_offset);
|
self.player.commit(this_frame_offset);
|
||||||
self.boss.commit(this_frame_offset);
|
self.boss.commit(this_frame_offset);
|
||||||
|
|
||||||
self.level
|
let background_offset = (this_frame_offset.floor().x + 8, 8).into();
|
||||||
.background
|
|
||||||
.set_position(this_frame_offset.floor());
|
self.level.background.set_pos(vram, background_offset);
|
||||||
self.level
|
self.level.foreground.set_pos(vram, background_offset);
|
||||||
.foreground
|
self.level.clouds.set_pos(vram, background_offset / 4);
|
||||||
.set_position(this_frame_offset.floor());
|
|
||||||
self.level
|
|
||||||
.clouds
|
|
||||||
.set_position(this_frame_offset.floor() / 4);
|
|
||||||
self.level.background.commit();
|
self.level.background.commit();
|
||||||
self.level.foreground.commit();
|
self.level.foreground.commit();
|
||||||
self.level.clouds.commit();
|
self.level.clouds.commit();
|
||||||
|
@ -2082,7 +2058,7 @@ impl<'a> Game<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_sunrise(background_distributor: &'a mut BackgroundDistributor, time: u16) {
|
fn update_sunrise(vram: &mut VRamManager, time: u16) {
|
||||||
let mut modified_palette = background::background.palettes[0].clone();
|
let mut modified_palette = background::background.palettes[0].clone();
|
||||||
|
|
||||||
let a = modified_palette.get_colour(0);
|
let a = modified_palette.get_colour(0);
|
||||||
|
@ -2093,10 +2069,10 @@ impl<'a> Game<'a> {
|
||||||
|
|
||||||
let modified_palettes = [modified_palette];
|
let modified_palettes = [modified_palette];
|
||||||
|
|
||||||
background_distributor.set_background_palettes(&modified_palettes);
|
vram.set_background_palettes(&modified_palettes);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_fade_out(background_distributor: &'a mut BackgroundDistributor, time: u16) {
|
fn update_fade_out(vram: &mut VRamManager, time: u16) {
|
||||||
let mut modified_palette = background::background.palettes[0].clone();
|
let mut modified_palette = background::background.palettes[0].clone();
|
||||||
|
|
||||||
let c = modified_palette.get_colour(2);
|
let c = modified_palette.get_colour(2);
|
||||||
|
@ -2107,15 +2083,10 @@ impl<'a> Game<'a> {
|
||||||
|
|
||||||
let modified_palettes = [modified_palette];
|
let modified_palettes = [modified_palette];
|
||||||
|
|
||||||
background_distributor.set_background_palettes(&modified_palettes);
|
vram.set_background_palettes(&modified_palettes);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(
|
fn new(object: &'a ObjectControl, level: Level, start_at_boss: bool) -> Self {
|
||||||
object: &'a ObjectControl,
|
|
||||||
level: Level,
|
|
||||||
background_distributor: &'a mut BackgroundDistributor,
|
|
||||||
start_at_boss: bool,
|
|
||||||
) -> Self {
|
|
||||||
let mut player = Player::new(object);
|
let mut player = Player::new(object);
|
||||||
let mut offset = (8, 8).into();
|
let mut offset = (8, 8).into();
|
||||||
if start_at_boss {
|
if start_at_boss {
|
||||||
|
@ -2139,8 +2110,6 @@ impl<'a> Game<'a> {
|
||||||
move_state: MoveState::Advancing,
|
move_state: MoveState::Advancing,
|
||||||
sunrise_timer: 0,
|
sunrise_timer: 0,
|
||||||
fade_count: 0,
|
fade_count: 0,
|
||||||
|
|
||||||
background_distributor,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2170,19 +2139,59 @@ fn game_with_level(gba: &mut agb::Gba) {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut background = gba.display.video.tiled0();
|
let mut background = gba.display.video.tiled0();
|
||||||
background.set_background_palettes(background::background.palettes);
|
background
|
||||||
background.set_background_tilemap(0, background::background.tiles);
|
.vram
|
||||||
|
.set_background_palettes(background::background.palettes);
|
||||||
|
|
||||||
|
let tileset_ref = background.vram.add_tileset(TileSet::new(
|
||||||
|
background::background.tiles,
|
||||||
|
TileFormat::FourBpp,
|
||||||
|
));
|
||||||
|
|
||||||
let mut object = gba.display.object.get();
|
let mut object = gba.display.object.get();
|
||||||
object.enable();
|
object.enable();
|
||||||
|
|
||||||
|
let backdrop = InfiniteScrolledMap::new(
|
||||||
|
background.background(Priority::P2),
|
||||||
|
Box::new(move |pos| {
|
||||||
|
(
|
||||||
|
tileset_ref,
|
||||||
|
TileSetting::from_raw(
|
||||||
|
tilemap::BACKGROUND_MAP[(pos.x + tilemap::WIDTH * pos.y) as usize],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
let foreground = InfiniteScrolledMap::new(
|
||||||
|
background.background(Priority::P0),
|
||||||
|
Box::new(move |pos| {
|
||||||
|
(
|
||||||
|
tileset_ref,
|
||||||
|
TileSetting::from_raw(
|
||||||
|
tilemap::FOREGROUND_MAP[(pos.x + tilemap::WIDTH * pos.y) as usize],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
let clouds = InfiniteScrolledMap::new(
|
||||||
|
background.background(Priority::P3),
|
||||||
|
Box::new(move |pos| {
|
||||||
|
agb::println!("CLOUDS: {}, {}", pos.x, pos.y);
|
||||||
|
|
||||||
|
(
|
||||||
|
tileset_ref,
|
||||||
|
TileSetting::from_raw(
|
||||||
|
tilemap::CLOUD_MAP[(pos.x + tilemap::WIDTH * pos.y) as usize],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
let mut game = Game::new(
|
let mut game = Game::new(
|
||||||
&object,
|
&object,
|
||||||
Level::load_level(
|
Level::load_level(backdrop, foreground, clouds, &mut background.vram),
|
||||||
background.get_regular().unwrap(),
|
|
||||||
background.get_regular().unwrap(),
|
|
||||||
background.get_regular().unwrap(),
|
|
||||||
),
|
|
||||||
&mut background,
|
|
||||||
start_at_boss,
|
start_at_boss,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2190,7 +2199,7 @@ fn game_with_level(gba: &mut agb::Gba) {
|
||||||
sfx.frame();
|
sfx.frame();
|
||||||
vblank.wait_for_vblank();
|
vblank.wait_for_vblank();
|
||||||
sfx.after_vblank();
|
sfx.after_vblank();
|
||||||
match game.advance_frame(&object, &mut sfx) {
|
match game.advance_frame(&object, &mut background.vram, &mut sfx) {
|
||||||
GameStatus::Continue => {}
|
GameStatus::Continue => {}
|
||||||
GameStatus::Lost => {
|
GameStatus::Lost => {
|
||||||
break false;
|
break false;
|
||||||
|
|
Loading…
Reference in a new issue