diff options
author | lonkaars <loek@pipeframe.xyz> | 2023-02-25 13:08:00 +0100 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2023-02-25 13:08:00 +0100 |
commit | 5850f4ab766256791f72301349e30d4cd304c675 (patch) | |
tree | ae72fb95eb7a028eb0a86fdc07340d97942f285a | |
parent | 1a2bd8b70c12d497acb2eba548d161b2bfc4f9b6 (diff) |
ppusim done
-rw-r--r-- | src/demo.c | 55 | ||||
-rw-r--r-- | src/demo.h | 44 | ||||
-rw-r--r-- | src/main.c | 94 | ||||
-rw-r--r-- | src/makefile | 3 | ||||
-rw-r--r-- | src/ppu/internals.c | 11 | ||||
-rw-r--r-- | src/ppu/internals.h | 2 | ||||
-rw-r--r-- | src/ppu/ppu.c | 2 | ||||
-rw-r--r-- | src/ppu/ppu.h | 2 | ||||
-rw-r--r-- | src/ppusim/mem.c | 2 | ||||
-rw-r--r-- | src/ppusim/pixel.c | 39 |
10 files changed, 147 insertions, 107 deletions
diff --git a/src/demo.c b/src/demo.c new file mode 100644 index 0000000..6248989 --- /dev/null +++ b/src/demo.c @@ -0,0 +1,55 @@ +#include <math.h> + +#include "demo.h" +#include "ppu/ppu.h" + +#define HH_DEMO_BALL_COUNT 5 +hh_s_ppu_loc_fam_entry g_hh_demo_balls[HH_DEMO_BALL_COUNT]; + +void hh_demo_setup() { + // load sprites + hh_ppu_update_sprite(0, HH_DBG_SPRITE_BALL); + hh_ppu_update_sprite(1, HH_DBG_SPRITE_CHECKERBOARD); + + // background pattern + hh_ppu_update_color(0, 1, (hh_ppu_rgb_color_t) {0x8, 0x8, 0x8}); + for (unsigned i = 0; i < HH_PPU_BG_CANVAS_TILES_H * HH_PPU_BG_CANVAS_TILES_V; i++) { + hh_ppu_update_background(i, (hh_s_ppu_loc_bam_entry) { + .horizontal_flip = false, + .vertical_flip = false, + .palette_index = 0, + .tilemap_index = 1, + }); + } + + // cool colors + hh_ppu_update_color(1, 1, (hh_ppu_rgb_color_t) {0xf, 0x0, 0xf}); + hh_ppu_update_color(2, 1, (hh_ppu_rgb_color_t) {0xf, 0xf, 0xf}); + hh_ppu_update_color(3, 1, (hh_ppu_rgb_color_t) {0xf, 0x0, 0x0}); + hh_ppu_update_color(4, 1, (hh_ppu_rgb_color_t) {0x0, 0xf, 0xf}); + hh_ppu_update_color(5, 1, (hh_ppu_rgb_color_t) {0x0, 0x0, 0xf}); + + // balls + for (unsigned i = 0; i < HH_DEMO_BALL_COUNT; i++) { + g_hh_demo_balls[i].horizontal_flip = false; + g_hh_demo_balls[i].vertical_flip = false; + g_hh_demo_balls[i].palette_index = i+1; + g_hh_demo_balls[i].tilemap_index = 0; + } +} + +void hh_demo_loop(unsigned long frame) { + // set background pattern position + hh_ppu_update_aux((hh_s_ppu_loc_aux) { + .bg_shift_x = (frame / 2) % HH_PPU_SPRITE_WIDTH, + .bg_shift_y = (frame / 8) % HH_PPU_SPRITE_HEIGHT, + .fg_fetch = 0, + .sysreset = 0, + }); + + for (unsigned i = 0; i < HH_DEMO_BALL_COUNT; i++) { + g_hh_demo_balls[i].position_x = HH_PPU_SCREEN_WIDTH/2 - HH_PPU_SPRITE_WIDTH/2 + (int)(60 * (double)sin((1*(double)frame + 6*(double)i) / 30)); + g_hh_demo_balls[i].position_y = HH_PPU_SCREEN_HEIGHT/2 - HH_PPU_SPRITE_HEIGHT/2 + (int)(30 * (double)sin((2*(double)frame + 6*(double)i) / 30)); + hh_ppu_update_foreground(i, g_hh_demo_balls[i]); + } +} diff --git a/src/demo.h b/src/demo.h new file mode 100644 index 0000000..89436b5 --- /dev/null +++ b/src/demo.h @@ -0,0 +1,44 @@ +#pragma once + +#include "ppu/types.h" + +void hh_demo_setup(); +void hh_demo_loop(unsigned long); + +static const hh_s_ppu_loc_sprite HH_DBG_SPRITE_BALL = { + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 +}; + +static const hh_s_ppu_loc_sprite HH_DBG_SPRITE_CHECKERBOARD = { + 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 +}; @@ -1,12 +1,8 @@ #include <stdlib.h> -#include <math.h> -#ifdef HH_TARGET_DESKTOP -#include <stdio.h> -#endif #include "main.h" #include "ppu/ppu.h" -#include "ppu/consts.h" +#include "demo.h" bool g_hh_run = true; @@ -21,97 +17,13 @@ void hh_ppu_vblank_interrupt() { static unsigned long frame = 0; frame++; -#ifdef HH_TARGET_DESKTOP - // printf("frame %lu\n", frame); -#endif - - unsigned shift = (double) sin((double) frame / 20) * 10 + 10; - hh_ppu_update_aux((hh_s_ppu_loc_aux) { - .bg_shift_x = shift, - .bg_shift_y = 0, - .fg_fetch = 0, - .sysreset = 0, - }); + hh_demo_loop(frame); } void hh_setup() { hh_ppu_init(); - hh_s_ppu_loc_sprite sprite = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 - }; - - for (int x = 0; x < HH_PPU_SPRITE_WIDTH; x++) { - for (int y = 0; y < HH_PPU_SPRITE_HEIGHT; y++) { - // sprite[y * HH_PPU_SPRITE_WIDTH + x] = (pow(x - 8, 2) + pow(y - 8, 2) < 64) ? 1 : 0; - uint8_t p = sprite[y * HH_PPU_SPRITE_WIDTH + x]; - printf("%c%c%c", p ? 'X' : ' ', p ? 'X' : ' ', p ? 'X' : ' '); - } - printf("\n"); - } - - hh_ppu_update_sprite(0, sprite); - - // hh_ppu_update_foreground(0, (hh_s_ppu_loc_fam_entry) { - // .horizontal_flip = false, - // .vertical_flip = false, - // .palette_index = 1, - // .tilemap_index = 0, - // .position_x = 30, - // .position_y = 40, - // }); - - hh_ppu_update_background(3, (hh_s_ppu_loc_bam_entry) { - .horizontal_flip = false, - .vertical_flip = false, - .palette_index = 1, - .tilemap_index = 0, - }); - hh_ppu_update_background(4, (hh_s_ppu_loc_bam_entry) { - .horizontal_flip = true, - .vertical_flip = false, - .palette_index = 2, - .tilemap_index = 0, - }); - hh_ppu_update_background(5, (hh_s_ppu_loc_bam_entry) { - .horizontal_flip = false, - .vertical_flip = false, - .palette_index = 3, - .tilemap_index = 0, - }); - hh_ppu_update_background(6, (hh_s_ppu_loc_bam_entry) { - .horizontal_flip = false, - .vertical_flip = true, - .palette_index = 4, - .tilemap_index = 0, - }); - hh_ppu_update_background(7, (hh_s_ppu_loc_bam_entry) { - .horizontal_flip = true, - .vertical_flip = true, - .palette_index = 5, - .tilemap_index = 0, - }); - - hh_ppu_update_color(1, 1, (hh_ppu_rgb_color_t) {0xf, 0x0, 0xf}); - hh_ppu_update_color(2, 1, (hh_ppu_rgb_color_t) {0xf, 0xf, 0xf}); - hh_ppu_update_color(3, 1, (hh_ppu_rgb_color_t) {0xf, 0x0, 0x0}); - hh_ppu_update_color(4, 1, (hh_ppu_rgb_color_t) {0x0, 0xf, 0xf}); - hh_ppu_update_color(5, 1, (hh_ppu_rgb_color_t) {0x0, 0x0, 0xf}); + hh_demo_setup(); } void hh_exit() { diff --git a/src/makefile b/src/makefile index 41311eb..83c7df5 100644 --- a/src/makefile +++ b/src/makefile @@ -28,7 +28,8 @@ CFLAGS += $(if $(DESKTOP), -DHH_TARGET_DESKTOP, ) LOCAL_SRCS += main.c \ ppu/internals.c \ - ppu/ppu.c + ppu/ppu.c \ + demo.c CFLAGS += $(SHARED_FLAGS) LFLAGS += $(SHARED_FLAGS) diff --git a/src/ppu/internals.c b/src/ppu/internals.c index 7826ece..e4817f1 100644 --- a/src/ppu/internals.c +++ b/src/ppu/internals.c @@ -4,8 +4,9 @@ #include "ppu/internals.h" bool hh_ppu_vram_valid_address(hh_ppu_addr_t addr) { + #warning unimlemented (void) addr; // compiler bruh - return true; // TODO + return true; } void hh_ppu_vram_write(hh_s_ppu_vram_data data) { @@ -36,7 +37,7 @@ hh_s_ppu_vram_data hh_ppu_2nat_fam(hh_s_ppu_loc_fam_entry e) { data[0] = HH_RESIZE(e.tilemap_index, 9, 0) << 0 | HH_RESIZE(e.palette_index, 2, 0) << 10 | HH_RESIZE(e.position_y, 2, 0) << 13; - data[1] = HH_RESIZE(e.position_y, 4, 0) << 0 | + data[1] = HH_RESIZE(e.position_y, 7, 3) << 0 | HH_RESIZE(e.position_x, 8, 0) << 5 | e.vertical_flip << 14 | e.horizontal_flip << 15; @@ -64,7 +65,7 @@ hh_s_ppu_vram_data hh_ppu_2nat_aux(hh_s_ppu_loc_aux aux) { return out; } -hh_s_ppu_vram_data hh_ppu_2nat_sprite(hh_ppu_loc_sprite_data_t sprite_data) { +hh_s_ppu_vram_data hh_ppu_2nat_sprite(const hh_ppu_loc_sprite_data_t sprite_data) { hh_ppu_data_t* data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_TMM_SPRITE_SIZE); for (unsigned i = 0; i < HH_PPU_SPRITE_WIDTH * HH_PPU_SPRITE_HEIGHT; i++) { @@ -84,9 +85,9 @@ hh_s_ppu_vram_data hh_ppu_2nat_sprite(hh_ppu_loc_sprite_data_t sprite_data) { hh_s_ppu_vram_data hh_ppu_2nat_color(hh_ppu_rgb_color_t rgb) { hh_ppu_data_t* data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_PAL_ENTRY_SIZE); - data[0] = HH_RESIZE(rgb[0], 3, 0) << 0 | + data[0] = HH_RESIZE(rgb[0], 3, 0) << 8 | HH_RESIZE(rgb[1], 3, 0) << 4 | - HH_RESIZE(rgb[2], 3, 0) << 8; + HH_RESIZE(rgb[2], 3, 0) << 0; hh_s_ppu_vram_data out = { .data = data, diff --git a/src/ppu/internals.h b/src/ppu/internals.h index 6e9dda7..8f50c52 100644 --- a/src/ppu/internals.h +++ b/src/ppu/internals.h @@ -25,6 +25,6 @@ void hh_ppu_vram_write(hh_s_ppu_vram_data data); hh_s_ppu_vram_data hh_ppu_2nat_bam(hh_s_ppu_loc_bam_entry); hh_s_ppu_vram_data hh_ppu_2nat_fam(hh_s_ppu_loc_fam_entry); hh_s_ppu_vram_data hh_ppu_2nat_aux(hh_s_ppu_loc_aux); -hh_s_ppu_vram_data hh_ppu_2nat_sprite(hh_ppu_loc_sprite_data_t); +hh_s_ppu_vram_data hh_ppu_2nat_sprite(const hh_ppu_loc_sprite_data_t); hh_s_ppu_vram_data hh_ppu_2nat_color(hh_ppu_rgb_color_t); diff --git a/src/ppu/ppu.c b/src/ppu/ppu.c index e2fccb9..5f33c55 100644 --- a/src/ppu/ppu.c +++ b/src/ppu/ppu.c @@ -18,7 +18,7 @@ void hh_ppu_update_background(unsigned index, hh_s_ppu_loc_bam_entry e) { free(s.data); } -void hh_ppu_update_sprite(unsigned tilemap_index, hh_s_ppu_loc_sprite sprite) { +void hh_ppu_update_sprite(unsigned tilemap_index, const hh_s_ppu_loc_sprite sprite) { hh_s_ppu_vram_data s = hh_ppu_2nat_sprite(sprite); s.offset = HH_PPU_VRAM_TMM_OFFSET + HH_PPU_VRAM_TMM_SPRITE_SIZE * tilemap_index; hh_ppu_vram_write(s); diff --git a/src/ppu/ppu.h b/src/ppu/ppu.h index 90f964e..cab0e30 100644 --- a/src/ppu/ppu.h +++ b/src/ppu/ppu.h @@ -13,7 +13,7 @@ void hh_ppu_update_background(unsigned index, hh_s_ppu_loc_bam_entry e); /* @brief update aux register */ void hh_ppu_update_aux(hh_s_ppu_loc_aux aux); /* @brief update single sprite */ -void hh_ppu_update_sprite(unsigned tilemap_index, hh_s_ppu_loc_sprite sprite); +void hh_ppu_update_sprite(unsigned tilemap_index, const hh_s_ppu_loc_sprite sprite); /* @brief update entire palette table */ void hh_ppu_update_palette_table(hh_ppu_loc_palette_table_t table); /* @brief update single palette */ diff --git a/src/ppusim/mem.c b/src/ppusim/mem.c index 72e01c5..e3f41f5 100644 --- a/src/ppusim/mem.c +++ b/src/ppusim/mem.c @@ -8,6 +8,6 @@ hh_ppu_data_t *g_hh_ppusim_vram = NULL; void hh_ppu_vram_dwrite(hh_ppu_addr_t addr, hh_ppu_data_t data) { if (!hh_ppu_vram_valid_address(addr)) return; - printf("ppu[0x%04x] = %04x\n", addr, data); + // printf("ppu[0x%04x] = %04x\n", addr, data); g_hh_ppusim_vram[addr] = data; } diff --git a/src/ppusim/pixel.c b/src/ppusim/pixel.c index 96ee998..2163c10 100644 --- a/src/ppusim/pixel.c +++ b/src/ppusim/pixel.c @@ -39,7 +39,7 @@ static uint8_t hh_ppusim_bg_pixel(unsigned x, unsigned y) { uint8_t cidx = 0; uint16_t tile_pixel_idx = hh_ppusim_apply_transform(loc_x, loc_y, HH_RESIZE(bam, 14, 14), HH_RESIZE(bam, 13, 13)); uint16_t tile_idx = HH_RESIZE(bam, 9, 0); - hh_ppu_addr_t ttm_addr = tile_idx + tile_pixel_idx / 5; + hh_ppu_addr_t ttm_addr = tile_idx * HH_PPU_VRAM_TMM_SPRITE_SIZE + tile_pixel_idx / 5; uint8_t word_bit_addr = (tile_pixel_idx % 5) * 3; hh_ppu_data_t tmm = g_hh_ppusim_vram[HH_PPU_VRAM_TMM_OFFSET + ttm_addr]; cidx |= HH_RESIZE(bam, 12, 10) << 3; @@ -47,13 +47,40 @@ static uint8_t hh_ppusim_bg_pixel(unsigned x, unsigned y) { return cidx; } +/* @brief get current fg pixel cidx */ +static uint8_t hh_ppusim_fg_pixel(unsigned x, unsigned y) { + x += 16; + y += 16; + uint8_t cidx = 0; + for (unsigned i = 0; i < HH_PPU_FG_SPRITE_COUNT; i++) { + unsigned fam_offset = i * HH_PPU_VRAM_FAM_ENTRY_SIZE; + hh_ppu_data_t* fam = &g_hh_ppusim_vram[HH_PPU_VRAM_FAM_OFFSET + fam_offset]; + unsigned sprite_y = HH_RESIZE(fam[0], 15, 13) | HH_RESIZE(fam[1], 4, 0) << 3; + unsigned sprite_x = HH_RESIZE(fam[1], 13, 5); + if (x < sprite_x) continue; + if (x >= sprite_x + HH_PPU_SPRITE_WIDTH) continue; + if (y < sprite_y) continue; + if (y >= sprite_y + HH_PPU_SPRITE_HEIGHT) continue; + unsigned loc_x = x - sprite_x; + unsigned loc_y = y - sprite_y; + uint16_t tile_pixel_idx = hh_ppusim_apply_transform(loc_x, loc_y, HH_RESIZE(fam[1], 15, 15), HH_RESIZE(fam[1], 14, 14)); + uint16_t tile_idx = HH_RESIZE(fam[0], 9, 0); + hh_ppu_addr_t ttm_addr = tile_idx * HH_PPU_VRAM_TMM_SPRITE_SIZE + tile_pixel_idx / 5; + uint8_t word_bit_addr = (tile_pixel_idx % 5) * 3; + hh_ppu_data_t tmm = g_hh_ppusim_vram[HH_PPU_VRAM_TMM_OFFSET + ttm_addr]; + unsigned cidx_col = HH_RESIZE(tmm, word_bit_addr+2, word_bit_addr); + if (cidx_col == 0) continue; + unsigned cidx_pal = HH_RESIZE(fam[0], 12, 10); + cidx = (cidx_col << 0) | (cidx_pal << 3); + break; + } + return cidx; +} + void hh_ppusim_pixel(SDL_Renderer* r, unsigned x, unsigned y) { - // loop through foreground sprites to get highest priority cidx uint8_t bg_cidx = hh_ppusim_bg_pixel(x, y); - // check if palette color cidx of foreground is 0 - // lookup color from PAL - // hh_ppusim_draw - uint8_t cidx = bg_cidx; + uint8_t fg_cidx = hh_ppusim_fg_pixel(x, y); + uint8_t cidx = (fg_cidx & HH_MASK(3)) == 0 ? bg_cidx : fg_cidx; hh_ppu_data_t pal_rgb = g_hh_ppusim_vram[HH_PPU_VRAM_PAL_OFFSET + cidx]; hh_ppu_rgb_color_t rgb = { HH_RESIZE(pal_rgb, 11, 8), |