static void myGPU_SetTexture(GPU_TEXUNIT unit, u32 data, u16 width, u16 height, u32 param, GPU_TEXCOLOR colorType) { u32 iunit = unit; u32 iwidth = width; u32 iheight = height; u32 icolor = colorType; DBGPRINT("set: %d %d %d %d %08x %08x\n", ctr_state.client_texture_current, iwidth, iheight, icolor, data, data >> 3); //svcSleepThread(1000000000); #ifdef _3DS switch (unit) { case GPU_TEXUNIT0: GPUCMD_AddWrite(GPUREG_TEXUNIT0_TYPE, icolor); GPUCMD_AddWrite(GPUREG_TEXUNIT0_ADDR1, (data) >> 3); GPUCMD_AddWrite(GPUREG_TEXUNIT0_DIM, (iwidth << 16) | iheight); GPUCMD_AddWrite(GPUREG_TEXUNIT0_PARAM, param); break; case GPU_TEXUNIT1: GPUCMD_AddWrite(GPUREG_TEXUNIT1_TYPE, icolor); GPUCMD_AddWrite(GPUREG_TEXUNIT1_ADDR, (data) >> 3); GPUCMD_AddWrite(GPUREG_TEXUNIT1_DIM, (iwidth << 16) | iheight); GPUCMD_AddWrite(GPUREG_TEXUNIT1_PARAM, param); break; case GPU_TEXUNIT2: GPUCMD_AddWrite(GPUREG_TEXUNIT2_TYPE, icolor); GPUCMD_AddWrite(GPUREG_TEXUNIT2_ADDR, (data) >> 3); GPUCMD_AddWrite(GPUREG_TEXUNIT2_DIM, (iwidth << 16) | iheight); GPUCMD_AddWrite(GPUREG_TEXUNIT2_PARAM, param); break; } #endif }
void gpuFrameBegin(void) { // Configure the viewport and the depth linear conversion function GPU_SetViewport( (u32*)osConvertVirtToPhys((u32)depthBuf), (u32*)osConvertVirtToPhys((u32)colorBuf), 0, 0, 240, 400); // The top screen is physically 240x400 pixels GPU_DepthMap(-1.0f, 0.0f); // calculate the depth value from the Z coordinate in the following way: -1.0*z + 0.0 // Configure some boilerplate 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); // This is unknown GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0); GPUCMD_AddWrite(GPUREG_0118, 0); // Configure alpha blending and test 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); int i; for (i = 0; i < 6; i ++) GPU_SetDummyTexEnv(i); }
void C3D_ImmDrawBegin(GPU_Primitive_t primitive) { C3Di_UpdateContext(); // Set primitive type GPUCMD_AddMaskedWrite(GPUREG_PRIMITIVE_CONFIG, 2, primitive); // Start a new primitive (breaks off a triangle strip/fan) GPUCMD_AddWrite(GPUREG_RESTART_PRIMITIVE, 1); // Not sure if this command is necessary GPUCMD_AddWrite(GPUREG_INDEXBUFFER_CONFIG, 0x80000000); // Enable vertex submission mode GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG2, 1, 1); // Enable drawing mode GPUCMD_AddMaskedWrite(GPUREG_START_DRAW_FUNC0, 1, 0); // Begin immediate-mode vertex submission GPUCMD_AddWrite(GPUREG_FIXEDATTRIB_INDEX, 0xF); }
void C3D_ImmDrawEnd(void) { // Go back to configuration mode GPUCMD_AddMaskedWrite(GPUREG_START_DRAW_FUNC0, 1, 1); // Disable vertex submission mode GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG2, 1, 0); // Clear the post-vertex cache GPUCMD_AddWrite(GPUREG_VTX_FUNC, 1); C3Di_GetContext()->flags |= C3DiF_DrawUsed; }
void sf2d_start_frame(gfxScreen_t screen, gfx3dSide_t side) { sf2d_pool_reset(); GPUCMD_SetBufferOffset(0); // Only upload the uniform if the screen changes if (screen != cur_screen) { if (screen == GFX_TOP) { matrix_gpu_set_uniform(ortho_matrix_top, projection_desc); } else { matrix_gpu_set_uniform(ortho_matrix_bot, projection_desc); } cur_screen = screen; } int screen_w; if (screen == GFX_TOP) { screen_w = 400; cur_side = side; } else { screen_w = 320; } GPU_SetViewport((u32 *)osConvertVirtToPhys((u32)gpu_depth_fb_addr), (u32 *)osConvertVirtToPhys((u32)gpu_fb_addr), 0, 0, 240, screen_w); GPU_DepthMap(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_NONE); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP); GPU_SetBlendingColor(0,0,0,0); GPU_SetDepthTestAndWriteMask(true, GPU_GEQUAL, GPU_WRITE_ALL); GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0); GPUCMD_AddWrite(GPUREG_0118, 0); GPU_SetAlphaBlending( GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ZERO ); GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00); GPU_SetDummyTexEnv(1); GPU_SetDummyTexEnv(2); GPU_SetDummyTexEnv(3); GPU_SetDummyTexEnv(4); GPU_SetDummyTexEnv(5); }
void drawPlayerGun(player_s* p) { if(!p)return; gsPushMatrix(); useCamera(&p->camera); gsLoadIdentity(); GPU_SetDepthTestAndWriteMask(true, GPU_ALWAYS, GPU_WRITE_DEPTH); gsSwitchRenderMode(-1); GPU_SetAttributeBuffers( 2, // number of attributes (u32*)osConvertVirtToPhys(rectangleBaseAddr), // we use the start of linear heap as base since that's where all our buffers are located GPU_ATTRIBFMT(0, 3, GPU_FLOAT)|GPU_ATTRIBFMT(1, 2, GPU_FLOAT), // we want v0 (vertex position) and v1 (texcoord) 0xFFC, // mask : we want v0 and v1 0x10, // permutation : we use identity 1, // number of buffers : we have one attribute per buffer (u32[]){(u32)rectangleVertexData-rectangleBaseAddr}, // buffer offsets (placeholders) (u64[]){0x10}, // attribute permutations for each buffer (u8[]){2} // number of attributes for each buffer ); gsSetShader(&passthroughProgram); GPU_DrawArray(GPU_TRIANGLES, 6); GPU_SetDepthTestAndWriteMask(true, GPU_ALWAYS, GPU_WRITE_ALL); GPUCMD_AddWrite(GPUREG_ATTRIBBUFFER0_CONFIG0, (u32)crosshairVertexData-rectangleBaseAddr); textureBind(&crosshairTexture, GPU_TEXUNIT0); GPU_DrawArray(GPU_TRIANGLES, 6); GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL); gsSwitchRenderMode(md2GsMode); gsTranslate(1.3, -1.65, -3.1); gsRotateY(p->tempAngle.y); gsRotateX(-p->tempAngle.x); gsRotateX(-0.1); gsRotateZ(M_PI/2); gsRotateY(-M_PI/2); gsRotateX(-M_PI/2); gsScale(3.0f/8, 3.0f/8, 3.0f/8); md2InstanceDraw(&p->gunInstance); gsPopMatrix(); }
void C3D_UpdateUniforms(GPU_SHADER_TYPE type) { int offset = type == GPU_GEOMETRY_SHADER ? (GPUREG_GSH_BOOLUNIFORM-GPUREG_VSH_BOOLUNIFORM) : 0; int i = 0; // Update FVec uniforms that come from shader constants if (C3Di_ShaderFVecData[type].dirty) { while (i < C3Di_ShaderFVecData[type].count) { float24Uniform_s* u = &C3Di_ShaderFVecData[type].data[i++]; GPUCMD_AddIncrementalWrites(GPUREG_VSH_FLOATUNIFORM_CONFIG+offset, (u32*)u, 4); C3D_FVUnifDirty[type][u->id] = false; } C3Di_ShaderFVecData[type].dirty = false; i = 0; } // Update FVec uniforms while (i < C3D_FVUNIF_COUNT) { if (!C3D_FVUnifDirty[type][i]) { i ++; continue; } // Find the number of consecutive dirty uniforms int j; for (j = i; j < C3D_FVUNIF_COUNT && C3D_FVUnifDirty[type][j]; j ++); // Upload the uniforms GPUCMD_AddWrite(GPUREG_VSH_FLOATUNIFORM_CONFIG+offset, 0x80000000|i); GPUCMD_AddWrites(GPUREG_VSH_FLOATUNIFORM_DATA+offset, (u32*)&C3D_FVUnif[type][i], (j-i)*4); // Clear the dirty flag int k; for (k = i; k < j; k ++) { C3D_FVUnifDirty[type][k] = false; C3Di_FVUnifEverDirty[type][k] = true; } // Advance i += j; } // Update IVec uniforms for (i = 0; i < C3D_IVUNIF_COUNT; i ++) { if (!C3D_IVUnifDirty[type][i]) continue; GPUCMD_AddWrite(GPUREG_VSH_INTUNIFORM_I0+offset+i, C3D_IVUnif[type][i]); C3D_IVUnifDirty[type][i] = false; C3Di_IVUnifEverDirty[type][i] = false; } // Update bool uniforms if (C3D_BoolUnifsDirty[type]) { GPUCMD_AddWrite(GPUREG_VSH_BOOLUNIFORM+offset, 0x7FFF0000 | C3D_BoolUnifs[type]); C3D_BoolUnifsDirty[type] = false; } }
void draw(void) { // WARNING: DO **NOT** USE ANY C3D STUFF, ESPECIALLY NOTHING EFFECT RELATED! // FIXME: Enable alpha blend for 50% mixing with BG GPUCMD_AddWrite(GPUREG_BLEND_COLOR, color_blend ? 0x7F7F7F7F : 0x00000000); GPUCMD_AddWrite(GPUREG_BLEND_FUNC, (GPU_BLEND_ADD << 0) | (GPU_BLEND_ADD << 8) | (GPU_ONE_MINUS_CONSTANT_COLOR << 16) | (GPU_CONSTANT_COLOR << 20) | (GPU_ONE_MINUS_CONSTANT_ALPHA << 24) | (GPU_CONSTANT_ALPHA << 28)); GPUCMD_AddWrite(GPUREG_COLOR_OPERATION, (0x0E4 << 24) | (1 << 8)); uint32_t compare_mode = test_high ? GPU_GREATER : GPU_LESS; // Set color and depth mask + depth test { uint32_t mask_reg = (depth_mask ? 1 << 12 : 0) | ((color_mask & 0xF) << 8); GPUCMD_AddWrite(GPUREG_DEPTH_COLOR_MASK, mask_reg | ((compare_mode & 7) << 4) | (!!depth_test)); } // Set stencil mask + stencil test { uint32_t buffer_mask = stencil_mask ? 0x2A : 0x00; // Mask used for buffer write uint32_t mask = 0xFF; // Mask for comparison uint32_t ref = 0x80; GPUCMD_AddWrite(GPUREG_STENCIL_TEST, ((mask & 0xFF) << 24) | ((ref & 0xFF) << 16) | ((buffer_mask & 0xFF) << 8) | ((compare_mode & 7) << 4) | (!!stencil_test)); //0-2 unsigned, Fail operation //4-6 unsigned, Z-fail operation //8-10 unsigned, Z-pass operation GPUCMD_AddWrite(GPUREG_STENCIL_OP, (GPU_STENCIL_INVERT << 8) | (GPU_STENCIL_INVERT << 4) | (GPU_STENCIL_KEEP << 0)); } // Allow functions.. GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_READ, (depth_read_allow ? 2 : 0) | (stencil_read_allow ? 1 : 0)); GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_WRITE, (depth_write_allow ? 2 : 0) | (stencil_write_allow ? 1 : 0)); GPUCMD_AddWrite(GPUREG_COLORBUFFER_READ, color_read_allow); GPUCMD_AddWrite(GPUREG_COLORBUFFER_WRITE, color_write_allow); // Configure depth values (= will always return 0.5) bool w_buffer = true; float depth_scale = -1.0f; float depth_offset = 0.0f; #if 1 GPUCMD_AddWrite(GPUREG_DEPTHMAP_ENABLE, w_buffer ? 0x00000000 : 0x00000001); GPUCMD_AddWrite(GPUREG_DEPTHMAP_SCALE, f32tof24(depth_scale)); GPUCMD_AddWrite(GPUREG_DEPTHMAP_OFFSET, f32tof24(depth_offset)); #endif // Draw the VBO C3D_DrawArrays(GPU_TRIANGLES, 0, 3); }
static void* ctr_init(const video_info_t* video, const input_driver_t** input, void** input_data) { void* ctrinput = NULL; ctr_video_t* ctr = (ctr_video_t*)linearAlloc(sizeof(ctr_video_t)); if (!ctr) return NULL; // gfxInitDefault(); // gfxSet3D(false); memset(ctr, 0, sizeof(ctr_video_t)); ctr->display_list_size = 0x40000; ctr->display_list = linearAlloc(ctr->display_list_size * sizeof(uint32_t)); GPU_Reset(NULL, ctr->display_list, ctr->display_list_size); ctr->texture_width = 512; ctr->texture_height = 512; ctr->texture_linear = linearMemAlign(ctr->texture_width * ctr->texture_height * sizeof(uint32_t), 128); ctr->texture_swizzled = linearMemAlign(ctr->texture_width * ctr->texture_height * sizeof(uint32_t), 128); ctr->frame_coords = linearAlloc(sizeof(ctr_vertex_t)); ctr->frame_coords->x0 = 0; ctr->frame_coords->y0 = 0; ctr->frame_coords->x1 = CTR_TOP_FRAMEBUFFER_WIDTH; ctr->frame_coords->y1 = CTR_TOP_FRAMEBUFFER_HEIGHT; ctr->frame_coords->u = CTR_TOP_FRAMEBUFFER_WIDTH; ctr->frame_coords->v = CTR_TOP_FRAMEBUFFER_HEIGHT; GSPGPU_FlushDataCache(NULL, (u8*)ctr->frame_coords, sizeof(ctr_vertex_t)); ctr->menu.texture_width = 512; ctr->menu.texture_height = 512; ctr->menu.texture_linear = linearMemAlign(ctr->texture_width * ctr->texture_height * sizeof(uint16_t), 128); ctr->menu.texture_swizzled = linearMemAlign(ctr->texture_width * ctr->texture_height * sizeof(uint16_t), 128); ctr->menu.frame_coords = linearAlloc(sizeof(ctr_vertex_t)); ctr->menu.frame_coords->x0 = 40; ctr->menu.frame_coords->y0 = 0; ctr->menu.frame_coords->x1 = CTR_TOP_FRAMEBUFFER_WIDTH - 40; ctr->menu.frame_coords->y1 = CTR_TOP_FRAMEBUFFER_HEIGHT; ctr->menu.frame_coords->u = CTR_TOP_FRAMEBUFFER_WIDTH - 80; ctr->menu.frame_coords->v = CTR_TOP_FRAMEBUFFER_HEIGHT; GSPGPU_FlushDataCache(NULL, (u8*)ctr->menu.frame_coords, sizeof(ctr_vertex_t)); ctr_set_scale_vector(&ctr->scale_vector, CTR_TOP_FRAMEBUFFER_WIDTH, CTR_TOP_FRAMEBUFFER_HEIGHT, ctr->texture_width, ctr->texture_height); ctr_set_scale_vector(&ctr->menu.scale_vector, CTR_TOP_FRAMEBUFFER_WIDTH, CTR_TOP_FRAMEBUFFER_HEIGHT, ctr->menu.texture_width, ctr->menu.texture_height); ctr->dvlb = DVLB_ParseFile((u32*)ctr_sprite_shader_shbin, ctr_sprite_shader_shbin_size); ctrGuSetVshGsh(&ctr->shader, ctr->dvlb, 2, 2); shaderProgramUse(&ctr->shader); GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), VIRT_TO_PHYS(CTR_GPU_FRAMEBUFFER), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, CTR_TOP_FRAMEBUFFER_WIDTH); // GPU_SetViewport(NULL, // VIRT_TO_PHYS(CTR_GPU_FRAMEBUFFER), // 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, CTR_TOP_FRAMEBUFFER_WIDTH); GPU_DepthMap(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_NONE); 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); GPU_SetDepthTestAndWriteMask(false, GPU_ALWAYS, GPU_WRITE_ALL); // GPU_SetDepthTestAndWriteMask(true, GPU_ALWAYS, GPU_WRITE_ALL); GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0); GPUCMD_AddWrite(GPUREG_0118, 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, 0), GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_MODULATE, GPU_MODULATE, 0xFFFFFFFF); GPU_SetTexEnv(1, GPU_PREVIOUS,GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(2, GPU_PREVIOUS,GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(3, GPU_PREVIOUS,GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(4, GPU_PREVIOUS,GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(5, GPU_PREVIOUS,GPU_PREVIOUS, 0, 0, 0, 0, 0); ctrGuSetAttributeBuffers(2, VIRT_TO_PHYS(ctr->menu.frame_coords), CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 0 | CTRGU_ATTRIBFMT(GPU_SHORT, 2) << 4, sizeof(ctr_vertex_t)); GPUCMD_Finalize(); ctrGuFlushAndRun(true); gspWaitForEvent(GSPEVENT_P3D, false); if (input && input_data) { ctrinput = input_ctr.init(); *input = ctrinput ? &input_ctr : NULL; *input_data = ctrinput; } return ctr; }
// topscreen void renderMenuFrame(u32* outBuffer, u32* outDepthBuffer) { GPU_SetViewport((u32*)osConvertVirtToPhys((u32)outDepthBuffer),(u32*)osConvertVirtToPhys((u32)outBuffer),0,0,240,400); GPU_DepthMap(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_FRONT_CCW); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP); GPU_SetBlendingColor(0,0,0,0); GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL); GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0); GPUCMD_AddWrite(GPUREG_0118, 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); gsMatrixMode(GS_MODELVIEW); gsPushMatrix(); gsLoadIdentity(); useCamera(&menuCamera); gsSwitchRenderMode(md2GsMode); md2InstanceDraw(&gladosInstance); md2InstanceDraw(&gladosLairInstance); gsPopMatrix(); GPU_SetDepthTestAndWriteMask(true, GPU_ALWAYS, GPU_WRITE_ALL); if(currentCameraState==2) { gsPushMatrix(); gsSwitchRenderMode(-1); GPU_SetAttributeBuffers( 1, // number of attributes (u32*)osConvertVirtToPhys(logoBaseAddr), // we use the start of linear heap as base since that's where all our buffers are located GPU_ATTRIBFMT(0, 3, GPU_FLOAT), // we want v0 (vertex position) 0xFFE, // mask : we want v0 0x0, // permutation : we use identity 1, // number of buffers : we have one attribute per buffer (u32[]){(u32)logoRectangleVertexData-logoBaseAddr}, // buffer offsets (placeholders) (u64[]){0x0}, // attribute permutations for each buffer (u8[]){1} // number of attributes for each buffer ); gsSetShader(&logoProgram); gsMatrixMode(GS_MODELVIEW); gsLoadIdentity(); gsPushMatrix(); gsTranslate(0.15f, 0.325f, 0.0f); gsScale(64.0f * 2.0f / 240.0f, 64.0f * 2.0f / 400.0f, 1.0f); gsTranslate(0.5f, 0.5f, 0.0f); gsRotateZ(logoangle+=0.01f); gsTranslate(-0.5f, -0.5f, 0.0f); gsUpdateTransformation(); textureBind(&rotateLogoTexture, GPU_TEXUNIT0); GPU_SetFloatUniform(GPU_VERTEX_SHADER, logoUniformTextureDimensions, (u32*)(float[]){0.0f, 0.0f, 1.0f, 1.0f}, 1);
static void* ctr_init(const video_info_t* video, const input_driver_t** input, void** input_data) { float refresh_rate; void* ctrinput = NULL; ctr_video_t* ctr = (ctr_video_t*)linearAlloc(sizeof(ctr_video_t)); if (!ctr) return NULL; memset(ctr, 0, sizeof(ctr_video_t)); ctr->vp.x = 0; ctr->vp.y = 0; ctr->vp.width = CTR_TOP_FRAMEBUFFER_WIDTH; ctr->vp.height = CTR_TOP_FRAMEBUFFER_HEIGHT; ctr->vp.full_width = CTR_TOP_FRAMEBUFFER_WIDTH; ctr->vp.full_height = CTR_TOP_FRAMEBUFFER_HEIGHT; ctr->display_list_size = 0x400; ctr->display_list = linearAlloc(ctr->display_list_size * sizeof(uint32_t)); GPU_Reset(NULL, ctr->display_list, ctr->display_list_size); ctr->rgb32 = video->rgb32; ctr->texture_width = video->input_scale * RARCH_SCALE_BASE; ctr->texture_height = video->input_scale * RARCH_SCALE_BASE; ctr->texture_linear = linearMemAlign(ctr->texture_width * ctr->texture_height * (ctr->rgb32? 4:2), 128); ctr->texture_swizzled = linearMemAlign(ctr->texture_width * ctr->texture_height * (ctr->rgb32? 4:2), 128); ctr->frame_coords = linearAlloc(3 * sizeof(ctr_vertex_t)); ctr->frame_coords->x0 = 0; ctr->frame_coords->y0 = 0; ctr->frame_coords->x1 = CTR_TOP_FRAMEBUFFER_WIDTH; ctr->frame_coords->y1 = CTR_TOP_FRAMEBUFFER_HEIGHT; ctr->frame_coords->u0 = 0; ctr->frame_coords->v0 = 0; ctr->frame_coords->u1 = CTR_TOP_FRAMEBUFFER_WIDTH; ctr->frame_coords->v1 = CTR_TOP_FRAMEBUFFER_HEIGHT; GSPGPU_FlushDataCache(ctr->frame_coords, sizeof(ctr_vertex_t)); ctr->menu.texture_width = 512; ctr->menu.texture_height = 512; ctr->menu.texture_linear = linearMemAlign(ctr->menu.texture_width * ctr->menu.texture_height * sizeof(uint16_t), 128); ctr->menu.texture_swizzled = linearMemAlign(ctr->menu.texture_width * ctr->menu.texture_height * sizeof(uint16_t), 128); ctr->menu.frame_coords = linearAlloc(sizeof(ctr_vertex_t)); ctr->menu.frame_coords->x0 = 40; ctr->menu.frame_coords->y0 = 0; ctr->menu.frame_coords->x1 = CTR_TOP_FRAMEBUFFER_WIDTH - 40; ctr->menu.frame_coords->y1 = CTR_TOP_FRAMEBUFFER_HEIGHT; ctr->menu.frame_coords->u0 = 0; ctr->menu.frame_coords->v0 = 0; ctr->menu.frame_coords->u1 = CTR_TOP_FRAMEBUFFER_WIDTH - 80; ctr->menu.frame_coords->v1 = CTR_TOP_FRAMEBUFFER_HEIGHT; GSPGPU_FlushDataCache(ctr->menu.frame_coords, sizeof(ctr_vertex_t)); ctr_set_scale_vector(&ctr->scale_vector, CTR_TOP_FRAMEBUFFER_WIDTH, CTR_TOP_FRAMEBUFFER_HEIGHT, ctr->texture_width, ctr->texture_height); ctr_set_scale_vector(&ctr->menu.scale_vector, CTR_TOP_FRAMEBUFFER_WIDTH, CTR_TOP_FRAMEBUFFER_HEIGHT, ctr->menu.texture_width, ctr->menu.texture_height); ctr->dvlb = DVLB_ParseFile((u32*)ctr_sprite_shbin, ctr_sprite_shbin_size); ctrGuSetVshGsh(&ctr->shader, ctr->dvlb, 2, 2); shaderProgramUse(&ctr->shader); GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, CTR_TOP_FRAMEBUFFER_WIDTH); GPU_DepthMap(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_NONE); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP); GPU_SetBlendingColor(0, 0, 0, 0); // GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL); GPU_SetDepthTestAndWriteMask(false, GPU_ALWAYS, GPU_WRITE_ALL); // GPU_SetDepthTestAndWriteMask(true, GPU_ALWAYS, GPU_WRITE_ALL); GPUCMD_AddMaskedWrite(GPUREG_EARLYDEPTH_TEST1, 0x1, 0); GPUCMD_AddWrite(GPUREG_EARLYDEPTH_TEST2, 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_TEXTURE0, GPU_TEXTURE0, 0, 0, GPU_REPLACE, GPU_REPLACE, 0); GPU_SetTexEnv(1, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(2, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(3, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(4, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(5, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); ctrGuSetAttributeBuffers(2, VIRT_TO_PHYS(ctr->menu.frame_coords), CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 0 | CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 4, sizeof(ctr_vertex_t)); GPUCMD_Finalize(); ctrGuFlushAndRun(true); gspWaitForEvent(GSPGPU_EVENT_P3D, false); if (input && input_data) { ctrinput = input_ctr.init(); *input = ctrinput ? &input_ctr : NULL; *input_data = ctrinput; } ctr->keep_aspect = true; ctr->should_resize = true; ctr->smooth = video->smooth; ctr->vsync = video->vsync; ctr->lcd_buttom_on = true; ctr->current_buffer_top = 0; ctr->empty_framebuffer = linearAlloc(320 * 240 * 2); memset(ctr->empty_framebuffer, 0, 320 * 240 * 2); refresh_rate = (32730.0 * 8192.0) / 4481134.0; driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &refresh_rate); aptHook(&ctr->lcd_aptHook, ctr_lcd_aptHook, ctr); return ctr; }
static void ctr_lcd_aptHook(APT_HookType hook, void* param) { ctr_video_t *ctr = (ctr_video_t*)param; if(!ctr) return; if(hook == APTHOOK_ONRESTORE) { GPUCMD_SetBufferOffset(0); shaderProgramUse(&ctr->shader); GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, CTR_TOP_FRAMEBUFFER_WIDTH); GPU_DepthMap(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_NONE); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP); GPU_SetBlendingColor(0, 0, 0, 0); GPU_SetDepthTestAndWriteMask(false, GPU_ALWAYS, GPU_WRITE_ALL); GPUCMD_AddMaskedWrite(GPUREG_EARLYDEPTH_TEST1, 0x1, 0); GPUCMD_AddWrite(GPUREG_EARLYDEPTH_TEST2, 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_TEXTURE0, GPU_TEXTURE0, 0, 0, GPU_REPLACE, GPU_REPLACE, 0); GPU_SetTexEnv(1, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(2, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(3, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(4, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(5, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); ctrGuSetAttributeBuffers(2, VIRT_TO_PHYS(ctr->menu.frame_coords), CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 0 | CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 4, sizeof(ctr_vertex_t)); GPUCMD_Finalize(); ctrGuFlushAndRun(true); gspWaitForEvent(GSPGPU_EVENT_P3D, false); } if((hook == APTHOOK_ONSUSPEND) && (ctr->video_mode == CTR_VIDEO_MODE_400x240)) { memcpy(gfxTopRightFramebuffers[ctr->current_buffer_top], gfxTopLeftFramebuffers[ctr->current_buffer_top], 400 * 240 * 3); GSPGPU_FlushDataCache(gfxTopRightFramebuffers[ctr->current_buffer_top], 400 * 240 * 3); } if ((hook == APTHOOK_ONSUSPEND)) ctr_set_parallax_layer(*(float*)0x1FF81080 != 0.0); if((hook == APTHOOK_ONSUSPEND) || (hook == APTHOOK_ONRESTORE)) { Handle lcd_handle; u8 not_2DS; CFGU_GetModelNintendo2DS(¬_2DS); if(not_2DS && srvGetServiceHandle(&lcd_handle, "gsp::Lcd") >= 0) { u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = ((hook == APTHOOK_ONSUSPEND) || ctr->lcd_buttom_on)? 0x00110040: 0x00120040; cmdbuf[1] = 2; svcSendSyncRequest(lcd_handle); svcCloseHandle(lcd_handle); } } }