forked from yifanlu/usbmc
-
Notifications
You must be signed in to change notification settings - Fork 3
/
debug_screen.c
167 lines (145 loc) · 5 KB
/
debug_screen.c
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <inttypes.h>
#include <psp2/display.h>
#include <psp2/kernel/sysmem.h>
#include <psp2/kernel/threadmgr.h>
extern unsigned char psvDebugScreenFont[];
#define SCREEN_WIDTH (960)
#define SCREEN_HEIGHT (544)
#define SCREEN_FB_WIDTH (960)
#define SCREEN_FB_SIZE (2 * 1024 * 1024)
#define SCREEN_FB_ALIGN (256 * 1024)
#define SCREEN_GLYPH_W (8)
#define SCREEN_GLYPH_H (8)
#define COLOR_BLACK 0xFF000000
#define COLOR_RED 0xFF0000FF
#define COLOR_BLUE 0xFF00FF00
#define COLOR_YELLOW 0xFF00FFFF
#define COLOR_GREEN 0xFFFF0000
#define COLOR_MAGENTA 0xFFFF00FF
#define COLOR_CYAN 0xFFFFFF00
#define COLOR_WHITE 0xFFFFFFFF
#define COLOR_GREY 0xFF808080
#define COLOR_DEFAULT_FG COLOR_WHITE
#define COLOR_DEFAULT_BG COLOR_BLACK
static int psvDebugScreenMutex; /*< avoid race condition when outputing strings */
static uint32_t psvDebugScreenCoordX = 0;
static uint32_t psvDebugScreenCoordY = 0;
static uint32_t psvDebugScreenColorFg = COLOR_DEFAULT_FG;
static uint32_t psvDebugScreenColorBg = COLOR_DEFAULT_BG;
static SceDisplayFrameBuf psvDebugScreenFrameBuf = {
sizeof(SceDisplayFrameBuf), NULL, SCREEN_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
uint32_t psvDebugScreenSetFgColor(uint32_t color) {
uint32_t prev_color = psvDebugScreenColorFg;
psvDebugScreenColorFg = color;
return prev_color;
}
uint32_t psvDebugScreenSetBgColor(uint32_t color) {
uint32_t prev_color = psvDebugScreenColorBg;
psvDebugScreenColorBg = color;
return prev_color;
}
static size_t psvDebugScreenEscape(const char *str){
int i,j, p=0, params[8]={};
for(i=0; i<8 && str[i]!='\0'; i++){
if(str[i] >= '0' && str[i] <= '9'){
params[p]=(params[p]*10) + (str[i] - '0');
}else if(str[i] == ';'){
p++;
}else if(str[i] == 'f' || str[i] == 'H'){
psvDebugScreenCoordX = params[0] * SCREEN_GLYPH_W;
psvDebugScreenCoordY = params[1] * SCREEN_GLYPH_H;
break;
}else if (str[i] == 'm'){
for(j=0; j<=p; j++){
switch(params[j]/10){/*bold,dim,underline,blink,invert,hidden => unsupported yet */
#define BIT2BYTE(bit) ( ((!!(bit&4))<<23) | ((!!(bit&2))<<15) | ((!!(bit&1))<<7) )
case 0:psvDebugScreenSetFgColor(COLOR_DEFAULT_FG);psvDebugScreenSetBgColor(COLOR_DEFAULT_BG);break;
case 3:psvDebugScreenSetFgColor(BIT2BYTE(params[j]%10));break;
case 9:psvDebugScreenSetFgColor(BIT2BYTE(params[j]%10) | 0x7F7F7F7F);break;
case 4:psvDebugScreenSetBgColor(BIT2BYTE(params[j]%10));break;
case 10:psvDebugScreenSetBgColor(BIT2BYTE(params[j]%10) | 0x7F7F7F7F);break;
#undef BIT2BYTE
}
}
break;
}
}
return i;
}
int psvDebugScreenInit() {
psvDebugScreenMutex = sceKernelCreateMutex("log_mutex", 0, 0, NULL);
SceUID displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCREEN_FB_SIZE, NULL);
sceKernelGetMemBlockBase(displayblock, (void**)&psvDebugScreenFrameBuf.base);
SceDisplayFrameBuf framebuf = {
.size = sizeof(framebuf),
.base = psvDebugScreenFrameBuf.base,
.pitch = SCREEN_WIDTH,
.pixelformat = SCE_DISPLAY_PIXELFORMAT_A8B8G8R8,
.width = SCREEN_WIDTH,
.height = SCREEN_HEIGHT,
};
return sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME);
}
void psvDebugScreenClear(int bg_color){
psvDebugScreenCoordX = psvDebugScreenCoordY = 0;
int i;
for(i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) {
((uint32_t*)psvDebugScreenFrameBuf.base)[i] = bg_color;
}
}
void* psvDebugScreenBase(void) {
return psvDebugScreenFrameBuf.base;
}
int psvDebugScreenPuts(const char * text){
int c, i, j, l;
uint8_t *font;
uint32_t *vram_ptr;
uint32_t *vram;
sceKernelLockMutex(psvDebugScreenMutex, 1, NULL);
for (c = 0; text[c] != '\0' ; c++) {
if (psvDebugScreenCoordX + 8 > SCREEN_WIDTH) {
psvDebugScreenCoordY += SCREEN_GLYPH_H;
psvDebugScreenCoordX = 0;
}
if (psvDebugScreenCoordY + 8 > SCREEN_HEIGHT) {
psvDebugScreenClear(psvDebugScreenColorBg);
}
if (text[c] == '\n') {
psvDebugScreenCoordX = 0;
psvDebugScreenCoordY += SCREEN_GLYPH_H;
continue;
} else if (text[c] == '\r') {
psvDebugScreenCoordX = 0;
continue;
} else if ((text[c] == '\e') && (text[c+1] == '[')) { /* escape code (change color, position ...) */
c+=psvDebugScreenEscape(text+2)+2;
continue;
}
vram = ((uint32_t*)psvDebugScreenFrameBuf.base) + psvDebugScreenCoordX + psvDebugScreenCoordY * SCREEN_FB_WIDTH;
font = &psvDebugScreenFont[ (int)text[c] * 8];
for (i = l = 0; i < SCREEN_GLYPH_W; i++, l += SCREEN_GLYPH_W, font++) {
vram_ptr = vram;
for (j = 0; j < SCREEN_GLYPH_W; j++) {
if ((*font & (128 >> j))) *vram_ptr = psvDebugScreenColorFg;
else *vram_ptr = psvDebugScreenColorBg;
vram_ptr++;
}
vram += SCREEN_FB_WIDTH;
}
psvDebugScreenCoordX += SCREEN_GLYPH_W;
}
sceKernelUnlockMutex(psvDebugScreenMutex, 1);
return c;
}
int psvDebugScreenPrintf(const char *format, ...) {
char buf[512];
va_list opt;
va_start(opt, format);
int ret = vsnprintf(buf, sizeof(buf), format, opt);
psvDebugScreenPuts(buf);
va_end(opt);
return ret;
}