Tuesday, October 17, 2006

XeO3: C64 Transfter

I've spent the evening building a PC64 transfer cable for the C64, and after looking around for the simple transfer programs, found none. I was pointed at a couple but every one I look at needs to be compiled, typed in.... something. Sod that - I'll port my Plus4 one. All it needs is the GetAByte function. Its tiny (around 256 bytes), and the PC command line is very simple - download and/or run. Easy.

I've also started looking at the editor again, but this time I'm making it a bit more flexable to help with the spectrum version. Before I was just storing MCM pixels as a single colour byte and assuming it was MCM. I also kept the sprite a fixed size since I was only interested in 16x16. But Russell can have any size on the spectrum - which would be nice - also quicker. When making larger sprites I have to join several 16x16's together. This sounds okay, but because a 16x16 is in fact a 24x24 due to the scroll region around each sprite, theres a lot of overlap and over drawing - which isn't good. The only problem with making a sprite system that could handle larger sprites is the cache would have to somehow autosize....It is possible, and for larger objects would be quicker - but it'd be a pain in the arse to write.

So I'll play with the C64<->PC transfer cable for the rest of the night, and then start back onto the editor tomorrow - saying my son gives me enough free time that is! It would be nice to get a debug stub onto the C64 as well, and finish my remote debugger. I got pretty far on the plus4 side, downloading, executing, stopping, stepping etc... not bad. I think I'd probably take all the code into C# now. Things like screen drawing and GUI's are just easier in that.

Monday, October 16, 2006

XeO3: The full cycle...

I'm on holiday at the moment, and I've been having fun playing with XeO3. I've spent the day cleaning up the code and trying to keep the memory usage down. I managed to strip around 150 bytes of code from the front end of XeO3 which is good, because I do hope to add more to it; a high score table along with a load/save to disk if possible.

I've been disapointing Luca with the latest restrictions. Like any game, as things start down the home straight, things get tight and the restrictions get tighter still. Hope I haven't upset him too much....

I've now completed the cycle. You can now start the game on the front end, play, die, and go back to the front end. "The circle is now complete, now I am the mast...." no hang on... thats not right. Anyway, it feels good to get it going in and out the frontend, and its starting to feel more like a game. I'm not sure what I'll do next... possibly back to the editor - Russell's gonna need it soon too.

XeO3: The Frontend


Now that I've saved a couple of K, I thought i'd better use it for a frontend before I use if for something else. I've already said that the front end will be pretty basic looking, theres just about enough memory to do one without having to load stuff in. Even with a turbo loader, I just dont really like having to load in the front end. You should be able to get there without having to load first. The game flow will be spoiled once you leave level 1 since if you die on level 2, you're going to have to load level 1 to start again - that can't be helped. But at least while you get used to the game, it's a pretty smooth and quick turn around.
So, here it is... basic, but functional. The text might change, but this is the basic look.... a logo would probably help I guess....

Sunday, October 15, 2006

XeO3: The memory hunt continues.

Just having a quick look over my memory map, correctly it here and there. I think what I really want to do is try and move all the variable sources like PathData and PreRotations together, these could vary if I really need the space. I’m not sure how much space the path data will take up, but traditionally I've set aside 4k and been struggling. However, these levels are quite a bit shorter than what I've had before so I make be able to shave as much as 1k off the paths. PreRotations is a total guess. I have no idea really how much I need in the cache. It all depends on alien speed, rotations, animation frames...lots. What I really need to do is add a flag to the cache for debugging to see just how busy it is, then I might be able to cut it down - there could be a lot of space to be gained in there.

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!