void retro_run(void) { int i; bool updated = false; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) check_variables(); input_poll_cb(); for (i=0; i < 130; i++) KBD_RES(i); for (i=0; i < sizeof(keymap)/sizeof(keymap_t); i++) if (input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, keymap[i].retro)) KBD_SET(keymap[i].fmsx); joystate = 0; for (i = 0; i < sizeof(joymap) / sizeof(keymap_t); i++) { if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, joymap[i].retro)) { if (i < joy_keyboard_begin) JOY_SET(joymap[i].fmsx); else KBD_SET(joymap[i].fmsx); } } RETRO_PERFORMANCE_INIT(core_retro_run); RETRO_PERFORMANCE_START(core_retro_run); RunZ80(&CPU); RenderAndPlayAudio(SND_RATE / 60); RETRO_PERFORMANCE_STOP(core_retro_run); fflush(stdout); #ifdef PSP static unsigned int __attribute__((aligned(16))) d_list[32]; void* const texture_vram_p = (void*) (0x44200000 - (640 * 480)); // max VRAM address - frame size sceKernelDcacheWritebackRange(XBuf, 256*240 ); sceGuStart(GU_DIRECT, d_list); sceGuCopyImage(GU_PSM_5650, 0, 0, image_buffer_width, image_buffer_height, image_buffer_width, image_buffer, 0, 0, image_buffer_width, texture_vram_p); sceGuTexSync(); sceGuTexImage(0, 512, 256, image_buffer_width, texture_vram_p); sceGuTexMode(GU_PSM_5650, 0, 0, GU_FALSE); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); sceGuDisable(GU_BLEND); sceGuFinish(); video_cb(texture_vram_p, image_buffer_width, image_buffer_height, image_buffer_width * sizeof(uint16_t)); #else video_cb(image_buffer, image_buffer_width, image_buffer_height, image_buffer_width * sizeof(uint16_t)); #endif }
void psp_sdl_gu_stretch(SDL_Rect* srcrect, SDL_Rect* dstrect) { SDL_Surface* src = blit_surface; unsigned short old_slice = 0; /* set when we load 2nd tex */ unsigned int slice, num_slices, width, height, tbw, off_x, off_bytes; struct texVertex *vertices; char *pixels; sceKernelDcacheWritebackAll(); off_bytes = (long)(((char*)src->pixels) + srcrect->x * src->format->BytesPerPixel) & 0xf; off_x = off_bytes / src->format->BytesPerPixel; width = roundUpToPowerOfTwo(srcrect->w + off_bytes); height = roundUpToPowerOfTwo(srcrect->h); tbw = src->pitch / src->format->BytesPerPixel; /* Align the texture prior to srcrect->x */ pixels = ((char*)src->pixels) + (srcrect->x - off_x) * src->format->BytesPerPixel + src->pitch * srcrect->y; num_slices = (srcrect->w + (PSP_SLICE_SIZE - 1)) / PSP_SLICE_SIZE; /* GE doesn't appreciate textures wider than 512 */ if (width > 512) width = 512; sceGuStart(GU_DIRECT,list); sceGuEnable(GU_TEXTURE_2D); sceGuTexMode(GU_PSM_5650, 0, 0, GU_FALSE); sceGuTexImage(0, width, height, tbw, pixels); sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); sceGuTexFilter(GU_LINEAR, GU_LINEAR); for (slice = 0; slice < num_slices; slice++) { vertices = (struct texVertex*)sceGuGetMemory(2 * sizeof(struct texVertex)); if ((slice * PSP_SLICE_SIZE) < width) { vertices[0].u = slice * PSP_SLICE_SIZE + off_x; } else { if (!old_slice) { /* load another texture (src width > 512) */ pixels += width * src->format->BytesPerPixel; sceGuTexImage(0, roundUpToPowerOfTwo(srcrect->w - width), height, tbw, pixels); sceGuTexSync(); old_slice = slice; } vertices[0].u = (slice - old_slice) * PSP_SLICE_SIZE + off_x; } vertices[1].u = vertices[0].u + PSP_SLICE_SIZE; if (vertices[1].u > (off_x + srcrect->w)) vertices[1].u = off_x + srcrect->w; vertices[0].v = 0; vertices[1].v = vertices[0].v + srcrect->h; vertices[0].x = dstrect->x + (slice * PSP_SLICE_SIZE * dstrect->w + (srcrect->w - 1)) / srcrect->w; vertices[1].x = vertices[0].x + (PSP_SLICE_SIZE * dstrect->w + (srcrect->w - 1)) / srcrect->w; if (vertices[1].x > (dstrect->x + dstrect->w)) vertices[1].x = dstrect->x + dstrect->w; vertices[0].y = dstrect->y; vertices[1].y = vertices[0].y + dstrect->h; vertices[0].z = 0; vertices[1].z = 0; sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D, 2,0,vertices); } sceGuFinish(); sceGuSync(0, 0); }