WP8 Development 17-23

Overview and persisting

Having built the SoundBoard app with lesson 1 through 23, I have been writing code, along with each video, while adequately commenting. I now have an unambiguous overview of Windows Phone 8 development and to challenge myself, I have volunteered for the opportunity to build the Windows Phone 8 interpretation of an app that is already available for iOS and Android, of which the SoundBoard app will be a great resource. I am going to repeat lesson 1 through 23, but not through video, rather, the text and screenshot version of each lesson and my source code commenting. It won’t be the app that I’ll build and of which I will publish the source code of (as communicated in C#: Day 2), but I will write a blog post of the trial and tribulation, methodology and result of my first attempt at an app. Most of what the app will be is accounted for with the SoundBoard app, but not everything, including the part that Bob Tabor challenges you to in the beginning of lesson 14. I’ll attempt to trounce that challenge with this app before continuing the series and I’ll elaborate on that separately. I’ll essentially attempt a few of his challenges at the end of lesson 23 as well, albeit with the app I am building. Naturally, I could begin smaller, i.e. building a variant of the “PetSounds” app, and persist from there. Although, I visualize that I would be able to do that easily enough.

Learning is half the fun

Packages, like the Coding4Fun Toolkit package and the Json.NET package are an invaluable resource along with the NuGet application-level package manager extension for Visual Studio. As for Json.NET, JSON and Json Data – all of which there was a referral to by Bob in lesson 21 – I didn’t get a palpable grasp of what either of them was and the use for them (other than the application of them in the SoundBoard app) as well as what Serialization and Deserialization implied. A few Bing queries afterward was enlightening (hint: underlined text == link). MSDN has a helpful article – albeit from 2002 – on Object Serialization in .NET and Windows Phone Dev Center has a topic on Serialization as well. Part 11 of Windows Store apps for Absolute Beginners with C# will probably clarify Json Data even further when I eventually get to that series. Thus, these packages, or Open Source libraries, with their preprogrammed Classes and Methods, have you building apps with littlest effort and with outright haste.

Lastly, Kudos to Clint Rutkas.

WP8 Development 6-16

Windows Phone 8 Development for Absolute Beginners goes on to the development of the SoundBoard app.

“Style is a simple way of saying complicated things.” — Jean Cocteau

The benefit to previous knowledge of CSS is increasingly apparent after the Part 6 lesson and going forward. The similarities to CSS when you style using Static Resources of which you give a key to be able to reference using Markup extensions, are obvious. The App.xaml being the equivalent to an external style sheet and the MainPage.xaml to the internal style sheet, while converting styles, or rather Theme resources, to a local value, corresponds to inline styles.

Who’s a pretty app?

Concocting a mockup from a sketch template as well as familiarizing with the Design Process and the different Tile templates is a desirable discipline. Live Tiles are preferable to the static icons of alternative mobile operating systems, and I’ll elaborate on that in a forthcoming blog post on iOS and Windows Phone, and later, on Android and Windows Phone as well.

Using Brain.ToComprehend();

Assimilating a fundamental grasp on the C# code and XAML markup, their syntax and how they operate individually and interact jointly, as well as the correlation of Runtime and Design-time, the IDE and the Windows Phone Emulator, is predominant thus far. I would not be able to write the SoundBoard app code by heart as of yet, but I have a newfound realization when contemplating the code. A Method stub, anyone?

Keep Calm and Develop On

Along somewhere, I did overlook a namespace: using SoundBoard.ViewModels; in MainPage.xaml.cs that had to be there for the Part 15 lesson. A mouseover the red squiggly line under SoundData revealed that “The type or namespace name ‘SoundData’ could not be found […]”, which had me identify where the SoundData Class, or rather, Object type, was established and how it was implemented, to solve the issue. Although, it is easier to mouseover the little blue rectangle under ‘SoundData’ (set the cursor anywhere within the red squiggly line), click the icon and select using SoundBoard.ViewModels; to have the IDE identify and solve the problem. When I went to comment on it, I saw someone have had that issue too and had already commented on it. Repeating a segment of the Part 15 lesson from the day before, gave me a better grasp on the LongListSelector_SelectionChanged Event handler and its related XAML Elements and Properties. Concluding that repetition is clarifying, solving a problem yourself is good practice, but should you run into an issue, see the comments.

As I download the video of each lesson, I play it with VLC media player set to Always on Top, writing the code in Visual Studio myself as it is playing. Amid C#, setting the Solution Explorer window to Auto Hide, and the Device window amid XAML too, the UI and video are both accessible on the 2560 pixel wide screen. Although, while doing Part 16, I lapsed when Bob Tabor uncommented line 26, BuildLocalizedApplicationBar(); of the MainPage.xaml.cs, and thus the Application Bar didn’t appear when I started debugging, although without a single error. Solving the issue was straightforward, the Application Bar had its invocation expression commented out and was therefor never invoked.

Furthermore, you don’t want to create two MainPage.xaml and MainPage.xaml.cs in the same project, like I tried when changing the Grid element into a StackPanel element in Part 5 – as I desired to have both for the purpose of repeating and with separate commenting in the same project – even if you rename Classes, et cetera. Create a copy of the project folder.

WP8 Development 1-5

I have gleefully finished part 1 through 5 of Channel 9, Windows Phone 8 Development for Absolute Beginners.

Windows Phone Emulator

A virtual Windows Phone device.

Installation and requirements

As you install the Windows Phone SDK (SDK 8.0), Microsoft Visual Studio Express 2012 for Windows Phone goes with it, both of which are free. It has a different layout to Microsoft Visual Studio Express 2013 for Windows Desktop, intelligibly. Thence, I now have both. There are system requirements for the former, which are Windows 8.1 Pro (or 8.0 Pro) 64-bit OS and an x86-64 CPU with either AMD or Intel Virtualization (AMD-V and VT-x respectively) and to have the BIOS or UEFI setting of that technology set to enabled) as the Windows Phone Emulator will use Hyper-V hardware virtualization. If you have any Intel Core i3/i5/i7 (nearly all Core 2) or AMD Athlon II, Phenom, Phenom II or FX processor, you are O.K.

Screenshots of the installation.

Windows Phone 8.0 SDK and Visual Studio Update 4 installation.

XHTML, HTML, XAML, SGML, XML … WTH.

My previous knowledge of HTML and CSS, specifically XHTML have been an asset as to grasping XAML. You have Elements and Attributes in XAML too (although termed Objects and Properties), recognizable from XHTML and HTML as well as the familiar syntax and structure. There are subtle differences as well of course, for instance, the lowercase tags of XHTML as opposed to case-sensitive CamelCase of XAML. While HTML is a derivative of SGML and XHTML is a derivative of XML – which is also a derivative of SGML – XAML too is a derivative of XML and the sum of fundamental knowledge of each, does coalesce into a revelation with a newfound grasp on – and an awareness of – markup language, namespaces, procedural programmingdeclarative programming and well-formedness that I didn’t have prior. Bob Tabor suggested to learn either of HTML vs. XHTML and CSS in the concluding thoughts to the C# Fundamentals: Development for Absolute Beginners series and it is already apparent as to why. XML itself has become increasingly compelling too. Eventually, I’ll do the HTML5 & CSS3 Fundamentals: Development for Absolute Beginners series as well. I am enthralled by C#, XAML and Visual Studio.

A Screenshot of the IDE.

The Integrated Development Environment (IDE).

C#: Day 4

Yesterday, I finished the 24 episode, 7+ hour, Channel 9, C# Fundamentals: Development for Absolute Beginners. While I could have been done by Day 3, or having done an extra episode or two each day, I chose to do it in a total of four. That allowed me to blog about it since Day 1, write the actual code myself, do the adequate note taking and commenting, go back and review what I had written, and do a little programming of my own. I think that was a good pace. Next is the 35 episode, 11+ hour, Channel 9, Windows Phone 8 Development for Absolute Beginners. Having completed this series, I should be prepared enough (I certainly am excited enough).

Finally, lesson 18 through 24, were especially rewarding and captivating (not that the previous seventeen weren’t). My admiration of the IDE has certainly increased as it is very helpful having automatic indentation when writing code around previous code and then with Enumerations and what Bob Tabor refers to as IDE magic: It truly is magical having an entire code block inserted for you that you otherwise would have typed yourself. Microsoft Visual Studio Express 2013 is an exceptional Integrated Development Environment.

Although I don’t go into detail of what is covered in the series from lesson to lesson, Exceptions was a heartfelt topic as I have been thorough with it ever since programming the ARexx language and through the Assembly language as well as ActionScript. Really, I think it should be Etiquette (deviquette?). Events were very familiar too of course, being what Bob refers to as the drive of a Graphical User Interface (GUI) application, which is close to what a few Doors were, with their Text-based User Interface (TUI), and also what ActionScript often is for, interactivity.

Concluding, below is the source code I wrote off the top of my head, summarizing C# Fundamentals: Development for Absolute Beginners.

I initially thought of Collections, Objects, ClassesMethods and LINQ, although, to obviate the beginner syndrome, chose the straightforward approach of the Framework Class Library (FCL), specifically the Base Class Library (BCL) and fundamental Statements, Expressions, Operators, Operands, StringsArrays, EventsStatic Classes and Static Class Members, Methods and Properties. Undoubtedly, there is a preferable approach to the logic I did and possibility to refactor the code I wrote, nonetheless, it does what it is intended to do.

I had an encounter with the “Index was outside the bounds of the array” error of which I set a breakpoint for debugging. It was satisfying to step over each statement, through each iteration and the branching, observing the Locals and Error List window and to pin variables and their value to the source (Debugging was something I used to like while programming the Assembly language too). A subsequent Bing of the error message and I knew what to look for.

This is a Windows Presentation Foundation (WPF) application (Native Windows Application), with a window of which you have a textbox to type in, a button to click and a textbox of which will output how long it took to type and the character total. The intent is to type a text without an ensuing space after a punctuation and a lowercase subsequent initial letter. When you click the button, it will insert a space after each punctuation and uppercase the subsequent initial letter into a capital letter. I contemplated whether to decipher acronyms and abbreviations too.

Screenshots of the WPF Application.

The C# and XAML WPF Application before and after a click of the Fix button.

The auto generated XAML in the IDE from dragging Controls from the Toolbox as well as from the use of the Properties Window was remarkable.

XAML

<Window x:Name="QuickNote" x:Class="QuickNote.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="QuickNote © Spiritus et Technologiae" Height="350" Width="525">
    <Grid>
        <TextBox x:Name="Notes" Height="255" Margin="10,10,10,0" TextWrapping="Wrap" Text="start typing here.click fix afterwards." VerticalAlignment="Top" ToolTip="Don't think of a space after punctuation or a subsequent capital letter. You do have to separate each word with a space and a sentance with punctuation though."/>
        <Button x:Name="Fix" Content="Fix" HorizontalAlignment="Left" Margin="220,280,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" ToolTip="Add a space at the end of each sentance and capitalize each initial letter."/>
        <TextBox x:Name="ElapsedTime" HorizontalAlignment="Left" Height="23" Margin="348,279,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="151"/>
    </Grid>
</Window>

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace QuickNote     // © Spiritus et Technologiae
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        DateTime startTime = DateTime.Now;                          // Start the timer when the application launches

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //string textInput = Notes.Text;                        // Get the note into variable "textInput" of data type "string"

            char[] charArray = Notes.Text.ToCharArray();            // An array with the characters of the input
            string arrayChar = "";                                  // Declaration statement
            string nextChar = "";
            Notes.Text = "";
            int i = 0;                                              // A pointer for the next character in the array
            bool y = true;                                          // A flag, if true then uppercase character

            foreach (char Char in charArray)                        // Iteration statement
            {
                if (i == charArray.Length - 1)                      // If there aren't any characters after the current character
                {                                                   // then break, preventing "Index was outside the bounds of the array"
                    break;
                }
                else
                {
                    i++;                                            // Increment the pointer each loop through
                    nextChar = charArray[i].ToString();             // Get next character into variable "nextChar", explicitly convert to
                                                                    // string, increment pointer to point to next character consecutively
                    arrayChar = Char.ToString();                    // Get the current character into the variable "arrayChar"

                    if (arrayChar == ".")                           // Following code is self-explanatory:
                    {
                        if (nextChar == " " || nextChar == ".")     // Decision statement
                        {
                            Notes.Text = Notes.Text + ".";
                            y = false;
                        }
                        else
                        {
                            Notes.Text = Notes.Text + ". ";         // Concatination
                            y = true;
                        }
                    }
                    else
                    {
                        if (y == true)
                        {
                            Notes.Text = Notes.Text + arrayChar.ToUpper();
                            y = false;
                        }
                        else
                        {
                            Notes.Text = Notes.Text + arrayChar;    // Expression statement
                        }
                    }
                }
            }

            Notes.Text = Notes.Text + nextChar;                     // The last character

            //string addSpaces = textInput.Replace(".", ". ");      // Replace punctuation with a punctuation and a space in the string
                                                                    // "textInput" to a new string "addSpaces"
            //Notes.Text = addSpaces;                               // Output the note with added spaces to the "Notes" textbox

            TimeSpan totalTime = DateTime.Now.Subtract(startTime);  // Get total time since "Fix" was last clicked or application launched

            ElapsedTime.Text = String.Format(
                "{0} s. and {1} char(s).",                          // Format and explicitly convert timer and counter and output it
                                                                    // to the textbox "ElapsedTime"
                Math.Round(totalTime.TotalSeconds).ToString(),      // Chaining
                Notes.Text.Length.ToString());

            startTime = DateTime.Now;                               // Reset the timer when "Fix" is clicked
        }
    }
}

Get the executable program in a zip archive here. In addition, get the Channel 9 Windows 8 app here, like the Microsoft Visual Studio Facebook page here and get Visual Studio Update 1 here.

C#: Day 3

Yesterday, finishing lesson 13 through 17, a big piece of the puzzle is where it should be. Though I did pause, rewind and replay as well as use Notepad extensively while also commenting the code excessively. Later, a Eureka moment had everything become easier to grasp. Now, the terminology is becoming part of my vocabulary and the syntax is becoming increasingly natural. I love the fluidity of the Microsoft Visual Studio Express 2013 IDE with its Code Snippets and its IntelliSense, which when you get used to them, will have you writing code efficiently. I like Visual C#.

While progressing through the series, there is less and less familiarities with my previous knowledge of the Amiga ARexx and Assembly language programming. The Amiga Workbench .library files are now essentially Assemblies in .dll files with the .NET Framework, which is a library of Classes that you reference. In a sense (but not exactly), the keyword is now ‘Using’ Instead of ‘Include’. There, you have Namespaces with Classes and their Members, the Methods and Properties. The concept of References are familiar too and now Memory Allocation is done by the .NET Framework Runtime.

So, Microsoft .NET and the Common Language Runtime (CLR) have been introduced and I am happy, as there is great benefit from it. I did like being as close to the hardware as the Assembly language had me be, it being a low-level programming language, with the Data registers, Address registers, Stack pointers and Program counter of the Motorola 68000 architecture. The thought processes were close to the behavior of the hardware, while now, its high-level programming languages that are instead akin to natural language. It does have its advantages of course, although I still prefer the former.

Familiarity was closest to my previous knowledge of ActionScript right from the beginning. I recognize Properties, Data types, Statements, Arguments et cetera from ActionScript, as well as the Syntax being somewhat similar. ActionScript 3.0 is an Object Oriented Programming (OOB) language as is C#.

Thus far, I am not able to do any programming of significance with what I have. Rather, I am still getting the know-how to be able to. We’ll see where I’m at after Day 4.

This is code I wrote while I was learning ActionScript 3.0 with lynda.com Flash CS3 for Designers. It is easy to comprehend it having gone through this series and vice versa:

// Output
// trace("Hello World");
/*
// Cat object, claw attribute equals sharp
Cat.claw = "sharp";
// Listen to the event of woman shout and then make cat do
Woman.addEventListener(Event.Shout, makecatdo);
// Function make cat do
function = makecatdo() {
	// Cat object, jump method
	Cat.jump();
}
*/
// A variable is a container for information, : and then type of variable (strict type)
var h:String = "Hello World";
trace(h);
var weather:String = "It's cold";
// A function is used to control when we want to do certain things
function traceit(e:Event):void {
	// String concatenation
	trace(weather + " in December");
}
// CamelCase myArcadeButton, listen to an event, mouse click, traceit or textit
myArcadeButton.addEventListener(MouseEvent.CLICK, textits)
// Set text property of myText
function textits(e:Event) {
//	outText.text = "My dynamic text or trace button";
	// Set input text equal to outText
	outText.text = inText.text;
}
// Seamless Roll Over and Roll Out
function rollover(e:Event) {
	// In and out labels should be the frame after stop action frame to get smooth transitions
	myBtn.gotoAndPlay("in");
}
myBtn.addEventListener(MouseEvent.MOUSE_OVER, rollover);
function rollout(e:Event) {
	myBtn.gotoAndPlay("out");
}
myBtn.addEventListener(MouseEvent.MOUSE_OUT, rollout);
// Set masker as myImage mask, use cash as bitmap on both to get shape soften fill edges (alpha)
myImage.mask = themask;
// Mask to behave as a button so that we can add a mouse event to it
themask.buttonMode = true;
themask.addEventListener(MouseEvent.MOUSE_DOWN, drag);
function drag(e:Event) {
	// Enable drag functionality
	themask.startDrag();
}
themask.addEventListener(MouseEvent.MOUSE_UP, nodrag);
function nodrag(e:Event) {
	// Disable drag functionality
	themask.stopDrag();
}
// So that it doesn't continue draging if mouse up outside mask
themask.addEventListener(MouseEvent.MOUSE_OUT, nodrag);
// UILoader component function to change source (load image)
function loadit(e:Event) {
	myLoader.source = "C:/image.jpg";
}
loaditBtn.addEventListener(MouseEvent.CLICK, loadit);
// Create object textLoader with all the properties and methods of the URLLoader class
var loader:URLLoader = new URLLoader();
// Create object requester
var requester:URLRequest = new URLRequest("C:/text.txt");
// Load the requester
loader.load(requester);
// When an event, loader.load(), is done, show text
loader.addEventListener(Event.COMPLETE, showtext);
// The show text function
function showtext(e:Event) {
	// myText text is going to be the data that the loader has loaded from requester
	// Can also be dynText.htmlText so that it can parse html tags
	dynText.text = (loader.data);
	// Properties
	dynText.background = true;
	dynText.backgroundColor = 0x000000;
	dynText.border = true;
	// Hexadecimal color starts with 0x instead of html #
	dynText.borderColor = 0xff6600;
}
// Clear loaded image
clearitBtn.addEventListener(MouseEvent.CLICK, clearit);
function clearit(e:Event) {
		myLoader.source = null;
}
/* An instance of the array class, not a new empty array, but a predefined array
   Array data is defined withing brackets, separated by commas
   Arrays are storage for multiple variables, entries are numbers starting from 0 as the first */
var myArray:Array = ["C:/image0.jpg","C:/image1.jpg","C:/image2.jpg","C:/image3.jpg","C:/image4.jpg","C:/image5.jpg","C:/image6.jpg","C:/image7.jpg"];
// The caption array for the images description (desc)
var descArray:Array = ["First image","Second image","Third image","Fourth image","Fifth image","Sixth image","Seventh image","Eighth image"];
// Gallery
tnBtn1.addEventListener(MouseEvent.CLICK, img1);
function img1(e:Event) {
	// Load first image from first variable in array, access entries in array within brackets
	galleryloader.source = myArray[0];
	caption.text = descArray[0];
}
tnBtn2.addEventListener(MouseEvent.CLICK, img2);
function img2(e:Event) {
	galleryloader.source = myArray[1];
	caption.text = descArray[1];
}
tnBtn3.addEventListener(MouseEvent.CLICK, img3);
function img3(e:Event) {
	galleryloader.source = myArray[2];
	caption.text = descArray[2];
}
tnBtn4.addEventListener(MouseEvent.CLICK, img4);
function img4(e:Event) {
	galleryloader.source = myArray[3];
	caption.text = descArray[3];
}
tnBtn5.addEventListener(MouseEvent.CLICK, img5);
function img5(e:Event) {
	galleryloader.source = myArray[4];
	caption.text = descArray[4];
}
tnBtn6.addEventListener(MouseEvent.CLICK, img6);
function img6(e:Event) {
	galleryloader.source = myArray[5];
	caption.text = descArray[5];
}
tnBtn7.addEventListener(MouseEvent.CLICK, img7);
function img7(e:Event) {
	galleryloader.source = myArray[6];
	caption.text = descArray[6];
}
tnBtn8.addEventListener(MouseEvent.CLICK, img8);
function img8(e:Event) {
	galleryloader.source = myArray[7];
	caption.text = descArray[7];
}
// Music loop on off toggle
myMusic.myStop.addEventListener(MouseEvent.CLICK, stopmusic);
function stopmusic(e:Event) {
	myMusic.gotoAndStop(1);
	trace("Stop");
	SoundMixer.stopAll();
/* ActionScript 2.0
	stopAllSounds();
*/
}
myMusic.myPlay.addEventListener(MouseEvent.CLICK, playmusic);
function playmusic(e:Event) {
	trace("Play");
	myMusic.gotoAndPlay(2);
}
/* Variables */
// Whole number, integer, positive or negative
var score:int = 15;
/*
// Whole number, integer, positive
var score:uint = 15;
// Whole number, integer, positive, negative and decimal
var score:Number = 15;
*/
/* Functions */
// Create function addNumbers with parameters num1, num2 with datatypes Number (Strict typing) and the function will also return a number :Number
function addNumbers(num1:Number, num2:Number):Number {
	// Return the sum of num1 and num2
	return num1 + num2;
}
// Run the above function (and trace result)
trace(addNumbers(5,15));
/* Events */
// Function will recieve value information to parameter "event" with datatype MouseEvent, return void (event handler function)
function buttonClicked(event:MouseEvent):void {
	trace("Button Clicked");
}
/* Event Listeners */
// Connect object my_btn with an event, in this case, a mouse event of click, and further connect it to an event handler function, buttonClicked above
// my_btn.addEventListener(MouseEvent.CLICK, buttonClicked);
/* Arrays */
// Create variable my_ary and make it an array datatype
// Square brackets, shorthand notation, can have multiple dataypes, separate with commas
var my_ary:Array = [5, "David", true];
// Each item in an array has an index number which starts at 0 for the first item
trace(my_ary[1]);
/* Dynamic text */
// Create an instance of the URLLoader class, first part of creating a dynamic text loader, the object that will hold the external text once loaded
var textLoader:URLLoader = new URLLoader();
// Create URL request, second part of creating a dynamic text loader
var textReq:URLRequest = new URLRequest("as3.html");
// External CSS
var cssLoader:URLLoader = new URLLoader();
var cssReq:URLRequest = new URLRequest("as3.css");
// Make an object with the StyleSheet class
var style:StyleSheet = new StyleSheet();
// Define tag a style, object datatype and class is a dynamic class we can create custom properties on any instance of the object class (object shorthand notation {}) setStyle method of the StyleSheet class, the style of a is in an object with dynamic property color, colon to specify value, which is a string
// style.setStyle("a", {color:"#CC0000"});
// Load external text
textLoader.load(textReq);
// Listen to when text is finished loading
textLoader.addEventListener(Event.COMPLETE, textLoaded);
// Function for the event when text had finished loading
function textLoaded(event:Event):void {
	// End instance names with _txt and _btn for code hints, text property .htmlText, the data that is loaded in from the external text .data, .text for ascii
//	external_txt.htmlText = textLoader.data;
	// Apply internal stylesheet
//	external_txt.styleSheet = style;
	// External style sheet
	cssLoader.load(cssReq);
	cssLoader.addEventListener(Event.COMPLETE, cssLoaded);
}
function cssLoaded(event:Event):void {
	// Read the text as CSS
	style.parseCSS(cssLoader.data);
	external_txt.htmlText = textLoader.data;
	external_txt.styleSheet = style;
}

An easy-to-read review of the Nokia DT-901 Qi Wireless Charging Pillow by Fatboy

A dream

The Nokia DT-901 Qi Wireless Charging Pillow by Fatboy is like a dream (pun intended) come true for all of those who don’t like to fiddle with chargers and cables. It charges using inductive charging. The product page at Nokia says “Relax and recharge”. I tried it in cyan for my ex-fiancées cyan Nokia Lumia 920 which has support for this built-in.

The Qi Wireless charging standard sprinkling magical electricity onto the batteries of smart phones.

Candles, lamp, bedside table, headboard and the Nokia DT-901 Qi Wireless Charging Pillow by Fatboy with a Nokia Lumia 920 on it.

Pillows.

The Nokia Lumia 920 on top of the Nokia DT-901 Qi Wireless Charging Pillow by Fatboy.

A closer look.

A closer look at the Nokia Lumia 920 on top of the Nokia DT-901 Qi Wireless Charging Pillow by Fatboy.

Micro-USB for charging?

Charging

A slight moment after placing the smart phone on the pillow, it charges. That’s what it does. It’s simple. And it does it well. It took about 2 hours and 50 minutes to fully charge from being completely depleted. A minor annoyance is that if you place the phone incorrectly, on occasion, it’ll start and stop charging randomly or not charge at all. That’s a minor issue but one that should be useful to know about (RTFM?).

OT

You just really wanted to know about the candles, the lamp, the bedside table and the headboard? They’re no IKEA. My ex-fiancée had an aptitude for that0. The headboard and bedside table are from Trendrum AB in Sweden. The lamp is from Ellos AB in Sweden. Then, Yankee Candle of course. They have a fundraising program, they do charitable giving and have a sustainability commitment. Made with natural fragrance extracts, real essential oils and natural fiber wicks, the lovely fragrance is an added benefit. And their Car Jar is fantastic. Their wax is Paraffin, so at least its vegan friendly, and made in South Deerfield, Massachusetts. It will only emit carbon dioxide and water vapor. (Yankee Candle should sponsor this blog post.) There are also the WoodWick Candles with their soy wax and wick made of wood. Although, at first, Virginia Gift Brands didn’t want to disclose what their wax blend consisted of, but eventually a customer service representative wrote that their wax is a soy based paraffin wax, I don’t know… They manufacture in Virginia.

C#: Day 2

The day before yesterday I finished lesson 6 through 12. It was fairly straight forward and everything is still very familiar to me because of my previous knowledge. The Assembly (Assembler) language Subroutine is now a Method, Libraries are practically still Libraries and Strings are still Strings, Structures are for instance Arrays and so forth. I’ll elaborate on that at another time. Bob Tabor is great to listen to and Golnaz as well as Clint Rutkas deserve credit for this series. The pacing is right and it encourages you to write the code for yourself as you go along. You get to know what you specifically should take away with you from a lesson and there is well thought out repetition throughout. You are eased into the IDE and what that is. You get to write the Hello World code that is easy to understand early on, which is a good motivator. All the while not going too far into the why and whatnot.

There is a lot of technical terminology and syntax to learn and even though I haven’t been too enthusiastic about learning technical terminology or syntax specifically before, it sort of came naturally, there is a lot of benefit from knowing them obviously. While pausing back and forth, I noted everything down in Notepad with my own words. You learn them as you go by. I also took notes on tips and tricks of the IDE and so forth. Early on, you also get introduced to commenting the code. I used to do that a lot while I was programming the ARexx and Assembly language. I used it for the purpose of readability. I comment on what code does, why it’s there and to mark up the code. It’s good practice and it makes it easier to return to the code later.

I won’t go into what you get to learn as much as I will document what I can do with C# from day to day as I progress through the series and then a subsequent book or another video series. Ultimately, I will document programming an actual application and publishing it, making the source code freely available. Yesterday I had a first attempt at my own C# code using what I got from Day 1 and 2. A Console Application which prompts you for your rent, electrical bill, and so forth, while all of the fixed monthly reoccurring expenses are pre-programmed. It returns my total as well as my fiancée’s total, where we split some of the bills while others we don’t. It also formats correctly to display in local currency. It doesn’t incorporate everything of what I have learned so far, far from it, but I won’t be needing the calculator every end of the month from now on. (Not that it was too complicated to start with, otherwise I would have used Excel in the first place.)

Screenshot of the Console Application.

The C# Console Application at the first prompt.

Here’s an addition to the nostalgia of yester-post. I was sixteen when I wrote the following Assembly language code (don’t ask why I hated Includes (?) and excuse the language):

;ClassicArc (c) by BigBang/Independent 1997, LHA/LZX Stripper/Adder/Checker.

;-----------------÷[ The Variables, Includes & Structures! ]÷----------------÷]

		Incdir	'Include:'
		Include	'Daydream.i'		;I just hate Includes.
		Include	'Exec_lib.i'
		Include	'Dreamdoor_lib.i'
		Include	'Exec/Exec.i'
		Include	'Dos_lib.i'
		Include	'Dos/Dos.i'

		STRUCTURE	Globals,0
		ULONG		Data_FileStrip,1
		ULONG		Data_FileAdd,1
		ULONG		Lenght_Strip,1		;A lot of shit.
		ULONG		Lenght_Add,1
		ULONG		Temporary_File,1
		ULONG		ClassicKeyfile,1
		ULONG		Keyfile_Buffer,1
		APTR		DayLib_Base,1
		APTR		DosLib_Base,1
		APTR		DD_DIF,1
		APTR		Openfile_Store,1
		STRUCT		Structures,dp_SIZEOF
		STRUCT		Work_Buffer,500
		STRUCT		Read_Buffer,16000
		STRUCT		LZX_ExecuteNew,100
		STRUCT		LZX_ExeAddStrip,100
		STRUCT		LHA_ExeStrip,100
		STRUCT		ARC_Check,100
		STRUCT		LHA_ExeAdd,100
		STRUCT		String_Pause,200
		STRUCT		String_BlockCheck,200
		STRUCT		String_BlockAdd,200
		STRUCT		String_BlockStrip,200
		STRUCT		String_BlockDupe,200
		STRUCT		String_MainPos,100
		STRUCT		String_EndPos,100
		STRUCT		String_FilePos,100
		STRUCT		String_FillItUp,100
		STRUCT		String_Progress,50
		STRUCT		String_Table,80
		STRUCT		File_Name,20
		STRUCT		Add_Name1,100
		STRUCT		Add_Name2,100
		STRUCT		Add_Name3,100
		STRUCT		Add_Name4,100
		STRUCT		Add_Name5,100
		STRUCT		Add_Name6,100
		STRUCT		Add_Name7,100
		STRUCT		CFGPath_Buffer,120
		UBYTE		CFG_FullBar,1
		UBYTE		CFG_Pause,1
		UBYTE		CFG_NewLZX,1
		UBYTE		LoopRead_Flag,1
		UBYTE		Log_Failed,1
		UBYTE		Keyfile_Flag,1
		UBYTE		Memory_Flag,1
		UBYTE		Found_Flag,1
		UBYTE		Finished_Flag,1
		UBYTE		Archive_Flag,1
		UBYTE		Progress_Count,1
		UBYTE		Dupe_Counter,1
		LABEL		Variables_SIZEOF

;--------------------÷[ Store commandline parameter! ]÷----------------------÷]

Run:		Movea.L	a0,a4
		Move.L	d0,d4

;-----------------÷[ Allocate required mem for structures! ]÷----------------÷]

Alloc:		Movea.L	4.W,a6
		Move.L	#Variables_SIZEOF,d0
		Move.L	#MEMF_PUBLIC!MEMF_CLEAR,d1
		Jsr	_LVOAllocMem(a6)
		Movea.L	d0,a5
		Beq.W	CleanUp

;-------------------÷[ Open libraries and check argument! ]÷-----------------÷]

Init:		Moveq	#36,d0
		Lea	DosLib(PC),a1
		Jsr	_LVOOpenLibrary(a6)
		Move.L	d0,DosLib_Base(a5)
		Beq.W	CleanUp
		Moveq	#5,d0
		Lea	DayLib(PC),a1
		Jsr	_LVOOpenLibrary(a6)
		Move.L	d0,DayLib_Base(a5)
		Beq.W	CleanUp
		Clr.B	-1(a4,d4.L)
		Tst.B	(a4)			;Was Argument supplied?
		Beq.W	CleanUp

;--------------------------÷[ Read Configuration! ]÷-------------------------÷>

ReadCFG:	Movea.L	DosLib_Base(a5),a6	;Get path to and open CFG.
		Move.L	#Variable,d1
		Lea	CFGPath_Buffer(a5),a0
		Moveq	#0,d4
		Move.L	a0,d2
		Moveq	#119,d3
		Jsr	_LVOGetVar(a6)
		Tst.L	d0
		Bmi.W	CleanUp
		Lea	CFGPath_Buffer(a5),a0
		Move.L	a0,d1
		Move.L	#Config,d2
		Moveq	#119,d3
		Jsr	_LVOAddPart(a6)
		Tst.L	d0
		Beq.W	CleanUp
		Lea	CFGPath_Buffer(a5),a0
		Move.L	a0,d1
		Move.L	#MODE_OLDFILE,d2
		Jsr	_LVOOpen(a6)
		Move.L	d0,d4
		Beq.W	CleanUp

		Lea	LZX_ExecuteNew(a5),a0	;Read first line from CFG.
		Moveq	#100,d3
		Bsr.W	.Read
		Lea	LZX_ExeAddStrip(a5),a0
		Moveq	#100,d3
		Bsr.W	.Read
		Lea	LHA_ExeStrip(a5),a0
		Moveq	#100,d3
		Bsr.W	.Read
		Lea	LHA_ExeAdd(a5),a0
		Moveq	#100,d3
		Bsr.W	.Read
		Lea	ARC_Check(a5),a0
		Moveq	#100,d3
		Bsr.W	.Read
		Lea	String_BlockStrip(a5),a0
		Move.L	#200,d3
		Bsr.B	.Read
		Lea	String_BlockAdd(a5),a0
		Move.L	#200,d3
		Bsr.B	.Read
		Lea	String_BlockCheck(a5),a0
		Move.L	#200,d3
		Bsr.B	.Read
		Lea	String_BlockDupe(a5),a0
		Move.L	#200,d3
		Bsr.B	.Read
		Lea	String_FilePos(a5),a0
		Moveq	#100,d3
		Bsr.B	.Read
		Lea	String_EndPos(a5),a0
		Moveq	#100,d3
		Bsr.B	.Read
		Lea	String_MainPos(a5),a0
		Moveq	#100,d3
		Bsr.B	.Read
		Lea	String_FillItUp(a5),a0
		Moveq	#100,d3
		Bsr.B	.Read
		Lea	String_Progress(a5),a0
		Moveq	#50,d3
		Bsr.B	.Read
		Lea	String_Table(a5),a0
		Moveq	#80,d3
		Bsr.B	.Read
		Lea	String_Pause(a5),a0
		Move.L	#200,d3
		Bsr.B	.Read
		Lea	CFG_FullBar(a5),a1
		Bsr.B	.ReadS
		Lea	CFG_Pause(a5),a1
		Bsr.B	.ReadS
		Lea	CFG_NewLZX(a5),a1
		Bsr.B	.ReadS			;Read last line in CFG.
		Bra.B	.Close

.Read		Move.L	a0,d2
		Move.L	d4,d1
		Jsr	_LVOFGets(a6)
		Movea.L	d0,a0
		Beq.W	CleanUp
.Loop		Cmpi.B	#10,(a0)+
		Beq.B	.Clear
		Bra.B	.Loop
.Clear		Clr.B	-(a0)
		Rts

.ReadS		Lea	Work_Buffer(a5),a0
		Move.L	a0,d2
		Move.L	d4,d1
		Moveq	#5,d3
		Jsr	_LVOFGets(a6)
		Movea.L	d0,a0
		Beq.W	CleanUp
		Move.B	(a0),(a1)
		Rts

.Close		Move.L	d4,d1			;Close Configuration.
		Jsr	_LVOClose(a6)

;-------------÷[ Initialize door & Get structure pointers! ]÷----------------÷]

InitDoor:	Movea.L	DayLib_Base(a5),a6
		Movea.L	a4,a0
		Jsr	_LVOInitDoor(a6)
		Move.L	d0,DD_DIF(a5)
		Beq.W	CleanUp
		Lea	Structures(a5),a0
		Jsr	_LVOInquirePointers(a6)

;-----------------------÷[ The door preparation code! ]÷---------------------÷]

Prepare:	Moveq	#17,d0
		Movea.L	dp_DoorParams+Structures(a5),a1
		Lea	File_Name(a5),a0
.Loop		Move.B	(a1)+,(a0)+		;Get filename.
		Tst.B	(a1)
		Beq.W	.CheckKey
		Dbf	d0,.Loop

.CheckKey	Movea.L	DosLib_Base(a5),a6
		Move.L	#GlobalKeyfile,d1	;Check for keyfile.
		Move.L	#MODE_OLDFILE,d2
		Jsr	_LVOOpen(a6)
		Move.L	d0,ClassicKeyfile(a5)
		Beq.B	.NoKeyfile
		Move.L	ClassicKeyfile(a5),d1
		Lea	Keyfile_Buffer(a5),a0
		Move.L	a0,d2
		Moveq	#4,d3
		Jsr	_LVORead(a6)		;Check if keyfile is legal.
		Move.L	Keyfile_Buffer(a5),d0
		Move.L	KeyNum(PC),d1
		Cmp.L	d0,d1
		Bne.B	.FalseKey
		Lea	Work_Buffer(a5),a0
		Move.L	a0,d2
		Moveq	#30,d3
		Move.L	ClassicKeyfile(a5),d1
		Jsr	_LVOFGets(a6)
		Movea.L	d0,a3
		Beq.W	Quick
		Move.L	dp_DayDream+Structures(a5),d0
		Addi.L	#CFG_SYSOPNAME,d0
		Move.L	d0,a4
.1		Cmpm.B	(a3)+,(a4)+
		Bne.B	.FalseKey
		Tst.B	(a4)
		Beq.B	.Continue
		Cmpi.B	#10,(a3)
		Beq.B	.Continue
		Bra.B	.1

.NoKeyfile	Move.B	#1,Keyfile_Flag(a5)	;If no keyfile was found!
		Bra.B	.Continue
.FalseKey	Movea.L	DayLib_Base(a5),a6	;If keyfile is illegal!
		Lea	IllegalKey(PC),a0
		Bsr.W	Sendit
		Move.L	DD_DIF(a5),d0
		Moveq	#0,d1
		Moveq	#3,d2
		Jsr	_LVOFetchKey(a6)
		Move.L	DD_DIF(a5),d0
		Jsr	_LVODisconnect(a6)
		Bra.W	Quick

.Continue	Cmpi.B	#"N",CFG_FullBar(a5)	;Use fullbar feature or not?
		Beq.B	.NameCheck
		Cmpi.B	#"n",CFG_FullBar(a5)
		Beq.B	.NameCheck
		Move.B	#1,CFG_FullBar(a5)
		Bra.B	.Skip
.NameCheck	Movea.L	DayLib_Base(a5),a6
		Clr.B	CFG_FullBar(a5)
.Skip		Moveq	#29,d0
		Lea	File_Name(a5),a0
.First1		Cmpi.B	#".",(a0)+
		Beq.B	.Second1
		Dbf	d0,.First1
		Bra.W	Quick
.Second1	Move.B	(a0)+,d0		;Check if filename = #?.LHA
		Cmpi.B	#"l",d0
		Beq.B	.Third1
		Cmpi.B	#"L",d0
		Beq.B	.Third1
		Bra.W	.Next
.Third1		Move.B	(a0)+,d0
		Cmpi.B	#"h",d0
		Beq.B	.Fourth1
		Cmpi.B	#"H",d0
		Beq.B	.Fourth1
		Bra.W	.Next
.Fourth1	Move.B	(a0)+,d0
		Cmpi.B	#"a",d0
		Beq.W	PreMain
		Cmpi.B	#"A",d0
		Beq.W	PreMain

.Next		Moveq	#29,d0
		Lea	File_Name(a5),a0
.First2		Cmpi.B	#".",(a0)+
		Beq.B	.Second2
		Dbf	d0,.First2
		Bra.W	Quick
.Second2	Move.B	(a0)+,d0		;Check if filename = #?.LZX/LZH
		Cmpi.B	#"l",d0
		Beq.B	.Third2
		Cmpi.B	#"L",d0
		Beq.B	.Third2
		Bra.W	Quick
.Third2		Move.B	(a0)+,d0
		Cmpi.B	#"z",d0
		Beq.B	.Fourth2
		Cmpi.B	#"Z",d0
		Beq.B	.Fourth2
		Bra.W	Quick
.Fourth2	Move.B	(a0)+,d0
		Cmpi.B	#"x",d0
		Beq.W	.LZX
		Cmpi.B	#"X",d0
		Beq.B	.LZX
		Cmpi.B	#"h",d0
		Beq.W	PreMain
		Cmpi.B	#"H",d0
		Beq.W	PreMain
		Bra.W	Quick

.LZX		Move.B	#1,Archive_Flag(a5)

.CountIt	Movea.L	DosLib_Base(a5),a6	;Count lenght of external
		Move.L	#DataStrip,d1		;Add files for progress bar.
		Move.L	#MODE_OLDFILE,d2
		Jsr	_LVOOpen(a6)
		Move.L	d0,Data_FileStrip(a5)
		Beq.W	Quick
		Move.L	#DataAdd,d1
		Move.L	#MODE_OLDFILE,d2
		Jsr	_LVOOpen(a6)
		Move.L	d0,Data_FileAdd(a5)
		Beq.W	Quick
		Moveq	#0,d5
		Move.L	Data_FileStrip(a5),d4
		Bsr.B	.Read
		Move.L	#175,d0			;Calculate.
		Divu	d5,d0
		Ext.L	d0
		Move.L	d0,Lenght_Strip(a5)	;Store counted & calculated
		Moveq	#0,d5			;Lenghts.
		Move.L	Data_FileAdd(a5),d4
		Bsr.B	.Read
		Move.L	#175,d0
		Divu	d5,d0
		Ext.L	d0
		Move.L	d0,Lenght_Add(a5)
		Move.L	Data_FileStrip(a5),d1
		Jsr	_LVOClose(a6)
		Move.L	Data_FileAdd(a5),d1
		Jsr	_LVOClose(a6)
		Bra.B	.GetData

.Read		Lea	Work_Buffer(a5),a0	;Count lenght.
		Move.L	a0,d2
		Moveq	#5,d3
		Move.L	d4,d1
		Jsr	_LVOFGets(a6)
		Addq.L	#1,d5
		Tst.L	d0
		Beq.B	.Finito
		Bra.B	.Read
.Finito		Rts

.GetData	Movea.L	DosLib_Base(a5),a6
		Move.L	#DataStrip,d1		;Open data files.
		Move.L	#MODE_OLDFILE,d2
		Jsr	_LVOOpen(a6)
		Move.L	d0,Data_FileStrip(a5)
		Beq.W	Quick
		Move.L	#DataAdd,d1
		Move.L	#MODE_OLDFILE,d2
		Jsr	_LVOOpen(a6)
		Move.L	d0,Data_FileAdd(a5)
		Beq.W	Quick
PreMain:	Movea.L	DayLib_Base(a5),a6

;--------------------÷[ The main add/strip/check code! ]÷--------------------÷]

Main:		Tst.B	Keyfile_Flag(a5)	;Disable LZX feature if no key!
		Beq.B	.Continue
		Tst.B	Archive_Flag(a5)
		Beq.B	.Continue
		Bra.W	Quick

.Continue	Move.L	DD_DIF(a5),d0
		Lea	External(PC),a0		;Send door layout.
		Move.L	#DDF_ADDEXTENSION,d1
		Jsr	_LVODisplayFile(a6)

		Move.L	DD_DIF(a5),d0
		Jsr	_LVOHideCursor(a6)

		Lea	String_FilePos(a5),a0
		Bsr.W	Sendit
		Lea	File_Name(a5),a0
		Bsr.W	Sendit
		Lea	String_MainPos(a5),a0
		Bsr.W	Sendit

		Move.L	DD_DIF(a5),d0
		Lea	Activity1(PC),a0
		Jsr	_LVOChangeActivity(a6)

		Movea.L	DosLib_Base(a5),a6
		Tst.B	Archive_Flag(a5)
		Bne.W	.LZX

		Lea	String_Table(a5),a4

.LHAStrip	Bsr.W	.DoIt
		Lea	String_Progress(a5),a0
		Move.W	#"  ",16(a0)
		Lea	LHA_ExeStrip(a5),a0	;Strip LHA archive.
		Bsr.W	.Format
		Bsr.W	.DoIt
		Bsr.W	.Execute
		Bsr.W	.DoIt
		Movea.L	DayLib_Base(a5),a6
		Tst.B	CFG_FullBar(a5)
		Beq.B	.G1
		Bra.B	.G2
.G1		Lea	String_FillItUp(a5),a0
		Bsr.W	Sendit
.G2		Lea	String_BlockStrip(a5),a0
		Bsr.W	Sendit
		Lea	String_MainPos(a5),a0
		Bsr.W	Sendit

		Tst.B	CFG_FullBar(a5)
		Beq.B	.A1
		Bra.B	.A2
.A1		Lea	String_FillItUp(a5),a0
		Move.B	#"4",11(a0)
		Bsr.W	Sendit
		Lea	String_FillItUp(a5),a0
		Move.B	#"5",11(a0)
.A2		Move.L	DD_DIF(a5),d0
		Lea	Activity2(PC),a0
		Jsr	_LVOChangeActivity(a6)
		Movea.L	DosLib_Base(a5),a6
		Tst.B	CFG_FullBar(a5)
		Beq.B	.B1
		Bra.B	.LHAAdd
.B1		Lea	String_Table(a5),a4
		Lea	String_Progress(a5),a0
		Move.W	#"0%",16(a0)

.LHAAdd		Bsr.W	.DoIt
		Lea	String_Progress(a5),a0
		Move.W	#"  ",16(a0)
		Lea	LHA_ExeAdd(a5),a0	;Add to LHA archive.
		Bsr.W	.Format
		Bsr.W	.DoIt
		Bsr.W	.Execute
		Bsr.W	.DoIt
		Movea.L	DayLib_Base(a5),a6
		Tst.B	CFG_FullBar(a5)
		Beq.B	.F1
		Bra.B	.F2
.F1		Lea	String_FillItUp(a5),a0
		Bsr.W	Sendit
.F2		Lea	String_BlockAdd(a5),a0
		Bsr.W	Sendit
		Lea	String_MainPos(a5),a0
		Bsr.W	Sendit
		Bra.W	.Check

.LZX		Cmpi.B	#"Y",CFG_NewLZX(a5)
		Beq.W	.NewLZX
		Cmpi.B	#"y",CFG_NewLZX(a5)
		Beq.W	.NewLZX
		Lea	String_Table(a5),a4

.LZXStrip	Move.L	Data_FileStrip(a5),d4	;Strip adds from LZX archive.
		Bsr.W	.GetNames
		Lea	LZX_ExeAddStrip(a5),a0
		Bsr.W	.ClearData
		Bsr.W	.Format
		Bsr.W	.Execute
		Move.L	Lenght_Strip(a5),d5
		Subq.L	#1,d5
		Bpl.B	.1
		Moveq	#0,d5
.1		Tst.B	Memory_Flag(a5)
		Beq.B	.4
		Lea	String_Progress(a5),a0
		Move.W	#"  ",16(a0)
.4		Lea	String_Progress(a5),a0
		Move.W	(a4)+,5(a0)
		Movea.L	DayLib_Base(a5),a6
		Bsr.W	Sendit
		Move.B	#1,Memory_Flag(a5)
		Addq.B	#1,Progress_Count(a5)
		Cmpi.B	#24,Progress_Count(a5)
		Bne.B	.2
		Lea	String_Progress(a5),a0
		Move.W	#"10",16(a0)
.2		Cmpi.B	#25,Progress_Count(a5)
		Bne.B	.3
		Lea	String_Progress(a5),a0
		Move.W	#"0%",16(a0)
.3		Dbf	d5,.1
		Movea.L	DosLib_Base(a5),a6
		Tst.B	Finished_Flag(a5)
		Beq.W	.LZXStrip
		Movea.L	DayLib_Base(a5),a6
		Tst.B	CFG_FullBar(a5)
		Beq.B	.X1
		Bra.B	.X2
.X1		Lea	String_FillItUp(a5),a0
		Bsr.W	Sendit
.X2		Lea	String_BlockStrip(a5),a0
		Bsr.W	Sendit
		Lea	String_MainPos(a5),a0
		Bsr.W	Sendit

		Move.L	DD_DIF(a5),d0
		Lea	Activity2(PC),a0
		Jsr	_LVOChangeActivity(a6)

		Tst.B	CFG_FullBar(a5)
		Beq.B	.Y1
		Bra.B	.Y2
.Y1		Lea	String_FillItUp(a5),a0
		Move.B	#"4",11(a0)
		Bsr.W	Sendit
		Lea	String_FillItUp(a5),a0
		Move.B	#"5",11(a0)

.Y2		Movea.L	DosLib_Base(a5),a6
		Lea	String_Progress(a5),a0
		Move.W	#"  ",16(a0)
		Clr.B	Memory_Flag(a5)
		Lea	LZX_ExeAddStrip(a5),a0
		Move.B	#"a",23(a0)
		Clr.B	Finished_Flag(a5)
		Tst.B	CFG_FullBar(a5)
		Beq.B	.O1
		Bra.B	.LZXAdd
.O1		Lea	String_Table(a5),a4

.LZXAdd		Move.L	Data_FileAdd(a5),d4	;Add adds to LZX archive.
		Bsr.W	.GetNames
		Lea	LZX_ExeAddStrip(a5),a0
		Bsr.W	.ClearData
		Bsr.W	.Format
		Bsr.W	.Execute
		Move.L	Lenght_Add(a5),d5
		Subq.L	#1,d5
		Bpl.B	.5
		Moveq	#0,d5
.5		Tst.B	Memory_Flag(a5)
		Beq.B	.6
		Lea	String_Progress(a5),a0
		Move.W	#"  ",16(a0)
.6		Lea	String_Progress(a5),a0
		Move.W	(a4)+,5(a0)
		Movea.L	DayLib_Base(a5),a6
		Bsr.W	Sendit
		Move.B	#1,Memory_Flag(a5)
		Addq.B	#1,Progress_Count(a5)
		Cmpi.B	#24,Progress_Count(a5)
		Bne.B	.7
		Lea	String_Progress(a5),a0
		Move.W	#"10",16(a0)
.7		Cmpi.B	#25,Progress_Count(a5)
		Bne.B	.8
		Lea	String_Progress(a5),a0
		Move.W	#"0%",16(a0)
.8		Dbf	d5,.5
		Lea	String_Progress(a5),a0
		Move.W	#"  ",16(a0)
		Movea.L	DosLib_Base(a5),a6
		Tst.B	Finished_Flag(a5)
		Beq.W	.LZXAdd
		Movea.L	DayLib_Base(a5),a6
		Lea	String_BlockAdd(a5),a0
		Bsr.W	Sendit
		Lea	String_MainPos(a5),a0
		Bsr.W	Sendit
		Tst.B	CFG_FullBar(a5)
		Beq.B	.Z1
		Bra.B	.Z2
.Z1		Lea	String_FillItUp(a5),a0
		Bsr.W	Sendit
.Z2		Bra.B	.Check

.NewLZX		Bsr.W	.DoIt
		Lea	String_Progress(a5),a0
		Move.W	#"  ",16(a0)
		Move.B	#2,Archive_Flag(a5)
		Move.L	Data_FileAdd(a5),d4
		Bsr.W	.GetNames
		Bsr.W	.DoIt
		Lea	LZX_ExecuteNew(a5),a0	;Strip and add to LZX archive.
		Bsr.W	.Format
		Bsr.W	.DoIt
		Bsr.W	.Execute
		Bsr.W	.DoIt
		Movea.L	DayLib_Base(a5),a6
		Tst.B	CFG_FullBar(a5)
		Beq.B	.H1
		Bra.B	.H2
.H1		Lea	String_FillItUp(a5),a0
		Bsr.W	Sendit
.H2		Lea	String_BlockStrip(a5),a0
		Bsr.W	Sendit
		Lea	String_BlockAdd(a5),a0
		Bsr.W	Sendit
		Lea	String_MainPos(a5),a0
		Bsr.W	Sendit
		Move.B	#1,Archive_Flag(a5)

.Check		Tst.B	Archive_Flag(a5)
		Beq.B	.Ok
		Cmpi.B	#"N",CFG_NewLZX(a5)	;No Fullbar if no NewLZX.
		Beq.W	.Change
		Cmpi.B	#"n",CFG_NewLZX(a5)
		Beq.W	.Change
		Bra.B	.Ok
.Change		Clr.B	CFG_FullBar(a5)

.Ok		Bsr.W	.DoIt
		Movea.L	DayLib_Base(a5),a6	;For LHA/LZH/LZX archives.
		Move.L	DD_DIF(a5),d0
		Lea	Activity3(PC),a0
		Jsr	_LVOChangeActivity(a6)
		Tst.B	CFG_FullBar(a5)
		Beq.B	.C1
		Bra.B	.C2
.C1		Lea	String_FillItUp(a5),a0
		Move.B	#"4",11(a0)
		Bsr.W	Sendit
		Movea.L	DosLib_Base(a5),a6
		Lea	String_FillItUp(a5),a0
		Move.B	#"5",11(a0)
		Lea	String_Progress(a5),a0
		Move.W	#"0%",16(a0)
.C2		Tst.B	CFG_FullBar(a5)
		Beq.B	.D1
		Bra.B	.D2
.D1		Lea	String_Table(a5),a4
.D2		Bsr.W	.DoIt			;Check archive.
		Lea	String_Progress(a5),a0
		Move.W	#"  ",16(a0)
		Lea	ARC_Check(a5),a0
		Tst.B	Archive_Flag(a5)
		Beq.B	.GoOn
		Move.L	#":LZX",1(a0)
.GoOn		Lea	File_Name(a5),a1
		Move.L	a1,d0
		Bsr.W	RawDoFmt
		Bsr.W	.DoIt
		Bsr.W	.Execute
		Bsr.W	.DoIt
		Move.L	#Temporary,d1		;Open file with check result.
		Move.L	#MODE_OLDFILE,d2
		Jsr	_LVOOpen(a6)
		Move.L	d0,Temporary_File(a5)
		Beq.W	Quick
.More		Move.L	Temporary_File(a5),d1	;Read 16kb from result file.
		Lea	Read_Buffer(a5),a0
		Move.L	a0,d2
		Move.L	#16000,d3
		Jsr	_LVORead(a6)
		Tst.L	d0
		Bmi.W	Quick
		Tst.L	d0
		Beq.B	.Prepare
		Move.B	#1,LoopRead_Flag(a5)
		Bra.B	.Prep
.Prepare	Clr.B	LoopRead_Flag(a5)

.Prep		Bsr.W	.DoIt
		Lea	Read_Buffer(a5),a0
		Move.W	#16000-1,d7
.Compare	Tst.B	(a0)			;Check if archive failed.
		Beq.W	.Cont
		Cmpi.B	#"f",(a0)+
		Beq.B	.NextA
		Dbf	d7,.Compare
		Bra.W	.Cont
.NextA		Cmpi.B	#"a",(a0)+
		Beq.B	.NextB
		Subq.L	#1,a0
		Bra.B	.Compare
.NextB		Cmpi.B	#"i",(a0)+
		Beq.B	.NextC
		Subq.L	#1,a0
		Bra.B	.Compare
.NextC		Cmpi.B	#"l",(a0)+
		Beq.B	.NextD
		Subq.L	#1,a0
		Bra.B	.Compare
.NextD		Cmpi.B	#"e",(a0)+
		Beq.B	.NextE
		Subq.L	#1,a0
		Bra.B	.Compare
.NextE		Cmpi.B	#"d",(a0)+
		Beq.B	.NextF
		Subq.L	#1,a0
		Bra.B	.Compare
.NextF		Move.B	#1,Log_Failed(a5)	;Set flag if filecheck fail!

.Cont		Tst.B	LoopRead_Flag(a5)
		Bne.W	.More
		Movea.L	DayLib_Base(a5),a6
		Tst.B	CFG_FullBar(a5)
		Beq.W	.I1
		Bra.W	.I2
.I1		Lea	String_FillItUp(a5),a0
		Bsr.W	Sendit
.I2		Lea	String_BlockCheck(a5),a0
		Bsr.W	Sendit
		Lea	String_MainPos(a5),a0
		Bsr.W	Sendit

.Dupe		Bsr.W	.DoIt
		Movea.L	DayLib_Base(a5),a6	;Check for a duplicate file!
		Move.L	DD_DIF(a5),d0
		Lea	Activity4(PC),a0
		Jsr	_LVOChangeActivity(a6)
		Tst.B	CFG_FullBar(a5)
		Beq.B	.J1
		Bra.B	.J2
.J1		Lea	String_FillItUp(a5),a0
		Move.B	#"4",11(a0)
		Bsr.W	Sendit
		Movea.L	DosLib_Base(a5),a6
		Lea	String_FillItUp(a5),a0
		Move.B	#"5",11(a0)
		Lea	String_Progress(a5),a0
		Move.W	#"0%",16(a0)
.J2		Tst.B	CFG_FullBar(a5)
		Beq.B	.K1
		Bra.B	.K2
.K1		Lea	String_Table(a5),a4
.K2		Bsr.W	.DoIt
		Lea	String_Progress(a5),a0
		Move.W	#"  ",16(a0)
		Move.L	#UploadLog,d1
.NewFile	Move.L	#MODE_OLDFILE,d2
		Jsr	_LVOOpen(a6)
		Move.L	d0,Openfile_Store(a5)
		Beq.W	Quick
.ReRead		Move.L	Openfile_Store(a5),d1
		Lea	Read_Buffer(a5),a0
		Move.L	a0,d2
		Move.L	#16000,d3
		Jsr	_LVORead(a6)
		Tst.L	d0
		Bmi.W	Quick
		Tst.L	d0
		Beq.B	.Prepare2
		Move.B	#1,LoopRead_Flag(a5)
		Bra.B	.Prep2
.Prepare2	Clr.B	LoopRead_Flag(a5)

.Prep2		Bsr.B	.CheckOut		;Dupe check in opened file.
		Tst.B	Found_Flag(a5)
		Bne.B	.Cont2
.NotFound	Tst.B	LoopRead_Flag(a5)	;If duplicate was not found.
		Bne.B	.ReRead
.PreRead	Bsr.W	.DoIt
		Addq.B	#1,Dupe_Counter(a5)	;Ready to check dupe in another
		Cmpi.B	#2,Dupe_Counter(a5)	;File!
		Beq.B	.CheckConf
		Move.L	Openfile_Store(a5),d1
		Jsr	_LVOClose(a6)
		Move.L	#DownloadLog,d1
		Bra.B	.NewFile
.CheckConf	Nop				;Check if file in current conf!

.Cont2		Tst.B	Found_Flag(a5)		;Delete file if duplicate.
		Beq.B	.NoDel
		Lea	File_Name(a5),a0
		Move.L	a0,d1
		Jsr	_LVODeleteFile(a6)
.NoDel		Movea.L	DayLib_Base(a5),a6	;End the dupe checking..
		Lea	String_FillItUp(a5),a0
		Bsr.W	Sendit
		Lea	String_BlockDupe(a5),a0
		Bsr.W	Sendit
		Lea	String_MainPos(a5),a0
		Bsr.W	Sendit
		Bra.W	EndDoor

.CheckOut	Lea	Read_Buffer(a5),a0	;Does File_Name(a5) exist in
		Move.W	#16000-1,d7		;The Read_Buffer(a5)?
		Lea	File_Name(a5),a1
		Movea.L	a1,a3
.X		Move.B	(a0)+,d0
		Cmp.B	(a1),d0
		Bne.B	.Z
		Movea.L	a0,a2
		Addq.L	#1,a1
.Y		Move.B	(a1)+,d0
		Tst.B	d0
		Beq.B	.Found
		Cmp.B	(a2)+,d0
		Beq.B	.Y
		Movea.L	a3,a1
.Z		Dbf	d7,.X
		Clr.B	Found_Flag(a5)
		Rts
.Found		Move.B	#1,Found_Flag(a5)
		Rts

.GetNames	Lea	Add_Name1(a5),a0	;Get add names from specified
		Bsr.W	.Read			;Data file.
		Lea	Add_Name2(a5),a0
		Bsr.B	.Read
		Lea	Add_Name3(a5),a0
		Bsr.B	.Read
		Lea	Add_Name4(a5),a0
		Bsr.B	.Read
		Lea	Add_Name5(a5),a0
		Bsr.B	.Read
		Lea	Add_Name6(a5),a0
		Bsr.B	.Read
		Lea	Add_Name7(a5),a0
		Bsr.B	.Read
		Rts

.Format		Lea	File_Name(a5),a1	;Fix string to execute.
		Move.L	a1,d0
		Tst.B	Archive_Flag(a5)
		Beq.B	.Skip
		Lea	Add_Name1(a5),a1
		Move.L	a1,d1
		Cmpi.B	#2,Archive_Flag(a5)
		Beq.B	.Skip
		Lea	Add_Name2(a5),a1
		Move.L	a1,d2
		Lea	Add_Name3(a5),a1
		Move.L	a1,d3
		Lea	Add_Name4(a5),a1
		Move.L	a1,d4
		Lea	Add_Name5(a5),a1
		Move.L	a1,d5
		Lea	Add_Name6(a5),a1
		Move.L	a1,d6
		Lea	Add_Name7(a5),a1
		Move.L	a1,d7
.Skip		Bsr.W	RawDoFmt
		Rts

.Execute	Movea.L	DayLib_Base(a5),a6	;Execute fixed string.
		Move.L	DD_DIF(a5),d0
		Lea	Work_Buffer(a5),a0
		Jsr	_LVOFifoExecute(a6)
		Movea.L	DosLib_Base(a5),a6
		Rts

.Read		Move.L	a0,d2			;Read line from data file.
		Moveq	#100,d3
		Move.L	d4,d1
		Jsr	_LVOFGets(a6)
		Movea.L	d0,a0
		Beq.B	.Finito
.Again		Cmpi.B	#10,(a0)+
		Bne.B	.Again
		Clr.B	-(a0)
		Rts
.Finito		Move.B	#1,Finished_Flag(a5)
		Rts

.ClearData	Moveq	#0,d0			;Clear all data registers.
		Move.L	d0,d1
		Moveq	#0,d2
		Move.L	d2,d3
		Moveq	#0,d4
		Move.L	d4,d5
		Moveq	#0,d6
		Move.L	d6,d7
		Rts

.DoIt		Lea	String_Progress(a5),a0	;Send a block to progress bar!
		Move.W	(a4)+,5(a0)
		Movea.L	DayLib_Base(a5),a6
		Bsr.W	Sendit
		Movea.L	DosLib_Base(a5),a6
		Rts

EndDoor:	Movea.L	DosLib_Base(a5),a6	;End the door..
		Tst.B	Log_Failed(a5)
		Beq.B	.3
		Lea	File_Name(a5),a0
		Move.L	a0,d0
		Lea	ArcFailure(PC),a0
		Bsr.W	RawDoFmt
		Movea.L	DayLib_Base(a5),a6
		Lea	Work_Buffer(a5),a0
		Move.L	DD_DIF(a5),d0
		Jsr	_LVOWriteLog(a6)
.3		Movea.L	DayLib_Base(a5),a6
		Cmpi.B	#"Y",CFG_Pause(a5)
		Beq.B	.2
		Cmpi.B	#"y",CFG_Pause(a5)
		Bne.B	.1
.2		Lea	String_Pause(a5),a0
		Bsr.W	Sendit
		Move.L	DD_DIF(a5),d0
		Moveq	#0,d1
		Moveq	#3,d2
		Jsr	_LVOFetchKey(a6)
.1		Lea	String_EndPos(a5),a0
		Bsr.W	Sendit
Quick:		Movea.L	DayLib_Base(a5),a6
		Move.L	DD_DIF(a5),d0
		Jsr	_LVOShowCursor(a6)
		Move.L	DD_DIF(a5),d0		;Quit the shit quickly.
		Jsr	_LVOCloseDoor(a6)

;------------------------÷[ Hasta la' vista.. baby! ]÷-----------------------÷]

CleanUp:	Movea.L	DosLib_Base(a5),a6	;Close and deallocate.
		Tst.L	Openfile_Store(a5)
		Beq.B	.Z
		Move.L	Openfile_Store(a5),d1
		Jsr	_LVOClose(a6)
.Z		Tst.L	Temporary_File(a5)
		Beq.B	.Y
		Move.L	Temporary_File(a5),d1
		Jsr	_LVOClose(a6)
		Move.L	#Temporary,d1
		Jsr	_LVODeleteFile(a6)
.Y		Tst.L	ClassicKeyfile(a5)
		Beq.B	.X
		Move.L	ClassicKeyfile(a5),d1
		Jsr     _LVOClose(a6)
.X		Tst.L	Data_FileStrip(a5)
		Beq.B	.0
		Move.L	Data_FileStrip(a5),d1
		Jsr	_LVOClose(a6)
.0		Tst.L	Data_FileAdd(a5)
		Beq.B	.1
		Move.L	Data_FileAdd(a5),d1
		Jsr	_LVOClose(a6)
.1		Movea.L	4.W,a6
		Tst.L	DosLib_Base(a5)
		Beq.B	.2
		Movea.L	DosLib_Base(a5),a1
		Jsr	_LVOCloseLibrary(a6)
.2		Tst.L	DayLib_Base(a5)
		Beq.B	.3
		Movea.L	DayLib_Base(a5),a1
		Jsr	_LVOCloseLibrary(a6)
.3		Tst.L	(a5)
		Beq.B	.Dasvedanja
		Movea.L	a5,a1
		Move.L	#Variables_SIZEOF,d0
		Jsr	_LVOFreeMem(a6)
.Dasvedanja	Moveq	#0,d0
		Rts				;Back to reality.

;------------------------÷[ Format string %s codes! ]÷-----------------------÷]

RawDoFmt:	Movem.L	d0-d7,-(sp)
		Movea.L	4.W,a6
		Lea	Work_Buffer(a5),a3
		Movea.L	SP,a1
		Lea	PutChar(PC),a2
		Jsr	_LVORawDoFmt(a6)
		Movem.L	(sp)+,d0-d7
		Rts

PutChar:	Move.B	d0,(a3)+
		Rts

;------------------------÷[ Send the string routine! ]÷----------------------÷]

Sendit:		Move.L	DD_DIF(a5),d0
		Jsr	_LVOSendString(a6)
		Rts

;---------------------------÷[ Strings and shit! ]÷--------------------------÷]

		Cnop	0,4
KeyNum:		Dc.L	999,0
DosLib:		Dc.B	'dos.library',0
DayLib:		Dc.B	'dreamdoor.library',0

Config:		Dc.B	'classicarc.cfg',0
Variable:	Dc.B	'dreamutils',0
External:	Dc.B	'classicarc',0

DownloadLog:	Dc.B	'daydream:logfiles/downloadlog.dat',0
UploadLog:	Dc.B	'daydream:logfiles/uploadlog.dat',0
Temporary:	Dc.B	't:classicarc.tmp',0
GlobalKeyfile:	Dc.B	's:classictools.key',0
DataStrip:	Dc.B	'daydream:data/filestrip.dat',0
DataAdd:	Dc.B	'daydream:data/fileadd.dat',0

ArcFailure:	Dc.B	'ULoad: %s, failed archive testing.',10,0

Activity1:	Dc.B	'Stripping File!',0
Activity2:	Dc.B	'Adding Adds To File!',0
Activity3:	Dc.B	'Checking File!',0
Activity4:	Dc.B	'Dupe Checking File!',0

IllegalKey:	Dc.B	12,10,27,'[0m This System Is Using An Illegal Copy Of The ClassicTools KeyFile!',10
		Dc.B	' Please Concider Registration And Support The ClassicTools Development!',10,' Disconnecting..',10,10,0

Version:	Dc.B	'$VER: ClassicArc v1.00 (c) by BigBang/Independent (03.01.97)',10,0
		Even

It is regrettable that this is the only assembly language source code I have managed to save. Prior to the above code, I wrote practically the same application in the ARexx language (I apologize about all the actual code being on one line. I will try to get the proper formatting back):

/*****************************************************************************/
/*                                                                           */
/*        lNS & dSY        pRESENTz    aNOTHER                               */
/* - --+-----------__--/\--________--________--___--________-----------+-- - */
/*     |          /  \/  \_\_____  \/  _____/_/   \/  _____/_  tOOL!   |     */
/*     |   _ __ _/   \/   \  ____   \_ \____  \_   \_  \     \_ __ _   |     */
/*     | .\\\\_\\____/     \_________/_________/____/_________//_////. |     */
/* - --+------------/_______/-sox--------------------------------------+-- - */
/*                                                                           */
/*        mAGiC-aRC version 1.80    Coded.. by dAvE / lUNAtICS / dESTiNY     */
/*         (c) 1996 dAvE/lNS^dSY    Design. by dAvE / lUNAtICS / dESTiNY     */
/*                                                                           */
/*****************************************************************************/

/* - -- --- ----÷{ dON'T tOUCH aNYTHiNG bELOW tHiS liNE!! }÷--- --- -- - */

parse arg node;Options results;nodeid = "DREAMREXX"node;address value nodeid;signal on error;signal on syntax;signal on ioerr;if ~exists("ENV:DreamUtils") then call END;call open(DU,"ENV:DreamUtils",'R');do;DreUti=ReadLn(DU);end;call Close(DU);call open(CFG,''DreUti'lNS-MagicArc.CFG','R');do;c1 = STRIP(readln(CFG));c2 = STRIP(readln(CFG));c3 = STRIP(readln(CFG));c4 = STRIP(readln(CFG));c5 = STRIP(readln(CFG));chk = STRIP(readln(CFG));adds = STRIP(readln(CFG));add1 = STRIP(readln(CFG));add2 = STRIP(readln(CFG));add3 = STRIP(readln(CFG));srp0 = STRIP(readln(CFG));srp1 = STRIP(readln(CFG));srp2 = STRIP(readln(CFG));srp3 = STRIP(readln(CFG));srp4 = STRIP(readln(CFG));srp5 = STRIP(readln(CFG));srp6 = STRIP(readln(CFG));srp7 = STRIP(readln(CFG));srp8 = STRIP(readln(CFG));srp9 = STRIP(readln(CFG));srpA = STRIP(readln(CFG));srpB = STRIP(readln(CFG));srpC = STRIP(readln(CFG));srpD = STRIP(readln(CFG));srpE = STRIP(readln(CFG));srpF = STRIP(readln(CFG));srpG = STRIP(readln(CFG));srpH = STRIP(readln(CFG));srpI = STRIP(readln(CFG));srpJ = STRIP(readln(CFG));srpK = STRIP(readln(CFG));srpL = STRIP(readln(CFG));srpM = STRIP(readln(CFG));srpN = STRIP(readln(CFG));srpO = STRIP(readln(CFG));srpP = STRIP(readln(CFG));srpQ = STRIP(readln(CFG));srpR = STRIP(readln(CFG));srpS = STRIP(readln(CFG));srpT = STRIP(readln(CFG));srpU = STRIP(readln(CFG));srpV = STRIP(readln(CFG));srpW = STRIP(readln(CFG));srpX = STRIP(readln(CFG));srpY = STRIP(readln(CFG));ddir = STRIP(readln(CFG));dir1 = STRIP(readln(CFG));dir2 = STRIP(readln(CFG));dir3 = STRIP(readln(CFG));dir4 = STRIP(readln(CFG));dir5 = STRIP(readln(CFG));adda = STRIP(readln(CFG));call Close(CFG);systeminfo 3;file=result;nl=newline;tr=transmit;ex=fifoexecute;ce=call END;tr1="__ "c1".."c5"Adds stripped from file..";tr2="__ "c1".."c5"Adds added to the file..";tr3="__ "c1".."c5"File has been checked..";pth="Daydream:Temporary/";y=0;if lastpos('.',file)=0 then ce;what=strip(upper(substr(file,lastpos('.',file),(length(file)-(lastpos('.',file)-1)))));if what=".LHA" | what=".LZH" | what=".LZX" | what=".ZIP" | what=".TXT" | what=".NFO" | what=".DOC" then y=1
if y=0 then ce;INTCOMMAND "CLS";nl;tr ""c3"    -"c4"-+-"c3"-"c4"-"c1"-"c3"---"c1"--"c3"--"c1"--"c3"--"c1"---"c3"-"c1"-"c3" -"c1"---"c3"-"c1"-- --"c3"-"c1"---- ----- ---- --- -- -- -";tr ""c4"      |"c5" Current File"c1" : __ "c1".. [ "c4""file""c1" ]";tr ""c3"      :"c5" Strip Status"c1" : __";tr ""c3"      :"c5" Add Status  "c1" : __";tr ""c4"      |"c5" Check Status"c1" : __";tr ""c3"    -"c4"-+"c3"-"c4"-"c1"-"c3"--"c1"-"c3"--"c1"----"c3"-"c1"----"c3"-"c1"-"c3"-"c4" --+"c3"-"c1"--"c3"-"c1"---"c3"--"c1"--- --"c3"-"c1"-- ---- --- -- -- -";tr ""c4"                              |"c5" mAGiC-aRC v"c4"1"c5"."c4"8"c5" bY dAvE"c4"/"c5"lNS"c4"^"c5"dSY";tr ""c3"                            --"c4"+-"c3"--"c1"-"c3"-"c1"- --"c3"-"c1"-- --"c3"-"c1"- --- -- -";if node=1 then call ND1;if node=2 then call ND2;if node=3 then call ND3;if node=4 then call ND4;if node=5 then call ND5;ce;ND1:;if what=".LHA" | what=".LZH" then call LHA;if what=".LZX" then call LZX;if what=".ZIP" then call ZIP;if what=".TXT" | what=".NFO" | what=".DOC" then call TXT;ce;ND2:;if what=".LHA" | what=".LZH" then call LHA;if what=".LZX" then call LZX;if what=".ZIP" then call ZIP;if what=".TXT" | what=".NFO" | what=".DOC" then call TXT;ce;ND3:;if what=".LHA" | what=".LZH" then call LHA;if what=".LZX" then call LZX;if what=".ZIP" then call ZIP;if what=".TXT" | what=".NFO" | what=".DOC" then call TXT;ce;ND4:;if what=".LHA" | what=".LZH" then call LHA;if what=".LZX" then call LZX;if what=".ZIP" then call ZIP;if what=".TXT" | what=".NFO" | what=".DOC" then call TXT;ce;ND5:;if what=".LHA" | what=".LZH" then call LHA;if what=".LZX" then call LZX;if what=".ZIP" then call ZIP;if what=".TXT" | what=".NFO" | what=".DOC" call TXT;ce;END:;nl;nl;nl;shutdown;exit;LHA:;if adds = "1" then call 1LHA;if adds = "2" then call 2LHA;if adds = "3" then call 3LHA;ce;1LHA:;ex "LHA d >NIL: "pth"Node"node"/"file" #?.Displayme #?.Add "srp0" "srp1" "srp2" "srp3" "srp4" "srp5" "srp6" "srp7" "srp8" "srp9" "srpA" "srpB" "srpC" "srpD" "srpE" "srpF" "srpG" "srpH" "srpI" "srpJ" "srpK" "srpL" "srpM" "srpN" "srpO" "srpP" "srpQ" "srpR" "srpS" "srpT" "srpU" "srpV" "srpW" "srpX" "srpY""
tr ""tr1"";nl;nl;nl;nl;nl;if adda = "N" then call CTA1;ex "LHA a >NIL: "pth"Node"node"/"file" "add1"";tr ""tr2"";nl;nl;nl;nl;CTA1:;if ddir = "N" then call CHKLHA;ex "LHA d >NIL: "dir1" "dir2" "dir3" "dir4" "dir5"";if chk = "Y" then call CHKLHA;else;ce;2LHA:;ex "LHA d >NIL: "pth"Node"node"/"file" #?.Displayme #?.Add "srp0" "srp1" "srp2" "srp3" "srp4" "srp5" "srp6" "srp7" "srp8" "srp9" "srpA" "srpB" "srpC" "srpD" "srpE" "srpF" "srpG" "srpH" "srpI" "srpJ" "srpK" "srpL" "srpM" "srpN" "srpO" "srpP" "srpQ" "srpR" "srpS" "srpT" "srpU" "srpV" "srpW" "srpX" "srpY"";tr ""tr1"";nl;nl;nl;nl;nl;if adda = "N" then call CTA2;ex "LHA a >NIL: "pth"Node"node"/"file" "add1" "add2"";tr ""tr2"";nl;nl;nl;nl;CTA2:;if ddir = "N" then call CHKLHA;ex "LHA d >NIL: "dir1" "dir2" "dir3" "dir4" "dir5"";if chk = "Y" then call CHKLHA;else;ce;3LHA:;ex "LHA d >NIL: "pth"Node"node"/"file" #?.Displayme #?.Add "srp0" "srp1" "srp2" "srp3" "srp4" "srp5" "srp6" "srp7" "srp8" "srp9" "srpA" "srpB" "srpC" "srpD" "srpE" "srpF" "srpG" "srpH" "srpI" "srpJ" "srpK" "srpL" "srpM" "srpN" "srpO" "srpP" "srpQ" "srpR" "srpS" "srpT" "srpU" "srpV" "srpW" "srpX" "srpY"";tr ""tr1"";nl;nl;nl;nl;nl;if adda = "N" then call CTA3;ex "LHA a >NIL: "pth"Node"node"/"file" "add1" "add2" "add3"";tr ""tr2"";nl;nl;nl;nl;CTA3:;if ddir = "N" then call CHKLHA;ex "LHA d >NIL: "dir1" "dir2" "dir3" "dir4" "dir5"";if chk = "Y" then call CHKLHA;else;ce;CHKLHA:;ex "LHA t >NIL: "pth"Node"node"/"file"";tr ""tr3"";nl;nl;nl;ce;LZX:;if adds = "1" then call 1LZX;if adds = "2" then call 2LZX;if adds = "3" then call 3LZX;ce;1LZX:;ex "LZX d >NIL: "pth"Node"node"/"file" #?.Displayme #?.Add "srp0" "srp1" "srp2" "srp3" "srp4" "srp5" "srp6" "srp7" "srp8" "srp9" "srpA" "srpB" "srpC" "srpD" "srpE" "srpF" "srpG" "srpH" "srpI" "srpJ" "srpK" "srpL" "srpM" "srpN" "srpO" "srpP" "srpQ" "srpR" "srpS" "srpT" "srpU" "srpV" "srpW" "srpX" "srpY"";tr ""tr1"";nl;nl;nl;nl;nl;if adda = "N" then call CTB1;ex "LZX af -1 >NIL: "pth"Node"node"/"file" "add1"";tr ""tr2"";nl;nl;nl;nl;CTB1:;if ddir = "N" then call CHKLZX;ex "LZX d >NIL: "dir1" "dir2" "dir3" "dir4" "dir5"";if chk = "Y" then call CHKLZX;else;ce;2LZX:
ex "LZX d >NIL: "pth"Node"node"/"file" #?.Displayme #?.Add "srp0" "srp1" "srp2" "srp3" "srp4" "srp5" "srp6" "srp7" "srp8" "srp9" "srpA" "srpB" "srpC" "srpD" "srpE" "srpF" "srpG" "srpH" "srpI" "srpJ" "srpK" "srpL" "srpM" "srpN" "srpO" "srpP" "srpQ" "srpR" "srpS" "srpT" "srpU" "srpV" "srpW" "srpX" "srpY"";tr ""tr1"";nl;nl;nl;nl;nl;if adda = "N" then call CTB2;ex "LZX af -1 >NIL: "pth"Node"node"/"file" "add1" "add2"";tr ""tr2"";nl;nl;nl;nl;CTB2:;if ddir = "N" then call CHKLZX;ex "LZX d >NIL: "dir1" "dir2" "dir3" "dir4" "dir5"";if chk = "Y" then call CHKLZX;else;ce;3LZX:;ex "LZX d >NIL: "pth"Node"node"/"file" #?.Displayme #?.Add "srp0" "srp1" "srp2" "srp3" "srp4" "srp5" "srp6" "srp7" "srp8" "srp9" "srpA" "srpB" "srpC" "srpD" "srpE" "srpF" "srpG" "srpH" "srpI" "srpJ" "srpK" "srpL" "srpM" "srpN" "srpO" "srpP" "srpQ" "srpR" "srpS" "srpT" "srpU" "srpV" "srpW" "srpX" "srpY"";tr ""tr1"";nl;nl;nl;nl;nl;nl;if adda = "N" then call CTB3;ex "LZX af -1 >NIL: "pth"Node"node"/"file" "add1" "add2" "add3"";tr ""tr2"";nl;nl;nl;nl;CTB3:;if ddir = "N" then call CHKLZX;ex "LZX d >NIL: "dir1" "dir2" "dir3" "dir4" "dir5"";if chk = "Y" then call CHKLZX;else;ce;CHKLZX:;ex "LZX t >NIL: "pth"Node"node"/"file"";tr ""tr3"";nl;nl;nl;ce;ZIP:;if adds = "1" then call 1ZIP;if adds = "2" then call 2ZIP;if adds = "3" then call 3ZIP;ce;1ZIP:;ex "ZIP >NIL: -d -q "pth"Node"node"/"file" #?.Displayme #?.Add "srp0" "srp1" "srp2" "srp3" "srp4" "srp5" "srp6" "srp7" "srp8" "srp9" "srpA" "srpB" "srpC" "srpD" "srpE" "srpF" "srpG" "srpH" "srpI" "srpJ" "srpK" "srpL" "srpM" "srpN" "srpO" "srpP" "srpQ" "srpR" "srpS" "srpT" "srpU" "srpV" "srpW" "srpX" "srpY"";tr ""tr1"";nl;nl;nl;nl;nl;nl;if adda = "N" then call CTD1;ex "ZIP >NIL: -1 -q "pth"Node"node"/"file" "add1"";tr ""tr2"";nl;nl;nl;nl;CTD1:;if ddir = "N" then call CHKZIP;ex "ZIP >NIL: -d -q "dir1" "dir2" "dir3" "dir4" "dir5"";if chk = "Y" then call CHKZIP;ce;2ZIP:;ex "ZIP >NIL: -d -q "pth"Node"node"/"file" #?.Displayme #?.Add "srp0" "srp1" "srp2" "srp3" "srp4" "srp5" "srp6" "srp7" "srp8" "srp9" "srpA" "srpB" "srpC" "srpD" "srpE" "srpF" "srpG" "srpH" "srpI" "srpJ" "srpK" "srpL" "srpM" "srpN" "srpO" "srpP" "srpQ" "srpR" "srpS" "srpT" "srpU" "srpV" "srpW" "srpX" "srpY""
tr ""tr1"";nl;nl;nl;nl;nl;nl;if adda = "N" then call CTD2;ex "ZIP >NIL: -1 -q "pth"Node"node"/"file" "add1" "add2"";tr ""tr2"";nl;nl;nl;nl;CTD2:;if ddir = "N" then call CHKZIP;ex "ZIP >NIL: -d -q "dir1" "dir2" "dir3" "dir4" "dir5"";if chk = "Y" then call CHKZIP;ce;3ZIP:;ex "ZIP >NIL: -d -q "pth"Node"node"/"file" #?.Displayme #?.Add "srp0" "srp1" "srp2" "srp3" "srp4" "srp5" "srp6" "srp7" "srp8" "srp9" "srpA" "srpB" "srpC" "srpD" "srpE" "srpF" "srpG" "srpH" "srpI" "srpJ" "srpK" "srpL" "srpM" "srpN" "srpO" "srpP" "srpQ" "srpR" "srpS" "srpT" "srpU" "srpV" "srpW" "srpX" "srpY"";tr ""tr1"";nl;nl;nl;nl;nl;nl;if adda = "N" then call CTD3;ex "ZIP >NIL: -1 -q "pth"Node"node"/"file" "add1" "add2" "add3"";tr ""tr2"";nl;nl;nl;nl;CTD3:;if ddir = "N" then call CHKZIP;ex "ZIP >NIL: -d -q "dir1" "dir2" "dir3" "dir4" "dir5"";if chk = "Y" then call CHKZIP;ce;CHKZIP:;ex "ZIP -T "pth"Node"node"/"file"";tr ""tr3"";nl;nl;nl;ce;TXT:;ex "Join "add1" "file" AS Ram:MagicArc.temp";ex "Join Ram:MagicArc.temp "add1" AS "file"";ex "Delete Ram:MagicArc.temp QUIET";tr ""tr2"";ce;error:;syntax:;ioerr:;ce

C#: Day 1

Cultural relic Commodore 64 home computer.

LOAD “$”,8,1

64 kB of RAM. Commodore 1530, SID, Commodore 1541, TAC-2, Floppy, Decrunchinget cetera. Introduction When we got our Commodore 64 I was so intrigued by the command-line interpreter, Commodore DOS, and fascinated by what my brother later did with BASIC, I had to try it for myself but only got a little further than Hello World. Later, I and my brother were introduced to the Demoscene as well, which sparked an interest for pixel art and coding that grew with subsequent computer platforms. I didn’t get far on the C64 and it wasn’t until after we got our Amiga 500 and then the Amiga 1200 that I really took to programming and pixel art (I love you Photoshop but you will never be my Deluxe Paint). During the A500 I developed an interest in the Amiga Workbench operating system. On the A1200 I developed further interest in hardware and software. I upgraded the A1200 from 14 MHz to 28 MHz, from 2 MB to an additional 4 MB RAM and a 40 MB HDD, next was a Motorola 68040 central processing unit at 33 Megahertz, 8 Megabyte of RAM, 540 MB Hard Disk Drive and had a 28.8k V.FAST Modem. Later, my brother talked me into breaking the bank on the Blizzard 1260 Accelerator with the Motorola 68060 CPU clocked at 50 MHz and with 16 MB Fast Memory. Sigh, the 39 MIPS in Workbench 3.0 (and Tornado) made it worthwhile. By then I had 1.1 GB HDD, more bauds and bits with a 57.6k Modem and a 6x CD-ROM. On it, I ran a Bulletin Board System, The Lock-Up BBS. Doors were the Apps of the time, for Bulletin Board Systems, which were the Internet equivalent of the time, sort of. As a Sysop, I was not satisfied with the available Doors so I quickly learned the ARexx language. I had a series of Doors when I jumped to the Assembly programming language and continued programming Doors. Optimizing the code became a passion. I even did CPU specific executables. I preferred customization and as a result my Doors were highly configurable. A few of my aliases were BigBang, Fusion and Dave. I had just begun coding a Workbench application at the time of the Commodore Amiga demise. When I got my first PC, with an AMD K6, I was turned off to programming on it at the time and quit (it wasn’t that easy breaking up with my Amiga and her Motorola 68000 family). Although, it was a good high-end PC at the time. Later though, I learned HTML and CSS. A while ago I was on and off ActionScript too but wasn’t convinced.

The Commodore Amiga 1200 personal computer.

Cultural relic A1200.

AGA, DOpus, X-COPY, D-COPYCloser by CNCD, ProTracker, OctaMED, Imagine, LightWave 3D, Joystick, Datic (Alfa Data) Chrystal Trackballet cetera. C Sharp Long overdue, I am finally going to be programming again. I chose C# (Visual C#) to go with the development of Windows 8 and in particular Windows Phone 8 apps and I will document the process here on my blog. Today I got around to begin the Channel 9, C# Fundamentals: Development for Absolute Beginners. I have no knowledge of any C programming language prior. I have finished lesson 1 through 5 and so far almost everything is very familiar due to my previous knowledge. I like the free Microsoft Visual Studio Express 2013 too (I’ll always miss you ASM-One). The low level Assembly programming language put me off to high level programming languages up until recently (I prefer the Close to Metal approach) but now I have a newfound interest. I’ll summarize and go into detail for my second day. Clearly, I got lost in nostalgia for this first post. My Initial experience is positive though!

Screenshots of various BBS Doors and the Amiga Workbench.

The Lock-Up BBS

Screenshot collage of a few of my Doors, my BBS, a glimpse of my Workbench, and ANSI.

An easy-to-read review of the Microsoft Sculpt Ergonomic Desktop

Trial and error

I love the Logitech Wireless Solar Keyboard K750 and the Microsoft Arc Touch Mouse. Having established that, I was looking for something ergonomic. At first, I tried the Microsoft Sculpt Comfort Keyboard and Microsoft Sculpt Comfort Mouse. While they were OK, they weren’t very ergonomic at all. Typing and using a mouse a lot, my wrists feel fatigued after very long sessions. The keyboard keys didn’t feel as good as the K750 either, and the separate mouse didn’t come with a transmitter. Using the ICIDU USB Mini Adapter, which is Bluetooth 2.1 and USB 1.1, Windows 8 couldn’t find the mouse. With the Trust Bluetooth 4.0 USB adapter, the mouse was found, but frequently lost the connection for some reason. I also recently used a new Logitech B110 mouse while waiting for something interesting to be released. It stopped working after just a few months. I guess you get what you pay for.

This is where the Microsoft Sculpt Ergonomic Desktop comes in.

The Microsoft Sculpt Ergonomic Desktop sitting on my desk.

ASUS PB278Q, Asus Xonar Essence One and Audio Pro Addon T8 as a reference.

A closeup of the Microsoft Sculpt Ergonomic Desktop.

Micro (Macro) soft and Bokeh courtesy of the Nokia Lumia 920.

The Microsoft Sculpt Ergonomic Desktop character layout.

A closer look at the keyboard character layout.

A closeup of the mouse.

Windows and back button on the mouse.

The Microsoft Sculpt Ergonomic Desktop viewed from the side.

View from the side with the Sennheiser HD650 far off.

The keyboard

The Microsoft Sculpt Ergonomic Desktop keyboard is unconventional looking to say the least. It has a separate part to optionally place the keyboard onto, to get an elevation to the wrist pad if you prefer. A fantastic little detail is that it snaps into place with magnets. When I placed my hands as they should, the wrists relaxed to the point that I just sat there like that for a while. It was that comfortable and natural. At first, the typing speed and spelling accuracy fell far below acceptable, but once I got used to it, it was lovely. The curvature and tilt together with the feel of the wrist pad is wonderful. It also has that premium feel to the keys like the K750 which the Sculpt Comfort Keyboard lacks. I do miss the battery free ease of the K750 but the mechanical switch of the Windows 8 function keys make up for it. As I mostly use the custom function keys I can leave the switch there and flip it whenever I need the traditional function keys instead of holding a function key depressed back and forth.

A pet peeve with the keyboard is the upper most row of keys. They are both smaller and don’t have the same premium feel to them. I often miss the escape key because of this. Somehow, I occasionally hit the Insert key instead of the Enter key and additionally miss the arrow keys. The Enter key and arrow keys are a bit small, but its probably because of the confined key spacing akin to a laptop keyboard.

The mouse

Microsoft Sculpt Ergonomic Desktop mouse is very comfortable although I was skeptical at first. The thumb rests comfortably in the indentation, where you also have the Windows button to go to the start screen on top, and on the side you have a back button, barely visible. The battery compartment underneath is easily opened as the lid is held by magnets, but still firm, and it’s the same on the keyboard as well. On the mouse, there is a power switch underneath. On most surfaces the mouse has a nice glide to it. The scroll wheel is fairly standard, but good, and is also a middle mouse button. The right and left mouse buttons are also fairly standard, but nice.

Numeric keypad

The separate numeric keypad is great, and leaves all that extra space on the desk. If and when I need it, I just reach for the drawer and get it out.

Conclusion

What I also like is that all three, the keyboard, mouse and numeric keypad, use the same included transmitter. Quick and easy connection with no lag. The mouse is instantly active when switching the mouse on after being turned off. I couldn’t recommend the Microsoft Sculpt Ergonomic Desktop more whole heartedly. Love it.