test sprite scaling
[gbajam21] / src / debug.c
1 #include <stdio.h>
2 #include <ctype.h>
3 #include <stdarg.h>
4 #include "gbaregs.h"
5 #include "intr.h"
6 #include "debug.h"
7 #include "util.h"
8
9 uint16_t vblperf_color[] = {
10         /* grn  blue   cyan  yellow  orng    red     purple  d.green purple ... */
11         /* 60    30     20     15     12      10      8.5     7.5    ... */
12         0x3e0, 0xf863, 0xffc0, 0x3ff, 0x1ff, 0x001f, 0xf81f, 0x1e0, 0xf81f, 0xf81f, 0xf81f
13 };
14
15 void vblperf_setcolor(int palidx)
16 {
17         vblperf_palptr = (uint16_t*)CRAM_BG_ADDR + palidx;
18 }
19
20
21 uint32_t panic_regs[16];
22 void get_panic_regs(void);
23
24 void panic(void *pc, const char *fmt, ...)
25 {
26         int y;
27         va_list ap;
28         uint32_t *reg;
29
30         get_panic_regs();
31
32         intr_disable();
33         REG_DISPCNT = 4 | DISPCNT_BG2;
34
35         set_bg_color(0, 31, 0, 0);
36         set_bg_color(0xff, 31, 31, 31);
37
38         fillblock_16byte((void*)VRAM_LFB_FB0_ADDR, 0, 240 * 160 / 16);
39
40         fillblock_16byte((unsigned char*)VRAM_LFB_FB0_ADDR + 240 * 3, 0xffffffff, 240 / 16);
41         dbg_drawstr(44, 0, " Panic at %p ", pc);
42
43         va_start(ap, fmt);
44         y = dbg_vdrawstr(0, 12, fmt, ap) + 8;
45         va_end(ap);
46
47         fillblock_16byte((unsigned char*)VRAM_LFB_FB0_ADDR + 240 * (y + 4), 0xffffffff, 240 / 16);
48         y += 8;
49
50         reg = panic_regs;
51         y = dbg_drawstr(0, y, " r0 %08x  r1 %08x\n r2 %08x  r3 %08x\n r4 %08x  r5 %08x\n r6 %08x  r7 %08x\n",
52                         reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6], reg[7]);
53         y = dbg_drawstr(0, y, " r8 %08x  r9 %08x\nr10 %08x r11 %08x\n ip %08x  sp %08x\n lr %08x  pc %08x\n",
54                         reg[8], reg[9], reg[10], reg[11], reg[12], reg[13], reg[14], reg[15]);
55
56         /* stop any sound/music playback */
57         REG_SOUNDCNT_H = SCNT_DSA_CLRFIFO | SCNT_DSB_CLRFIFO;
58         REG_TMCNT_H(1) &= ~TMCNT_EN;
59         REG_DMA1CNT_H = 0;
60         REG_DMA2CNT_H = 0;
61
62         for(;;);
63 }
64
65 void dbg_drawglyph(int x, int y, int c)
66 {
67         int i;
68         uint16_t pp;
69         unsigned char row;
70         uint16_t *ptr = (uint16_t*)VRAM_LFB_FB0_ADDR + (y << 7) - (y << 3) + (x >> 1);
71         unsigned char *fnt = font_8x8 + ((c & 0xff) << 3);
72
73         for(i=0; i<8; i++) {
74                 row = *fnt++;
75                 pp = row & 0x80 ? 0xff : 0;
76                 *ptr++ = pp | (row & 0x40 ? 0xff00 : 0);
77                 pp = row & 0x20 ? 0xff : 0;
78                 *ptr++ = pp | (row & 0x10 ? 0xff00 : 0);
79                 pp = row & 0x08 ? 0xff : 0;
80                 *ptr++ = pp | (row & 0x04 ? 0xff00 : 0);
81                 pp = row & 0x02 ? 0xff : 0;
82                 *ptr++ = pp | (row & 0x01 ? 0xff00 : 0);
83                 ptr += 120 - 4;
84         }
85 }
86
87 int dbg_vdrawstr(int x, int y, const char *fmt, va_list ap)
88 {
89         int startx, c;
90         char buf[128];
91         char *ptr = buf;
92
93         vsnprintf(buf, sizeof buf, fmt, ap);
94
95         startx = x;
96         while(*ptr) {
97                 if(y >= 160) break;
98
99                 c = *ptr++;
100                 switch(c) {
101                 case '\n':
102                         y += 8;
103                 case '\r':
104                         x = startx;
105                         break;
106
107                 default:
108                         dbg_drawglyph(x, y, c);
109                         x += 8;
110                         if(x >= 240 - 8) {
111                                 while(*ptr && isspace(*ptr)) ptr++;
112                                 x = 0;
113                                 y += 8;
114                         }
115                 }
116         }
117
118         return y;
119 }
120
121 int dbg_drawstr(int x, int y, const char *fmt, ...)
122 {
123         int res;
124         va_list ap;
125
126         va_start(ap, fmt);
127         res = dbg_vdrawstr(x, y, fmt, ap);
128         va_end(ap);
129         return res;
130 }
131
132 #ifdef EMUBUILD
133 __attribute__((target("arm")))
134 void emuprint(const char *fmt, ...)
135 {
136         char buf[128];
137         va_list ap;
138
139         va_start(ap, fmt);
140         vsnprintf(buf, sizeof buf, fmt, ap);
141         va_end(ap);
142
143         asm volatile(
144                 "mov r0, %0\n\t"
145                 "swi 0xff0000\n\t" :
146                 : "r" (buf)
147                 : "r0"
148         );
149 }
150 #else
151 void emuprint(const char *fmt, ...)
152 {
153 }
154 #endif