Subject: [stella] How RRampage works From: "Erik Mooney" <erik@xxxxxxxxxx> Date: Mon, 12 Apr 2004 12:21:17 -0500 |
I'm bored at work and can't stop thinking about River Rampage. So I wrote up a description of how it works. :) First, player 1 and missile 1 are used to draw the player and his bullets; P0 and M0 are used for the enemies and their shots. This is because P0/M0 have higher display priority than P1/M1; you don't want your bullets to obscure things that you need to dodge. The kernel is basically a 4-line loop (it's actually unrolled to 8, but 4 is good enough to describe it): Line 1: reposition P0 if necessary Line 2: do a bunch of calculations Line 3: reposition M0 (this always happens every 4 lines) Line 4: on every other iteration, HMOVE and display the player's bullets (so every bullet is 8 scanlines tall) NUSIZ1 is set to draw the multiple copies of the bullets, of course. The trick is that P1 and M1 are never fully repositioned during the screen - they're only HMOVEd, so we can reposition from one bullet to the next using only a few instructions instead of an entire scanline for each object. But the bullets are independent - what if you shoot, stop shooting, and shoot again so that there's a large horizontal space between successive bullets? The answer is that the game keeps calculating and HMOVEing invisible bullets on all the inbetween lines, even when you're not shooting, using GRP1 and ENAM1 to turn them off when appropriate. It initializes a new bullet every frame whether or not the joystick button is pressed. As for P0, I actually only reposition it every *four* lines, yet it still has single-line resolution. That's done through the indirect-indexed pointer to the sprite graphics. Every scanline does an indirect-indexed graphics lookup and store to GRP0. Every enemy sprite image in ROM is padded with three extra bytes of zeroes; and if necessary the code can adjust the pointer by up to 3 bytes.[1] So after the repositioning, we can keep writing 0 to GRP0 for up to three additional lines until it really is time to display the object. Similar idea to the hardware VDEL registers, but much more flexible and powerful. To make the GRP0 handling as fast as possible, I'm not even using SkipDraw. When the kernel reaches the end of a player object (this check runs once every 4 lines), it changes the high byte of the 16-bit pointer to point to an entire ROM page full of just zeroes. Then all the GRP0 lookups will just grab zeroes until we reach and initialize a new enemy object while scanning down the screen. ROM is plentiful, cycles aren't. :) This results in being able to have any vertical distance between two enemies, instead of constricting them to a specific schedule like in River Raid. The laser is the ball. That's just positioned once, offscreen, and when the kernel gets to the player's sprite, it writes 0 to ENABL. Cake. The last trick is how P1 gets repositioned after the bullets to draw the player's plane, without any interruption to the rest of the repositioning. This is done in a way that I theorized about years ago. :) When we reach the player's plane, the player's bullets are no longer being drawn, so scanline 4 of the kernel loop is available. It uses a JMP Indirect to branch to one of 11 different versions of that scanline based on the horizontal position of the player. Each version has its instructions ordered so that a STA RESP1 is timed to hit at the appropriate time. That does the coarse horizontal positioning just as a regular delay loop would, and HMP1/HMOVE fine-tunes the position as usual, and lets it run right back into positioning P0 on the next scanline if necessary. [1]This isn't implemented just yet (which is why that demo doesn't move anything vertically), as I need to work out exactly how to allocate the Superchip RAM. It'll be easiest if I have enough RAM to set up (offscreen) a separate pointer for each enemy. Gotta find some time to do more coding this week... ---------------------------------------------------------------------------------------------- Archives (includes files) at http://www.biglist.com/lists/stella/archives/ Unsub & more at http://www.biglist.com/lists/stella/
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [stella] Use of the Bit 1 of VB, Christian Bogey | Thread | re: [stella] How RRampage works, Lee Fastenau |
Re: [stella] Finally underway: 2600, Joseph Thompson | Date | RE: [stella] Re: About your tutoria, Christian Bogey |
Month |