Skip to content

Commit bf1d4bf

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 bf1d4bf

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,12 +35,14 @@ 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
4142
#else
4243
#define sceKernelLockMutex(m,v,x) m=v
4344
#define sceKernelUnlockMutex(m,v) m=v
45+
#define sceClibVsnprintf vsnprintf
4446
static char base[SCREEN_FB_WIDTH * SCREEN_HEIGHT * 4];
4547
#endif
4648

@@ -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+
SceUID displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCREEN_FB_SIZE, NULL);
105+
sceKernelGetMemBlockBase(displayblock, (void**)&base);
106+
SceDisplayFrameBuf setFrame = { sizeof(setFrame), base, SCREEN_FB_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
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)