Working with Amiga C using Visual Studio Code

Working with Amiga C using Visual Studio Code

I’ve found it rather difficult to go back to coding on the Amiga with the available editors. Most of them lack decent syntax highlighting, formatting, intellisense and autocomplete.

Professionally I’m used to using the likes of Visual Studio which supplies all those features. Using Visual Studio Code, a free IDE from Microsoft, with a few extensions I’ve been able to code in Amiga C on windows quite well.

In the screenshot below, I have a folder on google drive set up in the following structure.

  • DH0 and DH1 are Workbench and Work respectively
  • Original System is a fresh install of Workbench 3.1 that I can use to setup a new hard drive in a matter of seconds
  • I have a copy of the RKM Companion Disk as a helpful reminder of things
  • A Backup of both DH0 and DH1 when both areworking correctly
  • Various adf’s of Devpac, Dice C, and SAS C v6

I’ll skip the installing of Workbench and SAS/C; suffice it to say it’s a case of inserting disk 1 running the install file and then inserting the other 5 as prompted.

You can obtain SAS/C from tosec or possibly the eab

I have my WinUAE hard drives set up like this: (running as an a1200, fasted possible setting on the CPU)

My copy of Visual Studio Code has the following extensions installed, you may not need all of them but I’m pretty sure you need C/C++ from Microsoft. (see image)

I Create a folder in windows at C:\Users\Joe\Google Drive\_Amiga\DH1\Projects\Joe5, this will be where I store all the files

As this is shared via WinUAE it’s now possible to do the following in CLI:

  • cd Work:/Projects/Joe5
  • scsetup

This creates some files used by/with sas/c

In Visual Studio Code, go to File->Open Folder, and select the Joe5(or relevant) folder, this will give you a window similar to that below:

All be it without the main.c, which needs to be created ( done by clicking on the file icon under the project explorer)

Next, the include files need to be imported. This is currently a bit obtuse in it’s implimentation, but it’s the only realistic way I can find of doing it; by causing a problem in your code.
In the image below I try to reference the exec/types.h, VSCode does not yet know what that file is!

This is advantageous though as Clicking on the ‘Edit “includePath” setting’ allows us to then point VSCode to add Sas/C’s include directory. (your path’s may be different) see below:

When this is set, save and close main.c and you should have intellisense and autocomplete, very useful!.. allowing for things like this:

On the Amiga side, we can now run mkmk to create a makefile, after the make file has been created we can then smake

Due to my sloppy coding, I forgot to do a few things correctly, Which caused errors during the build process, I was able to output the results of the build to a file, also viewable in VSCode:

So I fix the code, and then run smake

Type main (the name of the program)

And that’s it!

P.S. This was written rather quickly, so any spelling mistakes or glaring errors I apologise for!

Download the example project.

XML Serialization quick and easy csharp

Serialization with XML and C#

this is mainly here as a reminder for me on how to do it!

To serialize to a file:


using System.Xml;
using System.Xml.Serialization;
// other code

List<string> mylist = this.getList();

Type stype = typeof(List<string>);

var serializer = new XmlSerializer(stype);
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true; // this is because of microsofts dodgy xml tag
using (var writer = XmlWriter.Create("outputfile.xml",settings))
{
serializer.Serialize(writer,mylist);
}
 

To serialize to a string:

string r = "";
List<string> mylist = this.getList();
   using (MemoryStream memS = new MemoryStream())
    {
      //set up the xml settings
      XmlWriterSettings settings = new XmlWriterSettings();
      settings.OmitXmlDeclaration = true;
      Type stype = typeof(mylist);
      var xmlSerializer = new XmlSerializer(stype);
      StringBuilder retString = new StringBuilder();
      using (XmlWriter writer = XmlTextWriter.Create(memS, settings))
       {
         //write the XML to a stream
         xmlSerializer.Serialize(writer, mylist);
         writer.Close();
       }
    //encode the memory stream to xml
    string v = Encoding.UTF8.GetString(memS.ToArray());
    r = v;             
    memS.Close(); // the using should do this anyway
    }        

To de-serialize xml from a string

public List<string> getMyStrings(string xmlString)
{
 XmlSerializer serializer = new XmlSerializer(typeof(List<string>));
   using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xmlString)))
    {
      return (List<string>)serializer.Deserialize(ms);
    }
}

That’s it, any errors are due to me typing most of it from memory, so if it doesn’t work it’s probably missing a ‘;’ or something

You will need these usings:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

Bootstrap compatible asp.net button

Similar to my previous post, you can use the following code to create a custom asp.net button with the ‘button’ tags used in HTML5 and bootstrap.

  [ParseChildren]
   public class bsButton : Button
    {

        private string _ButtonCss = "btn btn-default";
        [Browsable(true), Description("The css class"),]
        public string ButtonCss
        {
            get
            { return _ButtonCss; }
            set
            {
                _ButtonCss = value;
            }
        }

        private string _glyphicon = "";
        [Browsable(true), Description("GlyphiconName"),]
        public string glyphIcon
        {
            get
            {
                return _glyphicon;
            }
            set
            {
                _glyphicon = value;
            }

        }


        protected override void Render(HtmlTextWriter writer)
        {

            if (glyphIcon == "")
            {
                System.Web.UI.HtmlControls.HtmlGenericControl
                            btn = new System.Web.UI.HtmlControls.HtmlGenericControl("button");
                btn.Page = this.Page;
                btn.ID = this.ClientID;
                btn.InnerText = this.Text;
                btn.Attributes.Add("class", ButtonCss);
                btn.Visible = this.Visible;
                btn.Attributes.Add("name", this.UniqueID);
                btn.Attributes.Add("onchange", "__doPostBack('" + this.ClientID + "', 'OnClick',true)"); // fire postback
                btn.RenderControl(writer);
            }

            else {
                System.Web.UI.HtmlControls.HtmlGenericControl groupbtn = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
                groupbtn.Attributes.Add("class", "input-group-btn");

                System.Web.UI.HtmlControls.HtmlGenericControl
                       btn = new System.Web.UI.HtmlControls.HtmlGenericControl("button");
                System.Web.UI.HtmlControls.HtmlGenericControl
                    ithing = new System.Web.UI.HtmlControls.HtmlGenericControl("i");

                Literal litText = new Literal();

                ithing.Attributes.Add("class", "glyphicon glyphicon-" + glyphIcon);

                btn.Page = this.Page;
                btn.ID = this.ClientID;
                litText.Text = this.Text;
                btn.Attributes.Add("class", ButtonCss);
                btn.Visible = this.Visible;
                btn.Attributes.Add("name", this.UniqueID);
                btn.Attributes.Add("onchange", "__doPostBack('" + this.ClientID + "', 'OnClick',true)"); // fire postback
                btn.Controls.Add(ithing);
                btn.Controls.Add(litText);
                groupbtn.Controls.Add(btn);

                groupbtn.RenderControl(writer);


            }


        }
    }

you will need to surround that with

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Controls
{
//..Code here
}

Or append it to the class used for the radio button list.

Calculate a fraction in javascript

Calculating a fraction from a double in javascript

The following code will allow you to calculate a fraction in javascript

 function getFraction(dblValue, dblTolerance)
    {
        var f0 = 1 / dblValue;

        var f1 = 1 / (f0 - Math.floor(f0));

        var a_t = Math.floor(f0);

        var a_r = Math.round(f0);

        var b_t = Math.floor(f1);

        var b_r = Math.round(f1);

        var c = Math.round(1 / (f1 - Math.floor(f1)));

        if (Math.abs(1.0 / a_r - dblValue) <= dblTolerance)
        {
            return [1, a_r];
        }
        else if (Math.abs(b_r / (a_t * b_r + 1.0) - dblValue) <= dblTolerance)
        {
            return [b_r, a_t * b_r + 1];
        }
        else {
            return [c * b_t + 1, c * a_t * b_t + a_t + c];

        }
    }

For example the following code examples give you a numerator and a denominator

console.log(getFraction(0.75,0.02));
/*[3, 4]*/
/***********************************/

console.log(getFraction(0.5,0.02));
/*[1, 2]*/
/***********************************/

console.log(getFraction(0.25,0.02));
/*[1, 4]*/
/***********************************/

console.log(getFraction(0.33,0.02));
/*[1, 3]*/
/***********************************/

Hope that’s of use to somebody!

Delete / Drop all stored procedures in an SQL Database

The following SQL will delete all stored procedures in a specified database.
Make sure you specify the database you are using!

USE [MyDatabase]
DECLARE @spName varchar(500)
DECLARE _CurCursor CURSOR
 FOR SELECT [name] FROM sys.objects WHERE type = 'p'
 OPEN _CurCursor
 FETCH NEXT FROM _CurCursor INTO @spName
 WHILE @@fetch_status = 0
 BEGIN
 EXEC('DROP PROCEDURE ' + @spName)
 FETCH NEXT FROM _CurCursor INTO @spName
 END
CLOSE _CurCursor
DEALLOCATE _CurCursor

Sorry that it lacks formatting, though it should work with just a copy and paste