function _init()
frame = 0
-- Set up userdata so we can draw the screen to itself
-- by using memcpy() to a memmapped region of memory.
-- The userdata is now the contents of the previous frame,
-- and it is now possible to modify the current frame.
-- We can also call spr() with userdata
-- to draw the previous frame to the current one
screen = userdata("u8", 480, 270)
memmap(0x30000, screen)
end
function set_col_table(new, current, col)
poke(0x8000 + 64*new + current, col)
end
function _draw()
frame += 1
if frame == 1 then
-- Randomise the screen for the first frame.
for y=0,269 do
for x=0,479 do
if (rnd() < 0.2) pset(x, y, 7)
end
end
-- Copy the current screen to the buffer, just for the first frame
memcpy(0x30000, 0x10000, 0x20000)
end
--if (frame % 32 > 0) return
cls()
-- White cells drawn onto colour 0 will set the colour to 1, white onto 1 will be 2
-- and so on. This counts the number of neighbouring cells very quickly
for i=0, 7 do
set_col_table(7, i, i+1)
end
-- Draw the screen 8 times in a ring, for each neighbour. The colour tables
-- do the counting
for y=-1,1 do
for x=-1,1 do
if (x!=0 or y!=0) spr(screen, x, y)
end
end
-- Set up colour tables to turn the "counted" screen into the next frame
-- Set every colour to black except for drawing black onto 3 (brought back alive)
-- and 2 or 3 neighbours for alive (stay alive)
for i=0, 9 do
set_col_table(0, i, 0)
set_col_table(7, i, 0)
end
set_col_table(0, 3, 7)
set_col_table(7, 2, 7)
set_col_table(7, 3, 7)
-- Draw the screen to the "counted" version, with the rules set above
spr(screen, 0, 0)
-- Reset the draw state to make sure we have a predictable next frame
reset()
-- Copy the screen to the buffer for the next frame,
-- before we pollute it with the FPS counter
memcpy(0x30000, 0x10000, 0x20000)
-- FPS counter
if key("x") then
rectfill(0, 0, 44, 8, 0)
print("FPS: "..stat(7), 1, 1, 8)
end
end