VIP inspection tooling #4
			
				
			
		
		
		
	| 
						 | 
					@ -16,7 +16,7 @@ use crate::{
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::utils::{self, CharacterGrid};
 | 
					use super::utils::{self, CellData, CharacterGrid};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct BgMapWindow {
 | 
					pub struct BgMapWindow {
 | 
				
			||||||
    sim_id: SimId,
 | 
					    sim_id: SimId,
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,12 @@ impl BgMapWindow {
 | 
				
			||||||
            ui.add(image);
 | 
					            ui.add(image);
 | 
				
			||||||
            ui.section("Cell", |ui| {
 | 
					            ui.section("Cell", |ui| {
 | 
				
			||||||
                let cell = self.bgmaps.borrow().read::<u16>(self.cell_index);
 | 
					                let cell = self.bgmaps.borrow().read::<u16>(self.cell_index);
 | 
				
			||||||
                let (char_index, mut vflip, mut hflip, palette_index) = utils::parse_cell(cell);
 | 
					                let CellData {
 | 
				
			||||||
 | 
					                    char_index,
 | 
				
			||||||
 | 
					                    mut vflip,
 | 
				
			||||||
 | 
					                    mut hflip,
 | 
				
			||||||
 | 
					                    palette_index,
 | 
				
			||||||
 | 
					                } = CellData::parse(cell);
 | 
				
			||||||
                TableBuilder::new(ui)
 | 
					                TableBuilder::new(ui)
 | 
				
			||||||
                    .column(Column::remainder())
 | 
					                    .column(Column::remainder())
 | 
				
			||||||
                    .column(Column::remainder())
 | 
					                    .column(Column::remainder())
 | 
				
			||||||
| 
						 | 
					@ -245,7 +250,12 @@ impl BgMapRenderer {
 | 
				
			||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .enumerate()
 | 
					            .enumerate()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            let (char_index, vflip, hflip, palette_index) = utils::parse_cell(*cell);
 | 
					            let CellData {
 | 
				
			||||||
 | 
					                char_index,
 | 
				
			||||||
 | 
					                vflip,
 | 
				
			||||||
 | 
					                hflip,
 | 
				
			||||||
 | 
					                palette_index,
 | 
				
			||||||
 | 
					            } = CellData::parse(*cell);
 | 
				
			||||||
            let char = chardata.range::<u16>(char_index * 8, 8);
 | 
					            let char = chardata.range::<u16>(char_index * 8, 8);
 | 
				
			||||||
            let palette = &colors[palette_index];
 | 
					            let palette = &colors[palette_index];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -269,7 +279,12 @@ impl BgMapRenderer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let cell = bgmaps.read::<u16>(index);
 | 
					        let cell = bgmaps.read::<u16>(index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (char_index, vflip, hflip, palette_index) = utils::parse_cell(cell);
 | 
					        let CellData {
 | 
				
			||||||
 | 
					            char_index,
 | 
				
			||||||
 | 
					            vflip,
 | 
				
			||||||
 | 
					            hflip,
 | 
				
			||||||
 | 
					            palette_index,
 | 
				
			||||||
 | 
					        } = CellData::parse(cell);
 | 
				
			||||||
        let char = chardata.range::<u16>(char_index * 8, 8);
 | 
					        let char = chardata.range::<u16>(char_index * 8, 8);
 | 
				
			||||||
        let palette = if generic_palette {
 | 
					        let palette = if generic_palette {
 | 
				
			||||||
            utils::generic_palette(Color32::RED)
 | 
					            utils::generic_palette(Color32::RED)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ use crate::{
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::utils;
 | 
					use super::utils::{self, Object};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct ObjectWindow {
 | 
					pub struct ObjectWindow {
 | 
				
			||||||
    sim_id: SimId,
 | 
					    sim_id: SimId,
 | 
				
			||||||
| 
						 | 
					@ -31,8 +31,9 @@ pub struct ObjectWindow {
 | 
				
			||||||
impl ObjectWindow {
 | 
					impl ObjectWindow {
 | 
				
			||||||
    pub fn new(sim_id: SimId, memory: &mut MemoryMonitor, vram: &mut VramProcessor) -> Self {
 | 
					    pub fn new(sim_id: SimId, memory: &mut MemoryMonitor, vram: &mut VramProcessor) -> Self {
 | 
				
			||||||
        let renderer = ObjectRenderer::new(sim_id, memory);
 | 
					        let renderer = ObjectRenderer::new(sim_id, memory);
 | 
				
			||||||
        let ([object], params) = vram.add(renderer);
 | 
					        let ([zoom, full], params) = vram.add(renderer);
 | 
				
			||||||
        let loader = VramTextureLoader::new([("vram://object".into(), object)]);
 | 
					        let loader =
 | 
				
			||||||
 | 
					            VramTextureLoader::new([("vram://zoom".into(), zoom), ("vram://full".into(), full)]);
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            sim_id,
 | 
					            sim_id,
 | 
				
			||||||
            loader: Arc::new(loader),
 | 
					            loader: Arc::new(loader),
 | 
				
			||||||
| 
						 | 
					@ -59,14 +60,27 @@ impl ObjectWindow {
 | 
				
			||||||
                            ui.add(NumberEdit::new(&mut self.index).range(0..1024));
 | 
					                            ui.add(NumberEdit::new(&mut self.index).range(0..1024));
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					                    body.row(row_height, |mut row| {
 | 
				
			||||||
 | 
					                        row.col(|ui| {
 | 
				
			||||||
 | 
					                            ui.label("Address");
 | 
				
			||||||
 | 
					                        });
 | 
				
			||||||
 | 
					                        row.col(|ui| {
 | 
				
			||||||
 | 
					                            let address = 0x3e000 + self.index * 8;
 | 
				
			||||||
 | 
					                            let mut address_str = format!("{address:08x}");
 | 
				
			||||||
 | 
					                            ui.add_enabled(
 | 
				
			||||||
 | 
					                                false,
 | 
				
			||||||
 | 
					                                TextEdit::singleline(&mut address_str).horizontal_align(Align::Max),
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
 | 
					                        });
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					            let image = Image::new("vram://zoom")
 | 
				
			||||||
 | 
					                .maintain_aspect_ratio(true)
 | 
				
			||||||
 | 
					                .texture_options(TextureOptions::NEAREST);
 | 
				
			||||||
 | 
					            ui.add(image);
 | 
				
			||||||
            ui.section("Properties", |ui| {
 | 
					            ui.section("Properties", |ui| {
 | 
				
			||||||
                let object = self.objects.borrow().read::<[u16; 4]>(self.index);
 | 
					                let object = self.objects.borrow().read::<[u16; 4]>(self.index);
 | 
				
			||||||
                let mut x = ((object[0] & 0x3ff) << 6 >> 6) as i16;
 | 
					                let mut obj = Object::parse(object);
 | 
				
			||||||
                let mut parallax = ((object[1] & 0x3ff) << 6 >> 6) as i16;
 | 
					 | 
				
			||||||
                let mut y = ((object[2] & 0x0ff) << 8 >> 8) as i16;
 | 
					 | 
				
			||||||
                let (mut char_index, mut vflip, mut hflip, palette_index) =
 | 
					 | 
				
			||||||
                    utils::parse_cell(object[3]);
 | 
					 | 
				
			||||||
                TableBuilder::new(ui)
 | 
					                TableBuilder::new(ui)
 | 
				
			||||||
                    .column(Column::remainder())
 | 
					                    .column(Column::remainder())
 | 
				
			||||||
                    .column(Column::remainder())
 | 
					                    .column(Column::remainder())
 | 
				
			||||||
| 
						 | 
					@ -78,7 +92,7 @@ impl ObjectWindow {
 | 
				
			||||||
                            row.col(|ui| {
 | 
					                            row.col(|ui| {
 | 
				
			||||||
                                ui.add_enabled(
 | 
					                                ui.add_enabled(
 | 
				
			||||||
                                    false,
 | 
					                                    false,
 | 
				
			||||||
                                    NumberEdit::new(&mut char_index).range(0..2048),
 | 
					                                    NumberEdit::new(&mut obj.data.char_index).range(0..2048),
 | 
				
			||||||
                                );
 | 
					                                );
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
| 
						 | 
					@ -87,7 +101,7 @@ impl ObjectWindow {
 | 
				
			||||||
                                ui.label("Palette");
 | 
					                                ui.label("Palette");
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                            row.col(|ui| {
 | 
					                            row.col(|ui| {
 | 
				
			||||||
                                let mut palette = format!("OBJ {}", palette_index);
 | 
					                                let mut palette = format!("OBJ {}", obj.data.palette_index);
 | 
				
			||||||
                                ui.add_enabled(
 | 
					                                ui.add_enabled(
 | 
				
			||||||
                                    false,
 | 
					                                    false,
 | 
				
			||||||
                                    TextEdit::singleline(&mut palette).horizontal_align(Align::Max),
 | 
					                                    TextEdit::singleline(&mut palette).horizontal_align(Align::Max),
 | 
				
			||||||
| 
						 | 
					@ -99,7 +113,7 @@ impl ObjectWindow {
 | 
				
			||||||
                                ui.label("X");
 | 
					                                ui.label("X");
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                            row.col(|ui| {
 | 
					                            row.col(|ui| {
 | 
				
			||||||
                                ui.add_enabled(false, NumberEdit::new(&mut x).range(-512..512));
 | 
					                                ui.add_enabled(false, NumberEdit::new(&mut obj.x).range(-512..512));
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
                        body.row(row_height, |mut row| {
 | 
					                        body.row(row_height, |mut row| {
 | 
				
			||||||
| 
						 | 
					@ -107,7 +121,7 @@ impl ObjectWindow {
 | 
				
			||||||
                                ui.label("Y");
 | 
					                                ui.label("Y");
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                            row.col(|ui| {
 | 
					                            row.col(|ui| {
 | 
				
			||||||
                                ui.add_enabled(false, NumberEdit::new(&mut y).range(-8..=224));
 | 
					                                ui.add_enabled(false, NumberEdit::new(&mut obj.y).range(-8..=224));
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
                        body.row(row_height, |mut row| {
 | 
					                        body.row(row_height, |mut row| {
 | 
				
			||||||
| 
						 | 
					@ -117,17 +131,27 @@ impl ObjectWindow {
 | 
				
			||||||
                            row.col(|ui| {
 | 
					                            row.col(|ui| {
 | 
				
			||||||
                                ui.add_enabled(
 | 
					                                ui.add_enabled(
 | 
				
			||||||
                                    false,
 | 
					                                    false,
 | 
				
			||||||
                                    NumberEdit::new(&mut parallax).range(-512..512),
 | 
					                                    NumberEdit::new(&mut obj.parallax).range(-512..512),
 | 
				
			||||||
                                );
 | 
					                                );
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
                        body.row(row_height, |mut row| {
 | 
					                        body.row(row_height, |mut row| {
 | 
				
			||||||
                            row.col(|ui| {
 | 
					                            row.col(|ui| {
 | 
				
			||||||
                                let checkbox = Checkbox::new(&mut hflip, "H-flip");
 | 
					                                let checkbox = Checkbox::new(&mut obj.data.hflip, "H-flip");
 | 
				
			||||||
                                ui.add_enabled(false, checkbox);
 | 
					                                ui.add_enabled(false, checkbox);
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                            row.col(|ui| {
 | 
					                            row.col(|ui| {
 | 
				
			||||||
                                let checkbox = Checkbox::new(&mut vflip, "V-flip");
 | 
					                                let checkbox = Checkbox::new(&mut obj.data.vflip, "V-flip");
 | 
				
			||||||
 | 
					                                ui.add_enabled(false, checkbox);
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                        });
 | 
				
			||||||
 | 
					                        body.row(row_height, |mut row| {
 | 
				
			||||||
 | 
					                            row.col(|ui| {
 | 
				
			||||||
 | 
					                                let checkbox = Checkbox::new(&mut obj.lon, "Left");
 | 
				
			||||||
 | 
					                                ui.add_enabled(false, checkbox);
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                            row.col(|ui| {
 | 
				
			||||||
 | 
					                                let checkbox = Checkbox::new(&mut obj.ron, "Right");
 | 
				
			||||||
                                ui.add_enabled(false, checkbox);
 | 
					                                ui.add_enabled(false, checkbox);
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
| 
						 | 
					@ -153,7 +177,7 @@ impl ObjectWindow {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn show_object(&mut self, ui: &mut Ui) {
 | 
					    fn show_object(&mut self, ui: &mut Ui) {
 | 
				
			||||||
        let image = Image::new("vram://object")
 | 
					        let image = Image::new("vram://full")
 | 
				
			||||||
            .fit_to_original_size(self.scale)
 | 
					            .fit_to_original_size(self.scale)
 | 
				
			||||||
            .texture_options(TextureOptions::NEAREST);
 | 
					            .texture_options(TextureOptions::NEAREST);
 | 
				
			||||||
        ui.add(image);
 | 
					        ui.add(image);
 | 
				
			||||||
| 
						 | 
					@ -172,7 +196,7 @@ impl AppWindow for ObjectWindow {
 | 
				
			||||||
    fn initial_viewport(&self) -> ViewportBuilder {
 | 
					    fn initial_viewport(&self) -> ViewportBuilder {
 | 
				
			||||||
        ViewportBuilder::default()
 | 
					        ViewportBuilder::default()
 | 
				
			||||||
            .with_title(format!("Object Data ({})", self.sim_id))
 | 
					            .with_title(format!("Object Data ({})", self.sim_id))
 | 
				
			||||||
            .with_inner_size((640.0, 480.0))
 | 
					            .with_inner_size((640.0, 500.0))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn on_init(&mut self, ctx: &Context, _render_state: &egui_wgpu::RenderState) {
 | 
					    fn on_init(&mut self, ctx: &Context, _render_state: &egui_wgpu::RenderState) {
 | 
				
			||||||
| 
						 | 
					@ -239,50 +263,55 @@ impl ObjectRenderer {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn render_object(&self, image: &mut VramImage, params: &ObjectParams, eye: Eye) {
 | 
					    fn render_object(&self, image: &mut VramImage, params: &ObjectParams, use_pos: bool, eye: Eye) {
 | 
				
			||||||
        let chardata = self.chardata.borrow();
 | 
					        let chardata = self.chardata.borrow();
 | 
				
			||||||
        let objects = self.objects.borrow();
 | 
					        let objects = self.objects.borrow();
 | 
				
			||||||
        let brightness = self.brightness.borrow();
 | 
					        let brightness = self.brightness.borrow();
 | 
				
			||||||
        let palettes = self.palettes.borrow();
 | 
					        let palettes = self.palettes.borrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let object: [u16; 4] = objects.read(params.index);
 | 
					        let object: [u16; 4] = objects.read(params.index);
 | 
				
			||||||
 | 
					        let obj = Object::parse(object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let ron = object[1] & 0x4000 != 0;
 | 
					 | 
				
			||||||
        let lon = object[1] & 0x8000 != 0;
 | 
					 | 
				
			||||||
        if match eye {
 | 
					        if match eye {
 | 
				
			||||||
            Eye::Left => !lon,
 | 
					            Eye::Left => !obj.lon,
 | 
				
			||||||
            Eye::Right => !ron,
 | 
					            Eye::Right => !obj.ron,
 | 
				
			||||||
        } {
 | 
					        } {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let brts = brightness.range::<u8>(0, 8);
 | 
					        let brts = brightness.range::<u8>(0, 8);
 | 
				
			||||||
 | 
					        let (x, y) = if use_pos {
 | 
				
			||||||
        let x = ((object[0] & 0x3ff) << 6 >> 6) as i16;
 | 
					            let x = match eye {
 | 
				
			||||||
        let parallax = ((object[1] & 0x3ff) << 6 >> 6) as i16;
 | 
					                Eye::Left => obj.x - obj.parallax,
 | 
				
			||||||
        let y = ((object[2] & 0x0ff) << 8 >> 8) as i16;
 | 
					                Eye::Right => obj.x + obj.parallax,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
        let (x, color) = match eye {
 | 
					            (x, obj.y)
 | 
				
			||||||
            Eye::Left => (x - parallax, params.left_color),
 | 
					        } else {
 | 
				
			||||||
            Eye::Right => (x + parallax, params.right_color),
 | 
					            (0, 0)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (char_index, vflip, hflip, palette_index) = utils::parse_cell(object[3]);
 | 
					        let color = match eye {
 | 
				
			||||||
        let char = chardata.range::<u16>(char_index * 8, 8);
 | 
					            Eye::Left => params.left_color,
 | 
				
			||||||
 | 
					            Eye::Right => params.right_color,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let char = chardata.range::<u16>(obj.data.char_index * 8, 8);
 | 
				
			||||||
        let palette = if params.generic_palette {
 | 
					        let palette = if params.generic_palette {
 | 
				
			||||||
            utils::generic_palette(color)
 | 
					            utils::generic_palette(color)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            utils::parse_palette(palettes.read(8 + palette_index * 2), brts, color)
 | 
					            utils::parse_palette(palettes.read(8 + obj.data.palette_index * 2), brts, color)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for row in 0..8 {
 | 
					        for row in 0..8 {
 | 
				
			||||||
            let real_y = y + row as i16;
 | 
					            let real_y = y + row as i16;
 | 
				
			||||||
            if !(0..384).contains(&real_y) {
 | 
					            if !(0..224).contains(&real_y) {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            for (col, pixel) in utils::read_char_row(char, hflip, vflip, row).enumerate() {
 | 
					            for (col, pixel) in
 | 
				
			||||||
 | 
					                utils::read_char_row(char, obj.data.hflip, obj.data.vflip, row).enumerate()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                let real_x = x + col as i16;
 | 
					                let real_x = x + col as i16;
 | 
				
			||||||
                if !(0..224).contains(&real_x) {
 | 
					                if !(0..384).contains(&real_x) {
 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                image.add((real_x as usize, real_y as usize), palette[pixel as usize]);
 | 
					                image.add((real_x as usize, real_y as usize), palette[pixel as usize]);
 | 
				
			||||||
| 
						 | 
					@ -291,17 +320,19 @@ impl ObjectRenderer {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl VramRenderer<1> for ObjectRenderer {
 | 
					impl VramRenderer<2> for ObjectRenderer {
 | 
				
			||||||
    type Params = ObjectParams;
 | 
					    type Params = ObjectParams;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn sizes(&self) -> [[usize; 2]; 1] {
 | 
					    fn sizes(&self) -> [[usize; 2]; 2] {
 | 
				
			||||||
        [[384, 224]]
 | 
					        [[8, 8], [384, 224]]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn render(&mut self, params: &Self::Params, images: &mut [VramImage; 1]) {
 | 
					    fn render(&mut self, params: &Self::Params, images: &mut [VramImage; 2]) {
 | 
				
			||||||
        let image = &mut images[0];
 | 
					        images[0].clear();
 | 
				
			||||||
        image.clear();
 | 
					        self.render_object(&mut images[0], params, false, Eye::Left);
 | 
				
			||||||
        self.render_object(image, params, Eye::Left);
 | 
					        self.render_object(&mut images[0], params, false, Eye::Right);
 | 
				
			||||||
        self.render_object(image, params, Eye::Right);
 | 
					        images[1].clear();
 | 
				
			||||||
 | 
					        self.render_object(&mut images[1], params, true, Eye::Left);
 | 
				
			||||||
 | 
					        self.render_object(&mut images[1], params, true, Eye::Right);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,12 +28,57 @@ pub fn parse_palette(palette: u8, brts: &[u8], color: Color32) -> [Color32; 4] {
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn parse_cell(cell: u16) -> (usize, bool, bool, usize) {
 | 
					pub struct Object {
 | 
				
			||||||
    let char_index = (cell & 0x7ff) as usize;
 | 
					    pub x: i16,
 | 
				
			||||||
    let vflip = cell & 0x1000 != 0;
 | 
					    pub lon: bool,
 | 
				
			||||||
    let hflip = cell & 0x2000 != 0;
 | 
					    pub ron: bool,
 | 
				
			||||||
    let palette_index = (cell >> 14) as usize;
 | 
					    pub parallax: i16,
 | 
				
			||||||
    (char_index, vflip, hflip, palette_index)
 | 
					    pub y: i16,
 | 
				
			||||||
 | 
					    pub data: CellData,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Object {
 | 
				
			||||||
 | 
					    pub fn parse(object: [u16; 4]) -> Self {
 | 
				
			||||||
 | 
					        let x = ((object[0] & 0x3ff) << 6 >> 6) as i16;
 | 
				
			||||||
 | 
					        let parallax = ((object[1] & 0x3ff) << 6 >> 6) as i16;
 | 
				
			||||||
 | 
					        let lon = object[1] & 0x8000 != 0;
 | 
				
			||||||
 | 
					        let ron = object[1] & 0x4000 != 0;
 | 
				
			||||||
 | 
					        let y = (object[2] & 0x0ff) as i16;
 | 
				
			||||||
 | 
					        // Y is stored as the bottom 8 bits of an i16,
 | 
				
			||||||
 | 
					        // so only sign extend if it's out of range.
 | 
				
			||||||
 | 
					        let y = if y > 224 { y << 8 >> 8 } else { y };
 | 
				
			||||||
 | 
					        let data = CellData::parse(object[3]);
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            x,
 | 
				
			||||||
 | 
					            lon,
 | 
				
			||||||
 | 
					            ron,
 | 
				
			||||||
 | 
					            parallax,
 | 
				
			||||||
 | 
					            y,
 | 
				
			||||||
 | 
					            data,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct CellData {
 | 
				
			||||||
 | 
					    pub palette_index: usize,
 | 
				
			||||||
 | 
					    pub hflip: bool,
 | 
				
			||||||
 | 
					    pub vflip: bool,
 | 
				
			||||||
 | 
					    pub char_index: usize,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl CellData {
 | 
				
			||||||
 | 
					    pub fn parse(cell: u16) -> Self {
 | 
				
			||||||
 | 
					        let char_index = (cell & 0x7ff) as usize;
 | 
				
			||||||
 | 
					        let vflip = cell & 0x1000 != 0;
 | 
				
			||||||
 | 
					        let hflip = cell & 0x2000 != 0;
 | 
				
			||||||
 | 
					        let palette_index = (cell >> 14) as usize;
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            char_index,
 | 
				
			||||||
 | 
					            vflip,
 | 
				
			||||||
 | 
					            hflip,
 | 
				
			||||||
 | 
					            palette_index,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn read_char_row(
 | 
					pub fn read_char_row(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue