2014-05-30 05:09:54 +00:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
2017-05-06 00:05:36 +00:00
2014-05-30 05:09:54 +00:00
using BizHawk.Emulation.Common ;
namespace BizHawk.Emulation.Cores.WonderSwan
{
2017-07-12 19:10:55 +00:00
[Core("Cygne/Mednafen", "Dox, Mednafen Team", true, true, "0.9.36.5", "http://mednafen.sourceforge.net/")]
2015-08-06 00:12:09 +00:00
[ServiceNotApplicable(typeof(IDriveLight), typeof(IRegionable))]
2016-12-11 17:14:42 +00:00
public partial class WonderSwan : IEmulator , IVideoProvider , ISoundProvider ,
2015-01-13 22:29:06 +00:00
IInputPollable , IDebuggable
2014-05-30 05:09:54 +00:00
{
2014-08-23 19:06:37 +00:00
[CoreConstructor("WSWAN")]
2017-05-06 00:05:36 +00:00
public WonderSwan ( CoreComm comm , byte [ ] file , bool deterministic , object settings , object syncSettings )
2014-05-30 05:09:54 +00:00
{
2014-12-04 03:38:30 +00:00
ServiceProvider = new BasicServiceProvider ( this ) ;
2014-05-30 22:31:16 +00:00
CoreComm = comm ;
2017-05-06 00:05:36 +00:00
_Settings = ( Settings ) settings ? ? new Settings ( ) ;
_SyncSettings = ( SyncSettings ) syncSettings ? ? new SyncSettings ( ) ;
2014-05-30 22:31:16 +00:00
2014-08-23 19:06:37 +00:00
DeterministicEmulation = deterministic ; // when true, remember to force the RTC flag!
2014-05-30 05:09:54 +00:00
Core = BizSwan . bizswan_new ( ) ;
if ( Core = = IntPtr . Zero )
throw new InvalidOperationException ( "bizswan_new() returned NULL!" ) ;
try
{
2014-05-30 22:31:16 +00:00
var ss = _SyncSettings . GetNativeSettings ( ) ;
2014-08-23 19:06:37 +00:00
if ( deterministic )
2014-05-31 05:57:18 +00:00
ss . userealtime = false ;
2014-05-30 05:09:54 +00:00
2014-05-30 20:53:52 +00:00
bool rotate = false ;
2014-09-12 15:39:04 +00:00
if ( ! BizSwan . bizswan_load ( Core , file , file . Length , ref ss , ref rotate ) )
2014-05-30 05:09:54 +00:00
throw new InvalidOperationException ( "bizswan_load() returned FALSE!" ) ;
2015-01-14 22:00:46 +00:00
InitISaveRam ( ) ;
2014-05-30 20:53:52 +00:00
InitVideo ( rotate ) ;
2014-05-30 22:31:16 +00:00
PutSettings ( _Settings ) ;
2015-01-14 22:00:46 +00:00
InitIMemoryDomains ( ) ;
2014-06-19 15:57:07 +00:00
2015-01-14 22:00:46 +00:00
InitIStatable ( ) ;
2014-06-19 15:57:07 +00:00
InitDebugCallbacks ( ) ;
2014-05-30 05:09:54 +00:00
}
catch
{
Dispose ( ) ;
throw ;
}
}
2014-12-04 03:38:30 +00:00
public IEmulatorServiceProvider ServiceProvider { get ; private set ; }
2014-05-30 05:09:54 +00:00
public void Dispose ( )
{
if ( Core ! = IntPtr . Zero )
{
BizSwan . bizswan_delete ( Core ) ;
Core = IntPtr . Zero ;
}
}
2017-05-02 01:09:11 +00:00
public void FrameAdvance ( IController controller , bool render , bool rendersound = true )
2014-05-30 05:09:54 +00:00
{
Frame + + ;
IsLagFrame = true ;
2017-05-02 01:09:11 +00:00
if ( controller . IsPressed ( "Power" ) )
2014-05-30 05:09:54 +00:00
BizSwan . bizswan_reset ( Core ) ;
2014-06-04 02:03:40 +00:00
bool rotate = false ;
2014-05-30 05:09:54 +00:00
int soundbuffsize = sbuff . Length ;
2017-05-02 01:09:11 +00:00
IsLagFrame = BizSwan . bizswan_advance ( Core , GetButtons ( controller ) , ! render , vbuff , sbuff , ref soundbuffsize , ref rotate ) ;
2014-05-30 05:09:54 +00:00
if ( soundbuffsize = = sbuff . Length )
throw new Exception ( ) ;
sbuffcontains = soundbuffsize ;
2014-06-04 02:03:40 +00:00
InitVideo ( rotate ) ;
2014-05-30 05:09:54 +00:00
if ( IsLagFrame )
LagCount + + ;
}
2014-05-30 16:50:58 +00:00
public CoreComm CoreComm { get ; private set ; }
public void ResetCounters ( )
{
Frame = 0 ;
IsLagFrame = false ;
LagCount = 0 ;
}
2014-05-30 05:09:54 +00:00
IntPtr Core ;
public int Frame { get ; private set ; }
2015-07-09 17:05:30 +00:00
public int LagCount { get ; set ; }
2016-01-26 10:34:42 +00:00
public bool IsLagFrame { get ; set ; }
2014-05-30 05:09:54 +00:00
public string SystemId { get { return "WSWAN" ; } }
2014-05-30 18:10:39 +00:00
public bool DeterministicEmulation { get ; private set ; }
2014-05-30 05:09:54 +00:00
#region Debugging
2014-12-05 02:21:10 +00:00
private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem ( ) ;
public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks ; } }
2017-08-02 03:05:17 +00:00
private readonly MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem ( new [ ] { "System Bus" } ) ; // This isn't an actual memory domain in this core (yet), but there's nothing that enforces that it has to be
2014-12-05 02:21:10 +00:00
public IMemoryCallbackSystem MemoryCallbacks { get { return _memorycallbacks ; } }
2014-05-30 22:59:13 +00:00
2014-12-20 13:16:15 +00:00
public IDictionary < string , RegisterValue > GetCpuFlagsAndRegisters ( )
2014-05-30 05:09:54 +00:00
{
2014-12-20 13:16:15 +00:00
var ret = new Dictionary < string , RegisterValue > ( ) ;
2014-05-30 22:59:13 +00:00
for ( int i = ( int ) BizSwan . NecRegsMin ; i < = ( int ) BizSwan . NecRegsMax ; i + + )
{
BizSwan . NecRegs en = ( BizSwan . NecRegs ) i ;
uint val = BizSwan . bizswan_getnecreg ( Core , en ) ;
2014-12-20 03:19:33 +00:00
ret [ Enum . GetName ( typeof ( BizSwan . NecRegs ) , en ) ] = ( ushort ) val ;
2014-05-30 22:59:13 +00:00
}
return ret ;
2014-05-30 05:09:54 +00:00
}
2014-11-24 01:17:05 +00:00
[FeatureNotImplemented]
2014-05-31 17:03:21 +00:00
public void SetCpuRegister ( string register , int value )
{
throw new NotImplementedException ( ) ;
}
2014-12-20 13:29:57 +00:00
public bool CanStep ( StepType type ) { return false ; }
2014-12-14 18:58:16 +00:00
[FeatureNotImplemented]
2014-12-15 22:19:10 +00:00
public void Step ( StepType type ) { throw new NotImplementedException ( ) ; }
2014-12-14 18:58:16 +00:00
2017-01-10 01:23:05 +00:00
[FeatureNotImplemented]
2018-05-12 16:55:42 +00:00
public long TotalExecutedCycles { get { throw new NotImplementedException ( ) ; } }
2017-01-10 01:23:05 +00:00
2014-06-19 15:57:07 +00:00
BizSwan . MemoryCallback ReadCallbackD ;
BizSwan . MemoryCallback WriteCallbackD ;
BizSwan . MemoryCallback ExecCallbackD ;
BizSwan . ButtonCallback ButtonCallbackD ;
void ReadCallback ( uint addr )
{
2017-08-03 23:08:07 +00:00
MemoryCallbacks . CallReads ( addr , "System Bus" ) ;
2014-06-19 15:57:07 +00:00
}
void WriteCallback ( uint addr )
{
2017-08-03 23:08:07 +00:00
MemoryCallbacks . CallWrites ( addr , "System Bus" ) ;
2014-06-19 15:57:07 +00:00
}
void ExecCallback ( uint addr )
{
2017-08-03 23:08:07 +00:00
MemoryCallbacks . CallExecutes ( addr , "System Bus" ) ;
2014-06-19 15:57:07 +00:00
}
void ButtonCallback ( )
{
2014-12-04 00:43:12 +00:00
InputCallbacks . Call ( ) ;
2014-06-19 15:57:07 +00:00
}
void InitDebugCallbacks ( )
{
ReadCallbackD = new BizSwan . MemoryCallback ( ReadCallback ) ;
WriteCallbackD = new BizSwan . MemoryCallback ( WriteCallback ) ;
ExecCallbackD = new BizSwan . MemoryCallback ( ExecCallback ) ;
ButtonCallbackD = new BizSwan . ButtonCallback ( ButtonCallback ) ;
2014-12-04 01:22:34 +00:00
_inputCallbacks . ActiveChanged + = SetInputCallback ;
2014-12-05 02:21:10 +00:00
_memorycallbacks . ActiveChanged + = SetMemoryCallbacks ;
2014-12-04 01:22:34 +00:00
}
void SetInputCallback ( )
{
2014-12-05 02:21:10 +00:00
BizSwan . bizswan_setbuttoncallback ( Core , InputCallbacks . Any ( ) ? ButtonCallbackD : null ) ;
2014-06-19 15:57:07 +00:00
}
2014-12-04 01:22:34 +00:00
void SetMemoryCallbacks ( )
2014-06-19 15:57:07 +00:00
{
BizSwan . bizswan_setmemorycallbacks ( Core ,
2014-12-05 01:56:45 +00:00
MemoryCallbacks . HasReads ? ReadCallbackD : null ,
MemoryCallbacks . HasWrites ? WriteCallbackD : null ,
MemoryCallbacks . HasExecutes ? ExecCallbackD : null ) ;
2014-06-19 15:57:07 +00:00
}
2014-05-30 05:09:54 +00:00
#endregion
#region IVideoProvider
2014-05-30 20:53:52 +00:00
void InitVideo ( bool rotate )
{
if ( rotate )
{
BufferWidth = 144 ;
BufferHeight = 224 ;
}
else
{
BufferWidth = 224 ;
BufferHeight = 144 ;
}
}
2014-05-30 05:09:54 +00:00
private int [ ] vbuff = new int [ 224 * 144 ] ;
public int [ ] GetVideoBuffer ( )
{
return vbuff ;
}
2014-05-30 20:53:52 +00:00
public int VirtualWidth { get { return BufferWidth ; } }
public int VirtualHeight { get { return BufferHeight ; } }
public int BufferWidth { get ; private set ; }
public int BufferHeight { get ; private set ; }
2014-05-30 05:09:54 +00:00
public int BackgroundColor { get { return unchecked ( ( int ) 0xff000000 ) ; } }
2017-05-05 16:25:38 +00:00
public int VsyncNumerator = > 3072000 ; // master CPU clock, also pixel clock
public int VsyncDenominator = > ( 144 + 15 ) * ( 224 + 32 ) ; // 144 vislines, 15 vblank lines; 224 vispixels, 32 hblank pixels
2017-05-05 16:21:37 +00:00
2014-05-30 05:09:54 +00:00
#endregion
}
}