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"; + } + } } }