Well, the cache really is working well now. I've been able to strip it down from 137 entrys to 100 with out any noticable slow down. This saves around 2.5k which is great, but I may need the extra space if I want to bring on multiple baddie types at once, so I'm not about to splurge on memory just yet!
But the good news is that we're now at a point where I can FINALLY progress to the weapons system!! Everything appears to be running, and is stable, so thats going to be the next task!
Once I've done that I can look to making a new demo - PLAYABLE this time, albeit looking like mince. We don't want to give too much away on how it looks/feels so we're going to remove most of the backgrounds (make them solid blocks) and make the sprites very simple too. This will allow me to craft the difficulty a little better to users abilities and not make it too hard; which was the chief complaint with Blood Money (apparently). So while the games not really being closed to being finished, you do at least have something in the short term to look forward to!
Monday, June 25, 2007
XeO3: Sprite Cache....
Mmm...Now it gets interesting! Now that the cache routine is working properly, I can finally visualise it and see how much is used, and how it behaves... It's showing that its actually got a little room to spare - which is great as it means I can always steal some if I need to - however, that little function below that makes the cache work takes around 50+ cycles per sprite per game cycle for normal usage. That is when its not at the end or whatever... Thats 10 scanlines at least! Everygame cycle! (when all sprites are active)
so once again... its down to a balancing act - do we use the cache and perhaps get a couple of K back...or do we ditch it and gain 10 scanlines? Of course theres also an additional penalty of having to rotate the player ship everynow and then if we dont use the cache properly, and it could come at anytime, where as the cache is reasonably predictable.
It's never easy.....I suspect the cache will stay as 10 scanlines is less than rotating 1 sprite, and if I dont overload the screen with NEW sprites, I can be sure that it wont rotate + the full 10 scanlines at anyone time. I'll have a think....perhaps theres an even quicker way of doing this....
so once again... its down to a balancing act - do we use the cache and perhaps get a couple of K back...or do we ditch it and gain 10 scanlines? Of course theres also an additional penalty of having to rotate the player ship everynow and then if we dont use the cache properly, and it could come at anytime, where as the cache is reasonably predictable.
It's never easy.....I suspect the cache will stay as 10 scanlines is less than rotating 1 sprite, and if I dont overload the screen with NEW sprites, I can be sure that it wont rotate + the full 10 scanlines at anyone time. I'll have a think....perhaps theres an even quicker way of doing this....
XeO3: Internet development to the rescue!!
Well, TNT to the rescue! He spotted the problem and its not working a treat. Heres the final function, and you can see how all suggestions have been added and sped things up.
And there you go! Beleive it or not, this tiny bit of code is the whole reason XeO3 got started!! I wrote the whole sprite routine to try THIS big of code out! Stupid really... but there ya go!
Many thanks guys!
;
; Y = rotation index
; Temp+16 = pointer to the raw sprite info with an
; 8 byte cache index table
;
lda (Temp+16),y
tay
ldx Cache_Next-1,y
beq Skip_MoveToEnd
lda Cache_Prev-1,y
sta Cache_Prev-1,x
bne !We_are_Not_First ; STA above does not change flags
stx FirstCache ; X still holds Cache_Next-1
beq !SkipNotFirst
!We_are_Not_First:
tax ; NOW get prev
lda Cache_Next-1,y
sta Cache_Next-1,x
lda #0 ; Only need to clear here
!SkipNotFirst:
sta Cache_Next-1,y
lax LastCache
sta Cache_Prev-1,y ; *BUG HERE* -1 added.
tya
sta Cache_Next-1,x
sta LastCache
Skip_MoveToEnd:
And there you go! Beleive it or not, this tiny bit of code is the whole reason XeO3 got started!! I wrote the whole sprite routine to try THIS big of code out! Stupid really... but there ya go!
Many thanks guys!
Sunday, June 24, 2007
XeO3: Bloody bugs!!!
I've been writing the cache code, and its simple enough, but theres a bug in it, and I can't for the life of me find it!! So I thought I'd post it here to see if anyones got any ideas. I suspect I've just been looking at it too much; not that that helps me of course! Anyway, its a simple linked list but the indexes are all +1 so that 0 specifies the end of the list. To offset this I simply subtract 1 from the address to the links which allows the normal use again. Anyway, heres to code....
So.... There you go! If you spot anything, let me know - while I've still got hair!
;
; Y = rotation index
; Temp+16 = pointer to the raw sprite info with an
; 8 byte cache index table
;
lda (Temp+16),y ; get cache index using the current rotation index
tay ; into the sprite cache index list
ldx Cache_Next-1,y ; If we are last, then do nothing!!!
beq Skip_MoveToEnd
lda Cache_Prev-1,y ; get the PREV from our current cache block
sta Cache_Prev-1,x ; and store in the NEXT's Prev
; We've now unlinked from the NEXT item, unlink from PREV item
tax ; and set the PREV of our new one to the OLD last.
beq !We_are_First
lda Cache_Next-1,y
sta Cache_Next-1,x
bne !SkipFirst
!We_are_First:
ldx Cache_Next-1,y
stx FirstCache
lda #$00
sta Cache_Prev-1,x
!SkipFirst:
; Now link the cache block to the end
lda #0
sta Cache_Next-1,y ; get the PREV from our current cache block
lax LastCache
sta Cache_Prev,y ; Set the LAST entry as our prev.
tya
sta Cache_Next-1,x ; and set the last entry's NEXT as our new item
sta LastCache ; now set thr NEW last as the new item.
Skip_MoveToEnd:
So.... There you go! If you spot anything, let me know - while I've still got hair!
Saturday, June 23, 2007
XeO3: Microcoding
I've spent a very pleasent day slowly shifting through the sprite source and doing some micro optimisations; that is removing unneeded instructions and the odd cycle here and there. It'll have no huge impact, but it might help compensate for when I do the cache linking everyframe. The idea (as Ive said before) is when a frame from the cache is used, I remove it from the linked list, and add it to the bottom again (the end). This keeps used ones in the list, and unused ones drift to the top.
So, now I've dont this, I'll go and put the code in to actually use the cache properly and see how it all holds together.
So, now I've dont this, I'll go and put the code in to actually use the cache properly and see how it all holds together.
Friday, June 22, 2007
XeO3: Working Lunch!
The great thing about owning my own laptop is I can put the code onto it and bring it into work so I can play with it at lunchtime - fab! So, I've made the change where by I now no longer have a bitmask marking the rotations that have been cached, I now just use the cache index value directly and if its 0, then its not cached. This works great, and frees up 167 bytes (space for 4 more sprites!) Not that you really seed a speed up, but I know its a little quicker, so thats nice.
The next thing to do is to try and finally make the cache work the way its supposed to! This simply means keeping commonly used rotations in there, and letting ones I don't use much drift to the top of the free list - I hope to do that later tonight.
The next thing to do is to try and finally make the cache work the way its supposed to! This simply means keeping commonly used rotations in there, and letting ones I don't use much drift to the top of the free list - I hope to do that later tonight.
Thursday, June 21, 2007
XeO3: Sprite time...
So I'm sitting here fixing the damage I did while debugging last night, and it occurs to me that Im wasting time and memory with my sprite system - again; although not much of either this time.....
I currently store a bitmask to tell me if a rotation is cached, and an index which points to it - like this
Now, before I changed everything to indexes, the bitmask made sense, as it was quicker to check than the address. But now.... All I need to do is load the rotation index data and see if its 0. This will save 167 bytes, and all the time I spend masking the rotation flags. It will also help me speed up the cache itself - a little.
I currently store a bitmask to tell me if a rotation is cached, and an index which points to it - like this
db BitMask ; 1 bit per rotation. In MCM mode, ever other bit is unused.
db Rotation1_Index
db Rotation2_Index
db Rotation3_Index
db Rotation4_Index
db Rotation5_Index
db Rotation6_Index
db Rotation7_Index
db Rotation8_Index
ds 32 ; Raw Sprite Graphic
Now, before I changed everything to indexes, the bitmask made sense, as it was quicker to check than the address. But now.... All I need to do is load the rotation index data and see if its 0. This will save 167 bytes, and all the time I spend masking the rotation flags. It will also help me speed up the cache itself - a little.
Classic retro music on a HUGE scale....

This has to be seen (and heard) to be believed.... Not only does it look pretty cool, but its actually playing music! Click HERE to see it... Theres a tune in there I recognise, but cant place....yet.....
While we're at it... heres another scary image....
Edit: TETRIS!!! Thats it!!!
Wednesday, June 20, 2007
XeO3: Success!!!
At last!!! Found the little ******!!!!
After a really painful debug session with Yape (he really needs to make his debugger more usable!!!) I finally tracked the problem down to..........The player ship sprite! Yep... nothing to do with the cache at all - well, not really. It was the sprite rendering that fried the memory, but that was only because the player ship pointers had been nuked! Funny....Im sure this was the same bad bug as last time...I wonder if the fix got lost, I'll have to check my source control logs... Anyway, the fix was just 3 lines!
So...there we go... Crappy nights work, but worth it in the end. I'm thinking about releasing the current minus4, as its debugger is much nicer than anything else out there, and really helps.
Edit: Yep...it appears I only half fixed this the last time. I was drawing a bad sprite last time, and now it just killed it dead! Oh well...all fixed.
After a really painful debug session with Yape (he really needs to make his debugger more usable!!!) I finally tracked the problem down to..........The player ship sprite! Yep... nothing to do with the cache at all - well, not really. It was the sprite rendering that fried the memory, but that was only because the player ship pointers had been nuked! Funny....Im sure this was the same bad bug as last time...I wonder if the fix got lost, I'll have to check my source control logs... Anyway, the fix was just 3 lines!
lda PlayerAnims
ldx #0
jsr SetSpriteShape
So...there we go... Crappy nights work, but worth it in the end. I'm thinking about releasing the current minus4, as its debugger is much nicer than anything else out there, and really helps.
Edit: Yep...it appears I only half fixed this the last time. I was drawing a bad sprite last time, and now it just killed it dead! Oh well...all fixed.
XeO3: Problems....problems................problems
Still no advance on this graphics corruption and crash; I spent all of last night looking through code and playing with Minus4 to try and replicate the bug there, all with no luck. I still think it's to do with the new sprite cache initialisation code because if I run it once only, it seems to be fine. Problem is, the code looks okay to me, which means I'll have to step through all 137 sprite slots being initialised.
You know in a way, this restores my faith in development. When I started this, I had come to the conclusion that either I'd just gotten way better than when I was doing this stuff profesionally, or things were just not that hard now. But this shows that really nasty bugs can still rear their ugly heads, and are still a fag to track down. Thats not to say that its not easier over all - if I hadn't improved in the 18 years I've been doing this for a living, I'd be really worried!
You know in a way, this restores my faith in development. When I started this, I had come to the conclusion that either I'd just gotten way better than when I was doing this stuff profesionally, or things were just not that hard now. But this shows that really nasty bugs can still rear their ugly heads, and are still a fag to track down. Thats not to say that its not easier over all - if I hadn't improved in the 18 years I've been doing this for a living, I'd be really worried!
Subscribe to:
Comments (Atom)