vars U[64] buf // A buffer that can store the current and next row U curr_gen = 0 // Swap these offsets back and forth per generation U next_gen = 32 UU drawing_row_offset = 0 // Use this to track which row we're drawing U current_rule = %00011110 fn init_screen() // Scroll to attributes ppu_reset_addr($2000 + 960) // Set attributes for background for U i = 0; i < 64; i+= 1 {PPUDATA}(%11111111) //// Init the buffers to 0 //for i = 0; i < 64; i += 1 // buf[i] = 0 // Init the buffer to zero buf = U[64]() // Add an initial cell buf[16] = 1 fn assemble_code(U left, U middle, U right) U U out = %00000000 out |= left << 2 out |= middle << 1 out |= right return out fn calc_next_cell(U left, U middle, U right) U U code = assemble_code(left, middle, right) ct U mask7 = %10000000 ct U mask6 = %01000000 ct U mask5 = %00100000 ct U mask4 = %00010000 ct U mask3 = %00001000 ct U mask2 = %00000100 ct U mask1 = %00000010 ct U mask0 = %00000001 switch code case %00000111 return (current_rule & mask7) >> 7 case %00000110 return (current_rule & mask6) >> 6 case %00000101 return (current_rule & mask5) >> 5 case %00000100 return (current_rule & mask4) >> 4 case %00000011 return (current_rule & mask3) >> 3 case %00000010 return (current_rule & mask2) >> 2 case %00000001 return (current_rule & mask1) >> 1 case %00000000 return (current_rule & mask0) >> 0 fn calc_and_advance_gen() // Calculate the next row's values U left_ind = 0 U right_ind = 0 U left_cell = 0 U mid_cell = 0 U right_cell = 0 U next_cell = 0 for U i = 0; i < 32; i += 1 // Calculate indices for left and right of cell if i == 0 left_ind = 31 else left_ind = i - 1 if i == 31 right_ind = 0 else right_ind = i + 1 // Get left and right of cell left_cell = buf[curr_gen + left_ind] mid_cell = buf[curr_gen + i] right_cell = buf[curr_gen + right_ind] // Calc next cell next_cell = calc_next_cell(left_cell, mid_cell, right_cell) // Set next cell buf[next_gen + i] = next_cell // Advance next generation if curr_gen == 0 curr_gen = 32 next_gen = 0 else curr_gen = 0 next_gen = 32 // advance drawing row offset, looping back to top drawing_row_offset += 1 if drawing_row_offset == 30 drawing_row_offset = 0 fn upload_curr_gen() // "scroll" to the row we're at UU row_start = $2000 row_start += (drawing_row_offset * 32) ppu_reset_addr(row_start) for U i = 0; i < 32; i += 1 //32 columns //next_cell = 0 //get_next_gen(i) {PPUDATA}(buf[i+curr_gen]) nmi main_nmi() // Turn on rendering sprites and bg {PPUMASK}(PPUMASK_ON | PPUMASK_NO_CLIP) upload_curr_gen() ppu_reset_scroll(0, 0) mode main() : nmi main_nmi // Set the palette: palette = example_palette ppu_upload_palette() // Initialize the screen init_screen() // Turn the NMI on {PPUCTRL}(PPUCTRL_NMI_ON) // Loop forever: while true nmi calc_and_advance_gen() // Define the tileset (commonly called CHR): chrrom file(fmt, "tiles.png")