aboutsummaryrefslogtreecommitdiffstats
path: root/src/uxn/devices/ppu.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-19 16:29:20 +0200
committerBad Diode <bd@badd10de.dev>2021-05-19 16:29:20 +0200
commit9911609e8fff312c406e3407a519b39db79bdb97 (patch)
treebbef38c5eaac06e6658ec93c2e07c571166a836d /src/uxn/devices/ppu.c
parent60684bb15f5c68eb8248673da48cc4469537ffc9 (diff)
downloaduxngba-9911609e8fff312c406e3407a519b39db79bdb97.tar.gz
uxngba-9911609e8fff312c406e3407a519b39db79bdb97.zip
Implement double buffering drawing
Diffstat (limited to 'src/uxn/devices/ppu.c')
-rw-r--r--src/uxn/devices/ppu.c70
1 files changed, 50 insertions, 20 deletions
diff --git a/src/uxn/devices/ppu.c b/src/uxn/devices/ppu.c
index 836b7f0..d9208a5 100644
--- a/src/uxn/devices/ppu.c
+++ b/src/uxn/devices/ppu.c
@@ -32,6 +32,10 @@ static Uint8 font[][8] = {
32 {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c}, 32 {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c},
33 {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80}}; 33 {0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80}};
34 34
35u32 *backbuffer_bg0;
36u32 *backbuffer_bg1;
37static u8 dirty_tiles[20][30] = {0};
38
35void 39void
36putcolors(Ppu *p, Uint8 *addr) { 40putcolors(Ppu *p, Uint8 *addr) {
37 int i; 41 int i;
@@ -49,31 +53,38 @@ putcolors(Ppu *p, Uint8 *addr) {
49 53
50void 54void
51putpixel(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 color) { 55putpixel(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 color) {
52 if(x >= 30 * 8 || y >= 20 * 8)
53 return;
54
55 Uint32 pos = ((y & 7) + (((x >> 3) + (y >> 3) * 30) * 8)); 56 Uint32 pos = ((y & 7) + (((x >> 3) + (y >> 3) * 30) * 8));
56 Uint32 shift = (x & 7) << 2; 57 Uint32 shift = (x & 7) << 2;
57 layer[pos] = (layer[pos] & (~(0xF << shift))) | (color << shift); 58 layer[pos] = (layer[pos] & (~(0xF << shift))) | (color << shift);
59 dirty_tiles[y >> 3][x >> 3] = 1;
58} 60}
59 61
60void 62void
61puticn(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy) { 63puticn(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color,
64 Uint8 flipx, Uint8 flipy) {
62 Uint16 v, h; 65 Uint16 v, h;
63 for(v = 0; v < 8; v++) 66 for(v = 0; v < 8; v++) {
64 for(h = 0; h < 8; h++) { 67 for(h = 0; h < 8; h++) {
65 Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1); 68 Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1);
66 if(ch1 == 1 || (color != 0x05 && color != 0x0a && color != 0x0f)) 69 // if(ch1 == 1 || (color != 0x05 && color != 0x0a && color != 0x0f))
67 putpixel(p, 70 // putpixel(p,
68 layer, 71 // layer,
69 x + (flipx ? 7 - h : h), 72 // x + (flipx ? 7 - h : h),
70 y + (flipy ? 7 - v : v), 73 // y + (flipy ? 7 - v : v),
71 ch1 ? color % 4 : color / 4); 74 // ch1 ? color % 4 : color / 4);
75 // TODO: Add flip options directly to the screenblock?
76 putpixel(p,
77 layer,
78 x + h,
79 y + v,
80 ch1 ? color & 0x3 : color >> 2);
72 } 81 }
82 }
73} 83}
74 84
75void 85void
76putchr(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy) { 86putchr(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color,
87 Uint8 flipx, Uint8 flipy) {
77 Uint16 v, h; 88 Uint16 v, h;
78 for(v = 0; v < 8; v++) 89 for(v = 0; v < 8; v++)
79 for(h = 0; h < 8; h++) { 90 for(h = 0; h < 8; h++) {
@@ -87,6 +98,23 @@ putchr(Ppu *p, Uint32 *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Ui
87 } 98 }
88} 99}
89 100
101void
102flipbuf(Ppu *p) {
103 Tile *mem_fg = &TILE_MEM[0];
104 Tile *mem_bg = &TILE_MEM[2];
105 for (size_t j = 0; j < 20; ++j) {
106 for (size_t i = 0; i < 30; ++i) {
107 if (dirty_tiles[j][i] != 0) {
108 Tile *tile_fg = p->fg;
109 Tile *tile_bg = p->bg;
110 mem_fg[i + j * 30] = tile_fg[i + j * 30];
111 mem_bg[i + j * 30] = tile_bg[i + j * 30];
112 dirty_tiles[j][i] = 0;
113 }
114 }
115 }
116}
117
90int 118int
91initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad) { 119initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad) {
92 p->hor = hor; 120 p->hor = hor;
@@ -100,15 +128,19 @@ initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad) {
100 128
101 // Initialize backgrounds. 129 // Initialize backgrounds.
102 u8 cb_fg = 0; 130 u8 cb_fg = 0;
103 u8 sb_fg = 10;
104 u8 cb_bg = 2; 131 u8 cb_bg = 2;
105 u8 sb_bg = 26; 132 u8 sb_idx = 10;
106 BG_CTRL(0) = BG_CHARBLOCK(cb_fg) | BG_SCREENBLOCK(sb_fg) | BG_PRIORITY(1); 133 BG_CTRL(0) = BG_CHARBLOCK(cb_fg) | BG_SCREENBLOCK(sb_idx) | BG_PRIORITY(1);
107 BG_CTRL(1) = BG_CHARBLOCK(cb_bg) | BG_SCREENBLOCK(sb_bg) | BG_PRIORITY(2); 134 BG_CTRL(1) = BG_CHARBLOCK(cb_bg) | BG_SCREENBLOCK(sb_idx) | BG_PRIORITY(2);
135
136 backbuffer_bg0 = malloc(30 * 20 * sizeof(Tile));
137 backbuffer_bg1 = malloc(30 * 20 * sizeof(Tile));
108 138
109 // Clear tile memory. 139 // Clear tile memory.
110 p->fg = &TILE_MEM[cb_fg]; 140 p->fg = &TILE_MEM[cb_fg];
111 p->bg = &TILE_MEM[cb_bg]; 141 p->bg = &TILE_MEM[cb_bg];
142 p->fg = backbuffer_bg0;
143 p->bg = backbuffer_bg1;
112 for (size_t i = 0; i < 30 * 20 * 8; ++i) { 144 for (size_t i = 0; i < 30 * 20 * 8; ++i) {
113 p->fg[i] = 0; 145 p->fg[i] = 0;
114 p->bg[i] = 0; 146 p->bg[i] = 0;
@@ -121,13 +153,11 @@ initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad) {
121 PAL_BUFFER_BG[3] = COLOR_BLUE; 153 PAL_BUFFER_BG[3] = COLOR_BLUE;
122 154
123 // Initialize memory map. 155 // Initialize memory map.
124 u16 *fg_mem = SCREENBLOCK_MEM[sb_fg]; 156 u16 *mem_map = SCREENBLOCK_MEM[sb_idx];
125 u16 *bg_mem = SCREENBLOCK_MEM[sb_bg];
126 size_t k = 0; 157 size_t k = 0;
127 for (size_t j = 0; j < 20; ++j) { 158 for (size_t j = 0; j < 20; ++j) {
128 for (size_t i = 0; i < 30; ++i, ++k) { 159 for (size_t i = 0; i < 30; ++i, ++k) {
129 fg_mem[i + j * 32] = k; 160 mem_map[i + j * 32] = k;
130 bg_mem[i + j * 32] = k;
131 } 161 }
132 } 162 }
133 163