public static void SaveSRAM() { if (board != null) { if (SaveSRAMAtShutdown && board.SRAMSaveRequired) { Trace.WriteLine("Saving SRAM ..."); byte[] sramBuffer = new byte[0]; ZlipWrapper.CompressData(board.GetSRAMBuffer(), out sramBuffer); Stream str = new FileStream(SRAMFileName, FileMode.Create, FileAccess.Write); str.Write(sramBuffer, 0, sramBuffer.Length); str.Flush(); str.Close(); Trace.WriteLine("SRAM saved successfully."); } } }
/// <summary> /// Save current game state as /// </summary> /// <param name="fileName">The complete path where to save the file</param> public void SaveStateAs(string fileName) { if (state_is_loading_state) { this.EmulationPaused = false; this.view.WriteNotification("Can't save state while loading a state !", 120, Color.Red); return; } if (state_is_saving_state) { this.EmulationPaused = false; this.view.WriteNotification("Already saving state !!", 120, Color.Red); return; } state_is_saving_state = true; // Create the stream Stream stream = new MemoryStream(); BinaryWriter bin = new BinaryWriter(stream); // Write header bin.Write(Encoding.ASCII.GetBytes("MNS")); // Write MNS (My Nes State) bin.Write(state_version); // Write version (1 byte) // Write SHA1 for compare later for (int i = 0; i < this.memory.board.RomSHA1.Length; i += 2) { string v = this.memory.board.RomSHA1.Substring(i, 2).ToUpper(); bin.Write(System.Convert.ToByte(v, 16)); } // Write data #region General bin.Write(this.emulator.palCyc); #endregion #region APU this.apu.SaveState(bin); #endregion #region CPU this.cpu.SaveState(bin); #endregion #region DMA this.dma.SaveState(bin); #endregion #region DMC this.apu.dmcChannel.SaveState(bin); #endregion #region Input bin.Write(this.input.PORT0); bin.Write(this.input.PORT1); bin.Write(this.input.inputStrobe); #endregion #region Interrupts this.interrupts.SaveState(bin); #endregion #region Memory this.memory.SaveState(bin); #endregion #region Noise this.apu.noiseChannel.SaveState(bin); #endregion #region PPU this.ppu.SaveState(bin); #endregion #region Pulse 1 this.apu.pulse1Channel.SaveState(bin); #endregion #region Pulse 2 this.apu.pulse2Channel.SaveState(bin); #endregion #region Triangle this.apu.triangleChannel.SaveState(bin); #endregion // Compress data ! byte[] outData = new byte[0]; ZlipWrapper.CompressData(((MemoryStream)bin.BaseStream).GetBuffer(), out outData); // Write file ! Stream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write); fileStream.Write(outData, 0, outData.Length); // Save snapshot this.view.TakeSnapshot(STATEFolder, Path.GetFileNameWithoutExtension(fileName), ".jpg", true); // Finished ! bin.Flush(); bin.Close(); fileStream.Flush(); fileStream.Close(); state_is_saving_state = false; this.EmulationPaused = false; this.view.WriteNotification("State saved at slot " + STATESlot, 120, Color.Green); }
/// <summary> /// Save current game state as /// </summary> /// <param name="fileName">The complete path where to save the file</param> public static void SaveStateAs(string fileName) { if (state_is_loading_state) { EmulationPaused = false; videoOut.WriteNotification("Can't save state while loading a state !", 120, Color.Red); return; } if (state_is_saving_state) { EmulationPaused = false; videoOut.WriteNotification("Already saving state !!", 120, Color.Red); return; } state_is_saving_state = true; // Create the stream Stream stream = new MemoryStream(); BinaryWriter bin = new BinaryWriter(stream); // Write header bin.Write(Encoding.ASCII.GetBytes("MNS")); // Write MNS (My Nes State) bin.Write(state_version); // Write version (1 byte) // Write SHA1 for compare later for (int i = 0; i < board.RomSHA1.Length; i += 2) { string v = board.RomSHA1.Substring(i, 2).ToUpper(); bin.Write(System.Convert.ToByte(v, 16)); } // Write data #region General bin.Write(palCyc); #endregion #region APU bin.Write(Cycles); bin.Write(SequencingMode); bin.Write(CurrentSeq); bin.Write(isClockingDuration); bin.Write(FrameIrqEnabled); bin.Write(FrameIrqFlag); bin.Write(oddCycle); #endregion #region CPU bin.Write(registers.a); bin.Write(registers.c); bin.Write(registers.d); bin.Write(registers.eah); bin.Write(registers.eal); bin.Write(registers.i); bin.Write(registers.n); bin.Write(registers.pch); bin.Write(registers.pcl); bin.Write(registers.sph); bin.Write(registers.spl); bin.Write(registers.v); bin.Write(registers.x); bin.Write(registers.y); bin.Write(registers.z); bin.Write(M); bin.Write(opcode); bin.Write(byte_temp); bin.Write(int_temp); bin.Write(int_temp1); bin.Write(dummy); #endregion #region DMA bin.Write(dmaDMCDMAWaitCycles); bin.Write(dmaOAMDMAWaitCycles); bin.Write(isOamDma); bin.Write(oamdma_i); bin.Write(dmaDMCOn); bin.Write(dmaOAMOn); bin.Write(dmaDMC_occurring); bin.Write(dmaOAM_occurring); bin.Write(dmaOAMFinishCounter); bin.Write(dmaOamaddress); bin.Write(OAMCYCLE); bin.Write(latch); #endregion #region DMC bin.Write(DeltaIrqOccur); bin.Write(DMCIrqEnabled); bin.Write(dmc_dmaLooping); bin.Write(dmc_dmaEnabled); bin.Write(dmc_bufferFull); bin.Write(dmc_dmaAddrRefresh); bin.Write(dmc_dmaSizeRefresh); bin.Write(dmc_dmaSize); bin.Write(dmc_dmaBits); bin.Write(dmc_dmaByte); bin.Write(dmc_dmaAddr); bin.Write(dmc_dmaBuffer); bin.Write(dmc_output); bin.Write(dmc_cycles); bin.Write(dmc_freqTimer); #endregion #region Input bin.Write(PORT0); bin.Write(PORT1); bin.Write(inputStrobe); #endregion #region Interrupts bin.Write(NMI_Current); bin.Write(NMI_Old); bin.Write(NMI_Detected); bin.Write(IRQFlags); bin.Write(IRQ_Detected); bin.Write(interrupt_vector); bin.Write(interrupt_suspend_nmi); bin.Write(interrupt_suspend_irq); bin.Write(nmi_enabled); bin.Write(nmi_old); bin.Write(vbl_flag); bin.Write(vbl_flag_temp); #endregion #region Memory board.SaveState(bin); bin.Write(WRAM); bin.Write(palettes_bank); bin.Write(oam_ram); bin.Write(oam_secondary); bin.Write(BUS_ADDRESS); bin.Write(BUS_RW); bin.Write(BUS_RW_P); bin.Write(temp_4015); bin.Write(temp_4016); bin.Write(temp_4017); #endregion #region Noise bin.Write(noz_envelope); bin.Write(noz_env_startflag); bin.Write(noz_env_counter); bin.Write(noz_env_devider); bin.Write(noz_length_counter_halt_flag); bin.Write(noz_constant_volume_flag); bin.Write(noz_volume_decay_time); bin.Write(noz_duration_haltRequset); bin.Write(noz_duration_counter); bin.Write(noz_duration_reloadEnabled); bin.Write(noz_duration_reload); bin.Write(noz_duration_reloadRequst); bin.Write(noz_mode); bin.Write(noz_shiftRegister); bin.Write(noz_feedback); bin.Write(noz_frequency); bin.Write(noz_cycles); #endregion #region PPU bin.Write(VClock); bin.Write(HClock); bin.Write(oddSwap); bin.Write(current_pixel); bin.Write(temp); bin.Write(temp_comparator); bin.Write(bkg_pos); bin.Write(spr_pos); bin.Write(object0); bin.Write(infront); bin.Write(bkgPixel); bin.Write(sprPixel); bin.Write(bkg_fetch_address); bin.Write(bkg_fetch_nametable); bin.Write(bkg_fetch_attr); bin.Write(bkg_fetch_bit0); bin.Write(bkg_fetch_bit1); bin.Write(spr_fetch_address); bin.Write(spr_fetch_bit0); bin.Write(spr_fetch_bit1); bin.Write(spr_fetch_attr); for (int i = 0; i < spr_zero_buffer.Length; i++) { bin.Write(spr_zero_buffer[i]); } bin.Write(vram_temp); bin.Write(vram_address); bin.Write(vram_address_temp_access); bin.Write(vram_address_temp_access1); bin.Write(vram_increament); bin.Write(vram_flipflop); bin.Write(vram_fine); bin.Write(reg2007buffer); bin.Write(bkg_enabled); bin.Write(bkg_clipped); bin.Write(bkg_patternAddress); bin.Write(spr_enabled); bin.Write(spr_clipped); bin.Write(spr_patternAddress); bin.Write(spr_size16); bin.Write(spr_0Hit); bin.Write(spr_overflow); bin.Write(grayscale); bin.Write(emphasis); bin.Write(ppu_2002_temp); bin.Write(ppu_2004_temp); bin.Write(ppu_2007_temp); bin.Write(oam_address); bin.Write(oam_fetch_data); bin.Write(oam_evaluate_slot); bin.Write(oam_evaluate_count); bin.Write(oam_fetch_mode); bin.Write(oam_phase_index); bin.Write(spr_render_i); bin.Write(bkg_render_i); bin.Write(spr_evaluation_i); bin.Write(spr_render_temp_pixel); #endregion #region Pulse 1 bin.Write(sq1_envelope); bin.Write(sq1_env_startflag); bin.Write(sq1_env_counter); bin.Write(sq1_env_devider); bin.Write(sq1_length_counter_halt_flag); bin.Write(sq1_constant_volume_flag); bin.Write(sq1_volume_decay_time); bin.Write(sq1_duration_haltRequset); bin.Write(sq1_duration_counter); bin.Write(sq1_duration_reloadEnabled); bin.Write(sq1_duration_reload); bin.Write(sq1_duration_reloadRequst); bin.Write(sq1_dutyForm); bin.Write(sq1_dutyStep); bin.Write(sq1_sweepDeviderPeriod); bin.Write(sq1_sweepShiftCount); bin.Write(sq1_sweepCounter); bin.Write(sq1_sweepEnable); bin.Write(sq1_sweepReload); bin.Write(sq1_sweepNegateFlag); bin.Write(sq1_frequency); bin.Write(sq1_sweep); bin.Write(sq1_cycles); #endregion #region Pulse 2 bin.Write(sq2_envelope); bin.Write(sq2_env_startflag); bin.Write(sq2_env_counter); bin.Write(sq2_env_devider); bin.Write(sq2_length_counter_halt_flag); bin.Write(sq2_constant_volume_flag); bin.Write(sq2_volume_decay_time); bin.Write(sq2_duration_haltRequset); bin.Write(sq2_duration_counter); bin.Write(sq2_duration_reloadEnabled); bin.Write(sq2_duration_reload); bin.Write(sq2_duration_reloadRequst); bin.Write(sq2_dutyForm); bin.Write(sq2_dutyStep); bin.Write(sq2_sweepDeviderPeriod); bin.Write(sq2_sweepShiftCount); bin.Write(sq2_sweepCounter); bin.Write(sq2_sweepEnable); bin.Write(sq2_sweepReload); bin.Write(sq2_sweepNegateFlag); bin.Write(sq2_frequency); bin.Write(sq2_sweep); bin.Write(sq2_cycles); #endregion #region Triangle bin.Write(trl_length_counter_halt_flag); bin.Write(trl_duration_haltRequset); bin.Write(trl_duration_counter); bin.Write(trl_duration_reloadEnabled); bin.Write(trl_duration_reload); bin.Write(trl_duration_reloadRequst); bin.Write(trl_linearCounter); bin.Write(trl_linearCounterReload); bin.Write(trl_step); bin.Write(trl_linearCounterHalt); bin.Write(trl_halt); bin.Write(trl_frequency); bin.Write(trl_cycles); #endregion // Compress data ! byte[] outData = new byte[0]; ZlipWrapper.CompressData(((MemoryStream)bin.BaseStream).GetBuffer(), out outData); // Write file ! Stream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write); fileStream.Write(outData, 0, outData.Length); // Save snapshot videoOut.TakeSnapshot(STATEFolder, Path.GetFileNameWithoutExtension(fileName), ".jpg", true); // Finished ! bin.Flush(); bin.Close(); fileStream.Flush(); fileStream.Close(); state_is_saving_state = false; EmulationPaused = false; videoOut.WriteNotification("State saved at slot " + STATESlot, 120, Color.Green); }