Skip to content

Commit 22458e0

Browse files
committed
Make psvDebugScreen usable from prx
Using psvDebugScreen from a prx lead to the following issues: - vsnprintf call crash the app and so, shall be directed to the sceClib version - possible multiple call to psvDebugScreenInit (from eboot and prx) that could lead to a FrameBuffer stealing - modulo operation are not available when prx compiled with -nostdlib This commit aim to resolve those issues, but also give an explanation using comment.
1 parent 1bcea69 commit 22458e0

1 file changed

Lines changed: 24 additions & 10 deletions

File tree

common/debugScreen.h

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,17 @@ static uint32_t defaultBg = 0xFF000000, colorBg = 0xFF000000;
3535

3636
#ifdef __vita__
3737
#include <psp2/display.h>
38+
#include <psp2/kernel/clib.h>
3839
#include <psp2/kernel/sysmem.h>
3940
#include <psp2/kernel/threadmgr.h>
4041
static void* base; // pointer to frame buffer
42+
#ifdef PSVDEBUG_USE_LIBC_VSNPRINTF
43+
#define sceClibVsnprintf vsnprintf
44+
#endif
4145
#else
4246
#define sceKernelLockMutex(m,v,x) m=v
4347
#define sceKernelUnlockMutex(m,v) m=v
48+
#define sceClibVsnprintf vsnprintf
4449
static char base[SCREEN_FB_WIDTH * SCREEN_HEIGHT * 4];
4550
#endif
4651

@@ -90,27 +95,36 @@ static size_t psvDebugScreenEscape(const unsigned char *str) {
9095
}
9196
return 0;
9297
}
98+
9399
int psvDebugScreenInit() {
94-
#ifdef NO_psvDebugScreenInit
95-
return 0;/* avoid linking non-initializer (prx) with sceDisplay/sceMemory */
96-
#else
100+
#ifdef __vita__
97101
mutex = sceKernelCreateMutex("log_mutex", 0, 0, NULL);
98-
SceUID displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCREEN_FB_SIZE, NULL);
99-
sceKernelGetMemBlockBase(displayblock, (void**)&base);
100-
SceDisplayFrameBuf frame = { sizeof(frame), base, SCREEN_FB_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
101-
return sceDisplaySetFrameBuf(&frame, SCE_DISPLAY_SETBUF_NEXTFRAME);
102+
// First check if the FrameBuffer is already init (by the prx loader)
103+
SceDisplayFrameBuf getFrame = { sizeof(getFrame) };
104+
sceDisplayGetFrameBuf(&getFrame, SCE_DISPLAY_SETBUF_NEXTFRAME);
105+
// If not, init the FrameBuffer ourself
106+
if(!(base = getFrame.base)) {
107+
SceUID displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCREEN_FB_SIZE, NULL);
108+
sceKernelGetMemBlockBase(displayblock, (void**)&base);
109+
SceDisplayFrameBuf setFrame = { sizeof(setFrame), base, SCREEN_FB_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
110+
sceDisplaySetFrameBuf(&setFrame, SCE_DISPLAY_SETBUF_NEXTFRAME);
111+
}
102112
#endif
113+
return 0;
103114
}
104115

105116
int psvDebugScreenPuts(const char * _text) {
117+
if(!base)psvDebugScreenInit();
106118
const unsigned char*text = (const unsigned char*)_text;
107119
int bytes_per_glyph = (F.width * F.height) / 8;
108120
sceKernelLockMutex(mutex, 1, NULL);
109-
int c;
121+
int c,k;
110122
for (c = 0; text[c] ; c++) {
111123
unsigned char t = text[c];
112124
if (t == '\t') {
113-
coordX += SCREEN_TAB_W - coordX % SCREEN_TAB_W;
125+
//__aeabi_i(div)mod unavailable in -nostdlib => modulo manualy
126+
for(k = 0;coordX - k*SCREEN_TAB_W >= SCREEN_TAB_W; ++k);
127+
coordX += SCREEN_TAB_W - (coordX - k*SCREEN_TAB_W);
114128
continue;
115129
}
116130
if (coordX + F.width > SCREEN_WIDTH) {
@@ -159,7 +173,7 @@ int psvDebugScreenPrintf(const char *format, ...) {
159173

160174
va_list opt;
161175
va_start(opt, format);
162-
int ret = vsnprintf(buf, sizeof(buf), format, opt);
176+
int ret = sceClibVsnprintf(buf, sizeof(buf), format, opt);
163177
psvDebugScreenPuts(buf);
164178
va_end(opt);
165179

0 commit comments

Comments
 (0)