Jump to content
  • entries
    657
  • comments
    2,692
  • views
    898,671

The Story of Stay Frosty 2, Part 10


SpiceWare

1,323 views

In the prior build I had a few constants defined for allocating storage:

  • MAX_IP_WIDTH = 15
  • MAX_ELEVATORS_PER_LEVEL = 3
  • MAX_OBJECTS_PER_LEVEL = 6
  • MAX_LEVEL_CONTROL_DATA = 10

MAX_IP_WIDTH is the maximum width in bytes for Ice and Platform data. 5 bytes is needed for the width of a full screen, so a max width of 15 allows for levels that are 3 times wider than the screen. By using constants, the values can easily be adjusted - want to support a 4x level, just set MAX_IP_WIDTH equal to 20.

 

MAX_ELEVATORS_PER_LEVEL controls how many elevators can appear in each horizontal level in the level. Elevators are drawn using the ball object. The _LEVEL is how many rows of platform/ice appear on the level, with A being the topmost level. Levels within level is a bit confusing, so in hindsight it would have been better if I'd used _ZONE instead of _LEVEL.

 

Level with 5 zones:

blogentry-3056-0-00787800-1422203185_thumb.png

 

MAX_OBJECTS_PER_LEVEL controls the how many objects (fireballs, birds, presents, etc) can be in each zone.

 

MAX_LEVEL_CONTROL_DATA is used to allocate memory to keep track of the state of things within the level - things like fireball A0 is moving left (A meaning topmost zone, 0 meaning first fireball) or platform in zone B is moving right.

 

Missing was the maximum number of zones per level. I'd hardcoded everything to use 9 zones, but due to ROM becoming tight I wanted to lower that to 7. So I added a new constant:

  • MAX_PLATFORMS = 7

that in hindsight should have been called MAX_ZONES. I then revised the program to use it instead of the hardcoded 9, which netted a 300 byte savings in Display Data.

 

I then did some more work on cleaning up the staticky music. One of the problems was I originally didn't realize that STA AUDV0 should be done as soon as possible after the LDA #<AMPLITUDE command, so I had routines like this where the value for AMPLITUDE was retrieved at cycle 30, but wasn't put into AUDV0 until 49 cycles later:

 

AirLoop:	sta WSYNC       ; 3  0 - new line, cycle count starts over	sta AUDV0	; 3  3 	lda #<DF0DATAW	; 2  5 - Frosty Graphics	sta GRP0	; 3  8 update the sprite graphics	stx COLUP0	; 3 11 update the sprite color	lda #<DF1FLAG	; 2 13 nose	sta ENAM1	; 3 17 nose		lda #<DF2DATAW	; 2 19	sta GRP1	; 3 22 - update object graphic for *next* scanline (VDEL1 is set)	dey		; 2 24	cpy #10		; 2 26	bcc ExitAir	; 2 28	lda #<AMPLITUDE	; 2 30 load music data for next line	ldx DF1DATA	; 4 34 load Frosty Color data for next line	bcs AirLoop	; 3 37ExitAir:				;   29	...

Finding and fixing all those LDA #<AMPLITUDE/STA AUDV0 took quite a while, so you'll still hear static in the music for some time to come.

 

The objects (players, missile, ball) on the 2600 will wrap around the screen, which could be seen with the ice chest on level 11 of the prior build:

blogentry-3056-0-69680100-1422203726_thumb.jpg

 

When the fireballs were stationary the wrapping wasn't that noticeable, but once they started moving around it began to annoy me. I decided to use some of the Display Data RAM to apply a mask to the images in order to hide the wrap around effect. The mask works by doing a boolean AND to turn off the pixels that wrap around the screen. For the ice chest in the above photo, a mask of 252 (%11111100) would be used. In the image below, the left side shows the original image while the right side shows the ice chest after the mask has been applied:

blogentry-3056-0-80732600-1422203166_thumb.png

 

Level 11 with masking - sometimes fixing one issue (LDA #<AMPLITUDE/ STA AUDVO) causes new problems, hence the ice chest's color transition is now messed up:

blogentry-3056-0-07659200-1422203163_thumb.jpg

 

 

Nathan did some work on the Evil Bird:

And now, some birds (8x7, 4 frames):

 

The Evil Bird from Reindeer Rescue (although that one was eight frames):

bird_1.gif

 

A more sleek bird:

bird_2.gif

 

A little more animation here (but still four frames):

bird_3.gif

 

Firebird (10 lines tall):

bird_4.gif

 

while liveinabin did some more work on the label:

Hallo all!

 

I have something for show and tell! A label, no less!

 

StayFrostyII-1.jpg

 

That OK? If so, we need to get cracking on the manual text, I guess. We still on course for Xmas?

 

I thought we were still on course for Xmas 2010, so replied yes.

 

I then made a discovery for optimizing the C code:

Interesting ARM ROM usage discovery.

 

If globals(defined outside of a function) are used for the following 2 variables, the ARM ROM size is 15,808

int FROSTY_X_SPEED;int FROSTY_Y_SPEED;

there's limited space for globals, and if you use too much a "region ram is full" compile error occurs. Because of that, I started moving them into the Display Data bank using queue_init[]. I was surprised to see that the ARM ROM jump to 15,988.

volatile int *queue_int=(int *)0x40000C00;#define FROSTY_X_SPEED       queue_int[ 0x69 ]#define FROSTY_Y_SPEED       queue_int[ 0x6a ]

I was wondering if there might be a different way to do it, so I tried defining them as volatiles and the ARM ROM dropped to 15,880. Much better than using queue_int[], but still pretty bad compared to the global int.

volatile int *temp_frosty_x_speed=(int *)(0x40000C00 + 0x69*4);#define FROSTY_X_SPEED *temp_frosty_x_speedvolatile int *temp_frosty_y_speed=(int *)(0x40000C00 + 0x6a*4);#define FROSTY_Y_SPEED *temp_frosty_y_speed

Defining them as volatiles this way results in the ARM ROM being 15,824. Slightly worse than global int, but much better than queue_int[] or the initial volatile test.

#define FROSTY_X_SPEED *(volatile int *)(0x40000C00 + 0x69*4)#define FROSTY_Y_SPEED *(volatile int *)(0x40000C00 + 0x6a*4)

A lot of the data is being passed using queue[]). I've tested changing just 3 them (ones that are very noticeable, Frosty-X, Sun-X and ARM subroutine to run) and the ARM ROM is now down to 15672.

 

I changed a bunch of them and saved 976 bytes! I then modified it so the Sun & Sky color were controlled by the ARM code, they'd been hardcoded up until then. Also added the steam animation for when the snowman hit a fireball or stood on a lava platform.

 

 

Next Nathan and Thomas asked some questions to clarify the gameplay so we could start in on designing the levels:

OKay, so I've been pouring over this thread, and want to put together a comprehensive list of the game elements we've got to deal with, so we can start coming up with level designs.

 

Let me see if I've got this straight...

 

Levels:

  • Each level can be more than one screen wide.

Questions:

  • Does each wide level have to be a multiple of 40 playfield pixels wide?
  • If no, what is the minimum/maximum width you can add to a normal level?
  • What's the maximum width a level can be?
  • How many levels can we have in the game?
  • Does a level that's 2x wide take up twice the storage space as a 1x wide level? (Wider levels = fewer levels)
  • Is there space to add a moon graphic for night scenes? (I know there are no stars this time, but we can live without them.)

Zones:

  • There are up to nine horizontal zones running across the screen, which can each contain platforms, ice and one elevator.
  • The elevators can freely move within each zone, vertically or horizontally.
  • A zone height of 28 fits Frosty
  • A zone height of 24 fits a large fireball
  • 19 is the smallest zone available
  • A zone must be six lines taller than the tallest object displayed in it

Questions:

  • Is the extra six lines to account for the thickness of the platforms themselves?
  • Can the elevators cross over to other zones - provided there is not more than one elevator in a zone?
  • Is there a maximum zone height?
  • Can the number of zones change on a given screen (e.g. 9 on the left side, 6 on the right side)?
  • At a minimum, how wide do the platforms need to be?
  • Can the platforms be any number of playfield pixels wide?
  • Can the platforms be any number of playfield pixels apart?
  • Can Frosty fall off the bottom of the screen?
  • If so... can we have him fall into another level? (As a hidden level/secret room/easter egg.)

New sprites:

  • Ice chest is 17 tall, bottom 11 rows are second color (gives Frosty instant health)
  • Carrot is 16 tall, bottom 11 rows are second color (gives Frosty ability to throw snowballs)
  • Bird (evil) - height to be determined (steals Frosty's carrot)
  • To avoid flickering the above items, they must be 160 pixels (or 40 playfield pixels) away (horizontally) from the next nearest object (not including Frosty).

Questions:

  • Does the bird always put the carrot back to its point of origin, or can he put it somewhere else in the level?
  • How about if the ice chests were more than just another way to build Frosty back up? He already has ice blocks.
  • They could be the equivalent of treasure chests. His goal is to collect them all (Pitfall-like).
  • They could be power-ups. Different color chests unlock different temporary abilities. Maybe some levels would require him to smash or melt through ice barricades to exit. (This would mean adding an ice barricade somehow to the game.)
  • Ice chest power up ideas: double-jump, super-jump, unlimited (rapid-fire) snowballs, freeze enemies, un-meltability, solid-ice Frosty (for smashing things, slower melting, faster speed), fiery Frosty (he could throw fireballs to melt snow and ice), etc.

Frosty:

  • Melts when he runs into fireballs. Small fireball = melts one line (takes one hit to extinguish it). Med fireball = melts two lines (two hits). Large fireball = melts three lines (three hits).
  • Melts when moving over hot platforms.
  • Picking up a carrot allows Frosty to throw snowballs.
  • One snowball hitting a fireball has the same effect as Frosty running into a fireball once.
  • Frosty's speed/direction influence the speed/distance of him throwing a snowball.
  • Frosty can double-jump higher by tapping the joystick twice.

Questions:

  • How much does Frosty melt per thrown snowball?
  • Is the trajectory of the snowball finalized?
  • What is the range that Frosty can throw?
  • How far does he throw at a stand-still? At speed? Moving backwards? Jumping? Falling?
  • How fast does Frosty melt on a hot platform?
  • How fast does an ice block melt on a hot platform? (I could see a level where Frosty had to zip across a hot platform before all the ice on it melted, to make it safely across.)
  • Does he melt faster if sitting still on a hot platform?
  • How far does Frosty jump (vertically and horizontally)?
  • How far does Frosty double-jump?

It still seems to me that the game needs a goal, rather than being just an open-ended, repeating platformer. Whether collecting things, or battling a huge fireball boss at the end, or rescuing someone (Santa, Holly, Mrs. Frosty) there should be something to accomplish at the end.

 

I have some (noob) questions too:

- What does it take to finish a level? (reaching the opposite side or a dedicated exit, extinguish all fireballs,... a combination of those)

- Can a level wrap around?

- What's the scoring? (e.g. Do you get more points for hitting with a snowball? Or even more for hitting multiple times in a row? Do you get bonus points for remaining Frosty when you finish a level?...)

- Will there be bonus levels?

- Will there be hidden levels?

- How about power ups? (limited invulnerability, faster snowballs, swap snowballs and ice, kill all fireballs in a row, Ninja Frosty (double speed)...)

- Are there holes in the bottom? (e.g. Frosty could die then or wrap around vertically and appear at the top)

- ...

 

  • Level
  • Levels can currently be from 5-15 bytes, 40-120 PF pixels, or 1-3 screens wide. This can be increased.
  • Level data is defined by how many bytes wide it is, so the width changes in 8 PF pixel increments.
  • It's configured for 32 levels
  • One 2 screen wide level takes slightly less space than two 1 screen wide levels.
  • Yes, there's space for a moon graphic, see the bottom about the Display Data usage.

  • Zone
  • I reduced the # of zones from 9 to 7 to buy back some space in the Display Data bank.
  • The six lines are 3 lines for platforms themselves and 3 extra lines that are used to prep DPC+ pointers for displaying the zone's object sprite, setting the object's X position, saving collision data for a zone and some other things like "was that the last zone" logic.
  • Elevators can only appear above the top-most ice position and 3 scan lines below the platform above it.
  • Maximum zone height would be 173 for a single zone, though I suspect you're really asking how high so that Frosty can reach it. I'll check what's reachable with a single and with a double jump this evening.
  • Zones are fixed for the entire level. You could simulate 7 & 3 by not having platforms go the full-width of the screen. 9 zones would give use more flexibility with those layouts (ie: set up the 9 zones and only use 6 on the left side, 3 on the right). If I can get back support for 9 I will.
  • Platforms can be a single PF pixel wide.
  • Platforms can be as far apart as you want, there's no minimum. If you're asking for how far apart so that Frosty can still jump to them, I'll have to check that out.
  • Currently Frosty dies if he falls off the bottom of the screen.
  • Falling somewhere else might be doable - depends on ROM.

  • Sprites
  • The logic is set up to remember the carrot's position when the level is loaded. Routines to randomly put the carrot somewhere else would take up more ARM ROM space.
  • On the later levels, the speed of the ice melt becomes a problem with the wide levels. Ice Chests -> Full Health are a way to counter that.
  • Different colored chests could be done for different abilities, though different objects would probably be better (ie: color blind gamers)

  • Frosty
  • Frosty melts 1 line per snowball thrown.
  • I haven't looked at the trajectory, but I do like how it works now (based just on Frosty's inertial w/out the "hold fire button for more power" logic).
  • Frosty melts at 1/8th of a line for each frame he's on a lava platform.
  • Movement on a lava platform does not change the melt time - jumping across helps as you only melt when you're in contact with the platform.
  • For distance things I'll set up a level to test them.

  • Other
  • Extinguish all fireballs to enable the exit
  • Levels cannot wrap
  • Scoring isn't done yet. What's in place is:
    • 50 per fireball hit
    • 1-10 for ice (depends on size)

    [*]planned scoring

    • bonus points for size of Frosty at end of leve
    • bonus points for having nose at end of level
    • bonus points if Frosty's full-size at end of level

    [*]bonus/hidden levels - what would they be? do we have space for them?

    [*]powerups - currently the carrot lets you throw snowballs.

I've redone the level layout so platform layout is spit off from elevator/object layout. That lets us use the same platform layout with different object arrangements (plus the lava and platform movements can be different). Current ROM free

------ $490 bytes of ARM User Code left ------ $0  bytes free for BANK 4 'DPC+ overlap' ARM data storage ------ $cf Level 1 & 17 data ------ $72 Level 2 & 18 data ------ $69 Level 3 & 19 data ------ $44 Level 4 & 20 data ------ $44 Level 5 & 21 data ------ $72 Level 6 & 22 data ------ $5e Level 7 & 23 data ------ $5e Level 8 & 24 data ------ $5e Level 9 & 25 data ------ $5e Level 10 & 26 data ------ $cf Level 11 & 27 data ------ $72 Level 12 & 28 data ------ $69 Level 13 & 29 data ------ $37 Level 14 & 30 data ------ $44 Level 15 & 31 data ------ $72 Level 16 & 32 data ------ $132 bytes of BANK 4 ROM left ------ $28  bytes free for BANK 5 'DPC+ overlap' ARM data storage ------ $21b bytes of BANK 5a ROM left ------ $6f bytes of BANK 5b ROM left ------ $2aa bytes of Display Data ROM left

Whatever space is left over in the Display Data is used for masking objects as they move on/off screen. $2aa = 682 bytes. Probably need to leave 128+ bytes for the masking workspace. The rest can be used for additional objects, supporting wider levels, even level layout data.

 

 

 

There's been some talk about adding an eeprom, but I've not seen anything on how that would work, how I would code for & test, if Al's OK with it, etc. The space would let some of the graphics be moved out of Display Data to where the current level data is located, freeing up Display Data space for going back to 9 zones, wider levels, new objects, etc.

 

The other thing is music - not only the songs (when will the tracks be ready, how many tracks are there going to be, is there enough space to store them, etc), but what's causing the static in the playback. I've reviewed the source and don't see what's causing it.

 

I would rather not be scrambling at the last minute in December with these, especially since I took off next week for working on Stay Frosty.

 

 

More questions icon_smile.gif

  • How tall is each section of the screen: horizon/game area/score area/extra lives? (Usually I just pull this info off Stella screenshots... but, well... icon_rolleyes.gif )
  • For the mountains in the background: can they extend the entire height of the sky?
  • If a level is wider than 5 bytes, how then are the mountains handled? Are the first 5 bytes symmetrical, and if so reflected or duplicated? What of the extra width - is that symmetrical within itself?
  • Is the game area equally divided into zones, or can they be variable? (So if you're using all seven zones, do they all have to be the same height?)
  • Could we add a second location where the bird would leave the carrot? So on some levels, you might have to let the bird steal the carrot, in order for it to be placed strategically. (Not sure why... just thinking.)
  • Should the carrot expire, or stay with you until the bird steals it, or you die?
  • Different objects for other power-ups would be great if there's space. The different colored ice chests was more about saving ROM space.

 

The horizon data for the hills is 17 scan lines. The digits in the score area are 8 scan lines, the frosty head is 9 scan lines. Don't know what the padding space is but you can use the last of the Stella based screenshots as they've not changed.

attachicon.giffrosty2.bin_21.png attachicon.giffrosty2.bin_26.png

 

Mountains can go the full height. Still need to write the routines to allow the sun to hide behind the mountains.

 

Mountain data is not part of the level data. It does not shift with it. To save space it's just like in SF - 2.5 bytes reflected.

 

Each zone's height is independent of the other zones. They must add up to 173.

 

Something could probably be done to give the carrot a 2nd location to be replaced at.

 

Frosty loses the carrot at the end of each level, if he dies, or if the bird steals it.

 

Main problem with new objects is space for the ARM code for the logic of what happens when you collide with it.

 

 

I've rearranged the code so that I can create a source distribution to make it easy for others to edit level layouts.

To answer the distance questions, I added a number of test levels:

  • 4 - Elevator platform (zone changes height)
  • 7 - Single Jump Height
  • 8 - Double Jump Height
  • 9 - Single Jump Distance
  • 10 - Double Jump Distance

results from 7, single-jump test

  • 32 height can consistently make
  • 33 height can make, but not 100% of the time
  • 34 height cannot make

results from 8, double-jump test

  • 48 height can consistently make
  • 49 height can make, but not 100% of the time
  • 50 height cannot make

results from 9, single-jump test

  • 11 PF gap can be made
  • 12 PF gap can be made if melted
  • 13 PF gap cannot be made

results from 10, double-jump test

  • 15 PF gap can be made
  • 16 PF gap can be made, but not 100% of the time
  • 17 PF gap can be made if melted
  • 18 PF gap cannot be made

ROMs

sf2 20101116_NTSC.bin

sf2 20101116_PAL.bin

 

Source

SF2_20101116.zip

 

NOTE: While the ROMs work on the Harmony, they do not work in Stella.

 

Blog entry covers November 9 - 16, 2010

2 Comments


Recommended Comments

Nice to see you had DPC+ music working way back then!

And I knew you had music in the DPC+ demo...

 

I still would not become a member of AtariAge for another five months, and it would be another year or so after that until I helped enter the music note data for a lot of the levels.

 

It seems that every entry says the project was "running out of space", but you added a million more things over the next three years.

 

>>The optimization achieved is mind-blowing, and a great accomplishment.<< That can't be said enough times.

Link to comment

Using ARM and C code were new so we had a major learning curve going.

 

And, of course, every-time we freed up a chunk of ROM we just expanded the scope of the game - so it was a never ending battle.

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...