Some fast forwarding support.

This commit is contained in:
Themaister 2010-08-16 18:40:17 +02:00
parent 105fcdf8e9
commit 38ae262d85
5 changed files with 62 additions and 5 deletions

View File

@ -117,6 +117,7 @@ static const struct snes_keybind snes_keybinds[] = {
{ SNES_DEVICE_ID_JOYPAD_DOWN, GLFW_KEY_DOWN, 11 },
{ SNES_DEVICE_ID_JOYPAD_START, GLFW_KEY_ENTER, 6 },
{ SNES_DEVICE_ID_JOYPAD_SELECT, GLFW_KEY_RSHIFT, 14 },
{ SNES_FAST_FORWARD_KEY, GLFW_KEY_SPACE, 9 },
{ -1 }
};

View File

@ -24,6 +24,9 @@
#include <stdint.h>
#include <unistd.h>
#define SNES_FAST_FORWARD_KEY 0x666 // Hurr, durr
void set_fast_forward_button(bool state);
struct snes_keybind
{
int id;
@ -48,6 +51,7 @@ typedef struct audio_driver
ssize_t (*write)(void* data, const void* buf, size_t size);
bool (*stop)(void* data);
bool (*start)(void* data);
void (*set_nonblock_state)(void* data, bool toggle); // Should we care about blocking in audio thread? Fast forwarding.
void (*free)(void* data);
} audio_driver_t;
@ -64,6 +68,7 @@ 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? :)
bool (*frame)(void* data, const uint16_t* frame, int width, int height);
void (*set_nonblock_state)(void* data, bool toggle); // Should we care about syncing to vblank? Fast forwarding.
void (*free)(void* data);
} video_driver_t;

35
gl.c
View File

@ -29,7 +29,7 @@ static GLuint tex_filter;
typedef struct gl
{
int foo;
bool vsync;
} gl_t;
@ -68,11 +68,22 @@ static int16_t glfw_input_state(void *data, const struct snes_keybind *snes_keyb
glfwGetJoystickButtons(joypad_id, buttons, joypad_buttons);
}
// Finds fast forwarding state.
for ( i = 0; snes_keybinds[i].id != -1; i++ )
{
if ( snes_keybinds[i].id == SNES_FAST_FORWARD_KEY )
{
if ( snes_keybinds[i].joykey < joypad_buttons )
set_fast_forward_button(buttons[snes_keybinds[i].joykey] == GLFW_PRESS);
break;
}
}
for ( i = 0; snes_keybinds[i].id != -1; i++ )
{
if ( snes_keybinds[i].id == (int)id )
{
if ( glfwGetKey(snes_keybinds[i].key ))
if ( glfwGetKey(snes_keybinds[i].key) )
return 1;
if ( snes_keybinds[i].joykey < joypad_buttons && buttons[snes_keybinds[i].joykey] == GLFW_PRESS )
@ -171,10 +182,22 @@ static void gl_free(void *data)
free(gl_buffer);
}
static void gl_set_nonblock_state(void *data, bool state)
{
gl_t *gl = data;
if (gl->vsync)
{
if (state)
glfwSwapInterval(0);
else
glfwSwapInterval(1);
}
}
static void* gl_init(video_info_t *video, const input_driver_t **input)
{
gl_t *foo = malloc(sizeof(gl_t));
if ( foo == NULL )
gl_t *gl = malloc(sizeof(gl_t));
if ( gl == NULL )
return NULL;
keep_aspect = video->force_aspect;
@ -200,6 +223,7 @@ static void* gl_init(video_info_t *video, const input_driver_t **input)
glfwSwapInterval(1); // Force vsync
else
glfwSwapInterval(0);
gl->vsync = video->vsync;
gl_buffer = malloc(256 * 256 * 2 * video->input_scale * video->input_scale);
if ( !gl_buffer )
@ -225,12 +249,13 @@ static void* gl_init(video_info_t *video, const input_driver_t **input)
GL_UNSIGNED_SHORT_1_5_5_5_REV, gl_buffer);
*input = &input_glfw;
return foo;
return gl;
}
const video_driver_t video_gl = {
.init = gl_init,
.frame = gl_frame,
.set_nonblock_state = gl_set_nonblock_state,
.free = gl_free
};

View File

@ -25,6 +25,7 @@ typedef struct rsd
rsound_t *rd;
int latency;
int rate;
int nonblock;
} rsd_t;
static void* __rsd_init(const char* device, int rate, int latency)
@ -74,6 +75,9 @@ static ssize_t __rsd_write(void* data, const void* buf, size_t size)
{
rsd_t *rsd = data;
if ( rsd_delay_ms(rsd->rd) > rsd->latency && rsd->nonblock )
return 0;
if ( size == 0 )
return 0;
@ -101,6 +105,12 @@ static bool __rsd_stop(void *data)
return true;
}
static void __rsd_set_nonblock_state(void *data, bool state)
{
rsd_t *rsd = data;
rsd->nonblock = state;
}
static bool __rsd_start(void *data)
{
rsd_t *rsd = data;
@ -124,6 +134,7 @@ const audio_driver_t audio_rsound = {
.write = __rsd_write,
.stop = __rsd_stop,
.start = __rsd_start,
.set_nonblock_state = __rsd_set_nonblock_state,
.free = __rsd_free
};

15
ssnes.c
View File

@ -70,6 +70,21 @@ static void write_file(const char* path, uint8_t* data, size_t size);
static void load_save_file(const char* path, int type);
static void save_file(const char* path, int type);
// To avoid continous switching if we hold the button down, we require that the button must go from pressed, unpressed back to pressed to be able to toggle between then.
void set_fast_forward_button(bool new_button_state)
{
static bool old_button_state = false;
static bool syncing_state = false;
if (new_button_state && !old_button_state)
{
syncing_state = !syncing_state;
driver.video->set_nonblock_state(driver.video_data, syncing_state);
driver.audio->set_nonblock_state(driver.audio_data, syncing_state);
}
old_button_state = new_button_state;
}
static void init_drivers(void)
{
init_video_input();