Stellar Fortress v0.03
cdk1.zipNew Features:- 5 rotating shield rows implemented.To Do:- Add the player ship and enemy cannon.The shield code is complete. This was challenging and quite fun to work on. The shield consists of 14 rows, with 4 pixels per row. There are 14 columns per row. There are now 5 rings to the shield, and each ring rotates in the opposite direction of its neighbors. The rotation requires a lot of bit shifting. At first I tried to brute-force it, but the code was getting ugly. In the end I used a series of bit masks, and the code is much more managable. It requires about 1800 cycles per pass, but this only needs to run every 16th frame, so there's plenty of compute time left.
RotateShield LDA Frame AND #%00001111; Rotate the shield only on this multiple. BNE VBlankWait;aaaaaaa0 13 <^;bbbbbba0 12 >v;cccccba0 11 <^;ddddcba0 10 >v;eeedcba0 9 <^; edcba0 8; edcba0 7; edcba0 6; edcba0 5;eeedcba0 4 >^;ddddcba0 3 <v;cccccba0 2 >^;bbbbbba0 1 <v;aaaaaaa0 0 >^; Shift all bitfields, ignoring carry.; This will also shift the interior bits, but that will be cleared; by the clean up mask. LDX #13ShiftSideways LDA LShield,X ASL STA LShTemp,X LDA RShield,X ROR STA RShTemp,X DEX LDA RShield,X ASL STA RShTemp,X LDA LShield,X ROR STA LShTemp,X DEX BPL ShiftSideways;47 x 7 = 329 cycles; Clean up the horizontal and vertical side-effects of the bit shifting. LDX #13CleanShiftedBits LDA LCleanMask,X;4 AND LShTemp,X;3 STA LShTemp,X;4 LDA RCleanMask,X;4 AND RShTemp,X;3 STA RShTemp,X;4 DEX ;2 BPL CleanShiftedBits;3 27 x 14 = 378 cycles LDX #12ShiftUp LDA LShiftOddUp,X;4 AND LShield,X;3 ORA LShTemp+1,X;3 STA LShTemp+1,X;4 LDA RShiftEvenUp,X AND RShield,X ORA RShTemp+1,X STA RShTemp+1,X DEX BPL ShiftUp;33 x 13 = 429 cycles LDX #1ShiftDown LDA LShiftEvenDown,X AND LShield,X ORA LShTemp-1,X STA LShTemp-1,X LDA RShiftOddDown,X AND RShield,X ORA RShTemp-1,X STA RShTemp-1,X INX CPX #14 BNE ShiftDown;35 x 13 = 455 cycles; Copy the temp buffer into the main shield memory. LDX #13CopyShield1 LDA LShTemp,X STA LShield,X LDA RShTemp,X STA RShield,X DEX BPL CopyShield1;------------------------------------------------------------ align 256;Left side, shift odd bits up. Note, these are in reverse order of RAM.LShiftOddUp dc.b #%00000010;0 dc.b #%00000010 dc.b #%00001010 dc.b #%00001010 dc.b #%00101010 dc.b #%00101010 dc.b #%00101010 dc.b #%00101010 dc.b #%00101010 dc.b #%00001010 dc.b #%00001010 dc.b #%00000010 dc.b #%00000010; dc.b #%00000000;13 Placeholder. Not actually used.;Right side, shift odd bits down.RShiftOddDown dc.b #%00000000;0 dc.b #%00000010 dc.b #%00000010 dc.b #%00001010 dc.b #%00001010 dc.b #%00101010 dc.b #%00101010 dc.b #%00101010 dc.b #%00101010 dc.b #%00101010 dc.b #%00001010 dc.b #%00001010 dc.b #%00000010 dc.b #%00000010;13;Left side, shift even bits down.LShiftEvenDown dc.b #%00000000;0 dc.b #%00000000 dc.b #%00000100 dc.b #%00000100 dc.b #%00010100 dc.b #%00010100 dc.b #%00010100 dc.b #%00010100 dc.b #%00010100 dc.b #%00010100 dc.b #%00010100 dc.b #%00000100 dc.b #%00000100; dc.b #%00000000;13 Shares byte with next mask.;Right side, shift even bits up.RShiftEvenUp dc.b #%00000000 dc.b #%00000100 dc.b #%00000100 dc.b #%00010100 dc.b #%00010100 dc.b #%00010100 dc.b #%00010100 dc.b #%00010100 dc.b #%00010100 dc.b #%00010100 dc.b #%00000100 dc.b #%00000100 dc.b #%00000000 dc.b #%00000000;Left side post-shift clean mask.LCleanMask dc.b #%11111110 dc.b #%11111000 dc.b #%11111000 dc.b #%11100000 dc.b #%11100000 dc.b #%00000000 dc.b #%00000000 dc.b #%00000000 dc.b #%00000000 dc.b #%11000000 dc.b #%11110000 dc.b #%11110000; dc.b #%11111100; Shares 2 bytes with next mask.; dc.b #%11111100;Right side post-shift clean mask.RCleanMask dc.b #%11111100 dc.b #%11111100 dc.b #%11110000 dc.b #%11110000 dc.b #%11000000 dc.b #%00000000 dc.b #%00000000 dc.b #%00000000 dc.b #%00000000 dc.b #%11100000 dc.b #%11100000 dc.b #%11111000 dc.b #%11111000 dc.b #%11111110
This implementation will be useful for assigning difficulty levels to the game. I can now easily define how many rings will be in the shield, by leaving unwanted shield sections blank. In the demo, ring #3 is blank. On the hardest level, all 5 rings will be enabled.
1 Comment
Recommended Comments