Implement frame advance
This commit is contained in:
		
							parent
							
								
									e96ce2af07
								
							
						
					
					
						commit
						f2d3f5ec07
					
				| 
						 | 
				
			
			@ -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,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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| {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue