private void InitSaveRamBuff() { int size = 0; LibQuickNES.ThrowStringError(QN.qn_battery_ram_size(Context, ref size)); _saveRamBuff = new byte[size]; }
public void FrameAdvance(bool render, bool rendersound = true) { using (FP.Save()) { if (Controller["Power"]) { LibQuickNES.qn_reset(Context, true); } if (Controller["Reset"]) { LibQuickNES.qn_reset(Context, false); } int j1, j2; SetPads(out j1, out j2); Frame++; LibQuickNES.ThrowStringError(LibQuickNES.qn_emulate_frame(Context, j1, j2)); IsLagFrame = LibQuickNES.qn_get_joypad_read_count(Context) == 0; if (IsLagFrame) { LagCount++; } Blit(); DrainAudio(); } }
private void InitSaveStateBuff() { int size = 0; LibQuickNES.ThrowStringError(QN.qn_state_size(Context, ref size)); _saveStateBuff = new byte[size]; }
public bool PutSettings(object o) { _Settings = (QuickNESSettings)o; LibQuickNES.qn_set_sprite_limit(Context, _Settings.NumSprites); RecalculateCrops(); return(false); }
void InitSaveStateBuff() { int size = 0; LibQuickNES.ThrowStringError(LibQuickNES.qn_state_size(Context, ref size)); SaveStateBuff = new byte[size]; SaveStateBuff2 = new byte[size + 13]; }
public void Dispose() { if (Context != IntPtr.Zero) { LibQuickNES.qn_delete(Context); Context = IntPtr.Zero; } }
private static byte[] GetDefaultColors() { IntPtr src = LibQuickNES.qn_get_default_colors(); byte[] ret = new byte[1536]; Marshal.Copy(src, ret, 0, 1536); return(ret); }
public bool PutSettings(QuickNESSettings o) { _settings = o; LibQuickNES.qn_set_sprite_limit(Context, _settings.NumSprites); RecalculateCrops(); CalculatePalette(); return(false); }
public void SaveStateBinary(System.IO.BinaryWriter writer) { LibQuickNES.ThrowStringError(LibQuickNES.qn_state_save(Context, SaveStateBuff, SaveStateBuff.Length)); writer.Write(SaveStateBuff.Length); writer.Write(SaveStateBuff); // other variables writer.Write(IsLagFrame); writer.Write(LagCount); writer.Write(Frame); }
public bool FrameAdvance(IController controller, bool render, bool rendersound = true) { CheckDisposed(); using (FP.Save()) { if (controller.IsPressed("Power")) { QN.qn_reset(Context, true); } if (controller.IsPressed("Reset")) { QN.qn_reset(Context, false); } int j1, j2; SetPads(controller, out j1, out j2); if (Tracer.Enabled) { QN.qn_set_tracecb(Context, _tracecb); } else { QN.qn_set_tracecb(Context, null); } Frame++; LibQuickNES.ThrowStringError(QN.qn_emulate_frame(Context, j1, j2)); IsLagFrame = QN.qn_get_joypad_read_count(Context) == 0; if (IsLagFrame) { LagCount++; } if (render) { Blit(); } if (rendersound) { DrainAudio(); } if (CB1 != null) { CB1(); } if (CB2 != null) { CB2(); } } return(true); }
public QuickNES(CoreComm comm, byte[] file, object Settings, object SyncSettings) { using (FP.Save()) { ServiceProvider = new BasicServiceProvider(this); CoreComm = comm; Context = QN.qn_new(); if (Context == IntPtr.Zero) { throw new InvalidOperationException("qn_new() returned NULL"); } try { file = fix_ines_header(file); unsafe { fixed(byte *p = file) { Console.WriteLine((IntPtr)p); LibQuickNES.ThrowStringError(QN.qn_loadines(Context, file, file.Length)); } } InitSaveRamBuff(); InitSaveStateBuff(); InitAudio(); InitMemoryDomains(); int mapper = 0; string mappername = Marshal.PtrToStringAnsi(QN.qn_get_mapper(Context, ref mapper)); Console.WriteLine("QuickNES: Booted with Mapper #{0} \"{1}\"", mapper, mappername); BoardName = mappername; CoreComm.VsyncNum = 39375000; CoreComm.VsyncDen = 655171; PutSettings((QuickNESSettings)Settings ?? new QuickNESSettings()); _syncSettings = (QuickNESSyncSettings)SyncSettings ?? new QuickNESSyncSettings(); _syncSettingsNext = _syncSettings.Clone(); SetControllerDefinition(); ComputeBootGod(); ConnectTracer(); } catch { Dispose(); throw; } } }
public void SaveStateBinary(BinaryWriter writer) { CheckDisposed(); LibQuickNES.ThrowStringError(QN.qn_state_save(Context, _saveStateBuff, _saveStateBuff.Length)); writer.Write(_saveStateBuff.Length); writer.Write(_saveStateBuff); // other variables writer.Write(IsLagFrame); writer.Write(LagCount); writer.Write(Frame); }
public bool PutSettings(QuickNESSettings o) { _settings = o; LibQuickNES.qn_set_sprite_limit(Context, _settings.NumSprites); RecalculateCrops(); CalculatePalette(); CoreComm.ScreenLogicalOffsetX = o.ClipLeftAndRight ? 8 : 0; CoreComm.ScreenLogicalOffsetY = o.ClipTopAndBottom ? 8 : 0; return(false); }
public void Dispose() { if (Context != IntPtr.Zero) { LibQuickNES.qn_delete(Context); Context = IntPtr.Zero; } if (VideoOutput != null) { VideoOutputH.Free(); VideoOutput = null; } }
public IDictionary <string, RegisterValue> GetCpuFlagsAndRegisters() { int[] regs = new int[6]; var ret = new Dictionary <string, RegisterValue>(); LibQuickNES.qn_get_cpuregs(Context, regs); ret["A"] = (byte)regs[0]; ret["X"] = (byte)regs[1]; ret["Y"] = (byte)regs[2]; ret["SP"] = (ushort)regs[3]; ret["PC"] = (ushort)regs[4]; ret["P"] = (byte)regs[5]; return(ret); }
unsafe void InitMemoryDomains() { List <MemoryDomain> mm = new List <MemoryDomain>(); for (int i = 0; ; i++) { IntPtr data = IntPtr.Zero; int size = 0; bool writable = false; IntPtr name = IntPtr.Zero; if (!LibQuickNES.qn_get_memory_area(Context, i, ref data, ref size, ref writable, ref name)) { break; } if (data != IntPtr.Zero && size > 0 && name != IntPtr.Zero) { mm.Add(MemoryDomain.FromIntPtr(Marshal.PtrToStringAnsi(name), size, MemoryDomain.Endian.Little, data, writable)); } } // add system bus mm.Add(new MemoryDomain ( "System Bus", 0x10000, MemoryDomain.Endian.Unknown, delegate(long addr) { if (addr < 0 || addr >= 0x10000) { throw new ArgumentOutOfRangeException(); } return(LibQuickNES.qn_peek_prgbus(Context, (int)addr)); }, delegate(long addr, byte val) { if (addr < 0 || addr >= 0x10000) { throw new ArgumentOutOfRangeException(); } LibQuickNES.qn_poke_prgbus(Context, (int)addr, val); } )); _memoryDomains = new MemoryDomainList(mm); (ServiceProvider as BasicServiceProvider).Register <IMemoryDomains>(_memoryDomains); }
public void LoadStateBinary(System.IO.BinaryReader reader) { int len = reader.ReadInt32(); if (len != SaveStateBuff.Length) { throw new InvalidOperationException("Unexpected savestate buffer length!"); } reader.Read(SaveStateBuff, 0, SaveStateBuff.Length); LibQuickNES.ThrowStringError(LibQuickNES.qn_state_load(Context, SaveStateBuff, SaveStateBuff.Length)); // other variables IsLagFrame = reader.ReadBoolean(); LagCount = reader.ReadInt32(); Frame = reader.ReadInt32(); }
public QuickNES(CoreComm comm, byte[] file, object settings, object syncSettings) { FP = OSTailoredCode.IsUnixHost ? (IFPCtrl) new Unix_FPCtrl() : new Win32_FPCtrl(); using (FP.Save()) { ServiceProvider = new BasicServiceProvider(this); CoreComm = comm; Context = QN.qn_new(); if (Context == IntPtr.Zero) { throw new InvalidOperationException($"{nameof(QN.qn_new)}() returned NULL"); } try { file = FixInesHeader(file); LibQuickNES.ThrowStringError(QN.qn_loadines(Context, file, file.Length)); InitSaveRamBuff(); InitSaveStateBuff(); InitAudio(); InitMemoryDomains(); int mapper = 0; string mappername = Marshal.PtrToStringAnsi(QN.qn_get_mapper(Context, ref mapper)); Console.WriteLine("QuickNES: Booted with Mapper #{0} \"{1}\"", mapper, mappername); BoardName = mappername; PutSettings((QuickNESSettings)settings ?? new QuickNESSettings()); _syncSettings = (QuickNESSyncSettings)syncSettings ?? new QuickNESSyncSettings(); _syncSettingsNext = _syncSettings.Clone(); SetControllerDefinition(); ComputeBootGod(); ConnectTracer(); } catch { Dispose(); throw; } } }
void DrainAudio() { NumSamples = LibQuickNES.qn_read_audio(Context, MonoBuff, MonoBuff.Length); unsafe { fixed(short *_src = &MonoBuff[0], _dst = &StereoBuff[0]) { short *src = _src; short *dst = _dst; for (int i = 0; i < NumSamples; i++) { *dst++ = *src; *dst++ = *src++; } } } }
public bool FrameAdvance(IController controller, bool render, bool rendersound = true) { CheckDisposed(); using (FP.Save()) { if (controller.IsPressed("Power")) { QN.qn_reset(Context, true); } if (controller.IsPressed("Reset")) { QN.qn_reset(Context, false); } SetPads(controller, out var j1, out var j2); QN.qn_set_tracecb(Context, Tracer.IsEnabled() ? _traceCb : null); LibQuickNES.ThrowStringError(QN.qn_emulate_frame(Context, j1, j2)); IsLagFrame = QN.qn_get_joypad_read_count(Context) == 0; if (IsLagFrame) { LagCount++; } if (render) { Blit(); } if (rendersound) { DrainAudio(); } _callBack1?.Invoke(); _callBack2?.Invoke(); Frame++; return(true); } }
public QuickNES(CoreComm nextComm, byte[] Rom, object Settings) { using (FP.Save()) { CoreComm = nextComm; Context = LibQuickNES.qn_new(); if (Context == IntPtr.Zero) { throw new InvalidOperationException("qn_new() returned NULL"); } try { LibQuickNES.ThrowStringError(LibQuickNES.qn_loadines(Context, Rom, Rom.Length)); InitSaveRamBuff(); InitSaveStateBuff(); InitVideo(); InitAudio(); InitMemoryDomains(); int mapper = 0; string mappername = Marshal.PtrToStringAnsi(LibQuickNES.qn_get_mapper(Context, ref mapper)); Console.WriteLine("QuickNES: Booted with Mapper #{0} \"{1}\"", mapper, mappername); BoardName = mappername; CoreComm.VsyncNum = 39375000; CoreComm.VsyncDen = 655171; PutSettings(Settings ?? new QuickNESSettings()); ComputeBootGod(); } catch { Dispose(); throw; } } }
public byte[] CloneSaveRam() { LibQuickNES.ThrowStringError(QN.qn_battery_ram_save(Context, _saveRamBuff, _saveRamBuff.Length)); return((byte[])_saveRamBuff.Clone()); }
static QuickNES() { Resolver = new DynamicLibraryImportResolver(LibQuickNES.dllname); QN = BizInvoker.GetInvoker <LibQuickNES>(Resolver); }
private void InitAudio() { LibQuickNES.ThrowStringError(QN.qn_set_sample_rate(Context, 44100)); }
public void StoreSaveRam(byte[] data) { LibQuickNES.ThrowStringError(QN.qn_battery_ram_load(Context, data, data.Length)); }
public byte PeekPPU(int addr) { return(LibQuickNES.qn_peek_ppu(Context, addr)); }
public byte[] GetOam() { Marshal.Copy(LibQuickNES.qn_get_oammem(Context), oambuf, 0, 0x100); return(oambuf); }
public byte[] GetPalRam() { Marshal.Copy(LibQuickNES.qn_get_palmem(Context), palrambuf, 0, 0x20); return(palrambuf); }
public byte[] GetPPUBus() { LibQuickNES.qn_peek_ppubus(Context, ppubusbuf); return(ppubusbuf); }
static QuickNES() { LibQuickNES.qn_setup_mappers(); }