Klass Of '99 - Spectrum Conversion.
So many years late... and still not finished!
Yes, it's a crazy idea, but it just might work! I intend to code this entirely from scratch in Z80 assembly, I do not plan to nick bits from the Spectrum versions of Skool Daze and Bak 2 Skool.... The initial target machine is the Spectrum 128K. The completion date is unknown, but it's not likely to be in 1999 (not now). Well, obviously not! How's this for a vague release date: "before the Dolphin gets released". (Obviously written a very long time ago).
The game was started on the 1st of November (1999), although some tile and sprite routines had been worked on before (but they needed major modifications afterwards).
I had thought that "it would all be over by Christmas", but it's hard to judge the duration of a project that you've never tried before and I do bits on my emulators as well.
Oh yes, and I couldn't think of a decent background picture for this page.
The 30th anniversary of the ZX Spectrum! Sadly, I have nothing new for you. However, I will release my ancient and terribly slow work-in-progress version. I strongly recommend you use an emulator that can increase the emulated CPU speed of the Spectrum by 3 or 4 times to get the smooth experience.
Most of the playable aspects are there, only the range-based lines checking is missing, so you can get lines for leaving early and hitting a teacher with a catapult, but not for punching anyone (for example). The one tune playing is courtesy of Gasman.
KO99 W.I.P. (very slow): KO99WIP.ZIP
The speed is improving... slowly. It runs tolerably in 7 Mhz (needs a bit more for lovely smoothness), so I just need to get it to run twice as fast. What is odd is that the background stuff is taking too long by itself, let alone the points where you have to write a lot of updates to the screen.
I'm not sure how I did it, but I've managed to make it as slow as a flight simulator. I've freed about 1K and slightly increased the speed, but I don't have as much time to work on it at the moment.
Debugging nearly finished. Every gameplay aspect works, every speech bubble, blackboard, pickup, lights, shields, doors, timetable, renaming and other options. They all work. The only bit missing is code to draw sprites during scrolling and the renaming screen as well as the miscellaneous "region detection" lines, mainly down to memory. I'm down to 9.2K remaining out of the 128K. The biggest chunk is 4.3K, but it isn't in the main RAM... Mind you, that is with none of the bitmaps, no music and no sound! What a big game.
It is still running very slowly, but I can now start to think about optimisation (both speed and size).
Endless debugging... The game can now be played, to a degree. No terminals yet and the speed is... terminal. All the AI code is converted, which just leaves some of the lines code and sprite updating during scrolling to convert. Still a small mountain of debugging to go, then I can get onto optimisation.
A small selection of screens.
No new screenshots yet. The main loop runs, but goes rather slowly. A lot of AI converted, but still quite a bit to go. So much code! I had to use a bit of X128 debugging through DOSBox, as I could set up logging from a specific point rather more easily, very handy.
First screenshot of any note! It gets to the opening game screen but no further. The sprite is wrong, but I haven't set any of them up properly. Endless picky little bugs fixed to reach this point. If I can get the main loop to survive, then I can move onto including all the AI stubs. No indication of speed yet, probably slow and needing optimisation.
I'm currently using Spin for debugging. When I started this game I was using Win'98 first edition, so running X128 on the command line was no problem. Now, not so good... Win'XP and having to use a Windows app. for emulation. The debugger is fiddly, but it'll have to do (doesn't support PASMO labels) - I really can't be bothered writing my own.
First game screen.
Still going... got some of the front end running. Memory getting used up at a frightening rate and I've been forced to eat into bank 7, which I was hoping to leave free until the very end. It does make me wonder if I'll be able to fit the bitmaps and music in at all...
Well, I will not make any promises. Conversion to Z80 is going slowly and unsteadily. Anyone still willing to help convert the bitmaps will be gratefully welcomed!
I'll celebrate moving to a new ISP by updating the info here.
I've converted a huge chunk of the code to Z80, but I'm down to about 384 bytes in the main RAM area and will probably need to convert another 4K before it's all done and debugging/optimisation can begin, so some stuff will have to be squeezed and placed into other banks. Nothing is showing up yet as I've just been converting the code en-masse without testing. You may think that is a bad idea, but... erm... trust me!
Due to the chronic lack of RAM space, it's looking increasingly like the static bitmaps won't fit (especially in the 9.25K buffer I set aside), although I still have 16K allocated for the music/sfx but have no idea how much it will really take up as... it's not been done yet...
The intense period of work lasted longer than I expected!
I've done a lot of Z80 converting now, but still nowhere near finishing the vast amount of screen code, let alone any of the game code. I've already filled up most of bank 5 and practically all of bank 2... Some code has already been moved into bank 0. Banks 1, 3 and 4 were straight data conversions, so it's quite big already but nothing is on-screen yet.
Beta-testing showed few major bugs, so I decided to go ahead with the Z80 conversion, but then some work got in the way. Rest assured that I will be working on it when I find the time.
I think I've finally managed to finish all the "lines" code. No more receiving lines through walls either!
There's still the known bug where anyone can potentially get stuck on the stairs when time advances, I haven't been able to track it down yet.
I also had a go at compressing the 6 screens into 16K, but it didn't fit using my run-length / tile system. That's a bad sign, as most of the pictures are empty just now!
I've not been able to update this website for a while, as Orange had somehow made it so that I couldn't connect to the ftp site, but it's fixed now.
The prototype is now rather more advanced and approaching beta testing. Most gameplay things are implemented and I'm working on the options screen. I still have to do some of the lines code, but that will be going in near the end.
I hope the prototype will be ready by the end of this month, so I've set up a small number of testers. However, anyone who knows the original inside-out is welcome to join in.
Another year dawns for KO99!
I've been fixing little bits and pieces, as usual, and have now implemented the "leaving early" scenario (along with the 2,000 lines) as well as completing the "Eric hit me" and "Eric isn't here" situations.
More of the same, I'm still cleaning up the little bugs. I did look at the scrolling and I came back to the question that I've been wondering about for a while... KO99-style (1/2 at a time) scrolling or Skool Daze-style (1/4 at a time) scrolling?
Well, it's certainly hard getting back into this. I've fixed a few minor bits & pieces, but not really touched upon any big issues yet. I tried to speed up the writing on the board and it fell apart! I had to reinstate every single line, the balance between script & AI is very delicate. Anyway, some progress is always good.
I've got back into looking at the code. Ouch. There's a lot done, but a lot still to do. I'm just touching little bits and pieces around the edges while I try to figure out what's happening in the code.
One thing I did was add a 32-frame crystal animation, only to find that I only had space for 8 more sprites... It's all coming back to me now!
My goal is to try and complete the C prototype by February.
I've received the "Completed" tune from Matthew Westcott. That's four overall now and they're very nice.
I never did get around to putting up that screenshot... May as well do it now, seeing as there is a KO99 thread on WOS at the moment.
A little bit of news, Tommy has provided the title/loading screen. I will put up the screenshot later.
Slow progress, but a lot of the tasks have been done. The Q & A sessions, "Eric hit me", "Eric isn't here", George opening and closing the door, George going to his own room and most of the assembly. I've also guessed the starting positions for each character at the start of the day.
Regarding speed, I had a go and I think that the catapult bolt goes at frame rate/1, while the characters move between frame rate/2 to frame rate/4. This would likely require a frame rate twice as fast as I was planning though...
The lines "area" looks roughly 10 chars wide, as can be seen in the dinner hall.
I've finally written a simple task parser, so I'm starting to see some results (it would be far too awkward to figure out all the jumps by hand). Teachers and pupils can now be easily ordered to go to classes and go through the routine without any additional work on my part (until I change it so that the Einstein Q&A session is included).
There are two clear problems though. First of all, determining when (in the original) the timings for "area-based lines infractions" occur. Secondly, how fast each character moves...
Time for some screenshots:
Classes in action.
Again, the need for a good artist is shown clearly!
I've now created a decent front end loop (with palette fades) that can process the day-to-day flow of the game. Also, I've spent time watching the original to figure out the duration of each event in the game and to figure out where the random walking points are (I think I have them all now). I've also noticed that different teachers watch over the dinner halls on different days. There's no point in posting a new screenshot just now, I'll leave that for another day.
Another big step: darkness! The eyes are all sprites, while the red colour is provided by some tiles written underneath the big eyes. This meant that I had to move my AI loop before the displaying of the background and the sprites, hopefully that won't cause any problems...
Additionally, a DOSBOX bug means that I have to run it through DOS4GW (instead of PMODEW) in order to grab my screenshots!
Now for some bad news. It sounds like my artist has dropped out, leaving me with 6 bitmaps needing to be converted and a big font needing to be tidied up.
The text table is now nearly 13K, as I find other strings that weren't included in the original gametext.txt, like: "Turn to page 1XX and start reading."
I've now fixed up the panel to include all features required (hopefully) and added some code to write the letter in the safe, which works quite well. I also had a bit of a struggle to get the big font working (I admit that I don't know if I'll have room for the 3.5K required). It clearly needs tidied up for the monochrome world, but that's up to the artist... I'll show it displayed here along with the old "fail" screen, which will also be updated by the artist... Tommy...? Where are you?
The first time that the big font worked.
I'm now working on making the string table. This should allow for easier translation into other languages, should the need ever arise. I have found that the text strings will take up at least 11K, so it looks like it will get a bank to itself.
This has made me look into the memory usage of the game, by combining the information from the previous attempt with the current attempt:
So there you go - it will truly be a 128K game!
From previous experience, I know that the Code & Data will fill up the 32K of banks 2 & 0 and will spill into bank 5 as well. The sprite and tile banks are fairly well established (about 14K each) and the string bank will be at least 11K.
The unquantified items have space allocated for them, but will they fit? 16K for the music was always a rough guess (raw note data from the original XM is already more than 16K) and 9.25K for the 6 compressed bitmaps is rather tight (although, they do look as if they will have lots of "open space" in them). There may be some free space in bank 5, but it cannot be guaranteed. There may be a need to use some free "bits and pieces" in various other banks.
The other information in the table relates to the issue of "contention" in the RAM (which slows it down at certain times). The contended banks are different depending upon the Spectrum model (no contention at all for the Pentagon). This makes me wonder whether I should make it load speed-conscience items into different banks depending on the model used?
Finally, KO99 is a really annoying game when it comes to on-screen priorities. The terminal appears above everything on-screen... except for the lines boxes. I currently have the lines boxes appearing underneath the terminal and I may decide just to leave it like that.
It returns! I'm giving it one final go, this time I'm writing it in C using an emulated screen and taking into account my experience of the first attempt on the Spectrum. You may wonder why? It's because writing "finite" things like sprite routines (and so on) is easy enough under assembly, but more variable things like gameplay (that require frequent changes to get right) is easier to do in C.
Afterwards, I'll convert it to Z80 and the Spectrum version will be created.
There are clearly two problems with the C method, namely that it is hard to work out the code speed and the code size upon conversion. Hopefully, experience of the first attempt and experience of the Glove conversion (Tandy CoCo 2) will help prevent problems.
Now, I did say that I would give up entirely (and release what I'd done) if I hadn't finished by the end of 2005. Well, in my defence, no one will learn much from the source code due to the mess created by the limitations of using TASM (Table Assembler) and of having to split things up into separate pages. I'll have to keep my word at some point though...
The next version will use PASMO as the assembler and I'll use tools in a slightly more sensible manner. So far, I have received three tunes in Spectrum SoundTracker format. No new graphics yet, but I have changed the window colours...
Initial "Lines Box" and multiple speech bubbles.
Another year passes! And so on...
I made a pledge earlier in the year to have one last go or give up completely. To prepare for this, I have delegated some tasks. Tommy "Sadako" Pereira is working on the static screens and Matthew Westcott is working on the AY conversion of the original music.
Another year passes! I've been extremely busy, so I've had no time to work on this. Well, I have had the odd hour to spare, but that's mostly been used up by Fire & Ice recently... Still, just thought I'd say that I haven't cancelled it yet. This is one of those projects that I'd like to get out of the way, so that I can start looking at new things.
I actually played the notorious Spectrum version of Salamander to avoid working on this!!! Fortunately, the immunity poke on The Tipshop was broken (it doesn't give immunity from backgrounds or bullets, just baddies) which meant that I could only play it for about one minute.
My mouse is also half-broken, it has a wobbly wire which (amongst other things) can cause the mouse pointer to shoot up to the top-right of the screen and register a left mouse button click...
I've done some task list code, which should allow me to do some of the game mechanics much more easily than just embedding events into animation sequences.
Here's the first example, a bunch of kids are told to go and sit down, so they start at the back and try each chair until they've found a space. But I've asked six of them to sit on five chairs, so one is left constantly wandering up and down. (Naturally I chose the one with the darkest background, so you can't see a thing).
The two sets of numbers on screen are a symptom of my modified scroll routine. It now uses LDI/LDD and scrolls 64 pixels instead of 128, so it's a lot more like the Spectrum originals. (I absolutely had to do something to get the scrolling speed up). It does leave a nasty line at the side of the screen though.
Yet another uneventful image.
Took my first look at doing an "uber task list" and uploaded this page which has the 08/11 update on it...
I've also been playing the Abe's Escape conversion, which is excellent fun! I'm still missing 11 Mudokans though.
These days, my inbox seems to be clogged with "undelivered" emails from viruses on other peoples machines (I hope!)...
I had a little peek at it again. I've (finally) fixed the "dirty" blit to only update the necessary parts of the screen, which speeds it up a bit (doesn't fix the slow scrolling though and I can't get a proper screen grab of it). I also fixed part of the 4 pixel problem (broken animation frames), but more still needs to be fixed (which I didn't feel like doing). This has to be the first time I've ever hoovered rather than do more work on a piece of software!
This is clearly a game caught in development hell...
Just a little update here, I've not worked on it since March. Since 06/03, I finished off all the terminal bits and started working on one of the tricky bits - getting the sprites to move in four pixels steps (rather than eight). And there it stopped, half-working...
Oh that terminal... I cleared 1K, added all the appropriate tiles and now I only have 36 bytes left in the tile bank! Anyway, the main point of this update is to show the amazing terminal game "Mega Blaster" running on a Spectrum within a Spectrum! I made the terminal the full text width of the original, but this practically negates the need to update the sprites at the sides and covers up the number of lines (or where they will go eventually)... Judging by the pace of Mega Blaster, the whole game engine definitely needs to be about twice as fast (and I must stop those shields popping up at awkward moments!).
I didn't expect that I'd get to implement this, the terminal has always been listed as one of the "likely losses" (near the bottom of the page), now it's just a matter of slogging through to add the other screens and get them functioning.
My first ever Spectrum game!
I've mostly made things more efficient, so it goes a little bit faster - still needs a fair bit of optimising though. I've also attempted to make the terminal an interactive item, but I have to (somehow) clear about 1K off the tile page in order to fit all the Spectrum chars and the pre-shifted terminal game characters in (urg) before I can do it.
Anyway, the teachers can now wipe that filth off the board!
Chalk dust gets in your lungs...
Putting text on the panel has been one of the things I've been avoiding for ages. Also, one of the real pains (that ached in my mind in '99, while I was thinking about how far there was still to go) was the list of destinations, classes, etc... I've fixed part of that, so it's now possible to figure out where each character should be during class times (break times are another matter entirely...) and generate the appropriate text string for it - which subsequently gets printed to the panel!
I hadn't even calculated how wide the widest string would be, when I was designing the squashed version of the panel, but fortunately it was about 141 pixels and the panel had 160 pixels of space.
Another thing to note about the picture, is that I've gone and stuck everyone in the game. That's 34 people altogether and when they're all on screen at the same time - it slows down a bit... to about 4 frames per second. I'm sure there'll be a few things I can do to speed it up.
I've also finally updated the broken link to the original PC KO99 webpage...
Clearer than a tannoy...
Fed up with the slow progress with the in-game art, I decided to work on the code again. Mostly restructuring, to allow the adding of new features easily (or at all). Some code is finally being moved below 32768, but memory's still as tight as usual.
The positives are that I can have more objects in the game (but still only 20), Eric can drop crystals (but they don't have their effect yet), Albert's active and he can open/close the doors now.
Must redo the speech bubble code a bit, it's really slow.
Let me in!
Oh well, plenty of time to work on it now... :(
I've tentatively started working on the in-between-game screens, it's just as slow a process as when I worked on the 'fail' screen 7 months ago. (Brown next to orange - how much harder can you get?!) I could be lazy and just use BMP2SCR's monochrome conversion instead... Anyway, this one was the easiest:
Not that I can be bothered aligning it properly...
I see I got a miniscule mention in "Retro", where this is described as a "noble yet insane cause". I find it hard to disagree... Thanks to Jof for the mag.
Additionally, got mentioned in Lee's PeeknPoke website. Thanks guys! Inspired by your "Gob", I may put up a page which lists my teenage programming atrocities (thankfully, some of the most embarrassing examples got overwritten with music when I loaned a tape to a friend).
Behold the non-working terminal... It's a 100% accurate simulation if your keyboard membrane is broken. It's not actually wide enough to hold the text that the original game does, so I'll make it a bit wider.
Getting it there was difficult (naturally) as everything about coding this game is incredibly difficult. I had to clear some structures from the tile bank into low uncontended memory, in order to fit the terminal characters in... and instantly that area was full up as well! It's not that I'm anywhere near using up 128K, it's just that the useful areas keep filling up, making reshuffling necessary.
Yet another thing to slow the sprite routine down.
Two-and-a-half years later... What can I say that hasn't already been said before? Answer: Loads, because this is the least discussed project in existence (even when it was going quite well).
I see that there's a GBA version of KO99 and the author got to see the original source code - lucky for some!
The main things that have got me looking at this again are:
I've managed to get it to compile again. That's all! I've spent a week converting one of the screens (the "failed" screen) into something that the Spectrum can display, but even now it's still not finished. I can see how people are tempted to use BMP2SCR or just have everything in monochrome.
Yuck! This needs a lot of work.
I've been thinking about how to get this thing moving faster and without glitches. Blitting the full screen wastes up to two frames (I guess) as you have to let the scanline pass you before you start to copy anything. That probably makes the absolute fastest a game could run would be 1/4 (gameloops/frames) and that would only be in the best possible scenario. KO99 uses a very large number of sprites and is bound to slow to a crawl when they all get displayed, so I could use the 128K's second screen by writing directly to the non-displayed one. It means that it would take longer to write to the buffer (contended memory) but would save all that blit time. The main annoyance would be rearranging all the code so that the graphics and graphic-related code were below 49152, but while still keeping as much of it as possible in uncontended memory.... This would also eliminate any (remote) prospect of a 48K version.
I've also been thinking about a fancy tape loader for it, which is conclusive proof that my mind is drifting again.
Since these pages now show up in search engines, I've been receiving some spam, so I've spam-blocked the email addresses shown on these pages...
All progress halted due to work commitments. In this case, I hope I'll be able to resolve this.
Ah! Actually (sort of) kept my word! It's not easy to read, even with the variable width font squeezing as many letters in as possible, so a few changes will be required, but will I go as far as making the speech bubbles even wider?
Mr Wacker finally makes a speech, but Eric's attention span is so short that he can't even remember the start of the word.
Took a break! Modified the blackboard code (in the way described earlier) and will write the new speech bubble code today. Honest. Hmm....
I've also taken an indepth look into the XM format and I believe I've found the note data, this might lead to the music being converted from the PC original.
Finally rewrote the sprite routine, it's a little bit faster (still some scope for optimisation) but the main benefit is the extra memory available in the 32768-49151 region. This has allowed me to move the 1536 byte tile map there, which frees up space in the background graphics page. It also allows me to align more items on a 256 byte boundary. As the sprites are now "tiled" the sprites now take up 10K (+3K of lists) instead of 28K, this has freed up RAM page 3 completely.
Bombs can now be picked up, the key can be picked up, the crystal now appears in the box and can be picked up. I've changed the scrolling to move 16 pixels at a time, but it doesn't look very nice.
I will now be avoiding the rewriting of the variable width font routine, so that it modifies tiles, which would result in less overhead for the blackboards and would finally allow (da-da) the speech bubbles.
Time for some pictures:
A very big key. Almost knee height.
A crystal. In the box. Amazing. Yes.
Eric can't resist picking up a Malteser...
But I think they should recall this batch...
Some minor bomb details - collision detection working for people and safe. Still trying to avoid rewriting that sprite routine... A little difficulty - only 79 bytes left in my background graphics page.
I've added the green box, which does almost everything it needs (check for key, check for jump co-ords, open animation). Some aspects of the little bomb have been implemented, you can drop it and it explodes, although there is no co-ordinate checking so it just gets everyone. The safe opens, but no letter is revealed.
The scoreboard icons (bomb, key and crystal) now work. Underneath all this the "dirty bit" principle has been put in place, in preparation for the new sprite routine... which I've been avoiding up until now because I'll have to modify my sprite grabbing tool to put the sprites into their new format, generate tables and check for duplication.
As I said before, I was going to do the scoreboard so that each shield lit up every time you hit it's respective shield in the game. Additionally, you can see how the scoreboard has not degraded well to two colours and half it's size. You may also notice the 'items' boxes, the bit where the number of lines goes and (if you look very carefully) some darkened teachers heads, ready to light up and reveal a letter (when I've coded that bit). Although I'll probably just replace their heads with the letters, because I think I'll need those two lines above them for the class/room text.
Unfortunately, the background is now taking up 15800 bytes! I'm going to have to compress the tile map soon.
Now, for the first time on any Spectrum - It's Mr. Carter!
When a catapult bolt goes up - a shield must come down. Which leaves Eric facing murder charges...
And - Mr. Blessed!
Eric fires the new Russian/Chinese missile using the door frame as a hiding place.
I've finally got back in the mood, so it's all tiled. The doors now work (opened and closed via keypresses just now), the sprites walk underneath the door frames and we have.... shields! All 15 shields can be hit using the jump or catapult bouncing techniques and they drop! For testing purposes, Mr Carter and Mr Blessed now walk back and forth underneath the shields that require catapult bouncing.
There is a downside... scrolling is now agonisingly slow (as opposed to slow). The overhead of processing all those tiles causes the problem, although having to put them in contended memory (until I "tile" the sprites) doesn't help.
My next task is to implement the scoreboard so that the shields light up as you hit each one. Early attempts have shown that it doesn't look very good when you squash it to half it's height and 4/5ths of it's width.
I've done a lot of graphic conversion and coded a number of features but, due to the size of the task in hand, it's still nowhere near finished. I'd better explain that the coloured border is showing the cpu usage (about 800%) in some pictures and that the blit is not particularly good, leading to some tearing.
Eric jumps for no reason at all. Meanwhile, Mr Wacker has just walked past a big mincer.
Eric becomes an attention seeker.
Eric thought he saw 50p....
Eric bounces a catapult bolt off Mr Jackson's head.
Eric takes a seat.
Eric doesn't realise where that floor's been....
Eric tries to write "VARIABLE WIDTH FONT" on the blackboard, but the key response is so bad that he gets angry and writes a load of rubbish instead.
An evil robot starts writing on the board... Or is it Mr Jackson?
As well as a destination system, a partial waypoint system and an animation system that can trigger events at specific points within an animation.
Mr Wacker's attempt at making a speech is frustrated by the fact that I haven't actually written the speech bubble code yet...
Some substantial changes have taken place. The PC game runs in a 320x240 resolution, with the school being 192 pixels tall and the status bar being 48 pixels tall. Obviously it wouldn't fit into the Spectrum's 256x192, so the school has been reduced to 168 pixels tall with a 24 pixel tall status bar.
The sprites are AND/XOR masks in exactly the same style as the original Spectrum games, so purists need not worry. Actually, purists might worry a little bit, the perspective is slightly different in this game and combined with the squash in the Y-resolution, this has resulted in a clear perspective error with the chairs (but still, not too bad).
The sprites are currently moving 8 pixels at a time (instead of 4). I had been hoping that I could pre-shift them and they would still remain within a 24x32 grid, but....
The sprite routine also has X-flipping to keep memory requirements down.
XOR sprites were rejected (due to the messy effect) and full colour sprites were rejected because they only really work with big, square graphics.
One obvious problem is how I will manage to display all those sprites quickly enough. Answer.... don't know! I'll have to experiment, but I hope there won't be too many empty seats.
Other likely losses:
Fancy Things That I Really Shouldn't Be Thinking About Just Now.
Rich J., the author of the original PC version of Klass Of '99, is supporting me with advice, graphics and details. Although when he says "no source code", he means it (whenever I ask)! Webpage of the original .
(Please remove the CORNEDBEEF to reply).
(C) James McKay, 2012.