.ifndef TETRIS_CELL_S TETRIS_CELL_S: .include "./constants.s" .include "./rectangle.s" .include "./line.s" /* Change these parameters to select your favorite TETRIS cell size */ .equ TETRIS_CELL_SIZE, 21 // Original is 21px. .equ TETRIS_CELL_BORDER_SIZE, 4 // Original is 4px. /* * Params: * x0: u64 <- bottom left x position (game coordinates) * x1: u64 <- bottom left y position (game coordinates) * x2: in Tetromino* <- tetromino * x3: out u32* <- framebuffer */ draw_tetris_cell: stp lr, x19, [sp, -16]! mov x9, x2 // x9 <- tetromino mov x5, x3 // x5 <- framebuffer mov x0, x0 mov x1, x1 ldr w2, [x9, TETROMINO_DIFFUSE_COLOR] ldr w3, [x9, TETROMINO_SPECULAR_COLOR] ldr w4, [x9, TETROMINO_AMBIENT_COLOR] bl draw_tetris_cell_by_colors ldp lr, x19, [sp], 16 ret /* * Params: * x0: u64 <- bottom left x position (game coordinates) * x1: u64 <- bottom left y position (game coordinates) * w2: u32 <- diffuse color * w3: u32 <- specular color * w4: u32 <- ambient color * x5: out u32* <- framebuffer */ draw_tetris_cell_by_colors: stp lr, x19, [sp, -64]! stp x20, x21, [sp, 16] stp x22, x23, [sp, 32] stp x24, x25, [sp, 48] /* Save arguments */ mov x20, x0 // x20 <- bottom left x mov x21, x1 // x21 <- bottom left y mov w22, w2 // w22 <- diffuse color mov w23, w3 // w23 <- specular color mov w24, w4 // w24 <- ambient color mov x25, x5 // x25 <- framebuffer /* Draw border trapezoids */ mov x0, x20 mov x1, x21 mov w2, w23 mov w3, w24 mov x4, x25 bl draw_tetris_cell_trapezoids /* Draw inner rectangle */ add x0, x20, TETRIS_CELL_BORDER_SIZE // x0 = inner rectangle bottom left x add x1, x21, TETRIS_CELL_BORDER_SIZE // x1 = inner rectangle bottom left y add x2, x20, TETRIS_CELL_SIZE - 1 sub x2, x2, TETRIS_CELL_BORDER_SIZE // x2 = inner rectangle top right x add x3, x21, TETRIS_CELL_SIZE - 1 sub x3, x3, TETRIS_CELL_BORDER_SIZE // x3 = inner rectangle top right y mov x4, x25 // x4 = framebuffer mov w5, w22 // w5 = diffuse color bl draw_filled_rectangle /* Draw bottom left diagonal line */ mov x0, x20 mov x1, x21 add x2, x0, TETRIS_CELL_BORDER_SIZE - 1 add x3, x1, TETRIS_CELL_BORDER_SIZE - 1 mov x4, x25 // x4 = framebuffer mov w5, w22 // w5 = diffuse color bl draw_line /* Draw top right diagonal line */ add x0, x20, TETRIS_CELL_SIZE - 1 add x1, x21, TETRIS_CELL_SIZE - 1 sub x2, x0, TETRIS_CELL_BORDER_SIZE - 1 sub x3, x1, TETRIS_CELL_BORDER_SIZE - 1 mov x4, x25 // x4 = framebuffer mov w5, w22 // w5 = diffuse color bl draw_line ldp x24, x25, [sp, 48] ldp x22, x23, [sp, 32] ldp x20, x21, [sp, 16] ldp lr, x19, [sp], 64 ret /* * Params: * x0: u64 <- bottom left x position (game coordinates) * x1: u64 <- bottom left y position (game coordinates) * w2: u32 <- specular color * w3: u32 <- ambient color * x4: out u32* <- framebuffer */ draw_tetris_cell_trapezoids: stp lr, x19, [sp, -80]! stp x20, x21, [sp, 16] stp x22, x23, [sp, 32] stp x24, x25, [sp, 48] stp x26, x27, [sp, 64] mov w22, w2 // const w22 <- specular color mov w23, w3 // const w23 <- specular color /* Convert coordinates */ mov x9, SCREEN_HEIGH - 1 sub x1, x9, x1 // x1 = bottom left y coordinate (screen coordinates) sub x1, x1, TETRIS_CELL_SIZE - 1 // x1 = top left y coordinate (screen coordiantes) /* Initialize framebuffer pointers */ mov x24, SCREEN_WIDTH // x24 = SCREEN_WIDTH mul x24, x24, x1 // x24 = SCREEN_WIDTH * y = vertical offset add x24, x24, x0 // x24 = (SCREEN_WIDTH * y) + x = vertical + horizontal offset lsl x24, x24, BYTES_PER_PIXEL_SHIFT // x24 = total offset in bytes add x24, x4, x24 // x24 = top left of square mov x9, TETRIS_CELL_SIZE - 1 // x9 = size - 1 = space between corners mov x10, SCREEN_WIDTH mul x10, x9, x10 // x10 = space between corners * screen width = pixels between vertically aligned corners lsl x9, x9, BYTES_PER_PIXEL_SHIFT // x9 = space in bytes between horizontal corners lsl x10, x10, BYTES_PER_PIXEL_SHIFT // x10 = space in bytes between vertical corners add x25, x24, x10 // x25 = bottom left of square mov x26, x24 // x26 = top left of square add x27, x24, x9 // x27 = top right of square /* End initialize framebuffer pointers */ /* * x24 = top trapezoid pointer * x25 = bottom trapezoid pointer * x26 = left trapezoid pointer * x27 = right trapezoid pointer */ mov x20, 0 // x iterator mov x21, 0 // y iterator mov x15, TETRIS_CELL_SIZE // x15 = current row size draw_tetris_cell_trapezoids__next_row: cmp x21, TETRIS_CELL_BORDER_SIZE b.ge draw_tetris_cell_trapezoids__end draw_tetris_cell_trapezoids__next_col: cmp x20, x15 // check if we are at the end of the row b.ge draw_tetris_cell_trapezoids__end_row /* Draw pixels */ str w22, [x24] str w23, [x25] str w22, [x26] str w23, [x27] /* Advance pointers */ // Advance horizontally add x24, x24, BYTES_PER_PIXEL add x25, x25, BYTES_PER_PIXEL // Advance vertically mov x9, SCREEN_WIDTH lsl x9, x9, BYTES_PER_PIXEL_SHIFT add x26, x26, x9 add x27, x27, x9 add x20, x20, 1 // Increment x iterator b draw_tetris_cell_trapezoids__next_col draw_tetris_cell_trapezoids__end_row: /* Advance pointers for horizontal trapezoids */ // We need to move the pointers that are currently at the end of a row, // to the beginning of the next row (above or below), offseted by one pixel to the right neg x10, x15 add x10, x10, 1 lsl x10, x10, BYTES_PER_PIXEL_SHIFT mov x11, SCREEN_WIDTH lsl x11, x11, BYTES_PER_PIXEL_SHIFT add x9, x10, x11 add x24, x24, x9 sub x9, x10, x11 add x25, x25, x9 /* Advance pointers to vertical trapezoids */ // We need to move the pointers that are currently at the bottom of a column, // to the beginning of the next column (left or right), offseted by one row down mov x10, SCREEN_WIDTH mul x10, x10, x15 neg x10, x10 add x10, x10, SCREEN_WIDTH lsl x10, x10, BYTES_PER_PIXEL_SHIFT // x10 now moves a pointer to the second element of the current column (which has the same height as the first element of the next column) add x9, x10, BYTES_PER_PIXEL // x9 now moves to the beginning of the column on the right add x26, x26, x9 sub x9, x10, BYTES_PER_PIXEL // x9 now moves to the beginning of the column on the left add x27, x27, x9 sub x15, x15, 2 // Row size is decremented by 2 mov x20, 0 // Reset x add x21, x21, 1 // Increment y b draw_tetris_cell_trapezoids__next_row draw_tetris_cell_trapezoids__end: ldp x26, x27, [sp, 64] ldp x24, x25, [sp, 48] ldp x22, x23, [sp, 32] ldp x20, x21, [sp, 16] ldp lr, x19, [sp], 80 ret .endif