• entries
222
606
• views
593107

Z80 and C#-related shenanigans - now with added electronics.

## ARGH!

Fire Track (on the BBC Micro) is probably the fastest, hardest, most adrenaline-packed space shooter I've ever played!
I'm playing my way through the extended version to try and work out the game mechanics a bit more. I've been using an ancient "infinite lives" cheat disk with it, but even so... whew, this game is tough.
I have saved state images for Levels 1 to 22, though, at last. My nerves are shot to pieces, in any case!

It appears that I have to rethink the way enemies are handled. Currently, I store a list of 8 enemies and assume they all follow the same pattern. Wrong. For most of the game, you can have lots of enemies on-screen, each from a different pattern! Or the patterns can overlap, even. What I think I'll do instead is have a list of enemies with ID (attack type - I'll use the sprite number), (X,Y) coordinate (if it's (0,0) it means the slot is free, no enemy) then 5 bytes of extra storage that the enemy attack handler for that enemy can do whatever the Hell they like with. If I have a timer that decreases and fires off the next enemy whenever it underflows (either a predetermined one from a table of enemy attacks or just picking a random one - or, for some of the bonus levels, none at all). Plus, I can rewrite it without lots of use of the slow IX register.

I have, however, added mine support. There's a function to add a mine at a particular (x,y), where it gets set up correctly and will drift towards you (the DX and DY are set up when you add the mine). They aren't part of the collision detection routines yet (I'll add them with the enemy system rewrite) but already scare me [wink]

The above is the worst-case scenario - there are not usually more than 4-5 mines on screen at any one time.

As you can probably also see, there is still no black bar at the top of the display. I can't quite work out how to enable/handle line interrupts from the VDP, but have found a nice part of the VRAM that isn't being written to that is just the right size for use as an alternate name table. The way this'll work is that I switch the background layer to another location in VRAM for which tiles to use that is all blacked out, wait until I hit a scanline 8 pixels down then switch back to the name table which contains my real background layer. I don't have to deal with cutting out any sprites as I have 8 sprites dedicated to the score at the top, and as you probably know by now from my constant moaning about it there is an 8-sprite-per-scanline limit hence my score will stop anything else from being drawn in the sprite layer at the top.

Finally, here's a picture of the biggest pest I know - linkified for the spider-haters. These buggers are not very large (5-8cms, biggest approaching 10cms) but very annoying - they seem to like following set paths, and will run around back and forth on the edge of my vision. This particular one was very reluctant to be picked up and lobbed out of the window...

I spent a while last night on a reusable routine to fade between two different palettes.

-> -> ->

It just happens to be one of the muckiest pieces of code written so far. You can see it in action in a video I've knocked together here (262KB). [I haven't put together a video for a while, so any old excuse, eh?]

I rejigged a few bits of the code, including neatening up the core sprite routines (so they are now much faster, huzzah!)

I ran a test on what it would look like if I added 8 "mines" (sprite limit and all that). The result? Sprite flicker is very very low! Looks like I'll be able to add the mines without issue...

These mines are rather evil. You get varying numbers of them, starting with very few in the early levels and going up to 8 in the later levels (well, as far as I've managed to get!). As enemies appear on screen they "lay" a trail of mines that drift towards you.

(Screenshot from BeebEm).

## VGM Player now works!

Lots of fixes...

- Fixed reading of files. I'd used 'char' instead of 'unsigned char'. Files
that played back as plain silence now play back fully, also play at correct
speed. What a stupid mistake - it's amazing it worked at all!
I ended up rewriting the entire PSG emulation thinking it was that that was
to blame... evidently not!
- Halved frequency of noise channel by only switching output once on 2 clocks.
It was an octave too high before!
- Fixed odd jumping/incorrect (after loop) seek bar.
- Changed [x] exit button to use 'x' character rather than the cross symbol -
the cross appeared as a "Pt" sign under Windows 2000.
- Removed display of Japanese tags.
- VGM files that loop back to the exact start of the file are now looped rather
than ignored.
- Added display of system name for noise mode and very stupid autodetection.
- Sound output is now averaged inside each 44100Hz sample to "antialias" the
output. Sound output that relies on channels at 0 outputting fully now work.
Sampled audio still sounds a bit noisy/weird. Sound is now output at 16-bit.
- Option to enable/disable sound channels individually.
- Accelerated seeking considerably.

## Scoring

Fixed drunk pilots. New algorithm is about 20 lines shorter, 10 times faster, 5 times simpler. Reason for drunk pilots: drunk coder. Implemented scoring, including: Variable points for shooting enemies. Variable points for shooting objects on the ground. Display of score at top of screen. Updated pause screen, all sprites now remain on-screen, background is less wavy. Trimming of enemy attack times so they follow on from eachother nice and quickly. Numerous minor bugfixes and tweaks.
The score might look nice there, but it really needs to be stuck on a background - any sprites trying to come in are cut off and look really odd popping into existance 8 pixels down from the top of the screen (8 sprite limit, and I have 8 digits in my score). For example, see this:

Look at the top - you can see the nose of a ship appearing, and it looks horribly wrong.

Drawing a black bar might be achieved by swapping name table addresses when I hit a certain scanline, but that's mucky and so far the best result has been 3 or 4 VRAM timing errors per frame and a jumping area of the screen that shows junk. Wonderful!

I also did some more work on my VGM player. It now emulates the PSG correctly! There is one problem still - playback of VGM files that have a specific delay specified. The default timings (1/50th second, 1/60th second) both work beautifully... *sighs* The others play waaaay too fast.
Thankfully, this affects very few VGM files I've tried it with. I also ripped out the tacky visualisations (it's now just a boring console app), improved the seeking code to be time rather than file position based (more accurate) and added support for VGZ files (GZipped-up VGMs) using ZLIB.
If you're in the mood for excellent chiptunes, download the above and the VGM pack to a classic Sega game from SMS Power! - I'm particularly fond of the music from "The Flash". (Ristar's music is also excellent). [smile]

## And now for something completely different

I felt like a different project for the evening, so started work on a console-based VGM player.

Click to download. [193KB] (Comes with a few sample tunes).
There are a number of (mainly minor) bugs listed in the readme.txt file, but it's not too shabby. It uses SDL to produce the sound (directly writing to the primary buffer). I'd be interested to hear any feedback!

Oh, Fire Track... Well, there's a rip of the BBC Micro version's in-game music (just recorded directly from an emulator, hence the sfx over the top) in the above zip file. Give that a listen!

## It works!

Fire Track II for TI-83 Plus: 31 source files.
Fire Track for the Sega Game Gear: 42 source files.
Based on this information alone, you can deduce that FTGG will be vastly superior. [wink]

I just gave FT2 a try in VTI (I don't have any batteries in my calculator) and good grief it's slow. FTGG is much much faster... (though you should see it go when I set the enemy speed to two... I need more accurate control of speed, 1 being medium-ish easy, 2 being nightmarishly impossible!)

This makes me happy.

Things to notice about the above screenshot: Near pixel-perfect parallax star background (you can see some through the bullet holes!) Not one single poorly timed VDP write.
This has required an enormous amount of code rewriting!
First to be fixed was the VDP timing. With a few .ifdefs, restructuring of the main loop and addition of an extra function call, all sprite data is now written to a shadow in RAM and then all sent to the VDP at once. This means that in sprite-intensive frames the framerate drops (it is unnoticable!) instead of the VDP going bonkers.

Next up, the pixel-perfection. I do not know if you know how difficult this is to do on this hardware (or, at least to a hack coder like myself), so I'll do my best to explain.

On a purely software-driven system, you can create a bitmask of your tiles so that when you manually blend your layers together you can cut out the stars you don't need. Or, you just draw them first then draw the tiles on top.

On more advanced hardware you can Z-order your polygons, so that's all done for you.

On the Game Gear, I have two layers - sprites and background. I can set individual background tiles to be on top of sprites - but this would dump a solid 8x8 square on top of everything. In other words, ALL the sprites are drawn under the background tiles marked as being on top. I had toyed with the idea of bizarre palette tricks and messing around with the tiles themselves, thinking sprites would be too slow (I asked about this on the SMS Power! boards - apparantly some games do the sprite trick, so I gained confidence in it).

What I need to do is this:
Take the (x,y) of my star and convert this into an offset into the VRAM name table. Look up the value of the tile at this value. If it is 0 (blank tile), draw the star. (Special case to skip expensive stage below) Look up the tile in a table of sprites marked as transparent. If it isn't listed, don't draw it. Take the offset into our table of transparent tiles, multiply it by 64, use that as an offset into another table. Find how far into the nearest tile as an (x,y) coordinate we are - that is, x is in the range 0-7 and y is also in the range 0-7 inside the current tile. Use this coordinate to look up inside our mask whether to draw the sprite or not.

There was an awful lot to go wrong and it did, often. [sad] It works pretty well now, so I'm happy with where it is. [smile]

The function to calculate the VRAM name table offset based on an X,Y on screen was broken. It needs to take into account the current vertical scroll, you see, to calculate the offset, so was essentially doing this to calculate which 8-pixel-tall row a pixel was in:

row_offset = (y/8) + (scroll_y/8)

(where y is the coordinate we pass to the function) - which leads to all sorts of rounding errors! The correct function is, of course:

row_offset = (y+scroll_y) / 8

Which, oddly enough, didn't seem to work at all well - at certain times, the values returned were completely off. The reason is simple enough - our scroll_y is a value between 0 and 223, and out y coordinate is anything between 16 and 160. 160+223=383 - you try storing that in an 8-bit register! So I updated the entire function to 16-bit code where needed.

Z80 ASM gurus - my old code to divide A by 8 was the simple:

srl a
srl a
srl a

For my divide-hl-by-8 function (srl [reg] is a sort of [reg]>>=1 function) I use this:

srl h
rr l
srl h
rr l
srl h
rr l

-- is this the fastest I could use? Is there a nice 16-bit shift operation available to me?

Next I had to generate the transparency data. I edited my tile editor - solid green &00FF00 is taken to mean "transparent!" It dumps a list of any tile with transparency, then an expanded 64-byte table of the mask (1 byte per pixel - horribly big, but much faster than packing it into a 1bpp mask).

When I say "near pixel-perfect", I have a problem - my stars are 2x2 pixels, and so if they can overlap the borders by a pixel or two from time to time. It doesn't look too bad, and in my defense the original Fire Track displayed stars over ANY black areas on the background at some points...

## Parallax

Here's a nice little graphical enhancement...

...and here's the video for it! (I disabled collision detection for that video, so no silly comments, alright? [wink])

Now, there's a little problem with this system - well, a number of problems. The worst is this:

Oh dear. I'm now writing to the sprite table when the display is active, which (understandably) it does not like. On the Game Gear hardware, you can see this in the vertical bar of flickering stars towards the left hand side of the screen. I am not sure how I shall fix this, but I'm hoping that altering the sprite drawing routines to write to a RAM shadow then dumping the entire RAM shadow in the frame is faster than my current method which is to manually draw the sprites in a number of different routines.

The next problem is the detection of when to show/hide stars. Currently, it only does this based on tile index - so only tiles marked as being 0 are "transparent" and enable the stars (they're being drawn as sprites). This leads to them vanishing a good distance away from the edge of land.

Finally, there's the even weirder issue where the stars move at almost the same rate as the landscape but are shifted in alternate frames. If a star is on the boundary between tiles, one frame it is over tile 0 so is shown, next it is over tile X so is hidden, and this oscillates. Hopefully by fixing up a pixel-perfect "show/hide" function, I can fix up this problem as showing and hiding would be about 4 pixels away from the boundaries.

I have also started work on "Segue", a simple music system for Game Gear games. I'll support instruments (they just modulate the amplitude of notes when they are played) that can be bound to the different channels. The song itself will be a list of instructions - "play this tone X on channel Y" (where X is the period of the tone), "delay for X frames", "assign instrument X to channel Y" - that sort of thing.

EDIT: This journal is now low-res non-horizontal-scrolling friendly. [wink]

## Title screen goodness

I spent some time yesterday doing some 'fun' work on Fire Track - that's not to say that the other stuff is not fun, but I find the graphics work less head-hurting than the programming work.

Hence the spiffy title screen above! It was fun trying to fit that into 16 colours and able to be broken down into 256 tiles, but with a bit of shuffling around it's a mere 254 tiles and the GIF exporter in Photoshop has done a great job dropping down the colours.
The display on the Game Gear blends adjacent pixels together very nicely - on hardware, the title looks pretty flash. (It's difficult to get a good picture of Game Gear - you try taking a photo of a TV set and you'll see what I mean! As clear and sharp as your TV looks out the photo will usually look washed out or fuzzy). See, here is a screenshot of the game running in an emulator:

Not quite so smooth, is it? (Not to mention it's a different aspect ratio!) Still, it's a little more colourful than the original:

(Mine is a cleaned up version of the box cover with the text redrawn.)

As you can imagine, a title screen such as the above takes up a lot of space. 254 8x8 tiles means 254*8=2032 rows of pixels, each row is made up of 4 bytes (four colour bitplanes) giving us 8128 bytes or 7.94KB. Seeing as the ROM I'm using is only 32KB, things are going to get tight - not to mention that even without the title picture I get the following:

Building... (Sega Game Gear)
Setting base location 'D:\My Documents\Game Gear\Dev\Fire Track\'
Running batch job '"D:\My Documents\Visual Studio Projects\Latenite\bin\compile\Sega Game Gear.bat" ftrack.z80 ftrack "D:\My Documents\Visual Studio Projects\Latenite\bin\compile"'
Build process complete!
Bank 00 has 03729 bytes (11.38%) free.
Free space at $0029-$0065.
Free space at $7191-$7fdf.
Free space at $7ff8-$7ff9.
Free space at $7ffc-$7ffe.
3729 unused bytes of total 32768.

Erk! That's not much room at all, and I still need more space for the music. I need to jump to using 2 ROM banks - that'd give me a healthier 64KB to work in, and 48KB of that is set up to be directly accessible without any paging as default. Or so it goes in theory, but WLA-DX's syntax for defining memory locations/ROM bank setup has me totally stumped. Looks like I'll need to pester the SMS Power! chaps again. [embarrass]

Anyway, what is going on in Fire Track itself? I did do some coding last night as well as slacking off with some image editing, and these features are now implemented:
Final attack pattern is in place - small ships appear then attack you by setting a direction when at a certain Y coordinate and just heading into you in a straight line. This is slightly buggy, some ships appear to have drunk pilots and veer off in completely the wrong location. Not sure why that is, but most seem to hit the target (read as: ME). Bugfixes/tweaks on a couple of the enemies. The ones that randomly drift towards you (the dumbell-shaped blockers and another formation) now only start drifting in X once they are on-screen, else they all appear on screen in a vertical column and it looks really silly. If you complete a level it doesn't just automatically jump to the next level, you lose control of your ship and it flies up and off the top of the screen. I shall probably also stop the end face from looping so that when you finish and have flown the background doesn't just disappear, it's as if you accelerate and it moves downwards off screen to the blackness of empty space. The sound! How could I forget that? It now works on volume rather than the hard-coded priority, and thus sounds very much better. (The loudest sound is the one that is played, as I can only set one period/amplitude as a sound effect at any one time). Fixed a bug on the title screen where sound channel #2 was not being set (channel #1 was set twice by accident).

Rather than just see a list of what's done, have a list of what is left to do as I am feeling generous. [wink]
Get ROM paging correctly up and running so I can dump more data onto a second 32KB ROM chip. Add sounds for me exploding (uses the noise channel so isn't just a case of adding a new sound effect). Adding the "mine" enemy. This is a small spiky blobby thingummy (technical term) that drifts in a straight line until it hits the edge of the screen, at which point it reappears at a random location and drifts in a new, random direction. If it hits you, of course, you lose. You can see it in this screenshot of the BBC Micro version:

It's the thing above the two lower explosions. Music. I need music. I also need a music system, so defining instruments (attack fade, play effect (vibrato?), release fade) and notes, as well as all sorts of other nasty music things. Scoring. Parallax stars? (Maybe, hopefully!) Lots of other things I must have forgotten.
Until next time! Incidentally, my journal is now listed as the News section on my website.

## Minor progress

I've spent the last few days up North for a cousin's wedding, so not much has gone on regarding Fire Track.
A few things have been added, though!
The sound is now "mixed" (for want of a better word) much better. It's still not perfect, and I'd like to see how it sounds when favouring amplitude over priority. That'll be my next tweak!

I have added the cheat screen (also useful for testing sound!) which will appear if you hold down certain keys as the game starts. There are a new set of enemies...

They just drift towards you - and you can't shoot them (they block bullets, though).

Also, the "final platform" for a few levels has been implemented. This is for the levels where you don't finish up with a face to shoot the eyes on, just a platform:

You need to drift past it to beat the level.
When you have finished the last level, the epilogue now plays too.

Through extensive testing (playing?) the original, I have worked out the purpose of the question mark blocks:

Shoot out a certain number and you get a funny noise and are awarded an extra life!

Motion blur filters are so cool. [smile]

## Bloop-bleep, it's the 80s!

Sound! I am still musicless, but never fear, for sound effects will fill the gap. Screenshots are pretty poor for sound [wink], 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:

[sad] 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]

## Old projects and ugly XP icons

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]

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
Do
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
Loop

' Get the details:

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

' Close the registry keys:

getDefaultIcon.Close()
searchKey.Close()

' 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)
Next

If iconPath.Replace("""", "").ToUpper.EndsWith(".ICO") Then
If UBound(getPlainIconDetails) 0 Then plainIconName &= getPlainIconDetails(UBound(getPlainIconDetails))
Else
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)
Else
iconPtr = New IntPtr(iconSmall)
End If

Dim iconRes As Icon = Icon.FromHandle(iconPtr)

Dim returnBitmap As Bitmap = iconRes.ToBitmap
iconRes.Dispose()
If iconLarge 0 Then DestroyIcon(iconLarge)
If iconSmall 0 Then DestroyIcon(iconSmall)
Return returnBitmap
Else
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.

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 config.inc 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]

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]

## On the merits of Excel and running out of space

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]

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] 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]
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]
In fact, Latenite is also my first app that needs a splash screen, it takes so long to get going... [sad] 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]

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 - 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]

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!

## Fire Track

When people ask, in the future, what the greatest feature of Fire Track is, they will not say the graphics. Nor the gameplay. In fact, they will... well, see for yourself. (Sorry, it's a bit quiet). [smile]
There is one more attack pattern. I have redesigned the attack system so that the enemies do NOT have their clocks auto-incremented (though they can call a function in their update code to do so if they really need it). This is so I can use the clock to store states instead. The new attackers slide in from the top-right, move down until they are level with the player then slide right again.
One peculiarity of gameplay in Fire Track is that you are permanently firing. You can never let go of the fire button. Also, the enemy ships do not fire at you - they just try to crash in to you.
I ran out of room. The game refused to compile. So, with a bit of tweaking in the map editor and a rewritten scrolling routine, I have doubled the amount of free space (without the music, about 10000 bytes are free). I'm using RLE compression on each 20 bytes of the level. If I get even tighter for space, I could probably pack the 8 bit level bytes into 6 bits.

Here's an awful sprite of an explosion. It looks really ropey, but it's as close as I can get to the authentic Fire Track (ship) explosions. I don't know how good it'll look in action!

## Enemies!

They claim a picture says a thousand words.
In this case, with these two pictures and one video [549 frames] I estimate that I have saved myself from having to write over half a million words in this journal entry.

There is, of course, the usual shonkily shot video footage to watch: 416KB AVI.
The collision rectangles need a little bit of fine-tuning and something better than just vanishing sprites needs to be implemented, but the modular and simple system is there.
Each level contains a pointer to an "attacks" table.
Each "attacks" table entry contains a $FF terminated list of attack patterns, in order. Each attack pattern specifies - Which sprite number to use. A pointer to the routine to call to initialise the enemy sprite locations. A pointer to the routine to call to move each enemy sprite each frame. An attack time. Each enemy is held in a table containing an X,Y coordinate and a "ticks" counter that is incremented each frame automatically. The "attack time" timer is primed and decremented each frame, and once it hits zero the system moves to the next attack pattern from the level's list. This means that I can have a number of different patterns. So far, I've implemented a simple sine-wave attack and an even simpler random-positions-and-drift-past attack (both from the original game), but some attacks are more complex, relating to paths or drifting towards the player. This system I have in place should make having a wide variety of different types of attack simple. I got so far, compiled, ran on my Game Gear and - oh dear. Lots of nasty name table corruption. To save space, I had decided to check the bullets against the enemy ships inside the sprite-writing routine, which was obviously too slow (much popping, pushing and use of the index registers) and as such the sprites were being written after the screen had started to be displayed. I have moved the code outside the loop and restructured parts of the code, but I hope that I have enough time/space to implement other things properly, without being restricted too badly by the low CPU speed. I'm not getting far with this elsewhere, so I'll ask here - anybody here with BBC Micro skills? I really need help with the music side of things - not so much writing a sound/music engine for the game, but more the actual "porting". The BBC Micro has the EXACT SAME PSG in it, so I could probably write a modification for a BBC emulator (BeebEm, for example, comes with source) which logged writes to the PSG hardware port (and time-since-start-of-program), but I'd still have the piou-piou-piou-skrrch sound effects over the top. Does anyone have a BBC Micro disk with a copy of the Fire Track music on it? I remember seeing/using music collection disks which featured game music on them a decade ago, and SOMEONE must have a "raw" copy of the Fire Track music (how else is there a recording in the STH archives?) but nobody on the STH fora seem to be able to or want to help. ## Finished the levels! Wahey! ...and here is level 6. This, however, worries me: Hopefully I can cram in all the rest of the code, tables, graphics and music into 5K. Failing that, I might have to start compressing my levels... I don't believe I've introduced you to my enemies yet? Here's the complete sprite table - don't worry, the letters P, A, U, S, E and D do not feature as enemy craft! I spent some time adding a new command systen to QuadPlayer, so you can now set a song to loop back X times (or infinitely) to a particular spot. It'll only loop from the end, sadly. Nested repeats will be too evil to try and implement. I'd like to experiment more with white noise - maybe a command to set up certain channels as being white noise rather than tones? Not sure how I'd generate the white noise, as the register R (which is the source of my random number generators) isn't going to be very random if accessed in a short loop! Sample song, from a Kirby game (I added the fade at the end manually, that's not produced by the calculator!) Not bad, seeing as it has been generated by a calculator with no proper sound hardware. [smile] ## Level table complete! This doesn't mean that all the levels are complete, though. I still have the 6th layout to copy. 1 to 5 are all converted, though: Level 1 Level 2 Level 3 Level 4 Level 5 Levels 1 to 4 you've seen before, but I've switched the palettes around to show you that it's not all magenta, blue and yellow. [smile] The levels take ages - about 2 hours each - to copy. I have a table of all the palettes, zone names and landscapes arranged. Now it's a case of adding enemies and scoring and it's pretty much finished - well, graphically and gameplay-wise. Music will be painfull. For those Z80 buffs, here's a question - I need a 16-bit CP instruction (between HL and DE would be ideal). For a simple equality test, I have: ld a,h cp d jr nz,+ ld a,l cp e jr nz,+ ; Code in here +: (which would beif (hl==de) { // Code in here } in a C-type language). However, I sometimes need to check the carry flag, so also have this: cp_hl_de: push hl scf ccf sbc hl,de pop hl ret It works, but is pretty hackish. Any ideas for a better routine? Finally, on a non-FT related note, I have fixed up QuadPlayer (see lower journal posts) so that it now plays songs held in the calculator's Flash ROM correctly. It's not being released just yet, as a chap bouncing ideas off me would like a "loop" function (which is only complicated in the sense that I don't want to break compatibility with old versions of the player, so that old songs play fine in the new player and new songs don't crash the old player). I feel obliged to add this feature as he has converted a NES song from a Kirby game to the QuadPlayer format and it sounds awesome. [grin] If you look at the MP3 files, please realise that more careful bit manipulation resulted in less "squelchy" sound, and the current release produces crystal-clear tones. [smile] Finally, this journal would not be complete without my latest Fire Track tile table: ## Starting to look a bit like a game! Jump straight in with the latest video (2.27AVI, MPEG-4) Apologies for quality/wonkiness. Well, we just had a weekend which meant I got a bit more time to spend on Fire Track (I have no social life whatsoever. Hooray). Last time I showed you the simple scrolling level. There is now: Player sprite. Bullets being fired by the player. Hit detection with the terrain below, swapping out hit blocks with "blown up" ground. Support for collision detection with 1x1, 2x1 and 2x2 "buildings" on grid. Eye-watering abuse of sine tables and vcount - yes, it's the pause screen. Simple animated title screen to mimic the BBC Micro title screen. 'Levels' table, telling the engine which landscape and palettes to use. Sprite helper functions reset_sprites, any number of calls to draw_sprite or draw_large_sprite finished with finish_sprites to handle writing to the sprite table. Four complete landscapes copied from the BBC Micro version, accomplished with a BBC Micro emulator, a tool to record an area of the screen to a GIF and a LOT of patience. Yet another revision of the background tiles. Upgraded support tools to allow for easy production of multiple level sets, minor bug fixes. Minor bugfixes and one new awesome feature to Latenite Z80 editor. Good grief, I need to get out more! First of all, the NEW AWESOME feature to Latenite. Actually, it's not that awesome, but I like it. Before, if you hit F5 or clicked 'Compile-[Target Platform]' it would compile the file open in the current tab. So, if you made a fix to scroll.asm you'd have to edit, swap to ftrack.z80, hit F5, swap back to scroll.asm and so on. URGH. Now, when you start a compile it goes through all the current loaded documents. If it encounters a file with the directive ;#latenite:main in it it assumes that that is your main source file and compiles that instead. Much tab clicking has been reduced! The bug fixes were in the support tools (wlaerr.exe and tasmerr.exe) to fix some of the broken line number reporting. The new tile set is this: One day I'll get 'em right. [grin] Anyhow, I thought I'd explain how Fire Track handles levels. What you do is play through a number of zones. Each zone is made up of a couple (or more) levels. For most of the levels, they end with a large block of terrain that looks a bit like a snarling alien face. Grrr. To move on to the next level, you must shoot out both eyes. (Of course, shoot all the other tiles around first to get more points). This same face loops around and around until you have shot out both eyes. At the end of each zone you don't get the face at the end of the level, you instead get the starting platform again and as it approaches you get a sort of rising scale until you pass it when you get a 'waaaouwaaaouwaaaou' from the amazing square-wave sound chip and the name of the next zone. Rinse, lather, repeat. The starting platform. Now, it would be crazy to store hundreds of levels on such a low end platform. It would also be crazy to have very few levels. So... why not swap the palette around? Yeah, that'll convince 'em that it's actually a different level. Hmm, maybe not. Well.. swapping somes of the tiles around from time to time? You know that sort of big ring, swap that for the asterisk-shaped block. Or that doughnut-with-a-plus-sign-through-it, swap that for the weird pyramid. Hmm, maybe not. The still might notice. Ah, here is the best solution - as well as switch palettes and a few tiles, let's make the levels we've already seen go past a bit faster. They won't notice then, will they? Oh, as a final touch, in some levels make the player and enemy sprites white and magenta rather than red and yellow. GENIUS. [smile] And so begins the tedious task of sitting through the BBC Micro game, noting which landscape, palette and tiles are in use. So far I have done four of the levels. My VB.NET editor dumps them out as .db lists for the assembler, but also as PNG files for the Ben. Here they are, GIFfed up and ready to go (note: they are very tall images, so make sure your browser doesn't scales them down too small to see!) Level 1 Level 2 Level 3 Level 4 (Remember that we start from the bottom of the levels and move upwards). The original level designer(s) have 'hidden' a number of patterns in the levels - can you spot the question mark (easy), Pac-Man (complete with pips, a fruit and ghost), a hungry-looking snake or the sad face (easy)? Stay tuned for more Where's Wally-styled fun as some of the other levels have such gems as the number 42 made up out of question marks (someone liked Mr. Adams, I'm guessing), a stealth bomber and a Yin-Yang. I guess these little things make up for the RSI-inducing copying over and adapting from Beeb to Game Gear... I am, at heart, a programmer so it is at this point that I need to muse on how I'm going to display the score on-screen. My idea was as follows: Wait for vblank signal. Jump screen scroll location to top-left of name table. Write out a completely black palette apart from colour #15 (the last one) which is white. Make sure that the score is displayed in the top-left of the name table (it is in the blank space to the left of the vertical scrolling block - see some of my earlier screenshots from the emulator). Wait for the vertical line counter to hit a point 8 pixels down the visible screen. Jump back the scrolling window to the "normal" position, write the normal full colour palette out. This works fine... in an emulator. On hardware it ends up frying the name table, so the data gets garbled beyond all recognition. ARGH! I've singled it down to aggressive reading of port$7E, the vertical line counter. However, my pause screen (which reads this port, uses it to look up a vertical shift from a sine table, sets the x-scroll from this value) is even more aggressive and works fine on hardware!
There seems to be a way to enable an interrupt to fire when the vertical line counter hits a particular line, but looking through documentation I have, I have found that information on this interrupt is:
Different in every document.
Confusingly phrased.
Not mentioned at all.
Oh dear. Commercial games use a similar trick (waiting for the vertical line counter to hit a certain point, then do crazy things with the scroll/palette) but I can't work out how to do it myself... [sad]
*shrugs*
I will keep you posted!

## Scrolling!

Fine progress! I fiddled a bit more last night with the scrolling background.

First of all, I really needed a better way to produce my maps and dump out my tiles, so wrote a custom VB.NET program that opens "tiles.gif", converts all the tiles in it (and produces a palette) then displays a map editor. This speeds things up a lot - all it needs is the tiles.gif file and nothing else. It also saves the current map in "map.dat" which it saves/loads when you close/open the program, so I don't have to reenter the map by hand each time. [smile]

You might also notice that I have altered some of the tiles and added a handful of new ones:

(Fear the evil magenta!)

Smooth scrolling backgrounds on the Game Gear are "easy" to do, thanks to hardware support!

What you have is a largish buffer to hold your map in. You can offset the smaller view window inside this by controlling VDP registers $08 (x) and$09 (y). For the y-scroll axis (the one I'm interested in) you can enter a value of 0 to 224. Unfortunately, a value of zero indicates that the view rectangle is centred and NOT at the top row - which requires some fudging. I need to calculate where in this larger "map" buffer I need to output my map data as I move the view rectangle around. If the y range started from 0 being the top row of the map buffer all would be much easier - the jump from 223 to 0 32 pixels down means that I need to handle the top few rows slightly differently, which is a bit of a bore. At least this isn't the curse of having to handle converting a screen (x,y) coordinate into a memory location on the VDP - but I'll have to do that at some point to handle swapping map tiles to holes where my bullets have destroyed some element on the landscape below. *shivers*
With a good deal of trial and error, I finally get my landscape to smoothly scroll past:

Now, something I learned is that the "corruption" in my tiles is not actually corruption at all. The Tiles window displays all the VRAM, including the names table (my map buffer). No wonder it "corrupts" when I write to the names table... *slaps forehead* Well, it works in an emulator... do I dare try it on hardware?
Of course I do.

Click to view in action (270KB AVI, MPEG4)

According to my Game Gear this was produced "Under License" from Sega Enterprises Ltd. I think not. [grin]
Unless, of course, it's referring to the BIOS my Game Gear has, and as far as I know all the BIOS does is display that one screen. Answers on the back of a postcard!

## Fire Track for the Sega Game Gear

I've decided that it's time to develop some Game Gear software. [smile]
I'm going to start with a conversion of the BBC Micro game "Fire Track" which I have previously converted to the TI-83 Plus graphing calculator. It's a simple vertically scrolling space-shooter.

I'll be developing in my own Latenite Z80 editor - by knocking out a few batch files, I'm ready to compile to SMS\GG compatible binaries.

One problem I have is remembering memory locations and port addresses, so I'm writing an include file (gamegear.inc) of the most useful values and routines.asm that will contain a bunch of core reusable routines.
Fire Track was all about superbly smooth scrolling backgrounds, so it makes sense to start this project by developing the scrolling background bit. However, to get anywhere with that I'll need some background tiles to work with - fortunately, I've got my 8x8 background tiles from my TI-83 Plus version. Sadly, they were in black and white so I had to colour them in and tidy them up a bit:

When developing for the TI-83 Plus, memory is a prime concern so I had to keep the number of tiles down. With the Game Gear version, I can hopefully expand the number of tiles, and maybe even make them more... colourful. [rolleyes] Fire Track only had two levels that it repeated, one after another, with a simple palette switch and more enemies to make them "different". In my Fire Track 2 I made it randomly generate levels from a series of "chunks", so I'll probably implement that here.
A very simple program was written to initialise the VDP (video display processor), copy over the pallete and tile data and display all the tiles one after another. The result:

The "tilemap" screen shows the displayed tilemap (by changing VDP registers I can set the position of that clipping rectangle). The top-left screen is what the player would see, the top-right screen is the tile memory. The black shapes just under half way down are NOT intentional, and every test program I have written that writes to the "names" buffer (the area that indicates which tile to display on the grid - a sort of map) corrupts that area. In the emulator it doesn't make much difference, but on hardware it completely fudges everything else.
Ah yes, hardware. How can I test this on a real Game Gear?
First I need a working Game Gear. Cue two half-broken consoles, a screwdriver and some rearrangement:

...and I have one working Game Gear and one completely buggered one. [grin]
I'm using Tototek's GGPro cart to test on hardware.

Using a fairly odd piece of Windows software and a bit of fiddling in the BIOS you can send Game Gear ROMs to the cartridge. It even supports multiple ROMs (it adds a nifty little boot menu). Anyway, in this case I'm only really interested in "ftrack.gg" - and here we go:

Magic! Well, it doesn't appear to do much, I'll give you that. But it works...

## ASCII Madness II and Tutorials

Well, it's been a long time - here are two updates in one!

First up, ASCII Madness II. It's a text-mode scene demo that runs in the Windows console using characters from the extended ASCII set to produce the effects.
You can download it (and the source) from here.

Next up are some simple tutorials. Oldschool graphics stuff, I'm afraid, but hopefully someone will find them of interest. [smile] They are presented in the form that I would have liked to have read... and I know that I'm not very conventional in my learning style.
I'd be interested to see if the demo apps (blobs, tunnel) work fine - I've had one complaint that they can't find a particular DLL, which is a bit odd.

## QuadPlayer - four channel sound from a TI-83 Plus

No longer are we limited to two channels of sound, but here we have access to four!

If you have a TI-83 Plus calculator, there's a preliminary release here - and if you don't, some zipped up MP3 recordings here.

(Topic on MaxCoderz).

## Z80 ASM and PICAXE

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:

Clicky

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.