Skip to content

Commit 9aac54d

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 9aac54d

1 file changed

Lines changed: 19 additions & 9 deletions

File tree

common/debugScreen.h

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ static uint32_t defaultBg = 0xFF000000, colorBg = 0xFF000000;
3737
#include <psp2/display.h>
3838
#include <psp2/kernel/sysmem.h>
3939
#include <psp2/kernel/threadmgr.h>
40+
#define vsnprintf sceClibVsnprintf // direct vsnprintf call from suprx = crash
4041
static void* base; // pointer to frame buffer
4142
#else
4243
#define sceKernelLockMutex(m,v,x) m=v
@@ -90,27 +91,36 @@ static size_t psvDebugScreenEscape(const unsigned char *str) {
9091
}
9192
return 0;
9293
}
94+
9395
int psvDebugScreenInit() {
94-
#ifdef NO_psvDebugScreenInit
95-
return 0;/* avoid linking non-initializer (prx) with sceDisplay/sceMemory */
96-
#else
96+
#ifdef __vita__
9797
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);
98+
// First check if the FrameBuffer is already init (by the prx loader)
99+
SceDisplayFrameBuf getFrame = { sizeof(getFrame) };
100+
sceDisplayGetFrameBuf(&getFrame, SCE_DISPLAY_SETBUF_NEXTFRAME);
101+
// If not, init the FrameBuffer ourself
102+
if(!(base = getFrame.base)) {
103+
SceDisplayFrameBuf setFrame = { sizeof(setFrame), base, SCREEN_FB_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
104+
SceUID displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCREEN_FB_SIZE, NULL);
105+
sceKernelGetMemBlockBase(displayblock, (void**)&base);
106+
sceDisplaySetFrameBuf(&setFrame, SCE_DISPLAY_SETBUF_NEXTFRAME);
107+
}
102108
#endif
109+
return 0;
103110
}
104111

105112
int psvDebugScreenPuts(const char * _text) {
113+
if(!base)psvDebugScreenInit();
106114
const unsigned char*text = (const unsigned char*)_text;
107115
int bytes_per_glyph = (F.width * F.height) / 8;
108116
sceKernelLockMutex(mutex, 1, NULL);
109-
int c;
117+
int c,k;
110118
for (c = 0; text[c] ; c++) {
111119
unsigned char t = text[c];
112120
if (t == '\t') {
113-
coordX += SCREEN_TAB_W - coordX % SCREEN_TAB_W;
121+
//__aeabi_i(div)mod unavailable in -nostdlib => modulo manualy
122+
for(k = 0;coordX - k*SCREEN_TAB_W >= SCREEN_TAB_W; ++k);
123+
coordX += SCREEN_TAB_W - (coordX - k*SCREEN_TAB_W);
114124
continue;
115125
}
116126
if (coordX + F.width > SCREEN_WIDTH) {

0 commit comments

Comments
 (0)