Monday, 30th October 2006

This is a standalone application I've been sporadically working on which will be bundled with Latenite, but is perfectly usable away from it.




It's a plugin-extendable document browser. You can use it to manage a library of documents and display them in the tabbed browser on the right. It comes with plugins supporting text files, Rich Text documents, and anything IE supports (so in this case it's HTML and PDF).

I've also wrapped the XP Picture and Fax viewer as another plugin, but am having a few problems with that so I'm not sure if I'll end up writing my own image viewer. Multipage TIFFs would be nice, though.

Plugins can expose their own toolbars - hence the text file has a dropdown button with a list of encodings, which has been very handy for those hundreds of DOS text files I have knocking around.

The library is stored in an XML document, and I'm intending on devising a format for easy distribution of documentation - probably something as simple as a Zip archive containing the relevant files and a small XML document that can be merged with the main library one.

Two nifty links, if you didn't know about them already - famfamfam's glorious "Silk Icons" set and the oh-so-useful SkyBound Visual styles (notice how my tabs on the left of the screenshots render correctly, even though they're upside down).

Latenite and Brass 2

Wednesday, 11th October 2006


Both Latenite and Brass are getting a significant upgrade - and both are being written from scratch.

Both will sport a plugin-based architecture. This is most obvious with Brass - where pretty much everything - be it an assembler plugin or output plugin - can be extended by writing your own custom plugins. All Brass does is parse the basic syntax and pass it to the various plugins to work out what to do with it!

Latenite will load Brass and use it to provide feedback - such as error reporting and syntax highlighting - directly to the user.

General discussion is handled here; for what I mean with regards to Brass plugins, there's this post.

The basic idea is that you can plug in your own assembler and use it alongside Brass and Latenite.


Tuesday, 20th June 2006

There's a new Latenite beta - - available from my site. I hope this is the last Latenite 1 release; I'm moving away from the current IDE towards a revised Latenite 2, the focus more on interactivity with the assembler and the debugger (better 'Intellisense', breakpoints, variable watching and so on). This mainly revolves around a much improved text editor, currently in the works.


Not a very exciting thing to look at, but handling text selection, editing, copying, pasting, and highlighting - and keeping it fast - is being a bit of a pain.
For the most part, it is fast enough, but gets seriously sluggish when scrolling up and down at high resolutions (has to repaint the entire control as none of it is buffered).

That little 3D engine for the calculator I was working for (codenamed Nostromo) is not dead, as you might have thought;


(Old screenshot to refresh your collective memories). I have recently 'ported' the TASM-style code to the new Brass syntax, rewritten all of the wall handling code for increased performance and fixed some of the graphical glitches caused by overflow (lines wrapping incorrectly around the display). I have increased the resolution and accuracy of the maths in use as well, but it's still pretty sluggish with large amounts of data and still lacks occlusion and wall clipping to the view.

One (easy) way of speeding things up would be to split the world up into 'rooms' (or zones, pick whatever terminology you like) where each room is entirely self-contained and cannot be seen from any other room. By opening and closing doors between rooms you can add and remove which rooms are in the list to be drawn, keeping the geometry count low.

Of course, for this to work, I'd need a bit of collision detection to be able to work out which room the camera is in. sad.gif

In terms of occlusion, I'm a bit stumped. As far as I can tell, BSP might be the way to go, but have never been able to write a working 'BSP engine'. If anyone had any links they'd recommend on the theory and implementation behind this, I'd be very grateful.

Text Editing Woes

Thursday, 15th June 2006

I've had enough of my syntax-highlighting text editor in Latenite (it's a hack on top of the RichTextBox control, using all sorts of ugly Win32 hacks to beat it into submission). I'd much rather have a control I had some... 'control' over, so have taken to writing my own custom control.


One useful thing is that it supports Unicode characters nicely, unlike the RichTextBox


It doesn't currently support text selections (which is a bit of a problem) but once that's added it should be simple enough to start adding goodies to it that weren't easily possible via the RichTextBox control (reliable line highlighting, tab width manipulation, whitespace glyphs, collapsing code blocks and so on).

Debugging fun

Monday, 22nd May 2006

One part of the Latenite 'suite' that's needed some dire attention is the PindurTI interface. This talks to the excellent TI emulator via a non-interactive mode, and can therefore sit between Latenite (and your source code) and the emulated calculator (which is running your binary).

The current incarnation of this tool is very primitive - you have a calculator that you can run/pause and send files to. That's it.

A picture should illustrate what the new one's like and what the old one was missing:


There's a memory viewer, register viewer, and breakpoint window. Breakpoints are caught and highlighted in the breakpoint window.
Currently, there is no editing of the calculator state - PindurTI has yet to support writing back the status (it can only dump it at the moment). All the breakpoint and label information comes from the debug file exported directly by Brass.

Next Latenite Beta

Thursday, 23rd February 2006

Seeing as the MaxCoderz fora have died (I can't read or post on them at the temporary hosting), and I know at least kv reads this... wink.gif

Latest beta: /bin/latenite/ (full install).


  • No more hanging or locking up when running the PTI debugger (huzzah!) PindurTI debugger is still horribly, horribly incomplete :( (Boo!)
  • Reworked icon extraction code works for all files (no more incorrect icons!)
  • File tree plugins (bundled with .emr plugin) to expand certain files into a tree.
  • Copy/Paste doesn't accidentally copy/paste if the text editor isn't selected (Ctrl+C/Ctrl+V doesn't work anywhere else, though).
  • Minor bug fixes here and there; some visible, others invisible.
  • Brass template has old defines added for backwards compatibility.
  • Updated copy of Brass and Brass XML file.
  • Minor tweaks to help file CSS.
  • Blue icon bug in Windows versions prior to NT 5.1 (XP) should be fixed.

Known Issues

  • Holding tab/shift+tab down adds lots of surplus tabs.
  • Anything to do with the debugging (watch, breakpoints) has not been touched, and so old bugs remain there.
  • PTI debugger doens't handle errors very gracefully (infinite messagebox loops). Make sure your ROMs are correctly installed!

EarlyMorning Link
For the EarlyMorning interface to work you need to associate .emr files with EarlyMorning. You can do this by double-clicking any .emr file, then browsing to the EarlyMorning binary when prompted. Without this information, Windows won't know where to find EarlyMorning when it wants to open an EarlyMorning file.
If you run Latenite, .emr files should now appear with the EarlyMorning icon, and a little [+] by them. Click this to expand them! Something a bit like this:


Double clicking on a resource should open it in EarlyMorning.
Bear in mind that I forgot to copy kv's PM to disk, so built the interface by guessing. rolleyes.gif
Also bear in mind that EarlyMorning (the version I have, at least) has a bug, as it loads itself and expects to load resources relative to the current working directory. Opening a subresource has a hack in Latenite to fix this behaviour, but opening an EMR file by right-click->open will cause EM to crash.

@kv, you need something like this:

private string FixPath(string RelativePath) {
    return Path.Combine(Application.StartupPath, RelativePath);

private void Something() {
    // ... and use it like this:
    // Rather than:


Monday, 13th February 2006

They say that pictures are what make a journal interesting... but I don't really want to show the pretty pictures I have, as they'd spoil the surprise. Of what, you might ask? Well, I've been developing a TI-83/83+ scene demo, entitled "Microhertz" (for no particular reason). You can download it (and some screenshots, if you really must!) here.

Things have been very busy - a new Latenite beta, riddled with all new exciting "features" (*cough*), has been released... I'm slowly fixing them as and when I can smile.gif
It's a bit rubbish for debugging - you can start, pause, and stop a debugging session, but that's about it. Hopefully it won't be too long until I get around to actually sorting out all the debugging gubbins, but I'd rather get the main IDE and the primitive debugging more stable first.

One other TI project I'm working on is updating QuadPlayer. I have a 1.1 version which can play songs from the archive as well as RAM, has a loop function and other little fixes and tweaks. To complement it, I've written a simpler script for creating your own songs, a better Windows-based player for testing (which simulates QuadPlayer's internal sound generation system and has accurate timing) and (best of all) am working on a program that takes PSG VGM files (BBC Micro, Sega Master System &c) and converts them to QuadPlayer songs. So far, any songs that do "exciting" things - vibrato, for example - end up sounding horrible in high octaves (I'm having to limit 10-bit to 8-bit periods), but I have some very decent sounding QuadPlayer files based on Sega VGMs. Some songs use lots of short, fast notes - which sounds great on dedicated hardware, but when you have a delay as QuadPlayer stops outputting a square wave to fetch the next note, sounds crap.

YM2413 (OPLL) Emulation

Monday, 30th January 2006

As (yet another) side project to all this Z80 work, I've also decided to have a stab at the Japanese Master System's FM chip. It's a YM2413, and the documentation on it is fairly tricky to get to grips with - not only thanks to it being in typical Japanese-manual English.

So far, I have this - the VGM player is a bit buggy and extremely primitive (unfinished), but should be enough to demonstrate the current state of the OPLL. You'll need an FM VGM to try it with - the Space Harrier demo from the BIOS sounds pretty good.

If anybody has had any experience with the YM2413, I'd be interested to hear if you had any helpful tips...

In other news, I've been adding multipage program support to Brass, and Latenite has had a lot of debugger integration work done on it. It's still a long slog before it's in a presentable state, sadly.

TI Z80 Development Gets Cool

Tuesday, 10th January 2006

This excites me greatly - integrating a debugging emulator into Latenite is very, very awesome. CoBB's emulator is incredibly good as a standalone, being able to step through your code instruction-by-instruction with breakpoints and a watch window or two is just amazing! smile.gif

I spent most of the last few days working on Brass - adding for loops to assemble blocks of code multiple times and a few file operations for people not happy with the behaviour of .incbin. I also remembered to release an XML help file for Latenite.

The Marble Madness engine project has been plodding along in the background - I've written a fast masked, clipped, 16x16 sprite routine and have started tackling the big problem of mapping the ball's 3D coordinates to the screen (easy) and then to a heightmap (hard) for Physics.


Have a marble rolling off a ledge then bouncing off the right screen boundary. wink.gif

Intelligent macro-matching, VS icon nicking

Thursday, 22nd December 2005

Brass has got a new macro preprocessor, that hopefully makes the work of people writing things like the macro-driven TI ASM API easier, and will generate less redundant code.
TASM only supports simple find-and-replace macros; so, for example:

#define draw_sprite(x,y,sprite) ld a,x\ ld b,y\ ld hl,sprite\ call put_sprite

; Generates the following:
 ld a,10
 ld b,43
 ld hl,my_sprite
 call put_sprite

; Generates the following:
 ld a,a ; Rubbish!
 ld b,43
 ld hl,hl ; Not going to work...
 call put_sprite

Brass, however, supports more intelligent macros - like this example shows. It will switch between a variety of different macros, depending on the arguments passed in.

Latenite is still in development - nothing particularily visible, barring the new tooltips and worrying familiar icons.

Business with the Z80

Monday, 12th December 2005

I have been pretty busy with Brass and Latenite over the last few days - Latenite has had a few little adjustments/improvements/fixes, but also has a few new holes in it which means that it is unsuitable for release. I'm adding the ability to hook help files to projects rather than each project being loaded with every help file - this has the extra bonus that Brass will be able to compile help files straight from the source, which will then be reloaded on each build by Latenite.

I did something unheard of over the weekend as well - I read the SDK manual for the TI-83 Plus. Mainly because I was trying to work out how some of the function calls worked, but also the stuff they talk about with regards to applications (as opposed to programs - applications fill multiple 16KB pages of ROM on the calculator, programs are variable sizes and are copied to RAM location $9D93 for execution) was pretty interesting - and it sounds pretty nightmarish! I'll download some of the application development tools, see if I can puzzle them out and then try and recreate their behaviour in Brass. It's yet another output format - Brass can, with the .binarymode directive, switch between a number of binary output formats, including TI calculator formats (TI-73, TI-82, TI-83, TI-83+, TI-85, TI-86), raw binary and a number of hex text files (Intel, Intel word address, MOS technology and Motorola).

I'd never really understood how the LCD display driver worked on the TI-83 Plus, and the SDK documentation was pretty useful - even though I still can't quite work out why the X axis goes from top-to-bottom and the Y axis goes from left-to-right. It turns out direct access to the LCD can produce some very fast results... (and the world's worst greyscale):

Download binaries for TI-83/TI-83 Plus [Ion/MirageOS]

Yes, yes, I have a little 'something' about 3D tunnels.

I hate syntax highlighting.

Monday, 28th November 2005


I spent this weekend completely rewriting the syntax highlighting control - this time, from scratch. It seems that all the free ones are rubbish. sad.gif Mine is rubbish, but at least I can maintain it. wink.gif Now all I have to do is wait for the people using the beta to start complaining that it's eating their source code...

My test project for it was a Lotus-like 3D racing engine.


I think I need to research the way it works a little better... still, not too bad for a little over 400 bytes.


Monday, 21st November 2005

Latenite - looking more and more like a VS ripoff. grin.gif

latenite_0.0.1.0_a.jpg latenite_0.0.1.0_b.jpg latenite_0.0.1.0_c.jpg

XML Overload

Tuesday, 8th November 2005

Everything in the new version of Latenite is XML-based - the project files, the help files, the error logs... Never mind, it seems to work well.

Click for massive.

So far, the only thing that's useful (complete and working) is the 8XP Linker - linker is a bit of a fancy name for it, as all it really does is wrap a number of .bin COM files up into a single .8x? or 83? file for the TI-83(+). It's a Win32 app, which should help some people stuck with the old DOS apps who can't get them to run under WinNT.

The Build menu seems to work; all Build scripts are now based around the project (rather than the old method of a number of fixed ones). After all, a "Build→Sega Game Gear" option is a bit useless to a TI-8X app. Any .cmd file in your project's Build folder should appear on the menu for you to run.

There are still a few issues - remembering which files were opened when you close the project, remembering which the default build script is, search in entire project (so far only current file and all open files are supported), jump to line, jump to previous instance of selected word, open file at cursor... I also need to complete the Z80 instruction set help file, add a WLA-DX help file... Lots for me to be getting on with!

Latenite, VS 2005 and two screens.

Monday, 31st October 2005

Long time no update...
I haven't done any more work on FireTrack, that is now officially a dead project. sad.gif

Rearranged PC

I spent some part of this weekend rearranging my PC so I could take advantage of my DVI port. With a DVI→VGA adapter I could connect up the other 17" monitor that was currently going unused on my PS2. I also had a new second-hand (new to me, that is) VCR to throw into the mix - here are the results! (Hover for notes).

show_ps2.jpgAn image

Once again, I'm astounded as to how expensive cables are on the high street (last time it was a USB cable that threw me - £14 in Dixons, I ended up getting it for 99p on eBay). To connect the VCR to the VGA box I needed to convert the only output it gave me, SCART, to something usable - S-Video or composite. The only cable Dixons sold that converted SCART to composite out cost a whopping £39.99... no thanks! Maplin wasn't so bad, a two-way (switchable) SCART→S-Video/composite was only a tenner. Only thing left for me to get is a new VGA cable from my PC to the VGA box - my current cable is thinner than most serial cables I have! (In the photo of the VGA box, it's the one on the left) Needless to say, the image is very fuzzy and there is serious ghosting.

Visual Studio 2005

I recently received the Beta 2 in the post, and I'm (generally) highly impressed. However, I've run into a number of oddities along the way, not to mention some infuriating bugs. The worst is the image resource editor for adding images to menus and the like. Add a couple of images, set the image on a menu item and watch as it erases all your menus, adds them all back again before crashing with the error message:
vs_error.gif which point the IDE closes.
Another oddity is that after such a crash my program started crashing when it closed. The error was in this code (added by the form designer);

protected override void Dispose(bool disposing) {
	if (disposing && (components != null)) {

base.Dispose(disposing); was causing the error "Cannot access a disposed object. Object name: 'SplitterPanel'." I have no idea what would cause that, or which object "SplitterPanel" is at all. Changing the problematic line to this.Dispose(disposing); fixed the problem, but if anyone could shed light onto why this code was failing I'd be very grateful!

My only other major beef with VS2005 is that while most of the visual style bugs have been ironed out, some still remain. The worst one for me is the TabControl, as aligning the tab buttons to anything other than top results in some very odd results. Are MS ever going to decide on a consistent theme? rolleyes.gif


Latenite is back in redevelopment - hopefully this version will be released! I have completely rewritten it from scratch in C# (previously in VB.NET) - for one weekend's work, it's not looking too shabby.

Click for bigger.

Yes, it looks like a direct rip-off of VS, but is geared towards Z80 editing. I'm sticking to making it look/work like a simplified VS, as that seems to be the best way for things to work (after all, most image editing apps feel like variations on a theme of Photoshop). Some new features:

  • Fully XML-based help system makes help files considerably more manageable. HTML-based help viewer (rather than RTF) allows for better presentation and slicker (working!) hyperlinks.
  • Error logs are also returned as XML for neatness.
  • Compilation is now based around a bunch of sensible environment variables (the old system used a cryptic set of command-line arguments - %1 to %5). For example, this is the script for generic TI compilation:
    devpac8%1 "%SOURCE_FILE_NOEXT%"
  • Ability to undo more than one edit and redo again! - This is a big one! (A new class that just adds to the )
  • Sexy icon laden menus. If you create a compile script and save a PNG in the same folder with the same filename (so ZX Spectrum.cmd with a picture of a speccy as ZX Spectrum.png) it appears on the build menu.
  • Faster and more accurate line selection.

There is still a lot (of very dull stuff, no less) to do - project organisation, settings saving/loading, text search... Bah. One day!

Bloop-bleep, it's the 80s!

Wednesday, 14th September 2005

Sound! I am still musicless, but never fear, for sound effects will fill the gap. Screenshots are pretty poor for sound wink.gif, so here's the MP3.
Simple as it sounds, that takes a mere 163 lines of ASM code to work, and even then it's a fairly crap effect!
Each sound is stored as a series of "fades". Each fade contains the following data:

  • Starting period of the wave.
  • Starting amplitude of the wave.
  • Length of the wave in frames.
  • Amount to add to volume each frame.
  • Amount to add to period each frame.

Using these simple fades and joining them together you can very easily produce a fairly complex sound. There are currently only two sound effects, and both are a single "fade" long - one for firing, the other for when a tile on the ground has been hit.
Each sound effect is issued with a priority, in a little table, so that the most important sound is played over the top of the least important one. In this case, if you play a more important one over a less important one (higher pitched bleeps) it cuts the less important one out for good - which is rubbish, really. What I will have to do is to extend the system to act over a list of current sound effects that can be added to at any time. That way, which tone is sent to the PSG (the sound chip) can be decided at that point, based on priority (and maybe volume, I'll have to see how it sounds).

I fixed Latenite's ugly XP icon issue, and here are the results:

latenite_debug.png latenite_release.png

sad.gif The one on the left is the Debug build. The one on the right is the Release build. I have no idea why it is doing that on the right, or how I can fix it.

It gets better.


This is what it looks like in Release mode when running in the VS.NET IDE.
I shall now resist the urge to make an massive journal post this time. Honest. Just watch me. wink.gif

Old projects and ugly XP icons

Tuesday, 13th September 2005

This is going to be a very boring update, I'm afraid. I wasn't feeling too good so haven't got much done. sad.gif

First of all, Latenite updates. With the project thingummy, I thought it would be nicest if it displayed the proper Windows icons for file types rather than the ones I had hardcoded in. Here is a function I wrote to take a filename and return an icon (in the form of a .NET Bitmap) based on it and whether you requested a large or small icon.
It works by going into the registry and looking up the ".ext" key. Some keys like that contain a DefaultIcon property and a filename/index number of the icon to use, some just point at another subkey with that DefaultIcon property.
After I found that, I use the rather nasty ExtractIconEx to retrieve icon pointers from the DLL/ICO/EXE, select the one I want, copy that to an Icon (and then to a Bitmap) then clean up.
Here's a screenshot of it in action:


You'll notice the crud around the final icon. It seems that any XP-style icons with an alpha channel get mucked up by the ExtractIconEx ripping out the icon's data. If possible, I would force it to retrieve the 256 colour version (at 16x16, that's still a colour for every pixel!) but don't possess enough Win32 wizardry to achieve this. If anyone could help me, I'd really appreciate this.

Here is the module, in case someone finds it useful. Sorry if it appears a bit hacky, but it seems to work fine for me.

Module mdlIcons

    Private Declare Function ExtractIconEx Lib "shell32.dll" Alias "ExtractIconExA" (ByVal lpszFile As String, ByVal nIconIndex As Int32, ByRef phiconLarge As Int32, ByRef phiconSmall As Int32, ByVal nIcons As Int32) As Int32
    Private Declare Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Int32) As Int32

    Function getIconFromFilename(ByVal filename As String, ByVal largeIcon As Boolean) As Bitmap

        ' Grab the extension:
        Dim getExtension() As String = filename.Split(".")

        ' Look up the file type:
        Dim searchKey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("." & getExtension(UBound(getExtension)), False)

        ' Was anything found?
        If searchKey Is Nothing Then Return Nothing

        ' Go through until you hit the end:
        Dim getDefaultIcon As Microsoft.Win32.RegistryKey
            getDefaultIcon = searchKey.OpenSubKey("DefaultIcon", False)
            If Not (getDefaultIcon Is Nothing) Then Exit Do
            searchKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(searchKey.GetValue(""))
            If searchKey Is Nothing Then Return Nothing

        ' Get the details:

        Dim fileDescription As String = searchKey.GetValue("")
        Dim iconPath As String = getDefaultIcon.GetValue("")

        ' Close the registry keys:


        ' Now we have that data, we need to convert a "xxxx,0" path into a "xxxx" and a "0"

        Dim getPlainIconDetails() As String = iconPath.Replace("""", "").Split(",")
        Dim iconIndex As Integer = 0
        Dim plainIconName As String = getPlainIconDetails(0)

        For i As Integer = 1 To UBound(getPlainIconDetails) - 1
            plainIconName &= "," & getPlainIconDetails(i)

        If iconPath.Replace("""", "").ToUpper.EndsWith(".ICO") Then
            If UBound(getPlainIconDetails) <> 0 Then plainIconName &= getPlainIconDetails(UBound(getPlainIconDetails))
            iconIndex = Val(getPlainIconDetails(UBound(getPlainIconDetails)))
        End If

        ' Now we have all that info, let's grab the icon:

        Dim iconLarge As Int32
        Dim iconSmall As Int32
        If (ExtractIconEx(plainIconName, iconIndex, iconLarge, iconSmall, 1) > 0) Then
            Dim iconPtr As IntPtr

            If largeIcon = True Then
                iconPtr = New IntPtr(iconLarge)
                iconPtr = New IntPtr(iconSmall)
            End If

            Dim iconRes As Icon = Icon.FromHandle(iconPtr)

            Dim returnBitmap As Bitmap = iconRes.ToBitmap
            If iconLarge <> 0 Then DestroyIcon(iconLarge)
            If iconSmall <> 0 Then DestroyIcon(iconSmall)
            Return returnBitmap
            Return Nothing
        End If

    End Function

End Module

The C# source code I saw that used the ExtractIconEx call used ExtractIconExA instead of ExtractIconEx. I thought that this meant that A = alpha, so hopefully swapped the A in but VB.NET complained with a squiggly blue line. If only Win32 was as easy as that.

As far as Fire Track itself goes, there's nothing to really show for it - if you die, the game continues for a short way (with you invisible and uncontrollable) before decrementing your lives by one and sticking you back at the zone info screen. When you press START you get stuck back in the game at your old position in the level and you start again.
As dull as that sounds, there is a lot of work going on to achieve that - namely swapping palettes and tilesets to RAM and ROM and back again as required.

big_1.png big_2.png

Here's a silly pair of screenshots. I played around with some of the more interesting VDP mode bits last night, and this is the "sprite zoom" one. By changing a couple of lines of the sprite routines with .ifdef blocks I can now set a switch in my file before compiling and all sprites are double size. Not sure why one would want to do that, but it's nice to know that the option is there.

Finally, here are some old shots I could have shown in here a while back - I thought I'd teach myself some OpenGL, what with SDL just sitting around doing nothing much for me.


As ever, click for bigger. Yep, it's the generic starter app of a terrain engine. (The Perlin noise for heights was new to me, I'd only used a precalculated one from Photoshop before). I couldn't quite work out how to do ambient lighting, hence the black sides to the hills. Not to mention that the tiling of the ground texture is blatently visible. The water moves up and down slowly to "wave", and the entire water texture scrolls past slowly.
I wish those shots were "real" - in face, there are two major flaws in my engine. First up is the very poor culling for terrain chunks outside the view - it's purely 2D, so looking down at the ground looks like this:


...which isn't quite right. I also had to tweak the LOD calculation for the above shots - here it is with the LOD tuned the other way;


Lots of nasty holes. I couldn't quite work out the skirting myself, so consigned the project to the bins once again (as I do with about 49 out of 50 projects). It runs at ~150FPS in debug mode, which is something to be pleased with I suppose.

I will release Fire Track, though. I hope. If someone could help with the music.

Lost projects... now there's an idea for a Lounge thread. I think I'll spare that by posting a few in my journal instead. Some of these started out as Really Good Ideas at 3AM when I couldn't sleep, but never seemed to get anywhere:

Album Art Viewer - for those covers that Windows Media Player displays, which Windows Explorer hides.

WAD Reader - DOOM WADfile reader/viewer. Has support for all graphics ("pictures" and raw flats), DOS end screens, PC speaker sound effects. Can view pictures in special viewer where you can rotate the sprites or watch their animations (it has to guess a lot, so that's not perfect). Can export all lumps as raw data or convert to PNG (graphics) or RTF (DOS end screens). Can also play the PC speaker (not wave) sound effects if your PC has a PC speaker on the motherboard. VB.NET, but quite fast. Full screen pictures take about 2 seconds to render as properly, though. However, once rendered all are cached internally for instant retrieval.

Lemming Syndrome
- (click to download 194KB file, requires .NET runtimes) - wow! I forgot about this one. It was meant to be for the 1W1B contest - a challenge to work on a game for one week, with the requirement that you only used one button to control it. So, er, try and bounce me over the river in your lifeboat. There is no "game", as such, (unfinished), so it'll go on for ever.

MySQL Manager - I was feeling cheap and my trial to MySQL-Front was about to expire, so I started work on a MySQL clienty thing. It's massively faster at downloading/displaying data, but that's about all it actually does after I decided it was too much hassle to try and recreate a full tool, so I forked out for a license of MySQL-Front instead. rolleyes.gif

Anyway, this is scaring me, I just found a garishly coloured TETRIS.EXE that I swear I never wrote, but the code style is mine and it has my name on it, so I guess I actually did... I have been feeling a bit ropey for the last year-and-a-bit, so I guess it slipped my radar. Or I wrote it in my sleep. Or something. Just be glad I don't have an internet connection myself and have to rely on one at work, so you're safe from me posting in my sleep! grin.gif

On the merits of Excel and running out of space

Monday, 12th September 2005

Latest video. [2.29MB AVI]

You chaps probably don't know what a major headache it is trying to get clear, non-wobbly video... rolleyes.gif


I gave up in the end and went for the "propped-up against a wall with camera on stack of books" approach. The reason I cannot, therefore, appear to play the game very well is because I cannot see the screen. All I can see is a faint, inverted glow and have to guess where I am. Not fun.

Here are the major updates since last time:

  • Removed Blackadder theme rolleyes.gif
  • Altered colour contrast on title screen, added wipe to clear it in imitation of original, restructured code for better fades, changed timing, added sound. Title screen is now complete.
  • Rewrote entire code for checking bullet collisions with buildings on the ground from scratch. It now works perfectly.
  • Levels now "start" correctly, so the ship moves in from the bottom, the start platform moves towards you very fast until they are in the correct positions, at which point gameplay commences (much smoother than just dumping you at the start position with a full level already there).
  • All levels now mapped correctly, in order, with correct palettes for backgrounds AND sprites. Levels that end a zone with a platform rather than with the face are flagged as such and the correct end is substituted in now.
  • Each level can be pointed at a 'replacements' table, which lists "replace tile X with tile Y". Tiles are swapped around properly so that levels appear more varied.
  • Explosions are now fully implemented (2 kinds, background and foreground - with very slightly different animations) and working.
  • Path-based enemy attacks are now in full working order, using paths generated with a combination of my graphical calculator and Excel.
  • A couple of other new enemy attacks have been added.
  • The game now sports a BBC Micro font which can be used for proper text display.
  • The "epilogue" to the game is fully coded (type-writer effect for final message copied from original game, including sound effects and fades).
  • Each level now begins with a summary screen (sprite limits meant that displaying all your lives at the start of the level was impossible, so is now done on an interval screen). The screen displays the zone name and a number of lives, the number of lives being surrounded by orbiting space-ships (the number of those being the number of lives left).
  • The game now fully works on hardware (should now work on old hardware - not checked, as I do not have an old BIOS-less Game Gear) and in all emulators (I was not initialising the display correctly).
  • Destroyed terrain tiles are not updated live to the name table in the fairly intesive loop - they are saved to a list of destroyed tiles, which are then read off directly and updated when needed in the intensive graphics bit.

I've probably forgotten a lot of stuff. Bear with me.

There have been a number of "WTF" moments reading back some of the source. Take, for example, this gem:
Some explanation is needed here - this is from the code that handles the special case when you have shot a 2x2 square building and it lies out of bounds of the name table. The name table is my grid (32x28) of tiles indices that each point to an 8x8 tile in the VRAM. As the view point moves up this map, new tiles indices are written to it, or old ones are adjusted when something is blown up. The worst case scenario here is if the 2x2 tile lies just above the top of the name table - which is what the above code has to fudge. Look at this:

(I love debugging emulators!)
This shows all of my 32x28 tilemap. That funny white rectange is my view rectangle (it's currently half-off the display, and it loops around). If you look at the top and bottom edges of the tilemap, you'll see a ring has been shot out. Naturally, the bottom will have been hit first. What happens in this case is the address of the tiles that have been erased is decremented by a whole row of map points (there are 2 bytes to a spot on the name table, so I go backwards by 64). In this case, I find that the address is above the start of the tilemap so I add on 64*28 (which is the entire size of the table) and add it back to get back into the bounds of the table itself. As you can see, it was a successful operation in this case, but only because I was writing back HL this time and NOT the accumulator! No wonder my sprites were becoming destroyed as I was writing in completely the wrong part of the VRAM...

This is the screenshot from the emulator of the screen display for the above tilemap (the sprite layer is not displayed in the tilemap, for obvious reasons).

I'm still not getting very far with my quest for music. sad.gif
The only bit of the game that has music is the title screen, and that's not so much music as a weird noise (here is an MP3 of my Game Gear's rendition, this is the original from the BBC Micro). Even though I have specified that the noise channel (the one that produces the high beeping noises) to use the highest frequency, it's still lower than the Beeb. All the other notes are correct, though.

Latenite has got yet another update - project support. (It looks more and more like VS.NET every day!) Rather than create messy proejct files and stuff which makes distrubution tougher, I thought I'd go the easier route of just allowing people to stick directives in the file with the ;#latenite:main directive. You can now ;#latenite:name="name_of_project" and ;#latenite:project="file_name"[,"project_folder"].

Click for larger image

Skybound Visualstyles (which I'm using to fix the weird .NET XP interface bugs) looks lovely but hugely slows down the app - only really noticeable with so many hundreds of nested controls like me and when moving large windows on top of it forcing repaints, so now the XP styling option is saved away (so you can revert to boring standard grey if you like). Latenite now saves window/splitter positions when you close - a first for an app by me! grin.gif
In fact, Latenite is also my first app that needs a splash screen, it takes so long to get going... sad.gif It's only about 2 seconds, though, for it to track down all the tools, load all the documentation, add all the compiler scripts and present itself, so it's not too bad.

One overlooked piece of software is Microsoft Excel. People seem to develop a hatred of it, especially in people who end up trying to use it as a database application (it appears that this is what 9 out of 10 smallish (and some not so small!) companies do).
I have been using Excel to create those smooth curving paths for some of the enemies to follow. First, I prototype them on my graphical calculator (lots of trial and error involved!):


..before transferring into an Excel spreadsheet.

Click for legible!

The Excel spreadsheet is set up so that column A is the steps (usually 0 to 256) in ascending order. Column B is the X coordinate, column C is the Y coordinate.
Columns E and F serve a special purpose - they contain the differences between each element in columns B and C (so E3=B3-B2, E4=B4-B2 and so on). Columns G and H "fix" the values - if it's negative, make it positive and set the fourth bit (just add 8). This is for the internal representation of the paths. Column I contains the data I can just copy and paste into the source files - it starts with the initial (x,y) coordinate, and then has a list of bytes. Each byte signifies a change in (x) and change in (y), with the lower four bits for (x) and the upper four bits for (y).If the nibble is moving the object left or up (rather than right or down), then the most significant bit of that nibble is set. For example:

%0001 - move right/down 1 pixel
%0011 - move right/down 3 pixels
%1001 - move left/up 1 pixel
%1100 - move left/up 4 pixels

...and therefore...

%11000001 = move right one, up four.

Poor Excel has suffered a little bit of neglect from me - I used to use it to generate my trig tables. WLA-DX, the assembler I learn to love more and more every day, supports creation of a number of different tables - including trig tables - with a single directive. Just specify .dbsin (or .dbcos) followed by the start angle, how many bytes of trig table you want, the step between each angle, the magnitude of the sine wave and the DC offset and away it goes.
People still using TASM, STOP! Use WLA-DX. It's ace (and free, not shareware!).

You can never have enough pictures in a journal (hey, you should see this page load on our 700 bits/sec phone line at home!)
Here's the full list of sprites:


The last ship being after the explosions is a mistake, but it's too much hassle to change. I'm really pleased the way they've come out - I'm no pixel artist. smile.gif

I'll finish off with a few assorted screenies.


...I would have done. I should have done. However, when taking those screenshots I saw a glitch in the graphics. As an exercise for the reader, can YOU spot where the bug is?

(and it's not in one of those external functions I wrote - this is why copy-paste coding is bad, 'kay?)

Oh, (possibly?) final last thought popping into my head: one thing I really miss from the BBC Micro era is the comfortable keyboard layout. I mean, look at this small photo of a Master 128 keyboard:
Click for bigger

You might think that that blocky monstrosity would knacker your fingers, but that's not the reason. It's the fact that rather than squash one hand's fingers onto a small cursor pad (or the even sillier WASD), you balance movement between your two hands - Z and X for left and right, : and / for up and down. (On a modern UK layout, that'd be ZX and '/). The space bar is now conveniently accessible by both thumbs, and you can reach around most of the rest of the keyboard with your other fingers.
The Game Gear is an ergonomic handheld (unlike the uncomfortable Game Boy), so I'm reckoning that I can balance the controls between hands - ← and → on the d-pad can control left and right, and the 1 and 2 buttons can control up and down. I will offer multiple layouts, though, as otherwise that might confuse some people. wink.gif

Anyway, I hope you find this journal interesting. It seems a bit all over the place - video, pictures, rambling, odd bugs, nostalgia... The only thing that's an issue is my rapidly shrinking GDNet+ account web space!


Wednesday, 13th April 2005

I've been doing all sorts of odds and ends recently. I've acquired a Sega Game Gear, and so have started taking a look at programming on that - it has a Z80 CPU in there, so the languge isn't an issue, more so the hardware. Ah well, I can display a screen of text and cycle the colours around so far - nothing impressive, but the setup works.

I've also been playing with PICAXE microcontrollers again. Here is a pair of routines that can be used to get/send bytes using the TI hardware link protocol, for example. I am yet to do anything useful with them, however.

Windows programming has never been my favourite side of things, but I have also started work on a Z80 ASM "IDE" called Latenite:


It's mostly there, but now needs features galore to be added. So far it can be used to compile and source code, which is the main thing.

Subscribe to an RSS feed that only contains items with the Latenite tag.

FirstLast RSSSearchBrowse by dateIndexTags