void GPU_SetTexture2(u32* data, u16 width, u16 height, u32 param, GPU_TEXCOLOR colorType) { GPUCMD_AddSingleParam(0x000F009E, colorType); GPUCMD_AddSingleParam(0x000F009D, ((u32)data)>>3); GPUCMD_AddSingleParam(0x000F009A, (width)|(height<<16)); GPUCMD_AddSingleParam(0x000F009B, param); }
void GPUCMD_Finalize() { GPUCMD_AddSingleParam(0x0008025E, 0x00000000); GPUCMD_AddSingleParam(0x000F0111, 0x00000001); GPUCMD_AddSingleParam(0x000F0110, 0x00000001); GPUCMD_AddSingleParam(0x000F0010, 0x12345678); }
void GPU_SetUniform(u32 startreg, u32* data, u32 numreg) { if(!data)return; GPUCMD_AddSingleParam(0x000F02C0, 0x80000000|startreg); GPUCMD_Add(0x000F02C1, data, numreg*4); }
void glUniform4fv(GLint location, GLsizei count, const GLfloat* value) { ctrglFlushState(GL_SHADER_PROGRAM_CTR); GPUCMD_AddSingleParam(0x000F02C0, 0x80000000 | location); GPUCMD_Add(0x000F02C1, (u32*) value, count * 4); }
// topscreen void renderFrame() { GPU_SetViewport((u32*)osConvertVirtToPhys((u32)gpuDOut),(u32*)osConvertVirtToPhys((u32)gpuOut),0,0,240*2,400); GPU_DepthRange(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_BACK_CCW); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); GPU_SetStencilOp(GPU_KEEP, GPU_KEEP, GPU_KEEP); GPU_SetBlendingColor(0,0,0,0); GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL); GPUCMD_AddSingleParam(0x00010062, 0); GPUCMD_AddSingleParam(0x000F0118, 0); //setup shader SHDR_UseProgram(shader, 0); GPU_SetAlphaBlending(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00); GPU_SetTextureEnable(GPU_TEXUNIT0); GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), GPU_TEVOPERANDS(0,0,0), GPU_TEVOPERANDS(0,0,0), GPU_MODULATE, GPU_MODULATE, 0xFFFFFFFF); GPU_SetDummyTexEnv(1); GPU_SetDummyTexEnv(2); GPU_SetDummyTexEnv(3); GPU_SetDummyTexEnv(4); GPU_SetDummyTexEnv(5); //texturing stuff GPU_SetTexture(GPU_TEXUNIT0, (u32*)osConvertVirtToPhys((u32)texData),128,128,GPU_TEXTURE_MAG_FILTER(GPU_NEAREST)|GPU_TEXTURE_MIN_FILTER(GPU_NEAREST),GPU_RGBA8); GPU_SetAttributeBuffers(3, (u32*)osConvertVirtToPhys((u32)texData), GPU_ATTRIBFMT(0, 3, GPU_FLOAT)|GPU_ATTRIBFMT(1, 2, GPU_FLOAT)|GPU_ATTRIBFMT(2, 3, GPU_FLOAT), 0xFFC, 0x210, 1, (u32[]){0x00000000}, (u64[]){0x210}, (u8[]){3}); //setup lighting (this is specific to our shader) vect3Df_s lightDir=vnormf(vect3Df(cos(lightAngle), -1.0f, sin(lightAngle))); GPU_SetUniform(SHDR_GetUniformRegister(shader, "lightDirection", 0), (u32*)(float[]){0.0f, -lightDir.z, -lightDir.y, -lightDir.x}, 1);
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); }
void RenderTopScreen() { // notes on the drawing process // GPU hangs if we attempt to draw an even number of arrays :/ which is why we draw the border 'twice' // textures used here are actually 512x256. TODO: investigate if GPU_SetTexture() really has the params in the wrong order // or if we did something wrong. //general setup GPU_SetViewport((u32*)osConvertVirtToPhys((u32)gpuDOut),(u32*)osConvertVirtToPhys((u32)gpuOut),0,0,240*2,400); GPU_DepthRange(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_BACK_CCW); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00); GPU_SetDepthTest(false, GPU_ALWAYS, 0x1F); // ? GPUCMD_AddSingleParam(0x00010062, 0x00000000); //param always 0x0 according to code GPUCMD_AddSingleParam(0x000F0118, 0x00000000); //setup shader SHDR_UseProgram(shader, 0); //? GPUCMD_AddSingleParam(0x000F0100, 0x00E40100); GPUCMD_AddSingleParam(0x000F0101, 0x01010000); GPUCMD_AddSingleParam(0x000F0104, 0x00000010); //texturing stuff GPUCMD_AddSingleParam(0x0002006F, 0x00000100); GPUCMD_AddSingleParam(0x000F0080, 0x00011001); //enables/disables texturing //texenv GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE0, 0, 0), GPU_TEVSOURCES(GPU_CONSTANT, 0, 0), GPU_TEVOPERANDS(0,0,0), GPU_TEVOPERANDS(0,0,0), GPU_REPLACE, GPU_REPLACE, 0xFFFFFFFF); GPU_SetDummyTexEnv(1); GPU_SetDummyTexEnv(2); GPU_SetDummyTexEnv(3); GPU_SetDummyTexEnv(4); GPU_SetDummyTexEnv(5); //texturing stuff GPU_SetTexture((u32*)osConvertVirtToPhys((u32)BorderTex),256,512,0,GPU_RGBA8); // texture is actually 512x256 //setup matrices setUniformMatrix(0x24, mvMatrix); setUniformMatrix(0x20, projMatrix); // border GPU_SetAttributeBuffers(2, (u32*)osConvertVirtToPhys((u32)borderVertices), GPU_ATTRIBFMT(0, 3, GPU_FLOAT)|GPU_ATTRIBFMT(1, 2, GPU_FLOAT), 0xFFC, 0x10, 1, (u32[]){0x00000000}, (u64[]){0x10}, (u8[]){2}); GPU_DrawArray(GPU_TRIANGLES, 3); GPU_DrawArray(GPU_TRIANGLES, 2*3); GPU_DepthRange(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_BACK_CCW); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00); GPU_SetDepthTest(false, GPU_ALWAYS, 0x1F); GPUCMD_AddSingleParam(0x00010062, 0x00000000); GPUCMD_AddSingleParam(0x000F0118, 0x00000000); GPUCMD_AddSingleParam(0x000F0100, 0x00000100); GPUCMD_AddSingleParam(0x000F0101, 0x01010000); GPUCMD_AddSingleParam(0x000F0104, 0x00000010); //texturing stuff GPUCMD_AddSingleParam(0x0002006F, 0x00000700); // enables/disables texcoord output GPUCMD_AddSingleParam(0x000F0080, 0x00011007); //enables/disables texturing // TEXTURE ENV STAGES // --- // blending operation: (Main.Color +- (Sub.Color * Main.Alpha)) * Sub.Alpha // Main.Alpha = 0/255 depending on color math // Sub.Alpha = 128/255 depending on color div2 // note: the main/sub intensities are halved to prevent overflow during the operations. // (each TEV stage output is clamped to [0,255]) // stage 4 makes up for this // --- // STAGE 1: Out.Color = Sub.Color * Main.Alpha, Out.Alpha = Sub.Alpha + (1-Main.Alpha) (cancel out div2 when color math doesn't happen) GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE1, GPU_TEXTURE0, 0), GPU_TEVSOURCES(GPU_TEXTURE1, GPU_TEXTURE0, 0), GPU_TEVOPERANDS(0,2,0), GPU_TEVOPERANDS(0,1,0), GPU_MODULATE, GPU_ADD, 0xFFFFFFFF); // STAGE 2: Out.Color = Main.Color +- Prev.Color, Out.Alpha = Prev.Alpha GPU_SetTexEnv(1, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PREVIOUS, 0), GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), GPU_TEVOPERANDS(0,0,0), GPU_TEVOPERANDS(0,0,0), (PPU_ColorMath & 0x80) ? GPU_SUBTRACT:GPU_ADD, GPU_REPLACE, 0xFFFFFFFF); // STAGE 3: Out.Color = Prev.Color * Prev.Alpha, Out.Alpha = Prev.Alpha GPU_SetTexEnv(2, GPU_TEVSOURCES(GPU_PREVIOUS, GPU_PREVIOUS, 0), GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), GPU_TEVOPERANDS(0,2,0), GPU_TEVOPERANDS(0,0,0), GPU_MODULATE, GPU_REPLACE, 0xFFFFFFFF); // STAGE 4: Out.Color = Prev.Color + Prev.Color (doubling color intensity), Out.Alpha = Const.Alpha GPU_SetTexEnv(3, GPU_TEVSOURCES(GPU_PREVIOUS, GPU_PREVIOUS, 0), GPU_TEVSOURCES(GPU_CONSTANT, 0, 0), GPU_TEVOPERANDS(0,0,0), GPU_TEVOPERANDS(0,0,0), GPU_ADD, GPU_REPLACE, 0xFFFFFFFF); // STAGE 5: master brightness - Out.Color = Prev.Color * Bright.Alpha, Out.Alpha = Const.Alpha GPU_SetTexEnv(4, GPU_TEVSOURCES(GPU_PREVIOUS, GPU_TEXTURE2, 0), GPU_TEVSOURCES(GPU_CONSTANT, 0, 0), GPU_TEVOPERANDS(0,2,0), GPU_TEVOPERANDS(0,0,0), GPU_MODULATE, GPU_REPLACE, 0xFFFFFFFF); // STAGE 6: dummy GPU_SetDummyTexEnv(5); GPU_SetAttributeBuffers(3, (u32*)osConvertVirtToPhys((u32)screenVertices), GPU_ATTRIBFMT(0, 3, GPU_FLOAT)|GPU_ATTRIBFMT(1, 2, GPU_FLOAT)|GPU_ATTRIBFMT(2, 2, GPU_FLOAT), 0xFFC, 0x210, 1, (u32[]){0x00000000}, (u64[]){0x210}, (u8[]){3}); GPU_SetTexture((u32*)osConvertVirtToPhys((u32)MainScreenTex),256,512,0,GPU_RGBA8); GPU_SetTexture1((u32*)osConvertVirtToPhys((u32)SubScreenTex),256,512,0,GPU_RGBA8); GPU_SetTexture2((u32*)osConvertVirtToPhys((u32)BrightnessTex),256,8,0x200,GPU_A8); GPU_DrawArray(GPU_TRIANGLES, 2*3); }