add layer window
This commit is contained in:
parent
2685bc06e6
commit
b0a5373ff6
6 changed files with 82 additions and 25 deletions
|
@ -54,9 +54,13 @@ struct Args {
|
|||
hex: bool,
|
||||
|
||||
/// Show tile window
|
||||
#[arg(short, long)]
|
||||
#[arg(long)]
|
||||
tile_window: bool,
|
||||
|
||||
/// Show layer window
|
||||
#[arg(long)]
|
||||
layer_window: bool,
|
||||
|
||||
/// Scale display by...
|
||||
#[arg(short, long)]
|
||||
scale_factor: Option<usize>,
|
||||
|
@ -122,12 +126,19 @@ impl EmulatorHandler {
|
|||
let mut window_manager = WindowManager::new(sender);
|
||||
|
||||
let window = window_manager.add(factor, Some(Gilrs::new().unwrap()));
|
||||
|
||||
let tile_window: Option<WindowRenderer> = if args.tile_window {
|
||||
Some(window_manager.add(factor, None))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let layer_window: Option<WindowRenderer> = if args.layer_window {
|
||||
Some(window_manager.add(1, None))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let options = EmulatorOptions::new(window, rom, output)
|
||||
.with_save_path(args.save)
|
||||
.with_serial_target(if args.ascii {
|
||||
|
@ -149,6 +160,7 @@ impl EmulatorHandler {
|
|||
)
|
||||
.with_no_save(args.no_save)
|
||||
.with_tile_window(tile_window)
|
||||
.with_layer_window(layer_window)
|
||||
.with_cgb_mode(!args.dmg);
|
||||
|
||||
// let core: Box<dyn EmulatorCoreTrait> = if args.camera {
|
||||
|
|
|
@ -116,6 +116,7 @@ impl WindowRenderer {
|
|||
) -> (Self, WindowInfo) {
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("Gameboy")
|
||||
.with_resizable(false)
|
||||
.build(event_loop)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
@ -164,6 +164,7 @@ where
|
|||
{
|
||||
pub(crate) window: R,
|
||||
pub(crate) tile_window: Option<R>,
|
||||
pub(crate) layer_window: Option<R>,
|
||||
pub(crate) rom: RomFile,
|
||||
pub(crate) output: AudioOutput,
|
||||
pub(crate) save: Option<SramType>,
|
||||
|
@ -185,6 +186,7 @@ where
|
|||
Self {
|
||||
window,
|
||||
tile_window: None,
|
||||
layer_window: None,
|
||||
rom,
|
||||
output,
|
||||
save: None,
|
||||
|
@ -238,6 +240,11 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
pub fn with_layer_window(mut self, window: Option<R>) -> Self {
|
||||
self.layer_window = window;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_cgb_mode(mut self, cgb_mode: bool) -> Self {
|
||||
self.cgb_mode = cgb_mode;
|
||||
self
|
||||
|
|
|
@ -130,6 +130,7 @@ where
|
|||
options.output,
|
||||
options.serial_target,
|
||||
options.tile_window,
|
||||
options.layer_window,
|
||||
camera,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -119,6 +119,7 @@ where
|
|||
audio: AudioOutput,
|
||||
serial_target: SerialTarget,
|
||||
tile_window: Option<R>,
|
||||
layer_window: Option<R>,
|
||||
camera: CameraWrapperRef<C>,
|
||||
_phantom: PhantomData<ColourFormat>,
|
||||
}
|
||||
|
@ -134,6 +135,7 @@ where
|
|||
audio: AudioOutput,
|
||||
serial_target: SerialTarget,
|
||||
tile_window: Option<R>,
|
||||
layer_window: Option<R>,
|
||||
camera: CameraWrapperRef<C>,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -141,6 +143,7 @@ where
|
|||
audio,
|
||||
serial_target,
|
||||
tile_window,
|
||||
layer_window,
|
||||
camera,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
|
@ -170,7 +173,7 @@ where
|
|||
user_mode: false,
|
||||
oam_dma: OamDma::default(),
|
||||
joypad: Joypad::default(),
|
||||
gpu: Gpu::new(cgb, output.window, output.tile_window),
|
||||
gpu: Gpu::new(cgb, output.window, output.tile_window, output.layer_window),
|
||||
apu: Apu::new(output.audio),
|
||||
serial: Serial::new(output.serial_target),
|
||||
timers: Timer::init(),
|
||||
|
|
|
@ -40,6 +40,7 @@ where
|
|||
scanline: u8,
|
||||
lyc: u8,
|
||||
tile_window: Option<TileWindow<ColourFormat, R>>,
|
||||
layer_window: Option<(R, Vec<ColourFormat>)>,
|
||||
window_lc: u8,
|
||||
has_window_been_enabled: bool,
|
||||
bg_palette: Palette,
|
||||
|
@ -58,17 +59,30 @@ where
|
|||
ColourFormat: From<Colour> + Clone,
|
||||
R: Renderer<ColourFormat>,
|
||||
{
|
||||
pub fn new(cgb: bool, window: R, tile_window_renderer: Option<R>) -> Self {
|
||||
pub fn new(
|
||||
cgb: bool,
|
||||
window: R,
|
||||
tile_window_renderer: Option<R>,
|
||||
layer_window_renderer: Option<R>,
|
||||
) -> Self {
|
||||
let tile_window = tile_window_renderer
|
||||
.map(|tile_window_renderer| TileWindow::new(tile_window_renderer, cgb));
|
||||
let buffer = vec![
|
||||
if cgb {
|
||||
rgb_from_bytes(0xFFFF).into()
|
||||
} else {
|
||||
ColourInner::Error.rgb_bytes(None).into()
|
||||
};
|
||||
WIDTH * HEIGHT
|
||||
];
|
||||
|
||||
let blank_colour: ColourFormat = if cgb {
|
||||
rgb_from_bytes(0xFFFF).into()
|
||||
} else {
|
||||
ColourInner::Error.rgb_bytes(None).into()
|
||||
};
|
||||
|
||||
let buffer = vec![blank_colour.clone(); WIDTH * HEIGHT];
|
||||
|
||||
let layer_window = layer_window_renderer.map(|mut layer_window_renderer| {
|
||||
layer_window_renderer.prepare(WIDTH, HEIGHT * 3);
|
||||
(
|
||||
layer_window_renderer,
|
||||
vec![blank_colour; WIDTH * HEIGHT * 3],
|
||||
)
|
||||
});
|
||||
|
||||
Self {
|
||||
buffer,
|
||||
|
@ -83,6 +97,7 @@ where
|
|||
scanline: 0,
|
||||
lyc: 0xFF,
|
||||
tile_window,
|
||||
layer_window,
|
||||
window_lc: 0,
|
||||
has_window_been_enabled: false,
|
||||
bg_palette: Palette::from_byte(0xFC),
|
||||
|
@ -361,25 +376,28 @@ where
|
|||
}
|
||||
let x_coord = x_coord_uncorrected - 8;
|
||||
if x_coord < WIDTH {
|
||||
let cgb_data = self.cgb_data.as_ref().map(|v| {
|
||||
(
|
||||
&v.palettes.obj,
|
||||
if self.is_cgb_mode() {
|
||||
object.flags.cgb_palette
|
||||
} else {
|
||||
0
|
||||
},
|
||||
)
|
||||
});
|
||||
|
||||
let buffer_index = (scanline as usize * WIDTH) + x_coord;
|
||||
if (!object.flags.behind_bg_and_window && !self.is_bg_priority[x_coord])
|
||||
|| self.is_bg_zero[x_coord]
|
||||
|| (self.is_cgb_mode() && !self.lcdc.bg_window_enable)
|
||||
|| obj_priority
|
||||
{
|
||||
let cgb_data = self.cgb_data.as_ref().map(|v| {
|
||||
(
|
||||
&v.palettes.obj,
|
||||
if self.is_cgb_mode() {
|
||||
object.flags.cgb_palette
|
||||
} else {
|
||||
0
|
||||
},
|
||||
)
|
||||
});
|
||||
|
||||
self.buffer[buffer_index] = colour.rgb_bytes(cgb_data).into();
|
||||
}
|
||||
if let Some((_, ref mut buffer)) = self.layer_window {
|
||||
buffer[buffer_index + (2 * HEIGHT * WIDTH)] = colour.rgb_bytes(cgb_data).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -391,17 +409,17 @@ where
|
|||
tilemap: TilemapArea,
|
||||
offset_x: u8,
|
||||
offset_y: u8,
|
||||
wrap: bool,
|
||||
is_bg: bool,
|
||||
) {
|
||||
let (tile_line_y, did_wrap_y) = draw_from.overflowing_sub(offset_y);
|
||||
if did_wrap_y && !wrap {
|
||||
if did_wrap_y && !is_bg {
|
||||
return;
|
||||
}
|
||||
let tilemap_row = tile_line_y / 8;
|
||||
let row_addr = ((tilemap_row as usize * 32) % 0x400) as u16;
|
||||
for x in 0..WIDTH {
|
||||
let (tile_line_x, did_wrap_x) = (x as u8).overflowing_sub(offset_x);
|
||||
if did_wrap_x && !wrap {
|
||||
if did_wrap_x && !is_bg {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -460,10 +478,25 @@ where
|
|||
.map(|v| (&v.palettes.bg, attributes.palette));
|
||||
|
||||
self.buffer[(scanline as usize * WIDTH) + x] = colour.rgb_bytes(cgb_data).into();
|
||||
if let Some((_, ref mut buffer)) = self.layer_window {
|
||||
buffer[(scanline as usize * WIDTH) + x + if is_bg { 0 } else { HEIGHT * WIDTH }] =
|
||||
colour.rgb_bytes(cgb_data).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_window(&mut self) {
|
||||
self.window.display(&self.buffer);
|
||||
if let Some((ref mut window, ref mut buffer)) = self.layer_window {
|
||||
window.display(buffer);
|
||||
let blank_colour: ColourFormat = if self.cgb_data.is_some() {
|
||||
rgb_from_bytes(0xFFFF).into()
|
||||
} else {
|
||||
ColourInner::Error.rgb_bytes(None).into()
|
||||
};
|
||||
for val in buffer {
|
||||
*val = blank_colour.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue