MindBlow: Brainfuck IDE for ShiftOS

For 50,000 Codepoints you can write and run Brainfuck programs in
a dedicated IDE. Check out the site on "shiftnet/mindblow".

The IDE seems to be working perfectly. The site has some theming
issues.
This commit is contained in:
RogueAI42 2017-06-17 19:16:50 +10:00
parent 77cb4a9a14
commit dbf794c984
12 changed files with 1099 additions and 0 deletions

View file

@ -0,0 +1,209 @@
namespace ShiftOS.WinForms.Applications
{
partial class MindBlow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tabs = new System.Windows.Forms.TabControl();
this.console = new System.Windows.Forms.TabPage();
this.program = new System.Windows.Forms.TabPage();
this.monitor = new System.Windows.Forms.TabPage();
this.consoleout = new System.Windows.Forms.TextBox();
this.programinput = new System.Windows.Forms.TextBox();
this.load = new System.Windows.Forms.Button();
this.save = new System.Windows.Forms.Button();
this.memptr = new System.Windows.Forms.Label();
this.instptr = new System.Windows.Forms.Label();
this.memlist = new System.Windows.Forms.ListBox();
this.run = new System.Windows.Forms.Button();
this.tabs.SuspendLayout();
this.console.SuspendLayout();
this.program.SuspendLayout();
this.monitor.SuspendLayout();
this.SuspendLayout();
//
// tabs
//
this.tabs.Controls.Add(this.console);
this.tabs.Controls.Add(this.program);
this.tabs.Controls.Add(this.monitor);
this.tabs.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabs.Location = new System.Drawing.Point(0, 0);
this.tabs.Name = "tabs";
this.tabs.SelectedIndex = 0;
this.tabs.Size = new System.Drawing.Size(392, 269);
this.tabs.TabIndex = 0;
this.tabs.Selected += new System.Windows.Forms.TabControlEventHandler(this.tabs_Selected);
//
// console
//
this.console.Controls.Add(this.consoleout);
this.console.Location = new System.Drawing.Point(4, 22);
this.console.Name = "console";
this.console.Padding = new System.Windows.Forms.Padding(3);
this.console.Size = new System.Drawing.Size(384, 243);
this.console.TabIndex = 0;
this.console.Text = "Console";
this.console.UseVisualStyleBackColor = true;
//
// program
//
this.program.Controls.Add(this.run);
this.program.Controls.Add(this.save);
this.program.Controls.Add(this.load);
this.program.Controls.Add(this.programinput);
this.program.Location = new System.Drawing.Point(4, 22);
this.program.Name = "program";
this.program.Padding = new System.Windows.Forms.Padding(3);
this.program.Size = new System.Drawing.Size(384, 243);
this.program.TabIndex = 1;
this.program.Text = "Program";
this.program.UseVisualStyleBackColor = true;
//
// monitor
//
this.monitor.Controls.Add(this.memlist);
this.monitor.Controls.Add(this.instptr);
this.monitor.Controls.Add(this.memptr);
this.monitor.Location = new System.Drawing.Point(4, 22);
this.monitor.Name = "monitor";
this.monitor.Size = new System.Drawing.Size(384, 243);
this.monitor.TabIndex = 2;
this.monitor.Text = "Monitor";
this.monitor.UseVisualStyleBackColor = true;
//
// consoleout
//
this.consoleout.Dock = System.Windows.Forms.DockStyle.Fill;
this.consoleout.Location = new System.Drawing.Point(3, 3);
this.consoleout.Multiline = true;
this.consoleout.Name = "consoleout";
this.consoleout.ReadOnly = true;
this.consoleout.Size = new System.Drawing.Size(378, 237);
this.consoleout.TabIndex = 0;
//
// programinput
//
this.programinput.Location = new System.Drawing.Point(3, 0);
this.programinput.Multiline = true;
this.programinput.Name = "programinput";
this.programinput.Size = new System.Drawing.Size(378, 218);
this.programinput.TabIndex = 0;
//
// load
//
this.load.Location = new System.Drawing.Point(6, 217);
this.load.Name = "load";
this.load.Size = new System.Drawing.Size(115, 23);
this.load.TabIndex = 1;
this.load.Text = "Load";
this.load.UseVisualStyleBackColor = true;
this.load.Click += new System.EventHandler(this.load_Click);
//
// save
//
this.save.Location = new System.Drawing.Point(127, 217);
this.save.Name = "save";
this.save.Size = new System.Drawing.Size(114, 23);
this.save.TabIndex = 2;
this.save.Text = "Save";
this.save.UseVisualStyleBackColor = true;
this.save.Click += new System.EventHandler(this.save_Click);
//
// memptr
//
this.memptr.AutoSize = true;
this.memptr.Location = new System.Drawing.Point(8, 8);
this.memptr.Name = "memptr";
this.memptr.Size = new System.Drawing.Size(56, 13);
this.memptr.TabIndex = 0;
this.memptr.Text = "Memory: 0";
//
// instptr
//
this.instptr.AutoSize = true;
this.instptr.Location = new System.Drawing.Point(8, 21);
this.instptr.Name = "instptr";
this.instptr.Size = new System.Drawing.Size(68, 13);
this.instptr.TabIndex = 1;
this.instptr.Text = "Instruction: 0";
//
// memlist
//
this.memlist.FormattingEnabled = true;
this.memlist.Location = new System.Drawing.Point(11, 37);
this.memlist.Name = "memlist";
this.memlist.ScrollAlwaysVisible = true;
this.memlist.SelectionMode = System.Windows.Forms.SelectionMode.None;
this.memlist.Size = new System.Drawing.Size(370, 199);
this.memlist.TabIndex = 2;
//
// run
//
this.run.Location = new System.Drawing.Point(247, 217);
this.run.Name = "run";
this.run.Size = new System.Drawing.Size(131, 23);
this.run.TabIndex = 3;
this.run.Text = "Run";
this.run.UseVisualStyleBackColor = true;
this.run.Click += new System.EventHandler(this.run_Click);
//
// MindBlow
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tabs);
this.Name = "MindBlow";
this.Size = new System.Drawing.Size(392, 269);
this.Resize += new System.EventHandler(this.MindBlow_Resize);
this.tabs.ResumeLayout(false);
this.console.ResumeLayout(false);
this.console.PerformLayout();
this.program.ResumeLayout(false);
this.program.PerformLayout();
this.monitor.ResumeLayout(false);
this.monitor.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabs;
private System.Windows.Forms.TabPage console;
private System.Windows.Forms.TabPage program;
private System.Windows.Forms.TabPage monitor;
private System.Windows.Forms.TextBox consoleout;
private System.Windows.Forms.TextBox programinput;
private System.Windows.Forms.Button load;
private System.Windows.Forms.Button save;
private System.Windows.Forms.Label instptr;
private System.Windows.Forms.Label memptr;
private System.Windows.Forms.ListBox memlist;
private System.Windows.Forms.Button run;
}
}

View file

@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ShiftOS.Engine;
using System.IO;
using System.Threading;
namespace ShiftOS.WinForms.Applications
{
[WinOpen("mindblow")]
[Launcher("MindBlow", false, null, "Utilities")]
[RequiresUpgrade("mindblow")]
public partial class MindBlow : UserControl, IShiftOSWindow, IBFListener
{
private class TextBoxStream : Stream
{
private TextBox box;
private KeysConverter kc;
public TextBoxStream(TextBox mybox)
{
kc = new KeysConverter();
box = mybox;
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length => box.Text.Length;
public override long Position { get => Length; set => throw new NotImplementedException(); }
public override void Flush()
{
}
public override int Read(byte[] buffer, int offset, int count)
{
object lck = new object();
int ptr = offset;
KeyPressEventHandler handler = (o, a) =>
{
lock (lck)
{
buffer[ptr] = (byte)a.KeyChar;
ptr++;
}
};
Desktop.InvokeOnWorkerThread(() => box.KeyPress += handler);
while (true)
{
lock (lck)
if (ptr >= offset + count)
break;
}
Desktop.InvokeOnWorkerThread(() => box.KeyPress -= handler);
return count;
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
string output = "";
foreach (byte b in buffer.Skip(offset).Take(count))
output += Convert.ToChar(b);
Desktop.InvokeOnWorkerThread(() => box.Text += output);
}
}
private static string[] DefaultMem;
private BFInterpreter Interpreter;
private void DoLayout()
{
memlist.Left = 0;
memlist.Width = monitor.Width;
memlist.Height = monitor.Height - memlist.Top;
program.Top = 0;
program.Left = 0;
programinput.Width = program.Width;
programinput.Height = program.Height - load.Height;
load.Top = save.Top = run.Top = programinput.Height;
load.Width = save.Width = run.Width = save.Left = program.Width / 3;
run.Left = save.Left * 2;
}
public MindBlow()
{
InitializeComponent();
DefaultMem = new string[30000];
for (ushort i = 0; i < 30000; i++)
DefaultMem[i] = "0";
memlist.Items.AddRange(DefaultMem);
Interpreter = new BFInterpreter(new TextBoxStream(consoleout), this);
}
public void IPtrMoved(int newval)
{
Desktop.InvokeOnWorkerThread(() => instptr.Text = "Instruction: " + newval.ToString());
}
public void MemChanged(ushort pos, byte newval)
{
Desktop.InvokeOnWorkerThread(() => memlist.Items[pos] = newval.ToString());
}
public void MemReset()
{
Desktop.InvokeOnWorkerThread(() =>
{
memlist.Items.Clear();
memlist.Items.AddRange(DefaultMem);
});
}
public void OnLoad()
{
DoLayout();
}
public void OnSkinLoad()
{
}
public bool OnUnload()
{
return true;
}
public void OnUpgrade()
{
}
public void PointerMoved(ushort newval)
{
Desktop.InvokeOnWorkerThread(() => memptr.Text = "Memory: " + newval.ToString());
}
private void MindBlow_Resize(object sender, EventArgs e)
{
DoLayout();
}
private void run_Click(object sender, EventArgs e)
{
new Thread(() =>
{
Interpreter.Reset();
Interpreter.Execute(programinput.Text);
}).Start();
}
private void tabs_Selected(object sender, TabControlEventArgs e)
{
DoLayout();
}
private void load_Click(object sender, EventArgs e)
{
AppearanceManager.SetupDialog(new FileDialog(new string[] { ".bf" }, FileOpenerStyle.Open, new Action<string>((file) => programinput.Text = Objects.ShiftFS.Utils.ReadAllText(file))));
}
private void save_Click(object sender, EventArgs e)
{
AppearanceManager.SetupDialog(new FileDialog(new string[] { ".bf" }, FileOpenerStyle.Save, new Action<string>((file) => Objects.ShiftFS.Utils.WriteAllText(file, programinput.Text))));
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -1058,6 +1058,16 @@ namespace ShiftOS.WinForms.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap mindblow {
get {
object obj = ResourceManager.GetObject("mindblow", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View file

@ -34609,4 +34609,7 @@
<data name="ShiftOSFull" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ShiftOSFull.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="mindblow" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\mindblow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

@ -77,6 +77,12 @@
<Compile Include="Applications\IconManager.Designer.cs">
<DependentUpon>IconManager.cs</DependentUpon>
</Compile>
<Compile Include="Applications\MindBlow.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Applications\MindBlow.Designer.cs">
<DependentUpon>MindBlow.cs</DependentUpon>
</Compile>
<Compile Include="Applications\Pong.cs">
<SubType>UserControl</SubType>
</Compile>
@ -395,6 +401,12 @@
<Compile Include="ShiftnetSites\MainHomepage.Designer.cs">
<DependentUpon>MainHomepage.cs</DependentUpon>
</Compile>
<Compile Include="ShiftnetSites\MindBlow.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ShiftnetSites\MindBlow.Designer.cs">
<DependentUpon>MindBlow.cs</DependentUpon>
</Compile>
<Compile Include="ShiftnetSites\ShiftGames.cs">
<SubType>UserControl</SubType>
</Compile>
@ -484,6 +496,9 @@
<EmbeddedResource Include="Applications\IconManager.resx">
<DependentUpon>IconManager.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Applications\MindBlow.resx">
<DependentUpon>MindBlow.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Applications\Pong.resx">
<DependentUpon>Pong.cs</DependentUpon>
</EmbeddedResource>
@ -633,6 +648,9 @@
<EmbeddedResource Include="ShiftnetSites\MainHomepage.resx">
<DependentUpon>MainHomepage.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ShiftnetSites\MindBlow.resx">
<DependentUpon>MindBlow.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ShiftnetSites\ShiftGames.resx">
<DependentUpon>ShiftGames.cs</DependentUpon>
</EmbeddedResource>
@ -880,6 +898,7 @@
<None Include="Resources\iconSpeaker.bmp" />
<None Include="Resources\ShiftOSFull.png" />
<Content Include="Resources\GuessTheNumber.py" />
<None Include="Resources\mindblow.png" />
<Content Include="SystemIcons\iconArtpad.png" />
<Content Include="SystemIcons\iconAudioPlayer.png" />
<Content Include="SystemIcons\iconBitnoteDigger.png" />

View file

@ -0,0 +1,192 @@
namespace ShiftOS.WinForms.ShiftnetSites
{
partial class MindBlow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MindBlow));
this.nav = new System.Windows.Forms.Panel();
this.title = new System.Windows.Forms.Label();
this.aboutpnl = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
this.buybtn = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.aboutbtn = new System.Windows.Forms.LinkLabel();
this.tutorialpnl = new System.Windows.Forms.Panel();
this.label3 = new System.Windows.Forms.Label();
this.tutorialbtn = new System.Windows.Forms.LinkLabel();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.nav.SuspendLayout();
this.aboutpnl.SuspendLayout();
this.tutorialpnl.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// nav
//
this.nav.Controls.Add(this.tutorialbtn);
this.nav.Controls.Add(this.aboutbtn);
this.nav.Controls.Add(this.title);
this.nav.Dock = System.Windows.Forms.DockStyle.Left;
this.nav.Location = new System.Drawing.Point(0, 0);
this.nav.Name = "nav";
this.nav.Size = new System.Drawing.Size(200, 470);
this.nav.TabIndex = 0;
//
// title
//
this.title.AutoSize = true;
this.title.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.title.Location = new System.Drawing.Point(3, 0);
this.title.Name = "title";
this.title.Size = new System.Drawing.Size(101, 24);
this.title.TabIndex = 0;
this.title.Text = "MindBlow";
//
// aboutpnl
//
this.aboutpnl.Controls.Add(this.pictureBox1);
this.aboutpnl.Controls.Add(this.label2);
this.aboutpnl.Controls.Add(this.buybtn);
this.aboutpnl.Controls.Add(this.label1);
this.aboutpnl.Location = new System.Drawing.Point(206, 0);
this.aboutpnl.Name = "aboutpnl";
this.aboutpnl.Size = new System.Drawing.Size(512, 470);
this.aboutpnl.TabIndex = 1;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(3, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(313, 65);
this.label1.TabIndex = 0;
this.label1.Text = resources.GetString("label1.Text");
//
// buybtn
//
this.buybtn.Location = new System.Drawing.Point(6, 76);
this.buybtn.Name = "buybtn";
this.buybtn.Size = new System.Drawing.Size(75, 23);
this.buybtn.TabIndex = 1;
this.buybtn.Text = "Buy Now";
this.buybtn.UseVisualStyleBackColor = true;
this.buybtn.Click += new System.EventHandler(this.buybtn_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(87, 81);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(132, 13);
this.label2.TabIndex = 2;
this.label2.Text = "(Price: 50,000 Codepoints)";
//
// aboutbtn
//
this.aboutbtn.AutoSize = true;
this.aboutbtn.Location = new System.Drawing.Point(4, 24);
this.aboutbtn.Name = "aboutbtn";
this.aboutbtn.Size = new System.Drawing.Size(85, 13);
this.aboutbtn.TabIndex = 1;
this.aboutbtn.TabStop = true;
this.aboutbtn.Text = "About/Purchase";
this.aboutbtn.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.aboutbtn_LinkClicked);
//
// tutorialpnl
//
this.tutorialpnl.Controls.Add(this.label3);
this.tutorialpnl.Location = new System.Drawing.Point(209, 0);
this.tutorialpnl.Name = "tutorialpnl";
this.tutorialpnl.Size = new System.Drawing.Size(506, 467);
this.tutorialpnl.TabIndex = 2;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(3, 8);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(375, 208);
this.label3.TabIndex = 0;
this.label3.Text = resources.GetString("label3.Text");
//
// tutorialbtn
//
this.tutorialbtn.AutoSize = true;
this.tutorialbtn.Location = new System.Drawing.Point(4, 37);
this.tutorialbtn.Name = "tutorialbtn";
this.tutorialbtn.Size = new System.Drawing.Size(35, 13);
this.tutorialbtn.TabIndex = 2;
this.tutorialbtn.TabStop = true;
this.tutorialbtn.Text = "Guide";
this.tutorialbtn.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.tutorialbtn_LinkClicked);
//
// pictureBox1
//
this.pictureBox1.Image = global::ShiftOS.WinForms.Properties.Resources.mindblow;
this.pictureBox1.Location = new System.Drawing.Point(6, 105);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(390, 295);
this.pictureBox1.TabIndex = 3;
this.pictureBox1.TabStop = false;
//
// MindBlow
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.aboutpnl);
this.Controls.Add(this.tutorialpnl);
this.Controls.Add(this.nav);
this.Name = "MindBlow";
this.Size = new System.Drawing.Size(718, 470);
this.Resize += new System.EventHandler(this.MindBlow_Resize);
this.nav.ResumeLayout(false);
this.nav.PerformLayout();
this.aboutpnl.ResumeLayout(false);
this.aboutpnl.PerformLayout();
this.tutorialpnl.ResumeLayout(false);
this.tutorialpnl.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel nav;
private System.Windows.Forms.Label title;
private System.Windows.Forms.Panel aboutpnl;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button buybtn;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.LinkLabel aboutbtn;
private System.Windows.Forms.Panel tutorialpnl;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.LinkLabel tutorialbtn;
private System.Windows.Forms.PictureBox pictureBox1;
}
}

View file

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ShiftOS.Engine;
namespace ShiftOS.WinForms.ShiftnetSites
{
[ShiftnetSite("shiftnet/mindblow", "MindBlow", "World's First IDE for ShiftOS")]
public partial class MindBlow : UserControl, IShiftnetSite
{
public MindBlow()
{
InitializeComponent();
}
public event Action<string> GoToUrl;
public event Action GoBack;
private void DoLayout()
{
aboutpnl.Left = tutorialpnl.Left = nav.Width;
aboutpnl.Width = tutorialpnl.Width = Width - nav.Width;
tutorialpnl.Height = Height;
}
private void aboutbtn_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
aboutpnl.BringToFront();
}
private void tutorialbtn_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
tutorialpnl.BringToFront();
}
private void MindBlow_Resize(object sender, EventArgs e)
{
DoLayout();
}
private void buybtn_Click(object sender, EventArgs e)
{
if (Shiftorium.UpgradeInstalled("mindblow"))
Infobox.Show("Already Purchased", "You have already bought MindBlow.");
else if (SaveSystem.CurrentSave.Codepoints < 50000)
Infobox.Show("Not Enough Codepoints", "You do not have enough Codepoints to buy MindBlow.");
else
{
Shiftorium.Buy("mindblow", 50000);
Infobox.Show("Installation Complete", "MindBlow has been successfully installed.");
}
}
public void Setup()
{
DoLayout();
aboutpnl.BringToFront();
}
public void OnSkinLoad()
{
}
public void OnUpgrade()
{
}
}
}

View file

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="label1.Text" xml:space="preserve">
<value>Ever wanted to make your own ShiftOS software?
MindBlow is the world's first IDE designed specifically for ShiftOS.
It allows you to develop and run your own programs written in the
Brainfuck programming language.</value>
</data>
<data name="label3.Text" xml:space="preserve">
<value>The Brainfuck programming language is simple to learn and use.
There are a total of 8 commands in the language:
&gt; Increment the memory pointer.
&lt; Decrement the memory pointer.
+ Increment the number at the memory pointer.
- Decrement the number at the memory pointer.
. Print the ASCII value at the memory pointer.
, Get a character from the user and put its ASCII value at the memory pointer.
[ Jump to the next ']' if the number at the memory pointer is zero.
] Jump to the last '[' if the number at the memory pointer isn't zero.
Any characters that aren't valid commands will be ignored.
Here is a simple program to read 10 characters from the user and display them:
++++++++++
[-&gt;,.&lt;]</value>
</data>
</root>

View file

@ -0,0 +1,143 @@
/*
* MIT License
*
* Copyright (c) 2017 Michael VanOverbeek and ShiftOS devs
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ShiftOS.Engine
{
/// <summary>
/// Receives events from the interpreter.
/// </summary>
public interface IBFListener
{
void PointerMoved(ushort newval);
void IPtrMoved(int newval);
void MemChanged(ushort pos, byte newval);
void MemReset();
}
/// <summary>
/// Interprets Brainfuck code.
/// </summary>
public class BFInterpreter
{
private byte[] mem;
private ushort ptr;
private string prg;
private object lck;
private Stream str;
public IBFListener lst = null;
public BFInterpreter(Stream io, IBFListener listener = null, string program = "")
{
lck = new object();
prg = program;
str = io;
Reset();
lst = listener;
}
public void Execute()
{
lock (lck)
for (int iptr = 0; iptr < prg.Length; iptr++)
{
if (lst != null)
lst.IPtrMoved(iptr);
switch (prg[iptr])
{
case '>':
ptr++;
if (lst != null)
lst.PointerMoved(ptr);
break;
case '<':
ptr--;
if (lst != null)
lst.PointerMoved(ptr);
break;
case '+':
mem[ptr]++;
if (lst != null)
lst.MemChanged(ptr, mem[ptr]);
break;
case '-':
mem[ptr]--;
if (lst != null)
lst.MemChanged(ptr, mem[ptr]);
break;
case '.':
str.WriteByte(mem[ptr]);
break;
case ',':
mem[ptr] = (byte)str.ReadByte();
if (lst != null)
lst.MemChanged(ptr, mem[ptr]);
break;
case '[':
if (mem[ptr] == 0)
while (prg[iptr] != ']')
{
iptr++;
if (lst != null)
lst.IPtrMoved(iptr);
}
break;
case ']':
if (mem[ptr] != 0)
while (prg[iptr] != '[')
{
iptr--;
if (lst != null)
lst.IPtrMoved(iptr);
}
break;
}
}
}
public void Execute(string program)
{
lock (lck)
prg = program;
Execute();
}
public void Reset()
{
lock (lck)
{
mem = new byte[30000];
ptr = 0;
if (lst != null)
{
lst.MemReset();
lst.PointerMoved(0);
}
}
}
}
}

View file

@ -122,6 +122,7 @@
<Compile Include="AppearanceManager.cs" />
<Compile Include="AppLauncherDaemon.cs" />
<Compile Include="AudioManager.cs" />
<Compile Include="BFInterpreter.cs" />
<Compile Include="CommandParser.cs" />
<Compile Include="Commands.cs" />
<Compile Include="Command.cs" />