[stella] Silly game idea

Subject: [stella] Silly game idea
From: "B. Watson" <urchlay@xxxxxxxxxxxxxxxx>
Date: Mon, 22 Oct 2001 12:06:41 -0400 (EDT)
I've been having trouble with the game design aspect of 2600 programming. I
know 6502 asm fairly well, and am getting a handle on how to control the
hardware, but all the game ideas that I think of, have already been done..

Attached to this post is something I was playing with over the weekend,
it's not quite a game yet... I've got the birds moving around more or
less how I want them, though right now there's always a full screen's
worth of them (they should spawn randomly). The player's cursor should
be a crosshair or something, and the player himself should have some
animation when he moves (I was thinking of having his head roll in the
direction he's moving, or else he bounces like a ball)

Right now, you can move the cursor & player around, and when the cursor
is touching a bird, you can press the fire button to reverse its direction.
I was thinking that your mission in this game is to protect something by
pushing the birds away from it... or else you have to guide the birds into
picking up something for you. I'm trying to move away from the whole
`shooting stuff & killing it' kind of game...

There aren't any bounds checks on the player or cursor yet, so the game
acts funny if you move too far...

The kernel for this thing makes it kind of hard to position objects on the
display without them moving.. I call my player-positioning routine 7 times
during the kernel, and each call eats up 2 scanlines.. and the places where
they happen, aren't the same from frame to frame... I'm not doing a good
job of explaining this, just run it & you'll see what I'm talking about.

Anyway, I was hoping for some feedback... does it look like it might make
a good game? Does it stink? Somewhere in between?

Thanks...

B.

Attachment: wiz00.bin
Description: Binary data

; dizzywiz.asm

; by B. Watson <atari@xxxxxxxxxxxxxx>

; Idea for a silly game...

; (not yet) Tested on a real Atari 2600
; Tested on z26 v1.46 on a windows machine
; Tested on xstella 1.1 on a linux machine

 processor 6502
 include "vcs.h"

 seg.u data

 org $80

framectr ds 1
trigger ds 1
trigcnt ds 1
frame ds 2
evilctr ds 1
scanctr ds 1
ypos ds 1
random ds 2
goodx ds 1
goody ds 1
hitwho ds 1
tmp
tmpx ds 1
tmpd ds 1
evilstart
evil0x ds 1
evil0d ds 1
evil1x ds 1
evil1d ds 1
evil2x ds 1
evil2d ds 1
evil3x ds 1
evil3d ds 1
evil4x ds 1
evil4d ds 1
evil5x ds 1
evil5d ds 1
evil6x ds 1
evil6d ds 1
evil7x ds 1
evil7d ds 1
evilcnt = [.-evil0x]-1

 echo *-$80,"bytes of zero page used."

; constants:
XMAX = 136

 seg code

 org $F000

cartstart
 sei
 cld
 ldx #$ff
 txs
 lda #0
iloop
 sta 0,x
 dex
 bne iloop

initvcs
 lda #$AA
 sta random

 lda #>plane
 sta frame+1

 lda #$60
 sta goodx
 sta goody

 lda #$80
 sta trigger

 lda #$70 ; initial positions of evil dudes
 sta evil0x
 sta evil1x
 lda #$60
 sta evil2x
 sta evil3x
 lda #$50
 sta evil4x
 sta evil5x
 lda #$40
 sta evil6x
 sta evil7x
 lda #$01
 sta evil0d
 sta evil2d
 sta evil4d
 sta evil6d
 lda #$FF
 sta evil1d
 sta evil3d
 sta evil5d
 sta evil7d

 lda #$F0
 sta PF0
 lsr
 sta COLUBK
 lsr
 sta COLUP1
 lda #$05
 sta CTRLPF
 lda #5
 sta NUSIZ0 
 lda #$FF
 sta GRP1

main_loop
 lda #2
 sta VSYNC ; start blanking
 sta WSYNC
 sta WSYNC
 lda #44
 sta TIM64T ; go ahead & set timer
 lda #0
 sta WSYNC
 sta VSYNC ; 3 WSYNC's, then turn off VSYNC

game_calc
 inc framectr
; lda framectr
; and #$0f
; sta ypos
 inc ypos
 lda ypos
 cmp #18
 bne gc01
 lda #0
 sta ypos
 jsr rotate_evil
gc01
 ldx #evilcnt
 jsr move_evil
 lda evil0x
 jsr position_p0
 lda evil0d
 and #8
 sta REFP0

 lda #$0
 sta GRP0
 lda #$FF
 sta COLUP0
; lda framectr
; lsr
; lsr
; ora #1
; sta ypos

 lda trigcnt
 beq check_trigger
 lda #128
 sta trigger
 dec trigcnt
 bne trigger_done
check_trigger
 lda INPT4
 bmi trigger_done
 sta trigger
 lda #10
 sta trigcnt
trigger_done
  
 

 lda SWCHA
 bpl noleft
 dec goodx
noleft
 asl
 bpl noright
 inc goodx
noright
 asl
 bpl nodown
 inc goody
nodown
 asl
 bpl noup
 dec goody
noup
 
 asl hitwho
 ldx #0
wholoop
 asl hitwho
 bcc nothit
 lda evil1d,x
 bmi wasFF
 lda #$FF
 sta evil1d,x
 bne end_wholoop
wasFF
 lda #$01
 sta evil1d,x
nothit
end_wholoop
 inx
 inx
 cpx #14
 bne wholoop
 lda #0
 sta hitwho
 
 lda framectr
 ;ora #%11110000
 and #%00001111
 sta COLUP1


 lda goodx
 jsr position_p1
 lda #191
 sec
 sbc ypos
 sta scanctr

wait_timer
 lda INTIM
 bne wait_timer ; busy-wait for timer to expire
 sta WSYNC
 sta VBLANK

; kernel
;  ldy #191
; blank
;  sta WSYNC
;  dey
;  bne blank
; end_kernel

kernel
 ldy ypos
kill_top
 sta WSYNC
 dey
 bpl kill_top
; lda #$FF
; sta GRP0
 ldy #16
do_first_16
 lda plane,y
 sta GRP0
 sta WSYNC
 dey
 bne do_first_16

 lda #0
 sta evilctr

evil_loop
 ldx evilctr
 lda evil1d,x
 and #8
 sta REFP0
 ;sta CXCLR
; lda #0
; sta GRP0
 lda frametable,x
 sta frame
 lda evil1x,x
 jsr position_p0 ; eats 3 lines
 ;lda #$FF
 ;sta GRP0
 ldy #16
draw_player
 lda (frame),y
 sta GRP0
 dec scanctr
 ldx #$00
 sec
 sta WSYNC
 lda scanctr
 sbc goody
 and #$FC
 bne noplayer1
 dex
noplayer1
 stx GRP1
 dey
 bne draw_player
; lda CXPPMM ; test bit 7 for p0 - p1 collision
; asl
; rol hitwho
 inc evilctr
 inc evilctr
 lda evilctr
 cmp #14 ; = 7 times thru loop (2 inc's per)
 bne evil_loop

do_bottom
 lda #0
 sta GRP0
 lda #170-[16*8+2*7]
 sec
 sbc ypos
 tay
kill_rest
 sta WSYNC
 dey
 bpl kill_rest

 ldy #12
 sty COLUP1
draw_wizard_hat
 lda wizard_hat,y
 sta GRP1
 sta WSYNC
 dey
 bpl draw_wizard_hat

 ldy #7
 lda #63
 sta COLUP1
draw_wizard_face
 lda wizard_face,y
 sta GRP1
 sta WSYNC
 dey
 bpl draw_wizard_face

 lda #0
 sta GRP1
 

 lda #37
 sta TIM64T
overscan
 lda #2
 sta VBLANK
finish_overscan
 lda INTIM
 bne finish_overscan

 jmp main_loop

getrandbit
 lda random
 lsr
 lsr
 sbc random
 lsr
 ror random+1
 ror random
 lda random
 rts

getrandbyte
 ldx #8
grloop
 jsr getrandbit
 rol tmp
 dex
 bne grloop
 lda tmp
 rts

 align 256 ; guarantee our BNE doesn't cross a page

; so here's what's up with scanlines:
;  we must call this routine by cycle 67 of the previous scanline:
;  the JSR that got us here cost 6 cycles...
;  and we immediately do a STA WSYNC, 3 cycles.
;  we then spend one scanline positioning and one HMOVEing & checking collisions
;  So this routine eats 2 scanlines, and messes up the timing on the next one.
position_p0
 sta WSYNC ; 0
 tax ; 2
 lda hposlookup,x ; 4 = 6
 tax ; x has fine pos. ; 2 = 8
 and #$0f ; 2 = 10
 tay ; y has coarse pos. ; 2 = 12
badguy_posloop
 dey ; 2
 bpl badguy_posloop ; 2/3
reset_p0
 sta RESP0 ; 3 = (y*5)+27
 stx HMP0 ; now do fine positioning
 sta WSYNC
 sta HMOVE
; sty PF2
 dec scanctr
 dec scanctr
 lda trigger ; may as well do this now
 eor #128
 and CXPPMM ; check fire button too
 asl
 rol hitwho
 sta CXCLR
 ;sta WSYNC
 repeat 6
 nop
 repend
 sta HMCLR
; iny
; sty PF2
 rts

position_p1 ; for now, this only gets called in VBLANK
 sta WSYNC ; 0
 tax ; 2
 lda hposlookup,x ; 4 = 6
 tax ; x has fine pos. ; 2 = 8
 and #$0f ; 2 = 10
 tay ; y has coarse pos. ; 2 = 12
badguy_posloop1
 dey ; 2
 bpl badguy_posloop1 ; 2/3
reset_p1
 sta RESP1 ; 3 = (y*5)+27
 stx HMP1 ; now do fine positioning
 sta WSYNC
 sta HMOVE
 sta WSYNC
 sta HMCLR
 rts

 align 256 ; guarantee our BNE doesn't cross a page
move_evil
 lda evil0x,x ; get delta
 dex
 clc
 adc evil0x,x ; add position to delta 
 sta evil0x,x
 beq change_dir ; zero is bad, mmm'kay?
 cmp #XMAX
 bne x_is_valid
change_dir
 lda evil0x+1,x ; delta again
 bmi sk1
 lda #XMAX-1
 sta evil0x,x
 lda #$FF ; -1
 sta evil0x+1,x ; delta was 1, now -1
 bmi x_is_valid ; always branch (N always set)
sk1
 lda #$01
 sta evil0x,x
 lda #$01
 sta evil0x+1,x ; delta was -1, now set to 1
x_is_valid
 dex
 bpl move_evil
 rts 

rotate_evil
 lda evil7x
 sta tmpx
 lda evil7d
 sta tmpd

 lda evil6x
 sta evil7x
 lda evil6d
 sta evil7d

 lda evil5x
 sta evil6x
 lda evil5d
 sta evil6d

 lda evil4x
 sta evil5x
 lda evil4d
 sta evil5d

 lda evil3x
 sta evil4x
 lda evil3d
 sta evil4d

 lda evil2x
 sta evil3x
 lda evil2d
 sta evil3d

 lda evil1x
 sta evil2x
 lda evil1d
 sta evil2d

 lda evil0x
 sta evil1x
 lda evil0d
 sta evil1d

 lda tmpx
 sta evil0x
 lda tmpd
 sta evil0d

 rts
 


 echo *-$F000,"bytes of code"

 org $FE00
plane
 byte %00000000
 byte %00000000
 byte %00000000
 byte %11100000
 byte %01110000
 byte %00111000
 byte %11111111
 byte %11110111
 byte %11000110
 byte %10000000
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000000
plane2
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000111
 byte %11111111
 byte %11110110
 byte %11010000
 byte %10111000
 byte %00111000
 byte %01110000
 byte %11100000
 byte %11000000
 byte %10000000
 byte %00000000
 byte %00000000
plane3
 byte %00000000
 byte %00000000
 byte %00000000
 byte %11100000
 byte %01110000
 byte %00111011
 byte %11111100
 byte %11110111
 byte %11000110
 byte %10000000
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000000
 byte %00000000

wizard_face
 byte %00111110
 byte %01111111
 byte %01100011
 byte %01011101
 byte %01111111
 byte %01111111
 byte %01101011
 byte %00111110
wizard_hat
 byte %01111111
 byte %01110111
 byte %01101111
 byte %00101110
 byte %00101110
 byte %00110110
 byte %00011100
 byte %00011100
 byte %00011100
 byte %00001000
 byte %00001000
 byte %00001000

frametable ; odd bytes in this table don't even matter...
 byte #<plane
 byte #<plane
 byte #<plane
 byte #<plane
 byte #<plane2
 byte #<plane
 byte #<plane
 byte #<plane
 byte #<plane3
 byte #<plane
 byte #<plane
 byte #<plane
 byte #<plane
 byte #<plane
 org $FF00
hposlookup
; more or less stolen from David Schweinsberg's droids22.asm
; hi nybble: fine (HMP0)
; lo nybble: coarse (dey/bne loop)
; byte $20,$10
; byte $F0,$E0,$D0,$C0,$B0
; byte $A0,$90
 byte $71,$61,$51,$41,$31,$21,$11,$01
 byte  $F1,$E1,$D1,$C1,$B1,$A1,$91
 byte $72,$62,$52,$42,$32,$22,$12,$02
 byte  $F2,$E2,$D2,$C2,$B2,$A2,$92
 byte $73,$63,$53,$43,$33,$23,$13,$03
 byte  $F3,$E3,$D3,$C3,$B3,$A3,$93
 byte $74,$64,$54,$44,$34,$24,$14,$04
 byte  $F4,$E4,$D4,$C4,$B4,$A4,$94
 byte $75,$65,$55,$45,$35,$25,$15,$05
 byte  $F5,$E5,$D5,$C5,$B5,$A5,$95
 byte $76,$66,$56,$46,$36,$26,$16,$06
 byte  $F6,$E6,$D6,$C6,$B6,$A6,$96
 byte $77,$67,$57,$47,$37,$27,$17,$07
 byte  $F7,$E7,$D7,$C7,$B7,$A7,$97
 byte $78,$68,$58,$48,$38,$28,$18,$08
 byte  $F8,$E8,$D8,$C8,$B8,$A8,$98
 byte $79,$69,$59,$49,$39,$29,$19,$09
 byte  $F9,$E9,$D9,$C9,$B9,$A9,$99
 byte $7A,$6A,$5A,$4A,$3A,$2A,$1A,$0A
 byte  $FA,$EA,$DA,$CA,$BA,$AA,$9A
 byte $7B,$6B,$5B,$4B,$3B,$2B,$1B,$0B
 byte  $FB,$EB,$DB,$CB,$BB,$AB,$9B
 byte $7C,$6C,$5C


 org $FFFC
 word $F000
 word $F000


Current Thread