void draw() { startFrame(); sceGuTexMode(GU_PSM_T8, 0, 0, GU_FALSE); sceGuTexFilter(GU_NEAREST, GU_NEAREST); sceGuTexFunc(GU_TFX_DECAL, GU_TCC_RGB); sceGuClutMode(GU_PSM_8888, 0, 0xFF, 0); sceGuTexImage(0, 2, 2, 16, imageDataPatch); sceGuClutLoad(1, clutRGBY); sceGuPatchPrim(GU_TRIANGLE_STRIP); sceGuPatchDivide(16, 16); sceGuPatchFrontFace(GU_CW); sceGuDisable(GU_TEXTURE_2D); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices1_simple); // Let's see how UVs are interpolated. Simple bilinear will fail here. sceGuEnable(GU_TEXTURE_2D); sceGuDrawBezier(GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices2_uvs); sceGuDisable(GU_TEXTURE_2D); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices3_colors); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices4_pos); // Other primitive types. sceGuSendCommandi(55, 1); sceGuPatchDivide(4, 4); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices5_lines); sceGuSendCommandi(55, 2); sceGuPatchDivide(4, 4); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices6_points); sceGuSendCommandi(55, 3); sceGuPatchDivide(4, 4); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices7_prim3); sceGuSendCommandi(55, 4); sceGuPatchDivide(4, 4); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices8_prim4); sceGuPatchPrim(GU_TRIANGLE_STRIP); sceGuShadeModel(GU_FLAT); sceGuPatchDivide(1, 1); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices9_div1); sceGuPatchDivide(1, 2); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices10_div1_2); sceGuPatchDivide(2, 2); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices11_div2); sceGuPatchDivide(4, 4); sceGuShadeModel(GU_SMOOTH); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 2, NULL, vertices12_4x2); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 5, NULL, vertices13_4x5); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 8, NULL, vertices14_4x8); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D | GU_INDEX_8BIT, 4, 4, indices15_inds8, vertices15_inds8); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D | GU_INDEX_16BIT, 4, 4, indices16_inds16, vertices16_inds16); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D | GU_INDEX_BITS, 4, 4, indices17_inds32, vertices17_inds32); // Does the vertex pointer increment? sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices18_19_inc); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, NULL); // And indices? sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D | GU_INDEX_8BIT, 4, 4, indices20_21_ind_inc, vertices20_21_ind_inc); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D | GU_INDEX_8BIT, 4, 4, NULL, NULL); // What happens with division set to 0? sceGuShadeModel(GU_FLAT); sceGuPatchDivide(0, 0); sceGuDrawBezier(GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 4, 4, NULL, vertices22_div0); endFrame(); }
static void gba_draw_bg_mode0 (void) { // goto show_tiles; RETRO_PERFORMANCE_INIT(draw_bgs_procs); RETRO_PERFORMANCE_START(draw_bgs_procs); sceGuEnable(GU_BLEND); sceGuBlendFunc(GU_ADD,GU_SRC_ALPHA,GU_ONE_MINUS_SRC_ALPHA,0xFFFFFFFF,0xFFFFFFFF); // sceGuEnable(GU_DEPTH_TEST); sceGuDepthMask(GU_FALSE); sceGuDepthFunc(GU_GEQUAL); // sceGuDisable(GU_BLEND); //BG0 if (gba_video_registers->lcd_control.screen_display_BG3) draw_bg(&gba_video_registers->BG3_control, &gba_video_registers->BG3_scroll); if (gba_video_registers->lcd_control.screen_display_BG2) draw_bg(&gba_video_registers->BG2_control, &gba_video_registers->BG2_scroll); if (gba_video_registers->lcd_control.screen_display_BG1) draw_bg(&gba_video_registers->BG1_control, &gba_video_registers->BG1_scroll); if (gba_video_registers->lcd_control.screen_display_BG0) draw_bg(&gba_video_registers->BG0_control, &gba_video_registers->BG0_scroll); RETRO_PERFORMANCE_STOP(draw_bgs_procs); RETRO_PERFORMANCE_INIT(draw_sprites_proc); RETRO_PERFORMANCE_START(draw_sprites_proc); // draw_sprites_old(); // sceGuClutMode(GU_PSM_5551,0,0xFF,32); draw_sprites(); RETRO_PERFORMANCE_STOP(draw_sprites_proc); return; show_tiles: sceGuTexMode(GU_PSM_T16, 0, 0, GU_TRUE); sceGuClutMode(GU_PSM_5551,0,0xFF,0); sceGuClutLoad(32, palette_ram); sceGuDisable(GU_BLEND); sceGuEnable(GU_TEXTURE_2D); sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGB); // sceGuClutMode(GU_PSM_4444,0,0xFF,0); // sceGuClutLoad(32, index_copy_clut); if (show_4bit_tilemap) { sceGuTexImage(0, 256, 256, 256, ((u16*)GBA_VRAMTEXTURE_4bit) + 256 * 256 * tilemap_offset); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL,(void*)frame_256_256); } else { sceGuTexImage(0, 128, 256, 128, ((u16*)GBA_VRAMTEXTURE_8bit) + 128 * 256 * tilemap_offset); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL,(void*)frame_128_256); } }
static void *psp_init(const video_info_t *video, const input_driver_t **input, void **input_data) { /* to-do : add ASSERT() checks or use main RAM if * VRAM is too low for desired video->input_scale. */ void *pspinput; int pixel_format, lut_pixel_format, lut_block_count; unsigned int red_shift, color_mask; void *displayBuffer, *LUT_r, *LUT_b; psp1_video_t *psp = (psp1_video_t*)calloc(1, sizeof(psp1_video_t)); if (!psp) return NULL; sceGuInit(); psp->vp.x = 0; psp->vp.y = 0; psp->vp.width = SCEGU_SCR_WIDTH; psp->vp.height = SCEGU_SCR_HEIGHT; psp->vp.full_width = SCEGU_SCR_WIDTH; psp->vp.full_height = SCEGU_SCR_HEIGHT; /* Make sure anything using uncached pointers reserves * whole cachelines (memory address and size need to be a multiple of 64) * so it isn't overwritten by an unlucky cache writeback. * * This includes display lists since the Gu library uses * uncached pointers to write to them. */ /* Allocate more space if bigger display lists are needed. */ psp->main_dList = memalign(64, 256); psp->frame_dList = memalign(64, 256); psp->menu.dList = memalign(64, 256); psp->menu.frame = memalign(16, 2 * 480 * 272); psp->frame_coords = memalign(64, (((PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)) + 63) & ~63)); psp->menu.frame_coords = memalign(64, (((PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)) + 63) & ~63)); memset(psp->frame_coords, 0, PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)); memset(psp->menu.frame_coords, 0, PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)); sceKernelDcacheWritebackInvalidateAll(); psp->frame_coords = TO_UNCACHED_PTR(psp->frame_coords); psp->menu.frame_coords = TO_UNCACHED_PTR(psp->menu.frame_coords); psp->frame_coords->v0.x = 60; psp->frame_coords->v0.y = 0; psp->frame_coords->v0.u = 0; psp->frame_coords->v0.v = 0; psp->frame_coords->v1.x = 420; psp->frame_coords->v1.y = SCEGU_SCR_HEIGHT; psp->frame_coords->v1.u = 256; psp->frame_coords->v1.v = 240; psp->vsync = video->vsync; psp->rgb32 = video->rgb32; if(psp->rgb32) { uint32_t* LUT_r_local = (uint32_t*)(SCEGU_VRAM_BP32_2); uint32_t* LUT_b_local = (uint32_t*)(SCEGU_VRAM_BP32_2) + (1 << 8); red_shift = 8 + 8; color_mask = 0xFF; lut_block_count = (1 << 8) / 8; psp->texture = (void*)(LUT_b_local + (1 << 8)); psp->draw_buffer = SCEGU_VRAM_BP32_0; psp->bpp_log2 = 2; pixel_format = GU_PSM_8888; lut_pixel_format = GU_PSM_T32; displayBuffer = SCEGU_VRAM_BP32_1; for (u32 i=0; i < (1 << 8); i++){ LUT_r_local[i]= i; LUT_b_local[i]= i << (8 + 8); } LUT_r = (void*)LUT_r_local; LUT_b = (void*)LUT_b_local; } else { uint16_t* LUT_r_local = (uint16_t*)(SCEGU_VRAM_BP_2); uint16_t* LUT_b_local = (uint16_t*)(SCEGU_VRAM_BP_2) + (1 << 5); red_shift = 6 + 5; color_mask = 0x1F; lut_block_count = (1 << 5) / 8; psp->texture = (void*)(LUT_b_local + (1 << 5)); psp->draw_buffer = SCEGU_VRAM_BP_0; psp->bpp_log2 = 1; pixel_format = (g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_0RGB1555) ? GU_PSM_5551 : GU_PSM_5650 ; lut_pixel_format = GU_PSM_T16; displayBuffer = SCEGU_VRAM_BP_1; for (u16 i = 0; i < (1 << 5); i++) { LUT_r_local[i]= i; LUT_b_local[i]= i << (5 + 6); } LUT_r = (void*)LUT_r_local; LUT_b = (void*)LUT_b_local; } psp->tex_filter = video->smooth? GU_LINEAR : GU_NEAREST; /* TODO: check if necessary. */ sceDisplayWaitVblankStart(); sceGuDisplay(GU_FALSE); sceGuStart(GU_DIRECT, psp->main_dList); sceGuDrawBuffer(pixel_format, TO_GU_POINTER(psp->draw_buffer), SCEGU_VRAM_WIDTH); sceGuDispBuffer(SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT, TO_GU_POINTER(displayBuffer), SCEGU_VRAM_WIDTH); sceGuClearColor(0); sceGuScissor(0, 0, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuTexFilter(psp->tex_filter, psp->tex_filter); sceGuTexWrap (GU_CLAMP, GU_CLAMP); sceGuEnable(GU_TEXTURE_2D); sceGuDisable(GU_DEPTH_TEST); sceGuCallMode(GU_FALSE); sceGuFinish(); sceGuSync(0, 0); /* TODO : check if necessary */ sceDisplayWaitVblankStart(); sceGuDisplay(GU_TRUE); pspDebugScreenSetColorMode(pixel_format); pspDebugScreenSetBase(psp->draw_buffer); /* fill frame_dList : */ sceGuStart(GU_CALL, psp->frame_dList); sceGuTexMode(pixel_format, 0, 0, GU_FALSE); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); sceGuEnable(GU_BLEND); /* green only */ sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0x0000FF00, 0xFFFFFFFF); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); /* restore */ sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xFFFFFFFF, 0xFFFFFFFF); sceGuTexMode(lut_pixel_format, 0, 0, GU_FALSE); sceGuClutMode(pixel_format, red_shift, color_mask, 0); sceGuClutLoad(lut_block_count, LUT_r); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); sceGuClutMode(pixel_format, 0, color_mask, 0); sceGuClutLoad(lut_block_count, LUT_b); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); sceGuFinish(); if (input && input_data) { pspinput = input_psp.init(); *input = pspinput ? &input_psp : NULL; *input_data = pspinput; } psp->vblank_not_reached = true; sceKernelRegisterSubIntrHandler(PSP_VBLANK_INT, 0, psp_on_vblank, psp); sceKernelEnableSubIntr(PSP_VBLANK_INT, 0); psp->keep_aspect = true; psp->should_resize = true; psp->hw_render = false; return psp; error: RARCH_ERR("PSP1 video could not be initialized.\n"); return (void*)-1; }
static void draw_sprites(void) { int i; psp1_sprite_t* tile_coords = sceGuGetMemory(128*sizeof(psp1_sprite_t)); // sceGuClutLoad(32, palette_ram + 256); int mapping_mode_1D = gba_video_registers->lcd_control.obj_character_vram_mapping; typedef struct { int w; int h; }obj_size_t; static const obj_size_t obj_size[4][4]= { {{8,8},{16,16},{32,32},{64,64}}, {{16,8},{32,8},{32,16},{64,32}}, {{8,16},{8,32},{16,32},{32,64}}, {{0,0},{0,0},{0,0},{0,0}} }; sceGuTexMode(GU_PSM_T16, 0, 0, GU_TRUE); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); sceGuTexScale_8bit(1.0,1.0); sceGuClutLoad(32, palette_ram_4bit+256); // for (i=0; i < 128; i++) for (i=127; i >= 0; i--) { if (oam_attributes[i].obj_disable_flag) continue; if (oam_attributes[i].mode > 1) continue; if (oam_attributes[i].palette_mode_256) { sceGuClutLoad(32, palette_ram_8bit+256); printf("256!\n"); sceGuClutLoad(32, palette_ram_4bit+256); } else { // printf("16!\n"); int size_id = oam_attributes[i].size; int shape_id = oam_attributes[i].shape; if (shape_id>3) continue; int width = obj_size[shape_id][size_id].w; int height = obj_size[shape_id][size_id].h; psp1_sprite_t temp; temp = sprite_tiles[oam_attributes[i].flip_XY]; // temp = sprite_tiles[0]; temp.v1.x = width; temp.v1.y = height; *tile_coords = temp; sceGuOffset_(-oam_attributes[i].X, -oam_attributes[i].Y); if (mapping_mode_1D) { sceGuTexImage(0, width, height, width, GBA_VRAMTEXTURE_4bit + 256*256*2 + oam_attributes[i].id * 64); } else { // printf("2d!!\n"); sceGuTexImage(0, width, height, 256, GBA_VRAMTEXTURE_4bit + 256*256*2 + oam_attributes[i].id * 64); } sceGuClutMode(GU_PSM_5551,0,0x0F,oam_attributes[i].palette_id); sceGuDrawArray(GU_SPRITES, GU_TEXTURE_8BIT | GU_VERTEX_16BIT | GU_TRANSFORM_3D, 2, NULL,(void*)(tile_coords++)); } } }