Search the Community
Showing results for tags 'Reindeer Rescue'.
-
In the latest episode, Red and I discuss Christmas-themed Homebrews, all of which can be purchased here on Atariage.com. I was just amazed at how great the quality of the games are on Stella's Stocking. Can you imagine putting five games on one cartridge back in the day? Amazing work but some really talented programmers. I hope everyone has a Merry Christmas, and I want to thank everyone for their support, comments, suggestions, views, and subscriptions. It means a lot to me.
- 3 replies
-
- 8
-
- Stellas Stocking
- Stay Frosty 2
-
(and 2 more)
Tagged with:
-
AND, OF COURSE, it was my own buggy code all along. :roll:I have to run pretty quick, so I'll fill in the details later, but basically I committed the classic boneheaded ASM mistake: I forgot a '#' in front of a constant: lda GameFlags ora PLAYERCONTROL_BIT|SCROLLPF_BIT sta GameFlags Can't believe it. Well, mystery solved anyway.Will post fixed binary and source later. EDIT: Fixed source and binary attached. RR20060301.zip And a big thanks to Eckhard to sending me his modified version of z26 (that forced undefined bits high), seeing the problem in an emulator made it possible for me to track the problem down through the z26 log files, where I saw that the reason for the weird behavior was due to the game flags somehow becoming corrupted. It was a bit tedious, but it wasn't hard, ultimately, to track down exactly where they became corrupted; it was code that looked like this: lda bf ora CXP1FB sta bf Well, this will help me to be humble, anyway.
-
YOU GOTTA MOVE ON at some point; this is the final recap. And not much of a recap, truthfully, but maybe the one with the most content. Anyhoo, here's the source and the ROMs. Enjoy!ReindeerRescueSourceAndRoms.zip
-
MORE DEBRIEFING of Reindeer Rescue. It was such a whirlwind putting this together over the last month that I feel a bit wrung out right now. I'm hoping to write some of the development stuff down here to try to remember and try to collect my thoughts. So anyway. Here's a description of the kernel and how it works. First, a picture: The kernel has four main parts. The top part is the horizon, where the sky, the sun, the snowman, the snowmobile, and the hills are drawn. The sky is the background, the hills are the playfield (duplicated, symmetrical), and the other three objects are the players. The sun is stationary; the snowman and the snowmobile move from right to left. The sprite used for the sun is repositioned to draw the snowmobile. The real tricky part was this: the snowman/snowmobile scroll off the screen (completely) and then a new object replaces each of them on the right. I am using the whole width of the screen; how can I scroll something off/on the screen? Well, each of the two objects has a dedicated variable which is used to mask them. It was pretty tricky figuring out how to set up these variables, but the code to draw them is pretty simple: Screen4 ; jsr Ret3 jsr Ret3 ;+24 51 lda (Temp),Y sta.w PF0 ;+9 60 lda (Temp+2),Y sta PF1 ;+8 68 lda (Temp+4),Y sta PF2 ;+8 76 lda (MidSkyDataPtr),Y and MSOMask sta GRP0 ;+11 11 lda (LowSkyDataPtr),Y and LSOMask sta GRP1 ;+11 22 dey bpl Screen4 ;+5 27 The masking variables are MSOMask and LSOMask. Another thing that made the kernel tricky was this: You may notice that I claim that I repositioned the sun sprite to reuse it for the snowmobile. How is there, then, no HMOVE blank? Well, because I hit HMOVE early, ending at cycle 73, that's how. Actually, every HMOVE I strobe in the entire game is hit at cycle 73. This made the kernel a little convoluted, but this gave me the most headaches when I was figuring boundaries for sprites - because hitting HMOVE early moves all sprites 8 pixels left of where they would normally end up, when a sprite had an X-position of 3 it really ended up on the right side of the screen, at pixel 155. Anyway, moving on. After the horizon is drawn, the playfield is erased and its color is changed to match the background, and both sprites are repositioned. Player 0 is used to draw Santa, and player 1 is positioned to draw the reindeer. I also wanted the reindeer (and other flying things) to scroll smoothly on and off the screen - but, again, you can't really do that, since if you scroll things off the left edge of the screen they just show up on the right. So what I ended up doing was using PF0 to hide the sprites when they scroll on and off. So for about 20 scanlines PF0 is drawn on the left and then for the next 20 scanlines PF2 is drawn only on the right. So the playfield priority is changed so that the playfield appears in the foreground (after being in the background behind the snowman/snowmobile). This means that flying objects need to scroll onto the screen from the upper right and scroll off the screen in the middle left. But the effect is pretty cool. After these ~45 scanlines, the reindeer-sprite is repositioned and we begin the real fun part: the scrolling playfield. There are 8 bands of scrolling playfield, of varying heights, covering the next ~60 scanlines. For the top 7 scrolling bands, only the playfield and Santa are drawn; during the bottom band those are drawn plus the abominable snowman (A. Snowman). The scrolling playfield is stored in RAM; 8 bands, each with all six playfield registers drawn to, means 48 bytes. The Running Man demo used 10 bands with another column (of 10 bytes) which contained the data that was being scrolled onto the screen. I couldn't afford that much RAM for the playfield, so I cut it to 8 bands and rewrote the scrolling routine to keep track of how many bits had been scrolled on so I could pull the new data directly from the ROM one bit at a time. A. Snowman moves at exactly the same speed as the scrolling playfield; in four-pixel jumps. A little jerky, but still looks ok. After that is the floor, drawn with the background, then the string of Christmas lights, the score, and the Santa hats, all drawn with a general purpose subroutine I wrote that draws 48-pixels-wide bitmaps to the screen. That subroutine wasn't real hard to write, but it made creating the title screen, the game-over screen, the game-winning screen, and this section of the main kernel much easier. Just set the pointers to the bitmap and color data, set Y for how tall the bitmap is, and call the subroutine. It also made adding the score/hiscore to the title screen, game-over screen, and game-winning screen a breeze.
-
JUST WHEN I THOUGHT I WAS DONE it turns out I'm not. Anyway, I'll just reproduce what Al wrote to me and ask: anybody have any explanations or a fix? Message Two: If anybody has a Kroc cart or a CC and want to test Reindeer Runner for me? Manuel, I'm assuming that you have already, since you ran this on a real TV to test the PAL colors.This has me baffled; it is beyond my "expertise."The only weird thing that the game does is hit HMOVE at an odd time and, as mentioned in Eric B's weblog, it outputs 270 scanlines (NTSC); I do store the value of CXP0FB in RAM halfway down the screen (right before drawing the string of Christmas lights) and then use that stored value to process collisions between Santa and the playfield; so I suppose that maybe that value is being corrupted or lost somehow...? I dunno.Help? (Note: I'm going to post this same thing on the [stella] list...) EDIT: This is the pic referred to in comment #58:
-
AS MANY OF YOU are probably aware, I have been working on the AA Holiday Cart for the past month or so. I was keeping this a secret up until I was positive that I was going to get it done; but here's a condensed history of its development. The new game is titled Reindeer Rescue, and it is based on the demo I wrote about a year ago called Running Man. As I mentioned to Manuel a couple of days ago, it has been interesting going back to the very first thing I ever wrote for the 2600 - I think if I was starting from scratch to write Reindeer Rescue today, I would quickly abandon the project because I would not believe that I could write a kernel to do what I want. Specifically, the scrolling part of the kernel. First, let me explain briefly: The bottom half of the play area of the screen has 8 bands of horizontally scrolling playfield and two sprites. One sprite (Santa) can move freely throughout this area and is a multicolored sprite; every line of this sprite can be a different color. The other sprite is restricted to fitting inside the bottom band and is a single color.Each scrolling playfield band can be a different height. At the time, I had no qualms about writing a separate minikernel for each scrolling band - which means that this section of the kernel, about 60 scanlines, is 1K of code! If I were writing it now I would try very very hard to get the whole 60 scanlines in a single loop - and I think, ultimately, would decide that it couldn't be done without some kind of compromise (striping playfield, flicker, something). Anyway. I don't know if that makes any sense, but it was very interesting to look back at my first 2600 code. I ended up rewriting just about everything except the kernel, actually. The only major changes I made to the kernel were to rewrite the sprite-drawing code to use illegal opcodes (dcp), and to squeeze in line-by-line color changes of Santa all the way to the floor (previously, the runner's color couldn't change during the bottom band). This allowed Santa to have black boots, instead of running in his socks. This was an extremely rushed development! I didn't really start modifying the original demo until I heard back from Al that he wanted me to go ahead with this; after the Philly vgXpo. So I pretty much wrote all of it in a month Which explains why I was still making changes and testing things this morning. Also explains why the code is so sloppy and why I never got any other sound effects in except for Santa running and jumping. And when you get points. I really wanted to get a couple of squawks, roars, and zzzzaps in there (the code for playing sound effects is in there, but never gets called and there is no sound effects data to play if it did get called). Oh well. Maybe someone can hack some stuff in there someday. By far the trickiest part was handling collisions. There were a couple of big issues: 1) When I began development (mid-November) it was possible to back into the scrolling playfield. This was a problem because I didn't have an easy way to tell if you hit playfield from the front or the back, so I always moved you backwards if you touched playfield. This meant, though, that if you backed into the playfield it sucked you backwards and through whatever you touched! Not good. Eventual solution was to check the RAM locations where I stored the playfield data to see if there was a block of playfield behind you before I let you move backwards. 2) Because Santa leaves the ground completely in his running animation, it is possible, though difficult, to move Santa so that he ends up sticking his boots into middle of a playfield block. The picture below will hopefully help explain what I'm talking about: on the left, Santa is in a frame of animation where his feet would normally be off the ground, but his feet are flat on the ground. The right side shows what happens when his frame of animation changes to one where normally his feet would be flat on the ground: they are drawn below the ground. This is a problem because it looks really weird to make a jump and it looks like you cleared it when suddenly the game behaves like you hit a playfield block and pushes you way back. This was very tricky to fix. In a brilliant move, since I hadn't seen the problem crop up at all since I changed from the running man animation to the running santa animation, I assumed/pretended that it had magically fixed itself. Well, what do you know, Nathan discovered that it did, indeed happen. And he discovered it last Saturday. So I was up very late on Sunday fixing this problem; what I ended up doing was changing the sprite images of Santa with his feet off the ground - I added a horizontal bar on the lowest line, so that even when his boots were off the ground, there was still a piece of sprite to collide with the playfield and prevent Santa from sticking his boots into the ground. The real trick was that I didn't want this bar to show up on screen, so it needed to be the same color as the background. That would be easy, except that there are 4 different background colors throughout the game, there isn't time to change colors dynamically during the kernel, which necessitated 9 new color tables for Santa! And each of these 23-byte tables needed to be a certain distance from the front and back of a page, plus I had already used up all the open spots for graphics data in the bank with the kernel. Fortunately, there was room in the bank to stick pieces of the kernel, so now the kernel jumps from place to place inside bank 1 like a crazed frog. Those were the biggest pain in the neck to solve but there were plenty more just like it. Alrighty; this post has gone on long enough. I'll close with an overview of where things are in the ROM: Bank 1: Code that runs on poweron: clears registers, RAM, and TIA, and sets stack pointer. Initial setup stuff. VSYNC and the vertical retrace portion of the display, though this mostly calls subroutines that are in other banks.The play area of the kernel. Everywhere that Santa can go is drawn in this bank. Also, the portion of the title screen that draws Santa and the reindeer is in this bank. See the diagram: Everything inside the red line is drawn in bank 1. All the graphics that go inside there are in bank 1. Bank 2: The routine that scrolls the playfield plus all the level data. Also all the subroutines called during the vertical retrace are in this bank: Updating Santa's energy, reading the console switches, updating the score, moving the non-player-controlled objects, the subroutine that sets up a new level, and a kernel preparation subroutine. Bank 3: This was originally going to be a bank for just music and sound effects. It ended up with those routines, and their data, plus all of the overscan. The overscan is where I deal with collisions, move Santa, play music, and process most of the game's internal logic, like checking death conditions, doing whatever needs to be done when you beat a level, etc. The kernel for the part of the screen above the red box in the diagram above is also in this bank, and the graphics for this part of the screen are here as well. Bank 4: All other assorted kernels and pieces of kernels are here: the title screen kernel, the game over kernel, the game-winning kernel, plus the kernel for the area below the red box in the diagram above. Since all of those kernels make heavy use of 48-pixel-wide bitmaps, all the data for those bitmaps is here as well as a subroutine to display 48-pixel-wide bitmaps.