mirror of https://github.com/encounter/SDL.git
switch: handle aspect ratio correction in fullscreen mode
This commit is contained in:
parent
53e19d42b9
commit
05b71ace4f
|
@ -37,6 +37,7 @@
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
SDL_Surface *surface;
|
SDL_Surface *surface;
|
||||||
|
int x_offset;
|
||||||
} SWITCH_WindowData;
|
} SWITCH_WindowData;
|
||||||
|
|
||||||
static int SWITCH_VideoInit(_THIS);
|
static int SWITCH_VideoInit(_THIS);
|
||||||
|
@ -157,23 +158,31 @@ static int SWITCH_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *for
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hold a pointer to our surface
|
// hold a pointer to our stuff
|
||||||
data = SDL_calloc(1, sizeof(SWITCH_WindowData));
|
data = SDL_calloc(1, sizeof(SWITCH_WindowData));
|
||||||
data->surface = surface;
|
data->surface = surface;
|
||||||
SDL_SetWindowData(window, SWITCH_DATA, data);
|
|
||||||
|
|
||||||
// use switch hardware scaling in fullscreen mode
|
// use switch hardware scaling in fullscreen mode
|
||||||
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
||||||
gfxConfigureResolution(window->w, window->h);
|
float scaling = (float) window->h / (float) SCREEN_HEIGHT;
|
||||||
|
float w = SDL_min(SCREEN_WIDTH, SCREEN_WIDTH * scaling);
|
||||||
|
// calculate x offset, to respect aspect ratio
|
||||||
|
// round down to multiple of 4 for faster fb writes
|
||||||
|
int offset = (int) (w - (window->w)) / 2;
|
||||||
|
data->x_offset = offset & ~3;
|
||||||
|
gfxConfigureResolution((int) w, window->h);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gfxConfigureResolution(0, 0);
|
gfxConfigureResolution(0, 0);
|
||||||
|
data->x_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*format = SDL_PIXELFORMAT_ABGR8888;
|
*format = SDL_PIXELFORMAT_ABGR8888;
|
||||||
*pixels = surface->pixels;
|
*pixels = surface->pixels;
|
||||||
*pitch = surface->pitch;
|
*pitch = surface->pitch;
|
||||||
|
|
||||||
|
SDL_SetWindowData(window, SWITCH_DATA, data);
|
||||||
|
|
||||||
// inform SDL we're ready to accept inputs
|
// inform SDL we're ready to accept inputs
|
||||||
SDL_SetKeyboardFocus(window);
|
SDL_SetKeyboardFocus(window);
|
||||||
|
|
||||||
|
@ -189,25 +198,25 @@ static int SWITCH_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_R
|
||||||
u32 *src = (u32 *) data->surface->pixels;
|
u32 *src = (u32 *) data->surface->pixels;
|
||||||
u32 *dst = (u32 *) gfxGetFramebuffer(&fb_w, &fb_h);
|
u32 *dst = (u32 *) gfxGetFramebuffer(&fb_w, &fb_h);
|
||||||
|
|
||||||
// prevent framebuffer overflow in case of resolution change outside SDL,
|
// prevent fb overflow in case of resolution change outside SDL
|
||||||
// which should not happen
|
if (window->x + w > fb_w) {
|
||||||
if(window->x + w > fb_w) {
|
|
||||||
w = fb_w - window->x;
|
w = fb_w - window->x;
|
||||||
}
|
}
|
||||||
if(window->y + h > fb_h) {
|
if (window->y + h > fb_h) {
|
||||||
h = fb_h - window->y;
|
h = fb_h - window->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < h; y++) {
|
for (y = 0; y < h; y++) {
|
||||||
for (x = 0; x < w; x += 4) {
|
for (x = 0; x < w; x += 4) {
|
||||||
*((u128 *) &dst[gfxGetFramebufferDisplayOffset((u32) (x + window->x), (u32) (y + window->y))]) =
|
*((u128 *) &dst[gfxGetFramebufferDisplayOffset(
|
||||||
|
(u32) (x + window->x + data->x_offset), (u32) (y + window->y))]) =
|
||||||
*((u128 *) &src[y * w + x]);
|
*((u128 *) &src[y * w + x]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFlushBuffers();
|
gfxFlushBuffers();
|
||||||
gfxSwapBuffers();
|
gfxSwapBuffers();
|
||||||
// TODO: handle SDL_RENDERER_PRESENTVSYNC (SW_RenderDriver not using flags)
|
// TODO: handle SDL_RENDERER_PRESENTVSYNC (SW_RenderDriver not accepting flags)
|
||||||
gfxWaitForVsync();
|
gfxWaitForVsync();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -34,10 +34,11 @@ int main(int argc, char *argv[])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a 800x600 centered window for demonstration.
|
// create a 800x600 window for demonstration.
|
||||||
// if SDL_WINDOW_FULLSCREEN flag is passed, the window will be hardware scaled to fit switch screen.
|
// if SDL_WINDOW_FULLSCREEN flag is passed, it will be hardware scaled (stretched) to fit screen,
|
||||||
|
// will always be centered and aspect ratio maintained.
|
||||||
// maximum window dimension is currently limited to 1280x720
|
// maximum window dimension is currently limited to 1280x720
|
||||||
window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, 0);
|
window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_FULLSCREEN);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
printf("SDL_CreateWindow: %s\n", SDL_GetError());
|
printf("SDL_CreateWindow: %s\n", SDL_GetError());
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
@ -70,24 +71,24 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
|
|
||||||
case SDL_JOYAXISMOTION:
|
case SDL_JOYAXISMOTION:
|
||||||
printf("Joystick %d axis %d value: %d\n",
|
printf("Joystick %d axis %d value: %d\n",
|
||||||
event.jaxis.which,
|
event.jaxis.which,
|
||||||
event.jaxis.axis, event.jaxis.value);
|
event.jaxis.axis, event.jaxis.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_JOYBUTTONDOWN:
|
case SDL_JOYBUTTONDOWN:
|
||||||
printf("Joystick %d button %d down\n",
|
printf("Joystick %d button %d down\n",
|
||||||
event.jbutton.which, event.jbutton.button);
|
event.jbutton.which, event.jbutton.button);
|
||||||
// seek for joystick #0 down (B)
|
// seek for joystick #0 down (B)
|
||||||
// https://github.com/devkitPro/SDL/blob/switch-sdl2/src/joystick/switch/SDL_sysjoystick.c#L51
|
// https://github.com/devkitPro/SDL/blob/switch-sdl2/src/joystick/switch/SDL_sysjoystick.c#L51
|
||||||
if (event.jbutton.which == 0 && event.jbutton.button == 1) {
|
if (event.jbutton.which == 0 && event.jbutton.button == 1) {
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue