Saturday, October 14, 2006

XeO3: The Big Sqeeze!

Well, there comes a time in every project where all you seem to do is try and get a few bytes of memory back. It's usually a slow, grueling process where you look through virtually every line of code for the odd byte that you can save, and hope its enough. XeO3 has hit this point. Since I started doing the loading, I thought it was about time I did a front end, but before I did that, I needed memory - a lot more memory. My current code budget had around 300 bytes left which isn't enough to make toast, never mind a front end. The data block still has around 1k left so the first thing to do is try and merge them. This means rearanging the whole of memory to try and pack free areas together. Never fun.

Certain areas must still sit on certain boundarys (character sets, screens etc.) but the rest is free game. I've managed to move the data down by moving the sprites and character sets up, and the character animation down. So the current memory map looks like this:-


$0800-$17ff 2 Screens
$1800-$27ff Music (4K)
$2800-$65ff Game Code and DATA (15872 bytes)
$6600-$67ff Character bitmap animations
$6800-$77ff Game charactermap (double buffered) (4K)
$7800-$97ff Sprite graphics (167 16x16's) (8K)
$9800-$9fff Barrel shifter for sprite caching system (MCM version)
$a000-$a2ff Panel Character Set (95 chars + space)
$a300-$aea7 Level Data-13 screens (7*13 - 3x3=91*13=$49F, 200 3x3 blocks=$708) ($ba7)
$aea8-$aeff Spare (88 bytes)
$af00-$bfff PATH data... (4k+256 bytes)
$c000-$efeb 141 pre-rotations... ($2feb - 141*87)
$f000-$f578 ScrollBuffer
$f5a2-$f5ef Sprite address table (built at runtime)
$f6f0-$fd00 Spare.... (1.5k)
$fd00-$ffff IO/Hardware/Vectors


I moved the fixed table of sprite addresses out of the data area and into a bit of free space right at the top of memory, but instead of a table, I build it with a little code at runtime. This keeps the EXE down and saves loading diddy little tables. I also stripped out the last bits of the save/replace sprite system (it's still there, just commented out) which freed up a little more space.

So all in all I now have 2,721 bytes left. Still not a lot... Now it gets tricky....

XeO3: Turbo.

I've been looking at turbo loaders today, since we hope to include at least a basic one. We simply don't have space to put one in the code, but since I don't use any RAM below $0800, if we find one or two that sit below there, then we should be able to use them. To this end I've been doing a basic game loader. It install's FLoad, and then loads the game - pretty simple stuff. Its a shame it switches off the screen, but thats a small price to pay I guess. Luca has said that its a little unreliable, but until I find one as small then I'm stuck with it. Since it installs itself prior to the game, any turbo loader should work - or none! So if you have problems, you should be able to skip the loader and load the game directly. Well, thats the plan. If anyone knows of any turbo loader that resides completely under $800, then please point me to it. I'd also like to have a few loaders for different drives if possible - but they must all follow the <$0800 rule.

I've also found my beloved C16 Rom disassembly book which went missing for a while, so I'm pleased to see its return. Its got a great hardware register map, and all the 6502 instructions with timings - all in a neat little book. I bought it back in 86 and it helped me code Freek Out, start Minus4 (all versions!) and now XeO3. I'm also in backup mode just now. Its been a while since I did a proper backup, so Im busy burning a few disks of all the important stuff - although I have copies on my server anyway.

Oh...and to top all this off, my 1581 drive has started whistling when it spins, and suddenly changed from device 8 to 10 for no reason I can figure. Not good.

XeO3: Alien Bullets

I've sped up the alien bullet's a little using the same trick I used for the software sprites. Whenever a bullet is over space (character $00) I don't bother masking, I just copy the character data in. If I had another 4 characters spare, I would just poke a character on screen, which would mean that 70% of the time it would be as fast as it used to be. But this way, its still about double the speed. Heres the code for the normal masking of a bullet.


BullGFX1:
lda (Temp+10),y ; Get data from character we're
and #$0f ; about to overwrite, and mask it.
ora #$a0 ; now OR in the bullet graphic
sta (Temp+12),y ; and store into its new bitmap
iny ; and move on....
lda (Temp+10),y
and #$0f
ora #$d0
sta (Temp+12),y
iny
lda (Temp+10),y
and #$0f
ora #$b0
sta (Temp+12),y
iny
lda (Temp+10),y
and #$0f
ora #$a0
sta (Temp+12),y
iny
lda (Temp+10),y ; Since the bullet is only 4 high, we can
sta (Temp+12),y ; just copy the remaining lines.
iny
lda (Temp+10),y
sta (Temp+12),y
iny
lda (Temp+10),y
sta (Temp+12),y
iny
lda (Temp+10),y
sta (Temp+12),y
jmp RetMaskBull


Now this is pretty quick anyway. I have 4 routines like that to deal with the bullet in each of its positions (since a bullet takes up a quarter of a character, it can be in 4 places in a character). But the masking and copying still takes time. So heres what happens when I detect the bullet is over a space character.


BullGFX1_2:
lda #$a0 ; Get graphic data
sta (Temp+12),y ; Store in bitmap
iny ; move to next line
lda #$d0
sta (Temp+12),y
iny
lda #$b0
sta (Temp+12),y
iny
lda #$a0
sta (Temp+12),y
iny
lda #0 ; Since we know we are over a space, we can
sta (Temp+12),y ; just force in zero's all the time.
iny
sta (Temp+12),y
iny
sta (Temp+12),y
iny
sta (Temp+12),y
jmp RetMaskBull


This function should be the case most of the time, and help balance out the game and make it a bit more even. The faster routine's only added around 170 bytes to the code, so its well worth doing. Overall, the new bullet's take around 450 bytes extra of code - quite a lot, but worth it for the results it gives. There is always the chance that all the Aliens are over the background and so are all the bullets and this would cause the game to slow down. However, since we script the baddie movement, and can place the turrets where we like, we can simply design it all so that this worst case never happens, and you never experiance it. The only thing we can't design around is the player movement, and firing of his own weapons - we just have to leave as much CPU time as possible for that.

Friday, October 13, 2006

XeO3: Turrets Attack!!


What a night! I've spent the remainder of the night trying out a solution to alien bullets. There are up to 8 alien bullets at any given time and all they do is pick one of four characters and poke it to the character map screen. Now while this is fast, it does mean that theres usualyl a big black box around them. However since we dropped the turret rubble we freed up 4 more characters so I though I'd try doing actual sprite bullets - well, masking them on at least. I expected them to look pretty, but ultimately be too slow to use. The result is shown in the circle opposite. Much nicer than the big black box.

I got a nice surprise, because while expensive, it wasn't unmanageable! Even with a whole heap flying around it only takes around 8-16 scanlines tops. This is great! What it means is that where we WANT lots of turrets, we'll simply cut down a little on the number of sprites to compensate; and where we want lots or sprite, cut down on the turrets. If we had both, it would probably be too hard anyway!

Great stuff!

XeO3: Background Collisions!


Well, I decided tonight was the night. I was going to do the background collision detection. I've been thinking about it for a while and I'm finally happy with the method I've chosen. The problem you see is that I dont have anywhere near the CPU time left to do pixel-perfect collision. This is in fact, like drawing another sprite; and even if I had the CPU time to do that, I'd still rather draw another sprite!

So we're stuck with detecting characters under the player. This is nice in that its very quick, but bad because its terribly crude! If you look at the image shown, number 1 shows the sprite sitting in its 3x3 character block. Now although it's only a 16x16 sprite (2x2 characters), the sprite has to scroll through these to move around - such is the lot of a software sprite. Now, looking at image 2, you can see that if the sprite has move say 4 pixels along, and 4 down we are now sitting right back smack in the middle of a 3x3. So the question becomes - what do you hit?

If we were to simple use ANY chars from the 3x3, then you could be a whole character away, and still get hit. This isn't good. But, if you use a 2x2, then by the time the sprite has scrolled 8 pixels along, and 8 down, then we again are hitting the block above this time, but we aren't actually anywhere near it! It would also mean we could go completely into the block below, and not get hit! Neither of these is desirable.

The solution? Well, looking at image 3 - we'll only deal with Y movement for now. if we move 3 pixels down, what we'll actually do is use the TOP 2x2 (as shown in image 4), then if we move past that and go 4 or more down, we'll switch and start using the lower characters (as shown in the final image). We then apply the same theory to the X coordinate - simple!

This actually works out great! It gives us a natural 4 pixel boundary around the ship where we can "edge" into a block without getting hit, and it keeps us from hitting things miles away! All in all, a pretty nice solution.

So, the big question! What does this mean for the game? Well, the game's a foot...and pretty smelly too! You now have to avoid being hit by aliens, the turrets now shoot at you - and hit! - and you now have to move around the scenery! All we really need to do now, is add all the baddies in Luca's been working on, and do the weapon systems!

Thursday, October 12, 2006

XeO3: Don't bug me now....

Spent a little time fixing a couple of minor bugs.

The first happens when sprites cross stars - they disapear as though the sprites wheren't masked at all. Odd, because I spent some time making sure the stars would show correctly behind the sprites. I remember this because of the optimisation I did to the sprites where if the character its about to overdraw is $00, it doesn't "mask" it in, it copies it. This was quite a saving and it does 9 of these checks per sprite. Now since the stars are basically characters, I made a choice and accepted the slow down invloved. It would have been quicker for have the stars vanish. Anyway, after shuffling code around trying to figure out what the hell was going on, I discovered that it was indeed a simple bug. The stars were being drawn to the wrong screen. They got drawn to the front buffer, and not the back one. The reason it didn't look terrible is because the stars check to see that theres nothing there before they draw themselves - this is simply so that they'll draw behind the scrolling back ground. Anyway, I changed it to the backbuffer and PING! all is well.

The second was obviously a simple one. once you shot a baddie, he sometimes drops a coin. If you pick up this coin, you get money. However, if you then shoot the space where the coind was, the bullet hit something. Obviously, the coin wasn't as dead as I thought. Turns out when adding the NOSHOOT flag, I'd tried to optimise the bullet collision, and it hadn't worked. It could have, if I'd set that flag on every dead baddie - but I dont want to, so the extra check for it actually being active has to go back in.

Oh well... couple of minor fixes today only... Still, its good to get these things found before any games players find them and complain!

Oh, and with Russell deciding to do a spectrum version, Retro Edit has become even more important...*sigh*... so much for my idea of a simple tool to do the job. This means I'll have to do hires editing, and a spectrum tile editor. Russell has a lot of restrictions for his tiles, so a custom editor is needed. At least the sprite editor will be simpler, but it does mean I've to do it properly and do MCM with bit patterns rather than just numbers - bah!

XeO3: Play the game....

An interesting topic has come up on Lemon64; since this isn't a normal game that is going out to the public but more a game for the scene, should we automatically add cheat modes ourselves, and then every couple of months release a new code for say better weapons, money, shields, infinite lives etc.

Or should we do a normal game and let it get hacked live every other game does?

Wednesday, October 11, 2006

XeO3: And then there were 3.....

It seems like there may be another member of the XeO3 family! Russell Kay (author of PC Lemmings) who I currently sit beside at work and harass like a badger with a sore bum, has been persuaded to have a play with some old spectrum stuff again. He has actually written a spectrum game years and years ago called Zone Trooper . It wasn't wonderful, but he was just doing a port so it's not his fault, the code however was fab, and he did love the old speccy. So now, he's back - at least for a while - to have a play at doing a spectrum version of XeO3. Great Stuff!! Could it be the first multi-platform games release on the +4, C64 and Spectrum in well over 10 years?? Time will tell....

So, after that great news....I've nothing much to report. I've had an evening off and sat down and watched a film. I have imported the Plus/4 colour map into the editor and tomorrow I hope to start making the editor more usable - rather than just an animation tool. Still I'm a little sort on energy, so I think its an early night.

So...nothing done and it's STILL been a great night for XeO3 news!!

Tuesday, October 10, 2006

XeO3: Retro Edit


After talking to Luca, I feel somewhat ashamed. He described the process he uses for creating sprites and it was so bad, I was virtually blushing. I am now even more amazed at the superb animations he's manahed to create despite the terrible tools he's using. So, I've vowed to correct this as fast as I can. To this end, I've changed the focus of the editor, it really will now become a Jack of all trades. I'll do +4 sprite editing first, then add C64 editing so that I can get those streachy sprites, and then onto character and tile map editing and so on.

However,m before anyof that, I need to get Luca some tools he not only could use, but really wants to use. The problem with any developer is that we get so used to using our old tools that we just don't want to change, so I need to give him a tool that feels like his old slippers, buthas a whole new set of features that empower him.

The first on the list was loading in the current sprites and then being able to play back certain animations in various modes. This is now done. He can now scroll through the whole set, pick start and end frames, then play them back forward, backwards and in "pingpong" mode (where it bounces back and forth). This should at least allow him easier viewing until I can actually get editing and saving in place.

In the future, I think a realtime linkup with an actual machine would be very cool, as the anim plays on the PC, it also plays on your Plus/4 or C64 on the Tv... also theres no reason why when you plot a pixel on the PC you dont SEE that on the actual machine as well. I wonder how many people would use that......

Monday, October 09, 2006

XeO3: Editor


I've managed to get the Plus/4 sprites up and visible which is fine - fairly easy in C#, so next I'll need to get them scaling. I'll probably change a couple of bits internally so that I can have either 12x21 or 8x16 MCM sprites, this will let me view/edit either C64 or Plus/4 objects.

I released a new version of my assembler yesterday as well, I don't think very many folk use it, but I find it's really handy - particually the macro support which lets you do quite a lot.Turns out though that I don't test it nearly enough! One of the chaps on Lemon64 has managed to crash it a couple of times with ease. I guess without testers this kind of this will happen. Anyway, if you want to play with it you can grab it from my minus4 site.