Skip to content

Instantly share code, notes, and snippets.

@avdg
Created April 13, 2012 00:32
Show Gist options
  • Save avdg/2372316 to your computer and use it in GitHub Desktop.
Save avdg/2372316 to your computer and use it in GitHub Desktop.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SPACE PONG ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Player a: Use S and X ;;
; Player b: Use H and N ;;
; HOLD DOWN A KEY TO START THE GAME ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GOAL ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Be the real captain ;;
; Manouvering your bat space ships ;;
; and prevent polution in your space area ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; TODO
; include a black hole
; find a way to calibrate speed
; FIX SCREEN
; test/finish gameInput and nextState
;
; ADVANCED USERS
;
; Check :main to change values you probably care about
JSR main
BRK
SET PC, end ; When BRK stops working...
; const
:bat_char DAT "|"
:bat_space DAT " "
:ball_char DAT "*"
:space_char DAT " "
:key_a_up DAT "s"
:key_a_down DAT "x"
:key_b_up DAT "h"
:key_b_down DAT "n"
:wait DAT 0x0080 ; step timer
:dev_input_start DAT 0x9000
:dev_input_end DAT 0x900f
:dev_input_p DAT 0x9010
:dev_input_read DAT 0x9000 ; not a const, I lied :-(
:dev_screen_start DAT 0x8000
:dev_screen_x DAT 0x20
:dev_screen_y DAT 0x0C
; var
:bat_a_y DAT 0x00
:bat_b_y DAT 0x00
:ball_x DAT 0x00
:ball_y DAT 0x00
:ball_motion_x DAT 0x00
:ball_motion_y DAT 0x00
:p_a_motion DAT 0x00
:p_b_motion DAT 0x00
:score_a DAT 0x00
:score_b DAT 0x00
:seed DAT 0x1234 ; seed for randomness
;---------------
:main
; prevent null pointer for input device
SET a, [dev_input_p]
SET [a], [dev_input_start]
; calculated constants
SET x, [dev_screen_x]
SET y, [dev_screen_y]
SET a, y ; calculate bat position
SET b, a
DIV a, 2
SUB a, 1 ; align bat (storing start bat)
SET [bat_a_y], a
SET [bat_b_y], a
MOD b, 2
IFG 0, b
ADD [bat_b_y], 1
SET a, x ; set ball position
SET b, y
DIV a, 2
DIV b, 2
SET [ball_x], a
SET [ball_y], b
; the real pong menu stuff :-D
JSR draw
JSR drawIntro
JSR waitLoop
JSR clearIntro
; the real pong game stuff :-)
JSR draw
JSR loop
SET PC, POP
;---------------
:waitLoop ; waits until the user press the any key
SET a, [dev_input_p] ; copy pointer to next input
SET b, dev_input_read ; copy pointer to next read
SET x, [dev_input_start]
SET z, [dev_input_end]
SET i, [b] ; copy last know pointer value
:waitLoop1 ; loop until user press any key
JSR randomizeSeed
IFE i, [a]
SET PC, waitLoop1
SET j, [a]
:waitLoopClear ; clean buffer
SET [i], 0 ; increase i until j
ADD i, 1
IFG i, z ; overflow
SET i, x
IFN i, j ; compare i and j
SET PC, waitLoopClear
SET [b], i ; reset read position
SET PC, POP
;---------------
:loop ; game loop
JSR gameInput
JSR clearBall ; unpaint ball TODO use reg
JSR nextState
JSR draw
SET PC, loop ; repeat
SET PC, POP ; should be no-op
;--------------
:randomizeSeed ; used to determine direction new ball
; NOTE: shall not change registries
ADD [seed], 1
IFN O, 0
SET [seed], 0
SET PC, POP
;--------------
:resetMotion ; called before respawning the ball
SET a, [seed]
MOD a, 4
SET [ball_motion_x], 1
SET [ball_motion_y], 1
IFE a, 1
SET [ball_motion_x], 2
IFE a, 2
SET [ball_motion_y], 2
IFN a, 3
SET PC, POP
SET [ball_motion_x], 2
SET [ball_motion_y], 2
SET PC, POP
;--------------
:gameInput ; processes input while pong plays
SET i, 0
SET a, dev_input_read ; read position pointer
SET b, [dev_input_p] ; input position pointer
SET x, [dev_input_start]
SET z, [dev_input_end]
:gameInput1
SET c, [a] ; a is a pointer to pointer
IFE [c], [key_a_up]
:tmp2
SET PC, tmp2
IFE [c], [key_a_up]
SET [p_a_motion], 0x02
IFE [c], [key_a_down]
SET [p_a_motion], 0x01
IFE [c], [key_b_up]
SET [p_b_motion], 0x02
IFE [c], [key_b_down]
SET [p_b_motion], 0x01
IFE [c], 0
JSR randomizeSeed ; won't mess our registries
SET [c], 0 ; reset current input buffer pos
IFN [a], b ; move pointer
ADD [a], 1
IFG [a], z ; overflow
SET [a], x
ADD i, 1
IFG wait, i
SET PC, POP
SET PC, gameInput1
;--------------
:nextState ; calculates next game state
SET a, [dev_screen_y] ; max y pos
SUB a, 1
IFN [p_a_motion], 0x02
SET PC, nextState1
:tmp
SET PC, tmp
IFG [bat_a_y], 0
SUB [bat_a_y], 1
:nextState1
IFN [p_a_motion], 0x01
SET PC, nextState2
IFG a, [p_a_motion]
ADD bat_a_y, 1
:nextState2
IFN [p_b_motion], 0x02
SET PC, nextState3
IFG [bat_b_y], 0
SUB [bat_b_y], 1
:nextState3
IFN [p_b_motion], 0x01
SET PC, nextState4
IFG a, [p_b_motion]
ADD [bat_b_y], 1
:nextState4
; update game state
SET PC, POP
;--------------
:cls ; clears full screen
SET i, [dev_screen_start] ; start video buffer
SET j, [dev_screen_x] ; end video buffer
MUL j, [dev_screen_y]
ADD j, i
:cls1 ; clear each character on screen
SET [i], [space_char]
ADD i, 1
IFN i, j
SET PC, cls1
SET PC, POP
;--------------
:drawIntro ; surprisingly draws the intro
SET a, [dev_screen_start]
SET [a+1], "P"
SET [a+3], "O"
SET [a+5], "N"
SET [a+7], "G"
ADD a, [dev_screen_x]
SET [a+1], "P"
SET [a+3], "R"
SET [a+5], "E"
SET [a+7], "S"
SET [a+9], "S"
SET [a+11], " "
SET [a+13], "A"
SET [a+15], " "
SET [a+17], "K"
SET [a+19], "E"
SET [a+21], "Y"
SET PC, POP
;--------------
:clearIntro ; faster screen cleaner than cls :-)
SET a, [dev_screen_start]
SET [a+0], 0
SET [a+2], 0
SET [a+4], 0
SET [a+6], 0
ADD a, [dev_screen_x]
SET [a+0], 0
SET [a+2], 0
SET [a+4], 0
SET [a+6], 0
SET [a+8], 0
SET [a+10], 0
SET [a+12], 0
SET [a+14], 0
SET [a+16], 0
SET [a+18], 0
SET [a+20], 0
SET PC, POP
;--------------
:clearBall ; clears ball position for faster refresh
; TODO rename to clsPos, cleans pos a, b
SET A, [ball_y] ; parameter b
MUL A, [dev_screen_x]
ADD A, [ball_x] ; parameter a
ADD A, [dev_screen_start]
SET [a], [space_char]
SET PC, POP
;--------------
:draw ; draw procedure TODO new screen i/o
SET PC, POP
; >>> PLAYER A <<<
SET i, 0x0 ; current y pos bat
SET a, [dev_screen_start]
:drawLoop1 ; draw space above bat player a
IFE i, [bat_a_y]
SET PC, draw2
SET [a], [bat_space]
ADD a, [dev_screen_x]
ADD i, 1
SET PC, drawLoop1
:draw2 ; draws bat player a
SET [a], [bat_char]
ADD a, [dev_screen_x]
SET [a], [bat_char]
ADD a, [dev_screen_x]
SET [a], [bat_char]
ADD a, [dev_screen_x]
ADD i, 3
:draw3 ; draws space under bat player a
SET [a], [bat_space]
ADD a, [dev_screen_x]
ADD i, 1
IFN i, [dev_screen_y]
SET PC, draw3
:draw4 ; >>> PLAYER B <<<
SET i, 0 ; current y pos bat
SET a, [dev_screen_start]
ADD a, 0x1F
:drawLoop2 ; draws space above player b
IFE i, [bat_b_y]
SET PC, draw5
SET [a], [bat_space]
ADD a, [dev_screen_x]
ADD i, 1
SET PC, drawLoop2
:draw5 ; draws bat player b
SET [a], [bat_char]
ADD a, [dev_screen_x]
SET [a], [bat_char]
ADD a, [dev_screen_x]
SET [a], [bat_char]
ADD a, [dev_screen_x]
ADD i, 3
:draw6 ; draws space under bat player b
SET [a], [bat_space]
ADD a, [dev_screen_x]
ADD i, 1
IFN i, [dev_screen_y]
SET PC, draw6
; >>> BALL <<<
SET A, [ball_y]
MUL A, [dev_screen_x]
ADD A, [ball_x]
ADD A, [dev_screen_start]
SET [a], [ball_char]
SET PC, POP
;--------------
:end ; Of course you read the boring end ;-)
BRK
SET PC, end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment