From 345984212861553b4b0c7d2edb37f2111a413368 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sun, 1 Sep 2024 04:30:23 -0500 Subject: [PATCH] spinning triangle --- bits.h | 22 ++-- main.c | 167 +++++++++++++++++++++++++---- registers/graphics_engine_bits.csv | 22 ++-- registers/graphics_engine_bits.ods | Bin 24254 -> 24262 bytes 4 files changed, 168 insertions(+), 43 deletions(-) diff --git a/bits.h b/bits.h index 3767937..adcab53 100644 --- a/bits.h +++ b/bits.h @@ -178,7 +178,7 @@ #define VTX_XY__y_coordinate(v) (((v) & 0xffff) << 16) #define VTX_XY__x_coordinate(v) (((v) & 0xffff) << 0) #define VTX_XZ__z_coordinate(v) (((v) & 0xffff) << 16) -#define VTX_XZ__z_coordinate(v) (((v) & 0xffff) << 0) +#define VTX_XZ__x_coordinate(v) (((v) & 0xffff) << 0) #define VTX_YZ__z_coordinate(v) (((v) & 0xffff) << 16) #define VTX_YZ__y_coordinate(v) (((v) & 0xffff) << 0) #define VTX_DIFF__z_coordinate(v) (((v) & 0x3ff) << 20) @@ -307,17 +307,17 @@ #define GXSTAT__command_fifo_interrupt_condition__disable (0x0 << 30) #define GXSTAT__command_fifo_interrupt_condition__half_full (0x1 << 30) #define GXSTAT__command_fifo_interrupt_condition__empty (0x2 << 30) -#define GXSTAT__geometry_engine_busy(v) (((v) >> 27) & 0x1) -#define GXSTAT__fifo_status__empty(v) (((v) >> 26) & 0x1) -#define GXSTAT__fifo_status__less_than_half_full(v) (((v) >> 25) & 0x1) -#define GXSTAT__fifo_status__full(v) (((v) >> 24) & 0x1) +#define GXSTAT__geometry_engine_busy (0x1 << 27) +#define GXSTAT__fifo_status__empty (0x1 << 26) +#define GXSTAT__fifo_status__less_than_half_full (0x1 << 25) +#define GXSTAT__fifo_status__full (0x1 << 24) #define GXSTAT__command_fifo_count(v) (((v) >> 16) & 0xff) -#define GXSTAT__matrix_stack_status__stack_overflow_or_underflow(v) (((v) >> 15) & 0x1) -#define GXSTAT__matrix_stack_status__stack_busy(v) (((v) >> 14) & 0x1) -#define GXSTAT__matrix_stack_status__projection_matrix_stack_level(v) (((v) >> 13) & 0x1) -#define GXSTAT__matrix_stack_status__position_and_vector_matrix_stack_level(v) (((v) >> 8) & 0x1f) -#define GXSTAT__test_status(v) (((v) >> 1) & 0x1) -#define GXSTAT__test_busy(v) (((v) >> 0) & 0x1) +#define GXSTAT__matrix_stack_status__overflow_or_underflow (0x1 << 15) +#define GXSTAT__matrix_stack_status__busy (0x1 << 14) +#define GXSTAT__matrix_stack_status__projection_stack_level(v) (((v) >> 13) & 0x1) +#define GXSTAT__matrix_stack_status__position_and_vector_stack_level(v) (((v) >> 8) & 0x1f) +#define GXSTAT__test_status (0x1 << 1) +#define GXSTAT__test_busy (0x1 << 0) #define LISTRAM_COUNT__counter(v) (((v) >> 0) & 0xfff) #define VTXRAM_COUNT__counter(v) (((v) >> 0) & 0x1fff) #define OBJ_ATTRIBUTE_0__obj_shape__square (0x0 << 14) diff --git a/main.c b/main.c index 24aa9fc..1e07c86 100644 --- a/main.c +++ b/main.c @@ -398,12 +398,21 @@ void main() // 2d graphics engine B OBJ io_registers.a.VRAM_HI_CNT = (1 << 15) | (0b10 << 8); + io_registers.a.POWCNT = 0 + | POWCNT__lcd_output_destination__a_to_upper__b_to_lower + | POWCNT__2d_graphics_engine_b__enable + | POWCNT__geometry_engine__enable + | POWCNT__rendering_engine__enable + | POWCNT__2d_graphics_engine_a__enable + | POWCNT__lcd__enable; + io_registers.a.DISPCNT = 0 | DISPCNT__bg_screen_base_offset(0) | DISPCNT__bg_character_base_offset(0) | DISPCNT__display_mode__graphics_display | DISPCNT__bg0__enable - | DISPCNT__display_selection_for_bg0__2d_graphics + //| DISPCNT__display_selection_for_bg0__2d_graphics + | DISPCNT__display_selection_for_bg0__3d_graphics | DISPCNT__bg_mode__text0_text1_text2_text3 ; @@ -475,28 +484,28 @@ void main() for (int c_y = 0; c_y < 8; c_y++) { for (int c_x = 0; c_x < 8; c_x++) { for (int y = 0; y < 8; y++) { - int abs_y = c_y * 8 + y; - int abs_x = c_x * 8; - int origin = abs_y * 64 + abs_x; + int abs_y = c_y * 8 + y; + int abs_x = c_x * 8; + int origin = abs_y * 64 + abs_x; - uint8_t a = b_data[origin + 7]; - uint8_t b = b_data[origin + 6]; - uint8_t c = b_data[origin + 5]; - uint8_t d = b_data[origin + 4]; - uint8_t e = b_data[origin + 3]; - uint8_t f = b_data[origin + 2]; - uint8_t g = b_data[origin + 1]; - uint8_t h = b_data[origin + 0]; + uint8_t a = b_data[origin + 7]; + uint8_t b = b_data[origin + 6]; + uint8_t c = b_data[origin + 5]; + uint8_t d = b_data[origin + 4]; + uint8_t e = b_data[origin + 3]; + uint8_t f = b_data[origin + 2]; + uint8_t g = b_data[origin + 1]; + uint8_t h = b_data[origin + 0]; - obj_vram.b.character[c_y * 8 + c_x].u32[y] = 0 - | (a << 28) - | (b << 24) - | (c << 20) - | (d << 16) - | (e << 12) - | (f << 8) - | (g << 4) - | (h << 0); + obj_vram.b.character[c_y * 8 + c_x].u32[y] = 0 + | (a << 28) + | (b << 24) + | (c << 20) + | (d << 16) + | (e << 12) + | (f << 8) + | (g << 4) + | (h << 0); } } } @@ -533,6 +542,70 @@ void main() (1/β)cosθ */ + /* do 3d */ + while (io_registers.a.GXSTAT & GXSTAT__geometry_engine_busy); + + // clear matrix stack status + io_registers.a.GXSTAT |= GXSTAT__matrix_stack_status__overflow_or_underflow; + + // clear projection matrix stack + int projection_stack_level = GXSTAT__matrix_stack_status__projection_stack_level(io_registers.a.GXSTAT); + if (projection_stack_level) { + io_registers.a.MTX_MODE = MTX_MODE__matrix_mode__projection; + io_registers.a.MTX_POP = MTX_POP__number_of_pops(1); + } + + // clear position_and_vector matrix stack + int position_and_vector_stack_level = GXSTAT__matrix_stack_status__position_and_vector_stack_level(io_registers.a.GXSTAT); + if (position_and_vector_stack_level) { + io_registers.a.MTX_MODE = MTX_MODE__matrix_mode__position_and_vector; + io_registers.a.MTX_POP = MTX_POP__number_of_pops(position_and_vector_stack_level); + } + + // load identity matrices + io_registers.a.MTX_MODE = MTX_MODE__matrix_mode__projection; + io_registers.a.MTX_IDENTITY = 0; + io_registers.a.MTX_SCALE = (1 << 12); + io_registers.a.MTX_SCALE = (1 << 12); + io_registers.a.MTX_SCALE = (1 << 12); + + io_registers.a.MTX_MODE = MTX_MODE__matrix_mode__position; + io_registers.a.MTX_IDENTITY = 0; + + io_registers.a.MTX_MODE = MTX_MODE__matrix_mode__position_and_vector; + io_registers.a.MTX_IDENTITY = 0; + + io_registers.a.SWAP_BUFFERS = 0 + | SWAP_BUFFERS__depth_buffering__z_value + | SWAP_BUFFERS__translucent_polygon_y_sorting__auto_sort; + + io_registers.a.DISP3DCNT = 0 + | DISP3DCNT__clear_image__disable + | DISP3DCNT__fog_master__disable + | DISP3DCNT__edge_marking__disable + | DISP3DCNT__anti_aliasing__disable + | DISP3DCNT__alpha_blending__disable + | DISP3DCNT__alpha_test__disable + | DISP3DCNT__texture_mapping__disable; + + io_registers.a.CLEAR_COLOR = 0 + | CLEAR_COLOR__clear_polygon_id(31) + | CLEAR_COLOR__alpha_value(31) + | CLEAR_COLOR__red(10); + + io_registers.a.CLEAR_DEPTH = CLEAR_DEPTH__value(0x7fff); + + io_registers.a.POLYGON_ATTR = 0 + | POLYGON_ATTR__alpha_value(31) + | POLYGON_ATTR__render_front_surface__enable + | POLYGON_ATTR__render_back_surface__enable; + + io_registers.a.VIEWPORT = 0 + | VIEWPORT__y2(191) + | VIEWPORT__x2(255) + | VIEWPORT__y1(0) + | VIEWPORT__x1(0); + int theta = 0; while (1) { struct sign_v cos = cos_table[theta]; @@ -540,6 +613,58 @@ void main() if (sin_theta >= 360) sin_theta -= 360; struct sign_v sin = cos_table[sin_theta]; + int _cos = cos.sign ? -cos.v : cos.v; + int _sin = sin.sign ? -sin.v : sin.v; + + { + int x = -222; + int y = -128; + int x1 = x * _cos + y * _sin; + int y1 = -x * _sin + y * _cos; + + io_registers.a.BEGIN_VTXS = BEGIN_VTXS__type__triangle; + io_registers.a.COLOR = (31 << 10); // blue + io_registers.a.VTX_10 = 0 + | VTX_10__z_coordinate(1 << 6) + | VTX_10__y_coordinate(y1 >> (3 + 8)) + | VTX_10__x_coordinate(x1 >> (3 + 8)) + ; + } + + { + int x = 222; + int y = -128; + int x1 = x * _cos + y * _sin; + int y1 = -x * _sin + y * _cos; + + io_registers.a.COLOR = (31 << 5); // green + io_registers.a.VTX_10 = 0 + | VTX_10__z_coordinate(1 << 6) + | VTX_10__y_coordinate(y1 >> (3 + 8)) + | VTX_10__x_coordinate(x1 >> (3 + 8)) + ; + } + + { + int x = 0 << 8; + int y = 1 << 8; + int x1 = x * _cos + y * _sin; + int y1 = -x * _sin + y * _cos; + + io_registers.a.COLOR = (31 << 0); // blue + io_registers.a.VTX_10 = 0 + | VTX_10__z_coordinate(1 << 6) + | VTX_10__y_coordinate(y1 >> (3 + 8)) + | VTX_10__x_coordinate(x1 >> (3 + 8)) + ; + } + + io_registers.a.END_VTXS = 0; + + io_registers.a.SWAP_BUFFERS = 0 + | SWAP_BUFFERS__depth_buffering__z_value + | SWAP_BUFFERS__translucent_polygon_y_sorting__auto_sort; + // dx oam.b.param[0].pa = cos.sign ? cos.v : -cos.v; diff --git a/registers/graphics_engine_bits.csv b/registers/graphics_engine_bits.csv index ef5964d..1844aa1 100644 --- a/registers/graphics_engine_bits.csv +++ b/registers/graphics_engine_bits.csv @@ -202,7 +202,7 @@ "VTX_XY",,"15-0","x_coordinate",,"0xffff", ,,,,,, "VTX_XZ",,"31-16","z_coordinate",,"0xffff", -"VTX_XZ",,"15-0","z_coordinate",,"0xffff", +"VTX_XZ",,"15-0","x_coordinate",,"0xffff", ,,,,,, "VTX_YZ",,"31-16","z_coordinate",,"0xffff", "VTX_YZ",,"15-0","y_coordinate",,"0xffff", @@ -348,17 +348,17 @@ "GXSTAT","command_fifo_interrupt_condition","31-30","disable","0b00",, "GXSTAT","command_fifo_interrupt_condition","31-30","half_full","0b01",, "GXSTAT","command_fifo_interrupt_condition","31-30","empty","0b10",, -"GXSTAT",,27,"geometry_engine_busy",,, -"GXSTAT","fifo_status",26,"empty",,, -"GXSTAT","fifo_status",25,"less_than_half_full",,, -"GXSTAT","fifo_status",24,"full",,, +"GXSTAT",,27,"geometry_engine_busy",1,, +"GXSTAT","fifo_status",26,"empty",1,, +"GXSTAT","fifo_status",25,"less_than_half_full",1,, +"GXSTAT","fifo_status",24,"full",1,, "GXSTAT",,"23-16","command_fifo_count",,, -"GXSTAT","matrix_stack_status",15,"stack_overflow_or_underflow",,, -"GXSTAT","matrix_stack_status",14,"stack_busy",,, -"GXSTAT","matrix_stack_status",13,"projection_matrix_stack_level",,, -"GXSTAT","matrix_stack_status","12-8","position_and_vector_matrix_stack_level",,, -"GXSTAT",,1,"test_status",,, -"GXSTAT",,0,"test_busy",,, +"GXSTAT","matrix_stack_status",15,"overflow_or_underflow",1,, +"GXSTAT","matrix_stack_status",14,"busy",1,, +"GXSTAT","matrix_stack_status",13,"projection_stack_level",,, +"GXSTAT","matrix_stack_status","12-8","position_and_vector_stack_level",,, +"GXSTAT",,1,"test_status",1,, +"GXSTAT",,0,"test_busy",1,, ,,,,,, "LISTRAM_COUNT",,"11-0","counter",,, ,,,,,, diff --git a/registers/graphics_engine_bits.ods b/registers/graphics_engine_bits.ods index 355208b9893fe264081fca358481301bb3a6af1d..fec6c1734776fd46b7bb165ab8e470d909b0b0fa 100644 GIT binary patch delta 9734 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 Hf0_Ren@xIC delta 9801 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