Sprite Routine

flash · 20299

Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
on: January 20, 2009, 08:27:19 am
This is how we are going to have to address the sprites internally, then using a sub to convert the data to sprite display on the relevent screens with the modified coords. On a sprite between 2 screens - 2 sprites will be used to display the sprite as it passes between the 2 screens.

« Last Edit: January 21, 2009, 10:41:48 am by Flash »

Coding for the love of it!


Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #1 on: January 20, 2009, 02:04:55 pm
Further to the last post, I have worked out the code to do the sprite possitioning on the 2 screens.
The demo posted here (though basic) uses a single sprite to fall through the two screens using the coords shown above. In No$gba, this works as intended, but in Dualis and iDeaS - there is a 2 pixel overlap between the screens. I believe this is a fault with the emus and not the code!  :-\
When the sprite hits the base of screen 1, 2 sprites are used - one on each screen, until the overlap has passed and then the sprite is moved to the base screen.
The code also handles off side sprites without recourse to negative numbers - makes things a lot easier.
I will pehaps offset the Y pos further, so to add coords above the top screen to handle the mapping of oncoming enemies. This would also make the attack waves a BREEZE to coordinate. The entire wave could be set up off screen and then jusr "let go!".

Ok, for those who look at code - this is a basic first draft and has a lot of expansion to be done to it!
Ie. This will only work with sprites with a maximum of 32 pixels high. Not much use for the far larger bosses! This is easily modified though ;)

PS. Was really trying to put this off... It was a lot easier than i expected! A bit like writing a multiplexor on the c64!
« Last Edit: January 21, 2009, 10:50:07 am by Flash »

Coding for the love of it!


Offline BaDToaD

  • Proterian
  • Dragon 32
  • *****
    • Posts: 76
Reply #2 on: January 20, 2009, 04:03:52 pm
I love how you can bang the metal and call it easy. You always did freak me out you weirdo ;)

I still remember going to bed with you programming away in your room only to get up in the morning and find you still at it... LOL



Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #3 on: January 20, 2009, 04:38:44 pm
That was because I am slow!!! :D  :D  :D

It is nice to code in ASM and not have to rely on C to transcode the program to IT'S interpretation. In ASM you write your own code to do a routine rather than someone else library!

Got to love it!!! :)

Coding for the love of it!


Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #4 on: January 20, 2009, 07:36:08 pm
Had another thought about the sprite coord system,If I can work this, then all attack waves can be pre-placed in whitespace and then set in motion!This would be a much easier way of doing it!
« Last Edit: January 21, 2009, 10:32:46 am by Flash »

Coding for the love of it!


Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #5 on: January 21, 2009, 10:58:38 am
Ok, got the code working as intended! Phew! We now have a really nice 384x384 offscreen area in which to construct our attack waves. Once the sprites are placed there, we can move them as if they where active and they will apear on either screen when they reach the screen areas! The code was fairly easy, though at the moment it will only work with sprites of X by32. So, the Y res can only be 32. This is not very good when we want to have 8 pixel bullets and 128x128 pixel motherships. The code can easily be modified to enable any size X and Y though!
Code: [Select]
ldr r0,=OBJ_ATTRIBUTE0(0)
ldr r2, =(ATTR0_COLOR_16 | ATTR0_SQUARE)
ldr r3,=576-32
sub r1,r3
cmp r1,#32
addmi r1,#256
sub r1,#32
and r1,#0xff @ Y is only 0-255
orr r2,r1
strh r2,[r0]
@ Draw X
adrl r0,[spriteX] @ get X coord mem space
ldr r1,[r0] @ add ,rX for offsets
cmp r1,#64 @ if less than 64, this is off left of screen
addmi r1,#512 @ convert coord for offscreen (64 each side)
sub r1,#64 @ Take 64 off our X
ldr r3,=0x1ff @ Make sure 0-512 only as higher would affect attributes
ldr r0,=OBJ_ATTRIBUTE1(0)
ldr r2, =(ATTR1_SIZE_32)
and r1,r3
orr r2,r1
strh r2,[r0]

If that makes any sense?

In the code I have used 32 directly rather than muddling it in with the calculations so it is easy to change to a variable for sprite Y size.
« Last Edit: January 21, 2009, 11:01:26 am by Flash »

Coding for the love of it!


Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #6 on: January 21, 2009, 03:33:38 pm
Ok, sprite code works with the new coord system and also allows for varied sprites and numbers.
So, you can position 128 sprites and have a different image in each and put them anywhere!

Doesn't look very exciting, but it does pretty much underpin a shootem up!

PS. Just realised that I have instinctively put 8 sprites on the screen  ;D

PS2. The code is writing all the sprite data to BUF_xxxx registers. At the moment these are indexed to the real registers, but will be switched to a buffer later. This is so the real registers can be bulk updated in the correct place so that they update correctly on a real DS. You cannot update during Vblank (or the other way round). This is why our sprites stay at 0,0 on a real DS - the coords cannot be updated. This is called - forward thinking... I try to do that now and again ;)
« Last Edit: January 21, 2009, 06:20:57 pm by Flash »

Coding for the love of it!


Offline headkaze

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 7838
Reply #7 on: January 21, 2009, 07:52:41 pm
Great demos Flash, just been checking them out. I feel like I'm falling behind a bit but there is still plenty to do.

Are you sure you can only update sprites during vblank? Sound a little strange. In libnds they have an area for OAM data that is updated all at once as well, so your probably right there.

Looking good :)

PS. I find myself working in power of two's all the time, and it makes sense to think like that when your coding ;)



Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #8 on: January 21, 2009, 07:57:37 pm
Glad you like the code! It is getting there!
It is only a fairly small step to move this into the main code and add firing, then from there (trickier) background collisions. Then attack waves....
So, I am trying to think ahead with everything so that all routines can coordinate to create the whole.

I am sure I read some where that you can only update it in the vblank (or out of it?). Take this example - no vblank. Main game has, and it is not updated!


Coding for the love of it!


Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #9 on: January 26, 2009, 11:55:36 am
What would be really great is:-

To take the sprite rotate code, make it flexible and integrate it into the spriteDraw routine.

We could have another line of 128 bytes for Angle. This could be read by the draw code and the attribute applied.

Bet ya $5au you can't/can work it out (delete whichever results in me winning)  ;D

Coding for the love of it!


Offline headkaze

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 7838
Reply #10 on: January 26, 2009, 01:44:58 pm
It would be easy to do IMHO. The sprite and sprite_rs demos are very similar. The only difference is to set a few extra bits, some extra initialization and maintaining special areas of OAM for the rotation. I've already made a set of macro's to make accessing this all pretty easy.

Do we really want sprite rotation in Warhawk? If we need it I'll implement it no problem.



Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #11 on: January 26, 2009, 03:09:32 pm
I think it is worth adding to the warhawk drawsprite code. It is the code that draws the sprites on top/bottom or both depending on position. If in the middle of the 2 screens, both sprites needs updating.

We could add spriteRotate with 128 bytes and set the relevent sprite to the angle we want for each. It may be used for ship death (sprin it round and crash with explosion) and also end of level bosses could rotate (perhaps)

still it will be a nice adition to our sprite code that may well get used on other things..

Coding for the love of it!


Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #12 on: May 06, 2009, 10:35:28 pm
I have a feeling this topic is a bit dead?

Is it worth removing it or is the data on the drawsprite code still valid?

Coding for the love of it!


Offline sverx

  • RBP Member
  • IBM PC
  • *****
    • Posts: 516
  • "Ow!!! What's that ?!?!"
    • My NDS folder
Reply #13 on: August 26, 2009, 07:26:40 am
Very interesting topic! Even if it's abandoned, I would like to add a detail: yes, sprites can be rotated (and even scaled!) on a DS, but that can't be done in a 'per sprite' base. Instead, there are 32 classes: each class has its rotation/scaling matrix (4 halfwords) and a sprite which has the ATTR0_ROTSCALE attribute bits should also have a class specified thru ATTR1_ROTDATA(n)  (0 <= n < 32).
So a little bit more of trickery is needed :)

Bye!




Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #14 on: August 26, 2009, 07:33:45 am
It is a shame that all 128 sprites cannot have individual rotation values.

One way round that is to use 3d. Have a flat texture (spaceship picture) mapped to a single plane and rotated that. Then everything could be rotated.

Coding for the love of it!


Offline sverx

  • RBP Member
  • IBM PC
  • *****
    • Posts: 516
  • "Ow!!! What's that ?!?!"
    • My NDS folder
Reply #15 on: August 26, 2009, 07:42:13 am
Well, indeed is a shame that there's no individual rotation, btw -if you don't need scaling- it's possible to define the classes with values that would split the 360° in 32 parts (will be 11,25° each) or even in 24 parts only (so it's 15° each) and use the class as a 'rotation' value with some degrees resolution.
I bet it won't be bad, sprites are quite small after all ;)

Bye!



Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #16 on: October 01, 2009, 11:05:51 pm
What would be really nice is to be able to use hardware to rotate a sprite to a buffer and grab rotated data and dump that to an active sprite. Sadly, the rotated data is not stored to be read. :(

Would be nice to find a way to adress all 128 with rotation rather than the limited 32. Real shame.. Though I am sure there is a way round the limitation somewhere in the hardware.
« Last Edit: October 01, 2009, 11:07:13 pm by Flash »

Coding for the love of it!


Offline sverx

  • RBP Member
  • IBM PC
  • *****
    • Posts: 516
  • "Ow!!! What's that ?!?!"
    • My NDS folder
Reply #17 on: October 02, 2009, 07:06:54 am
What would be really nice is to be able to use hardware to rotate a sprite to a buffer and grab rotated data and dump that to an active sprite.

So that you can check per-pixel collisions on a rotated sprite?

Would be nice to find a way to adress all 128 with rotation rather than the limited 32. Real shame.. Though I am sure there is a way round the limitation somewhere in the hardware.

All 128 sprites can be rotated, it's just that there are only 32 possible affine matrix (rotations) at a given moment. But it shouldn't be so hard implement a system that counts all the 128 wanted sprite rotations degrees and -if they are more than 32- assigns to some sprites the closest rotation possibile... if it's well done you won't even notice that approximation.




Offline flash

  • Administrator
  • Blue Gene Super Computer
  • **********
    • Posts: 13180
Reply #18 on: October 02, 2009, 07:56:20 am
With rotation, I meant it would be nice if each sprite could have an idividual rotation value. On larger sprites the 32 limit would be much more noticeable.

Not that I can think of a reason to use rotation at the moment, though we nearly did in Warhawk.

Coding for the love of it!