Skip to content

Commit 60dbada

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 60dbada

1 file changed

Lines changed: 20 additions & 9 deletions

File tree

common/debugScreen.h

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ 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>
41+
#define vsnprintf sceClibVsnprintf // direct vsnprintf call from suprx = crash
4042
static void* base; // pointer to frame buffer
4143
#else
4244
#define sceKernelLockMutex(m,v,x) m=v
@@ -90,27 +92,36 @@ static size_t psvDebugScreenEscape(const unsigned char *str) {
9092
}
9193
return 0;
9294
}
95+
9396
int psvDebugScreenInit() {
94-
#ifdef NO_psvDebugScreenInit
95-
return 0;/* avoid linking non-initializer (prx) with sceDisplay/sceMemory */
96-
#else
97+
#ifdef __vita__
9798
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);
99+
// First check if the FrameBuffer is already init (by the prx loader)
100+
SceDisplayFrameBuf getFrame = { sizeof(getFrame) };
101+
sceDisplayGetFrameBuf(&getFrame, SCE_DISPLAY_SETBUF_NEXTFRAME);
102+
// If not, init the FrameBuffer ourself
103+
if(!(base = getFrame.base)) {
104+
SceDisplayFrameBuf setFrame = { sizeof(setFrame), base, SCREEN_FB_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
105+
SceUID displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCREEN_FB_SIZE, NULL);
106+
sceKernelGetMemBlockBase(displayblock, (void**)&base);
107+
sceDisplaySetFrameBuf(&setFrame, SCE_DISPLAY_SETBUF_NEXTFRAME);
108+
}
102109
#endif
110+
return 0;
103111
}
104112

105113
int psvDebugScreenPuts(const char * _text) {
114+
if(!base)psvDebugScreenInit();
106115
const unsigned char*text = (const unsigned char*)_text;
107116
int bytes_per_glyph = (F.width * F.height) / 8;
108117
sceKernelLockMutex(mutex, 1, NULL);
109-
int c;
118+
int c,k;
110119
for (c = 0; text[c] ; c++) {
111120
unsigned char t = text[c];
112121
if (t == '\t') {
113-
coordX += SCREEN_TAB_W - coordX % SCREEN_TAB_W;
122+
//__aeabi_i(div)mod unavailable in -nostdlib => modulo manualy
123+
for(k = 0;coordX - k*SCREEN_TAB_W >= SCREEN_TAB_W; ++k);
124+
coordX += SCREEN_TAB_W - (coordX - k*SCREEN_TAB_W);
114125
continue;
115126
}
116127
if (coordX + F.width > SCREEN_WIDTH) {

0 commit comments

Comments
 (0)