Sunday, December 31, 2006

Last code of 2006...

*sniff* There goes another year, man do I feel old now. Well, almost...couple of hours left I guess.

I've just updated my uploader ROM to fix some minor issues, and to add a loading bar. Its great to have programming space to burn! When I was coding it, I kept it as small as possible so that anyone typing it in by hand didn't have too much to do. But now its on ROM and doesn't even have to fit in the small space I'd use before, I can splurge on visuals a bit. Nothing too much, just the loading bar from the C64 one. I might add more features later on. I was also testing my new EPROM UV eraser which I guess works fine as the new code went on easily enough.

I hope to get a couple of 16K EPROM's soon and I'll put OS96 on it so I can do some stuff for Solder.

Lets hope we have as much fun next year as we did this, it looks like being a very busy one for me at work, so I hope I can find the time to finish XeO3 - I think 2007 could be the year!! Have a great new year peeps!

Saturday, December 30, 2006

Stupid, Stupid, Stupid....

Yep...just realised I've been stupid. Theres no need to make a "userport" addon to expose more lines for ROM selection as I can just add a new hardware register(s) that do anything I want. idiot. This is in fact what Solder did on his 1Mb ROM expansion.

I wonder if you could add RAM instead of ROM and just write to it and page in in/out.... I know that writes fall through to the RAM under it, but if it could write to both, than while you'd lose 32k of RAM under the ROM (or rather pretend ROM as its now RAM), but gain megabytes of parged RAM for doing whatever you like....I wonder.. I suspect someone with a bit more skill would have to try that.

I think the 1st thing I'll do as an add-on, is a new register that sets some LED's, this is the basis of everything you add on a computer really, so it should be pretty good fun.

(Oh...and whoever designed the "8bit baby" has never plugged one of them into a Plus/4 in their life!)

Friday, December 29, 2006

Plus/4 hardware fun.


I've having a bit of fun making my first ROM for the Plus/4, nothing too amazing but getting used to developing and burning ROM's for it. I've put my uploader onto ROM so that I don't have to load it from disk anymore and for a first attempt, its almost there. I altered minus4w so that I can autoload a ROM as well as a program so that I can test it better; although being an uploader, I can only test it so far inside an emulator!

I removed the 3-plus-1 ROM's from my development machine and put in an 8K EPROM (the slot's designed for 16K eproms, but 8K works just fine), and I now get the screen shown. I pinched the start-up code from the 3-plus-1 ROM's as its pretty handy, and I'll release it as source later on. Using this stuff, I could build a complete debug system on ROM meaning I leave virtually all the RAM for a game/application, which would be very cool.

I was also thinking about XeO3 and wondering if I could put it on a ROM, and I could...but it would be a little odd. I suspect that I'd need more than the available ROM slots left, so I'd need to have a cartridge and a connector from that into the userport so that I can expose a couple more control lines and page more ROM's in/out (probably allowing up to a 512k ROM), but that would mean that I could do a version of XeO3 completely ROM driven - no loading times! How cool would that be!

I also still want to try and make an MMC interface at somepoint and have a ROM bootup and load a basic filemanager fom the MMC card. This again means that there would be basic loading on ROM and you could put games etc. on an MMC rather than ROM/DISK. However, since this would take over the expansion port, you really need a SID card on there as well....bummer. The SID interface doesn't look too hard though, so you never know.

Anyways....I'll release all this stuff as soon as it's in a fit state - getting tools on ROM is pretty neat, particually since the Plus/4 has 2 available ROM slots internally - which I do really like.

Monday, December 25, 2006

Merry Christmas!!!!


God bless you all, and I hope everyone has a great day!

Friday, December 22, 2006

Electronics fun.

I've been having fun with my electronics toys again - sorry. :) A whole load of stuff arrived so I've been playing away with PIC's and LED's. I'm planing to build a scrolling message using giant LED Matrix disaplays (5x8's) so I've been learning PIC assembler. You can code a PIC in basic and C, but while the assembler is a little odd, its still far more flexible than either language.

While learning PIC assembly, I've managed to kill 3 pics in the process - doh. I'd originally read that there were 16 availble I/O pins on the PIC I'm using, however, thats not really true; theres 15 I/O lines and 1 input line. However after setting this input line to output, I've discovered that I can't reprogram them. Oh well, just as well they're cheap! a PIC16F628A is only around £1 a chip so its not the end of the world, but I'm glad I figured it out quickly!!

I've now progressed past the little pic+flashing LED onto something a bit more interesting, I've started to play with interrupts and generating them via an external PIN which I'll use to do some interrupt driven COM's. The PC will send data over a couple of wires, although I might look into the USART's every PIC seems to have. The picture opposite has a PIC16F628A driving some LEDs and a 555 Timer generating an external interrupt pulse. Great fun.

It seems to take quite a while to do even the most basic stuff in electronics, something I'd never fully appricated before - particually since you end up checking and double checking EVERYTHING! However, its great fun, and I'm looking forward to building some real toys for my Plus/4 and C64. I just got a batch of C64 carts and EPROMs and I'm waiting for my new EPROM programmer which means I'll be able to put my C64 uploader on EPROM so I don't have to load it each time, that'll be very cool. I'm also waiting for some 8bit baby's so I can try and do some Plus/4 stuff, althought the Plus/4 has a couple of EPROM sockets inside the machine and that may let me do the same on that machine too - very cool.

Oh....and I also had never realised just how much NOISE will appear on a wire that is simply waving around in the air! Its amazing! It doesn't stay at 0 volts, or"X" volts...but jumps up and down like a yo-yo! Also, if I did get it sitting still at 0 Volts, as I moved my had towars it, it starts to get electrically charged - even though I never touch it! Thats just so cool....

Thursday, December 14, 2006

XeO3: Bug spray....

I've had an interesting evening here, what with fighting with 2 year olds and trying to get them to sleep, and tracking down some elusive bugs, its been quite eventful. However, I've managed to eliminate 2 nasty bugs, one in the cache system and one on the front end... letme take you through them, or rather how I go about bug hunting... I've discovered over the years that debugging is a real art form, and one not many new folk are very good at - so here we go...

Bug 1. Cache system - okay, I had a fair idea where this one was since I had just rewriten the whole cache but the problem is that the cache is pretty large so first things first, chop it down to 1 entry. This means it's gonna hurt as every sprite will get rotated every frame, but Im debugging so what the hell. After stepping through the code I discover I've taken some short cuts in the code which speeds things up, but also requires at least 2 cache entries - okay, 2's still not bad, so we set that. Next, we have to verify that the cache is actually intact, and looking correct. With 140 odd entries, this would be pretty horrible to do, but with 2 it's a doddle. Turns out not all is well in the state of cache land. So I set about rewriting the cache initialisation stuff. This is a bit of a mind bender - again because I've decided to improve things.

You see, being a coder I count from 0 up, which means my indexes also start at 0. But the probelm is, I also want to use 0 to specify a no links (like a NULL in C), so I increment every entry by 1 so that 0 is 1, 1 is 2 and so on....this is pretty easy, but then it means that all the table accesses have to have a -1 with them to offset this.

Anyway, after rebuilding the linked list (using indexes this time), I fix up the main code that refrences them to use -1's and fix a couple of $FF index issues and we're all set. Cache bug appears to be fixed.

Bug 2. I thought this was a really simple one, I'd moved all the graphics around and suddenly the front end font vanished; okay I thought, I'll just have to move something to point to the new graphics...but no. Bugger. Now, whenever you get a bug that you simply don't understand, the trick is to knock out as much code as you can while still having the bug occur. This narrows down the amount of code you have to debug, and also reduces any interactions between modules where any funny issues might be happening. So, I do this.... I remove the ECM mode stuff, force in specific character set addresses, and make damn sure the character set is where I expect - it is, and its all as expected; but still no font.

I play for a while trying to get something to appear, firstly by altering the PRINT routine so that it only writes WHITE to the colourmap, and then by filling the whole damn screen with WHITE. Ah! There we go! Something...but not a font. Now, I know its displaying the right character set as the stars are all working, and if I poke around in there with $00's and $FF's I can see it - but still no font.

Okay...what next. If in doubt - try it on a real machine. Mmm...looks the same, press and hold reset and hay look... the logo changes to the FONT characters as the IRQ's go down, so they are there.

Okay...Now I know the grahics are right, lets step through the print routine - which I was assuming worked fine. Now I have a table lookup to translate ascii into my font using self mod code, and it turns out that this table USED to be on a 256 byte bounday, so I would store the character in the low byte and have the high byte point to the table. However, with the big memory move, its all changed... and this table no longer sits on a nice 256 byte boundry! The result is that during the look up, all letters are changing to a space! DOH! So, now I align the table and PING! All working again, so quickly put in all the bits I'd taken out, and bang! Back to normal.


So... when debugging, lop out as much as you can; coment out huge sections, #ifdef 0, or whatever! The less code you have to step through, the quicker you'll find that bug - Here endith the lesson.

Tuesday, December 12, 2006

XeO3: Bugging me....

Been a few weeks now since I last did anything really, so I started to try and hunt down the bug in the new cache system. I'm getting less and less time just now, so I only really got a chance to go over the code a little but I'm sure its in the cache. I reduced the number of cache entries down to 2, and the sprite corruption showed up everywhere, so I think its something to do with the last cache block, although I've no idea currently what that is. I hope to start proper debugging tonight, but that assumes I'll be able to stay awake long enough. I'm currently struggling with a cold which has me virtually asleep at my desk.

Anyway, while plodding away with XeO3 this year, I've been thinking that 8bit development has gotten far easier than it used to be, and I don't think theres any one reason why, I think tools are better, turn around is better, editors and web help and we just know more about it. Hell, I did the C64 multiplexor in a couple of days! It used to take weeks! But with this bug, I'm starting to think that its all just down to experiance. I've done lots of harder things now, and retro coding is pretty simple as far as game logic goes, so we just dont make as many mistakes as we used to when we were starting out. This new bug on the other hand is a little more complex as it's now using a more advanced/faster cache that will take a little time to unravel. Still, its good to know that I can still learn stuff, and Im not quite as thick as I once was.

Monday, November 27, 2006

XeO3: Pausing to gather our thoughts...

Yes I know... I've not done much XeO3 stuff for a while. I'm actually busy learning electronics, something I've always wanted to do but never found the time (or books) to learn. However, I've now gotten some of these so I'm trying to learn the fundamentals just now and that takes time... time that would normally be spent on XeO3. This has of course given rise to some new possibilities. The whole reason for learning this stuff is so that I can build add-on's for my retro machines, and we're currently wondering if you can build a retro game cartridge cheaply enough that people would buy XeO3 as a cartridge..... Anyway, this is all a sideline just now...The new cache system still has a nasty bug in it and is currently corrupting memory, so I'll have to track that down soon, and then try and tackle the weapons system....so once I get over the initial electronics hurdle, I'll be back on XeO3.....honest :)

Friday, November 24, 2006

OOOooooo.....Interesting.....very interesting.....

http://www.xbox-scene.com/xbox1data/sep/EEyuFuZkpFZpCHcoON.php

U.S. Copyright Office issues new abandonware rights>>

Here's something abandonware enthusiasts can be thankful for: the Library of Congress yesterday approved six exemptions to US copyright. The one most pertinent to gamers is that, for archival purposes, copy protection on software no longer being sold or supported by its copyright holder can be cracked.What does this mean? Well, those retro games -- classic or otherwise -- that you can't seem to find anywhere can now be preserved without fear of ramifications. Although it is still unlawful to distribute the old games, free or otherwise, rarely do any abandonware cases go to court. The ruling is more symbolic than anything, but a step in the right direction.

Thursday, November 23, 2006

XeO3: Please Wait....Loading............

I was testing out TNT's new 1581 turbo loader last night, and WOW! what a speed. The whole thing loads in less the 10 seconds! Thats 179 blocks (45k) that load in a blip! While speaking to Luca I had mentioned that if I thought that most folk had a 1581, then I wouldn't worry about packing in the front end to the main EXE as it would all load in under a second! Pitty...Oh well, I guess the only way to really guarantee that kind of thing is to make a proper cartridge game; which is also somthing I considered BTW. Using a cart as a large instant Disk would be very neat, and I do think I'll do an MMC64 version that does just that! Once

the C64 version is done, I'll start splitting it off into parts and putting them on a memory card so that it can act like a cartridge. This not only gives instant loading, but also a huge capacity. I wonder how many MMC64's have been sold? The good thing is that unlike the SuperCPU, these are still being sold! So if someone wants to play XeO3 from cartridge, they can run out and buy one! I'll have to do a little investigation as to how it all works, but from what I've seen, it should be easy enough.

I wonder how much these cost to make.... If you could get it down a bit, you could bundle one with the game and sell it cased so it looked like a normal cart - even though there was an MMC inside! Althought thats probably taking it too far.....

Sunday, November 19, 2006

XeO3: Spectrum Wars....

I've been trying to fix a +3 spectrum for Russell today. I have 3 of them, but only 1 working one - and even that one isn't perfect as the load/save cable has been butchered to make a SAVE-ONLY cable. This probably happened when the socket broke. However, I've ripped them appart, took the working drive and put it inside one of the other machines (that has a proper tape connector) and all is well. So at least I have 1 fully working +3.

As for the others, well I discovered that on both disk drives, the belt has degraded too much and is now more or less just a blob of rubber. Fortunately I have 2 spare belts (no idea where I got them...but you can get them from ebay these days), and I've repaired both. But only one of them is actually fully functional. The other kinda works, but doesn't read anything. I suspect it might be the heads needing cleaned, but theres always the chance its just plain dead.

It was touch and go for a little on the working drive as when I opened it up, a tiny pin dropped out and I had NO idea where it came from - and the drive didn't work without it. But, after searching for a while on the NET, turns out its the write pin or something and I was able to plop it back into place.

The last +3 is pretty dead though; well....kind of. It boots, and you get the Copyright message at the start, but the menu doesn't appear. It just stays on the copyright message. I swapped the ROMS with one of the working +3's, and it was the same, so the ROM's are fine. I suspect its waiting on something, but I've no idea what. I have a multiface +3 and it can break in and works fine, so the Z80 is working okay as well. Oh, and if I reset and hold down BREAK, I get the test picture and the machine beeps away. Very odd. Still, I might butcher it so I can get a working tape connector on the other machine which now is working thanks to the 3rd drive having its belt replaced.

I've also discovered a really cool TZX 2 WAV program which converts TZX files into WAV files, which can then be played out the PC's audio and loaded in on a REAL spectrum! Very cool indeed. I've been busy taking snapshots of them and saving them to disk - its great seeing all my old fav's on the real machine again. And it's also shown that Cobra DOES indeed run in a frame.... After seeing Russell's scrolling code - I wonder how he managed that!

So, the next thing to probably try is chopping the end of a +3 lightgun and using that AUX port to download programs directly. I'm not convinced this will be terribly quick, but I guess at least Russell will be able to view his work on a real machine.

Edit: Oh....I did try Xeo3 on the +3, but it didn't work since Russ uses that 48k ULA hack. This means I'll have to hook up a real 48k spectrum to see it....Perhaps later :)

Thursday, November 16, 2006

Retro TV.

THIS is an old BBC documentary about Imagine and Ocean... Pretty funny to see now, but I would have loved to have seen it back in the day.... Have a watch... pretty good fun.

Tuesday, November 14, 2006

XeO3: Father Ted....

Okay.... I've gotten the TED sound playing the main theme, although its been a bit of a nightmare.... it turns out that normally these operate at location $D400 - the original location of the SID on the C64. But add-on for the plus/4 is mapped to $fd40 (or $fe80), but when the card isn't there then this is just normal IO space - and theres no RAM there. This means it just doesn't work! What I've ended up doing is making a relocate routine that runs through SID music player and then moves the writes to the SID card to an area of memory the Frequency convertor can get access to. I've also managed to shrink it down by 50 bytes, but I've had to add the relocate routine... so I've uised up just over 1k for this.

However....now for the REALLY bad news! This routine takes around 16 scan lines to run, and thats on top of the SID player! This is very painful! So, if we run low on memory again, this is the first to go as it will slow the game down in busy areas.

Still, I've given Luca the mconv source and he can release it on +4 world at somepoint so others can use it. As I said earlier, the source lets you play around with it easier..... as well as relocate it and change the storage locations.

XeO3: Mr. Ted Sound

The current poll on plus/4 world showing that only 28% of users have a SID card has forced me to include the TED frequancy convertor MConv. This unfortunatly steals yet another 1024 bytes leaving me with only 3k in the main code block. I spent last night disassembling it and typing it back in so that I have a source version and can relocate it all easily. Once it's fully working I'll let Luca upload it back onto Plus/4 world so everyone can get some use from it. It makes it very simple to relocate, change the SID base address and basiclly fiddle with the code. I'll also be able to shrink it very slightly since there were a few NOP's and the like due to it being written in the monitor. Having done a full game like that, I can appreciate the problems involved....

Once this is working, I'll get back to the sprite cache and finish that off, and then hit the weapon system I think.

Sunday, November 12, 2006

XeO3: The big push.

After a small break due to family, work and a cold, I'm now back on track and pushing down the memory to try and free up as much as I can for the last chunk of code. I've rewriten the sprite cache, packed the sprite data and done a general re-jig of the data layout. I've managed to save 4K which means everything can move up by a whole bank ($1000) and this lets me easily pack this 4K in with the current code and data, which brings the grand total memory free to 6.5k - which isn't bad at all. Of course theres still lots to do, but this should give me plenty of space to do it! The remaining 1.5k is right at the top of memory, which makes it a bit of a faff to use for most things - unless I can generate tables there.

So, now that this little(!) task is taken care of, I can start to go through my to-do list. If I get the weapon system working, Luca and I can try and release a test level which won't be used in the final game, but will give us feedback on difficulty levels from - well all of you. If you look at Luca's page, you'll see he did another level based on the level 1 graphics. This is the one you'll get to play with first.

But before I do all that, I'll need to test the new cache system and make sure its holding up okay, and then try and insert the code I took out before that actually makes the cache work properly. If that still doesn't work as well as I hope, then I'll change it all again and make it a simple queue.

It should also be noted that the remaining 6.5k is IT. There is no more free memory after this runs out, which means if I need more space, then I need to start cutting things out....Lets hope it doesn't come to that.

Wednesday, November 08, 2006

XeO3: Sprites....damn them....

Well, Russell and I have discussed this cache problem at length, and came to the simple, resounding conclusion - I'm a moron. When I started doing the sprite routine some 6 years or more ago, I hadn't done any real 6502 in anger (as it were), for over 10 years before that! And when I designed it, I used normal structures of things. This is bad. In 6502 you really want to use the index registers and multiple arrays for structs. Like this.....

  struct
dw Next
dw Last
db index
db flags
ds 8
ds 72
end

But instead, you should really do this....
NextIndex   ds  140
LastIndex ds 140
index ds 140
flags ds 140
GfxLo ds 140
GfxHi ds 140

Now, you really have to wonder why I haven't clicked with this before since my scripting system does just that! Well, now that I know, I'll make it part of the rewrite of the sprite system, but this is a pretty large undertaking and will take time...... bugger.

Anyway, even after I do all this Im still not sure I'll be able to use the cache to its full. Even at 40-50 cycles, thats almost a full scanline, and with 10 sprites, thats a lot to waste every game cycle. With a simple circular list, you only lost around 20-30 every minute or so....

Doing this change will also allow me to remove the redundent 8 bytes in each sprite-cache block, which will help save space overall.

Tuesday, November 07, 2006

XeO3: The Sprite Cache.

I finally got around to visualising the sprite cache, and in doing so I was in for a shock. It wasn't working! Well, not the way I'd planned. When I originally designed it, I had intended for sprites that were used a lot to stay in the cache, so I'd used a doubly linked list so that I could unlink and entry and place it at the bottom. This would then keep it as far from the TOP (which is the next free slot) as possible. Its a simple idea that works extremely well when used with textures on the PC. However, mine wasn't working - in fact, all that was happening was I was operating a simple queue system. It came off the front, and went on the rear. This means that when enough baddies have passed, I have to recache the graphics that are still in use - like the player ship. This wasn't the idea at all!

So, I added the missing code to push it down to the bottom of the stack where it would stay until it hadn't been used in ages and then it would get freed and used again. However...being a ful 16bit doubly linked list - it isn't quick, and sprite engine takes a hammering because of it; way too much in fact. So now I'm left wondering if I should in fact scrap this idea, and just use a simple queue. This would help speed up allocations, but I'd still have the same issues I have now - which you don't really notice anyway!

I'm just not sure.... the whole concept of the sprite system came about because I wanted to use the texture cache idea to help keep things fast, and now thats the code thats slowing it all down!

Bugger.....

XeO3: ZZZZZZZZZZzzzzzzzzzzzzzzzz..............

Yep....did nothing but sleep again last night..Oh well... Just as well this isn't my day job.....

I have been thinking about the absolute limits of memory I can free up though, and I reckon I can claw back around 4k from various sources - tops. After that, I need to start cutting features.

   1k  -   Sprite Cache by seperating all the sprite data from from the sprite structure.
1k - Sprite definitions. Just now there is a 16bit pointer to a cached rotation,
if I change this to a cache number, I can save 8 bytes per sprite *167 sprites,
but I'll then need a 300 byte look-up table, so gain around 1k overall.
1k - Paths. I really dont think Im going to need a full 4k for the scripting. The levels
aren't that long really (compared to Blood Money which used 4k for paths as well),
so I can probably cut at least 1K, possibly 1.5k
1.5k- Theres currently a free block right at the top of memory of 1.5k which Im desperately
trying to hold on to, but if push comes to shove.... it'll have to go too.

Now this is a fair bit to free up, and the sprite stuff will take a little bit of work but once done, that should set us on course to finish up the main code. wow....code complete...who would have though it... Still, not there yet!

The to-do list is currently...

  Finish Weapon system
Finish loader with the new Turbo Loader
Add loading screen
Add High scrore table to the front end (top 10)
Save High scores to disk
Add TED music player - if possible
Add multi-load for more levels (make sure its a variable number for skining later)
Do a TEST level that we can release to help get the difficulty right.
Make all levels
End sequance - even if its a simple one

I think that about covers it..... Still lots to do, but we're over the hill and rolling down the other side.

Sunday, November 05, 2006

XeO3: Another day, another feature....

I've been playing with the sprite routine again last night, and came up with a nice little feature that I'll use when baddies are shot. As you can see the sprites now turn completely single colour and flash when they get struck. On the C64 something this is pretty easy to do since each sprite has its own colour, so you can just flash that - but when drawing software sprites, its not as simple - this is in fact a whole new sprite! Or is it.... All I do for this is to use an inverse of the AUTOMASK and ORA the data into the display. The automask if you'll recall is a way of automatically masking MCM pixel data, and given any sprite the automask works out the data needed to MASK it on - so invert that, and you have your FLAT sprite.

Like everything, its not without its expense. It costs around 200 bytes for the code, and is slightly slower (when a sprite is over space) than normal. But it only happens every now and then, and being able to tell you've hit something is great, particually on baddies that take plently of wallop - or ones with limited collision areas - like a BOSS or something.

I also had to get Luca to swap all the colours to make use of it as it must use colour bits %11 or I have to AND as well.... Still, its a neat little touch so we'll probably try and keep it in.

Its also that time again, and I have to go hunting for memory once more. I've decided to rewrite yet more areas of the sprite routine - mainly the data structures as this should save around 2k overall - quite a saving. But theres a lot of work involved; I'm going to replace the cache pointers with a cache index (and a small table). Also, due to the way I move sprites up and down, I have 8 bytes at the start of every cache block to allow for a sprite to move down (I move the draw pointer up 1, the sprite gets drawn down 1 pixel mode), and because these are located directly beside the cache info, I have to repeat these 8 bytes all the time. However, if I split up the INFO structs, and the DATA itself, I can store 8 bytes at the start, and then remove all the others - again, a small table will probably suffice.

Saturday, November 04, 2006

XeO3: Faster and faster....

The thing I love most about fully open development is that no matter how clever you think you've been, and how well you think you've written something, someone almost always comes along and improves it! It's not that I'm bad at what I do, or that the other person is way smarter; no, it's simply that a fresh pair of eyes and a different brain can pickup on small things you've missed. This is especially true if you've been staring at the same few lines for months trying to improve it. You're brain gets into a rut, and you just can't get past what you see. Open internet development gets rid of this by allowing anyone on the web to help. Sometimes the codes so obscure that no one can understand it - but thats fine, your no worse off... But other times, its a nice small snippet that someone points out something and you slap your forehead and say "why didn't I think of that!!"

Heres a case in point.... Some time back I was struggling to find a faster way to fire bullets, and it took me several days to come up with what I thought was the perfect solution - and to be fair to me, it was pretty spiffy. So I happily posted it for everyone to see and use. Heres the original...


FreeList db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,$ff
;
; Usage:- AllocBullet [x|y] Specify the X or Y register that hold the bullet to free
;
AllocBullet macro
ld\0 FreeIndex ; 3 ldx FreeIndex
lda FreeList,\0 ; 4 lda FreeList
bmi !NoneFree ; 2 bmi !NoneFree
in\0 ; 2 inx
st\0 FreeIndex ; 3 stx FreeIndex
ta\0 ; 2 tax
dec BullInUse,\0 ; - dont count this... its not in the new one.
!NoneFree:
ta\0 ; 2 = 18 tax X=next free bullet (or $ff for none left).
; (best case=12) Negative flag SET on none left
endm


Now, this was a pretty fantastic improvement over the original which was just a loop through "N" bullets. It was fast, it didn't matter how many bullets you had to allocate from, the time was linear. Great! Then along came TNT (who incedently is doing a cool remake of paradriod), who quickly pointed out that if I reversed the stack it would be even quicker - like this:-


AllocBullet macro
ld\0 FreeIndex ; 3
bmi !NoneFree ; 2 (best case=6)
lda FreeList,\0 ; 4
de\0 ; 2
st\0 FreeIndex ; 4
ta\0 ; 2 = 17
!NoneFree:
endm


Now I had fiddled with the routine for some time, but had missed this simple switch, and this is the great thing about open internet development. My game goes faster, and I hardly had to lift a finger! While it appears to be a small change, allocations happen all the time, so if you can knock of a cycle, or make it early out quicker, then its all good.

Anyway.... the reason for all this is that I've been retro fitting all my allocators with TNT's new version, and it reminded me why I'm doing all this in the first place: Open Internet Development is good, for a retro scene - its vital!

XeO3: Surprise Surprise!!!

I've spent the evening playing with the main game again, this time adding a couple of new cool features that we'll keep quiet about for the time being. However I was also adding the speedup I was on about yesterday to the X axis this time and in doing so I managed to speed up Y a bit as well. Doing this then led me to this new feature - its pretty cool, and its somthing that a C64 would struggle to do properly - if at all! The current thinking is that each port of the game will actually have quite a bit different, to the extent that some would say its not a true port, but a different game. While I could cripple one version to make anothers more like it, I don't want to - I want each machine to be pushed to its limits, even if that means adding features that the other versions won't have!

Purists will complain that they want XeO3 ported exactly, but I think having a great game - regardless of what the original looked like - is more important. It also means there may be several new games fo people to play which look only vuagely like each other. The style and baddies will be the same, but I suspect the levels and probably the paths they follow will all differ - weapons should be fine though. If someone wants an identical port - they can do it themselves by mixing code from one playform to the others.

However, this also free's me up to use the C64 sprites better, have more detailed backgrounds and all that this entails, and it also means that the spectrum version can push its own strengths - should be good!!!

One thing has occured to me though, I'm going to have to untangle the sprite routine from the Plus/4 version into some sort of framework so others can use it properly! Its a bit intertwined just now and some might have difficulty extracting it....

Thursday, November 02, 2006

XeO3: Go faster sprites....

Just had a small brainwave..... Normally 16x16 sprites actually draw 24x24 due to rotation, however when the sprite "fits" perfectly inside a 16x16 (say its coordinate is 0,0 and hence has no actual rotation), you can drop the surrounding characters. While drawing the chars themselves don't take long, they still have to get masked. BUT! becasue +4 sprites are character based, so is my clipping routeing, which means I can drop any individual character from the sprite simply by flagging the character its about to overdraw as $FF. This is how I do clipping off the top and edges, I just have a table of indexes some of which point to $FF characters.

Normal NoY NoX NoX&Y
-------------------------------
ADG ADG AD AD
BEH BEH BE BE
CFI CF

Anyway, what I now do is check to see if the Y coordinate has a fractional component, and if not, I set the bottom row to be clipped! If we still have to draw the full 24x24 sprite (which is most of the time), then this only adds 30 cycles PER sprite(300 over all), which isn't much - really. However, if we find we're dipping below our desired framerate I now have another tool to help speed things up. Take a sprite that simply flys across the screen, well if I make sure this sprite does this on an 8 pixel Y boundary, then its always going to be significantly faster due to the fact it will never draw the lower row.

I could do the same on X where I drop the last row, but because of the scrolling, this won't happen very often... I'll probably try it and see, but I think the Y check is good enough.

RetroEdit: Cleaning up.

Okay, back to real work again.... I'm cleaning up my RetroBitmap control and converting the rest of the application to use it, which is taking a little longer than planned. I now also have to re-evaluate whether I want to have a per-sprite HIRES/MCM switch. While not really important for a C64/Plus4 it might be down the line if I decided to add Amiga editing and add a "number of colours" mode. This might mean you couldn't edit 16 and 32 colour sprites in the same project. However, changing each sprite can be a pain depending on what your doing. I'm still not sure how I'll handle this, but Im edging towards each sprite still having their own mode.

The Control now renders everything correctly and I can now play animations back as before, although I've still to add the all important keyboard short-cuts. The control can now also be any size (although, there may be invalid combinations like a 13x13 in MCM etc.) and can render to any size bitmap. The bitmap is public so that you can replicate it in other controls; I for example scale it and use it to display the various sizes of the sprite without having to re-render it. I hope to add some sort of custom exporter-pluging system (at somepoint) so you can save your own formats. I was reading the discussion on WorldOfSpectrum forums and they were talking about a funny zig-zag format. I'll try and add all the common ones from the start, and then let you do plugin's for any new formats.

All this is pretty far down the line....Possibly even after XeO3 is finished. Also, I plan to save everything in some sort of IFF format (project files that is) so that they are easy to disect; if anyone else has an opinion, nows the time to object. I was considering just using some of C#'s native serializing stuff, but I want folk to be able to extract stuff from it if then need to.

Oh...and one last thing..... Do people just want a load of sprites that the can "view" as animations, or do they want a list of anims that the program orginises nicely for them? Just now I have (say) 167 sprites, and I set IN and OUT points and then view the anims. This is very easy to use, but it means I cant set up say a "baddie" animation and save out delays etc. But usually these numbers are different for each program so its not worth it..... anyone have an opinion on that?

Wednesday, November 01, 2006

Uploader....

I've now finished my new uploader, and it's actually turned out to be a fairly good idea. I've been using my MMC64 to upload and play C64 games. It turns out however, that it just isn't very good as some file - anything really big I suspect. I have several .PRG files which I thought had gotten corrupted because the MMC64 wouldn't run them properly, however, my download program manages fine. This could be for a few reasons though. The MMC64 hasn't actually started BASIC yet, so it may not have everything ready to run these programs, or it might be that its not setting up certain BASIC addresses for the unpackers or something. Or it could just be that its too big and simply won't work.

Whatever the case, my uploader manages these games fine! It takes around 6 seconds to transfer a full sized C64 program which is pretty quick. I currently use the MMC64 to load the boot program which is much quicker than loading off disk, and then my command line tool to send the .PRG file I want to run. I'll probably expand this to include .P00 and .T64 files as well as these are pretty simple and would be quite handy. I could write a little GUI tool I guess, which would be particually handy if all you're doing is running games. But I suspect most people have other ways of getting stuff to the C64 (let alone having to build the cable( so I'll not worry about it just yet.

Anyway, if you want it.... you can download it from my minus4 site, minus4.plus4.net. It includes the to .PRG files for the C64 and the +4, both are tiny and if need be, could be typed in. The wiring diagram is in the text file - Enjoy!

I'm also planing to port my DEBUGSTUB I have for the Plus/4 over to the C64, as this will let me control the C64 fom the PC. The initial plan was to write a full and proper remote debugger, complete with source level debugging. I got as far as being able to start/stop programs, and then single step them but it needs lots of work. However, as a side line, this program lets me control the Plus4 completely from the PC side, meaning I can download images, sounds and tools to it and use it as a slave for editing. Imaging having a PC editor that shows you the graphics on the PC AND on the Plus/4 as you draw them. This would be extremely handy as viewing on a TV changes things hugely. If I ever learn enough electronics to be able to build a Spectrum interface, then I'd probably add this kind of thing there as well.... RetroEdit could be turn out to be extremely cool.

Monday, October 30, 2006

XeO3: C64 time....

I got my new dual parallel port today, so I spent the evening updating the Plus/4 downloader to allow me to change port address, and writing the new C64 downloader. The piccy shows the new cable before I've tidied it all up and put the casing on; but now that I know it all works, I can do that whenever.

The C64 cable is cool as it sets a whole byte at once (unlike the +4 that sends nibbles). But it only seems to match the +4 speed, probably due to the higher clockspeed on the +4. I suspect I could knock a second off the +4 one if I blacked the screen, but 6-7 seconds for 64k is quick enough. This should allow a quicker turn around of testing on the C64 version as it downloads under the ROM's and VIC chip, which in turn means I dont HAVE to pack it to run/test it.

Once I've cleaned it all up I'll post the new C64 downloader, along with the wiring diagram - although I suspect its the same as a few others, its very simple: 8 Data wires, 1 signal, and 1 busy - easy. I know loads of folk will simply point out that theres already 1,000,000 downloaders, but from what I saw, they were all far too complicated - I just want download and run!

XeO3: Selling an idea.....

I was over at Lemon64 and they have a really handy poll there which asks what you do you C64-ing on, an actual machine, VICE,CCS64 or another emulator. I'd expected it to be around 15-20:1 in favour of emualtor (based on people I know), but I'm happy to be proved wrong again! Its early days on the poll (I think), but currently around 44% of you play on a real machine!! wow! Thats great, and pretty cool. It also brings up the question of selling disks again since my original argument was that ony a handful would want to buy an actual disk, I'll need to start another pool and see what people actually want but it may be we have to start thinking about making an actual product to sell to folk so they can play on their actual machines.

I wonder what the +4 ratio is.......

Sunday, October 29, 2006

RetroEdit: Back again...

After a short break - where I more or less did nothing but sleep, I've come back to RetroEdit and decided to shuffle things around yet again. While it's been going fairly well one thing thats been lurking at the back of my mind is that I'm going to have to do this all again - but this time with characters. The one thing I hate doing is repeating the same work, even if its cut and paste job, its just horrible. So, I'm about to move the rendering part (and probably the editing side) over to a user control. In VB and C# you can write your own controls that you can then drop into your windows form. This is pretty handy since on most retro machines the rendering for sprites is the same as the rendering for characters. i.e. The Spectrum is still HIRES, the C64 still has HIRES and MCM - as does the +4. So, I'll move all this code into its own display (RetroBitmap) and then I'll be able to use it for drawing/editing both sprites and characters (or chars+tiles on the spectrum).

It also means that once released, others can simply swipe the .DLL file and use it themselves inside their own C# or VB project - which is also nice.

Wednesday, October 25, 2006

And.....rest....


Done nothing at all tonight.... well, not quite nothing. I got an Opus Discovery disk drive for the spectrum months ago from ebay for a steal (around £14 I think), problem was it didn't work. I've spent the past few nights tinkering with it and I finally figured out what was wrong. The disk drive itself simply wasn't working. After pulling it apart and putting it back together the drive started up and kinda worked, but I got disk errors. So, I dismantled it again and saw it was more or less a standard PC floppy drive, but plugging in a PC floppy didn't work. Probably because back then they were XT drives. So I was trying to think of a way to get an old XT drive to try, and searched the web for one, but with no luck. Or rather no luck I want - $170!! No thanks.

Then I had a brainwave. I'd just gotten an 1581 drive assembly (without drives) where it stated the drives were removed for use in the Amiga, so I thought...what about an Amiga drive? I was a bit reluctant to destroy an Amiga to get this working, but I thought try and see - I could always keep an eye open on ebay for a dead Amiga. Then it stuck me: The Atari ST reads and writes PC disks... Anyway, since I have a huge amount of crap, I of course have a dead Atari ST, so I removed the drive and plugged it it - BANG! works a treat! It seems to have all the jumpers the PC XT drives have as well, so if your ever after an old XT drive, try an atari one first - they're cheaper!

So, job done - back onto Retro Edit tomorrow I hope.

Tuesday, October 24, 2006

RetroEdit: Clean up.

I've not done that much tonight, just cleaning the code up and putting in the machine selection system I was yattering on about yesterday. Now if I load in some sprites and I select SPECTRUM as the global machine state, it sets all the sprites to hires. Same goes for PLUS4 and C64. On SPECTRUM mode, it also disables MCM selections and so on. This is the kind of things I've been doing, nothing earth shattering.

I've also added in an Enable Mask tick box, and an Edit Mask tick (which becomes active when masks are enabled - of course). This means on spectrum sprites, you can edit masks along with the sprites. I'm thinking of putting in a basic "light box" mode as well, to let you see the next (and possibly the previous ) frame so animation is a little easier. I'll also allow this mode for MASK editing, so you can see the shape you're trying to bring out. All these kinds of features till take time to do which is a bit of a pain, but its back to the problem of a single state that then effect the almost every other state, and you have to make sure its valid. Yuck.

I hope to start basic editing tomorrow so that it'll actually become useful, so once I get HIRES and MCM drawing it, I can let Luca lose on it, and see how it holds up. I need to figure out how to detect key presses in c# first so I can use things like + and - to change sprites, and 'm' to toggle the mask view on and off, that kind of thing. So still lots to do.

Monday, October 23, 2006

RetroEdit: HiRes Appears...

I've spent the evening changing the editor into something a little bit more sophisticated, it can now do Hires and MCM sprites - although I still can't edit them. I've also added C64 and Spectrum modes so that once I allow you to select it, you'll now be able to edit using those colours. Internally, its almost completely changed. before I had a simple C# List<byte[]> for my sprites, but now I've gone and made a nice Sprite class that contains everything about a sprite - the basic array that makes up the pixels, its width and height, and which editing system its using (Plus/4 and C64 in MCM or Hires, and Spectrum).

While this actually lets me have every sprite different in the animation sequence - even down to different systems(!), its actually a little impracticle. I suspect what you actually want is a global editing mode, so that you when select C64, Plus/4 or spectrum the whole project swaps to that. I think what you really want is to be able to load in sprites from one system, and convert it to another - as best it can. This will mean that C64_MCM->Spectrum conversion gets the HIRES version of the sprite, but it gives a starting point for editing; rather than having to do each one by hand.

However, I will allow each sprite on the same system to vary - because thats perfectly valid. So MCM/HIRES isn't a global state, but one for each sprite. This means you could create many C64 MCM sprites, and then create some HIRES overlays for them, all within the same project.

This is actually the thing that pisses me off most about editors. Theres so many dependencies. Change one radio button or drop down menu, and you have to do shit loads behind the scenes, and make sure every combination works!.... pain in the bum. However... I hope to be able to use the same basic classes in the character editing which means you should be able to edit 16x16 characters for the spectrum - or Plus/4. Internally, its stored as a simple array, but when you save it out, it'll convert it to the correct output format. Plus4 Sprites, chars, sprectrum sprites, C64 hardware sprites; well...thats the theory.

Sunday, October 22, 2006

XeO3: The games afoot...

Luca and I have been hammering out the how the actual weapon system is going to work and I have to say its one of the few times where internet development really sucks. Trying to chat about something like this and get the details right so that we both agree is hard enough, but having to type every line into Windows Messenger is just a nightmare. If we were in the same room, it could be done in about 5-10 min since we could discuss it easily, draw diagrams on a bits of paper, and basically get to sorted quickly. But over the net, it took us the better part of an hour to go through it and make sure we both understood what the hell we were talking about. Oh well, its all sorted now - I'll let Luca go through it all though.

I've also been trying to figure out how to erase files from a floppy using the kernal. Little bit of a pain, since theres hardly anything telling you how to execute disk commands from assembler. I know you can do this in DOS...

  open 15,8,15,"S0:FILE"
close 15

But, I wasn't sure how to actually do it in assembler. I finally found some code after a bit of hunting around and this is now what I do...

    lda  #15                   ; file handle
ldx #8 ; device
tay ; command channel
jsr SETLFS ; set channel details
lda #8 ; length of filename ("S0:SCORE")
ldx #LO(HISCORENAME) ; pointer to score
ldy #HI(HISCORENAME)
jsr SETNAM ; Set file name
jsr OPEN ; perform OPEN command
lda #15
jsr CLOSE ; and close the channel

And thats all there is to it. When we have the turbo installed we'll have to issue a save with overwrite and get the turbo (on the disk drive side) to erase the file first. This is all to avoid the SAVE "@0:filename" bug. However, after all this is done, it'll mean we can save hiscores to disk for a proper record - which is cool.

Saturday, October 21, 2006

XeO3: Not as stupid as I look!

After yesterdays head-banging moment, I sorted out exactly what I'd need to do in order to get a proper double buffered star field. Then after groaning inwardly at the effort involved just to get a bloody star field running, I slapped myself hard across the face with a virtual fish - and got on with it. I now needed another two 100 byte tables (CPU built, so theres stack of memory for that), 4 star routines in total (2 to draw, 2 to clear - ouch!), but could reduce the size of my logo drawing code to almost nothing - much better.

So...What does the new Star code do? Well, picking up from yesterday... It now copies the current index into a SAVE_STAR table (2 of these, 1 fro each frame), checks to see if it can draw a star at the desired location, and then draws the correct character, and colours it with a random colour (multicoloured stars are much nicer than depth queued gray ones) at the same time making sure its in HIRES mode (top half of the screen is in MCM mode). This is fine... Now comes the really annoying part. To wipe them, I read from one of the SAVE_STAR tables, check to see if a star is actually there, and if so wipe it. I dont need to wipe the colour, as theres nothing else going to go there.

Now for 360 stars, this is horrible, much slower than clearing screen and blasting it on. However.... for the original 100 stars, its much faster. So...strike a little bit of a middle ground (240 stars or less - undecided just yet), and the fact I no longer have to continually draw the text and the logo, means I win out over all. So the original idea wasn't that dumb after all, and while I may actually be as stupid as I look, at least this time I get to keep my head firmly attached to my shoulders - but theres always tomorrow.

Friday, October 20, 2006

XeO3: Stupidity abounds....

I often wonder why programmers are never given protective head gear, since every now and then we do something so stupid then you either bang you head off a desk, or get someone to hit you with a hammer. I've been thinking about rewriting the front end star field so that it goes in between the stuff thats already there. This means I wouldn't have to clear the screen and then redraw it every frame! Quite a saving.

So I set about doing this thinking all I need to do is double buffer the star locations and then clear anything thats in the "clear" list. Sounds easy doesn't it. The problem being, that my star field is actually in 4 places at once. A star can have a location of 0 to 255, which I then store in $0c00,$0d00,$0e00 and $0f00. This means I get 4 stars for the price of 1, and when a star leaves one zone (goes from 0 to $ff) it smoothly enters the next and you never know.

The problem being, to clear the stars, I can't just store a location, I need to check to see if a star is actually there because it might be visible in one bank, but hidden in another. When you add this time to the increased time taken to actually plot the stars, it'll probably come out longer than the current method! Idiot. I'll have to sit down and think about it a bit more. Theres always the chance that because I dont redraw the logo or the text, that this doesn't matter, but I'd like to be able to have lots of time to spare so I can scroll stuff onto and off of the screen - and Im not convinced I can do that knowing how long it'll take.

Its a pitty as well, I increased the number of offsets from 24 to 90 (giving me 360 stars in total) thinking that since I'd saved stacks of time, I could now bump up the number - WRONG!. Idiot!!.... Wheres that baseball bat when you need it.....

BTW - this star routine was pinched from Delta on the C64, I spent a while hunting it down years coz I thought it was fab.

Thursday, October 19, 2006

XeO3: Death of a Parallel port....

Well, looks like I've fried part of my parallel port; damn. Pin 11 (busy line) doesn't appear to work anymore. This is probably why I wasn't able to get the C64 to set it - or at least the PC to notice. The plus/4 downloader is now also dead because it also uses that bit; damn. I know the machine and cable are okay as I've currently got the Plus4 plugged into my server and it can upload from there; damn. Although....its VERY odd that only 1 pin has died - I'd have expected the whole thing to go, but since the C64 still happily displays values getting sent TO it, I know its still a little bit alive!

Oh well, this means I'll have to go buy a plug in card - but if I get a dual port, then I can have the C64 and Plus4 both plugged in at once. At least some good has some out of it. I remember reading about doing hardware stuff. You dont just pay with your time while you debug it, you pay with your wallet. Oh so true. Still, it also means my C64 cable is now ready to go....all it needs is a downloader! It should be around twice the speed of the plus4 one which can currently download XeO3 in around 7.5 seconds. 3 seconds, 7 seconds... doesn't really matter I guess - fast is fast.

If I get around to doing my remote debugger, it might be nice to have a proper bidirectional port - even if it is a nibble. When I was doing a playstation debugger with the PSone action replay's I was using a bidirectional serial port on that and it was great, it made its communications very robust. I'm still determained to do a full, proper remote debugger for both the C64 and the Plus4. Theres something very satisfying about debugging on actual hardware. Of course...emulators have some BIG advantages - like being able to debug interupts, being able to stop and view hardware registers at any point...well... pretty much everything! But its still not a real machine your controlling. Oh I dont know...it would just be cool.

XeO3: A work in progress...

I've added the new front end logo, made sure the game cycles properly and all the usual stuff. So I've decided to treat every one with a video of the current state of play. Its nothing fancy but shows the game running and lets you hear the sounds and music togther. The paths and animations aren't final, but it does show you it all working. Hope you can view it okay.

I've now got a grand total of 440 bytes left. This means the big squeze is on again! I also need to shuffle the memory map once more so that I can use large space at the top of memory to store the logo and character map. I hoped to keep this space, but it looks like its now about to get all used up. Bugger.

The only free or at least flexible space is now the sprite cache. This area can take a little bit of a pounding since if its not in the cache it'll just redo it. However, it does take more CPU time to re-cache something so I'm reluctant to do so.

Edit: The direct youtube link is: www.youtube.com/watch?v=W-DtKhk6qFw

Wednesday, October 18, 2006

XeO3: Front End..

So after a couple of days squeezing the front end down as much as I can, I've now spent today putting much of it back in - bugger. I got a logo from Luca to try and tart the front end up a bit, and it means I have to start double buffering the front end a bit. Since the logo itself takes up almost 1K, it also means I'll have to try and free up even more space. Its worth it though as it does help make the front end a bit nicer. I hope to finish this up tomorrow, and then I can take stock of the damage its done to the memory. At least if we do need to trim it, theres at the very worst we could just reduce its size.... It also means my nice and simple 3 layer starfield isn't nice and simple anymore. I now need to double buffer that as well so I dont need to redraw the logo all the time! Its never easy.....

I've had to redo my C64 parallel cable as I got the pins backwards! Doh. Idiot. All the diagrams I found to tell me the pins never actually got around to telling me that it was describing the back of the computer, and not the cable itself. I had assumed that it was descibing the cable, since thats what everyone wants to know! But no... wrong again. Anyway, I've built my own cable rather than the PC64 one, and once I manage to get the PA2 line working, I'll be able to download a whole byte at a time, rather than a nibble which all the other cables seem to do. Not sure why... it might be to do with old parallel ports not being bi-directional or something, but I don't really know. If I can't get the PA2 line working, then I'll have to drop down to a nibble and use some of the datalines as handshaking - which I'd rather not do; although if Im desprate, I could do 7 bit.... but thats horrible!

Edit: Oh! And after finding the old instructions to my SID card, I've discovered it has an adjustable volume! FAB!! I can now balance out the TED and SID music without having to turn TED music down to virtually nothing! Hurrah!!

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!

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.

XeO3: Editors.

I'm taking a small break to play a bit more with my C# stuff. I've gotten the Plus/4 sprites loading in, so now all I need to do is scale them. But to see the results, I thought I'd extend the program I was doing into something a little more useful. Something that can load in sprites, characters and XeO3 style maps. I may even add editing to it at a later date.

Once I have the drawing working, I'll write a quite scale function that'll allow me to save out full size C64 sprites - although they'll be a bit rough around the edges. The biggest issue I have with XeO3 on the Plus/4, is that I can't view or edit sprites easily, Luca has to make little Plus/4 programs that show his work animating in a self contained PRG, which is far from ideal - so I hope this will help a bit more.

Level editing is also a concern as the current one was created by "FatMan", and he has long since vanished. So now we really need to be able to create one outselves, particually if we want others to make new levels or even games out of it.

I'll have to watchout when doing this program, as the temptation is to make an all singing all dancing app, which will take longer to write than the game itself. If I was doing an editor to "sell", I guess I would make everything variable and portable. But the idea is to keep the goal in mind, and not get too carried away with what should remain, a simple XeO3 editor.

Sunday, October 08, 2006

XeO3: C#

So, I thought it was about time I got the full benifit of the Multiplexor, so I'm about to do a small c# program (my latest language of choice) to convert into the proper format, and scale it up to the required size. Now the aspect will obviously change, and it will look a bit naff.... but it'll help "fill" the screen with sprites AND give me a basis for converting over Luca's art in the future.

On another note, I was speaking to TNT over at Lemon64 and we got into chatting about old programming diarys from ZZap days, anyway he reminded me about the Citadel one as well as the Morpheus one I've just read. I seem to remember this one being pretty cool to. He's currently doing a supped up version of Paradroid and I'm trying to persuade him to do a diary as well. I love reading techy stuff like this, and I'm sure others do to. These days games are such a closely guarded secret that you never get to hear the gritty details which is a shape. Also things are now so complicated that it can take weeks to do the smallest thing which doesn't make for good reading.

If you have an opinion on this, or if you like reading this kind of stuff, then let me know and perhaps I'll start to try and push more people to keep retro coding blogs.

Saturday, October 07, 2006

XeO3: A job well done....

Okay, I spent a little bit of time optimising the IRQ side of the multiplexor, and I can now get a sprite within 10-11 lines of the other set. Thats not bad, not bad at all (I seem to remember Blood Money being almost 20). This should be more than enough for a game. I more or less copied Dan's IRQ model for this (although I did a macro with some paramaters rather than having to maintain a whole chunk of code) and I've gotten it down to the barest minimum I can get away with. Heres the macro I used, which if you compare with Dan's, you'll find it quite close with only minor changes. If I had a couple of these, I could save an extra 4 per sprite - but thats excessive :)

;
; \0 = sprite number ( 1,2,3,4,5,6,7 )
; \1 = x+y offset ( 2,4,6,8,10,12,14 )
; \2 = NEXT sprite ( 2,3,4,5,6,7,1 )
; \3 = "b" for bcc or "j" for jcc
;
sub_amount equ 10 ; number of lines before a sprite needs to be setup


SetUpSprite macro
DoSprite\0:
cpy #\0 ; is this the Hardware sprite we're after?
bne NextHWSprite\0 ; not THIS sprite ->jump to next


SkipCPY\0:
lda XTable,x ; Store the sprites "X" coordinate in the
sta $d000+\1 ; VIC hardware sprite register


lda $d010 ; get all sprite significant bits
and #~(1<<\0) ; mask OFF this one
ora XSig,x ; already set for the correct bit!
sta $d010 ; so we OR in this sprite and store it!


lda YTable,x ; Get sprite Y coordinate
sta $d001+\1 ; store in VIC hardware register


lda XShape,x ; get the sprite graphic
sta HWShape1+\0 ; Since we have a double buffered screen,
sta HWShape2+\0 ; we store it in BOTH locations.


lda SprCol,x ; Get sprite colour
sta $d027+\0 ; store in VIC hardware


inx ; next sprite in list
ldy #\2 ; next hardware sprite


lda YTable,x ; Get sprite Y
jeq EndOfSpriteList2 ; 0? If so all finished
sbc $d012
cmp #4 ; do we HAVE enough time for another IRQ? (magic number)
\3cc SkipCPY\2 ; if not do it now!


;
; If we've lots of raster time until the next sprite
; but the sprite we will be copying over was already drawn
; by the VIC, then just copy it over NOW!
;
;sec ; Carry is ALREADY set
lda $d012 ; Get the current raster
sbc #22 ; -22 gets us the last "safe" sprite
sbc $d001+(\2*2) ; location. Now subtract the next sprite Y
\3cs SkipCPY\2 ; is > last sprite, then setup NOW!



;
; If its further down the screen, and the current sprite
; is still being drawn, then setup a new IRQ just above the
; sprite to handle it
;
;sec ; dont set carry, we'll offset this in the SBC
lda YTable,x ; if we can't copy now, then we set up
sbc #sub_amount-1 ; a new RASTER IRQ based on the next sprite (-1 for SEC)
sta $D012 ; and its Y coord.
jmp EndMultiIRQ ; and then this starts all over again!


NextHWSprite\0:
endm


I may not have mentioned this to the C64 guys, but once the game is finished, I plan on giving the source out, along with some documentaion that should allow others to either skin it quickly into another shooter, or to hack it into something completely different. I've always thought that the main problem with the scene was that good games take time, so no one can usually be bothered to make one - and when they do, they feel completely attached to the source and want to keep their master-peice. So I decieded from Day 1 of the Plus4 version that it was all going to get released. There no money in it, so why hold on to it when it could do so much good the scene.

That supercpu shoot-em-up is a good example - I wonder how much they actually made from it.... whats the point? I'm even trying to keep the comments up to date!! So don't say I'm not good to you all!!

Also, if theres anything I've touched on that anyone would liked explained, then just drop a comment letting me know, and I'll try to post something more about it.

XeO3: Multiplexor V1.0

Well, the first version is done and although it still needs seriously optimised, it's in and working. I ended up using a slight hybrid between the one from Blood Money, and Dan's one from Armalyte. I loved the way he gathers sprites into blocks IF the hardware sprite your going to overwrite next has finished rendering, then it doesn't bother with a new IRQ, it just does it anyway! Very cool. I'll probably unroll the multiplexor IRQ and that'll help me get sprites closer to other ones. It looks like I'll have to redo a few paths from the Plus4 as they are a little close for the multiplexor (since they're 16x16 and not 24x21); theres an advantage to having software sprites... Still, it'll probably make the games a little different so you can have fun playing them both!

I'll probably try and get a C64 teaser done soon now, but I still have a couple of bugs to fix on it - and the sprites are still all actually only 16x16, even though its displaying 24x21! I might just "scale" them for now, just so they fill more of the screen.

Luca has also said he's not really interested in doing any changes for the C64 version - he's a Plus/4 man through and through, so nearer the time I'll be on the look out for a dedicated C64 artist to add some spit and polish.

Friday, October 06, 2006

Xeo3: Vice...


Well, thanks to the comment made the other day, I've managed to add symbols to VICE. Since I use my own assembler, it was a quick 10 min job to get the symbol table exported in the VICE format. This does help when trying to track down odd bugs so its very much appricated - whoever it was (names on the comments would help!). Although not being able to have a memory window is prehistoric!!

I've got the basic flow of the Multiplexor in, so now I need to test the start of it, and then start generating interrupts. I can test the beginings since I copy in the first 7 sprites in the list to save having to do early interrupts. Its also a good way to start, it lets you see if things are progressing the way you expect.

Xeo3: Multiplexor...

I've been sitting here playing with a C64 multiplexor - boy has it been a long time since I did this! Actually, reading about Dan's one from Armalyte is what got me doing the port in the fist place. Armalyte was probably the best looking game to come out on the C64, so I had a read through his source and got back in the mood. Pretty interesting it was too, I'd never really used the stack much since I tended to stick to zero page lda/sta as it was one cycle quicker, but his multiplexor sort approach was novel. So, I did some tests on it and compared it to the one I had in Blood Money... His varaied quite a lot and either gained a few scanlines or lost a few depending on sprite order etc. Mine is pretty much static (unless theres < MAXSPRITES on screen, in which case it gains) so I've decided to stick with mine for now, particually since it does a proper sort, while Dan's is an approximation (which is usually good enough for a multiplexor).

So now that its all sorted, I'm just about to start on the actual fun stuff! Building new raster interrupts based on where a sprite needs to go. When I first used this in Blood Money (after hacking Armalyte to find out how he did it), I thought it was very cool indeed. In fact, it took me a while to actually believe thats what he was doing - very cool stuff. In Ballistix, I'd gone with a static array as documented by Braybrook in Morpheus, and since I HAD to control 32 sprites for that, it was probably a fairly wise course of action. But for Blood Money, I could use something more flexible, and after seeing Armalyte, I just had to know how he did it.

Anyway, I'm about to do it again. I'm not quite sure if I'll follow his IRQ routine either, as I hate maintaining large unrolled loops. Im sure at some point in the future I can unroll it if I need to.

OH! And I've just discovered a 4th C64 that I have, and its the older ones with the original SID chip in it, so I can at last listen to all the old classics on the machine itself! Ahh...bliss.