Debugger: Lua - Added Lua scripts examples (by upsilandre)

This commit is contained in:
Sour 2018-04-15 14:20:15 -04:00
parent c107bd643d
commit 204d49a1b1
14 changed files with 566 additions and 140 deletions

View file

@ -1,4 +1,5 @@
using System;
using Mesen.GUI.Config;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -17,5 +18,43 @@ namespace Mesen.GUI.Controls
}
base.WndProc(ref m);
}
public void AddItemToToolbar(ToolStripMenuItem item, string caption = null)
{
if(item == null) {
this.Items.Add("-");
} else {
ToolStripItem newItem = item.HasDropDownItems ? (ToolStripItem)new ToolStripDropDownButton(item.Text, item.Image) : (ToolStripItem)new ToolStripButton(item.Image);
if(item.Image == null) {
newItem.Text = item.Text;
}
newItem.ToolTipText = (caption ?? item.Text) + (item.ShortcutKeys != Keys.None ? $" ({DebuggerShortcutsConfig.GetShortcutDisplay(item.ShortcutKeys)})" : "");
newItem.Click += (s, e) => item.PerformClick();
if(newItem is ToolStripButton) {
((ToolStripButton)newItem).Checked = item.Checked;
item.CheckedChanged += (s, e) => ((ToolStripButton)newItem).Checked = item.Checked;
}
newItem.Enabled = item.Enabled;
newItem.MouseEnter += (s, e) => newItem.ToolTipText = (caption ?? item.Text) + (item.ShortcutKeys != Keys.None ? $" ({DebuggerShortcutsConfig.GetShortcutDisplay(item.ShortcutKeys)})" : "");
item.EnabledChanged += (s, e) => newItem.Enabled = item.Enabled;
item.VisibleChanged += (s, e) => newItem.Visible = item.Visible;
if(item.HasDropDownItems) {
foreach(ToolStripItem ddItem in item.DropDownItems) {
ToolStripItem newDdItem = ((ToolStripDropDownButton)newItem).DropDownItems.Add(ddItem.Text, ddItem.Image);
newDdItem.Click += (s, e) => ddItem.PerformClick();
}
}
this.Items.Add(newItem);
}
}
public void AddItemsToToolbar(params ToolStripMenuItem[] items)
{
foreach(ToolStripMenuItem item in items) {
AddItemToToolbar(item);
}
}
}
}

View file

@ -229,7 +229,7 @@ namespace Mesen.GUI.Debugger
private void InitToolbar()
{
AddItemsToToolbar(
tsToolbar.AddItemsToToolbar(
mnuSaveRom, mnuRevertChanges, null,
mnuImportLabels, mnuExportLabels, null,
mnuContinue, mnuBreak, null,
@ -241,37 +241,9 @@ namespace Mesen.GUI.Debugger
mnuEditHeader, null,
mnuSplitView, null
);
AddItemToToolbar(mnuShowVerifiedData, "Show Verified Data");
AddItemToToolbar(mnuShowUnidentifiedData, "Show Unidentified Code/Data");
AddItemsToToolbar(null, mnuBreakIn, null, mnuBreakOn);
}
private void AddItemToToolbar(ToolStripMenuItem item, string caption = null)
{
if(item == null) {
tsToolbar.Items.Add("-");
} else {
ToolStripButton newItem = new ToolStripButton(item.Image);
if(item.Image == null) {
newItem.Text = item.Text;
}
newItem.ToolTipText = (caption ?? item.Text) + (item.ShortcutKeys != Keys.None ? $" ({DebuggerShortcutsConfig.GetShortcutDisplay(item.ShortcutKeys)})" : "");
newItem.Click += (s, e) => item.PerformClick();
newItem.Checked = item.Checked;
newItem.Enabled = item.Enabled;
newItem.MouseEnter += (s, e) => newItem.ToolTipText = (caption ?? item.Text) + (item.ShortcutKeys != Keys.None ? $" ({DebuggerShortcutsConfig.GetShortcutDisplay(item.ShortcutKeys)})" : "");
item.EnabledChanged += (s, e) => newItem.Enabled = item.Enabled;
item.CheckedChanged += (s, e) => newItem.Checked = item.Checked;
item.VisibleChanged += (s, e) => newItem.Visible = item.Visible;
tsToolbar.Items.Add(newItem);
}
}
private void AddItemsToToolbar(params ToolStripMenuItem[] items)
{
foreach(ToolStripMenuItem item in items) {
AddItemToToolbar(item);
}
tsToolbar.AddItemToToolbar(mnuShowVerifiedData, "Show Verified Data");
tsToolbar.AddItemToToolbar(mnuShowUnidentifiedData, "Show Unidentified Code/Data");
tsToolbar.AddItemsToToolbar(null, mnuBreakIn, null, mnuBreakOn);
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)

View file

@ -39,6 +39,7 @@
this.mnuSave = new System.Windows.Forms.ToolStripMenuItem();
this.mnuSaveAs = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuBuiltInScripts = new System.Windows.Forms.ToolStripMenuItem();
this.mnuRecentScripts = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
@ -61,12 +62,7 @@
this.mnuBlankWindow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuTutorialScript = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoLoadLastScript = new System.Windows.Forms.ToolStripMenuItem();
this.toolStrip1 = new Mesen.GUI.Controls.ctrlMesenToolStrip();
this.btnOpen = new System.Windows.Forms.ToolStripButton();
this.btnSave = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.btnRun = new System.Windows.Forms.ToolStripButton();
this.btnStop = new System.Windows.Forms.ToolStripButton();
this.tsToolbar = new Mesen.GUI.Controls.ctrlMesenToolStrip();
this.txtScriptContent = new FastColoredTextBoxNS.FastColoredTextBox();
this.contextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mnuCopy = new System.Windows.Forms.ToolStripMenuItem();
@ -81,7 +77,6 @@
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.lblScriptActive = new System.Windows.Forms.ToolStripStatusLabel();
this.mnuMain.SuspendLayout();
this.toolStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.txtScriptContent)).BeginInit();
this.contextMenu.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.ctrlSplit)).BeginInit();
@ -111,6 +106,7 @@
this.mnuSave,
this.mnuSaveAs,
this.toolStripMenuItem1,
this.mnuBuiltInScripts,
this.mnuRecentScripts,
this.toolStripMenuItem2,
this.mnuClose});
@ -140,7 +136,7 @@
this.mnuSave.Name = "mnuSave";
this.mnuSave.Size = new System.Drawing.Size(178, 22);
this.mnuSave.Text = "Save";
this.mnuSave.Click += new System.EventHandler(this.btnSave_Click);
this.mnuSave.Click += new System.EventHandler(this.mnuSave_Click);
//
// mnuSaveAs
//
@ -154,6 +150,13 @@
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(175, 6);
//
// mnuBuiltInScripts
//
this.mnuBuiltInScripts.Image = global::Mesen.GUI.Properties.Resources.LogWindow;
this.mnuBuiltInScripts.Name = "mnuBuiltInScripts";
this.mnuBuiltInScripts.Size = new System.Drawing.Size(178, 22);
this.mnuBuiltInScripts.Text = "Built-in Scripts";
//
// mnuRecentScripts
//
this.mnuRecentScripts.Name = "mnuRecentScripts";
@ -326,66 +329,14 @@
this.mnuAutoLoadLastScript.Text = "Load the last script loaded";
this.mnuAutoLoadLastScript.Click += new System.EventHandler(this.mnuAutoLoadLastScript_Click);
//
// toolStrip1
// tsToolbar
//
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.btnOpen,
this.btnSave,
this.toolStripSeparator1,
this.btnRun,
this.btnStop});
this.toolStrip1.Location = new System.Drawing.Point(0, 24);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
this.toolStrip1.Size = new System.Drawing.Size(965, 25);
this.toolStrip1.TabIndex = 1;
this.toolStrip1.Text = "toolStrip1";
//
// btnOpen
//
this.btnOpen.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.btnOpen.Image = global::Mesen.GUI.Properties.Resources.FolderOpen;
this.btnOpen.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnOpen.Name = "btnOpen";
this.btnOpen.Size = new System.Drawing.Size(23, 22);
this.btnOpen.Text = "Open";
this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click);
//
// btnSave
//
this.btnSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.btnSave.Image = global::Mesen.GUI.Properties.Resources.Floppy;
this.btnSave.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnSave.Name = "btnSave";
this.btnSave.Size = new System.Drawing.Size(23, 22);
this.btnSave.Text = "Save";
this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
//
// btnRun
//
this.btnRun.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.btnRun.Image = global::Mesen.GUI.Properties.Resources.Play;
this.btnRun.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnRun.Name = "btnRun";
this.btnRun.Size = new System.Drawing.Size(23, 22);
this.btnRun.Text = "Run";
this.btnRun.Click += new System.EventHandler(this.btnRun_Click);
//
// btnStop
//
this.btnStop.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.btnStop.Image = global::Mesen.GUI.Properties.Resources.Stop;
this.btnStop.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnStop.Name = "btnStop";
this.btnStop.Size = new System.Drawing.Size(23, 22);
this.btnStop.Text = "Stop";
this.btnStop.ToolTipText = "Stop";
this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
this.tsToolbar.Location = new System.Drawing.Point(0, 24);
this.tsToolbar.Name = "tsToolbar";
this.tsToolbar.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
this.tsToolbar.Size = new System.Drawing.Size(965, 25);
this.tsToolbar.TabIndex = 1;
this.tsToolbar.Text = "toolStrip1";
//
// txtScriptContent
//
@ -414,7 +365,6 @@
this.txtScriptContent.Cursor = System.Windows.Forms.Cursors.IBeam;
this.txtScriptContent.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.txtScriptContent.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtScriptContent.Font = new System.Drawing.Font("Courier New", 9.75F);
this.txtScriptContent.IsReplaceMode = false;
this.txtScriptContent.Language = FastColoredTextBoxNS.Language.Lua;
this.txtScriptContent.LeftBracket = '(';
@ -547,7 +497,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(965, 587);
this.Controls.Add(this.ctrlSplit);
this.Controls.Add(this.toolStrip1);
this.Controls.Add(this.tsToolbar);
this.Controls.Add(this.mnuMain);
this.Controls.Add(this.statusStrip1);
this.MainMenuStrip = this.mnuMain;
@ -556,8 +506,6 @@
this.Text = "Script Window";
this.mnuMain.ResumeLayout(false);
this.mnuMain.PerformLayout();
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.txtScriptContent)).EndInit();
this.contextMenu.ResumeLayout(false);
this.ctrlSplit.Panel1.ResumeLayout(false);
@ -577,21 +525,16 @@
private Mesen.GUI.Controls.ctrlMesenMenuStrip mnuMain;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuOpen;
private Mesen.GUI.Controls.ctrlMesenToolStrip toolStrip1;
private System.Windows.Forms.ToolStripButton btnRun;
private Mesen.GUI.Controls.ctrlMesenToolStrip tsToolbar;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem mnuClose;
private System.Windows.Forms.ToolStripMenuItem scriptToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuRun;
private FastColoredTextBoxNS.FastColoredTextBox txtScriptContent;
private System.Windows.Forms.ToolStripButton btnSave;
private System.Windows.Forms.ToolStripButton btnOpen;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripMenuItem mnuSave;
private System.Windows.Forms.ToolStripMenuItem mnuRecentScripts;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
private System.Windows.Forms.ToolStripMenuItem mnuStop;
private System.Windows.Forms.ToolStripButton btnStop;
private GUI.Controls.ctrlSplitContainer ctrlSplit;
private System.Windows.Forms.TextBox txtLog;
private System.Windows.Forms.Timer tmrLog;
@ -622,5 +565,6 @@
private System.Windows.Forms.ToolStripMenuItem mnuAutoLoadLastScript;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem6;
private System.Windows.Forms.ToolStripMenuItem mnuSelectFont;
private System.Windows.Forms.ToolStripMenuItem mnuBuiltInScripts;
}
}

View file

@ -30,6 +30,20 @@ namespace Mesen.GUI.Debugger
{
InitializeComponent();
List<string> builtInScripts = new List<string> { "DmcCapture.lua", "DrawMode.lua", "GameBoyMode.lua", "Grid.lua", "ReverseMode.lua", "SpriteBox.lua" };
foreach(string script in builtInScripts) {
ToolStripItem item = mnuBuiltInScripts.DropDownItems.Add(script);
item.Click += (s, e) => {
LoadBuiltInScript(item.Text);
};
}
tsToolbar.AddItemsToToolbar(
mnuOpen, mnuSave, null,
mnuRun, mnuStop, null,
mnuBuiltInScripts
);
DebugInfo config = ConfigManager.Config.DebugInfo;
_popupMenu = new AutocompleteMenu(txtScriptContent, this);
@ -80,13 +94,7 @@ namespace Mesen.GUI.Debugger
LoadScriptFile(scriptToLoad, false);
}
} else if(mnuTutorialScript.Checked) {
using(Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Mesen.GUI.Debugger.Example.lua")) {
using(StreamReader reader = new StreamReader(stream)) {
txtScriptContent.Text = reader.ReadToEnd();
_originalText = txtScriptContent.Text;
txtScriptContent.ClearUndo();
}
}
LoadBuiltInScript("Example.lua");
}
}
@ -195,6 +203,18 @@ namespace Mesen.GUI.Debugger
}
return true;
}
private void LoadBuiltInScript(string name)
{
if(!SavePrompt()) {
return;
}
this.Text = $"{name} - Script Window";
txtScriptContent.Text = ResourceManager.ReadZippedResource(name);
_originalText = txtScriptContent.Text;
txtScriptContent.ClearUndo();
}
public void LoadScriptFile(string filepath, bool runScript = true)
{
@ -311,11 +331,6 @@ namespace Mesen.GUI.Debugger
LoadScript();
}
private void btnRun_Click(object sender, EventArgs e)
{
RunScript();
}
private void mnuClose_Click(object sender, EventArgs e)
{
this.Close();
@ -326,7 +341,7 @@ namespace Mesen.GUI.Debugger
RunScript();
}
private void btnSave_Click(object sender, EventArgs e)
private void mnuSave_Click(object sender, EventArgs e)
{
SaveScript();
}
@ -336,21 +351,11 @@ namespace Mesen.GUI.Debugger
SaveAs(Path.GetFileName(this._filePath));
}
private void btnOpen_Click(object sender, EventArgs e)
{
LoadScript();
}
private void mnuStop_Click(object sender, EventArgs e)
{
StopScript();
}
private void btnStop_Click(object sender, EventArgs e)
{
StopScript();
}
private void tmrLog_Tick(object sender, EventArgs e)
{
if(_scriptId >= 0) {
@ -364,7 +369,7 @@ namespace Mesen.GUI.Debugger
}
}
mnuSave.Enabled = btnSave.Enabled = txtScriptContent.Text != _originalText;
mnuSave.Enabled = txtScriptContent.Text != _originalText;
if(_filePath != null && File.Exists(_filePath) && mnuAutoReload.Checked) {
if(_lastTimestamp < File.GetLastWriteTime(_filePath)) {

View file

@ -123,16 +123,16 @@
<metadata name="mnuMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>107, 17</value>
</metadata>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="tsToolbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>211, 17</value>
</metadata>
<metadata name="contextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>523, 17</value>
<value>521, 17</value>
</metadata>
<metadata name="tmrLog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>316, 17</value>
<value>314, 17</value>
</metadata>
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>407, 17</value>
<value>405, 17</value>
</metadata>
</root>

View file

@ -0,0 +1,127 @@
-----------------------
-- Name: DMC Capture
-- Author: upsilandre
-----------------------
-- Displays information about the DMC samples: [Sample Address] [Sample Size (bytes)] [Sample Frequency]
-- Every new sample encountered will be logged in the script's log window.
-- Right-clicking on the screen turns on DMC sample recording. While recording, any sample played
-- will be recorded on the disk in .wav format in the LuaScriptData folder
-----------------------
function Main()
dmc = emu.getState().apu.dmc
SelectRecord()
if dmc.bytesRemaining > 0 then
freq = math.floor(dmc.sampleRate)
new = true
if nbSample > 0 then
for i = 1,nbSample do
if (dmc.sampleAddr == sample.addr[i] and dmc.sampleLength == sample.length[i] and dmc.period == sample.period[i]) then
new = false
break
end
end
end
if new then
nbSample = nbSample + 1
sample.addr[nbSample] = dmc.sampleAddr
sample.length[nbSample] = dmc.sampleLength
sample.period[nbSample] = dmc.period
emu.log(nbSample.." >> $"..string.format("%X ", dmc.sampleAddr)..string.format("%4d bytes ",dmc.sampleLength)..string.format("%5d hertz ",freq)..stringR)
if record then
SampleRecord(dmc.sampleAddr, dmc.sampleLength, freq)
end
end
if dmc.sampleAddr ~= lastSampleAddr or dmc.sampleLength ~= lastSampleLength or dmc.period ~= lastSamplePeriod then
lastSampleAddr = dmc.sampleAddr
lastSampleLength = dmc.sampleLength
lastSamplePeriod = dmc.period
emu.drawString(4, 7, " $"..string.format("%X ", dmc.sampleAddr)..string.format("%4d bytes ",dmc.sampleLength)..string.format("%5d hertz ",freq), 0xffffff, 0x40ffffff, 2)
else
emu.drawString(4, 7, " $"..string.format("%X ", dmc.sampleAddr)..string.format("%4d bytes ",dmc.sampleLength)..string.format("%5d hertz ",freq), 0xc0c0c0, 0x40202020, 1)
end
end
end
function SelectRecord()
if emu.getMouseState().right then
if not hold then
hold = true
record = not record
nbSample = 0
emu.log("______________________________________________________________________\n")
if record then
emu.log("File path = "..emu.getScriptDataFolder().."\\\n")
end
end
else
hold = false
end
if record then
stringR = " recorded"
emu.drawRectangle(193, 5, 42, 11, 0x404040, true, 1)
emu.drawRectangle(192, 4, 44, 13, 0x808080, false, 1)
emu.drawString(196, 7, "RECORD", 0xFF0000, 0xFF000000, 1)
else
stringR = ""
end
end
function SampleRecord(addr, length, freq)
dataLen = length * 8 + 1
header[5] = (dataLen + 36) & 255
header[6] = (dataLen + 36) >> 8
header[25] = freq & 255
header[26] = freq >> 8
header[29] = header[25]
header[30] = header[26]
header[41] = dataLen & 255
header[42] = dataLen >> 8
header[45] = 0x80
fileName = string.sub(emu.getRomInfo().name, 1, #emu.getRomInfo().name - 4)..string.format("_$%X_", addr)..length.."b_"..freq.."hz.wav"
fileOutput = io.open(emu.getScriptDataFolder().."\\"..fileName, "w+b")
for k = 1,45 do
fileOutput:write(string.char(header[k]))
end
lastSample = 0x80
for i = 0, length - 1 do
bitMask = 1
byte = emu.read(addr + i, emu.memType.cpuDebug)
for j = 1,8 do
if byte & bitMask > 0 then
newSample = lastSample + 4
if newSample == 256 then
newSample = 252
end
else
newSample = lastSample - 4
if newSample == -4 then
newSample = 0
end
end
fileOutput:write(string.char(newSample))
lastSample = newSample
bitMask = bitMask << 1
end
end
fileOutput:close()
end
sample = {}
sample.addr = {}
sample.length = {}
sample.period = {}
nbSample = 0
record = false
hold = false
header = {0x52,0x49,0x46,0x46,0x00,0x00,0x00,0x00,
0x57,0x41,0x56,0x45,0x66,0x6D,0x74,0x20,
0x10,0x00,0x00,0x00,0x01,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x00,0x08,0x00,0x64,0x61,0x74,0x61,
0x00,0x00,0x00,0x00}
emu.addEventCallback(Main, emu.eventType.endFrame);
emu.displayMessage("Script", "DMC Capture")

View file

@ -0,0 +1,30 @@
-----------------------
-- Name: Draw Mode
-- Author: upsilandre
-----------------------
-- Allows you to draw an overlay over the game's screen by left-clicking with the mouse.
-- Right-click to clear the overlay.
-----------------------
function Main()
mouse = emu.getMouseState()
if mouse.left then
if not hold then
hold = true
else
emu.drawLine( oldX, oldY, mouse.x, mouse.y, 0xFF0000, 10000000)
end
oldX = mouse.x
oldY = mouse.y
else
hold = false
end
if mouse.right then
emu.clearScreen()
end
end
hold = false
emu.addEventCallback(Main, emu.eventType.endFrame);
emu.displayMessage("Script", "Draw Mode")

View file

@ -1,4 +1,4 @@
--This is an example script to give a general idea of how to build scripts
--This is an example script to give a general idea of how to build scripts
--Press F5 or click the Run button to execute it
--Scripts must be written in Lua (https://www.lua.org)
--This text editor contains an auto-complete feature for all Mesen-specific functions

View file

@ -0,0 +1,98 @@
-----------------------
-- Name: Game Boy Mode
-- Author: upsilandre
-----------------------
-- Simulates the game boy's display limitations
-- 1. Adds a 160x144 frame which can be moved by clicking inside it. Clicking outside of it will hide the black overlay.
-- 2. Restricts the palette to a 4-color palette like the game boy - right-click the screen to change the palette.
-----------------------
function Main()
mouse = emu.getMouseState()
if mouse.left then
if stencil then
if mouse.x > window_X and mouse.x < window_X + 160 and mouse.y > window_Y and mouse.y < window_Y + 144 then
window_X = mouse.x - 80
window_Y = mouse.y - 72
else
stencil = false
holdLeft = true
end
else
if not holdLeft then
holdLeft = true
stencil = true
window_X = mouse.x - 80
window_Y = mouse.y - 72
end
end
else
holdLeft = false
end
if mouse.right then
if not holdRight then
holdRight = true
colorB = color1
color1 = color2
color2 = color3
color3 = color4
color4 = colorB
cycleP = cycleP + 1
if cycleP == 4 then
cycleP = 0
colorB = color5
color5 = color6
color6 = color7
color7 = color8
color8 = colorB
end
end
else
holdRight = false
end
if stencil then
if window_X > 0 then
emu.drawRectangle(0, window_Y, window_X, 144, 0x000000, true)
end
if window_X < 96 then
emu.drawRectangle(window_X + 160, window_Y, 96 - window_X, 144, 0x000000, true)
end
if window_Y > 0 then
emu.drawRectangle(0, 0, 256, window_Y, 0x000000, true)
end
if window_Y < 96 then
emu.drawRectangle(0, window_Y + 144, 256, 96 - window_Y, 0x000000, true)
end
end
for x = 0,0x0f,4 do
emu.write(x, color1, emu.memType.palette)
emu.write(x + 1, color2, emu.memType.palette)
emu.write(x + 2, color3, emu.memType.palette)
emu.write(x + 3, color4, emu.memType.palette)
emu.write(x + 16, color1, emu.memType.palette)
emu.write(x + 17, color6, emu.memType.palette)
emu.write(x + 18, color7, emu.memType.palette)
emu.write(x + 19, color8, emu.memType.palette)
end
end
window_X = 48
window_Y = 48
cycleP = 0
colorB = 0
color1 = 0x38
color2 = 0x28
color3 = 0x18
color4 = 0x08
color5 = 0x38
color6 = 0x28
color7 = 0x18
color8 = 0x08
stencil = true
holdLeft = false
holdRight = false
emu.addEventCallback(Main, emu.eventType.startFrame)
emu.displayMessage("Script", "GameBoy mode")

View file

@ -0,0 +1,42 @@
-----------------------
-- Name: Grid
-- Author: upsilandre
-----------------------
-- Displays a grid overlay on the screen (8x8, 16x16 or 32x32) - right-click to change the grid's size
-----------------------
function Main()
if emu.getMouseState().right then
if not hold then
hold = true
mode = (mode + 1) % 3
emu.drawRectangle( 95, 87, 67, 11, 0x808080, false, 50)
if mode == 0 then
size = 8
emu.drawString(96, 89, " 8x8 Grid ", 0xFFFFFF, 0x404040, 50)
elseif mode == 1 then
size = 16
emu.drawString(96, 89, " 16x16 Grid ", 0xFFFFFF, 0x404040, 50)
else
size = 32
emu.drawString(96, 89, " 32x32 Grid ", 0xFFFFFF, 0x404040, 50)
end
end
else
hold = false
end
for i = 0, 239, size do
emu.drawLine( 0, i, 255, i, color, 1)
end
for i = 0, 255, size do
emu.drawLine( i, 0, i, 239, color, 1)
end
end
color = 0xC0FF0000
hold = false
mode = 0
size = 8
emu.addEventCallback(Main, emu.eventType.endFrame);
emu.displayMessage("Script", "Grid")

View file

@ -0,0 +1,24 @@
-----------------------
-- Name: Reverse Mode
-- Author: upsilandre
-----------------------
-- Flips the game screen horizontally and inverts the left & right buttons
-- on the controller, allowing you to play through games in reverse.
-----------------------
bufferO = {}
function Main()
input = emu.getInput(0)
input.left, input.right = input.right, input.left
emu.setInput(0, input)
bufferI = emu.getScreenBuffer()
for y = 0, 239 do
for x = 0, 255 do
bufferO[y*256 + x] = bufferI[y*256 + 255 - x]
end
end
emu.setScreenBuffer(bufferO)
end
emu.addEventCallback(Main, emu.eventType.inputPolled)
emu.displayMessage("Script", "Reverse Mode")

View file

@ -0,0 +1,110 @@
-----------------------
-- Name: Sprite Box
-- Author: upsilandre
-----------------------
-- Displays a box around each sprite, as well as a sprite counter.
-- The counter displays the number of sprites on the screen (and will be shown in red if sprite overflow occurred on any scanline)
--
-- Each scanline with overflow will be marked by a small red line on the left side of the screen.
-- As the number of sprites over the limit increases, the line will progressively turn orange, yellow and then white.
--
-- Sprites with a red box as normal priority sprites, those in blue are background priority sprites.
--
-- 4 different display modes exist (change mode by right-clicking on the screen):
-- 1- Edge Mode: Displays a rectangle outline around the sprites
-- 2- Fill Mode: Displays a transparent overlay over the sprites
-- 3- Priority Mode: Displays a transparent overlay over the sprites (the overlay's opacity is proportional to the sprite's position in OAM RAM)
-- 4- Off Mode: Displays the sprite counter and nothing else
-----------------------
function Main()
SelectMode()
spritesOnScreen = 0
counterColor = 0xFFFFFF
for scanline = 0,254 do
spritesOnLine[scanline] = 0
end
ppu = emu.getState().ppu
if ppu.control.largeSprites then
height = 16
else
height = 8
end
for oamAddr = 0, 252, 4 do
spriteY = emu.read(oamAddr, emu.memType.oam) + 1
if spriteY < 240 then
spritesOnScreen = spritesOnScreen + 1
for i = 0, (height - 1 ) do
spritesOnLine[spriteY + i] = spritesOnLine[spriteY + i] + 1
end
end
spriteX = emu.read(oamAddr + 3, emu.memType.oam)
if emu.read(oamAddr + 2, emu.memType.oam) & 32 == 0 then
color = 0xff0000
else
color = 0x0000ff
end
if mode == 2 then
alpha = oamAddr / 4 * 0x03000000 + 0x20000000
end
emu.drawRectangle(spriteX, spriteY, 8, height, color + alpha, fill, 1)
end
for scanline = 0,239 do
overflow = spritesOnLine[scanline] - 8
if overflow > 0 then
if overflow > 16 then
overflowColor = 0xFFFFFF
elseif overflow > 8 then
overflowColor = 0xFFFF00 + (((overflow - 1) & 7) << 5)
else
overflowColor = 0xFF0000 + (((overflow - 1) & 7) << 13)
end
emu.drawLine(0, scanline, 7, scanline, overflowColor, 1)
counterColor = 0xFF0000
end
end
emu.drawRectangle(121, 3, 13, 9, 0x404040, true, 1)
emu.drawRectangle(120, 2, 15, 11, 0x808080, false, 1)
emu.drawString(122, 4, string.format("%02d", spritesOnScreen), counterColor, 0xFF000000, 1)
end
function SelectMode()
if emu.getMouseState().right then
if not holdButton then
mode = (mode + 1) & 3
emu.drawRectangle(94, 87, 68, 12, 0x404040, true, 50)
emu.drawRectangle(93, 86, 70, 14, 0x808080, false, 50)
if mode == 0 then
fill = false
alpha = 0x40000000
emu.drawString(92, 89, " Edge Mode ", 0xFFFFFF, 0xFF000000, 50)
elseif mode == 1 then
fill = true
alpha = 0x80000000
emu.drawString(92, 89, " Fill Mode ", 0xFFFFFF, 0xFF000000, 50)
elseif mode == 2 then
emu.drawString(92, 89, " Priority Mode ", 0xFFFFFF, 0xFF000000, 50)
else
emu.drawString(92, 89, " OFF Mode ", 0xFFFFFF, 0xFF000000, 50)
alpha =0xFF000000
end
holdButton = true
end
else
holdButton = false
end
end
mode = 0
alpha = 0x40000000
holdButton = false
fill = false
spritesOnLine = {}
emu.addEventCallback(Main, emu.eventType.startFrame)
emu.displayMessage("Script", "Sprite Box")

View file

@ -1168,6 +1168,24 @@
<Compile Include="RuntimeChecker.cs" />
<Compile Include="SingleInstance.cs" />
<Compile Include="TestRunner.cs" />
<None Include="Dependencies\LuaScripts\DmcCapture.lua">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Dependencies\LuaScripts\DrawMode.lua">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Dependencies\LuaScripts\GameBoyMode.lua">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Dependencies\LuaScripts\Grid.lua">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Dependencies\LuaScripts\ReverseMode.lua">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Dependencies\LuaScripts\SpriteBox.lua">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Resources\SwitchView.png" />
<None Include="Resources\SelectAll.png" />
<None Include="Resources\Paste.png" />
@ -1227,7 +1245,9 @@
<EmbeddedResource Include="Debugger\Controls\ctrlSourceViewer.resx">
<DependentUpon>ctrlSourceViewer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Example.lua" />
<EmbeddedResource Include="Dependencies\LuaScripts\Example.lua">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<None Include="Resources\PipetteSmall.png" />
<None Include="Resources\Enum.png" />
<None Include="Resources\Script.png" />

View file

@ -66,6 +66,21 @@ namespace Mesen.GUI
return null;
}
public static string ReadZippedResource(string filename)
{
ZipArchive zip = new ZipArchive(Assembly.GetExecutingAssembly().GetManifestResourceStream("Mesen.GUI.Dependencies.Dependencies.zip"));
foreach(ZipArchiveEntry entry in zip.Entries) {
if(entry.Name == filename) {
using(Stream stream = entry.Open()) {
using(StreamReader reader = new StreamReader(stream)) {
return reader.ReadToEnd();
}
}
}
}
return null;
}
private static void CleanupOldFiles()
{
try {