Compare commits

..

3 Commits

3 changed files with 57 additions and 7 deletions

View File

@ -291,6 +291,26 @@ impl Emulator {
);
}
fn frame_advance(&mut self) {
if self
.state
.compare_exchange(
EmulatorState::Paused,
EmulatorState::Stepping,
Ordering::AcqRel,
Ordering::Acquire,
)
.is_err_and(|s| s == EmulatorState::Running)
{
let _ = self.state.compare_exchange(
EmulatorState::Running,
EmulatorState::Stepping,
Ordering::AcqRel,
Ordering::Relaxed,
);
}
}
fn save_sram(&mut self, sim_id: SimId) -> Result<()> {
let sim = self.sims.get_mut(sim_id.to_index());
let cart = self.carts[sim_id.to_index()].as_mut();
@ -366,6 +386,7 @@ impl Emulator {
debugger.stop_reason = None;
true
}
fn debug_step(&mut self, sim_id: SimId) {
if self.debug_continue(sim_id) {
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
@ -428,7 +449,7 @@ impl Emulator {
// Don't emulate if the state is "paused", or if any sim is paused in the debugger
let running = match state {
EmulatorState::Paused => false,
EmulatorState::Running => true,
EmulatorState::Running | EmulatorState::Stepping => true,
EmulatorState::Debugging => self.debuggers.values().all(|d| d.stop_reason.is_none()),
};
let p1_running = running && p1_state == SimState::Ready;
@ -442,6 +463,10 @@ impl Emulator {
self.sims[SimId::Player2.to_index()].emulate();
}
if state == EmulatorState::Stepping {
self.state.store(EmulatorState::Paused, Ordering::Release);
}
// Debug state
if state == EmulatorState::Debugging {
for sim_id in SimId::values() {
@ -539,6 +564,9 @@ impl Emulator {
EmulatorCommand::Resume => {
self.resume_sims();
}
EmulatorCommand::FrameAdvance => {
self.frame_advance();
}
EmulatorCommand::StartDebugging(sim_id, debugger) => {
self.start_debugging(sim_id, debugger);
}
@ -665,6 +693,7 @@ pub enum EmulatorCommand {
StopSecondSim,
Pause,
Resume,
FrameAdvance,
StartDebugging(SimId, DebugSender),
StopDebugging(SimId),
DebugInterrupt(SimId),
@ -700,6 +729,7 @@ pub enum SimState {
pub enum EmulatorState {
Paused,
Running,
Stepping,
Debugging,
}

View File

@ -86,6 +86,7 @@ impl GameWindow {
let is_ready = self.client.sim_state(self.sim_id) == SimState::Ready;
let can_pause = is_ready && state == EmulatorState::Running;
let can_resume = is_ready && state == EmulatorState::Paused;
let can_frame_advance = is_ready && state != EmulatorState::Debugging;
if state == EmulatorState::Running {
if ui.add_enabled(can_pause, Button::new("Pause")).clicked() {
self.client.send_command(EmulatorCommand::Pause);
@ -100,6 +101,14 @@ impl GameWindow {
.send_command(EmulatorCommand::Reset(self.sim_id));
ui.close_menu();
}
ui.separator();
if ui
.add_enabled(can_frame_advance, Button::new("Frame Advance"))
.clicked()
{
self.client.send_command(EmulatorCommand::FrameAdvance);
ui.close_menu();
}
});
ui.menu_button("Options", |ui| self.show_options_menu(ctx, ui));
ui.menu_button("Multiplayer", |ui| {

View File

@ -643,6 +643,15 @@ impl WorldRenderer {
shades.map(|s| shade(s, params.right_color)),
]
};
let palettes = {
let palettes = self.palettes.borrow().read::<[u8; 8]>(0);
[
utils::parse_palette(palettes[0]),
utils::parse_palette(palettes[2]),
utils::parse_palette(palettes[4]),
utils::parse_palette(palettes[6]),
]
};
let chardata = self.chardata.borrow();
let bgmaps = self.bgmaps.borrow();
@ -667,7 +676,8 @@ impl WorldRenderer {
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 shade = palettes[cell.palette_index][pixel as usize];
image.add((dx as usize, dy as usize), colors[0][shade as usize]);
}
let dx = x + world.dst_x + world.dst_parallax;
@ -680,7 +690,8 @@ impl WorldRenderer {
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[1][pixel as usize]);
let shade = palettes[cell.palette_index][pixel as usize];
image.add((dx as usize, dy as usize), colors[1][shade as usize]);
}
}
}
@ -976,8 +987,8 @@ impl<'a> SourceCoordCalculator<'a> {
(sx, sy)
}
SourceParam::Affine(affine) => {
let sx = affine_coord(affine.src_x, x, affine.dx, affine.src_parallax.min(0).abs());
let sy = affine_coord(affine.src_y, x, affine.dy, affine.src_parallax.min(0).abs());
let sx = affine_coord(affine.src_x, x, affine.dx, affine.src_parallax.min(0));
let sy = affine_coord(affine.src_y, x, affine.dy, affine.src_parallax.min(0));
(sx, sy)
}
}
@ -997,8 +1008,8 @@ impl<'a> SourceCoordCalculator<'a> {
(sx, sy)
}
SourceParam::Affine(affine) => {
let sx = affine_coord(affine.src_x, x, affine.dx, -affine.src_parallax.max(0));
let sy = affine_coord(affine.src_y, x, affine.dy, -affine.src_parallax.max(0));
let sx = affine_coord(affine.src_x, x, affine.dx, affine.src_parallax.max(0));
let sy = affine_coord(affine.src_y, x, affine.dy, affine.src_parallax.max(0));
(sx, sy)
}
}