scroll down works on CHIP-8 and High-Res modes
scroll left and right work in stdef and hidef adds octo test roms adds schip fonts to memory
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,393 @@
|
||||
###########################################
|
||||
#
|
||||
# Deep8
|
||||
#
|
||||
# A stripped down port of the Mako game
|
||||
# "Deep" for Chip8.
|
||||
# Move your boat left and right with A/D
|
||||
# Press S to drop a bomb and release S
|
||||
# to detonate it. Destroy incoming
|
||||
# squid before they tip your boat!
|
||||
#
|
||||
# This game was one of the earliest
|
||||
# programs written using Octo.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: waves
|
||||
0b00110011
|
||||
0b11101110
|
||||
|
||||
: boat
|
||||
0b00000100
|
||||
0b00000100
|
||||
0b11111111
|
||||
0b11111111
|
||||
0b01111101
|
||||
|
||||
: boat-flip
|
||||
0b00000000
|
||||
0b00000000
|
||||
0b01111101
|
||||
0b11111111
|
||||
0b11111111
|
||||
|
||||
: bomb
|
||||
0b00001000
|
||||
0b00010100
|
||||
0b00010000
|
||||
0b00111000
|
||||
0b00111000
|
||||
0b00111000
|
||||
|
||||
: fall
|
||||
0b01000000
|
||||
0b01010000
|
||||
0b01100000
|
||||
0b11110000
|
||||
0b01100000
|
||||
0b01000000
|
||||
|
||||
: squid-0
|
||||
0b00111100
|
||||
0b00111100
|
||||
0b01011010
|
||||
0b01011010
|
||||
|
||||
: squid-1
|
||||
0b00111100
|
||||
0b00111100
|
||||
0b11011011
|
||||
0b00100100
|
||||
|
||||
: boom
|
||||
0b10010000
|
||||
0b00010010
|
||||
0b01100000
|
||||
0b00000000
|
||||
0b10000011
|
||||
0b00100100
|
||||
0b00100001
|
||||
|
||||
: title-0
|
||||
0b00010000
|
||||
0b00010000
|
||||
0b00010000
|
||||
0b00010000
|
||||
0b01110000
|
||||
0b10010000
|
||||
0b10010000
|
||||
0b10010000
|
||||
0b10010000
|
||||
0b01110000
|
||||
: title-1
|
||||
0b01100000
|
||||
0b10010000
|
||||
0b11110000
|
||||
0b10000000
|
||||
0b10000000
|
||||
0b01110000
|
||||
: title-2
|
||||
0b11100000
|
||||
0b10010000
|
||||
0b10010000
|
||||
0b10010000
|
||||
0b10010000
|
||||
0b11100010
|
||||
0b10000000
|
||||
0b10000000
|
||||
0b10000000
|
||||
0b10000000
|
||||
|
||||
: end-0
|
||||
0b11101010
|
||||
0b01001110
|
||||
0b01001010
|
||||
0b01001010
|
||||
: end-1
|
||||
0b11100111
|
||||
0b11000110
|
||||
0b10000100
|
||||
0b11100111
|
||||
: end-2
|
||||
0b01100110
|
||||
0b01010101
|
||||
0b01010101
|
||||
0b01010110
|
||||
|
||||
# register scratchpad:
|
||||
: scratch 0 0 0 0
|
||||
|
||||
# storage for BCD decoding:
|
||||
: score-digits 0 0 0
|
||||
|
||||
# enemy data:
|
||||
: e1 1 0 0
|
||||
: e2 20 0 0
|
||||
: e3 40 0 0
|
||||
: e4 90 0 0
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Introduction
|
||||
#
|
||||
###########################################
|
||||
|
||||
: draw-waves
|
||||
i := waves
|
||||
v0 := 0 # x
|
||||
v1 := 7 # y
|
||||
loop
|
||||
sprite v0 v1 2
|
||||
v0 += 8
|
||||
while v0 != 64
|
||||
again
|
||||
;
|
||||
|
||||
: title
|
||||
draw-waves
|
||||
i := title-0
|
||||
v0 := 16
|
||||
v1 := 12
|
||||
sprite v0 v1 10
|
||||
i := title-1
|
||||
v0 += 8
|
||||
v1 += 4
|
||||
sprite v0 v1 6
|
||||
v0 += 8
|
||||
sprite v0 v1 6
|
||||
i := title-2
|
||||
v0 += 8
|
||||
sprite v0 v1 10
|
||||
v0 := key
|
||||
;
|
||||
|
||||
: draw-score
|
||||
i := score-digits
|
||||
load v2
|
||||
i := hex v0
|
||||
v0 := 49
|
||||
v3 := 1
|
||||
sprite v0 v3 5
|
||||
i := hex v1
|
||||
v0 += 5
|
||||
sprite v0 v3 5
|
||||
i := hex v2
|
||||
v0 += 5
|
||||
sprite v0 v3 5
|
||||
;
|
||||
|
||||
: inc-score
|
||||
i := scratch
|
||||
save v3
|
||||
draw-score
|
||||
v9 += 1
|
||||
i := score-digits
|
||||
bcd v9
|
||||
draw-score
|
||||
i := scratch
|
||||
load v3
|
||||
;
|
||||
|
||||
: init-game
|
||||
clear
|
||||
draw-waves
|
||||
v8 := 0 # enemy tick timer
|
||||
v9 := 0 # player score
|
||||
va := 32 # player horizontal position
|
||||
vb := 1 # player vertical position
|
||||
vc := 10 # bomb horizontal position
|
||||
vd := 10 # bomb vertical position
|
||||
ve := 0 # bomb state (0=invisible, 1=falling, 2+=exploding)
|
||||
|
||||
# draw initial boat
|
||||
i := boat
|
||||
sprite va vb 5
|
||||
|
||||
# draw initial score
|
||||
draw-score
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Game Over
|
||||
#
|
||||
###########################################
|
||||
|
||||
: delay-loop
|
||||
v0 := 0
|
||||
loop
|
||||
v0 += 1
|
||||
while v0 != 32
|
||||
again
|
||||
;
|
||||
|
||||
: game-over
|
||||
# erase player
|
||||
i := boat
|
||||
sprite va vb 5
|
||||
|
||||
# flip boat
|
||||
i := boat-flip
|
||||
sprite va vb 5
|
||||
|
||||
# animate the player sinking
|
||||
i := fall
|
||||
vb := 8
|
||||
sprite va vb 6
|
||||
loop
|
||||
delay-loop
|
||||
sprite va vb 6
|
||||
vb += 1
|
||||
sprite va vb 6
|
||||
while vb != 26
|
||||
again
|
||||
sprite va vb 6
|
||||
|
||||
# show 'the end'
|
||||
va := 20
|
||||
vb := 14
|
||||
i := end-0
|
||||
sprite va vb 4
|
||||
i := end-1
|
||||
va += 8
|
||||
sprite va vb 4
|
||||
i := end-2
|
||||
va += 8
|
||||
sprite va vb 4
|
||||
|
||||
loop again
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Enemy Logic
|
||||
#
|
||||
###########################################
|
||||
|
||||
# v0 - enemy timer. (0=swim, >0=time until next spawn)
|
||||
# v1 - horizontal position
|
||||
# v2 - vertical position
|
||||
|
||||
: enemy-sprite
|
||||
v4 := 1
|
||||
v4 &= v2
|
||||
i := squid-0
|
||||
if v4 == 1 then i := squid-1
|
||||
;
|
||||
|
||||
: spawn-enemy
|
||||
v1 := random 63
|
||||
v2 := 28
|
||||
enemy-sprite
|
||||
sprite v1 v2 4
|
||||
;
|
||||
|
||||
: count-enemy
|
||||
v0 -= v3
|
||||
if v0 == 0 then spawn-enemy
|
||||
;
|
||||
|
||||
: update-enemy
|
||||
if v0 != 0 then jump count-enemy
|
||||
enemy-sprite
|
||||
sprite v1 v2 4
|
||||
v2 -= v3
|
||||
|
||||
# kill the player if
|
||||
# an enemy reaches the surface:
|
||||
if v2 == 8 then jump game-over
|
||||
|
||||
enemy-sprite
|
||||
sprite v1 v2 4
|
||||
|
||||
# die on collision:
|
||||
if vf == 0 then return
|
||||
sprite v1 v2 4
|
||||
v0 := random 31
|
||||
v0 += 10
|
||||
inc-score
|
||||
;
|
||||
|
||||
: update-enemies
|
||||
v3 := 1
|
||||
v8 ^= v3
|
||||
if v8 == 0 then return
|
||||
i := e1 load v2 update-enemy i := e1 save v2
|
||||
i := e2 load v2 update-enemy i := e2 save v2
|
||||
i := e3 load v2 update-enemy i := e3 save v2
|
||||
i := e4 load v2 update-enemy i := e4 save v2
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Player/Bomb Logic
|
||||
#
|
||||
###########################################
|
||||
|
||||
: bomb-fire
|
||||
if ve != 0 then return
|
||||
vc := va
|
||||
vd := 10
|
||||
ve := 1
|
||||
i := bomb
|
||||
sprite vc vd 6
|
||||
;
|
||||
|
||||
: update-player
|
||||
v2 := 3
|
||||
v1 := va
|
||||
v0 := 7
|
||||
if v0 key then va -= v2
|
||||
v0 := 9
|
||||
if v0 key then va += v2
|
||||
v0 := 8
|
||||
if v0 key then bomb-fire
|
||||
if v1 == va then return
|
||||
i := boat
|
||||
sprite v1 vb 5
|
||||
sprite va vb 5
|
||||
;
|
||||
|
||||
: bomb-explode
|
||||
ve := 2
|
||||
i := boom
|
||||
sprite vc vd 7
|
||||
;
|
||||
|
||||
: bomb-falling
|
||||
i := bomb
|
||||
sprite vc vd 6
|
||||
vd += 1
|
||||
if vd == 25 then jump bomb-explode
|
||||
v0 := 8
|
||||
if v0 -key then jump bomb-explode
|
||||
sprite vc vd 6
|
||||
;
|
||||
|
||||
: bomb-exploding
|
||||
ve += 1
|
||||
if ve != 4 then return
|
||||
ve := 0
|
||||
i := boom
|
||||
sprite vc vd 7
|
||||
;
|
||||
|
||||
: update-bomb
|
||||
if ve == 1 then jump bomb-falling
|
||||
if ve != 0 then jump bomb-exploding
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Main Loop
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
title
|
||||
init-game
|
||||
loop
|
||||
update-player
|
||||
update-bomb
|
||||
update-enemies
|
||||
again
|
||||
@@ -0,0 +1,34 @@
|
||||
# Chip8 is a virtual machine designed in 1977 for programming video games.
|
||||
# Octo is a high level assembler, disassembler and simulator for Chip8.
|
||||
# Click 'Run' and then press ASWD to move the sprite around the screen.
|
||||
# Click the Octo logo for source, documentation and examples.
|
||||
|
||||
:alias px v1
|
||||
:alias py v2
|
||||
|
||||
: main
|
||||
px := random 0b0011111
|
||||
py := random 0b0001111
|
||||
i := person
|
||||
sprite px py 8
|
||||
|
||||
loop
|
||||
# erase the player, update its position and then redraw:
|
||||
sprite px py 8
|
||||
v0 := OCTO_KEY_W if v0 key then py += -1
|
||||
v0 := OCTO_KEY_S if v0 key then py += 1
|
||||
v0 := OCTO_KEY_A if v0 key then px += -1
|
||||
v0 := OCTO_KEY_D if v0 key then px += 1
|
||||
sprite px py 8
|
||||
|
||||
# lock the framerate of this program via the delay timer:
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
vf := 3
|
||||
delay := vf
|
||||
again
|
||||
|
||||
: person
|
||||
0x70 0x70 0x20 0x70 0xA8 0x20 0x50 0x50
|
||||
@@ -0,0 +1,310 @@
|
||||
###########################################
|
||||
#
|
||||
# Chipenstein 3D
|
||||
#
|
||||
# A work-in-progress experiment
|
||||
# in creating a raycast 2.5d shooter.
|
||||
# Uses PWM techniques to simulate extra
|
||||
# colors and must run at 1000 cycles/frame.
|
||||
# Epilepsy warning!
|
||||
#
|
||||
###########################################
|
||||
|
||||
# The largest a map for this approach could be is 16x16.
|
||||
# Technically we don't have to surround all sides with
|
||||
# walls due to wraparound, but if there is a ray path
|
||||
# around the map without hitting a wall our raycast
|
||||
# routine will get stuck in an infinite loop:
|
||||
|
||||
: map-data
|
||||
0xFF 0x01 0xFF 0x01 0xFF 0x01 0xFF 0x01 0xFF 0x01
|
||||
0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF
|
||||
0xFF 0xFF 0x01 0xFF 0x00 0x00 0x00 0x00 0x00 0x01
|
||||
0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF
|
||||
0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01
|
||||
0x01 0x00 0xFF 0x01 0x00 0x00 0x00 0xFF 0x00 0xFF
|
||||
0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01
|
||||
0x01 0xFF 0x01 0xFF 0x01 0xFF 0x01 0xFF 0x01 0xFF
|
||||
|
||||
: collision-test
|
||||
# take whole x/y in vc/vd, return map color in v0
|
||||
i := map-data
|
||||
vF := 0b111
|
||||
vc &= vF
|
||||
i += vc # + (x % 8)
|
||||
vd &= vF
|
||||
v0 <<= vd
|
||||
v0 <<= v0
|
||||
v0 <<= v0
|
||||
i += v0 # + (y % 8)*8
|
||||
load v0 # the current map color
|
||||
;
|
||||
|
||||
: player-position
|
||||
0 0 0 0 # scratchpad
|
||||
|
||||
: save-position
|
||||
v0 := va
|
||||
v1 := vb
|
||||
v2 := vc
|
||||
v3 := vd
|
||||
i := player-position
|
||||
save v3
|
||||
;
|
||||
|
||||
: restore-position
|
||||
i := player-position
|
||||
load v3
|
||||
va := v0
|
||||
vb := v1
|
||||
vc := v2
|
||||
vd := v3
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Raycasting
|
||||
#
|
||||
###########################################
|
||||
|
||||
# This is a table of the deltas and magnitudes for a fixed-point representation
|
||||
# of a cosine function. 64 entries correspond to ~5.6 degrees each.
|
||||
# deltas are interleaved with magnitudes- 0 for positive and 1 for negative.
|
||||
# deltas are normalized to slightly over half a step to make the distance calculations
|
||||
# come up with a maximum distance of roughly 15. Generated like so:
|
||||
#
|
||||
# for(int x = 0; x < 64; x++) {
|
||||
# double s = Math.cos(Math.PI*2/64*x);
|
||||
# System.out.format("0x%02X 0x%02X ", (int)(140 * Math.abs(s)), (s>=0) ?0 : 1);
|
||||
# if (x % 8 == 7) { System.out.println(); }
|
||||
# }
|
||||
|
||||
: cosine-table
|
||||
0x8C 0x00 0x8B 0x00 0x89 0x00 0x85 0x00 0x81 0x00 0x7B 0x00 0x74 0x00 0x6C 0x00
|
||||
0x62 0x00 0x58 0x00 0x4D 0x00 0x41 0x00 0x35 0x00 0x28 0x00 0x1B 0x00 0x0D 0x00
|
||||
0x00 0x00 0x0D 0x01 0x1B 0x01 0x28 0x01 0x35 0x01 0x41 0x01 0x4D 0x01 0x58 0x01
|
||||
0x62 0x01 0x6C 0x01 0x74 0x01 0x7B 0x01 0x81 0x01 0x85 0x01 0x89 0x01 0x8B 0x01
|
||||
0x8C 0x01 0x8B 0x01 0x89 0x01 0x85 0x01 0x81 0x01 0x7B 0x01 0x74 0x01 0x6C 0x01
|
||||
0x62 0x01 0x58 0x01 0x4D 0x01 0x41 0x01 0x35 0x01 0x28 0x01 0x1B 0x01 0x0D 0x01
|
||||
0x00 0x01 0x0D 0x00 0x1B 0x00 0x28 0x00 0x35 0x00 0x41 0x00 0x4D 0x00 0x58 0x00
|
||||
0x62 0x00 0x6C 0x00 0x74 0x00 0x7B 0x00 0x81 0x00 0x85 0x00 0x89 0x00 0x8B 0x00
|
||||
|
||||
: get-cosine
|
||||
# takes angle in v0,
|
||||
# returns delta, magnitude in v0, v1
|
||||
vf := 0b111111
|
||||
v0 &= vf # mod 64
|
||||
v0 <<= v0
|
||||
i := cosine-table
|
||||
i += v0
|
||||
load v1
|
||||
;
|
||||
|
||||
: get-angles
|
||||
# takes angle in v3,
|
||||
# unpacks x/y delta/mag into v4-v7
|
||||
|
||||
# cos(a) = cosine-table[(a % 64) << 1]
|
||||
v0 := v3
|
||||
get-cosine
|
||||
v4 := v0 # x delta
|
||||
v5 := v1 # x magnitude
|
||||
|
||||
# sin(a) = cosine-table[(a+16 % 64) << 1]
|
||||
v0 := v3
|
||||
v0 += 16
|
||||
get-cosine
|
||||
v6 := v0 # y delta
|
||||
v7 := v1 # y magnitude
|
||||
;
|
||||
|
||||
: delta-step
|
||||
vf := 0
|
||||
if v5 == 0 then va += v4 # positive x delta
|
||||
if vf == 1 then vc += 1 # carry in
|
||||
|
||||
vf := 0
|
||||
if v5 == 1 then va -= v4 # negative x delta
|
||||
if vf == 0 then vc += -1 # borrow out
|
||||
|
||||
vf := 0
|
||||
if v7 == 0 then vb += v6 # positive y delta
|
||||
if vf == 1 then vd += 1 # carry in
|
||||
|
||||
vf := 0
|
||||
if v7 == 1 then vb -= v6 # negative y delta
|
||||
if vf == 0 then vd += -1 # borrow out
|
||||
;
|
||||
|
||||
: heights
|
||||
# {height, color}
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
|
||||
: raycast
|
||||
save-position
|
||||
|
||||
#v0-v1 are available as scratch.
|
||||
|
||||
v8 := 0 # loop index * 2
|
||||
v3 := v9 # scan angle
|
||||
v3 += -8
|
||||
loop
|
||||
get-angles
|
||||
|
||||
v2 := 16 # height+1
|
||||
loop
|
||||
delta-step
|
||||
v2 += -1 # count down height
|
||||
collision-test # returns result in v0
|
||||
while v2 != 0
|
||||
if v0 == 0 then
|
||||
again
|
||||
|
||||
# save height and color in heights table:
|
||||
i := heights
|
||||
i += v8
|
||||
v1 := v0
|
||||
v0 := v2
|
||||
save v1
|
||||
|
||||
vf := v3
|
||||
restore-position
|
||||
v3 := vf
|
||||
|
||||
v8 += 2
|
||||
v3 += 1 # 16 slices * 5.625 = 90 degree FoV
|
||||
if v8 != 32 then
|
||||
again
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Rendering
|
||||
#
|
||||
###########################################
|
||||
|
||||
# this 45-byte table allows me to construct all the necessary vertical
|
||||
# strips using only immediate i and a height offset:
|
||||
|
||||
: top 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
: btm 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
|
||||
: sync
|
||||
# take advantage of the fact that vf
|
||||
# is always a free register if we aren't
|
||||
# doing any operations that can carry:
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
vf := 1
|
||||
delay := vf
|
||||
;
|
||||
|
||||
: draw-heights
|
||||
# registers for draw loop:
|
||||
# v0 is used to store the current height
|
||||
# v1 stores the 'color' bitmask
|
||||
v2 := 0 # heightmap index
|
||||
v3 := 1 # upward strip Y
|
||||
v4 := 16 # down strip Y
|
||||
v5 := 0 # strip X (avoid shifting v1 in loop)
|
||||
v6 := 15 # constant
|
||||
|
||||
sync clear
|
||||
loop
|
||||
# fetch height of column
|
||||
i := heights
|
||||
i += v2
|
||||
load v1
|
||||
|
||||
# apply PWM duty cycle for 'color'
|
||||
v1 &= ve
|
||||
if v1 == 0 then v0 := 0
|
||||
|
||||
# draw upward strip
|
||||
i := top
|
||||
i += v0
|
||||
v0 =- v6
|
||||
sprite v5 v3 15
|
||||
|
||||
# draw downward strip
|
||||
i := btm
|
||||
i += v0
|
||||
sprite v5 v4 15
|
||||
|
||||
# draw 16 columns
|
||||
v2 += 2
|
||||
v5 += 4
|
||||
if v2 != 32 then
|
||||
again
|
||||
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Main Loop
|
||||
#
|
||||
###########################################
|
||||
|
||||
: gun
|
||||
0x10 0x18 0x24 0x24 0x24 0x24 0x5A 0xC2 0xE7 0x7F 0x3E 0x21 0x41 0x41
|
||||
|
||||
: spin-left
|
||||
v9 += -1
|
||||
raycast
|
||||
;
|
||||
|
||||
: spin-right
|
||||
v9 += 1
|
||||
raycast
|
||||
;
|
||||
|
||||
: walk-forward
|
||||
v3 := v9
|
||||
get-angles
|
||||
delta-step
|
||||
raycast
|
||||
;
|
||||
|
||||
: walk-backward
|
||||
v3 := v9
|
||||
get-angles
|
||||
vf := 1
|
||||
v5 ^= vf
|
||||
v7 ^= vf
|
||||
delta-step
|
||||
raycast
|
||||
;
|
||||
|
||||
: main
|
||||
# global state:
|
||||
v9 := 30 # player angle
|
||||
va := 128 # x position (fractional)
|
||||
vb := 128 # y position (fractional)
|
||||
vc := 5 # x position (whole)
|
||||
vd := 5 # y position (whole)
|
||||
ve := 0 # rolling frame counter
|
||||
|
||||
raycast
|
||||
|
||||
loop
|
||||
draw-heights
|
||||
i := gun
|
||||
v0 := 38
|
||||
v1 := 18
|
||||
sprite v0 v1 14
|
||||
|
||||
ve += 1
|
||||
|
||||
v0 := 7
|
||||
if v0 key then spin-left
|
||||
v0 := 9
|
||||
if v0 key then spin-right
|
||||
v0 := 5
|
||||
if v0 key then walk-forward
|
||||
v0 := 8
|
||||
if v0 key then walk-backward
|
||||
again
|
||||
@@ -0,0 +1,83 @@
|
||||
###########################################
|
||||
#
|
||||
# Sprite scrolling demo:
|
||||
#
|
||||
# Draw a computer monitor with a scrolling
|
||||
# image by using two copies of its sprites
|
||||
# and adjusting an offset into that data
|
||||
# before each draw.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
# draw the background:
|
||||
|
||||
v0 := 16
|
||||
v1 := 4
|
||||
i := comp-LT
|
||||
sprite v0 v1 11
|
||||
v0 += 8
|
||||
i := comp-T
|
||||
sprite v0 v1 3
|
||||
v0 += 8
|
||||
sprite v0 v1 3
|
||||
v0 += 8
|
||||
i := comp-RT
|
||||
sprite v0 v1 11
|
||||
|
||||
v0 := 16
|
||||
v1 += 11
|
||||
i := comp-LB
|
||||
sprite v0 v1 15
|
||||
v0 += 8
|
||||
v1 += 7
|
||||
i := comp-B
|
||||
sprite v0 v1 8
|
||||
v0 += 8
|
||||
sprite v0 v1 8
|
||||
v0 += 8
|
||||
v1 += -7
|
||||
i := comp-RB
|
||||
sprite v0 v1 15
|
||||
|
||||
# main animation loop:
|
||||
|
||||
va := 24 # left x
|
||||
vb := 32 # right x
|
||||
vc := 7 # common y
|
||||
v9 := 0 # scroll offset
|
||||
v8 := 0b1111 # constant
|
||||
draw-texture
|
||||
loop
|
||||
draw-texture
|
||||
v9 += 1
|
||||
v9 &= v8
|
||||
draw-texture
|
||||
|
||||
vF := 4
|
||||
delay := vF
|
||||
loop
|
||||
vF := delay
|
||||
if vF != 0 then
|
||||
again
|
||||
again
|
||||
|
||||
: draw-texture
|
||||
i := grenade-L
|
||||
i += v9
|
||||
sprite va vc 15
|
||||
i := grenade-R
|
||||
i += v9
|
||||
sprite vb vc 15
|
||||
;
|
||||
|
||||
: grenade-L 0x0F 0x30 0x7C 0x7C 0xF8 0xF4 0xE0 0xE8 0xF0 0xE8 0xE0 0x68 0x70 0x34 0x08 0x00
|
||||
0x0F 0x30 0x7C 0x7C 0xF8 0xF4 0xE0 0xE8 0xF0 0xE8 0xE0 0x68 0x70 0x34 0x08 0x00
|
||||
: grenade-R 0xF0 0x0C 0x46 0x66 0x33 0x13 0x0B 0x0B 0x1F 0x0F 0x0F 0x1E 0x1E 0x1C 0x30 0x00
|
||||
0xF0 0x0C 0x46 0x66 0x33 0x13 0x0B 0x0B 0x1F 0x0F 0x0F 0x1E 0x1E 0x1C 0x30 0x00
|
||||
: comp-LT 0x3F 0x3F 0x3F 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C
|
||||
: comp-RT 0xFC 0xFC 0xFC 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C
|
||||
: comp-T 0xFF 0xFF 0xFF
|
||||
: comp-LB 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3F 0x3F 0x3F 0x00 0x07 0x1C 0x73 0x7F
|
||||
: comp-RB 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0xFC 0xFC 0xFC 0x00 0xE0 0xD8 0x26 0xFE
|
||||
: comp-B 0xFF 0xFF 0xFF 0xFF 0x33 0xCC 0x33 0xFF
|
||||
@@ -0,0 +1,23 @@
|
||||
###########################################
|
||||
#
|
||||
# Key input test program.
|
||||
# Move a dot around the screen in response
|
||||
# to keypresses.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: dot
|
||||
0b10000000
|
||||
|
||||
: main
|
||||
v0 := 10
|
||||
v1 := 10
|
||||
i := dot
|
||||
|
||||
loop
|
||||
sprite v0 v1 1
|
||||
v2 := 7 if v2 key then v0 += -1 # left
|
||||
v2 := 9 if v2 key then v0 += 1 # right
|
||||
v2 := 5 if v2 key then v1 += -1 # up
|
||||
v2 := 8 if v2 key then v1 += 1 # down
|
||||
again
|
||||
@@ -0,0 +1,30 @@
|
||||
###########################################
|
||||
#
|
||||
# Smile
|
||||
#
|
||||
# Draw smiley faces on the screen randomly
|
||||
# and periodically clear the display.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: smile
|
||||
0b00100100
|
||||
0b00100100
|
||||
0b00000000
|
||||
0b10000001
|
||||
0b01000010
|
||||
0b00111100
|
||||
|
||||
: main
|
||||
i := smile
|
||||
loop
|
||||
v2 := 0
|
||||
loop
|
||||
v0 := random 0b00111111
|
||||
v1 := random 0b00011111
|
||||
sprite v0 v1 6
|
||||
v2 += 1
|
||||
if v2 != 32 then
|
||||
again
|
||||
clear
|
||||
again
|
||||
@@ -0,0 +1,73 @@
|
||||
###########################################
|
||||
#
|
||||
# An Octo implementation of an in-place
|
||||
# selection sort capable of operating on
|
||||
# arrays of a fixed size up to 256 elements.
|
||||
#
|
||||
###########################################
|
||||
|
||||
:const SIZE 16
|
||||
:calc SIZE-1 { SIZE - 1 }
|
||||
|
||||
:alias here v1
|
||||
:alias rest v2
|
||||
:alias min-index v3
|
||||
:alias min-value v4
|
||||
:alias here-value v5
|
||||
|
||||
: selection-sort
|
||||
here := 0
|
||||
loop
|
||||
min-index := here
|
||||
i := data
|
||||
i += here
|
||||
load v0
|
||||
min-value := v0
|
||||
here-value := v0
|
||||
|
||||
rest := here
|
||||
rest += 1
|
||||
i := data
|
||||
i += rest
|
||||
loop
|
||||
load v0
|
||||
if v0 < min-value begin
|
||||
min-index := rest
|
||||
min-value := v0
|
||||
end
|
||||
|
||||
rest += 1
|
||||
if rest != SIZE then
|
||||
again
|
||||
|
||||
if min-index != here begin
|
||||
v0 := here-value
|
||||
i := data
|
||||
i += min-index
|
||||
save v0
|
||||
|
||||
v0 := min-value
|
||||
i := data
|
||||
i += here
|
||||
save v0
|
||||
end
|
||||
|
||||
here += 1
|
||||
if here != SIZE-1 then
|
||||
again
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example
|
||||
#
|
||||
###########################################
|
||||
|
||||
: data 14 5 15 6 1 3 10 7 0 9 11 4 2 13 8 12
|
||||
|
||||
: main
|
||||
selection-sort
|
||||
i := data
|
||||
load vf
|
||||
:breakpoint sort-complete
|
||||
;
|
||||
@@ -0,0 +1,116 @@
|
||||
###########################################
|
||||
#
|
||||
# An Octo implementation of an in-place
|
||||
# heap sort capable of operating on
|
||||
# arrays of a fixed size up to 255 elements.
|
||||
#
|
||||
###########################################
|
||||
|
||||
:const SIZE 16
|
||||
:calc SIZE-1 { SIZE - 1 }
|
||||
:calc LIMIT { ( SIZE / 2 ) + 1 }
|
||||
|
||||
:alias left-val v0
|
||||
:alias right-val v1
|
||||
:alias start v2
|
||||
:alias root v3
|
||||
:alias last v4
|
||||
:alias best v5
|
||||
:alias left v6
|
||||
:alias best-val v7
|
||||
:alias root-val v8
|
||||
|
||||
: heap-sort
|
||||
start := LIMIT
|
||||
last := SIZE
|
||||
loop
|
||||
root := start
|
||||
sift-down
|
||||
start += -1
|
||||
if start != -1 then
|
||||
again
|
||||
|
||||
start := SIZE-1
|
||||
loop
|
||||
# swap data[0] with data[start]:
|
||||
i := data
|
||||
load v0
|
||||
vf := v0
|
||||
|
||||
i := data
|
||||
i += start
|
||||
load v0
|
||||
i := data
|
||||
save v0
|
||||
|
||||
i := data
|
||||
i += start
|
||||
v0 := vf
|
||||
save v0
|
||||
|
||||
start += -1
|
||||
root := 0
|
||||
last := start
|
||||
sift-down
|
||||
|
||||
if start != 0 then
|
||||
again
|
||||
;
|
||||
|
||||
: assign-best
|
||||
best := left
|
||||
best-val := left-val
|
||||
jump found-best
|
||||
|
||||
: sift-down
|
||||
i := data
|
||||
i += root
|
||||
load v0
|
||||
root-val := v0
|
||||
|
||||
loop
|
||||
left <<= root
|
||||
|
||||
if left > last then return
|
||||
|
||||
i := data
|
||||
i += left
|
||||
load v1
|
||||
|
||||
best := left
|
||||
best += 1
|
||||
best-val := right-val
|
||||
|
||||
if left-val > right-val then jump assign-best
|
||||
if left == last then jump assign-best
|
||||
: found-best
|
||||
|
||||
if root-val >= best-val then return
|
||||
|
||||
i := data
|
||||
i += root
|
||||
v0 := best-val
|
||||
save v0
|
||||
|
||||
i := data
|
||||
i += best
|
||||
v0 := root-val
|
||||
save v0
|
||||
|
||||
root := best
|
||||
again
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example
|
||||
#
|
||||
###########################################
|
||||
|
||||
: data 14 5 15 6 1 3 10 7 0 9 11 4 2 13 8 12
|
||||
|
||||
: main
|
||||
heap-sort
|
||||
i := data
|
||||
load vf
|
||||
:breakpoint sort-complete
|
||||
;
|
||||
@@ -0,0 +1,131 @@
|
||||
###########################################
|
||||
#
|
||||
# An Octo implementation of an unusual
|
||||
# sorting algorithm which combines an
|
||||
# optimal sorting network and a merge pass.
|
||||
# This implementation is designed to sort
|
||||
# exactly 16 items. The 'sort-8' subroutine
|
||||
# can be used alone to sort the values
|
||||
# stored in the bottom 8 registers.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: sort-8
|
||||
# compare-and-swap:
|
||||
:macro cas A B {
|
||||
if A > B begin
|
||||
vf := A
|
||||
A := B
|
||||
B := vf
|
||||
end
|
||||
}
|
||||
|
||||
cas v0 v1
|
||||
cas v2 v3
|
||||
cas v4 v5
|
||||
cas v6 v7
|
||||
cas v0 v2
|
||||
cas v4 v6
|
||||
cas v1 v3
|
||||
cas v0 v4
|
||||
cas v5 v7
|
||||
cas v3 v7
|
||||
cas v1 v5
|
||||
cas v3 v5
|
||||
cas v2 v6
|
||||
cas v2 v4
|
||||
cas v1 v2
|
||||
cas v3 v6
|
||||
cas v2 v4
|
||||
cas v5 v6
|
||||
cas v3 v4
|
||||
;
|
||||
|
||||
: heap1 0 0 0 0 0 0 0 0
|
||||
: heap2 0 0 0 0 0 0 0 0
|
||||
|
||||
:alias val1 v8
|
||||
:alias val2 v9
|
||||
:alias dest va
|
||||
:alias index1 vb
|
||||
:alias index2 vc
|
||||
|
||||
: fused-sort
|
||||
i := data
|
||||
load v7
|
||||
sort-8
|
||||
val1 := v0
|
||||
i := heap1
|
||||
save v7
|
||||
|
||||
i := data
|
||||
load v7
|
||||
load v7 # cheaper than adding an offset of 8
|
||||
sort-8
|
||||
val2 := v0
|
||||
i := heap2
|
||||
save v7
|
||||
|
||||
index1 := 1
|
||||
index2 := 1
|
||||
dest := 0
|
||||
|
||||
: merge
|
||||
if val1 > val2 then jump merge-2
|
||||
append-1
|
||||
if index1 != 9 then jump merge
|
||||
loop
|
||||
append-2
|
||||
if dest == 16 then return
|
||||
again
|
||||
|
||||
: merge-2
|
||||
append-2
|
||||
if index2 != 9 then jump merge
|
||||
loop
|
||||
append-1
|
||||
if dest == 16 then return
|
||||
again
|
||||
|
||||
: append-1
|
||||
v0 := val1
|
||||
i := data
|
||||
i += dest
|
||||
save v0
|
||||
dest += 1
|
||||
|
||||
i := heap1
|
||||
i += index1
|
||||
load v0
|
||||
val1 := v0
|
||||
index1 += 1
|
||||
;
|
||||
|
||||
: append-2
|
||||
v0 := val2
|
||||
i := data
|
||||
i += dest
|
||||
save v0
|
||||
dest += 1
|
||||
|
||||
i := heap2
|
||||
i += index2
|
||||
load v0
|
||||
val2 := v0
|
||||
index2 += 1
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example
|
||||
#
|
||||
###########################################
|
||||
|
||||
: data 14 5 15 6 1 3 10 7 0 9 11 4 2 13 8 12
|
||||
|
||||
: main
|
||||
fused-sort
|
||||
i := data
|
||||
load vf
|
||||
:breakpoint sort-complete
|
||||
;
|
||||
@@ -0,0 +1,90 @@
|
||||
###########################################
|
||||
#
|
||||
# An Octo implementation of a
|
||||
# bucket sort capable of operating on
|
||||
# arrays of a fixed size up to 256 elements,
|
||||
# with values ranging 0-15.
|
||||
# This technique could be generalized
|
||||
# for full-byte values given a larger
|
||||
# bucket array.
|
||||
#
|
||||
###########################################
|
||||
|
||||
:const SIZE 16
|
||||
:const MAX_VAL 16
|
||||
|
||||
: empty
|
||||
0 0 0 0 0 0 0 0
|
||||
|
||||
: buckets
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
|
||||
: bucket-sort
|
||||
# zero bucket array
|
||||
i := empty
|
||||
load v7
|
||||
save v7 # unrolled loop to zero bucket array
|
||||
save v7 # and initialize loop counters for later.
|
||||
|
||||
# bucket the elements
|
||||
# v1 is data index (already 0)
|
||||
loop
|
||||
# load data
|
||||
i := data
|
||||
i += v1
|
||||
load v0
|
||||
vf := v0
|
||||
|
||||
# increment bucket
|
||||
i := buckets
|
||||
i += vf
|
||||
load v0
|
||||
v0 += 1
|
||||
i := buckets
|
||||
i += vf
|
||||
save v0
|
||||
|
||||
v1 += 1
|
||||
if v1 != SIZE then
|
||||
again
|
||||
|
||||
# unpack bucket counts
|
||||
# v1 is temporary count
|
||||
# v2 is data index (already 0)
|
||||
# v3 is bucket index (already 0)
|
||||
loop
|
||||
i := buckets
|
||||
i += v3
|
||||
load v0
|
||||
if v0 != 0 begin
|
||||
v1 := v0
|
||||
v0 := v3
|
||||
i := data
|
||||
i += v2
|
||||
v2 += v1
|
||||
loop
|
||||
save v0
|
||||
v1 += -1
|
||||
if v1 != 0 then
|
||||
again
|
||||
end
|
||||
v3 += 1
|
||||
if v3 != MAX_VAL then
|
||||
again
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example
|
||||
#
|
||||
###########################################
|
||||
|
||||
: data 14 5 15 6 1 3 10 7 0 9 11 4 2 13 8 12
|
||||
|
||||
: main
|
||||
bucket-sort
|
||||
i := data
|
||||
load vf
|
||||
:breakpoint sort-complete
|
||||
;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
###########################################
|
||||
#
|
||||
# A modular stack data structure using
|
||||
# a v0-based calling convention.
|
||||
# vf is used as a working temporary
|
||||
# register because it is "fragile".
|
||||
# maximum stack size is 256 bytes.
|
||||
#
|
||||
###########################################
|
||||
|
||||
# the first value is the pointer index
|
||||
: stack 0 0 0 0 0 0 0 0 0
|
||||
|
||||
: push
|
||||
# modifies vf, v0
|
||||
# takes argument in v0
|
||||
# stack[++stack[0] + 1] := v0
|
||||
|
||||
i := stack
|
||||
vf := v0
|
||||
load v0
|
||||
i += v0
|
||||
v0 := vf
|
||||
save v0
|
||||
|
||||
i := stack
|
||||
load v0
|
||||
v0 += 1
|
||||
i := stack
|
||||
save v0
|
||||
;
|
||||
|
||||
: pop
|
||||
# modifies vf, v0
|
||||
# returns result in v0
|
||||
# v0 := stack[stack[0]-- + 1]
|
||||
|
||||
i := stack
|
||||
load v0
|
||||
v0 += -1
|
||||
vf := v0
|
||||
i := stack
|
||||
save v0
|
||||
i += vf
|
||||
load v0
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example:
|
||||
#
|
||||
###########################################
|
||||
|
||||
: print
|
||||
# takes an arg in v0
|
||||
i := hex v0
|
||||
sprite va vb 5
|
||||
va += 6
|
||||
;
|
||||
|
||||
: main
|
||||
va := 3
|
||||
vb := 3
|
||||
|
||||
v0 := 5 push
|
||||
v0 := 3 push
|
||||
v0 := 1 push
|
||||
pop print
|
||||
v0 := 9 push
|
||||
pop print
|
||||
pop print
|
||||
pop print
|
||||
|
||||
# should print '1935'
|
||||
@@ -0,0 +1,80 @@
|
||||
###########################################
|
||||
#
|
||||
# A modular stack data structure using
|
||||
# a vf-based calling convention.
|
||||
# This approach can only be extended up to
|
||||
# a size 16 stack.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: scratch 0 0 0 0 0 0 0 0
|
||||
: under 0
|
||||
: stack 0
|
||||
: over 0 0 0 0 0 0 0
|
||||
|
||||
: push
|
||||
# here we take our argument from vf.
|
||||
# and do not corrupt any other registers.
|
||||
# we can eliminate the scratch saving
|
||||
# and restoring if low registers don't
|
||||
# need to be preserved.
|
||||
|
||||
i := scratch
|
||||
save v6
|
||||
|
||||
i := stack
|
||||
load v6
|
||||
i := over
|
||||
save v6
|
||||
i := stack
|
||||
v0 := vf
|
||||
save v0
|
||||
|
||||
i := scratch
|
||||
load v6
|
||||
;
|
||||
|
||||
: pop
|
||||
# result is left in vf.
|
||||
# again, we don't corrupt any other registers.
|
||||
|
||||
i := scratch
|
||||
save v7
|
||||
|
||||
i := stack
|
||||
load v7
|
||||
vf := v0
|
||||
i := under
|
||||
save v7
|
||||
|
||||
i := scratch
|
||||
load v7
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example:
|
||||
#
|
||||
###########################################
|
||||
|
||||
: print
|
||||
# takes an arg in vf
|
||||
i := hex vf
|
||||
sprite va vb 5
|
||||
va += 6
|
||||
;
|
||||
|
||||
: main
|
||||
va := 3
|
||||
vb := 3
|
||||
|
||||
vf := 5 push
|
||||
vf := 3 push
|
||||
vf := 1 push
|
||||
pop print
|
||||
vf := 9 push
|
||||
pop print
|
||||
pop print
|
||||
pop print
|
||||
|
||||
# should print '1935'
|
||||
@@ -0,0 +1,55 @@
|
||||
###########################################
|
||||
#
|
||||
# A modular stack data structure using
|
||||
# a v0-based calling convention.
|
||||
# This approach reserves a dedicated
|
||||
# register for a stack pointer and as
|
||||
# a result is very simple and fast.
|
||||
# maximum stack size is 256 bytes.
|
||||
#
|
||||
###########################################
|
||||
|
||||
:alias stack-ptr vd
|
||||
: stack 0 0 0 0 0 0 0 0
|
||||
|
||||
: push
|
||||
i := stack
|
||||
i += stack-ptr
|
||||
save v0
|
||||
stack-ptr += 1
|
||||
;
|
||||
|
||||
: pop
|
||||
stack-ptr += -1
|
||||
i := stack
|
||||
i += stack-ptr
|
||||
load v0
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example:
|
||||
#
|
||||
###########################################
|
||||
|
||||
: print
|
||||
# takes an arg in v0
|
||||
i := hex v0
|
||||
sprite va vb 5
|
||||
va += 6
|
||||
;
|
||||
|
||||
: main
|
||||
va := 3
|
||||
vb := 3
|
||||
|
||||
v0 := 5 push
|
||||
v0 := 3 push
|
||||
v0 := 1 push
|
||||
pop print
|
||||
v0 := 9 push
|
||||
pop print
|
||||
pop print
|
||||
pop print
|
||||
|
||||
# should print '1935'
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,254 @@
|
||||
###########################################
|
||||
#
|
||||
# F8Z: a chip8/Octo tech demo
|
||||
#
|
||||
# A/D move gomez left and right.
|
||||
# Q/E rotate the world around him.
|
||||
# Runs best at 100 cycles/frame.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: letter-F 0x07 0x19 0x61 0x81 0x87 0x99 0x81 0x81 0x87 0x9E 0x98 0x90 0x90 0xF0 0xE0
|
||||
: letter-8 0x0E 0x33 0x41 0x89 0x99 0x93 0x81 0xC1 0x89 0x99 0x91 0x83 0xCE 0x78 0x60
|
||||
: letter-Z 0x07 0x19 0x61 0x81 0x91 0xE1 0x43 0x86 0x89 0x81 0x81 0x87 0x9E 0xF8 0x60
|
||||
|
||||
: cloud1 0x07 0x0F 0x7F 0xFF
|
||||
: cloud2 0xC0 0xE0 0xFE 0xFF
|
||||
: cloud3 0x30 0x7E 0xFF
|
||||
|
||||
: pillar # (padded to 16 bytes/side)
|
||||
0x06 0x1B 0x65 0x8F 0xD5 0xBD 0xFB 0x7E 0x83 0xBB 0xBB 0xBB 0x83 0x7F 0xFD 0x00
|
||||
0x78 0xD6 0xFE 0xFD 0xBF 0xFF 0xFE 0xFF 0x83 0xAB 0xAB 0xBB 0x82 0xFF 0xBF 0x00
|
||||
0x60 0xB8 0xFE 0xFB 0x7B 0x7F 0xFF 0xDF 0x83 0xBA 0xA3 0xBB 0x83 0x7F 0xFD 0x00
|
||||
0x16 0xD9 0xA6 0xBB 0xFB 0xFF 0xDF 0xFE 0x82 0xBB 0xAB 0xAB 0x83 0x7F 0xF9 0x00
|
||||
|
||||
: floors # (padded to 8 bytes/tile)
|
||||
0xFE 0xFE 0xFE 0xE0 0xEF 0xEF 0xEF 0x00
|
||||
0xEF 0xEF 0xEF 0xE0 0xFE 0xFE 0xFE 0x00
|
||||
0xEF 0xEF 0xEF 0xE0 0xEE 0xEE 0xEE 0x00
|
||||
0xFE 0xFE 0xFE 0xE0 0xEE 0xEE 0xEE 0x00
|
||||
|
||||
: gomez # (padded to 16 bytes/frame)
|
||||
0x00 0x00 0x60 0xE0 0x7E 0xFF 0xBD 0xF7 0x7E 0x18 0x3C 0x5E 0x3C 0x3C 0x24 0x00 # facing right
|
||||
0x00 0x60 0x60 0xFE 0xFF 0xBD 0xF7 0x7E 0x18 0x3C 0x5E 0x3C 0x3C 0x48 0x00 0x00
|
||||
0x00 0x60 0x60 0xFE 0xFF 0xBD 0xF7 0x7E 0x18 0x7E 0x1C 0x3C 0x3C 0x24 0x00 0x00
|
||||
0x00 0x00 0x60 0xFE 0xFF 0xFF 0xBD 0x76 0x18 0x3C 0x5E 0x3C 0x3C 0x12 0x00 0x00
|
||||
0x00 0x00 0x06 0x07 0x7E 0xFF 0xBD 0xEF 0x7E 0x18 0x3C 0x7A 0x3C 0x3C 0x24 0x00 # facing left
|
||||
0x00 0x06 0x06 0x7F 0xFF 0xBD 0xEF 0x7E 0x18 0x3C 0x7A 0x3C 0x3C 0x12 0x00 0x00
|
||||
0x00 0x06 0x06 0x7F 0xFF 0xBD 0xEF 0x7E 0x18 0x7E 0x38 0x3C 0x3C 0x24 0x00 0x00
|
||||
0x00 0x00 0x06 0x7F 0xFF 0xFF 0xBD 0x6E 0x18 0x3C 0x7A 0x3C 0x3C 0x48 0x00 0x00
|
||||
|
||||
: pillar-pos
|
||||
46 10 16 46
|
||||
|
||||
: cloud-delta
|
||||
254 255 254 255 2 1 2 1
|
||||
|
||||
: sync
|
||||
v2 := 4
|
||||
delay := v2
|
||||
loop
|
||||
v2 := delay
|
||||
if v2 != 0 then
|
||||
again
|
||||
;
|
||||
|
||||
: draw-objects
|
||||
v0 := 2
|
||||
v1 := vd
|
||||
v1 += 8
|
||||
v2 := 1
|
||||
i := gomez
|
||||
i += vc # animation frame
|
||||
i += v8 # direction facing
|
||||
sprite va vb 15
|
||||
|
||||
# clouds
|
||||
i := cloud1
|
||||
sprite vd v0 4
|
||||
i := cloud2
|
||||
sprite v1 v0 4
|
||||
i := cloud3
|
||||
sprite ve v2 3
|
||||
|
||||
# pillar
|
||||
i := pillar-pos # get x coord
|
||||
i += v5
|
||||
load v0
|
||||
v1 := 9
|
||||
i := pillar
|
||||
v2 <<= v5 # add (rotation * 16)
|
||||
v2 <<= v2
|
||||
v2 <<= v2
|
||||
v2 <<= v2
|
||||
i += v2
|
||||
sprite v0 v1 15
|
||||
;
|
||||
|
||||
: draw-background
|
||||
v0 := 0
|
||||
v1 := 25
|
||||
loop
|
||||
i := floors
|
||||
v2 := random 0b11000
|
||||
i += v2
|
||||
sprite v0 v1 7
|
||||
v0 += 8
|
||||
if v0 != 64 then
|
||||
again
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Wipe Effects
|
||||
#
|
||||
###########################################
|
||||
|
||||
: wipe-common
|
||||
v1 := 16
|
||||
buzzer := v1
|
||||
|
||||
v1 := 0b11 # wrap rotation modulo 4
|
||||
v5 &= v1
|
||||
|
||||
i := gomez
|
||||
loop
|
||||
i += v1
|
||||
|
||||
v1 := 1
|
||||
sprite v0 v1 15
|
||||
v1 := 16
|
||||
sprite v0 v1 15
|
||||
|
||||
sync
|
||||
|
||||
v1 := 1
|
||||
sprite v0 v1 15
|
||||
v1 := 16
|
||||
sprite v0 v1 15
|
||||
v2 := v0
|
||||
|
||||
v0 += v3
|
||||
v1 := 0b111111
|
||||
v2 := v0
|
||||
v2 &= v1
|
||||
if v2 != 0 then
|
||||
again
|
||||
clear
|
||||
draw-background
|
||||
;
|
||||
|
||||
: wipe-left
|
||||
# rotate player's position
|
||||
v0 := va
|
||||
va := v7
|
||||
v7 := 64
|
||||
v7 -= v0
|
||||
|
||||
v5 += -1
|
||||
v0 := 64
|
||||
v3 := -16
|
||||
jump wipe-common
|
||||
|
||||
: wipe-right
|
||||
# rotate player's position
|
||||
v0 := va
|
||||
va := v7
|
||||
v7 := 64
|
||||
v7 += v0
|
||||
|
||||
v5 += 1
|
||||
v0 := 0
|
||||
v3 := 16
|
||||
jump wipe-common
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Movement and Animation
|
||||
#
|
||||
###########################################
|
||||
|
||||
: walk
|
||||
v9 += -1 # count down anim timer
|
||||
vc += 16 # advance frame
|
||||
v0 := 0b0110000
|
||||
vc &= v0
|
||||
if v8 == 0 then va += 1 # move
|
||||
if v8 != 0 then va += -1
|
||||
;
|
||||
|
||||
: face-left v8 := 64 ;
|
||||
: move-left if v8 == 0 then jump face-left v9 := 4 ;
|
||||
: face-right v8 := 0 ;
|
||||
: move-right if v8 == 64 then jump face-right v9 := 4 ;
|
||||
|
||||
: move-player
|
||||
if v9 != 0 then jump walk
|
||||
v0 := 7
|
||||
if v0 key then jump move-left
|
||||
v0 := 9
|
||||
if v0 key then jump move-right
|
||||
v0 := 4
|
||||
if v0 key then jump wipe-left
|
||||
v0 := 6
|
||||
if v0 key then jump wipe-right
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Main Loop
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
# title screen
|
||||
v0 := 15
|
||||
v1 := 13
|
||||
i := letter-F
|
||||
sprite v0 v1 15
|
||||
v0 += 12
|
||||
v1 += -5
|
||||
i := letter-8
|
||||
sprite v0 v1 15
|
||||
v0 += 12
|
||||
v1 += -5
|
||||
i := letter-Z
|
||||
sprite v0 v1 15
|
||||
v0 := 16
|
||||
loop
|
||||
sync
|
||||
v0 += -1
|
||||
if v0 != 0 then
|
||||
again
|
||||
clear
|
||||
|
||||
# v0-v3 are used extensively as temporaries
|
||||
# v4 is still free
|
||||
|
||||
v5 := 0 # rotation index
|
||||
v6 := 0 # real x
|
||||
v7 := 0 # real y
|
||||
v8 := 0 # 0 - right, 64 - left
|
||||
v9 := 0 # moving?
|
||||
va := 10 # player x position
|
||||
vb := 10 # player y position
|
||||
vc := 0 # player anim frame
|
||||
vd := 10 # big cloud x
|
||||
ve := 40 # small cloud x
|
||||
|
||||
draw-background
|
||||
draw-objects
|
||||
loop
|
||||
draw-objects
|
||||
move-player
|
||||
|
||||
i := cloud-delta
|
||||
i += v5
|
||||
i += v5
|
||||
load v1
|
||||
vd += v0
|
||||
ve += v1
|
||||
|
||||
draw-objects
|
||||
sync
|
||||
again
|
||||
@@ -0,0 +1,231 @@
|
||||
###########################################
|
||||
#
|
||||
# Fuse
|
||||
#
|
||||
# A minimalist reinterpretation of
|
||||
# the classic Pipe Dream. Assemble lines
|
||||
# to guide a burning fuse. Don't let it
|
||||
# burn out!
|
||||
#
|
||||
# Press WASD to move the current line
|
||||
# fragments and E to lay them down.
|
||||
# You cannot lay down a line overlapping
|
||||
# any existing lines.
|
||||
#
|
||||
# Runs best at 7 cycles/frame.
|
||||
#
|
||||
# John Earnest
|
||||
#
|
||||
###########################################
|
||||
|
||||
:alias ex vd # fuse position x
|
||||
:alias ey vc # fuse position y
|
||||
:alias px vb # cursor position x
|
||||
:alias py va # cursor position y
|
||||
:alias tile v9 # selected tile
|
||||
:alias timer-0 v8 # fuse movement cookoff
|
||||
:alias timer-1 v7 # score (low digits)
|
||||
:alias timer-2 v6 # score (high digits)
|
||||
|
||||
:const tile-mask 0b111000
|
||||
:const fuse-speed 3 # higher is slower
|
||||
|
||||
: main
|
||||
init-game
|
||||
|
||||
# draw starting cursor:
|
||||
i := tiles
|
||||
i += tile
|
||||
sprite px py 8
|
||||
|
||||
# wait for an initial key press:
|
||||
show-title
|
||||
v0 := key
|
||||
show-title
|
||||
|
||||
loop
|
||||
i := tiles
|
||||
i += tile
|
||||
|
||||
v0 := 6 if v0 key begin # keyboard E
|
||||
# wait for key release:
|
||||
loop if v0 key then again
|
||||
|
||||
# we can't drop a tile overlapping
|
||||
# any existing lines:
|
||||
sprite px py 8 # erase
|
||||
sprite px py 8 # redraw
|
||||
|
||||
if vf == 0 begin
|
||||
# drop a tile:
|
||||
tile := random tile-mask
|
||||
i := tiles
|
||||
i += tile
|
||||
sprite px py 8
|
||||
end
|
||||
else
|
||||
# erase the cursor:
|
||||
sprite px py 8
|
||||
|
||||
# move cursor:
|
||||
v0 := 5 if v0 key then py += -1 # keyboard W
|
||||
v0 := 8 if v0 key then py += 1 # keyboard S
|
||||
v0 := 7 if v0 key then px += -1 # keyboard A
|
||||
v0 := 9 if v0 key then px += 1 # keyboard D
|
||||
|
||||
# handle fuse movement without
|
||||
# the cursor drawn, to avoid
|
||||
# extreme weirdness:
|
||||
move-fuse
|
||||
|
||||
# redraw cursor:
|
||||
i := tiles
|
||||
i += tile
|
||||
sprite px py 8
|
||||
end
|
||||
|
||||
# sync framerate
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
vf := 6
|
||||
delay := vf
|
||||
again
|
||||
|
||||
: init-game
|
||||
clear
|
||||
|
||||
# set up a random starting position:
|
||||
ex := random 15
|
||||
ex += 8
|
||||
ey := random 31
|
||||
ey += 16
|
||||
v0 := random 0b11000
|
||||
i := starts
|
||||
i += v0
|
||||
sprite ex ey 8
|
||||
|
||||
# initialize the cursor:
|
||||
tile := random tile-mask
|
||||
px := 1
|
||||
py := 1
|
||||
|
||||
# reset score:
|
||||
timer-0 := 0
|
||||
timer-1 := 0
|
||||
timer-2 := 0
|
||||
;
|
||||
|
||||
: move-fuse
|
||||
# don't move every single frame:
|
||||
timer-0 += 1
|
||||
if timer-0 != fuse-speed then return
|
||||
timer-0 := 0
|
||||
|
||||
# increment score:
|
||||
timer-1 += 1
|
||||
if timer-1 == 100 begin
|
||||
timer-1 := 0
|
||||
timer-2 += 1
|
||||
end
|
||||
|
||||
:macro try-move SPRITE REG DELTA {
|
||||
i := SPRITE
|
||||
sprite ex ey 5
|
||||
if vf != 0 begin
|
||||
REG += DELTA
|
||||
return
|
||||
end
|
||||
sprite ex ey 5
|
||||
}
|
||||
try-move dot-n ey -1 # north
|
||||
try-move dot-e ex 1 # east
|
||||
try-move dot-s ey 1 # south
|
||||
try-move dot-w ex -1 # west
|
||||
|
||||
: game-over
|
||||
# no trail, so we've failed!
|
||||
i := dot
|
||||
v0 := 6 # keyboard E
|
||||
loop
|
||||
sprite ex ey 5
|
||||
if v0 -key then # key down
|
||||
again
|
||||
loop
|
||||
if v0 key then # key up
|
||||
again
|
||||
clear
|
||||
|
||||
: show-score
|
||||
v3 := 37 # x position
|
||||
v4 := 10 # y position
|
||||
|
||||
# draw low two digits:
|
||||
i := digit-buffer
|
||||
bcd timer-1
|
||||
show-score-byte
|
||||
|
||||
# draw high two digits:
|
||||
i := digit-buffer
|
||||
bcd timer-2
|
||||
show-score-byte
|
||||
|
||||
# wait for any key:
|
||||
v0 := key
|
||||
|
||||
init-game
|
||||
;
|
||||
|
||||
: show-score-byte
|
||||
load v2
|
||||
i := hex v2
|
||||
sprite v3 v4 5
|
||||
v3 += -5
|
||||
i := hex v1
|
||||
sprite v3 v4 5
|
||||
v3 += -5
|
||||
;
|
||||
|
||||
: show-title
|
||||
v0 := 52
|
||||
v1 := 2
|
||||
v2 := 1
|
||||
i := title
|
||||
loop
|
||||
sprite v0 v1 1
|
||||
v1 += 1
|
||||
i += v2
|
||||
if v1 != 30 then
|
||||
again
|
||||
;
|
||||
|
||||
: digit-buffer 0 0 0
|
||||
|
||||
: title
|
||||
0x7F 0xFF 0xC0 0xFC 0xC0 0xC0 0x00 0xC3
|
||||
0xC3 0xC3 0xFF 0x7E 0x00 0x7F 0xFF 0xC0
|
||||
0xFF 0x03 0xFF 0xFE 0x00 0x7F 0xFF 0xC0
|
||||
0xFC 0xC0 0xFF 0x7F
|
||||
|
||||
: dot 0x00 0x00 0x00 0x10 0x00
|
||||
: dot-n 0x00 0x00 0x10 0x00 0x00
|
||||
: dot-s 0x00 0x00 0x00 0x00 0x10
|
||||
: dot-e 0x00 0x00 0x00 0x08 0x00
|
||||
: dot-w 0x00 0x00 0x00 0x20 0x00
|
||||
|
||||
: starts
|
||||
0x40 0x5C 0x54 0x44 0x44 0x7C 0x00 0x00 # N
|
||||
0x00 0x7F 0x40 0x4C 0x44 0x7C 0x00 0x00 # E
|
||||
0x00 0x7C 0x44 0x44 0x54 0x74 0x04 0x00 # S
|
||||
0x00 0x3C 0x24 0x24 0x04 0xFC 0x00 0x00 # W
|
||||
|
||||
: tiles
|
||||
0x20 0x20 0xE0 0x00 0x0F 0x08 0x08 0x08 # cross 1
|
||||
0x04 0x04 0x0C 0x08 0xEF 0x20 0x20 0x20 # cross 2
|
||||
0x02 0x7E 0x40 0x7E 0x02 0x7E 0x40 0x7E # zig n-s
|
||||
0xC0 0x5C 0x54 0x55 0x55 0x55 0x57 0x70 # zig e-w
|
||||
0x14 0x14 0x34 0xE7 0x00 0x7E 0xC3 0x00 # tee N
|
||||
0x40 0x5F 0x50 0x57 0x54 0x54 0x54 0x54 # tee E
|
||||
0x00 0xF0 0x1F 0xC0 0x6E 0x2A 0x2B 0x28 # tee S
|
||||
0x22 0xE2 0x02 0x72 0x56 0x54 0xD4 0x14 # tee W
|
||||
@@ -0,0 +1,215 @@
|
||||
###########################################
|
||||
#
|
||||
# Grad School Simulator 2014
|
||||
#
|
||||
# "Welcome to the sunless depths of my ennui."
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
hires
|
||||
draw-background
|
||||
loop
|
||||
do-behavior
|
||||
again
|
||||
|
||||
: do-behavior
|
||||
# by AND masking an 8 bit value with 0b1110
|
||||
# we can create the numbers 0,2,4,8,10,12,14,16:
|
||||
v0 := random 0b1110
|
||||
jump0 behavior-table
|
||||
|
||||
: behavior-table
|
||||
# this is a jump table. Each entry
|
||||
# is 1 instruction long, or 2 bytes:
|
||||
jump blink
|
||||
jump blink
|
||||
jump idle
|
||||
jump idle
|
||||
jump grimace
|
||||
jump show-icon
|
||||
jump show-icon
|
||||
jump show-icon
|
||||
|
||||
# here I've overlapped two subroutines,
|
||||
# since they share the same ending instructions:
|
||||
: blink
|
||||
blink-toggle
|
||||
vf := 10 wait
|
||||
blink-toggle
|
||||
: idle
|
||||
vf := 45 wait
|
||||
;
|
||||
|
||||
: blink-toggle
|
||||
i := blink-mask
|
||||
v0 := 55
|
||||
v1 := 26
|
||||
sprite v0 v1 3
|
||||
v0 := 65
|
||||
v1 := 26
|
||||
sprite v0 v1 3
|
||||
;
|
||||
|
||||
: wait
|
||||
# takes a time argument in vf.
|
||||
# vf gets destroyed by +/-/>>/<</sprite
|
||||
# so we can freely use it as a temp value.
|
||||
delay := vf
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
;
|
||||
|
||||
: grimace
|
||||
i := grimace-mask
|
||||
v0 := 59
|
||||
v1 := 37
|
||||
sprite v0 v1 1
|
||||
jump idle
|
||||
|
||||
: blink-mask
|
||||
# this is carefully designed to xor with
|
||||
# the base image and toggle eye blinks:
|
||||
0x60 0x60 0xF0
|
||||
|
||||
: grimace-mask
|
||||
# same idea as blink-mask:
|
||||
0x1C
|
||||
|
||||
|
||||
: show-icon
|
||||
icon-setup
|
||||
draw-icon
|
||||
v1 += -1
|
||||
draw-icon
|
||||
v1 += 1
|
||||
draw-icon
|
||||
v1 += -1
|
||||
draw-icon
|
||||
jump idle
|
||||
|
||||
: draw-icon
|
||||
sprite v1 v2 0
|
||||
vf := 10 wait
|
||||
sprite v1 v2 0
|
||||
;
|
||||
|
||||
: icon-setup
|
||||
# by AND masking an 8 bit value with 0b11000
|
||||
# we can create the numbers 0, 8, 16 or 24:
|
||||
v0 := random 0b11000
|
||||
jump0 icon-setup-table
|
||||
|
||||
: icon-setup-table
|
||||
# this is a jump table. Each entry
|
||||
# is 4 instructions long, or 8 bytes:
|
||||
v1 := 27 v2 := 16 i := hungry ;
|
||||
v1 := 27 v2 := 16 i := cold ;
|
||||
v1 := 80 v2 := 16 i := tired ;
|
||||
v1 := 80 v2 := 16 i := busy ;
|
||||
|
||||
: hungry # (left side)
|
||||
0x1F 0x20 0x20 0xD8 0x50 0x06 0xC0 0x02
|
||||
0x95 0x24 0x95 0x62 0x9F 0x64 0x4E 0x63
|
||||
0x84 0x21 0x84 0x22 0xC4 0x24 0x84 0x24
|
||||
0x81 0x02 0x58 0xD2 0x27 0x24 0x00 0x38
|
||||
: cold # (left side)
|
||||
0x3F 0xE0 0x40 0x10 0x8C 0x68 0x92 0x08
|
||||
0x92 0x68 0x92 0x08 0x92 0x68 0x92 0x08
|
||||
0x92 0x68 0x92 0x08 0xA1 0x68 0xBF 0x08
|
||||
0xBF 0x08 0x9E 0x07 0x40 0x02 0x3F 0xFC
|
||||
: tired # (right side)
|
||||
0x3F 0x80 0x40 0x4C 0xBF 0x2A 0x9F 0x24
|
||||
0x46 0x10 0x4C 0x0C 0x9F 0x02 0xBF 0x02
|
||||
0x80 0x79 0x84 0x31 0xA0 0x61 0x82 0xF9
|
||||
0x40 0x02 0x26 0x3C 0x29 0xC0 0x70 0x00
|
||||
: busy # (right side)
|
||||
0x0F 0xE0 0x30 0x10 0x47 0x88 0x47 0x84
|
||||
0x88 0x44 0x91 0x24 0x91 0x24 0x97 0x24
|
||||
0x90 0x24 0x88 0x44 0x47 0x88 0x47 0x88
|
||||
0x20 0x10 0x27 0xE0 0x28 0x00 0x70 0x00
|
||||
|
||||
: draw-background
|
||||
i := background
|
||||
v0 := 1 # sprite stride
|
||||
v1 := 0 # sprite x
|
||||
v2 := 0 # sprite y
|
||||
loop
|
||||
# I could draw this in larger chunks by packing
|
||||
# the data differently, but I like vertical wipes:
|
||||
sprite v1 v2 1
|
||||
i += v0
|
||||
v1 += 8
|
||||
if v1 == 128 then v2 += 1
|
||||
if v1 == 128 then v1 := 0
|
||||
if v2 != 64 then
|
||||
again
|
||||
;
|
||||
|
||||
: background
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x7C 0x00 0x00 0x00 0x78 0x00 0x00 0x00 0x07 0x80 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0xFE 0x00 0x00 0x00 0xFC 0x06 0x00 0x00 0x0F 0xD8 0x00 0x00 0x00 0x00 0x00
|
||||
0x01 0xC6 0x00 0x00 0x00 0xCC 0x06 0x00 0x06 0x0C 0xD8 0x00 0x0C 0x00 0x00 0x00
|
||||
0x01 0x86 0x00 0x00 0xE0 0xC0 0x0C 0x00 0x06 0x0C 0x00 0x00 0x0C 0x03 0x00 0x00
|
||||
0x03 0x80 0xE3 0xC0 0xC0 0xE1 0x8E 0x18 0xCC 0x0E 0x37 0x66 0xD9 0xE3 0x31 0xC0
|
||||
0x03 0x3C 0xF0 0xE7 0xC0 0x73 0xDF 0x3D 0xEC 0x07 0x37 0xF6 0xD8 0x7F 0xF9 0xE0
|
||||
0x03 0x3D 0xB7 0xEB 0x80 0x37 0x1B 0x2D 0x78 0x03 0x6D 0x6C 0xB3 0xF6 0x5B 0x60
|
||||
0x03 0x19 0xBC 0xDB 0x83 0x36 0x3B 0x6F 0x78 0x33 0x6D 0x6D 0xB6 0x66 0xDB 0x60
|
||||
0x03 0xFB 0x0F 0xDF 0x03 0xF7 0xB6 0x7B 0xD8 0x3F 0xD8 0xCD 0xB7 0xEC 0xF6 0x00
|
||||
0x01 0xF3 0x07 0x8F 0x01 0xE3 0x37 0x31 0x9C 0x1E 0xD8 0xCF 0x3B 0xCE 0xE6 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF 0xE4 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x03 0xFF 0xF8 0x20 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x07 0xFF 0xFF 0xC0 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x07 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x1F 0xFF 0xFF 0x80 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x3F 0xFF 0xFF 0xC0 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x7F 0xFF 0xFF 0xE0 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0xBC 0xFF 0x87 0xF0 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x7C 0x3F 0xE7 0xF0 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x78 0x03 0xE3 0xB0 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x78 0x00 0x03 0xA0 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x78 0x09 0x03 0x80 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0xF1 0xF1 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0xFF 0xF0 0xFE 0x80 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0xDC 0xDF 0xB2 0x80 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x5C 0xD0 0xB2 0x80 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x54 0x10 0x82 0x80 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x74 0x30 0xC3 0x80 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x37 0xF0 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x11 0xD0 0xBA 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x08 0x10 0x82 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x08 0x0F 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x00 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x03 0xFC 0x00 0x07 0x80 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x06 0xAA 0x00 0x06 0xC0 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x0D 0x55 0x1C 0x0D 0x60 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x1A 0xAF 0xC0 0x3A 0xB0 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x1D 0x7F 0x7F 0xFD 0x70 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x3A 0xFA 0x31 0xFE 0xB8 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x35 0xD0 0x5F 0x57 0x58 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x2B 0xA4 0x20 0x83 0xA8 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x75 0x00 0x1F 0x0B 0x5C 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x6B 0xA0 0x0E 0x02 0xAC 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x77 0x00 0x04 0x00 0xDC 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x6A 0x00 0x00 0x01 0xAC 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0xF7 0x00 0x00 0x00 0x5E 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0xEC 0x00 0x00 0x00 0xFE 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0xF4 0x02 0x00 0x00 0x3E 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0xF9 0xC0 0x00 0x0D 0xDE 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0xFE 0x30 0x00 0x12 0x36 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0xF8 0x50 0x00 0x53 0x9E 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xE0 0xC9 0x00 0x24 0x43 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0x00 0x00 0x84 0x00 0x00 0xD9 0x48 0x01 0x24 0xC0 0x80 0x00 0x10 0x00 0x00 0x00
|
||||
0x00 0x20 0x00 0x03 0xC1 0xB3 0x24 0x00 0x29 0x22 0x40 0x60 0x00 0x80 0x00 0x04
|
||||
0x00 0x00 0x00 0x04 0x21 0x76 0xA7 0xFF 0xF2 0x31 0xA0 0x00 0x00 0x00 0x00 0x40
|
||||
0x00 0x00 0x7F 0xFB 0x1F 0xFE 0x9D 0x99 0x9E 0xF8 0xFF 0xFF 0xF0 0x00 0x00 0x00
|
||||
0x55 0x55 0x80 0xDA 0xB8 0x7E 0x7A 0x66 0x67 0xFF 0xE0 0x08 0x0E 0xAA 0xAA 0xAA
|
||||
0xFF 0xFE 0x61 0x17 0xF0 0xF5 0x9D 0x99 0x99 0xB4 0x07 0xFE 0x7B 0xFF 0xFF 0xFF
|
||||
0xFF 0xF8 0x32 0x20 0x01 0x08 0x00 0x00 0x00 0x02 0x78 0x01 0x8C 0xFF 0xFF 0xFF
|
||||
0xFF 0xE1 0x04 0x20 0x06 0x47 0xFF 0xFF 0xFF 0xFC 0x23 0xFC 0xE3 0x3F 0xFF 0xFF
|
||||
0xFF 0x80 0x83 0xFF 0xF9 0xC0 0x14 0x00 0x08 0x00 0x18 0x00 0x19 0x0F 0xFF 0xFF
|
||||
0xFF 0xF8 0x00 0x04 0x03 0x80 0x28 0x07 0xFF 0xE2 0x04 0xBF 0x8E 0xDF 0xFF 0xFF
|
||||
@@ -0,0 +1,73 @@
|
||||
###########################################
|
||||
#
|
||||
# Keyboard Test
|
||||
#
|
||||
# A simple live display of which CHIP-8
|
||||
# keys appear to be held down at any given time.
|
||||
# useful for testing alternative Keyboard
|
||||
# layouts or input routines.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: held 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
: keymap 0x1 0x2 0x3 0xC 0x4 0x5 0x6 0xD 0x7 0x8 0x9 0xE 0xA 0x0 0xB 0xF
|
||||
: button 0x7E 0xFF 0xFF 0xFF 0xFF 0xFF 0x7E
|
||||
|
||||
: main
|
||||
:const cell 8
|
||||
:calc start-x { 2 + 32 - ( cell * 4 ) / 2 }
|
||||
:calc start-y { 1 + 0 }
|
||||
:calc end-x { start-x + cell * 4 }
|
||||
:calc end-y { start-y + cell * 4 }
|
||||
|
||||
v1 := start-x
|
||||
v2 := start-y
|
||||
v3 := 0
|
||||
loop
|
||||
i := keymap
|
||||
i += v3
|
||||
load v0
|
||||
i := hex v0
|
||||
sprite v1 v2 5
|
||||
v1 += cell
|
||||
if v1 == end-x then v2 += cell
|
||||
if v1 == end-x then v1 := start-x
|
||||
v3 += 1
|
||||
if v3 != 16 then
|
||||
again
|
||||
|
||||
loop
|
||||
# unroll this loop fully to try to
|
||||
# minimize input lag:
|
||||
:macro scan {
|
||||
:calc keycode { @ keymap + CALLS }
|
||||
:calc heldaddr { held + CALLS }
|
||||
:calc kx { -2 + start-x + cell * floor CALLS % 4 }
|
||||
:calc ky { -1 + start-y + cell * floor CALLS / 4 }
|
||||
v1 := keycode
|
||||
v2 := kx
|
||||
v3 := ky
|
||||
i := heldaddr
|
||||
load v0
|
||||
if v0 == 0 begin
|
||||
if v1 key begin
|
||||
v0 := 1
|
||||
i := button
|
||||
sprite v2 v3 7
|
||||
end
|
||||
else
|
||||
if v1 -key begin
|
||||
v0 := 0
|
||||
i := button
|
||||
sprite v2 v3 7
|
||||
end
|
||||
end
|
||||
i := heldaddr
|
||||
save v0
|
||||
}
|
||||
scan scan scan scan
|
||||
scan scan scan scan
|
||||
scan scan scan scan
|
||||
scan scan scan scan
|
||||
again
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
###########################################
|
||||
#
|
||||
# MacroMirror
|
||||
#
|
||||
# Statically compute vertically or
|
||||
# horizontally mirrored copies of 8x8 sprites
|
||||
# using macros and the '@' operator.
|
||||
# These techniques generalize readily to
|
||||
# arbitrary-sized memory blocks.
|
||||
#
|
||||
# John Earnest
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
v1 := 10
|
||||
i := sprite-1 sprite v0 v0 8
|
||||
i := sprite-2 sprite v0 v1 8
|
||||
i := sprite-3 sprite v1 v0 8
|
||||
i := sprite-4 sprite v1 v1 8
|
||||
loop again
|
||||
|
||||
# see http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits
|
||||
:macro rev8 X { :byte { 0xFF & ( 0x10101 * ( 0x22110 & 0x0802 * X ) | 0x88440 & 0x8020 * X ) >> 16 } }
|
||||
|
||||
:macro mirror-v_ { :byte { @ from + 7 - HERE - to } }
|
||||
:macro mirror-h_ { :calc t { @ from + HERE - to } rev8 t }
|
||||
:macro mirror-8 BASE OP { :calc to { HERE } :calc from { BASE } OP OP OP OP OP OP OP OP }
|
||||
:macro mirror-v BASE { mirror-8 BASE mirror-v_ }
|
||||
:macro mirror-h BASE { mirror-8 BASE mirror-h_ }
|
||||
|
||||
: sprite-1 0x18 0x2C 0x46 0x83 0xEF 0x2C 0x2C 0x3C
|
||||
: sprite-3 0x18 0x14 0xF2 0x81 0xF3 0xF6 0x1C 0x18
|
||||
: sprite-2 mirror-v sprite-1
|
||||
: sprite-4 mirror-h sprite-3
|
||||
@@ -0,0 +1,80 @@
|
||||
###########################################
|
||||
#
|
||||
# Mondri8
|
||||
#
|
||||
# Draw random compositions in the style
|
||||
# of Piet Mondrian. When drawing completes,
|
||||
# press any Chip8 key to draw another.
|
||||
#
|
||||
###########################################
|
||||
|
||||
:const LINE_COUNT 10
|
||||
:const FILL_COUNT 5
|
||||
|
||||
:alias x v0
|
||||
:alias y v1
|
||||
:alias px v2 # x position when scanning
|
||||
:alias py v3 # y position when scanning
|
||||
:alias dx v4 # change (delta) in x position when scanning
|
||||
:alias dy v5 # change (delta) in y position when scanning
|
||||
:alias counter v6
|
||||
|
||||
: main
|
||||
hires
|
||||
i := point
|
||||
loop
|
||||
counter := LINE_COUNT
|
||||
loop
|
||||
somewhere h-line
|
||||
somewhere v-line
|
||||
counter += -1
|
||||
if counter != 0 then
|
||||
again
|
||||
counter := FILL_COUNT
|
||||
loop
|
||||
somewhere fill
|
||||
counter += -1
|
||||
if counter != 0 then
|
||||
again
|
||||
v0 := key
|
||||
clear
|
||||
again
|
||||
|
||||
: somewhere
|
||||
x := random 0xFF
|
||||
y := random 0xFF
|
||||
;
|
||||
|
||||
: scan
|
||||
loop
|
||||
sprite px py 1
|
||||
while vf == 0
|
||||
px += dx
|
||||
py += dy
|
||||
again
|
||||
sprite px py 1
|
||||
;
|
||||
|
||||
: v-line
|
||||
px := x dx := 0
|
||||
py := y dy := -1 scan
|
||||
py := y dy := 1 py += dy scan
|
||||
;
|
||||
|
||||
: h-line
|
||||
py := y dy := 0
|
||||
px := x dx := -1 scan
|
||||
px := x dx := 1 px += dx scan
|
||||
;
|
||||
|
||||
: fill
|
||||
loop
|
||||
h-line
|
||||
y += 1
|
||||
sprite x y 1
|
||||
while vf == 0
|
||||
again
|
||||
sprite x y 1
|
||||
;
|
||||
|
||||
: point 0x80
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,295 @@
|
||||
###########################################
|
||||
#
|
||||
# Outlaw
|
||||
#
|
||||
# An adaptation of the Atari 2600 game
|
||||
# "Outlaw" for the Chip8.
|
||||
#
|
||||
# Move with ASWD and fire with E.
|
||||
# Holding a direction while firing will
|
||||
# fire an angled shot, which ricochets.
|
||||
# Plays fairly well at 30 cycles/frame
|
||||
#
|
||||
###########################################
|
||||
|
||||
: cactus 0x38 0x38 0x3B 0x1B 0x1B 0x1B 0xDF 0xDE 0xD8 0xD8 0xF8 0x78 0x18 0x1C 0x0C
|
||||
: left 0x00 0x00 0x70 0xF8 0x70 0x67 0x7C 0x60 0x60 0x78 0x28 0xEC
|
||||
: lwalk1 0x18 0x3E 0x1C 0x18 0x7E 0x99 0x99 0x99 0x5A 0x3C 0x66 0xC3
|
||||
: lwalk2 0x18 0x3E 0x1C 0x18 0x7E 0x99 0x99 0x99 0x5A 0x3C 0x24 0x36
|
||||
: right 0x00 0x00 0x06 0x1F 0x0E 0xE6 0x3E 0x06 0x06 0x1E 0x14 0x37
|
||||
: rwalk1 0x18 0x7C 0x38 0x18 0x7E 0x99 0x99 0x99 0x5A 0x3C 0x66 0xC3
|
||||
: rwalk2 0x18 0x7C 0x38 0x18 0x7E 0x99 0x99 0x99 0x5A 0x3C 0x24 0x6C
|
||||
: edge 0xFF 0xFF
|
||||
: bullet 0x80
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Register map
|
||||
#
|
||||
###########################################
|
||||
|
||||
:alias leftx ve
|
||||
:alias lefty vd
|
||||
:alias leftframe vc
|
||||
:alias leftbx vb
|
||||
:alias leftby va
|
||||
:alias leftfire v9
|
||||
|
||||
:alias rightx v8
|
||||
:alias righty v7
|
||||
:alias rightframe v6
|
||||
:alias rightbx v5
|
||||
:alias rightby v4
|
||||
:alias rightfire v3
|
||||
|
||||
:const FIRE_ST 1
|
||||
:const FIRE_UP 2
|
||||
:const FIRE_DN 3
|
||||
|
||||
# v0-v2 and vf are left as temporaries
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Bullets
|
||||
#
|
||||
###########################################
|
||||
|
||||
: fire-left-bullet
|
||||
v0 := 6
|
||||
if v0 -key then return
|
||||
leftfire := FIRE_ST
|
||||
v0 := 5
|
||||
if v0 key then leftfire := FIRE_UP
|
||||
v0 := 8
|
||||
if v0 key then leftfire := FIRE_DN
|
||||
|
||||
# spawn bullet
|
||||
leftbx := leftx
|
||||
leftbx += 9
|
||||
leftby := lefty
|
||||
leftby += 5
|
||||
|
||||
# draw initial bullet frame
|
||||
i := bullet
|
||||
sprite leftbx leftby 1
|
||||
;
|
||||
|
||||
: move-left-bullet
|
||||
sprite leftbx leftby 1
|
||||
leftbx += 1
|
||||
if leftfire == FIRE_UP then leftby += -1
|
||||
if leftfire == FIRE_DN then leftby += 1
|
||||
|
||||
# bounce off top and bottom edge
|
||||
if leftby == 1 then leftfire := FIRE_DN
|
||||
if leftby == 30 then leftfire := FIRE_UP
|
||||
|
||||
# despawn on right edge
|
||||
if leftbx == 63 then leftfire := 0
|
||||
if leftfire == 0 then return
|
||||
sprite leftbx leftby 1
|
||||
|
||||
# collide with obstacles
|
||||
if vf == 0 then return
|
||||
leftfire := 0
|
||||
;
|
||||
|
||||
: fire-right-bullet
|
||||
if rightfire != 0 then return
|
||||
rightfire := FIRE_ST
|
||||
v0 := random 0b11
|
||||
if v0 == 1 then rightfire := FIRE_UP
|
||||
if v0 == 2 then rightfire := FIRE_DN
|
||||
|
||||
# spawn bullet
|
||||
rightbx := rightx
|
||||
rightbx += -1
|
||||
rightby := righty
|
||||
rightby += 5
|
||||
|
||||
# draw initial bullet frame
|
||||
i := bullet
|
||||
sprite rightbx rightby 1
|
||||
;
|
||||
|
||||
: move-right-bullet
|
||||
sprite rightbx rightby 1
|
||||
rightbx += -1
|
||||
if rightfire == FIRE_UP then rightby += -1
|
||||
if rightfire == FIRE_DN then rightby += 1
|
||||
|
||||
# bounce off top and bottom edge
|
||||
if rightby == 1 then rightfire := FIRE_DN
|
||||
if rightby == 30 then rightfire := FIRE_UP
|
||||
|
||||
# despawn on right edge
|
||||
if rightbx == 0 then rightfire := 0
|
||||
if rightfire == 0 then return
|
||||
sprite rightbx rightby 1
|
||||
|
||||
# collide with obstacles
|
||||
if vf == 0 then return
|
||||
rightfire := 0
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Gunslingers
|
||||
#
|
||||
###########################################
|
||||
|
||||
: move-left-player
|
||||
v1 := leftx
|
||||
v2 := lefty
|
||||
|
||||
# process movement keys
|
||||
v0 := 7
|
||||
if v0 key then v1 += -1
|
||||
v0 := 9
|
||||
if v0 key then v1 += 1
|
||||
v0 := 5
|
||||
if v0 key then v2 += -1
|
||||
v0 := 8
|
||||
if v0 key then v2 += 1
|
||||
|
||||
# animate player movement
|
||||
v0 := 0
|
||||
if v1 != leftx then v0 := 24
|
||||
if v2 != lefty then v0 := 24
|
||||
if leftframe == 24 then v0 := 12
|
||||
vf := 6
|
||||
if vf key then v0 := 0
|
||||
|
||||
# clamp position within left side
|
||||
if v1 == 0 then v1 := 1
|
||||
if v1 == 21 then v1 := 20
|
||||
if v2 == 0 then v2 := 1
|
||||
if v2 == 18 then v2 := 17
|
||||
|
||||
# update position
|
||||
i := left
|
||||
i += leftframe
|
||||
sprite leftx lefty 12
|
||||
leftx := v1
|
||||
lefty := v2
|
||||
leftframe := v0
|
||||
i := left
|
||||
i += leftframe
|
||||
sprite leftx lefty 12
|
||||
;
|
||||
|
||||
: brain-table
|
||||
v1 += -1 return
|
||||
v1 += 1 return
|
||||
v2 += -1 return # vertical movement is 2x as likely
|
||||
v2 += -1 return # as horizontal movement
|
||||
v2 += 1 return
|
||||
v2 += 1 return
|
||||
v0 := v0 return # do nothing
|
||||
fire-right-bullet return
|
||||
: do-brain
|
||||
v0 := random 0b11100 # entries are 4 bytes each
|
||||
jump0 brain-table
|
||||
|
||||
: move-right-player
|
||||
v1 := rightx
|
||||
v2 := righty
|
||||
|
||||
# process (random) movement
|
||||
do-brain
|
||||
|
||||
# animate movement
|
||||
v0 := 0
|
||||
if v1 != rightx then v0 := 24
|
||||
if v2 != righty then v0 := 24
|
||||
if rightframe == 24 then v0 := 12
|
||||
|
||||
# clamp position within right side
|
||||
if v1 == 35 then v1 := 36
|
||||
if v1 == 56 then v1 := 55
|
||||
if v2 == 0 then v2 := 1
|
||||
if v2 == 18 then v2 := 17
|
||||
|
||||
# update position
|
||||
i := right
|
||||
i += rightframe
|
||||
sprite rightx righty 12
|
||||
rightx := v1
|
||||
righty := v2
|
||||
rightframe := v0
|
||||
i := right
|
||||
i += rightframe
|
||||
sprite rightx righty 12
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Main
|
||||
#
|
||||
###########################################
|
||||
|
||||
: rightdead
|
||||
sprite rightx righty 12
|
||||
i := bullet
|
||||
sprite leftbx leftby 1
|
||||
|
||||
: gameover
|
||||
v0 := 32
|
||||
buzzer := v0
|
||||
delay := v0
|
||||
loop
|
||||
v0 := delay
|
||||
if v0 != 0 then
|
||||
again
|
||||
jump main
|
||||
|
||||
: leftdead
|
||||
sprite leftx lefty 12
|
||||
i := bullet
|
||||
sprite rightbx rightby 1
|
||||
jump gameover
|
||||
|
||||
: main
|
||||
# initialize state
|
||||
leftx := 5
|
||||
lefty := 10
|
||||
leftframe := 0
|
||||
rightx := 51
|
||||
righty := 10
|
||||
rightframe := 0
|
||||
leftfire := 0
|
||||
rightfire := 0
|
||||
|
||||
# draw background
|
||||
clear
|
||||
i := cactus
|
||||
v0 := 28
|
||||
v1 := 9
|
||||
sprite v0 v1 15
|
||||
|
||||
i := edge
|
||||
v0 := 0
|
||||
v1 := 31
|
||||
loop
|
||||
sprite v0 v1 2
|
||||
v0 += 8
|
||||
if v0 != 64 then
|
||||
again
|
||||
|
||||
i := left
|
||||
sprite leftx lefty 12
|
||||
i := right
|
||||
sprite rightx righty 12
|
||||
|
||||
# main game loop
|
||||
loop
|
||||
move-left-player
|
||||
if vf != 0 then jump leftdead
|
||||
move-right-player
|
||||
if vf != 0 then jump rightdead
|
||||
|
||||
i := bullet
|
||||
if leftfire != 0 then move-left-bullet
|
||||
if leftfire == 0 then fire-left-bullet
|
||||
if rightfire != 0 then move-right-bullet
|
||||
again
|
||||
@@ -0,0 +1,39 @@
|
||||
###########################################
|
||||
#
|
||||
# Sinusoid
|
||||
#
|
||||
# Demonstrate :calc and :macro by computing
|
||||
# a sinusoidal lookup table at compile time.
|
||||
#
|
||||
# John Earnest
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
hires
|
||||
loop
|
||||
scroll-down 2
|
||||
i := table
|
||||
i += v2
|
||||
load v1
|
||||
i := thin
|
||||
sprite v0 v3 2
|
||||
i := thick
|
||||
sprite v1 v3 2
|
||||
v2 += 2
|
||||
again
|
||||
|
||||
: thin 0x0F 0x0F
|
||||
: thick 0xFF 0xFF
|
||||
|
||||
: table
|
||||
:macro S2 {
|
||||
:calc rads { ( HERE - table ) * ( 2 * PI ) / 256 }
|
||||
:byte { 56 + 38 * sin rads }
|
||||
:byte { 56 + 16 * cos rads }
|
||||
}
|
||||
|
||||
# expand S2 2*8*8 times for a 256-byte table:
|
||||
:macro S1 { S2 S2 S2 S2 S2 S2 S2 S2 }
|
||||
:macro S0 { S1 S1 S1 S1 S1 S1 S1 S1 }
|
||||
S0 S0
|
||||
@@ -0,0 +1,805 @@
|
||||
###########################################
|
||||
#
|
||||
# Slippery Slope
|
||||
#
|
||||
# built for Octojam 2018.
|
||||
# level editor: http://beyondloom.com/tools/slipedit.html
|
||||
#
|
||||
# John Earnest
|
||||
#
|
||||
###########################################
|
||||
|
||||
:const MODE-INPUT 0
|
||||
:const MODE-MOVE 1
|
||||
:const MODE-NEXT 2
|
||||
:const MODE-RESET 3
|
||||
|
||||
:const FINAL_LEVEL 0xA
|
||||
|
||||
# v0-v2 are reserved as temporaries.
|
||||
:alias px vD # player x position (tiles)
|
||||
:alias py vC # player y position (tiles)
|
||||
:alias pdir vB # player direction ( E N W S )
|
||||
:alias pmode vA # see MODE-XXX
|
||||
:alias gx v9 # goal x position
|
||||
:alias gy v8 # goal y position
|
||||
:alias gf v7 # goal frame (0,5,10,15)
|
||||
:alias level v6 # current level no.
|
||||
|
||||
:alias move-dx v5 # x amount player moved this step
|
||||
:alias move-dy v4 # y amount player moved this step
|
||||
:alias move-dir v3 # temporary direction
|
||||
|
||||
:alias load-ti vD # tile index
|
||||
:alias load-tx vC # x position
|
||||
:alias load-ty vB # y position
|
||||
|
||||
:alias copy-off vE # when unpacking, offset
|
||||
:alias copy-lvl vD # when unpacking, level index
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Utilities
|
||||
#
|
||||
###########################################
|
||||
|
||||
:macro temp-begin { :calc there { HERE } :org 0 }
|
||||
:macro temp-end { :org there }
|
||||
:macro xor_ { :byte { ( @ a + HERE - to ) ^ @ b + HERE - to } }
|
||||
:macro xor A B { :calc to { HERE } :calc a { A } :calc b { B }
|
||||
xor_ xor_ xor_ xor_ xor_ }
|
||||
|
||||
:macro sync N {
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
vf := N
|
||||
delay := vf
|
||||
}
|
||||
:macro copy-2 SRC DST {
|
||||
i := SRC load v1
|
||||
i := DST save v1
|
||||
}
|
||||
:macro times-5 SRC DST {
|
||||
DST := SRC
|
||||
DST <<= DST
|
||||
DST <<= DST
|
||||
DST += SRC
|
||||
}
|
||||
:macro times-6 SRC DST {
|
||||
DST := SRC
|
||||
DST += SRC
|
||||
DST += SRC
|
||||
DST += DST
|
||||
}
|
||||
:macro to-tile SX SY DX DY {
|
||||
times-5 SX DX DX += 2
|
||||
times-5 SY DY DY += 1
|
||||
}
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Step Counter
|
||||
#
|
||||
###########################################
|
||||
|
||||
: step-total 0 0 # high 2 digits, low 2 digits
|
||||
: step-level 0 0
|
||||
: step-bcd 0 0 0
|
||||
|
||||
:macro steps-clear {
|
||||
v0 := 0
|
||||
v1 := 0
|
||||
i := step-total
|
||||
save v1
|
||||
i := step-level
|
||||
save v1
|
||||
}
|
||||
|
||||
:macro steps-inc {
|
||||
i := step-level
|
||||
load v1
|
||||
v1 += 1
|
||||
if v1 == 100 begin
|
||||
v0 += 1
|
||||
v1 := 0
|
||||
end
|
||||
if v0 == 100 begin
|
||||
# cap at 9999
|
||||
v1 := 99
|
||||
v0 := 99
|
||||
end
|
||||
i := step-level
|
||||
save v1
|
||||
}
|
||||
|
||||
:macro steps-reset-level { copy-2 step-total step-level }
|
||||
:macro steps-next-level { copy-2 step-level step-total }
|
||||
|
||||
:macro steps-show-digits SRC {
|
||||
i := SRC
|
||||
load v0
|
||||
i := step-bcd
|
||||
bcd v0
|
||||
load v2
|
||||
i := hex v1
|
||||
sprite v3 v4 5
|
||||
v3 += 5
|
||||
i := hex v2
|
||||
sprite v3 v4 5
|
||||
v3 += 5
|
||||
}
|
||||
:macro steps-show { # at v3,v4
|
||||
steps-show-digits step-level
|
||||
:calc low-digits { 1 + step-level }
|
||||
steps-show-digits low-digits
|
||||
}
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Level Representation
|
||||
#
|
||||
###########################################
|
||||
|
||||
:const board-rows 6
|
||||
:const board-cols 12
|
||||
:calc board-size { board-rows * board-cols }
|
||||
: board
|
||||
00 00 00 00 00 00
|
||||
00 00 00 05 00 00
|
||||
00 00 05 00 05 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
|
||||
: goal-position 10 03 # (x tiles, y tiles)
|
||||
: start-position 02 03 # (x tiles, y tiles)
|
||||
|
||||
: level-unpack-stash
|
||||
0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0
|
||||
|
||||
:macro level-base-addr {
|
||||
v0 := copy-lvl
|
||||
i := level-data
|
||||
loop
|
||||
while v0 != 1
|
||||
v0 += -1
|
||||
vf := 76
|
||||
i += vf
|
||||
again
|
||||
}
|
||||
: level-unpack
|
||||
# we need most of the registers for bulk copying,
|
||||
# so stash the entire register file in a buffer:
|
||||
vf := level
|
||||
i := level-unpack-stash
|
||||
save vf
|
||||
|
||||
# copy tile data
|
||||
copy-off := 0 # source/dest offset
|
||||
copy-lvl := vf # level index
|
||||
loop
|
||||
level-base-addr
|
||||
i += copy-off
|
||||
load vb
|
||||
|
||||
i := board
|
||||
i += copy-off
|
||||
save vb
|
||||
|
||||
copy-off += 12
|
||||
if copy-off != 72 then
|
||||
again
|
||||
|
||||
# copy goal/start positions
|
||||
level-base-addr
|
||||
i += copy-off
|
||||
load v3
|
||||
i := goal-position
|
||||
save v3
|
||||
|
||||
i := level-unpack-stash
|
||||
load vf
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Text
|
||||
#
|
||||
###########################################
|
||||
|
||||
: let-A 0xF0 0xB0 0xF0 0xB0
|
||||
: let-D 0xE0 0xB0 0xB0 0xE0
|
||||
: let-E 0xF0 0xE0 0xC0 0xF0
|
||||
: let-G 0xF0 0xC0 0xD0 0xF0
|
||||
: let-H 0xB0 0xF0 0xB0 0xB0
|
||||
: let-I 0xC0 0x00 0xC0 0xC0
|
||||
: let-L 0xC0 0xC0 0xC0 0xE0
|
||||
: let-M 0xD8 0xE8 0xC8 0xC8
|
||||
: let-N 0xE0 0xF0 0xD0 0xD0
|
||||
: let-O 0xF0 0xB0 0xB0 0xF0
|
||||
: let-P 0xF0 0xB0 0xF0 0x80
|
||||
: let-R 0xF0 0xF0 0xA0 0x90
|
||||
: let-S 0xF0 0xE0 0x30 0xF0
|
||||
: let-T 0xF0 0x60 0x60 0x60
|
||||
: let-V 0xB0 0xB0 0xB0 0x60
|
||||
: let-Y 0xB0 0xF0 0x30 0xF0
|
||||
|
||||
:stringmode print " " {
|
||||
v0 += 4
|
||||
}
|
||||
:stringmode print "ADEGHILMNOPRSTVY" {
|
||||
:calc S { let-A + VALUE * 4 }
|
||||
i := S
|
||||
sprite v0 v1 4
|
||||
# compute the width of each glyph statically:
|
||||
:calc p { ( @ S ) | ( @ 1 + S ) | ( @ 2 + S ) | ( @ 3 + S ) }
|
||||
:calc w { 9 - ( log p & - p ) / log 2 }
|
||||
v0 += w
|
||||
}
|
||||
|
||||
:macro draw-title {
|
||||
v0 := 14
|
||||
v1 := 4
|
||||
print "SLIPPERY"
|
||||
v0 := 20
|
||||
v1 := 24
|
||||
print "SLOPE"
|
||||
}
|
||||
|
||||
:macro draw-gameover {
|
||||
v0 := 15
|
||||
v1 := 12
|
||||
print "THE END"
|
||||
v3 := 8
|
||||
v4 := 20
|
||||
steps-show
|
||||
v0 := v3
|
||||
v1 := v4
|
||||
print " STEPS"
|
||||
}
|
||||
|
||||
:macro draw-levelno {
|
||||
v0 := 17
|
||||
v1 := 12
|
||||
print "LEVEL "
|
||||
i := hex level
|
||||
sprite v0 v1 5
|
||||
}
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Player And Movement
|
||||
#
|
||||
###########################################
|
||||
|
||||
: stand 0x20 0x70 0x70 0x30 0x20
|
||||
0x20 0x70 0x70 0x70 0x50
|
||||
0x20 0x70 0x70 0x60 0x20
|
||||
0x20 0x70 0xF8 0x70 0x50
|
||||
: slide 0x20 0x38 0x30 0x38 0x48
|
||||
0x20 0xF0 0x78 0xB0 0x90
|
||||
0x20 0xE0 0x60 0xE0 0x90
|
||||
0x20 0xF8 0x70 0x70 0x48
|
||||
|
||||
:macro draw-player {
|
||||
times-5 pdir v0
|
||||
i += v0
|
||||
to-tile px py v0 v1
|
||||
sprite v0 v1 5
|
||||
}
|
||||
:macro draw-stand { i := stand draw-player }
|
||||
:macro draw-slide { i := slide draw-player }
|
||||
|
||||
: deltas 1 0 0 -1 -1 0 0 1
|
||||
: dirs-\ 3 2 1 0
|
||||
: dirs-/ 1 0 3 2
|
||||
|
||||
:macro at-edge REG DELTA VAL {
|
||||
if REG == VAL begin
|
||||
REG -= DELTA
|
||||
pmode := MODE-INPUT
|
||||
end
|
||||
}
|
||||
:macro get-current-tile {
|
||||
times-6 px v0
|
||||
v0 += py
|
||||
i := board
|
||||
i += v0
|
||||
load v0
|
||||
v1 := v0
|
||||
}
|
||||
:macro set-current-tile {
|
||||
times-6 px v0
|
||||
v0 += py
|
||||
i := board
|
||||
i += v0
|
||||
v0 := v1
|
||||
save v0
|
||||
}
|
||||
:macro draw-current-tile {
|
||||
i := tiles
|
||||
i += v1
|
||||
times-5 px v0
|
||||
times-5 py v1
|
||||
v0 += 2
|
||||
v1 += 1
|
||||
sprite v0 v1 5
|
||||
}
|
||||
:macro change-dir TABLE {
|
||||
i := TABLE
|
||||
i += pdir
|
||||
load v0
|
||||
pdir := v0
|
||||
}
|
||||
:macro move-player {
|
||||
loop
|
||||
# move in facing direction
|
||||
i := deltas
|
||||
i += pdir
|
||||
i += pdir
|
||||
|
||||
load v1
|
||||
move-dx := v0
|
||||
move-dy := v1
|
||||
px += move-dx
|
||||
py += move-dy
|
||||
|
||||
# out of bounds?
|
||||
at-edge px move-dx -1
|
||||
at-edge px move-dx 12
|
||||
at-edge py move-dy -1
|
||||
at-edge py move-dy 6
|
||||
|
||||
# at goal?
|
||||
to-tile px py v0 v1
|
||||
v0 ^= gx
|
||||
v1 ^= gy
|
||||
v0 |= v1
|
||||
if v0 == 0 then pmode := MODE-NEXT
|
||||
|
||||
# check current cell (into v1)
|
||||
get-current-tile
|
||||
|
||||
if v1 == tile-wall begin
|
||||
px -= move-dx
|
||||
py -= move-dy
|
||||
pmode := MODE-INPUT
|
||||
end
|
||||
|
||||
if v1 == tile-hole begin
|
||||
pmode := MODE-RESET
|
||||
end
|
||||
|
||||
if v1 == tile-mir-\ begin
|
||||
change-dir dirs-\
|
||||
end
|
||||
|
||||
if v1 == tile-mir-/ begin
|
||||
change-dir dirs-/
|
||||
end
|
||||
|
||||
if v1 == tile-flip-\ begin
|
||||
change-dir dirs-\
|
||||
draw-current-tile
|
||||
v1 := tile-flop-/
|
||||
set-current-tile
|
||||
draw-current-tile
|
||||
v1 := 0 # avoid fallthrough!
|
||||
end
|
||||
|
||||
if v1 == tile-flop-/ begin
|
||||
change-dir dirs-/
|
||||
draw-current-tile
|
||||
v1 := tile-flip-\
|
||||
set-current-tile
|
||||
draw-current-tile
|
||||
v1 := 0 # avoid fallthrough!
|
||||
end
|
||||
|
||||
if v1 >= tile-ground begin
|
||||
draw-current-tile
|
||||
pmode := MODE-INPUT
|
||||
end
|
||||
|
||||
while pmode == MODE-MOVE
|
||||
draw-slide
|
||||
animate-goal
|
||||
sync 5
|
||||
draw-slide
|
||||
again
|
||||
}
|
||||
|
||||
:macro poll-key KEY DIR {
|
||||
vf := KEY if vf key begin
|
||||
pmode := MODE-MOVE
|
||||
move-dir := DIR
|
||||
end
|
||||
}
|
||||
:macro poll-player {
|
||||
poll-key OCTO_KEY_D 0
|
||||
poll-key OCTO_KEY_W 1
|
||||
poll-key OCTO_KEY_A 2
|
||||
poll-key OCTO_KEY_S 3
|
||||
if pmode == MODE-MOVE begin
|
||||
steps-inc
|
||||
draw-stand
|
||||
get-current-tile
|
||||
if v1 >= tile-ground begin
|
||||
draw-current-tile
|
||||
end
|
||||
pdir := move-dir
|
||||
move-player
|
||||
draw-stand
|
||||
end
|
||||
if level != 0 begin
|
||||
vf := OCTO_KEY_E
|
||||
if vf key then pmode := MODE-RESET
|
||||
end
|
||||
}
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Level Display
|
||||
#
|
||||
###########################################
|
||||
|
||||
: line 0xFF # top and bottom edge
|
||||
: corner 0x80 # 1px
|
||||
: wall 0xC0 0xC0 0xC0 0xC0 0xC0 # 2x15 pixels
|
||||
0xC0 0xC0 0xC0 0xC0 0xC0
|
||||
0xC0 0xC0 0xC0 0xC0 0xC0
|
||||
|
||||
:macro draw-border {
|
||||
i := wall
|
||||
v0 := 0
|
||||
v1 := 62
|
||||
v2 := 1
|
||||
sprite v0 v2 15
|
||||
sprite v1 v2 15
|
||||
v2 := 16
|
||||
sprite v0 v2 15
|
||||
sprite v1 v2 15
|
||||
|
||||
i := line
|
||||
v1 := 0
|
||||
v2 := 31
|
||||
loop
|
||||
sprite v0 v1 1
|
||||
sprite v0 v2 1
|
||||
v0 += 8
|
||||
if v0 != 64 then
|
||||
again
|
||||
|
||||
i := corner
|
||||
v0 := 2
|
||||
v1 := 61
|
||||
v2 := 1
|
||||
sprite v0 v2 1
|
||||
sprite v1 v2 1
|
||||
v2 := 30
|
||||
sprite v0 v2 1
|
||||
sprite v1 v2 1
|
||||
}
|
||||
|
||||
temp-begin
|
||||
: tgoal-1 0x50 0x80 0x08 0x80 0x50
|
||||
: tgoal-2 0x50 0x88 0x00 0x88 0x20
|
||||
: tgoal-3 0x50 0x08 0x80 0x08 0x50
|
||||
temp-end
|
||||
: goal-0 0x20 0x88 0x00 0x88 0x50
|
||||
: goal-1 xor goal-0 tgoal-1
|
||||
: goal-2 xor tgoal-1 tgoal-2
|
||||
: goal-3 xor tgoal-2 tgoal-3
|
||||
: goal-4 xor tgoal-3 goal-0
|
||||
|
||||
:macro init-goal {
|
||||
gf := 0
|
||||
i := goal-0
|
||||
sprite gx gy 5
|
||||
}
|
||||
|
||||
:macro animate-goal {
|
||||
i := goal-1
|
||||
i += gf
|
||||
sprite gx gy 5
|
||||
gf += 5
|
||||
if gf == 20 then gf := 0
|
||||
}
|
||||
|
||||
: tiles 0x00 0x00 0x00 0x00 0x00 # empty space
|
||||
0xF8 0xF8 0xF8 0xF8 0xF8 :const tile-wall 5
|
||||
0x88 0x50 0x20 0x50 0x88 :const tile-hole 10
|
||||
0x80 0x40 0x20 0x10 0x08 :const tile-mir-\ 15
|
||||
0x08 0x10 0x20 0x40 0x80 :const tile-mir-/ 20
|
||||
0x80 0x60 0x50 0x30 0x08 :const tile-flip-\ 25
|
||||
0x08 0x30 0x70 0x60 0x80 :const tile-flop-/ 30
|
||||
0x50 0x88 0x88 0x88 0x70 :const tile-ground 35
|
||||
0x58 0x80 0x80 0x80 0x78
|
||||
0x88 0x88 0x88 0x88 0x70
|
||||
0x80 0x80 0x80 0x80 0x78
|
||||
0x50 0x08 0x08 0x08 0xF0
|
||||
0x58 0x00 0x00 0x00 0xF8
|
||||
0x08 0x08 0x08 0x08 0xF0
|
||||
0x00 0x00 0x00 0x00 0xF8
|
||||
0x50 0x88 0x88 0x88 0x88
|
||||
0x58 0x80 0x80 0x80 0x80
|
||||
0x88 0x88 0x88 0x88 0x88
|
||||
0x80 0x80 0x80 0x80 0x80
|
||||
0x50 0x08 0x08 0x08 0x08
|
||||
0x58 0x00 0x00 0x00 0x00
|
||||
0x08 0x08 0x08 0x08 0x08
|
||||
0x00 0x00 0x00 0x00 0x00
|
||||
|
||||
:macro load-tile REG Y {
|
||||
i := tiles
|
||||
i += REG
|
||||
load-ty := Y
|
||||
sprite load-tx load-ty 5
|
||||
}
|
||||
: load-level
|
||||
clear
|
||||
draw-border
|
||||
load-ti := 0
|
||||
load-tx := 2
|
||||
loop
|
||||
i := board
|
||||
i += load-ti
|
||||
load v5
|
||||
|
||||
load-tile v0 1
|
||||
load-tile v1 6
|
||||
load-tile v2 11
|
||||
load-tile v3 16
|
||||
load-tile v4 21
|
||||
load-tile v5 26
|
||||
|
||||
load-tx += 5
|
||||
load-ti += board-rows
|
||||
if load-ti != board-size then
|
||||
again
|
||||
i := goal-position
|
||||
load v3
|
||||
to-tile v0 v1 gx gy
|
||||
init-goal
|
||||
|
||||
px := v2
|
||||
py := v3
|
||||
pdir := 3
|
||||
pmode := MODE-INPUT
|
||||
draw-stand
|
||||
;
|
||||
|
||||
:macro try-key KEY {
|
||||
vf := KEY
|
||||
while vf -key
|
||||
}
|
||||
:macro wait-key {
|
||||
v4 := random 3
|
||||
i := deltas
|
||||
i += v4
|
||||
i += v4
|
||||
load v1
|
||||
v0 += v0
|
||||
v2 := random 63
|
||||
v3 := random 31
|
||||
i := slide
|
||||
i += v4
|
||||
i += v4
|
||||
i += v4
|
||||
i += v4
|
||||
i += v4
|
||||
sprite v2 v3 5
|
||||
loop
|
||||
sprite v2 v3 5
|
||||
v2 += v0
|
||||
v3 += v1
|
||||
sprite v2 v3 5
|
||||
try-key OCTO_KEY_E
|
||||
try-key OCTO_KEY_A
|
||||
try-key OCTO_KEY_S
|
||||
try-key OCTO_KEY_W
|
||||
try-key OCTO_KEY_D
|
||||
again
|
||||
}
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Main
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
load-level
|
||||
draw-title
|
||||
|
||||
loop
|
||||
loop
|
||||
poll-player
|
||||
while pmode == MODE-INPUT
|
||||
animate-goal
|
||||
sync 5
|
||||
again
|
||||
|
||||
if pmode == MODE-RESET begin
|
||||
steps-reset-level
|
||||
level-unpack
|
||||
load-level
|
||||
end
|
||||
|
||||
if pmode == MODE-NEXT begin
|
||||
clear
|
||||
if level == FINAL_LEVEL begin
|
||||
level := 1
|
||||
draw-gameover
|
||||
steps-clear
|
||||
steps-inc # start screen takes 1 move
|
||||
else
|
||||
level += 1
|
||||
draw-levelno
|
||||
end
|
||||
steps-next-level
|
||||
level-unpack
|
||||
wait-key
|
||||
load-level
|
||||
end
|
||||
again
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Level Data
|
||||
#
|
||||
###########################################
|
||||
|
||||
: level-data
|
||||
: level-1 # just walls and sliding
|
||||
05 05 05 00 00 00
|
||||
05 00 00 00 00 00
|
||||
05 00 00 00 00 00
|
||||
00 00 05 00 00 05
|
||||
00 00 05 00 00 05
|
||||
05 05 05 00 00 05
|
||||
00 00 00 00 00 05
|
||||
00 00 00 05 05 05
|
||||
00 00 00 00 00 05
|
||||
05 00 00 00 00 00
|
||||
05 00 00 00 05 00
|
||||
05 05 05 05 05 00
|
||||
10 03 04 01
|
||||
: level-2 # more walls and sliding
|
||||
00 00 00 00 00 05
|
||||
00 05 00 00 00 05
|
||||
05 00 00 00 00 05
|
||||
05 00 00 00 05 05
|
||||
05 05 00 00 05 05
|
||||
00 00 00 00 00 05
|
||||
05 05 00 00 00 05
|
||||
05 00 00 00 00 05
|
||||
05 00 00 00 05 05
|
||||
05 00 00 00 00 05
|
||||
00 00 00 00 00 05
|
||||
00 00 00 00 05 05
|
||||
05 00 01 04
|
||||
|
||||
: level-3 # introduce mirrors
|
||||
05 05 05 05 05 05
|
||||
05 05 00 00 00 05
|
||||
05 05 00 00 00 05
|
||||
05 00 00 00 00 05
|
||||
05 00 00 20 00 00
|
||||
05 00 00 00 00 00
|
||||
05 05 00 00 00 05
|
||||
05 05 05 00 05 05
|
||||
05 05 00 00 00 05
|
||||
05 05 00 00 00 05
|
||||
05 05 00 00 00 05
|
||||
05 05 05 05 05 05
|
||||
09 03 02 03
|
||||
: level-4 # many mirrors
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 20
|
||||
15 00 00 00 00 00
|
||||
00 05 00 00 00 00
|
||||
00 00 00 00 15 00
|
||||
00 20 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
15 00 00 05 00 20
|
||||
00 15 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 15 00 00
|
||||
10 03 01 01
|
||||
: level-5 # mild mirror maze
|
||||
00 20 00 00 15 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 20
|
||||
15 00 00 00 00 00
|
||||
20 00 00 00 00 00
|
||||
15 00 15 00 00 20
|
||||
20 20 15 20 00 15
|
||||
15 00 00 00 00 20
|
||||
20 20 00 00 00 15
|
||||
15 00 00 15 00 20
|
||||
10 20 15 00 00 15
|
||||
00 20 15 20 15 20
|
||||
11 00 00 02
|
||||
|
||||
: level-6 # introduce ground
|
||||
10 10 10 10 10 10
|
||||
10 00 00 00 00 10
|
||||
10 00 00 00 00 10
|
||||
10 00 00 00 00 10
|
||||
10 00 00 00 00 10
|
||||
10 00 80 50 00 10
|
||||
10 00 95 65 00 10
|
||||
10 00 00 00 00 10
|
||||
10 00 00 00 00 10
|
||||
10 00 00 00 00 10
|
||||
10 00 00 00 00 10
|
||||
10 10 10 10 10 10
|
||||
09 03 02 02
|
||||
: level-7 # good clean fun with ground + mirrors
|
||||
00 00 00 55 00 00
|
||||
00 00 00 00 00 05
|
||||
05 15 00 00 00 00
|
||||
00 00 00 20 00 75
|
||||
00 00 00 00 00 00
|
||||
05 05 05 00 00 00
|
||||
05 05 05 00 20 00
|
||||
05 20 00 00 20 00
|
||||
00 00 00 15 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
90 50 00 10 00 20
|
||||
03 00 08 00
|
||||
|
||||
: level-8 # introduce flip-flops
|
||||
05 05 05 05 05 05
|
||||
05 05 05 05 05 05
|
||||
05 05 05 00 05 05
|
||||
05 05 05 00 05 05
|
||||
05 00 00 30 00 00
|
||||
05 05 00 00 05 05
|
||||
05 05 00 00 05 05
|
||||
00 00 25 00 00 05
|
||||
05 05 00 05 05 05
|
||||
05 05 00 05 05 05
|
||||
05 05 05 05 05 05
|
||||
05 05 05 05 05 05
|
||||
09 02 02 03
|
||||
: level-9 # mirror maze with a few flip-flops
|
||||
15 20 00 00 20 15
|
||||
00 00 15 00 35 00
|
||||
20 00 00 00 00 20
|
||||
00 15 00 00 00 15
|
||||
00 30 00 20 00 00
|
||||
45 00 00 00 00 20
|
||||
00 20 15 20 00 00
|
||||
00 00 00 00 25 00
|
||||
20 00 20 00 00 20
|
||||
00 00 00 20 35 00
|
||||
00 00 00 00 15 00
|
||||
20 15 00 20 00 20
|
||||
02 02 10 01
|
||||
: level-A # many flip-flops
|
||||
00 00 10 05 05 00
|
||||
00 00 00 10 05 00
|
||||
05 05 00 00 00 00
|
||||
50 00 25 00 00 20
|
||||
70 00 30 00 00 15
|
||||
70 00 30 30 00 20
|
||||
70 00 30 30 00 15
|
||||
70 00 25 00 00 20
|
||||
70 00 30 25 00 15
|
||||
65 00 30 00 00 20
|
||||
00 00 05 00 00 00
|
||||
00 00 05 00 00 00
|
||||
00 05 11 01
|
||||
@@ -0,0 +1,382 @@
|
||||
###########################################
|
||||
#
|
||||
# Snow Daze
|
||||
#
|
||||
# Clear all the snow off your driveway
|
||||
# before you're late for work!
|
||||
# Press ASWD to move around the driveway
|
||||
# and press E to shovel snow behind you.
|
||||
# Runs best at 100 cycles/frame.
|
||||
#
|
||||
# Created for the 2015 CCP Game Jam
|
||||
# Theme: Winter
|
||||
#
|
||||
###########################################
|
||||
|
||||
:alias px va
|
||||
:alias py vb
|
||||
:alias dir vc
|
||||
:alias frame vd
|
||||
:alias timer v9
|
||||
:alias timerx v8
|
||||
:alias endflag v7
|
||||
|
||||
:const LEFT 45
|
||||
:const RIGHT 0
|
||||
:const TICK_TIME 8
|
||||
:const SNOWFALL 8
|
||||
|
||||
: draw-image
|
||||
v0 := 0
|
||||
v1 := 0
|
||||
v2 := 32
|
||||
loop
|
||||
sprite v0 v1 0
|
||||
i += v2
|
||||
v0 += 16
|
||||
if v0 == 128 begin
|
||||
v0 := 0
|
||||
v1 += 16
|
||||
end
|
||||
if v1 != 64 then
|
||||
again
|
||||
;
|
||||
|
||||
: draw-player
|
||||
i := person-r
|
||||
i += dir
|
||||
i += frame
|
||||
sprite px py 15
|
||||
;
|
||||
|
||||
: do-snow
|
||||
i := snow
|
||||
v3 := 0
|
||||
loop
|
||||
v1 := random 0b111111
|
||||
v1 += 32
|
||||
v2 := random 0b11111
|
||||
v2 += 16
|
||||
sprite v1 v2 15
|
||||
v0 := 5 wait
|
||||
v3 += 1
|
||||
if v3 != SNOWFALL then
|
||||
again
|
||||
;
|
||||
|
||||
: do-scoop
|
||||
frame := 15
|
||||
draw-player
|
||||
v0 := 5 gamewait
|
||||
draw-player
|
||||
frame := 30
|
||||
draw-player
|
||||
v0 := 5 gamewait
|
||||
draw-player
|
||||
frame := 0
|
||||
|
||||
v1 := py
|
||||
i := snow
|
||||
|
||||
:macro scoop DELTA1 DELTA2 {
|
||||
v0 := px
|
||||
v0 += DELTA1
|
||||
sprite v0 v1 15
|
||||
if vf == 0 begin
|
||||
sprite v0 v1 15
|
||||
else
|
||||
v0 += DELTA2
|
||||
sprite v0 v1 15
|
||||
if vf == 1 then sprite v0 v1 15
|
||||
end
|
||||
}
|
||||
if dir == LEFT begin
|
||||
scoop -8 16
|
||||
else
|
||||
scoop 8 -16
|
||||
end
|
||||
;
|
||||
|
||||
: move-player
|
||||
vf := 5 if vf key begin
|
||||
if py != 10 then py += -1
|
||||
end
|
||||
vf := 8 if vf key begin
|
||||
if py != 0x31 then py += 1
|
||||
end
|
||||
vf := 7 if vf key begin
|
||||
px += -1
|
||||
dir := LEFT
|
||||
end
|
||||
vf := 9 if vf key begin
|
||||
px += 1
|
||||
dir := RIGHT
|
||||
end
|
||||
vf := 6 if vf key then do-scoop
|
||||
;
|
||||
|
||||
: countdown
|
||||
if timer == 0 begin
|
||||
timer := TICK_TIME
|
||||
vf := 4
|
||||
i := timeslice
|
||||
sprite timerx vf 3
|
||||
timerx += -1
|
||||
if timerx == 3 then endflag := 1
|
||||
else
|
||||
timer += -1
|
||||
end
|
||||
;
|
||||
|
||||
: gamewait
|
||||
loop
|
||||
sync
|
||||
countdown
|
||||
v0 += -1
|
||||
if v0 != 0 then
|
||||
again
|
||||
;
|
||||
|
||||
: wait
|
||||
loop
|
||||
sync
|
||||
v0 += -1
|
||||
if v0 != 0 then
|
||||
again
|
||||
;
|
||||
|
||||
: game-over
|
||||
draw-player
|
||||
v0 := 20 wait
|
||||
|
||||
v1 := 32
|
||||
v2 := 15
|
||||
v3 := 0
|
||||
i := block
|
||||
loop
|
||||
sprite v1 v2 0
|
||||
if vf != 0 then v3 += 1
|
||||
v0 := 5 wait
|
||||
sprite v1 v2 0
|
||||
v1 += 16
|
||||
if v1 == 96 begin
|
||||
v1 := 32
|
||||
v2 += 16
|
||||
end
|
||||
if v2 != 63 then
|
||||
again
|
||||
i := bighex v3
|
||||
v1 := 60
|
||||
v2 := 14
|
||||
sprite v1 v2 10
|
||||
|
||||
v0 := 20 wait
|
||||
v0 := key
|
||||
setup
|
||||
;
|
||||
|
||||
: sync
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
vf := 2
|
||||
delay := vf
|
||||
;
|
||||
|
||||
: intro-num
|
||||
i := bighex v0
|
||||
v1 := 60
|
||||
v2 := 14
|
||||
sprite v1 v2 10
|
||||
v0 := 10 wait
|
||||
sprite v1 v2 10
|
||||
;
|
||||
|
||||
: setup
|
||||
clear
|
||||
i := background
|
||||
draw-image
|
||||
timerx := 123
|
||||
timer := 0
|
||||
px := 64
|
||||
py := 32
|
||||
endflag := 0
|
||||
draw-player
|
||||
do-snow
|
||||
v0 := 10 wait
|
||||
v0 := 3 intro-num
|
||||
v0 := 2 intro-num
|
||||
v0 := 1 intro-num
|
||||
;
|
||||
|
||||
: main
|
||||
hires
|
||||
setup
|
||||
loop
|
||||
draw-player
|
||||
move-player
|
||||
draw-player
|
||||
countdown
|
||||
if endflag == 1 then game-over
|
||||
sync
|
||||
again
|
||||
|
||||
: timeslice
|
||||
0x80 0x80 0x80
|
||||
: block
|
||||
0x00 0x00 0x7F 0xFE 0x7F 0xFE 0x7F 0xFE
|
||||
0x7F 0xFE 0x7F 0xFE 0x7F 0xFE 0x7F 0xFE
|
||||
0x7F 0xFE 0x7F 0xFE 0x7F 0xFE 0x7F 0xFE
|
||||
0x7F 0xFE 0x7F 0xFE 0x7F 0xFE 0x00 0x00
|
||||
: snow
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x7E 0x7E 0x7E 0x00
|
||||
: person-r
|
||||
0x38 0x38 0x28 0x3C 0x78 0x70 0x78 0x78
|
||||
0xF8 0xF8 0xFB 0x7F 0x4F 0x4B 0x6C
|
||||
: scoop1-r
|
||||
0x00 0x1C 0x1C 0x14 0x1E 0x7C 0xF8 0xF8
|
||||
0xFC 0xFC 0xFC 0x7F 0x4F 0x4F 0x6F
|
||||
: scoop2-r
|
||||
0xC0 0xCE 0x4E 0x6A 0x7F 0xFE 0x78 0x7E
|
||||
0x7C 0xF8 0xF8 0xF8 0x38 0x48 0x6C
|
||||
: person-l
|
||||
0x1C 0x1C 0x14 0x3C 0x1E 0x0E 0x1E 0x1E
|
||||
0x1F 0x1F 0xDF 0xFE 0xF2 0xD2 0x36
|
||||
: scoop1-l
|
||||
0x00 0x38 0x38 0x28 0x78 0x3E 0x1F 0x1F
|
||||
0x3F 0x3F 0x3F 0xFE 0xF2 0xF2 0xF6
|
||||
: scoop2-l
|
||||
0x03 0x73 0x72 0x56 0xFE 0x7F 0x1E 0x7E
|
||||
0x3E 0x1F 0x1F 0x1F 0x1C 0x12 0x36
|
||||
|
||||
: background # (1024 bytes)
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xE0 0x00
|
||||
0xEF 0xFF 0xEF 0xFF 0xEF 0xFF 0xE0 0x00
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0xFF 0xFE 0xFF 0xFE 0xFF 0xFE
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFE 0xFF 0xFE
|
||||
0x00 0x00 0x00 0x00 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x7F 0xFF 0x7F 0xFF 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x00
|
||||
0xFF 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x07
|
||||
0xFF 0xF7 0xFF 0xF7 0xFF 0xF7 0x00 0x07
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFE 0xFF 0xFE
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFE 0xFF 0xFE
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFE 0xFF 0xFE
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFE 0xFF 0xFE
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFE 0xFF 0xFE
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFE 0xFF 0xFE
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFE 0xFF 0xFE
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFC 0xFF 0xFE
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0x7F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFE
|
||||
0xFF 0xFF 0xFF 0xFF 0xF8 0xFB 0x00 0x00
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFE 0xFF 0xFE
|
||||
0xFF 0xFC 0xFF 0xFC 0xFF 0xEE 0xFF 0xFE
|
||||
0xFF 0xFE 0xFF 0xFE 0xFF 0xFC 0xFF 0xF8
|
||||
0xFF 0xB8 0xFF 0xF0 0x8F 0xC0 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x5F 0xFF 0x7F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0x3F 0xFF 0x5F 0xFF 0x7F 0xFF 0x7F 0xFF
|
||||
0x3F 0xFF 0x3E 0xFF 0x3F 0xFF 0x1F 0xFF
|
||||
0x0F 0xDF 0x01 0xFF 0x00 0x3D 0x00 0x00
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x7F
|
||||
0xFF 0xFF 0xFF 0xFF 0xFE 0x1F 0x00 0x00
|
||||
@@ -0,0 +1,188 @@
|
||||
###########################################
|
||||
#
|
||||
# Sw8 Copter
|
||||
#
|
||||
# An adaptation of "Swing Copters"
|
||||
# for the Super Chip8.
|
||||
# Runs best at 100 cycles/frame.
|
||||
#
|
||||
# Press E to start a game and then
|
||||
# press E to switch directions.
|
||||
# Avoid obstacles!
|
||||
#
|
||||
###########################################
|
||||
|
||||
:alias score v7
|
||||
:alias collide v8
|
||||
:alias player-key v9
|
||||
:alias player-x va
|
||||
:alias player-y vb
|
||||
:alias player-frame vc
|
||||
:alias player-dir vd
|
||||
|
||||
:const H_SPEED 3
|
||||
:const BUTTON 6
|
||||
|
||||
: sync
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
vf := 2
|
||||
delay := vf
|
||||
;
|
||||
|
||||
: girders
|
||||
i := girder
|
||||
v0 := 88
|
||||
v1 := 8
|
||||
loop
|
||||
sprite v0 v1 0
|
||||
v0 += 16
|
||||
if v0 != 168 then
|
||||
again
|
||||
;
|
||||
|
||||
: draw-copter
|
||||
i := face-l
|
||||
if player-dir == H_SPEED then i := face-r
|
||||
collide := 0
|
||||
sprite player-x player-y 0
|
||||
collide |= vf
|
||||
i := blade-0
|
||||
if player-frame == 1 then i := blade-1
|
||||
v0 := 16
|
||||
v0 =- player-y
|
||||
sprite player-x v0 0
|
||||
collide |= vf
|
||||
;
|
||||
|
||||
: wait-release
|
||||
if v0 key then return
|
||||
player-key := 0
|
||||
;
|
||||
|
||||
: switch-dir
|
||||
v0 := BUTTON
|
||||
if player-key != 0 then jump wait-release
|
||||
if v0 -key then return
|
||||
player-key := 1
|
||||
|
||||
# (~x)+1 = -x
|
||||
v0 := 0xFF
|
||||
player-dir ^= v0
|
||||
player-dir += 1
|
||||
;
|
||||
|
||||
: move-up
|
||||
player-y += -1
|
||||
v0 := 63
|
||||
v0 &= player-y
|
||||
if v0 == 0 then score += 1
|
||||
;
|
||||
|
||||
: move-copter
|
||||
v0 := 1
|
||||
player-frame ^= v0
|
||||
move-up
|
||||
v0 := random 1
|
||||
if v0 == 1 then move-up
|
||||
player-x += player-dir
|
||||
switch-dir
|
||||
;
|
||||
|
||||
: wait-key
|
||||
v0 := 56
|
||||
v1 := 18
|
||||
i := tapbubble
|
||||
sprite v0 v1 0
|
||||
vf := BUTTON
|
||||
loop
|
||||
if vf -key then
|
||||
again
|
||||
sprite v0 v1 0
|
||||
;
|
||||
|
||||
: game-over
|
||||
vf := 16
|
||||
buzzer := vf
|
||||
delay := vf
|
||||
loop
|
||||
draw-copter
|
||||
scroll-left
|
||||
draw-copter
|
||||
draw-copter
|
||||
scroll-right
|
||||
draw-copter
|
||||
draw-copter
|
||||
scroll-right
|
||||
draw-copter
|
||||
draw-copter
|
||||
scroll-left
|
||||
draw-copter
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
|
||||
: show-score
|
||||
i := bcd-buffer
|
||||
bcd score
|
||||
load v2
|
||||
i := bighex v1
|
||||
v0 := 55
|
||||
v1 := 30
|
||||
sprite v0 v1 10
|
||||
i := bighex v2
|
||||
v0 += 9
|
||||
sprite v0 v1 10
|
||||
vf := BUTTON
|
||||
loop
|
||||
if vf -key then
|
||||
again
|
||||
clear
|
||||
|
||||
: main
|
||||
hires
|
||||
player-x := 56
|
||||
player-y := 48
|
||||
player-dir := H_SPEED
|
||||
player-key := 0
|
||||
score := 0
|
||||
|
||||
girders
|
||||
draw-copter
|
||||
wait-key
|
||||
|
||||
loop
|
||||
draw-copter
|
||||
move-copter
|
||||
draw-copter
|
||||
if collide != 0 then jump game-over
|
||||
sync
|
||||
again
|
||||
|
||||
: bcd-buffer 0 0 0
|
||||
|
||||
: blade-0
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x01 0x80 0x02 0x40 0x7A 0x5E 0x89 0x91 0xF0 0x0F 0x01 0x80 0x01 0x80 0x00 0x00
|
||||
|
||||
: blade-1
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x01 0x80 0x02 0x40 0x0E 0xF0 0x31 0x0C 0x3E 0xFC 0x01 0x80 0x01 0x80 0x00 0x00
|
||||
|
||||
: face-r
|
||||
0x07 0xC0 0x18 0x30 0x20 0x08 0x23 0xB8 0x44 0x44 0x48 0x8A 0x48 0x02 0x48 0x02
|
||||
0x34 0x44 0x23 0xB8 0x30 0x08 0x4B 0xF4 0x48 0x14 0x30 0x18 0x11 0x20 0x0F 0xC0
|
||||
|
||||
: face-l
|
||||
0x03 0xE0 0x0C 0x18 0x10 0x04 0x1D 0xC4 0x22 0x22 0x51 0x12 0x40 0x12 0x40 0x12
|
||||
0x22 0x2C 0x1D 0xC4 0x10 0x0C 0x2F 0x92 0x28 0x12 0x18 0x0C 0x04 0x88 0x03 0xF0
|
||||
|
||||
: girder
|
||||
0xFF 0xFF 0x00 0x00 0xC3 0xC3 0x7E 0x7E 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x7E 0x7E
|
||||
0xFF 0xFF 0x00 0x00 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
|
||||
: tapbubble
|
||||
0x3F 0xFC 0x7F 0xFE 0xFF 0xFF 0xF0 0x0F 0xF0 0x0F 0xF3 0xFF 0xF0 0x7F 0xF0 0x7F
|
||||
0xF3 0xFF 0xF0 0x0F 0xF0 0x0F 0xFF 0xFF 0x7F 0xFE 0x3F 0xFC 0x00 0xC0 0x00 0x80
|
||||
@@ -0,0 +1,39 @@
|
||||
###########################################
|
||||
#
|
||||
# Tank
|
||||
#
|
||||
# Classic Chip8 program translated from
|
||||
# VIPer Volume 1 Issue 1 (June 1978), pg 12-14
|
||||
# https://github.com/mattmikolay/viper/blob/master/volume1/issue1.pdf
|
||||
#
|
||||
# Press 2/E/S/Q to move the tank.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: tankup
|
||||
0x10 0x54 0x7c 0x6c 0x7c 0x7c
|
||||
: tankdown
|
||||
0x44 0x7c 0x7c 0x6c 0x7c 0x54 0x10
|
||||
: tankleft
|
||||
0x0 0xfc 0x78 0x6e 0x78 0xfc
|
||||
: tankright
|
||||
0x0 0x3f 0x1e 0x76 0x1e 0x3f 0x0
|
||||
|
||||
: up v2 += -1 i := tankup ;
|
||||
: down v2 += 1 i := tankdown ;
|
||||
: right v1 += -1 i := tankright ;
|
||||
: left v1 += 1 i := tankleft ;
|
||||
|
||||
: main
|
||||
v1 := 0x20
|
||||
v2 := 0x10
|
||||
i := tankup
|
||||
loop
|
||||
sprite v1 v2 7
|
||||
v0 := key
|
||||
sprite v1 v2 7
|
||||
if v0 == 2 then up
|
||||
if v0 == 4 then right
|
||||
if v0 == 6 then left
|
||||
if v0 == 8 then down
|
||||
again
|
||||
@@ -0,0 +1,23 @@
|
||||
###########################################
|
||||
#
|
||||
# Big Font
|
||||
#
|
||||
# High resolution font test program.
|
||||
# Draw the complete SuperChip high res
|
||||
# hex character set.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
hires
|
||||
loop
|
||||
i := bighex v0
|
||||
sprite v1 v2 10
|
||||
v1 += 9
|
||||
v0 += 1
|
||||
if v0 == 8 then v1 := 0
|
||||
if v0 == 8 then v2 += 11
|
||||
if v0 != 16 then
|
||||
again
|
||||
|
||||
loop again
|
||||
@@ -0,0 +1,72 @@
|
||||
###########################################
|
||||
#
|
||||
# Branch Test
|
||||
#
|
||||
# Tests the if...begin...else...then
|
||||
# control structure.
|
||||
# Should print "51368"
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
# simple taken branch
|
||||
v0 := 1
|
||||
v1 := 3
|
||||
if v1 == 3 begin
|
||||
v0 := 2
|
||||
v0 += 3
|
||||
end
|
||||
print0
|
||||
|
||||
# simple not taken branch
|
||||
v0 := 1
|
||||
v1 := 3
|
||||
if v1 != 3 begin
|
||||
v0 := 2
|
||||
v0 += 3
|
||||
end
|
||||
print0
|
||||
|
||||
# else taken
|
||||
v0 := 2
|
||||
v1 := 3
|
||||
if v1 != v0 begin
|
||||
v0 := 1
|
||||
v0 += 2
|
||||
else
|
||||
v0 := 2
|
||||
v0 += 4
|
||||
end
|
||||
print0
|
||||
|
||||
# else not taken
|
||||
v0 := 2
|
||||
v1 := 3
|
||||
if v1 < v0 begin
|
||||
v0 := 1
|
||||
v0 += 2
|
||||
else
|
||||
v0 := 2
|
||||
v0 += 4
|
||||
end
|
||||
print0
|
||||
|
||||
# nesting
|
||||
v0 := 1
|
||||
if v0 != 0 begin
|
||||
if v0 != 2 begin
|
||||
v0 := 7
|
||||
else
|
||||
v0 := 3
|
||||
end
|
||||
v0 += 1
|
||||
end
|
||||
print0
|
||||
|
||||
loop again
|
||||
|
||||
: print0
|
||||
i := hex v0
|
||||
sprite va vb 5
|
||||
va += 5
|
||||
;
|
||||
@@ -0,0 +1,32 @@
|
||||
###########################################
|
||||
#
|
||||
# Collision Detection Test
|
||||
#
|
||||
# Draws two overlapping sprites and
|
||||
# displays the contents of the vF register.
|
||||
# Should print "1".
|
||||
#
|
||||
###########################################
|
||||
|
||||
: square
|
||||
0b11110000
|
||||
0b11110000
|
||||
0b11110000
|
||||
0b11110000
|
||||
|
||||
: main
|
||||
v0 := 20
|
||||
v1 := 10
|
||||
i := square
|
||||
|
||||
sprite v0 v1 4
|
||||
v0 += 2
|
||||
v1 += 2
|
||||
sprite v0 v1 4
|
||||
|
||||
v2 := vf
|
||||
v0 += 10
|
||||
i := hex v2
|
||||
sprite v0 v1 5
|
||||
|
||||
loop again
|
||||
@@ -0,0 +1,70 @@
|
||||
###########################################
|
||||
#
|
||||
# Numeric Comparison Tests
|
||||
#
|
||||
# Exercises all combinations of
|
||||
# register-to-register and register-to-constant
|
||||
# comparisons with the synthetic pseudo-ops
|
||||
# < > <= and >=
|
||||
#
|
||||
###########################################
|
||||
|
||||
: print
|
||||
i := hex v0
|
||||
sprite va vb 5
|
||||
va += 5
|
||||
v0 := 0
|
||||
;
|
||||
|
||||
: newline
|
||||
va := 0
|
||||
vb += 6
|
||||
;
|
||||
|
||||
: greater? if v1 > v2 then v0 := 1 print ;
|
||||
: greater5? if v1 > 5 then v0 := 1 print ;
|
||||
: less? if v1 < v2 then v0 := 1 print ;
|
||||
: less5? if v1 < 5 then v0 := 1 print ;
|
||||
: greatere? if v1 >= v2 then v0 := 1 print ;
|
||||
: greatere5? if v1 >= 5 then v0 := 1 print ;
|
||||
: lesse? if v1 <= v2 then v0 := 1 print ;
|
||||
: lesse5? if v1 <= 5 then v0 := 1 print ;
|
||||
|
||||
: main
|
||||
# 001001
|
||||
v1 := 3 v2 := 5 greater?
|
||||
v1 := 3 v2 := 3 greater?
|
||||
v1 := 5 v2 := 3 greater?
|
||||
v1 := 3 greater5?
|
||||
v1 := 5 greater5?
|
||||
v1 := 7 greater5?
|
||||
newline
|
||||
|
||||
# 100100
|
||||
v1 := 3 v2 := 5 less?
|
||||
v1 := 3 v2 := 3 less?
|
||||
v1 := 5 v2 := 3 less?
|
||||
v1 := 3 less5?
|
||||
v1 := 5 less5?
|
||||
v1 := 7 less5?
|
||||
newline
|
||||
|
||||
# 011011
|
||||
v1 := 3 v2 := 5 greatere?
|
||||
v1 := 3 v2 := 3 greatere?
|
||||
v1 := 5 v2 := 3 greatere?
|
||||
v1 := 3 greatere5?
|
||||
v1 := 5 greatere5?
|
||||
v1 := 7 greatere5?
|
||||
newline
|
||||
|
||||
# 110110
|
||||
v1 := 3 v2 := 5 lesse?
|
||||
v1 := 3 v2 := 3 lesse?
|
||||
v1 := 5 v2 := 3 lesse?
|
||||
v1 := 3 lesse5?
|
||||
v1 := 5 lesse5?
|
||||
v1 := 7 lesse5?
|
||||
|
||||
loop again
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
###########################################
|
||||
#
|
||||
# Loop Construct Tests
|
||||
#
|
||||
# Tests boundary conditions using `if`
|
||||
# and `while` with simple and synthetic
|
||||
# comparison operators.
|
||||
# Should draw 5 vertical strips of 6 boxes.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
# while with pseudo-op
|
||||
v0 := 0
|
||||
v1 := 0
|
||||
loop
|
||||
while v1 < 30
|
||||
sprite v0 v1 5
|
||||
v1 += 5
|
||||
again
|
||||
|
||||
# while with simple comparison
|
||||
v0 := 5
|
||||
v1 := 0
|
||||
loop
|
||||
while v1 != 30
|
||||
sprite v0 v1 5
|
||||
v1 += 5
|
||||
again
|
||||
|
||||
# if with pseudo-op
|
||||
v0 := 10
|
||||
v1 := 0
|
||||
loop
|
||||
if v1 >= 30 then jump done1
|
||||
sprite v0 v1 5
|
||||
v1 += 5
|
||||
again
|
||||
: done1
|
||||
|
||||
# if with simple comparison
|
||||
v0 := 15
|
||||
v1 := 0
|
||||
loop
|
||||
if v1 == 30 then jump done2
|
||||
sprite v0 v1 5
|
||||
v1 += 5
|
||||
again
|
||||
: done2
|
||||
|
||||
# nested loops with while
|
||||
v0 := 20
|
||||
v1 := 0
|
||||
loop
|
||||
while v1 != 25
|
||||
sprite v0 v1 5
|
||||
v1 += 5
|
||||
v2 := 5
|
||||
loop
|
||||
v2 += -1
|
||||
if v2 != 0 then
|
||||
again
|
||||
again
|
||||
sprite v0 v1 5
|
||||
|
||||
loop again
|
||||
@@ -0,0 +1,34 @@
|
||||
###########################################
|
||||
#
|
||||
# Next Test
|
||||
#
|
||||
# Demonstrates the use of the :next
|
||||
# operative to refer to the second byte
|
||||
# of an instruction. Mainly used for
|
||||
# writing self-modifying code.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: lt v0 := -1 i := vx save v0 ;
|
||||
: rt v0 := 1 i := vx save v0 ;
|
||||
|
||||
: up v0 := -1 i := vy save v0 ;
|
||||
: dn v0 := 1 i := vy save v0 ;
|
||||
|
||||
: main
|
||||
va := 2
|
||||
vb := 8
|
||||
|
||||
loop
|
||||
clear
|
||||
i := hex vc
|
||||
sprite va vb 5
|
||||
|
||||
:next vx va += 1
|
||||
:next vy vb += 1
|
||||
|
||||
if va == 0 then rt
|
||||
if va == 59 then lt
|
||||
if vb == 0 then dn
|
||||
if vb == 26 then up
|
||||
again
|
||||
@@ -0,0 +1,66 @@
|
||||
###########################################
|
||||
#
|
||||
# Quirks Mode Tests
|
||||
#
|
||||
# Examines the behavior of operations
|
||||
# which have multiple interpretations
|
||||
# in the wild and demonstrates the
|
||||
# distinction between Octo's defaults
|
||||
# and quirks modes for each instruction.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: buffer 0 3
|
||||
|
||||
: main
|
||||
# Perform a shift where source and dest
|
||||
# differ. The correct behavior will draw a 1
|
||||
# while in-place vx modification will draw 2.
|
||||
v0 := 4
|
||||
v1 := 2
|
||||
v0 >>= v1
|
||||
i := hex v0
|
||||
va := 5
|
||||
sprite va va 5
|
||||
|
||||
# perform a repeated store and load.
|
||||
# the correct behavior should print 3 due to i autoincrements.
|
||||
# quirks mode will print 4.
|
||||
i := buffer
|
||||
v0 := 4
|
||||
save v0
|
||||
v0 := 9 # just clobber v0 in case
|
||||
load v0
|
||||
i := hex v0
|
||||
vb := 12
|
||||
sprite va vb 5
|
||||
|
||||
# perform an arithmetic operation which stores to vf.
|
||||
# the correct behavior should write the carry flag last, resulting in 0.
|
||||
# quirks mode will print 6.
|
||||
vf := 3
|
||||
vf <<= vf
|
||||
i := hex vf
|
||||
vb := 19
|
||||
sprite va vb 5
|
||||
|
||||
# try a jump0 instruction.
|
||||
# the correct behavior should respect the value of v0 as an offset, resulting in 7
|
||||
# quirks mode will respect v2 instead (in this case), resulting in 8.
|
||||
v0 := 8
|
||||
v2 := 4
|
||||
jump0 jump-table
|
||||
|
||||
: jump-table
|
||||
0x00 0x00 0x00 0x00
|
||||
vf := 8 jump show-jump0-result
|
||||
vf := 7 jump show-jump0-result
|
||||
0x00 0x00 0x00 0x00
|
||||
|
||||
: show-jump0-result
|
||||
i := hex vf
|
||||
va := 10
|
||||
vb := 5
|
||||
sprite va vb 5
|
||||
|
||||
loop again
|
||||
@@ -0,0 +1,69 @@
|
||||
###########################################
|
||||
#
|
||||
# Unpacking Tests
|
||||
#
|
||||
# Uses the :unpack operative to perform
|
||||
# self-modification and rewrite an
|
||||
# i := NNN instruction.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: font
|
||||
0x20 0x20 0x20 0x00 0x20 0xF0 0x10 0x70 0x00 0x40 0xE0 0x90 0xE0 0x90 0x90 0x90
|
||||
0xE0 0x90 0xE0 0x90 0xE0 0x80 0x80 0xD0 0xB0 0xB0 0x90 0x90 0x90 0x90 0x60 0x60
|
||||
0x90 0x90 0x90 0x60 0x90 0xD0 0xB0 0x90 0x90 0x90 0x50 0x20 0x40 0x00 0x00 0x00
|
||||
0x00 0x00 0x60 0x90 0xF0 0x90 0x90 0xF0 0x90 0x90 0xF0 0x80 0xE0 0x80 0x80 0x80
|
||||
0x80 0xF0 0x80 0xE0 0x80 0xF0 0x40 0x40 0x40 0xF0 0x20 0x40 0x80 0xF0 0x20 0x20
|
||||
0x20 0xC0 0x60 0x90 0x80 0x90 0x60 0x90 0x90 0xB0 0x70 0x80 0xB0 0x90 0x70 0x80
|
||||
0x60 0x10 0xE0 0x90 0xA0 0xC0 0xA0 0x90 0x90 0xB0 0xB0 0xD0 0xF0 0x40 0x40 0x40
|
||||
0x40 0x90 0x90 0x70 0x10 0xE0
|
||||
|
||||
# draw and linewrap a string at an address given
|
||||
# in the v0-v1 registers. The string will consist
|
||||
# of a sequence of offsets into the font data:
|
||||
|
||||
: display-string
|
||||
i := string-addr
|
||||
save v1
|
||||
v1 := 2 # character x
|
||||
v2 := 1 # character y
|
||||
v3 := 0 # byte index
|
||||
# v4 contains string length
|
||||
loop
|
||||
: string-addr 0 0
|
||||
i += v3
|
||||
load v0
|
||||
i := font
|
||||
i += v0
|
||||
sprite v1 v2 5
|
||||
v1 += 5
|
||||
if v1 == 62 then v2 += 6
|
||||
if v1 == 62 then v1 := 2
|
||||
v3 += 1
|
||||
if v3 != v4 then
|
||||
again
|
||||
;
|
||||
|
||||
: demo-string
|
||||
0x71 0x1F 0x1A 0x2D 0x35 0x41 0x32 0x0A 0x2D 0x2D 0x2D 0x2D 0x32 0x2D 0x0A 0x1A
|
||||
0x17 0x10 0x3D 0x41 0x2D 0x45 0x24 0x2D 0x6C 0x35 0x41 0x2D 0x0C 0x45 0x5E 0x6C
|
||||
0x32 0x24 0x52 0x41
|
||||
:const demo-string-length 36
|
||||
|
||||
# these constants demonstrate all the valid opcodes
|
||||
# which can be built with the high nybble in :unpack
|
||||
:const JUMP 0x1 # jump <label>
|
||||
:const CALL 0x2 # <label>
|
||||
:const INDEX 0xA # i := <label>
|
||||
:const JUMP0 0xB # jump0 <label>
|
||||
|
||||
# these aliases are defaults but can be overridden
|
||||
# to unpack into alternate registers
|
||||
:alias unpack-hi v0
|
||||
:alias unpack-lo v1
|
||||
|
||||
: main
|
||||
:unpack INDEX demo-string
|
||||
v4 := demo-string-length
|
||||
display-string
|
||||
loop again
|
||||
@@ -0,0 +1,18 @@
|
||||
###########################################
|
||||
#
|
||||
# Key Input Test
|
||||
#
|
||||
# Prompt for a keypress,
|
||||
# then display its hex digit onscreen.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
v0 := 20
|
||||
v1 := 10
|
||||
loop
|
||||
v2 := key
|
||||
clear
|
||||
i := hex v2
|
||||
sprite v0 v1 5
|
||||
again
|
||||
@@ -0,0 +1,103 @@
|
||||
###########################################
|
||||
#
|
||||
# XO-Chip Tests
|
||||
#
|
||||
# Perform basic exercises demonstrating
|
||||
# the XO-Chip extended instructions
|
||||
# to verify the behavior of the compiler,
|
||||
# emulator and disassembler.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
|
||||
# demonstrate playing an audio sample:
|
||||
i := long gurgle
|
||||
audio
|
||||
v0 := 3
|
||||
loop
|
||||
vf := 10
|
||||
buzzer := vf
|
||||
vf := 15
|
||||
wait
|
||||
v0 += -1
|
||||
if v0 != 0 then
|
||||
again
|
||||
|
||||
# demonstrate drawing a color sprite:
|
||||
plane 3
|
||||
i := long rocket
|
||||
v2 := 24
|
||||
sprite v2 v1 0
|
||||
|
||||
# demonstrate the ranged load instructions
|
||||
# drawing hex characters to plane 2.
|
||||
# should display F B A.
|
||||
print-init
|
||||
i := long data1
|
||||
load vf - vf
|
||||
print
|
||||
|
||||
i := long data2
|
||||
load v1 - v0
|
||||
vf := v0 print
|
||||
vf := v1 print
|
||||
|
||||
# demonstrate vertical scrolling
|
||||
# in both directions with one plane:
|
||||
plane 1
|
||||
loop
|
||||
v0 := 0
|
||||
loop
|
||||
vf := 5 wait
|
||||
scroll-down 1
|
||||
v0 += 1
|
||||
if v0 != 16 then
|
||||
again
|
||||
loop
|
||||
vf := 5 wait
|
||||
scroll-up 1
|
||||
v0 += -1
|
||||
if v0 != 0 then
|
||||
again
|
||||
vf := 20 wait
|
||||
again
|
||||
|
||||
: wait
|
||||
delay := vf
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
;
|
||||
|
||||
: print-init
|
||||
plane 2
|
||||
ve := 4
|
||||
vd := 1
|
||||
;
|
||||
|
||||
: print
|
||||
i := hex vf
|
||||
sprite ve vd 5
|
||||
vd += 6
|
||||
;
|
||||
|
||||
# place static data beyond normal addressing space:
|
||||
:org 0x1000
|
||||
: gurgle
|
||||
0x55 0xAA 0x55 0xAA 0x55 0xAA 0x55 0xAA
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
|
||||
: rocket
|
||||
0x03 0xC0 0x05 0xE0 0x08 0x70 0x09 0xF0
|
||||
0x13 0xF8 0x12 0xF8 0x11 0xB8 0x08 0x30
|
||||
0x08 0xB0 0x04 0x60 0x04 0xE0 0x1E 0x78
|
||||
0x2E 0x5C 0x26 0x4C 0x23 0xC4 0x3C 0x3C
|
||||
0x03 0xC0 0x06 0x20 0x0F 0x90 0x0F 0x90
|
||||
0x1E 0x48 0x1F 0x48 0x1F 0xC8 0x0F 0xD0
|
||||
0x0F 0xD0 0x07 0xA0 0x07 0xA0 0x1B 0xD8
|
||||
0x33 0xE4 0x3B 0xF4 0x3F 0xFC 0x3C 0x3C
|
||||
|
||||
: data1 0x0F
|
||||
: data2 0x0A 0x0B
|
||||
@@ -0,0 +1,104 @@
|
||||
###########################################
|
||||
#
|
||||
# Vertical Clip
|
||||
#
|
||||
# Sprite drawing routines which are capable
|
||||
# of clipping a sprite along the top and
|
||||
# bottom edges of the screen.
|
||||
#
|
||||
# These routines are designed with 'lores'
|
||||
# 64x32 pixel graphics in mind.
|
||||
#
|
||||
# Sprite y coordinates must range between
|
||||
# 17 and 64- at either extreme the sprite
|
||||
# is completely invisible. If only a partial
|
||||
# clip along one edge is necessary or
|
||||
# other constraints can be added these
|
||||
# routines could be simplified.
|
||||
#
|
||||
###########################################
|
||||
|
||||
:const HEIGHT 15 # sprite height
|
||||
:const N_EDGE 32
|
||||
:calc N_LIMIT { N_EDGE - HEIGHT }
|
||||
:const S_EDGE 64
|
||||
:calc S_LIMIT { S_EDGE - HEIGHT }
|
||||
|
||||
:alias offset vd # could be a temp register
|
||||
:alias height vc # could be a temp register
|
||||
:alias y vb
|
||||
:alias x va
|
||||
|
||||
: flower
|
||||
0x3C 0x66 0x57 0xB7 0xFB 0x7A 0x1A
|
||||
0xC4 0x64 0x79 0x12 0x26 0x2C 0x10 0x08
|
||||
|
||||
: draw-sprite
|
||||
# If our sprite is below the north edge,
|
||||
# we don't need to perform top clipping:
|
||||
if y >= N_EDGE then jump clip-s
|
||||
|
||||
# Calculate the number of pixels we should
|
||||
# draw and the corresponding offset into
|
||||
# the sprite data which should be used:
|
||||
offset := N_EDGE
|
||||
offset -= y
|
||||
height := HEIGHT
|
||||
height -= offset
|
||||
|
||||
# If we're entirely off the top edge,
|
||||
# we don't need to draw anything:
|
||||
if height == 0 then return
|
||||
|
||||
# Overwrite the lowest nybble of the 'sprite instruction
|
||||
# to reflect the desired height:
|
||||
v0 := height
|
||||
i := nrows
|
||||
save v0
|
||||
v0 := 0
|
||||
|
||||
i := flower
|
||||
i += offset
|
||||
:next nrows sprite x v0 HEIGHT
|
||||
;
|
||||
|
||||
: clip-s
|
||||
# Calculate the number of pixels we
|
||||
# should draw based on the height of the screen:
|
||||
height := S_EDGE
|
||||
height -= y
|
||||
|
||||
# Drawing a 0-height sprite has the unintended
|
||||
# consequence of drawing a SuperChip 16x16 sprite,
|
||||
# so we must break if the sprite is fully offscreen:
|
||||
if height == 0 then return
|
||||
|
||||
# On the other hand, if we're far enough away from the
|
||||
# bottom edge we should display the full sprite.
|
||||
# We could skip this step if the sprite was always
|
||||
# against the bottom edge:
|
||||
if y < S_LIMIT then height := HEIGHT
|
||||
|
||||
# Overwrite the lowest nybble of the 'sprite' instruction
|
||||
# to parameterize the sprite height on the fly.
|
||||
# We must also preserve the y register setting, but
|
||||
# that is known statically:
|
||||
v0 := 0xB0
|
||||
v0 += height
|
||||
i := srows
|
||||
save v0
|
||||
|
||||
i := flower
|
||||
:next srows sprite x y HEIGHT
|
||||
;
|
||||
|
||||
: main
|
||||
x := 28
|
||||
y := 32
|
||||
loop
|
||||
clear
|
||||
draw-sprite
|
||||
v0 := key
|
||||
if v0 == 5 then y += -1
|
||||
if v0 == 8 then y += 1
|
||||
again
|
||||
@@ -0,0 +1,45 @@
|
||||
###########################################
|
||||
#
|
||||
# Music Player
|
||||
#
|
||||
# A very simple music player based on
|
||||
# the XO-Chip audio system playing
|
||||
# a rendition of the Cave Story theme.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
loop
|
||||
cave-1
|
||||
cave-2
|
||||
cave-1
|
||||
cave-3
|
||||
again
|
||||
|
||||
: cave-1 D$4 --- G$4 --- D$4 --- G$4 ---
|
||||
D-4 --- G$4 --- D-4 --- G$4 ---
|
||||
C$4 --- G$4 --- C$4 --- G$4 --- ;
|
||||
: cave-2 C-4 --- G$4 --- C-4 --- C$4 D-4 ;
|
||||
: cave-3 B-4 --- A$4 --- G$4 --- --- --- ;
|
||||
|
||||
:macro sample { :calc t { 6 + HERE } i := t note ; }
|
||||
: B-4 sample 0xF8 0x78 0x78 0x78 0x78 0x78 0x78 0x78 0x78 0x78 0x7C 0x3C 0x3C 0x3C 0x3C 0x3C # 494hz
|
||||
: A$4 sample 0xF8 0x78 0x3C 0x3E 0x1E 0x1F 0x0F 0x07 0x87 0x83 0xC3 0xE1 0xE0 0xF0 0xF0 0x78 # 466hz
|
||||
: G$4 sample 0xF8 0x3E 0x0F 0x87 0xC1 0xF0 0x7C 0x3E 0x0F 0x83 0xC1 0xF0 0x7C 0x1E 0x0F 0x83 # 415hz
|
||||
: D$4 sample 0xFE 0x07 0xF0 0x3F 0x81 0xFC 0x0F 0xC0 0x7E 0x03 0xF0 0x1F 0x81 0xFC 0x0F 0xE0 # 311hz
|
||||
: D-4 sample 0xFE 0x03 0xF8 0x0F 0xE0 0x7F 0x01 0xFC 0x07 0xF0 0x3F 0x80 0xFE 0x03 0xF8 0x1F # 293hz
|
||||
: C$4 sample 0xFF 0x01 0xFC 0x07 0xF8 0x0F 0xE0 0x3F 0x80 0x7F 0x01 0xFC 0x03 0xF8 0x0F 0xE0 # 277hz
|
||||
: C-4 sample 0xFF 0x00 0xFE 0x01 0xFE 0x03 0xFC 0x03 0xF8 0x07 0xF0 0x0F 0xF0 0x1F 0xE0 0x1F # 262hz
|
||||
: --- sample 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 # silence
|
||||
|
||||
: note
|
||||
audio
|
||||
vf := 6 # actual note duration
|
||||
delay := vf
|
||||
vf := 60 # prevent background flicker
|
||||
buzzer := vf
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
;
|
||||
@@ -0,0 +1,52 @@
|
||||
###########################################
|
||||
#
|
||||
# Music Player 2
|
||||
#
|
||||
# A music player using the pitch register,
|
||||
# instead of varying the pattern buffer.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
loop
|
||||
cave-1
|
||||
cave-2
|
||||
cave-1
|
||||
cave-3
|
||||
again
|
||||
|
||||
: cave-1 D$4 --- G$4 --- D$4 --- G$4 ---
|
||||
D-4 --- G$4 --- D-4 --- G$4 ---
|
||||
C$4 --- G$4 --- C$4 --- G$4 --- ;
|
||||
: cave-2 C-4 --- G$4 --- C-4 --- C$4 D-4 ;
|
||||
: cave-3 B-4 --- A$4 --- G$4 --- --- --- ;
|
||||
|
||||
: ---
|
||||
i := silence
|
||||
jump play
|
||||
: note
|
||||
pitch := vf
|
||||
i := waveform
|
||||
: play
|
||||
audio
|
||||
vf := 6 # actual note duration
|
||||
delay := vf
|
||||
vf := 60 # prevent background flicker
|
||||
buzzer := vf
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
;
|
||||
|
||||
:macro def-note NAME PITCH { : NAME vf := PITCH jump note }
|
||||
def-note B-4 159
|
||||
def-note A$4 155
|
||||
def-note G$4 147
|
||||
def-note D$4 127
|
||||
def-note D-4 123
|
||||
def-note C$4 119
|
||||
def-note C-4 115
|
||||
|
||||
: waveform 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF
|
||||
: silence 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
Reference in New Issue
Block a user