Instantly share code, notes, and snippets.

@yne /main.c
Created Sep 2, 2017

Embed
What would you like to do?
PSV Progress
#include <string.h>
#include <stdbool.h>
#include <psp2/types.h>
#include <psp2/kernel/processmgr.h>
#include <psp2/message_dialog.h>
#include <psp2/display.h>
#include <psp2/apputil.h>
#include <psp2/gxm.h>
#include <psp2/ctrl.h>
#include <psp2/kernel/sysmem.h>
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
#define DISPLAY_WIDTH 960
#define DISPLAY_HEIGHT 544
#define DISPLAY_STRIDE_IN_PIXELS 1024
#define DISPLAY_BUFFER_COUNT 2
#define DISPLAY_MAX_PENDING_SWAPS 1
typedef struct{
void*data;
SceGxmSyncObject*sync;
SceGxmColorSurface surf;
SceUID uid;
}displayBuffer;
unsigned int backBufferIndex = 0;
unsigned int frontBufferIndex = 0;
/* could be converted as struct displayBuffer[] */
displayBuffer dbuf[DISPLAY_BUFFER_COUNT];
void *dram_alloc(unsigned int size, SceUID *uid){
void *mem;
*uid = sceKernelAllocMemBlock("gpu_mem", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, ALIGN(size,256*1024), NULL);
sceKernelGetMemBlockBase(*uid, &mem);
sceGxmMapMemory(mem, ALIGN(size,256*1024), SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE);
return mem;
}
void gxm_vsync_cb(const void *callback_data){
sceDisplaySetFrameBuf(&(SceDisplayFrameBuf){sizeof(SceDisplayFrameBuf),
*((void **)callback_data),DISPLAY_STRIDE_IN_PIXELS, 0,
DISPLAY_WIDTH,DISPLAY_HEIGHT}, SCE_DISPLAY_SETBUF_NEXTFRAME);
}
void gxm_init(){
sceGxmInitialize(&(SceGxmInitializeParams){0,DISPLAY_MAX_PENDING_SWAPS,gxm_vsync_cb,sizeof(void *),SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE});
unsigned int i;
for (i = 0; i < DISPLAY_BUFFER_COUNT; i++) {
dbuf[i].data = dram_alloc(4*DISPLAY_STRIDE_IN_PIXELS*DISPLAY_HEIGHT, &dbuf[i].uid);
sceGxmColorSurfaceInit(&dbuf[i].surf,SCE_GXM_COLOR_FORMAT_A8B8G8R8,SCE_GXM_COLOR_SURFACE_LINEAR,SCE_GXM_COLOR_SURFACE_SCALE_NONE,SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,DISPLAY_WIDTH,DISPLAY_HEIGHT,DISPLAY_STRIDE_IN_PIXELS,dbuf[i].data);
sceGxmSyncObjectCreate(&dbuf[i].sync);
}
}
void gxm_swap(){
sceGxmPadHeartbeat(&dbuf[backBufferIndex].surf, dbuf[backBufferIndex].sync);
sceGxmDisplayQueueAddEntry(dbuf[frontBufferIndex].sync, dbuf[backBufferIndex].sync, &dbuf[backBufferIndex].data);
frontBufferIndex = backBufferIndex;
backBufferIndex = (backBufferIndex + 1) % DISPLAY_BUFFER_COUNT;
}
void gxm_term(){
sceGxmTerminate();
/*TODO*/
}
int main(int argc, const char *argv[]) {
sceAppUtilInit(&(SceAppUtilInitParam){}, &(SceAppUtilBootParam){});
sceCommonDialogSetConfigParam(&(SceCommonDialogConfigParam){});
gxm_init();
int progress = 0;
bool has_canceled = false;
uint32_t last_status = 0x10FFFF10;
if(sceMsgDialogInit(&(SceMsgDialogParam){
.mode=SCE_MSG_DIALOG_MODE_PROGRESS_BAR,
.progBarParam=&(SceMsgDialogProgressBarParam){
.barType=SCE_MSG_DIALOG_PROGRESSBAR_TYPE_PERCENTAGE,
.msg="progres bar sample title"}})<0)sceKernelExitProcess(0);
if(sceMsgDialogProgressBarSetValue(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, progress=0)<0)sceKernelExitProcess(0);
SceCtrlData ctrl;
int i=0;
while (!has_canceled) {
//clear current screen buffer
memset(dbuf[backBufferIndex].data, last_status | i, DISPLAY_HEIGHT*DISPLAY_STRIDE_IN_PIXELS*4);
sceCtrlPeekBufferPositive(0, &ctrl, 1);
if((i++>500) || (ctrl.buttons == SCE_CTRL_START))
has_canceled=true;
if (sceMsgDialogGetStatus() == SCE_COMMON_DIALOG_STATUS_FINISHED) {
SceMsgDialogResult msgres={};
sceMsgDialogGetResult(&msgres);
//CANCEL may be triggerd by a sceMsgDialogClose() call;
has_canceled = (msgres.result==SCE_COMMON_DIALOG_RESULT_USER_CANCELED);
sceMsgDialogTerm();
} else {
progress++;
sceMsgDialogProgressBarInc(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, 1);
}
sceCommonDialogUpdate(&(SceCommonDialogUpdateParam){{
NULL,dbuf[backBufferIndex].data,0,0,
DISPLAY_WIDTH,DISPLAY_HEIGHT,DISPLAY_STRIDE_IN_PIXELS},
dbuf[backBufferIndex].sync});
gxm_swap();
sceDisplayWaitVblankStart();
}
gxm_term();
sceKernelExitProcess(0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment