diff --git a/Docs/content/apireference/_index.md b/Docs/content/apireference/_index.md
index 6b8df70a..fb8f464e 100644
--- a/Docs/content/apireference/_index.md
+++ b/Docs/content/apireference/_index.md
@@ -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 [emu.stop()](/apireference/emulation.html#stop) function. The [emu.stop()](/apireference/emulation.html#stop) 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.
\ No newline at end of file
+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 [emu.stop()](/apireference/emulation.html#stop) function. The [emu.stop()](/apireference/emulation.html#stop) 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 %}}
diff --git a/Docs/content/debugging/Debugger.md b/Docs/content/debugging/Debugger.md
index c4f53f65..4a0577f9 100644
--- a/Docs/content/debugging/Debugger.md
+++ b/Docs/content/debugging/Debugger.md
@@ -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 ##
diff --git a/Docs/static/images/EditLabel.png b/Docs/static/images/EditLabel.png
index 36ef8391..0453e597 100644
Binary files a/Docs/static/images/EditLabel.png and b/Docs/static/images/EditLabel.png differ
diff --git a/GUI.NET/Debugger/frmEditLabel.Designer.cs b/GUI.NET/Debugger/frmEditLabel.Designer.cs
index 490283d6..10ff09fa 100644
--- a/GUI.NET/Debugger/frmEditLabel.Designer.cs
+++ b/GUI.NET/Debugger/frmEditLabel.Designer.cs
@@ -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);
}
diff --git a/GUI.NET/Debugger/frmEditLabel.cs b/GUI.NET/Debugger/frmEditLabel.cs
index 2a8e5dca..2a690736 100644
--- a/GUI.NET/Debugger/frmEditLabel.cs
+++ b/GUI.NET/Debugger/frmEditLabel.cs
@@ -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";
+ }
+ }
}
}