mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-13 22:08:34 +00:00
Fixes here and there...
This commit is contained in:
parent
eca7a59dd1
commit
86e080476a
@ -69,6 +69,8 @@ static const bool video_smooth = true;
|
||||
// On resize and fullscreen, rendering area will stay 4:3
|
||||
static const bool force_aspect = true;
|
||||
|
||||
#define SNES_ASPECT_RATIO (4.0/3)
|
||||
|
||||
////////////////
|
||||
// Audio
|
||||
////////////////
|
||||
|
12
driver.c
12
driver.c
@ -103,7 +103,7 @@ static void find_input_driver(void)
|
||||
}
|
||||
}
|
||||
SSNES_ERR("Couldn't find any input driver named \"%s\"\n", g_settings.input.driver);
|
||||
fprintf(stderr, "Available video drivers are:\n");
|
||||
fprintf(stderr, "Available input drivers are:\n");
|
||||
for (int i = 0; i < sizeof(input_drivers) / sizeof(input_driver_t*); i++)
|
||||
fprintf(stderr, "\t%s\n", video_drivers[i]->ident);
|
||||
|
||||
@ -194,7 +194,7 @@ void init_video_input(void)
|
||||
};
|
||||
|
||||
const input_driver_t *tmp = driver.input;
|
||||
driver.video_data = driver.video->init(&video, &driver.input);
|
||||
driver.video_data = driver.video->init(&video, &driver.input, &driver.input_data);
|
||||
|
||||
if ( driver.video_data == NULL )
|
||||
{
|
||||
@ -202,12 +202,8 @@ void init_video_input(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Video driver also provides an input driver.
|
||||
if ( driver.input != NULL )
|
||||
{
|
||||
driver.input_data = driver.video_data;
|
||||
}
|
||||
else // We use our configured input driver.
|
||||
// Video driver didn't provide an input driver so we use configured one.
|
||||
if (driver.input == NULL)
|
||||
{
|
||||
driver.input = tmp;
|
||||
if (driver.input != NULL)
|
||||
|
6
driver.h
6
driver.h
@ -72,10 +72,12 @@ typedef struct input_driver
|
||||
|
||||
typedef struct video_driver
|
||||
{
|
||||
void* (*init)(video_info_t *video, const input_driver_t **input);
|
||||
// Should the video driver act as an input driver as well? :)
|
||||
void* (*init)(video_info_t *video, const input_driver_t **input, void **input_data);
|
||||
// Should the video driver act as an input driver as well? :) The video init might preinitialize an input driver to override the settings in case the video driver relies on input driver for event handling, e.g.
|
||||
bool (*frame)(void* data, const uint16_t* frame, int width, int height, int pitch);
|
||||
void (*set_nonblock_state)(void* data, bool toggle); // Should we care about syncing to vblank? Fast forwarding.
|
||||
// Is the window still active?
|
||||
bool (*alive)(void *data);
|
||||
void (*free)(void* data);
|
||||
const char *ident;
|
||||
} video_driver_t;
|
||||
|
@ -42,6 +42,7 @@ struct settings
|
||||
bool vsync;
|
||||
bool smooth;
|
||||
bool force_aspect;
|
||||
float aspect_ratio;
|
||||
char cg_shader_path[256];
|
||||
char bsnes_shader_path[256];
|
||||
unsigned filter;
|
||||
|
91
gfx/gl.c
91
gfx/gl.c
@ -29,6 +29,7 @@
|
||||
#define NO_SDL_GLEXT
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_opengl.h>
|
||||
#include "input/sdl_input.h"
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/glext.h>
|
||||
@ -63,6 +64,13 @@ typedef struct gl
|
||||
GLuint texture;
|
||||
GLuint tex_filter;
|
||||
|
||||
bool should_resize;
|
||||
bool quitting;
|
||||
|
||||
unsigned win_width;
|
||||
unsigned win_height;
|
||||
unsigned vp_width;
|
||||
unsigned vp_height;
|
||||
unsigned last_width;
|
||||
unsigned last_height;
|
||||
unsigned tex_w, tex_h;
|
||||
@ -123,39 +131,37 @@ static inline void gl_shader_set_params(unsigned width, unsigned height,
|
||||
#endif
|
||||
}
|
||||
|
||||
#define SNES_ASPECT_RATIO (4.0/3)
|
||||
|
||||
static void set_viewport(int width, int height)
|
||||
static void set_viewport(gl_t *gl)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
GLuint out_width = width, out_height = height;
|
||||
GLuint out_width = gl->win_width, out_height = gl->win_height;
|
||||
|
||||
if ( keep_aspect )
|
||||
{
|
||||
float desired_aspect = SNES_ASPECT_RATIO;
|
||||
float device_aspect = (float)width / height;
|
||||
float desired_aspect = g_settings.video.aspect_ratio;
|
||||
float device_aspect = (float)gl->win_width / gl->win_height;
|
||||
|
||||
// If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff),
|
||||
// assume they are actually equal.
|
||||
if ( (int)(device_aspect*1000) > (int)(desired_aspect*1000) )
|
||||
{
|
||||
float delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5;
|
||||
glViewport(width * (0.5 - delta), 0, 2.0 * width * delta, height);
|
||||
out_width = (int)(2.0 * width * delta);
|
||||
glViewport(gl->win_width * (0.5 - delta), 0, 2.0 * gl->win_width * delta, gl->win_height);
|
||||
out_width = (int)(2.0 * gl->win_width * delta);
|
||||
}
|
||||
|
||||
else if ( (int)(device_aspect*1000) < (int)(desired_aspect*1000) )
|
||||
{
|
||||
float delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5;
|
||||
glViewport(0, height * (0.5 - delta), width, 2.0 * height * delta);
|
||||
out_height = (int)(2.0 * height * delta);
|
||||
glViewport(0, gl->win_height * (0.5 - delta), gl->win_width, 2.0 * gl->win_height * delta);
|
||||
out_height = (int)(2.0 * gl->win_height * delta);
|
||||
}
|
||||
else
|
||||
glViewport(0, 0, width, height);
|
||||
glViewport(0, 0, gl->win_width, gl->win_height);
|
||||
}
|
||||
else
|
||||
glViewport(0, 0, width, height);
|
||||
glViewport(0, 0, gl->win_width, gl->win_height);
|
||||
|
||||
glOrtho(0, 1, 0, 1, -1, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
@ -163,8 +169,8 @@ static void set_viewport(int width, int height)
|
||||
|
||||
gl_shader_set_proj_matrix();
|
||||
|
||||
gl_width = out_width;
|
||||
gl_height = out_height;
|
||||
gl->vp_width = out_width;
|
||||
gl->vp_height = out_height;
|
||||
}
|
||||
|
||||
static float tv_to_fps(const struct timeval *tv, const struct timeval *new_tv, int frames)
|
||||
@ -202,6 +208,13 @@ static bool gl_frame(void *data, const uint16_t* frame, int width, int height, i
|
||||
{
|
||||
gl_t *gl = data;
|
||||
|
||||
if (gl->should_resize)
|
||||
{
|
||||
gl->should_resize = false;
|
||||
SDL_SetVideoMode(gl->win_width, gl->win_height, 32, SDL_OPENGL | SDL_RESIZABLE | (g_settings.video.fullscreen ? SDL_FULLSCREEN : 0));
|
||||
set_viewport(gl);
|
||||
}
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
gl_shader_set_params(width, height, gl->tex_w, gl->tex_h, gl_width, gl_height);
|
||||
@ -235,6 +248,7 @@ static bool gl_frame(void *data, const uint16_t* frame, int width, int height, i
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
|
||||
show_fps();
|
||||
glFlush();
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
return true;
|
||||
@ -256,12 +270,13 @@ static void gl_set_nonblock_state(void *data, bool state)
|
||||
gl_t *gl = data;
|
||||
if (gl->vsync)
|
||||
{
|
||||
SSNES_LOG("GL VSync => %s\n", state ? "off" : "on");
|
||||
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, state ? 0 : 1);
|
||||
//SDL_SetVideoMode(gl->width, gl->height, 32, SDL_OPENGL | (video->fullscreen ? SDL_FULLSCREEN : 0));
|
||||
//SDL_SetVideoMode(gl->win_width, gl->win_height, 32, SDL_OPENGL | SDL_RESIZABLE | (g_settings.video.fullscreen ? SDL_FULLSCREEN : 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void* gl_init(video_info_t *video, const input_driver_t **input)
|
||||
static void* gl_init(video_info_t *video, const input_driver_t **input, void **input_data)
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||
return NULL;
|
||||
@ -269,20 +284,36 @@ static void* gl_init(video_info_t *video, const input_driver_t **input)
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, video->vsync ? 1 : 0);
|
||||
|
||||
if (!SDL_SetVideoMode(video->width, video->height, 32, SDL_OPENGL | (video->fullscreen ? SDL_FULLSCREEN : 0)))
|
||||
if (!SDL_SetVideoMode(video->width, video->height, 32, SDL_OPENGL | SDL_RESIZABLE | (video->fullscreen ? SDL_FULLSCREEN : 0)))
|
||||
return NULL;
|
||||
|
||||
int attr = 0;
|
||||
SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &attr);
|
||||
if (attr <= 0 && video->vsync)
|
||||
SSNES_WARN("GL VSync has not been enabled!\n");
|
||||
attr = 0;
|
||||
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &attr);
|
||||
if (attr <= 0)
|
||||
SSNES_WARN("GL double buffer has not been enabled!\n");
|
||||
|
||||
// Remove that ugly mouse :D
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
gl_t *gl = calloc(1, sizeof(gl_t));
|
||||
if ( gl == NULL )
|
||||
if (!gl)
|
||||
return NULL;
|
||||
|
||||
gl->win_width = video->width;
|
||||
gl->win_height = video->height;
|
||||
gl->vsync = video->vsync;
|
||||
|
||||
keep_aspect = video->force_aspect;
|
||||
if ( video->smooth )
|
||||
gl->tex_filter = GL_LINEAR;
|
||||
else
|
||||
gl->tex_filter = GL_NEAREST;
|
||||
|
||||
set_viewport(video->width, video->height);
|
||||
set_viewport(gl);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_DITHER);
|
||||
@ -323,13 +354,33 @@ static void* gl_init(video_info_t *video, const input_driver_t **input)
|
||||
|
||||
gl_shader_init();
|
||||
|
||||
*input = NULL;
|
||||
// Hook up SDL input driver to get SDL_QUIT events and RESIZE.
|
||||
sdl_input_t *sdl_input = input_sdl.init();
|
||||
if (sdl_input)
|
||||
{
|
||||
sdl_input->quitting = &gl->quitting;
|
||||
sdl_input->should_resize = &gl->should_resize;
|
||||
sdl_input->new_width = &gl->win_width;
|
||||
sdl_input->new_height = &gl->win_height;
|
||||
*input = &input_sdl;
|
||||
*input_data = sdl_input;
|
||||
}
|
||||
else
|
||||
*input = NULL;
|
||||
|
||||
return gl;
|
||||
}
|
||||
|
||||
static bool gl_alive(void *data)
|
||||
{
|
||||
gl_t *gl = data;
|
||||
return !gl->quitting;
|
||||
}
|
||||
|
||||
const video_driver_t video_gl = {
|
||||
.init = gl_init,
|
||||
.frame = gl_frame,
|
||||
.alive = gl_alive,
|
||||
.set_nonblock_state = gl_set_nonblock_state,
|
||||
.free = gl_free,
|
||||
.ident = "gl"
|
||||
|
48
input/sdl.c
48
input/sdl.c
@ -23,15 +23,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <libsnes.hpp>
|
||||
|
||||
typedef struct sdl_input
|
||||
{
|
||||
bool quitting;
|
||||
SDL_Joystick *joysticks[2];
|
||||
unsigned num_axes[2];
|
||||
unsigned num_buttons[2];
|
||||
unsigned num_joysticks;
|
||||
} sdl_input_t;
|
||||
#include "sdl_input.h"
|
||||
|
||||
static void* sdl_input_init(void)
|
||||
{
|
||||
@ -43,6 +35,8 @@ static void* sdl_input_init(void)
|
||||
return NULL;
|
||||
|
||||
sdl->num_joysticks = SDL_NumJoysticks();
|
||||
if (sdl->num_joysticks > 2)
|
||||
sdl->num_joysticks = 2;
|
||||
for (unsigned i = 0; i < sdl->num_joysticks; i++)
|
||||
{
|
||||
sdl->joysticks[i] = SDL_JoystickOpen(i);
|
||||
@ -64,11 +58,6 @@ static void* sdl_input_init(void)
|
||||
|
||||
static bool sdl_key_pressed(void *data, int key)
|
||||
{
|
||||
// Check to see if we have to exit.
|
||||
sdl_input_t *sdl = data;
|
||||
if (sdl->quitting && key == g_settings.input.exit_emulator_key)
|
||||
return true;
|
||||
|
||||
int num_keys;
|
||||
Uint8 *keymap = SDL_GetKeyState(&num_keys);
|
||||
|
||||
@ -98,7 +87,7 @@ static bool sdl_is_pressed(sdl_input_t *sdl, int port_num, const struct snes_key
|
||||
}
|
||||
if (AXIS_POS_GET(key->joyaxis) < sdl->num_axes[port_num])
|
||||
{
|
||||
Sint16 val = SDL_JoystickGetAxis(sdl->joysticks[port_num], AXIS_NEG_GET(key->joyaxis));
|
||||
Sint16 val = SDL_JoystickGetAxis(sdl->joysticks[port_num], AXIS_POS_GET(key->joyaxis));
|
||||
float scaled = (float)val / 0x8000;
|
||||
if (scaled > g_settings.input.axis_threshold)
|
||||
return true;
|
||||
@ -136,7 +125,7 @@ static void sdl_input_free(void *data)
|
||||
{
|
||||
sdl_input_t *sdl = data;
|
||||
for (int i = 0; i < sdl->num_joysticks; i++)
|
||||
SDL_JoystickClose(i);
|
||||
SDL_JoystickClose(sdl->joysticks[i]);
|
||||
|
||||
free(data);
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
@ -148,14 +137,31 @@ static void sdl_input_poll(void *data)
|
||||
SDL_PumpEvents();
|
||||
SDL_Event event;
|
||||
|
||||
// Search for SDL_QUIT
|
||||
sdl_input_t *sdl = data;
|
||||
// Search for events...
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
if (event.type == SDL_QUIT)
|
||||
switch (event.type)
|
||||
{
|
||||
sdl_input_t *sdl = data;
|
||||
sdl->quitting = true;
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
if (sdl->quitting)
|
||||
{
|
||||
*sdl->quitting = true;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_VIDEORESIZE:
|
||||
if (sdl->should_resize)
|
||||
{
|
||||
*sdl->new_width = event.resize.w;
|
||||
*sdl->new_height = event.resize.h;
|
||||
*sdl->should_resize = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
36
input/sdl_input.h
Normal file
36
input/sdl_input.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* SSNES - A Super Ninteno Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SSNES_SDL_INPUT_H
|
||||
#define __SSNES_SDL_INPUT_H
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
typedef struct sdl_input
|
||||
{
|
||||
SDL_Joystick *joysticks[2];
|
||||
unsigned num_axes[2];
|
||||
unsigned num_buttons[2];
|
||||
unsigned num_joysticks;
|
||||
|
||||
// A video driver could pre-init with the SDL driver and have it handle resizing events...
|
||||
bool *quitting;
|
||||
bool *should_resize;
|
||||
unsigned *new_width;
|
||||
unsigned *new_height;
|
||||
} sdl_input_t;
|
||||
|
||||
#endif
|
@ -90,6 +90,7 @@ static void set_defaults(void)
|
||||
g_settings.video.vsync = vsync;
|
||||
g_settings.video.smooth = video_smooth;
|
||||
g_settings.video.force_aspect = force_aspect;
|
||||
g_settings.video.aspect_ratio = SNES_ASPECT_RATIO;
|
||||
|
||||
g_settings.audio.enable = audio_enable;
|
||||
g_settings.audio.out_rate = out_rate;
|
||||
@ -183,6 +184,9 @@ void parse_config(void)
|
||||
if (config_get_bool(conf, "video_force_aspect", &tmp_bool))
|
||||
g_settings.video.force_aspect = tmp_bool;
|
||||
|
||||
if (config_get_double(conf, "video_aspect_ratio", &tmp_double))
|
||||
g_settings.video.aspect_ratio = tmp_double;
|
||||
|
||||
if (config_get_string(conf, "video_cg_shader", &tmp_str))
|
||||
{
|
||||
strncpy(g_settings.video.cg_shader_path, tmp_str, sizeof(g_settings.video.cg_shader_path) - 1);
|
||||
|
4
ssnes.c
4
ssnes.c
@ -417,10 +417,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
///// TODO: Modular friendly!!!
|
||||
for(;;)
|
||||
{
|
||||
if (driver.input->key_pressed(driver.input_data, g_settings.input.exit_emulator_key))
|
||||
if (driver.input->key_pressed(driver.input_data, g_settings.input.exit_emulator_key) ||
|
||||
!driver.video->alive(driver.video_data))
|
||||
break;
|
||||
|
||||
if (driver.input->key_pressed(driver.input_data, g_settings.input.save_state_key))
|
||||
|
@ -22,9 +22,12 @@
|
||||
# Smoothens picture with bilinear filtering. Should be disabled if using Cg shaders.
|
||||
# video_smooth = true
|
||||
|
||||
# Forces rendering area to stay 4:3.
|
||||
# Forces rendering area to stay equal to SNES aspect ratio 4:3 or as defined in video_aspect_ratio.
|
||||
# video_force_aspect = true
|
||||
|
||||
# A floating point value for video aspect ratio (width / height)
|
||||
# video_aspect_ratio = 1.333
|
||||
|
||||
# Path to Cg shader. If enabled
|
||||
# video_cg_shader = "/path/to/cg/shader.cg"
|
||||
|
||||
@ -65,6 +68,9 @@
|
||||
|
||||
### Input
|
||||
|
||||
# Input driver. Depending on video driver, it might force a different input driver.
|
||||
# input_driver = sdl
|
||||
|
||||
# Defines axis threshold. Possible values are [0.0, 1.0]
|
||||
# input_axis_threshold = 0.6
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user