void GPU_Reset(u32* gxbuf, u32* gpuBuf, u32 gpuBufSize) { int i; static u32 param[0x80]; static u32 zero[0x80]; memset(zero, 0x00, 0x80*4); GPUCMD_SetBuffer(gpuBuf, gpuBufSize, 0); GPUCMD_AddSingleParam(0x000D0080, 0x00011000); for(i=0x1;i<0xC;i++)GPUCMD_AddSingleParam(0x000F0080+i, 0x00000000); GPUCMD_AddSingleParam(0x000F008C, 0x00FF0000); GPUCMD_AddSingleParam(0x000F008D, 0x00000000); GPUCMD_AddSingleParam(0x000F008E, 0x00000000); for(i=0x0;i<0xF;i++)GPUCMD_AddSingleParam(0x000F0090+i, 0x00000000); GPUCMD_AddSingleParam(0x00010245, 0x00000001); GPUCMD_AddSingleParam(0x00010244, 0x00000000); GPUCMD_AddSingleParam(0x00080289, 0x80000000); GPUCMD_AddSingleParam(0x000B0229, 0x00000000); GPUCMD_AddSingleParam(0x000F0252, 0x00000000); GPUCMD_AddSingleParam(0x000F0251, 0x00000000); GPUCMD_AddSingleParam(0x000F0254, 0x00000000); GPUCMD_AddSingleParam(0x00010253, 0x00000000); GPUCMD_AddSingleParam(0x000F0242, 0x00000000); GPUCMD_AddSingleParam(0x000F024A, 0x00000000); GPUCMD_AddSingleParam(0x0005025E, 0x00000000); GPUCMD_Add(0x800F0101, zero, 0x00000007); GPUCMD_AddSingleParam(0x000F011F, 0x00010140); GPUCMD_AddSingleParam(0x000F0100, 0x00E40100); GPUCMD_AddSingleParam(0x000F0101, 0x01010000); GPUCMD_AddSingleParam(0x000F0107, 0x00001F40); GPUCMD_AddSingleParam(0x000F0105, 0xFF00FF10); GPUCMD_AddSingleParam(0x00010061, 0x00000003); GPUCMD_AddSingleParam(0x00010062, 0x00000000); GPUCMD_AddSingleParam(0x000F0065, 0x00000000); GPUCMD_AddSingleParam(0x000F0066, 0x00000000); GPUCMD_AddSingleParam(0x000F0067, 0x00000000); GPUCMD_AddSingleParam(0x00010118, 0x00000000); GPUCMD_AddSingleParam(0x000F011B, 0x00000000); GPUCMD_AddSingleParam(0x0007006A, 0x00FFFFFF); GPUCMD_AddSingleParam(0x000F0102, 0x00000003); GPUCMD_AddSingleParam(0x00080126, 0x03000000); GPUCMD_Add(0x800F0040, zero, 0x00000010); param[0x0]=0x1F1F1F1F; param[0x1]=0x1F1F1F1F; param[0x2]=0x1F1F1F1F; param[0x3]=0x1F1F1F1F; param[0x4]=0x1F1F1F1F; param[0x5]=0x1F1F1F1F; param[0x6]=0x1F1F1F1F; GPUCMD_Add(0x800F0050, param, 0x00000007); GPUCMD_AddSingleParam(0x000F0058, 0x00000100); GPUCMD_AddSingleParam(0x000F004C, 0x00000001); GPUCMD_AddSingleParam(0x000F006F, 0x00000000); GPUCMD_AddSingleParam(0x00020060, 0x00000000); GPUCMD_AddSingleParam(0x000C0069, 0x00020000); GPUCMD_AddSingleParam(0x000F0113, 0x0000000F); GPUCMD_AddSingleParam(0x000F0112, 0x0000000F); GPUCMD_AddSingleParam(0x000F0114, 0x00000003); GPUCMD_AddSingleParam(0x000F0115, 0x00000003); GPUCMD_AddSingleParam(0x000F01C5, 0x00000000); for(i=0;i<32;i++)GPUCMD_Add(0x800F01C8, zero, 0x00000008); GPUCMD_AddSingleParam(0x000F01C5, 0x00000100); for(i=0;i<32;i++)GPUCMD_Add(0x800F01C8, zero, 0x00000008); GPUCMD_AddSingleParam(0x000F01C5, 0x00000200); for(i=0;i<32;i++)GPUCMD_Add(0x800F01C8, zero, 0x00000008); GPUCMD_AddSingleParam(0x000F01C5, 0x00000300); for(i=0;i<32;i++)GPUCMD_Add(0x800F01C8, zero, 0x00000008); GPUCMD_AddSingleParam(0x000F01C5, 0x00000400); for(i=0;i<32;i++)GPUCMD_Add(0x800F01C8, zero, 0x00000008); GPUCMD_AddSingleParam(0x000F01C5, 0x00000500); for(i=0;i<32;i++)GPUCMD_Add(0x800F01C8, zero, 0x00000008); GPUCMD_AddSingleParam(0x000F01C5, 0x00000600); for(i=0;i<32;i++)GPUCMD_Add(0x800F01C8, zero, 0x00000008); GPUCMD_AddSingleParam(0x000F0290, 0x80000000); for(i=0;i<48;i++)GPUCMD_Add(0x800F0291, zero, 0x00000008); GPUCMD_AddSingleParam(0x000F02CB, 0x00000000); for(i=0;i<4;i++)GPUCMD_Add(0x000F02CC, zero, 0x00000080); GPUCMD_AddSingleParam(0x000F029B, 0x00000200); for(i=0;i<28;i++)GPUCMD_Add(0x000F029C, zero, 0x00000080); GPUCMD_AddSingleParam(0x000F02BF, 0x00000000); GPUCMD_AddSingleParam(0x000F02B1, 0x00000000); GPUCMD_AddSingleParam(0x000F02B2, 0x00000000); GPUCMD_AddSingleParam(0x000F02B3, 0x00000000); GPUCMD_AddSingleParam(0x000F02B4, 0x00000000); param[0x0]=0xFFFFFFFF; param[0x1]=0xFFFFFFFF; GPUCMD_Add(0x800F028B, param, 0x00000002); GPUCMD_Add(0x800F0205, zero, 0x00000024); for(i=0;i<gpuResetSequenceLength;i++)GPUCMD_AddSingleParam(gpuResetSequence[i*2],gpuResetSequence[i*2+1]); GPUCMD_Finalize(); GPUCMD_Run(gpuBuf); }
int main() { int i, x, y; touchPosition lastTouch; u32 repeatkeys = 0; int repeatstate = 0; int repeatcount = 0; running = 0; pause = 0; exitemu = 0; PPU_Init(); srvInit(); aptInit(); aptOpenSession(); APT_SetAppCpuTimeLimit(NULL, 30); // enables syscore usage aptCloseSession(); gfxInit(); hidInit(NULL); fsInit(); GPU_Init(NULL); gpuCmdSize = 0x40000; gpuCmd = (u32*)linearAlloc(gpuCmdSize*4); GPU_Reset(gxCmdBuf, gpuCmd, gpuCmdSize); shader = SHDR_ParseSHBIN((u32*)blarg_shbin, blarg_shbin_size); GX_SetMemoryFill(gxCmdBuf, (u32*)gpuOut, 0x404040FF, (u32*)&gpuOut[0x2EE00], 0x201, (u32*)gpuDOut, 0x00000000, (u32*)&gpuDOut[0x2EE00], 0x201); gfxSwapBuffersGpu(); UI_SetFramebuffer(gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL)); BorderTex = (u32*)linearAlloc(512*256*4); MainScreenTex = (u32*)linearAlloc(512*256*4); SubScreenTex = (u32*)linearAlloc(512*256*4); BrightnessTex = (u8*)linearAlloc(8*256); borderVertices = (float*)linearAlloc(5*3 * 2 * sizeof(float)); screenVertices = (float*)linearAlloc(7*3 * 2 * sizeof(float)); float* fptr = &vertexList[0]; for (i = 0; i < 5*3*2; i++) borderVertices[i] = *fptr++; for (i = 0; i < 7*3*2; i++) screenVertices[i] = *fptr++; sdmcArchive = (FS_archive){0x9, (FS_path){PATH_EMPTY, 1, (u8*)""}}; FSUSER_OpenArchive(NULL, &sdmcArchive); if (!LoadBorder("/blargSnesBorder.bmp")) CopyBitmapToTexture(defaultborder, BorderTex, 400, 240, 0xFF, 0, 64, true); CopyBitmapToTexture(screenfill, PPU_MainBuffer, 256, 224, 0, 16, 64, false); memset(PPU_SubBuffer, 0, 256*256*4); memset(PPU_Brightness, 0xFF, 224); UI_Switch(&UI_ROMMenu); svcCreateEvent(&SPCSync, 0); aptSetupEventHandler(); APP_STATUS status; while((status = aptGetStatus()) != APP_EXITING) { if(status == APP_RUNNING) { svcSignalEvent(SPCSync); hidScanInput(); u32 press = hidKeysDown(); u32 held = hidKeysHeld(); u32 release = hidKeysUp(); GPUCMD_SetBuffer(gpuCmd, gpuCmdSize, 0); RenderTopScreen(); GPUCMD_Finalize(); GPUCMD_Run(gxCmdBuf); if (running) { // emulate CPU_Run(); // runs the SNES for one frame. Handles PPU rendering. // SRAM autosave check // TODO: also save SRAM under certain circumstances (pausing, returning to home menu, etc) framecount++; if (!(framecount & 7)) SNES_SaveSRAM(); } else { // update UI if (held & KEY_TOUCH) { hidTouchRead(&lastTouch); UI_Touch(true, lastTouch.px, lastTouch.py); held &= ~KEY_TOUCH; } else if (release & KEY_TOUCH) { UI_Touch(false, lastTouch.px, lastTouch.py); release &= ~KEY_TOUCH; } if (press) { UI_ButtonPress(press); // key repeat repeatkeys = press & (KEY_UP|KEY_DOWN|KEY_LEFT|KEY_RIGHT); repeatstate = 1; repeatcount = 15; } else if (held == repeatkeys) { repeatcount--; if (!repeatcount) { repeatcount = 7; if (repeatstate == 2) UI_ButtonPress(repeatkeys); else repeatstate = 2; } } } UI_SetFramebuffer(gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL)); UI_Render(); /*GPUCMD_SetBuffer(gpuCmd, gpuCmdSize, 0); RenderTopScreen(); GPUCMD_Finalize(); GPUCMD_Run(gxCmdBuf);*/ // flush the bottomscreen cache while the PICA200 is busy rendering GSPGPU_FlushDataCache(NULL, gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL), 0x38400); // wait for the PICA200 to finish drawing gspWaitForP3D(); // copy new screen textures // SetDisplayTransfer with flags=2 converts linear graphics to the tiled format used for textures GX_SetDisplayTransfer(gxCmdBuf, PPU_MainBuffer, 0x01000200, MainScreenTex, 0x01000200, 0x2); gspWaitForPPF(); GX_SetDisplayTransfer(gxCmdBuf, PPU_SubBuffer, 0x01000200, SubScreenTex, 0x01000200, 0x2); gspWaitForPPF(); // copy brightness. // TODO do better u8* bptr = BrightnessTex; for (i = 0; i < 224;) { u32 pixels = *(u32*)&PPU_Brightness[i]; i += 4; *bptr = (u8)pixels; pixels >>= 8; bptr += 2; *bptr = (u8)pixels; pixels >>= 8; bptr += 6; *bptr = (u8)pixels; pixels >>= 8; bptr += 2; *bptr = (u8)pixels; pixels >>= 8; bptr += 22; } // transfer the final color buffer to the LCD and clear it // we can mostly overlap those two operations GX_SetDisplayTransfer(gxCmdBuf, gpuOut, 0x019001E0, (u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), 0x019001E0, 0x01001000); svcSleepThread(20000); GX_SetMemoryFill(gxCmdBuf, gpuOut, 0x404040FF, &gpuOut[0x2EE00], 0x201, gpuDOut, 0x00000000, &gpuDOut[0x2EE00], 0x201); gspWaitForPPF(); gspWaitForPSC0(); gspWaitForEvent(GSPEVENT_VBlank0, false); gfxSwapBuffersGpu(); } else if(status == APP_SUSPENDING)