millfork/examples/crossplatform/life.mfk

209 lines
3.9 KiB
Plaintext

#if CBM_64 || CBM_264
const byte width = 40
const byte height = 25
#endif
#if ZX_SPECTRUM
const byte width = 32
const byte height = 24
#endif
#if ATARI_8
const byte width = 40
const byte height = 24
#endif
const word area = word(width) * word(height)
// representation: $1 live now $80 live soon
const byte ALIVE = $81
const byte DEAD = 0
array buffer [width * height] align(256)
void init_buffer() {
pointer p
for p,buffer.addr,paralleluntil,buffer.addr+area {
p[0] = DEAD
}
// glider:
buffer[1*width + 2] = ALIVE
buffer[2*width + 3] = ALIVE
buffer[3*width + 1] = ALIVE
buffer[3*width + 2] = ALIVE
buffer[3*width + 3] = ALIVE
}
void do_round() align(fast) {
byte x, y, sum, j
pointer p
p = buffer.addr - width - 1
for y,0,until,height {
for x,0,until,width {
sum = 0
if y != 0 {
if x != 0 { sum += p[0] }
sum += p[1]
if x != width - 1 { sum += p[2] }
}
if true {
if x != 0 { sum += p[width] }
if x != width - 1 { sum += p[width + 2] }
}
if y != height - 1 {
if x != 0 { sum += p[2 * width] }
sum += p[2 * width + 1]
if x != width - 1 { sum += p[2 * width + 2] }
}
sum &= $7f
if sum == 3 {
p[width + 1] |= $80
} else if sum != 2 {
p[width + 1] &= $7f
}
p += 1
}
}
p = buffer.addr
for j,0,paralleluntil,height {
for x,0,paralleluntil,width {
if p[x] & $80 != 0 { p[x] = ALIVE }
else { p[x] = DEAD }
}
p += width
}
}
#if CBM_64
void init_gfx() {
byte i
for i,0,paralleluntil,250 {
c64_color_ram[i+000]=light_blue
c64_color_ram[i+250]=light_blue
c64_color_ram[i+500]=light_blue
c64_color_ram[i+750]=light_blue
}
}
void redraw() align(fast) {
pointer src, dest
byte x, y
src = buffer.addr
dest = $400
for y,0,until,height {
for x,0,until,width {
if src[x] != 0 {
dest[x] = 128 + ' '
} else {
dest[x] = ' '
}
}
src += width
dest += width
}
}
void wait_frame() align(fast) {
while vic_raster != $ff {}
while vic_raster == $ff {}
}
#endif
#if CBM_264
void init_gfx() {
}
void redraw() align(fast) {
pointer src, dest
byte x, y
src = buffer.addr
dest = $c00
for y,0,until,height {
for x,0,until,width {
if src[x] != 0 {
dest[x] = 128 + ' '
} else {
dest[x] = ' '
}
}
src += width
dest += width
}
}
void wait_frame() align(fast) {
while ted_raster_y != $ff {}
while ted_raster_y == $ff {}
}
#endif
#if ATARI_8
pointer screen_start @$58
byte clock @$14
void init_gfx() {
}
void redraw() align(fast) {
pointer src, dest
byte x, y
src = buffer.addr
dest = screen_start
for y,0,until,height {
for x,0,until,width {
if src[x] != 0 {
dest[x] = 128 + ' 'scr
} else {
dest[x] = ' 'scr
}
}
src += width
dest += width
}
}
void wait_frame() align(fast) {
while clock != clock {}
}
#endif
#if ZX_SPECTRUM
void init_gfx() {
}
void redraw() align(fast) {
pointer src, dest
byte x, y
src = buffer.addr
dest = $5800
for y,0,until,height {
for x,0,until,width {
if src[x] != 0 {
dest[x] = 0
} else {
dest[x] = $3f
}
}
src += width
dest += width
}
}
asm macro void wait_frame() {
halt
}
#endif
void main() {
init_gfx()
init_buffer()
redraw()
while true {
wait_frame()
do_round()
redraw()
}
}