2011-01-21 03:59:50 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
2011-01-11 02:55:51 +00:00
|
|
|
|
|
|
|
|
|
namespace BizHawk
|
|
|
|
|
{
|
2011-07-30 20:49:36 +00:00
|
|
|
|
public interface IEmulator : IDisposable
|
|
|
|
|
{
|
|
|
|
|
IVideoProvider VideoProvider { get; }
|
2012-10-11 01:14:14 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// sound provider for async operation. this is optional, and is only required after StartAsyncSound() is called and returns true
|
|
|
|
|
/// </summary>
|
2011-07-30 20:49:36 +00:00
|
|
|
|
ISoundProvider SoundProvider { get; }
|
2012-10-11 01:14:14 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// sound provider for sync operation. this is manditory
|
|
|
|
|
/// </summary>
|
sound api changes. added a new ISyncSoundProvider, which works similarly to ISoundProvider except the source (not the sink) determines the number of samples to process. Added facilities to metaspu, dcfilter, speexresampler to work with ISyncSoundProvider. Add ISyncSoundProvider to IEmulator. All IEmulators must provide sync sound, but they need not provide async sound. When async is needed and an IEmulator doesn't provide it, the frontend will wrap it in a vecna metaspu. SNES, GB changed to provide sync sound only. All other emulator cores mostly unchanged; they just provide stub fakesync alongside async, for now. For the moment, the only use of the sync sound is for realtime audio throttling, where it works and sounds quite nice. In the future, sync sound will be supported for AV dumping as well.
2012-10-11 00:44:59 +00:00
|
|
|
|
ISyncSoundProvider SyncSoundProvider { get; }
|
2012-10-11 01:14:14 +00:00
|
|
|
|
/// <summary>start async operation. (on construct, sync operation is assumed).</summary>
|
|
|
|
|
/// <returns>false if core doesn't support async sound; SyncSoundProvider will continue to be used in that case</returns>
|
sound api changes. added a new ISyncSoundProvider, which works similarly to ISoundProvider except the source (not the sink) determines the number of samples to process. Added facilities to metaspu, dcfilter, speexresampler to work with ISyncSoundProvider. Add ISyncSoundProvider to IEmulator. All IEmulators must provide sync sound, but they need not provide async sound. When async is needed and an IEmulator doesn't provide it, the frontend will wrap it in a vecna metaspu. SNES, GB changed to provide sync sound only. All other emulator cores mostly unchanged; they just provide stub fakesync alongside async, for now. For the moment, the only use of the sync sound is for realtime audio throttling, where it works and sounds quite nice. In the future, sync sound will be supported for AV dumping as well.
2012-10-11 00:44:59 +00:00
|
|
|
|
bool StartAsyncSound();
|
2012-10-11 01:14:14 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// end async operation, returning to sync operation. after this, all sound requests will go to the SyncSoundProvider
|
|
|
|
|
/// </summary>
|
sound api changes. added a new ISyncSoundProvider, which works similarly to ISoundProvider except the source (not the sink) determines the number of samples to process. Added facilities to metaspu, dcfilter, speexresampler to work with ISyncSoundProvider. Add ISyncSoundProvider to IEmulator. All IEmulators must provide sync sound, but they need not provide async sound. When async is needed and an IEmulator doesn't provide it, the frontend will wrap it in a vecna metaspu. SNES, GB changed to provide sync sound only. All other emulator cores mostly unchanged; they just provide stub fakesync alongside async, for now. For the moment, the only use of the sync sound is for realtime audio throttling, where it works and sounds quite nice. In the future, sync sound will be supported for AV dumping as well.
2012-10-11 00:44:59 +00:00
|
|
|
|
void EndAsyncSound();
|
2011-07-30 20:49:36 +00:00
|
|
|
|
|
|
|
|
|
ControllerDefinition ControllerDefinition { get; }
|
|
|
|
|
IController Controller { get; set; }
|
|
|
|
|
|
2012-10-11 01:14:14 +00:00
|
|
|
|
// note that some? cores expect you to call SoundProvider.GetSamples() after each FrameAdvance()
|
2012-09-20 19:52:47 +00:00
|
|
|
|
// please do this, even when rendersound = false
|
2012-09-20 20:00:14 +00:00
|
|
|
|
void FrameAdvance(bool render, bool rendersound = true);
|
2011-07-30 20:49:36 +00:00
|
|
|
|
|
|
|
|
|
int Frame { get; }
|
|
|
|
|
int LagCount { get; set; }
|
|
|
|
|
bool IsLagFrame { get; }
|
|
|
|
|
string SystemId { get; }
|
2012-10-03 15:31:04 +00:00
|
|
|
|
/// <summary>if you want to set this, look in the emulator's constructor or Load() method</summary>
|
|
|
|
|
bool DeterministicEmulation { get; }
|
2011-07-30 20:49:36 +00:00
|
|
|
|
|
2013-08-24 16:54:22 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// identifying information about a "mapper" or similar capability. null if no such useful distinction can be drawn
|
|
|
|
|
/// </summary>
|
|
|
|
|
string BoardName { get; }
|
|
|
|
|
|
2012-09-04 07:09:00 +00:00
|
|
|
|
/// <summary>
|
2012-09-14 22:28:38 +00:00
|
|
|
|
/// return a copy of the saveram. editing it won't do you any good unless you later call StoreSaveRam()
|
2012-09-04 07:09:00 +00:00
|
|
|
|
/// </summary>
|
2012-09-14 22:28:38 +00:00
|
|
|
|
byte[] ReadSaveRam();
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// store new saveram to the emu core. the data should be the same size as the return from ReadSaveRam()
|
|
|
|
|
/// </summary>
|
|
|
|
|
void StoreSaveRam(byte[] data);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// reset saveram to a standard initial state
|
|
|
|
|
/// </summary>
|
|
|
|
|
void ClearSaveRam();
|
|
|
|
|
|
|
|
|
|
|
2011-07-30 20:49:36 +00:00
|
|
|
|
bool SaveRamModified { get; set; }
|
|
|
|
|
|
2013-11-03 16:29:51 +00:00
|
|
|
|
void ResetCounters();
|
2011-07-30 20:49:36 +00:00
|
|
|
|
void SaveStateText(TextWriter writer);
|
|
|
|
|
void LoadStateText(TextReader reader);
|
|
|
|
|
void SaveStateBinary(BinaryWriter writer);
|
|
|
|
|
void LoadStateBinary(BinaryReader reader);
|
|
|
|
|
byte[] SaveStateBinary();
|
2011-01-21 03:59:50 +00:00
|
|
|
|
|
2013-05-06 20:51:28 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// true if the core would rather give a binary savestate than a text one. both must function regardless
|
|
|
|
|
/// </summary>
|
|
|
|
|
bool BinarySaveStatesPreferred { get; }
|
|
|
|
|
|
2012-12-10 00:43:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// the corecomm module in use by this core.
|
|
|
|
|
/// </summary>
|
|
|
|
|
CoreComm CoreComm { get; }
|
2011-02-21 09:48:53 +00:00
|
|
|
|
|
2011-07-30 20:49:36 +00:00
|
|
|
|
// ----- Client Debugging API stuff -----
|
|
|
|
|
IList<MemoryDomain> MemoryDomains { get; }
|
2012-09-11 17:37:17 +00:00
|
|
|
|
// this MUST BE the same as MemoryDomains[0], else DRAGONS
|
2011-07-30 20:49:36 +00:00
|
|
|
|
MemoryDomain MainMemory { get; }
|
|
|
|
|
}
|
2011-01-21 03:59:50 +00:00
|
|
|
|
|
2011-07-30 20:49:36 +00:00
|
|
|
|
public class MemoryDomain
|
|
|
|
|
{
|
|
|
|
|
public readonly string Name;
|
|
|
|
|
public readonly int Size;
|
|
|
|
|
public readonly Endian Endian;
|
2011-01-21 03:59:50 +00:00
|
|
|
|
|
2011-07-30 20:49:36 +00:00
|
|
|
|
public readonly Func<int, byte> PeekByte;
|
|
|
|
|
public readonly Action<int, byte> PokeByte;
|
2011-08-03 02:13:42 +00:00
|
|
|
|
|
2011-07-30 20:49:36 +00:00
|
|
|
|
public MemoryDomain(string name, int size, Endian endian, Func<int, byte> peekByte, Action<int, byte> pokeByte)
|
|
|
|
|
{
|
|
|
|
|
Name = name;
|
|
|
|
|
Size = size;
|
|
|
|
|
Endian = endian;
|
|
|
|
|
PeekByte = peekByte;
|
|
|
|
|
PokeByte = pokeByte;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-04 00:20:36 +00:00
|
|
|
|
public MemoryDomain()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-30 20:49:36 +00:00
|
|
|
|
public MemoryDomain(MemoryDomain domain)
|
|
|
|
|
{
|
|
|
|
|
Name = domain.Name;
|
|
|
|
|
Size = domain.Size;
|
|
|
|
|
Endian = domain.Endian;
|
|
|
|
|
PeekByte = domain.PeekByte;
|
|
|
|
|
PokeByte = domain.PokeByte;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
|
|
|
|
return Name;
|
|
|
|
|
}
|
2013-09-21 14:32:37 +00:00
|
|
|
|
|
|
|
|
|
public ushort PeekWord(int addr, Endian endian)
|
|
|
|
|
{
|
|
|
|
|
switch (endian)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case Endian.Big:
|
|
|
|
|
return (ushort)((PeekByte(addr) << 8) | (PeekByte(addr + 1)));
|
|
|
|
|
case Endian.Little:
|
|
|
|
|
return (ushort)((PeekByte(addr)) | (PeekByte(addr + 1) << 8));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public uint PeekDWord(int addr, Endian endian)
|
|
|
|
|
{
|
|
|
|
|
switch (endian)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case Endian.Big:
|
|
|
|
|
return (uint)((PeekByte(addr) << 24)
|
|
|
|
|
| (PeekByte(addr + 1) << 16)
|
|
|
|
|
| (PeekByte(addr + 2) << 8)
|
|
|
|
|
| (PeekByte(addr + 3) << 0));
|
|
|
|
|
case Endian.Little:
|
|
|
|
|
return (uint)((PeekByte(addr) << 0)
|
|
|
|
|
| (PeekByte(addr + 1) << 8)
|
|
|
|
|
| (PeekByte(addr + 2) << 16)
|
|
|
|
|
| (PeekByte(addr + 3) << 24));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PokeWord(int addr, ushort val, Endian endian)
|
|
|
|
|
{
|
|
|
|
|
switch (endian)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case Endian.Big:
|
|
|
|
|
PokeByte(addr + 0, (byte)(val >> 8));
|
|
|
|
|
PokeByte(addr + 1, (byte)(val));
|
|
|
|
|
break;
|
|
|
|
|
case Endian.Little:
|
|
|
|
|
PokeByte(addr + 0, (byte)(val));
|
|
|
|
|
PokeByte(addr + 1, (byte)(val >> 8));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void PokeDWord(int addr, uint val, Endian endian)
|
|
|
|
|
{
|
|
|
|
|
switch (endian)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case Endian.Big:
|
|
|
|
|
PokeByte(addr + 0, (byte)(val >> 24));
|
|
|
|
|
PokeByte(addr + 1, (byte)(val >> 16));
|
|
|
|
|
PokeByte(addr + 2, (byte)(val >> 8));
|
|
|
|
|
PokeByte(addr + 3, (byte)(val));
|
|
|
|
|
break;
|
|
|
|
|
case Endian.Little:
|
|
|
|
|
PokeByte(addr + 0, (byte)(val));
|
|
|
|
|
PokeByte(addr + 1, (byte)(val >> 8));
|
|
|
|
|
PokeByte(addr + 2, (byte)(val >> 16));
|
|
|
|
|
PokeByte(addr + 3, (byte)(val >> 24));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-07-30 20:49:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public enum Endian { Big, Little, Unknown }
|
|
|
|
|
|
2013-03-25 01:59:34 +00:00
|
|
|
|
public enum DisplayType { NTSC, PAL, DENDY }
|
2011-01-11 02:55:51 +00:00
|
|
|
|
}
|