Jump to content
IGNORED

Circus AtariAge (2600)


Omegamatrix

Recommended Posts

The latest version of Circus AtariAge (the PRGE Demo) can be found here:

http://atariage.com/forums/topic/207391-circus-atariage-2600/?p=2842632

 

New! Now there is also a PAL60 version of the PRGE Demo. It was done some time after so it's in a different post. Link below. :)

 

http://atariage.com/forums/topic/207391-circus-atariage-2600/?p=2891028

 

post-7074-0-41037200-1381084630_thumb.pngpost-7074-0-40434900-1381084636_thumb.png

post-7074-0-51938600-1381084642_thumb.pngpost-7074-0-95354400-1381084648_thumb.png

post-7074-0-64720300-1381084656_thumb.pngpost-7074-0-12167800-1381084663_thumb.png

 

 

 

Below is the very old, first version, which is nothing like the current build:

CircusAtariAge(ver1).zip

  • Like 9
Link to comment
Share on other sites

Impressive!

 

6 looks better on my C= 1084. The motion on 5 looked jerkier, some of the balloons looked like they were wiggling back and forth as they traveled across the screen.

 

Is the 5 and 6 what you defined BALLOON_FRAMES as for each build? If so, it might be worth building a version where the difficulty and TV Type switches change the value on the fly so you can compare them without having to reload. Using all 3 switches gives you 8 possible values.

 

  SEG.U RIOT_RAM
...
BALLOON_FRAMES  ds 1


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; update balloon frames
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 LAX SWCHB ; difficulty and TV Type readings in bits 7 6 and 3 of both A and X register
 ROL
 ROL
 ROL ; bits 7 6 now in bits 1 0
 and #3
 sta BALLOON_FRAMES ; value is 0-3
 tax 
 and #8 ; bit 3 has TV Type
 lsr ; now in bit 2
 ora BALLOON_FRAMES ; value is now 0-7
 ;clc - not needed, bit 0 of A was 0 when LSR occurred so the carry's already cleared
 adc #2
 sta BALLOON_FRAMES ; value is now 2-9

; add code here to update the lives score to show BALLON_FRAMES value
; for visual feedback of which value is currently selected

   lda    balloonCounter
   ldx    #0
   ldy    balloonIndex
   cmp    #BALLOON_FRAMES
   bcc    .exitBalloonUpdates ; changed from bne to bcc since user could have changed it to a value we've already passed

   stx    balloonCounter   ; reset

Edited by SpiceWare
Link to comment
Share on other sites

Impressive!

 

6 looks better on my C= 1084. The motion on 5 looked jerkier, some of the balloons looked like they were wiggling back and forth as they traveled across the screen.

 

Is the 5 and 6 what you defined BALLOON_FRAMES as for each build? If so, it might be worth building a version where the difficulty and TV Type switches change the value on the fly so you can compare them without having to reload. Using all 3 switches gives you 8 possible values.

 

Thanks! I liked the idea of one build where you could change the framerate dynamically too. Here's one where you just push the joystick up/down and you can read the "balloonFrameNum" in the score below.

 

 

 

CircusAtariAge(ver1.1).bin

 

 

Use Alt-P in Stella.

Edited by Omegamatrix
Link to comment
Share on other sites

Nice!

 

I notice the wiggle with the odd values of 3, 5, 7 and 9. Once it gets to 11 the wiggle is no longer noticeable with the odd values. So for me the values that look good are 1, evens from 2-8, and from 10 on up.

 

Assuming MAME is accurate, it takes about 8 seconds for a balloon to cross the screen. A balloon frame value of 10 matches that.

Link to comment
Share on other sites

The wiggle comes from how the balloons shift. If you enable phosper mode in Stella, and step through the debugger you can see that in even frames the same columns of balloons seems to shift first. At a fast frame rate the balloons start appearing in groups of 2 because of this.

 

In odd numbered frames mode the first columns of balloons to shift alternates. This averages out the spacing but makes the balloons appear to wiggle more.

 

 

The natural thing to do would be to shift the graphics to smooth out the wiggling. The current constraints of the kernel allow the balloons to be 5 pixels wide maximum, and the balloons can only appear at certain positions. I have experimented with different things like strobing NUSIZ1, using COLUP1, the playfield, etc... but nothing worked except this. I really like the 5 pixels for the balloons, I think 4 pixels looks bad for the balloons. I might be able to shift the string and shadow on the balloons a little bit to make the wobbling appear less, but that is still constrained within the 5 pixel space.

 

 

I find framerate 1 and 6 are appealing, and I'm waiting for everyone's input. I really want a lot of speed in the balloons.

Link to comment
Share on other sites

I find framerate 1 and 6 are appealing, and I'm waiting for everyone's input. I really want a lot of speed in the balloons.

 

The speedy balloons look do look slick, though I suspect it could make the game easier as the clown would end up popping more of them on each pass.

Edited by SpiceWare
Link to comment
Share on other sites

The speedy balloons look do look slick, though I suspect it could make the game easier as the clown would end up popping more of them on each pass.

 

I agree. The challenge here is the original had blazing speed, and it made the game a lot of fun as your "stickman" would get thrown around quickly. I refuse to call him a clown, because quite honestly clowns scare the crap out of me. So I'm sticking to the original here showing stickmen. From a color blinded persons perspective IMHO I find the stickman much easier to distinguish when he's moving quickly amongst the balloons if he is a solid color. I can change the balloon colors on every line, but currently I'm just doing two colors (balloon and string). It would be interesting to see if the animation would look better by increasing luminance or altering colors on certain frames. I don't know yet. One of the interesting observations I made doing all of this is jerky animations appear to scroll faster then smooth. It's just an optical illusion though.

 

But I regress, I meant to be talking about the original games speed. If you look at the moving platforms, that is the originals speed. So at 6 frames I'm running half as fast as I would like. I'm not sure yet how to increase speed without sacrificing smooth graphics.

Edited by Omegamatrix
Link to comment
Share on other sites

I'm currently exploring using a combination of NUSIZ1 and the playfield to hide balloons. I think earlier I tried using a combination of NUSIZ1 and updating GRP1 to hide the balloons and it didn't pan out. If this new try works then I might be able to scroll the balloons smoother, as I would potentially be able to use all 8 bits of GRP1, instead of just bits 7 to 3.

 

 

So the main problem with using the playfield to mask balloons is that you have to give the playfield priority over the GRPx registers. This effectively means that the jumper also gets covered up. With NUSIZ1 set to two copies medium you can take away one of the balloons without using the playfield. This all sounds good in theory but I still have to explore how to mask the end balloons if the jumper is in that area, and if I can actually get all the PF updates done in time. Also I have to tread a little bit lightly and do some extensive testing on a real system, because I don't think updates to NUSIZ1 while the sprite is being drawn is fully handled in Stella yet (like in the Meltdown proto, for example). I believe Stephena will have this for Stella 4.0.

 

 

I hope this will work.

Link to comment
Share on other sites

Also I have to tread a little bit lightly and do some extensive testing on a real system, because I don't think updates to NUSIZ1 while the sprite is being drawn is fully handled in Stella yet (like in the Meltdown proto, for example). I believe Stephena will have this for Stella 4.0.

 

Version 3.8, actually. And I'm working on that right now, and hope to have it finished by the end of the month.

Link to comment
Share on other sites

I haven't had time to do any coding, but I did explore playfield masking while using NUSIZ1 and it looked very promising! I threw all the balloon positions for each frame into an excel sheet. Visually I found that an asynchronous playfield is the way to go as the bits used to mask each balloon never overlap each other. :)

 

post-7074-0-20916200-1358144827_thumb.png

 

post-7074-0-35063900-1358144849_thumb.png

 

 

As can be seen in the balloon picture:

 

A) There are nine balloons shown each frame. There is an exception where 10 are occasionally shown, but lets ignore it for now. Two frames are flickered to give the appearance of 18 balloons.

B) I chose to turn off balloons 2,4,6, and 8. Looking at the excel sheet pictured above, the balloon mask bits for this particular position were found in the top row of the group I labeled as 6, (the group number is on the left side of the sheet). The excel sheet shows PF0 as blue/white columns, PF1 as green/white, and PF2 as orange/white. Both sides of the playfield are shown overlapped in the excel sheet. Looking at the sheet it can be seen the masking for balloon 8 would also cover up the player graphics. So the ball will be used to mask balloon 8, and the playfield will simply be set with these values:

PF0 = $00

PF1 = $3C

PF2 = $30

C) Here the player is on top of a balloon that needs to be masked. Since the playfield has priority over the player graphics neither the playfield or ball can be used to cover up this balloon. The balloon can be hidden by storing 0 to GRP1 and then restoring the graphics afterward, but that does not work once the balloon gets shifted by 1 or more pixel to the right. Specifically you would be limited to using bits 7-3 of the graphics register. You could try to hide the balloon by making COLUP1 the same as the background (black), but that turns out to be even more limiting as the write seems to take effect after 4 pixels leaving only bits 7-4 of GRP1 available for graphics.

 

So finally a working solution is to update NUSIZ1 to 2 copies medium or 3 copies medium to prevent the balloon where the player is from being drawn, and then quickly switching back to 3 copies close.

 

 

The things I like about all this are:

- The playfield and ball can be set outside of the loop and left alone. Only NUSIZ1 might have to be dealt with.

- More time should be free inside of the loops, and outside of them as well.

- I might be able to just do a series of rom loops (6+ or so) for the different positions.

 

The things I need to work out or think about are:

- I will need to position the ball between rows of balloons. I will probably use a cycle 74 hmove with some time slicing to be able to still do stuff while the ball gets re-positioned. The player won't get covered up by a hmove line with a cycle 73/74 hmove, and I have a routine I wrote a while back where I can do the rough and fine position all it in 1 line.

- I might need a specific loop to do the 10 balloon oddball cases. This is not an extra balloon coming out of nowhere, it is where the balloon should naturally enter as it first appears, and is accounted for in the balloons that scroll across the screen.

- The very first balloon might be a headache to mask if the player is over it. It might need a specific loop as well as a extra strobe of RESP1 might be needed.

Link to comment
Share on other sites

Have you considered using the RESPn trick as used in Space Instigators?

 

Upside:

No flicker

 

Downside:

Scroll is not smooth

Ridiculously complicated; requires self modifying code in RAM and special handling when gaps are too big

Eats up a bunch of RAM

Scanlines between rows are difficult to do anything with as you're setting up the RAM routine - Unless you want to sacrifice even more RAM by setting each row up in advance.

Link to comment
Share on other sites

I haven't looked at Space Instigator's before, Christopher. I might take a look later though.

 

Right now I'm running a ram kernel as well. Actually I'm running two ram kernels, one for the balloons and one for the score. They both occupy the same ram space and I reload that space as needed. The heart of the ram balloon kernel works by using RESP1 and GRP1 alternatively as such:

 

LoopBalloons:
   nop
COLOR_BALLOON_TAB:
   lda    ColRedBallTab-1,Y
   sta    COLUP1
PLAYER_GFX_TAB:
   lda    JumperGfxTab-1,Y
   sta    GRP0
BALLOON_GFX_TAB:
   lda    BalloonLeftGfx-1,Y
   dey
BALLOON_1:
   sta    GRP1
BALLOON_2:
   sta    GRP1
   sty    RESP1
BALLOON_3:
   sta    GRP1
   sty    RESP1
BALLOON_4:
   sta    GRP1
   sty    RESP1
BALLOON_5:
   sta    GRP1
   sty    RESP1
BALLOON_6:
   sta    GRP1
   sty    RESP1
BALLOON_7:
   sta    GRP1
   sty    RESP1
BALLOON_8:
   sta    GRP1
   sty    RESP1
BALLOON_9:
   sta    GRP1
   sty    RESP1
   bne    LoopBalloons
EXIT_LOOP_BALLOONS:
   jmp    BalloonPrep

 

So, when I want to mask a balloon I simply change a sta GRP1 to a stx GRP0 in ram. 'X' has been pre-loaded to zero outside the loop. This method has it's limitations as only bits 7-3 of GRP1 can be used. Note that if none of the balloons are being masked, then you can use all 8 bits of GRP1. The jerkiness of the graphics comes from not being able to shift the GRP1 graphics.

 

 

So I'm currently exploring a new method of using NUSIZ1 and the playfield, and I gave an outline of that above. It looks great so far, I just have to find time to program it. I'm also going to do a flickerless row display of all 18 and a bit balloons (at a lower luminance value). I've already proofed this out and it will be used before the player starts the game. This will cut down on the flickering, if just for a bit of time.

 

 

The downside with this method is I can only do a flickerless display if all 18 balloons are being shown (and no player in them), or 17 balloons with the ball being used to mask one balloon. It is also possible to implement it under some circumstances when there is a big enough gap to update the playfield, but that gets real messy. The 18 and a bit balloons (pre-player contact) will be flickerless, evenly spaced, and scroll smoothly.

Edited by Omegamatrix
Link to comment
Share on other sites

You're already using the technique by hammering RESP1. Though using GRP1 as an on/off switch is sweet and would have simplified things considerably in Instigators as there's a bunch of exception handling for when RESPn strobing can't be used (too few objects, gap too wide). This is how Space Instigators does it:

 

position1:

STA WSYNC

Scan1p:

lda (Aliens_Display_Offset),y ;5

sta GRP0 ;3

sta GRP1 ;3

lda Scanline ;3 Cycles 2 Bytes

inc Scanline ;5

 

sta RESP0 ;3

sta RESP1,x ;4

sta RESP0,x ;4

sta RESP1,x ;4

sta RESP0,x ;4

sta RESP1,x ;4

sta RESP0,x ;4

sta RESP1,x ;4

sta RESP0,x ;4

 

sbc DrawnShot_Pos_Y ;3 Cycles 2 Bytes

lsr

tax ;2 Cycles 1 Byte

lda Player_Shot_Data_Table,x ;4 Cycles 3 Bytes

sta.w ENABL ;3 Cycles 2 Bytes

ldx #0 ;2

dey ;2

bpl Scan1p ;2

rts ;2

Link to comment
Share on other sites

FWIW, I think you could save a few cycles (and possibly more importantly, RAM) per scanline by unrolling your loops, using constants instead of variables and only having sta GRP1/sty RESP1 in RAM. But that's not going to solve your real problem which is that a smooth scroll really isn't possible using this technique. IMO it looks fine in Space Instigators due to the pacing, sound and animation. Maybe try to approach the problem from that way around - turn it from a bug into a feature?

Space Instigators+.bin

Link to comment
Share on other sites

FWIW, I think you could save a few cycles (and possibly more importantly, RAM) per scanline by unrolling your loops, using constants instead of variables and only having sta GRP1/sty RESP1 in RAM. But that's not going to solve your real problem which is that a smooth scroll really isn't possible using this technique.

 

 

I believe smooth scrolling is attainable. In post #15 I've outlined my plan of attack, which uses a different kernel altogether. It'll likely be a series of rom kernels which will allow me to overcome the limit of using only five bits of GRP1 that's imposed in the old kernel.

 

 

Originally I had everything unwound, and then I realized almost the same amount of temp ram was being wasted in the ram score kernel. So I rolled it up to make the code base a little smaller and keep it more manageable There was also plans for a tertiary ram logo kernel for the title screen, but that might change quite a bit before I get there. I haven't started that yet. First things first. Some of the variables that were in that loop are variables which are reserved for feature expansions, such as when the balloon animations will come in. ;)

 

 

Here is a small demo of all the balloons fully on (no flickering) with smooth scrolling. I plan to use this while the player is waiting to start a game, and possibly if a row regenerates (perhaps pulsing through some luminescence to highlight the row for a brief while). Obviously this can't be used when the player occupies the same area, as you need both player GRPx registers to create the balloons. As balloons disappear you have to flicker to achieve masking unless a gap exists which is long enough to update the playfield, or a single balloon is missing which the ball can mask.

 

 

 

post-7074-0-72531200-1358331153_thumb.png

 

FullBalloonTest.bin

 

 

Press up and down to control the speed. The caveat here is this hasn't been tested at all on real hardware yet. I hope it works!!

Edited by Omegamatrix
  • Like 2
Link to comment
Share on other sites

I once was proud of displaying 11 Space Invaders using a similar approach as Christopher described above (sta RESP1,x; a RESP0,x). So I think I understand most problems you are facing.

 

Very smart kernel. :thumbsup:

Edited by Thomas Jentzsch
Link to comment
Share on other sites

The current constraints of the kernel allow the balloons to be 5 pixels wide maximum, and the balloons can only appear at certain positions.

 

This is because you`re altering GRP1 while the sprite is being drawn, right?

 

I think this might work (haven't tested, maybe this week-end)

 

With the original kernal, use this instead:

sta GRP1

sty.w RESP1

 

This should add 1 cycle/3 pixels between sprites (resulting in 4 pixels between sprites) but allow you to use all 8 pixels in each sprite. In order to do smooth scrolling between the gaps then depending on the actual width of the objects you need multiple kernals each offset by 1 cycle/3 pixels.

 

Kernal1:

XXXXXXXX0000XXXXXXXX

Kernal 2:

XXXXXXXX0000XXXXXXXX

Kernal 3:

XXXXXXXX0000XXXXXXXX

Kernal 4:

XXXXXXXX0000XXXXXXXX

 

So two four pixel wide objects scrolling from left to right would progress as:

 

#####XXX0000#####XXX

X#####XX0000X#####XX

XX#####X0000XX#####X

#####XXX0000#####XXX

X#####XX0000X#####XX

XX#####X0000XX#####X

#####XXX0000#####XXX

X#####XX0000X#####XX

XX#####X0000XX#####X

XXX#####0000XXX#####

X#####XX0000X#####XX

XX#####X0000XX#####X

XXXXXXXX0000#####XXX0000#####XXX

 

(Need to view with fixed width fonts - cut and paste into notepad or something).

 

Big downside is the increased gap between objects (same as Space Instigators) but OTOH, if you preload A, X and Y with one of them zero'ed you can do masking with sta/stx/sty GRP1 and two different bitmaps per line. And hopefully still have time to do other things...

Link to comment
Share on other sites

This is because you`re altering GRP1 while the sprite is being drawn, right?

 

Correct!

 

Big downside is the increased gap between objects (same as Space Instigators)

 

I think this is the big problem with this solution. The spacing right now looks good to me, but if it is the same spacing as Space Instigators then the gaps would feel to wide.

 

 

With the plan of attack I made in post 15 I should be able to use any of the eight pixels. It will probably be more routines then 4, but should achieve the smooth scrolling too.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

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