Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; Note: CLOBBERS REGISTERS
- ; Use my v2 (available on this site) if you want to have it play nice
- ; coded by Soron of http://0x10cforum.com/, for the DCPU
- ; hereby released into the public domain
- ; (or use the Unlicense, CC0, etc., if your country doesn't have public domain)
- ; targetted for the DCPU-16 Studio assembler/emulator
- ; may or may not work for other emulators, since I/O hasn't been made official
- ; the snake is drawn on the background, and the food on the foreground
- ; suggested tweaks:
- ; adjust sleep_duration to speed up/slow down the game
- ; adjust the upper nybble of food_char to change food color
- ; adjust the lower byte of food_char to change food shape
- ; adjust prng_dat to start with a different RNG seed
- ; if you're not using a 32x16 window, adjust assorted things to not break
- ; (things such as dat_width and dat_height, up_dir and down_dir, etc.)
- ; note: assumes that it'll be run as a standalone program
- ; this could also probably be made more efficient, but, uh... not a priority,
- ; given that we're looping 0x1000 times just to slow things down!
- ; directions:
- ; 0x0001 = right
- ; 0x0020 = down (assuming a 32 char-width screen)
- ; 0xFFFF = left
- ; 0xFFE0 = up
- ; up/down WILL need to be changed if you use a different-width screen
- ; how registers, etc., are used:
- ; A = head position
- ; B = direction
- ; C = food position
- ; X = position of thing to draw on screen, etc
- ; Y = position of last segment touched
- ; Z = temporary data storage, for assorted calculations
- ; I = for loops and other iterations
- ; J = address of the stack element which stores the pos of start of tail
- ; SP = address of the stack element which stores the pos of end of tail
- ; O = not used. Why would you use this for Snake? What sort of madman ARE you?
- :init
- JSR clear_screen
- SET A, 0x0001 ; head position (add 0x8000 to get screen pos)
- SET B, 0x0001 ; direction
- JSR gen_food
- SET J, SP ; keep track of where OUR stack starts
- SET PUSH, 0x0000 ; start of tail position
- BOR [0x8000], [tail_color]
- BOR [0x8001], [head_color]
- :game_loop
- JSR sleep
- IFE [0x9000], [up_key]
- SET PC, turn_up
- IFE [0x9000], [down_key]
- SET PC, turn_down
- IFE [0x9000], [left_key]
- SET PC, turn_left
- IFE [0x9000], [right_key]
- SET PC, turn_right
- :move_snake
- SET [0x9000], 0
- SET Y, A
- ADD A, B ; yay overflow ^_^!
- SET X, A
- :check_collision
- SET Z, [dat_width]
- MUL Z, [dat_height]
- IFG X, Z ; went off the screen somehow
- SET PC, lose_game
- SET Z, X
- ADD Z, 0x8000
- IFE [Z], [tail_color] ; hit the tail!
- SET PC, lose_game
- IFE B, [dir_left]
- SET PC, check_edge_collision
- IFE B, [dir_right]
- SET PC, check_edge_collision
- SET PC, draw_snake
- :check_edge_collision
- ;change this next block if you changed screen width
- SET X, A
- AND X, 0xFFE0
- SET Z, Y
- AND Z, 0xFFE0
- IFN X, Z
- SET PC, lose_game ; we have gone off the left/right edge!
- SET X, A
- :draw_snake
- ADD X, 0x8000
- BOR [X], [head_color]
- SET I, J
- :tail_loop
- SUB I, 1
- IFG SP, I
- SET PC, finish_tail
- SET Z, [I]
- SET [I], Y
- SET Y, Z
- SET X, [I]
- ADD X, 0x8000
- BOR [X], [tail_color]
- SET PC, tail_loop
- :turn_left
- IFN B, [dir_right]
- SET B, [dir_left]
- SET PC, move_snake
- :turn_right
- IFN B, [dir_left]
- SET B, [dir_right]
- SET PC, move_snake
- :turn_up
- IFN B, [dir_down]
- SET B, [dir_up]
- SET PC, move_snake
- :turn_down
- IFN B, [dir_up]
- SET B, [dir_down]
- SET PC, move_snake
- :finish_tail
- IFE A, C
- SET PC, grow_tail
- SET X, Y
- ADD X, 0x8000
- AND [X], 0xF0FF
- SET PC, game_loop
- :grow_tail
- SET PUSH, Y
- SET X, C
- ADD X, 0x8000
- AND [X], 0x0F00 ; make sure to clear the old food item!
- JSR gen_food
- SET PC, game_loop
- :gen_food
- JSR rand
- SET C, [prng_dat]
- SET Z, [dat_width]
- MUL Z, [dat_height]
- MOD C, Z
- SET X, C
- ADD X, 0x8000
- BOR [X], [food_char]
- SET PC, POP
- :lose_game
- SET PC, init
- :sleep
- SET I, 0
- :sleep_loop
- ADD I, 1
- IFG I, [sleep_duration]
- SET PC, POP
- SET PC, sleep_loop
- :sleep_duration
- DAT 0x1000
- :clear_screen
- SET A, SP
- SET SP, 0x8000
- :clear_screen_loop
- SET POP, 0
- IFG SP, 0x8200
- SET PC, clear_screen_exit
- SET PC, clear_screen_loop
- :clear_screen_exit
- SET SP, A
- SET PC, POP
- :rand
- ;introduce at least a LITTLE unpredictability
- MUL [prng_dat], A
- ADD [prng_dat], SP
- ;now do the actual work
- MUL [prng_dat], 31421
- ADD [prng_dat], 6927
- SET PC, POP
- :prng_dat
- DAT 0x13AD ; a reasonable start value
- ;if you change width, you WILL need to double-check edge-of-screen collision
- :dat_width
- DAT 32
- :dat_height
- DAT 16
- :head_color
- DAT 0x0700
- :tail_color
- DAT 0x0F00
- :food_char
- DAT 0xC040 ; "@" char, for all y'all roguelike fans :)
- :dir_right
- DAT 0x0001
- :dir_down
- DAT 0x0020 ; relies on screen width
- :dir_left
- DAT 0xFFFF
- :dir_up
- DAT 0xFFE0 ; relies on screen width
- :up_key
- DAT 0x0003
- :down_key
- DAT 0x0004
- :left_key
- DAT 0x0001
- :right_key
- DAT 0x0002
Advertisement
Add Comment
Please, Sign In to add comment