Sunday, 28 February 2021

2021: a space invaders odyssey

 Yes, it's been a while. A long while.

It's occurred to me recently that over the last several months I've been wasting an inordinate amount of time reading group posts on social media and scouring ads for retro games, and I figured I'd be much better off wasting that time working on Retro Ports.

And so I'm intending to attempt another resurrection of my retro development projects. Whilst I'm keen to get started on something new, I'm (again) going to try to finish off a few of my pending projects.

First cab off the rank is Space Invaders on the CoCo3; get that fully playable with or without sound.

Then I'll look at bringing Asteroids (again, CoCo3) up to speed with so-called pre-compiled sprites.

And I should release the full versions of Lode Runner and Championship Lode Runner on the CoCo3.

That leaves another couple of Asteroids ports (Apple IIc/IIGS and a TBA platform) and of course Donkey Kong on the Neo Geo which I last working on in 2013...

New (porting) projects under consideration include Karateka, Prince of Persia and Xevious, though I also have a few FPGA projects that need some updating on MiSTer, including the Irem M62 hardware amongst others.

But I'd better not get ahead of myself... stay tuned.

Thursday, 9 July 2020

Shelter in place!

The shields are now rendered in the correct location on the screen. As planned, the code now buffers the complete 512-byte area of the screen containing the shields. So whilst the rendering into the buffer is now more complicated, the save/restore is a simple block copy. This is in contrast with the original code.

However, now I'm not 100% sure that this won't cause graphical glitches if there's another object (eg player laser) in the shield area when the player is hit. In theory the laser will be saved and restored and become another 'shield'. Which means I would need to store a copy of the virgin shields as a mask... arghh...

This is getting more complicated than I ever thought it would be.

I've also introduced a few more graphical glitches, most notably in the explosions, which I simply cannot explain from merely updating the shield rendering at all.

But with the shields done now, I think all that remains is to review dead code, revisit all the alignment issues (absolute locations on the screen) and then fix the graphical glitches one-by-one. Once all that's complete, all that remains is to reposition the score (and credit text if required) and maybe then think about adding some rudimentary sound.

Until next time...

Wednesday, 1 July 2020

Shielding you from the ugly truth

I've rotated the shields and have them rendered on the screen...

Shield locations are only approximate at this point

... but, and it's a pretty big but at this point, not accurately. The locations are only approximate atm, off by progressively a few (more) pixels for each shield left-to-right. But it's a good start.

The shields have quite 'inconvenient' dimensions and spacing; 22 pixels across and spaced 23 pixels apart. Not an issue on a vertical monitor but after rotating, the rendering obviously needs to progressively shift each shield by 5 bits (22+23/8 = 5r5).

The shields are actually rendered into a RAM buffer at the start of each wave and then block-copied to/from the screen at the start/end of the player's turn. Thus each player's shields are saved and then subsequently restored during a 2-player game.

Because RAM is limited on the original hardware, shields are 'packed' together in the buffer without any intervening empty space. Each player's buffer is 22*2*4 = 176 bytes.

Already simply rotating the shields requires 3*16*4 = 192 bytes, which is too big for the existing player data structure. So I've had to move that just to get this far.

Given this, and the fact that I have plenty of RAM to play with, the easiest solution would be to buffer the entire 16 rows of the video memory for each player, ie. 16*32 = 512 bytes. And since the save/restore is only done between plays, the slight difference in execution speed will be of absolutely no consequence.

So this is my next task.

Thursday, 11 June 2020

Less magic, more explosions!

Not much time to work on it as I have a sneaking suspicion that getting Space Inavders working on the CoCo3 is pretty low on my employer's priority list.

Fixed the player explosion, UFO explosion and the UFO score when hit.

A number of 'magic numbers' in the disassembly have been fixed, including instances in both code and data. In order to get things working properly I've also had to ensure certain groups of data structures - such as various tables for the UFO - don't span 256-byte boundaries.

Getting closer now to finishing the coding, mainly shields. Then I'll be moving onto optimising and cleaning up (removing old and duplicate code) before debugging and tweaking alignment. The most obvious glitch is hitting an alien just as they're dropping down and not erasing it.

Tuesday, 9 June 2020

Things are about to explode!

Two very brief sessions over the last few days.

Player lasers and alien explosions are all-but-fixed now. I've realised that I need to go back and review all the reference points used for the rotation again. But it's something I'll leave until all the rendering routines at least look correct, even if there are some minor alignment issues.

I've also been able to re-use some of the object-specific rendering routines for multiple objects, so I'll have to go back and rename some of them at least.

The game is playable now, albeit with occasional graphics glitches. The oustanding issues are UFO explosion, player explosion and invader bomb explosion (hitting shields and/or bottom of the screen). And shield orientation of course.

I would hope to have these issues sorted by the end of the week, though it depends on work/family/exercise/sleep commitments.

Saturday, 6 June 2020

This is Da bomb!!!

Unexpectedly got a bit more time tonight to work on Space Invaders.

Started to look at the invader bomb rendering code. The routine that renders a bomb also checks for collision with other objects; namely shields and player laser base. I decided to concentrate on the rendering for now and worry about collisions later.

Turns out what I had already coded was only missing a single instruction once I added the requisite bomb sprite data. But the invaders would drop a bomb, it would animate correctly for the 4 different frames in the table, then produce garbage. And then they'd stop dropping bombs. It was time to examine the logic beyond the rendering routine.

Ahh, "magic numbers". Not Tomohiro Nishikado's fault of course, but rather that of the person reverse-engineering the code, though perhaps Tomohiro doesn't get away completely unscathed because he does make an assumption about tables not spanning 256-byte boundaries.

In order to save space and time, several data structures store the LSB of the last entry in a table. And in several places, the code compares that value with a hard-coded value to determine if the end of a table has been reached. So when rotating the graphics data and hence shifting data structures throughout memory, those hard-coded values are invariably then incorrect. Oops. The fix of course was to use the label of the table and appropriate arithmetic to calculate the LSB at assembly time.

And as mentioned, in a couple of instances (other) tables were traversed and reset using arithmetic on the LSB only, which obviously worked for the original code as-is but again, after rotating graphics, some of those tables actually spanned a 256-byte boundary and things subsequently went haywire. Fortunately I have copious amounts of memory on the CoCo3 and aligning those tables was trouble-free.

Incidentally during this process I found a minor bug in my original transcode; I was only displaying 3 of the 4 frames of animation for the "squiggly" bomb.

Once all that was sorted, the bombs pretty much worked correctly. I say "pretty much" at this point because there do seem to be times when an inordinate number of "squiggly" bombs are being dropped, and no others. That doesn't appear to happen on the arcade game under MAME. So I need to do further testing on that.

Explosions are a bit messy, but bombs seem to work now!

Now I mentioned that I hadn't taken any notice of the collision logic. So I was somewhat surpised when I was hit by an invader bomb and duly exploded! The shields are similarly damaged, though I haven't visited the explosion routine(s) yet; something I'd negelected to mention in previous posts. As you can see, they currently wreak havoc on the graphics below the laser base.

I'll probably tackle them next, before moving on to player lasers.

Friday, 5 June 2020

Unidentified Fixed Object!

Not a lot of time to work on it today so a quick update - UFO fixed!

The UFO sprite has 4 blank pixels on each side in order to self-erase when flying across the top of the screen, for a total of 24 pixels across. However, when displayed in the score advance table, the code points to the 5th pixel and only draws 16 pixels.

As a result, I had to separately rotate and store both 16- and 24-bit versions of the sprite. The former is rendered by the generic simple (aligned) sprite routine, the latter by a (new) routine to display a 24-pixel sprite.

UFO is rendered correctly now. Getting closer!
Bombs and lasers next!