2014-05-21 00:17:35 +00:00
using System ;
2014-06-03 02:19:13 +00:00
using System.ComponentModel ;
2014-05-21 00:17:35 +00:00
using System.Linq ;
2017-07-10 04:51:02 +00:00
using NLua ;
2016-12-04 17:50:07 +00:00
2014-09-01 18:43:41 +00:00
using BizHawk.Emulation.Common ;
2013-11-14 13:15:41 +00:00
using BizHawk.Emulation.Cores.Nintendo.NES ;
2014-04-22 01:38:19 +00:00
using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES ;
2013-10-28 19:13:01 +00:00
2013-11-02 01:56:00 +00:00
namespace BizHawk.Client.Common
2013-10-28 19:13:01 +00:00
{
2014-06-03 02:19:13 +00:00
[Description("Functions related specifically to Nes Cores")]
2014-06-01 22:02:59 +00:00
public sealed class NesLuaLibrary : LuaLibraryBase
2013-10-28 19:13:01 +00:00
{
2014-01-26 03:26:52 +00:00
// TODO:
// perhaps with the new core config system, one could
// automatically bring out all of the settings to a lua table, with names. that
// would be completely arbitrary and would remove the whole requirement for this mess
2014-05-21 00:17:35 +00:00
public NesLuaLibrary ( Lua lua )
: base ( lua ) { }
2014-12-17 23:03:58 +00:00
[OptionalService]
2017-05-19 13:58:23 +00:00
private NES Neshawk { get ; set ; }
2016-12-04 17:50:07 +00:00
2014-12-17 23:03:58 +00:00
[OptionalService]
2017-05-19 13:58:23 +00:00
private QuickNES Quicknes { get ; set ; }
2014-12-17 23:03:58 +00:00
2016-12-04 17:50:07 +00:00
[OptionalService]
2017-05-19 13:58:23 +00:00
private IMemoryDomains MemoryDomains { get ; set ; }
2016-12-04 17:50:07 +00:00
2017-05-19 13:58:23 +00:00
private bool NESAvailable = > Neshawk ! = null | | Quicknes ! = null ;
2014-12-17 23:03:58 +00:00
2017-05-19 13:58:23 +00:00
private bool HasMemoryDOmains = > MemoryDomains ! = null ;
2016-12-04 17:50:07 +00:00
2017-04-15 20:37:30 +00:00
public NesLuaLibrary ( Lua lua , Action < string > logOutputCallback )
2014-05-21 00:17:35 +00:00
: base ( lua , logOutputCallback ) { }
2017-04-14 19:59:01 +00:00
public override string Name = > "nes" ;
2013-10-29 16:03:06 +00:00
2018-03-04 17:48:38 +00:00
[LuaMethodExample("addgamegenie", "nes.addgamegenie( \"GXXZZLVI\" );")]
2017-07-10 19:02:00 +00:00
[LuaMethod("addgamegenie", "Adds the specified game genie code. If an NES game is not currently loaded or the code is not a valid game genie code, this will have no effect")]
2014-01-26 03:26:52 +00:00
public void AddGameGenie ( string code )
2013-10-28 19:13:01 +00:00
{
2016-12-04 17:50:07 +00:00
if ( NESAvailable & & HasMemoryDOmains )
2013-10-28 19:13:01 +00:00
{
2013-11-02 01:48:35 +00:00
var decoder = new NESGameGenieDecoder ( code ) ;
2013-12-30 01:58:44 +00:00
var watch = Watch . GenerateWatch (
2017-05-19 13:58:23 +00:00
MemoryDomains [ "System Bus" ] ,
2013-11-02 01:48:35 +00:00
decoder . Address ,
2015-11-28 21:47:16 +00:00
WatchSize . Byte ,
DisplayType . Hex ,
false ,
code ) ;
2014-02-03 20:48:01 +00:00
2013-11-02 01:48:35 +00:00
Global . CheatList . Add ( new Cheat (
watch ,
decoder . Value ,
2014-02-03 20:48:01 +00:00
decoder . Compare ) ) ;
2013-10-28 19:13:01 +00:00
}
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("getallowmorethaneightsprites", "if ( nes.getallowmorethaneightsprites( ) ) then\r\n\tconsole.log( \"Gets the NES setting 'Allow more than 8 sprites per scanline' value\" );\r\nend;")]
2017-07-10 19:02:00 +00:00
[LuaMethod("getallowmorethaneightsprites", "Gets the NES setting 'Allow more than 8 sprites per scanline' value")]
2014-12-17 23:03:58 +00:00
public bool GetAllowMoreThanEightSprites ( )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Quicknes ! = null )
2014-04-22 01:38:19 +00:00
{
2017-05-19 13:58:23 +00:00
return Quicknes . GetSettings ( ) . NumSprites ! = 8 ;
2014-12-17 23:03:58 +00:00
}
2017-04-14 19:59:01 +00:00
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2014-12-17 23:03:58 +00:00
{
2017-05-19 13:58:23 +00:00
return Neshawk . GetSettings ( ) . AllowMoreThanEightSprites ;
2014-04-22 01:38:19 +00:00
}
2014-12-17 23:03:58 +00:00
throw new InvalidOperationException ( ) ;
2013-10-28 19:13:01 +00:00
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("getbottomscanline", "local innesget = nes.getbottomscanline( false );")]
2017-07-10 19:02:00 +00:00
[LuaMethod("getbottomscanline", "Gets the current value for the bottom scanline value")]
2014-12-17 23:03:58 +00:00
public int GetBottomScanline ( bool pal = false )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Quicknes ! = null )
2014-12-17 23:03:58 +00:00
{
2017-05-19 13:58:23 +00:00
return Quicknes . GetSettings ( ) . ClipTopAndBottom ? 231 : 239 ;
2014-12-17 23:03:58 +00:00
}
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2014-04-22 01:38:19 +00:00
{
2014-12-17 23:03:58 +00:00
return pal
2017-05-19 13:58:23 +00:00
? Neshawk . GetSettings ( ) . PAL_BottomLine
: Neshawk . GetSettings ( ) . NTSC_BottomLine ;
2014-04-22 01:38:19 +00:00
}
2014-12-17 23:03:58 +00:00
throw new InvalidOperationException ( ) ;
2013-10-28 19:13:01 +00:00
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("getclipleftandright", "if ( nes.getclipleftandright( ) ) then\r\n\tconsole.log( \"Gets the current value for the Clip Left and Right sides option\" );\r\nend;")]
2017-07-10 19:02:00 +00:00
[LuaMethod("getclipleftandright", "Gets the current value for the Clip Left and Right sides option")]
2014-12-17 23:03:58 +00:00
public bool GetClipLeftAndRight ( )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Quicknes ! = null )
2014-12-17 23:03:58 +00:00
{
2017-05-19 13:58:23 +00:00
return Quicknes . GetSettings ( ) . ClipLeftAndRight ;
2014-12-17 23:03:58 +00:00
}
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2014-04-22 01:38:19 +00:00
{
2017-05-19 13:58:23 +00:00
return Neshawk . GetSettings ( ) . ClipLeftAndRight ;
2014-04-22 01:38:19 +00:00
}
2014-12-17 23:03:58 +00:00
throw new InvalidOperationException ( ) ;
2013-10-28 19:13:01 +00:00
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("getdispbackground", "if ( nes.getdispbackground( ) ) then\r\n\tconsole.log( \"Indicates whether or not the bg layer is being displayed\" );\r\nend;")]
2017-07-10 19:02:00 +00:00
[LuaMethod("getdispbackground", "Indicates whether or not the bg layer is being displayed")]
2014-12-17 23:03:58 +00:00
public bool GetDisplayBackground ( )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Quicknes ! = null )
2014-04-22 01:38:19 +00:00
{
return true ;
}
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2014-12-17 23:03:58 +00:00
{
2017-05-19 13:58:23 +00:00
return Neshawk . GetSettings ( ) . DispBackground ;
2014-12-17 23:03:58 +00:00
}
throw new InvalidOperationException ( ) ;
2013-10-28 19:13:01 +00:00
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("getdispsprites", "if ( nes.getdispsprites( ) ) then\r\n\tconsole.log( \"Indicates whether or not sprites are being displayed\" );\r\nend;")]
2017-07-10 19:02:00 +00:00
[LuaMethod("getdispsprites", "Indicates whether or not sprites are being displayed")]
2014-12-17 23:03:58 +00:00
public bool GetDisplaySprites ( )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Quicknes ! = null )
2014-04-22 01:38:19 +00:00
{
2017-05-19 13:58:23 +00:00
return Quicknes . GetSettings ( ) . NumSprites > 0 ;
2014-12-17 23:03:58 +00:00
}
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2014-12-17 23:03:58 +00:00
{
2017-05-19 13:58:23 +00:00
return Neshawk . GetSettings ( ) . DispSprites ;
2014-04-22 01:38:19 +00:00
}
2014-12-17 23:03:58 +00:00
throw new InvalidOperationException ( ) ;
2013-10-28 19:13:01 +00:00
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("gettopscanline", "local innesget = nes.gettopscanline(false);")]
2017-07-10 19:02:00 +00:00
[LuaMethod("gettopscanline", "Gets the current value for the top scanline value")]
2014-12-17 23:03:58 +00:00
public int GetTopScanline ( bool pal = false )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Quicknes ! = null )
2014-04-22 01:38:19 +00:00
{
2017-05-19 13:58:23 +00:00
return Quicknes . GetSettings ( ) . ClipTopAndBottom ? 8 : 0 ;
2014-04-22 01:38:19 +00:00
}
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2014-12-17 23:03:58 +00:00
{
return pal
2017-05-19 13:58:23 +00:00
? Neshawk . GetSettings ( ) . PAL_TopLine
: Neshawk . GetSettings ( ) . NTSC_TopLine ;
2014-12-17 23:03:58 +00:00
}
throw new InvalidOperationException ( ) ;
2013-10-28 19:13:01 +00:00
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("removegamegenie", "nes.removegamegenie( \"GXXZZLVI\" );")]
2017-07-10 19:02:00 +00:00
[LuaMethod("removegamegenie", "Removes the specified game genie code. If an NES game is not currently loaded or the code is not a valid game genie code, this will have no effect")]
2014-01-26 03:26:52 +00:00
public void RemoveGameGenie ( string code )
2013-10-28 19:13:01 +00:00
{
2014-12-17 23:03:58 +00:00
if ( NESAvailable )
2013-10-28 19:13:01 +00:00
{
2013-11-02 01:48:35 +00:00
var decoder = new NESGameGenieDecoder ( code ) ;
Global . CheatList . RemoveRange (
2017-05-18 16:36:38 +00:00
Global . CheatList . Where ( c = > c . Address = = decoder . Address ) ) ;
2013-10-28 19:13:01 +00:00
}
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("setallowmorethaneightsprites", "nes.setallowmorethaneightsprites( true );")]
2017-07-10 19:02:00 +00:00
[LuaMethod("setallowmorethaneightsprites", "Sets the NES setting 'Allow more than 8 sprites per scanline'")]
2014-12-17 23:03:58 +00:00
public void SetAllowMoreThanEightSprites ( bool allow )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
var s = Neshawk . GetSettings ( ) ;
2013-12-22 00:44:39 +00:00
s . AllowMoreThanEightSprites = allow ;
2017-05-19 13:58:23 +00:00
Neshawk . PutSettings ( s ) ;
2013-10-28 19:13:01 +00:00
}
2017-05-19 13:58:23 +00:00
else if ( Quicknes ! = null )
2014-04-22 01:38:19 +00:00
{
2017-05-19 13:58:23 +00:00
var s = Quicknes . GetSettings ( ) ;
2014-04-22 01:38:19 +00:00
s . NumSprites = allow ? 64 : 8 ;
2017-05-19 13:58:23 +00:00
Quicknes . PutSettings ( s ) ;
2014-04-22 01:38:19 +00:00
}
2013-10-28 19:13:01 +00:00
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("setclipleftandright", "nes.setclipleftandright( true );")]
2017-07-10 19:02:00 +00:00
[LuaMethod("setclipleftandright", "Sets the Clip Left and Right sides option")]
2014-12-17 23:03:58 +00:00
public void SetClipLeftAndRight ( bool leftandright )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
var s = Neshawk . GetSettings ( ) ;
2013-12-22 00:44:39 +00:00
s . ClipLeftAndRight = leftandright ;
2017-05-19 13:58:23 +00:00
Neshawk . PutSettings ( s ) ;
2013-10-28 19:13:01 +00:00
}
2017-05-19 13:58:23 +00:00
else if ( Quicknes ! = null )
2014-04-22 01:38:19 +00:00
{
2017-05-19 13:58:23 +00:00
var s = Quicknes . GetSettings ( ) ;
2014-04-22 01:38:19 +00:00
s . ClipLeftAndRight = leftandright ;
2017-05-19 13:58:23 +00:00
Quicknes . PutSettings ( s ) ;
2014-04-22 01:38:19 +00:00
}
2013-10-28 19:13:01 +00:00
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("setdispbackground", "nes.setdispbackground( true );")]
2017-07-10 19:02:00 +00:00
[LuaMethod("setdispbackground", "Sets whether or not the background layer will be displayed")]
2014-12-17 23:03:58 +00:00
public void SetDisplayBackground ( bool show )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2013-12-22 00:44:39 +00:00
{
2017-05-19 13:58:23 +00:00
var s = Neshawk . GetSettings ( ) ;
2013-12-22 00:44:39 +00:00
s . DispBackground = show ;
2017-05-19 13:58:23 +00:00
Neshawk . PutSettings ( s ) ;
2013-12-22 00:44:39 +00:00
}
2013-10-28 19:13:01 +00:00
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("setdispsprites", "nes.setdispsprites( true );")]
2017-07-10 19:02:00 +00:00
[LuaMethod("setdispsprites", "Sets whether or not sprites will be displayed")]
2014-12-17 23:03:58 +00:00
public void SetDisplaySprites ( bool show )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2013-12-22 00:44:39 +00:00
{
2017-05-19 13:58:23 +00:00
var s = Neshawk . GetSettings ( ) ;
2013-12-22 00:44:39 +00:00
s . DispSprites = show ;
2017-05-19 13:58:23 +00:00
Neshawk . PutSettings ( s ) ;
2014-12-17 23:03:58 +00:00
}
2017-05-19 13:58:23 +00:00
else if ( Quicknes ! = null )
2014-12-17 23:03:58 +00:00
{
2017-05-19 13:58:23 +00:00
var s = Quicknes . GetSettings ( ) ;
2014-12-17 23:03:58 +00:00
s . NumSprites = show ? 8 : 0 ;
2017-05-19 13:58:23 +00:00
Quicknes . PutSettings ( s ) ;
2013-12-22 00:44:39 +00:00
}
2013-10-28 19:13:01 +00:00
}
2018-03-04 17:48:38 +00:00
[LuaMethodExample("setscanlines", "nes.setscanlines( 10, 20, false );")]
2017-07-10 19:02:00 +00:00
[LuaMethod("setscanlines", "sets the top and bottom scanlines to be drawn (same values as in the graphics options dialog). Top must be in the range of 0 to 127, bottom must be between 128 and 239. Not supported in the Quick Nes core")]
2014-12-17 23:03:58 +00:00
public void SetScanlines ( int top , int bottom , bool pal = false )
2013-10-28 19:13:01 +00:00
{
2017-05-19 13:58:23 +00:00
if ( Neshawk ! = null )
2013-10-28 19:13:01 +00:00
{
2014-01-27 01:15:56 +00:00
if ( top > 127 )
2013-12-22 00:44:39 +00:00
{
2014-01-27 01:15:56 +00:00
top = 127 ;
2013-12-22 00:44:39 +00:00
}
2014-01-27 01:15:56 +00:00
else if ( top < 0 )
2013-12-22 00:44:39 +00:00
{
2014-01-27 01:15:56 +00:00
top = 0 ;
2013-12-22 00:44:39 +00:00
}
2013-10-28 19:13:01 +00:00
2014-01-27 01:15:56 +00:00
if ( bottom > 239 )
2013-12-22 00:44:39 +00:00
{
2014-01-27 01:15:56 +00:00
bottom = 239 ;
2013-12-22 00:44:39 +00:00
}
2014-01-27 01:15:56 +00:00
else if ( bottom < 128 )
2013-12-22 00:44:39 +00:00
{
2014-01-27 01:15:56 +00:00
bottom = 128 ;
2013-12-22 00:44:39 +00:00
}
2013-10-28 19:13:01 +00:00
2017-05-19 13:58:23 +00:00
var s = Neshawk . GetSettings ( ) ;
2013-10-28 19:13:01 +00:00
if ( pal )
{
2014-01-27 01:15:56 +00:00
s . PAL_TopLine = top ;
s . PAL_BottomLine = bottom ;
2013-10-28 19:13:01 +00:00
}
else
{
2014-01-27 01:15:56 +00:00
s . NTSC_TopLine = top ;
s . NTSC_BottomLine = bottom ;
2013-10-28 19:13:01 +00:00
}
2013-12-22 00:44:39 +00:00
2017-05-19 13:58:23 +00:00
Neshawk . PutSettings ( s ) ;
2013-10-28 19:13:01 +00:00
}
}
}
}