Lua - OnMemoryRead() and OnMemoryWrite() - support multiple events, hook to the registered functions system, add ability to name function, return a GUID.

This commit is contained in:
adelikat 2013-11-10 21:20:55 +00:00
parent ded77beb65
commit e7a481e6c4
9 changed files with 76 additions and 161 deletions

View File

@ -159,78 +159,21 @@ namespace BizHawk.Client.Common
return nlf.GUID.ToString();
}
public void event_onmemoryread(LuaFunction luaf, object address = null)
public string event_onmemoryread(LuaFunction luaf, object address = null, string name = null)
{
//TODO: allow a list of addresses
if (luaf != null)
{
int? _addr;
if (address == null)
{
_addr = null;
}
else
{
_addr = LuaInt(address);
}
Global.Emulator.CoreComm.MemoryCallbackSystem.ReadAddr = _addr;
Global.Emulator.CoreComm.MemoryCallbackSystem.SetReadCallback(delegate(uint addr)
{
try
{
luaf.Call(addr);
}
catch (SystemException e)
{
LogOutputCallback(
"error running function attached by lua function event.onmemoryread" +
"\nError message: " +
e.Message);
}
});
}
else
{
Global.Emulator.CoreComm.MemoryCallbackSystem.SetReadCallback(null);
}
NamedLuaFunction nlf = new NamedLuaFunction(luaf, "OnMemoryRead", LogOutputCallback, name);
_luaFunctions.Add(nlf);
Global.CoreComm.MemoryCallbackSystem.AddRead(nlf.Callback, (address != null ? LuaUInt(address) : (uint?)null));
return nlf.GUID.ToString();
}
public void event_onmemorywrite(LuaFunction luaf, object address = null)
public string event_onmemorywrite(LuaFunction luaf, object address = null, string name = null)
{
//TODO: allow a list of addresses
if (luaf != null)
{
int? _addr;
if (address == null)
{
_addr = null;
}
else
{
_addr = LuaInt(address);
}
Global.Emulator.CoreComm.MemoryCallbackSystem.WriteAddr = _addr;
Global.Emulator.CoreComm.MemoryCallbackSystem.SetWriteCallback(delegate(uint addr)
{
try
{
luaf.Call(addr);
}
catch (SystemException e)
{
LogOutputCallback(
"error running function attached by lua function event.onmemoryread" +
"\nError message: " +
e.Message);
}
});
}
else
{
Global.Emulator.CoreComm.MemoryCallbackSystem.SetWriteCallback(null);
}
NamedLuaFunction nlf = new NamedLuaFunction(luaf, "OnMemoryWrite", LogOutputCallback, name);
_luaFunctions.Add(nlf);
Global.CoreComm.MemoryCallbackSystem.AddWrite(nlf.Callback, (address != null ? LuaUInt(address) : (uint?)null));
return nlf.GUID.ToString();
}
public string event_onsavestate(LuaFunction luaf, string name = null)

View File

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace BizHawk.Emulation.Common
@ -149,70 +151,76 @@ namespace BizHawk.Emulation.Common
public class MemoryCallbackSystem
{
public int? ReadAddr = null;
private Action<uint> ReadCallback;
public void SetReadCallback(Action<uint> func)
private List<Action> _reads = new List<Action>();
private List<uint?> _readAddrs = new List<uint?>();
private List<Action> _writes = new List<Action>();
private List<uint?> _writeAddrs = new List<uint?>();
public void AddRead(Action function, uint? addr)
{
ReadCallback = func;
_reads.Add(function);
_readAddrs.Add(addr);
}
public bool HasRead
public void AddWrite(Action function, uint? addr)
{
get
{
return ReadCallback != null;
}
_writes.Add(function);
_writeAddrs.Add(addr);
}
public void TriggerRead(int addr)
public void CallRead(uint addr)
{
if (ReadCallback != null)
for (int i = 0; i < _reads.Count; i++)
{
if (ReadAddr != null)
if (!_readAddrs[i].HasValue || _readAddrs[i].Value == addr)
{
if (ReadAddr == addr)
{
ReadCallback((uint)addr);
}
}
else
{
ReadCallback((uint)addr);
_reads[i]();
}
}
}
public int? WriteAddr = null;
private Action<uint> WriteCallback;
public void SetWriteCallback(Action<uint> func)
public void CallWrite(uint addr)
{
WriteCallback = func;
}
public bool HasWrite
{
get
for (int i = 0; i < _writes.Count; i++)
{
return WriteCallback != null;
if (_writeAddrs[i] == addr)
{
_writes[i]();
}
}
}
public void TriggerWrite(int addr)
public bool HasReads { get { return _reads.Any(); } }
public bool HasWrites { get { return _writes.Any(); } }
public void Remove(Action action)
{
if (WriteCallback != null)
for (int i = 0; i < _reads.Count; i++)
{
if (WriteAddr != null)
if (_reads[i] == action)
{
if (WriteAddr == addr)
{
WriteCallback((uint)addr);
}
}
else
{
WriteCallback((uint)addr);
_reads.Remove(_reads[i]);
_readAddrs.Remove(_readAddrs[i]);
}
}
for (int i = 0; i < _writes.Count; i++)
{
if (_writes[i] == action)
{
_writes.Remove(_writes[i]);
_writeAddrs.Remove(_writeAddrs[i]);
}
}
}
public void Clear()
{
_reads.Clear();
_readAddrs.Clear();
_writes.Clear();
_writes.Clear();
}
}
}

View File

@ -113,10 +113,7 @@ namespace BizHawk
{
byte temp = mapper.ReadMemory((ushort)(addr&0x1FFF));
if (CoreComm.MemoryCallbackSystem.HasRead)
{
CoreComm.MemoryCallbackSystem.TriggerRead(addr);
}
CoreComm.MemoryCallbackSystem.CallRead(addr);
return temp;
}
@ -132,10 +129,7 @@ namespace BizHawk
{
mapper.WriteMemory((ushort)(addr & 0x1FFF), value);
if (CoreComm.MemoryCallbackSystem.HasWrite)
{
CoreComm.MemoryCallbackSystem.TriggerWrite(addr);
}
CoreComm.MemoryCallbackSystem.CallWrite((uint)addr);
}
public void HardReset()

View File

@ -52,10 +52,7 @@ namespace BizHawk.Emulation.Consoles.Calculator
ret = rom[romPage * 0x4000 + addr - 0x4000]; //other rom page
else ret = ram[addr - 0x8000];
if (CoreComm.MemoryCallbackSystem.HasRead)
{
CoreComm.MemoryCallbackSystem.TriggerRead(addr);
}
CoreComm.MemoryCallbackSystem.CallRead(addr);
return ret;
}
@ -68,10 +65,7 @@ namespace BizHawk.Emulation.Consoles.Calculator
return; //other rom page
else ram[addr - 0x8000] = value;
if (CoreComm.MemoryCallbackSystem.HasWrite)
{
CoreComm.MemoryCallbackSystem.TriggerWrite(addr);
}
CoreComm.MemoryCallbackSystem.CallWrite(addr);
}
public void WriteHardware(ushort addr, byte value)

View File

@ -164,10 +164,7 @@
}
}
if (CoreComm.MemoryCallbackSystem.HasRead)
{
CoreComm.MemoryCallbackSystem.TriggerRead(addr);
}
CoreComm.MemoryCallbackSystem.CallRead(addr);
if (cart != null)
{
@ -359,10 +356,7 @@
}
}
if (CoreComm.MemoryCallbackSystem.HasWrite)
{
CoreComm.MemoryCallbackSystem.TriggerWrite(addr);
}
CoreComm.MemoryCallbackSystem.CallWrite(addr);
return (cart || stic || psg);
}

View File

@ -477,12 +477,12 @@ namespace BizHawk.Emulation.Consoles.GB
// we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point
if (mcs.HasRead)
readcb = delegate(uint addr) { mcs.TriggerRead((int)addr); RefreshMemoryCallbacks(); };
if (mcs.HasReads)
readcb = delegate(uint addr) { mcs.CallRead(addr); RefreshMemoryCallbacks(); };
else
readcb = null;
if (mcs.HasWrite)
writecb = delegate(uint addr) { mcs.TriggerWrite((int)addr); RefreshMemoryCallbacks(); };
if (mcs.HasWrites)
writecb = delegate(uint addr) { mcs.CallWrite(addr); RefreshMemoryCallbacks(); };
else
writecb = null;

View File

@ -554,10 +554,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ret = sysbus_watch[addr].ApplyGameGenie(ret);
}
if (CoreComm.MemoryCallbackSystem.HasRead)
{
CoreComm.MemoryCallbackSystem.TriggerRead(addr);
}
CoreComm.MemoryCallbackSystem.CallRead(addr);
DB = ret;
@ -611,10 +608,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
board.WritePRG(addr - 0x8000, value);
}
if (CoreComm.MemoryCallbackSystem.HasWrite)
{
CoreComm.MemoryCallbackSystem.TriggerWrite(addr);
}
CoreComm.MemoryCallbackSystem.CallWrite(addr);
}
}

View File

@ -35,10 +35,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
return 0xFF;
}
if (CoreComm.MemoryCallbackSystem.HasRead)
{
CoreComm.MemoryCallbackSystem.TriggerRead(addr);
}
CoreComm.MemoryCallbackSystem.CallRead((uint)addr);
Log.Error("MEM", "UNHANDLED READ: {0:X6}", addr);
return 0xFF;
@ -76,10 +73,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
else
Log.Error("MEM", "UNHANDLED WRITE: {0:X6}:{1:X2}", addr, value);
if (CoreComm.MemoryCallbackSystem.HasWrite)
{
CoreComm.MemoryCallbackSystem.TriggerWrite(addr);
}
CoreComm.MemoryCallbackSystem.CallWrite((uint)addr);
}
}
}

View File

@ -43,10 +43,7 @@
ret = SystemRam[address & RamSizeMask];
}
if (CoreComm.MemoryCallbackSystem.HasRead)
{
CoreComm.MemoryCallbackSystem.TriggerRead(address);
}
CoreComm.MemoryCallbackSystem.CallRead(address);
return ret;
}
@ -81,10 +78,7 @@
return;
}
if (CoreComm.MemoryCallbackSystem.HasWrite)
{
CoreComm.MemoryCallbackSystem.TriggerWrite(address);
}
CoreComm.MemoryCallbackSystem.CallWrite((uint)address);
}
void InitSegaMapper()