Skip to content

Commit

Permalink
Make psvDebugScreen usable from prx
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
yne committed Jan 20, 2018
1 parent 1bcea69 commit 60dbada
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions common/debugScreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ static uint32_t defaultBg = 0xFF000000, colorBg = 0xFF000000;

#ifdef __vita__
#include <psp2/display.h>
#include <psp2/kernel/clib.h>
#include <psp2/kernel/sysmem.h>
#include <psp2/kernel/threadmgr.h>
#define vsnprintf sceClibVsnprintf // direct vsnprintf call from suprx = crash
static void* base; // pointer to frame buffer
#else
#define sceKernelLockMutex(m,v,x) m=v
Expand Down Expand Up @@ -90,27 +92,36 @@ static size_t psvDebugScreenEscape(const unsigned char *str) {
}
return 0;
}

int psvDebugScreenInit() {
#ifdef NO_psvDebugScreenInit
return 0;/* avoid linking non-initializer (prx) with sceDisplay/sceMemory */
#else
#ifdef __vita__
mutex = sceKernelCreateMutex("log_mutex", 0, 0, NULL);
SceUID displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCREEN_FB_SIZE, NULL);
sceKernelGetMemBlockBase(displayblock, (void**)&base);
SceDisplayFrameBuf frame = { sizeof(frame), base, SCREEN_FB_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
return sceDisplaySetFrameBuf(&frame, SCE_DISPLAY_SETBUF_NEXTFRAME);
// First check if the FrameBuffer is already init (by the prx loader)
SceDisplayFrameBuf getFrame = { sizeof(getFrame) };
sceDisplayGetFrameBuf(&getFrame, SCE_DISPLAY_SETBUF_NEXTFRAME);
// If not, init the FrameBuffer ourself
if(!(base = getFrame.base)) {
SceDisplayFrameBuf setFrame = { sizeof(setFrame), base, SCREEN_FB_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
SceUID displayblock = sceKernelAllocMemBlock("display", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCREEN_FB_SIZE, NULL);
sceKernelGetMemBlockBase(displayblock, (void**)&base);
sceDisplaySetFrameBuf(&setFrame, SCE_DISPLAY_SETBUF_NEXTFRAME);
}
#endif
return 0;
}

int psvDebugScreenPuts(const char * _text) {
if(!base)psvDebugScreenInit();
const unsigned char*text = (const unsigned char*)_text;
int bytes_per_glyph = (F.width * F.height) / 8;
sceKernelLockMutex(mutex, 1, NULL);
int c;
int c,k;
for (c = 0; text[c] ; c++) {
unsigned char t = text[c];
if (t == '\t') {
coordX += SCREEN_TAB_W - coordX % SCREEN_TAB_W;
//__aeabi_i(div)mod unavailable in -nostdlib => modulo manualy
for(k = 0;coordX - k*SCREEN_TAB_W >= SCREEN_TAB_W; ++k);
coordX += SCREEN_TAB_W - (coordX - k*SCREEN_TAB_W);
continue;
}
if (coordX + F.width > SCREEN_WIDTH) {
Expand Down

0 comments on commit 60dbada

Please sign in to comment.