VIP inspection tooling #4
			
				
			
		
		
		
	| 
						 | 
					@ -98,8 +98,11 @@ macro_rules! primitive_memory_value_impl {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
primitive_memory_value_impl!(u8, 1);
 | 
					primitive_memory_value_impl!(u8, 1);
 | 
				
			||||||
 | 
					primitive_memory_value_impl!(i8, 2);
 | 
				
			||||||
primitive_memory_value_impl!(u16, 2);
 | 
					primitive_memory_value_impl!(u16, 2);
 | 
				
			||||||
 | 
					primitive_memory_value_impl!(i16, 2);
 | 
				
			||||||
primitive_memory_value_impl!(u32, 4);
 | 
					primitive_memory_value_impl!(u32, 4);
 | 
				
			||||||
 | 
					primitive_memory_value_impl!(i32, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<const N: usize, T: MemoryValue> MemoryValue for [T; N] {
 | 
					impl<const N: usize, T: MemoryValue> MemoryValue for [T; N] {
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,10 +34,11 @@ pub trait UiExt {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl UiExt for Ui {
 | 
					impl UiExt for Ui {
 | 
				
			||||||
    fn section(&mut self, title: impl Into<String>, add_contents: impl FnOnce(&mut Ui)) {
 | 
					    fn section(&mut self, title: impl Into<String>, add_contents: impl FnOnce(&mut Ui)) {
 | 
				
			||||||
 | 
					        let title: String = title.into();
 | 
				
			||||||
        let mut frame = Frame::group(self.style());
 | 
					        let mut frame = Frame::group(self.style());
 | 
				
			||||||
        frame.outer_margin.top += 10.0;
 | 
					        frame.outer_margin.top += 10.0;
 | 
				
			||||||
        frame.inner_margin.top += 2.0;
 | 
					        frame.inner_margin.top += 2.0;
 | 
				
			||||||
        let res = frame.show(self, add_contents);
 | 
					        let res = self.push_id(&title, |ui| frame.show(ui, add_contents));
 | 
				
			||||||
        let text = RichText::new(title).background_color(self.style().visuals.panel_fill);
 | 
					        let text = RichText::new(title).background_color(self.style().visuals.panel_fill);
 | 
				
			||||||
        let old_rect = res.response.rect;
 | 
					        let old_rect = res.response.rect;
 | 
				
			||||||
        let mut text_rect = old_rect;
 | 
					        let mut text_rect = old_rect;
 | 
				
			||||||
| 
						 | 
					@ -133,12 +134,14 @@ impl<'a, T: Number> NumberEdit<'a, T> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T: Number> Widget for NumberEdit<'_, T> {
 | 
					impl<T: Number> Widget for NumberEdit<'_, T> {
 | 
				
			||||||
    fn ui(self, ui: &mut Ui) -> Response {
 | 
					    fn ui(self, ui: &mut Ui) -> Response {
 | 
				
			||||||
 | 
					        let id = ui.id();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (last_value, mut str, focus) = ui.memory(|m| {
 | 
					        let (last_value, mut str, focus) = ui.memory(|m| {
 | 
				
			||||||
            let (lv, s) = m
 | 
					            let (lv, s) = m
 | 
				
			||||||
                .data
 | 
					                .data
 | 
				
			||||||
                .get_temp(ui.id())
 | 
					                .get_temp(id)
 | 
				
			||||||
                .unwrap_or((*self.value, self.value.to_string()));
 | 
					                .unwrap_or((*self.value, self.value.to_string()));
 | 
				
			||||||
            let focus = m.has_focus(ui.id());
 | 
					            let focus = m.has_focus(id);
 | 
				
			||||||
            (lv, s, focus)
 | 
					            (lv, s, focus)
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        let mut stale = false;
 | 
					        let mut stale = false;
 | 
				
			||||||
| 
						 | 
					@ -174,7 +177,7 @@ impl<T: Number> Widget for NumberEdit<'_, T> {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        let text = TextEdit::singleline(&mut str)
 | 
					        let text = TextEdit::singleline(&mut str)
 | 
				
			||||||
            .horizontal_align(Align::Max)
 | 
					            .horizontal_align(Align::Max)
 | 
				
			||||||
            .id(ui.id())
 | 
					            .id(id)
 | 
				
			||||||
            .margin(Margin {
 | 
					            .margin(Margin {
 | 
				
			||||||
                left: 4.0,
 | 
					                left: 4.0,
 | 
				
			||||||
                right: 20.0,
 | 
					                right: 20.0,
 | 
				
			||||||
| 
						 | 
					@ -242,7 +245,7 @@ impl<T: Number> Widget for NumberEdit<'_, T> {
 | 
				
			||||||
            stale = true;
 | 
					            stale = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if stale {
 | 
					        if stale {
 | 
				
			||||||
            ui.memory_mut(|m| m.data.insert_temp(ui.id(), (*self.value, str)));
 | 
					            ui.memory_mut(|m| m.data.insert_temp(id, (*self.value, str)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        res
 | 
					        res
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,9 @@ pub struct WorldWindow {
 | 
				
			||||||
    sim_id: SimId,
 | 
					    sim_id: SimId,
 | 
				
			||||||
    loader: Arc<VramTextureLoader>,
 | 
					    loader: Arc<VramTextureLoader>,
 | 
				
			||||||
    worlds: MemoryView,
 | 
					    worlds: MemoryView,
 | 
				
			||||||
 | 
					    bgmaps: MemoryView,
 | 
				
			||||||
    index: usize,
 | 
					    index: usize,
 | 
				
			||||||
 | 
					    param_index: usize,
 | 
				
			||||||
    generic_palette: bool,
 | 
					    generic_palette: bool,
 | 
				
			||||||
    params: VramParams<WorldParams>,
 | 
					    params: VramParams<WorldParams>,
 | 
				
			||||||
    scale: f32,
 | 
					    scale: f32,
 | 
				
			||||||
| 
						 | 
					@ -45,7 +47,9 @@ impl WorldWindow {
 | 
				
			||||||
            sim_id,
 | 
					            sim_id,
 | 
				
			||||||
            loader: Arc::new(loader),
 | 
					            loader: Arc::new(loader),
 | 
				
			||||||
            worlds: memory.watch(sim_id, 0x3d800, 0x400),
 | 
					            worlds: memory.watch(sim_id, 0x3d800, 0x400),
 | 
				
			||||||
 | 
					            bgmaps: memory.watch(sim_id, 0x00020000, 0x20000),
 | 
				
			||||||
            index: params.index,
 | 
					            index: params.index,
 | 
				
			||||||
 | 
					            param_index: 0,
 | 
				
			||||||
            generic_palette: params.generic_palette,
 | 
					            generic_palette: params.generic_palette,
 | 
				
			||||||
            params,
 | 
					            params,
 | 
				
			||||||
            scale: 1.0,
 | 
					            scale: 1.0,
 | 
				
			||||||
| 
						 | 
					@ -262,6 +266,57 @@ impl WorldWindow {
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					            if world.header.mode == WorldMode::HBias {
 | 
				
			||||||
 | 
					                ui.section("H-bias", |ui| {
 | 
				
			||||||
 | 
					                    TableBuilder::new(ui)
 | 
				
			||||||
 | 
					                        .column(Column::remainder())
 | 
				
			||||||
 | 
					                        .column(Column::remainder())
 | 
				
			||||||
 | 
					                        .body(|mut body| {
 | 
				
			||||||
 | 
					                            body.row(row_height, |mut row| {
 | 
				
			||||||
 | 
					                                row.col(|ui| {
 | 
				
			||||||
 | 
					                                    ui.label("Index");
 | 
				
			||||||
 | 
					                                });
 | 
				
			||||||
 | 
					                                row.col(|ui| {
 | 
				
			||||||
 | 
					                                    ui.add(NumberEdit::new(&mut self.param_index).range(0..32));
 | 
				
			||||||
 | 
					                                });
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                            let base = world.param_base + self.param_index * 2;
 | 
				
			||||||
 | 
					                            let mut param = HBiasParam::load(&self.bgmaps.borrow(), base);
 | 
				
			||||||
 | 
					                            body.row(row_height, |mut row| {
 | 
				
			||||||
 | 
					                                row.col(|ui| {
 | 
				
			||||||
 | 
					                                    ui.label("Address");
 | 
				
			||||||
 | 
					                                });
 | 
				
			||||||
 | 
					                                row.col(|ui| {
 | 
				
			||||||
 | 
					                                    let address = 0x00020000 + base * 2;
 | 
				
			||||||
 | 
					                                    let mut address_str = format!("{address:08x}");
 | 
				
			||||||
 | 
					                                    ui.add_enabled(
 | 
				
			||||||
 | 
					                                        false,
 | 
				
			||||||
 | 
					                                        TextEdit::singleline(&mut address_str)
 | 
				
			||||||
 | 
					                                            .horizontal_align(Align::Max),
 | 
				
			||||||
 | 
					                                    );
 | 
				
			||||||
 | 
					                                });
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                            body.row(row_height, |mut row| {
 | 
				
			||||||
 | 
					                                row.col(|ui| {
 | 
				
			||||||
 | 
					                                    ui.label("Left");
 | 
				
			||||||
 | 
					                                });
 | 
				
			||||||
 | 
					                                row.col(|ui| {
 | 
				
			||||||
 | 
					                                    ui.add(NumberEdit::new(&mut param.left).range(-4096..4096));
 | 
				
			||||||
 | 
					                                });
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                            body.row(row_height, |mut row| {
 | 
				
			||||||
 | 
					                                row.col(|ui| {
 | 
				
			||||||
 | 
					                                    ui.label("Right");
 | 
				
			||||||
 | 
					                                });
 | 
				
			||||||
 | 
					                                row.col(|ui| {
 | 
				
			||||||
 | 
					                                    ui.add(NumberEdit::new(&mut param.right).range(-4096..4096));
 | 
				
			||||||
 | 
					                                });
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                        });
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                self.param_index = 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            ui.section("Display", |ui| {
 | 
					            ui.section("Display", |ui| {
 | 
				
			||||||
                ui.horizontal(|ui| {
 | 
					                ui.horizontal(|ui| {
 | 
				
			||||||
                    ui.label("Scale");
 | 
					                    ui.label("Scale");
 | 
				
			||||||
| 
						 | 
					@ -497,48 +552,44 @@ impl WorldRenderer {
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut chars = CharCache::new(self.chardata.borrow());
 | 
					        let chardata = self.chardata.borrow();
 | 
				
			||||||
        let mut cells = CellCache::new(self.bgmaps.borrow());
 | 
					        let bgmaps = self.bgmaps.borrow();
 | 
				
			||||||
 | 
					        let mut chars = [CharCache::new(&chardata), CharCache::new(&chardata)];
 | 
				
			||||||
 | 
					        let mut cells = [CellCache::new(&bgmaps), CellCache::new(&bgmaps)];
 | 
				
			||||||
 | 
					        let mut source = SourceCoordCalculator::new(&bgmaps, &world);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for y in 0..height {
 | 
					        for y in 0..height {
 | 
				
			||||||
            let dy = y + world.dst_y;
 | 
					            let dy = y + world.dst_y;
 | 
				
			||||||
            if !(0..224).contains(&dy) {
 | 
					            if !(0..224).contains(&dy) {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            let sy = y + world.src_y;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // left side
 | 
					 | 
				
			||||||
            for x in 0..world.width {
 | 
					            for x in 0..world.width {
 | 
				
			||||||
                let dx = x + world.dst_x - world.dst_parallax;
 | 
					                let dx = x + world.dst_x - world.dst_parallax;
 | 
				
			||||||
                if !(0..384).contains(&dx) {
 | 
					                if world.header.lon && (0..384).contains(&dx) {
 | 
				
			||||||
                    continue;
 | 
					                    let (sx, sy) = source.left(x, y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    let cell_index = world.source_cell(sx, sy);
 | 
				
			||||||
 | 
					                    let cell = cells[0].get(cell_index);
 | 
				
			||||||
 | 
					                    let char = chars[0].get(cell.char_index);
 | 
				
			||||||
 | 
					                    let row = (sy & 0x7) as usize;
 | 
				
			||||||
 | 
					                    let col = (sx & 0x7) as usize;
 | 
				
			||||||
 | 
					                    let pixel = utils::read_char_pixel(char, cell.hflip, cell.vflip, row, col);
 | 
				
			||||||
 | 
					                    image.add((dx as usize, dy as usize), colors[0][pixel as usize]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                let sx = x + world.src_x - world.src_parallax;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let cell_index = world.source_cell(sx, sy);
 | 
					 | 
				
			||||||
                let cell = cells.get(cell_index);
 | 
					 | 
				
			||||||
                let char = chars.get(cell.char_index);
 | 
					 | 
				
			||||||
                let row = (sy & 0x7) as usize;
 | 
					 | 
				
			||||||
                let col = (sx & 0x7) as usize;
 | 
					 | 
				
			||||||
                let pixel = utils::read_char_pixel(char, cell.hflip, cell.vflip, row, col);
 | 
					 | 
				
			||||||
                image.add((dx as usize, dy as usize), colors[0][pixel as usize]);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // right side
 | 
					 | 
				
			||||||
            for x in 0..world.width {
 | 
					 | 
				
			||||||
                let dx = x + world.dst_x + world.dst_parallax;
 | 
					                let dx = x + world.dst_x + world.dst_parallax;
 | 
				
			||||||
                if !(0..384).contains(&dx) {
 | 
					                if world.header.ron && (0..384).contains(&dx) {
 | 
				
			||||||
                    continue;
 | 
					                    let (sx, sy) = source.right(x, y);
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                let sx = x + world.src_x + world.src_parallax;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let cell_index = world.source_cell(sx, sy);
 | 
					                    let cell_index = world.source_cell(sx, sy);
 | 
				
			||||||
                let cell = cells.get(cell_index);
 | 
					                    let cell = cells[1].get(cell_index);
 | 
				
			||||||
                let char = chars.get(cell.char_index);
 | 
					                    let char = chars[1].get(cell.char_index);
 | 
				
			||||||
                let row = (sy & 0x7) as usize;
 | 
					                    let row = (sy & 0x7) as usize;
 | 
				
			||||||
                let col = (sx & 0x7) as usize;
 | 
					                    let col = (sx & 0x7) as usize;
 | 
				
			||||||
                let pixel = utils::read_char_pixel(char, cell.hflip, cell.vflip, row, col);
 | 
					                    let pixel = utils::read_char_pixel(char, cell.hflip, cell.vflip, row, col);
 | 
				
			||||||
                image.add((dx as usize, dy as usize), colors[1][pixel as usize]);
 | 
					                    image.add((dx as usize, dy as usize), colors[1][pixel as usize]);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -556,7 +607,7 @@ impl VramRenderer<1> for WorldRenderer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let worlds = self.worlds.borrow();
 | 
					        let worlds = self.worlds.borrow();
 | 
				
			||||||
        let header = WorldHeader::parse(worlds.read(params.index * 16));
 | 
					        let header = WorldHeader::parse(worlds.read(params.index * 16));
 | 
				
			||||||
        if header.end || (!header.lon && header.ron) {
 | 
					        if header.end || (!header.lon && !header.ron) {
 | 
				
			||||||
            image.clear();
 | 
					            image.clear();
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -693,13 +744,13 @@ impl Display for WorldMode {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct CellCache<'a> {
 | 
					struct CellCache<'a> {
 | 
				
			||||||
    bgmaps: MemoryRef<'a>,
 | 
					    bgmaps: &'a MemoryRef<'a>,
 | 
				
			||||||
    index: usize,
 | 
					    index: usize,
 | 
				
			||||||
    cell: CellData,
 | 
					    cell: CellData,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a> CellCache<'a> {
 | 
					impl<'a> CellCache<'a> {
 | 
				
			||||||
    fn new(bgmaps: MemoryRef<'a>) -> Self {
 | 
					    fn new(bgmaps: &'a MemoryRef<'a>) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            bgmaps,
 | 
					            bgmaps,
 | 
				
			||||||
            index: 0x10000,
 | 
					            index: 0x10000,
 | 
				
			||||||
| 
						 | 
					@ -718,13 +769,13 @@ impl<'a> CellCache<'a> {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct CharCache<'a> {
 | 
					struct CharCache<'a> {
 | 
				
			||||||
    chardata: MemoryRef<'a>,
 | 
					    chardata: &'a MemoryRef<'a>,
 | 
				
			||||||
    index: usize,
 | 
					    index: usize,
 | 
				
			||||||
    char: [u16; 8],
 | 
					    char: [u16; 8],
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a> CharCache<'a> {
 | 
					impl<'a> CharCache<'a> {
 | 
				
			||||||
    fn new(chardata: MemoryRef<'a>) -> Self {
 | 
					    fn new(chardata: &'a MemoryRef<'a>) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            chardata,
 | 
					            chardata,
 | 
				
			||||||
            index: 2048,
 | 
					            index: 2048,
 | 
				
			||||||
| 
						 | 
					@ -740,3 +791,82 @@ impl<'a> CharCache<'a> {
 | 
				
			||||||
        &self.char
 | 
					        &self.char
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct SourceCoordCalculator<'a> {
 | 
				
			||||||
 | 
					    params: &'a MemoryRef<'a>,
 | 
				
			||||||
 | 
					    world: &'a World,
 | 
				
			||||||
 | 
					    y: i16,
 | 
				
			||||||
 | 
					    param: SourceParam,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'a> SourceCoordCalculator<'a> {
 | 
				
			||||||
 | 
					    fn new(params: &'a MemoryRef<'a>, world: &'a World) -> Self {
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            params,
 | 
				
			||||||
 | 
					            world,
 | 
				
			||||||
 | 
					            y: -1,
 | 
				
			||||||
 | 
					            param: SourceParam::Normal,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn left(&mut self, x: i16, y: i16) -> (i16, i16) {
 | 
				
			||||||
 | 
					        self.update_param(y);
 | 
				
			||||||
 | 
					        match &self.param {
 | 
				
			||||||
 | 
					            SourceParam::HBias(HBiasParam { left, .. }) => {
 | 
				
			||||||
 | 
					                let sx = x + self.world.src_x - self.world.src_parallax + *left;
 | 
				
			||||||
 | 
					                let sy = y + self.world.src_y;
 | 
				
			||||||
 | 
					                (sx, sy)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            SourceParam::Normal => {
 | 
				
			||||||
 | 
					                let sx = x + self.world.src_x - self.world.src_parallax;
 | 
				
			||||||
 | 
					                let sy = y + self.world.src_y;
 | 
				
			||||||
 | 
					                (sx, sy)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn right(&mut self, x: i16, y: i16) -> (i16, i16) {
 | 
				
			||||||
 | 
					        self.update_param(y);
 | 
				
			||||||
 | 
					        match &self.param {
 | 
				
			||||||
 | 
					            SourceParam::HBias(HBiasParam { right, .. }) => {
 | 
				
			||||||
 | 
					                let sx = x + self.world.src_x + self.world.src_parallax + *right;
 | 
				
			||||||
 | 
					                let sy = y + self.world.src_y;
 | 
				
			||||||
 | 
					                (sx, sy)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            SourceParam::Normal => {
 | 
				
			||||||
 | 
					                let sx = x + self.world.src_x + self.world.src_parallax;
 | 
				
			||||||
 | 
					                let sy = y + self.world.src_y;
 | 
				
			||||||
 | 
					                (sx, sy)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn update_param(&mut self, y: i16) {
 | 
				
			||||||
 | 
					        if self.y == y {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if self.world.header.mode == WorldMode::HBias {
 | 
				
			||||||
 | 
					            let base = self.world.param_base + (2 * y as usize);
 | 
				
			||||||
 | 
					            self.param = SourceParam::HBias(HBiasParam::load(self.params, base));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self.y = y;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum SourceParam {
 | 
				
			||||||
 | 
					    Normal,
 | 
				
			||||||
 | 
					    HBias(HBiasParam),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct HBiasParam {
 | 
				
			||||||
 | 
					    left: i16,
 | 
				
			||||||
 | 
					    right: i16,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl HBiasParam {
 | 
				
			||||||
 | 
					    fn load(params: &MemoryRef, index: usize) -> Self {
 | 
				
			||||||
 | 
					        let left = params.read::<i16>(index) << 3 >> 3;
 | 
				
			||||||
 | 
					        let right = params.read::<i16>(index | 1) << 3 >> 3;
 | 
				
			||||||
 | 
					        Self { left, right }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue