2013-04-24 22:09:11 +00:00
using System ;
2013-11-10 18:15:32 +00:00
using System.Collections.Generic ;
2013-11-10 21:20:55 +00:00
using System.Linq ;
2013-04-24 22:09:11 +00:00
using System.Text ;
2013-11-04 01:39:19 +00:00
namespace BizHawk.Emulation.Common
2011-06-11 22:15:08 +00:00
{
2012-12-10 00:43:43 +00:00
public class CoreComm
2011-06-11 22:15:08 +00:00
{
2013-08-10 01:17:06 +00:00
public ICoreFileProvider CoreFileProvider ;
2013-04-24 22:09:11 +00:00
2012-09-16 19:38:08 +00:00
/// <summary>
/// if this is set, then the cpu should dump trace info to CpuTraceStream
/// </summary>
2012-09-30 02:37:00 +00:00
public TraceBuffer Tracer = new TraceBuffer ( ) ;
2012-10-06 13:34:04 +00:00
/// <summary>
/// for emu.on_snoop()
/// </summary>
2013-11-10 18:15:32 +00:00
public InputCallbackSystem InputCallback = new InputCallbackSystem ( ) ;
2012-10-13 18:59:09 +00:00
public MemoryCallbackSystem MemoryCallbackSystem = new MemoryCallbackSystem ( ) ;
2011-06-11 22:15:08 +00:00
2012-07-11 21:37:35 +00:00
public double VsyncRate
{
get
{
return VsyncNum / ( double ) VsyncDen ;
}
}
public int VsyncNum = 60 ;
public int VsyncDen = 1 ;
2012-11-04 23:29:06 +00:00
//a core should set these if you wish to provide rom status information yourself. otherwise it will be calculated by the frontend in a way you may not like, using RomGame-related concepts.
2011-07-10 21:00:28 +00:00
public string RomStatusAnnotation ;
public string RomStatusDetails ;
2012-09-16 19:38:08 +00:00
2012-09-20 00:22:24 +00:00
public int ScreenLogicalOffsetX , ScreenLogicalOffsetY ;
2012-09-30 02:07:14 +00:00
public bool CpuTraceAvailable = false ;
2012-11-24 00:45:25 +00:00
public string TraceHeader = "Instructions" ;
2012-11-26 01:43:34 +00:00
2012-11-26 02:25:23 +00:00
// size hint to a/v out resizer. this probably belongs in VideoProvider? but it's somewhat different than VirtualWidth...
public int NominalWidth = 640 ;
public int NominalHeight = 480 ;
2012-11-26 01:43:34 +00:00
public bool DriveLED = false ;
public bool UsesDriveLed = false ;
2013-12-10 17:58:12 +00:00
/// <summary>
/// show a message. reasonably annoying (dialog box), shouldn't be used most of the time
/// </summary>
public Action < string > ShowMessage { get ; private set ; }
2014-03-18 03:03:53 +00:00
/// <summary>
/// show a message. less annoying (OSD message). Should be used for ignorable helpful messages
/// </summary>
public Action < string > Notify { get ; private set ; }
public CoreComm ( Action < string > ShowMessage , Action < string > NotifyMessage )
2013-12-10 17:58:12 +00:00
{
this . ShowMessage = ShowMessage ;
2014-03-18 03:03:53 +00:00
this . Notify = NotifyMessage ;
2013-12-10 17:58:12 +00:00
}
2014-06-08 23:30:34 +00:00
public Func < object > RequestGLContext ;
public Action < object > ActivateGLContext ;
public Action DeactivateGLContext ; //this shouldnt be necessary.. frontend should be changing context before it does anything.. but for now..
2014-07-12 20:42:44 +00:00
public Func < bool > DispSnowyNullEmulator ;
2011-06-11 22:15:08 +00:00
}
2012-09-30 02:37:00 +00:00
public class TraceBuffer
{
public string TakeContents ( )
{
string s = buffer . ToString ( ) ;
buffer . Clear ( ) ;
return s ;
}
public string Contents
{
get
{
return buffer . ToString ( ) ;
}
}
public void Put ( string content )
{
if ( logging )
{
2013-11-29 00:35:05 +00:00
buffer . AppendLine ( content ) ;
2012-09-30 02:37:00 +00:00
}
}
public TraceBuffer ( )
{
buffer = new StringBuilder ( ) ;
}
public bool Enabled
{
get
{
return logging ;
}
set
{
logging = value ;
}
}
2013-11-04 03:12:50 +00:00
private readonly StringBuilder buffer ;
private bool logging ;
2012-09-30 02:37:00 +00:00
}
2012-10-13 18:59:09 +00:00
2013-11-10 18:15:32 +00:00
public class InputCallbackSystem
{
2013-11-15 01:52:03 +00:00
private readonly List < Action > _list = new List < Action > ( ) ;
2013-11-10 18:15:32 +00:00
public void Add ( Action action )
{
_list . Add ( action ) ;
}
public void Call ( )
{
foreach ( var action in _list )
{
action ( ) ;
}
}
public void Remove ( Action action )
{
2013-11-10 19:19:58 +00:00
_list . Remove ( action ) ;
2013-11-10 18:15:32 +00:00
}
2013-11-10 21:56:02 +00:00
public void RemoveAll ( IEnumerable < Action > actions )
{
foreach ( var action in actions )
{
_list . Remove ( action ) ;
}
}
2013-11-10 18:15:32 +00:00
public void Clear ( )
{
_list . Clear ( ) ;
}
2014-06-19 15:57:07 +00:00
// why was this missing?
public bool Has { get { return _list . Any ( ) ; } }
2013-11-10 18:15:32 +00:00
}
2012-10-13 18:59:09 +00:00
public class MemoryCallbackSystem
{
2013-11-15 01:52:03 +00:00
private readonly List < Action > _reads = new List < Action > ( ) ;
private readonly List < uint? > _readAddrs = new List < uint? > ( ) ;
2013-11-10 21:20:55 +00:00
2013-11-15 01:52:03 +00:00
private readonly List < Action > _writes = new List < Action > ( ) ;
private readonly List < uint? > _writeAddrs = new List < uint? > ( ) ;
2013-11-10 21:20:55 +00:00
2013-11-15 01:52:03 +00:00
private readonly List < Action > _executes = new List < Action > ( ) ;
private readonly List < uint > _execAddrs = new List < uint > ( ) ;
2013-11-12 01:51:07 +00:00
2013-11-10 21:20:55 +00:00
public void AddRead ( Action function , uint? addr )
2012-10-14 14:08:25 +00:00
{
2013-11-10 21:20:55 +00:00
_reads . Add ( function ) ;
_readAddrs . Add ( addr ) ;
2012-10-14 14:08:25 +00:00
}
2013-11-10 21:20:55 +00:00
public void AddWrite ( Action function , uint? addr )
2012-10-14 14:08:25 +00:00
{
2013-11-10 21:20:55 +00:00
_writes . Add ( function ) ;
_writeAddrs . Add ( addr ) ;
2012-10-14 14:08:25 +00:00
}
2012-10-13 18:59:09 +00:00
2013-11-12 01:51:07 +00:00
public void AddExecute ( Action function , uint addr )
{
_executes . Add ( function ) ;
_execAddrs . Add ( addr ) ;
}
2013-11-10 21:20:55 +00:00
public void CallRead ( uint addr )
2012-10-13 18:59:09 +00:00
{
2013-11-10 21:20:55 +00:00
for ( int i = 0 ; i < _reads . Count ; i + + )
2012-10-13 18:59:09 +00:00
{
2013-11-10 21:20:55 +00:00
if ( ! _readAddrs [ i ] . HasValue | | _readAddrs [ i ] . Value = = addr )
2012-10-13 18:59:09 +00:00
{
2013-11-10 21:20:55 +00:00
_reads [ i ] ( ) ;
2012-10-13 18:59:09 +00:00
}
}
}
2013-11-10 21:20:55 +00:00
public void CallWrite ( uint addr )
2012-10-14 14:08:25 +00:00
{
2013-11-10 21:20:55 +00:00
for ( int i = 0 ; i < _writes . Count ; i + + )
2012-10-14 14:08:25 +00:00
{
2013-11-17 02:36:52 +00:00
if ( ! _writeAddrs [ i ] . HasValue | | _writeAddrs [ i ] = = addr )
2013-11-10 21:20:55 +00:00
{
_writes [ i ] ( ) ;
}
2012-10-14 14:08:25 +00:00
}
}
2012-10-13 18:59:09 +00:00
2013-11-12 01:06:33 +00:00
public void CallExecute ( uint addr )
{
2013-11-12 01:51:07 +00:00
for ( int i = 0 ; i < _executes . Count ; i + + )
2013-11-12 01:06:33 +00:00
{
2013-11-12 01:51:07 +00:00
if ( _execAddrs [ i ] = = addr )
2013-11-12 01:06:33 +00:00
{
2013-11-12 01:51:07 +00:00
_executes [ i ] ( ) ;
2013-11-12 01:06:33 +00:00
}
}
}
2013-11-10 21:20:55 +00:00
public bool HasReads { get { return _reads . Any ( ) ; } }
public bool HasWrites { get { return _writes . Any ( ) ; } }
2013-11-12 01:51:07 +00:00
public bool HasExecutes { get { return _executes . Any ( ) ; } }
2013-11-10 21:20:55 +00:00
public void Remove ( Action action )
2012-10-13 18:59:09 +00:00
{
2013-11-10 21:20:55 +00:00
for ( int i = 0 ; i < _reads . Count ; i + + )
2012-10-13 18:59:09 +00:00
{
2013-11-10 21:20:55 +00:00
if ( _reads [ i ] = = action )
2012-10-13 18:59:09 +00:00
{
2013-11-10 21:20:55 +00:00
_reads . Remove ( _reads [ i ] ) ;
_readAddrs . Remove ( _readAddrs [ i ] ) ;
2012-10-13 18:59:09 +00:00
}
2013-11-10 21:20:55 +00:00
}
for ( int i = 0 ; i < _writes . Count ; i + + )
{
if ( _writes [ i ] = = action )
2012-10-13 18:59:09 +00:00
{
2013-11-10 21:20:55 +00:00
_writes . Remove ( _writes [ i ] ) ;
_writeAddrs . Remove ( _writeAddrs [ i ] ) ;
2012-10-13 18:59:09 +00:00
}
}
2013-11-12 01:51:07 +00:00
for ( int i = 0 ; i < _executes . Count ; i + + )
{
if ( _executes [ i ] = = action )
{
_executes . Remove ( _executes [ i ] ) ;
_execAddrs . Remove ( _execAddrs [ i ] ) ;
}
}
2012-10-13 18:59:09 +00:00
}
2013-11-10 21:20:55 +00:00
2013-11-10 21:56:02 +00:00
public void RemoveAll ( IEnumerable < Action > actions )
{
foreach ( var action in actions )
{
Remove ( action ) ;
}
}
2013-11-10 21:20:55 +00:00
public void Clear ( )
{
_reads . Clear ( ) ;
_readAddrs . Clear ( ) ;
_writes . Clear ( ) ;
_writes . Clear ( ) ;
2013-11-12 01:51:07 +00:00
_executes . Clear ( ) ;
_execAddrs . Clear ( ) ;
2013-11-10 21:20:55 +00:00
}
2012-10-13 18:59:09 +00:00
}
2012-03-11 06:50:46 +00:00
}