Пример #1
0
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();
}
Пример #2
0
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");
}
Пример #3
0
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();
}
Пример #4
0
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);
}
Пример #5
0
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);
	}
Пример #6
0
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();
}
Пример #7
0
void restoreLoadExecVSHCommon()
{
	_sw( LoadExecVSHCommon_ori[0].val, LoadExecVSHCommon_ori[0].addr );
	_sw( LoadExecVSHCommon_ori[1].val, LoadExecVSHCommon_ori[1].addr );
	sceKernelIcacheInvalidateAll();
	sceKernelDcacheWritebackInvalidateAll();
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
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();
}
Пример #11
0
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();
}
Пример #12
0
// 0x00000168
int clear_cache(void)
{
	sceKernelIcacheInvalidateAll();
	sceKernelDcacheWritebackInvalidateAll();

	return 0;
}
Пример #13
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 );
}
Пример #14
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);
}
Пример #15
0
/**
 * 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;
}
Пример #16
0
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();
}
Пример #17
0
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");
}
Пример #18
0
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();
}
Пример #19
0
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");
}
Пример #20
0
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;
}
Пример #21
0
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;
}
Пример #22
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");
}
Пример #23
0
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 );
}
Пример #24
0
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;
}
Пример #25
0
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);
}
Пример #26
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;
}
Пример #27
0
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 );
}
Пример #28
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;*/
		}
Пример #29
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->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;
}
Пример #30
0
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;
}