void patchMemPartitionInfo() { if ( model == PSP_MODEL_STANDARD ) sceKernelSetDdrMemoryProtection( ( void * )0x88300000, 0x00100000, 0xf ); else sceKernelSetDdrMemoryProtection( ( void * )0x88600000, 0x00200000, 0xf ); tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceSystemMemoryManager" ); // 0x02001021 move $v0 $s0 int offset = 0x00001304; if ( fw_version == FW_371 || fw_version == FW_380 || fw_version == FW_390 ) { offset = 0x00001304; //for 3.71, 3.80, 3.90 } else if ( fw_version == FW_401 ) { offset = 0x00003A68; //for 4.01 } else if ( fw_version == FW_500 || fw_version == FW_550 ) { offset = 0x00003AA8; //for 5.00 } _sw( 0x02001021, pMod->text_addr + offset ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); PspSysmemPartitionInfo info; memset( &info, 0, sizeof( PspSysmemPartitionInfo ) ); info.size = sizeof( PspSysmemPartitionInfo ); PspSysmemPartitionInfo * p_info = ( PspSysmemPartitionInfo * )sceKernelQueryMemoryPartitionInfo( 4, &info ); if ( model == PSP_MODEL_STANDARD ) p_info->startaddr = 0x08300000; else p_info->startaddr = 0x08600000; p_info->attr = 0xf; //restore _sw( 0x00001021, pMod->text_addr + offset ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
void drawUploadTransfer() { sceDisplaySetMode(0, SCR_WIDTH, SCR_HEIGHT); sceGuStart(GU_DIRECT, list); sceGuTexFilter(GU_LINEAR, GU_LINEAR); sceGuFinish(); sceGuSync(0, 0); // This time, we only need one buffer. switchBuf(0, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddOne, vertices1); sceDisplayWaitVblank(); // Okay, let's draw a totally different pattern in memory. for (int y = 0; y < 272; ++y) { for (int x = 0; x < 512; ++x) { copybuf[y * 512 + x] = (x & 1) + (y & 1); } } sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(getBufAddr(0), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); // Now download should display out pattern. displayBuffer("Pattern"); }
void displayBuffer(const char *reason) { sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(copybuf, drawbuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); const u32 *buf = copybuf; checkpoint(NULL); schedf("%s: ", reason); // This prevents drawing to the screen, which makes the test faster. HAS_DISPLAY = 0; for (int y = 0; y < 1; ++y) { for (int x = 0; x < 1; ++x) { // For the purposes of this test, ignore alpha. schedf("%06x", buf[y * 512 + x] & 0x00FFFFFF); } schedf("\n"); flushschedf(); } HAS_DISPLAY = 1; // Reset. memset(copybuf, 0, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(drawbuf, copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); }
void testBlendFunc(const char *title, u32 prev, u32 c, int op, int src, int dst, u32 fixa, u32 fixb) { for (size_t i = 0; i < sizeof(copybuf) / 4; ++i) { copybuf[i] = prev; } sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(sceGeEdramGetAddr(), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceGuStart(GU_DIRECT, list); sceGuEnable(GU_BLEND); sceGuBlendFunc(op, src, dst, fixa, fixb); sceGuEnable(GU_STENCIL_TEST); sceGuStencilFunc(GU_ALWAYS, 0xAA, 0xFF); sceGuStencilOp(GU_REPLACE, GU_REPLACE, GU_REPLACE); drawBoxCommands(c); sceGuFinish(); sceGuSync(GU_SYNC_WAIT, GU_SYNC_WHAT_DONE); displayBuffer(title); sceGuDisable(GU_BLEND); }
void me_csc ( volatile struct me_struct *nocache, unsigned char *cy, unsigned char *cu, unsigned char *cv, int l0, int l1, int l2, unsigned char *out, int width, int height, int line_size ) { struct csc_struct me; struct csc_struct main_cpu; int height_div_2 = height >> 1; int height_div_4 = height >> 2; me.cy = cy; me.cu = cu; me.cv = cv; me.l0 = l0; me.l1 = l1; me.l2 = l2; me.out = out; me.width = width; me.height = height_div_2; me.line_size = line_size; main_cpu.cy = cy + height_div_2 * l0; main_cpu.cu = cu + height_div_4 * l1; main_cpu.cv = cv + height_div_4 * l2; main_cpu.l0 = l0; main_cpu.l1 = l1; main_cpu.l2 = l2; main_cpu.out = out + height_div_2 * (line_size << 2); main_cpu.width = width; main_cpu.height = height_div_2; main_cpu.line_size = line_size; sceKernelDcacheWritebackInvalidateAll(); me_start(nocache, &me_csc_asm, &me); csc_asm(&main_cpu); sceKernelDcacheWritebackInvalidateAll(); me_wait(nocache); }
void displayBuffer(const char *reason) { sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(copybuf, sceGeEdramGetAddr(), sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); const u32 *buf = copybuf; checkpoint("%s: COLOR=%08x", reason, buf[0]); // Reset. memset(copybuf, 0x44, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(sceGeEdramGetAddr(), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); }
void restoreLoadExecVSHCommon() { _sw( LoadExecVSHCommon_ori[0].val, LoadExecVSHCommon_ori[0].addr ); _sw( LoadExecVSHCommon_ori[1].val, LoadExecVSHCommon_ori[1].addr ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
void *Red3dLoadFile(const char *path, int mempart) { void *ptr, *readbuffer; int c = Red3dCheckFile(path); if(c >= 0) return DirIndex[c]->address; int fd = sceIoOpen(path, PSP_O_RDONLY, 0777); if(fd >= 0) { u32 size = sceIoLseek(fd, 0, SEEK_END); sceIoLseek(fd, 0, SEEK_SET); readbuffer = malloc(size); sceIoRead(fd, readbuffer, size); ptr = Red3dLoadBuf(readbuffer, size, mempart); free(readbuffer); sceKernelDcacheWritebackInvalidateAll(); sceIoClose(fd); return ptr; } return NULL; }
int parseDiff( const char * file, tSceModule * mod ) { int off = inCtf( file ); if ( off < 0 ) { log( "there's no patch for %s\n", file ); return 0; } int ctf = sceIoOpen( cxmb_theme_file, PSP_O_RDONLY, 0644 ); if ( ctf < 0 ) { log( "no ctf file found!\n" ); return -1; } sceIoLseek( ctf, ctf_header[off].start, PSP_SEEK_SET ); log( "patch %s!\nstart: %08x\nsize: %08x\n", file, ctf_header[off].start, ctf_header[off].size ); unsigned int attr[2]; int i = 0; while( i < ctf_header[off].size ) { sceIoRead( ctf, attr, 8 ); sceIoRead( ctf, ( void * )( mod->text_addr + attr[0] ), attr[1] ); i ++; } sceIoClose( ctf ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); log( "%s patched!\n", file ); return 0; }
void wifiModulesPatch1() { tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceThreadManager" ); //a0 = 4, change partition id to 4 if ( fw_version == FW_371 ) threadman_offset = 0x00010B30; else if ( fw_version == FW_380 || fw_version == FW_390 ) threadman_offset = 0x00010CB8; else if ( fw_version == FW_401 ) threadman_offset = 0x00012154; else if ( fw_version == FW_500 || fw_version == FW_550 ) threadman_offset = 0x000121E0; _sw( 0x34040004, pMod->text_addr + threadman_offset ); pMod = ( tSceModule * )sceKernelFindModuleByName( "sceModuleManager" ); //a3 stack size 0x40000 -> 0x10000 if ( fw_version == FW_371 ) modulemgr_offset = 0x000076A0; else if ( fw_version == FW_380 || fw_version == FW_390 ) modulemgr_offset = 0x00007C9C; else if ( fw_version == FW_401 ) modulemgr_offset = 0x00007C50; else if ( fw_version == FW_500 ) modulemgr_offset = 0x00007C84; //added for 5.50 else if ( fw_version == FW_550 ) modulemgr_offset = 0x00007F80; _sw( 0x3C070001, pMod->text_addr + modulemgr_offset ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
void wifiModulesPatch2() { if ( fw_version == FW_550 ) { //module renamed to sceNet_Service in 5.50 tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceNet_Service" ); //a2 partid = 4 of ifhandle _sw( 0x34050004, pMod->text_addr + 0x000014D8 ); //for 5.50 } else { tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceNetInterface_Service" ); _sw( 0x34050004, pMod->text_addr + 0x00001440 ); //for 3.71, 3.80, 3.90, 4.01, 5.00 } tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceNet_Library" ); unsigned int net_offset = 0; if ( fw_version == FW_371 || fw_version == FW_380 || fw_version == FW_390 ) net_offset = 0x00001800; else if ( fw_version == FW_401 ) net_offset = 0x00002320; else if ( fw_version == FW_500 || fw_version == FW_550 ) net_offset = 0x00002348; _sw( 0x34020002, pMod->text_addr + net_offset ); _sw( 0xAFA20000, pMod->text_addr + net_offset + 0x4 ); _sw( 0x3C020000, pMod->text_addr + net_offset + 0xC ); pMod = ( tSceModule * )sceKernelFindModuleByName( "sceModuleManager" ); //a3 stack size 0x10000 -> 0x4000 _sw( 0x34074000, pMod->text_addr + modulemgr_offset ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
// 0x00000168 int clear_cache(void) { sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); return 0; }
static int MainThread( SceSize args, void *argp ) { hookDisplay(); sceKernelDcacheWritebackInvalidateAll(); sceKernelIcacheInvalidateAll(); unsigned int paddata_old = 0; SceCtrlData paddata; sceKernelDelayThread(10000); while(1) { sceCtrlPeekBufferPositive(&paddata, 1); if(paddata.Buttons != paddata_old) { //press "note" button and magick begin if(paddata.Buttons & PSP_CTRL_NOTE) { //can parse command list can_parse = 1; } } paddata_old = paddata.Buttons; sceKernelDelayThread(10000); } return( 0 ); }
void drawBoxCommands(u32 c) { vertices_f32[0] = makeVertex32(c, -1.0, -1.0, 0.0); vertices_f32[1] = makeVertex32(c, 1.0, 1.0, 0.0); // Clearing cache is fun. Let's do it all the time. sceKernelDcacheWritebackInvalidateAll(); sceGuDrawArray(GU_SPRITES, GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 2, NULL, vertices_f32); }
/** * display_init: Initialize the PSP display. * * [Parameters] * None * [Return value] * Nonzero on success, zero on error */ int display_init(void) { /* Have we already initialized? */ static int initted = 0; if (initted) { return 1; } /* Clear out VRAM */ memset(sceGeEdramGetAddr(), 0, sceGeEdramGetSize()); sceKernelDcacheWritebackInvalidateAll(); /* Set display mode */ int32_t res = sceDisplaySetMode(0, DISPLAY_WIDTH, DISPLAY_HEIGHT); if (res < 0) { DMSG("sceDisplaySetMode() failed: %s", psp_strerror(res)); return 0; } display_width = DISPLAY_WIDTH; display_height = DISPLAY_HEIGHT; display_mode = PSP_DISPLAY_PIXEL_FORMAT_8888; display_bpp = 32; /* Initialize VRAM pointers */ uint8_t *vram_addr = sceGeEdramGetAddr(); uint32_t vram_size = sceGeEdramGetSize(); const uint32_t frame_size = DISPLAY_STRIDE * DISPLAY_HEIGHT * (display_bpp/8); int i; for (i = 0; i < lenof(surfaces); i++) { surfaces[i] = vram_addr + i*frame_size; } vram_spare_ptr = (uint8_t *)(vram_addr + lenof(surfaces)*frame_size); vram_next_alloc = vram_spare_ptr; vram_top = vram_addr + vram_size; displayed_surface = 0; work_surface = 1; swap_pending = 0; /* Set the currently-displayed buffer */ sceDisplaySetFrameBuf(surfaces[displayed_surface], DISPLAY_STRIDE, display_mode, PSP_DISPLAY_SETBUF_IMMEDIATE); /* Set up the GU library */ guInit(); guStart(GU_DIRECT, display_list); guDispBuffer(DISPLAY_WIDTH, DISPLAY_HEIGHT, surfaces[displayed_surface], DISPLAY_STRIDE); guFinish(); guSync(0, 0); /* Success */ initted = 1; return 1; }
void wifiModulesPatch3() { tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceModuleManager" ); //restore _sw( 0x02403821, pMod->text_addr + modulemgr_offset ); pMod = ( tSceModule * )sceKernelFindModuleByName( "sceThreadManager" ); //restore _sw( 0x02402021, pMod->text_addr + threadman_offset ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); }
void init() { sceGuInit(); sceGuStart(GU_DIRECT, list); sceGuDrawBuffer(GU_PSM_8888, fbp0, 512); sceGuDispBuffer(480, 272, fbp0, 512); sceGuDepthBuffer(dbp0, 512); sceGuOffset(2048 - (240 / 2), 2048 - (136 / 2)); sceGuViewport(2048, 2048, 240, 136); sceGuDepthRange(65535, 0); sceGuDepthMask(0); sceGuScissor(0, 0, 480, 272); sceGuEnable(GU_SCISSOR_TEST); sceGuFrontFace(GU_CW); sceGuShadeModel(GU_SMOOTH); sceGuDisable(GU_TEXTURE_2D); ScePspFMatrix4 ones = { {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, }; sceGuSetMatrix(GU_MODEL, &ones); sceGuSetMatrix(GU_VIEW, &ones); sceGuSetMatrix(GU_PROJECTION, &ones); sceGuFinish(); sceGuSync(0, 0); sceDisplayWaitVblankStart(); sceGuDisplay(1); memset(copybuf, 0x44, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(sceGeEdramGetAddr(), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); displayBuffer("Initial"); }
void init() { void *fbp0 = 0; drawbuf = (u32 *)sceGeEdramGetAddr(); sceGuInit(); sceGuStart(GU_DIRECT, list); sceGuDrawBuffer(GU_PSM_8888, fbp0, BUF_WIDTH); sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, fbp0, BUF_WIDTH); sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuFinish(); sceGuSync(0, 0); sceDisplayWaitVblankStart(); sceGuDisplay(1); memset(copybuf, 0, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(drawbuf, copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); }
void drawIntraTransfer() { sceDisplaySetMode(0, SCR_WIDTH, SCR_HEIGHT); sceGuStart(GU_DIRECT, list); sceGuTexFilter(GU_LINEAR, GU_LINEAR); sceGuFinish(); sceGuSync(0, 0); // This time, we only need one buffer. switchBuf(0, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddOne, vertices1); sceDisplayWaitVblank(); // Next, let's copy from this buffer to itself. sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(getBufAddr(0), (u8 *)getBufAddr(0) + sizeof(copybuf) / 2, sizeof(copybuf) / 2); sceKernelDcacheWritebackInvalidateAll(); // Now download should display a different buffer. displayBuffer("Spliced buffer"); }
void displayBuffer(const char *reason) { sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(copybuf, drawbuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); const u32 *buf = copybuf; checkpoint(reason); // This prevents drawing to the screen, which makes the test faster. HAS_DISPLAY = 0; for (int y = 0; y < 272; ++y) { for (int x = 0; x < 480; ++x) { if (buf[y * 512 + x] != 0) { schedf("%x", buf[y * 512 + x]); } else { schedf(" "); } } schedf("\n"); flushschedf(); } HAS_DISPLAY = 1; }
int main(int argc, char *argv[]) { SceCtrlData ctl; pspDebugScreenInit(); sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); /* Copy our small program into the ME reset vector */ memcpy((void *)0xbfc00040, me_run, (int)(me_end - me_run)); sceKernelDcacheWritebackInvalidateAll(); sceSysregMeResetEnable(); sceSysregMeBusClockEnable(); sceSysregMeResetDisable(); sceSysregVmeResetDisable(); while(1) { volatile u32 *count = (u32*) 0xBFC00060; pspDebugScreenSetXY(0, 0); pspDebugScreenPrintf("ME Basic Example, press Home to exit\n"); sceKernelDcacheWritebackInvalidateAll(); pspDebugScreenPrintf("ME Counter: %08x\n", *count); sceCtrlReadBufferPositive(&ctl, 1); if(ctl.Buttons & PSP_CTRL_HOME) { sceKernelExitGame(); } sceDisplayWaitVblankStart(); } return 0; }
void drawInterTransfer() { sceDisplaySetMode(0, SCR_WIDTH, SCR_HEIGHT); // First draw a texture to buffer 1. We'll use a clut here from memory. switchBuf(0, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddOne, vertices1); // Second, another texture to buffer 2. With a different clut so that they are visibly different. switchBuf(1, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddThree, vertices1); sceDisplayWaitVblank(); // Okay, at this point we have two buffers. Let's display one to make sure download works. displayBuffer("Initial download"); // Next, let's copy between them. sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(getBufAddr(1), getBufAddr(0), sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); // Now download should display the other buffer. displayBuffer("Copied buffer"); }
int OnModuleStart( tSceModule * mod ) { log( "on module %s start\n", mod->modname ); if ( strcmp( mod->modname, "scePaf_Module" ) == 0 ) { parseDiff("/vsh/module/paf.prx", mod ); } else if ( strcmp( mod->modname, "sceVshCommonGui_Module" ) == 0 ) { parseDiff("/vsh/module/common_gui.prx", mod ); } else if ( strcmp( mod->modname, "vsh_module" ) == 0 ) { parseDiff("/vsh/module/vshmain.prx", mod ); } else if ( strcmp( mod->modname, "sysconf_plugin_module" ) == 0 ) { unsigned int offset = getSysconfOffset(); if ( fw_version == FW_500 ) { unsigned int addr = mod->text_addr + offset; char *sfx = (char *)addr; sfx[0] = 'C'; } else { unsigned int h_addr = _lw( mod->text_addr + offset ); unsigned int l_addr = _lw( mod->text_addr + offset + 0xC ); unsigned int addr = ( ( h_addr & 0xFFFF ) << 16 ) | ( l_addr & 0xFFFF ); char * sfx = "CTF"; _sw( *( unsigned int * )sfx, addr ); } sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); log( "patched sysconf\n" ); } if ( !previous ) return 0; return previous( mod ); }
void * patchLoadExecVSHCommon( void * func ) { tSceModule * pMod = ( tSceModule * )sceKernelFindModuleByName( "sceLoadExec" ); if ( fw_version == FW_371 ) LoadExecVSHCommon_ori[0].addr = pMod->text_addr + 0x0000121c; //same in standare/slim else if ( fw_version == FW_380 || fw_version == FW_390 ) LoadExecVSHCommon_ori[0].addr = pMod->text_addr + 0x000014cc; //same in standare/slim else if ( fw_version == FW_401 ) LoadExecVSHCommon_ori[0].addr = pMod->text_addr + 0x00001E1C; //same in standare/slim else if ( fw_version == FW_500 ) LoadExecVSHCommon_ori[0].addr = pMod->text_addr + 0x00001E58; //verified in phat else if ( fw_version == FW_550 ) LoadExecVSHCommon_ori[0].addr = pMod->text_addr + 0x00001F3C; //same on slim & phat LoadExecVSHCommon_ori[1].addr = LoadExecVSHCommon_ori[0].addr + 4; LoadExecVSHCommon_ori[0].val = _lw( LoadExecVSHCommon_ori[0].addr ); LoadExecVSHCommon_ori[1].val = _lw( LoadExecVSHCommon_ori[1].addr ); MAKE_JUMP( LoadExecVSHCommon_ori[0].addr, func ); _sw( NOP, LoadExecVSHCommon_ori[1].addr ); sceKernelIcacheInvalidateAll(); sceKernelDcacheWritebackInvalidateAll(); return ( void * )LoadExecVSHCommon_ori[0].addr; }
triSInt AT3_Thread(SceSize args, ScePVoid argp) { while(AT3_Loaded) { if(AT3_Playing) { if(AT3_CallBack) AT3_CallBack((triS16 *) ((triSInt) AT3_Mix_Buffer | 0x40000000), AT3_SAMPLES); AT3_Samples_Played += sceAudioOutputBlocking(AT3_Channel, AT3_Volume, (triVoid *) ((triSInt) AT3_Mix_Buffer | 0x40000000)); sceAudiocodecDecode(AT3_Codec_Buffer, AT3_TYPE_ATRAC3); AT3_pos += AT3_Codec_Buffer[AT3_POS_INPUT_BUFFER]; memcpy( (void*)AT3_Buffer, (void*)AT3_pos, AT3_align ); if (AT3_align==192) { memcpy( (void*)(AT3_Buffer+192), (void*)AT3_Buffer, 192 ); } //AT3_Codec_Buffer[AT3_POS_INPUT_BUFFER] = AT3_pos; if(AT3_pos >= ((AT3_length - AT3_Datas_Start) + AT3_Codec_Buffer[AT3_INITIAL_BUFFER])) { AT3_pos = AT3_Codec_Buffer[AT3_INITIAL_BUFFER] + AT3_Datas_Start; if(!AT3_Loop) AT3_Playing = 0; } } else memset(AT3_Mix_Buffer, 0, AT3_SAMPLES * 2 * 2); sceKernelDcacheWritebackInvalidateAll(); sceKernelDelayThread(10); } return(0); }
static void *psp_init(const video_info_t *video, const input_driver_t **input, void **input_data) { /* to-do : add ASSERT() checks or use main RAM if * VRAM is too low for desired video->input_scale. */ void *pspinput; int pixel_format, lut_pixel_format, lut_block_count; unsigned int red_shift, color_mask; void *displayBuffer, *LUT_r, *LUT_b; psp1_video_t *psp = (psp1_video_t*)calloc(1, sizeof(psp1_video_t)); if (!psp) return NULL; sceGuInit(); psp->vp.x = 0; psp->vp.y = 0; psp->vp.width = SCEGU_SCR_WIDTH; psp->vp.height = SCEGU_SCR_HEIGHT; psp->vp.full_width = SCEGU_SCR_WIDTH; psp->vp.full_height = SCEGU_SCR_HEIGHT; /* Make sure anything using uncached pointers reserves * whole cachelines (memory address and size need to be a multiple of 64) * so it isn't overwritten by an unlucky cache writeback. * * This includes display lists since the Gu library uses * uncached pointers to write to them. */ /* Allocate more space if bigger display lists are needed. */ psp->main_dList = memalign(64, 256); psp->frame_dList = memalign(64, 256); psp->menu.dList = memalign(64, 256); psp->menu.frame = memalign(16, 2 * 480 * 272); psp->frame_coords = memalign(64, (((PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)) + 63) & ~63)); psp->menu.frame_coords = memalign(64, (((PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)) + 63) & ~63)); memset(psp->frame_coords, 0, PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)); memset(psp->menu.frame_coords, 0, PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)); sceKernelDcacheWritebackInvalidateAll(); psp->frame_coords = TO_UNCACHED_PTR(psp->frame_coords); psp->menu.frame_coords = TO_UNCACHED_PTR(psp->menu.frame_coords); psp->frame_coords->v0.x = 60; psp->frame_coords->v0.y = 0; psp->frame_coords->v0.u = 0; psp->frame_coords->v0.v = 0; psp->frame_coords->v1.x = 420; psp->frame_coords->v1.y = SCEGU_SCR_HEIGHT; psp->frame_coords->v1.u = 256; psp->frame_coords->v1.v = 240; psp->vsync = video->vsync; psp->rgb32 = video->rgb32; if(psp->rgb32) { uint32_t* LUT_r_local = (uint32_t*)(SCEGU_VRAM_BP32_2); uint32_t* LUT_b_local = (uint32_t*)(SCEGU_VRAM_BP32_2) + (1 << 8); red_shift = 8 + 8; color_mask = 0xFF; lut_block_count = (1 << 8) / 8; psp->texture = (void*)(LUT_b_local + (1 << 8)); psp->draw_buffer = SCEGU_VRAM_BP32_0; psp->bpp_log2 = 2; pixel_format = GU_PSM_8888; lut_pixel_format = GU_PSM_T32; displayBuffer = SCEGU_VRAM_BP32_1; for (u32 i=0; i < (1 << 8); i++){ LUT_r_local[i]= i; LUT_b_local[i]= i << (8 + 8); } LUT_r = (void*)LUT_r_local; LUT_b = (void*)LUT_b_local; } else { uint16_t* LUT_r_local = (uint16_t*)(SCEGU_VRAM_BP_2); uint16_t* LUT_b_local = (uint16_t*)(SCEGU_VRAM_BP_2) + (1 << 5); red_shift = 6 + 5; color_mask = 0x1F; lut_block_count = (1 << 5) / 8; psp->texture = (void*)(LUT_b_local + (1 << 5)); psp->draw_buffer = SCEGU_VRAM_BP_0; psp->bpp_log2 = 1; pixel_format = (g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_0RGB1555) ? GU_PSM_5551 : GU_PSM_5650 ; lut_pixel_format = GU_PSM_T16; displayBuffer = SCEGU_VRAM_BP_1; for (u16 i = 0; i < (1 << 5); i++) { LUT_r_local[i]= i; LUT_b_local[i]= i << (5 + 6); } LUT_r = (void*)LUT_r_local; LUT_b = (void*)LUT_b_local; } psp->tex_filter = video->smooth? GU_LINEAR : GU_NEAREST; /* TODO: check if necessary. */ sceDisplayWaitVblankStart(); sceGuDisplay(GU_FALSE); sceGuStart(GU_DIRECT, psp->main_dList); sceGuDrawBuffer(pixel_format, TO_GU_POINTER(psp->draw_buffer), SCEGU_VRAM_WIDTH); sceGuDispBuffer(SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT, TO_GU_POINTER(displayBuffer), SCEGU_VRAM_WIDTH); sceGuClearColor(0); sceGuScissor(0, 0, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuTexFilter(psp->tex_filter, psp->tex_filter); sceGuTexWrap (GU_CLAMP, GU_CLAMP); sceGuEnable(GU_TEXTURE_2D); sceGuDisable(GU_DEPTH_TEST); sceGuCallMode(GU_FALSE); sceGuFinish(); sceGuSync(0, 0); /* TODO : check if necessary */ sceDisplayWaitVblankStart(); sceGuDisplay(GU_TRUE); pspDebugScreenSetColorMode(pixel_format); pspDebugScreenSetBase(psp->draw_buffer); /* fill frame_dList : */ sceGuStart(GU_CALL, psp->frame_dList); sceGuTexMode(pixel_format, 0, 0, GU_FALSE); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); sceGuEnable(GU_BLEND); /* green only */ sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0x0000FF00, 0xFFFFFFFF); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); /* restore */ sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xFFFFFFFF, 0xFFFFFFFF); sceGuTexMode(lut_pixel_format, 0, 0, GU_FALSE); sceGuClutMode(pixel_format, red_shift, color_mask, 0); sceGuClutLoad(lut_block_count, LUT_r); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); sceGuClutMode(pixel_format, 0, color_mask, 0); sceGuClutLoad(lut_block_count, LUT_b); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); sceGuFinish(); if (input && input_data) { pspinput = input_psp.init(); *input = pspinput ? &input_psp : NULL; *input_data = pspinput; } psp->vblank_not_reached = true; sceKernelRegisterSubIntrHandler(PSP_VBLANK_INT, 0, psp_on_vblank, psp); sceKernelEnableSubIntr(PSP_VBLANK_INT, 0); psp->keep_aspect = true; psp->should_resize = true; psp->hw_render = false; return psp; error: RARCH_ERR("PSP1 video could not be initialized.\n"); return (void*)-1; }
static int MainThread( SceSize args, void *argp ) { hookDisplay(); sceKernelDcacheWritebackInvalidateAll(); sceKernelIcacheInvalidateAll(); //scePowerTick( 0 ); unsigned int paddata_old = 0; char file[64], flag = 0, size = 0; int x, y, fd, count = 0, thread_count_start, thread_count_now; SceUID thread_buf_start[MAX_THREAD], thread_buf_now[MAX_THREAD], myThread = sceKernelGetThreadId(); SceCtrlData paddata; sceKernelDelayThread(10000); sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, thread_buf_start, MAX_THREAD, &thread_count_start); while(1) { sceCtrlPeekBufferPositive(&paddata, 1); if(paddata.Buttons != paddata_old) { //press "note" button and magick begin if(paddata.Buttons & PSP_CTRL_NOTE) { // IdList Now sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, thread_buf_now, MAX_THREAD, &thread_count_now); //hold all threads for a moment for(x = 0; x < thread_count_now; x++) { // thread id match 0 or 1 unsigned char match = 0; SceUID tmp_thid = thread_buf_now[x]; for(y = 0; y < thread_count_start; y++) { if((tmp_thid == thread_buf_start[y]) || (tmp_thid == myThread)) { match = 1; y = thread_count_start; } } if(thread_count_start == 0) match = 1; if(match == 0) { sceKernelSuspendThread(tmp_thid); } } //can parse command list can_parse = 1; //resume all threads for(x = 0; x < thread_count_now; x++) { // thread id match 0 or 1 unsigned char match = 0; SceUID tmp_thid = thread_buf_now[x]; for(y = 0; y < thread_count_start; y++) { if((tmp_thid == thread_buf_start[y]) || (tmp_thid == myThread)) { match = 1; y = thread_count_start; } } if(thread_count_start == 0) match = 1; if(match == 0) { sceKernelResumeThread(tmp_thid); } } } } paddata_old = paddata.Buttons; sceKernelDelayThread(10000); } return( 0 ); }
Image* TextureManager::LoadPng(const char* filename,int ColorMode,int Swizzle,int Vram) { unsigned short *Buffer; //unsigned short *swizzled_pixels = NULL; int OutBytesPerPixel; int Power2Width = 0; int Power2Height = 0; png_structp png_ptr; png_infop info_ptr; unsigned int sig_read = 0; png_uint_32 width, height,x, y; int bit_depth, color_type, interlace_type; unsigned int* line; FILE *fp; if(ColorMode == GU_PSM_4444 || ColorMode == GU_PSM_5650 || ColorMode == GU_PSM_5551) OutBytesPerPixel = 2; else OutBytesPerPixel = 4; if ((fp = fopen(filename, "rb")) == NULL) { printf("Can't open file %s\n",filename); return NULL; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fclose(fp); return NULL; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); return NULL; } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, sig_read); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL); png_set_strip_16(png_ptr); png_set_packing(png_ptr); if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); line = (unsigned int*)malloc(width * 4); if (!line) { fclose(fp); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); return NULL; } Power2Width = PowerOfTwo(width); Power2Height = PowerOfTwo(height); //Buffer = (unsigned short*)memalign(16,Power2Width*Power2Height*OutBytesPerPixel); //Buffer = (unsigned short*)malloc(sizeof(unsigned short) * (Power2Width*Power2Height*OutBytesPerPixel)); Buffer = (unsigned short*)malloc(Power2Width*Power2Height*OutBytesPerPixel); for (y = 0; y < height; y++) { png_read_row(png_ptr, (unsigned char*) line, NULL); for (x = 0; x < width; x++) { unsigned int *Buffer32 = (unsigned int*)Buffer; unsigned int color32 = line[x]; unsigned short color16; if(ColorMode == GU_PSM_5551) { color16 = Color8888To5551(color32); Buffer[y*Power2Width+x] = color16; } else if(ColorMode == GU_PSM_4444) { color16 = Color8888To4444(color32); Buffer[y*Power2Width+x] = color16; } else if(ColorMode == GU_PSM_5650) { color16 = Color8888To5650(color32); Buffer[y*Power2Width+x] = color16; } else { Buffer32[y*Power2Width+x] = color32; } } } free(line); png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); fclose(fp); Image *Image1 = new Image(); Image1->Width = width; Image1->Height = height; Image1->power2Width = Power2Width; Image1->power2Height = Power2Height; Image1->vRam = Vram; Image1->ColorMode = ColorMode; Image1->Swizzle = Swizzle; /*if (Vram == 1) { swizzled_pixels = (unsigned short*)getStaticVramTexture(Power2Width,Power2Height,ColorMode);//valloc(Image1->power2Height*Image1->power2Width*OutBytesPerPixel); }else { swizzled_pixels = (unsigned short*)memalign(16,Image1->power2Height*Image1->power2Width*OutBytesPerPixel); //swizzled_pixels = (unsigned short*)malloc(sizeof(unsigned short) * (Power2Width*Power2Height*OutBytesPerPixel)); } swizzle_fast((u8*)swizzled_pixels,(const u8*)Buffer,Image1->power2Width*OutBytesPerPixel,Image1->power2Height);*/ if (Vram == 1) { Image1->ImageData = (unsigned short*)getStaticVramTexture(Power2Width,Power2Height,ColorMode); }else { Image1->ImageData = (unsigned short*)malloc(Image1->power2Height*Image1->power2Width*OutBytesPerPixel); } swizzle_fast((u8*)Image1->ImageData,(const u8*)Buffer,Image1->power2Width*OutBytesPerPixel,Image1->power2Height); free(Buffer); //clear the cache or there will be some errors sceKernelDcacheWritebackInvalidateAll(); return Image1; /*unsigned short *Buffer; unsigned short *swizzled_pixels = NULL; int OutBytesPerPixel; int Power2Width = 0; int Power2Height = 0; png_structp png_ptr; png_infop info_ptr; unsigned int sig_read = 0; png_uint_32 width, height,x, y; int bit_depth, color_type, interlace_type; unsigned int* line; FILE *fp; if(ColorMode == GU_PSM_4444 || ColorMode == GU_PSM_5650 || ColorMode == GU_PSM_5551) OutBytesPerPixel = 2; else OutBytesPerPixel = 4; if ((fp = fopen(filename, "rb")) == NULL) { printf("Can't open file %s\n",filename); return NULL; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fclose(fp); return NULL; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); return NULL; } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, sig_read); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL); png_set_strip_16(png_ptr); png_set_packing(png_ptr); if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); line = (unsigned int*) malloc(width * 4); if (!line) { fclose(fp); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); return NULL; } Power2Width = PowerOfTwo(width); Power2Height = PowerOfTwo(height); Buffer = (unsigned short*)memalign(16,width*height*OutBytesPerPixel); for (y = 0; y < height; y++) { png_read_row(png_ptr, (unsigned char*) line, NULL); for (x = 0; x < width; x++) { unsigned int *Buffer32 = (unsigned int*)Buffer; unsigned int color32 = line[x]; unsigned short color16; if(ColorMode == GU_PSM_5551) { color16 = Color8888To5551(color32); Buffer[y*width+x] = color16; } else if(ColorMode == GU_PSM_4444) { color16 = Color8888To4444(color32); Buffer[y*width+x] = color16; } else if(ColorMode == GU_PSM_5650) { color16 = Color8888To5650(color32); Buffer[y*width+x] = color16; } else { Buffer32[y*width+x] = color32; } } } free(line); png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); fclose(fp); Image *Image1 = (Image*)malloc(sizeof(Image)); Image1->Width = width; Image1->Height = height; Image1->power2Width = Power2Width; Image1->power2Height = Power2Height; Image1->vRam = Vram; Image1->ColorMode = ColorMode; Image1->Swizzle = Swizzle; if (Vram == 1) { swizzled_pixels = (unsigned short*)getStaticVramTexture(Power2Width,Power2Height,ColorMode);//valloc(Image1->power2Height*Image1->power2Width*OutBytesPerPixel); }else { swizzled_pixels = (unsigned short*)memalign(16,Image1->power2Height*Image1->power2Width*OutBytesPerPixel); } if(Swizzle == 1) { swizzle_fast((u8*)swizzled_pixels,(const u8*)Buffer,Image1->power2Width*OutBytesPerPixel,Image1->power2Height); // 512*2 because swizzle operates in bytes, and each pixel in a 16-bit texture is 2 bytes sceKernelDcacheWritebackAll(); Image1->ImageData = swizzled_pixels; free(Buffer); }else { Image1->ImageData = Buffer; } return Image1; } Image* TextureManager::CreateImage(int width,int height,int ColorMode,int Vram) { Image *Image1 = (Image*)malloc(sizeof(Image)); Image1->Width = width; Image1->Height = height; Image1->power2Width = width; Image1->power2Height = height; Image1->vRam = Vram; Image1->ColorMode = ColorMode; int OutBytesPerPixel = 0; if(ColorMode == GU_PSM_4444 || ColorMode == GU_PSM_5650 || ColorMode == GU_PSM_5551) OutBytesPerPixel = 2; else OutBytesPerPixel = 4; if (Vram == 1) { Image1->ImageData = (unsigned short*)getStaticVramTexture(width,height,ColorMode); }else { Image1->ImageData = (unsigned short*)memalign(16,Image1->power2Height*Image1->power2Width*OutBytesPerPixel); } return Image1;*/ }
static void *psp_init(const video_info_t *video, const input_driver_t **input, void **input_data) { // to-do : add ASSERT() checks or use main RAM if VRAM is too low for desired video->input_scale void *pspinput; int pixel_format, lut_pixel_format, lut_block_count; unsigned int red_shift, color_mask; void *displayBuffer, *LUT_r, *LUT_b; psp1_video_t *psp = (psp1_video_t*)calloc(1, sizeof(psp1_video_t)); if (!psp) return NULL; sceGuInit(); psp->main_dList = memalign(16, 256); // make sure to allocate more space if bigger display lists are needed. psp->frame_dList = memalign(16, 256); psp->rgui.dList = memalign(16, 256); psp->rgui.frame = memalign(16, 2 * 480 * 272); psp->frame_coords = memalign(64, 1 * sizeof(psp1_sprite_t)); psp->rgui.frame_coords = memalign(64, 16 * sizeof(psp1_sprite_t)); memset(psp->frame_coords , 0, 1 * sizeof(psp1_sprite_t)); memset(psp->rgui.frame_coords , 0, 16 * sizeof(psp1_sprite_t)); sceKernelDcacheWritebackInvalidateAll(); psp->frame_coords = TO_UNCACHED_PTR(psp->frame_coords); psp->rgui.frame_coords = TO_UNCACHED_PTR(psp->rgui.frame_coords);; psp->frame_coords->v0.x = 60; psp->frame_coords->v0.y = 0; psp->frame_coords->v0.u = 0; psp->frame_coords->v0.v = 0; psp->frame_coords->v1.x = 420; psp->frame_coords->v1.y = SCEGU_SCR_HEIGHT; psp->frame_coords->v1.u = 256; psp->frame_coords->v1.v = 240; psp->vsync = video->vsync; psp->rgb32 = video->rgb32; if(psp->rgb32) { uint32_t* LUT_r_local = (uint32_t*)(SCEGU_VRAM_BP32_2); uint32_t* LUT_b_local = (uint32_t*)(SCEGU_VRAM_BP32_2) + (1 << 8); red_shift = 8 + 8; color_mask = 0xFF; lut_block_count = (1 << 8) / 8; psp->texture = (void*)(LUT_b_local + (1 << 8)); psp->draw_buffer = SCEGU_VRAM_BP32_0; psp->bpp_log2 = 2; pixel_format = GU_PSM_8888; lut_pixel_format = GU_PSM_T32; displayBuffer = SCEGU_VRAM_BP32_1; for (u32 i=0; i < (1 << 8); i++) { LUT_r_local[i]= i; LUT_b_local[i]= i << (8 + 8); } LUT_r = (void*)LUT_r_local; LUT_b = (void*)LUT_b_local; } else { uint16_t* LUT_r_local = (uint16_t*)(SCEGU_VRAM_BP_2); uint16_t* LUT_b_local = (uint16_t*)(SCEGU_VRAM_BP_2) + (1 << 5); red_shift = 6 + 5; color_mask = 0x1F; lut_block_count = (1 << 5) / 8; psp->texture = (void*)(LUT_b_local + (1 << 5)); psp->draw_buffer = SCEGU_VRAM_BP_0; psp->bpp_log2 = 1; pixel_format = GU_PSM_5650; lut_pixel_format = GU_PSM_T16; displayBuffer = SCEGU_VRAM_BP_1; for (u16 i = 0; i < (1 << 5); i++) { LUT_r_local[i]= i; LUT_b_local[i]= i << (5 + 6); } LUT_r = (void*)LUT_r_local; LUT_b = (void*)LUT_b_local; } sceDisplayWaitVblankStart(); // TODO : check if necessary sceGuDisplay(GU_FALSE); sceGuStart(GU_DIRECT, psp->main_dList); sceGuDrawBuffer(pixel_format, TO_GU_POINTER(psp->draw_buffer), SCEGU_VRAM_WIDTH); sceGuDispBuffer(SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT, TO_GU_POINTER(displayBuffer), SCEGU_VRAM_WIDTH); sceGuClearColor(0); sceGuScissor(0, 0, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuTexFilter(GU_LINEAR, GU_LINEAR); // TODO , move this to display list sceGuTexWrap (GU_CLAMP, GU_CLAMP); sceGuEnable(GU_TEXTURE_2D); sceGuDisable(GU_DEPTH_TEST); sceGuCallMode(GU_FALSE); sceGuFinish(); sceGuSync(0, 0); sceDisplayWaitVblankStart(); // TODO : check if necessary sceGuDisplay(GU_TRUE); pspDebugScreenSetColorMode(pixel_format); pspDebugScreenSetBase(psp->draw_buffer); // fill frame_dList : sceGuStart(GU_CALL, psp->frame_dList); sceGuTexMode(pixel_format, 0, 0, GU_FALSE); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); sceGuEnable(GU_BLEND); sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0x0000FF00, 0xFFFFFFFF); // green only sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL, (void*)(psp->frame_coords)); sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xFFFFFFFF, 0xFFFFFFFF); // restore sceGuTexMode(lut_pixel_format, 0, 0, GU_FALSE); sceGuClutMode(pixel_format, red_shift, color_mask, 0); sceGuClutLoad(lut_block_count, LUT_r); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL, (void*)(psp->frame_coords)); sceGuClutMode(pixel_format, 0, color_mask, 0); sceGuClutLoad(lut_block_count, LUT_b); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL, (void*)(psp->frame_coords)); sceGuFinish(); if (input && input_data) { pspinput = input_psp.init(); *input = pspinput ? &input_psp : NULL; *input_data = pspinput; } return psp; error: RARCH_ERR("PSP1 video could not be initialized.\n"); return (void*)-1; }
static pgeObj *pgeObjLoadInternal(unsigned char *buffer, unsigned int size) { typedef struct objVertex { float x, y, z; } objVertex; typedef objVertex objNormal; typedef struct objTexCoord { float u, v; } objTexCoord; typedef struct objTriangle { unsigned int vertex[3]; unsigned int normal[3]; unsigned int texcoord[3]; unsigned int color; } objTriangle; typedef struct objModel { unsigned int numVertex, numNormal, numTexCoord, numTriangle, numMaterial; objVertex *vertexArray; objNormal *normalArray; objTexCoord *texCoordArray; objTriangle *triangleArray; } objModel; objModel *model = pgeMalloc(sizeof(objModel)); pgeObjMtl *mtl = NULL; unsigned char *currentpos, *endpos; unsigned int position = 0; int vertpos = 0, normalpos = 0, texvertpos = 0, facepos = 0; char readbuffer[512]; char materialname[128]; currentpos = buffer; endpos = buffer + size; // Seek through file, counting number of entries we are interesting in while(currentpos != endpos) { position = 0; while((isdeadspace(*currentpos)) && (currentpos != endpos)) currentpos++; while((!iseol(*currentpos)) && (currentpos != endpos) && (position < 512)) { readbuffer[position++] = *currentpos; currentpos++; } readbuffer[position] = 0; if(strequal(readbuffer, "vn", &readbuffer[position], 2)) model->numNormal++; else if(strequal(readbuffer, "vt", &readbuffer[position], 2)) model->numTexCoord++; else if(strequal(readbuffer, "v", &readbuffer[position], 1)) model->numVertex++; else if(strequal(readbuffer, "f", &readbuffer[position], 1)) model->numTriangle++; else if(strequal(readbuffer, "mtllib", &readbuffer[position], 6)) model->numMaterial++; } // Allocate what we need if(model->numVertex > 0) { model->vertexArray = pgeMalloc(model->numVertex * sizeof(objVertex)); if(!model->vertexArray) { pgeFree(model); return NULL; } } if(model->numNormal > 0) { model->normalArray = pgeMalloc(model->numNormal * sizeof(objNormal)); if(!model->normalArray) { pgeFree(model->vertexArray); pgeFree(model); return NULL; } } if(model->numTexCoord > 0) { model->texCoordArray = pgeMalloc(model->numTexCoord * sizeof(objTexCoord)); if(!model->texCoordArray) { pgeFree(model->vertexArray); pgeFree(model->normalArray); pgeFree(model); return NULL; } } if(model->numTriangle > 0) { model->triangleArray = pgeMalloc(model->numTriangle * sizeof(objTriangle)); if(!model->triangleArray) { pgeFree(model->vertexArray); pgeFree(model->normalArray); pgeFree(model->texCoordArray); pgeFree(model); return NULL; } } // Read from the start of the file again and fill our arrays currentpos = buffer; unsigned int currentcolor = 0xFFFFFFFF; float tempnv = 0.0f; while(currentpos != endpos) { position = 0; while((isdeadspace(*currentpos)) && (currentpos != endpos)) currentpos++; while((!iseol(*currentpos)) && (currentpos != endpos) && (position < 512)) { readbuffer[position++] = *currentpos; currentpos++; } readbuffer[position] = 0; if(strequal(readbuffer, "vn", &readbuffer[position], 2)) { sscanf(readbuffer, "vn %f %f %f", &model->normalArray[normalpos].x, &model->normalArray[normalpos].y, &model->normalArray[normalpos].z); normalpos++; } else if(strequal(readbuffer, "vt", &readbuffer[position], 2)) { sscanf(readbuffer, "vt %f %f", &model->texCoordArray[texvertpos].u, &model->texCoordArray[texvertpos].v); texvertpos++; } else if(strequal(readbuffer, "v", &readbuffer[position], 1)) { sscanf(readbuffer, "v %f %f %f", &model->vertexArray[vertpos].x, &model->vertexArray[vertpos].y, &model->vertexArray[vertpos].z); vertpos++; } else if(strequal(readbuffer, "f", &readbuffer[position], 1)) { if(model->numMaterial > 0) model->triangleArray[facepos].color = currentcolor; if(model->numTexCoord > 0 && model->numNormal > 0) { sscanf(readbuffer, "f %d/%d/%d %d/%d/%d %d/%d/%d", &model->triangleArray[facepos].vertex[0], &model->triangleArray[facepos].texcoord[0], &model->triangleArray[facepos].normal[0], &model->triangleArray[facepos].vertex[1], &model->triangleArray[facepos].texcoord[1], &model->triangleArray[facepos].normal[1], &model->triangleArray[facepos].vertex[2], &model->triangleArray[facepos].texcoord[2], &model->triangleArray[facepos].normal[2]); facepos++; } else if(model->numNormal > 0) { sscanf(readbuffer, "f %d//%d %d//%d %d//%d", &model->triangleArray[facepos].vertex[0], &model->triangleArray[facepos].normal[0], &model->triangleArray[facepos].vertex[1], &model->triangleArray[facepos].normal[1], &model->triangleArray[facepos].vertex[2], &model->triangleArray[facepos].normal[2]); facepos++; } else if(model->numTexCoord > 0) { sscanf(readbuffer, "f %d/%d %d/%d %d/%d", &model->triangleArray[facepos].vertex[0], &model->triangleArray[facepos].texcoord[0], &model->triangleArray[facepos].vertex[1], &model->triangleArray[facepos].texcoord[1], &model->triangleArray[facepos].vertex[2], &model->triangleArray[facepos].texcoord[2]); facepos++; } else { sscanf(readbuffer, "f %d %d %d", &model->triangleArray[facepos].vertex[0], &model->triangleArray[facepos].vertex[1], &model->triangleArray[facepos].vertex[2]); facepos++; } } else if(strequal(readbuffer, "mtllib", &readbuffer[position], 6)) { sscanf(readbuffer, "mtllib %s", materialname); mtl = pgeObjLoadMaterial(materialname); if(!mtl) { pgeFree(model->vertexArray); pgeFree(model->normalArray); pgeFree(model->texCoordArray); pgeFree(model); return NULL; } } else if(strequal(readbuffer, "usemtl", &readbuffer[position], 6)) { sscanf(readbuffer, "usemtl %s", materialname); currentcolor = pgeObjSetColorFromMaterial(mtl, materialname); } } pgeObj *obj = (pgeObj *)pgeMalloc(sizeof(pgeObj)); if(!obj) { pgeFree(model->vertexArray); pgeFree(model->normalArray); pgeFree(model->texCoordArray); pgeFree(model->triangleArray); pgeFree(model); return NULL; } memset(obj, 0, sizeof(obj)); // Arrange the data into our vert array. obj->numvertices = model->numTriangle * 3; int i = 0; int f = 0; int v = 0; if(model->numTexCoord > 0 && model->numNormal > 0) { if(model->numMaterial == 0) { obj->vertices = (pgeVertTNV *)pgeMalloc(sizeof(pgeVertTNV) * model->numTriangle * 3); pgeVertTNV *ptr = (pgeVertTNV *)obj->vertices; obj->drawflag = GU_TEXTURE_32BITF|GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D; for(i = 0; i < model->numTriangle;i++) { for(f = 0; f < 3;f++) { ptr[v].u = model->texCoordArray[model->triangleArray[i].texcoord[f]-1].u; ptr[v].v = 1.0f - model->texCoordArray[model->triangleArray[i].texcoord[f]-1].v; ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x; ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y; ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z; tempnv = 1.0f/(pgeMathSqrt(ptr[v].x*ptr[v].x + ptr[v].y*ptr[v].y + ptr[v].z*ptr[v].z)); ptr[v].nx = ptr[v].x * tempnv; ptr[v].ny = ptr[v].y * tempnv; ptr[v].nz = ptr[v].z * tempnv; v++; } } } else { obj->vertices = (pgeVertTCNV *)pgeMalloc(sizeof(pgeVertTCNV) * model->numTriangle * 3); pgeVertTCNV *ptr = (pgeVertTCNV *)obj->vertices; obj->drawflag = GU_COLOR_8888|GU_TEXTURE_32BITF|GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D; for(i = 0; i < model->numTriangle;i++) { for(f = 0; f < 3;f++) { ptr[v].u = model->texCoordArray[model->triangleArray[i].texcoord[f]-1].u; ptr[v].v = 1.0f - model->texCoordArray[model->triangleArray[i].texcoord[f]-1].v; ptr[v].color = model->triangleArray[i].color; ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x; ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y; ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z; tempnv = 1.0f/(pgeMathSqrt(ptr[v].x*ptr[v].x + ptr[v].y*ptr[v].y + ptr[v].z*ptr[v].z)); ptr[v].nx = ptr[v].x * tempnv; ptr[v].ny = ptr[v].y * tempnv; ptr[v].nz = ptr[v].z * tempnv; v++; } } } } else if(model->numTexCoord > 0) { if(model->numMaterial == 0) { obj->vertices = (pgeVertTV *)pgeMalloc(sizeof(pgeVertTV) * model->numTriangle * 3); pgeVertTV *ptr = (pgeVertTV *)obj->vertices; obj->drawflag = GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D; for(i = 0; i < model->numTriangle;i++) { for(f = 0; f < 3;f++) { ptr[v].u = model->texCoordArray[model->triangleArray[i].texcoord[f]-1].u; ptr[v].v = 1.0f - model->texCoordArray[model->triangleArray[i].texcoord[f]-1].v; ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x; ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y; ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z; v++; } } } else { obj->vertices = (pgeVertTCV *)pgeMalloc(sizeof(pgeVertTCV) * model->numTriangle * 3); pgeVertTCV *ptr = (pgeVertTCV *)obj->vertices; obj->drawflag = GU_COLOR_8888|GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D; for(i = 0; i < model->numTriangle;i++) { for(f = 0; f < 3;f++) { ptr[v].u = model->texCoordArray[model->triangleArray[i].texcoord[f]-1].u; ptr[v].v = 1.0f - model->texCoordArray[model->triangleArray[i].texcoord[f]-1].v; ptr[v].color = model->triangleArray[i].color; ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x; ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y; ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z; v++; } } } } else if(model->numNormal > 0) { if(model->numMaterial == 0) { obj->vertices = (pgeVertNV *)pgeMalloc(sizeof(pgeVertNV) * model->numTriangle * 3); pgeVertNV *ptr = (pgeVertNV *)obj->vertices; obj->drawflag = GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D; for(i = 0; i < model->numTriangle;i++) { for(f = 0; f < 3;f++) { ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x; ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y; ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z; tempnv = 1.0f/(pgeMathSqrt(ptr[v].x*ptr[v].x + ptr[v].y*ptr[v].y + ptr[v].z*ptr[v].z)); ptr[v].nx = ptr[v].x * tempnv; ptr[v].ny = ptr[v].y * tempnv; ptr[v].nz = ptr[v].z * tempnv; v++; } } } else { obj->vertices = (pgeVertCNV *)pgeMalloc(sizeof(pgeVertCNV) * model->numTriangle * 3); pgeVertCNV *ptr = (pgeVertCNV *)obj->vertices; obj->drawflag = GU_COLOR_8888|GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D; for(i = 0; i < model->numTriangle;i++) { for(f = 0; f < 3;f++) { ptr[v].color = model->triangleArray[i].color; ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x; ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y; ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z; tempnv = 1.0f/(pgeMathSqrt(ptr[v].x*ptr[v].x + ptr[v].y*ptr[v].y + ptr[v].z*ptr[v].z)); ptr[v].nx = ptr[v].x * tempnv; ptr[v].ny = ptr[v].y * tempnv; ptr[v].nz = ptr[v].z * tempnv; v++; } } } } else { if(model->numMaterial == 0) { obj->vertices = (pgeVertV *)pgeMalloc(sizeof(pgeVertV) * model->numTriangle * 3); pgeVertV *ptr = (pgeVertV *)obj->vertices; obj->drawflag = GU_VERTEX_32BITF|GU_TRANSFORM_3D; for(i = 0; i < model->numTriangle;i++) { for(f = 0; f < 3;f++) { ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x; ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y; ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z; v++; } } } else { obj->vertices = (pgeVertCV *)pgeMalloc(sizeof(pgeVertCV) * model->numTriangle * 3); pgeVertCV *ptr = (pgeVertCV *)obj->vertices; obj->drawflag = GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D; for(i = 0; i < model->numTriangle;i++) { for(f = 0; f < 3;f++) { ptr[v].color = model->triangleArray[i].color; ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x; ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y; ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z; v++; } } } } // Tidy up if(model->vertexArray) pgeFree(model->vertexArray); if(model->normalArray) pgeFree(model->normalArray); if(model->texCoordArray) pgeFree(model->texCoordArray); if(model->triangleArray) pgeFree(model->triangleArray); if(model) pgeFree(model); if(mtl) { for(i = 0;i < mtl->nummaterials;i++) { if(mtl->materials[i].name) pgeFree(mtl->materials[i].name); if(mtl->materials) pgeFree(mtl->materials); } pgeFree(mtl); } sceKernelDcacheWritebackInvalidateAll(); return obj; }