Saturday 14 November 2009

Move, Thy Spritely Sprites!

Well, after another long hiatus (working on my Forth project, which is nearly finished, but not quite) I find I'm drifting back to this one. I tend to do that. This has partly been prompted by a certain Owen Brand, an very enthusiastic and loyal TI user who runs a kicking little web site, here all dedicated to things TI. He was rather taken by this project, and has posted some videos of the current state of Manic Miner on the TI to The Tube. I'll post the links when I can actually get onto YouTube. It's blocked from where I am. Anyway, this is his YouTube channel, where you will find lots of TI related videos.

So, what do I have in store for you this time? Not an awful lot. I've mostly been reading my code to familiarise myself with it again. It's been a while since I looked at it. Now, dear reader, I don't know if you are an assembly coder or not (it seems to be a dying art these days, it's all C, C++ or Java - does nobody like to get down and dirty with the hardware anymore? 'Yall should try Forth. It's kind of like dirty sex, without the damp bits).

Well, I don't know about you guys, but I comment my assembly code a LOT. Every single line has a comment*. The idea is, in two years time, the comments will tell me what my code does (and others). Well, despite my copious comments, reading my code back has still led to a few "what idiot wrote this?" moments. It's so depressing when I realise it was me! Closer inspection however usually reveals that I was right the first time. Doing it a certain way saves a register, or maybe a shorter op-code (faster), so sometimes the code looks a little contrived (for example taking a hit early on to set things up using lots of registers, meaning I can use indirect addressing later and take advantage of both the extra speed and shorter op-codes).

The game engine itself (partly written) is all hooked on the video interrupt. There are 60 interrupts a second on the NTSC consoles, and 50 on the PAL (European) consoles. So all the interrupt code is written to be as short as possible. Get in, do the job, and get out.

The level renderer (the code that sets up the graphics for each screen and draws the level) is not interrupt based. I believe the ZX Spectrum version re-draws the entire screen every frame - there's no need to do that on the TI - we have sprites which are independent of the background, so the animation (sprites) won't disturb anything underneath.

Currently (IIRC) the game engine is logically divided into 12 frames. I call different parts of the 'total job' on different frames. For example, on every frame:
  • Decrement portal flash delay counter (the portal is the exit to the next level)
  • Service speech synthesizer (which may immediately return if there is no work to do)
  • Decrement the air delay counter
  • Decrement animation counter for the 'life sprites' (indicates how many lives remain)
Then, on frames 0 and 5 I:
  • Cycle the key colours
  • Animate the conveyors (if required)
  • Do guardian animation
So, I should should still have frames (say 2 and 8) available to:
  • Read the keyboard/joystick
  • Animate Willy (Miner Willy, our hero)
When I get around to it!
The guardian animation is a separate engine in its own right. It's just called by the ISR (interrupt service routine) every six frames, and does a different amount of work each time, depending on which guardian(s) need to be moved. Basically it works by decrementing counters. There are counters for:
  • Movement frequency (how often to physically move on the screen)
  • X upper extent (how far to the right the guardian can move)
  • X lower extent (how far to the left to guardian can move)
  • Y upper extent (how far up the screen)
  • Y lower extent (how far down the screen)
When the current X and/or Y position of the guardian is equal to an extent, its appropriate delta value is inverted (in this case, the delta is how many pixels to move at a time). Thus the guardian changes direction, until it gets to the opposite extent. Then of course, it switches direction again.

That's the plan anyway! I'm just about to start putting the code together. The nice thing about coding a generic engine is (of course) it only has to be done the once. Then each level just has some data to initialise each guardians start positions, colour, animation frame index, x and deltas and extents. Simples!

We'll see how it shakes out. I'll probably code the engine so that it's 'intelligent' in terms of writing to VDP ram. Makes the engine a bit more complex, but it not write to VDP unless there is something to write - saving a time penalty (VDP on the TI is a IO device, you write to it through a 3 byte window - it's not part of the CPUs memory space).

Stay tuned. When I get level 1 (Central Cavern), and level 2 (the cold room) animating, I reckon I will have cracked the animation engine.

There are a couple of exception cases (the Kong levels for examine, and Eugene's lair) which do special things when all the keys on a level have been collected. I'll look at that when I get to it!



* except comments. Comments don't have comments. That would be really silly.

Thursday 26 February 2009

Code is therapy...


As alluded to in earlier posts, the graphic data is laregely done, say, 90% percent complete.

Being a bit of a sadist, I decided I couldn't be bothered writing code on the ZX Spectrum to rip the graphics. I've put this down to three reasons:
  • I'm thoroughly lazy
  • I'm not clever enough to do that on the speccy
  • I'm thoroughly lazy
It would be "much easier"* I thought, to write my own sprite editor and just draw the grahics on the screen. I suppose it was "easy" but it was very time-consuming. Still, writing the editor was interesting: I wrote a version first in Extended Basic which worked fine, and was much faster than similar programs I had seen running in Extended Basic, through the use of a few cunning tricks.

Of course, it would be much better if I wrote it in C. Why would it be better? Well, you know, because it would! I therefore determined I would re-write a perfectly working and fully functional peice of code in C**, "because I could". Still, the finished result (youtube video below) was pretty nice, in a retro-uber-geek-this-guy-should-get-out-more kind of way.

So, that was the graphics done, and imported into my source files. What next?

Well, I decided to just dive right in and start the code to define the graphics for each level:

For those that aren't in the know, the video memory on the TI-99/4A (or indeed any machine using the TMS9919 video graphics processor) is seperate from the CPU memory. The chip has a two text modes (1:32x24, 16 colours 2:40 x 24, 1 colour) and a bitmap mode. As a remarkable stroke of luck, the screen resolution is exactly the same as the ZX Spectrum: 256 x 192 pixels.

Now, the ZX spectrum screen is bitmapped only - there are no text modes. However, the spectrum's video memory is normal CPU addressable memory, so access to it is very fast. Access to the TI's video memory is through memory mapped IO: two addresses, one for reading, one for writing. A third address allows you to set up the VDP address that you are interested in, and after that, subsequent accesses will auto-increment the address for you. Nice.

Well, after a lot of thought, I determined that the 32x24 pattern mode would be fine for my needs. There are 256 definable characters, and after analysing every level using JSWED, I determined that every level would fit.

In pattern mode, the 256 ASCII character set is further subdivided into sets of 8 characters. Each set may have one forground and one background colour, thus careful planning is required to group your characters according to the colour attributes required. This took a few evenings of chin scratching. Excel to the rescue: I built a spreadsheet to work out the character assignments.

I now knew exactly which ASCII characters would hold which definitions on each level. For simplicity of code, all common objects occupy the same characters between levels (walls, floor, keys, doors, conveyors etc) only their colours and actualy graphical definitions change between levels.





* Feel free to laugh
** What's wrong with me?

Still bubbling away...

Well, it's been a while since I last posted to this blog, so I thought it high time I posted an update. You could be forgiven for thinking that no progress has been made, or indeed that development on the project has ceased. However, you'd be wrong!

Nay my friends, I have been having a veritable code frenzy of Manic Miner-ness. Part of the reason for the massive delay has been due to me making a very serious mistake. Some time ago, a discussion at work about programming languages led me to declare to all that would listen that Forth was, and I quote: "Shit". I then went on a rant about how unreadable it was, and that it was stupid because everything was written 'backwards'.

"Oh" said my colleagues, in a "there-must-be-more-to-life-than-this" type of way.

A few hours later, guilt somewhat got the better of me. I mean, there I was telling everyone how crap Forth was, and the truth was that I actually knew *nothing* about it. I mean, totally and completely bugger all. As a result, I determined I would learn a little bit about the language, just, you know, so I could blast it a bit more and really sound like I knew what I was talking about when I told everyone how crap it was.

Trouble is, it's not rubbish. It's actually amazing. Brilliant. Perhaps the most simple, beautiful language I have ever seen. When I finally got the Interpreted Threaded Code concept, and how code was compiled, I was simply hooked. I simply had to have a go at it. So, I somewhat naively launched into writing my own Forth engine in 9900 assembly (you know, as you do). I even invested in some old books. You'll be glad to know (though not half as glad as me) that the code written so far works, and is very fast. It runs Forth code just fine. I've just got to finish the command line interpreter and fully test all the words and it will be maybe 98% finished (just block commands to finish).

So, that's the reason for the delay. I spent days and days coding my Forth engine, and totally left Manic Miner to languish. A poor show.

Accept, it's not really a poor show is it? One of the cool things about coding in your own time is that you get to work on the things you want to work on when you want to work on them. Coding up the graphics for Manic Miner was such a large job, including coding up my own sprite editor and animator, that it sapped my energy and enthusiasm for while, only to be replaced with Forth.

A few weeks ago, I decided to revisit the code I had done for Manic Miner to 'remind' myself of how it all worked, only to find that there wasn't really any code at all - just lots of data, so I thought I would spend an evening or two putting some code together to test my data. You know, as you do... That was probably over a month ago, and an awful lot of progress has been made. In the next few posts I'll summarise where I am with the code so far. Stay tuned!

Sunday 29 June 2008

Code Orgy

Well, today has been a long day. I was hoping to go home for the weekend and spend some time with my family, but alas, it was not to be.

So, in a bit of a sulk, I decided to sulk in a corner and finish getting the data files written. I didn't realise it would take me 14 hours. Cue major league sulk! :-)

I now have 20 files, one for each level containing:
  • Sprite frames for monsters
  • Speech data
  • Level name
  • Character set colours for the character sets (the 9929 video processor divides the ASCII set up into groups of 8 characters, each group can have different foreground and background colours)
The character sets on the 9929 make it a pain to organise which characters (having the same colour attributes) should be grouped together, nevertheless it is done now.

In addition, an additional file holds the 8x8 character graphics used on the levels - the graphics are re-used quite a bit on different levels, so rather than re-define the same graphics time after time, I've just defined them once. Each level then consists of a table of pointers that point to appropriate places to take the data from. Much more economical. I was going to use the sprite editor that I wrote to do the Manic Miner sprites to do the 8x8 graphics, but in the end I just used JSWED to display the characters in a grid, and worked out the hex in my head by eye (if that makes sense). Geeky? Yes. Fun? Er, no, not really!

Finally, for a bit of fun (!), I managed to get the ZX Spectrum character set out of the ZX ROM, so I've created a data file for that also - so the game should play with the real Sinclair character set.

Next step: screen layout for the levels. I'm thinking RLE (run-length encoding) is probably the best way to go, economical without trying to be too clever.

I think tomorrow I'll cut my first lines of code, instead of working with purely (boring) graphic data.

Funky.

Thursday 26 June 2008

Sprites

Concentrating on getting the sprites done. Most of the sprites in Manic Miner have 8 frame animation sequences. I've been concentrating on getting these captured.

I've been using JSWED (Jet Set Willy Editor, a great PC program) to display the sprites using JSWED's built in sprite editor. Then, I recreate them 'on the TI' (which is actually running in an emulator, called Win994a) using a sprite editor that I have written in C, pretty much for this project, although I have released the sprite editor to the public, with source.

Here's a video of it in action:



Using this program, I can recreate each frame, and animate them to check they look ok. The program then saves them to 'disk' for me in HEX, the easiest and 'standard' format in the TI world for dealing with sprite graphics. Makes it very easy to import the sprite definitions into assembly source code files.

I guess I could have just taken a Manic Miner Z80 snapshot file and written a bit of C or .Net to find the sprites and extract them, but somehow, that takes the fun out of it! it's far more 'fun' to write an sprite editor in C first, even before you start your main project!

Even worse than that, I wrote version 1 of the sprite editor in TI Extended Basic. Yeah, yeah, I know, I know!

Mark.

Sunday 22 June 2008

Greets

For a while now I've had a burning desire to do a version of Manic Miner on the TI-99/4A. There is clearly some masochistic kink in my personality which leads me to do these non-trivial, yet pretty much pointless things.

Then again, why do people climb mountains? For the view? I don't think so. To prove to others that they can do it? Well, I guess there's some of that. But I think most mountain climbers climb simply to prove to themselves that they can do it. I think this is the case with me and this project.

As with most things, I mull these things over in my mind for a long while before I start them. A sort of mental 'batch-job' runs, steadily gathering data over a long period of time, and one day, completely unexpectedly you understand, the batch-job completes and either returns true, or false. In this particular case, the job returned true.

Shit.

So, this blog (I hate blogs. I mean, how sad are blogs? Haven't people got more interesting things to do? I mean get a life for God's sake. Er, yes. Right) will detail the travails of my effort to re-produce Manic Miner on the TI-99/4A. It will also serve as a bloody useful reminder to me about how the code works as it becomes more complex!

For anyone that's interested, the TI-99/4A was produced in the early 80's by Texas Instruments. A 16 bit machine with powerful graphics and sound (for the time) features, including 32 hardware sprites.

Manic Miner was written by a 16 year old in Liverpool by the name of Matthew Smith, who, rather inexplicably it would appear, had no interest in either Dire Straits or girls (I know, I know, go figure) for the Sinclair ZX Spectrum. The game, a platform game, has garnered legendary cult status*, particularly in Britain, where it sold by the shed load.

Both machines hold fond places in my heart. The TI-99/4A was purchased for me by my step father, who, tired of pulling me out of the local supermarket to come and eat dinner (I was in the computer section of our local Co-Op writing code on the Spectrum's, Vic 20's, C64's, Orics etc and generally trying to teach myself about them) had noticed my fascination, and decided that he ought to encourage this, as 'computers will be the future'.

This would have been 1983. The year TI ceased making the machine. Thatchers Britain, in 1983 was a pretty grim place. The Falklands war had just ended, miners strike about to kick off (IIRC), and three million un-employed. Including my step-father. Despite this, he scrimped, saved, and did odd-jobs to get enough money together to buy a £199 TI-99/4A. We spent hours and hours and hours and hours in front of that machine (plugged into the living-room telly) typing in games from magazines and changing them to see how they worked. Happy days. I learned a lot about BASIC programming.

The 4A was/is a great machine, but it just didn't do well in the UK. The home computer wars were about to kick off, and TI just didn't do a good job of promoting it in the UK. It had a number of problems. The closed architecture of the machines meant it was impossible to harness the power of the machine without the hideously-expensive (and weighty) Peripheral Expansion Box, and it got left behind by the ZX Spectrum and Commodore machine that gave full access to the casual user of all the machines resources. Also, the game cartridges for the 4A, although generally excellent (my school mates sat in awe at Parsec and Alpiner) they required the selling of a body organ, or a short stint dealing in contra-band or arms running to purchase them.

My step-father flogged the TI. Shit. What was I going to do now? My mates had Spectrums, ZX81's, Vics, C64s, and the only thing I had now was a shitty old Philips Videopac (although I wish I still had it!). This was a bad day. He apologised for selling the TI, but said when he had some more money, he'd buy me another computer. Yeah, right.

Christmas 1984. My step-father had got a job as a care-taker at a local shopping mall in Shrewsbury, Shropshire. Things were looking up. On that Christmas morning, I ripped the paper off an innocuous looking box to reveal a shiny new Sinclair ZX Spectrum 48K.

And it was all mine.

Oh joy of joys. Now I could join the computer elite at school. No longer on the fringes. Instead of listening to my friends tales of rubber-keyed fetishism, I could be one of them. Anyway, sod all that, it meant I could swap cassettes with them on the play ground (we had an Amstrad TS88 tower system that was perfect for tape-to-tape copying!)

The TI was forgotten. I had a Speccy. It didn't get any better than this. I learned BASIC on it, Z80 on it, and played one or two (million) games on it. Bliss.

For some bizarre reason that I'm not really aware of, I bought another TI-99/4A. It would have been around 1998. I can't even remember how or from whom I got the machine. But I stuck with it. I liked using it. I joined the TI UK user group, and started reading TI*MES, their monthly magazine. Before I knew it, I was writing my own articles for the magazine. Oh the fame.

After a getting a full expansion system and tons of software, I eventually sold the lot circa 1997 after buying a PC. A completely dumb move that I've regretted ever since. I had tons of really cool hardware, Ramdisks, the lot. What a twonk.

About three years ago, I re-discovered the TI for the third time via the beauty of emulation. I now get my TI fix via Classic99 and Win994A. The ultimate portable TI. (I also have ZX32, a great Speccy emulator!)

Since then I've been writing assembly language, dabbling here and there. But this is it. The real deal. A big project.

Will I pull it off (ooer, missus, oooh matron etc)? Who knows, stay tuned and find out.

It could be a wild ride, there again it could be like a Sunday drive in a Trabant: A lot of noise, without really going anywhere... Time will tell...

Mark.

* and then some