Jump to content
  • entries
    657
  • comments
    2,702
  • views
    904,419

release candidate 3


SpiceWare

2,568 views

  • fixed the synchronized rotation issue with large asteroids

When I first started coding Space Rocks, I set it up to support an arbitrary number of styles for each size of asteroid as I didn't know how many would end up in the game. So I wrote the original InitWave routine like this to select a random asteroid style, rotation and speed:

 gSpriteAnimSeqID[i] = LARGE_ASTEROID_SEQ_ID + ((LARGE_VARIATIONS * (Random32() & 0xff)) >> ;
gSpriteAnimControl[i] = RandomRotation();

 

LARGE_VARIATIONS is defined as the number of styles, say 2, 3 or 4. The multiplication with Random32(), combined with the masking (&) and shifting (>>) results in 0-1 for 2 styles, 0-2 for 3 and 0-3 for 4.

 

I thought we'd end up with 3, maybe 4, but the graphics took more space than I was expecting so we ended up with just 21 styles (and we even had to reduce the number of rotation positions from 32 to 24.) As ROM grew ever tighter, I started optimizing the code and rewrote that section like this:

 gSpriteAnimSeqID[i] = LARGE_ASTEROID_SEQ_ID + (Random32() & 1);
gSpriteAnimControl[i] = RandomRotation();

 

Because the style of asteroid and the rotation were in sync with each other (so that style A rotates one direction and B the other), something had to be going on in RandomRotation(). At first glance it's not obvious what it could be:

unsigned char RandomRotation()
{
// bit 7 controls rotation direction, 0-6 speed
// rotation speeds 8-23
return ((Random32() >> 24) & 0x8F) + 8;
}

 

 

In computers, there's no such thing as random. We simulate random using various techniques, and the one I'm using in Space Rocks is known as a Linear Feedback Shift Register (LFSR). The specific implementation I'm using is the Galios LFSR.

unsigned int Random32()
{
static unsigned int random = 0x02468ace;

return random = (random >> 1) ^ (unsigned int)(-(random & 1u) & 0xd0000001u);
}

 

In looking at the init wave routines, bit 0 of the random number is being used to determine which asteroid style is drawn.

 

In looking at the rotation/speed routines, bit 31 of the random number is being used to determine the direction of rotation.

 

In looking at the random number routine, the prior random number is manipulated in such a way that the inversion of whatever was in bit 0 is now in bit 31 (if bit 0 had 0, then bit 31 will get 1. If bit 0 had 1, 31 will get 0). This link between bit 0 of the prior and bit 31 of the current random number is what caused the rotation and style to be in sync.

 

To fix the problem of synchronized rotations, I modified RandomRotation to use a different 8 bit segment of the LFSR as such:

unsigned char RandomRotation()
{
// bit 7 controls rotation direction, 0-6 speed
// rotation speeds 8-23
return ((Random32() >> 16) & 0x8F) + 8;
}

 

 

1there's really 4 styles as each style is available in solid or vector format.

 

 

ROMs

spacerocks20121004_NTSC.bin

spacerocks20121004_PAL.bin

 

Note: if you have a Harmony, please run the Stress Test ROM on your real Atari so we can make sure the screen jitter and rolling problem has been resolved.

 

spacerocks20121004_STRESS_TEST.bin

 

Source

spacerocks20121004.zip

29 Comments


Recommended Comments



did the P1EarlyHM58 and changed the sleep2/jump to dec Sleep5. Also shifted some things and bank 5 free space is now: 1, 1, 0, 109. I should be able to shift 3 (possible 4 due to overlapping) large asteroid graphics from the ARM bank to bank 5.

 

Original hyperspace delay was 75, it's now 40. That calculates out to a 2.7 second delay, 2.3 effective when considering the .4 seconds of warp-in.

 

Now to see what I can do to add "shield recharge" logic :)

Link to comment

I have the shield recharge logic in place with some diagnostics in the second score to show me time remaining. Going to do some playtesting tonight, and possible tomorrow, before I post Release Candidate 4.

 

 

I set it up so that the recharge rate is half the usage rate. This means if you use the shields for 1 second, it takes 2 seconds to recharge. You can use the shields again before their fully recharged as such:

  • Initial shield level = 3 seconds remain
  • Use for 1 second, 2 seconds remain
  • don't use for 1 second, 2.5 seconds remain
  • use for 1 second, 1.5 seconds remain
  • don't use for 1 second, 2 seconds remain
  • use for 1 second, 1 second remains
  • don't use for 4 seconds, 3 seconds remain (full strength)

Link to comment

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...