mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 03:32:46 +00:00
VIDEO/SUNXI: Make setting aspect ratio in menu work and fixed segfault on new content loading.
This commit is contained in:
parent
866970fb1c
commit
0776932b3a
@ -542,7 +542,8 @@ struct sunxi_video
|
||||
unsigned int menu_height;
|
||||
unsigned int menu_pitch;
|
||||
|
||||
bool aspect_changed;
|
||||
float aspect_ratio;
|
||||
bool readjust_pending;
|
||||
};
|
||||
|
||||
static void sunxi_blank_console(struct sunxi_video *_dispvars)
|
||||
@ -633,6 +634,11 @@ static void *sunxi_gfx_init(const video_info_t *video,
|
||||
_dispvars->keep_vsync = true;
|
||||
_dispvars->menu_active = false;
|
||||
_dispvars->bytes_per_pixel = video->rgb32 ? 4 : 2;
|
||||
/* It's very important that we set aspect here because the
|
||||
* call seq when a core is loaded is gfx_init()->set_aspect()->gfx_frame()
|
||||
* and we don't want the main surface to be setup in set_aspect()
|
||||
* before we get to gfx_frame(). */
|
||||
_dispvars->aspect_ratio = video_driver_get_aspect_ratio();
|
||||
|
||||
switch (_dispvars->bytes_per_pixel)
|
||||
{
|
||||
@ -745,29 +751,7 @@ static void sunxi_setup_scale (void *data,
|
||||
_dispvars->pages[i].address = ((uint32_t*) _dispvars->sunxi_disp->framebuffer_addr + (_dispvars->sunxi_disp->yres + i * _dispvars->src_height) * _dispvars->dst_pitch/4);
|
||||
}
|
||||
|
||||
switch (settings->video.aspect_ratio_idx)
|
||||
{
|
||||
case ASPECT_RATIO_4_3:
|
||||
aspect = (float)4 / (float)3;
|
||||
break;
|
||||
case ASPECT_RATIO_16_9:
|
||||
aspect = (float)16 / (float)9;
|
||||
break;
|
||||
case ASPECT_RATIO_16_10:
|
||||
aspect = (float)16 / (float)10;
|
||||
break;
|
||||
case ASPECT_RATIO_16_15:
|
||||
aspect = (float)16 / (float)15;
|
||||
break;
|
||||
case ASPECT_RATIO_CORE:
|
||||
aspect = (float)_dispvars->src_width / (float)_dispvars->src_height;
|
||||
break;
|
||||
default:
|
||||
aspect = (float)_dispvars->src_width / (float)_dispvars->src_height;
|
||||
break;
|
||||
}
|
||||
|
||||
visible_width = _dispvars->sunxi_disp->yres * aspect;
|
||||
visible_width = _dispvars->sunxi_disp->yres * _dispvars->aspect_ratio;
|
||||
xpos = (_dispvars->sunxi_disp->xres - visible_width) / 2;
|
||||
|
||||
/* setup layer window */
|
||||
@ -782,7 +766,7 @@ static bool sunxi_gfx_frame(void *data, const void *frame, unsigned width,
|
||||
{
|
||||
struct sunxi_video *_dispvars = (struct sunxi_video*)data;
|
||||
|
||||
if (_dispvars->src_width != width || _dispvars->src_height != height)
|
||||
if (_dispvars->src_width != width || _dispvars->src_height != height || _dispvars->readjust_pending)
|
||||
{
|
||||
/* Sanity check on new dimensions */
|
||||
if (width == 0 || height == 0)
|
||||
@ -792,6 +776,7 @@ static bool sunxi_gfx_frame(void *data, const void *frame, unsigned width,
|
||||
_dispvars->src_width, _dispvars->src_height, width, height);
|
||||
|
||||
sunxi_setup_scale(_dispvars, width, height, pitch);
|
||||
_dispvars->readjust_pending = false;
|
||||
}
|
||||
|
||||
if (_dispvars->menu_active)
|
||||
@ -898,40 +883,43 @@ static void sunxi_set_texture_enable(void *data, bool state, bool full_screen)
|
||||
static void sunxi_set_texture_frame(void *data, const void *frame, bool rgb32,
|
||||
unsigned width, unsigned height, float alpha)
|
||||
{
|
||||
uint16_t src_pix;
|
||||
uint32_t R, G, B, dst_pix;
|
||||
unsigned int i, j;
|
||||
struct sunxi_video *_dispvars = (struct sunxi_video*)data;
|
||||
|
||||
/* We have to go on a pixel format conversion adventure for now, until we can
|
||||
* convince RGUI to output in an 8888 format. */
|
||||
unsigned int src_pitch = width * 2;
|
||||
unsigned int dst_pitch = _dispvars->sunxi_disp->xres * 4;
|
||||
unsigned int dst_width = _dispvars->sunxi_disp->xres;
|
||||
uint32_t line[dst_width];
|
||||
|
||||
if (_dispvars->menu_active) {
|
||||
uint16_t src_pix;
|
||||
uint32_t R, G, B, dst_pix;
|
||||
unsigned int i, j;
|
||||
|
||||
/* We have to go on a pixel format conversion adventure for now, until we can
|
||||
* convince RGUI to output in an 8888 format. */
|
||||
unsigned int src_pitch = width * 2;
|
||||
unsigned int dst_pitch = _dispvars->sunxi_disp->xres * 4;
|
||||
unsigned int dst_width = _dispvars->sunxi_disp->xres;
|
||||
uint32_t line[dst_width];
|
||||
|
||||
/* Remember, memcpy() works with 8bits pointers for increments. */
|
||||
char *dst_base_addr = (char*)(_dispvars->pages[0].address);
|
||||
char *src_base_addr = (char*)frame;
|
||||
/* Remember, memcpy() works with 8bits pointers for increments. */
|
||||
char *dst_base_addr = (char*)(_dispvars->pages[0].address);
|
||||
char *src_base_addr = (char*)frame;
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
for (j = 0; j < src_pitch / 2; j++)
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
src_pix = *((uint16_t*)frame + (src_pitch / 2 * i) + j);
|
||||
/* The hex AND is for keeping only the part we need for each component. */
|
||||
R = (src_pix << 8) & 0x00FF0000;
|
||||
G = (src_pix << 4) & 0x0000FF00;
|
||||
B = (src_pix << 0) & 0x000000FF;
|
||||
line[j] = (0 | R | G | B);
|
||||
for (j = 0; j < src_pitch / 2; j++)
|
||||
{
|
||||
src_pix = *((uint16_t*)frame + (src_pitch / 2 * i) + j);
|
||||
/* The hex AND is for keeping only the part we need for each component. */
|
||||
R = (src_pix << 8) & 0x00FF0000;
|
||||
G = (src_pix << 4) & 0x0000FF00;
|
||||
B = (src_pix << 0) & 0x000000FF;
|
||||
line[j] = (0 | R | G | B);
|
||||
}
|
||||
memcpy(dst_base_addr + (dst_pitch * i), (char*)line, dst_pitch);
|
||||
}
|
||||
memcpy(dst_base_addr + (dst_pitch * i), (char*)line, dst_pitch);
|
||||
}
|
||||
|
||||
/* Issue pageflip. Will flip on next vsync. */
|
||||
sunxi_layer_set_rgb_input_buffer(_dispvars->sunxi_disp,
|
||||
_dispvars->sunxi_disp->bits_per_pixel,
|
||||
_dispvars->pages[0].offset, width, height, _dispvars->sunxi_disp->xres);
|
||||
/* Issue pageflip. Will flip on next vsync. */
|
||||
sunxi_layer_set_rgb_input_buffer(_dispvars->sunxi_disp,
|
||||
_dispvars->sunxi_disp->bits_per_pixel,
|
||||
_dispvars->pages[0].offset, width, height, _dispvars->sunxi_disp->xres);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t sunxi_get_frame_count(void *data)
|
||||
@ -942,6 +930,18 @@ static uint64_t sunxi_get_frame_count(void *data)
|
||||
return _dispvars->frame_count;
|
||||
}
|
||||
|
||||
static void sunxi_set_aspect_ratio (void *data, unsigned aspect_ratio_idx)
|
||||
{
|
||||
struct sunxi_video *_dispvars = (struct sunxi_video*)data;
|
||||
/* Here we obtain the new aspect ratio. */
|
||||
float new_aspect = aspectratio_lut[aspect_ratio_idx].value;
|
||||
if (new_aspect != _dispvars->aspect_ratio) {
|
||||
_dispvars->aspect_ratio = new_aspect;
|
||||
/* So we setup scale again on the next gfx_frame. */
|
||||
_dispvars->readjust_pending = true;
|
||||
}
|
||||
}
|
||||
|
||||
static const video_poke_interface_t sunxi_poke_interface = {
|
||||
sunxi_get_frame_count,
|
||||
NULL, /* set_video_mode */
|
||||
@ -951,7 +951,7 @@ static const video_poke_interface_t sunxi_poke_interface = {
|
||||
NULL, /* get_video_output_next */
|
||||
NULL, /* get_current_framebuffer */
|
||||
NULL, /* get_proc_address */
|
||||
NULL, /* sunxi_set_aspect_ratio */
|
||||
sunxi_set_aspect_ratio,
|
||||
NULL, /* sunxi_apply_state_changes */
|
||||
#ifdef HAVE_MENU
|
||||
sunxi_set_texture_frame,
|
||||
|
Loading…
x
Reference in New Issue
Block a user