diff options
| author | lonkaars <loek@pipeframe.xyz> | 2023-02-24 22:24:50 +0100 | 
|---|---|---|
| committer | lonkaars <loek@pipeframe.xyz> | 2023-02-24 22:24:50 +0100 | 
| commit | 1a2bd8b70c12d497acb2eba548d161b2bfc4f9b6 (patch) | |
| tree | 593cddcc473aad7a5e55f870893d813f17651a85 /src | |
| parent | 97dd5f6bd354c8e931778c79c7a421d5bdaafee5 (diff) | |
background sprites working in ppusim
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 88 | ||||
| -rw-r--r-- | src/ppu/internals.c | 17 | ||||
| -rw-r--r-- | src/ppu/internals.h | 5 | ||||
| -rw-r--r-- | src/ppusim/pixel.c | 45 | 
4 files changed, 127 insertions, 28 deletions
@@ -24,36 +24,94 @@ void hh_ppu_vblank_interrupt() {  #ifdef HH_TARGET_DESKTOP  	// printf("frame %lu\n", frame);  #endif -} - -void hh_setup() { -	hh_ppu_init(); +	unsigned shift = (double) sin((double) frame / 20) * 10 + 10;  	hh_ppu_update_aux((hh_s_ppu_loc_aux) { -		.bg_shift_x = 24, +		.bg_shift_x = shift,  		.bg_shift_y = 0, -		.fg_fetch = 1, -		.sysreset = 1, +		.fg_fetch = 0, +		.sysreset = 0,  	}); +} -	hh_s_ppu_loc_sprite sprite = {0}; +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) < 67) ? 1 : 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) { +	// 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, -		.position_x = 30, -		.position_y = 40 +	}); +	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) {15, 0, 15}); +	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});  }  void hh_exit() { diff --git a/src/ppu/internals.c b/src/ppu/internals.c index 5b47b75..7826ece 100644 --- a/src/ppu/internals.c +++ b/src/ppu/internals.c @@ -3,11 +3,6 @@  #include "ppu/types.h"  #include "ppu/internals.h" -/** @brief generate bitmask with `n` bits set to one from LSB */ -#define HH_MASK(n) ((1 << (n))-1) -/** @brief resize `in` to `upper downto lower` like in vhdl */ -#define HH_RESIZE(in, upper, lower) ((((hh_ppu_data_t)(in)) & HH_MASK(upper+1-lower)) >> lower) -  bool hh_ppu_vram_valid_address(hh_ppu_addr_t addr) {  	(void) addr; // compiler bruh  	return true; // TODO @@ -72,13 +67,11 @@ hh_s_ppu_vram_data hh_ppu_2nat_aux(hh_s_ppu_loc_aux aux) {  hh_s_ppu_vram_data hh_ppu_2nat_sprite(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 x = 0; x < HH_PPU_SPRITE_WIDTH; x++) { -		for (unsigned y = 0; y < HH_PPU_SPRITE_HEIGHT; y++) { -			unsigned i = y * HH_PPU_SPRITE_WIDTH + x; -			unsigned word = i / 5; -			unsigned pixel = i % 5; -			data[word] |= HH_RESIZE(sprite_data[i], 2, 0) << pixel * 3; -		} +	for (unsigned i = 0; i < HH_PPU_SPRITE_WIDTH * HH_PPU_SPRITE_HEIGHT; i++) { +		unsigned word = i / 5; +		unsigned pixel = i % 5; +		if (pixel == 0) data[word] = 0; +		data[word] |= HH_RESIZE(sprite_data[i], 2, 0) << pixel * 3;  	}  	hh_s_ppu_vram_data out = { diff --git a/src/ppu/internals.h b/src/ppu/internals.h index 7b60255..6e9dda7 100644 --- a/src/ppu/internals.h +++ b/src/ppu/internals.h @@ -4,6 +4,11 @@  #include "ppu/types.h" +/** @brief generate bitmask with `n` bits set to one from LSB */ +#define HH_MASK(n) ((1 << (n))-1) +/** @brief resize `in` to `upper downto lower` like in vhdl */ +#define HH_RESIZE(in, upper, lower) ((((hh_ppu_data_t)(in)) & (HH_MASK(upper+1-lower) << lower)) >> lower) +  typedef struct {  	hh_ppu_addr_t offset;  	hh_ppu_addr_t size; diff --git a/src/ppusim/pixel.c b/src/ppusim/pixel.c index 3a09ccd..96ee998 100644 --- a/src/ppusim/pixel.c +++ b/src/ppusim/pixel.c @@ -1,6 +1,10 @@  #include <SDL2/SDL.h> +#include <stdbool.h> +#include "ppu/internals.h" +#include "ppusim/mem.h"  #include "ppusim/sim.h" +#include "ppu/consts.h"  static void hh_ppusim_draw(SDL_Renderer* r, unsigned px, unsigned py, unsigned cr, unsigned cg, unsigned cb) {  	SDL_SetRenderDrawColor(r, cr, cg, cb, 255); @@ -12,11 +16,50 @@ static void hh_ppusim_draw(SDL_Renderer* r, unsigned px, unsigned py, unsigned c  	});  } +/* transform xy if tile is flipped */ +static uint16_t hh_ppusim_apply_transform(unsigned x, unsigned y, bool fliph, bool flipv) { +	unsigned tx = fliph ? HH_PPU_SPRITE_WIDTH - x - 1 : x; +	unsigned ty = flipv ? HH_PPU_SPRITE_HEIGHT - y - 1 : y; +	return ty * HH_PPU_SPRITE_WIDTH + tx; +} + +/* @brief get current bg pixel cidx */ +static uint8_t hh_ppusim_bg_pixel(unsigned x, unsigned y) { +	hh_ppu_data_t* aux = &g_hh_ppusim_vram[HH_PPU_VRAM_AUX_OFFSET]; +	unsigned bg_shift_y = HH_RESIZE(aux[0], 7, 0); +	unsigned bg_shift_x = HH_RESIZE(aux[0], 15, 8) | HH_RESIZE(aux[1], 0, 0) << 8; +	unsigned abs_x = bg_shift_x + x; +	unsigned abs_y = bg_shift_y + y; +	unsigned grid_x = abs_x / HH_PPU_SPRITE_WIDTH; +	unsigned grid_y = abs_y / HH_PPU_SPRITE_HEIGHT; +	unsigned loc_x = abs_x - grid_x * HH_PPU_SPRITE_WIDTH; +	unsigned loc_y = abs_y - grid_y * HH_PPU_SPRITE_HEIGHT; +	unsigned bam_offset = grid_y * HH_PPU_BG_CANVAS_TILES_H + grid_x; +	hh_ppu_data_t bam = g_hh_ppusim_vram[HH_PPU_VRAM_BAM_OFFSET + bam_offset]; +	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; +	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; +	cidx |= HH_RESIZE(tmm, word_bit_addr+2, word_bit_addr) << 0; +	return cidx; +} +  void hh_ppusim_pixel(SDL_Renderer* r, unsigned x, unsigned y) {  	// loop through foreground sprites to get highest priority cidx -	// get background 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; +	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), +		HH_RESIZE(pal_rgb, 7, 4), +		HH_RESIZE(pal_rgb, 3, 0) +	}; +	hh_ppusim_draw(r, x, y, rgb[0] << 4, rgb[1] << 4, rgb[2] << 4);  }  |