Docs: Added information on luasocket and multi-byte labels

This commit is contained in:
Sour 2019-01-12 13:47:07 -05:00
parent 6c33ffaa0a
commit 62d9213a41
5 changed files with 119 additions and 71 deletions

View file

@ -23,7 +23,9 @@ Lua scripting is still a relatively recent feature and the API is not quite stab
* [Enums](/apireference/enums.html)
## Test Runner Mode ##
## Additional features ##
### Test Runner Mode ###
Mesen can be started in a headless test runner mode that can be used to implement automated testing by using Lua scripts.
@ -32,4 +34,32 @@ To start Mesen in headless mode, use the `--testrunner` command line option and
Mesen.exe --testrunner MyGame.nes MyTest.lua
```
This will start Mesen (headless), load the game and the Lua script and start executing the game at maximum speed until the Lua script calls the <kbd>[emu.stop()](/apireference/emulation.html#stop)</kbd> function. The <kbd>[emu.stop()](/apireference/emulation.html#stop)</kbd> function can specify an exit code, which will be returned by the Mesen process, which can be used to validate whether the test passed or failed.
This will start Mesen (headless), load the game and the Lua script and start executing the game at maximum speed until the Lua script calls the <kbd>[emu.stop()](/apireference/emulation.html#stop)</kbd> function. The <kbd>[emu.stop()](/apireference/emulation.html#stop)</kbd> function can specify an exit code, which will be returned by the Mesen process, which can be used to validate whether the test passed or failed.
### LuaSocket ###
The Lua implementation found in Mesen has a version of [LuaSocket](http://w3.impa.br/~diego/software/luasocket/) ([GitHub](https://github.com/diegonehab/luasocket)) built into it. The `socket` and `mime` packages are available and can be accessed by using `local socket = require("socket.core")` and `local mime = require("mime.core")`, respectively.
See [LuaSocket's documentation](http://w3.impa.br/~diego/software/luasocket/reference.html) for more information on how to use this library.
Here is a tiny TCP socket sample that connects to google.com via HTTP and downloads the page:
```
local socket = require("socket.core")
local tcp = sock.tcp()
--Set a 2-second timeout for all request, otherwise the process could hang!
tcp:settimeout(2)
local res = tcp:connect("www.google.com", 80)
tcp:send("GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n")
local text
repeat
text = tcp:receive()
emu.log(text)
until text == nil
```
{{% notice warning %}}
Using sockets without calling the `settimeout(seconds)` function (and specifying a reasonable number of seconds) first can result in the Mesen process hanging until the socket finishes the operation it is waiting for.
For this reason, it is highly recommended to **ALWAYS** call `settimeout(seconds)` on any newly created TCP/etc object before calling any other function on it.
{{% /notice %}}

View file

@ -283,7 +283,9 @@ Various types of labels can be defined:
- **Register**: These are used to give name to built-in or mapper-specific registers. For example, the $2000 PPU register could be renamed to "PpuControl".
There are some restrictions on what a label can contain -- in general, they must begin with a letter or an underscore and cannot contain spaces or most non-alphanumeric characters.
Every type of label can also contain a comment. Comments are shown in the code window as well as in the tooltips that are displayed when putting your cursor over a label in the code window.
Labels can also contain a comment which is shown in the code window as well as in the tooltips that are displayed when putting your cursor over a label in the code window.
Multi-byte labels can be defined using the `Length` setting. This can be used to define multi-byte values, arrays or pointers in the code. Multi-byte labels will be shown with a +X offset modifier when referred to in the code window (e.g: `MyArrayLabel+2`)
## Function List ##

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

@ -28,6 +28,10 @@
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
this.nudLength = new Mesen.GUI.Controls.MesenNumericUpDown();
this.lblBytes = new System.Windows.Forms.Label();
this.lblLength = new System.Windows.Forms.Label();
this.lblLabel = new System.Windows.Forms.Label();
this.lblComment = new System.Windows.Forms.Label();
this.txtComment = new System.Windows.Forms.TextBox();
@ -39,13 +43,9 @@
this.lblAddressSign = new System.Windows.Forms.Label();
this.txtAddress = new System.Windows.Forms.TextBox();
this.lblRange = new System.Windows.Forms.Label();
this.lblLength = new System.Windows.Forms.Label();
this.nudLength = new Mesen.GUI.Controls.MesenNumericUpDown();
this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
this.lblBytes = new System.Windows.Forms.Label();
this.tableLayoutPanel1.SuspendLayout();
this.flowLayoutPanel2.SuspendLayout();
this.flowLayoutPanel3.SuspendLayout();
this.flowLayoutPanel2.SuspendLayout();
this.SuspendLayout();
//
// baseConfigPanel
@ -80,6 +80,68 @@
this.tableLayoutPanel1.Size = new System.Drawing.Size(377, 242);
this.tableLayoutPanel1.TabIndex = 2;
//
// flowLayoutPanel3
//
this.flowLayoutPanel3.Controls.Add(this.nudLength);
this.flowLayoutPanel3.Controls.Add(this.lblBytes);
this.flowLayoutPanel3.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
this.flowLayoutPanel3.Location = new System.Drawing.Point(60, 216);
this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel3.Name = "flowLayoutPanel3";
this.flowLayoutPanel3.Size = new System.Drawing.Size(200, 26);
this.flowLayoutPanel3.TabIndex = 9;
//
// nudLength
//
this.nudLength.DecimalPlaces = 0;
this.nudLength.Increment = new decimal(new int[] {
1,
0,
0,
0});
this.nudLength.Location = new System.Drawing.Point(3, 3);
this.nudLength.Maximum = new decimal(new int[] {
65536,
0,
0,
0});
this.nudLength.MaximumSize = new System.Drawing.Size(10000, 21);
this.nudLength.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudLength.MinimumSize = new System.Drawing.Size(0, 21);
this.nudLength.Name = "nudLength";
this.nudLength.Size = new System.Drawing.Size(52, 21);
this.nudLength.TabIndex = 9;
this.nudLength.Value = new decimal(new int[] {
1,
0,
0,
0});
this.nudLength.ValueChanged += new System.EventHandler(this.nudLength_ValueChanged);
//
// lblBytes
//
this.lblBytes.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblBytes.AutoSize = true;
this.lblBytes.Location = new System.Drawing.Point(61, 7);
this.lblBytes.Name = "lblBytes";
this.lblBytes.Size = new System.Drawing.Size(32, 13);
this.lblBytes.TabIndex = 10;
this.lblBytes.Text = "bytes";
//
// lblLength
//
this.lblLength.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblLength.AutoSize = true;
this.lblLength.Location = new System.Drawing.Point(3, 222);
this.lblLength.Name = "lblLength";
this.lblLength.Size = new System.Drawing.Size(43, 13);
this.lblLength.TabIndex = 8;
this.lblLength.Text = "Length:";
//
// lblLabel
//
this.lblLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
@ -189,67 +251,6 @@
this.lblRange.TabIndex = 10;
this.lblRange.Text = "(range)";
//
// lblLength
//
this.lblLength.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblLength.AutoSize = true;
this.lblLength.Location = new System.Drawing.Point(3, 222);
this.lblLength.Name = "lblLength";
this.lblLength.Size = new System.Drawing.Size(43, 13);
this.lblLength.TabIndex = 8;
this.lblLength.Text = "Length:";
//
// nudLength
//
this.nudLength.DecimalPlaces = 0;
this.nudLength.Increment = new decimal(new int[] {
1,
0,
0,
0});
this.nudLength.Location = new System.Drawing.Point(3, 3);
this.nudLength.Maximum = new decimal(new int[] {
65536,
0,
0,
0});
this.nudLength.MaximumSize = new System.Drawing.Size(10000, 21);
this.nudLength.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudLength.MinimumSize = new System.Drawing.Size(0, 21);
this.nudLength.Name = "nudLength";
this.nudLength.Size = new System.Drawing.Size(52, 21);
this.nudLength.TabIndex = 9;
this.nudLength.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// flowLayoutPanel3
//
this.flowLayoutPanel3.Controls.Add(this.nudLength);
this.flowLayoutPanel3.Controls.Add(this.lblBytes);
this.flowLayoutPanel3.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
this.flowLayoutPanel3.Location = new System.Drawing.Point(60, 216);
this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel3.Name = "flowLayoutPanel3";
this.flowLayoutPanel3.Size = new System.Drawing.Size(200, 26);
this.flowLayoutPanel3.TabIndex = 9;
//
// lblBytes
//
this.lblBytes.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblBytes.AutoSize = true;
this.lblBytes.Location = new System.Drawing.Point(61, 7);
this.lblBytes.Name = "lblBytes";
this.lblBytes.Size = new System.Drawing.Size(84, 13);
this.lblBytes.TabIndex = 10;
this.lblBytes.Text = "bytes (for arrays)";
//
// frmEditLabel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -264,10 +265,10 @@
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
this.flowLayoutPanel3.ResumeLayout(false);
this.flowLayoutPanel3.PerformLayout();
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
this.ResumeLayout(false);
}

View file

@ -43,6 +43,7 @@ namespace Mesen.GUI.Debugger
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
UpdateByteLabel();
txtLabel.Focus();
}
@ -100,5 +101,19 @@ namespace Mesen.GUI.Debugger
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void nudLength_ValueChanged(object sender, EventArgs e)
{
UpdateByteLabel();
}
private void UpdateByteLabel()
{
if(nudLength.Value > 1) {
lblBytes.Text = "bytes";
} else {
lblBytes.Text = "byte";
}
}
}
}