Psp2Ui::Psp2Ui(int width, int height) :
	BaseUi() {
	
	starttick = sceKernelGetProcessTimeWide() / 1000;
	frame = 0;
	zoom_state = 0;
	trigger_state = false;
	vita2d_init();
	vita2d_texture_set_alloc_memblock_type(SCE_KERNEL_MEMBLOCK_TYPE_USER_RW);
	current_display_mode.width = width;
	current_display_mode.height = height;
	current_display_mode.bpp = 32;
	const DynamicFormat format(
		32,
		0x000000FF,
		0x0000FF00,
		0x00FF0000,
		0xFF000000,
		PF::Alpha);
	main_texture = vita2d_create_empty_texture_format(
												width, height,
												SCE_GXM_TEXTURE_FORMAT_A8B8G8R8);
	Bitmap::SetFormat(Bitmap::ChooseFormat(format));
	main_surface = Bitmap::Create(vita2d_texture_get_datap(main_texture),width, height, vita2d_texture_get_stride(main_texture), format);
	
	#ifdef SUPPORT_AUDIO
		audio_.reset(new Psp2Audio());
	#endif
	
	scePowerSetArmClockFrequency(444);
	sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG);
	
}
Exemplo n.º 2
0
int run_emu(const char *path)
{
	SceCtrlData pad;
	unsigned int joypad1, joypad2;
	
	setup_audio();

	emu->set_sample_rate(44100);
	emu->set_equalizer(Nes_Emu::nes_eq);
	emu->set_palette_range(0);

	vita2d_texture *tex = vita2d_create_empty_texture(Nes_Emu::image_width, Nes_Emu::image_height);
	void *tex_data = vita2d_texture_get_datap(tex);

	static uint32_t video_buffer[Nes_Emu::image_width * Nes_Emu::image_height];
	emu->set_pixels(video_buffer, Nes_Emu::image_width);

	Auto_File_Reader freader(path);
	emu->load_ines(freader);

	int scale = 2;
	int pos_x = SCREEN_W/2 - (Nes_Emu::image_width/2)*scale;
	int pos_y = SCREEN_H/2 - (Nes_Emu::image_height/2)*scale;

	while (1) {
		sceCtrlPeekBufferPositive(0, &pad, 1);
		if ((pad.buttons & CHANGE_GAME_MASK) == CHANGE_GAME_MASK) break;

		joypad1 = joypad2 = update_input(&pad);

		emu->emulate_frame(joypad1, joypad2);
		const Nes_Emu::frame_t &frame = emu->frame();

		const uint8_t *in_pixels = frame.pixels;
		uint32_t *out_pixels = (uint32_t *)tex_data;

		for (unsigned h = 0; h < Nes_Emu::image_height;
			h++, in_pixels += frame.pitch, out_pixels += Nes_Emu::image_width) {
			for (unsigned w = 0; w < Nes_Emu::image_width; w++) {
				unsigned col = frame.palette[in_pixels[w]];
				const Nes_Emu::rgb_t& rgb = emu->nes_colors[col];
				unsigned r = rgb.red;
				unsigned g = rgb.green;
				unsigned b = rgb.blue;
				out_pixels[w] = 0xFF000000 | (r << 0) | (g << 8) | (b << 16);
			}
		}

		vita2d_start_drawing();
		vita2d_clear_screen();

		vita2d_draw_texture_scale(tex, pos_x, pos_y, scale, scale);
		show_fps();

		vita2d_end_drawing();
		vita2d_swap_buffers();
	}

	return 0;
}
Exemplo n.º 3
0
void	VID_Init (unsigned char *palette)
{
	// Configurating vita2d environment
	vita2d_set_vblank_wait(0);
	
	tex_buffer = vita2d_create_empty_texture_format(widths[3], heights[3], SCE_GXM_TEXTURE_BASE_FORMAT_P8);
	vid.maxwarpwidth = vid.width = vid.conwidth = widths[3];
	vid.maxwarpheight = vid.height = vid.conheight = heights[3];
	vid.rowbytes = vid.conrowbytes = widths[3];
	
	vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
	vid.numpages = 2;
	vid.colormap = host_colormap;
	vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
	vid.buffer = vid.conbuffer = vid.direct = vita2d_texture_get_datap(tex_buffer);
	
	// Set correct palette for the texture
	VID_SetPalette(palette);
		
	// Init Quake Cache
	d_pzbuffer = zbuffer;
	surfcache = malloc(SURFCACHE_SIZE);
	D_InitCaches (surfcache, SURFCACHE_SIZE);
	
	sprintf(res_string,"Current Resolution: %ld x %ld", widths[3], heights[3]);
	Cvar_RegisterVariable (&res_val);
	Cvar_RegisterVariable(&vid_vsync);
	
}
Exemplo n.º 4
0
static uintptr_t vita_load_texture(void *video_data, void *data,
      bool threaded, enum texture_filter_type filter_type)
{
   unsigned int stride, pitch, j;
   uint32_t             *tex32    = NULL;
   const uint32_t *frame32        = NULL;
   struct texture_image *image    = (struct texture_image*)data;
   struct vita2d_texture *texture = vita2d_create_empty_texture_format(image->width, 
     image->height,SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB);

   if (!texture)
      return 0;

   if ((filter_type == TEXTURE_FILTER_MIPMAP_LINEAR) || 
      (filter_type == TEXTURE_FILTER_LINEAR))
      vita2d_texture_set_filters(texture,
            SCE_GXM_TEXTURE_FILTER_LINEAR,
            SCE_GXM_TEXTURE_FILTER_LINEAR);

   stride                      = vita2d_texture_get_stride(texture);
   stride                     /= 4;

   tex32                       = vita2d_texture_get_datap(texture);
   frame32                     = image->pixels;
   pitch                       = image->width;

   for (j = 0; j < image->height; j++)
         memcpy_neon(
               &tex32[j*stride],
               &frame32[j*pitch],
               pitch * sizeof(uint32_t));

   return (uintptr_t)texture;
}
Exemplo n.º 5
0
void VID_ChangeRes(float scale){

	// Freeing texture
	vita2d_free_texture(tex_buffer);
	
	int idx = (scale / 0.333);
	
	// Changing renderer resolution
	int width = widths[idx];
	int height = heights[idx];
	tex_buffer = vita2d_create_empty_texture_format(width, height, SCE_GXM_TEXTURE_BASE_FORMAT_P8);
	vid.maxwarpwidth = vid.width = vid.conwidth = width;
	vid.maxwarpheight = vid.height = vid.conheight = height;
	vid.rowbytes = vid.conrowbytes = width;	
	vid.buffer = vid.conbuffer = vid.direct = vita2d_texture_get_datap(tex_buffer);
	sprintf(res_string,"Current Resolution: %ld x %ld", widths[idx], heights[idx]);
	
	// Forcing a palette restoration
	fixpalette = v_gamma.value;
	Cvar_SetValue ("v_gamma", 0.1);
	
	// Changing scale value
	rend_scale = scales[idx];
	
}
Exemplo n.º 6
0
int texture_atlas_insert(texture_atlas *atlas, unsigned int character, const void *image, int width, int height, int bitmap_left, int bitmap_top, int advance_x, int advance_y, int glyph_size)
{
	bp2d_size size;
	size.w = width;
	size.h = height;

	bp2d_position pos;
	if (bp2d_insert(atlas->bp_root, &size, &pos) == 0)
		return 0;

	atlas_htab_entry *entry = malloc(sizeof(*entry));

	entry->rect.x = pos.x;
	entry->rect.y = pos.y;
	entry->rect.w = width;
	entry->rect.h = height;
	entry->bitmap_left = bitmap_left;
	entry->bitmap_top = bitmap_top;
	entry->advance_x = advance_x;
	entry->advance_y = advance_y;
	entry->glyph_size = glyph_size;

	int_htab_insert(atlas->htab, character, entry);

	void *tex_data = vita2d_texture_get_datap(atlas->tex);
	unsigned int tex_width = vita2d_texture_get_width(atlas->tex);

	int i;
	for (i = 0; i < height; i++) {
		memcpy(tex_data + (pos.x + (pos.y + i)*tex_width), image + i*width, width);
	}

	return 1;
}
Exemplo n.º 7
0
static bool vita_get_current_sw_framebuffer(void *data,
      struct retro_framebuffer *framebuffer)
{
   vita_video_t *vita = (vita_video_t*)data;

   if (!vita->texture || vita->width != framebuffer->width ||
         vita->height != framebuffer->height)
   {
      if(vita->texture)
      {
         vita2d_wait_rendering_done();
         vita2d_free_texture(vita->texture);
         vita->texture = NULL;
      }

      vita->width = framebuffer->width;
      vita->height = framebuffer->height;
      vita->texture = vita2d_create_empty_texture_format(
            vita->width, vita->height, vita->format);
      vita2d_texture_set_filters(vita->texture,
            vita->tex_filter,vita->tex_filter);
   }

   framebuffer->data         = vita2d_texture_get_datap(vita->texture);
   framebuffer->pitch        = vita2d_texture_get_stride(vita->texture);
   framebuffer->format       = vita->rgb32 
      ? RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565;
   framebuffer->memory_flags = 0;

   return true;
}
Exemplo n.º 8
0
static int atlas_add_glyph_pgf(vita2d_pgf *font, unsigned int character)
{
	SceFontCharInfo char_info;
	if (sceFontGetCharInfo(font->font_handle, character, &char_info) < 0)
		return 0;

	int pos_x;
	int pos_y;
	if (!texture_atlas_insert(font->tex_atlas, character,
		char_info.bitmapWidth, char_info.bitmapHeight,
		char_info.bitmapLeft, char_info.bitmapTop,
		char_info.sfp26AdvanceH,
		char_info.sfp26AdvanceV,
		0, &pos_x, &pos_y))
			return 0;

	vita2d_texture *tex = font->tex_atlas->tex;

	SceFontGlyphImage glyph_image;
	glyph_image.pixelFormat = SCE_FONT_PIXELFORMAT_8;
	glyph_image.xPos64 = pos_x << 6;
	glyph_image.yPos64 = pos_y << 6;
	glyph_image.bufWidth = vita2d_texture_get_width(tex);
	glyph_image.bufHeight = vita2d_texture_get_height(tex);
	glyph_image.bytesPerLine = vita2d_texture_get_stride(tex);
	glyph_image.pad = 0;
	glyph_image.bufferPtr = (unsigned int)vita2d_texture_get_datap(tex);

	return sceFontGetCharGlyphImage(font->font_handle, character, &glyph_image) == 0;
}
Exemplo n.º 9
0
static void vita_set_texture_frame(void *data, const void *frame, bool rgb32,
      unsigned width, unsigned height, float alpha)
{
   int i, j;
   void *tex_p;
   unsigned int stride;
   vita_video_t *vita = (vita_video_t*)data;

   (void)alpha;

   if (width != vita->menu.width && height != vita->menu.height && vita->menu.texture)
   {
      vita2d_free_texture(vita->menu.texture);
      vita->menu.texture = NULL;
   }

   if (!vita->menu.texture)
   {
      if (rgb32)
      {
         vita->menu.texture = vita2d_create_empty_texture(width, height);
         RARCH_LOG("Creating Frame RGBA8 texture: w: %i  h: %i\n", width, height);
      }
      else
      {
         vita->menu.texture = vita2d_create_empty_texture_format(width, height, SCE_GXM_TEXTURE_FORMAT_U4U4U4U4_RGBA);
         RARCH_LOG("Creating Frame R5G6B5 texture: w: %i  h: %i\n", width, height);
      }
      vita->menu.width  = width;
      vita->menu.height = height;
   }

   vita2d_texture_set_filters(vita->menu.texture,SCE_GXM_TEXTURE_FILTER_LINEAR,SCE_GXM_TEXTURE_FILTER_LINEAR);

   tex_p  = vita2d_texture_get_datap(vita->menu.texture);
   stride = vita2d_texture_get_stride(vita->menu.texture);

   if (rgb32)
   {
      uint32_t         *tex32 = tex_p;
      const uint32_t *frame32 = frame;

      stride                 /= 4;

      for (i = 0; i < height; i++)
         for (j = 0; j < width; j++)
            tex32[j + i*stride] = frame32[j + i*width];
   }
   else
   {
      uint16_t               *tex16 = tex_p;
      const uint16_t       *frame16 = frame;

      stride                       /= 2;

      for (i = 0; i < height; i++)
         for (j = 0; j < width; j++)
            tex16[j + i*stride] = frame16[j + i*width];
   }
}
Exemplo n.º 10
0
Psp2Ui::Psp2Ui(int width, int height) :
	BaseUi() {
	
	starttick = sceKernelGetProcessTimeWide() / 1000;
	frame = 0;
	zoom_state = 0;
	in_use_shader = 0;
	touch_x_start = -1;
	trigger_state = false;
	set_shader = true;
	vita2d_init();
	vita2d_set_vblank_wait(0);
	shaders[0] = vita2d_create_shader((SceGxmProgram*) opaque_v, (SceGxmProgram*) texture_f);
	shaders[1] = vita2d_create_shader((SceGxmProgram*) sharp_bilinear_v, (SceGxmProgram*) sharp_bilinear_f);
	shaders[2] = vita2d_create_shader((SceGxmProgram*) lcd3x_v, (SceGxmProgram*) lcd3x_f);
	shaders[3] = vita2d_create_shader((SceGxmProgram*) xbr_2x_fast_v, (SceGxmProgram*) xbr_2x_fast_f);
	gpu_texture = vita2d_create_empty_texture_format(
												width, height,
												SCE_GXM_TEXTURE_FORMAT_A8B8G8R8);
	vita2d_texture_set_alloc_memblock_type(SCE_KERNEL_MEMBLOCK_TYPE_USER_RW);
	current_display_mode.width = width;
	current_display_mode.height = height;
	current_display_mode.bpp = 32;
	const DynamicFormat format(
		32,
		0x000000FF,
		0x0000FF00,
		0x00FF0000,
		0xFF000000,
		PF::Alpha);
	main_texture = vita2d_create_empty_texture_format(
												width, height,
												SCE_GXM_TEXTURE_FORMAT_A8B8G8R8);
	next_texture = vita2d_create_empty_texture_format(
												width, height,
												SCE_GXM_TEXTURE_FORMAT_A8B8G8R8);
	Bitmap::SetFormat(Bitmap::ChooseFormat(format));
	main_surface = Bitmap::Create(vita2d_texture_get_datap(main_texture),width, height, vita2d_texture_get_stride(main_texture), format);
	
	#ifdef SUPPORT_AUDIO
		audio_.reset(new Psp2Audio());
	#endif
	
	scePowerSetArmClockFrequency(444);
	scePowerSetBusClockFrequency(222);
	scePowerSetGpuClockFrequency(222);
	scePowerSetGpuXbarClockFrequency(222);
	
	sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG);
	sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
	
	GPU_Mutex = sceKernelCreateSema("GPU Mutex", 0, 1, 1, NULL);
	GPU_Cleanup_Mutex = sceKernelCreateSema("GPU Cleanup Mutex", 0, 1, 1, NULL);
	GPU_Thread = sceKernelCreateThread("GPU Thread", &renderThread, 0x10000100, 0x10000, 0, 0, NULL);
	sceKernelStartThread(GPU_Thread, sizeof(GPU_Thread), &GPU_Thread);
	
}
Exemplo n.º 11
0
void video_Init(){
	vita2d_init();
	vita2d_set_vblank_wait(0);
	vita2d_set_clear_color(RGBA8(0, 0, 0, 0xFF));

	fb = vita2d_create_empty_texture_format(256, 192*2,
		SCE_GXM_TEXTURE_FORMAT_U1U5U5U5_ABGR);

	data = vita2d_texture_get_datap(fb);
}
Exemplo n.º 12
0
static int renderThread(unsigned int args, void* arg){
	
	for (;;){
	
		sceKernelWaitSema(GPU_Mutex, 1, NULL);
		memcpy(vita2d_texture_get_datap(gpu_texture), vita2d_texture_get_datap(next_texture), vita2d_texture_get_stride(gpu_texture)*240);
		sceKernelSignalSema(GPU_Mutex, 1);
		
		sceKernelWaitSema(GPU_Cleanup_Mutex, 1, NULL);
		
		if (main_texture == NULL) sceKernelExitDeleteThread(0); // Exit procedure
		
		vita2d_start_drawing();
   
		if (set_shader){
			Output::Post("Shader set to %s.",shader_names[in_use_shader]);
			set_shader = false;
			vita2d_texture_set_program(shaders[in_use_shader]->vertexProgram, shaders[in_use_shader]->fragmentProgram);
			vita2d_texture_set_wvp(shaders[in_use_shader]->wvpParam);
			vita2d_texture_set_vertexInput(&shaders[in_use_shader]->vertexInput);
			vita2d_texture_set_fragmentInput(&shaders[in_use_shader]->fragmentInput);
		}
   
		vita2d_clear_screen();
		switch (zoom_state){
			case 0: // 640x480
				vita2d_draw_texture_scale(gpu_texture, 160, 32, 2.0, 2.0);
				break;
			case 1: // 725x544
				vita2d_draw_texture_scale(gpu_texture, 117, 0, 2.266, 2.266);
				break;
			case 2: // 960x544
				vita2d_draw_texture_scale(gpu_texture, 0, 0, 3, 2.266);
				break;
		}
		vita2d_end_drawing();
		vita2d_wait_rendering_done();
		vita2d_swap_buffers();
		sceKernelSignalSema(GPU_Cleanup_Mutex, 1);
	
	}
	
}
Exemplo n.º 13
0
int main()
{
	vita2d_init();
	vita2d_set_clear_color(RGBA8(0x40, 0x40, 0x40, 0xFF));

	vita2d_pgf *pgf = vita2d_load_default_pgf();

	vita2d_texture *tex = vita2d_create_empty_texture(128, 128);
	unsigned int *tex_data = vita2d_texture_get_datap(tex);

	SceCtrlData pad;
	memset(&pad, 0, sizeof(pad));

	float rad = 0.0f;

	while (1) {
		sceCtrlPeekBufferPositive(0, &pad, 1);
		if (pad.buttons & SCE_CTRL_START) break;

		vita2d_start_drawing();
		vita2d_clear_screen();

		vita2d_draw_rectangle(20, 20, 400, 250, RGBA8(255, 0, 0, 255));
		vita2d_draw_rectangle(680, 350, 100, 150, RGBA8(0, 0, 255, 255));
		vita2d_draw_fill_circle(200, 420, 100, RGBA8(0, 255,0 ,255));

		/* Fill the texture with random data */
		int i, j;
		for (i = 0; i < 128; i++) {
			for (j = 0; j < 128; j++) {
				tex_data[j + i*128] = rand();
			}
		}

		vita2d_draw_texture_rotate(tex, 940/2, 544/2, rad);

		vita2d_draw_line(500, 30, 800, 300, RGBA8(255, 0, 255, 255));

		vita2d_pgf_draw_text(pgf, 700, 30, RGBA8(0,255,0,255), 1.0f, "PGF Font sample!");

		vita2d_end_drawing();
		vita2d_swap_buffers();

		rad += 0.1f;
	}

	vita2d_fini();
	vita2d_free_texture(tex);
	vita2d_free_pgf(pgf);

	sceKernelExitProcess(0);
	return 0;
}
Exemplo n.º 14
0
static int atlas_add_glyph(vita2d_pgf *font, unsigned int character)
{
	SceFontHandle font_handle = font->font_handle_list->font_handle;
	SceFontCharInfo char_info;
	bp2d_position position;
	void *texture_data;
	vita2d_texture *tex = font->atlas->texture;

	vita2d_pgf_font_handle *tmp = font->font_handle_list;
	while (tmp) {
		if (tmp->in_font_group == NULL || tmp->in_font_group(character)) {
			font_handle = tmp->font_handle;
			break;
		}
		tmp = tmp->next;
	}

	if (sceFontGetCharInfo(font_handle, character, &char_info) < 0)
		return 0;

	bp2d_size size = {
		char_info.bitmapWidth,
		char_info.bitmapHeight
	};

	texture_atlas_entry_data data = {
		char_info.bitmapLeft,
		char_info.bitmapTop,
		char_info.sfp26AdvanceH,
		char_info.sfp26AdvanceV,
		0
	};

	if (!texture_atlas_insert(font->atlas, character, &size, &data,
				  &position))
			return 0;

	texture_data = vita2d_texture_get_datap(tex);

	SceFontGlyphImage glyph_image;
	glyph_image.pixelFormat = SCE_FONT_PIXELFORMAT_8;
	glyph_image.xPos64 = position.x << 6;
	glyph_image.yPos64 = position.y << 6;
	glyph_image.bufWidth = vita2d_texture_get_width(tex);
	glyph_image.bufHeight = vita2d_texture_get_height(tex);
	glyph_image.bytesPerLine = vita2d_texture_get_stride(tex);
	glyph_image.pad = 0;
	glyph_image.bufferPtr = (unsigned int)texture_data;

	return sceFontGetCharGlyphImage(font_handle, character, &glyph_image) == 0;
}
Exemplo n.º 15
0
static void init(void)
{
	vita2d_init();
	vita2d_set_clear_color(RGBA8(0x40, 0x40, 0x40, 0xFF));

	sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG);

	fullscreen_scale_x = SCREEN_W / (float)GAMEBOY_WIDTH;
	fullscreen_scale_y = SCREEN_H / (float)GAMEBOY_HEIGHT;

	gb_texture = vita2d_create_empty_texture(GAMEBOY_WIDTH, GAMEBOY_HEIGHT);
	gb_texture_pixels = vita2d_texture_get_datap(gb_texture);

	set_scale(3);

	theGearboyCore = new GearboyCore();
	theGearboyCore->Init();
}
Exemplo n.º 16
0
static void *vita2d_font_init_font(void *gl_data, const char *font_path, float font_size)
{
	 unsigned int stride, pitch, j, k;
   const struct font_atlas *atlas = NULL;
	 vita_font_t *font = (vita_font_t*)calloc(1, sizeof(*font));

	 if (!font)
	 	 return NULL;

	 if (!font_renderer_create_default((const void**)&font->font_driver,
	 				 &font->font_data, font_path, font_size))
	 {
	 	 RARCH_WARN("Couldn't initialize font renderer.\n");
	 	 free(font);
	 	 return NULL;
	 }

	 atlas = font->font_driver->get_atlas(font->font_data);

	 font->texture = vita2d_create_empty_texture_format(atlas->width,atlas->height,SCE_GXM_TEXTURE_FORMAT_U8_R111);

	 if (!font->texture) {
 		free(font);
 		return NULL;
 	 }

	 vita2d_texture_set_filters(font->texture,
 				   SCE_GXM_TEXTURE_FILTER_POINT,
 				   SCE_GXM_TEXTURE_FILTER_LINEAR);

	 stride = vita2d_texture_get_stride(font->texture);
   uint8_t             *tex32 = vita2d_texture_get_datap(font->texture);
   const uint8_t     *frame32 = atlas->buffer;
   pitch = atlas->width;
   for (j = 0; j < atlas->height; j++)
      for (k = 0; k < atlas->width; k++)
         tex32[k + j*stride] = frame32[k + j*pitch];

   return font;
}
Exemplo n.º 17
0
static bool vita2d_overlay_load(void *data, const void *image_data, unsigned num_images)
{
   unsigned i,j,k;
   unsigned int stride, pitch;
   vita_video_t *vita = (vita_video_t*)data;
   const struct texture_image *images = (const struct texture_image*)image_data;

   vita2d_free_overlay(vita);
   vita->overlay = (struct vita_overlay_data*)calloc(num_images, sizeof(*vita->overlay));
   if (!vita->overlay)
      return false;

   vita->overlays = num_images;

   for (i = 0; i < num_images; i++)
   {
      struct vita_overlay_data *o = (struct vita_overlay_data*)&vita->overlay[i];
      o->width = images[i].width;
      o->height = images[i].height;
      o->tex = vita2d_create_empty_texture_format(o->width , o->height, SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB);
      vita2d_texture_set_filters(o->tex,SCE_GXM_TEXTURE_FILTER_LINEAR,SCE_GXM_TEXTURE_FILTER_LINEAR);
      stride = vita2d_texture_get_stride(o->tex);
      stride                     /= 4;
      uint32_t             *tex32 = vita2d_texture_get_datap(o->tex);
      const uint32_t     *frame32 = images[i].pixels;
      pitch = o->width;
      for (j = 0; j < o->height; j++)
         for (k = 0; k < o->width; k++)
            tex32[k + j*stride] = frame32[k + j*pitch];
      
      vita2d_overlay_tex_geom(vita, i, 0, 0, 1, 1); /* Default. Stretch to whole screen. */
      vita2d_overlay_vertex_geom(vita, i, 0, 0, 1, 1);
      vita->overlay[i].alpha_mod = 1.0f;
   }

   return true;
}
Exemplo n.º 18
0
static bool vita2d_gfx_frame(void *data, const void *frame,
      unsigned width, unsigned height, uint64_t frame_count,
      unsigned pitch, const char *msg, video_frame_info_t *video_info)
{
   void *tex_p;
   vita_video_t *vita = (vita_video_t *)data;

   if (frame)
   {
      if(!(vita->texture&&vita2d_texture_get_datap(vita->texture)==frame))
      {
         unsigned i;
         unsigned int stride;

         if ((width != vita->width || height != vita->height) && vita->texture)
         {
            vita2d_free_texture(vita->texture);
            vita->texture = NULL;
         }

         if (!vita->texture)
         {
            RARCH_LOG("Creating texture: %ix%i\n", width, height);
            vita->width = width;
            vita->height = height;
            vita->texture = vita2d_create_empty_texture_format(width, height, vita->format);
            vita2d_texture_set_filters(vita->texture,vita->tex_filter,vita->tex_filter);
         }
         tex_p = vita2d_texture_get_datap(vita->texture);
         stride = vita2d_texture_get_stride(vita->texture);

         if (vita->format == SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1RGB)
         {
            stride                     /= 4;
            pitch                      /= 4;
            uint32_t             *tex32 = tex_p;
            const uint32_t     *frame32 = frame;

            for (i = 0; i < height; i++)
               memcpy_neon(&tex32[i*stride],&frame32[i*pitch],pitch*sizeof(uint32_t));
         }
         else
         {
            stride                 /= 2;
            pitch                  /= 2;
            uint16_t *tex16         = tex_p;
            const uint16_t *frame16 = frame;

            for (i = 0; i < height; i++)
               memcpy_neon(&tex16[i*stride],&frame16[i*pitch],width*sizeof(uint16_t));
         }
      }
   }

   if (vita->should_resize)
      vita2d_gfx_update_viewport(vita);

   vita2d_start_drawing();

   vita2d_draw_rectangle(0,0,PSP_FB_WIDTH,PSP_FB_HEIGHT,vita2d_get_clear_color());

   if (vita->texture)
   {
      if (vita->fullscreen)
         vita2d_draw_texture_scale(vita->texture,
               0, 0,
               PSP_FB_WIDTH  / (float)vita->width,
               PSP_FB_HEIGHT / (float)vita->height);
      else
      {
         const float radian = 90 * 0.0174532925f;
         const float rad = vita->rotation * radian;
         float scalex = vita->vp.width / (float)vita->width;
         float scaley = vita->vp.height / (float)vita->height;
         vita2d_draw_texture_scale_rotate(vita->texture,vita->vp.x,
               vita->vp.y, scalex, scaley, rad);
      }
   }

#ifdef HAVE_OVERLAY
   if (vita->overlay_enable)
      vita2d_render_overlay(vita);
#endif

   if (vita->menu.active)
   {
#ifdef HAVE_MENU
      menu_driver_frame(video_info);
#endif

      if(vita->menu.texture)
      {
         if (vita->fullscreen)
            vita2d_draw_texture_scale(vita->menu.texture,
                  0, 0,
                  PSP_FB_WIDTH  / (float)vita->menu.width,
                  PSP_FB_HEIGHT / (float)vita->menu.height);
         else
         {
            if (vita->menu.width > vita->menu.height)
            {
               float scale = PSP_FB_HEIGHT / (float)vita->menu.height;
               float w = vita->menu.width * scale;
               vita2d_draw_texture_scale(vita->menu.texture,
                     PSP_FB_WIDTH / 2.0f - w/2.0f, 0.0f,
                     scale, scale);
            }
            else
            {
               float scale = PSP_FB_WIDTH / (float)vita->menu.width;
               float h = vita->menu.height * scale;
               vita2d_draw_texture_scale(vita->menu.texture,
                     0.0f, PSP_FB_HEIGHT / 2.0f - h/2.0f,
                     scale, scale);
            }
         }
      }
   }

   if(!string_is_empty(msg))
      font_driver_render_msg(video_info, NULL, msg, NULL);

   vita2d_end_drawing();
   vita2d_swap_buffers();

   return true;
}
Exemplo n.º 19
0
static vita2d_texture *_vita2d_load_PNG_generic(const void *io_ptr, png_rw_ptr read_data_fn)
{
	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (png_ptr == NULL) {
		goto error_create_read;
	}

	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL) {
		goto error_create_info;
	}

	png_bytep *row_ptrs = NULL;

	if (setjmp(png_jmpbuf(png_ptr))) {
		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)0);
		if (row_ptrs != NULL)
			free(row_ptrs);
		return NULL;
	}

	png_set_read_fn(png_ptr, (png_voidp)io_ptr, read_data_fn);
	png_set_sig_bytes(png_ptr, PNG_SIGSIZE);
	png_read_info(png_ptr, info_ptr);

	unsigned int width, height;
	int bit_depth, color_type;

	png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
		&color_type, NULL, NULL, NULL);

	if ((color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8)
		|| (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
		|| png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)
		|| (bit_depth == 16)) {
			png_set_expand(png_ptr);
	}

	if (bit_depth == 16)
		png_set_scale_16(png_ptr);

	if (bit_depth == 8 && color_type == PNG_COLOR_TYPE_RGB)
		png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);

	if (color_type == PNG_COLOR_TYPE_GRAY ||
	    color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
		png_set_gray_to_rgb(png_ptr);

	if (color_type == PNG_COLOR_TYPE_PALETTE) {
		png_set_palette_to_rgb(png_ptr);
		png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);
	}

	if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
		png_set_expand_gray_1_2_4_to_8(png_ptr);

	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
		png_set_tRNS_to_alpha(png_ptr);

	if (bit_depth < 8)
		png_set_packing(png_ptr);

	png_read_update_info(png_ptr, info_ptr);

	row_ptrs = (png_bytep *)malloc(sizeof(png_bytep) * height);
	if (!row_ptrs)
		goto error_alloc_rows;

	vita2d_texture *texture = vita2d_create_empty_texture(width, height);
	if (!texture)
		goto error_create_tex;

	void *texture_data = vita2d_texture_get_datap(texture);
	unsigned int stride = vita2d_texture_get_stride(texture);

	int i;
	for (i = 0; i < height; i++) {
		row_ptrs[i] = (png_bytep)(texture_data + i*stride);
	}

	png_read_image(png_ptr, row_ptrs);

	png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)0);
	free(row_ptrs);

	return texture;

error_create_tex:
	free(row_ptrs);
error_alloc_rows:
	png_destroy_info_struct(png_ptr, &info_ptr);
error_create_info:
	png_destroy_read_struct(&png_ptr, (png_infopp)0, (png_infopp)0);
error_create_read:
	return NULL;
}
Exemplo n.º 20
0
void Psp2Ui::UpdateDisplay() {
	sceKernelWaitSema(GPU_Mutex, 1, NULL);
	memcpy(vita2d_texture_get_datap(next_texture), vita2d_texture_get_datap(main_texture), vita2d_texture_get_stride(main_texture)*240);
	sceKernelSignalSema(GPU_Mutex, 1);
}
Exemplo n.º 21
0
void loadTheme() {
	#define COLOR_ENTRY(name) { #name, CONFIG_TYPE_HEXDECIMAL, (void *)&name }
	ConfigEntry colors_entries[] = {
		// Shell colors
		COLOR_ENTRY(BACKGROUND_COLOR),
		COLOR_ENTRY(TITLE_COLOR),
		COLOR_ENTRY(PATH_COLOR),
		COLOR_ENTRY(DATE_TIME_COLOR),

		// Settings colors
		COLOR_ENTRY(SETTINGS_MENU_COLOR),
		COLOR_ENTRY(SETTINGS_MENU_FOCUS_COLOR),
		COLOR_ENTRY(SETTINGS_MENU_TITLE_COLOR),
		COLOR_ENTRY(SETTINGS_MENU_ITEM_COLOR),
		COLOR_ENTRY(SETTINGS_MENU_OPTION_COLOR),

		// File browser colors
		COLOR_ENTRY(FOCUS_COLOR),
		COLOR_ENTRY(FILE_COLOR),
		COLOR_ENTRY(SFO_COLOR),
		COLOR_ENTRY(TXT_COLOR),
		COLOR_ENTRY(FOLDER_COLOR),
		COLOR_ENTRY(IMAGE_COLOR),
		COLOR_ENTRY(ARCHIVE_COLOR),
		COLOR_ENTRY(SCROLL_BAR_COLOR),
		COLOR_ENTRY(SCROLL_BAR_BG_COLOR),
		COLOR_ENTRY(MARKED_COLOR),

		// Context menu colors
		COLOR_ENTRY(CONTEXT_MENU_TEXT_COLOR),
		COLOR_ENTRY(CONTEXT_MENU_FOCUS_COLOR),
		COLOR_ENTRY(CONTEXT_MENU_COLOR),
		COLOR_ENTRY(CONTEXT_MENU_MORE_COLOR),
		COLOR_ENTRY(INVISIBLE_COLOR),

		// Dialog colors
		COLOR_ENTRY(DIALOG_COLOR),
		COLOR_ENTRY(DIALOG_BG_COLOR),
		COLOR_ENTRY(PROGRESS_BAR_COLOR),
		COLOR_ENTRY(PROGRESS_BAR_BG_COLOR),

		// Hex editor colors
		COLOR_ENTRY(HEX_COLOR),
		COLOR_ENTRY(HEX_OFFSET_COLOR),
		COLOR_ENTRY(HEX_NIBBLE_COLOR),

		// Text editor colors
		COLOR_ENTRY(TEXT_COLOR),
		COLOR_ENTRY(TEXT_FOCUS_COLOR),
		COLOR_ENTRY(TEXT_LINE_NUMBER_COLOR),
		COLOR_ENTRY(TEXT_LINE_NUMBER_COLOR_FOCUS),
		COLOR_ENTRY(TEXT_HIGHLIGHT_COLOR),

		// Photo viewer colors
		COLOR_ENTRY(PHOTO_ZOOM_COLOR),

		// Audio player colors
		COLOR_ENTRY(AUDIO_INFO_ASSIGN),
		COLOR_ENTRY(AUDIO_INFO),
		COLOR_ENTRY(AUDIO_SPEED),
		COLOR_ENTRY(AUDIO_TIME_CURRENT),
		COLOR_ENTRY(AUDIO_TIME_SLASH),
		COLOR_ENTRY(AUDIO_TIME_TOTAL),
		COLOR_ENTRY(AUDIO_TIME_BAR),
		COLOR_ENTRY(AUDIO_TIME_BAR_BG),
	};

	int i;

	// Load default config file
	readConfigBuffer(&_binary_resources_colors_txt_start, (int)&_binary_resources_colors_txt_size, colors_entries, sizeof(colors_entries) / sizeof(ConfigEntry));

	// Load custom config file
	if (use_custom_config) {
		char path[MAX_PATH_LENGTH];

		char *theme_name = NULL;
		ConfigEntry theme_entries[] = {
			{ "THEME_NAME", CONFIG_TYPE_STRING, (void *)&theme_name },
		};

		// Load theme config
		readConfig("ux0:VitaShell/theme/theme.txt", theme_entries, sizeof(theme_entries) / sizeof(ConfigEntry));

		if (theme_name) {
			// Load colors config
			snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/theme/%s/colors.txt", theme_name);
			readConfig(path, colors_entries, sizeof(colors_entries) / sizeof(ConfigEntry));
			
			// Font
			snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/theme/%s/font.pgf", theme_name);
 			font = vita2d_load_custom_pgf(path);
			
			// Load theme
			for (i = 0; i < N_THEME_IMAGES; i++) {
				snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/theme/%s/%s", theme_name, theme_images[i].name);
				if (theme_images[i].texture && *(theme_images[i].texture) == NULL)
					*(theme_images[i].texture) = vita2d_load_PNG_file(path);
			}
		}
	}

	// Load default theme
	for (i = 0; i < N_THEME_IMAGES; i++) {
		if (theme_images[i].texture && *(theme_images[i].texture) == NULL && theme_images[i].default_buf)
			*(theme_images[i].texture) = vita2d_load_PNG_buffer(theme_images[i].default_buf);
	}

	// Load default pngs
	if (!dialog_image) {
		dialog_image = vita2d_create_empty_texture(SCREEN_WIDTH, SCREEN_HEIGHT);
		void *data = vita2d_texture_get_datap(dialog_image);

		int y;
		for (y = 0; y < SCREEN_HEIGHT; y++) {
			int x;
			for (x = 0; x < SCREEN_WIDTH; x++) {
				((uint32_t *)data)[x + SCREEN_WIDTH * y] = DIALOG_BG_COLOR;
			}
		}
	}

	if (!context_image) {
		context_image = vita2d_create_empty_texture(SCREEN_WIDTH, SCREEN_HEIGHT);
		void *data = vita2d_texture_get_datap(context_image);

		int y;
		for (y = 0; y < SCREEN_HEIGHT; y++) {
			int x;
			for (x = 0; x < SCREEN_WIDTH; x++) {
				((uint32_t *)data)[x + SCREEN_WIDTH * y] = CONTEXT_MENU_COLOR;
			}
		}
	}

	if (!context_more_image) {
		context_more_image = vita2d_create_empty_texture(SCREEN_WIDTH, SCREEN_HEIGHT);
		void *data = vita2d_texture_get_datap(context_more_image);

		int y;
		for (y = 0; y < SCREEN_HEIGHT; y++) {
			int x;
			for (x = 0; x < SCREEN_WIDTH; x++) {
				((uint32_t *)data)[x + SCREEN_WIDTH * y] = CONTEXT_MENU_MORE_COLOR;
			}
		}
	}

	if (!settings_image) {
		settings_image = vita2d_create_empty_texture(SCREEN_WIDTH, SCREEN_HEIGHT);
		void *data = vita2d_texture_get_datap(settings_image);

		int y;
		for (y = 0; y < SCREEN_HEIGHT; y++) {
			int x;
			for (x = 0; x < SCREEN_WIDTH; x++) {
				((uint32_t *)data)[x + SCREEN_WIDTH * y] = SETTINGS_MENU_COLOR;
			}
		}
	}

	// Load system fonts
	if (!font)
		font = loadSystemFonts();

	// Font size cache
	for (i = 0; i < 256; i++) {
		char character[2];
		character[0] = i;
		character[1] = '\0';

		font_size_cache[i] = vita2d_pgf_text_width(font, FONT_SIZE, character);
	}
}
Exemplo n.º 22
0
/***
 * Callback for when a new frame is generated that we need to render.
 */
bool retro_video_refresh_callback(const void *data, unsigned width, unsigned height, size_t pitch)
{
	curr_frame++;

    // initialize our main render texture once we get the dimensions for the first time
    if (!tex)
    {
        tex = vita2d_create_empty_texture_format(width, height, SCE_GXM_TEXTURE_FORMAT_R5G6B5);
        tex_data = vita2d_texture_get_datap(tex);

        // initialize PSPImage
        if (Screen)
            free(Screen);
        int size = width * height * 2;

        Screen = (PspImage*)malloc(sizeof(PspImage));

        Screen->TextureFormat = SCE_GXM_TEXTURE_FORMAT_R5G6B5;
        Screen->PalSize = (unsigned short)0;
        memset(tex_data, 0, size);

        Screen->Width = width;
        Screen->Height = height;
        Screen->Pixels = tex_data;
        Screen->Texture = tex;

        Screen->Viewport.X = 0;
        Screen->Viewport.Y = 0;
        Screen->Viewport.Width = width;
        Screen->Viewport.Height = height;

        int i;
        for (i = 1; i < width; i *= 2);
            Screen->PowerOfTwo = (i == width);
        Screen->BytesPerPixel = 2;
        Screen->FreeBuffer = 0;
        Screen->Depth = 16;
    }

    // initialize our render variables if they're uninitalized, or
    // if they've changed due to user action
	if(OptionsChanged)
	{
        OptionsChanged = false;

		// handle changes to scale from the options
        switch (Options.DisplayMode)
        {
        case DISPLAY_MODE_UNSCALED:
            scale_x = 1.0f;
            scale_y = 1.0f;
            break;
        case DISPLAY_MODE_2X:
            scale_x = 2.0f;
            scale_y = 2.0f;
            break;
        case DISPLAY_MODE_FIT_HEIGHT:
            scale_y = (float)SCREEN_H / (float)height;
            scale_x = scale_y;
            break;
        case DISPLAY_MODE_FILL_SCREEN:
            scale_x = (float)SCREEN_W / (float)width;
            scale_y = (float)SCREEN_H / (float)height;
            break;
        }

		curr_frame = 0;
        curr_fps = 0.0f;
		pos_x = (SCREEN_W / 2) - (width / 2) * scale_x;
		pos_y = (SCREEN_H / 2) - (height / 2) * scale_y;

        // handle texture filtering options
        tex_filter = Options.TextureFilter ? SCE_GXM_TEXTURE_FILTER_LINEAR : SCE_GXM_TEXTURE_FILTER_POINT;

        sceGxmTextureSetMinFilter(&(tex->gxm_tex), tex_filter);
        sceGxmTextureSetMagFilter(&(tex->gxm_tex), tex_filter);
	}

	// copy the input pixels into the output buffer
	const uint16_t* in_pixels = (const uint16_t*)data;
	uint16_t *out_pixels = (uint16_t *)tex_data;

	for (h = 0; h < height; h++, in_pixels += pitch / 2, out_pixels += width) 
	{
		memcpy(out_pixels, in_pixels, width * sizeof(uint16_t));
	}

    // draw the screen
	vita2d_start_drawing();

	vita2d_draw_texture_scale(tex, pos_x, pos_y, scale_x, scale_y);

    if(Options.ShowFps)
        show_fps();

	vita2d_end_drawing();
	vita2d_swap_buffers();

	return true;
}
Exemplo n.º 23
0
/* Programme "Flocon de Koch" */
int main(int argc, char *argv[])
{
	struct parameters parameters;
	struct list *koch = NULL;
	uint32_t *picture = NULL;
	char *outfile = NULL;
	bool screenshots = false;

	srand(time(NULL));

#ifdef PSP2
	vita2d_init();
	vita2d_set_clear_color(RGBA8(0, 0, 0, 0xFF));

	vita2d_texture *tex = vita2d_create_empty_texture(960, 544);
	uint32_t *tex_data = vita2d_texture_get_datap(tex);

	SceCtrlData pad, lastbuttons;
	memset(&pad, 0, sizeof(pad));
#endif


	/* Initialisations */
	init_parameters(&parameters, argc, argv);
	show_parameters(parameters);
	init_koch(&koch, parameters.image_size, parameters.segment_length);
	outfile = malloc(3 + strlen(parameters.outfile) + 1);


	int32_t i = 0, step = 1;
	bool done = false;

	/* Génération de chaque flocon */
	while (!done)
	{
#ifdef PSP2
		lastbuttons = pad;

		sceCtrlPeekBufferPositive(0, &pad, 1);
		if (pad.buttons & PSP2_CTRL_TRIANGLE) break;


		if (PRESSED(lastbuttons.buttons, pad.buttons, PSP2_CTRL_LTRIGGER))
			parameters.fg_color = RGBA8(rand()%255, rand()%255, rand()%255, 255);

		//if (PRESSED(lastbuttons.buttons, pad.buttons, PSP2_CTRL_RTRIGGER))
		//	screenshots ^= 1;

		vita2d_start_drawing();
		vita2d_clear_screen();
#endif
		sprintf(outfile, "%02d_%s", i, parameters.outfile);

		if (step > 0)
			generer_koch(koch, i);
		else {

			for (uint32_t j = 0; j < i; j++)
				generer_koch(koch, j);
		}
		//show_koch_list(koch);

		/* Ne générer l'image que si c'est la dernière ou qu'on les génère toutes */
		if (parameters.all_images || i == parameters.nb_iterations)
		{
			init_picture(&picture, parameters.image_size, parameters.bg_color);

			render_image_bresenham(picture, koch, parameters.image_size, parameters.fg_color);

			#ifndef PSP2

			const uint32_t LEN = 960 * 544;

			uint32_t *data = calloc(LEN, sizeof(uint32_t));

			for (uint32_t i = 0; i < LEN; i++)
				data[i] = 0;


			uint32_t k = 0;

			for (uint32_t i = 0; i < 544; i++)
				for (uint32_t j = 0; j < 960; j++) {

					if (208 <= j && j < 752 && k < 544*544)
						data[i * 960 + j] = picture[k++];

					else
						data[i * 960 + j] = 0;
				}

			create_image(data, 960, 544, outfile);
			//create_image(picture, parameters.image_size, parameters.image_size, outfile);
			#else

			uint32_t k = 0;
			for (uint32_t i = 0; i < 544; i++)
				for (uint32_t j = 0; j < 960; j++) {

					if (208 <= j && j < 752 && k < 544*544)
						tex_data[i * 960 + j] = picture[k++];

					else
						tex_data[i * 960 + j] = 0;
				}

			if (screenshots)
				create_image(tex_data, 960, 544, outfile);

			#endif
		}


#ifdef PSP2
		vita2d_draw_texture(tex, 0, 0);
		vita2d_end_drawing();
		vita2d_swap_buffers();
		sceKernelDelayThread(100000);
#endif



		i = i + step;


		if (i == parameters.nb_iterations)
#ifdef PSP2
			i--, step = -1;
#else
			done = true;
#endif

		else if (i == 0) {
			step = 1;
			free_koch(koch);
			init_koch(&koch, parameters.image_size, parameters.segment_length);
		}

		if (step < 0) {
			free_koch(koch);
			init_koch(&koch, parameters.image_size, parameters.segment_length);
		}

		if (parameters.nb_iterations == 1)
			done = true;
	}
Exemplo n.º 24
0
static bool vita2d_gfx_frame(void *data, const void *frame,
      unsigned width, unsigned height, uint64_t frame_count,
      unsigned pitch, const char *msg)
{
   int i, j;
   void *tex_p;
   unsigned int stride;
   vita_video_t *vita = (vita_video_t *)data;

   (void)frame;
   (void)width;
   (void)height;
   (void)pitch;
   (void)msg;

   if (frame)
   {
      if ((width != vita->width || height != vita->height) && vita->texture)
      {
         vita2d_free_texture(vita->texture);
         vita->texture = NULL;
      }

      if (!vita->texture)
      {
         RARCH_LOG("Creating texture: %ix%i\n", width, height);
         vita->width = width;
         vita->height = height;
         vita->texture = vita2d_create_empty_texture_format(width, height, vita->format);
         vita2d_texture_set_filters(vita->texture,vita->tex_filter,vita->tex_filter);
      }
      tex_p = vita2d_texture_get_datap(vita->texture);
      stride = vita2d_texture_get_stride(vita->texture);

      if (vita->format == SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1RGB)
      {
         stride                     /= 4;
         pitch                      /= 4;
         uint32_t             *tex32 = tex_p;
         const uint32_t     *frame32 = frame;

         for (i = 0; i < height; i++)
            for (j = 0; j < width; j++)
               tex32[j + i*stride] = frame32[j + i*pitch];
      }
      else
      {
         stride                 /= 2;
         pitch                  /= 2;
         uint16_t *tex16         = tex_p;
         const uint16_t *frame16 = frame;

         for (i = 0; i < height; i++)
            for (j = 0; j < width; j++)
               tex16[j + i*stride] = frame16[j + i*pitch];
      }
   }

   if (vita->should_resize)
      vita2d_gfx_update_viewport(vita);

   vita2d_start_drawing();
   vita2d_clear_screen();

   if (vita->texture)
   {
      if (vita->fullscreen)
         vita2d_draw_texture_scale(vita->texture,
               0, 0,
               PSP_FB_WIDTH  / (float)vita->width,
               PSP_FB_HEIGHT / (float)vita->height);
      else
      {
         const float radian = 90 * 0.0174532925f;
         const float rad = vita->rotation * radian;
         float scalex = vita->vp.width / (float)vita->width;
         float scaley = vita->vp.height / (float)vita->height;
         vita2d_draw_texture_scale_rotate(vita->texture, vita->vp.x,
               vita->vp.y, scalex, scaley, rad);
      }
   }

   if (vita->menu.active && vita->menu.texture)
   {
      if (vita->fullscreen)
         vita2d_draw_texture_scale(vita->menu.texture,
               0, 0,
               PSP_FB_WIDTH  / (float)vita->menu.width,
               PSP_FB_HEIGHT / (float)vita->menu.height);
      else
      {
         if (vita->menu.width > vita->menu.height)
         {
            float scale = PSP_FB_HEIGHT / (float)vita->menu.height;
            float w = vita->menu.width * scale;
            vita2d_draw_texture_scale(vita->menu.texture,
                  PSP_FB_WIDTH / 2.0f - w/2.0f, 0.0f,
                  scale, scale);
         }
         else
         {
            float scale = PSP_FB_WIDTH / (float)vita->menu.width;
            float h = vita->menu.height * scale;
            vita2d_draw_texture_scale(vita->menu.texture,
                  0.0f, PSP_FB_HEIGHT / 2.0f - h/2.0f,
                  scale, scale);
         }
      }
   }

   vita2d_end_drawing();
   vita2d_swap_buffers();

   return true;
}