diff options
| author | Patrick Kingston <patrick@pkingston.xyz> | 2026-02-14 18:17:50 -0500 |
|---|---|---|
| committer | Patrick Kingston <patrick@pkingston.xyz> | 2026-02-14 18:17:50 -0500 |
| commit | eb7da883997f4ae3bb5baa7875d94d37a6c14f1d (patch) | |
| tree | 007050dc116435ef0f0b7d0f851a2cd4c9cf2671 /main.fab | |
| parent | 62966cf7418c73d68870a6f1adb87042a23c2471 (diff) | |
Create Elementary cellular automata
Cellular automata now makes a new row
every frame and resets at the top.
Diffstat (limited to 'main.fab')
| -rw-r--r-- | main.fab | 132 |
1 files changed, 98 insertions, 34 deletions
@@ -1,54 +1,118 @@ vars - U[8] buf // A buffer that can store the current and next row - U row_a = 0 // We swap back and forth between these two offsets for each row - U row_b = 4 - UU drawing_row_offset = 0// Use this to track which row we're drawing + 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 - U next_cell = 0 fn init_screen() - ppu_reset_addr($2000) + // Scroll to attributes + ppu_reset_addr($2000 + 960) + // Set attributes for background + for U i = 0; i < 64; i+= 1 + {PPUDATA}(%11111111) - // Set background tiles - for UU i = 0; i < 960; i += 1 - {PPUDATA}(1) + //// Init the buffers to 0 + //for i = 0; i < 64; i += 1 + // buf[i] = 0 - U i = 0 - // Set attributes for background - for i = 0; i < 64; i+= 1 - {PPUDATA}(%00011011) + // Init the buffer to zero + buf = U[64]() + // Add an initial cell + buf[16] = 1 - // Init the buffers to 0 - for i = 0; i < 8; i += 1 - buf[i] = 0 -fn calc_and_upload_next_row() - // "scroll" to the row we're at - UU row_start = $2000 - row_start += (drawing_row_offset * 32) - ppu_reset_addr(row_start) +fn assemble_code(U left, U middle, U right) U + U out = %00000000 + out |= left << 2 + out |= middle << 1 + out |= right + return out - for UU i = 0; i < 32; i += 1 - //next_cell = 0 //get_next_gen(i) - {PPUDATA}(next_cell) +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 - drawing_row_offset += 1 +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 - if next_cell - next_cell = 0 - else - next_cell = 1 -nmi main_nmi() - ppu_upload_oam_poll_pads(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]) - calc_and_upload_next_row() +nmi main_nmi() // Turn on rendering sprites and bg {PPUMASK}(PPUMASK_ON | PPUMASK_NO_CLIP) + upload_curr_gen() + ppu_reset_scroll(0, 0) @@ -58,7 +122,7 @@ mode main() palette = example_palette ppu_upload_palette() - // Load the background + // Initialize the screen init_screen() // Turn the NMI on @@ -66,8 +130,8 @@ mode main() // Loop forever: while true - update_pads() nmi + calc_and_advance_gen() // Define the tileset (commonly called CHR): chrrom |
