mirror of
https://github.com/libretro/RetroArch
synced 2025-03-21 04:21:13 +00:00
Start implementing some minor extensions to libsnes.
This commit is contained in:
parent
fad89f9d2d
commit
0522a2d6a0
@ -111,7 +111,6 @@
|
|||||||
// Windowed
|
// Windowed
|
||||||
static const float xscale = 3.0; // Real x res = aspect * base_size * xscale
|
static const float xscale = 3.0; // Real x res = aspect * base_size * xscale
|
||||||
static const float yscale = 3.0; // Real y res = base_size * yscale
|
static const float yscale = 3.0; // Real y res = base_size * yscale
|
||||||
static const unsigned base_size = 224; // Base size for windowed mode.
|
|
||||||
|
|
||||||
// Fullscreen
|
// Fullscreen
|
||||||
static const bool fullscreen = false; // To start in Fullscreen or not
|
static const bool fullscreen = false; // To start in Fullscreen or not
|
||||||
|
25
driver.c
25
driver.c
@ -330,17 +330,17 @@ static void init_filter(void)
|
|||||||
|
|
||||||
g_extern.filter.active = true;
|
g_extern.filter.active = true;
|
||||||
|
|
||||||
unsigned width = 512;
|
unsigned width = g_extern.system.geom.max_width;
|
||||||
unsigned height = 512;
|
unsigned height = g_extern.system.geom.max_height;
|
||||||
g_extern.filter.psize(&width, &height);
|
g_extern.filter.psize(&width, &height);
|
||||||
|
|
||||||
unsigned pow2_x = next_pow2(ceil(width));
|
unsigned pow2_x = next_pow2(ceil(width));
|
||||||
unsigned pow2_y = next_pow2(ceil(height));
|
unsigned pow2_y = next_pow2(ceil(height));
|
||||||
unsigned maxsize = pow2_x > pow2_y ? pow2_x : pow2_y;
|
unsigned maxsize = pow2_x > pow2_y ? pow2_x : pow2_y;
|
||||||
g_extern.filter.scale = maxsize / 256;
|
g_extern.filter.scale = maxsize / SSNES_SCALE_BASE;
|
||||||
|
|
||||||
g_extern.filter.buffer = malloc(256 * 256 * g_extern.filter.scale * g_extern.filter.scale * sizeof(uint32_t));
|
g_extern.filter.buffer = malloc(SSNES_SCALE_BASE * SSNES_SCALE_BASE * g_extern.filter.scale * g_extern.filter.scale * sizeof(uint32_t));
|
||||||
g_extern.filter.pitch = 256 * g_extern.filter.scale * sizeof(uint32_t);
|
g_extern.filter.pitch = SSNES_SCALE_BASE * g_extern.filter.scale * sizeof(uint32_t);
|
||||||
assert(g_extern.filter.buffer);
|
assert(g_extern.filter.buffer);
|
||||||
|
|
||||||
g_extern.filter.colormap = malloc(32768 * sizeof(uint32_t));
|
g_extern.filter.colormap = malloc(32768 * sizeof(uint32_t));
|
||||||
@ -412,8 +412,9 @@ void init_video_input(void)
|
|||||||
init_shader_dir();
|
init_shader_dir();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We use at least 512x512 textures to accomodate for hi-res games.
|
unsigned max_dim = max(g_extern.system.geom.max_width, g_extern.system.geom.max_height);
|
||||||
unsigned scale = 2;
|
unsigned scale = max_dim / SSNES_SCALE_BASE;
|
||||||
|
scale = max(scale, 1);
|
||||||
|
|
||||||
find_video_driver();
|
find_video_driver();
|
||||||
find_input_driver();
|
find_input_driver();
|
||||||
@ -432,16 +433,18 @@ void init_video_input(void)
|
|||||||
{
|
{
|
||||||
if (g_settings.video.force_aspect)
|
if (g_settings.video.force_aspect)
|
||||||
{
|
{
|
||||||
width = roundf(g_settings.video.base_size * g_settings.video.xscale * g_settings.video.aspect_ratio);
|
width = roundf(g_extern.system.geom.base_height * g_settings.video.xscale * g_settings.video.aspect_ratio);
|
||||||
height = roundf(g_settings.video.base_size * g_settings.video.yscale);
|
height = roundf(g_extern.system.geom.base_height * g_settings.video.yscale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
width = roundf(8.0f / 7.0f * g_settings.video.base_size * g_settings.video.xscale); // Assume 8:7 aspect.
|
width = roundf(g_extern.system.geom.base_width * g_settings.video.xscale);
|
||||||
height = roundf(g_settings.video.base_size * g_settings.video.yscale);
|
height = roundf(g_extern.system.geom.base_height * g_settings.video.yscale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSNES_LOG("Video @ %ux%u\n", width, height);
|
||||||
|
|
||||||
video_info_t video = {
|
video_info_t video = {
|
||||||
.width = width,
|
.width = width,
|
||||||
.height = height,
|
.height = height,
|
||||||
|
86
dynamic.c
86
dynamic.c
@ -96,6 +96,8 @@ unsigned (*psnes_get_memory_size)(unsigned);
|
|||||||
void (*psnes_unload_cartridge)(void);
|
void (*psnes_unload_cartridge)(void);
|
||||||
void (*psnes_term)(void);
|
void (*psnes_term)(void);
|
||||||
|
|
||||||
|
static void set_environment(void);
|
||||||
|
|
||||||
#ifdef HAVE_DYNAMIC
|
#ifdef HAVE_DYNAMIC
|
||||||
static void load_dynamic(void)
|
static void load_dynamic(void)
|
||||||
{
|
{
|
||||||
@ -181,30 +183,23 @@ static void set_statics(void)
|
|||||||
|
|
||||||
void init_dlsym(void)
|
void init_dlsym(void)
|
||||||
{
|
{
|
||||||
// Guarantee that we can do "dirty" casting. Every OS that this program supports should pass this ...
|
// Guarantee that we can do "dirty" casting.
|
||||||
|
// Every OS that this program supports should pass this ...
|
||||||
assert(sizeof(void*) == sizeof(void (*)(void)));
|
assert(sizeof(void*) == sizeof(void (*)(void)));
|
||||||
|
|
||||||
#ifdef HAVE_DYNAMIC
|
#ifdef HAVE_DYNAMIC
|
||||||
|
|
||||||
#ifndef _WIN32 // Try to verify that -lsnes was not linked in from other modules
|
// Try to verify that -lsnes was not linked in from other modules
|
||||||
// since loading it dynamically and with -l will fail hard.
|
// since loading it dynamically and with -l will fail hard.
|
||||||
void *lib = dlopen(NULL, RTLD_LAZY);
|
function_t sym = dylib_proc(NULL, "snes_init");
|
||||||
if (lib)
|
|
||||||
{
|
|
||||||
void *sym = dlsym(lib, "snes_init");
|
|
||||||
if (sym)
|
if (sym)
|
||||||
{
|
{
|
||||||
SSNES_ERR("Serious problem! SSNES wants to load libsnes dyamically, but it is already linked!\n");
|
SSNES_ERR("Serious problem! SSNES wants to load libsnes dyamically, but it is already linked!\n");
|
||||||
SSNES_ERR("This could happen if other modules SSNES depends on link against libsnes directly.\n");
|
SSNES_ERR("This could happen if other modules SSNES depends on link against libsnes directly.\n");
|
||||||
SSNES_ERR("Proceeding could cause a crash! Aborting ...\n");
|
SSNES_ERR("Proceeding could cause a crash! Aborting ...\n");
|
||||||
dlclose(lib);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
dlclose(lib);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!*g_settings.libsnes)
|
if (!*g_settings.libsnes)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@ -220,6 +215,8 @@ void init_dlsym(void)
|
|||||||
#else
|
#else
|
||||||
set_statics();
|
set_statics();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
set_environment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninit_dlsym(void)
|
void uninit_dlsym(void)
|
||||||
@ -243,16 +240,26 @@ dylib_t dylib_load(const char *path)
|
|||||||
function_t dylib_proc(dylib_t lib, const char *proc)
|
function_t dylib_proc(dylib_t lib, const char *proc)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
function_t sym = (function_t)GetProcAddress(lib, proc);
|
function_t sym = (function_t)GetProcAddress(lib ? lib : GetModuleHandle(NULL), proc);
|
||||||
#else
|
#else
|
||||||
|
void *ptr_sym = NULL;
|
||||||
|
if (lib)
|
||||||
|
ptr_sym = dlsym(lib, proc);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void *handle = dlopen(NULL, RTLD_LAZY);
|
||||||
|
if (handle)
|
||||||
|
{
|
||||||
|
ptr_sym = dlsym(handle, proc);
|
||||||
|
dlclose(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Dirty hack to workaround the non-legality of void* -> fn-pointer casts.
|
// Dirty hack to workaround the non-legality of void* -> fn-pointer casts.
|
||||||
void *ptr_sym = dlsym(lib, proc);
|
|
||||||
function_t sym;
|
function_t sym;
|
||||||
memcpy(&sym, &ptr_sym, sizeof(void*));
|
memcpy(&sym, &ptr_sym, sizeof(void*));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!sym)
|
|
||||||
SSNES_WARN("Failed to load symbol \"%s\"\n", proc);
|
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,3 +272,52 @@ void dylib_close(dylib_t lib)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool environment_cb(unsigned cmd, void *data)
|
||||||
|
{
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case SNES_ENVIRONMENT_GET_FULLPATH:
|
||||||
|
*(const char**)data = g_extern.system.fullpath;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SNES_ENVIRONMENT_SET_GEOMETRY:
|
||||||
|
g_extern.system.geom = *(const struct snes_geometry*)data;
|
||||||
|
g_extern.system.geom.max_width = next_pow2(g_extern.system.geom.max_width);
|
||||||
|
g_extern.system.geom.max_height = next_pow2(g_extern.system.geom.max_height);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SNES_ENVIRONMENT_SET_PITCH:
|
||||||
|
g_extern.system.pitch = *(const unsigned*)data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assume SNES as defaults.
|
||||||
|
static void set_environment_defaults(void)
|
||||||
|
{
|
||||||
|
g_extern.system.pitch = 0; // 0 is classic libsnes semantics.
|
||||||
|
g_extern.system.geom = (struct snes_geometry) {
|
||||||
|
.base_width = 256,
|
||||||
|
.base_height = 224,
|
||||||
|
.max_width = 512,
|
||||||
|
.max_height = 512,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSNES extension hooks. Totally optional 'n shizz :)
|
||||||
|
static void set_environment(void)
|
||||||
|
{
|
||||||
|
void (*psnes_set_environment)(snes_environment_t) =
|
||||||
|
(void (*)(snes_environment_t))dylib_proc(lib_handle, "snes_set_environment");
|
||||||
|
|
||||||
|
if (psnes_set_environment)
|
||||||
|
psnes_set_environment(environment_cb);
|
||||||
|
|
||||||
|
set_environment_defaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
18
general.h
18
general.h
@ -74,7 +74,6 @@ struct settings
|
|||||||
char driver[32];
|
char driver[32];
|
||||||
float xscale;
|
float xscale;
|
||||||
float yscale;
|
float yscale;
|
||||||
unsigned base_size;
|
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
unsigned fullscreen_x;
|
unsigned fullscreen_x;
|
||||||
unsigned fullscreen_y;
|
unsigned fullscreen_y;
|
||||||
@ -208,6 +207,13 @@ struct global
|
|||||||
|
|
||||||
unsigned state_slot;
|
unsigned state_slot;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct snes_geometry geom;
|
||||||
|
unsigned pitch; // If 0, has classic libsnes semantics.
|
||||||
|
char fullpath[MAXPATHLEN];
|
||||||
|
} system;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
hermite_resampler_t *source;
|
hermite_resampler_t *source;
|
||||||
@ -329,6 +335,16 @@ extern struct global g_extern;
|
|||||||
fflush(stderr); \
|
fflush(stderr); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#ifndef max
|
||||||
|
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SSNES_SCALE_BASE 256
|
||||||
|
|
||||||
static inline uint32_t next_pow2(uint32_t v)
|
static inline uint32_t next_pow2(uint32_t v)
|
||||||
{
|
{
|
||||||
v--;
|
v--;
|
||||||
|
18
libsnes.hpp
18
libsnes.hpp
@ -66,11 +66,29 @@ extern "C" {
|
|||||||
#define SNES_MEMORY_OAM 103
|
#define SNES_MEMORY_OAM 103
|
||||||
#define SNES_MEMORY_CGRAM 104
|
#define SNES_MEMORY_CGRAM 104
|
||||||
|
|
||||||
|
// SSNES extension. Not required to be implemented for a working implementation.
|
||||||
|
#define SNES_ENVIRONMENT_GET_FULLPATH 0 // const char **
|
||||||
|
#define SNES_ENVIRONMENT_SET_GEOMETRY 1 // const struct snes_geometry *
|
||||||
|
#define SNES_ENVIRONMENT_SET_PITCH 2 // const unsigned *
|
||||||
|
|
||||||
|
struct snes_geometry
|
||||||
|
{
|
||||||
|
unsigned base_width; // Nominal video width of system.
|
||||||
|
unsigned base_height; // Nominal video height of system.
|
||||||
|
unsigned max_width; // Maximum possible width of system.
|
||||||
|
unsigned max_height; // Maximum possible height of system.
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef bool (*snes_environment_t)(unsigned cmd, void *data);
|
||||||
|
void snes_set_environment(snes_environment_t);
|
||||||
|
////
|
||||||
|
|
||||||
typedef void (*snes_video_refresh_t)(const uint16_t *data, unsigned width, unsigned height);
|
typedef void (*snes_video_refresh_t)(const uint16_t *data, unsigned width, unsigned height);
|
||||||
typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right);
|
typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right);
|
||||||
typedef void (*snes_input_poll_t)(void);
|
typedef void (*snes_input_poll_t)(void);
|
||||||
typedef int16_t (*snes_input_state_t)(bool port, unsigned device, unsigned index, unsigned id);
|
typedef int16_t (*snes_input_state_t)(bool port, unsigned device, unsigned index, unsigned id);
|
||||||
|
|
||||||
|
|
||||||
unsigned snes_library_revision_major(void);
|
unsigned snes_library_revision_major(void);
|
||||||
unsigned snes_library_revision_minor(void);
|
unsigned snes_library_revision_minor(void);
|
||||||
|
|
||||||
|
@ -120,7 +120,6 @@ static void set_defaults(void)
|
|||||||
|
|
||||||
g_settings.video.xscale = xscale;
|
g_settings.video.xscale = xscale;
|
||||||
g_settings.video.yscale = yscale;
|
g_settings.video.yscale = yscale;
|
||||||
g_settings.video.base_size = base_size;
|
|
||||||
g_settings.video.fullscreen = g_extern.force_fullscreen ? true : fullscreen;
|
g_settings.video.fullscreen = g_extern.force_fullscreen ? true : fullscreen;
|
||||||
g_settings.video.fullscreen_x = fullscreen_x;
|
g_settings.video.fullscreen_x = fullscreen_x;
|
||||||
g_settings.video.fullscreen_y = fullscreen_y;
|
g_settings.video.fullscreen_y = fullscreen_y;
|
||||||
@ -302,7 +301,6 @@ static void parse_config_file(void)
|
|||||||
|
|
||||||
CONFIG_GET_DOUBLE(video.xscale, "video_xscale");
|
CONFIG_GET_DOUBLE(video.xscale, "video_xscale");
|
||||||
CONFIG_GET_DOUBLE(video.yscale, "video_yscale");
|
CONFIG_GET_DOUBLE(video.yscale, "video_yscale");
|
||||||
CONFIG_GET_INT(video.base_size, "video_base_size");
|
|
||||||
CONFIG_GET_INT(video.fullscreen_x, "video_fullscreen_x");
|
CONFIG_GET_INT(video.fullscreen_x, "video_fullscreen_x");
|
||||||
CONFIG_GET_INT(video.fullscreen_y, "video_fullscreen_y");
|
CONFIG_GET_INT(video.fullscreen_y, "video_fullscreen_y");
|
||||||
|
|
||||||
|
69
ssnes.c
69
ssnes.c
@ -85,6 +85,14 @@ static void set_fast_forward_button(bool new_button_state, bool new_hold_button_
|
|||||||
old_hold_button_state = new_hold_button_state;
|
old_hold_button_state = new_hold_button_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned lines_to_pitch(unsigned height)
|
||||||
|
{
|
||||||
|
if (g_extern.system.pitch == 0) // SNES semantics
|
||||||
|
return ((height == 448) || (height == 478)) ? 1024 : 2048;
|
||||||
|
else
|
||||||
|
return g_extern.system.pitch;
|
||||||
|
}
|
||||||
|
|
||||||
static void video_cached_frame(void);
|
static void video_cached_frame(void);
|
||||||
static void take_screenshot(void)
|
static void take_screenshot(void)
|
||||||
{
|
{
|
||||||
@ -100,7 +108,7 @@ static void take_screenshot(void)
|
|||||||
ret = screenshot_dump(g_settings.screenshot_directory,
|
ret = screenshot_dump(g_settings.screenshot_directory,
|
||||||
data,
|
data,
|
||||||
width, height,
|
width, height,
|
||||||
(height == 448 || height == 478) ? 1024 : 2048);
|
lines_to_pitch(height));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *msg = NULL;
|
const char *msg = NULL;
|
||||||
@ -126,6 +134,25 @@ static void take_screenshot(void)
|
|||||||
msg_queue_push(g_extern.msg_queue, msg, 1, 180);
|
msg_queue_push(g_extern.msg_queue, msg, 1, 180);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void adjust_crop(const uint16_t **data, unsigned *height)
|
||||||
|
{
|
||||||
|
// Rather SNES specific.
|
||||||
|
if (g_settings.video.crop_overscan)
|
||||||
|
{
|
||||||
|
if (*height == 239)
|
||||||
|
{
|
||||||
|
*data += 7 * 1024; // Skip 7 top scanlines.
|
||||||
|
*height = 224;
|
||||||
|
}
|
||||||
|
else if (*height == 478)
|
||||||
|
{
|
||||||
|
*data += 15 * 512; // Skip 15 top scanlines.
|
||||||
|
*height = 448;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// libsnes: 0.065
|
// libsnes: 0.065
|
||||||
// Format received is 16-bit 0RRRRRGGGGGBBBBB
|
// Format received is 16-bit 0RRRRRGGGGGBBBBB
|
||||||
static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
||||||
@ -133,19 +160,7 @@ static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
|||||||
if (!g_extern.video_active)
|
if (!g_extern.video_active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_settings.video.crop_overscan)
|
adjust_crop(&data, &height);
|
||||||
{
|
|
||||||
if (height == 239)
|
|
||||||
{
|
|
||||||
data += 7 * 1024; // Skip 7 top scanlines.
|
|
||||||
height = 224;
|
|
||||||
}
|
|
||||||
else if (height == 478)
|
|
||||||
{
|
|
||||||
data += 15 * 512; // Skip 15 top scanlines.
|
|
||||||
height = 448;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slightly messy code,
|
// Slightly messy code,
|
||||||
// but we really need to do processing before blocking on VSync for best possible scheduling.
|
// but we really need to do processing before blocking on VSync for best possible scheduling.
|
||||||
@ -154,7 +169,7 @@ static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
|||||||
{
|
{
|
||||||
struct ffemu_video_data ffemu_data = {
|
struct ffemu_video_data ffemu_data = {
|
||||||
.data = data,
|
.data = data,
|
||||||
.pitch = height == 448 || height == 478 ? 1024 : 2048,
|
.pitch = lines_to_pitch(height),
|
||||||
.width = width,
|
.width = width,
|
||||||
.height = height,
|
.height = height,
|
||||||
};
|
};
|
||||||
@ -171,7 +186,7 @@ static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
|||||||
unsigned oheight = height;
|
unsigned oheight = height;
|
||||||
g_extern.filter.psize(&owidth, &oheight);
|
g_extern.filter.psize(&owidth, &oheight);
|
||||||
g_extern.filter.prender(g_extern.filter.colormap, g_extern.filter.buffer,
|
g_extern.filter.prender(g_extern.filter.colormap, g_extern.filter.buffer,
|
||||||
g_extern.filter.pitch, data, (height == 448 || height == 478) ? 1024 : 2048, width, height);
|
g_extern.filter.pitch, data, lines_to_pitch(height), width, height);
|
||||||
|
|
||||||
#ifdef HAVE_FFMPEG
|
#ifdef HAVE_FFMPEG
|
||||||
if (g_extern.recording && g_settings.video.post_filter_record)
|
if (g_extern.recording && g_settings.video.post_filter_record)
|
||||||
@ -189,10 +204,10 @@ static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
|||||||
if (!driver.video->frame(driver.video_data, g_extern.filter.buffer, owidth, oheight, g_extern.filter.pitch, msg))
|
if (!driver.video->frame(driver.video_data, g_extern.filter.buffer, owidth, oheight, g_extern.filter.pitch, msg))
|
||||||
g_extern.video_active = false;
|
g_extern.video_active = false;
|
||||||
}
|
}
|
||||||
else if (!driver.video->frame(driver.video_data, data, width, height, (height == 448 || height == 478) ? 1024 : 2048, msg))
|
else if (!driver.video->frame(driver.video_data, data, width, height, lines_to_pitch(height), msg))
|
||||||
g_extern.video_active = false;
|
g_extern.video_active = false;
|
||||||
#else
|
#else
|
||||||
if (!driver.video->frame(driver.video_data, data, width, height, (height == 448 || height == 478) ? 1024 : 2048, msg))
|
if (!driver.video->frame(driver.video_data, data, width, height, lines_to_pitch(height), msg))
|
||||||
g_extern.video_active = false;
|
g_extern.video_active = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -457,6 +472,8 @@ static void print_help(void)
|
|||||||
|
|
||||||
static void set_basename(const char *path)
|
static void set_basename(const char *path)
|
||||||
{
|
{
|
||||||
|
strlcpy(g_extern.system.fullpath, path, sizeof(g_extern.system.fullpath));
|
||||||
|
|
||||||
strlcpy(g_extern.basename, path, sizeof(g_extern.basename));
|
strlcpy(g_extern.basename, path, sizeof(g_extern.basename));
|
||||||
char *dst = strrchr(g_extern.basename, '.');
|
char *dst = strrchr(g_extern.basename, '.');
|
||||||
if (dst)
|
if (dst)
|
||||||
@ -921,10 +938,10 @@ static void init_recording(void)
|
|||||||
struct ffemu_rational ntsc_fps = {60000, 1000};
|
struct ffemu_rational ntsc_fps = {60000, 1000};
|
||||||
struct ffemu_rational pal_fps = {50000, 1000};
|
struct ffemu_rational pal_fps = {50000, 1000};
|
||||||
struct ffemu_params params = {
|
struct ffemu_params params = {
|
||||||
.out_width = 256,
|
.out_width = g_extern.system.geom.base_width,
|
||||||
.out_height = 224,
|
.out_height = g_extern.system.geom.base_height,
|
||||||
.fb_width = 512,
|
.fb_width = g_extern.system.geom.max_width,
|
||||||
.fb_height = 512,
|
.fb_height = g_extern.system.geom.max_height,
|
||||||
.channels = 2,
|
.channels = 2,
|
||||||
.samplerate = 32000,
|
.samplerate = 32000,
|
||||||
.filename = g_extern.record_path,
|
.filename = g_extern.record_path,
|
||||||
@ -939,8 +956,8 @@ static void init_recording(void)
|
|||||||
}
|
}
|
||||||
else if (g_settings.video.hires_record)
|
else if (g_settings.video.hires_record)
|
||||||
{
|
{
|
||||||
params.out_width = 512;
|
params.out_width *= 2;
|
||||||
params.out_height = 448;
|
params.out_height *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_settings.video.force_aspect)
|
if (g_settings.video.force_aspect)
|
||||||
@ -953,8 +970,8 @@ static void init_recording(void)
|
|||||||
g_extern.filter.psize(¶ms.out_width, ¶ms.out_height);
|
g_extern.filter.psize(¶ms.out_width, ¶ms.out_height);
|
||||||
params.rgb32 = true;
|
params.rgb32 = true;
|
||||||
|
|
||||||
unsigned max_width = 512;
|
unsigned max_width = params.fb_width;
|
||||||
unsigned max_height = 512;
|
unsigned max_height = params.fb_height;
|
||||||
g_extern.filter.psize(&max_width, &max_height);
|
g_extern.filter.psize(&max_width, &max_height);
|
||||||
params.fb_width = next_pow2(max_width);
|
params.fb_width = next_pow2(max_width);
|
||||||
params.fb_height = next_pow2(max_height);
|
params.fb_height = next_pow2(max_height);
|
||||||
|
@ -24,9 +24,6 @@
|
|||||||
# video_xscale = 3.0
|
# video_xscale = 3.0
|
||||||
# video_yscale = 3.0
|
# video_yscale = 3.0
|
||||||
|
|
||||||
# Base size for windowed mode calculations. Generally 224 for SNES, but can be modified.
|
|
||||||
# video_base_size = 224
|
|
||||||
|
|
||||||
# Fullscreen resolution. Resolution of 0 uses the resolution of the desktop.
|
# Fullscreen resolution. Resolution of 0 uses the resolution of the desktop.
|
||||||
# video_fullscreen_x = 0
|
# video_fullscreen_x = 0
|
||||||
# video_fullscreen_y = 0
|
# video_fullscreen_y = 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user