summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-04-18 14:21:50 +0200
committerBad Diode <bd@badd10de.dev>2021-04-18 14:21:50 +0200
commit344d070dfbfe4bbde93708a0c14436b57f487007 (patch)
tree56340358fd31a6e56c92b50fe73f82582ed9332d
parent6a736dbcf0f34b04d3a950a38fbb539a7807d2d8 (diff)
downloadgba-experiments-344d070dfbfe4bbde93708a0c14436b57f487007.tar.gz
gba-experiments-344d070dfbfe4bbde93708a0c14436b57f487007.zip
Add initial sprite tests
-rw-r--r--src/main.c191
1 files changed, 129 insertions, 62 deletions
diff --git a/src/main.c b/src/main.c
index b09d54f..07c809e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,23 +25,29 @@
25#define DISP_STATUS *((vu32*)(MEM_IO + 0x0004)) 25#define DISP_STATUS *((vu32*)(MEM_IO + 0x0004))
26#define DISP_VCOUNT *((vu32*)(MEM_IO + 0x0006)) 26#define DISP_VCOUNT *((vu32*)(MEM_IO + 0x0006))
27 27
28// Bits for display control. 28// The first three bits in the DISP_CTRL are used to control the video mode.
29#define DISP_CTRL_PAGE (1 << 4) 29#define DISP_MODE_0 0x0000
30 30#define DISP_MODE_1 0x0001
31// Display modes. 31#define DISP_MODE_2 0x0002
32#define DISP_MODE_0 0x0000 32#define DISP_MODE_3 0x0003
33#define DISP_MODE_1 0x0001 33#define DISP_MODE_4 0x0004
34#define DISP_MODE_2 0x0002 34#define DISP_MODE_5 0x0005
35#define DISP_MODE_3 0x0003 35#define DISP_GB (1 << 3)
36#define DISP_MODE_4 0x0004 36#define DISP_PAGE (1 << 4)
37#define DISP_MODE_5 0x0005 37#define DISP_OAM_HBLANK (1 << 5)
38 38#define DISP_OBJ_1D (1 << 6)
39// Layers. 39#define DISP_BLANK (1 << 7)
40#define DISP_BG_0 0x0100 40#define DISP_BG_0 (1 << 8)
41#define DISP_BG_1 0x0200 41#define DISP_BG_1 (1 << 9)
42#define DISP_BG_2 0x0400 42#define DISP_BG_2 (1 << 10)
43#define DISP_BG_3 0x0800 43#define DISP_BG_3 (1 << 11)
44#define DISP_OBJ 0x1000 44#define DISP_OBJ (1 << 12)
45
46// Registers to control of BG layers.
47#define BG_CTRL_0 *((vu16*)(0x04000008 + 0x0000))
48#define BG_CTRL_1 *((vu16*)(0x04000008 + 0x0002))
49#define BG_CTRL_2 *((vu16*)(0x04000008 + 0x0004))
50#define BG_CTRL_3 *((vu16*)(0x04000008 + 0x0006))
45 51
46// Screen settings. 52// Screen settings.
47#define SCREEN_WIDTH 240 53#define SCREEN_WIDTH 240
@@ -51,6 +57,19 @@
51// (RGB) have a 0--31 range. For example, pure red would be rgb15(31, 0, 0). 57// (RGB) have a 0--31 range. For example, pure red would be rgb15(31, 0, 0).
52typedef u16 Color; 58typedef u16 Color;
53 59
60//
61// Tile memory access.
62//
63
64// NOTE: Only defining 4bpp tiles for now.
65typedef struct Tile {
66 u32 data[8];
67} Tile;
68
69typedef Tile TileBlock[512];
70
71#define TILE_MEM ((TileBlock*) MEM_VRAM)
72
54// We can treat the screen as a HxW matrix. With the following macro we can 73// We can treat the screen as a HxW matrix. With the following macro we can
55// write a pixel to the screen at the (x, y) position using: 74// write a pixel to the screen at the (x, y) position using:
56// 75//
@@ -59,7 +78,8 @@ typedef u16 Color;
59typedef Color Scanline[SCREEN_WIDTH]; 78typedef Color Scanline[SCREEN_WIDTH];
60#define FRAMEBUFFER ((Scanline*)MEM_VRAM) 79#define FRAMEBUFFER ((Scanline*)MEM_VRAM)
61#define SCREEN_BUFFER ((vu16*) MEM_VRAM) 80#define SCREEN_BUFFER ((vu16*) MEM_VRAM)
62#define PAL_BUFFER ((vu16*) MEM_PAL) 81#define PAL_BUFFER_BG ((vu16*) MEM_PAL)
82#define PAL_BUFFER_SPRITES ((vu16*) 0x05000200)
63 83
64// 84//
65// Colors. 85// Colors.
@@ -271,7 +291,7 @@ draw_fill_rect_m4(int x0, int y0, int x1, int y1, u8 col_index, vu16 *buffer) {
271 291
272static inline void 292static inline void
273flip_page() { 293flip_page() {
274 DISP_CTRL ^= DISP_CTRL_PAGE; 294 DISP_CTRL ^= DISP_PAGE;
275} 295}
276 296
277#define SCREEN_PAGE_1 ((vu16*) MEM_VRAM) 297#define SCREEN_PAGE_1 ((vu16*) MEM_VRAM)
@@ -367,33 +387,8 @@ key_hold(u32 key) {
367// Check if the given key/button is currently pressed. 387// Check if the given key/button is currently pressed.
368#define KEY_PRESSED(key) (~(KEY_INPUTS) & key) 388#define KEY_PRESSED(key) (~(KEY_INPUTS) & key)
369 389
370int main(void) { 390void
371 DISP_CTRL = DISP_MODE_3 | DISP_BG_2; 391draw_logo() {
372
373 // Test setting OBJ parameters for sprite N with my custom macros.
374 OBJ_ATTR_0(0) = 0xBADD;
375 OBJ_ATTR_1(0) = 0x10DE;
376 OBJ_ATTR_2(0) = 0xAC1D;
377 OBJ_ATTR_0(1) = 0xFA7E;
378 OBJ_ATTR_1(1) = 0xD15E;
379 OBJ_ATTR_2(1) = 0xA5ED;
380 OBJ_ATTR_0(2) = 0xBADD;
381 OBJ_ATTR_1(2) = 0x10DE;
382 OBJ_ATTR_2(2) = 0xAC1D;
383 OBJ_ATTR_0(3) = 0xFA7E;
384 OBJ_ATTR_1(3) = 0xD15E;
385 OBJ_ATTR_2(3) = 0xA5ED;
386 OBJ_AFFINE_PA(0) = 0x0011;
387 OBJ_AFFINE_PB(0) = 0x2233;
388 OBJ_AFFINE_PC(0) = 0x4455;
389 OBJ_AFFINE_PD(0) = 0x6677;
390 OBJ_AFFINE_PA(1) = 0xAABB;
391 OBJ_AFFINE_PB(1) = 0xCCDD;
392 OBJ_AFFINE_PC(1) = 0xEEFF;
393 OBJ_AFFINE_PD(1) = 0x0101;
394
395 // draw_fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_GREY);
396
397 int side = 60; 392 int side = 60;
398 int line = 35; 393 int line = 35;
399 int height = side * 0.5; 394 int height = side * 0.5;
@@ -425,31 +420,103 @@ int main(void) {
425 draw_line(x + height, y, x + height + line, y, COLOR_WHITE); 420 draw_line(x + height, y, x + height + line, y, COLOR_WHITE);
426 draw_line(x - line, y + 1, x, y + 1, COLOR_WHITE); 421 draw_line(x - line, y + 1, x, y + 1, COLOR_WHITE);
427 draw_line(x + height, y + 1, x + height + line, y + 1, COLOR_WHITE); 422 draw_line(x + height, y + 1, x + height + line, y + 1, COLOR_WHITE);
423}
424
425int main(void) {
426 // Configure the display in mode 0 to show OBJs, where tile memory is
427 // sequential.
428 DISP_CTRL = DISP_MODE_0 | DISP_OBJ | DISP_OBJ_1D;
429
430 // Create two 4bpp tiles, one filled with color 1 and another with color 2.
431 Tile *tile_mem = &TILE_MEM[4][0];
432 for (size_t i = 0; i < 8; ++i) {
433 tile_mem->data[i] = 0x11111111;
434 }
435 for (size_t i = 8; i < 16; ++i) {
436 tile_mem->data[i] = 0x22222222;
437 }
438
439 // Add colors to the sprite color palette. Tiles with color number 0 are
440 // treated as transparent.
441 PAL_BUFFER_SPRITES[1] = COLOR_WHITE;
442 PAL_BUFFER_SPRITES[2] = COLOR_RED;
443 PAL_BUFFER_SPRITES[3] = COLOR_CYAN;
444 PAL_BUFFER_SPRITES[4] = COLOR_GREY;
445 PAL_BUFFER_SPRITES[5] = COLOR_BLACK;
446 PAL_BUFFER_SPRITES[15] = COLOR_RED;
447
448 int x_a = 100;
449 int y_a = 100;
450 int tile_id_a = 0;
451 int x_b = 50;
452 int y_b = 50;
453 int tile_id_b = 1;
454
455 OBJ_ATTR_0(0) = y_a;
456 OBJ_ATTR_1(0) = x_a;
457 OBJ_ATTR_2(0) = tile_id_a;
458
459 OBJ_ATTR_0(1) = y_b;
460 OBJ_ATTR_1(1) = x_b;
461 OBJ_ATTR_2(1) = tile_id_b;
462
463 // for (size_t i = 0; i < 16; ++i) {
464 // PAL_BUFFER_SPRITES[i] = COLOR_RED;
465 // }
466 // PAL_BUFFER_SPRITES[0] = COLOR_RED;
467 // PAL_BUFFER_BG[0] = COLOR_WHITE;
468
469 // for (size_t i = 0; i < sizeof(tile_mem->data); ++i) {
470 // tile_mem->data[i] = COLOR_WHITE;
471 // }
472
428 int frame_counter = 0; 473 int frame_counter = 0;
429 bool toggle_key_down = false; 474 int active_sprite = 0;
430 while(true) { 475 while(true) {
431 wait_vsync(); 476 wait_vsync();
432 if (frame_counter++ > 30) {
433 frame_counter = 0;
434 }
435 poll_keys(); 477 poll_keys();
436 478
437 // Toggle frame counter when we press down. 479 // Toggle frame counter when we press down.
438 if (key_pressed(KEY_DOWN)) { 480 if (key_pressed(KEY_DOWN) || key_hold(KEY_DOWN)) {
439 toggle_key_down ^= 1; 481 if (active_sprite == 0) {
482 y_a += 3;
483 } else {
484 y_b += 3;
485 }
440 } 486 }
441 if (toggle_key_down) { 487 if (key_pressed(KEY_UP) || key_hold(KEY_UP)) {
442 put_text(8, 8, COLOR_GREY, "TOGGLE: OFF"); 488 if (active_sprite == 0) {
443 put_text(8, 8, COLOR_RED, "TOGGLE: ON"); 489 y_a -= 3;
444 } else { 490 } else {
445 put_text(8, 8, COLOR_GREY, "TOGGLE: ON"); 491 y_b -= 3;
446 put_text(8, 8, COLOR_RED, "TOGGLE: OFF"); 492 }
493 }
494 if (key_pressed(KEY_LEFT) || key_hold(KEY_LEFT)) {
495 if (active_sprite == 0) {
496 x_a -= 3;
497 } else {
498 x_b -= 3;
499 }
447 } 500 }
448 if (key_hold(KEY_DOWN)) { 501 if (key_pressed(KEY_RIGHT) || key_hold(KEY_RIGHT)) {
449 put_text(8, 24, COLOR_RED, "HOLDING"); 502 if (active_sprite == 0) {
450 } else { 503 x_a += 3;
451 put_text(8, 24, COLOR_GREY, "HOLDING"); 504 } else {
505 x_b += 3;
506 }
452 } 507 }
508 if (key_pressed(KEY_B)) {
509 if (active_sprite == 0) {
510 active_sprite = 1;
511 } else {
512 active_sprite = 0;
513 }
514 }
515
516 OBJ_ATTR_0(0) = y_a & 0xFF;
517 OBJ_ATTR_1(0) = x_a & 0xFF;
518 OBJ_ATTR_0(1) = y_b & 0xFF;
519 OBJ_ATTR_1(1) = x_b & 0xFF;
453 }; 520 };
454 521
455 return 0; 522 return 0;