aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-18 18:18:18 +0200
committerBad Diode <bd@badd10de.dev>2021-05-18 18:18:18 +0200
commitec5b9644db2ff26cc6f0cc3d84854b714a25eff9 (patch)
treee6806bbe0bc84a20d11f620c0425ab58aba12b42 /src/main.c
parent0c7265cf0de9d4ec95d28c5e103c00a63f4a1697 (diff)
downloaduxngba-ec5b9644db2ff26cc6f0cc3d84854b714a25eff9.tar.gz
uxngba-ec5b9644db2ff26cc6f0cc3d84854b714a25eff9.zip
Draw directly to the FRAMEBUFFER
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c118
1 files changed, 59 insertions, 59 deletions
diff --git a/src/main.c b/src/main.c
index 77cabcc..9866f19 100644
--- a/src/main.c
+++ b/src/main.c
@@ -21,14 +21,14 @@ static Device *devscreen;
21 21
22void 22void
23nil_talk(Device *d, Uint8 b0, Uint8 w) { 23nil_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
29void 29void
30console_talk(Device *d, u8 b0, u8 w) { 30console_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) {
42void 42void
43system_talk(Device *d, Uint8 b0, Uint8 w) 43system_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
55void 55void
56screen_talk(Device *d, Uint8 b0, Uint8 w) { 56screen_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
74void 74void
75redraw(Uint16 *dst, Uxn *u) { 75redraw(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
89void 82void
90init_uxn(Uxn *u) { 83init_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
118int main(void) { 111int 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