Beispiel #1
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);
	
}
Beispiel #2
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;
}
Beispiel #3
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;
}
Beispiel #4
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];
	
}
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);
	
}
Beispiel #6
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);
	
}
Beispiel #7
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];
   }
}
Beispiel #8
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);
}
Beispiel #9
0
texture_atlas *texture_atlas_create(int width, int height, SceGxmTextureFormat format)
{
	texture_atlas *atlas = malloc(sizeof(*atlas));
	if (!atlas)
		return NULL;

	bp2d_rectangle rect;
	rect.x = 0;
	rect.y = 0;
	rect.w = width;
	rect.h = height;

	atlas->tex = vita2d_create_empty_texture_format(width, height, format);
	atlas->bp_root = bp2d_create(&rect);
	atlas->htab = int_htab_create(256);

	return atlas;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
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;
}
Beispiel #14
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;
}