feat(demo): exercise Mode 4 and 5 page switching
This commit is contained in:
parent
cf9ee0ca65
commit
52194cd38b
1 changed files with 75 additions and 0 deletions
75
src/bitmap_demo.rs
Normal file
75
src/bitmap_demo.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
//! Original Mode 4/5 page-flipping demos. ARM code copies both images through
|
||||
//! BIOS services, samples input, and switches the displayed page during VBlank.
|
||||
|
||||
use crate::{
|
||||
affine_demo,
|
||||
graphics_demo::{GraphicsDemo, GraphicsError},
|
||||
input::Buttons,
|
||||
machine::Machine,
|
||||
memory::MemoryError,
|
||||
video::Framebuffer,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u16)]
|
||||
pub enum BitmapMode {
|
||||
Mode4 = 4,
|
||||
Mode5 = 5,
|
||||
}
|
||||
|
||||
/// Debug words: completed updates, signed pan X, signed pan Y.
|
||||
pub const BITMAP_STATE: u32 = 0x0200_0000;
|
||||
|
||||
pub struct BitmapDemo {
|
||||
runner: GraphicsDemo,
|
||||
mode: BitmapMode,
|
||||
}
|
||||
impl BitmapDemo {
|
||||
pub fn new(mode: BitmapMode) -> Result<Self, MemoryError> {
|
||||
Ok(Self {
|
||||
runner: GraphicsDemo::with_program(affine_demo::bitmap_program(mode as u16))?,
|
||||
mode,
|
||||
})
|
||||
}
|
||||
pub fn machine(&self) -> &Machine {
|
||||
self.runner.machine()
|
||||
}
|
||||
pub fn frame(
|
||||
&mut self,
|
||||
buttons: Buttons,
|
||||
output: &mut Framebuffer,
|
||||
) -> Result<usize, GraphicsError> {
|
||||
self.runner
|
||||
.frame_with_control(buttons, output, 0x400 | self.mode as u16)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn assets(mode: u16) -> Vec<u8> {
|
||||
let mut palette = [0_u16; 256];
|
||||
palette[0] = 0x4000;
|
||||
for (i, color) in palette.iter_mut().enumerate().skip(1) {
|
||||
*color = ((i & 31) | (((i >> 3) & 31) << 5) | (((i * 3) & 31) << 10)) as u16;
|
||||
}
|
||||
let mut data: Vec<u8> = palette.into_iter().flat_map(u16::to_le_bytes).collect();
|
||||
let mut vram = vec![0_u8; 0x14000];
|
||||
let (width, height) = if mode == 4 { (240, 160) } else { (160, 128) };
|
||||
for page in 0..2 {
|
||||
for y in 0..height {
|
||||
for x in 0..width {
|
||||
let offset = y * width + x;
|
||||
if mode == 4 {
|
||||
vram[page * 0xa000 + offset] = ((x / 8 + 3 * (y / 8) + page * 64) & 255) as u8;
|
||||
} else {
|
||||
let color = (((x / 5 + page * 11) & 31)
|
||||
| (((y / 4 + page * 7) & 31) << 5)
|
||||
| (((x / 8 + y / 8 + page * 5) & 31) << 10))
|
||||
as u16;
|
||||
let address = page * 0xa000 + offset * 2;
|
||||
vram[address..address + 2].copy_from_slice(&color.to_le_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
data.extend(vram);
|
||||
data
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue