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(); 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 NamedLuaFunction nlf = new NamedLuaFunction(luaf, "OnMemoryRead", LogOutputCallback, name);
if (luaf != null) _luaFunctions.Add(nlf);
{ Global.CoreComm.MemoryCallbackSystem.AddRead(nlf.Callback, (address != null ? LuaUInt(address) : (uint?)null));
int? _addr; return nlf.GUID.ToString();
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);
}
} }
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 NamedLuaFunction nlf = new NamedLuaFunction(luaf, "OnMemoryWrite", LogOutputCallback, name);
if (luaf != null) _luaFunctions.Add(nlf);
{ Global.CoreComm.MemoryCallbackSystem.AddWrite(nlf.Callback, (address != null ? LuaUInt(address) : (uint?)null));
int? _addr; return nlf.GUID.ToString();
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);
}
} }
public string event_onsavestate(LuaFunction luaf, string name = null) public string event_onsavestate(LuaFunction luaf, string name = null)

View File

@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
namespace BizHawk.Emulation.Common namespace BizHawk.Emulation.Common
@ -149,70 +151,76 @@ namespace BizHawk.Emulation.Common
public class MemoryCallbackSystem public class MemoryCallbackSystem
{ {
public int? ReadAddr = null; private List<Action> _reads = new List<Action>();
private Action<uint> ReadCallback; private List<uint?> _readAddrs = new List<uint?>();
public void SetReadCallback(Action<uint> func)
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 _writes.Add(function);
{ _writeAddrs.Add(addr);
return ReadCallback != null;
}
} }
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) _reads[i]();
{
ReadCallback((uint)addr);
}
}
else
{
ReadCallback((uint)addr);
} }
} }
} }
public int? WriteAddr = null; public void CallWrite(uint addr)
private Action<uint> WriteCallback;
public void SetWriteCallback(Action<uint> func)
{ {
WriteCallback = func; for (int i = 0; i < _writes.Count; i++)
}
public bool HasWrite
{
get
{ {
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) _reads.Remove(_reads[i]);
{ _readAddrs.Remove(_readAddrs[i]);
WriteCallback((uint)addr);
}
}
else
{
WriteCallback((uint)addr);
} }
} }
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)); byte temp = mapper.ReadMemory((ushort)(addr&0x1FFF));
if (CoreComm.MemoryCallbackSystem.HasRead) CoreComm.MemoryCallbackSystem.CallRead(addr);
{
CoreComm.MemoryCallbackSystem.TriggerRead(addr);
}
return temp; return temp;
} }
@ -132,10 +129,7 @@ namespace BizHawk
{ {
mapper.WriteMemory((ushort)(addr & 0x1FFF), value); mapper.WriteMemory((ushort)(addr & 0x1FFF), value);
if (CoreComm.MemoryCallbackSystem.HasWrite) CoreComm.MemoryCallbackSystem.CallWrite((uint)addr);
{
CoreComm.MemoryCallbackSystem.TriggerWrite(addr);
}
} }
public void HardReset() public void HardReset()

View File

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

View File

@ -164,10 +164,7 @@
} }
} }
if (CoreComm.MemoryCallbackSystem.HasRead) CoreComm.MemoryCallbackSystem.CallRead(addr);
{
CoreComm.MemoryCallbackSystem.TriggerRead(addr);
}
if (cart != null) if (cart != null)
{ {
@ -359,10 +356,7 @@
} }
} }
if (CoreComm.MemoryCallbackSystem.HasWrite) CoreComm.MemoryCallbackSystem.CallWrite(addr);
{
CoreComm.MemoryCallbackSystem.TriggerWrite(addr);
}
return (cart || stic || psg); 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 // we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point
if (mcs.HasRead) if (mcs.HasReads)
readcb = delegate(uint addr) { mcs.TriggerRead((int)addr); RefreshMemoryCallbacks(); }; readcb = delegate(uint addr) { mcs.CallRead(addr); RefreshMemoryCallbacks(); };
else else
readcb = null; readcb = null;
if (mcs.HasWrite) if (mcs.HasWrites)
writecb = delegate(uint addr) { mcs.TriggerWrite((int)addr); RefreshMemoryCallbacks(); }; writecb = delegate(uint addr) { mcs.CallWrite(addr); RefreshMemoryCallbacks(); };
else else
writecb = null; writecb = null;

View File

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

View File

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

View File

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