Skip to main content

Title screen

Thanks to the sample code of really smart people out there, I now have a working title screen!

The hardest part was similar to the last problems I talked about: cycle timings getting messed up while crossing a page boundary.

To get a nice large "hi-res" graphic on the atari, you have to take both sprite objects, tell the Atari to repeat them 3 times close together, and then stagger them.  (Imagine the 3 repeated planes on Combat, or the 3 players on Football. Then imagine 2 sets of those interleaved with each other) That gets you halfway there, but then you have to very exact timings to update the sprite's graphic data mid-scanline.  Because the Atari is so doggone slow, the timings are really tricky. (Although the technique eventually became fairly well-known -- any game with a 6-digit score display most likely used this technique).

I got the code all working thanks to that sample code I posted to above, but if I fiddled much with the graphics data, the timings would get off by 1 clock cycle, and it would fail. Turns out, again, that it was crossing a page boundary. This time with a LDA instruction (loading the accumulator from memory) -- if you do a "LDA foo,X" command, which loads the accumulator with whatever byte is at memory location (foo + the value of the X register), and foo+X crosses a page boundary from foo, it takes 5 cycles instead of 4.

Luckily the assembler gives you a nice "align" pseudo-opcode that lets you force alignment of your data into page boundaries, which fixed it.

After getting the title displayed, I wanted to make it pretty. I have 8 whole clock cycles free per line to do what I want with, but to update the color of the whole thing, I have to write to 2 registers (COLUP0 and COLUP1, the color registers for each sprite), which alone takes 6 cycles. There's not enough time left to pick or calculate the color for the scanline.

So I unrolled the kernel loop by half, which lets me use 16 clock cycles every 2 lines. That's plenty of time to load a base color, add to it based on the current line, and then write it to the color registers. The end result is a pretty animated title graphic:

Right now the PASSWD option doesn't do anything :-(

The half-unrolled loop ended up looking like:
.loop:
    sty     tmpVar              ; 3

    ;update the color
    tya                         ; 2
    adc     PlayerColorDef      ; 3
    sta     COLUP0              ; 3 = 11

    lda     (ptr+$0),y          ; 5
    sta     GRP0                ; 3
    lda     (ptr+$2),y          ; 5
    sta     GRP1                ; 3
    lda     (ptr+$4),y          ; 5
    sta     GRP0                ; 3
    lda     (ptr+$6),y          ; 5
    sta     tmpVar2             ; 3 = 32

    lax     (ptr+$a),y          ; 5
    lda     (ptr+$8),y          ; 5
    ldy     tmpVar2             ; 3
    sty     GRP1                ; 3        
    sta     GRP0                ; 3
    stx     GRP1                ; 3
    sta     GRP0                ; 3 = 25

    ldy     tmpVar              ; 3
    dey                         ; 2

    ;burning 3 cycles in place of the bpl since the loop is half-unrolled
    sty     tmpVar              ;3 (in place of the bpl)


    sty     tmpVar              ; 3

    ;update the color
    tya                         ; 2
    adc     PlayerColorDef      ; 3
    sta     COLUP1              ; 3 = 11

    lda     (ptr+$0),y          ; 5
    sta     GRP0                ; 3
    lda     (ptr+$2),y          ; 5
    sta     GRP1                ; 3
    lda     (ptr+$4),y          ; 5
    sta     GRP0                ; 3
    lda     (ptr+$6),y          ; 5
    sta     tmpVar2             ; 3 = 32

    lax     (ptr+$a),y          ; 5
    lda     (ptr+$8),y          ; 5
    ldy     tmpVar2             ; 3
    sty     GRP1                ; 3         
    sta     GRP0                ; 3
    stx     GRP1                ; 3
    sta     GRP0                ; 3 = 25

    ldy     tmpVar              ; 3
    dey                         ; 2

    bpl     .loop               ; 2/3 =  7/8

Comments

sverx said…
I'm amazed by all this, really!
(But NO, I won't start learning another assembly)

Popular posts from this blog

Retrospex 32 Review

RetrospexInternational recently sent me a couple units of their new handheld device, the Retrospex 32, a new dedicated GameboyAdvance emulator handheld.  To make the unit playable out of the box, they pre-loaded a handful of homebrew games, including Anguna, which is why they were kind enough to send me 2 of the units to play with.  I was pretty excited to get my hands on the device and try it (I loved my old GBA micro with a good flash cart!), and see Anguna running on it. So here's my thoughts after playing with it.



Their website lists the Retrospex 32 for £59.99, which is around $100 USD. It seems like it's marketed toward people into retro-gaming (which makes sense for a dedicated GBA emulator device). At that price, with that target market, and such a limited set of functionality (why not make it a multi-machine emulator, and emulate all the old consoles?), it would hopefully do a really good job of it.

The short version of my review: it doesn't. It has one job (emula…

Making the game fun

The real trick for Spacey McRacey (as I'm calling it now) is going to be making it fun.  And that's what I'm rather unsure about at this point.

I have a game design that basically works. The technical issues are mostly sorted out, I just need to get a few more implemented before I can seriously play test it.

But fun? It's hard to know if it's actually going to be any fun to play.  With a 4-player party-style game, it's seems like it might be hard to hit that fine line where everyone is close and competing, where everything feels exciting and tense, as opposed to tedious and boring.  And despite envisioning my game as fun, it might just be boring to play.

Some of that comes down to tweaking it. Tweaking the speeds, difficulties, etc, will make a difference. (If it's too easy to shoot people from behind, then it will be nearly impossible to hold a lead for very long, which could ruin it and make it no fun. If it's too hard to kill the guy in front, it wil…

Killer Queen

So at PRGE, I played an arcade game that just left me amazed.  Killer Queen.

It's a 10-player game. You have 2 cabinets linked together, and 5 players huddled on each one. Each one is a team of 5 people, working together to play a simple one-screen 2d platformer.  But what made it work was the high quality game design.

First, the game is relatively simple, yet there is a lot going on at once.  One player plays the queen, the most important and powerful character on the team. The others start as workers, but can become warriors who can fly around and attack in a very joust-like flappy contest of height.  The real trick is that there are three completely different ways to win: either collect a bunch of berries and bring them back to your base, or ride a REALLY SLOW snail across the screen (while other people try to kill you, and you hope your team protects you), or kill the enemy queen 3 times.  There's some other things going on as well (using berries to upgrade, capturing upgr…