aboutsummaryrefslogtreecommitdiff
path: root/src/ppu/internals.c
blob: 650ba3e63fb790eb2665826d09fadff5aa612f8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <stdlib.h>

#include "ppu/types.h"
#include "ppu/internals.h"
#include "ppu/consts.h"

bool hh_ppu_vram_valid_address(hh_ppu_addr_t addr) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
	if ((addr >= HH_PPU_VRAM_TMM_OFFSET) && (addr < (HH_PPU_VRAM_TMM_OFFSET + HH_PPU_VRAM_TMM_SIZE))) return true;
	if ((addr >= HH_PPU_VRAM_BAM_OFFSET) && (addr < (HH_PPU_VRAM_BAM_OFFSET + HH_PPU_VRAM_BAM_SIZE))) return true;
	if ((addr >= HH_PPU_VRAM_FAM_OFFSET) && (addr < (HH_PPU_VRAM_FAM_OFFSET + HH_PPU_VRAM_FAM_SIZE))) return true;
	if ((addr >= HH_PPU_VRAM_PAL_OFFSET) && (addr < (HH_PPU_VRAM_PAL_OFFSET + HH_PPU_VRAM_PAL_SIZE))) return true;
	if ((addr >= HH_PPU_VRAM_AUX_OFFSET) && (addr < (HH_PPU_VRAM_AUX_OFFSET + HH_PPU_VRAM_AUX_SIZE))) return true;
#pragma GCC diagnostic pop
	return false;
}

void hh_ppu_vram_write(hh_s_ppu_vram_data data) {
	for (unsigned i = 0; i < data.size; i++)
		hh_ppu_vram_dwrite(data.offset + i, data.data[i]);
}

hh_s_ppu_vram_data hh_ppu_2nat_bam(hh_s_ppu_loc_bam_entry e) {
	hh_ppu_data_t* data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_BAM_ENTRY_SIZE);

	data[0] = HH_RESIZE(e.tilemap_index, 9, 0) << 0 |
	          HH_RESIZE(e.palette_index, 2, 0) << 10 |
	          e.vertical_flip << 13 |
	          e.horizontal_flip << 14;

	hh_s_ppu_vram_data out = {
		.data = data,
		.size = HH_PPU_VRAM_FAM_ENTRY_SIZE
	};
	return out;
}

hh_s_ppu_vram_data hh_ppu_2nat_fam(hh_s_ppu_loc_fam_entry e) {
	hh_ppu_data_t* data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_FAM_ENTRY_SIZE);

	e.position_x += 16;
	e.position_y += 16;
	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, 7, 3) << 0 |
	          HH_RESIZE(e.position_x, 8, 0) << 5 |
	          e.vertical_flip << 14 |
	          e.horizontal_flip << 15;

	hh_s_ppu_vram_data out = {
		.data = data,
		.size = HH_PPU_VRAM_FAM_ENTRY_SIZE
	};
	return out;
}

hh_s_ppu_vram_data hh_ppu_2nat_aux(hh_s_ppu_loc_aux aux) {
	hh_ppu_data_t* data = malloc(sizeof(hh_ppu_data_t) * HH_PPU_VRAM_AUX_SIZE);

	data[0] = HH_RESIZE(aux.bg_shift_y, 7, 0) << 0 |
	          HH_RESIZE(aux.bg_shift_x, 7, 0) << 8;
	data[1] = HH_RESIZE(aux.bg_shift_x, 8, 8) << 0 |
	          aux.fg_fetch << 1 |
	          aux.sysreset << 2;

	hh_s_ppu_vram_data out = {
		.data = data,
		.size = HH_PPU_VRAM_AUX_SIZE
	};
	return out;
}

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++) {
		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 = {
		.data = data,
		.size = HH_PPU_VRAM_TMM_SPRITE_SIZE
	};
	return out;
}

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) << 8 |
	          HH_RESIZE(rgb[1], 3, 0) << 4 |
	          HH_RESIZE(rgb[2], 3, 0) << 0;

	hh_s_ppu_vram_data out = {
		.data = data,
		.size = HH_PPU_VRAM_PAL_ENTRY_SIZE
	};
	return out;
}