diff options
author | Bad Diode <bd@badd10de.dev> | 2021-05-18 18:18:18 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-05-18 18:18:18 +0200 |
commit | ec5b9644db2ff26cc6f0cc3d84854b714a25eff9 (patch) | |
tree | e6806bbe0bc84a20d11f620c0425ab58aba12b42 /src/main.c | |
parent | 0c7265cf0de9d4ec95d28c5e103c00a63f4a1697 (diff) | |
download | uxngba-ec5b9644db2ff26cc6f0cc3d84854b714a25eff9.tar.gz uxngba-ec5b9644db2ff26cc6f0cc3d84854b714a25eff9.zip |
Draw directly to the FRAMEBUFFER
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 118 |
1 files changed, 59 insertions, 59 deletions
@@ -21,14 +21,14 @@ static Device *devscreen; | |||
21 | 21 | ||
22 | void | 22 | void |
23 | nil_talk(Device *d, Uint8 b0, Uint8 w) { | 23 | nil_talk(Device *d, Uint8 b0, Uint8 w) { |
24 | (void)d; | 24 | (void)d; |
25 | (void)b0; | 25 | (void)b0; |
26 | (void)w; | 26 | (void)w; |
27 | } | 27 | } |
28 | 28 | ||
29 | void | 29 | void |
30 | console_talk(Device *d, u8 b0, u8 w) { | 30 | console_talk(Device *d, u8 b0, u8 w) { |
31 | if(!w) { | 31 | if(!w) { |
32 | return; | 32 | return; |
33 | } | 33 | } |
34 | switch(b0) { | 34 | switch(b0) { |
@@ -42,77 +42,70 @@ console_talk(Device *d, u8 b0, u8 w) { | |||
42 | void | 42 | void |
43 | system_talk(Device *d, Uint8 b0, Uint8 w) | 43 | system_talk(Device *d, Uint8 b0, Uint8 w) |
44 | { | 44 | { |
45 | if(!w) { | 45 | if(!w) { |
46 | d->dat[0x2] = d->u->wst.ptr; | 46 | d->dat[0x2] = d->u->wst.ptr; |
47 | d->dat[0x3] = d->u->rst.ptr; | 47 | d->dat[0x3] = d->u->rst.ptr; |
48 | } else { | 48 | } else { |
49 | putcolors(&ppu, &d->dat[0x8]); | 49 | putcolors(&ppu, &d->dat[0x8]); |
50 | reqdraw = 1; | 50 | reqdraw = 1; |
51 | } | 51 | } |
52 | (void)b0; | 52 | (void)b0; |
53 | } | 53 | } |
54 | 54 | ||
55 | void | 55 | void |
56 | screen_talk(Device *d, Uint8 b0, Uint8 w) { | 56 | screen_talk(Device *d, Uint8 b0, Uint8 w) { |
57 | if(w && b0 == 0xe) { | 57 | if(w && b0 == 0xe) { |
58 | Uint16 x = mempeek16(d->dat, 0x8); | 58 | Uint16 x = mempeek16(d->dat, 0x8); |
59 | Uint16 y = mempeek16(d->dat, 0xa); | 59 | Uint16 y = mempeek16(d->dat, 0xa); |
60 | Uint8 *addr = &d->mem[mempeek16(d->dat, 0xc)]; | 60 | Uint8 *addr = &d->mem[mempeek16(d->dat, 0xc)]; |
61 | Uint8 *layer = d->dat[0xe] >> 4 & 0x1 ? ppu.fg : ppu.bg; | 61 | Uint8 *layer = d->dat[0xe] >> 4 & 0x1 ? ppu.fg : ppu.bg; |
62 | Uint8 mode = d->dat[0xe] >> 5; | 62 | Uint8 mode = d->dat[0xe] >> 5; |
63 | if(!mode) { | 63 | if(!mode) { |
64 | putpixel(&ppu, layer, x, y, d->dat[0xe] & 0x3); | 64 | putpixel(&ppu, layer, x, y, d->dat[0xe] & 0x3); |
65 | } else if(mode-- & 0x1) { | 65 | } else if(mode-- & 0x1) { |
66 | puticn(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4); | 66 | puticn(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4); |
67 | } else { | 67 | } else { |
68 | putchr(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4); | 68 | putchr(&ppu, layer, x, y, addr, d->dat[0xe] & 0xf, mode & 0x2, mode & 0x4); |
69 | } | 69 | } |
70 | reqdraw = 1; | 70 | reqdraw = 1; |
71 | } | 71 | } |
72 | } | 72 | } |
73 | 73 | ||
74 | void | 74 | void |
75 | redraw(Uint16 *dst, Uxn *u) { | 75 | redraw(Uint16 *dst, Uxn *u) { |
76 | // TODO: The screen will flicker but using Mode4 for double buffering would | 76 | // TODO: The screen will flicker but using Mode4 for double buffering would |
77 | // be way too slow. | 77 | // be way too slow. |
78 | drawppu(&ppu); | 78 | drawppu(&ppu); |
79 | clear_screen_m3(); | 79 | reqdraw = 0; |
80 | // Copy ppu data to framebuffer. | ||
81 | for (size_t j = 0; j < ppu.height; ++j) { | ||
82 | for (size_t i = 0; i < ppu.width; ++i) { | ||
83 | FRAMEBUFFER[j][i] = ppu.output[i + j * ppu.width]; | ||
84 | } | ||
85 | } | ||
86 | reqdraw = 0; | ||
87 | } | 80 | } |
88 | 81 | ||
89 | void | 82 | void |
90 | init_uxn(Uxn *u) { | 83 | init_uxn(Uxn *u) { |
91 | // Initialize PPU. | 84 | // Initialize PPU. |
92 | initppu(&ppu, 30, 20, 0); | 85 | initppu(&ppu, 30, 20, 0); |
93 | 86 | ||
94 | // Copy rom to VM. | 87 | // Copy rom to VM. |
95 | memcpy(u->ram.dat + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom)); | 88 | memcpy(u->ram.dat + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom)); |
96 | 89 | ||
97 | // Prepare devices. | 90 | // Prepare devices. |
98 | portuxn(u, 0x0, "system", system_talk); | 91 | portuxn(u, 0x0, "system", system_talk); |
99 | portuxn(u, 0x1, "console", console_talk); | 92 | portuxn(u, 0x1, "console", console_talk); |
100 | devscreen = portuxn(u, 0x2, "screen", screen_talk); | 93 | devscreen = portuxn(u, 0x2, "screen", screen_talk); |
101 | portuxn(u, 0x3, "---", nil_talk); | 94 | portuxn(u, 0x3, "---", nil_talk); |
102 | portuxn(u, 0x4, "---", nil_talk); | 95 | portuxn(u, 0x4, "---", nil_talk); |
103 | portuxn(u, 0x5, "---", nil_talk); | 96 | portuxn(u, 0x5, "---", nil_talk); |
104 | portuxn(u, 0x6, "---", nil_talk); | 97 | portuxn(u, 0x6, "---", nil_talk); |
105 | portuxn(u, 0x7, "---", nil_talk); | 98 | portuxn(u, 0x7, "---", nil_talk); |
106 | portuxn(u, 0x8, "---", nil_talk); | 99 | portuxn(u, 0x8, "---", nil_talk); |
107 | portuxn(u, 0x9, "---", nil_talk); | 100 | portuxn(u, 0x9, "---", nil_talk); |
108 | portuxn(u, 0xa, "---", nil_talk); | 101 | portuxn(u, 0xa, "---", nil_talk); |
109 | portuxn(u, 0xb, "---", nil_talk); | 102 | portuxn(u, 0xb, "---", nil_talk); |
110 | portuxn(u, 0xc, "---", nil_talk); | 103 | portuxn(u, 0xc, "---", nil_talk); |
111 | portuxn(u, 0xd, "---", nil_talk); | 104 | portuxn(u, 0xd, "---", nil_talk); |
112 | portuxn(u, 0xe, "---", nil_talk); | 105 | portuxn(u, 0xe, "---", nil_talk); |
113 | portuxn(u, 0xf, "---", nil_talk); | 106 | portuxn(u, 0xf, "---", nil_talk); |
114 | mempoke16(devscreen->dat, 2, ppu.hor * 8); | 107 | mempoke16(devscreen->dat, 2, ppu.hor * 8); |
115 | mempoke16(devscreen->dat, 4, ppu.ver * 8); | 108 | mempoke16(devscreen->dat, 4, ppu.ver * 8); |
116 | } | 109 | } |
117 | 110 | ||
118 | int main(void) { | 111 | int main(void) { |
@@ -126,7 +119,7 @@ int main(void) { | |||
126 | .data = small_font, | 119 | .data = small_font, |
127 | .char_width = 4, | 120 | .char_width = 4, |
128 | .char_height = 8, | 121 | .char_height = 8, |
129 | .color = COLOR_BLUE, | 122 | .color = COLOR_WHITE, |
130 | .char_map = small_font_map, | 123 | .char_map = small_font_map, |
131 | }); | 124 | }); |
132 | 125 | ||
@@ -137,17 +130,24 @@ int main(void) { | |||
137 | // Initialize VM. | 130 | // Initialize VM. |
138 | Uxn u = {0}; | 131 | Uxn u = {0}; |
139 | init_uxn(&u); | 132 | init_uxn(&u); |
140 | evaluxn(&u, 0x0100); | 133 | evaluxn(&u, 0x0100); |
141 | 134 | ||
142 | // Main loop. | 135 | // Main loop. |
143 | int frame_counter = 0; | 136 | int frame_counter = 0; |
144 | while(true) { | 137 | while(true) { |
145 | bios_vblank_wait(); | 138 | bios_vblank_wait(); |
146 | poll_keys(); | 139 | poll_keys(); |
147 | evaluxn(&u, mempeek16(devscreen->dat, 0)); | 140 | profile_start(); |
148 | if(reqdraw) { | 141 | evaluxn(&u, mempeek16(devscreen->dat, 0)); |
149 | redraw(ppu.output, &u); | 142 | int eval_cycles = profile_stop(); |
143 | profile_start(); | ||
144 | if(reqdraw) { | ||
145 | redraw(ppu.output, &u); | ||
150 | } | 146 | } |
147 | int redraw_cycles = profile_stop(); | ||
148 | txt_position(0, 0); | ||
149 | txt_printf("EVAL: %d\n", eval_cycles); | ||
150 | txt_printf("REDRAW: %d\n", redraw_cycles); | ||
151 | frame_counter++; | 151 | frame_counter++; |
152 | }; | 152 | }; |
153 | 153 | ||