Merge remote-tracking branch 'upstream/master' into zip_support

This commit is contained in:
Timo Strunk 2014-09-09 15:38:14 +02:00
commit 4d65063a83
101 changed files with 2943 additions and 1987 deletions

View File

@ -96,7 +96,9 @@
96355CE01788E72A0010DBFA /* Products */,
96355CE91788E72A0010DBFA /* Supporting Files */,
);
indentWidth = 3;
sourceTree = "<group>";
tabWidth = 3;
};
96355CE01788E72A0010DBFA /* Products */ = {
isa = PBXGroup;

View File

@ -203,7 +203,7 @@ static char** waiting_argv;
if (filenames.count == 1 && [filenames objectAtIndex:0])
{
NSString *__core = [filenames objectAtIndex:0];
const char *core_name = driver.menu->info.library_name;
const char *core_name = g_extern.menu.info.library_name;
strlcpy(g_extern.fullpath, __core.UTF8String, sizeof(g_extern.fullpath));
if (core_name)
@ -232,7 +232,7 @@ static char** waiting_argv;
{
NSURL *url = (NSURL*)panel.URL;
NSString *__core = url.path;
const char *core_name = driver.menu->info.library_name;
const char *core_name = g_extern.menu.info.library_name;
strlcpy(g_extern.fullpath, __core.UTF8String, sizeof(g_extern.fullpath));
if (core_name)

View File

@ -97,7 +97,9 @@
96355CE01788E72A0010DBFA /* Products */,
96355CE91788E72A0010DBFA /* Supporting Files */,
);
indentWidth = 3;
sourceTree = "<group>";
tabWidth = 3;
};
96355CE01788E72A0010DBFA /* Products */ = {
isa = PBXGroup;

View File

@ -150,7 +150,9 @@
96AFAE2616C1D4EA009DE44C /* Products */,
96AFAE3416C1D4EA009DE44C /* Supporting Files */,
);
indentWidth = 3;
sourceTree = "<group>";
tabWidth = 3;
};
96AFAE2616C1D4EA009DE44C /* Products */ = {
isa = PBXGroup;

View File

@ -51,7 +51,8 @@ struct rarch_dsp_filter
unsigned num_instances;
};
static const struct dspfilter_implementation *find_implementation(rarch_dsp_filter_t *dsp, const char *ident)
static const struct dspfilter_implementation *find_implementation(
rarch_dsp_filter_t *dsp, const char *ident)
{
unsigned i;
for (i = 0; i < dsp->num_plugs; i++)
@ -69,7 +70,8 @@ struct dsp_userdata
const char *prefix[2];
};
static int get_float(void *userdata, const char *key_str, float *value, float default_value)
static int get_float(void *userdata, const char *key_str,
float *value, float default_value)
{
struct dsp_userdata *dsp = (struct dsp_userdata*)userdata;
@ -85,7 +87,8 @@ static int get_float(void *userdata, const char *key_str, float *value, float de
return got;
}
static int get_int(void *userdata, const char *key_str, int *value, int default_value)
static int get_int(void *userdata, const char *key_str,
int *value, int default_value)
{
struct dsp_userdata *dsp = (struct dsp_userdata*)userdata;
@ -185,7 +188,8 @@ static bool create_filter_graph(rarch_dsp_filter_t *dsp, float sample_rate)
if (!config_get_uint(dsp->conf, "filters", &filters))
return false;
dsp->instances = (struct rarch_dsp_instance*)calloc(filters, sizeof(*dsp->instances));
dsp->instances = (struct rarch_dsp_instance*)
calloc(filters, sizeof(*dsp->instances));
if (!dsp->instances)
return false;
@ -206,7 +210,8 @@ static bool create_filter_graph(rarch_dsp_filter_t *dsp, float sample_rate)
struct dsp_userdata userdata;
userdata.conf = dsp->conf;
userdata.prefix[0] = key; // Index-specific configs take priority over ident-specific.
/* Index-specific configs take priority over ident-specific. */
userdata.prefix[0] = key;
userdata.prefix[1] = dsp->instances[i].impl->short_ident;
struct dspfilter_info info = { sample_rate };
@ -242,7 +247,8 @@ static bool append_plugs(rarch_dsp_filter_t *dsp)
unsigned i;
dspfilter_simd_mask_t mask = rarch_get_cpu_features();
dsp->plugs = (struct rarch_dsp_plug*)calloc(ARRAY_SIZE(dsp_plugs_builtin), sizeof(*dsp->plugs));
dsp->plugs = (struct rarch_dsp_plug*)
calloc(ARRAY_SIZE(dsp_plugs_builtin), sizeof(*dsp->plugs));
if (!dsp->plugs)
return false;
dsp->num_plugs = ARRAY_SIZE(dsp_plugs_builtin);
@ -268,7 +274,8 @@ static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list)
if (!lib)
continue;
dspfilter_get_implementation_t cb = (dspfilter_get_implementation_t)dylib_proc(lib, "dspfilter_get_implementation");
dspfilter_get_implementation_t cb = (dspfilter_get_implementation_t)
dylib_proc(lib, "dspfilter_get_implementation");
if (!cb)
{
dylib_close(lib);
@ -288,7 +295,8 @@ static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list)
continue;
}
struct rarch_dsp_plug *new_plugs = (struct rarch_dsp_plug*)realloc(dsp->plugs, sizeof(*dsp->plugs) * (dsp->num_plugs + 1));
struct rarch_dsp_plug *new_plugs = (struct rarch_dsp_plug*)
realloc(dsp->plugs, sizeof(*dsp->plugs) * (dsp->num_plugs + 1));
if (!new_plugs)
{
dylib_close(lib);
@ -307,7 +315,8 @@ static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list)
}
#endif
rarch_dsp_filter_t *rarch_dsp_filter_new(const char *filter_config, float sample_rate)
rarch_dsp_filter_t *rarch_dsp_filter_new(
const char *filter_config, float sample_rate)
{
#if !defined(HAVE_FILTERS_BUILTIN) && defined(HAVE_DYLIB)
char basedir[PATH_MAX];
@ -381,7 +390,8 @@ void rarch_dsp_filter_free(rarch_dsp_filter_t *dsp)
free(dsp);
}
void rarch_dsp_filter_process(rarch_dsp_filter_t *dsp, struct rarch_dsp_data *data)
void rarch_dsp_filter_process(rarch_dsp_filter_t *dsp,
struct rarch_dsp_data *data)
{
unsigned i;
struct dspfilter_output output = {0};
@ -394,7 +404,8 @@ void rarch_dsp_filter_process(rarch_dsp_filter_t *dsp, struct rarch_dsp_data *da
{
input.samples = output.samples;
input.frames = output.frames;
dsp->instances[i].impl->process(dsp->instances[i].impl_data, &output, &input);
dsp->instances[i].impl->process(
dsp->instances[i].impl_data, &output, &input);
}
data->output = output.samples;

View File

@ -18,7 +18,8 @@
typedef struct rarch_dsp_filter rarch_dsp_filter_t;
rarch_dsp_filter_t *rarch_dsp_filter_new(const char *filter_config, float sample_rate);
rarch_dsp_filter_t *rarch_dsp_filter_new(const char *filter_config,
float sample_rate);
void rarch_dsp_filter_free(rarch_dsp_filter_t *dsp);
@ -27,12 +28,13 @@ struct rarch_dsp_data
float *input;
unsigned input_frames;
// Set by rarch_dsp_filter_process().
/* Set by rarch_dsp_filter_process(). */
float *output;
unsigned output_frames;
};
void rarch_dsp_filter_process(rarch_dsp_filter_t *dsp, struct rarch_dsp_data *data);
void rarch_dsp_filter_process(rarch_dsp_filter_t *dsp,
struct rarch_dsp_data *data);
#endif

View File

@ -39,7 +39,9 @@ static int find_resampler_driver_index(const char *driver)
return -1;
}
// Resampler is used by multiple modules so avoid clobbering g_extern.audio_data.resampler here.
/* Resampler is used by multiple modules so avoid
* clobbering g_extern.audio_data.resampler here. */
static const rarch_resampler_t *find_resampler_driver(const char *ident)
{
int i = find_resampler_driver_index(ident);
@ -64,22 +66,27 @@ void find_prev_resampler_driver(void)
{
int i = find_resampler_driver_index(g_settings.audio.resampler);
if (i > 0)
strlcpy(g_settings.audio.resampler, resampler_drivers[i - 1]->ident, sizeof(g_settings.audio.resampler));
strlcpy(g_settings.audio.resampler, resampler_drivers[i - 1]->ident,
sizeof(g_settings.audio.resampler));
else
RARCH_WARN("Couldn't find any previous resampler driver (current one: \"%s\").\n", g_extern.audio_data.resampler->ident);
RARCH_WARN("Couldn't find any previous resampler driver (current one: \"%s\").\n",
g_extern.audio_data.resampler->ident);
}
void find_next_resampler_driver(void)
{
int i = find_resampler_driver_index(g_settings.audio.resampler);
if (i >= 0 && resampler_drivers[i + 1])
strlcpy(g_settings.audio.resampler, resampler_drivers[i + 1]->ident, sizeof(g_settings.audio.resampler));
strlcpy(g_settings.audio.resampler, resampler_drivers[i + 1]->ident,
sizeof(g_settings.audio.resampler));
else
RARCH_WARN("Couldn't find any next resampler driver (current one: \"%s\").\n", g_extern.audio_data.resampler->ident);
RARCH_WARN("Couldn't find any next resampler driver (current one: \"%s\").\n",
g_extern.audio_data.resampler->ident);
}
#endif
bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, const char *ident, double bw_ratio)
bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend,
const char *ident, double bw_ratio)
{
if (*re && *backend)
(*backend)->free(*re);

View File

@ -26,8 +26,8 @@
#include <math.h>
#include "../boolean.h"
// M_PI is left out of ISO C99 :(
#ifndef M_PI
/* M_PI is left out of ISO C99 :( */
#define M_PI 3.14159265358979323846264338327
#endif
@ -44,7 +44,9 @@ struct resampler_data
typedef struct rarch_resampler
{
void *(*init)(double bandwidth_mod); // Bandwidth factor. Will be < 1.0 for downsampling, > 1.0 for upsamling. Corresponds to expected resampling ratio.
/* Bandwidth factor. Will be < 1.0 for downsampling, > 1.0 for upsamling.
* Corresponds to expected resampling ratio. */
void *(*init)(double bandwidth_mod);
void (*process)(void *re, struct resampler_data *data);
void (*free)(void *re);
const char *ident;
@ -53,12 +55,14 @@ typedef struct rarch_resampler
extern const rarch_resampler_t sinc_resampler;
extern const rarch_resampler_t CC_resampler;
// Reallocs resampler. Will free previous handle before allocating a new one.
// If ident is NULL, first resampler will be used.
bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, const char *ident, double bw_ratio);
/* Reallocs resampler. Will free previous handle before
* allocating a new one. If ident is NULL, first resampler will be used. */
bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend,
const char *ident, double bw_ratio);
// Convenience macros.
// freep makes sure to set handles to NULL to avoid double-free in rarch_resampler_realloc.
/* Convenience macros.
* freep makes sure to set handles to NULL to avoid double-free
* in rarch_resampler_realloc. */
#define rarch_resampler_freep(backend, handle) do { \
if (*(backend) && *(handle)) \
(*backend)->free(*handle); \

View File

@ -42,7 +42,8 @@ void audio_convert_float_to_s16_C(int16_t *out,
for (i = 0; i < samples; i++)
{
int32_t val = (int32_t)(in[i] * 0x8000);
out[i] = (val > 0x7FFF) ? 0x7FFF : (val < -0x8000 ? -0x8000 : (int16_t)val);
out[i] = (val > 0x7FFF) ? 0x7FFF :
(val < -0x8000 ? -0x8000 : (int16_t)val);
}
}
@ -98,7 +99,9 @@ void audio_convert_s16_to_float_altivec(float *out,
size_t samples_in = samples;
const vector float gain_vec = { gain, gain , gain, gain };
const vector float zero_vec = { 0.0f, 0.0f, 0.0f, 0.0f};
// Unaligned loads/store is a bit expensive, so we optimize for the good path (very likely).
/* Unaligned loads/store is a bit expensive, so we
* optimize for the good path (very likely). */
if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0)
{
size_t i;
@ -123,7 +126,9 @@ void audio_convert_float_to_s16_altivec(int16_t *out,
const float *in, size_t samples)
{
int samples_in = samples;
// Unaligned loads/store is a bit expensive, so we optimize for the good path (very likely).
/* Unaligned loads/store is a bit expensive,
* so we optimize for the good path (very likely). */
if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0)
{
size_t i;
@ -141,21 +146,26 @@ void audio_convert_float_to_s16_altivec(int16_t *out,
audio_convert_float_to_s16_C(out, in, samples_in);
}
#elif defined(__ARM_NEON__)
void audio_convert_s16_float_asm(float *out, const int16_t *in, size_t samples, const float *gain); // Avoid potential hard-float/soft-float ABI issues.
static void audio_convert_s16_to_float_neon(float *out, const int16_t *in, size_t samples,
float gain)
/* Avoid potential hard-float/soft-float ABI issues. */
void audio_convert_s16_float_asm(float *out, const int16_t *in,
size_t samples, const float *gain);
static void audio_convert_s16_to_float_neon(float *out,
const int16_t *in, size_t samples, float gain)
{
size_t aligned_samples = samples & ~7;
if (aligned_samples)
audio_convert_s16_float_asm(out, in, aligned_samples, &gain);
// Could do all conversion in ASM, but keep it simple for now.
/* Could do all conversion in ASM, but keep it simple for now. */
audio_convert_s16_to_float_C(out + aligned_samples, in + aligned_samples,
samples - aligned_samples, gain);
}
void audio_convert_float_s16_asm(int16_t *out, const float *in, size_t samples);
static void audio_convert_float_to_s16_neon(int16_t *out, const float *in, size_t samples)
static void audio_convert_float_to_s16_neon(int16_t *out,
const float *in, size_t samples)
{
size_t aligned_samples = samples & ~7;
if (aligned_samples)
@ -169,8 +179,9 @@ void audio_convert_s16_to_float_ALLEGREX(float *out,
const int16_t *in, size_t samples, float gain)
{
#ifdef DEBUG
// Make sure the buffer is 16 byte aligned, this should be the default behaviour of malloc in the PSPSDK.
// Only the output buffer can be assumed to be 16-byte aligned.
/* Make sure the buffer is 16 byte aligned, this should be the
* default behaviour of malloc in the PSPSDK.
* Only the output buffer can be assumed to be 16-byte aligned. */
rarch_assert(((uintptr_t)out & 0xf) == 0);
#endif
@ -227,8 +238,9 @@ void audio_convert_float_to_s16_ALLEGREX(int16_t *out,
const float *in, size_t samples)
{
#ifdef DEBUG
// Make sure the buffers are 16 byte aligned, this should be the default behaviour of malloc in the PSPSDK.
// Both buffers are allocated by RetroArch, so can assume alignment.
/* Make sure the buffers are 16 byte aligned, this should be
* the default behaviour of malloc in the PSPSDK.
* Both buffers are allocated by RetroArch, so can assume alignment. */
rarch_assert(((uintptr_t)in & 0xf) == 0);
rarch_assert(((uintptr_t)out & 0xf) == 0);
#endif
@ -257,7 +269,8 @@ void audio_convert_float_to_s16_ALLEGREX(int16_t *out,
for (; i < samples; i++)
{
int32_t val = (int32_t)(in[i] * 0x8000);
out[i] = (val > 0x7FFF) ? 0x7FFF : (val < -0x8000 ? -0x8000 : (int16_t)val);
out[i] = (val > 0x7FFF) ? 0x7FFF :
(val < -0x8000 ? -0x8000 : (int16_t)val);
}
}
#endif

View File

@ -29,7 +29,8 @@ typedef struct android_camera
GLuint tex;
} androidcamera_t;
static void *android_camera_init(const char *device, uint64_t caps, unsigned width, unsigned height)
static void *android_camera_init(const char *device, uint64_t caps,
unsigned width, unsigned height)
{
JNIEnv *env;
jclass class;
@ -44,7 +45,8 @@ static void *android_camera_init(const char *device, uint64_t caps, unsigned wid
}
struct android_app *android_app = (struct android_app*)g_android;
androidcamera_t *androidcamera = (androidcamera_t*)calloc(1, sizeof(androidcamera_t));
androidcamera_t *androidcamera = (androidcamera_t*)
calloc(1, sizeof(androidcamera_t));
if (!androidcamera)
return NULL;
@ -56,31 +58,38 @@ static void *android_camera_init(const char *device, uint64_t caps, unsigned wid
if (class == NULL)
goto dealloc;
GET_METHOD_ID(env, androidcamera->onCameraInit, class, "onCameraInit", "()V");
GET_METHOD_ID(env, androidcamera->onCameraInit, class,
"onCameraInit", "()V");
if (!androidcamera->onCameraInit)
goto dealloc;
GET_METHOD_ID(env, androidcamera->onCameraFree, class, "onCameraFree", "()V");
GET_METHOD_ID(env, androidcamera->onCameraFree, class,
"onCameraFree", "()V");
if (!androidcamera->onCameraFree)
goto dealloc;
GET_METHOD_ID(env, androidcamera->onCameraSetTexture, class, "onCameraSetTexture", "(I)V");
GET_METHOD_ID(env, androidcamera->onCameraSetTexture, class,
"onCameraSetTexture", "(I)V");
if (!androidcamera->onCameraSetTexture)
goto dealloc;
GET_METHOD_ID(env, androidcamera->onCameraStart, class, "onCameraStart", "()V");
GET_METHOD_ID(env, androidcamera->onCameraStart, class,
"onCameraStart", "()V");
if (!androidcamera->onCameraStart)
goto dealloc;
GET_METHOD_ID(env, androidcamera->onCameraStop, class, "onCameraStop", "()V");
GET_METHOD_ID(env, androidcamera->onCameraStop, class,
"onCameraStop", "()V");
if (!androidcamera->onCameraStop)
goto dealloc;
GET_METHOD_ID(env, androidcamera->onCameraPoll, class, "onCameraPoll", "()Z");
GET_METHOD_ID(env, androidcamera->onCameraPoll, class,
"onCameraPoll", "()Z");
if (!androidcamera->onCameraPoll)
goto dealloc;
CALL_VOID_METHOD(env, android_app->activity->clazz, androidcamera->onCameraInit);
CALL_VOID_METHOD(env, android_app->activity->clazz,
androidcamera->onCameraInit);
return androidcamera;
dealloc:
@ -96,7 +105,8 @@ static void android_camera_free(void *data)
if (!env)
return;
CALL_VOID_METHOD(env, android_app->activity->clazz, androidcamera->onCameraFree);
CALL_VOID_METHOD(env, android_app->activity->clazz,
androidcamera->onCameraFree);
free(androidcamera);
}
@ -111,13 +121,17 @@ static bool android_camera_start(void *data)
glGenTextures(1, &androidcamera->tex);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, androidcamera->tex);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
CALL_VOID_METHOD_PARAM(env, android_app->activity->clazz, androidcamera->onCameraSetTexture, (int) androidcamera->tex);
CALL_VOID_METHOD(env, android_app->activity->clazz, androidcamera->onCameraStart);
CALL_VOID_METHOD_PARAM(env, android_app->activity->clazz,
androidcamera->onCameraSetTexture, (int) androidcamera->tex);
CALL_VOID_METHOD(env, android_app->activity->clazz,
androidcamera->onCameraStart);
return true;
}
@ -130,13 +144,15 @@ static void android_camera_stop(void *data)
if (!env)
return;
CALL_VOID_METHOD(env, android_app->activity->clazz, androidcamera->onCameraStop);
CALL_VOID_METHOD(env, android_app->activity->clazz,
androidcamera->onCameraStop);
if (androidcamera->tex)
glDeleteTextures(1, &androidcamera->tex);
}
static bool android_camera_poll(void *data, retro_camera_frame_raw_framebuffer_t frame_raw_cb,
static bool android_camera_poll(void *data,
retro_camera_frame_raw_framebuffer_t frame_raw_cb,
retro_camera_frame_opengl_texture_t frame_gl_cb)
{
struct android_app *android_app = (struct android_app*)g_android;
@ -148,11 +164,13 @@ static bool android_camera_poll(void *data, retro_camera_frame_raw_framebuffer_t
(void)frame_raw_cb;
jboolean newFrame;
CALL_BOOLEAN_METHOD(env, newFrame, android_app->activity->clazz, androidcamera->onCameraPoll);
CALL_BOOLEAN_METHOD(env, newFrame, android_app->activity->clazz,
androidcamera->onCameraPoll);
if (newFrame)
{
// FIXME: Identity for now. Use proper texture matrix as returned by Android Camera.
/* FIXME: Identity for now. Use proper texture matrix as
* returned by Android Camera. */
static const float affine[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,

View File

@ -61,7 +61,8 @@ typedef struct video4linux
char dev_name[PATH_MAX];
} video4linux_t;
static void process_image(video4linux_t *v4l, const uint8_t *buffer_yuv)
static void process_image(video4linux_t *v4l,
const uint8_t *buffer_yuv)
{
RARCH_PERFORMANCE_INIT(yuv_convert_direct);
RARCH_PERFORMANCE_START(yuv_convert_direct);
@ -182,7 +183,8 @@ static bool init_device(void *data)
if (!(cap.capabilities & V4L2_CAP_STREAMING))
{
RARCH_ERR("%s does not support streaming I/O (V4L2_CAP_STREAMING).\n", v4l->dev_name);
RARCH_ERR("%s does not support streaming I/O (V4L2_CAP_STREAMING).\n",
v4l->dev_name);
return false;
}
@ -193,7 +195,7 @@ static bool init_device(void *data)
{
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect;
// Ignore errors here.
/* Ignore errors here. */
xioctl(v4l->fd, VIDIOC_S_CROP, &crop);
}
@ -211,21 +213,23 @@ static bool init_device(void *data)
return false;
}
// VIDIOC_S_FMT may change width, height and pitch.
/* VIDIOC_S_FMT may change width, height and pitch. */
v4l->width = fmt.fmt.pix.width;
v4l->height = fmt.fmt.pix.height;
v4l->pitch = max(fmt.fmt.pix.bytesperline, v4l->width * 2);
// Sanity check to see if our assumptions are met.
// It is possible to support whatever the device gives us,
// but this dramatically increases complexity.
/* Sanity check to see if our assumptions are met.
* It is possible to support whatever the device gives us,
* but this dramatically increases complexity.
*/
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV)
{
RARCH_ERR("The V4L2 device doesn't support YUYV.\n");
return false;
}
if (fmt.fmt.pix.field != V4L2_FIELD_NONE && fmt.fmt.pix.field != V4L2_FIELD_INTERLACED)
if (fmt.fmt.pix.field != V4L2_FIELD_NONE
&& fmt.fmt.pix.field != V4L2_FIELD_INTERLACED)
{
RARCH_ERR("The V4L2 device doesn't support progressive nor interlaced video.\n");
return false;
@ -300,7 +304,8 @@ static void v4l_free(void *data)
free(v4l);
}
static void *v4l_init(const char *device, uint64_t caps, unsigned width, unsigned height)
static void *v4l_init(const char *device, uint64_t caps,
unsigned width, unsigned height)
{
struct stat st;
@ -314,7 +319,8 @@ static void *v4l_init(const char *device, uint64_t caps, unsigned width, unsigne
if (!v4l)
return NULL;
strlcpy(v4l->dev_name, device ? device : "/dev/video0", sizeof(v4l->dev_name));
strlcpy(v4l->dev_name, device ? device : "/dev/video0",
sizeof(v4l->dev_name));
v4l->width = width;
v4l->height = height;
@ -322,7 +328,8 @@ static void *v4l_init(const char *device, uint64_t caps, unsigned width, unsigne
if (stat(v4l->dev_name, &st) == -1)
{
RARCH_ERR("Cannot identify '%s' : %d, %s\n", v4l->dev_name, errno, strerror(errno));
RARCH_ERR("Cannot identify '%s' : %d, %s\n", v4l->dev_name,
errno, strerror(errno));
goto error;
}
@ -336,14 +343,17 @@ static void *v4l_init(const char *device, uint64_t caps, unsigned width, unsigne
if (v4l->fd == -1)
{
RARCH_ERR("Cannot open '%s': %d, %s\n", v4l->dev_name, errno, strerror(errno));
RARCH_ERR("Cannot open '%s': %d, %s\n", v4l->dev_name,
errno, strerror(errno));
goto error;
}
if (!init_device(v4l))
goto error;
v4l->buffer_output = (uint32_t*)malloc(v4l->width * v4l->height * sizeof(uint32_t));
v4l->buffer_output = (uint32_t*)
malloc(v4l->width * v4l->height * sizeof(uint32_t));
if (!v4l->buffer_output)
{
RARCH_ERR("Failed to allocate output buffer.\n");
@ -403,7 +413,8 @@ static bool preprocess_image(void *data)
return true;
}
static bool v4l_poll(void *data, retro_camera_frame_raw_framebuffer_t frame_raw_cb,
static bool v4l_poll(void *data,
retro_camera_frame_raw_framebuffer_t frame_raw_cb,
retro_camera_frame_opengl_texture_t frame_gl_cb)
{
video4linux_t *v4l = (video4linux_t*)data;
@ -415,7 +426,8 @@ static bool v4l_poll(void *data, retro_camera_frame_raw_framebuffer_t frame_raw_
if (preprocess_image(data))
{
if (frame_raw_cb != NULL)
frame_raw_cb(v4l->buffer_output, v4l->width, v4l->height, v4l->width * 4);
frame_raw_cb(v4l->buffer_output, v4l->width,
v4l->height, v4l->width * 4);
return true;
}
else

View File

@ -14,7 +14,8 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Prefix header for all source files of the 'RetroArch' target in the 'RetroArch' project
/* Prefix header for all source files of the 'RetroArch'
* target in the 'RetroArch' project. */
#ifdef IOS
#import <Availability.h>

View File

@ -80,8 +80,8 @@ static int parse_short(const char *optstring, char * const *argv)
bool extra_opt = argv[0][2];
bool takes_arg = opt[1] == ':';
// If we take an argument, and we see additional characters,
// this is in fact the argument (i.e. -cfoo is same as -c foo).
/* If we take an argument, and we see additional characters,
* this is in fact the argument (i.e. -cfoo is same as -c foo). */
bool embedded_arg = extra_opt && takes_arg;
if (takes_arg)
@ -99,8 +99,11 @@ static int parse_short(const char *optstring, char * const *argv)
return optarg ? opt[0] : '?';
}
else if (embedded_arg) // If we see additional characters, and they don't take arguments, this means we have multiple flags in one.
else if (embedded_arg)
{
/* If we see additional characters,
* and they don't take arguments, this
* means we have multiple flags in one. */
memmove(&argv[0][1], &argv[0][2], strlen(&argv[0][2]) + 1);
return opt[0];
}
@ -127,7 +130,7 @@ static int parse_long(const struct option *longopts, char * const *argv)
if (!opt)
return '?';
// getopt_long has an "optional" arg, but we don't bother with that.
/* getopt_long has an "optional" arg, but we don't bother with that. */
if (opt->has_arg && !argv[1])
return '?';
@ -144,8 +147,8 @@ static int parse_long(const struct option *longopts, char * const *argv)
*opt->flag = opt->val;
return 0;
}
else
return opt->val;
return opt->val;
}
static void shuffle_block(char **begin, char **last, char **end)
@ -175,18 +178,19 @@ int getopt_long(int argc, char *argv[],
int short_index = find_short_index(&argv[optind]);
int long_index = find_long_index(&argv[optind]);
// We're done here.
/* We're done here. */
if (short_index == -1 && long_index == -1)
return -1;
// Reorder argv so that non-options come last.
// Non-POSIXy, but that's what getopt does by default.
/* Reorder argv so that non-options come last.
* Non-POSIXy, but that's what getopt does by default. */
if ((short_index > 0) && ((short_index < long_index) || (long_index == -1)))
{
shuffle_block(&argv[optind], &argv[optind + short_index], &argv[argc]);
short_index = 0;
}
else if ((long_index > 0) && ((long_index < short_index) || (short_index == -1)))
else if ((long_index > 0) && ((long_index < short_index)
|| (short_index == -1)))
{
shuffle_block(&argv[optind], &argv[optind + long_index], &argv[argc]);
long_index = 0;
@ -205,7 +209,7 @@ int getopt_long(int argc, char *argv[],
#endif
#ifndef HAVE_STRCASESTR
// Pretty much strncasecmp.
/* Pretty much strncasecmp. */
static int casencmp(const char *a, const char *b, size_t n)
{
size_t i;
@ -239,7 +243,7 @@ char *strcasestr_rarch__(const char *haystack, const char *needle)
#ifndef HAVE_STRL
// Implementation of strlcpy()/strlcat() based on OpenBSD.
/* Implementation of strlcpy()/strlcat() based on OpenBSD. */
size_t strlcpy(char *dest, const char *source, size_t size)
{

View File

@ -21,8 +21,11 @@
#include "fnmatch_rarch.h"
// Implemnentation of fnmatch(3) so it can be distributed to non *nix platforms
// No flags are implemented ATM. We don't use them. Add flags as needed.
/* Implemnentation of fnmatch(3) so it can be
* distributed to non *nix platforms.
*
* No flags are implemented ATM.
* We don't use them. Add flags as needed. */
int rl_fnmatch(const char *pattern, const char *string, int flags)
{
@ -31,30 +34,32 @@ int rl_fnmatch(const char *pattern, const char *string, int flags)
int rv;
for (c = pattern; *c != '\0'; c++)
{
// String ended before pattern
/* String ended before pattern */
if ((*c != '*') && (*string == '\0'))
return FNM_NOMATCH;
switch (*c)
{
// Match any number of unknown chars
/* Match any number of unknown chars */
case '*':
// Find next node in the pattern ignoring multiple
// asterixes
/* Find next node in the pattern
* ignoring multiple asterixes
*/
do {
c++;
if (*c == '\0')
return 0;
} while (*c == '*');
// Match the remaining pattern ingnoring more and more
// chars.
/* Match the remaining pattern
* ignoring more and more characters. */
do {
// We reached the end of the string without a
// match. There is a way to optimize this by
// calculating the minimum chars needed to
// match the remaining pattern but I don't
// think it is worth the work ATM.
/* We reached the end of the string without a
* match. There is a way to optimize this by
* calculating the minimum chars needed to
* match the remaining pattern but I don't
* think it is worth the work ATM.
*/
if (*string == '\0')
return FNM_NOMATCH;
@ -63,16 +68,16 @@ int rl_fnmatch(const char *pattern, const char *string, int flags)
} while (rv != 0);
return 0;
// Match char from list
/* Match char from list */
case '[':
charmatch = 0;
for (c++; *c != ']'; c++)
{
// Bad formath
/* Bad format */
if (*c == '\0')
return FNM_NOMATCH;
// Match already found
/* Match already found */
if (charmatch)
continue;
@ -80,21 +85,21 @@ int rl_fnmatch(const char *pattern, const char *string, int flags)
charmatch = 1;
}
// No match in list
/* No match in list */
if (!charmatch)
return FNM_NOMATCH;
string++;
break;
// Has any char
/* Has any character */
case '?':
string++;
break;
// Match following char verbatim
/* Match following character verbatim */
case '\\':
c++;
// Dangling escape at end of pattern
if (*c == '\0') // FIXME: Was c == '\0' (makes no sense). Not sure if c == NULL or *c == '\0' is intended. Assuming *c due to c++ right before.
/* Dangling escape at end of pattern */
if (*c == '\0') /* FIXME: Was c == '\0' (makes no sense). Not sure if c == NULL or *c == '\0' is intended. Assuming *c due to c++ right before. */
return FNM_NOMATCH;
default:
if (*c != *string)
@ -103,7 +108,7 @@ int rl_fnmatch(const char *pattern, const char *string, int flags)
}
}
// End of string and end of pattend
/* End of string and end of pattend */
if (*string == '\0')
return 0;
return FNM_NOMATCH;

View File

@ -20,14 +20,15 @@
#include "config.h"
#endif
// Custom implementation of the GNU getopt_long for portability.
// Not designed to be fully compatible,
// but compatible with the features RetroArch uses.
/* Custom implementation of the GNU getopt_long for portability.
* Not designed to be fully compatible, but compatible with
* the features RetroArch uses. */
#ifdef HAVE_GETOPT_LONG
#include <getopt.h>
#else
// Avoid possible naming collisions during link since we prefer to use the actual name.
/* Avoid possible naming collisions during link since we
* prefer to use the actual name. */
#define getopt_long(argc, argv, optstring, longopts, longindex) __getopt_long_rarch(argc, argv, optstring, longopts, longindex)
#ifdef __cplusplus
@ -42,8 +43,9 @@ struct option
int val;
};
// argv[] is declared with char * const argv[] in GNU,
// but this makes no sense, as non-POSIX getopt_long mutates argv (non-opts are moved to the end).
/* argv[] is declared with char * const argv[] in GNU,
* but this makes no sense, as non-POSIX getopt_long
* mutates argv (non-opts are moved to the end). */
int getopt_long(int argc, char *argv[],
const char *optstring, const struct option *longopts, int *longindex);
extern char *optarg;

View File

@ -72,12 +72,11 @@ static bool validate_header(const char **ptr)
if (!eol)
return false;
// Always use UTF-8. Don't really care to check.
/* Always use UTF-8. Don't really care to check. */
*ptr = eol + 3;
return true;
}
else
return true;
return true;
}
static bool range_is_space(const char *begin, const char *end)
@ -113,7 +112,8 @@ static char *strdup_range(const char *begin, const char *end)
static char *strdup_range_escape(const char *begin, const char *end)
{
return strdup_range(begin, end); // Escaping is ignored. Assume we don't deal with that.
/* Escaping is ignored. Assume we don't deal with that. */
return strdup_range(begin, end);
}
static struct rxml_attrib_node *rxml_parse_attrs(const char *str)
@ -148,7 +148,8 @@ static struct rxml_attrib_node *rxml_parse_attrs(const char *str)
if (!attrib || !value)
goto end;
struct rxml_attrib_node *new_node = (struct rxml_attrib_node*)calloc(1, sizeof(*new_node));
struct rxml_attrib_node *new_node =
(struct rxml_attrib_node*)calloc(1, sizeof(*new_node));
if (!new_node)
goto end;
@ -233,9 +234,10 @@ static struct rxml_node *rxml_parse_node(const char **ptr_)
if (!rxml_parse_tag(node, str))
goto error;
is_closing = strstr(ptr, "/>") + 1 == closing; // Are spaces between / and > allowed?
/* Are spaces between / and > allowed? */
is_closing = strstr(ptr, "/>") + 1 == closing;
// Look for more data. Either child nodes or data.
/* Look for more data. Either child nodes or data. */
if (!is_closing)
{
size_t closing_tag_size = strlen(node->name) + 4;
@ -262,8 +264,9 @@ static struct rxml_node *rxml_parse_node(const char **ptr_)
goto error;
}
if (cdata_start && range_is_space(closing + 1, cdata_start)) // CDATA section
if (cdata_start && range_is_space(closing + 1, cdata_start))
{
/* CDATA section */
const char *cdata_end = strstr(cdata_start, "]]>");
if (!cdata_end)
{
@ -273,10 +276,11 @@ static struct rxml_node *rxml_parse_node(const char **ptr_)
node->data = strdup_range(cdata_start + strlen("<![CDATA["), cdata_end);
}
else if (closing_start && closing_start == child_start) // Simple Data
else if (closing_start && closing_start == child_start) /* Simple Data */
node->data = strdup_range(closing + 1, closing_start);
else // Parse all child nodes.
else
{
/* Parse all child nodes. */
struct rxml_node *list = NULL;
struct rxml_node *tail = NULL;
@ -356,7 +360,8 @@ static char *purge_xml_comments(const char *str)
copy_src = comment_end + strlen("-->");
}
// Avoid strcpy() as OpenBSD is anal and hates you for using it even when it's perfectly safe.
/* Avoid strcpy() as OpenBSD is anal and hates you
* for using it even when it's perfectly safe. */
len = strlen(copy_src);
memcpy(copy_dest, copy_src, len);
copy_dest[len] = '\0';

View File

@ -20,14 +20,16 @@
extern "C" {
#endif
// Total NIH. Very trivial "XML" implementation for use in RetroArch.
// Error checking is minimal. Invalid documents may lead to very buggy behavior, but
// memory corruption should never happen.
//
// Only parts of standard that RetroArch cares about is supported.
// Nothing more, nothing less. "Clever" XML documents will probably break the implementation.
//
// Do *NOT* try to use this for anything else. You have been warned.
/* Total NIH. Very trivial "XML" implementation for use in RetroArch.
* Error checking is minimal. Invalid documents may lead to very
* buggy behavior, but memory corruption should never happen.
*
* Only parts of standard that RetroArch cares about is supported.
* Nothing more, nothing less. "Clever" XML documents will
* probably break the implementation.
*
* Do *NOT* try to use this for anything else. You have been warned.
*/
typedef struct rxml_document rxml_document_t;
@ -47,7 +49,9 @@ struct rxml_node
struct rxml_node *children;
struct rxml_node *next;
int type; // Dummy. Used by libxml2 compat. Is always set to 0, so XML_ELEMENT_NODE check goes through.
/* Dummy. Used by libxml2 compat.
* Is always set to 0, so XML_ELEMENT_NODE check goes through. */
int type;
};
rxml_document_t *rxml_load_document(const char *path);
@ -55,14 +59,16 @@ void rxml_free_document(rxml_document_t *doc);
struct rxml_node *rxml_root_node(rxml_document_t *doc);
// Drop const-correctness here to avoid warnings when used as libxml2 compat.
// xmlGetProp() returns xmlChar*, which is supposed to be passed to xmlFree().
/* Drop const-correctness here to avoid warnings
* when used as libxml2 compat.
* xmlGetProp() returns xmlChar*, which is supposed
* to be passed to xmlFree(). */
char *rxml_node_attrib(struct rxml_node *node, const char *attrib);
#ifdef RXML_LIBXML2_COMPAT
// Compat for part of libxml2 that RetroArch uses.
/* Compat for part of libxml2 that RetroArch uses. */
#define LIBXML_TEST_VERSION ((void)0)
typedef char xmlChar; // It's really unsigned char, but it doesn't matter.
typedef char xmlChar; /* It's really unsigned char, but it doesn't matter. */
typedef struct rxml_node *xmlNodePtr;
typedef void *xmlParserCtxtPtr;
typedef rxml_document_t *xmlDocPtr;

View File

@ -22,8 +22,10 @@ static void print_siblings(struct rxml_node *node, unsigned level)
if (node->data)
fprintf(stderr, "%*sData: %s\n", level * 4, "", node->data);
for (const struct rxml_attrib_node *attrib = node->attrib; attrib; attrib = attrib->next)
fprintf(stderr, "%*s Attrib: %s = %s\n", level * 4, "", attrib->attrib, attrib->value);
for (const struct rxml_attrib_node *attrib =
node->attrib; attrib; attrib = attrib->next)
fprintf(stderr, "%*s Attrib: %s = %s\n", level * 4, "",
attrib->attrib, attrib->value);
if (node->children)
print_siblings(node->children, level + 1);

View File

@ -28,7 +28,8 @@
extern "C" {
#endif
// Avoid possible naming collisions during link since we prefer to use the actual name.
/* Avoid possible naming collisions during link
* since we prefer to use the actual name. */
#define strcasestr(haystack, needle) strcasestr_rarch__(haystack, needle)
char *strcasestr(const char *haystack, const char *needle);

View File

@ -28,7 +28,8 @@
#ifdef __cplusplus
extern "C" {
#endif
// Avoid possible naming collisions during link since we prefer to use the actual name.
/* Avoid possible naming collisions during link since
* we prefer to use the actual name. */
#define strlcpy(dst, src, size) strlcpy_rarch__(dst, src, size)
#define strlcat(dst, src, size) strlcat_rarch__(dst, src, size)

View File

@ -262,9 +262,7 @@ enum
#define DEFAULT_ASPECT_RATIO -1.0f
#endif
////////////////
// Video
////////////////
/* VIDEO */
#if defined(_XBOX360)
#define DEFAULT_GAMMA 1
@ -274,16 +272,27 @@ enum
static const unsigned int def_user_language = 0;
// Windowed
// Real x resolution = aspect * base_size * x scale
// Real y resolution = base_size * y scale
/* Windowed
* Real x resolution = aspect * base_size * x scale
* Real y resolution = base_size * y scale
*/
static const float scale = 3.0;
// Fullscreen
static const bool fullscreen = false; // To start in Fullscreen or not.
static const bool windowed_fullscreen = true; // To use windowed mode or not when going fullscreen.
static const unsigned monitor_index = 0; // Which monitor to prefer. 0 is any monitor, 1 and up selects specific monitors, 1 being the first monitor.
static const unsigned fullscreen_x = 0; // Fullscreen resolution. A value of 0 uses the desktop resolution.
/* Fullscreen */
/* To start in Fullscreen, or not. */
static const bool fullscreen = false;
/* To use windowed mode or not when going fullscreen. */
static const bool windowed_fullscreen = true;
/* Which monitor to prefer. 0 is any monitor, 1 and up selects
* specific monitors, 1 being the first monitor. */
static const unsigned monitor_index = 0;
/* Fullscreen resolution. A value of 0 uses the desktop
* resolution. */
static const unsigned fullscreen_x = 0;
static const unsigned fullscreen_y = 0;
#if defined(RARCH_CONSOLE) || defined(__APPLE__)
@ -292,72 +301,89 @@ static const bool load_dummy_on_core_shutdown = false;
static const bool load_dummy_on_core_shutdown = true;
#endif
// Forcibly disable composition. Only valid on Windows Vista/7/8 for now.
/* Forcibly disable composition.
* Only valid on Windows Vista/7/8 for now. */
static const bool disable_composition = false;
// Video VSYNC (recommended)
/* Video VSYNC (recommended) */
static const bool vsync = true;
// Attempts to hard-synchronize CPU and GPU. Can reduce latency at cost of performance.
/* Attempts to hard-synchronize CPU and GPU.
* Can reduce latency at cost of performance. */
static const bool hard_sync = false;
// Configures how many frames the GPU can run ahead of CPU.
// 0: Syncs to GPU immediately.
// 1: Syncs to previous frame.
// 2: Etc ...
/* Configures how many frames the GPU can run ahead of CPU.
* 0: Syncs to GPU immediately.
* 1: Syncs to previous frame.
* 2: Etc ...
*/
static const unsigned hard_sync_frames = 0;
// Sets how many milliseconds to delay after VSync before running the core.
// Can reduce latency at cost of higher risk of stuttering.
/* Sets how many milliseconds to delay after VSync before running the core.
* Can reduce latency at cost of higher risk of stuttering.
*/
static const unsigned frame_delay = 0;
// Inserts a black frame inbetween frames.
// Useful for 120 Hz monitors who want to play 60 Hz material with eliminated ghosting. video_refresh_rate should still be configured as if it is a 60 Hz monitor (divide refresh rate by 2).
/* Inserts a black frame inbetween frames.
* Useful for 120 Hz monitors who want to play 60 Hz material with eliminated
* ghosting. video_refresh_rate should still be configured as if it
* is a 60 Hz monitor (divide refresh rate by 2).
*/
static bool black_frame_insertion = false;
// Uses a custom swap interval for VSync.
// Set this to effectively halve monitor refresh rate.
/* Uses a custom swap interval for VSync.
* Set this to effectively halve monitor refresh rate.
*/
static unsigned swap_interval = 1;
// Threaded video. Will possibly increase performance significantly at cost of worse synchronization and latency.
/* Threaded video. Will possibly increase performance significantly
* at the cost of worse synchronization and latency.
*/
static const bool video_threaded = false;
// Set to true if HW render cores should get their private context.
/* Set to true if HW render cores should get their private context. */
static const bool video_shared_context = false;
// Sets GC/Wii screen width
/* Sets GC/Wii screen width. */
static const unsigned video_viwidth = 640;
// Smooths picture
/* Smooths picture. */
static const bool video_smooth = true;
// On resize and fullscreen, rendering area will stay 4:3
/* On resize and fullscreen, rendering area will stay 4:3 */
static const bool force_aspect = true;
// Enable use of shaders.
/* Enable use of shaders. */
#ifdef RARCH_CONSOLE
static const bool shader_enable = true;
#else
static const bool shader_enable = false;
#endif
// Only scale in integer steps.
// The base size depends on system-reported geometry and aspect ratio.
// If video_force_aspect is not set, X/Y will be integer scaled independently.
/* Only scale in integer steps.
* The base size depends on system-reported geometry and aspect ratio.
* If video_force_aspect is not set, X/Y will be integer scaled independently.
*/
static const bool scale_integer = false;
// Controls aspect ratio handling.
static const float aspect_ratio = DEFAULT_ASPECT_RATIO; // Automatic
static const bool aspect_ratio_auto = false; // 1:1 PAR
/* Controls aspect ratio handling. */
/* Automatic */
static const float aspect_ratio = DEFAULT_ASPECT_RATIO;
/* 1:1 PAR */
static const bool aspect_ratio_auto = false;
#if defined(__CELLOS_LV2) || defined(_XBOX360)
static unsigned aspect_ratio_idx = ASPECT_RATIO_16_9;
#elif defined(RARCH_CONSOLE)
static unsigned aspect_ratio_idx = ASPECT_RATIO_4_3;
#else
static unsigned aspect_ratio_idx = ASPECT_RATIO_CONFIG; // Use g_settings.video.aspect_ratio.
/* Use g_settings.video.aspect_ratio. */
static unsigned aspect_ratio_idx = ASPECT_RATIO_CONFIG;
#endif
// Save configuration file on exit
/* Save configuration file on exit. */
static bool config_save_on_exit = true;
static const bool default_overlay_enable = false;
@ -377,174 +403,183 @@ static bool default_core_specific_config = true;
static bool default_core_specific_config = false;
#endif
// Crop overscanned frames.
/* Crop overscanned frames. */
static const bool crop_overscan = true;
// Font size for on-screen messages.
/* Font size for on-screen messages. */
#if defined(HAVE_RMENU)
static const float font_size = 1.0f;
#else
static const float font_size = 32;
#endif
// Offset for where messages will be placed on-screen. Values are in range [0.0, 1.0].
/* Offset for where messages will be placed on-screen.
* Values are in range [0.0, 1.0]. */
static const float message_pos_offset_x = 0.05;
#ifdef RARCH_CONSOLE
static const float message_pos_offset_y = 0.90;
#else
static const float message_pos_offset_y = 0.05;
#endif
// Color of the message.
static const uint32_t message_color = 0xffff00; // RGB hex value.
// Record post-filtered (CPU filter) video rather than raw game output.
/* Color of the message.
* RGB hex value. */
static const uint32_t message_color = 0xffff00;
/* Record post-filtered (CPU filter) video,
* rather than raw game output. */
static const bool post_filter_record = false;
// Screenshots post-shaded GPU output if available.
/* Screenshots post-shaded GPU output if available. */
static const bool gpu_screenshot = true;
// Record post-shaded GPU output instead of raw game footage if available.
/* Record post-shaded GPU output instead of raw game footage if available. */
static const bool gpu_record = false;
// OSD-messages
/* OSD-messages. */
static const bool font_enable = true;
// The accurate refresh rate of your monitor (Hz).
// This is used to calculate audio input rate with the formula:
// audio_input_rate = game_input_rate * display_refresh_rate / game_refresh_rate.
// If the implementation does not report any values,
// NTSC defaults will be assumed for compatibility.
// This value should stay close to 60Hz to avoid large pitch changes.
// If your monitor does not run at 60Hz, or something close to it, disable VSync,
// and leave this at its default.
/* The accurate refresh rate of your monitor (Hz).
* This is used to calculate audio input rate with the formula:
* audio_input_rate = game_input_rate * display_refresh_rate /
* game_refresh_rate.
*
* If the implementation does not report any values,
* NTSC defaults will be assumed for compatibility.
* This value should stay close to 60Hz to avoid large pitch changes.
* If your monitor does not run at 60Hz, or something close to it,
* disable VSync, and leave this at its default. */
#if defined(RARCH_CONSOLE)
static const float refresh_rate = 60/1.001;
#else
static const float refresh_rate = 59.95;
#endif
// Allow games to set rotation. If false, rotation requests are honored, but ignored.
// Used for setups where one manually rotates the monitor.
/* Allow games to set rotation. If false, rotation requests are
* honored, but ignored.
* Used for setups where one manually rotates the monitor. */
static const bool allow_rotate = true;
////////////////
// Audio
////////////////
/* AUDIO */
// Will enable audio or not.
/* Will enable audio or not. */
static const bool audio_enable = true;
// Output samplerate
/* Output samplerate. */
static const unsigned out_rate = 48000;
// Audio device (e.g. hw:0,0 or /dev/audio). If NULL, will use defaults.
/* Audio device (e.g. hw:0,0 or /dev/audio). If NULL, will use defaults. */
static const char *audio_device = NULL;
// Desired audio latency in milliseconds. Might not be honored if driver can't provide given latency.
/* Desired audio latency in milliseconds. Might not be honored
* if driver can't provide given latency. */
static const int out_latency = 64;
// Will sync audio. (recommended)
/* Will sync audio. (recommended) */
static const bool audio_sync = true;
// Audio rate control
/* Audio rate control. */
#if defined(GEKKO) || !defined(RARCH_CONSOLE)
static const bool rate_control = true;
#else
static const bool rate_control = false;
#endif
// Rate control delta. Defines how much rate_control is allowed to adjust input rate.
/* Rate control delta. Defines how much rate_control
* is allowed to adjust input rate. */
static const float rate_control_delta = 0.005;
// Default audio volume in dB. (0.0 dB == unity gain).
/* Default audio volume in dB. (0.0 dB == unity gain). */
static const float audio_volume = 0.0;
//////////////
// Misc
//////////////
/* MISC */
// Enables displaying the current frames per second.
/* Enables displaying the current frames per second. */
static const bool fps_show = false;
// Enables use of rewind. This will incur some memory footprint depending on the save state buffer.
/* Enables use of rewind. This will incur some memory footprint
* depending on the save state buffer. */
static const bool rewind_enable = false;
// The buffer size for the rewind buffer. This needs to be about 15-20MB per minute. Very game dependant.
static const unsigned rewind_buffer_size = 20 << 20; // 20MiB
/* The buffer size for the rewind buffer. This needs to be about
* 15-20MB per minute. Very game dependant. */
static const unsigned rewind_buffer_size = 20 << 20; /* 20MiB */
// How many frames to rewind at a time.
/* How many frames to rewind at a time. */
static const unsigned rewind_granularity = 1;
// Pause gameplay when gameplay loses focus.
/* Pause gameplay when gameplay loses focus. */
static const bool pause_nonactive = false;
// Saves non-volatile SRAM at a regular interval. It is measured in seconds. A value of 0 disables autosave.
/* Saves non-volatile SRAM at a regular interval.
* It is measured in seconds. A value of 0 disables autosave. */
static const unsigned autosave_interval = 0;
// When being client over netplay, use keybinds for player 1 rather than player 2.
/* When being client over netplay, use keybinds for
* player 1 rather than player 2. */
static const bool netplay_client_swap_input = true;
// On save state load, block SRAM from being overwritten.
// This could potentially lead to buggy games.
/* On save state load, block SRAM from being overwritten.
* This could potentially lead to buggy games. */
static const bool block_sram_overwrite = false;
// When saving savestates, state index is automatically incremented before saving.
// When the content is loaded, state index will be set to the highest existing value.
/* When saving savestates, state index is automatically
* incremented before saving.
* When the content is loaded, state index will be set
* to the highest existing value. */
static const bool savestate_auto_index = false;
// Automatically saves a savestate at the end of RetroArch's lifetime.
// The path is $SRAM_PATH.auto.
// RetroArch will automatically load any savestate with this path on startup if savestate_auto_load is set.
/* Automatically saves a savestate at the end of RetroArch's lifetime.
* The path is $SRAM_PATH.auto.
* RetroArch will automatically load any savestate with this path on
* startup if savestate_auto_load is set. */
static const bool savestate_auto_save = false;
static const bool savestate_auto_load = true;
// Slowmotion ratio.
/* Slowmotion ratio. */
static const float slowmotion_ratio = 3.0;
// Maximum fast forward ratio (Zero => no limit).
/* Maximum fast forward ratio (Zero => no limit). */
static const float fastforward_ratio = -1.0;
// Enable stdin/network command interface
/* Enable stdin/network command interface. */
static const bool network_cmd_enable = false;
static const uint16_t network_cmd_port = 55355;
static const bool stdin_cmd_enable = false;
// Number of entries that will be kept in content history file.
/* Number of entries that will be kept in content history playlist file. */
static const unsigned default_content_history_size = 100;
// Show Menu start-up screen on boot.
/* Show Menu start-up screen on boot. */
static const bool menu_show_start_screen = true;
// Log level for libretro cores (GET_LOG_INTERFACE).
/* Log level for libretro cores (GET_LOG_INTERFACE). */
static const unsigned libretro_log_level = 0;
#ifndef RARCH_DEFAULT_PORT
#define RARCH_DEFAULT_PORT 55435
#endif
////////////////////
// Keybinds, Joypad
////////////////////
/* KEYBINDS, JOYPAD */
// Axis threshold (between 0.0 and 1.0)
// How far an axis must be tilted to result in a button press
/* Axis threshold (between 0.0 and 1.0)
* How far an axis must be tilted to result in a button press. */
static const float axis_threshold = 0.5;
// Describes speed of which turbo-enabled buttons toggle.
/* Describes speed of which turbo-enabled buttons toggle. */
static const unsigned turbo_period = 6;
static const unsigned turbo_duty_cycle = 3;
// Enable input auto-detection. Will attempt to autoconfigure
// gamepads, plug-and-play style.
/* Enable input auto-detection. Will attempt to autoconfigure
* gamepads, plug-and-play style. */
static const bool input_autodetect_enable = true;
#ifndef IS_SALAMANDER
#include "intl/intl.h"
// Player 1
/* Player 1 */
static const struct retro_keybind retro_keybinds_1[] = {
// | RetroPad button | desc | keyboard key | js btn | js axis |
/* | RetroPad button | desc | keyboard key | js btn | js axis | */
{ true, RETRO_DEVICE_ID_JOYPAD_B, RETRO_LBL_JOYPAD_B, RETROK_z, NO_BTN, 0, AXIS_NONE },
{ true, RETRO_DEVICE_ID_JOYPAD_Y, RETRO_LBL_JOYPAD_Y, RETROK_a, NO_BTN, 0, AXIS_NONE },
{ true, RETRO_DEVICE_ID_JOYPAD_SELECT, RETRO_LBL_JOYPAD_SELECT, RETROK_RSHIFT, NO_BTN, 0, AXIS_NONE },
@ -604,9 +639,9 @@ static const struct retro_keybind retro_keybinds_1[] = {
{ true, RARCH_MENU_TOGGLE, RETRO_LBL_MENU_TOGGLE, RETROK_F1, NO_BTN, 0, AXIS_NONE },
};
// Players 2 to MAX_PLAYERS
/* Players 2 to MAX_PLAYERS */
static const struct retro_keybind retro_keybinds_rest[] = {
// | RetroPad button | desc | keyboard key | js btn | js axis |
/* | RetroPad button | desc | keyboard key | js btn | js axis | */
{ true, RETRO_DEVICE_ID_JOYPAD_B, RETRO_LBL_JOYPAD_B, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE },
{ true, RETRO_DEVICE_ID_JOYPAD_Y, RETRO_LBL_JOYPAD_Y, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE },
{ true, RETRO_DEVICE_ID_JOYPAD_SELECT, RETRO_LBL_JOYPAD_SELECT, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE },

View File

@ -174,6 +174,12 @@ core_info_list_t *core_info_list_new(const char *modules_path)
core_info[i].permissions_list =
string_split(core_info[i].permissions, "|");
if (config_get_string(core_info[i].data, "license",
&core_info[i].licenses) &&
core_info[i].licenses)
core_info[i].licenses_list =
string_split(core_info[i].licenses, "|");
if (config_get_string(core_info[i].data, "notes",
&core_info[i].notes) &&
core_info[i].notes)
@ -213,12 +219,14 @@ void core_info_list_free(core_info_list_t *core_info_list)
free(info->supported_extensions);
free(info->authors);
free(info->permissions);
free(info->licenses);
free(info->notes);
if (info->supported_extensions_list)
string_list_free(info->supported_extensions_list);
string_list_free(info->authors_list);
string_list_free(info->note_list);
string_list_free(info->permissions_list);
string_list_free(info->licenses_list);
config_file_free(info->data);
for (j = 0; j < info->firmware_count; j++)

View File

@ -45,11 +45,13 @@ typedef struct
char *supported_extensions;
char *authors;
char *permissions;
char *licenses;
char *notes;
struct string_list *note_list;
struct string_list *supported_extensions_list;
struct string_list *authors_list;
struct string_list *permissions_list;
struct string_list *licenses_list;
core_info_firmware_t *firmware;
size_t firmware_count;

View File

@ -231,17 +231,20 @@ typedef struct input_driver
{
void *(*init)(void);
void (*poll)(void *data);
int16_t (*input_state)(void *data, const struct retro_keybind **retro_keybinds,
int16_t (*input_state)(void *data,
const struct retro_keybind **retro_keybinds,
unsigned port, unsigned device, unsigned index, unsigned id);
bool (*key_pressed)(void *data, int key);
void (*free)(void *data);
bool (*set_sensor_state)(void *data, unsigned port, enum retro_sensor_action action, unsigned rate);
bool (*set_sensor_state)(void *data, unsigned port,
enum retro_sensor_action action, unsigned rate);
float (*get_sensor_input)(void *data, unsigned port, unsigned id);
uint64_t (*get_capabilities)(void *data);
const char *ident;
void (*grab_mouse)(void *data, bool state);
bool (*set_rumble)(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t state);
bool (*set_rumble)(void *data, unsigned port,
enum retro_rumble_effect effect, uint16_t state);
const rarch_joypad_driver_t *(*get_joypad_driver)(void *data);
} input_driver_t;
@ -263,7 +266,8 @@ typedef struct camera_driver
{
/* FIXME: params for initialization - queries for resolution,
* framerate, color format which might or might not be honored. */
void *(*init)(const char *device, uint64_t buffer_types, unsigned width, unsigned height);
void *(*init)(const char *device, uint64_t buffer_types,
unsigned width, unsigned height);
void (*free)(void *data);
@ -288,8 +292,10 @@ typedef struct location_driver
bool (*start)(void *data);
void (*stop)(void *data);
bool (*get_position)(void *data, double *lat, double *lon, double *horiz_accuracy, double *vert_accuracy);
void (*set_interval)(void *data, unsigned interval_msecs, unsigned interval_distance);
bool (*get_position)(void *data, double *lat, double *lon,
double *horiz_accuracy, double *vert_accuracy);
void (*set_interval)(void *data, unsigned interval_msecs,
unsigned interval_distance);
const char *ident;
} location_driver_t;
@ -299,9 +305,12 @@ struct rarch_viewport;
typedef struct video_overlay_interface
{
void (*enable)(void *data, bool state);
bool (*load)(void *data, const struct texture_image *images, unsigned num_images);
void (*tex_geom)(void *data, unsigned image, float x, float y, float w, float h);
void (*vertex_geom)(void *data, unsigned image, float x, float y, float w, float h);
bool (*load)(void *data,
const struct texture_image *images, unsigned num_images);
void (*tex_geom)(void *data, unsigned image,
float x, float y, float w, float h);
void (*vertex_geom)(void *data, unsigned image,
float x, float y, float w, float h);
void (*full_screen)(void *data, bool enable);
void (*set_alpha)(void *data, unsigned image, float mod);
} video_overlay_interface_t;
@ -348,7 +357,8 @@ typedef struct video_poke_interface
/* Enable or disable rendering. */
void (*set_texture_enable)(void *data, bool enable, bool full_screen);
#endif
void (*set_osd_msg)(void *data, const char *msg, const struct font_params *params);
void (*set_osd_msg)(void *data, const char *msg,
const struct font_params *params);
void (*show_mouse)(void *data, bool state);
void (*grab_mouse_toggle)(void *data);

View File

@ -123,7 +123,7 @@ void libretro_get_environment_info(void (*func)(retro_environment_t),
{
load_no_content_hook = load_no_content;
// load_no_content gets set in this callback.
/* load_no_content gets set in this callback. */
func(environ_cb_get_system_info);
}

View File

@ -90,32 +90,7 @@ static int menu_info_screen_iterate(unsigned action)
strlcpy(needle, label, sizeof(needle));
}
if (needle[0] == '\0' || setting_data_get_description(needle, msg, sizeof(msg)) == -1)
{
switch (info_type)
{
case MENU_SETTINGS_BIND_DEVICE:
snprintf(msg, sizeof(msg),
" -- Input Device. \n"
" \n"
"Picks which gamepad to use for player N. \n"
"The name of the pad is available."
);
break;
case MENU_SETTINGS_BIND_DEVICE_TYPE:
snprintf(msg, sizeof(msg),
" -- Input Device Type. \n"
" \n"
"Picks which device type to use. This is \n"
"relevant for the libretro core itself."
);
break;
default:
snprintf(msg, sizeof(msg),
"-- No info on this item available. --\n");
}
}
setting_data_get_description(needle, msg, sizeof(msg));
if (driver.video_data && driver.menu_ctx &&
driver.menu_ctx->render_messagebox)
@ -614,136 +589,136 @@ static int menu_setting_set(unsigned id, const char *label,
gfx_shader_resolve_parameters(NULL, driver.menu->shader);
#endif
}
else if (!strcmp(label, "input_bind_device_id"))
{
int *p = &g_settings.input.joypad_map[port];
if (action == MENU_ACTION_START)
*p = port;
else if (action == MENU_ACTION_LEFT)
(*p)--;
else if (action == MENU_ACTION_RIGHT)
(*p)++;
if (*p < -1)
*p = -1;
else if (*p >= MAX_PLAYERS)
*p = MAX_PLAYERS - 1;
}
else if (!strcmp(label, "input_bind_device_type"))
{
unsigned current_device, current_index, i, devices[128];
const struct retro_controller_info *desc;
unsigned types = 0;
devices[types++] = RETRO_DEVICE_NONE;
devices[types++] = RETRO_DEVICE_JOYPAD;
/* Only push RETRO_DEVICE_ANALOG as default if we use an
* older core which doesn't use SET_CONTROLLER_INFO. */
if (!g_extern.system.num_ports)
devices[types++] = RETRO_DEVICE_ANALOG;
desc = port < g_extern.system.num_ports ?
&g_extern.system.ports[port] : NULL;
if (desc)
{
for (i = 0; i < desc->num_types; i++)
{
unsigned id = desc->types[i].id;
if (types < ARRAY_SIZE(devices) &&
id != RETRO_DEVICE_NONE &&
id != RETRO_DEVICE_JOYPAD)
devices[types++] = id;
}
}
current_device = g_settings.input.libretro_device[port];
current_index = 0;
for (i = 0; i < types; i++)
{
if (current_device == devices[i])
{
current_index = i;
break;
}
}
bool updated = true;
switch (action)
{
case MENU_ACTION_START:
current_device = RETRO_DEVICE_JOYPAD;
break;
case MENU_ACTION_LEFT:
current_device = devices
[(current_index + types - 1) % types];
break;
case MENU_ACTION_RIGHT:
case MENU_ACTION_OK:
current_device = devices
[(current_index + 1) % types];
break;
default:
updated = false;
}
if (updated)
{
g_settings.input.libretro_device[port] = current_device;
pretro_set_controller_port_device(port, current_device);
}
}
else if (!strcmp(label, "input_bind_player_no"))
{
if (action == MENU_ACTION_START)
driver.menu->current_pad = 0;
else if (action == MENU_ACTION_LEFT)
{
if (driver.menu->current_pad != 0)
driver.menu->current_pad--;
}
else if (action == MENU_ACTION_RIGHT)
{
if (driver.menu->current_pad < MAX_PLAYERS - 1)
driver.menu->current_pad++;
}
if (port != driver.menu->current_pad)
driver.menu->need_refresh = true;
port = driver.menu->current_pad;
}
else if (!strcmp(label, "input_bind_analog_dpad_mode"))
{
switch (action)
{
case MENU_ACTION_START:
g_settings.input.analog_dpad_mode[port] = 0;
break;
case MENU_ACTION_OK:
case MENU_ACTION_RIGHT:
g_settings.input.analog_dpad_mode[port] =
(g_settings.input.analog_dpad_mode[port] + 1)
% ANALOG_DPAD_LAST;
break;
case MENU_ACTION_LEFT:
g_settings.input.analog_dpad_mode[port] =
(g_settings.input.analog_dpad_mode
[port] + ANALOG_DPAD_LAST - 1) % ANALOG_DPAD_LAST;
break;
default:
break;
}
}
else
{
switch (id)
{
case MENU_SETTINGS_BIND_PLAYER:
if (action == MENU_ACTION_START)
driver.menu->current_pad = 0;
else if (action == MENU_ACTION_LEFT)
{
if (driver.menu->current_pad != 0)
driver.menu->current_pad--;
}
else if (action == MENU_ACTION_RIGHT)
{
if (driver.menu->current_pad < MAX_PLAYERS - 1)
driver.menu->current_pad++;
}
if (port != driver.menu->current_pad)
driver.menu->need_refresh = true;
port = driver.menu->current_pad;
break;
case MENU_SETTINGS_BIND_DEVICE:
{
int *p = &g_settings.input.joypad_map[port];
if (action == MENU_ACTION_START)
*p = port;
else if (action == MENU_ACTION_LEFT)
(*p)--;
else if (action == MENU_ACTION_RIGHT)
(*p)++;
if (*p < -1)
*p = -1;
else if (*p >= MAX_PLAYERS)
*p = MAX_PLAYERS - 1;
}
break;
case MENU_SETTINGS_BIND_ANALOG_MODE:
switch (action)
{
case MENU_ACTION_START:
g_settings.input.analog_dpad_mode[port] = 0;
break;
case MENU_ACTION_OK:
case MENU_ACTION_RIGHT:
g_settings.input.analog_dpad_mode[port] =
(g_settings.input.analog_dpad_mode[port] + 1)
% ANALOG_DPAD_LAST;
break;
case MENU_ACTION_LEFT:
g_settings.input.analog_dpad_mode[port] =
(g_settings.input.analog_dpad_mode
[port] + ANALOG_DPAD_LAST - 1) % ANALOG_DPAD_LAST;
break;
default:
break;
}
break;
case MENU_SETTINGS_BIND_DEVICE_TYPE:
{
unsigned current_device, current_index, i, devices[128];
const struct retro_controller_info *desc;
unsigned types = 0;
devices[types++] = RETRO_DEVICE_NONE;
devices[types++] = RETRO_DEVICE_JOYPAD;
/* Only push RETRO_DEVICE_ANALOG as default if we use an
* older core which doesn't use SET_CONTROLLER_INFO. */
if (!g_extern.system.num_ports)
devices[types++] = RETRO_DEVICE_ANALOG;
desc = port < g_extern.system.num_ports ?
&g_extern.system.ports[port] : NULL;
if (desc)
{
for (i = 0; i < desc->num_types; i++)
{
unsigned id = desc->types[i].id;
if (types < ARRAY_SIZE(devices) &&
id != RETRO_DEVICE_NONE &&
id != RETRO_DEVICE_JOYPAD)
devices[types++] = id;
}
}
current_device = g_settings.input.libretro_device[port];
current_index = 0;
for (i = 0; i < types; i++)
{
if (current_device == devices[i])
{
current_index = i;
break;
}
}
bool updated = true;
switch (action)
{
case MENU_ACTION_START:
current_device = RETRO_DEVICE_JOYPAD;
break;
case MENU_ACTION_LEFT:
current_device = devices
[(current_index + types - 1) % types];
break;
case MENU_ACTION_RIGHT:
case MENU_ACTION_OK:
current_device = devices
[(current_index + 1) % types];
break;
default:
updated = false;
}
if (updated)
{
g_settings.input.libretro_device[port] = current_device;
pretro_set_controller_port_device(port, current_device);
}
break;
}
case MENU_SETTINGS_CUSTOM_BIND_MODE:
if (action == MENU_ACTION_LEFT || action == MENU_ACTION_RIGHT)
driver.menu->bind_mode_keyboard =
@ -1364,7 +1339,10 @@ static int menu_custom_bind_iterate_keyboard(void *data,
if (timeout <= 0)
{
menu->binds.begin++;
menu->binds.target->key = RETROK_UNKNOWN; /* Could be unsafe, but whatever. */
/* Could be unsafe, but whatever. */
menu->binds.target->key = RETROK_UNKNOWN;
menu->binds.target++;
menu->binds.timeout_end = rarch_get_time_usec() +
MENU_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000;
@ -1389,7 +1367,7 @@ static int menu_custom_bind_iterate_keyboard(void *data,
}
static int menu_action_ok(const char *dir,
static int menu_action_ok(const char *menu_path,
const char *menu_label, unsigned menu_type)
{
const char *label = NULL;
@ -1423,7 +1401,7 @@ static int menu_action_ok(const char *dir,
&& type == MENU_FILE_PLAIN)
{
int ret = rarch_defer_core(g_extern.core_info,
dir, path, driver.menu->deferred_path,
menu_path, path, driver.menu->deferred_path,
sizeof(driver.menu->deferred_path));
if (ret == -1)
@ -1443,13 +1421,13 @@ static int menu_action_ok(const char *dir,
else if ((setting && setting->type == ST_DIR)
&& (type == MENU_FILE_USE_DIRECTORY))
{
menu_common_setting_set_current_string(setting, dir);
menu_common_setting_set_current_string(setting, menu_path);
menu_entries_pop_stack(driver.menu->menu_stack, setting->name);
}
else if ((setting && setting->type == ST_PATH)
&& (type == MENU_FILE_PLAIN))
{
menu_common_setting_set_current_string_path(setting, dir, path);
menu_common_setting_set_current_string_path(setting, menu_path, path);
menu_entries_pop_stack(driver.menu->menu_stack, setting->name);
}
#ifdef HAVE_SHADER_MANAGER
@ -1457,7 +1435,7 @@ static int menu_action_ok(const char *dir,
&& type == MENU_FILE_PLAIN)
{
char shader_path[PATH_MAX];
fill_pathname_join(shader_path, dir, path, sizeof(shader_path));
fill_pathname_join(shader_path, menu_path, path, sizeof(shader_path));
if (driver.menu_ctx && driver.menu_ctx->backend &&
driver.menu_ctx->backend->shader_manager_set_preset)
driver.menu_ctx->backend->shader_manager_set_preset(
@ -1470,7 +1448,8 @@ static int menu_action_ok(const char *dir,
&& type == MENU_FILE_PLAIN)
{
fill_pathname_join(driver.menu->shader->pass[hack_shader_pass].source.path,
dir, path, sizeof(driver.menu->shader->pass[hack_shader_pass].source.path));
menu_path, path,
sizeof(driver.menu->shader->pass[hack_shader_pass].source.path));
/* This will reset any changed parameters. */
gfx_shader_resolve_parameters(NULL, driver.menu->shader);
@ -1491,7 +1470,7 @@ static int menu_action_ok(const char *dir,
else if (!strcmp(menu_label, "core_list")
&& type == MENU_FILE_CORE)
{
fill_pathname_join(g_settings.libretro, dir, path,
fill_pathname_join(g_settings.libretro, menu_path, path,
sizeof(g_settings.libretro));
rarch_main_command(RARCH_CMD_LOAD_CORE);
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
@ -1516,7 +1495,7 @@ static int menu_action_ok(const char *dir,
&& type == MENU_FILE_PLAIN)
{
char config[PATH_MAX];
fill_pathname_join(config, dir, path, sizeof(config));
fill_pathname_join(config, menu_path, path, sizeof(config));
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
driver.menu->msg_force = true;
if (rarch_replace_config(config))
@ -1525,10 +1504,11 @@ static int menu_action_ok(const char *dir,
return -1;
}
}
else if (!strcmp(menu_label, "disk_image_append") && type == MENU_FILE_PLAIN)
else if (!strcmp(menu_label, "disk_image_append")
&& type == MENU_FILE_PLAIN)
{
char image[PATH_MAX];
fill_pathname_join(image, dir, path, sizeof(image));
fill_pathname_join(image, menu_path, path, sizeof(image));
rarch_disk_control_append_image(image);
rarch_main_command(RARCH_CMD_RESUME);
@ -1539,7 +1519,7 @@ static int menu_action_ok(const char *dir,
else if (menu_parse_check(label, type) == 0)
{
char cat_path[PATH_MAX];
fill_pathname_join(cat_path, dir, path, sizeof(cat_path));
fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path));
menu_entries_push(driver.menu->menu_stack,
cat_path, menu_label, type, driver.menu->selection_ptr);
@ -1547,7 +1527,7 @@ static int menu_action_ok(const char *dir,
else if (type == MENU_FILE_CARCHIVE)
{
char cat_path[PATH_MAX];
fill_pathname_join(cat_path, dir, path, sizeof(cat_path));
fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path));
menu_entries_push(driver.menu->menu_stack,
cat_path, menu_label, type, driver.menu->selection_ptr);
@ -1556,11 +1536,12 @@ static int menu_action_ok(const char *dir,
#ifdef HAVE_COMPRESSION
else if (type == MENU_FILE_IN_CARCHIVE)
{
fill_pathname_join(g_extern.fullpath, dir, path,
fill_pathname_join(g_extern.fullpath, menu_path, path,
sizeof(g_extern.fullpath));
g_extern.is_carchive = true;
strncpy(g_extern.carchive_path,dir,sizeof(g_extern.carchive_path));
strncpy(g_extern.carchive_path, menu_path,
sizeof(g_extern.carchive_path));
rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
@ -1570,7 +1551,7 @@ static int menu_action_ok(const char *dir,
#endif
else
{
fill_pathname_join(g_extern.fullpath, dir, path,
fill_pathname_join(g_extern.fullpath, menu_path, path,
sizeof(g_extern.fullpath));
rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
@ -1594,8 +1575,6 @@ static int menu_common_iterate(unsigned action)
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->set_texture)
driver.menu_ctx->set_texture(driver.menu);
//RARCH_LOG("Menu label: %s\n", menu_label);
if (!strcmp(menu_label, "help"))
return menu_start_screen_iterate(action);
else if (!strcmp(menu_label, "info_screen"))

View File

@ -31,6 +31,8 @@
#include "../../../config.def.h"
#include "../../../input/keyboard_line.h"
#include "../../../settings_data.h"
#include "../disp/lakka.h"
#ifdef HAVE_CONFIG_H

View File

@ -36,6 +36,7 @@
#include "../../../performance.h"
#include "../../../input/input_common.h"
#include "../../../settings_data.h"
#include "../../../screenshot.h"
#include "../../../gfx/fonts/bitmap.h"
@ -697,6 +698,8 @@ static void lakka_context_destroy(void *data)
void lakka_init_settings(void)
{
rarch_setting_t *setting_data = (rarch_setting_t*)setting_data_get_list();
menu_category_t *category = (menu_category_t*)&categories[0];
strlcpy(category->name, "Settings", sizeof(category->name));
@ -707,101 +710,77 @@ void lakka_init_settings(void)
category->items = (menu_item_t*)
calloc(category->num_items, sizeof(menu_item_t));
int j, k;
int j, k, jj, kk;
for (j = 0; j <= 512; j++)
{
rarch_setting_t group = (rarch_setting_t)setting_data[j];
// General options item
if (group.type == ST_GROUP)
{
category->num_items++;
category->items = (menu_item_t*)
realloc(category->items, category->num_items * sizeof(menu_item_t));
menu_item_t *item = (menu_item_t*)&category->items[jj];
strlcpy(item->name, group.name, sizeof(item->name));
item->alpha = jj ? 0.5 : 1.0;
item->zoom = jj ? i_passive_zoom : i_active_zoom;
item->y = jj ?
vspacing*(under_item_offset+jj) : vspacing * active_item_factor;
item->active_subitem = 0;
item->num_subitems = 0;
kk = 0;
for (k = 0; k <= 512; k++)
{
rarch_setting_t subgroup = (rarch_setting_t)setting_data[k];
if (subgroup.type == ST_SUB_GROUP) // TODO filter on parent
{
item->num_subitems++;
#if 0
item->subitems = (menu_subitem_t*)
realloc(item->subitems, item->num_subitems * sizeof(menu_subitem_t));
#endif
item->subitems = (menu_subitem_t*)
calloc(item->num_subitems, sizeof(menu_subitem_t));
menu_subitem_t *subitem = (menu_subitem_t*)&item->subitems[kk];
strlcpy(subitem->name, subgroup.name, sizeof(subitem->name));
subitem->alpha = kk ? 1.0 : 0.5;
subitem->zoom = kk ? i_active_zoom : i_passive_zoom;
subitem->y = kk ? vspacing * (kk + under_item_offset)
: vspacing * active_item_factor;
kk++;
}
}
jj++;
}
}
j = 0;
category->num_items++;
category->items = (menu_item_t*)
realloc(category->items, category->num_items * sizeof(menu_item_t));
menu_item_t *item0 = (menu_item_t*)&category->items[j];
menu_item_t *itemq = (menu_item_t*)&category->items[jj];
strlcpy(item0->name, "General Options", sizeof(item0->name));
item0->alpha = j ? 0.5 : 1.0;
item0->zoom = j ? i_passive_zoom : i_active_zoom;
item0->y = j ?
vspacing*(under_item_offset+j) : vspacing * active_item_factor;
item0->active_subitem = 0;
item0->num_subitems = 0;
/* General options subitems */
k = 0;
item0->num_subitems++;
#if 0
item0->subitems = (menu_subitem_t*)
realloc(item0->subitems, item0->num_subitems * sizeof(menu_subitem_t));
#endif
item0->subitems = (menu_subitem_t*)
calloc(item0->num_subitems, sizeof(menu_subitem_t));
menu_subitem_t *subitem0 = (menu_subitem_t*)&item0->subitems[k];
strlcpy(subitem0->name, "Libretro Logging Level", sizeof(subitem0->name));
subitem0->alpha = k ? 1.0 : 0.5;
subitem0->zoom = k ? i_active_zoom : i_passive_zoom;
subitem0->y = k ? vspacing * (k + under_item_offset)
: vspacing * active_item_factor;
k = 1;
item0->num_subitems++;
item0->subitems = (menu_subitem_t*)
realloc(item0->subitems, item0->num_subitems * sizeof(menu_subitem_t));
#if 0
item0->subitems = (menu_subitem_t*)
calloc(item0->num_subitems, sizeof(menu_subitem_t));
#endif
menu_subitem_t *subitem1 = (menu_subitem_t*)&item0->subitems[k];
strlcpy(subitem1->name, "Logging Verbosity", sizeof(subitem1->name));
subitem1->alpha = k ? 1.0 : 0.5;
subitem1->zoom = k ? i_active_zoom : i_passive_zoom;
subitem1->y = k ? vspacing * (k + under_item_offset) :
strlcpy(itemq->name, "Quit RetroArch", sizeof(itemq->name));
itemq->alpha = jj ? 0.5 : 1.0;
itemq->zoom = jj ? i_passive_zoom : i_active_zoom;
itemq->y = jj ? vspacing*(under_item_offset+jj) :
vspacing * active_item_factor;
k = 2;
item0->num_subitems++;
item0->subitems = (menu_subitem_t*)
realloc(item0->subitems, item0->num_subitems * sizeof(menu_subitem_t));
#if 0
item0->subitems = (menu_subitem_t*)
calloc(item0->num_subitems, sizeof(menu_subitem_t));
#endif
menu_subitem_t *subitem2 = (menu_subitem_t*)&item0->subitems[k];
strlcpy(subitem2->name, "Configuration Save On Exit",
sizeof(subitem2->name));
subitem2->alpha = k ? 1.0 : 0.5;
subitem2->zoom = k ? i_active_zoom : i_passive_zoom;
subitem2->y = k ? vspacing * (k + under_item_offset) :
vspacing * active_item_factor;
/* Quit item */
j = 1;
category->num_items++;
category->items = (menu_item_t*)
realloc(category->items, category->num_items * sizeof(menu_item_t));
menu_item_t *item1 = (menu_item_t*)&category->items[j];
strlcpy(item1->name, "Quit RetroArch", sizeof(item1->name));
item1->alpha = j ? 0.5 : 1.0;
item1->zoom = j ? i_passive_zoom : i_active_zoom;
item1->y = j ? vspacing*(under_item_offset+j) :
vspacing * active_item_factor;
item1->active_subitem = 0;
item1->num_subitems = 0;
itemq->active_subitem = 0;
itemq->num_subitems = 0;
}
void lakka_settings_context_reset(void)
{
menu_item_t *item;
int k;
int j, k;
menu_category_t *category = (menu_category_t*)&categories[0];
if (!category)
@ -810,18 +789,16 @@ void lakka_settings_context_reset(void)
category->icon = textures[TEXTURE_SETTINGS].id;
category->item_icon = textures[TEXTURE_SETTING].id;
/* General options item */
item = (menu_item_t*)&category->items[0];
/* General options subitems */
for (k = 0; k < 2; k++)
for (j = 0; j < category->num_items; j++)
{
menu_subitem_t *subitem = (menu_subitem_t*)&item->subitems[k];
subitem->icon = textures[TEXTURE_SUBSETTING].id;
}
item = (menu_item_t*)&category->items[j];
/* Quit item */
item = (menu_item_t*)&category->items[1];
for (k = 0; k < item->num_subitems; k++)
{
menu_subitem_t *subitem = (menu_subitem_t*)&item->subitems[k];
subitem->icon = textures[TEXTURE_SUBSETTING].id;
}
}
}

View File

@ -331,7 +331,9 @@ static void rgui_render(void)
snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION,
core_name, core_version);
blit_line(RGUI_TERM_START_X + RGUI_TERM_START_X, (RGUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) +
blit_line(
RGUI_TERM_START_X + RGUI_TERM_START_X,
(RGUI_TERM_HEIGHT * FONT_HEIGHT_STRIDE) +
RGUI_TERM_START_Y + 2, title_msg, true);
unsigned x, y;
@ -352,7 +354,7 @@ static void rgui_render(void)
setting_data_get_list(),
driver.menu->selection_buf->list[i].label);
unsigned w = 21;
unsigned w = 19;
(void)setting;
if (!strcmp(label, "performance_counters"))
@ -414,7 +416,8 @@ static void rgui_render(void)
snprintf(message, sizeof(message), "%c %-*.*s %-*s",
selected ? '>' : ' ',
RGUI_TERM_WIDTH - (w + 1 + 2), RGUI_TERM_WIDTH - (w + 1 + 2),
RGUI_TERM_WIDTH - (w + 1 + 2),
RGUI_TERM_WIDTH - (w + 1 + 2),
entry_title_buf,
w,
type_str_buf);
@ -438,7 +441,7 @@ static void rgui_render(void)
if (driver.menu->keyboard.display)
{
char msg[1024];
char msg[PATH_MAX];
const char *str = *driver.menu->keyboard.buffer;
if (!str)
str = "";
@ -469,8 +472,7 @@ static void *rgui_init(void)
if (!ret)
{
RARCH_ERR("No font bitmap or binary, abort");
/* TODO - should be refactored - perhaps don't do rarch_fail but instead
* exit program */
rarch_main_command(RARCH_CMD_QUIT_RETROARCH);
return NULL;
}

View File

@ -225,7 +225,7 @@ static void rmenu_render(void)
char message[256];
char type_str[256];
unsigned w = 21;
unsigned w = 19;
if (type == MENU_FILE_CORE)
{

View File

@ -437,7 +437,7 @@ static void rmenu_xui_render(void)
char message[256];
char type_str[256];
unsigned w = 21;
unsigned w = 19;
if (type == MENU_FILE_CORE)
{
@ -533,7 +533,7 @@ static void rmenu_xui_navigation_alphabet(void *data, size_t *ptr_out)
}
static void rmenu_xui_list_insert(void *data,
const char *path, size_t list_size)
const char *path, const char *, size_t list_size)
{
(void)data;
wchar_t buf[PATH_MAX];

View File

@ -52,10 +52,10 @@ static void throttle_frame(void)
/* Update menu state which depends on config. */
static void menu_update_libretro_info(menu_handle_t *menu)
static void update_libretro_info(struct retro_system_info *info)
{
#ifndef HAVE_DYNAMIC
retro_get_system_info(&g_extern.menu.info);
retro_get_system_info(info);
#endif
core_info_list_free(g_extern.core_info);
@ -63,7 +63,7 @@ static void menu_update_libretro_info(menu_handle_t *menu)
if (*g_settings.libretro_directory)
g_extern.core_info = core_info_list_new(g_settings.libretro_directory);
rarch_update_system_info(&g_extern.menu.info, NULL);
rarch_update_system_info(info, NULL);
}
static void menu_environment_get(int *argc, char *argv[],
@ -132,7 +132,7 @@ bool load_menu_content(void)
}
if (driver.menu)
menu_update_libretro_info(driver.menu);
update_libretro_info(&g_extern.menu.info);
rarch_main_command(RARCH_CMD_HISTORY_DEINIT);
rarch_main_command(RARCH_CMD_HISTORY_INIT);
@ -181,7 +181,7 @@ void *menu_init(const void *data)
menu->frame_buf_show = true;
menu->current_pad = 0;
menu_update_libretro_info(menu);
update_libretro_info(&g_extern.menu.info);
if (menu_ctx->backend
&& menu_ctx->backend->shader_manager_init)

View File

@ -103,11 +103,6 @@ typedef enum
MENU_SETTINGS_SHADER_PASS_SCALE_0,
MENU_SETTINGS_SHADER_PASS_SCALE_LAST = MENU_SETTINGS_SHADER_PASS_SCALE_0 + (GFX_MAX_SHADERS - 1),
MENU_SETTINGS_BIND_PLAYER,
MENU_SETTINGS_BIND_DEVICE,
MENU_SETTINGS_BIND_DEVICE_TYPE,
MENU_SETTINGS_BIND_ANALOG_MODE,
// Match up with libretro order for simplicity.
MENU_SETTINGS_BIND_BEGIN,
MENU_SETTINGS_BIND_LAST = MENU_SETTINGS_BIND_BEGIN + RARCH_ANALOG_RIGHT_Y_MINUS,

View File

@ -145,6 +145,15 @@ void menu_entries_pop(file_list_t *list)
}
}
static int setting_set_flags(rarch_setting_t *setting)
{
if (setting->flags & SD_FLAG_ALLOW_INPUT)
return MENU_FILE_LINEFEED;
if (setting->flags & SD_FLAG_PUSH_ACTION)
return MENU_FILE_SWITCH;
return 0;
}
int menu_entries_push_list(menu_handle_t *menu,
file_list_t *list,
const char *path, const char *label,
@ -166,54 +175,80 @@ int menu_entries_push_list(menu_handle_t *menu,
if (!strcmp(label, "mainmenu"))
{
setting_data = (rarch_setting_t *)setting_data_get_mainmenu(true);
rarch_setting_t *setting = (rarch_setting_t*)setting_data_find_setting(setting_data,
"Main Menu");
file_list_clear(list);
add_setting_entry(menu,list,"core_list", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"history_list", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"detect_core_list", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"load_content", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"core_options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"core_information", MENU_FILE_SWITCH, setting_data);
if (g_extern.main_is_init && !g_extern.libretro_dummy)
for (; setting->type != ST_END_GROUP; setting++)
{
if (g_extern.system.disk_control.get_num_images)
file_list_push(list, "Core Disk Options", "disk_options",
MENU_FILE_SWITCH, 0);
if (
setting->type == ST_GROUP ||
setting->type == ST_SUB_GROUP ||
setting->type == ST_END_SUB_GROUP
)
continue;
file_list_push(list, setting->short_description,
setting->name, setting_set_flags(setting), 0);
}
add_setting_entry(menu,list,"settings", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"performance_counters", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"savestate", 0, setting_data);
add_setting_entry(menu,list,"loadstate", 0, setting_data);
add_setting_entry(menu,list,"take_screenshot", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"resume_content", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"restart_content", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"restart_retroarch", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"configurations", 0, setting_data);
add_setting_entry(menu,list,"save_new_config", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"help", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"quit_retroarch", MENU_FILE_SWITCH, setting_data);
}
else if (!strcmp(path, "General Options"))
else if (
!strcmp(label, "Driver Options") ||
!strcmp(label, "General Options") ||
!strcmp(label, "Overlay Options") ||
!strcmp(label, "Privacy Options") ||
!strcmp(label, "Video Options") ||
!strcmp(label, "Audio Options") ||
!strcmp(label, "Path Options") ||
!strcmp(label, "Font Options") ||
!strcmp(label, "User Options") ||
!strcmp(label, "Netplay Options")
)
{
rarch_setting_t *setting_data = (rarch_setting_t*)setting_data_get_list();
rarch_setting_t *setting = (rarch_setting_t*)setting_data_find_setting(setting_data,
label);
file_list_clear(list);
add_setting_entry(menu,list,"libretro_log_level", 0, setting_data);
add_setting_entry(menu,list,"log_verbosity", 0, setting_data);
add_setting_entry(menu,list,"perfcnt_enable", 0, setting_data);
add_setting_entry(menu,list,"game_history_size", 0, setting_data);
add_setting_entry(menu,list,"config_save_on_exit", 0, setting_data);
add_setting_entry(menu,list,"core_specific_config", 0, setting_data);
add_setting_entry(menu,list,"video_gpu_screenshot", 0, setting_data);
add_setting_entry(menu,list,"dummy_on_core_shutdown", 0, setting_data);
add_setting_entry(menu,list,"fps_show", 0, setting_data);
add_setting_entry(menu,list,"fastforward_ratio", 0, setting_data);
add_setting_entry(menu,list,"slowmotion_ratio", 0, setting_data);
add_setting_entry(menu,list,"rewind_enable", 0, setting_data);
add_setting_entry(menu,list,"rewind_granularity", 0, setting_data);
add_setting_entry(menu,list,"block_sram_overwrite", 0, setting_data);
add_setting_entry(menu,list,"autosave_interval", 0, setting_data);
add_setting_entry(menu,list,"video_disable_composition", 0, setting_data);
add_setting_entry(menu,list,"pause_nonactive", 0, setting_data);
add_setting_entry(menu,list,"savestate_auto_save", 0, setting_data);
add_setting_entry(menu,list,"savestate_auto_load", 0, setting_data);
if (!strcmp(label, "Video Options"))
{
#if defined(GEKKO) || defined(__CELLOS_LV2__)
file_list_push(list, "Screen Resolution", "",
MENU_SETTINGS_VIDEO_RESOLUTION, 0);
#endif
file_list_push(list, "Custom Ratio", "",
MENU_SETTINGS_CUSTOM_VIEWPORT, 0);
}
for (; setting->type != ST_END_GROUP; setting++)
{
if (
setting->type == ST_GROUP ||
setting->type == ST_SUB_GROUP ||
setting->type == ST_END_SUB_GROUP
)
continue;
file_list_push(list, setting->short_description,
setting->name, setting_set_flags(setting), 0);
}
}
else if (!strcmp(label, "settings"))
{
rarch_setting_t *setting_data = (rarch_setting_t*)setting_data_get_list();
rarch_setting_t *setting = (rarch_setting_t*)setting_data_find_setting(setting_data,
"Driver Options");
file_list_clear(list);
for (; setting->type != ST_NONE; setting++)
{
if (setting->type == ST_GROUP)
file_list_push(list, setting->short_description,
setting->name, MENU_FILE_SWITCH, 0);
}
}
else if (!strcmp(label, "history_list"))
{
@ -284,6 +319,15 @@ int menu_entries_push_list(menu_handle_t *menu,
MENU_SETTINGS_CORE_INFO_NONE, 0);
}
if (info->licenses_list)
{
strlcpy(tmp, "License(s): ", sizeof(tmp));
string_list_join_concat(tmp, sizeof(tmp),
info->licenses_list, ", ");
file_list_push(list, tmp, "",
MENU_SETTINGS_CORE_INFO_NONE, 0);
}
if (info->supported_extensions_list)
{
strlcpy(tmp, "Supported extensions: ", sizeof(tmp));
@ -358,22 +402,6 @@ int menu_entries_push_list(menu_handle_t *menu,
do_action = true;
}
else if (!strcmp(label, "User Options"))
{
file_list_clear(list);
add_setting_entry(menu,list,"netplay_nickname", MENU_FILE_LINEFEED, setting_data);
add_setting_entry(menu,list,"user_language", MENU_FILE_LINEFEED, setting_data);
}
else if (!strcmp(label, "Netplay Options"))
{
file_list_clear(list);
add_setting_entry(menu,list,"netplay_enable", 0, setting_data);
add_setting_entry(menu,list,"netplay_mode", 0, setting_data);
add_setting_entry(menu,list,"netplay_spectator_mode_enable", 0, setting_data);
add_setting_entry(menu,list,"netplay_ip_address", 0, setting_data);
add_setting_entry(menu,list,"netplay_tcp_udp_port", MENU_FILE_LINEFEED, setting_data);
add_setting_entry(menu,list,"netplay_delay_frames", 0, setting_data);
}
else if (!strcmp(label, "core_counters"))
{
file_list_clear(list);
@ -386,19 +414,6 @@ int menu_entries_push_list(menu_handle_t *menu,
menu_entries_push_perfcounter(menu, list, perf_counters_rarch,
perf_ptr_rarch, MENU_SETTINGS_PERF_COUNTERS_BEGIN);
}
else if (!strcmp(label, "Privacy Options"))
{
file_list_clear(list);
add_setting_entry(menu,list,"camera_allow", 0, setting_data);
add_setting_entry(menu,list,"location_allow", 0, setting_data);
}
else if (!strcmp(label, "Overlay Options"))
{
file_list_clear(list);
add_setting_entry(menu,list,"input_overlay", 0, setting_data);
add_setting_entry(menu,list,"input_overlay_opacity", 0, setting_data);
add_setting_entry(menu,list,"input_overlay_scale", 0, setting_data);
}
else if (!strcmp(label, "core_options"))
{
file_list_clear(list);
@ -415,30 +430,13 @@ int menu_entries_push_list(menu_handle_t *menu,
file_list_push(list, "No options available.", "",
MENU_SETTINGS_CORE_OPTION_NONE, 0);
}
else if (!strcmp(label, "Audio Options"))
{
file_list_clear(list);
add_setting_entry(menu,list,"audio_dsp_plugin", 0, setting_data);
add_setting_entry(menu,list,"audio_enable", 0, setting_data);
add_setting_entry(menu,list,"audio_mute_enable", 0, setting_data);
add_setting_entry(menu,list,"audio_latency", 0, setting_data);
add_setting_entry(menu,list,"audio_sync", 0, setting_data);
add_setting_entry(menu,list,"audio_rate_control_delta", 0, setting_data);
add_setting_entry(menu,list,"system_bgm_enable", 0, setting_data);
add_setting_entry(menu,list,"audio_volume", 0, setting_data);
add_setting_entry(menu,list,"audio_device", MENU_FILE_LINEFEED, setting_data);
}
else if (!strcmp(label, "Input Options"))
{
file_list_clear(list);
file_list_push(list, "Player", "",
MENU_SETTINGS_BIND_PLAYER, 0);
file_list_push(list, "Device", "",
MENU_SETTINGS_BIND_DEVICE, 0);
file_list_push(list, "Device Type", "",
MENU_SETTINGS_BIND_DEVICE_TYPE, 0);
file_list_push(list, "Analog D-pad Mode", "",
MENU_SETTINGS_BIND_ANALOG_MODE, 0);
file_list_push(list, "Player", "input_bind_player_no", 0, 0);
file_list_push(list, "Device", "input_bind_device_id", 0, 0);
file_list_push(list, "Device Type", "input_bind_device_type", 0, 0);
file_list_push(list, "Analog D-pad Mode", "input_bind_analog_dpad_mode", 0, 0);
add_setting_entry(menu,list,"input_axis_threshold", 0, setting_data);
add_setting_entry(menu,list,"input_autodetect_enable", 0, setting_data);
add_setting_entry(menu,list,"input_turbo_period", 0, setting_data);
@ -453,97 +451,6 @@ int menu_entries_push_list(menu_handle_t *menu,
for (i = MENU_SETTINGS_BIND_BEGIN; i <= MENU_SETTINGS_BIND_ALL_LAST; i++)
add_setting_entry(menu, list, input_config_bind_map[i - MENU_SETTINGS_BIND_BEGIN].base, i, setting_data);
}
else if (!strcmp(label, "Driver Options"))
{
file_list_clear(list);
add_setting_entry(menu,list,"video_driver", 0, setting_data);
add_setting_entry(menu,list,"audio_driver", 0, setting_data);
add_setting_entry(menu,list,"audio_resampler_driver", 0, setting_data);
add_setting_entry(menu,list,"input_driver", 0, setting_data);
add_setting_entry(menu,list,"camera_driver", 0, setting_data);
add_setting_entry(menu,list,"location_driver", 0, setting_data);
add_setting_entry(menu,list,"menu_driver", 0, setting_data);
}
else if (!strcmp(label, "Video Options"))
{
file_list_clear(list);
add_setting_entry(menu,list,"video_shared_context", 0, setting_data);
#if defined(GEKKO) || defined(__CELLOS_LV2__)
file_list_push(list, "Screen Resolution", "",
MENU_SETTINGS_VIDEO_RESOLUTION, 0);
#endif
add_setting_entry(menu,list,"video_viwidth", 0, setting_data);
add_setting_entry(menu,list,"video_filter", 0, setting_data);
add_setting_entry(menu,list, "pal60_enable", 0, setting_data);
add_setting_entry(menu,list,"video_smooth", 0, setting_data);
add_setting_entry(menu,list, "soft_filter", 0, setting_data);
add_setting_entry(menu,list,"video_gamma", 0, setting_data);
add_setting_entry(menu,list,"video_filter_flicker", 0,
setting_data);
add_setting_entry(menu,list,"video_scale_integer", 0, setting_data);
add_setting_entry(menu,list,"aspect_ratio_index", 0, setting_data);
file_list_push(list, "Custom Ratio", "",
MENU_SETTINGS_CUSTOM_VIEWPORT, 0);
add_setting_entry(menu,list,"video_fullscreen", 0, setting_data);
add_setting_entry(menu,list,"video_windowed_fullscreen", 0, setting_data);
add_setting_entry(menu,list,"video_rotation", 0, setting_data);
add_setting_entry(menu,list,"video_vsync", 0, setting_data);
add_setting_entry(menu,list,"video_hard_sync", 0, setting_data);
add_setting_entry(menu,list,"video_hard_sync_frames", 0, setting_data);
add_setting_entry(menu,list,"video_frame_delay", 0, setting_data);
add_setting_entry(menu,list,"video_black_frame_insertion", 0, setting_data);
add_setting_entry(menu,list,"video_swap_interval", 0, setting_data);
add_setting_entry(menu,list,"video_threaded", 0, setting_data);
add_setting_entry(menu,list,"video_scale", 0, setting_data);
add_setting_entry(menu,list,"video_crop_overscan", 0, setting_data);
add_setting_entry(menu,list,"video_monitor_index", 0, setting_data);
add_setting_entry(menu,list,"video_refresh_rate", 0, setting_data);
add_setting_entry(menu,list,"video_refresh_rate_auto", 0, setting_data);
}
else if (!strcmp(label, "Font Options"))
{
file_list_clear(list);
add_setting_entry(menu,list,"video_font_enable", 0, setting_data);
add_setting_entry(menu,list,"video_font_size", 0, setting_data);
}
else if (!strcmp(label, "settings"))
{
file_list_clear(list);
add_setting_entry(menu,list,"Driver Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"General Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"Video Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"Shader Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"Font Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"Audio Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"Input Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"Overlay Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"User Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"Netplay Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"Path Options", MENU_FILE_SWITCH, setting_data);
add_setting_entry(menu,list,"Privacy Options",
MENU_FILE_SWITCH, setting_data);
}
else if (!strcmp(label, "Path Options"))
{
file_list_clear(list);
add_setting_entry(menu,list,"rgui_browser_directory", 0, setting_data);
add_setting_entry(menu,list,"content_directory", 0, setting_data);
add_setting_entry(menu,list,"assets_directory", 0, setting_data);
add_setting_entry(menu,list,"rgui_config_directory", 0, setting_data);
add_setting_entry(menu,list,"libretro_dir_path", 0, setting_data);
add_setting_entry(menu,list,"libretro_info_path", 0, setting_data);
add_setting_entry(menu,list,"game_history_path", 0, setting_data);
add_setting_entry(menu,list,"video_filter_dir", 0, setting_data);
add_setting_entry(menu,list,"audio_filter_dir", 0, setting_data);
add_setting_entry(menu,list,"video_shader_dir", 0, setting_data);
add_setting_entry(menu,list,"savestate_directory", 0, setting_data);
add_setting_entry(menu,list,"savefile_directory", 0, setting_data);
add_setting_entry(menu,list,"overlay_directory", 0, setting_data);
add_setting_entry(menu,list,"system_directory", 0, setting_data);
add_setting_entry(menu,list,"screenshot_directory", 0, setting_data);
add_setting_entry(menu,list,"joypad_autoconfig_dir", 0, setting_data);
add_setting_entry(menu,list,"extraction_directory", 0, setting_data);
}
else if (!strcmp(label, "Shader Options"))
{
struct gfx_shader *shader = (struct gfx_shader*)menu->shader;

View File

@ -235,7 +235,6 @@ static void frontend_xdk_get_environment_settings(int *argc, char *argv[],
#endif
#ifndef IS_SALAMANDER
exit:
g_extern.verbosity = original_verbose;
#endif
}

View File

@ -51,8 +51,9 @@
#endif
#endif
// Platform-specific headers
// Windows
/* Platform-specific headers */
/* Windows */
#ifdef _WIN32
#ifdef _XBOX
#include <xtl.h>
@ -63,16 +64,15 @@
#include "msvc/msvc_compat.h"
#endif
// Wii and PSL1GHT - for usleep (among others)
/* Wii and PSL1GHT - for usleep (among others) */
#if defined(GEKKO) || defined(__PSL1GHT__) || defined(__QNX__)
#include <unistd.h>
#endif
// PSP
/* PSP */
#if defined(PSP)
#include <pspthreadman.h>
#endif
//////////////
#ifdef HAVE_NETPLAY
#include "netplay.h"
@ -204,7 +204,8 @@ struct defaults
} settings;
};
// All config related settings go here.
/* All config related settings go here. */
struct settings
{
struct
@ -309,7 +310,7 @@ struct settings
bool rate_control;
float rate_control_delta;
float volume; // dB scale
float volume; /* dB scale. */
char resampler[32];
} audio;
@ -320,7 +321,8 @@ struct settings
char keyboard_layout[64];
struct retro_keybind binds[MAX_PLAYERS][RARCH_BIND_LIST_END];
// Set by autoconfiguration in joypad_autoconfig_dir. Does not override main binds.
/* Set by autoconfiguration in joypad_autoconfig_dir.
* Does not override main binds. */
struct retro_keybind autoconf_binds[MAX_PLAYERS][RARCH_BIND_LIST_END];
bool autoconfigured[MAX_PLAYERS];

View File

@ -16,7 +16,7 @@
*/
#ifdef _XBOX
#include "../../xdk/xdk_d3d.h"
#include "../d3d9/xdk_d3d.h"
#else
#include "../d3d9/d3d.hpp"
#include "win32_common.h"

View File

@ -31,9 +31,10 @@
#define HAVE_SHADERS
#endif
//forward decls
/* forward decls */
static bool d3d_init_luts(d3d_video_t *d3d);
static void d3d_set_font_rect(d3d_video_t *d3d, const struct font_params *params);
static void d3d_set_font_rect(d3d_video_t *d3d,
const struct font_params *params);
static bool d3d_process_shader(d3d_video_t *d3d);
static bool d3d_init_multipass(d3d_video_t *d3d);
static void d3d_deinit_chain(d3d_video_t *d3d);
@ -49,7 +50,8 @@ namespace Monitor
static unsigned num_mons;
}
static BOOL CALLBACK monitor_enum_proc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
static BOOL CALLBACK monitor_enum_proc(HMONITOR hMonitor,
HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
Monitor::all_hms[Monitor::num_mons++] = hMonitor;
return TRUE;
@ -62,11 +64,13 @@ static RECT d3d_monitor_rect(d3d_video_t *d3d)
EnumDisplayMonitors(NULL, NULL, monitor_enum_proc, 0);
if (!Monitor::last_hm)
Monitor::last_hm = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTONEAREST);
Monitor::last_hm = MonitorFromWindow(
GetDesktopWindow(), MONITOR_DEFAULTTONEAREST);
HMONITOR hm_to_use = Monitor::last_hm;
unsigned fs_monitor = g_settings.video.monitor_index;
if (fs_monitor && fs_monitor <= Monitor::num_mons && Monitor::all_hms[fs_monitor - 1])
if (fs_monitor && fs_monitor <= Monitor::num_mons
&& Monitor::all_hms[fs_monitor - 1])
{
hm_to_use = Monitor::all_hms[fs_monitor - 1];
d3d->cur_mon_id = fs_monitor - 1;
@ -96,14 +100,16 @@ static void d3d_recompute_pass_sizes(d3d_video_t *d3d)
{
LinkInfo link_info = {0};
link_info.pass = &d3d->shader.pass[0];
link_info.tex_w = link_info.tex_h = d3d->video_info.input_scale * RARCH_SCALE_BASE;
link_info.tex_w = link_info.tex_h =
d3d->video_info.input_scale * RARCH_SCALE_BASE;
unsigned current_width = link_info.tex_w;
unsigned current_height = link_info.tex_h;
unsigned out_width = 0;
unsigned out_height = 0;
if (!renderchain_set_pass_size(d3d->chain, 0, current_width, current_height))
if (!renderchain_set_pass_size(d3d->chain, 0,
current_width, current_height))
{
RARCH_ERR("[D3D]: Failed to set pass size.\n");
return;
@ -118,7 +124,8 @@ static void d3d_recompute_pass_sizes(d3d_video_t *d3d)
link_info.tex_w = next_pow2(out_width);
link_info.tex_h = next_pow2(out_height);
if (!renderchain_set_pass_size(d3d->chain, i, link_info.tex_w, link_info.tex_h))
if (!renderchain_set_pass_size(d3d->chain, i,
link_info.tex_w, link_info.tex_h))
{
RARCH_ERR("[D3D]: Failed to set pass size.\n");
return;
@ -139,7 +146,8 @@ static bool d3d_init_imports(d3d_video_t *d3d)
state_tracker_info tracker_info = {0};
tracker_info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
tracker_info.wram = (uint8_t*)
pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
tracker_info.info = d3d->shader.variable;
tracker_info.info_elem = d3d->shader.variables;
@ -150,7 +158,8 @@ static bool d3d_init_imports(d3d_video_t *d3d)
tracker_info.script_is_file = true;
}
tracker_info.script_class = *d3d->shader.script_class ? d3d->shader.script_class : NULL;
tracker_info.script_class =
*d3d->shader.script_class ? d3d->shader.script_class : NULL;
#endif
state_tracker_t *state_tracker = state_tracker_init(&tracker_info);
@ -168,18 +177,20 @@ static bool d3d_init_imports(d3d_video_t *d3d)
static bool d3d_init_chain(d3d_video_t *d3d, const video_info_t *video_info)
{
LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev;
// Setup information for first pass.
/* Setup information for first pass. */
LinkInfo link_info = {0};
link_info.pass = &d3d->shader.pass[0];
link_info.tex_w = link_info.tex_h = video_info->input_scale * RARCH_SCALE_BASE;
link_info.tex_w = link_info.tex_h =
video_info->input_scale * RARCH_SCALE_BASE;
d3d_deinit_chain(d3d);
d3d->chain = new renderchain_t();
if (!d3d->chain)
return false;
if (!renderchain_init(d3d->chain, &d3d->video_info, d3dr, d3d->cgCtx, &d3d->final_viewport, &link_info,
if (!renderchain_init(d3d->chain, &d3d->video_info, d3dr,
d3d->cgCtx, &d3d->final_viewport, &link_info,
d3d->video_info.rgb32 ? ARGB : RGB565))
{
RARCH_ERR("[D3D9]: Failed to init render chain.\n");
@ -257,12 +268,16 @@ static bool d3d_init_multipass(d3d_video_t *d3d)
{
if (!d3d->shader.pass[i].fbo.valid)
{
d3d->shader.pass[i].fbo.scale_x = d3d->shader.pass[i].fbo.scale_y = 1.0f;
d3d->shader.pass[i].fbo.type_x = d3d->shader.pass[i].fbo.type_y = RARCH_SCALE_INPUT;
d3d->shader.pass[i].fbo.scale_x =
d3d->shader.pass[i].fbo.scale_y = 1.0f;
d3d->shader.pass[i].fbo.type_x =
d3d->shader.pass[i].fbo.type_y = RARCH_SCALE_INPUT;
}
}
bool use_extra_pass = d3d->shader.passes < GFX_MAX_SHADERS && d3d->shader.pass[d3d->shader.passes - 1].fbo.valid;
bool use_extra_pass = d3d->shader.passes < GFX_MAX_SHADERS &&
d3d->shader.pass[d3d->shader.passes - 1].fbo.valid;
if (use_extra_pass)
{
d3d->shader.passes++;
@ -282,7 +297,8 @@ static bool d3d_init_multipass(d3d_video_t *d3d)
}
#endif
static void d3d_set_font_rect(d3d_video_t *d3d, const struct font_params *params)
static void d3d_set_font_rect(d3d_video_t *d3d,
const struct font_params *params)
{
#ifndef _XBOX
float pos_x = g_settings.video.msg_pos_x;
@ -296,9 +312,12 @@ static void d3d_set_font_rect(d3d_video_t *d3d, const struct font_params *params
font_size *= params->scale;
}
d3d->font_rect.left = d3d->final_viewport.X + d3d->final_viewport.Width * pos_x;
d3d->font_rect.right = d3d->final_viewport.X + d3d->final_viewport.Width;
d3d->font_rect.top = d3d->final_viewport.Y + (1.0f - pos_y) * d3d->final_viewport.Height - font_size;
d3d->font_rect.left = d3d->final_viewport.X +
d3d->final_viewport.Width * pos_x;
d3d->font_rect.right = d3d->final_viewport.X +
d3d->final_viewport.Width;
d3d->font_rect.top = d3d->final_viewport.Y +
(1.0f - pos_y) * d3d->final_viewport.Height - font_size;
d3d->font_rect.bottom = d3d->final_viewport.Height;
d3d->font_rect_shifted = d3d->font_rect;
@ -317,7 +336,8 @@ static bool d3d_init_singlepass(d3d_video_t *d3d)
pass.fbo.valid = true;
pass.fbo.scale_x = pass.fbo.scale_y = 1.0;
pass.fbo.type_x = pass.fbo.type_y = RARCH_SCALE_VIEWPORT;
strlcpy(pass.source.path, d3d->cg_shader.c_str(), sizeof(pass.source.path));
strlcpy(pass.source.path, d3d->cg_shader.c_str(),
sizeof(pass.source.path));
return true;
}
@ -325,7 +345,8 @@ static bool d3d_init_singlepass(d3d_video_t *d3d)
static bool d3d_process_shader(d3d_video_t *d3d)
{
#ifdef HAVE_FBO
if (strcmp(path_get_extension(d3d->cg_shader.c_str()), "cgp") == 0)
if (strcmp(path_get_extension(
d3d->cg_shader.c_str()), "cgp") == 0)
return d3d_init_multipass(d3d);
#endif
@ -336,7 +357,8 @@ static bool d3d_init_luts(d3d_video_t *d3d)
{
for (unsigned i = 0; i < d3d->shader.luts; i++)
{
bool ret = renderchain_add_lut(d3d->chain, d3d->shader.lut[i].id, d3d->shader.lut[i].path,
bool ret = renderchain_add_lut(
d3d->chain, d3d->shader.lut[i].id, d3d->shader.lut[i].path,
d3d->shader.lut[i].filter == RARCH_FILTER_UNSPEC ?
g_settings.video.smooth :
(d3d->shader.lut[i].filter == RARCH_FILTER_LINEAR));
@ -415,8 +437,8 @@ static bool d3d_init_base(void *data, const video_info_t *info)
return true;
}
static void d3d_calculate_rect(d3d_video_t *d3d, unsigned width, unsigned height,
bool keep, float desired_aspect);
static void d3d_calculate_rect(d3d_video_t *d3d, unsigned width,
unsigned height, bool keep, float desired_aspect);
static bool d3d_initialize(void *data, const video_info_t *info)
{
@ -465,7 +487,8 @@ static bool d3d_initialize(void *data, const video_info_t *info)
if (!ret)
return ret;
d3d_calculate_rect(d3d, d3d->screen_width, d3d->screen_height, info->force_aspect, g_extern.system.aspect_ratio);
d3d_calculate_rect(d3d, d3d->screen_width, d3d->screen_height,
info->force_aspect, g_extern.system.aspect_ratio);
#ifdef HAVE_SHADERS
if (!d3d_init_shader(d3d))
@ -482,9 +505,11 @@ static bool d3d_initialize(void *data, const video_info_t *info)
}
#if defined(_XBOX360)
strlcpy(g_settings.video.font_path, "game:\\media\\Arial_12.xpr", sizeof(g_settings.video.font_path));
strlcpy(g_settings.video.font_path, "game:\\media\\Arial_12.xpr",
sizeof(g_settings.video.font_path));
#endif
d3d->font_ctx = d3d_font_init_first(d3d, g_settings.video.font_path, g_settings.video.font_size);
d3d->font_ctx = d3d_font_init_first(d3d, g_settings.video.font_path,
g_settings.video.font_size);
if (!d3d->font_ctx)
{
RARCH_ERR("Failed to initialize font.\n");
@ -513,11 +538,12 @@ bool d3d_restore(d3d_video_t *d3d)
#include "d3d_overlays.cpp"
#endif
static void d3d_set_viewport(d3d_video_t *d3d, int x, int y, unsigned width, unsigned height)
static void d3d_set_viewport(d3d_video_t *d3d, int x, int y,
unsigned width, unsigned height)
{
D3DVIEWPORT viewport;
// D3D doesn't support negative X/Y viewports ...
/* D3D doesn't support negative X/Y viewports ... */
if (x < 0)
x = 0;
if (y < 0)
@ -535,7 +561,8 @@ static void d3d_set_viewport(d3d_video_t *d3d, int x, int y, unsigned width, uns
d3d_set_font_rect(d3d, NULL);
}
static void d3d_calculate_rect(d3d_video_t *d3d, unsigned width, unsigned height,
static void d3d_calculate_rect(d3d_video_t *d3d,
unsigned width, unsigned height,
bool keep, float desired_aspect)
{
if (g_settings.video.scale_integer)
@ -550,23 +577,29 @@ static void d3d_calculate_rect(d3d_video_t *d3d, unsigned width, unsigned height
{
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
{
const rarch_viewport_t &custom = g_extern.console.screen.viewports.custom_vp;
d3d_set_viewport(d3d, custom.x, custom.y, custom.width, custom.height);
const rarch_viewport_t &custom =
g_extern.console.screen.viewports.custom_vp;
d3d_set_viewport(d3d, custom.x, custom.y,
custom.width, custom.height);
}
else
{
float device_aspect = static_cast<float>(width) / static_cast<float>(height);
float device_aspect = static_cast<float>(width) /
static_cast<float>(height);
if (fabsf(device_aspect - desired_aspect) < 0.0001f)
d3d_set_viewport(d3d, 0, 0, width, height);
else if (device_aspect > desired_aspect)
{
float delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f;
d3d_set_viewport(d3d, int(roundf(width * (0.5f - delta))), 0, unsigned(roundf(2.0f * width * delta)), height);
d3d_set_viewport(d3d, int(roundf(width * (0.5f - delta))),
0, unsigned(roundf(2.0f * width * delta)), height);
}
else
{
float delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f;
d3d_set_viewport(d3d, 0, int(roundf(height * (0.5f - delta))), width, unsigned(roundf(2.0f * height * delta)));
d3d_set_viewport(d3d, 0, int(roundf(height * (0.5f - delta))),
width, unsigned(roundf(2.0f * height * delta)));
}
}
}
@ -587,7 +620,7 @@ static bool d3d_frame(void *data, const void *frame,
RARCH_PERFORMANCE_START(d3d_frame);
#ifndef _XBOX
// We cannot recover in fullscreen.
/* We cannot recover in fullscreen. */
if (d3d->needs_restore && IsIconic(d3d->hWnd))
return true;
#endif
@ -599,14 +632,17 @@ static bool d3d_frame(void *data, const void *frame,
if (d3d->should_resize)
{
d3d_calculate_rect(d3d, d3d->screen_width, d3d->screen_height, d3d->video_info.force_aspect, g_extern.system.aspect_ratio);
d3d_calculate_rect(d3d, d3d->screen_width,
d3d->screen_height, d3d->video_info.force_aspect,
g_extern.system.aspect_ratio);
renderchain_set_final_viewport(d3d->chain, &d3d->final_viewport);
d3d_recompute_pass_sizes(d3d);
d3d->should_resize = false;
}
// render_chain() only clears out viewport, clear out everything.
/* render_chain() only clears out viewport, clear out everything. */
screen_vp.X = 0;
screen_vp.Y = 0;
screen_vp.MinZ = 0;
@ -625,7 +661,8 @@ static bool d3d_frame(void *data, const void *frame,
d3dr->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0);
}
if (!renderchain_render(d3d->chain, frame, width, height, pitch, d3d->dev_rotation))
if (!renderchain_render(d3d->chain, frame, width,
height, pitch, d3d->dev_rotation))
{
RARCH_ERR("[D3D]: Failed to render scene.\n");
return false;
@ -663,7 +700,8 @@ static bool d3d_frame(void *data, const void *frame,
#endif
#ifdef HAVE_MENU
if (g_extern.lifecycle_state & (1ULL << MODE_MENU) && driver.menu_ctx && driver.menu_ctx->frame)
if (g_extern.lifecycle_state & (1ULL << MODE_MENU)
&& driver.menu_ctx && driver.menu_ctx->frame)
driver.menu_ctx->frame();
#endif
@ -737,7 +775,8 @@ static void d3d_free(void *data)
d3d->g_pD3D->Release();
#ifdef HAVE_MONITOR
Monitor::last_hm = MonitorFromWindow(d3d->hWnd, MONITOR_DEFAULTTONEAREST);
Monitor::last_hm = MonitorFromWindow(d3d->hWnd,
MONITOR_DEFAULTTONEAREST);
DestroyWindow(d3d->hWnd);
#endif
@ -779,10 +818,11 @@ static bool d3d_read_viewport(void *data, uint8_t *buffer)
goto end;
}
if (FAILED(d3d->d3d_err = d3dr->CreateOffscreenPlainSurface(d3d->screen_width,
d3d->screen_height,
D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM,
&dest, NULL)))
if (FAILED(d3d->d3d_err = d3dr->CreateOffscreenPlainSurface(
d3d->screen_width,
d3d->screen_height,
D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM,
&dest, NULL)))
{
ret = false;
goto end;
@ -803,7 +843,8 @@ static bool d3d_read_viewport(void *data, uint8_t *buffer)
pixels += (d3d->final_viewport.Height - 1) * pitchpix;
pixels -= d3d->final_viewport.Y * pitchpix;
for (unsigned y = 0; y < d3d->final_viewport.Height; y++, pixels -= pitchpix)
for (unsigned y = 0; y < d3d->final_viewport.Height;
y++, pixels -= pitchpix)
{
for (unsigned x = 0; x < d3d->final_viewport.Width; x++)
{
@ -827,7 +868,8 @@ end:
return ret;
}
static bool d3d_set_shader(void *data, enum rarch_shader_type type, const char *path)
static bool d3d_set_shader(void *data,
enum rarch_shader_type type, const char *path)
{
d3d_video_t *d3d = (d3d_video_t*)data;
std::string shader = "";
@ -855,7 +897,8 @@ static bool d3d_set_shader(void *data, enum rarch_shader_type type, const char *
}
#ifdef HAVE_MENU
static void d3d_get_poke_interface(void *data, const video_poke_interface_t **iface);
static void d3d_get_poke_interface(void *data,
const video_poke_interface_t **iface);
#endif
static void d3d_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
@ -865,7 +908,9 @@ static void d3d_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
switch (aspect_ratio_idx)
{
case ASPECT_RATIO_SQUARE:
gfx_set_square_pixel_viewport(g_extern.system.av_info.geometry.base_width, g_extern.system.av_info.geometry.base_height);
gfx_set_square_pixel_viewport(
g_extern.system.av_info.geometry.base_width,
g_extern.system.av_info.geometry.base_height);
break;
case ASPECT_RATIO_CORE:
@ -891,7 +936,8 @@ static void d3d_apply_state_changes(void *data)
d3d->should_resize = true;
}
static void d3d_set_osd_msg(void *data, const char *msg, const struct font_params *params)
static void d3d_set_osd_msg(void *data, const char *msg,
const struct font_params *params)
{
d3d_video_t *d3d = (d3d_video_t*)data;
@ -917,7 +963,8 @@ static void d3d_set_menu_texture_frame(void *data,
{
d3d_video_t *d3d = (d3d_video_t*)data;
if (!d3d->menu->tex || d3d->menu->tex_w != width || d3d->menu->tex_h != height)
if (!d3d->menu->tex || d3d->menu->tex_w != width
|| d3d->menu->tex_h != height)
{
if (d3d->menu && d3d->menu->tex)
d3d->menu->tex->Release();
@ -943,17 +990,20 @@ static void d3d_set_menu_texture_frame(void *data,
{
uint8_t *dst = (uint8_t*)d3dlr.pBits;
const uint32_t *src = (const uint32_t*)frame;
for (unsigned h = 0; h < height; h++, dst += d3dlr.Pitch, src += width)
for (unsigned h = 0; h < height;
h++, dst += d3dlr.Pitch, src += width)
{
memcpy(dst, src, width * sizeof(uint32_t));
memset(dst + width * sizeof(uint32_t), 0, d3dlr.Pitch - width * sizeof(uint32_t));
memset(dst + width * sizeof(uint32_t), 0,
d3dlr.Pitch - width * sizeof(uint32_t));
}
}
else
{
uint32_t *dst = (uint32_t*)d3dlr.pBits;
const uint16_t *src = (const uint16_t*)frame;
for (unsigned h = 0; h < height; h++, dst += d3dlr.Pitch >> 2, src += width)
for (unsigned h = 0; h < height;
h++, dst += d3dlr.Pitch >> 2, src += width)
{
for (unsigned w = 0; w < width; w++)
{
@ -976,7 +1026,8 @@ static void d3d_set_menu_texture_frame(void *data,
}
}
static void d3d_set_menu_texture_enable(void *data, bool state, bool full_screen)
static void d3d_set_menu_texture_enable(void *data,
bool state, bool full_screen)
{
d3d_video_t *d3d = (d3d_video_t*)data;
@ -1005,14 +1056,17 @@ static const video_poke_interface_t d3d_poke_interface = {
d3d_show_mouse,
};
static void d3d_get_poke_interface(void *data, const video_poke_interface_t **iface)
static void d3d_get_poke_interface(void *data,
const video_poke_interface_t **iface)
{
(void)data;
*iface = &d3d_poke_interface;
}
// Delay constructor due to lack of exceptions.
static bool d3d_construct(d3d_video_t *d3d, const video_info_t *info, const input_driver_t **input,
/* Delay constructor due to lack of exceptions. */
static bool d3d_construct(d3d_video_t *d3d,
const video_info_t *info, const input_driver_t **input,
void **input_data)
{
d3d->should_resize = false;
@ -1043,8 +1097,10 @@ static bool d3d_construct(d3d_video_t *d3d, const video_info_t *info, const inpu
d3d->windowClass.hInstance = NULL;
d3d->windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
d3d->windowClass.lpszClassName = "RetroArch";
d3d->windowClass.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON));
d3d->windowClass.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0);
d3d->windowClass.hIcon = LoadIcon(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDI_ICON));
d3d->windowClass.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0);
if (!info->fullscreen)
d3d->windowClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
@ -1057,9 +1113,13 @@ static bool d3d_construct(d3d_video_t *d3d, const video_info_t *info, const inpu
bool windowed_full = g_settings.video.windowed_fullscreen;
full_x = (windowed_full || info->width == 0) ? (mon_rect.right - mon_rect.left) : info->width;
full_y = (windowed_full || info->height == 0) ? (mon_rect.bottom - mon_rect.top) : info->height;
RARCH_LOG("[D3D]: Monitor size: %dx%d.\n", (int)(mon_rect.right - mon_rect.left), (int)(mon_rect.bottom - mon_rect.top));
full_x = (windowed_full || info->width == 0) ?
(mon_rect.right - mon_rect.left) : info->width;
full_y = (windowed_full || info->height == 0) ?
(mon_rect.bottom - mon_rect.top) : info->height;
RARCH_LOG("[D3D]: Monitor size: %dx%d.\n",
(int)(mon_rect.right - mon_rect.left),
(int)(mon_rect.bottom - mon_rect.top));
#else
if (d3d->ctx_driver && d3d->ctx_driver->get_video_size)
d3d->ctx_driver->get_video_size(&full_x, &full_y);
@ -1114,10 +1174,11 @@ static bool d3d_construct(d3d_video_t *d3d, const video_info_t *info, const inpu
#endif
#ifdef HAVE_SHADERS
// This should only be done once here
// to avoid set_shader() to be overridden
// later.
enum rarch_shader_type type = gfx_shader_parse_type(g_settings.video.shader_path, RARCH_SHADER_NONE);
/* This should only be done once here
* to avoid set_shader() to be overridden
* later. */
enum rarch_shader_type type =
gfx_shader_parse_type(g_settings.video.shader_path, RARCH_SHADER_NONE);
if (g_settings.video.shader_enable && type == RARCH_SHADER_CG)
d3d->cg_shader = g_settings.video.shader_path;
@ -1139,7 +1200,7 @@ static bool d3d_construct(d3d_video_t *d3d, const video_info_t *info, const inpu
static const gfx_ctx_driver_t *d3d_get_context(void)
{
// TODO: GL core contexts through ANGLE?
/* TODO: GL core contexts through ANGLE? */
enum gfx_ctx_api api;
unsigned major, minor;
#if defined(_XBOX1)
@ -1167,7 +1228,7 @@ static void *d3d_init(const video_info_t *info, const input_driver_t **input,
return NULL;
}
//default values
/* default values */
vid->g_pD3D = NULL;
vid->dev = NULL;
#ifndef _XBOX

View File

@ -1,5 +1,7 @@
static void d3d_overlay_render(void *data, overlay_t *overlay)
{
void *verts;
unsigned i;
d3d_video_t *d3d = (d3d_video_t*)data;
if (!overlay || !overlay->tex)
@ -15,10 +17,12 @@ static void d3d_overlay_render(void *data, overlay_t *overlay)
if (!overlay->vert_buf)
{
D3DDevice_CreateVertexBuffers(d3d->dev, sizeof(vert),
d3d->dev->GetSoftwareVertexProcessing() ? D3DUSAGE_SOFTWAREPROCESSING : 0, 0, D3DPOOL_MANAGED, &overlay->vert_buf, NULL);
d3d->dev->GetSoftwareVertexProcessing() ?
D3DUSAGE_SOFTWAREPROCESSING : 0, 0, D3DPOOL_MANAGED,
&overlay->vert_buf, NULL);
}
for (unsigned i = 0; i < 4; i++)
for (i = 0; i < 4; i++)
{
vert[i].z = 0.5f;
vert[i].r = vert[i].g = vert[i].b = 1.0f;
@ -29,13 +33,17 @@ static void d3d_overlay_render(void *data, overlay_t *overlay)
float overlay_height = d3d->final_viewport.Height;
vert[0].x = overlay->vert_coords.x * overlay_width;
vert[1].x = (overlay->vert_coords.x + overlay->vert_coords.w) * overlay_width;
vert[1].x = (overlay->vert_coords.x + overlay->vert_coords.w)
* overlay_width;
vert[2].x = overlay->vert_coords.x * overlay_width;
vert[3].x = (overlay->vert_coords.x + overlay->vert_coords.w) * overlay_width;
vert[3].x = (overlay->vert_coords.x + overlay->vert_coords.w)
* overlay_width;
vert[0].y = overlay->vert_coords.y * overlay_height;
vert[1].y = overlay->vert_coords.y * overlay_height;
vert[2].y = (overlay->vert_coords.y + overlay->vert_coords.h) * overlay_height;
vert[3].y = (overlay->vert_coords.y + overlay->vert_coords.h) * overlay_height;
vert[2].y = (overlay->vert_coords.y + overlay->vert_coords.h)
* overlay_height;
vert[3].y = (overlay->vert_coords.y + overlay->vert_coords.h)
* overlay_height;
vert[0].u = overlay->tex_coords.x;
vert[1].u = overlay->tex_coords.x + overlay->tex_coords.w;
@ -46,14 +54,13 @@ static void d3d_overlay_render(void *data, overlay_t *overlay)
vert[2].v = overlay->tex_coords.y + overlay->tex_coords.h;
vert[3].v = overlay->tex_coords.y + overlay->tex_coords.h;
// Align texels and vertices.
for (unsigned i = 0; i < 4; i++)
/* Align texels and vertices. */
for (i = 0; i < 4; i++)
{
vert[i].x -= 0.5f;
vert[i].y += 0.5f;
}
void *verts;
overlay->vert_buf->Lock(0, sizeof(vert), &verts, 0);
memcpy(verts, vert, sizeof(vert));
overlay->vert_buf->Unlock();
@ -66,9 +73,12 @@ static void d3d_overlay_render(void *data, overlay_t *overlay)
#ifndef _XBOX1
// set vertex decl for overlay
D3DVERTEXELEMENT vElems[4] = {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_TEXCOORD, 0},
{0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_COLOR, 0},
D3DDECL_END()
};
LPDIRECT3DVERTEXDECLARATION vertex_decl;
@ -77,11 +87,12 @@ static void d3d_overlay_render(void *data, overlay_t *overlay)
vertex_decl->Release();
#endif
D3DDevice_SetStreamSources(d3d->dev, 0, overlay->vert_buf, 0, sizeof(overlay_vertex));
D3DDevice_SetStreamSources(d3d->dev, 0, overlay->vert_buf,
0, sizeof(overlay_vertex));
if (overlay->fullscreen)
{
// set viewport to full window
/* Set viewport to full window. */
D3DVIEWPORT vp_full;
vp_full.X = 0;
vp_full.Y = 0;
@ -92,7 +103,7 @@ static void d3d_overlay_render(void *data, overlay_t *overlay)
d3d->dev->SetViewport(&vp_full);
}
// render overlay
/* Render overlay. */
d3d->dev->SetTexture(0, overlay->tex);
D3DDevice_SetSamplerState_AddressU(d3d->dev, 0, D3DTADDRESS_BORDER);
D3DDevice_SetSamplerState_AddressV(d3d->dev, 0, D3DTADDRESS_BORDER);
@ -100,7 +111,7 @@ static void d3d_overlay_render(void *data, overlay_t *overlay)
D3DDevice_SetSamplerState_MagFilter(d3d->dev, 0, D3DTEXF_LINEAR);
D3DDevice_DrawPrimitive(d3d->dev, D3DPT_TRIANGLESTRIP, 0, 2);
// restore previous state
/* Restore previous state. */
d3d->dev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
d3d->dev->SetViewport(&d3d->final_viewport);
}
@ -108,6 +119,7 @@ static void d3d_overlay_render(void *data, overlay_t *overlay)
void d3d_free_overlay(void *data, overlay_t *overlay)
{
d3d_video_t *d3d = (d3d_video_t*)data;
if (overlay->tex)
overlay->tex->Release();
if (overlay->vert_buf)
@ -116,8 +128,10 @@ void d3d_free_overlay(void *data, overlay_t *overlay)
void d3d_free_overlays(void *data)
{
unsigned i;
d3d_video_t *d3d = (d3d_video_t*)data;
for (unsigned i = 0; i < d3d->overlays.size(); i++)
for (i = 0; i < d3d->overlays.size(); i++)
d3d_free_overlay(d3d, &d3d->overlays[i]);
d3d->overlays.clear();
}
@ -150,18 +164,24 @@ static void d3d_overlay_vertex_geom(void *data,
d3d->overlays[index].vert_coords.h = h;
}
static bool d3d_overlay_load(void *data, const texture_image *images, unsigned num_images)
static bool d3d_overlay_load(void *data,
const texture_image *images, unsigned num_images)
{
unsigned i, y;
d3d_video_t *d3d = (d3d_video_t*)data;
d3d_free_overlays(data);
d3d->overlays.resize(num_images);
for (unsigned i = 0; i < num_images; i++)
for (i = 0; i < num_images; i++)
{
unsigned width = images[i].width;
unsigned height = images[i].height;
overlay_t &overlay = d3d->overlays[i];
if (FAILED(d3d->dev->CreateTexture(width, height, 1,
if (FAILED(d3d->dev->CreateTexture(
width,
height,
1,
0,
D3DFMT_A8R8G8B8,
D3DPOOL_MANAGED,
@ -172,19 +192,23 @@ static bool d3d_overlay_load(void *data, const texture_image *images, unsigned n
}
D3DLOCKED_RECT d3dlr;
if (SUCCEEDED(overlay.tex->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK)))
if (SUCCEEDED(overlay.tex->LockRect(0, &d3dlr,
NULL, D3DLOCK_NOSYSLOCK)))
{
uint32_t *dst = static_cast<uint32_t*>(d3dlr.pBits);
const uint32_t *src = images[i].pixels;
unsigned pitch = d3dlr.Pitch >> 2;
for (unsigned y = 0; y < height; y++, dst += pitch, src += width)
for (y = 0; y < height; y++, dst += pitch, src += width)
memcpy(dst, src, width << 2);
overlay.tex->UnlockRect(0);
}
overlay.tex_w = width;
overlay.tex_h = height;
d3d_overlay_tex_geom(d3d, i, 0, 0, 1, 1); // Default. Stretch to whole screen.
/* Default. Stretch to whole screen. */
d3d_overlay_tex_geom(d3d, i, 0, 0, 1, 1);
d3d_overlay_vertex_geom(d3d, i, 0, 0, 1, 1);
}
@ -193,9 +217,10 @@ static bool d3d_overlay_load(void *data, const texture_image *images, unsigned n
static void d3d_overlay_enable(void *data, bool state)
{
unsigned i;
d3d_video_t *d3d = (d3d_video_t*)data;
for (unsigned i = 0; i < d3d->overlays.size(); i++)
for (i = 0; i < d3d->overlays.size(); i++)
d3d->overlays_enabled = state;
if (d3d && d3d->ctx_driver && d3d->ctx_driver->show_mouse)
@ -204,9 +229,10 @@ static void d3d_overlay_enable(void *data, bool state)
static void d3d_overlay_full_screen(void *data, bool enable)
{
unsigned i;
d3d_video_t *d3d = (d3d_video_t*)data;
for (unsigned i = 0; i < d3d->overlays.size(); i++)
for (i = 0; i < d3d->overlays.size(); i++)
d3d->overlays[i].fullscreen = enable;
}
@ -225,7 +251,8 @@ static const video_overlay_interface_t d3d_overlay_interface = {
d3d_overlay_set_alpha,
};
static void d3d_get_overlay_interface(void *data, const video_overlay_interface_t **iface)
static void d3d_get_overlay_interface(void *data,
const video_overlay_interface_t **iface)
{
(void)data;
*iface = &d3d_overlay_interface;

View File

@ -20,8 +20,7 @@ static inline D3DTEXTUREFILTERTYPE translate_filter(unsigned type)
{
if (type == RARCH_FILTER_UNSPEC)
return g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT;
else
return type == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT;
return type == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT;
}
static inline D3DTEXTUREFILTERTYPE translate_filter(bool smooth)
@ -106,13 +105,15 @@ void renderchain_clear(void *data)
chain->luts.clear();
}
void renderchain_set_final_viewport(void *data, const D3DVIEWPORT *final_viewport)
void renderchain_set_final_viewport(void *data,
const D3DVIEWPORT *final_viewport)
{
renderchain_t *chain = (renderchain_t*)data;
chain->final_viewport = (D3DVIEWPORT*)final_viewport;
}
bool renderchain_set_pass_size(void *data, unsigned pass_index, unsigned width, unsigned height)
bool renderchain_set_pass_size(void *data, unsigned pass_index,
unsigned width, unsigned height)
{
renderchain_t *chain = (renderchain_t*)data;
LPDIRECT3DDEVICE d3dr = chain->dev;
@ -125,7 +126,8 @@ bool renderchain_set_pass_size(void *data, unsigned pass_index, unsigned width,
if (FAILED(d3dr->CreateTexture(width, height, 1,
D3DUSAGE_RENDERTARGET,
chain->passes.back().info.pass->fbo.fp_fbo ? D3DFMT_A32B32G32R32F : D3DFMT_A8R8G8B8,
chain->passes.back().info.pass->fbo.fp_fbo ?
D3DFMT_A32B32G32R32F : D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT,
&pass.tex, NULL)))
return false;
@ -148,12 +150,15 @@ bool renderchain_add_pass(void *data, const LinkInfo *info)
pass.last_width = 0;
pass.last_height = 0;
renderchain_compile_shaders(chain, pass.fPrg, pass.vPrg, info->pass->source.path);
renderchain_compile_shaders(chain, pass.fPrg,
pass.vPrg, info->pass->source.path);
if (!renderchain_init_shader_fvf(chain, pass))
return false;
if (FAILED(D3DDevice_CreateVertexBuffers(d3dr, 4 * sizeof(Vertex),
d3dr->GetSoftwareVertexProcessing() ? D3DUSAGE_SOFTWAREPROCESSING : 0,
d3dr->GetSoftwareVertexProcessing()
? D3DUSAGE_SOFTWAREPROCESSING : 0,
0,
D3DPOOL_DEFAULT,
&pass.vertex_buf,
@ -162,7 +167,8 @@ bool renderchain_add_pass(void *data, const LinkInfo *info)
if (FAILED(d3dr->CreateTexture(info->tex_w, info->tex_h, 1,
D3DUSAGE_RENDERTARGET,
chain->passes.back().info.pass->fbo.fp_fbo ? D3DFMT_A32B32G32R32F : D3DFMT_A8R8G8B8,
chain->passes.back().info.pass->fbo.fp_fbo
? D3DFMT_A32B32G32R32F : D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT,
&pass.tex, NULL)))
return false;
@ -251,7 +257,8 @@ bool renderchain_render(void *chain_data, const void *data,
unsigned current_height = height;
unsigned out_width = 0;
unsigned out_height = 0;
renderchain_convert_geometry(chain, &chain->passes[0].info, out_width, out_height,
renderchain_convert_geometry(chain, &chain->passes[0].info,
out_width, out_height,
current_width, current_height, chain->final_viewport);
#ifdef _XBOX1
d3dr->SetFlickerFilter(g_extern.console.screen.flicker_filter_index);
@ -323,11 +330,13 @@ bool renderchain_render(void *chain_data, const void *data,
renderchain_end_render(chain);
renderchain_set_shaders(chain, chain->fStock, chain->vStock);
renderchain_set_mvp(chain, chain->vStock, chain->final_viewport->Width, chain->final_viewport->Height, 0);
renderchain_set_mvp(chain, chain->vStock, chain->final_viewport->Width,
chain->final_viewport->Height, 0);
return true;
}
bool renderchain_create_first_pass(void *data, const LinkInfo *info, PixelFormat fmt)
bool renderchain_create_first_pass(void *data, const LinkInfo *info,
PixelFormat fmt)
{
renderchain_t *chain = (renderchain_t*)data;
D3DXMATRIX ident;
@ -349,32 +358,33 @@ bool renderchain_create_first_pass(void *data, const LinkInfo *info, PixelFormat
if (FAILED(d3dr->CreateVertexBuffer(
4 * sizeof(Vertex),
d3dr->GetSoftwareVertexProcessing() ? D3DUSAGE_SOFTWAREPROCESSING : 0,
d3dr->GetSoftwareVertexProcessing()
? D3DUSAGE_SOFTWAREPROCESSING : 0,
0,
D3DPOOL_DEFAULT,
&chain->prev.vertex_buf[i],
NULL)))
{
return false;
}
if (FAILED(d3dr->CreateTexture(info->tex_w, info->tex_h, 1, 0,
fmt == RGB565 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8,
D3DPOOL_MANAGED,
&chain->prev.tex[i], NULL)))
{
return false;
}
d3dr->SetTexture(0, chain->prev.tex[i]);
D3DDevice_SetSamplerState_MinFilter(d3dr, 0, translate_filter(info->pass->filter));
D3DDevice_SetSamplerState_MagFilter(d3dr, 0, translate_filter(info->pass->filter));
D3DDevice_SetSamplerState_MinFilter(d3dr, 0,
translate_filter(info->pass->filter));
D3DDevice_SetSamplerState_MagFilter(d3dr, 0,
translate_filter(info->pass->filter));
D3DDevice_SetSamplerState_AddressU(d3dr, 0, D3DTADDRESS_BORDER);
D3DDevice_SetSamplerState_AddressV(d3dr, 0, D3DTADDRESS_BORDER);
d3dr->SetTexture(0, NULL);
}
renderchain_compile_shaders(chain, pass.fPrg, pass.vPrg, info->pass->source.path);
renderchain_compile_shaders(chain, pass.fPrg,
pass.vPrg, info->pass->source.path);
if (!renderchain_init_shader_fvf(chain, pass))
return false;
chain->passes.push_back(pass);
@ -431,7 +441,7 @@ void renderchain_set_vertices(void *data, Pass &pass,
vert[2].lut_v = 1.0f;
vert[3].lut_v = 1.0f;
// Align texels and vertices.
/* Align texels and vertices. */
for (unsigned i = 0; i < 4; i++)
{
vert[i].x -= 0.5f;
@ -524,7 +534,8 @@ void renderchain_blit_to_texture(void *data, const void *frame,
Pass &first = chain->passes[0];
if (first.last_width != width || first.last_height != height)
{
D3DTexture_LockRectClear(first, first.tex, 0, d3dlr, NULL, D3DLOCK_NOSYSLOCK);
D3DTexture_LockRectClear(first, first.tex, 0, d3dlr,
NULL, D3DLOCK_NOSYSLOCK);
}
D3DTexture_Blit(chain, desc, d3dlr, frame, width, height, pitch);
@ -537,8 +548,10 @@ void renderchain_render_pass(void *data, Pass &pass, unsigned pass_index)
renderchain_set_shaders(chain, pass.fPrg, pass.vPrg);
d3dr->SetTexture(0, pass.tex);
D3DDevice_SetSamplerState_MinFilter(d3dr, 0, translate_filter(pass.info.pass->filter));
D3DDevice_SetSamplerState_MagFilter(d3dr, 0, translate_filter(pass.info.pass->filter));
D3DDevice_SetSamplerState_MinFilter(d3dr, 0,
translate_filter(pass.info.pass->filter));
D3DDevice_SetSamplerState_MagFilter(d3dr, 0,
translate_filter(pass.info.pass->filter));
#ifdef _XBOX1
d3dr->SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1);
@ -547,7 +560,8 @@ void renderchain_render_pass(void *data, Pass &pass, unsigned pass_index)
#endif
for (unsigned i = 0; i < 4; i++)
{
D3DDevice_SetStreamSources(d3dr, i, pass.vertex_buf, 0, sizeof(Vertex));
D3DDevice_SetStreamSources(d3dr, i,
pass.vertex_buf, 0, sizeof(Vertex));
}
renderchain_bind_orig(chain, pass);
@ -604,19 +618,24 @@ void renderchain_log_info(void *data, const LinkInfo *info)
break;
}
RARCH_LOG("\tBilinear filter: %s\n", info->pass->filter == RARCH_FILTER_LINEAR ? "true" : "false");
RARCH_LOG("\tBilinear filter: %s\n",
info->pass->filter == RARCH_FILTER_LINEAR ? "true" : "false");
}
void renderchain_unbind_all(void *data)
{
renderchain_t *chain = (renderchain_t*)data;
LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)chain->dev;
// Have to be a bit anal about it.
// Render targets hate it when they have filters apparently.
/* Have to be a bit anal about it.
* Render targets hate it when they have filters apparently.
*/
for (unsigned i = 0; i < chain->bound_tex.size(); i++)
{
D3DDevice_SetSamplerState_MinFilter(d3dr, chain->bound_tex[i], D3DTEXF_POINT);
D3DDevice_SetSamplerState_MagFilter(d3dr, chain->bound_tex[i], D3DTEXF_POINT);
D3DDevice_SetSamplerState_MinFilter(d3dr,
chain->bound_tex[i], D3DTEXF_POINT);
D3DDevice_SetSamplerState_MagFilter(d3dr,
chain->bound_tex[i], D3DTEXF_POINT);
d3dr->SetTexture(chain->bound_tex[i], NULL);
}

View File

@ -101,61 +101,97 @@ typedef struct renderchain
} renderchain_t;
void renderchain_free(void *data);
bool renderchain_init(void *data, const video_info_t *video_info,
LPDIRECT3DDEVICE dev_,
CGcontext cgCtx_,
const D3DVIEWPORT *final_viewport_,
const LinkInfo *info,
PixelFormat fmt);
void renderchain_clear(void *data);
void renderchain_set_final_viewport(void *data, const D3DVIEWPORT *final_viewport);
bool renderchain_set_pass_size(void *data, unsigned pass_index, unsigned width, unsigned height);
void renderchain_set_final_viewport(void *data,
const D3DVIEWPORT *final_viewport);
bool renderchain_set_pass_size(void *data, unsigned pass_index,
unsigned width, unsigned height);
bool renderchain_add_pass(void *data, const LinkInfo *info);
bool renderchain_add_lut(void *data, const std::string &id,
const std::string &path,
bool smooth);
void renderchain_add_state_tracker(void *data, state_tracker_t *tracker);
void renderchain_start_render(void *data);
void renderchain_end_render(void *data);
bool renderchain_render(void *chain_data, const void *data,
unsigned width, unsigned height, unsigned pitch, unsigned rotation);
D3DTEXTUREFILTERTYPE renderchain_translate_filter(unsigned type);
D3DTEXTUREFILTERTYPE renderchain_translate_filter(bool smooth);
bool renderchain_create_first_pass(void *data, const LinkInfo *info, PixelFormat fmt);
bool renderchain_create_first_pass(void *data,
const LinkInfo *info, PixelFormat fmt);
void renderchain_set_vertices(void *data, Pass &pass,
unsigned width, unsigned height,
unsigned out_width, unsigned out_height,
unsigned vp_width, unsigned vp_height,
unsigned rotation);
void renderchain_set_viewport(void *data, D3DVIEWPORT *vp);
void renderchain_set_mvp(void *data, CGprogram &vPrg,
unsigned vp_width, unsigned vp_height,
unsigned rotation);
void renderchain_convert_geometry(void *data, const LinkInfo *info,
unsigned &out_width, unsigned &out_height,
unsigned width, unsigned height,
D3DVIEWPORT *final_viewport);
void renderchain_blit_to_texture(void *data, const void *frame,
unsigned width, unsigned height,
unsigned pitch);
void renderchain_render_pass(void *data, Pass &pass, unsigned pass_index);
void renderchain_log_info(void *data, const LinkInfo *info);
void renderchain_unbind_all(void *data);
bool renderchain_compile_shaders(void *data, CGprogram &fPrg, CGprogram &vPrg, const std::string &shader);
bool renderchain_compile_shaders(void *data, CGprogram &fPrg,
CGprogram &vPrg, const std::string &shader);
void renderchain_set_shaders(void *data, CGprogram &fPrg, CGprogram &vPrg);
void renderchain_destroy_stock_shader(void *data);
void renderchain_destroy_shader(void *data, int i);
void renderchain_set_shader_mvp(void *data, CGprogram &vPrg, D3DXMATRIX &tmp);
void renderchain_set_shader_params(void *data, Pass &pass,
unsigned video_w, unsigned video_h,
unsigned tex_w, unsigned tex_h,
unsigned viewport_w, unsigned viewport_h);
void renderchain_bind_tracker(void *data, Pass &pass, unsigned pass_index);
bool renderchain_init_shader_fvf(void *data, Pass &pass);
void renderchain_bind_orig(void *data, Pass &pass);
void renderchain_bind_prev(void *data, Pass &pass);
void renderchain_bind_luts(void *data, Pass &pass);
void renderchain_bind_pass(void *data, Pass &pass, unsigned pass_index);
#endif

View File

@ -47,13 +47,16 @@ static inline bool validate_param_name(const char *name)
return true;
}
static inline CGparameter find_param_from_semantic(CGparameter param, const std::string &sem)
static inline CGparameter find_param_from_semantic(
CGparameter param, const std::string &sem)
{
while (param)
{
if (cgGetParameterType(param) == CG_STRUCT)
{
CGparameter ret = find_param_from_semantic(cgGetFirstStructParameter(param), sem);
CGparameter ret = find_param_from_semantic(
cgGetFirstStructParameter(param), sem);
if (ret)
return ret;
}
@ -72,12 +75,15 @@ static inline CGparameter find_param_from_semantic(CGparameter param, const std:
return NULL;
}
static inline CGparameter find_param_from_semantic(CGprogram prog, const std::string &sem)
static inline CGparameter find_param_from_semantic(CGprogram prog,
const std::string &sem)
{
return find_param_from_semantic(cgGetFirstParameter(prog, CG_PROGRAM), sem);
return find_param_from_semantic(cgGetFirstParameter(
prog, CG_PROGRAM), sem);
}
bool renderchain_compile_shaders(void *data, CGprogram &fPrg, CGprogram &vPrg, const std::string &shader)
bool renderchain_compile_shaders(void *data, CGprogram &fPrg,
CGprogram &vPrg, const std::string &shader)
{
renderchain_t *chain = (renderchain_t*)data;
CGprofile vertex_profile = cgD3D9GetLatestVertexProfile();
@ -204,12 +210,15 @@ void renderchain_bind_tracker(void *data, Pass &pass, unsigned pass_index)
return;
if (pass_index == 1)
chain->uniform_cnt = state_get_uniform(chain->tracker, chain->uniform_info, MAX_VARIABLES, chain->frame_count);
chain->uniform_cnt = state_get_uniform(chain->tracker,
chain->uniform_info, MAX_VARIABLES, chain->frame_count);
for (unsigned i = 0; i < chain->uniform_cnt; i++)
{
set_cg_param(pass.fPrg, chain->uniform_info[i].id, chain->uniform_info[i].value);
set_cg_param(pass.vPrg, chain->uniform_info[i].id, chain->uniform_info[i].value);
set_cg_param(pass.fPrg, chain->uniform_info[i].id,
chain->uniform_info[i].value);
set_cg_param(pass.vPrg, chain->uniform_info[i].id,
chain->uniform_info[i].value);
}
}
@ -423,7 +432,9 @@ void renderchain_bind_prev(void *data, Pass &pass)
{
unsigned index = cgGetParameterResourceIndex(param);
LPDIRECT3DTEXTURE tex = chain->prev.tex[(chain->prev.ptr - (i + 1)) & TEXTURESMASK];
LPDIRECT3DTEXTURE tex = (LPDIRECT3DTEXTURE)
chain->prev.tex[(chain->prev.ptr - (i + 1)) & TEXTURESMASK];
chain->dev->SetTexture(index, tex);
chain->bound_tex.push_back(index);
@ -439,7 +450,8 @@ void renderchain_bind_prev(void *data, Pass &pass)
if (param)
{
unsigned index = pass.attrib_map[cgGetParameterResourceIndex(param)];
LPDIRECT3DVERTEXBUFFER vert_buf = chain->prev.vertex_buf[(chain->prev.ptr - (i + 1)) & TEXTURESMASK];
LPDIRECT3DVERTEXBUFFER vert_buf = (LPDIRECT3DVERTEXBUFFER)
chain->prev.vertex_buf[(chain->prev.ptr - (i + 1)) & TEXTURESMASK];
chain->bound_vert.push_back(index);
chain->dev->SetStreamSource(index, vert_buf, 0, sizeof(Vertex));
@ -452,8 +464,10 @@ void renderchain_bind_luts(void *data, Pass &pass)
renderchain_t *chain = (renderchain_t*)data;
for (unsigned i = 0; i < chain->luts.size(); i++)
{
CGparameter fparam = cgGetNamedParameter(pass.fPrg, chain->luts[i].id.c_str());
CGparameter fparam = cgGetNamedParameter(
pass.fPrg, chain->luts[i].id.c_str());
int bound_index = -1;
if (fparam)
{
unsigned index = cgGetParameterResourceIndex(fparam);
@ -463,12 +477,16 @@ void renderchain_bind_luts(void *data, Pass &pass)
translate_filter(chain->luts[i].smooth));
chain->dev->SetSamplerState(index, D3DSAMP_MINFILTER,
translate_filter(chain->luts[i].smooth));
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU,
D3DTADDRESS_BORDER);
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV,
D3DTADDRESS_BORDER);
chain->bound_tex.push_back(index);
}
CGparameter vparam = cgGetNamedParameter(pass.vPrg, chain->luts[i].id.c_str());
CGparameter vparam = cgGetNamedParameter(
pass.vPrg, chain->luts[i].id.c_str());
if (vparam)
{
unsigned index = cgGetParameterResourceIndex(vparam);
@ -479,8 +497,10 @@ void renderchain_bind_luts(void *data, Pass &pass)
translate_filter(chain->luts[i].smooth));
chain->dev->SetSamplerState(index, D3DSAMP_MINFILTER,
translate_filter(chain->luts[i].smooth));
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU,
D3DTADDRESS_BORDER);
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV,
D3DTADDRESS_BORDER);
chain->bound_tex.push_back(index);
}
}
@ -490,9 +510,12 @@ void renderchain_bind_luts(void *data, Pass &pass)
void renderchain_bind_pass(void *data, Pass &pass, unsigned pass_index)
{
renderchain_t *chain = (renderchain_t*)data;
// We only bother binding passes which are two indices behind.
if (pass_index < 3)
{
/* We only bother binding passes which are two indices behind. */
return;
}
for (unsigned i = 1; i < pass_index - 1; i++)
{
@ -530,15 +553,18 @@ void renderchain_bind_pass(void *data, Pass &pass, unsigned pass_index)
translate_filter(chain->passes[i].info.pass->filter));
chain->dev->SetSamplerState(index, D3DSAMP_MINFILTER,
translate_filter(chain->passes[i].info.pass->filter));
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU,
D3DTADDRESS_BORDER);
chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV,
D3DTADDRESS_BORDER);
}
param = cgGetNamedParameter(pass.vPrg, attr_tex_coord.c_str());
if (param)
{
unsigned index = pass.attrib_map[cgGetParameterResourceIndex(param)];
chain->dev->SetStreamSource(index, chain->passes[i].vertex_buf, 0, sizeof(Vertex));
chain->dev->SetStreamSource(index, chain->passes[i].vertex_buf,
0, sizeof(Vertex));
chain->bound_vert.push_back(index);
}
}

View File

@ -131,9 +131,12 @@ static void renderchain_render_pass(void *data, const void *frame, unsigned widt
d3d_video_t *d3d = (d3d_video_t*)data;
LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev;
#ifdef _XBOX1
#if defined(_XBOX1)
d3dr->SetFlickerFilter(g_extern.console.screen.flicker_filter_index);
d3dr->SetSoftDisplayFilter(g_extern.console.softfilter_enable);
#elif defined(_XBOX360)
DWORD fetchConstant;
UINT64 pendingMask3;
#endif
renderchain_blit_to_texture(d3d, frame, width, height, pitch);

View File

@ -27,7 +27,7 @@
#include "../../gfx/fonts/d3d_font.h"
#include "../../gfx/gfx_context.h"
#include "../../xdk/xdk_defines.h"
#include "../../gfx/d3d9/xdk_defines.h"
#define DFONT_MAX 4096
#if defined(_XBOX360)

View File

@ -109,4 +109,8 @@
#define D3DDevice_DrawPrimitive(dev, type, start, count) dev->DrawPrimitive(type, start, count)
#ifndef D3DCREATE_SOFTWARE_VERTEXPROCESSING
#define D3DCREATE_SOFTWARE_VERTEXPROCESSING 0
#endif
#endif

View File

@ -92,7 +92,8 @@ struct rarch_softfilter
#endif
};
static const struct softfilter_implementation *softfilter_find_implementation(rarch_softfilter_t *filt, const char *ident)
static const struct softfilter_implementation *
softfilter_find_implementation(rarch_softfilter_t *filt, const char *ident)
{
unsigned i;
for (i = 0; i < filt->num_plugs; i++)
@ -110,7 +111,8 @@ struct softfilter_userdata
const char *prefix[2];
};
static int softfilter_get_float(void *userdata, const char *key_str, float *value, float default_value)
static int softfilter_get_float(void *userdata, const char *key_str,
float *value, float default_value)
{
struct softfilter_userdata *filt = (struct softfilter_userdata*)userdata;
@ -126,7 +128,8 @@ static int softfilter_get_float(void *userdata, const char *key_str, float *valu
return got;
}
static int softfilter_get_int(void *userdata, const char *key_str, int *value, int default_value)
static int softfilter_get_int(void *userdata, const char *key_str,
int *value, int default_value)
{
struct softfilter_userdata *filt = (struct softfilter_userdata*)userdata;
@ -242,10 +245,11 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt,
return false;
userdata.conf = filt->conf;
userdata.prefix[0] = key; // Index-specific configs take priority over ident-specific.
/* Index-specific configs take priority over ident-specific. */
userdata.prefix[0] = key;
userdata.prefix[1] = filt->impl->short_ident;
// Simple assumptions.
/* Simple assumptions. */
filt->pix_fmt = in_pixel_format;
input_fmts = filt->impl->query_input_formats();
@ -268,7 +272,8 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt,
}
output_fmts = filt->impl->query_output_formats(input_fmt);
if (output_fmts & input_fmt) // If we have a match of input/output formats, use that.
/* If we have a match of input/output formats, use that. */
if (output_fmts & input_fmt)
filt->out_pix_fmt = in_pixel_format;
else if (output_fmts & SOFTFILTER_FMT_XRGB8888)
filt->out_pix_fmt = RETRO_PIXEL_FORMAT_XRGB8888;
@ -283,8 +288,10 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt,
filt->max_width = max_width;
filt->max_height = max_height;
filt->impl_data = filt->impl->create(&softfilter_config, input_fmt, input_fmt, max_width, max_height,
threads != RARCH_SOFTFILTER_THREADS_AUTO ? threads : rarch_get_cpu_cores(), cpu_features,
filt->impl_data = filt->impl->create(
&softfilter_config, input_fmt, input_fmt, max_width, max_height,
threads != RARCH_SOFTFILTER_THREADS_AUTO ? threads :
rarch_get_cpu_cores(), cpu_features,
&userdata);
if (!filt->impl_data)
{
@ -301,7 +308,8 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt,
RARCH_LOG("Using %u threads for softfilter.\n", threads);
filt->packets = (struct softfilter_work_packet*)calloc(threads, sizeof(*filt->packets));
filt->packets = (struct softfilter_work_packet*)
calloc(threads, sizeof(*filt->packets));
if (!filt->packets)
{
RARCH_ERR("Failed to allocate softfilter packets.\n");
@ -309,7 +317,8 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt,
}
#ifdef HAVE_THREADS
filt->thread_data = (struct filter_thread_data*)calloc(threads, sizeof(*filt->thread_data));
filt->thread_data = (struct filter_thread_data*)
calloc(threads, sizeof(*filt->thread_data));
if (!filt->thread_data)
return false;
filt->threads = threads;
@ -326,7 +335,8 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt,
filt->thread_data[i].cond = scond_new();
if (!filt->thread_data[i].cond)
return false;
filt->thread_data[i].thread = sthread_create(filter_thread_loop, &filt->thread_data[i]);
filt->thread_data[i].thread = sthread_create(
filter_thread_loop, &filt->thread_data[i]);
if (!filt->thread_data[i].thread)
return false;
}
@ -336,7 +346,8 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt,
}
#ifdef HAVE_DYLIB
static bool append_softfilter_plugs(rarch_softfilter_t *filt, struct string_list *list)
static bool append_softfilter_plugs(rarch_softfilter_t *filt,
struct string_list *list)
{
unsigned i;
softfilter_simd_mask_t mask = rarch_get_cpu_features();
@ -347,7 +358,8 @@ static bool append_softfilter_plugs(rarch_softfilter_t *filt, struct string_list
if (!lib)
continue;
softfilter_get_implementation_t cb = (softfilter_get_implementation_t)dylib_proc(lib, "softfilter_get_implementation");
softfilter_get_implementation_t cb = (softfilter_get_implementation_t)
dylib_proc(lib, "softfilter_get_implementation");
if (!cb)
{
dylib_close(lib);
@ -367,14 +379,16 @@ static bool append_softfilter_plugs(rarch_softfilter_t *filt, struct string_list
continue;
}
struct rarch_soft_plug *new_plugs = (struct rarch_soft_plug*)realloc(filt->plugs, sizeof(*filt->plugs) * (filt->num_plugs + 1));
struct rarch_soft_plug *new_plugs = (struct rarch_soft_plug*)
realloc(filt->plugs, sizeof(*filt->plugs) * (filt->num_plugs + 1));
if (!new_plugs)
{
dylib_close(lib);
return false;
}
RARCH_LOG("[SoftFilter]: Found plug: %s (%s).\n", impl->ident, impl->short_ident);
RARCH_LOG("[SoftFilter]: Found plug: %s (%s).\n",
impl->ident, impl->short_ident);
filt->plugs = new_plugs;
filt->plugs[filt->num_plugs].lib = lib;
@ -415,7 +429,8 @@ static bool append_softfilter_plugs(rarch_softfilter_t *filt)
unsigned i;
softfilter_simd_mask_t mask = rarch_get_cpu_features();
filt->plugs = (struct rarch_soft_plug*)calloc(ARRAY_SIZE(soft_plugs_builtin), sizeof(*filt->plugs));
filt->plugs = (struct rarch_soft_plug*)
calloc(ARRAY_SIZE(soft_plugs_builtin), sizeof(*filt->plugs));
if (!filt->plugs)
return false;
filt->num_plugs = ARRAY_SIZE(soft_plugs_builtin);
@ -431,9 +446,6 @@ static bool append_softfilter_plugs(rarch_softfilter_t *filt)
}
#endif
rarch_softfilter_t *rarch_softfilter_new(const char *filter_config,
unsigned threads,
enum retro_pixel_format in_pixel_format,
@ -527,7 +539,8 @@ void rarch_softfilter_free(rarch_softfilter_t *filt)
void rarch_softfilter_get_max_output_size(rarch_softfilter_t *filt,
unsigned *width, unsigned *height)
{
rarch_softfilter_get_output_size(filt, width, height, filt->max_width, filt->max_height);
rarch_softfilter_get_output_size(filt, width, height,
filt->max_width, filt->max_height);
}
void rarch_softfilter_get_output_size(rarch_softfilter_t *filt,
@ -535,10 +548,12 @@ void rarch_softfilter_get_output_size(rarch_softfilter_t *filt,
unsigned width, unsigned height)
{
if (filt && filt->impl && filt->impl->query_output_size)
filt->impl->query_output_size(filt->impl_data, out_width, out_height, width, height);
filt->impl->query_output_size(filt->impl_data, out_width,
out_height, width, height);
}
enum retro_pixel_format rarch_softfilter_get_output_format(rarch_softfilter_t *filt)
enum retro_pixel_format rarch_softfilter_get_output_format(
rarch_softfilter_t *filt)
{
return filt->out_pix_fmt;
}
@ -554,10 +569,12 @@ void rarch_softfilter_process(rarch_softfilter_t *filt,
output, output_stride, input, width, height, input_stride);
#ifdef HAVE_THREADS
// Fire off workers
/* Fire off workers */
for (i = 0; i < filt->threads; i++)
{
//RARCH_LOG("Firing off filter thread %u ...\n", i);
#if 0
RARCH_LOG("Firing off filter thread %u ...\n", i);
#endif
filt->thread_data[i].packet = &filt->packets[i];
slock_lock(filt->thread_data[i].lock);
filt->thread_data[i].done = false;
@ -565,10 +582,12 @@ void rarch_softfilter_process(rarch_softfilter_t *filt,
slock_unlock(filt->thread_data[i].lock);
}
// Wait for workers
/* Wait for workers */
for (i = 0; i < filt->threads; i++)
{
//RARCH_LOG("Waiting for filter thread %u ...\n", i);
#if 0
RARCH_LOG("Waiting for filter thread %u ...\n", i);
#endif
slock_lock(filt->thread_data[i].lock);
while (!filt->thread_data[i].done)
scond_wait(filt->thread_data[i].cond, filt->thread_data[i].lock);

View File

@ -38,7 +38,8 @@ void rarch_softfilter_get_output_size(rarch_softfilter_t *filt,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height);
enum retro_pixel_format rarch_softfilter_get_output_format(rarch_softfilter_t *filt);
enum retro_pixel_format rarch_softfilter_get_output_format(
rarch_softfilter_t *filt);
void rarch_softfilter_process(rarch_softfilter_t *filt,
void *output, size_t output_stride,

View File

@ -33,8 +33,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Compile: gcc -o twoxbr.so -shared twoxbr.c -std=c99 -O3 -Wall -pedantic -fPIC
#include "softfilter.h"
#include <stdlib.h>
#include <string.h>
@ -233,7 +231,8 @@ static void *twoxbr_generic_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -247,7 +246,8 @@ static void *twoxbr_generic_create(const struct softfilter_config *config,
return filt;
}
static void twoxbr_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void twoxbr_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = width * TWOXBR_SCALE;
@ -261,12 +261,6 @@ static void twoxbr_generic_destroy(void *data)
free(filt);
}
//---------------------------------------------------------------------------------------------------------------------------
#define ALPHA_BLEND_128_W(dst, src) dst = ((src & pg_lbmask) >> 1) + ((dst & pg_lbmask) >> 1)
#define ALPHA_BLEND_32_W(dst, src) \
@ -418,7 +412,8 @@ static void twoxbr_generic_destroy(void *data)
float df8(uint32_t A, uint32_t B, uint32_t pg_red_mask, uint32_t pg_green_mask, uint32_t pg_blue_mask)
float df8(uint32_t A, uint32_t B,
uint32_t pg_red_mask, uint32_t pg_green_mask, uint32_t pg_blue_mask)
{
uint32_t r, g, b;
uint32_t y, u, v;
@ -440,7 +435,8 @@ float df8(uint32_t A, uint32_t B, uint32_t pg_red_mask, uint32_t pg_green_mask,
return 48*y + 7*u + 6*v;
}
int eq8(uint32_t A, uint32_t B, uint32_t pg_red_mask, uint32_t pg_green_mask, uint32_t pg_blue_mask)
int eq8(uint32_t A, uint32_t B,
uint32_t pg_red_mask, uint32_t pg_green_mask, uint32_t pg_blue_mask)
{
uint32_t r, g, b;
uint32_t y, u, v;
@ -600,12 +596,13 @@ static void twoxbr_generic_xrgb8888(void *data, unsigned width, unsigned height,
{
twoxbr_declare_variables(uint32_t, in, nextline);
//---------------------------------------
// Map of the pixels: A1 B1 C1
// A0 PA PB PC C4
// D0 PD PE PF F4
// G0 PG PH PI I4
// G5 H5 I5
/*
* Map of the pixels: A1 B1 C1
* A0 PA PB PC C4
* D0 PD PE PF F4
* G0 PG PH PI I4
* G5 H5 I5
*/
twoxbr_function(FILTRO_RGB8888, filt);
}
@ -639,12 +636,13 @@ static void twoxbr_generic_rgb565(void *data, unsigned width, unsigned height,
{
twoxbr_declare_variables(uint16_t, in, nextline);
//---------------------------------------
// Map of the pixels: A1 B1 C1
// A0 PA PB PC C4
// D0 PD PE PF F4
// G0 PG PH PI I4
// G5 H5 I5
/*
* Map of the pixels: A1 B1 C1
* A0 PA PB PC C4
* D0 PD PE PF F4
* G0 PG PH PI I4
* G5 H5 I5
*/
twoxbr_function(FILTRO_RGB565, filt);
}
@ -656,56 +654,68 @@ static void twoxbr_generic_rgb565(void *data, unsigned width, unsigned height,
static void twoxbr_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
twoxbr_generic_rgb565(data, width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565, output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void twoxbr_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint32_t *input = (uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
twoxbr_generic_xrgb8888(data, width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output,
thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
}
static void twoxbr_generic_packets(void *data,
struct softfilter_work_packet *packets,
void *output, size_t output_stride,
const void *input, unsigned width, unsigned height, size_t input_stride)
const void *input, unsigned width,
unsigned height, size_t input_stride)
{
struct filter_data *filt = (struct filter_data*)data;
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
thr->out_data = (uint8_t*)output + y_start * TWOXBR_SCALE * output_stride;
thr->out_data = (uint8_t*)output + y_start *
TWOXBR_SCALE * output_stride;
thr->in_data = (const uint8_t*)input + y_start * input_stride;
thr->out_pitch = output_stride;
thr->in_pitch = input_stride;
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can access
* pixels outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
if (filt->in_fmt == SOFTFILTER_FMT_RGB565)
packets[i].work = twoxbr_work_cb_rgb565;
//else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
//packets[i].work = twoxbr_work_cb_rgb4444;
#if 0
else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
packets[i].work = twoxbr_work_cb_rgb4444;
#endif
else if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888)
packets[i].work = twoxbr_work_cb_xrgb8888;
packets[i].thread_data = thr;
@ -727,7 +737,8 @@ static const struct softfilter_implementation twoxbr_generic = {
"2xbr",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &twoxbr_generic;

View File

@ -14,8 +14,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Compile: gcc -o twoxsai.so -shared twoxsai.c -std=c99 -O3 -Wall -pedantic -fPIC
#include "softfilter.h"
#include <stdlib.h>
#include <string.h>
@ -76,7 +74,8 @@ static void *twoxsai_generic_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -87,7 +86,8 @@ static void *twoxsai_generic_create(const struct softfilter_config *config,
return filt;
}
static void twoxsai_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void twoxsai_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = width * TWOXSAI_SCALE;
@ -130,8 +130,7 @@ static void twoxsai_generic_destroy(void *data)
typename_t colorL = *(in + nextline + 2); \
typename_t colorM = *(in + nextline + nextline - 1); \
typename_t colorN = *(in + nextline + nextline + 0); \
typename_t colorO = *(in + nextline + nextline + 1); \
//typename_t colorP = *(in + nextline + nextline + 2);
typename_t colorO = *(in + nextline + nextline + 1);
#ifndef twoxsai_function
#define twoxsai_function(result_cb, interpolate_cb, interpolate2_cb) \
@ -237,13 +236,15 @@ static void twoxsai_generic_xrgb8888(unsigned width, unsigned height,
{
twoxsai_declare_variables(uint32_t, in, nextline);
//---------------------------------------
// Map of the pixels: I|E F|J
// G|A B|K
// H|C D|L
// M|N O|P
/*
* Map of the pixels: I|E F|J
* G|A B|K
* H|C D|L
* M|N O|P
*/
twoxsai_function(twoxsai_result, twoxsai_interpolate_xrgb8888, twoxsai_interpolate2_xrgb8888);
twoxsai_function(twoxsai_result, twoxsai_interpolate_xrgb8888,
twoxsai_interpolate2_xrgb8888);
}
src += src_stride;
@ -267,13 +268,15 @@ static void twoxsai_generic_rgb565(unsigned width, unsigned height,
{
twoxsai_declare_variables(uint16_t, in, nextline);
//---------------------------------------
// Map of the pixels: I|E F|J
// G|A B|K
// H|C D|L
// M|N O|P
/*
* Map of the pixels: I|E F|J
* G|A B|K
* H|C D|L
* M|N O|P
*/
twoxsai_function(twoxsai_result, twoxsai_interpolate_rgb565, twoxsai_interpolate2_rgb565);
twoxsai_function(twoxsai_result, twoxsai_interpolate_rgb565,
twoxsai_interpolate2_rgb565);
}
src += src_stride;
@ -283,56 +286,71 @@ static void twoxsai_generic_rgb565(unsigned width, unsigned height,
static void twoxsai_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
twoxsai_generic_rgb565(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void twoxsai_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint32_t *input = (uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
twoxsai_generic_xrgb8888(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_XRGB8888,
output,
thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
}
static void twoxsai_generic_packets(void *data,
struct softfilter_work_packet *packets,
void *output, size_t output_stride,
const void *input, unsigned width, unsigned height, size_t input_stride)
const void *input, unsigned width,
unsigned height, size_t input_stride)
{
struct filter_data *filt = (struct filter_data*)data;
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
thr->out_data = (uint8_t*)output + y_start * TWOXSAI_SCALE * output_stride;
thr->out_data = (uint8_t*)output + y_start *
TWOXSAI_SCALE * output_stride;
thr->in_data = (const uint8_t*)input + y_start * input_stride;
thr->out_pitch = output_stride;
thr->in_pitch = input_stride;
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can access pixels
* outside their given buffer.
*/
thr->first = y_start;
thr->last = y_end == height;
if (filt->in_fmt == SOFTFILTER_FMT_RGB565)
packets[i].work = twoxsai_work_cb_rgb565;
//else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
//packets[i].work = twoxsai_work_cb_rgb4444;
#if 0
else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
packets[i].work = twoxsai_work_cb_rgb4444;
#endif
else if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888)
packets[i].work = twoxsai_work_cb_xrgb8888;
packets[i].thread_data = thr;
@ -354,7 +372,8 @@ static const struct softfilter_implementation twoxsai_generic = {
"2xsai",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &twoxsai_generic;

View File

@ -126,7 +126,8 @@ static void *blargg_ntsc_snes_generic_create(const struct softfilter_config *con
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -141,7 +142,8 @@ static void *blargg_ntsc_snes_generic_create(const struct softfilter_config *con
}
static void blargg_ntsc_snes_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void blargg_ntsc_snes_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = SNES_NTSC_OUT_WIDTH(width);
@ -165,9 +167,11 @@ static void blargg_ntsc_snes_render_rgb565(void *data, int width, int height,
{
struct filter_data *filt = (struct filter_data*)data;
if(width <= 256)
snes_ntsc_blit(filt->ntsc, input, pitch, filt->burst, width, height, output, outpitch * 2, first, last);
snes_ntsc_blit(filt->ntsc, input, pitch, filt->burst,
width, height, output, outpitch * 2, first, last);
else
snes_ntsc_blit_hires(filt->ntsc, input, pitch, filt->burst, width, height, output, outpitch * 2, first, last);
snes_ntsc_blit_hires(filt->ntsc, input, pitch, filt->burst,
width, height, output, outpitch * 2, first, last);
filt->burst ^= filt->burst_toggle;
}
@ -185,14 +189,18 @@ static void blargg_ntsc_snes_rgb565(void *data, unsigned width, unsigned height,
static void blargg_ntsc_snes_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
blargg_ntsc_snes_rgb565(data, width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void blargg_ntsc_snes_generic_packets(void *data,
@ -204,7 +212,8 @@ static void blargg_ntsc_snes_generic_packets(void *data,
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
@ -215,7 +224,8 @@ static void blargg_ntsc_snes_generic_packets(void *data,
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can
* access pixels outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
@ -240,7 +250,8 @@ static const struct softfilter_implementation blargg_ntsc_snes_generic = {
"blargg_ntsc_snes",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &blargg_ntsc_snes_generic;

View File

@ -14,9 +14,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Compile: gcc -o darken.so -shared darken.c -std=c99 -O3 -Wall -pedantic -fPIC
// Useless filter, just nice as a reference for other filters.
/* Useless filter, just nice as a reference for other filters. */
#include "softfilter.h"
#include <stdlib.h>
@ -75,7 +73,8 @@ static void *darken_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -102,28 +101,32 @@ static void darken_destroy(void *data)
static void darken_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
const uint32_t *input = (const uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
unsigned x, y;
for (y = 0; y < height; y++, input += thr->in_pitch >> 2, output += thr->out_pitch >> 2)
for (y = 0; y < height;
y++, input += thr->in_pitch >> 2, output += thr->out_pitch >> 2)
for (x = 0; x < width; x++)
output[x] = (input[x] >> 2) & (0x3f * 0x01010101);
}
static void darken_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
const uint16_t *input = (const uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
unsigned x, y;
for (y = 0; y < height; y++, input += thr->in_pitch >> 1, output += thr->out_pitch >> 1)
for (y = 0; y < height;
y++, input += thr->in_pitch >> 1, output += thr->out_pitch >> 1)
for (x = 0; x < width; x++)
output[x] = (input[x] >> 2) & ((0x7 << 0) | (0xf << 5) | (0x7 << 11));
}
@ -137,7 +140,8 @@ static void darken_packets(void *data,
struct filter_data *filt = (struct filter_data*)data;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
thr->out_data = (uint8_t*)output + y_start * output_stride;
@ -170,7 +174,8 @@ static const struct softfilter_implementation darken = {
"darken",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &darken;

View File

@ -14,8 +14,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Compile: gcc -o epx.so -shared epx.c -std=c99 -O3 -Wall -pedantic -fPIC
#include "softfilter.h"
#include <stdlib.h>
@ -75,7 +73,8 @@ static void *epx_generic_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -86,7 +85,8 @@ static void *epx_generic_create(const struct softfilter_config *config,
return filt;
}
static void epx_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void epx_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = width * EPX_SCALE;
@ -113,11 +113,12 @@ static void EPX_16 (int width, int height,
height -= 2;
// D
// A X C
// B
/* D
* A X C
* B
*/
// top edge
/* top edge */
sP = (uint16_t *)(src - prevline);
lP = (uint16_t *) (src + src_stride);
@ -159,10 +160,12 @@ static void EPX_16 (int width, int height,
{
#ifdef MSB_FIRST
*dP1 = (colorX << 16) + colorX;
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + ((colorB == colorC) ? colorB : colorX);
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) +
((colorB == colorC) ? colorB : colorX);
#else
*dP1 = colorX + (colorX << 16);
*dP2 = ((colorA == colorB) ? colorA : colorX) + (((colorB == colorC) ? colorB : colorX) << 16);
*dP2 = ((colorA == colorB) ? colorA : colorX) +
(((colorB == colorC) ? colorB : colorX) << 16);
#endif
}
else
@ -172,7 +175,7 @@ static void EPX_16 (int width, int height,
dP2++;
}
// right edge
/* right edge */
colorA = colorX;
colorX = colorC;
@ -194,8 +197,6 @@ static void EPX_16 (int width, int height,
src += src_stride;
dst += dst_stride << 1;
//
for (; height; height--)
{
sP = (uint16_t *) src;
@ -204,7 +205,7 @@ static void EPX_16 (int width, int height,
dP1 = (uint32_t *) dst;
dP2 = (uint32_t *) (dst + dst_stride);
// left edge
/* left edge */
colorX = *sP;
colorC = *++sP;
@ -227,8 +228,6 @@ static void EPX_16 (int width, int height,
dP1++;
dP2++;
//
for (w = width - 2; w; w--)
{
colorA = colorX;
@ -240,11 +239,15 @@ static void EPX_16 (int width, int height,
if ((colorA != colorC) && (colorB != colorD))
{
#ifdef MSB_FIRST
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + ((colorC == colorD) ? colorC : colorX);
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + ((colorB == colorC) ? colorB : colorX);
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) +
((colorC == colorD) ? colorC : colorX);
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) +
((colorB == colorC) ? colorB : colorX);
#else
*dP1 = ((colorD == colorA) ? colorD : colorX) + (((colorC == colorD) ? colorC : colorX) << 16);
*dP2 = ((colorA == colorB) ? colorA : colorX) + (((colorB == colorC) ? colorB : colorX) << 16);
*dP1 = ((colorD == colorA) ? colorD : colorX) +
(((colorC == colorD) ? colorC : colorX) << 16);
*dP2 = ((colorA == colorB) ? colorA : colorX) +
(((colorB == colorC) ? colorB : colorX) << 16);
#endif
}
else
@ -254,7 +257,7 @@ static void EPX_16 (int width, int height,
dP2++;
}
// right edge
/* right edge */
colorA = colorX;
colorX = colorC;
@ -278,14 +281,14 @@ static void EPX_16 (int width, int height,
dst += dst_stride << 1;
}
// bottom edge
/* bottom edge */
sP = (uint16_t *) src;
uP = (uint16_t *) (src - src_stride);
dP1 = (uint32_t *) dst;
dP2 = (uint32_t *) (dst + dst_stride);
// left edge
/* left edge */
colorX = *sP;
colorC = *++sP;
@ -307,8 +310,6 @@ static void EPX_16 (int width, int height,
dP1++;
dP2++;
//
for (w = width - 2; w; w--)
{
colorA = colorX;
@ -319,10 +320,12 @@ static void EPX_16 (int width, int height,
if ((colorA != colorC) && (colorX != colorD))
{
#ifdef MSB_FIRST
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + ((colorC == colorD) ? colorC : colorX);
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) +
((colorC == colorD) ? colorC : colorX);
*dP2 = (colorX << 16) + colorX;
#else
*dP1 = ((colorD == colorA) ? colorD : colorX) + (((colorC == colorD) ? colorC : colorX) << 16);
*dP1 = ((colorD == colorA) ? colorD : colorX) +
(((colorC == colorD) ? colorC : colorX) << 16);
*dP2 = colorX + (colorX << 16);
#endif
}
@ -333,7 +336,7 @@ static void EPX_16 (int width, int height,
dP2++;
}
// right edge
/* right edge */
colorA = colorX;
colorX = colorC;
@ -366,14 +369,18 @@ static void epx_generic_rgb565(unsigned width, unsigned height,
static void epx_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
epx_generic_rgb565(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
@ -386,7 +393,8 @@ static void epx_generic_packets(void *data,
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
@ -397,7 +405,8 @@ static void epx_generic_packets(void *data,
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can
* access pixels outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
@ -422,7 +431,8 @@ static const struct softfilter_implementation epx_generic = {
"epx",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &epx_generic;

View File

@ -14,8 +14,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Compile: gcc -o lq2x.so -shared lq2x.c -std=c99 -O3 -Wall -pedantic -fPIC
#include "softfilter.h"
#include <stdlib.h>
@ -75,7 +73,8 @@ static void *lq2x_generic_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -86,7 +85,8 @@ static void *lq2x_generic_create(const struct softfilter_config *config,
return filt;
}
static void lq2x_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void lq2x_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = width * LQ2X_SCALE;
@ -194,19 +194,24 @@ static void lq2x_generic_xrgb8888(unsigned width, unsigned height,
static void lq2x_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
lq2x_generic_rgb565(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void lq2x_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint32_t *input = (uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
@ -215,19 +220,24 @@ static void lq2x_work_cb_xrgb8888(void *data, void *thread_data)
(void)data;
lq2x_generic_xrgb8888(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_XRGB8888,
output,
thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
}
static void lq2x_generic_packets(void *data,
struct softfilter_work_packet *packets,
void *output, size_t output_stride,
const void *input, unsigned width, unsigned height, size_t input_stride)
const void *input, unsigned width,
unsigned height, size_t input_stride)
{
struct filter_data *filt = (struct filter_data*)data;
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
@ -238,14 +248,17 @@ static void lq2x_generic_packets(void *data,
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can access pixels
* outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
if (filt->in_fmt == SOFTFILTER_FMT_RGB565)
packets[i].work = lq2x_work_cb_rgb565;
//else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
//packets[i].work = lq2x_work_cb_rgb4444;
#if 0
else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
packets[i].work = lq2x_work_cb_rgb4444;
#endif
else if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888)
packets[i].work = lq2x_work_cb_xrgb8888;
packets[i].thread_data = thr;
@ -267,7 +280,8 @@ static const struct softfilter_implementation lq2x_generic = {
"lq2x",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &lq2x_generic;

View File

@ -14,8 +14,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// Compile: gcc -o phosphor2x.so -shared phosphor2x.c -std=c99 -O3 -Wall -pedantic -fPIC
#include "softfilter.h"
#include "boolean.h"
#include <stdlib.h>
@ -106,96 +104,111 @@ static inline unsigned max_component_rgb565(uint32_t color)
return max;
}
static void blit_linear_line_xrgb8888(uint32_t * out, const uint32_t *in, unsigned width)
static void blit_linear_line_xrgb8888(uint32_t * out,
const uint32_t *in, unsigned width)
{
unsigned i;
// Splat pixels out on the line.
/* Splat pixels out on the line. */
for (i = 0; i < width; i++)
out[i << 1] = in[i];
// Blend in-between pixels.
/* Blend in-between pixels. */
for (i = 1; i < (width << 1) - 1; i += 2)
out[i] = blend_pixels_xrgb8888(out[i - 1], out[i + 1]);
// Blend edge pixels against black.
/* Blend edge pixels against black. */
out[0] = blend_pixels_xrgb8888(out[0], 0);
out[(width << 1) - 1] = blend_pixels_xrgb8888(out[(width << 1) - 1], 0);
out[(width << 1) - 1] =
blend_pixels_xrgb8888(out[(width << 1) - 1], 0);
}
static void blit_linear_line_rgb565(uint16_t * out, const uint16_t *in, unsigned width)
static void blit_linear_line_rgb565(uint16_t * out,
const uint16_t *in, unsigned width)
{
unsigned i;
// Splat pixels out on the line.
/* Splat pixels out on the line. */
for (i = 0; i < width; i++)
out[i << 1] = in[i];
// Blend in-between pixels.
/* Blend in-between pixels. */
for (i = 1; i < (width << 1) - 1; i += 2)
out[i] = blend_pixels_rgb565(out[i - 1], out[i + 1]);
out[i] =
blend_pixels_rgb565(out[i - 1], out[i + 1]);
// Blend edge pixels against black.
/* Blend edge pixels against black. */
out[0] = blend_pixels_rgb565(out[0], 0);
out[(width << 1) - 1] = blend_pixels_rgb565(out[(width << 1) - 1], 0);
out[(width << 1) - 1] =
blend_pixels_rgb565(out[(width << 1) - 1], 0);
}
static void bleed_phosphors_xrgb8888(void *data, uint32_t *scanline, unsigned width)
static void bleed_phosphors_xrgb8888(void *data,
uint32_t *scanline, unsigned width)
{
unsigned x;
struct filter_data *filt = (struct filter_data*)data;
// Red phosphor
/* Red phosphor */
for (x = 0; x < width; x += 2)
{
unsigned r = red_xrgb8888(scanline[x]);
unsigned r_set = clamp8(r * filt->phosphor_bleed * filt->phosphor_bloom_8888[r]);
unsigned r_set = clamp8(r * filt->phosphor_bleed *
filt->phosphor_bloom_8888[r]);
set_red_xrgb8888(scanline[x + 1], r_set);
}
// Green phosphor
/* Green phosphor */
for (x = 0; x < width; x++)
{
unsigned g = green_xrgb8888(scanline[x]);
unsigned g_set = clamp8((g >> 1) + 0.5 * g * filt->phosphor_bleed * filt->phosphor_bloom_8888[g]);
unsigned g_set = clamp8((g >> 1) + 0.5 * g *
filt->phosphor_bleed * filt->phosphor_bloom_8888[g]);
set_green_xrgb8888(scanline[x], g_set);
}
// Blue phosphor
/* Blue phosphor */
set_blue_xrgb8888(scanline[0], 0);
for (x = 1; x < width; x += 2)
{
unsigned b = blue_xrgb8888(scanline[x]);
unsigned b_set = clamp8(b * filt->phosphor_bleed * filt->phosphor_bloom_8888[b]);
unsigned b_set = clamp8(b * filt->phosphor_bleed *
filt->phosphor_bloom_8888[b]);
set_blue_xrgb8888(scanline[x + 1], b_set);
}
}
static void bleed_phosphors_rgb565(void *data, uint16_t *scanline, unsigned width)
static void bleed_phosphors_rgb565(void *data,
uint16_t *scanline, unsigned width)
{
unsigned x;
struct filter_data *filt = (struct filter_data*)data;
// Red phosphor
/* Red phosphor */
for (x = 0; x < width; x += 2)
{
unsigned r = red_rgb565(scanline[x]);
unsigned r_set = clamp6(r * filt->phosphor_bleed * filt->phosphor_bloom_565[r]);
unsigned r_set = clamp6(r * filt->phosphor_bleed *
filt->phosphor_bloom_565[r]);
set_red_rgb565(scanline[x + 1], r_set);
}
// Green phosphor
/* Green phosphor */
for (x = 0; x < width; x++)
{
unsigned g = green_rgb565(scanline[x]);
unsigned g_set = clamp6((g >> 1) + 0.5 * g * filt->phosphor_bleed * filt->phosphor_bloom_565[g]);
unsigned g_set = clamp6((g >> 1) + 0.5 * g *
filt->phosphor_bleed * filt->phosphor_bloom_565[g]);
set_green_rgb565(scanline[x], g_set);
}
// Blue phosphor
/* Blue phosphor */
set_blue_rgb565(scanline[0], 0);
for (x = 1; x < width; x += 2)
{
unsigned b = blue_rgb565(scanline[x]);
unsigned b_set = clamp6(b * filt->phosphor_bleed * filt->phosphor_bloom_565[b]);
unsigned b_set = clamp6(b * filt->phosphor_bleed *
filt->phosphor_bloom_565[b]);
set_blue_rgb565(scanline[x + 1], b_set);
}
}
@ -233,7 +246,8 @@ static void *phosphor2x_generic_create(const struct softfilter_config *config,
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -248,24 +262,36 @@ static void *phosphor2x_generic_create(const struct softfilter_config *config,
filt->scanrange_low = 0.5;
filt->scanrange_high = 0.65;
// Init lookup tables:
// phosphorBloom = (scaleTimes .* linspace(0, 1, 255) .^ (1/2.2)) + scaleAdd;
// Not exactly sure of order of operations here ...
#if 0
/* Initialize lookup tables: */
phosphorBloom = (scaleTimes .*
linspace(0, 1, 255) .^ (1/2.2)) + scaleAdd;
/* Not exactly sure of order of operations here ... */
#endif
for (i = 0; i < 256; i++)
{
filt->phosphor_bloom_8888[i] = filt->scale_times * powf((float)i / 255.0f, 1.0f/2.2f) + filt->scale_add;
filt->scan_range_8888[i] = filt->scanrange_low + i * (filt->scanrange_high - filt->scanrange_low) / 255.0f;
filt->phosphor_bloom_8888[i] =
filt->scale_times * powf((float)i / 255.0f, 1.0f/2.2f) +
filt->scale_add;
filt->scan_range_8888[i] =
filt->scanrange_low + i *
(filt->scanrange_high - filt->scanrange_low) / 255.0f;
}
for (i = 0; i < 64; i++)
{
filt->phosphor_bloom_565[i] = filt->scale_times * powf((float)i / 31.0f, 1.0f/2.2f) + filt->scale_add;
filt->scan_range_565[i] = filt->scanrange_low + i * (filt->scanrange_high - filt->scanrange_low) / 31.0f;
filt->phosphor_bloom_565[i] =
filt->scale_times * powf((float)i / 31.0f, 1.0f/2.2f)
+ filt->scale_add;
filt->scan_range_565[i] =
filt->scanrange_low + i *
(filt->scanrange_high - filt->scanrange_low) / 31.0f;
}
return filt;
}
static void phosphor2x_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void phosphor2x_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
(void)data;
@ -280,7 +306,8 @@ static void phosphor2x_generic_destroy(void *data)
free(filt);
}
static void phosphor2x_generic_xrgb8888(void *data, unsigned width, unsigned height,
static void phosphor2x_generic_xrgb8888(void *data,
unsigned width, unsigned height,
int first, int last, uint32_t *src,
unsigned src_stride, uint32_t *dst, unsigned dst_stride)
{
@ -296,28 +323,39 @@ static void phosphor2x_generic_xrgb8888(void *data, unsigned width, unsigned hei
{
uint32_t *out_line, *scan_out;
unsigned x;
const uint32_t *in_line = (const uint32_t*)(src + y * (src_stride)); // Input
const uint32_t *in_line = (const uint32_t*)(src + y * (src_stride));
out_line = (uint32_t*)(dst + y * (dst_stride) * 2); // Output in a scanlines fashion.
/* output in a scanlines fashion. */
out_line = (uint32_t*)(dst + y * (dst_stride) * 2);
blit_linear_line_xrgb8888(out_line, in_line, width); // Bilinear stretch horizontally.
bleed_phosphors_xrgb8888(filt, out_line, width << 1); // Mask 'n bleed phosphors.
/* Bilinear stretch horizontally. */
blit_linear_line_xrgb8888(out_line, in_line, width);
// Apply scanlines
/* Mask 'n bleed phosphors */
bleed_phosphors_xrgb8888(filt, out_line, width << 1);
/* Apply scanlines */
scan_out = (uint32_t*)out_line + (dst_stride);
for (x = 0; x < (width << 1); x++)
{
unsigned max = max_component_xrgb8888(out_line[x]);
set_red_xrgb8888(scan_out[x], (uint32_t)(filt->scan_range_8888[max] * red_xrgb8888(out_line[x])));
set_green_xrgb8888(scan_out[x], (uint32_t)(filt->scan_range_8888[max] * green_xrgb8888(out_line[x])));
set_blue_xrgb8888(scan_out[x], (uint32_t)(filt->scan_range_8888[max] * blue_xrgb8888(out_line[x])));
set_red_xrgb8888(scan_out[x],
(uint32_t)(filt->scan_range_8888[max] *
red_xrgb8888(out_line[x])));
set_green_xrgb8888(scan_out[x],
(uint32_t)(filt->scan_range_8888[max] *
green_xrgb8888(out_line[x])));
set_blue_xrgb8888(scan_out[x],
(uint32_t)(filt->scan_range_8888[max] *
blue_xrgb8888(out_line[x])));
}
}
}
static void phosphor2x_generic_rgb565(void *data, unsigned width, unsigned height,
static void phosphor2x_generic_rgb565(void *data,
unsigned width, unsigned height,
int first, int last, uint16_t *src,
unsigned src_stride, uint16_t *dst, unsigned dst_stride)
{
@ -333,48 +371,65 @@ static void phosphor2x_generic_rgb565(void *data, unsigned width, unsigned heigh
{
uint16_t *scan_out;
unsigned x;
uint16_t *out_line = (uint16_t*)(dst + y * (dst_stride) * 2); // Output in a scanlines fashion.
const uint16_t *in_line = (const uint16_t*)(src + y * (src_stride)); // Input
/* Output in a scanlines fashion. */
uint16_t *out_line = (uint16_t*)(dst + y * (dst_stride) * 2);
const uint16_t *in_line = (const uint16_t*)(src + y * (src_stride));
blit_linear_line_rgb565(out_line, in_line, width); // Bilinear stretch horizontally.
bleed_phosphors_rgb565(filt, out_line, width << 1); // Mask 'n bleed phosphors.
/* Bilinear stretch horizontally. */
blit_linear_line_rgb565(out_line, in_line, width);
// Apply scanlines.
/* Mask 'n bleed phosphors. */
bleed_phosphors_rgb565(filt, out_line, width << 1);
/* Apply scanlines. */
scan_out = (uint16_t*)(out_line + (dst_stride));
for (x = 0; x < (width << 1); x++)
{
unsigned max = max_component_rgb565(out_line[x]);
set_red_rgb565(scan_out[x], (uint16_t)(filt->scan_range_565[max] * red_rgb565(out_line[x])));
set_green_rgb565(scan_out[x], (uint16_t)(filt->scan_range_565[max] * green_rgb565(out_line[x])));
set_blue_rgb565(scan_out[x], (uint16_t)(filt->scan_range_565[max] * blue_rgb565(out_line[x])));
set_red_rgb565(scan_out[x],
(uint16_t)(filt->scan_range_565[max] *
red_rgb565(out_line[x])));
set_green_rgb565(scan_out[x],
(uint16_t)(filt->scan_range_565[max] *
green_rgb565(out_line[x])));
set_blue_rgb565(scan_out[x],
(uint16_t)(filt->scan_range_565[max] *
blue_rgb565(out_line[x])));
}
}
}
static void phosphor2x_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint32_t *input = (uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
phosphor2x_generic_xrgb8888(data, width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_XRGB8888,
output,
thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
}
static void phosphor2x_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
uint16_t *input = (uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
phosphor2x_generic_rgb565(data, width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void phosphor2x_generic_packets(void *data,
@ -386,7 +441,8 @@ static void phosphor2x_generic_packets(void *data,
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
@ -397,14 +453,17 @@ static void phosphor2x_generic_packets(void *data,
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can access pixels
* outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
if (filt->in_fmt == SOFTFILTER_FMT_RGB565)
packets[i].work = phosphor2x_work_cb_rgb565;
//else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
//packets[i].work = phosphor2x_work_cb_rgb4444;
#if 0
else if (filt->in_fmt == SOFTFILTER_FMT_RGB4444)
packets[i].work = phosphor2x_work_cb_rgb4444;
#endif
if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888)
packets[i].work = phosphor2x_work_cb_xrgb8888;
packets[i].thread_data = thr;
@ -426,7 +485,8 @@ static const struct softfilter_implementation phosphor2x_generic = {
"phosphor2x",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &phosphor2x_generic;

View File

@ -91,7 +91,8 @@ static void scale2x_generic_rgb565(unsigned width, unsigned height,
uint16_t *out0, *out1;
out0 = (uint16_t*)dst;
out1 = (uint16_t*)(dst + dst_stride);
SCALE2X_GENERIC(uint16_t, width, height, first, last, src, src_stride, dst, dst_stride, out0, out1);
SCALE2X_GENERIC(uint16_t, width, height, first, last,
src, src_stride, dst, dst_stride, out0, out1);
}
static void scale2x_generic_xrgb8888(unsigned width, unsigned height,
@ -103,7 +104,8 @@ static void scale2x_generic_xrgb8888(unsigned width, unsigned height,
uint32_t *out0, *out1;
out0 = (uint32_t*)dst;
out1 = (uint32_t*)(dst + dst_stride);
SCALE2X_GENERIC(uint32_t, width, height, first, last, src, src_stride, dst, dst_stride, out0, out1);
SCALE2X_GENERIC(uint32_t, width, height, first, last,
src, src_stride, dst, dst_stride, out0, out1);
}
static unsigned scale2x_generic_input_fmts(void)
@ -134,7 +136,8 @@ static void *scale2x_generic_create(const struct softfilter_config *config,
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
if (!filt)
return NULL;
filt->workers = (struct softfilter_thread_data*)calloc(threads, sizeof(struct softfilter_thread_data));
filt->workers = (struct softfilter_thread_data*)
calloc(threads, sizeof(struct softfilter_thread_data));
filt->threads = threads;
filt->in_fmt = in_fmt;
if (!filt->workers)
@ -145,7 +148,8 @@ static void *scale2x_generic_create(const struct softfilter_config *config,
return filt;
}
static void scale2x_generic_output(void *data, unsigned *out_width, unsigned *out_height,
static void scale2x_generic_output(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height)
{
*out_width = width * SCALE2X_SCALE;
@ -161,26 +165,34 @@ static void scale2x_generic_destroy(void *data)
static void scale2x_work_cb_xrgb8888(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
const uint32_t *input = (const uint32_t*)thr->in_data;
uint32_t *output = (uint32_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
scale2x_generic_xrgb8888(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_XRGB8888, output, thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_XRGB8888,
output,
thr->out_pitch / SOFTFILTER_BPP_XRGB8888);
}
static void scale2x_work_cb_rgb565(void *data, void *thread_data)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)thread_data;
const uint16_t *input = (const uint16_t*)thr->in_data;
uint16_t *output = (uint16_t*)thr->out_data;
unsigned width = thr->width;
unsigned height = thr->height;
scale2x_generic_rgb565(width, height,
thr->first, thr->last, input, thr->in_pitch / SOFTFILTER_BPP_RGB565, output, thr->out_pitch / SOFTFILTER_BPP_RGB565);
thr->first, thr->last, input,
thr->in_pitch / SOFTFILTER_BPP_RGB565,
output,
thr->out_pitch / SOFTFILTER_BPP_RGB565);
}
static void scale2x_generic_packets(void *data,
@ -192,18 +204,21 @@ static void scale2x_generic_packets(void *data,
unsigned i;
for (i = 0; i < filt->threads; i++)
{
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i];
struct softfilter_thread_data *thr =
(struct softfilter_thread_data*)&filt->workers[i];
unsigned y_start = (height * i) / filt->threads;
unsigned y_end = (height * (i + 1)) / filt->threads;
thr->out_data = (uint8_t*)output + y_start * SCALE2X_SCALE * output_stride;
thr->out_data = (uint8_t*)output + y_start *
SCALE2X_SCALE * output_stride;
thr->in_data = (const uint8_t*)input + y_start * input_stride;
thr->out_pitch = output_stride;
thr->in_pitch = input_stride;
thr->width = width;
thr->height = y_end - y_start;
// Workers need to know if they can access pixels outside their given buffer.
/* Workers need to know if they can access pixels
* outside their given buffer. */
thr->first = y_start;
thr->last = y_end == height;
@ -230,7 +245,8 @@ static const struct softfilter_implementation scale2x_generic = {
"scale2x",
};
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd)
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd)
{
(void)simd;
return &scale2x_generic;

View File

@ -39,16 +39,22 @@ extern "C" {
#define SOFTFILTER_SIMD_VFPU (1 << 13)
#define SOFTFILTER_SIMD_PS (1 << 14)
// A bit-mask of all supported SIMD instruction sets.
// Allows an implementation to pick different softfilter_implementation structs.
/* A bit-mask of all supported SIMD instruction sets.
* Allows an implementation to pick different
* softfilter_implementation structs. */
typedef unsigned softfilter_simd_mask_t;
// Returns true if config key was found. Otherwise, returns false, and sets value to default value.
typedef int (*softfilter_config_get_float_t)(void *userdata, const char *key, float *value, float default_value);
typedef int (*softfilter_config_get_int_t)(void *userdata, const char *key, int *value, int default_value);
/* Returns true if config key was found. Otherwise, returns false,
* and sets value to default value. */
typedef int (*softfilter_config_get_float_t)(void *userdata,
const char *key, float *value, float default_value);
// Allocates an array with values. free() with softfilter_config_free_t.
typedef int (*softfilter_config_get_float_array_t)(void *userdata, const char *key,
typedef int (*softfilter_config_get_int_t)(void *userdata,
const char *key, int *value, int default_value);
/* Allocates an array with values. free() with softfilter_config_free_t. */
typedef int (*softfilter_config_get_float_array_t)(void *userdata,
const char *key,
float **values, unsigned *out_num_values,
const float *default_values, unsigned num_default_values);
@ -56,9 +62,11 @@ typedef int (*softfilter_config_get_int_array_t)(void *userdata, const char *key
int **values, unsigned *out_num_values,
const int *default_values, unsigned num_default_values);
typedef int (*softfilter_config_get_string_t)(void *userdata, const char *key, char **output, const char *default_output);
typedef int (*softfilter_config_get_string_t)(void *userdata,
const char *key, char **output, const char *default_output);
// Calls free() in host runtime. Sometimes needed on Windows. free() on NULL is fine.
/* Calls free() in host runtime.
* Sometimes needed on Windows. free() on NULL is fine. */
typedef void (*softfilter_config_free_t)(void *ptr);
struct softfilter_config
@ -70,36 +78,44 @@ struct softfilter_config
softfilter_config_get_int_array_t get_int_array;
softfilter_config_get_string_t get_string;
softfilter_config_free_t free; // Avoid problems where softfilter plug and host are linked against different C runtimes.
/* Avoid problems where softfilter plug and
* host are linked against different C runtimes. */
softfilter_config_free_t free;
};
// Dynamic library entrypoint.
typedef const struct softfilter_implementation *(*softfilter_get_implementation_t)(softfilter_simd_mask_t);
// The same SIMD mask argument is forwarded to create() callback as well to avoid having to keep lots of state around.
const struct softfilter_implementation *softfilter_get_implementation(softfilter_simd_mask_t simd);
/* Dynamic library entrypoint. */
typedef const struct softfilter_implementation
*(*softfilter_get_implementation_t)(softfilter_simd_mask_t);
/* The same SIMD mask argument is forwarded to create() callback
* as well to avoid having to keep lots of state around. */
const struct softfilter_implementation *softfilter_get_implementation(
softfilter_simd_mask_t simd);
#define SOFTFILTER_API_VERSION 2
// Required base color formats
/* Required base color formats */
#define SOFTFILTER_FMT_NONE 0
#define SOFTFILTER_FMT_RGB565 (1 << 0)
#define SOFTFILTER_FMT_XRGB8888 (1 << 1)
// Optional color formats
/* Optional color formats */
#define SOFTFILTER_FMT_RGB4444 (1 << 2)
#define SOFTFILTER_BPP_RGB565 2
#define SOFTFILTER_BPP_XRGB8888 4
// Softfilter implementation.
// Returns a bitmask of supported input formats.
/* Softfilter implementation.
* Returns a bitmask of supported input formats. */
typedef unsigned (*softfilter_query_input_formats_t)(void);
// Returns a bitmask of supported output formats for a given input format.
/* Returns a bitmask of supported output formats
* for a given input format. */
typedef unsigned (*softfilter_query_output_formats_t)(unsigned input_format);
// In softfilter_process_t, the softfilter implementation submits work units to a worker thread pool.
/* In softfilter_process_t, the softfilter implementation
* submits work units to a worker thread pool. */
typedef void (*softfilter_work_t)(void *data, void *thread_data);
struct softfilter_work_packet
{
@ -107,31 +123,41 @@ struct softfilter_work_packet
void *thread_data;
};
// Create a filter with given input and output formats as well as maximum possible input size.
// Input sizes can very per call to softfilter_process_t, but they will never be larger than the maximum.
typedef void *(*softfilter_create_t)(const struct softfilter_config *config, unsigned in_fmt, unsigned out_fmt,
/* Create a filter with given input and output formats as well as
* maximum possible input size.
*
* Input sizes can very per call to softfilter_process_t, but they
* will never be larger than the maximum. */
typedef void *(*softfilter_create_t)(const struct softfilter_config *config,
unsigned in_fmt, unsigned out_fmt,
unsigned max_width, unsigned max_height,
unsigned threads, softfilter_simd_mask_t simd, void *userdata);
typedef void (*softfilter_destroy_t)(void *data);
// Given an input size, query the output size of the filter.
// If width and height == max_width/max_height, no other combination of width/height must return a larger size in any dimension.
/* Given an input size, query the output size of the filter.
* If width and height == max_width/max_height, no other combination
* of width/height must return a larger size in any dimension. */
typedef void (*softfilter_query_output_size_t)(void *data,
unsigned *out_width, unsigned *out_height,
unsigned width, unsigned height);
// First step of processing a frame. The filter submits work by filling in the packets array.
// The number of elements in the array is as returned by query_num_threads.
// The processing itself happens in worker threads after this returns.
/* First step of processing a frame. The filter submits work by
* filling in the packets array.
*
* The number of elements in the array is as returned by query_num_threads.
* The processing itself happens in worker threads after this returns.
*/
typedef void (*softfilter_get_work_packets_t)(void *data,
struct softfilter_work_packet *packets,
void *output, size_t output_stride,
const void *input, unsigned width, unsigned height, size_t input_stride);
// Returns the number of worker threads the filter will use.
// This can differ from the value passed to create() instead the filter cannot be parallelized, etc. The number of threads must be less-or-equal compared to the value passed to create().
/* Returns the number of worker threads the filter will use.
* This can differ from the value passed to create() instead the filter
* cannot be parallelized, etc. The number of threads must be less-or-equal
* compared to the value passed to create(). */
typedef unsigned (*softfilter_query_num_threads_t)(void *data);
/////
struct softfilter_implementation
{
@ -145,9 +171,13 @@ struct softfilter_implementation
softfilter_query_output_size_t query_output_size;
softfilter_get_work_packets_t get_work_packets;
unsigned api_version; // Must be SOFTFILTER_API_VERSION
const char *ident; // Human readable identifier of implementation.
const char *short_ident; // Computer-friendly short version of ident. Lower case, no spaces and special characters, etc.
/* Must be SOFTFILTER_API_VERSION. */
unsigned api_version;
/* Human readable identifier of implementation. */
const char *ident;
/* Computer-friendly short version of ident.
* Lower case, no spaces and special characters, etc. */
const char *short_ident;
};
#ifdef __cplusplus

View File

@ -38,16 +38,19 @@ static const struct font_atlas *font_renderer_get_atlas(void *data)
return &handle->atlas;
}
static const struct font_glyph *font_renderer_get_glyph(void *data, uint32_t code)
static const struct font_glyph *font_renderer_get_glyph(
void *data, uint32_t code)
{
bm_renderer_t *handle = (bm_renderer_t*)data;
return code < ATLAS_SIZE ? &handle->glyphs[code] : NULL;
}
static void char_to_texture(bm_renderer_t *handle, uint8_t letter, unsigned atlas_x, unsigned atlas_y)
static void char_to_texture(bm_renderer_t *handle, uint8_t letter,
unsigned atlas_x, unsigned atlas_y)
{
unsigned y, x, xo, yo;
uint8_t *target = handle->atlas.buffer + atlas_x + atlas_y * handle->atlas.width;
uint8_t *target = handle->atlas.buffer + atlas_x +
atlas_y * handle->atlas.width;
for (y = 0; y < FONT_HEIGHT; y++)
{

View File

@ -27,7 +27,8 @@ static const d3d_font_renderer_t *d3d_font_backends[] = {
#endif
};
const d3d_font_renderer_t *d3d_font_init_first(void *data, const char *font_path, unsigned font_size)
const d3d_font_renderer_t *d3d_font_init_first(void *data,
const char *font_path, unsigned font_size)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE(d3d_font_backends); i++)

View File

@ -28,7 +28,8 @@ typedef struct d3d_font_renderer
{
bool (*init)(void *data, const char *font_path, unsigned font_size);
void (*deinit)(void *data);
void (*render_msg)(void *data, const char *msg, const struct font_params *params);
void (*render_msg)(void *data, const char *msg,
const struct font_params *params);
const char *ident;
} d3d_font_renderer_t;

View File

@ -19,7 +19,8 @@
#include "../gfx_common.h"
#include "../../general.h"
static bool d3dfonts_w32_init_font(void *data, const char *font_path, unsigned font_size)
static bool d3dfonts_w32_init_font(void *data,
const char *font_path, unsigned font_size)
{
(void)font_path;
@ -49,7 +50,8 @@ static void d3dfonts_w32_deinit_font(void *data)
d3d->font = NULL;
}
static void d3dfonts_w32_render_msg(void *data, const char *msg, const struct font_params *params)
static void d3dfonts_w32_render_msg(void *data, const char *msg,
const struct font_params *params)
{
d3d_video_t *d3d = (d3d_video_t*)data;

View File

@ -30,7 +30,8 @@ static const font_renderer_driver_t *font_backends[] = {
NULL
};
bool font_renderer_create_default(const font_renderer_driver_t **driver, void **handle,
bool font_renderer_create_default(
const font_renderer_driver_t **driver, void **handle,
const char *font_path, unsigned font_size)
{
unsigned i;
@ -45,12 +46,14 @@ bool font_renderer_create_default(const font_renderer_driver_t **driver, void **
*handle = font_backends[i]->init(path, font_size);
if (*handle)
{
RARCH_LOG("Using font rendering backend: %s.\n", font_backends[i]->ident);
RARCH_LOG("Using font rendering backend: %s.\n",
font_backends[i]->ident);
*driver = font_backends[i];
return true;
}
else
RARCH_ERR("Failed to create rendering backend: %s.\n", font_backends[i]->ident);
RARCH_ERR("Failed to create rendering backend: %s.\n",
font_backends[i]->ident);
}
*driver = NULL;

View File

@ -20,32 +20,36 @@
#include <stdint.h>
#include "../../boolean.h"
// All coordinates and offsets are top-left oriented.
//
// This is a texture-atlas approach which allows text to be drawn in a single draw call.
// It is up to the code using this interface to actually generate proper vertex buffers and upload the atlas texture to GPU.
/* All coordinates and offsets are top-left oriented.
*
* This is a texture-atlas approach which allows text to
* be drawn in a single draw call.
*
* It is up to the code using this interface to actually
* generate proper vertex buffers and upload the atlas texture to GPU. */
struct font_glyph
{
unsigned width;
unsigned height;
// Texel coordiate offset for top-left pixel of this glyph.
/* Texel coordinate offset for top-left pixel of this glyph. */
unsigned atlas_offset_x;
unsigned atlas_offset_y;
// When drawing this glyph, apply an offset to current X/Y draw coordinate.
/* When drawing this glyph, apply an offset to
* current X/Y draw coordinate. */
int draw_offset_x;
int draw_offset_y;
// Advance X/Y draw coordinates after drawing this glyph.
/* Advance X/Y draw coordinates after drawing this glyph. */
int advance_x;
int advance_y;
};
struct font_atlas
{
uint8_t *buffer; // Alpha channel.
uint8_t *buffer; /* Alpha channel. */
unsigned width;
unsigned height;
};
@ -53,19 +57,25 @@ struct font_atlas
typedef struct font_renderer_driver
{
void *(*init)(const char *font_path, float font_size);
const struct font_atlas *(*get_atlas)(void *data);
const struct font_glyph *(*get_glyph)(void *data, uint32_t code); // Returns NULL if no glyph for this code is found.
/* Returns NULL if no glyph for this code is found. */
const struct font_glyph *(*get_glyph)(void *data, uint32_t code);
void (*free)(void *data);
const char *(*get_default_font)(void);
const char *ident;
} font_renderer_driver_t;
extern const font_renderer_driver_t ft_font_renderer;
extern const font_renderer_driver_t bitmap_font_renderer;
// font_path can be NULL for default font.
bool font_renderer_create_default(const font_renderer_driver_t **driver, void **handle, const char *font_path, unsigned font_size);
/* font_path can be NULL for default font. */
bool font_renderer_create_default(const font_renderer_driver_t **driver,
void **handle, const char *font_path, unsigned font_size);
#endif

View File

@ -87,7 +87,7 @@ static bool ft_renderer_create_atlas(ft_renderer_t *handle)
FT_Render_Glyph(handle->face->glyph, FT_RENDER_MODE_NORMAL);
FT_GlyphSlot slot = handle->face->glyph;
// Some glyphs can be blank.
/* Some glyphs can be blank. */
buffer[i] = (uint8_t*)calloc(slot->bitmap.rows * slot->bitmap.pitch, 1);
glyph->width = slot->bitmap.width;
@ -100,7 +100,8 @@ static bool ft_renderer_create_atlas(ft_renderer_t *handle)
glyph->draw_offset_y = -slot->bitmap_top;
if (buffer[i])
memcpy(buffer[i], slot->bitmap.buffer, slot->bitmap.rows * pitches[i]);
memcpy(buffer[i], slot->bitmap.buffer,
slot->bitmap.rows * pitches[i]);
max_width = max(max_width, (unsigned)slot->bitmap.width);
max_height = max(max_height, (unsigned)slot->bitmap.rows);
}
@ -115,7 +116,7 @@ static bool ft_renderer_create_atlas(ft_renderer_t *handle)
goto end;
}
// Blit our texture atlas.
/* Blit our texture atlas. */
for (i = 0; i < ATLAS_SIZE; i++)
{
unsigned r, c;
@ -132,7 +133,8 @@ static bool ft_renderer_create_atlas(ft_renderer_t *handle)
if (buffer[i])
{
const uint8_t *src = buffer[i];
for (r = 0; r < handle->glyphs[i].height; r++, dst += handle->atlas.width, src += pitches[i])
for (r = 0; r < handle->glyphs[i].height;
r++, dst += handle->atlas.width, src += pitches[i])
for (c = 0; c < handle->glyphs[i].width; c++)
dst[c] = src[c];
}
@ -174,7 +176,8 @@ error:
return NULL;
}
// Not the cleanest way to do things for sure, but should hopefully work ... :)
/* Not the cleanest way to do things for sure,
* but should hopefully work ... */
static const char *font_paths[] = {
#if defined(_WIN32)
@ -190,10 +193,10 @@ static const char *font_paths[] = {
"/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf",
"/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf",
#endif
"osd-font.ttf", // Magic font to search for, useful for distribution.
"osd-font.ttf", /* Magic font to search for, useful for distribution. */
};
// Highly OS/platform dependent.
/* Highly OS/platform dependent. */
static const char *ft_renderer_get_default_font(void)
{
size_t i;

View File

@ -36,7 +36,8 @@ static void *gl_init_font(void *gl_data, const char *font_path, float font_size)
font->gl = (gl_t*)gl_data;
if (!font_renderer_create_default(&font->font_driver, &font->font_data, font_path, font_size))
if (!font_renderer_create_default(&font->font_driver,
&font->font_data, font_path, font_size))
{
RARCH_WARN("Couldn't init font renderer.\n");
free(font);
@ -54,9 +55,12 @@ static void *gl_init_font(void *gl_data, const char *font_path, float font_size)
unsigned width = next_pow2(atlas->width);
unsigned height = next_pow2(atlas->height);
// Ideally, we'd use single component textures, but the difference in ways to do that between core GL and GLES/legacy GL
// is too great to bother going down that route.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
/* Ideally, we'd use single component textures, but the
* difference in ways to do that between core GL and GLES/legacy GL
* is too great to bother going down that route. */
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
uint8_t *tmp_buffer = (uint8_t*)malloc(atlas->width * atlas->height * 4);
if (tmp_buffer)
@ -71,7 +75,8 @@ static void *gl_init_font(void *gl_data, const char *font_path, float font_size)
*dst++ = 0xff;
*dst++ = *src++;
}
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, atlas->width, atlas->height, GL_RGBA, GL_UNSIGNED_BYTE, tmp_buffer);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, atlas->width,
atlas->height, GL_RGBA, GL_UNSIGNED_BYTE, tmp_buffer);
free(tmp_buffer);
}
@ -106,7 +111,8 @@ static void gl_free_font(void *data)
font_color[ 4 * (6 * i + c) + 3] = color[3]; \
} while(0)
static void render_message(gl_raster_t *font, const char *msg, GLfloat scale, const GLfloat color[4], GLfloat pos_x, GLfloat pos_y)
static void render_message(gl_raster_t *font, const char *msg, GLfloat scale,
const GLfloat color[4], GLfloat pos_x, GLfloat pos_y)
{
unsigned i;
gl_t *gl = font->gl;
@ -133,15 +139,16 @@ static void render_message(gl_raster_t *font, const char *msg, GLfloat scale, co
while (msg_len_full)
{
// Rebind shaders so attrib cache gets reset.
/* Rebind shaders so attrib cache gets reset. */
if (gl->shader && gl->shader->use)
gl->shader->use(gl, GL_SHADER_STOCK_BLEND);
for (i = 0; i < msg_len; i++)
{
const struct font_glyph *gly = font->font_driver->get_glyph(font->font_data, (uint8_t)msg[i]);
const struct font_glyph *gly =
font->font_driver->get_glyph(font->font_data, (uint8_t)msg[i]);
if (!gly)
gly = font->font_driver->get_glyph(font->font_data, '?'); // Do something smarter here ...
gly = font->font_driver->get_glyph(font->font_data, '?'); /* Do something smarter here ... */
if (!gly)
continue;
@ -152,13 +159,13 @@ static void render_message(gl_raster_t *font, const char *msg, GLfloat scale, co
int width = gly->width;
int height = gly->height;
emit(0, 0, 1); // Bottom-left
emit(1, 1, 1); // Bottom-right
emit(2, 0, 0); // Top-left
emit(0, 0, 1); /* Bottom-left */
emit(1, 1, 1); /* Bottom-right */
emit(2, 0, 0); /* Top-left */
emit(3, 1, 0); // Top-right
emit(4, 0, 0); // Top-left
emit(5, 1, 1); // Bottom-right
emit(3, 1, 0); /* Top-right */
emit(4, 0, 0); /* Top-left */
emit(5, 1, 1); /* Bottom-right */
#undef emit
delta_x += gly->advance_x;
@ -177,7 +184,7 @@ static void render_message(gl_raster_t *font, const char *msg, GLfloat scale, co
msg_len = min(msg_len_full, MAX_MSG_LEN_CHUNK);
}
// Post - Go back to old rendering path.
/* Post - Go back to old rendering path. */
gl->coords.vertex = gl->vertex_ptr;
gl->coords.tex_coord = gl->tex_coords;
gl->coords.color = gl->white_color_ptr;
@ -185,7 +192,8 @@ static void render_message(gl_raster_t *font, const char *msg, GLfloat scale, co
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
}
static void gl_render_msg(void *data, const char *msg, const struct font_params *params)
static void gl_render_msg(void *data, const char *msg,
const struct font_params *params)
{
GLfloat x, y, scale, drop_mod;
GLfloat color[4], color_dark[4];
@ -213,7 +221,7 @@ static void gl_render_msg(void *data, const char *msg, const struct font_params
color[2] = FONT_COLOR_GET_BLUE(params->color) / 255.0f;
color[3] = FONT_COLOR_GET_ALPHA(params->color) / 255.0f;
// If alpha is 0.0f, turn it into default 1.0f
/* If alpha is 0.0f, turn it into default 1.0f */
if (color[3] <= 0.0f)
color[3] = 1.0f;
}
@ -234,7 +242,8 @@ static void gl_render_msg(void *data, const char *msg, const struct font_params
drop_mod = 0.3f;
}
gl_set_viewport(gl, gl->win_width, gl->win_height, full_screen, false);
gl_set_viewport(gl, gl->win_width, gl->win_height,
full_screen, false);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
@ -247,7 +256,8 @@ static void gl_render_msg(void *data, const char *msg, const struct font_params
color_dark[3] = color[3];
render_message(font, msg, scale, color_dark,
x + scale * drop_x / gl->vp.width, y + scale * drop_y / gl->vp.height);
x + scale * drop_x / gl->vp.width, y +
scale * drop_y / gl->vp.height);
}
render_message(font, msg, scale, color, x, y);

View File

@ -50,7 +50,7 @@ static void *gl_init_font(void *gl_data, const char *font_path, float font_size)
DbgFontInit(&cfg);
// Doesn't need any state.
/* Doesn't need any state. */
return (void*)-1;
}
@ -60,7 +60,8 @@ static void gl_deinit_font(void *data)
DbgFontExit();
}
static void gl_render_msg(void *data, const char *msg, const struct font_params *params)
static void gl_render_msg(void *data, const char *msg,
const struct font_params *params)
{
(void)data;
float x, y, scale;
@ -87,7 +88,8 @@ static void gl_render_msg(void *data, const char *msg, const struct font_params
DbgFontPrint(x, y, scale - 0.01f, WHITE, msg);
#ifdef SN_TARGET_PSP2
/* FIXME - if we ever get around to this port, move this out to some better place */
/* FIXME - if we ever get around to this port,
* move this out to some better place */
sceDbgFontFlush();
#endif
}

View File

@ -22,7 +22,8 @@
static XFONT *debug_font;
static D3DSurface *pFrontBuffer;
static bool xfonts_init_font(void *data, const char *font_path, unsigned font_size)
static bool xfonts_init_font(void *data,
const char *font_path, unsigned font_size)
{
(void)font_path;
(void)font_size;
@ -42,7 +43,8 @@ static void xfonts_deinit_font(void *data)
(void)data;
}
static void xfonts_render_msg(void *data, const char *msg, const struct font_params *params)
static void xfonts_render_msg(void *data, const char *msg,
const struct font_params *params)
{
d3d_video_t *d3d = (d3d_video_t*)data;
wchar_t str[PATH_MAX];

View File

@ -105,7 +105,8 @@ typedef struct {
static Font_Locals_t s_FontLocals;
static HRESULT xdk360_video_font_create_shaders (void *data, xdk360_video_font_t * font)
static HRESULT xdk360_video_font_create_shaders(
void *data, xdk360_video_font_t * font)
{
HRESULT hr;
d3d_video_t *d3d = (d3d_video_t*)data;
@ -177,7 +178,8 @@ static HRESULT xdk360_video_font_create_shaders (void *data, xdk360_video_font_t
return hr;
}
static bool xdk_init_font(void *data, const char *font_path, unsigned font_size)
static bool xdk_init_font(void *data,
const char *font_path, unsigned font_size)
{
(void)font_size;
@ -221,7 +223,7 @@ static bool xdk_init_font(void *data, const char *font_path, unsigned font_size)
// Read the glyph attributes from the file
font->m_dwNumGlyphs = ((const FontFileStrikesImage_t *)pData)->m_dwNumGlyphs;
font->m_Glyphs = ((const FontFileStrikesImage_t *)pData)->m_Glyphs; // Pointer
font->m_Glyphs = ((const FontFileStrikesImage_t *)pData)->m_Glyphs;
}
else
{
@ -229,7 +231,7 @@ static bool xdk_init_font(void *data, const char *font_path, unsigned font_size)
goto error;
}
// Create the vertex and pixel shaders for rendering the font
/* Create the vertex and pixel shaders for rendering the font */
if (FAILED(xdk360_video_font_create_shaders(d3d, font)))
{
RARCH_ERR( "Could not create font shaders.\n" );
@ -247,7 +249,7 @@ static void xdk_deinit_font(void *data)
{
xdk360_video_font_t *font = &m_Font;
// Destroy the font
/* Destroy the font */
font->m_pFontTexture = NULL;
font->m_dwNumGlyphs = 0L;
font->m_Glyphs = NULL;
@ -347,7 +349,8 @@ static void xdk_video_font_draw_text(xdk360_video_font_t *font, void *video_data
volatile float * pVertex;
unsigned long dwNumChars = wcslen(strText);
d3dr->BeginVertices(D3DPT_QUADLIST, 4 * dwNumChars, sizeof(XMFLOAT4), (void**)&pVertex);
d3dr->BeginVertices(D3DPT_QUADLIST, 4 * dwNumChars,
sizeof(XMFLOAT4), (void**)&pVertex);
// Draw four vertices for each glyph
while (*strText)
@ -435,7 +438,8 @@ static void xdk_video_font_draw_text(xdk360_video_font_t *font, void *video_data
d3dr->EndVertices();
}
static void xdk_render_msg(void *data, const char *str_msg, const struct font_params *params)
static void xdk_render_msg(void *data, const char *str_msg,
const struct font_params *params)
{
d3d_video_t *d3d = (d3d_video_t*)data;
xdk360_video_font_t *font = &m_Font;

View File

@ -18,7 +18,8 @@
#include "../general.h"
#include "../performance.h"
static inline float time_to_fps(retro_time_t last_time, retro_time_t new_time, int frames)
static inline float time_to_fps(retro_time_t last_time,
retro_time_t new_time, int frames)
{
return (1000000.0f * frames) / (new_time - last_time);
}
@ -35,9 +36,11 @@ bool gfx_get_fps(char *buf, size_t size, char *buf_fps, size_t size_fps)
retro_time_t new_time = rarch_get_time_usec();
if (g_extern.frame_count)
{
unsigned write_index = g_extern.measure_data.frame_time_samples_count++ &
unsigned write_index =
g_extern.measure_data.frame_time_samples_count++ &
(MEASURE_FRAME_TIME_SAMPLES_COUNT - 1);
g_extern.measure_data.frame_time_samples[write_index] = new_time - fps_time;
g_extern.measure_data.frame_time_samples[write_index] =
new_time - fps_time;
fps_time = new_time;
if ((g_extern.frame_count % FPS_UPDATE_INTERVAL) == 0)
@ -45,12 +48,14 @@ bool gfx_get_fps(char *buf, size_t size, char *buf_fps, size_t size_fps)
last_fps = time_to_fps(time, new_time, FPS_UPDATE_INTERVAL);
time = new_time;
snprintf(buf, size, "%s || FPS: %6.1f || Frames: %u", g_extern.title_buf, last_fps, g_extern.frame_count);
snprintf(buf, size, "%s || FPS: %6.1f || Frames: %u",
g_extern.title_buf, last_fps, g_extern.frame_count);
ret = true;
}
if (buf_fps)
snprintf(buf_fps, size_fps, "FPS: %6.1f || Frames: %u", last_fps, g_extern.frame_count);
snprintf(buf_fps, size_fps, "FPS: %6.1f || Frames: %u",
last_fps, g_extern.frame_count);
}
else
{
@ -67,8 +72,11 @@ bool gfx_get_fps(char *buf, size_t size, char *buf_fps, size_t size_fps)
#if defined(_WIN32) && !defined(_XBOX)
#include <windows.h>
#include "../dynamic.h"
// We only load this library once, so we let it be unloaded at application shutdown,
// since unloading it early seems to cause issues on some systems.
/* We only load this library once, so we let it be
* unloaded at application shutdown, since unloading
* it early seems to cause issues on some systems.
*/
static dylib_t dwmlib;
static bool dwm_composition_disabled;
@ -96,7 +104,8 @@ static void gfx_init_dwm(void)
}
atexit(gfx_dwm_shutdown);
HRESULT (WINAPI *mmcss)(BOOL) = (HRESULT (WINAPI*)(BOOL))dylib_proc(dwmlib, "DwmEnableMMCSS");
HRESULT (WINAPI *mmcss)(BOOL) =
(HRESULT (WINAPI*)(BOOL))dylib_proc(dwmlib, "DwmEnableMMCSS");
if (mmcss)
{
RARCH_LOG("Setting multimedia scheduling for DWM.\n");
@ -113,7 +122,8 @@ void gfx_set_dwm(void)
if (g_settings.video.disable_composition == dwm_composition_disabled)
return;
HRESULT (WINAPI *composition_enable)(UINT) = (HRESULT (WINAPI*)(UINT))dylib_proc(dwmlib, "DwmEnableComposition");
HRESULT (WINAPI *composition_enable)(UINT) =
(HRESULT (WINAPI*)(UINT))dylib_proc(dwmlib, "DwmEnableComposition");
if (!composition_enable)
{
RARCH_ERR("Did not find DwmEnableComposition ...\n");
@ -127,7 +137,8 @@ void gfx_set_dwm(void)
}
#endif
void gfx_scale_integer(struct rarch_viewport *vp, unsigned width, unsigned height, float aspect_ratio, bool keep_aspect)
void gfx_scale_integer(struct rarch_viewport *vp, unsigned width,
unsigned height, float aspect_ratio, bool keep_aspect)
{
int padding_x = 0;
int padding_y = 0;
@ -135,7 +146,8 @@ void gfx_scale_integer(struct rarch_viewport *vp, unsigned width, unsigned heigh
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
{
const struct rarch_viewport *custom =
(const struct rarch_viewport*)&g_extern.console.screen.viewports.custom_vp;
(const struct rarch_viewport*)
&g_extern.console.screen.viewports.custom_vp;
padding_x = width - custom->width;
padding_y = height - custom->height;
@ -144,27 +156,34 @@ void gfx_scale_integer(struct rarch_viewport *vp, unsigned width, unsigned heigh
}
else
{
// Use system reported sizes as these define the geometry for the "normal" case.
/* Use system reported sizes as these define the
* geometry for the "normal" case. */
unsigned base_height = g_extern.system.av_info.geometry.base_height;
if (base_height == 0)
base_height = 1;
// Account for non-square pixels.
// This is sort of contradictory with the goal of integer scale,
// but it is desirable in some cases.
// If square pixels are used, base_height will be equal to g_extern.system.av_info.base_height.
/* Account for non-square pixels.
* This is sort of contradictory with the goal of integer scale,
* but it is desirable in some cases.
*
* If square pixels are used, base_height will be equal to
* g_extern.system.av_info.base_height. */
unsigned base_width = (unsigned)roundf(base_height * aspect_ratio);
// Make sure that we don't get 0x scale ...
/* Make sure that we don't get 0x scale ... */
if (width >= base_width && height >= base_height)
{
if (keep_aspect) // X/Y scale must be same.
if (keep_aspect)
{
/* X/Y scale must be same. */
unsigned max_scale = min(width / base_width, height / base_height);
padding_x = width - base_width * max_scale;
padding_y = height - base_height * max_scale;
}
else // X/Y can be independent, each scaled as much as possible.
else
{
/* X/Y can be independent, each scaled as much as possible. */
padding_x = width % base_width;
padding_y = height % base_height;
}
@ -240,23 +259,27 @@ void gfx_set_square_pixel_viewport(unsigned width, unsigned height)
void gfx_set_core_viewport(void)
{
const struct retro_game_geometry *geom = &g_extern.system.av_info.geometry;
const struct retro_game_geometry *geom =
(const struct retro_game_geometry*)&g_extern.system.av_info.geometry;
if (geom->base_width <= 0.0f || geom->base_height <= 0.0f)
return;
// Fallback to 1:1 pixel ratio if none provided
/* Fallback to 1:1 pixel ratio if none provided */
if (geom->aspect_ratio > 0.0f)
aspectratio_lut[ASPECT_RATIO_CORE].value = geom->aspect_ratio;
else
aspectratio_lut[ASPECT_RATIO_CORE].value = (float)geom->base_width / geom->base_height;
aspectratio_lut[ASPECT_RATIO_CORE].value =
(float)geom->base_width / geom->base_height;
}
void gfx_set_config_viewport(void)
{
if (g_settings.video.aspect_ratio < 0.0f)
{
const struct retro_game_geometry *geom = &g_extern.system.av_info.geometry;
const struct retro_game_geometry *geom =
(const struct retro_game_geometry*)
&g_extern.system.av_info.geometry;
if (geom->aspect_ratio > 0.0f && g_settings.video.aspect_ratio_auto)
aspectratio_lut[ASPECT_RATIO_CONFIG].value = geom->aspect_ratio;
@ -265,15 +288,17 @@ void gfx_set_config_viewport(void)
unsigned base_width = geom->base_width;
unsigned base_height = geom->base_height;
// Get around division by zero errors
/* Get around division by zero errors */
if (base_width == 0)
base_width = 1;
if (base_height == 0)
base_height = 1;
aspectratio_lut[ASPECT_RATIO_CONFIG].value = (float)base_width / base_height; // 1:1 PAR.
aspectratio_lut[ASPECT_RATIO_CONFIG].value =
(float)base_width / base_height; /* 1:1 PAR. */
}
}
else
aspectratio_lut[ASPECT_RATIO_CONFIG].value = g_settings.video.aspect_ratio;
aspectratio_lut[ASPECT_RATIO_CONFIG].value =
g_settings.video.aspect_ratio;
}

View File

@ -30,15 +30,19 @@ extern "C" {
#include "../config.h"
#endif
// bufs gets a string suitable for Window title, buf_fps for raw FPS only.
// buf_fps is optional.
bool gfx_get_fps(char *buf, size_t size, char *buf_fps, size_t size_fps);
/* bufs gets a string suitable for Window title,
* buf_fps for raw FPS only.
* buf_fps is optional.
*/
bool gfx_get_fps(char *buf, size_t size,
char *buf_fps, size_t size_fps);
#ifdef _WIN32
void gfx_set_dwm(void);
#endif
void gfx_scale_integer(struct rarch_viewport *vp, unsigned win_width, unsigned win_height,
void gfx_scale_integer(struct rarch_viewport *vp,
unsigned win_width, unsigned win_height,
float aspect_ratio, bool keep_aspect);
enum aspect_ratio

View File

@ -59,7 +59,8 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = {
#if defined(__QNX__)
&gfx_ctx_bbqnx,
#endif
#if defined(IOS) || defined(OSX) //< Don't use __APPLE__ as it breaks basic SDL builds
#if defined(IOS) || defined(OSX)
/* < Don't use __APPLE__ as it breaks basic SDL builds */
&gfx_ctx_apple,
#endif
#if (defined(HAVE_SDL) || defined(HAVE_SDL2)) && defined(HAVE_OPENGL)
@ -83,7 +84,9 @@ const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident)
return NULL;
}
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor, bool hw_render_ctx)
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data,
enum gfx_ctx_api api, unsigned major,
unsigned minor, bool hw_render_ctx)
{
unsigned i;
for (i = 0; gfx_ctx_drivers[i]; i++)

View File

@ -40,71 +40,89 @@ enum gfx_ctx_api
typedef void (*gfx_ctx_proc_t)(void);
// The opaque void* argument should be the overlying driver data (e.g. gl_t for OpenGL contexts).
// This will allow us in the future to have separate contexts to separate gl_t structs (if needed).
// For now, this is only relevant for D3D.
/* The opaque void* argument should be the overlying driver data
* (e.g. gl_t for OpenGL contexts).
*
* This will allow us in the future to have separate contexts
* to separate gl_t structs (if needed).
*
* For now, this is only relevant for D3D. */
typedef struct gfx_ctx_driver
{
bool (*init)(void *data);
void (*destroy)(void *data);
bool (*bind_api)(void *data, enum gfx_ctx_api, unsigned major, unsigned minor); // Which API to bind to.
/* Which API to bind to. */
bool (*bind_api)(void *data, enum gfx_ctx_api,
unsigned major, unsigned minor);
// Sets the swap interval.
/* Sets the swap interval. */
void (*swap_interval)(void *data, unsigned);
// Sets video mode. Creates a window, etc.
/* Sets video mode. Creates a window, etc. */
bool (*set_video_mode)(void*, unsigned, unsigned, bool);
// Gets current window size.
// If not initialized yet, it returns current screen size.
/* Gets current window size.
* If not initialized yet, it returns current screen size. */
void (*get_video_size)(void*, unsigned*, unsigned*);
// Translates a window size to an aspect ratio.
// In most cases this will be just width / height, but
// some contexts will better know which actual aspect ratio is used.
// This can be NULL to assume the default behavior.
/* Translates a window size to an aspect ratio.
* In most cases this will be just width / height, but
* some contexts will better know which actual aspect ratio is used.
* This can be NULL to assume the default behavior.
*/
float (*translate_aspect)(void*, unsigned, unsigned);
// Asks driver to update window title (FPS, etc).
/* Asks driver to update window title (FPS, etc). */
void (*update_window_title)(void*);
// Queries for resize and quit events.
// Also processes events.
void (*check_window)(void*, bool*, bool*, unsigned*, unsigned*, unsigned);
/* Queries for resize and quit events.
* Also processes events. */
void (*check_window)(void*, bool*, bool*,
unsigned*, unsigned*, unsigned);
// Acknowledge a resize event. This is needed for some APIs. Most backends will ignore this.
/* Acknowledge a resize event. This is needed for some APIs.
* Most backends will ignore this. */
void (*set_resize)(void*, unsigned, unsigned);
// Checks if window has input focus.
/* Checks if window has input focus. */
bool (*has_focus)(void*);
// Swaps buffers. VBlank sync depends on earlier calls to swap_interval.
/* Swaps buffers. VBlank sync depends on
* earlier calls to swap_interval. */
void (*swap_buffers)(void*);
// Most video backends will want to use a certain input driver.
// Checks for it here.
/* Most video backends will want to use a certain input driver.
* Checks for it here. */
void (*input_driver)(void*, const input_driver_t**, void**);
// Wraps whatever gl_proc_address() there is.
// Does not take opaque, to avoid lots of ugly wrapper code.
/* Wraps whatever gl_proc_address() there is.
* Does not take opaque, to avoid lots of ugly wrapper code. */
gfx_ctx_proc_t (*get_proc_address)(const char*);
#ifdef HAVE_EGL
// Returns true if this context supports EGLImage buffers for screen drawing and was initalized correctly.
/* Returns true if this context supports EGLImage buffers for
* screen drawing and was initalized correctly. */
bool (*init_egl_image_buffer)(void*, const video_info_t*);
// Writes the frame to the EGLImage and sets image_handle to it. Returns true if a new image handle is created.
// Always returns true the first time it's called for a new index. The graphics core must handle a change in the handle correctly.
bool (*write_egl_image)(void*, const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle);
/* Writes the frame to the EGLImage and sets image_handle to it.
* Returns true if a new image handle is created.
* Always returns true the first time it's called for a new index.
* The graphics core must handle a change in the handle correctly. */
bool (*write_egl_image)(void*, const void *frame, unsigned width,
unsigned height, unsigned pitch, bool rgb32,
unsigned index, void **image_handle);
#endif
// Shows or hides mouse. Can be NULL if context doesn't have a concept of mouse pointer.
/* Shows or hides mouse. Can be NULL if context doesn't
* have a concept of mouse pointer. */
void (*show_mouse)(void*, bool state);
// Human readable string.
/* Human readable string. */
const char *ident;
// Optional. Binds HW-render offscreen context.
/* Optional. Binds HW-render offscreen context. */
void (*bind_hw_render)(void *data, bool enable);
} gfx_ctx_driver_t;
@ -125,8 +143,12 @@ extern const gfx_ctx_driver_t gfx_ctx_apple;
extern const gfx_ctx_driver_t gfx_ctx_emscripten;
extern const gfx_ctx_driver_t gfx_ctx_null;
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize.
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor, bool hw_render_ctx); // Finds first suitable driver and initializes.
/* Finds driver with ident. Does not initialize. */
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident);
/* Finds first suitable driver and initializes. */
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api,
unsigned major, unsigned minor, bool hw_render_ctx);
#ifdef __cplusplus
}

View File

@ -409,9 +409,6 @@ static void gl_compute_fbo_geometry(gl_t *gl, unsigned width, unsigned height,
case RARCH_SCALE_VIEWPORT:
gl->fbo_rect[i].img_width = gl->fbo_rect[i].max_img_width = gl->fbo_scale[i].scale_x * vp_width;
break;
default:
break;
}
switch (gl->fbo_scale[i].type_y)
@ -428,9 +425,6 @@ static void gl_compute_fbo_geometry(gl_t *gl, unsigned width, unsigned height,
case RARCH_SCALE_VIEWPORT:
gl->fbo_rect[i].img_height = gl->fbo_rect[i].max_img_height = gl->fbo_scale[i].scale_y * vp_height;
break;
default:
break;
}
if (gl->fbo_rect[i].img_width > (unsigned)max_size)
@ -2411,9 +2405,9 @@ static void gl_update_tex_filter_frame(gl_t *gl)
context_bind_hw_render(gl, true);
}
#if defined(HAVE_GLSL) || defined(HAVE_CG)
static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *path)
{
#if defined(HAVE_GLSL) || defined(HAVE_CG)
gl_t *gl = (gl_t*)data;
if (!gl)
@ -2507,8 +2501,10 @@ static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *p
gl_set_shader_viewport(gl, 1);
context_bind_hw_render(gl, true);
return true;
}
#else
return false;
#endif
}
static void gl_viewport_info(void *data, struct rarch_viewport *vp)
{
@ -2524,9 +2520,9 @@ static void gl_viewport_info(void *data, struct rarch_viewport *vp)
vp->y = top_dist;
}
#ifndef NO_GL_READ_PIXELS
static bool gl_read_viewport(void *data, uint8_t *buffer)
{
#ifndef NO_GL_READ_PIXELS
gl_t *gl = (gl_t*)data;
if (!gl)
return false;
@ -2623,8 +2619,10 @@ static bool gl_read_viewport(void *data, uint8_t *buffer)
RARCH_PERFORMANCE_STOP(read_viewport);
context_bind_hw_render(gl, true);
return true;
}
#else
return false;
#endif
}
#ifdef HAVE_OVERLAY
static void gl_free_overlay(gl_t *gl);
@ -2972,11 +2970,7 @@ const video_driver_t video_gl = {
gl_alive,
gl_focus,
#if defined(HAVE_GLSL) || defined(HAVE_CG)
gl_set_shader,
#else
NULL,
#endif
gl_free,
"gl",
@ -2985,11 +2979,7 @@ const video_driver_t video_gl = {
gl_viewport_info,
#ifndef NO_GL_READ_PIXELS
gl_read_viewport,
#else
NULL,
#endif
#ifdef HAVE_OVERLAY
gl_get_overlay_interface,

View File

@ -48,7 +48,7 @@ uint32_t g_orientation;
static struct
{
uint32_t *data; // needs to be resizable
uint32_t *data; /* needs to be resizable. */
unsigned width;
unsigned height;
GXTexObj obj;
@ -126,8 +126,10 @@ void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines)
viHeightMultiplier = 1;
viWidth = g_settings.video.viwidth;
#if defined(HW_RVL)
//if (CONF_GetAspectRatio() == CONF_ASPECT_16_9)
//viWidth = 704;
#if 0
if (CONF_GetAspectRatio() == CONF_ASPECT_16_9)
viWidth = 704;
#endif
progressive = CONF_GetProgressiveScan() > 0 && VIDEO_HaveComponentCable();
switch (CONF_GetVideo())
@ -208,7 +210,8 @@ void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines)
gx_mode.viWidth = viWidth;
gx_mode.viHeight = gx_mode.xfbHeight * viHeightMultiplier;
gx_mode.viXOrigin = (max_width - gx_mode.viWidth) / 2;
gx_mode.viYOrigin = (max_height - gx_mode.viHeight) / (2 * viHeightMultiplier);
gx_mode.viYOrigin =
(max_height - gx_mode.viHeight) / (2 * viHeightMultiplier);
gx_mode.xfbMode = modetype == VI_INTERLACE ? VI_XFBMODE_DF : VI_XFBMODE_SF;
gx_mode.field_rendering = GX_FALSE;
gx_mode.aa = GX_FALSE;
@ -259,17 +262,21 @@ void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines)
(void)xfbHeight;
GX_SetDispCopyDst(xfbWidth, xfbHeight);
GX_SetCopyFilter(gx_mode.aa, gx_mode.sample_pattern, (gx_mode.xfbMode == VI_XFBMODE_SF) ? GX_FALSE : GX_TRUE,
GX_SetCopyFilter(gx_mode.aa, gx_mode.sample_pattern,
(gx_mode.xfbMode == VI_XFBMODE_SF) ? GX_FALSE : GX_TRUE,
gx_mode.vfilter);
GXColor color = { 0, 0, 0, 0xff };
GX_SetCopyClear(color, GX_MAX_Z24);
GX_SetFieldMode(gx_mode.field_rendering, (gx_mode.viHeight == 2 * gx_mode.xfbHeight) ? GX_ENABLE : GX_DISABLE);
GX_SetFieldMode(gx_mode.field_rendering,
(gx_mode.viHeight == 2 * gx_mode.xfbHeight) ? GX_ENABLE : GX_DISABLE);
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GX_InvalidateTexAll();
GX_Flush();
_CPU_ISR_Restore(level);
RARCH_LOG("GX Resolution: %dx%d (%s)\n", gx_mode.fbWidth, gx_mode.efbHeight, (gx_mode.viTVMode & 3) == VI_INTERLACE ? "interlaced" : "progressive");
RARCH_LOG("GX Resolution: %dx%d (%s)\n", gx_mode.fbWidth,
gx_mode.efbHeight, (gx_mode.viTVMode & 3) == VI_INTERLACE
? "interlaced" : "progressive");
if (driver.menu)
{
@ -299,7 +306,7 @@ void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines)
driver_set_monitor_refresh_rate(59.94f);
}
// don't spam the queue when scrolling through resolutions
/* Don't spam the queue when scrolling through resolutions. */
msg_queue_clear(g_extern.msg_queue);
g_current_framebuf = 0;
@ -308,7 +315,9 @@ void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines)
const char *gx_get_video_mode(void)
{
static char format[16];
snprintf(format, sizeof(format), "%.3ux%.3u%c", gx_mode.fbWidth, gx_mode.efbHeight, (gx_mode.viTVMode & 3) == VI_INTERLACE ? 'i' : 'p');
snprintf(format, sizeof(format), "%.3ux%.3u%c",
gx_mode.fbWidth, gx_mode.efbHeight,
(gx_mode.viTVMode & 3) == VI_INTERLACE ? 'i' : 'p');
return format;
}
@ -317,7 +326,9 @@ static void gx_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
gx_video_t *gx = (gx_video_t*)driver.video_data;
if (aspect_ratio_idx == ASPECT_RATIO_SQUARE)
gfx_set_square_pixel_viewport(g_extern.system.av_info.geometry.base_width, g_extern.system.av_info.geometry.base_height);
gfx_set_square_pixel_viewport(
g_extern.system.av_info.geometry.base_width,
g_extern.system.av_info.geometry.base_height);
else if (aspect_ratio_idx == ASPECT_RATIO_CORE)
gfx_set_core_viewport();
else if (aspect_ratio_idx == ASPECT_RATIO_CONFIG)
@ -337,7 +348,8 @@ static void setup_video_mode(void *data)
unsigned i;
if (!g_framebuf[0])
for (i = 0; i < 2; i++)
g_framebuf[i] = MEM_K0_TO_K1(memalign(32, 640 * 576 * VI_DISPLAY_PIX_SZ));
g_framebuf[i] = MEM_K0_TO_K1(
memalign(32, 640 * 576 * VI_DISPLAY_PIX_SZ));
g_current_framebuf = 0;
g_draw_done = true;
@ -368,9 +380,13 @@ static void init_texture(void *data, unsigned width, unsigned height)
menu_h = driver.menu->height;
}
__GX_InitTexObj(fb_ptr, g_tex.data, width, height, (gx->rgb32) ? GX_TF_RGBA8 : gx->menu_texture_enable ? GX_TF_RGB5A3 : GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
__GX_InitTexObj(fb_ptr, g_tex.data, width, height,
(gx->rgb32) ? GX_TF_RGBA8 : gx->menu_texture_enable ?
GX_TF_RGB5A3 : GX_TF_RGB565,
GX_CLAMP, GX_CLAMP, GX_FALSE);
__GX_InitTexObjFilterMode(fb_ptr, g_filter, g_filter);
__GX_InitTexObj(menu_ptr, menu_tex.data, menu_w, menu_h, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE);
__GX_InitTexObj(menu_ptr, menu_tex.data, menu_w, menu_h,
GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE);
__GX_InitTexObjFilterMode(menu_ptr, g_filter, g_filter);
__GX_InvalidateTexAll(__gx);
}
@ -404,18 +420,23 @@ static void init_vtx(void *data, const video_info_t *video)
GX_SetNumTexGens(1);
GX_SetNumChans(1);
GX_SetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHTNULL, GX_DF_NONE, GX_AF_NONE);
GX_SetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG,
GX_SRC_VTX, GX_LIGHTNULL, GX_DF_NONE, GX_AF_NONE);
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GX_InvVtxCache();
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA,
GX_BL_INVSRCALPHA, GX_LO_CLEAR);
if (gx->scale != video->input_scale || gx->rgb32 != video->rgb32)
if (gx->scale != video->input_scale ||
gx->rgb32 != video->rgb32)
{
RARCH_LOG("[GX] reallocate texture\n");
free(g_tex.data);
g_tex.data = memalign(32, RARCH_SCALE_BASE * RARCH_SCALE_BASE * video->input_scale * video->input_scale * (video->rgb32 ? 4 : 2));
g_tex.data = memalign(32,
RARCH_SCALE_BASE * RARCH_SCALE_BASE * video->input_scale *
video->input_scale * (video->rgb32 ? 4 : 2));
g_tex.width = g_tex.height = RARCH_SCALE_BASE * video->input_scale;
if (!g_tex.data)
@ -425,7 +446,8 @@ static void init_vtx(void *data, const video_info_t *video)
}
}
DCFlushRange(g_tex.data, g_tex.width * g_tex.height * video->rgb32 ? 4 : 2);
DCFlushRange(g_tex.data, g_tex.width *
g_tex.height * video->rgb32 ? 4 : 2);
gx->rgb32 = video->rgb32;
gx->scale = video->input_scale;
@ -450,11 +472,13 @@ static void build_disp_list(void)
display_list_size = GX_EndDispList();
}
//#define TAKE_EFB_SCREENSHOT_ON_EXIT
#if 0
#define TAKE_EFB_SCREENSHOT_ON_EXIT
#endif
#ifdef TAKE_EFB_SCREENSHOT_ON_EXIT
// Adapted from code by Crayon for GRRLIB (http://code.google.com/p/grrlib)
/* Adapted from code by Crayon for GRRLIB (http://code.google.com/p/grrlib) */
static void gx_efb_screenshot(void)
{
int x, y;
@ -521,7 +545,8 @@ static void *gx_init(const video_info_t *video,
static void update_texture_asm(const uint32_t *src, const uint32_t *dst,
unsigned width, unsigned height, unsigned pitch)
{
register uint32_t tmp0, tmp1, tmp2, tmp3, line2, line2b, line3, line3b, line4, line4b, line5;
register uint32_t tmp0, tmp1, tmp2, tmp3, line2, line2b,
line3, line3b, line4, line4b, line5;
asm volatile (
" srwi %[width], %[width], 2 \n"
@ -631,8 +656,9 @@ static void convert_texture16(const uint32_t *_src, uint32_t *_dst,
unsigned tmp_pitch = pitch >> 2;
unsigned width2 = width >> 1;
// Texture data is 4x4 tiled @ 16bpp.
// Use 32-bit to transfer more data per cycle.
/* Texture data is 4x4 tiled @ 16bpp.
* Use 32-bit to transfer more data per cycle.
*/
const uint32_t *src = _src;
uint32_t *dst = _dst;
for (unsigned i = 0; i < height; i += 4, dst += 4 * width2)
@ -701,24 +727,27 @@ static void gx_resize(void *data)
#endif
GX_SetDispCopyGamma(g_extern.console.screen.gamma_correction);
if (gx->keep_aspect && gx_mode.efbHeight >= 480) // ingore this for custom resolutions
if (gx->keep_aspect && gx_mode.efbHeight >= 480) /* ignore this for custom resolutions */
{
float desired_aspect = g_extern.system.aspect_ratio;
if (desired_aspect == 0.0)
desired_aspect = 1.0;
#ifdef HW_RVL
float device_aspect = CONF_GetAspectRatio() == CONF_ASPECT_4_3 ? 4.0 / 3.0 : 16.0 / 9.0;
float device_aspect = CONF_GetAspectRatio() == CONF_ASPECT_4_3 ?
4.0 / 3.0 : 16.0 / 9.0;
#else
float device_aspect = 4.0 / 3.0;
#endif
if (g_orientation == ORIENTATION_VERTICAL || g_orientation == ORIENTATION_FLIPPED_ROTATED)
if (g_orientation == ORIENTATION_VERTICAL ||
g_orientation == ORIENTATION_FLIPPED_ROTATED)
desired_aspect = 1.0 / desired_aspect;
float delta;
#ifdef RARCH_CONSOLE
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
{
if (!g_extern.console.screen.viewports.custom_vp.width || !g_extern.console.screen.viewports.custom_vp.height)
if (!g_extern.console.screen.viewports.custom_vp.width ||
!g_extern.console.screen.viewports.custom_vp.height)
{
g_extern.console.screen.viewports.custom_vp.x = 0;
g_extern.console.screen.viewports.custom_vp.y = 0;
@ -736,8 +765,9 @@ static void gx_resize(void *data)
{
if (fabs(device_aspect - desired_aspect) < 0.0001)
{
// If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff),
// assume they are actually equal.
/* If the aspect ratios of screen and desired aspect ratio
* are sufficiently equal (floating point stuff),
* assume they are actually equal. */
}
else if (device_aspect > desired_aspect)
{
@ -896,7 +926,7 @@ static bool gx_frame(void *data, const void *frame,
return true;
if (!frame)
width = height = 4; // draw a black square in the background
width = height = 4; /* draw a black square in the background */
if(gx->should_resize)
{
@ -939,8 +969,10 @@ static bool gx_frame(void *data, const void *frame,
if (gx->menu_texture_enable && gx->menu_data)
{
convert_texture16(gx->menu_data, menu_tex.data, driver.menu->width, driver.menu->height, driver.menu->width * 2);
DCFlushRange(menu_tex.data, driver.menu->width * driver.menu->height * 2);
convert_texture16(gx->menu_data, menu_tex.data,
driver.menu->width, driver.menu->height, driver.menu->width * 2);
DCFlushRange(menu_tex.data,
driver.menu->width * driver.menu->height * 2);
}
__GX_InvalidateTexAll(__gx);
@ -965,7 +997,8 @@ static bool gx_frame(void *data, const void *frame,
char fps_txt[128], fps_text_buf[128];
bool fps_draw = g_settings.fps_show;
gfx_get_fps(fps_txt, sizeof(fps_txt), fps_draw ? fps_text_buf : NULL, sizeof(fps_text_buf));
gfx_get_fps(fps_txt, sizeof(fps_txt),
fps_draw ? fps_text_buf : NULL, sizeof(fps_text_buf));
if (fps_draw)
{
@ -975,12 +1008,14 @@ static bool gx_frame(void *data, const void *frame,
gx_blit_line(x, y, fps_text_buf);
y += FONT_HEIGHT * (gx->double_strike ? 1 : 2);
snprintf(mem1_txt, sizeof(mem1_txt), "MEM1: %8d / %8d", SYSMEM1_SIZE - SYS_GetArena1Size(), SYSMEM1_SIZE);
snprintf(mem1_txt, sizeof(mem1_txt), "MEM1: %8d / %8d",
SYSMEM1_SIZE - SYS_GetArena1Size(), SYSMEM1_SIZE);
gx_blit_line(x, y, mem1_txt);
#ifdef HW_RVL
y += FONT_HEIGHT * (gx->double_strike ? 1 : 2);
char mem2_txt[128];
snprintf(mem2_txt, sizeof(mem2_txt), "MEM2: %8d / %8d", gx_mem2_used(), gx_mem2_total());
snprintf(mem2_txt, sizeof(mem2_txt), "MEM2: %8d / %8d",
gx_mem2_used(), gx_mem2_total());
gx_blit_line(x, y, mem2_txt);
#endif
}
@ -1073,7 +1108,8 @@ static void gx_set_texture_enable(void *data, bool enable, bool full_screen)
if (gx)
{
gx->menu_texture_enable = enable;
// need to make sure the game texture is the right pixel format for menu overlay
/* need to make sure the game texture is the right pixel
* format for menu overlay. */
gx->should_resize = true;
}
}
@ -1124,10 +1160,13 @@ static bool gx_overlay_load(void *data, const struct texture_image *images, unsi
for (i = 0; i < num_images; i++)
{
struct gx_overlay_data *o = (struct gx_overlay_data*)&gx->overlay[i];
GX_InitTexObj(&o->tex, images[i].pixels, images[i].width, images[i].height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj(&o->tex, images[i].pixels, images[i].width,
images[i].height,
GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObjFilterMode(&g_tex.obj, GX_LINEAR, GX_LINEAR);
DCFlushRange(images[i].pixels, images[i].width * images[i].height * sizeof(uint32_t));
gx_overlay_tex_geom(gx, i, 0, 0, 1, 1); // Default. Stretch to whole screen.
DCFlushRange(images[i].pixels, images[i].width *
images[i].height * sizeof(uint32_t));
gx_overlay_tex_geom(gx, i, 0, 0, 1, 1); /* Default. Stretch to whole screen. */
gx_overlay_vertex_geom(gx, i, 0, 0, 1, 1);
gx->overlay[i].alpha_mod = 1.0f;
}
@ -1136,7 +1175,8 @@ static bool gx_overlay_load(void *data, const struct texture_image *images, unsi
return true;
}
static void gx_overlay_tex_geom(void *data, unsigned image, float x, float y, float w, float h)
static void gx_overlay_tex_geom(void *data, unsigned image,
float x, float y, float w, float h)
{
gx_video_t *gx = (gx_video_t*)data;
struct gx_overlay_data *o;
@ -1159,18 +1199,19 @@ static void gx_overlay_tex_geom(void *data, unsigned image, float x, float y, fl
}
}
static void gx_overlay_vertex_geom(void *data, unsigned image, float x, float y, float w, float h)
static void gx_overlay_vertex_geom(void *data, unsigned image,
float x, float y, float w, float h)
{
gx_video_t *gx = (gx_video_t*)data;
struct gx_overlay_data *o;
o = NULL;
// Flipped, so we preserve top-down semantics.
/* Flipped, so we preserve top-down semantics. */
y = 1.0f - y;
h = -h;
// expand from 0 - 1 to -1 - 1
/* expand from 0 - 1 to -1 - 1 */
x = (x * 2.0f) - 1.0f;
y = (y * 2.0f) - 1.0f;
w = (w * 2.0f);
@ -1224,21 +1265,29 @@ static void gx_render_overlay(void *data)
GX_LoadTexObj(&gx->overlay[i].tex, GX_TEXMAP0);
GX_Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4);
GX_Position3f32(gx->overlay[i].vertex_coord[0], gx->overlay[i].vertex_coord[1], -0.5);
GX_Position3f32(gx->overlay[i].vertex_coord[0],
gx->overlay[i].vertex_coord[1], -0.5);
GX_Color4u8(255, 255, 255, (u8)(gx->overlay[i].alpha_mod * 255.0f));
GX_TexCoord2f32(gx->overlay[i].tex_coord[0], gx->overlay[i].tex_coord[1]);
GX_TexCoord2f32(gx->overlay[i].tex_coord[0],
gx->overlay[i].tex_coord[1]);
GX_Position3f32(gx->overlay[i].vertex_coord[2], gx->overlay[i].vertex_coord[3], -0.5);
GX_Position3f32(gx->overlay[i].vertex_coord[2],
gx->overlay[i].vertex_coord[3], -0.5);
GX_Color4u8(255, 255, 255, (u8)(gx->overlay[i].alpha_mod * 255.0f));
GX_TexCoord2f32(gx->overlay[i].tex_coord[2], gx->overlay[i].tex_coord[3]);
GX_TexCoord2f32(gx->overlay[i].tex_coord[2],
gx->overlay[i].tex_coord[3]);
GX_Position3f32(gx->overlay[i].vertex_coord[4], gx->overlay[i].vertex_coord[5], -0.5);
GX_Position3f32(gx->overlay[i].vertex_coord[4],
gx->overlay[i].vertex_coord[5], -0.5);
GX_Color4u8(255, 255, 255, (u8)(gx->overlay[i].alpha_mod * 255.0f));
GX_TexCoord2f32(gx->overlay[i].tex_coord[4], gx->overlay[i].tex_coord[5]);
GX_TexCoord2f32(gx->overlay[i].tex_coord[4],
gx->overlay[i].tex_coord[5]);
GX_Position3f32(gx->overlay[i].vertex_coord[6], gx->overlay[i].vertex_coord[7], -0.5);
GX_Position3f32(gx->overlay[i].vertex_coord[6],
gx->overlay[i].vertex_coord[7], -0.5);
GX_Color4u8(255, 255, 255, (u8)(gx->overlay[i].alpha_mod * 255.0f));
GX_TexCoord2f32(gx->overlay[i].tex_coord[6], gx->overlay[i].tex_coord[7]);
GX_TexCoord2f32(gx->overlay[i].tex_coord[6],
gx->overlay[i].tex_coord[7]);
GX_End();
}

View File

@ -36,10 +36,6 @@
#include <cell/codec.h>
#endif
/*******************************************************************************
Image decompression - structs
********************************************************************************/
typedef struct CtrlMallocArg
{
uint32_t mallocCallCounts;
@ -73,10 +69,6 @@ static int img_free(void *ptr, void *a)
return 0;
}
/*******************************************************************************
Image decompression - libJPEG
********************************************************************************/
static bool ps3_load_jpeg(const char *path, struct texture_image *out_img)
{
size_t img_size;
@ -188,10 +180,6 @@ error:
return false;
}
/*******************************************************************************
Image decompression - libPNG
********************************************************************************/
static bool ps3_load_png(const char *path, struct texture_image *out_img)
{
size_t img_size;
@ -269,16 +257,19 @@ static bool ps3_load_png(const char *path, struct texture_image *out_img)
if (ret != CELL_OK)
goto error;
img_size = outParam.output_width * outParam.output_height * sizeof(uint32_t);
img_size = outParam.output_width *
outParam.output_height * sizeof(uint32_t);
out_img->pixels = (uint32_t*)malloc(img_size);
memset(out_img->pixels, 0, img_size);
#ifdef __PSL1GHT__
uint64_t output_bytes_per_line = outParam.output_width * 4;
ret = cellPngDecDecodeData(mHandle, sHandle, (uint8_t*)out_img->pixels, &output_bytes_per_line, &dOutInfo);
ret = cellPngDecDecodeData(mHandle, sHandle, (uint8_t*)
out_img->pixels, &output_bytes_per_line, &dOutInfo);
#else
dCtrlParam.output_bytes_per_line = outParam.output_width * 4;
ret = cellPngDecDecodeData(mHandle, sHandle, (uint8_t*)out_img->pixels, &dCtrlParam, &dOutInfo);
ret = cellPngDecDecodeData(mHandle, sHandle, (uint8_t*)
out_img->pixels, &dCtrlParam, &dOutInfo);
#endif
if (ret != CELL_OK || dOutInfo.status != CELL_PNGDEC_DEC_STATUS_FINISH)

View File

@ -26,8 +26,10 @@
#include "../../general.h"
#include "../rpng/rpng.h"
static bool rpng_image_load_tga_shift(const char *path, struct texture_image *out_img,
unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift)
static bool rpng_image_load_tga_shift(const char *path,
struct texture_image *out_img,
unsigned a_shift, unsigned r_shift,
unsigned g_shift, unsigned b_shift)
{
unsigned i;
void *raw_buf = NULL;
@ -40,7 +42,7 @@ static bool rpng_image_load_tga_shift(const char *path, struct texture_image *ou
uint8_t *buf = (uint8_t*)raw_buf;
if (buf[2] != 2) // Uncompressed RGB
if (buf[2] != 2)
{
RARCH_ERR("TGA image is not uncompressed RGB.\n");
free(buf);
@ -80,7 +82,8 @@ static bool rpng_image_load_tga_shift(const char *path, struct texture_image *ou
uint32_t r = tmp[i * 4 + 2];
uint32_t a = tmp[i * 4 + 3];
out_img->pixels[i] = (a << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
out_img->pixels[i] = (a << a_shift) |
(r << r_shift) | (g << g_shift) | (b << b_shift);
}
}
else if (bits == 24)
@ -92,7 +95,8 @@ static bool rpng_image_load_tga_shift(const char *path, struct texture_image *ou
uint32_t r = tmp[i * 3 + 2];
uint32_t a = 0xff;
out_img->pixels[i] = (a << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
out_img->pixels[i] = (a << a_shift) |
(r << r_shift) | (g << g_shift) | (b << b_shift);
}
}
else
@ -108,15 +112,19 @@ static bool rpng_image_load_tga_shift(const char *path, struct texture_image *ou
return true;
}
static bool rpng_image_load_argb_shift(const char *path, struct texture_image *out_img,
unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift)
static bool rpng_image_load_argb_shift(const char *path,
struct texture_image *out_img,
unsigned a_shift, unsigned r_shift,
unsigned g_shift, unsigned b_shift)
{
if (strstr(path, ".tga"))
return rpng_image_load_tga_shift(path, out_img, a_shift, r_shift, g_shift, b_shift);
return rpng_image_load_tga_shift(path, out_img,
a_shift, r_shift, g_shift, b_shift);
#ifdef HAVE_ZLIB
else if (strstr(path, ".png"))
{
bool ret = rpng_load_image_argb(path, &out_img->pixels, &out_img->width, &out_img->height);
bool ret = rpng_load_image_argb(path,
&out_img->pixels, &out_img->width, &out_img->height);
if (!ret)
return false;
@ -134,7 +142,8 @@ static bool rpng_image_load_argb_shift(const char *path, struct texture_image *o
uint8_t r = (uint8_t)(col >> 16);
uint8_t g = (uint8_t)(col >> 8);
uint8_t b = (uint8_t)(col >> 0);
pixels[i] = (a << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
pixels[i] = (a << a_shift) |
(r << r_shift) | (g << g_shift) | (b << b_shift);
}
}
@ -167,8 +176,10 @@ static bool rpng_image_load_argb_shift(const char *path, struct texture_image *o
static bool rpng_gx_convert_texture32(struct texture_image *image)
{
// memory allocation in libogc is extremely primitive so try to avoid gaps in memory when converting
// by copying over to temp buffer first then converting over into main buffer again
/* Memory allocation in libogc is extremely primitive so try
* to avoid gaps in memory when converting by copying over to
* a temporary buffer first, then converting over into
* main buffer again. */
void *tmp = malloc(image->width * image->height * sizeof(uint32_t));
if (!tmp)
@ -209,7 +220,7 @@ bool texture_image_load(struct texture_image *out_img, const char *path)
{
bool ret;
// This interface "leak" is very ugly. FIXME: Fix this properly ...
/* This interface "leak" is very ugly. FIXME: Fix this properly ... */
if (driver.gfx_use_rgba)
ret = rpng_image_load_argb_shift(path, out_img, 24, 0, 8, 16);
else

View File

@ -35,8 +35,10 @@ bool texture_image_load(struct texture_image *out_img, const char *path)
return false;
}
// create a vertex buffer for the quad that will display the texture
if (FAILED(D3DDevice_CreateVertexBuffers(d3d->dev, 4 * sizeof(Vertex), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &out_img->vertex_buf, NULL)))
/* create a vertex buffer for the quad that will display the texture */
if (FAILED(D3DDevice_CreateVertexBuffers(d3d->dev, 4 * sizeof(Vertex),
D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED, &out_img->vertex_buf, NULL)))
{
RARCH_ERR("Error occurred during CreateVertexBuffer().\n");
out_img->pixels->Release();

View File

@ -117,7 +117,8 @@ typedef struct psp1_video
#define PSP_FRAME_SLICE_COUNT (PSP_FRAME_ROWS_COUNT * PSP_FRAME_COLUMNS_COUNT)
#define PSP_FRAME_VERTEX_COUNT (PSP_FRAME_SLICE_COUNT * 2)
static inline void psp_set_screen_coords (psp1_sprite_t* framecoords, int x, int y, int width, int height)
static inline void psp_set_screen_coords (psp1_sprite_t* framecoords,
int x, int y, int width, int height)
{
int i;
int current_column = 0;
@ -146,7 +147,8 @@ static inline void psp_set_screen_coords (psp1_sprite_t* framecoords, int x, int
}
}
static inline void psp_set_tex_coords (psp1_sprite_t* framecoords, int width, int height)
static inline void psp_set_tex_coords (psp1_sprite_t* framecoords,
int width, int height)
{
int i;
int current_column = 0;
@ -183,7 +185,8 @@ static void psp_on_vblank(u32 sub, psp1_video_t *psp)
static void *psp_init(const video_info_t *video,
const input_driver_t **input, void **input_data)
{
// to-do : add ASSERT() checks or use main RAM if VRAM is too low for desired video->input_scale
/* to-do : add ASSERT() checks or use main RAM if
* VRAM is too low for desired video->input_scale. */
void *pspinput;
int pixel_format, lut_pixel_format, lut_block_count;
unsigned int red_shift, color_mask;
@ -202,22 +205,32 @@ static void *psp_init(const video_info_t *video,
psp->vp.full_width = SCEGU_SCR_WIDTH;
psp->vp.full_height = SCEGU_SCR_HEIGHT;
// make sure anything using uncached pointers reserves whole cachelines (memory address and size need to be a multiple of 64)
// so it isn't overwritten by an unlucky cache writeback.
// this includes display lists since the Gu library uses unchached pointers to write to them.
/* Make sure anything using uncached pointers reserves
* whole cachelines (memory address and size need to be a multiple of 64)
* so it isn't overwritten by an unlucky cache writeback.
*
* This includes display lists since the Gu library uses
* uncached pointers to write to them. */
/* Allocate more space if bigger display lists are needed. */
psp->main_dList = memalign(64, 256);
psp->main_dList = memalign(64, 256); // allocate more space if bigger display lists are needed.
psp->frame_dList = memalign(64, 256);
psp->menu.dList = memalign(64, 256);
psp->menu.frame = memalign(16, 2 * 480 * 272);
psp->frame_coords = memalign(64, (((PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)) + 63) & ~63));
psp->menu.frame_coords = memalign(64, (((PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)) + 63) & ~63));
psp->frame_coords = memalign(64,
(((PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)) + 63) & ~63));
psp->menu.frame_coords = memalign(64,
(((PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t)) + 63) & ~63));
memset(psp->frame_coords, 0,
PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t));
memset(psp->menu.frame_coords, 0,
PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t));
memset(psp->frame_coords , 0, PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t));
memset(psp->menu.frame_coords , 0, PSP_FRAME_SLICE_COUNT * sizeof(psp1_sprite_t));
sceKernelDcacheWritebackInvalidateAll();
psp->frame_coords = TO_UNCACHED_PTR(psp->frame_coords);
psp->menu.frame_coords = TO_UNCACHED_PTR(psp->menu.frame_coords);;
psp->menu.frame_coords = TO_UNCACHED_PTR(psp->menu.frame_coords);
psp->frame_coords->v0.x = 60;
psp->frame_coords->v0.y = 0;
@ -272,12 +285,16 @@ static void *psp_init(const video_info_t *video,
psp->draw_buffer = SCEGU_VRAM_BP_0;
psp->bpp_log2 = 1;
pixel_format = (g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_0RGB1555)? GU_PSM_5551 : GU_PSM_5650 ;
pixel_format =
(g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_0RGB1555)
? GU_PSM_5551 : GU_PSM_5650 ;
lut_pixel_format = GU_PSM_T16;
displayBuffer = SCEGU_VRAM_BP_1;
for (u16 i = 0; i < (1 << 5); i++){
for (u16 i = 0; i < (1 << 5); i++)
{
LUT_r_local[i]= i;
LUT_b_local[i]= i << (5 + 6);
}
@ -289,13 +306,17 @@ static void *psp_init(const video_info_t *video,
psp->tex_filter = video->smooth? GU_LINEAR : GU_NEAREST;
sceDisplayWaitVblankStart(); // TODO : check if necessary
/* TODO: check if necessary. */
sceDisplayWaitVblankStart();
sceGuDisplay(GU_FALSE);
sceGuStart(GU_DIRECT, psp->main_dList);
sceGuDrawBuffer(pixel_format, TO_GU_POINTER(psp->draw_buffer), SCEGU_VRAM_WIDTH);
sceGuDispBuffer(SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT, TO_GU_POINTER(displayBuffer), SCEGU_VRAM_WIDTH);
sceGuDrawBuffer(pixel_format, TO_GU_POINTER(psp->draw_buffer),
SCEGU_VRAM_WIDTH);
sceGuDispBuffer(SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT,
TO_GU_POINTER(displayBuffer), SCEGU_VRAM_WIDTH);
sceGuClearColor(0);
sceGuScissor(0, 0, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
@ -307,35 +328,45 @@ static void *psp_init(const video_info_t *video,
sceGuFinish();
sceGuSync(0, 0);
sceDisplayWaitVblankStart(); // TODO : check if necessary
/* TODO : check if necessary */
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
pspDebugScreenSetColorMode(pixel_format);
pspDebugScreenSetBase(psp->draw_buffer);
// fill frame_dList :
/* fill frame_dList : */
sceGuStart(GU_CALL, psp->frame_dList);
sceGuTexMode(pixel_format, 0, 0, GU_FALSE);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0x0000FF00, 0xFFFFFFFF); // green only
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords));
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xFFFFFFFF, 0xFFFFFFFF); // restore
/* green only */
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0x0000FF00, 0xFFFFFFFF);
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF |
GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL,
(void*)(psp->frame_coords));
/* restore */
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xFFFFFFFF, 0xFFFFFFFF);
sceGuTexMode(lut_pixel_format, 0, 0, GU_FALSE);
sceGuClutMode(pixel_format, red_shift, color_mask, 0);
sceGuClutLoad(lut_block_count, LUT_r);
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords));
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF |
GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL,
(void*)(psp->frame_coords));
sceGuClutMode(pixel_format, 0, color_mask, 0);
sceGuClutLoad(lut_block_count, LUT_b);
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords));
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF |
GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL,
(void*)(psp->frame_coords));
sceGuFinish();
@ -383,7 +414,7 @@ static bool psp_frame(void *data, const void *frame,
psp->hw_render = false;
if (!psp->hw_render)
sceGuSync(0, 0); // let the core decide when to sync when HW_RENDER
sceGuSync(0, 0); /* let the core decide when to sync when HW_RENDER */
pspDebugScreenSetBase(psp->draw_buffer);
@ -439,14 +470,20 @@ static bool psp_frame(void *data, const void *frame,
sceGuTexFilter(psp->tex_filter, psp->tex_filter);
sceGuClear(GU_COLOR_BUFFER_BIT);
if (psp->hw_render) // frame in VRAM ? texture/palette was set in core so draw directly
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords));
/* frame in VRAM ? texture/palette was
* set in core so draw directly */
if (psp->hw_render)
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF |
GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL,
(void*)(psp->frame_coords));
else
{
if (frame!=NULL)
if (frame)
{
sceKernelDcacheWritebackRange(frame,pitch * height);
sceGuCopyImage(GU_PSM_5650, ((u32)frame & 0xF) >> psp->bpp_log2, 0, width, height, pitch >> psp->bpp_log2, (void*)((u32)frame & ~0xF), 0, 0, width, psp->texture);
sceGuCopyImage(GU_PSM_5650, ((u32)frame & 0xF) >> psp->bpp_log2,
0, width, height, pitch >> psp->bpp_log2,
(void*)((u32)frame & ~0xF), 0, 0, width, psp->texture);
}
sceGuTexImage(0, next_pow2(width), next_pow2(height), width, psp->texture);
sceGuCallList(psp->frame_dList);
@ -522,16 +559,19 @@ static void psp_set_texture_frame(void *data, const void *frame, bool rgb32,
psp1_video_t *psp = (psp1_video_t*)data;
#ifdef DEBUG
rarch_assert((width*height) < (480 * 272)); // psp->menu.frame buffer size is (480 * 272)*2 Bytes
/* psp->menu.frame buffer size is (480 * 272)*2 Bytes */
rarch_assert((width*height) < (480 * 272));
#endif
psp_set_screen_coords(psp->menu.frame_coords, 0, 0, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT);
psp_set_screen_coords(psp->menu.frame_coords, 0, 0,
SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT);
psp_set_tex_coords(psp->menu.frame_coords, width, height);
sceKernelDcacheWritebackRange(frame, width * height * 2);
sceGuStart(GU_DIRECT, psp->main_dList);
sceGuCopyImage(GU_PSM_4444, 0, 0, width, height, width, (void*)frame, 0, 0, width, psp->menu.frame);
sceGuCopyImage(GU_PSM_4444, 0, 0, width, height, width,
(void*)frame, 0, 0, width, psp->menu.frame);
sceGuFinish();
sceGuStart(GU_SEND, psp->menu.dList);
@ -541,10 +581,15 @@ static void psp_set_texture_frame(void *data, const void *frame, bool rgb32,
sceGuTexImage(0, next_pow2(width), next_pow2(height), width, psp->menu.frame);
sceGuEnable(GU_BLEND);
// sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); // default blending
#if 0
/* default blending */
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
#endif
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xF0F0F0F0, 0x0F0F0F0F);
;
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, psp->menu.frame_coords);
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF |
GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL,
psp->menu.frame_coords);
sceGuFinish();
}
@ -560,35 +605,38 @@ static void psp_set_texture_enable(void *data, bool state, bool full_screen)
static inline void psp_update_frame_coords(psp1_video_t* psp)
{
// psp1_vertex_t *v0, *v1;
/* TODO: no rotation for now */
#if 0
psp1_vertex_t *v0, *v1;
// if (psp->rotation & 0x2)
// {
// v0 = &psp->frame_coords->v1;
// v1 = &psp->frame_coords->v0;
// }
// else
// {
// v0 = &psp->frame_coords->v0;
// v1 = &psp->frame_coords->v1;
// }
if (psp->rotation & 0x2)
{
v0 = &psp->frame_coords->v1;
v1 = &psp->frame_coords->v0;
}
else
{
v0 = &psp->frame_coords->v0;
v1 = &psp->frame_coords->v1;
}
// if (psp->rotation & 0x1)
// {
// v0->x = psp->vp.x + psp->vp.width;
// v1->x = psp->vp.x;
// }
// else
// {
// v0->x = psp->vp.x;
// v1->x = psp->vp.x + psp->vp.width;
// }
if (psp->rotation & 0x1)
{
v0->x = psp->vp.x + psp->vp.width;
v1->x = psp->vp.x;
}
else
{
v0->x = psp->vp.x;
v1->x = psp->vp.x + psp->vp.width;
}
// v0->y = psp->vp.y;
// v1->y = psp->vp.y + psp->vp.height;
v0->y = psp->vp.y;
v1->y = psp->vp.y + psp->vp.height;
#endif
// no rotation for now
psp_set_screen_coords(psp->frame_coords, psp->vp.x, psp->vp.y, psp->vp.width, psp->vp.height);
psp_set_screen_coords(psp->frame_coords, psp->vp.x,
psp->vp.y, psp->vp.width, psp->vp.height);
}
static void psp_update_viewport(psp1_video_t* psp)
@ -602,7 +650,8 @@ static void psp_update_viewport(psp1_video_t* psp)
if (g_settings.video.scale_integer)
{
gfx_scale_integer(&psp->vp, SCEGU_SCR_WIDTH, SCEGU_SCR_HEIGHT, g_extern.system.aspect_ratio, psp->keep_aspect);
gfx_scale_integer(&psp->vp, SCEGU_SCR_WIDTH,
SCEGU_SCR_HEIGHT, g_extern.system.aspect_ratio, psp->keep_aspect);
width = psp->vp.width;
height = psp->vp.height;
}
@ -625,20 +674,25 @@ static void psp_update_viewport(psp1_video_t* psp)
else
#endif
{
if ((fabsf(device_aspect - desired_aspect) < 0.0001f)||(fabsf((16.0/9.0) - desired_aspect) < 0.0001f))
if ((fabsf(device_aspect - desired_aspect) < 0.0001f)
|| (fabsf((16.0/9.0) - desired_aspect) < 0.0001f))
{
// If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff),
// assume they are actually equal.
/* If the aspect ratios of screen and desired aspect
* ratio are sufficiently equal (floating point stuff),
* assume they are actually equal.
*/
}
else if (device_aspect > desired_aspect)
{
delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f;
delta = (desired_aspect / device_aspect - 1.0f)
/ 2.0f + 0.5f;
x = (int)roundf(width * (0.5f - delta));
width = (unsigned)roundf(2.0f * width * delta);
}
else
{
delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f;
delta = (device_aspect / desired_aspect - 1.0f)
/ 2.0f + 0.5f;
y = (int)roundf(height * (0.5f - delta));
height = (unsigned)roundf(2.0f * height * delta);
}
@ -682,7 +736,9 @@ static void psp_set_aspect_ratio(void *data, unsigned aspectratio_index)
switch (aspectratio_index)
{
case ASPECT_RATIO_SQUARE:
gfx_set_square_pixel_viewport(g_extern.system.av_info.geometry.base_width, g_extern.system.av_info.geometry.base_height);
gfx_set_square_pixel_viewport(
g_extern.system.av_info.geometry.base_width,
g_extern.system.av_info.geometry.base_height);
break;
case ASPECT_RATIO_CORE:
@ -733,7 +789,8 @@ static const video_poke_interface_t psp_poke_interface = {
NULL
};
static void psp_get_poke_interface(void *data, const video_poke_interface_t **iface)
static void psp_get_poke_interface(void *data,
const video_poke_interface_t **iface)
{
(void)data;
*iface = &psp_poke_interface;

View File

@ -62,10 +62,10 @@ typedef struct
{
/* row 0 */
unsigned char enable; // Light enable
unsigned char type; // Light type
unsigned char xpos; // X position
unsigned char ypos; // Y position
unsigned char enable; /* Light enable */
unsigned char type; /* Light type */
unsigned char xpos; /* X position */
unsigned char ypos; /* Y position */
/* row 1 */
@ -107,9 +107,9 @@ extern int gu_object_stack_depth;
extern GuLightSettings light_settings[4];
static int tbpcmd_tbl[8] = { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7 }; // 0x30A18
static int tbwcmd_tbl[8] = { 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf }; // 0x30A38
static int tsizecmd_tbl[8] = { 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf }; // 0x30A58
static int tbpcmd_tbl[8] = { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7 }; /* 0x30A18 */
static int tbwcmd_tbl[8] = { 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf }; /* 0x30A38 */
static int tsizecmd_tbl[8] = { 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf }; /* 0x30A58 */
#define sendCommandi(cmd, argument) *(gu_list->current++) = (cmd << 24) | (argument & 0xffffff)

View File

@ -128,17 +128,18 @@ static enum png_chunk_type png_chunk_type(const struct png_chunk *chunk)
static bool png_read_chunk(FILE *file, struct png_chunk *chunk)
{
free(chunk->data);
chunk->data = (uint8_t*)calloc(1, chunk->size + sizeof(uint32_t)); // CRC32
chunk->data = (uint8_t*)calloc(1, chunk->size + sizeof(uint32_t)); /* CRC32 */
if (!chunk->data)
return false;
if (fread(chunk->data, 1, chunk->size + sizeof(uint32_t), file) != (chunk->size + sizeof(uint32_t)))
if (fread(chunk->data, 1, chunk->size +
sizeof(uint32_t), file) != (chunk->size + sizeof(uint32_t)))
{
free(chunk->data);
return false;
}
// Ignore CRC.
/* Ignore CRC. */
return true;
}
@ -148,7 +149,8 @@ static void png_free_chunk(struct png_chunk *chunk)
chunk->data = NULL;
}
static bool png_parse_ihdr(FILE *file, struct png_chunk *chunk, struct png_ihdr *ihdr)
static bool png_parse_ihdr(FILE *file,
struct png_chunk *chunk, struct png_ihdr *ihdr)
{
unsigned i;
bool ret = true;
@ -169,7 +171,8 @@ static bool png_parse_ihdr(FILE *file, struct png_chunk *chunk, struct png_ihdr
if (ihdr->width == 0 || ihdr->height == 0)
GOTO_END_ERROR();
if (ihdr->color_type == 2 || ihdr->color_type == 4 || ihdr->color_type == 6)
if (ihdr->color_type == 2 ||
ihdr->color_type == 4 || ihdr->color_type == 6)
{
if (ihdr->depth != 8 && ihdr->depth != 16)
GOTO_END_ERROR();
@ -245,7 +248,8 @@ static inline int paeth(int a, int b, int c)
return c;
}
static inline void copy_line_rgb(uint32_t *data, const uint8_t *decoded, unsigned width, unsigned bpp)
static inline void copy_line_rgb(uint32_t *data,
const uint8_t *decoded, unsigned width, unsigned bpp)
{
unsigned i;
bpp /= 8;
@ -261,7 +265,8 @@ static inline void copy_line_rgb(uint32_t *data, const uint8_t *decoded, unsigne
}
}
static inline void copy_line_rgba(uint32_t *data, const uint8_t *decoded, unsigned width, unsigned bpp)
static inline void copy_line_rgba(uint32_t *data,
const uint8_t *decoded, unsigned width, unsigned bpp)
{
unsigned i;
bpp /= 8;
@ -279,7 +284,8 @@ static inline void copy_line_rgba(uint32_t *data, const uint8_t *decoded, unsign
}
}
static inline void copy_line_bw(uint32_t *data, const uint8_t *decoded, unsigned width, unsigned depth)
static inline void copy_line_bw(uint32_t *data,
const uint8_t *decoded, unsigned width, unsigned depth)
{
unsigned i, bit;
if (depth == 16)
@ -308,7 +314,8 @@ static inline void copy_line_bw(uint32_t *data, const uint8_t *decoded, unsigned
}
}
static inline void copy_line_gray_alpha(uint32_t *data, const uint8_t *decoded, unsigned width,
static inline void copy_line_gray_alpha(uint32_t *data,
const uint8_t *decoded, unsigned width,
unsigned bpp)
{
unsigned i;
@ -324,7 +331,9 @@ static inline void copy_line_gray_alpha(uint32_t *data, const uint8_t *decoded,
}
}
static inline void copy_line_plt(uint32_t *data, const uint8_t *decoded, unsigned width, unsigned depth, const uint32_t *palette)
static inline void copy_line_plt(uint32_t *data,
const uint8_t *decoded, unsigned width,
unsigned depth, const uint32_t *palette)
{
unsigned i, bit;
unsigned mask = (1 << depth) - 1;
@ -387,7 +396,8 @@ static void png_pass_geom(const struct png_ihdr *ihdr,
static bool png_reverse_filter(uint32_t *data, const struct png_ihdr *ihdr,
const uint8_t *inflate_buf, size_t inflate_buf_size, const uint32_t *palette)
const uint8_t *inflate_buf, size_t inflate_buf_size,
const uint32_t *palette)
{
unsigned i, h;
bool ret = true;
@ -412,23 +422,23 @@ static bool png_reverse_filter(uint32_t *data, const struct png_ihdr *ihdr,
unsigned filter = *inflate_buf++;
switch (filter)
{
case 0: // None
case 0: /* None */
memcpy(decoded_scanline, inflate_buf, pitch);
break;
case 1: // Sub
case 1: /* Sub */
for (i = 0; i < bpp; i++)
decoded_scanline[i] = inflate_buf[i];
for (i = bpp; i < pitch; i++)
decoded_scanline[i] = decoded_scanline[i - bpp] + inflate_buf[i];
break;
case 2: // Up
case 2: /* Up */
for (i = 0; i < pitch; i++)
decoded_scanline[i] = prev_scanline[i] + inflate_buf[i];
break;
case 3: // Average
case 3: /* Average */
for (i = 0; i < bpp; i++)
{
uint8_t avg = prev_scanline[i] >> 1;
@ -441,11 +451,12 @@ static bool png_reverse_filter(uint32_t *data, const struct png_ihdr *ihdr,
}
break;
case 4: // Paeth
case 4: /* Paeth */
for (i = 0; i < bpp; i++)
decoded_scanline[i] = paeth(0, prev_scanline[i], 0) + inflate_buf[i];
for (i = bpp; i < pitch; i++)
decoded_scanline[i] = paeth(decoded_scanline[i - bpp], prev_scanline[i], prev_scanline[i - bpp]) + inflate_buf[i];
decoded_scanline[i] = paeth(decoded_scanline[i - bpp],
prev_scanline[i], prev_scanline[i - bpp]) + inflate_buf[i];
break;
default:
@ -457,9 +468,11 @@ static bool png_reverse_filter(uint32_t *data, const struct png_ihdr *ihdr,
else if (ihdr->color_type == 2)
copy_line_rgb(data, decoded_scanline, ihdr->width, ihdr->depth);
else if (ihdr->color_type == 3)
copy_line_plt(data, decoded_scanline, ihdr->width, ihdr->depth, palette);
copy_line_plt(data, decoded_scanline, ihdr->width,
ihdr->depth, palette);
else if (ihdr->color_type == 4)
copy_line_gray_alpha(data, decoded_scanline, ihdr->width, ihdr->depth);
copy_line_gray_alpha(data, decoded_scanline, ihdr->width,
ihdr->depth);
else if (ihdr->color_type == 6)
copy_line_rgba(data, decoded_scanline, ihdr->width, ihdr->depth);
@ -481,11 +494,13 @@ struct adam7_pass
};
static void deinterlace_pass(uint32_t *data, const struct png_ihdr *ihdr,
const uint32_t *input, unsigned pass_width, unsigned pass_height, const struct adam7_pass *pass)
const uint32_t *input, unsigned pass_width, unsigned pass_height,
const struct adam7_pass *pass)
{
unsigned x, y;
data += pass->y * ihdr->width + pass->x;
for (y = 0; y < pass_height; y++, data += ihdr->width * pass->stride_y, input += pass_width)
for (y = 0; y < pass_height;
y++, data += ihdr->width * pass->stride_y, input += pass_width)
{
uint32_t *out = data;
for (x = 0; x < pass_width; x++, out += pass->stride_x)
@ -493,8 +508,10 @@ static void deinterlace_pass(uint32_t *data, const struct png_ihdr *ihdr,
}
}
static bool png_reverse_filter_adam7(uint32_t *data, const struct png_ihdr *ihdr,
const uint8_t *inflate_buf, size_t inflate_buf_size, const uint32_t *palette)
static bool png_reverse_filter_adam7(uint32_t *data,
const struct png_ihdr *ihdr,
const uint8_t *inflate_buf, size_t inflate_buf_size,
const uint32_t *palette)
{
unsigned pass;
static const struct adam7_pass passes[] = {
@ -509,13 +526,18 @@ static bool png_reverse_filter_adam7(uint32_t *data, const struct png_ihdr *ihdr
for (pass = 0; pass < ARRAY_SIZE(passes); pass++)
{
if (ihdr->width <= passes[pass].x || ihdr->height <= passes[pass].y) // Empty pass
if (ihdr->width <= passes[pass].x ||
ihdr->height <= passes[pass].y) /* Empty pass */
continue;
unsigned pass_width = (ihdr->width - passes[pass].x + passes[pass].stride_x - 1) / passes[pass].stride_x;
unsigned pass_height = (ihdr->height - passes[pass].y + passes[pass].stride_y - 1) / passes[pass].stride_y;
unsigned pass_width = (ihdr->width -
passes[pass].x + passes[pass].stride_x - 1) / passes[pass].stride_x;
unsigned pass_height = (ihdr->height - passes[pass].y +
passes[pass].stride_y - 1) / passes[pass].stride_y;
uint32_t *tmp_data = (uint32_t*)
malloc(pass_width * pass_height * sizeof(uint32_t));
uint32_t *tmp_data = (uint32_t*)malloc(pass_width * pass_height * sizeof(uint32_t));
if (!tmp_data)
return false;
@ -524,7 +546,8 @@ static bool png_reverse_filter_adam7(uint32_t *data, const struct png_ihdr *ihdr
tmp_ihdr.height = pass_height;
size_t pass_size;
png_pass_geom(&tmp_ihdr, pass_width, pass_height, NULL, NULL, &pass_size);
png_pass_geom(&tmp_ihdr, pass_width,
pass_height, NULL, NULL, &pass_size);
if (pass_size > inflate_buf_size)
{
@ -532,7 +555,8 @@ static bool png_reverse_filter_adam7(uint32_t *data, const struct png_ihdr *ihdr
return false;
}
if (!png_reverse_filter(tmp_data, &tmp_ihdr, inflate_buf, pass_size, palette))
if (!png_reverse_filter(tmp_data,
&tmp_ihdr, inflate_buf, pass_size, palette))
{
free(tmp_data);
return false;
@ -541,14 +565,16 @@ static bool png_reverse_filter_adam7(uint32_t *data, const struct png_ihdr *ihdr
inflate_buf += pass_size;
inflate_buf_size -= pass_size;
deinterlace_pass(data, ihdr, tmp_data, pass_width, pass_height, &passes[pass]);
deinterlace_pass(data,
ihdr, tmp_data, pass_width, pass_height, &passes[pass]);
free(tmp_data);
}
return true;
}
static bool png_append_idat(FILE *file, const struct png_chunk *chunk, struct idat_buffer *buf)
static bool png_append_idat(FILE *file,
const struct png_chunk *chunk, struct idat_buffer *buf)
{
uint8_t *new_buffer = (uint8_t*)realloc(buf->data, buf->size + chunk->size);
if (!new_buffer)
@ -587,7 +613,8 @@ static bool png_read_plte(FILE *file, uint32_t *buffer, unsigned entries)
return true;
}
bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, unsigned *height)
bool rpng_load_image_argb(const char *path, uint32_t **data,
unsigned *width, unsigned *height)
{
long pos;
*data = NULL;
@ -622,8 +649,9 @@ bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, un
if (memcmp(header, png_magic, sizeof(png_magic)) != 0)
GOTO_END_ERROR();
// feof() apparently isn't triggered after a seek (IEND).
for (pos = ftell(file); pos < file_len && pos >= 0; pos = ftell(file))
/* feof() apparently isn't triggered after a seek (IEND). */
for (pos = ftell(file);
pos < file_len && pos >= 0; pos = ftell(file))
{
struct png_chunk chunk = {0};
if (!read_chunk_header(file, &chunk))
@ -692,7 +720,7 @@ bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, un
GOTO_END_ERROR();
png_pass_geom(&ihdr, ihdr.width, ihdr.height, NULL, NULL, &inflate_buf_size);
if (ihdr.interlace == 1) // To be sure.
if (ihdr.interlace == 1) /* To be sure. */
inflate_buf_size *= 2;
inflate_buf = (uint8_t*)malloc(inflate_buf_size);
@ -714,7 +742,7 @@ bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, un
*width = ihdr.width;
*height = ihdr.height;
#ifdef GEKKO
// we often use these in textures, make sure they're 32-byte aligned
/* we often use these in textures, make sure they're 32-byte aligned */
*data = (uint32_t*)memalign(32, ihdr.width * ihdr.height * sizeof(uint32_t));
#else
*data = (uint32_t*)malloc(ihdr.width * ihdr.height * sizeof(uint32_t));
@ -724,10 +752,12 @@ bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, un
if (ihdr.interlace == 1)
{
if (!png_reverse_filter_adam7(*data, &ihdr, inflate_buf, stream.total_out, palette))
if (!png_reverse_filter_adam7(*data,
&ihdr, inflate_buf, stream.total_out, palette))
GOTO_END_ERROR();
}
else if (!png_reverse_filter(*data, &ihdr, inflate_buf, stream.total_out, palette))
else if (!png_reverse_filter(*data,
&ihdr, inflate_buf, stream.total_out, palette))
GOTO_END_ERROR();
end:
@ -779,7 +809,8 @@ static bool png_write_ihdr(FILE *file, const struct png_ihdr *ihdr)
if (fwrite(ihdr_raw, 1, sizeof(ihdr_raw), file) != sizeof(ihdr_raw))
return false;
if (!png_write_crc(file, ihdr_raw + sizeof(uint32_t), sizeof(ihdr_raw) - sizeof(uint32_t)))
if (!png_write_crc(file, ihdr_raw + sizeof(uint32_t),
sizeof(ihdr_raw) - sizeof(uint32_t)))
return false;
return true;
@ -806,7 +837,8 @@ static bool png_write_iend(FILE *file)
if (fwrite(data, 1, sizeof(data), file) != sizeof(data))
return false;
if (!png_write_crc(file, data + sizeof(uint32_t), sizeof(data) - sizeof(uint32_t)))
if (!png_write_crc(file, data + sizeof(uint32_t),
sizeof(data) - sizeof(uint32_t)))
return false;
return true;
@ -845,8 +877,8 @@ static unsigned count_sad(const uint8_t *data, size_t size)
return cnt;
}
static unsigned filter_up(uint8_t *target, const uint8_t *line, const uint8_t *prev,
unsigned width, unsigned bpp)
static unsigned filter_up(uint8_t *target, const uint8_t *line,
const uint8_t *prev, unsigned width, unsigned bpp)
{
unsigned i;
width *= bpp;
@ -869,8 +901,8 @@ static unsigned filter_sub(uint8_t *target, const uint8_t *line,
return count_sad(target, width);
}
static unsigned filter_avg(uint8_t *target, const uint8_t *line, const uint8_t *prev,
unsigned width, unsigned bpp)
static unsigned filter_avg(uint8_t *target, const uint8_t *line,
const uint8_t *prev, unsigned width, unsigned bpp)
{
unsigned i;
width *= bpp;
@ -882,7 +914,8 @@ static unsigned filter_avg(uint8_t *target, const uint8_t *line, const uint8_t *
return count_sad(target, width);
}
static unsigned filter_paeth(uint8_t *target, const uint8_t *line, const uint8_t *prev,
static unsigned filter_paeth(uint8_t *target,
const uint8_t *line, const uint8_t *prev,
unsigned width, unsigned bpp)
{
unsigned i;
@ -895,7 +928,8 @@ static unsigned filter_paeth(uint8_t *target, const uint8_t *line, const uint8_t
return count_sad(target, width);
}
static bool rpng_save_image(const char *path, const uint8_t *data,
static bool rpng_save_image(const char *path,
const uint8_t *data,
unsigned width, unsigned height, unsigned pitch, unsigned bpp)
{
unsigned h;
@ -925,7 +959,7 @@ static bool rpng_save_image(const char *path, const uint8_t *data,
ihdr.width = width;
ihdr.height = height;
ihdr.depth = 8;
ihdr.color_type = bpp == sizeof(uint32_t) ? 6 : 2; // RGBA or RGB
ihdr.color_type = bpp == sizeof(uint32_t) ? 6 : 2; /* RGBA or RGB */
if (!png_write_ihdr(file, &ihdr))
GOTO_END_ERROR();
@ -955,9 +989,12 @@ static bool rpng_save_image(const char *path, const uint8_t *data,
else
copy_bgr24_line(rgba_line, data, width);
// Try every filtering method, and choose the method
// which has most entries as zero.
// This is probably not very optimal, but it's very simple to implement.
/* Try every filtering method, and choose the method
* which has most entries as zero.
*
* This is probably not very optimal, but it's very
* simple to implement.
*/
unsigned none_score = count_sad(rgba_line, width * bpp);
unsigned up_score = filter_up(up_filtered, rgba_line, prev_encoded, width, bpp);
unsigned sub_score = filter_sub(sub_filtered, rgba_line, width, bpp);
@ -1002,7 +1039,7 @@ static bool rpng_save_image(const char *path, const uint8_t *data,
memcpy(prev_encoded, rgba_line, width * bpp);
}
deflate_buf = (uint8_t*)malloc(encode_buf_size * 2); // Just to be sure.
deflate_buf = (uint8_t*)malloc(encode_buf_size * 2); /* Just to be sure. */
if (!deflate_buf)
GOTO_END_ERROR();
@ -1044,13 +1081,15 @@ end:
bool rpng_save_image_argb(const char *path, const uint32_t *data,
unsigned width, unsigned height, unsigned pitch)
{
return rpng_save_image(path, (const uint8_t*)data, width, height, pitch, sizeof(uint32_t));
return rpng_save_image(path, (const uint8_t*)data,
width, height, pitch, sizeof(uint32_t));
}
bool rpng_save_image_bgr24(const char *path, const uint8_t *data,
unsigned width, unsigned height, unsigned pitch)
{
return rpng_save_image(path, (const uint8_t*)data, width, height, pitch, 3);
return rpng_save_image(path, (const uint8_t*)data,
width, height, pitch, 3);
}
#endif

View File

@ -28,7 +28,8 @@
extern "C" {
#endif
bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, unsigned *height);
bool rpng_load_image_argb(const char *path, uint32_t **data,
unsigned *width, unsigned *height);
#ifdef HAVE_ZLIB_DEFLATE
bool rpng_save_image_argb(const char *path, const uint32_t *data,

View File

@ -31,10 +31,14 @@ int main(int argc, char *argv[])
const char *in_path = argc == 2 ? argv[1] : "/tmp/test.png";
const uint32_t test_data[] = {
0xff000000 | 0x50, 0xff000000 | 0x80, 0xff000000 | 0x40, 0xff000000 | 0x88,
0xff000000 | 0x50, 0xff000000 | 0x80, 0xff000000 | 0x40, 0xff000000 | 0x88,
0xff000000 | 0xc3, 0xff000000 | 0xd3, 0xff000000 | 0xc3, 0xff000000 | 0xd3,
0xff000000 | 0xc3, 0xff000000 | 0xd3, 0xff000000 | 0xc3, 0xff000000 | 0xd3,
0xff000000 | 0x50, 0xff000000 | 0x80,
0xff000000 | 0x40, 0xff000000 | 0x88,
0xff000000 | 0x50, 0xff000000 | 0x80,
0xff000000 | 0x40, 0xff000000 | 0x88,
0xff000000 | 0xc3, 0xff000000 | 0xd3,
0xff000000 | 0xc3, 0xff000000 | 0xd3,
0xff000000 | 0xc3, 0xff000000 | 0xd3,
0xff000000 | 0xc3, 0xff000000 | 0xd3,
};
if (!rpng_save_image_argb("/tmp/test.png", test_data, 4, 4, 16))

View File

@ -41,7 +41,8 @@ void conv_rgb565_0rgb1555(void *output_, const void *input_,
const __m128i hi_mask = _mm_set1_epi16(0x7fe0);
const __m128i lo_mask = _mm_set1_epi16(0x1f);
for (h = 0; h < height; h++, output += out_stride >> 1, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride >> 1, input += in_stride >> 1)
{
for (w = 0; w < max_width; w += 8)
{
@ -69,7 +70,8 @@ void conv_rgb565_0rgb1555(void *output_, const void *input_,
const uint16_t *input = (const uint16_t*)input_;
uint16_t *output = (uint16_t*)output_;
for (h = 0; h < height; h++, output += out_stride >> 1, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride >> 1, input += in_stride >> 1)
{
for (w = 0; w < width; w++)
{
@ -94,11 +96,13 @@ void conv_0rgb1555_rgb565(void *output_, const void *input_,
int max_width = width - 7;
const __m128i hi_mask = _mm_set1_epi16((int16_t)((0x1f << 11) | (0x1f << 6)));
const __m128i hi_mask = _mm_set1_epi16(
(int16_t)((0x1f << 11) | (0x1f << 6)));
const __m128i lo_mask = _mm_set1_epi16(0x1f);
const __m128i glow_mask = _mm_set1_epi16(1 << 5);
for (h = 0; h < height; h++, output += out_stride >> 1, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride >> 1, input += in_stride >> 1)
{
for (w = 0; w < max_width; w += 8)
{
@ -106,7 +110,8 @@ void conv_0rgb1555_rgb565(void *output_, const void *input_,
__m128i rg = _mm_and_si128(_mm_slli_epi16(in, 1), hi_mask);
__m128i b = _mm_and_si128(in, lo_mask);
__m128i glow = _mm_and_si128(_mm_srli_epi16(in, 4), glow_mask);
_mm_storeu_si128((__m128i*)(output + w), _mm_or_si128(rg, _mm_or_si128(b, glow)));
_mm_storeu_si128((__m128i*)(output + w),
_mm_or_si128(rg, _mm_or_si128(b, glow)));
}
for (; w < width; w++)
@ -128,7 +133,8 @@ void conv_0rgb1555_rgb565(void *output_, const void *input_,
const uint16_t *input = (const uint16_t*)input_;
uint16_t *output = (uint16_t*)output_;
for (h = 0; h < height; h++, output += out_stride >> 1, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride >> 1, input += in_stride >> 1)
{
for (w = 0; w < width; w++)
{
@ -159,7 +165,8 @@ void conv_0rgb1555_argb8888(void *output_, const void *input_,
int max_width = width - 7;
for (h = 0; h < height; h++, output += out_stride >> 2, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride >> 2, input += in_stride >> 1)
{
for (w = 0; w < max_width; w += 8)
{
@ -177,8 +184,10 @@ void conv_0rgb1555_argb8888(void *output_, const void *input_,
__m128i res_lo_ra = _mm_unpacklo_epi8(r, a);
__m128i res_hi_ra = _mm_unpackhi_epi8(r, a);
__m128i res_lo = _mm_or_si128(res_lo_bg, _mm_slli_si128(res_lo_ra, 2));
__m128i res_hi = _mm_or_si128(res_hi_bg, _mm_slli_si128(res_hi_ra, 2));
__m128i res_lo = _mm_or_si128(res_lo_bg,
_mm_slli_si128(res_lo_ra, 2));
__m128i res_hi = _mm_or_si128(res_hi_bg,
_mm_slli_si128(res_hi_ra, 2));
_mm_storeu_si128((__m128i*)(output + w + 0), res_lo);
_mm_storeu_si128((__m128i*)(output + w + 4), res_hi);
@ -207,7 +216,8 @@ void conv_0rgb1555_argb8888(void *output_, const void *input_,
const uint16_t *input = (const uint16_t*)input_;
uint32_t *output = (uint32_t*)output_;
for (h = 0; h < height; h++, output += out_stride >> 2, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride >> 2, input += in_stride >> 1)
{
for (w = 0; w < width; w++)
{
@ -244,7 +254,8 @@ void conv_rgb565_argb8888(void *output_, const void *input_,
int max_width = width - 7;
for (h = 0; h < height; h++, output += out_stride >> 2, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride >> 2, input += in_stride >> 1)
{
for (w = 0; w < max_width; w += 8)
{
@ -262,8 +273,10 @@ void conv_rgb565_argb8888(void *output_, const void *input_,
__m128i res_lo_ra = _mm_unpacklo_epi8(r, a);
__m128i res_hi_ra = _mm_unpackhi_epi8(r, a);
__m128i res_lo = _mm_or_si128(res_lo_bg, _mm_slli_si128(res_lo_ra, 2));
__m128i res_hi = _mm_or_si128(res_hi_bg, _mm_slli_si128(res_hi_ra, 2));
__m128i res_lo = _mm_or_si128(res_lo_bg,
_mm_slli_si128(res_lo_ra, 2));
__m128i res_hi = _mm_or_si128(res_hi_bg,
_mm_slli_si128(res_hi_ra, 2));
_mm_storeu_si128((__m128i*)(output + w + 0), res_lo);
_mm_storeu_si128((__m128i*)(output + w + 4), res_hi);
@ -292,7 +305,8 @@ void conv_rgb565_argb8888(void *output_, const void *input_,
const uint16_t *input = (const uint16_t*)input_;
uint32_t *output = (uint32_t*)output_;
for (h = 0; h < height; h++, output += out_stride >> 2, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride >> 2, input += in_stride >> 1)
{
for (w = 0; w < width; w++)
{
@ -318,7 +332,8 @@ void conv_rgba4444_argb8888(void *output_, const void *input_,
const uint16_t *input = (const uint16_t*)input_;
uint32_t *output = (uint32_t*)output_;
for (h = 0; h < height; h++, output += out_stride >> 2, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride >> 2, input += in_stride >> 1)
{
for (w = 0; w < width; w++)
{
@ -332,15 +347,15 @@ void conv_rgba4444_argb8888(void *output_, const void *input_,
b = (b << 4) | b;
a = (a << 4) | a;
//output[w] = (0xffu << 24) | (r << 16) | (g << 8) | (b << 0);
output[w] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
}
}
}
#if defined(__SSE2__)
// :( TODO: Make this saner.
static inline void store_bgr24_sse2(void *output, __m128i a, __m128i b, __m128i c, __m128i d)
/* :( TODO: Make this saner. */
static inline void store_bgr24_sse2(void *output, __m128i a,
__m128i b, __m128i c, __m128i d)
{
const __m128i mask_0 = _mm_set_epi32(0, 0, 0, 0x00ffffff);
const __m128i mask_1 = _mm_set_epi32(0, 0, 0x00ffffff, 0);
@ -371,13 +386,16 @@ static inline void store_bgr24_sse2(void *output, __m128i a, __m128i b, __m128i
__m128i *out = (__m128i*)output;
_mm_storeu_si128(out + 0,
_mm_or_si128(a0, _mm_or_si128(a1, _mm_or_si128(a2, _mm_or_si128(a3, _mm_or_si128(a4, a5))))));
_mm_or_si128(a0, _mm_or_si128(a1, _mm_or_si128(a2,
_mm_or_si128(a3, _mm_or_si128(a4, a5))))));
_mm_storeu_si128(out + 1,
_mm_or_si128(b0, _mm_or_si128(b1, _mm_or_si128(b2, _mm_or_si128(b3, _mm_or_si128(b4, b5))))));
_mm_or_si128(b0, _mm_or_si128(b1, _mm_or_si128(b2,
_mm_or_si128(b3, _mm_or_si128(b4, b5))))));
_mm_storeu_si128(out + 2,
_mm_or_si128(c0, _mm_or_si128(c1, _mm_or_si128(c2, _mm_or_si128(c3, _mm_or_si128(c4, c5))))));
_mm_or_si128(c0, _mm_or_si128(c1, _mm_or_si128(c2,
_mm_or_si128(c3, _mm_or_si128(c4, c5))))));
}
void conv_0rgb1555_bgr24(void *output_, const void *input_,
@ -396,7 +414,8 @@ void conv_0rgb1555_bgr24(void *output_, const void *input_,
int max_width = width - 15;
for (h = 0; h < height; h++, output += out_stride, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride, input += in_stride >> 1)
{
uint8_t *out = output;
@ -427,12 +446,16 @@ void conv_0rgb1555_bgr24(void *output_, const void *input_,
__m128i res_hi_ra0 = _mm_unpackhi_epi8(r0, a);
__m128i res_hi_ra1 = _mm_unpackhi_epi8(r1, a);
__m128i res_lo0 = _mm_or_si128(res_lo_bg0, _mm_slli_si128(res_lo_ra0, 2));
__m128i res_lo1 = _mm_or_si128(res_lo_bg1, _mm_slli_si128(res_lo_ra1, 2));
__m128i res_hi0 = _mm_or_si128(res_hi_bg0, _mm_slli_si128(res_hi_ra0, 2));
__m128i res_hi1 = _mm_or_si128(res_hi_bg1, _mm_slli_si128(res_hi_ra1, 2));
__m128i res_lo0 = _mm_or_si128(res_lo_bg0,
_mm_slli_si128(res_lo_ra0, 2));
__m128i res_lo1 = _mm_or_si128(res_lo_bg1,
_mm_slli_si128(res_lo_ra1, 2));
__m128i res_hi0 = _mm_or_si128(res_hi_bg0,
_mm_slli_si128(res_hi_ra0, 2));
__m128i res_hi1 = _mm_or_si128(res_hi_bg1,
_mm_slli_si128(res_hi_ra1, 2));
// Non-POT pixel sizes ftl :(
/* Non-POT pixel sizes ftl :( */
store_bgr24_sse2(out, res_lo0, res_hi0, res_lo1, res_hi1);
}
@ -502,10 +525,14 @@ void conv_rgb565_bgr24(void *output_, const void *input_,
__m128i res_lo_ra1 = _mm_unpacklo_epi8(r1, a);
__m128i res_hi_ra1 = _mm_unpackhi_epi8(r1, a);
__m128i res_lo0 = _mm_or_si128(res_lo_bg0, _mm_slli_si128(res_lo_ra0, 2));
__m128i res_hi0 = _mm_or_si128(res_hi_bg0, _mm_slli_si128(res_hi_ra0, 2));
__m128i res_lo1 = _mm_or_si128(res_lo_bg1, _mm_slli_si128(res_lo_ra1, 2));
__m128i res_hi1 = _mm_or_si128(res_hi_bg1, _mm_slli_si128(res_hi_ra1, 2));
__m128i res_lo0 = _mm_or_si128(res_lo_bg0,
_mm_slli_si128(res_lo_ra0, 2));
__m128i res_hi0 = _mm_or_si128(res_hi_bg0,
_mm_slli_si128(res_hi_ra0, 2));
__m128i res_lo1 = _mm_or_si128(res_lo_bg1,
_mm_slli_si128(res_lo_ra1, 2));
__m128i res_hi1 = _mm_or_si128(res_hi_bg1,
_mm_slli_si128(res_hi_ra1, 2));
store_bgr24_sse2(out, res_lo0, res_hi0, res_lo1, res_hi1);
}
@ -535,7 +562,8 @@ void conv_0rgb1555_bgr24(void *output_, const void *input_,
const uint16_t *input = (const uint16_t*)input_;
uint8_t *output = (uint8_t*)output_;
for (h = 0; h < height; h++, output += out_stride, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride, input += in_stride >> 1)
{
uint8_t *out = output;
for (w = 0; w < width; w++)
@ -563,7 +591,8 @@ void conv_rgb565_bgr24(void *output_, const void *input_,
const uint16_t *input = (const uint16_t*)input_;
uint8_t *output = (uint8_t*)output_;
for (h = 0; h < height; h++, output += out_stride, input += in_stride >> 1)
for (h = 0; h < height;
h++, output += out_stride, input += in_stride >> 1)
{
uint8_t *out = output;
for (w = 0; w < width; w++)
@ -592,7 +621,8 @@ void conv_bgr24_argb8888(void *output_, const void *input_,
const uint8_t *input = (const uint8_t*)input_;
uint32_t *output = (uint32_t*)output_;
for (h = 0; h < height; h++, output += out_stride >> 2, input += in_stride)
for (h = 0; h < height;
h++, output += out_stride >> 2, input += in_stride)
{
const uint8_t *inp = input;
for (w = 0; w < width; w++)
@ -613,7 +643,8 @@ void conv_argb8888_0rgb1555(void *output_, const void *input_,
const uint32_t *input = (const uint32_t*)input_;
uint16_t *output = (uint16_t*)output_;
for (h = 0; h < height; h++, output += out_stride >> 1, input += in_stride >> 2)
for (h = 0; h < height;
h++, output += out_stride >> 1, input += in_stride >> 2)
{
for (w = 0; w < width; w++)
{
@ -637,7 +668,8 @@ void conv_argb8888_bgr24(void *output_, const void *input_,
int max_width = width - 15;
for (h = 0; h < height; h++, output += out_stride, input += in_stride >> 2)
for (h = 0; h < height;
h++, output += out_stride, input += in_stride >> 2)
{
uint8_t *out = output;
@ -668,7 +700,8 @@ void conv_argb8888_bgr24(void *output_, const void *input_,
const uint32_t *input = (const uint32_t*)input_;
uint8_t *output = (uint8_t*)output_;
for (h = 0; h < height; h++, output += out_stride, input += in_stride >> 2)
for (h = 0; h < height;
h++, output += out_stride, input += in_stride >> 2)
{
uint8_t *out = output;
for (w = 0; w < width; w++)
@ -690,12 +723,14 @@ void conv_argb8888_abgr8888(void *output_, const void *input_,
const uint32_t *input = (const uint32_t*)input_;
uint32_t *output = (uint32_t*)output_;
for (h = 0; h < height; h++, output += out_stride >> 2, input += in_stride >> 2)
for (h = 0; h < height;
h++, output += out_stride >> 2, input += in_stride >> 2)
{
for (w = 0; w < width; w++)
{
uint32_t col = input[w];
output[w] = ((col << 16) & 0xff0000) | ((col >> 16) & 0xff) | (col & 0xff00ff00);
output[w] = ((col << 16) & 0xff0000) |
((col >> 16) & 0xff) | (col & 0xff00ff00);
}
}
}
@ -727,27 +762,28 @@ void conv_yuyv_argb8888(void *output_, const void *input_,
const __m128i u_b_mul = _mm_set1_epi16(YUV_MAT_U_B);
const __m128i v_r_mul = _mm_set1_epi16(YUV_MAT_V_R);
const __m128i v_g_mul = _mm_set1_epi16(YUV_MAT_V_G);
const __m128i a = _mm_cmpeq_epi16(_mm_setzero_si128(), _mm_setzero_si128());
const __m128i a = _mm_cmpeq_epi16(_mm_setzero_si128(),
_mm_setzero_si128());
for (h = 0; h < height; h++, output += out_stride >> 2, input += in_stride)
{
const uint8_t *src = input;
uint32_t *dst = output;
// Each loop processes 16 pixels.
/* Each loop processes 16 pixels. */
for (w = 0; w + 16 <= width; w += 16, src += 32, dst += 16)
{
__m128i yuv0 = _mm_loadu_si128((const __m128i*)(src + 0)); // [Y0, U0, Y1, V0, Y2, U1, Y3, V1, ...]
__m128i yuv1 = _mm_loadu_si128((const __m128i*)(src + 16)); // [Y0, U0, Y1, V0, Y2, U1, Y3, V1, ...]
__m128i yuv0 = _mm_loadu_si128((const __m128i*)(src + 0)); /* [Y0, U0, Y1, V0, Y2, U1, Y3, V1, ...] */
__m128i yuv1 = _mm_loadu_si128((const __m128i*)(src + 16)); /* [Y0, U0, Y1, V0, Y2, U1, Y3, V1, ...] */
__m128i y0 = _mm_and_si128(yuv0, mask_y); // [Y0, Y1, Y2, ...] (16-bit)
__m128i u0 = _mm_and_si128(yuv0, mask_u); // [0, U0, 0, 0, 0, U1, 0, 0, ...]
__m128i v0 = _mm_and_si128(yuv0, mask_v); // [0, 0, 0, V1, 0, , 0, V1, ...]
__m128i y1 = _mm_and_si128(yuv1, mask_y); // [Y0, Y1, Y2, ...] (16-bit)
__m128i u1 = _mm_and_si128(yuv1, mask_u); // [0, U0, 0, 0, 0, U1, 0, 0, ...]
__m128i v1 = _mm_and_si128(yuv1, mask_v); // [0, 0, 0, V1, 0, , 0, V1, ...]
__m128i y0 = _mm_and_si128(yuv0, mask_y); /* [Y0, Y1, Y2, ...] (16-bit) */
__m128i u0 = _mm_and_si128(yuv0, mask_u); /* [0, U0, 0, 0, 0, U1, 0, 0, ...] */
__m128i v0 = _mm_and_si128(yuv0, mask_v); /* [0, 0, 0, V1, 0, , 0, V1, ...] */
__m128i y1 = _mm_and_si128(yuv1, mask_y); /* [Y0, Y1, Y2, ...] (16-bit) */
__m128i u1 = _mm_and_si128(yuv1, mask_u); /* [0, U0, 0, 0, 0, U1, 0, 0, ...] */
__m128i v1 = _mm_and_si128(yuv1, mask_v); /* [0, 0, 0, V1, 0, , 0, V1, ...] */
// Juggle around to get U and V in the same 16-bit format as Y.
/* Juggle around to get U and V in the same 16-bit format as Y. */
u0 = _mm_srli_si128(u0, 1);
v0 = _mm_srli_si128(v0, 3);
u1 = _mm_srli_si128(u1, 1);
@ -755,17 +791,17 @@ void conv_yuyv_argb8888(void *output_, const void *input_,
__m128i u = _mm_packs_epi32(u0, u1);
__m128i v = _mm_packs_epi32(v0, v1);
// Apply YUV offsets (U, V) -= (-128, -128)
/* Apply YUV offsets (U, V) -= (-128, -128). */
u = _mm_sub_epi16(u, chroma_offset);
v = _mm_sub_epi16(v, chroma_offset);
// Upscale chroma horizontally (nearest)
/* Upscale chroma horizontally (nearest). */
u0 = _mm_unpacklo_epi16(u, u);
u1 = _mm_unpackhi_epi16(u, u);
v0 = _mm_unpacklo_epi16(v, v);
v1 = _mm_unpackhi_epi16(v, v);
// Apply transformations
/* Apply transformations. */
y0 = _mm_mullo_epi16(y0, yuv_mul);
y1 = _mm_mullo_epi16(y1, yuv_mul);
__m128i u0_g = _mm_mullo_epi16(u0, u_g_mul);
@ -777,21 +813,27 @@ void conv_yuyv_argb8888(void *output_, const void *input_,
__m128i v0_g = _mm_mullo_epi16(v0, v_g_mul);
__m128i v1_g = _mm_mullo_epi16(v1, v_g_mul);
// Add contibutions from the transformed components.
__m128i r0 = _mm_srai_epi16(_mm_adds_epi16(_mm_adds_epi16(y0, v0_r), round_offset), YUV_SHIFT);
__m128i g0 = _mm_srai_epi16(_mm_adds_epi16(_mm_adds_epi16(_mm_adds_epi16(y0, v0_g), u0_g), round_offset), YUV_SHIFT);
__m128i b0 = _mm_srai_epi16(_mm_adds_epi16(_mm_adds_epi16(y0, u0_b), round_offset), YUV_SHIFT);
/* Add contibutions from the transformed components. */
__m128i r0 = _mm_srai_epi16(_mm_adds_epi16(_mm_adds_epi16(y0, v0_r),
round_offset), YUV_SHIFT);
__m128i g0 = _mm_srai_epi16(_mm_adds_epi16(
_mm_adds_epi16(_mm_adds_epi16(y0, v0_g), u0_g), round_offset), YUV_SHIFT);
__m128i b0 = _mm_srai_epi16(_mm_adds_epi16(
_mm_adds_epi16(y0, u0_b), round_offset), YUV_SHIFT);
__m128i r1 = _mm_srai_epi16(_mm_adds_epi16(_mm_adds_epi16(y1, v1_r), round_offset), YUV_SHIFT);
__m128i g1 = _mm_srai_epi16(_mm_adds_epi16(_mm_adds_epi16(_mm_adds_epi16(y1, v1_g), u1_g), round_offset), YUV_SHIFT);
__m128i b1 = _mm_srai_epi16(_mm_adds_epi16(_mm_adds_epi16(y1, u1_b), round_offset), YUV_SHIFT);
__m128i r1 = _mm_srai_epi16(_mm_adds_epi16(
_mm_adds_epi16(y1, v1_r), round_offset), YUV_SHIFT);
__m128i g1 = _mm_srai_epi16(_mm_adds_epi16(
_mm_adds_epi16(_mm_adds_epi16(y1, v1_g), u1_g), round_offset), YUV_SHIFT);
__m128i b1 = _mm_srai_epi16(_mm_adds_epi16(
_mm_adds_epi16(y1, u1_b), round_offset), YUV_SHIFT);
// Saturate into 8-bit.
/* Saturate into 8-bit. */
r0 = _mm_packus_epi16(r0, r1);
g0 = _mm_packus_epi16(g0, g1);
b0 = _mm_packus_epi16(b0, b1);
// Interleave into ARGB.
/* Interleave into ARGB. */
__m128i res_lo_bg = _mm_unpacklo_epi8(b0, g0);
__m128i res_hi_bg = _mm_unpackhi_epi8(b0, g0);
__m128i res_lo_ra = _mm_unpacklo_epi8(r0, a);
@ -807,7 +849,7 @@ void conv_yuyv_argb8888(void *output_, const void *input_,
_mm_storeu_si128((__m128i*)(dst + 12), res3);
}
// Finish off the rest (if any) in C.
/* Finish off the rest (if any) in C. */
for (; w < width; w += 2, src += 4, dst += 2)
{
int y0 = src[0];
@ -837,7 +879,8 @@ void conv_yuyv_argb8888(void *output_, const void *input_,
const uint8_t *input = (const uint8_t*)input_;
uint32_t *output = (uint32_t*)output_;
for (h = 0; h < height; h++, output += out_stride >> 2, input += in_stride)
for (h = 0; h < height;
h++, output += out_stride >> 2, input += in_stride)
{
const uint8_t *src = input;
uint32_t *dst = output;
@ -876,7 +919,8 @@ void conv_copy(void *output_, const void *input_,
const uint8_t *input = (const uint8_t*)input_;
uint8_t *output = (uint8_t*)output_;
for (h = 0; h < height; h++, output += out_stride, input += in_stride)
for (h = 0; h < height;
h++, output += out_stride, input += in_stride)
memcpy(output, input, copy_len);
}

View File

@ -40,14 +40,18 @@ static bool allocate_frames(struct scaler_ctx *ctx)
ctx->scaled.stride = ((ctx->out_width + 7) & ~7) * sizeof(uint64_t);
ctx->scaled.width = ctx->out_width;
ctx->scaled.height = ctx->in_height;
ctx->scaled.frame = (uint64_t*)scaler_alloc(sizeof(uint64_t), (ctx->scaled.stride * ctx->scaled.height) >> 3);
ctx->scaled.frame = (uint64_t*)
scaler_alloc(sizeof(uint64_t),
(ctx->scaled.stride * ctx->scaled.height) >> 3);
if (!ctx->scaled.frame)
return false;
if (ctx->in_fmt != SCALER_FMT_ARGB8888)
{
ctx->input.stride = ((ctx->in_width + 7) & ~7) * sizeof(uint32_t);
ctx->input.frame = (uint32_t*)scaler_alloc(sizeof(uint32_t), (ctx->input.stride * ctx->in_height) >> 2);
ctx->input.frame = (uint32_t*)
scaler_alloc(sizeof(uint32_t),
(ctx->input.stride * ctx->in_height) >> 2);
if (!ctx->input.frame)
return false;
}
@ -55,7 +59,9 @@ static bool allocate_frames(struct scaler_ctx *ctx)
if (ctx->out_fmt != SCALER_FMT_ARGB8888)
{
ctx->output.stride = ((ctx->out_width + 7) & ~7) * sizeof(uint32_t);
ctx->output.frame = (uint32_t*)scaler_alloc(sizeof(uint32_t), (ctx->output.stride * ctx->out_height) >> 2);
ctx->output.frame = (uint32_t*)
scaler_alloc(sizeof(uint32_t),
(ctx->output.stride * ctx->out_height) >> 2);
if (!ctx->output.frame)
return false;
}
@ -67,29 +73,41 @@ static bool set_direct_pix_conv(struct scaler_ctx *ctx)
{
if (ctx->in_fmt == ctx->out_fmt)
ctx->direct_pixconv = conv_copy;
else if (ctx->in_fmt == SCALER_FMT_0RGB1555 && ctx->out_fmt == SCALER_FMT_ARGB8888)
else if (ctx->in_fmt == SCALER_FMT_0RGB1555
&& ctx->out_fmt == SCALER_FMT_ARGB8888)
ctx->direct_pixconv = conv_0rgb1555_argb8888;
else if (ctx->in_fmt == SCALER_FMT_RGB565 && ctx->out_fmt == SCALER_FMT_ARGB8888)
else if (ctx->in_fmt == SCALER_FMT_RGB565
&& ctx->out_fmt == SCALER_FMT_ARGB8888)
ctx->direct_pixconv = conv_rgb565_argb8888;
else if (ctx->in_fmt == SCALER_FMT_RGB565 && ctx->out_fmt == SCALER_FMT_BGR24)
else if (ctx->in_fmt == SCALER_FMT_RGB565
&& ctx->out_fmt == SCALER_FMT_BGR24)
ctx->direct_pixconv = conv_rgb565_bgr24;
else if (ctx->in_fmt == SCALER_FMT_0RGB1555 && ctx->out_fmt == SCALER_FMT_RGB565)
else if (ctx->in_fmt == SCALER_FMT_0RGB1555
&& ctx->out_fmt == SCALER_FMT_RGB565)
ctx->direct_pixconv = conv_0rgb1555_rgb565;
else if (ctx->in_fmt == SCALER_FMT_RGB565 && ctx->out_fmt == SCALER_FMT_0RGB1555)
else if (ctx->in_fmt == SCALER_FMT_RGB565
&& ctx->out_fmt == SCALER_FMT_0RGB1555)
ctx->direct_pixconv = conv_rgb565_0rgb1555;
else if (ctx->in_fmt == SCALER_FMT_BGR24 && ctx->out_fmt == SCALER_FMT_ARGB8888)
else if (ctx->in_fmt == SCALER_FMT_BGR24
&& ctx->out_fmt == SCALER_FMT_ARGB8888)
ctx->direct_pixconv = conv_bgr24_argb8888;
else if (ctx->in_fmt == SCALER_FMT_ARGB8888 && ctx->out_fmt == SCALER_FMT_0RGB1555)
else if (ctx->in_fmt == SCALER_FMT_ARGB8888
&& ctx->out_fmt == SCALER_FMT_0RGB1555)
ctx->direct_pixconv = conv_argb8888_0rgb1555;
else if (ctx->in_fmt == SCALER_FMT_ARGB8888 && ctx->out_fmt == SCALER_FMT_BGR24)
else if (ctx->in_fmt == SCALER_FMT_ARGB8888
&& ctx->out_fmt == SCALER_FMT_BGR24)
ctx->direct_pixconv = conv_argb8888_bgr24;
else if (ctx->in_fmt == SCALER_FMT_0RGB1555 && ctx->out_fmt == SCALER_FMT_BGR24)
else if (ctx->in_fmt == SCALER_FMT_0RGB1555
&& ctx->out_fmt == SCALER_FMT_BGR24)
ctx->direct_pixconv = conv_0rgb1555_bgr24;
else if (ctx->in_fmt == SCALER_FMT_ARGB8888 && ctx->out_fmt == SCALER_FMT_ABGR8888)
else if (ctx->in_fmt == SCALER_FMT_ARGB8888
&& ctx->out_fmt == SCALER_FMT_ABGR8888)
ctx->direct_pixconv = conv_argb8888_abgr8888;
else if (ctx->in_fmt == SCALER_FMT_YUYV && ctx->out_fmt == SCALER_FMT_ARGB8888)
else if (ctx->in_fmt == SCALER_FMT_YUYV
&& ctx->out_fmt == SCALER_FMT_ARGB8888)
ctx->direct_pixconv = conv_yuyv_argb8888;
else if (ctx->in_fmt == SCALER_FMT_RGBA4444 && ctx->out_fmt == SCALER_FMT_ARGB8888)
else if (ctx->in_fmt == SCALER_FMT_RGBA4444
&& ctx->out_fmt == SCALER_FMT_ARGB8888)
ctx->direct_pixconv = conv_rgba4444_argb8888;
else
return false;
@ -102,7 +120,7 @@ static bool set_pix_conv(struct scaler_ctx *ctx)
switch (ctx->in_fmt)
{
case SCALER_FMT_ARGB8888:
// No need to convert :D
/* No need to convert :D */
break;
case SCALER_FMT_0RGB1555:
@ -128,7 +146,7 @@ static bool set_pix_conv(struct scaler_ctx *ctx)
switch (ctx->out_fmt)
{
case SCALER_FMT_ARGB8888:
// No need to convert :D
/* No need to convert :D */
break;
case SCALER_FMT_0RGB1555:
@ -151,7 +169,7 @@ bool scaler_ctx_gen_filter(struct scaler_ctx *ctx)
scaler_ctx_gen_reset(ctx);
if (ctx->in_width == ctx->out_width && ctx->in_height == ctx->out_height)
ctx->unscaled = true; // Only pixel format conversion ...
ctx->unscaled = true; /* Only pixel format conversion ... */
else
{
ctx->scaler_horiz = scaler_argb8888_horiz;
@ -201,14 +219,16 @@ void scaler_ctx_gen_reset(struct scaler_ctx *ctx)
void scaler_ctx_scale(struct scaler_ctx *ctx,
void *output, const void *input)
{
if (ctx->unscaled) // Just perform straight pixel conversion.
if (ctx->unscaled)
{
/* Just perform straight pixel conversion. */
ctx->direct_pixconv(output, input,
ctx->out_width, ctx->out_height,
ctx->out_stride, ctx->in_stride);
}
else if (ctx->scaler_special) // Take some special, and (hopefully) more optimized path.
else if (ctx->scaler_special)
{
/* Take some special, and (hopefully) more optimized path. */
const void *inp = input;
int in_stride = ctx->in_stride;
@ -244,8 +264,9 @@ void scaler_ctx_scale(struct scaler_ctx *ctx,
ctx->out_stride, ctx->output.stride);
}
}
else // Take generic filter path.
else
{
/* Take generic filter path. */
if (ctx->in_fmt != SCALER_FMT_ARGB8888)
{
ctx->in_pixconv(ctx->input.frame, input,

View File

@ -18,8 +18,11 @@
#include "scaler.h"
void scaler_argb8888_vert(const struct scaler_ctx *ctx, void *output, int stride);
void scaler_argb8888_horiz(const struct scaler_ctx *ctx, const void *input, int stride);
void scaler_argb8888_vert(const struct scaler_ctx *ctx,
void *output, int stride);
void scaler_argb8888_horiz(const struct scaler_ctx *ctx,
const void *input, int stride);
void scaler_argb8888_point_special(const struct scaler_ctx *ctx,
void *output, const void *input,

View File

@ -32,9 +32,12 @@
#include "state_tracker.h"
//#define RARCH_CG_DEBUG
#if 0
#define RARCH_CG_DEBUG
#endif
// Used when we call deactivate() since just unbinding the program didn't seem to work... :(
/* Used when we call deactivate() since just unbinding
* the program didn't seem to work... */
static const char *stock_cg_program =
"struct input"
"{"
@ -149,7 +152,7 @@ static char cg_alias_define[GFX_MAX_SHADERS][128];
static void gl_cg_reset_attrib(void)
{
unsigned i;
// Add sanity check that we did not overflow.
/* Add sanity check that we did not overflow. */
rarch_assert(cg_attrib_index <= ARRAY_SIZE(cg_attribs));
for (i = 0; i < cg_attrib_index; i++)
@ -207,19 +210,22 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height,
{
(void)data;
unsigned i;
if (!cg_active || (active_index == 0) || (active_index == GL_SHADER_STOCK_BLEND))
if (!cg_active || (active_index == 0) ||
(active_index == GL_SHADER_STOCK_BLEND))
return;
// Set frame.
/* Set frame. */
set_param_2f(prg[active_index].vid_size_f, width, height);
set_param_2f(prg[active_index].tex_size_f, tex_width, tex_height);
set_param_2f(prg[active_index].out_size_f, out_width, out_height);
set_param_1f(prg[active_index].frame_dir_f, g_extern.frame_is_reverse ? -1.0 : 1.0);
set_param_1f(prg[active_index].frame_dir_f,
g_extern.frame_is_reverse ? -1.0 : 1.0);
set_param_2f(prg[active_index].vid_size_v, width, height);
set_param_2f(prg[active_index].tex_size_v, tex_width, tex_height);
set_param_2f(prg[active_index].out_size_v, out_width, out_height);
set_param_1f(prg[active_index].frame_dir_v, g_extern.frame_is_reverse ? -1.0 : 1.0);
set_param_1f(prg[active_index].frame_dir_v,
g_extern.frame_is_reverse ? -1.0 : 1.0);
if (prg[active_index].frame_cnt_f || prg[active_index].frame_cnt_v)
{
@ -231,7 +237,7 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height,
set_param_1f(prg[active_index].frame_cnt_v, (float)frame_count);
}
// Set orig texture.
/* Set orig texture. */
CGparameter param = prg[active_index].orig.tex;
if (param)
{
@ -239,18 +245,23 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height,
cgGLEnableTextureParameter(param);
}
set_param_2f(prg[active_index].orig.vid_size_v, info->input_size[0], info->input_size[1]);
set_param_2f(prg[active_index].orig.vid_size_f, info->input_size[0], info->input_size[1]);
set_param_2f(prg[active_index].orig.tex_size_v, info->tex_size[0], info->tex_size[1]);
set_param_2f(prg[active_index].orig.tex_size_f, info->tex_size[0], info->tex_size[1]);
set_param_2f(prg[active_index].orig.vid_size_v,
info->input_size[0], info->input_size[1]);
set_param_2f(prg[active_index].orig.vid_size_f,
info->input_size[0], info->input_size[1]);
set_param_2f(prg[active_index].orig.tex_size_v,
info->tex_size[0], info->tex_size[1]);
set_param_2f(prg[active_index].orig.tex_size_f,
info->tex_size[0], info->tex_size[1]);
if (prg[active_index].orig.coord)
{
cgGLSetParameterPointer(prg[active_index].orig.coord, 2, GL_FLOAT, 0, info->coord);
cgGLSetParameterPointer(prg[active_index].orig.coord, 2,
GL_FLOAT, 0, info->coord);
cgGLEnableClientState(prg[active_index].orig.coord);
cg_attribs[cg_attrib_index++] = prg[active_index].orig.coord;
}
// Set prev textures.
/* Set prev textures. */
for (i = 0; i < PREV_TEXTURES; i++)
{
param = prg[active_index].prev[i].tex;
@ -260,30 +271,38 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height,
cgGLEnableTextureParameter(param);
}
set_param_2f(prg[active_index].prev[i].vid_size_v, prev_info[i].input_size[0], prev_info[i].input_size[1]);
set_param_2f(prg[active_index].prev[i].vid_size_f, prev_info[i].input_size[0], prev_info[i].input_size[1]);
set_param_2f(prg[active_index].prev[i].tex_size_v, prev_info[i].tex_size[0], prev_info[i].tex_size[1]);
set_param_2f(prg[active_index].prev[i].tex_size_f, prev_info[i].tex_size[0], prev_info[i].tex_size[1]);
set_param_2f(prg[active_index].prev[i].vid_size_v,
prev_info[i].input_size[0], prev_info[i].input_size[1]);
set_param_2f(prg[active_index].prev[i].vid_size_f,
prev_info[i].input_size[0], prev_info[i].input_size[1]);
set_param_2f(prg[active_index].prev[i].tex_size_v,
prev_info[i].tex_size[0], prev_info[i].tex_size[1]);
set_param_2f(prg[active_index].prev[i].tex_size_f,
prev_info[i].tex_size[0], prev_info[i].tex_size[1]);
if (prg[active_index].prev[i].coord)
{
cgGLSetParameterPointer(prg[active_index].prev[i].coord, 2, GL_FLOAT, 0, prev_info[i].coord);
cgGLSetParameterPointer(prg[active_index].prev[i].coord,
2, GL_FLOAT, 0, prev_info[i].coord);
cgGLEnableClientState(prg[active_index].prev[i].coord);
cg_attribs[cg_attrib_index++] = prg[active_index].prev[i].coord;
}
}
// Set lookup textures.
/* Set lookup textures. */
for (i = 0; i < cg_shader->luts; i++)
{
CGparameter fparam = cgGetNamedParameter(prg[active_index].fprg, cg_shader->lut[i].id);
CGparameter fparam = cgGetNamedParameter(
prg[active_index].fprg, cg_shader->lut[i].id);
if (fparam)
{
cgGLSetTextureParameter(fparam, lut_textures[i]);
cgGLEnableTextureParameter(fparam);
}
CGparameter vparam = cgGetNamedParameter(prg[active_index].vprg, cg_shader->lut[i].id);
CGparameter vparam = cgGetNamedParameter(
prg[active_index].vprg, cg_shader->lut[i].id);
if (vparam)
{
cgGLSetTextureParameter(vparam, lut_textures[i]);
@ -291,55 +310,66 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height,
}
}
// Set FBO textures.
/* Set FBO textures. */
if (active_index)
{
for (i = 0; i < fbo_info_cnt; i++)
{
if (prg[active_index].fbo[i].tex)
{
cgGLSetTextureParameter(prg[active_index].fbo[i].tex, fbo_info[i].tex);
cgGLSetTextureParameter(
prg[active_index].fbo[i].tex, fbo_info[i].tex);
cgGLEnableTextureParameter(prg[active_index].fbo[i].tex);
}
set_param_2f(prg[active_index].fbo[i].vid_size_v, fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
set_param_2f(prg[active_index].fbo[i].vid_size_f, fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
set_param_2f(prg[active_index].fbo[i].vid_size_v,
fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
set_param_2f(prg[active_index].fbo[i].vid_size_f,
fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
set_param_2f(prg[active_index].fbo[i].tex_size_v, fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
set_param_2f(prg[active_index].fbo[i].tex_size_f, fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
set_param_2f(prg[active_index].fbo[i].tex_size_v,
fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
set_param_2f(prg[active_index].fbo[i].tex_size_f,
fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
if (prg[active_index].fbo[i].coord)
{
cgGLSetParameterPointer(prg[active_index].fbo[i].coord, 2, GL_FLOAT, 0, fbo_info[i].coord);
cgGLSetParameterPointer(prg[active_index].fbo[i].coord,
2, GL_FLOAT, 0, fbo_info[i].coord);
cgGLEnableClientState(prg[active_index].fbo[i].coord);
cg_attribs[cg_attrib_index++] = prg[active_index].fbo[i].coord;
}
}
}
// #pragma parameters
/* #pragma parameters. */
for (i = 0; i < cg_shader->num_parameters; i++)
{
CGparameter param_v = cgGetNamedParameter(prg[active_index].vprg, cg_shader->parameters[i].id);
CGparameter param_f = cgGetNamedParameter(prg[active_index].fprg, cg_shader->parameters[i].id);
CGparameter param_v = cgGetNamedParameter(
prg[active_index].vprg, cg_shader->parameters[i].id);
CGparameter param_f = cgGetNamedParameter(
prg[active_index].fprg, cg_shader->parameters[i].id);
set_param_1f(param_v, cg_shader->parameters[i].current);
set_param_1f(param_f, cg_shader->parameters[i].current);
}
// Set state parameters
/* Set state parameters. */
if (state_tracker)
{
// Only query uniforms in first pass.
/* Only query uniforms in first pass. */
static struct state_tracker_uniform info[MAX_VARIABLES];
static unsigned cnt = 0;
if (active_index == 1)
cnt = state_get_uniform(state_tracker, info, MAX_VARIABLES, frame_count);
cnt = state_get_uniform(state_tracker, info,
MAX_VARIABLES, frame_count);
for (i = 0; i < cnt; i++)
{
CGparameter param_v = cgGetNamedParameter(prg[active_index].vprg, info[i].id);
CGparameter param_f = cgGetNamedParameter(prg[active_index].fprg, info[i].id);
CGparameter param_v = cgGetNamedParameter(
prg[active_index].vprg, info[i].id);
CGparameter param_f = cgGetNamedParameter(
prg[active_index].fprg, info[i].id);
set_param_1f(param_v, info[i].value);
set_param_1f(param_f, info[i].value);
}
@ -353,7 +383,7 @@ static void gl_cg_deinit_progs(void)
cgGLUnbindProgram(cgFProf);
cgGLUnbindProgram(cgVProf);
// Programs may alias [0].
/* Programs may alias [0]. */
for (i = 1; i < GFX_MAX_SHADERS; i++)
{
if (prg[i].fprg && prg[i].fprg != prg[0].fprg)
@ -393,7 +423,7 @@ static void gl_cg_deinit_state(void)
cg_shader = NULL;
}
// Final deinit.
/* Final deinit. */
static void gl_cg_deinit_context_state(void)
{
if (cgCtx)
@ -404,7 +434,7 @@ static void gl_cg_deinit_context_state(void)
}
}
// Full deinit.
/* Full deinit. */
static void gl_cg_deinit(void)
{
gl_cg_deinit_state();
@ -418,7 +448,8 @@ static void gl_cg_deinit(void)
listing_##type = strdup(list); \
}
static bool load_program(unsigned index, const char *prog, bool path_is_file)
static bool load_program(unsigned index,
const char *prog, bool path_is_file)
{
bool ret = true;
char *listing_f = NULL;
@ -438,16 +469,20 @@ static bool load_program(unsigned index, const char *prog, bool path_is_file)
if (path_is_file)
{
prg[index].fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, prog, cgFProf, "main_fragment", argv);
prg[index].fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE,
prog, cgFProf, "main_fragment", argv);
SET_LISTING(f);
prg[index].vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, prog, cgVProf, "main_vertex", argv);
prg[index].vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE,
prog, cgVProf, "main_vertex", argv);
SET_LISTING(v);
}
else
{
prg[index].fprg = cgCreateProgram(cgCtx, CG_SOURCE, prog, cgFProf, "main_fragment", argv);
prg[index].fprg = cgCreateProgram(cgCtx, CG_SOURCE,
prog, cgFProf, "main_fragment", argv);
SET_LISTING(f);
prg[index].vprg = cgCreateProgram(cgCtx, CG_SOURCE, prog, cgVProf, "main_vertex", argv);
prg[index].vprg = cgCreateProgram(cgCtx, CG_SOURCE,
prog, cgVProf, "main_vertex", argv);
SET_LISTING(v);
}
@ -501,7 +536,8 @@ static bool load_plain(const char *path)
if (path)
{
RARCH_LOG("Loading Cg file: %s\n", path);
strlcpy(cg_shader->pass[0].source.path, path, sizeof(cg_shader->pass[0].source.path));
strlcpy(cg_shader->pass[0].source.path, path,
sizeof(cg_shader->pass[0].source.path));
if (!load_program(1, path, true))
return false;
}
@ -538,14 +574,16 @@ static bool load_imports(void)
memtype = -1u;
}
if ((memtype != -1u) && (cg_shader->variable[i].addr >= pretro_get_memory_size(memtype)))
if ((memtype != -1u) &&
(cg_shader->variable[i].addr >= pretro_get_memory_size(memtype)))
{
RARCH_ERR("Address out of bounds.\n");
return false;
}
}
tracker_info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
tracker_info.wram = (uint8_t*)
pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
tracker_info.info = cg_shader->variable;
tracker_info.info_elem = cg_shader->variables;
@ -556,7 +594,8 @@ static bool load_imports(void)
tracker_info.script_is_file = true;
}
tracker_info.script_class = *cg_shader->script_class ? cg_shader->script_class : NULL;
tracker_info.script_class =
*cg_shader->script_class ? cg_shader->script_class : NULL;
#endif
state_tracker = state_tracker_init(&tracker_info);
@ -609,13 +648,15 @@ static bool load_preset(const char *path)
if (cg_shader->passes > GFX_MAX_SHADERS - 3)
{
RARCH_WARN("Too many shaders ... Capping shader amount to %d.\n", GFX_MAX_SHADERS - 3);
RARCH_WARN("Too many shaders ... Capping shader amount to %d.\n",
GFX_MAX_SHADERS - 3);
cg_shader->passes = GFX_MAX_SHADERS - 3;
}
for (i = 0; i < cg_shader->passes; i++)
if (*cg_shader->pass[i].alias)
snprintf(cg_alias_define[i], sizeof(cg_alias_define[i]), "-D%s_ALIAS", cg_shader->pass[i].alias);
snprintf(cg_alias_define[i], sizeof(cg_alias_define[i]),
"-D%s_ALIAS", cg_shader->pass[i].alias);
for (i = 0; i < cg_shader->passes; i++)
{
@ -646,7 +687,8 @@ static void set_program_base_attrib(unsigned i)
CGparameter param = cgGetFirstParameter(prg[i].vprg, CG_PROGRAM);
for (; param; param = cgGetNextParameter(param))
{
if (cgGetParameterDirection(param) != CG_IN || cgGetParameterVariability(param) != CG_VARYING)
if (cgGetParameterDirection(param) != CG_IN
|| cgGetParameterVariability(param) != CG_VARYING)
continue;
const char *semantic = cgGetParameterSemantic(param);
@ -754,18 +796,26 @@ static void set_program_attributes(unsigned i)
"PREV6",
};
snprintf(attr_buf_tex, sizeof(attr_buf_tex), "%s.texture", prev_names[j]);
snprintf(attr_buf_vid_size, sizeof(attr_buf_vid_size), "%s.video_size", prev_names[j]);
snprintf(attr_buf_tex_size, sizeof(attr_buf_tex_size), "%s.texture_size", prev_names[j]);
snprintf(attr_buf_coord, sizeof(attr_buf_coord), "%s.tex_coord", prev_names[j]);
snprintf(attr_buf_tex, sizeof(attr_buf_tex),
"%s.texture", prev_names[j]);
snprintf(attr_buf_vid_size, sizeof(attr_buf_vid_size),
"%s.video_size", prev_names[j]);
snprintf(attr_buf_tex_size, sizeof(attr_buf_tex_size),
"%s.texture_size", prev_names[j]);
snprintf(attr_buf_coord, sizeof(attr_buf_coord),
"%s.tex_coord", prev_names[j]);
prg[i].prev[j].tex = cgGetNamedParameter(prg[i].fprg, attr_buf_tex);
prg[i].prev[j].vid_size_v = cgGetNamedParameter(prg[i].vprg, attr_buf_vid_size);
prg[i].prev[j].vid_size_f = cgGetNamedParameter(prg[i].fprg, attr_buf_vid_size);
prg[i].prev[j].vid_size_v =
cgGetNamedParameter(prg[i].vprg, attr_buf_vid_size);
prg[i].prev[j].vid_size_f =
cgGetNamedParameter(prg[i].fprg, attr_buf_vid_size);
prg[i].prev[j].tex_size_v = cgGetNamedParameter(prg[i].vprg, attr_buf_tex_size);
prg[i].prev[j].tex_size_f = cgGetNamedParameter(prg[i].fprg, attr_buf_tex_size);
prg[i].prev[j].tex_size_v =
cgGetNamedParameter(prg[i].vprg, attr_buf_tex_size);
prg[i].prev[j].tex_size_f =
cgGetNamedParameter(prg[i].fprg, attr_buf_tex_size);
prg[i].prev[j].coord = cgGetNamedParameter(prg[i].vprg, attr_buf_coord);
}
@ -838,13 +888,14 @@ static bool gl_cg_init(void *data, const char *path)
for (i = 1; i <= cg_shader->passes; i++)
set_program_attributes(i);
// If we aren't using last pass non-FBO shader,
// this shader will be assumed to be "fixed-function".
// Just use prg[0] for that pass, which will be
// pass-through.
/* If we aren't using last pass non-FBO shader,
* this shader will be assumed to be "fixed-function".
*
* Just use prg[0] for that pass, which will be
* pass-through. */
prg[cg_shader->passes + 1] = prg[0];
// No need to apply Android hack in Cg.
/* No need to apply Android hack in Cg. */
prg[GL_SHADER_STOCK_BLEND] = prg[0];
cgGLBindProgram(prg[1].fprg);

View File

@ -38,15 +38,18 @@ void gl_load_texture_data(GLuint obj, const struct texture_image *img,
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
#endif
glTexImage2D(GL_TEXTURE_2D,
0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, img->width, img->height,
0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, RARCH_GL_FORMAT32, img->pixels);
0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32,
img->width, img->height,
0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32,
RARCH_GL_FORMAT32, img->pixels);
#ifndef HAVE_PSGL
if (mipmap)
glGenerateMipmap(GL_TEXTURE_2D);
#endif
}
bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures)
bool gl_load_luts(const struct gfx_shader *generic_shader,
GLuint *lut_textures)
{
unsigned i;
unsigned num_luts = min(generic_shader->luts, GFX_MAX_TEXTURES);
@ -54,8 +57,9 @@ bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures)
if (!generic_shader->luts)
return true;
// Original shader_glsl.c code only generated one texture handle. I assume
// it was a bug, but if not, replace num_luts with 1 when GLSL is used.
/* Original shader_glsl.c code only generated one
* texture handle. I assume it was a bug, but if not,
* replace num_luts with 1 when GLSL is used. */
glGenTextures(num_luts, lut_textures);
for (i = 0; i < num_luts; i++)
{
@ -65,7 +69,8 @@ bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures)
if (!texture_image_load(&img, generic_shader->lut[i].path))
{
RARCH_ERR("Failed to load texture image from: \"%s\"\n", generic_shader->lut[i].path);
RARCH_ERR("Failed to load texture image from: \"%s\"\n",
generic_shader->lut[i].path);
return false;
}

View File

@ -81,7 +81,8 @@ struct gl_shader_backend
#ifdef HAVE_OPENGL
void gl_load_texture_data(GLuint obj, const struct texture_image *img,
GLenum wrap, bool linear, bool mipmap);
bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures);
bool gl_load_luts(const struct gfx_shader *generic_shader,
GLuint *lut_textures);
#endif
#endif

View File

@ -60,7 +60,7 @@ static unsigned gl_attrib_index;
static char glsl_alias_define[1024];
// Cache the VBO.
/* Cache the VBO. */
struct cache_vbo
{
GLuint vbo_primary;
@ -120,8 +120,8 @@ static const char *glsl_prefixes[] = {
"ruby",
};
// Need to duplicate these to work around broken stuff on Android.
// Must enforce alpha = 1.0 or 32-bit games can potentially go black.
/* Need to duplicate these to work around broken stuff on Android.
* Must enforce alpha = 1.0 or 32-bit games can potentially go black. */
static const char *stock_vertex_modern =
"attribute vec2 TexCoord;\n"
"attribute vec2 VertexCoord;\n"
@ -308,7 +308,8 @@ static void print_linker_log(GLuint obj)
free(info_log);
}
static bool compile_shader(GLuint shader, const char *define, const char *program)
static bool compile_shader(GLuint shader,
const char *define, const char *program)
{
char version[32] = {0};
if (glsl_core && !strstr(program, "#version"))
@ -354,7 +355,8 @@ static bool link_program(GLuint prog)
return false;
}
static GLuint compile_program(const char *vertex, const char *fragment, unsigned i)
static GLuint compile_program(const char *vertex,
const char *fragment, unsigned i)
{
GLuint prog = glCreateProgram();
if (!prog)
@ -367,7 +369,8 @@ static GLuint compile_program(const char *vertex, const char *fragment, unsigned
{
RARCH_LOG("Found GLSL vertex shader.\n");
vert = glCreateShader(GL_VERTEX_SHADER);
if (!compile_shader(vert, "#define VERTEX\n#define PARAMETER_UNIFORM\n", vertex))
if (!compile_shader(
vert, "#define VERTEX\n#define PARAMETER_UNIFORM\n", vertex))
{
RARCH_ERR("Failed to compile vertex shader #%u\n", i);
return 0;
@ -380,7 +383,8 @@ static GLuint compile_program(const char *vertex, const char *fragment, unsigned
{
RARCH_LOG("Found GLSL fragment shader.\n");
frag = glCreateShader(GL_FRAGMENT_SHADER);
if (!compile_shader(frag, "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", fragment))
if (!compile_shader(frag,
"#define FRAGMENT\n#define PARAMETER_UNIFORM\n", fragment))
{
RARCH_ERR("Failed to compile fragment shader #%u\n", i);
return 0;
@ -398,8 +402,9 @@ static GLuint compile_program(const char *vertex, const char *fragment, unsigned
return 0;
}
// Clean up dead memory. We're not going to relink the program.
// Detaching first seems to kill some mobile drivers (according to the intertubes anyways).
/* Clean up dead memory. We're not going to relink the program.
* Detaching first seems to kill some mobile drivers
* (according to the intertubes anyways). */
if (vert)
glDeleteShader(vert);
if (frag)
@ -414,7 +419,8 @@ static GLuint compile_program(const char *vertex, const char *fragment, unsigned
return prog;
}
static bool load_source_path(struct gfx_shader_pass *pass, const char *path)
static bool load_source_path(struct gfx_shader_pass *pass,
const char *path)
{
if (read_file(path, (void**)&pass->source.string.vertex) <= 0)
return false;
@ -430,9 +436,10 @@ static bool compile_programs(GLuint *gl_prog)
{
struct gfx_shader_pass *pass = &glsl_shader->pass[i];
// If we load from GLSLP (CGP),
// load the file here, and pretend
// we were really using XML all along.
/* If we load from GLSLP (CGP),
* load the file here, and pretend
* we were really using XML all along.
*/
if (*pass->source.path && !load_source_path(pass, pass->source.path))
{
RARCH_ERR("Failed to load GLSL shader: %s.\n", pass->source.path);
@ -458,7 +465,7 @@ static bool compile_programs(GLuint *gl_prog)
static void gl_glsl_reset_attrib(void)
{
unsigned i;
// Add sanity check that we did not overflow.
/* Add sanity check that we did not overflow. */
rarch_assert(gl_attrib_index <= ARRAY_SIZE(gl_attribs));
for (i = 0; i < gl_attrib_index; i++)
@ -466,25 +473,31 @@ static void gl_glsl_reset_attrib(void)
gl_attrib_index = 0;
}
static void gl_glsl_set_vbo(GLfloat **buffer, size_t *buffer_elems, const GLfloat *data, size_t elems)
static void gl_glsl_set_vbo(GLfloat **buffer, size_t *buffer_elems,
const GLfloat *data, size_t elems)
{
if (elems != *buffer_elems || memcmp(data, *buffer, elems * sizeof(GLfloat)))
if (elems != *buffer_elems ||
memcmp(data, *buffer, elems * sizeof(GLfloat)))
{
if (elems > *buffer_elems)
{
GLfloat *new_buffer = (GLfloat*)realloc(*buffer, elems * sizeof(GLfloat));
GLfloat *new_buffer = (GLfloat*)
realloc(*buffer, elems * sizeof(GLfloat));
rarch_assert(new_buffer);
*buffer = new_buffer;
}
memcpy(*buffer, data, elems * sizeof(GLfloat));
glBufferData(GL_ARRAY_BUFFER, elems * sizeof(GLfloat), data, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, elems * sizeof(GLfloat),
data, GL_STATIC_DRAW);
*buffer_elems = elems;
}
}
static void gl_glsl_set_attribs(GLuint vbo, GLfloat **buffer, size_t *buffer_elems,
const GLfloat *data, size_t elems, const struct glsl_attrib *attrs, size_t num_attrs)
static void gl_glsl_set_attribs(GLuint vbo,
GLfloat **buffer, size_t *buffer_elems,
const GLfloat *data, size_t elems,
const struct glsl_attrib *attrs, size_t num_attrs)
{
size_t i;
glBindBuffer(GL_ARRAY_BUFFER, vbo);
@ -517,7 +530,8 @@ static void clear_uniforms_frame(struct shader_uniforms_frame *frame)
frame->tex_coord = -1;
}
static void find_uniforms_frame(GLuint prog, struct shader_uniforms_frame *frame, const char *base)
static void find_uniforms_frame(GLuint prog,
struct shader_uniforms_frame *frame, const char *base)
{
char texture[64];
char texture_size[64];
@ -539,7 +553,8 @@ static void find_uniforms_frame(GLuint prog, struct shader_uniforms_frame *frame
frame->tex_coord = get_attrib(prog, tex_coord);
}
static void find_uniforms(unsigned pass, GLuint prog, struct shader_uniforms *uni)
static void find_uniforms(unsigned pass, GLuint prog,
struct shader_uniforms *uni)
{
unsigned i;
glUseProgram(prog);
@ -660,10 +675,13 @@ static bool gl_glsl_init(void *data, const char *path)
bool shader_support = glCreateProgram && glUseProgram && glCreateShader
&& glDeleteShader && glShaderSource && glCompileShader && glAttachShader
&& glDetachShader && glLinkProgram && glGetUniformLocation
&& glUniform1i && glUniform1f && glUniform2fv && glUniform4fv && glUniformMatrix4fv
&& glGetShaderiv && glGetShaderInfoLog && glGetProgramiv && glGetProgramInfoLog
&& glUniform1i && glUniform1f && glUniform2fv && glUniform4fv
&& glUniformMatrix4fv
&& glGetShaderiv && glGetShaderInfoLog && glGetProgramiv
&& glGetProgramInfoLog
&& glDeleteProgram && glGetAttachedShaders
&& glGetAttribLocation && glEnableVertexAttribArray && glDisableVertexAttribArray
&& glGetAttribLocation && glEnableVertexAttribArray
&& glDisableVertexAttribArray
&& glVertexAttribPointer
&& glGenBuffers && glBufferData && glDeleteBuffers && glBindBuffer;
@ -685,7 +703,8 @@ static bool gl_glsl_init(void *data, const char *path)
bool ret;
if (strcmp(path_get_extension(path), "glsl") == 0)
{
strlcpy(glsl_shader->pass[0].source.path, path, sizeof(glsl_shader->pass[0].source.path));
strlcpy(glsl_shader->pass[0].source.path, path,
sizeof(glsl_shader->pass[0].source.path));
glsl_shader->passes = 1;
glsl_shader->modern = true;
ret = true;
@ -714,8 +733,10 @@ static bool gl_glsl_init(void *data, const char *path)
{
RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
glsl_shader->passes = 1;
glsl_shader->pass[0].source.string.vertex = strdup(glsl_core ? stock_vertex_core : stock_vertex_modern);
glsl_shader->pass[0].source.string.fragment = strdup(glsl_core ? stock_fragment_core : stock_fragment_modern);
glsl_shader->pass[0].source.string.vertex =
strdup(glsl_core ? stock_vertex_core : stock_vertex_modern);
glsl_shader->pass[0].source.string.fragment =
strdup(glsl_core ? stock_fragment_core : stock_fragment_modern);
glsl_shader->modern = true;
}
@ -753,15 +774,16 @@ static bool gl_glsl_init(void *data, const char *path)
}
#endif
// Find all aliases we use in our GLSLP and add #defines for them so
// that a shader can choose a fallback if we are not using a preset.
/* Find all aliases we use in our GLSLP and add #defines for them so
* that a shader can choose a fallback if we are not using a preset. */
*glsl_alias_define = '\0';
for (i = 0; i < glsl_shader->passes; i++)
{
if (*glsl_shader->pass[i].alias)
{
char define[128];
snprintf(define, sizeof(define), "#define %s_ALIAS\n", glsl_shader->pass[i].alias);
snprintf(define, sizeof(define), "#define %s_ALIAS\n",
glsl_shader->pass[i].alias);
strlcat(glsl_alias_define, define, sizeof(glsl_alias_define));
}
}
@ -813,9 +835,13 @@ static bool gl_glsl_init(void *data, const char *path)
if (glsl_shader->modern)
{
gl_program[GL_SHADER_STOCK_BLEND] = compile_program(glsl_core ? stock_vertex_core_blend : stock_vertex_modern_blend,
glsl_core ? stock_fragment_core_blend : stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND);
find_uniforms(0, gl_program[GL_SHADER_STOCK_BLEND], &gl_uniforms[GL_SHADER_STOCK_BLEND]);
gl_program[GL_SHADER_STOCK_BLEND] = compile_program(glsl_core ?
stock_vertex_core_blend : stock_vertex_modern_blend,
glsl_core ?
stock_fragment_core_blend : stock_fragment_modern_blend,
GL_SHADER_STOCK_BLEND);
find_uniforms(0, gl_program[GL_SHADER_STOCK_BLEND],
&gl_uniforms[GL_SHADER_STOCK_BLEND]);
}
else
{
@ -890,7 +916,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
{
if (uni->lut_texture[i] >= 0)
{
// Have to rebind as HW render could override this.
/* Have to rebind as HW render could override this. */
glActiveTexture(GL_TEXTURE0 + texunit);
glBindTexture(GL_TEXTURE_2D, gl_teximage[i]);
glUniform1i(uni->lut_texture[i], texunit);
@ -898,12 +924,12 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
}
}
// Set original texture.
/* Set original texture. */
if (active_index)
{
if (uni->orig.texture >= 0)
{
// Bind original texture.
/* Bind original texture. */
glActiveTexture(GL_TEXTURE0 + texunit);
glUniform1i(uni->orig.texture, texunit);
glBindTexture(GL_TEXTURE_2D, info->tex);
@ -916,7 +942,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
if (uni->orig.input_size >= 0)
glUniform2fv(uni->orig.input_size, 1, info->input_size);
// Pass texture coordinates.
/* Pass texture coordinates. */
if (uni->orig.tex_coord >= 0)
{
attr->loc = uni->orig.tex_coord;
@ -929,7 +955,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
size += 8;
}
// Bind FBO textures.
/* Bind FBO textures. */
for (i = 0; i < fbo_info_cnt; i++)
{
if (uni->pass[i].texture)
@ -960,7 +986,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
}
}
// Set previous textures. Only bind if they're actually used.
/* Set previous textures. Only bind if they're actually used. */
for (i = 0; i < PREV_TEXTURES; i++)
{
if (uni->prev[i].texture >= 0)
@ -977,7 +1003,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
if (uni->prev[i].input_size >= 0)
glUniform2fv(uni->prev[i].input_size, 1, prev_info[i].input_size);
// Pass texture coordinates.
/* Pass texture coordinates. */
if (uni->prev[i].tex_coord >= 0)
{
attr->loc = uni->prev[i].tex_coord;
@ -1001,25 +1027,28 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
glActiveTexture(GL_TEXTURE0);
// #pragma parameters
/* #pragma parameters. */
for (i = 0; i < glsl_shader->num_parameters; i++)
{
int location = glGetUniformLocation(gl_program[active_index], glsl_shader->parameters[i].id);
int location = glGetUniformLocation(gl_program[active_index],
glsl_shader->parameters[i].id);
glUniform1f(location, glsl_shader->parameters[i].current);
}
// Set state parameters
/* Set state parameters. */
if (gl_state_tracker)
{
static struct state_tracker_uniform info[GFX_MAX_VARIABLES];
static unsigned cnt = 0;
if (active_index == 1)
cnt = state_get_uniform(gl_state_tracker, info, GFX_MAX_VARIABLES, frame_count);
cnt = state_get_uniform(gl_state_tracker, info,
GFX_MAX_VARIABLES, frame_count);
for (i = 0; i < cnt; i++)
{
int location = glGetUniformLocation(gl_program[active_index], info[i].id);
int location = glGetUniformLocation(gl_program[active_index],
info[i].id);
glUniform1f(location, info[i].value);
}
}
@ -1043,11 +1072,12 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
if (!glsl_enable || !glsl_shader->modern)
return false;
// Avoid hitting malloc on every single regular quad draw.
/* Avoid hitting malloc on every single regular quad draw. */
GLfloat short_buffer[4 * (2 + 2 + 4 + 2)];
GLfloat *buffer = short_buffer;
if (coords->vertices > 4)
buffer = (GLfloat*)calloc(coords->vertices * (2 + 2 + 4 + 2), sizeof(*buffer));
buffer = (GLfloat*)calloc(coords->vertices *
(2 + 2 + 4 + 2), sizeof(*buffer));
if (!buffer)
return false;
@ -1067,7 +1097,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
attribs_size++;
attr++;
memcpy(buffer + size, coords->tex_coord, 2 * coords->vertices * sizeof(GLfloat));
memcpy(buffer + size, coords->tex_coord,
2 * coords->vertices * sizeof(GLfloat));
size += 2 * coords->vertices;
}
@ -1079,7 +1110,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
attribs_size++;
attr++;
memcpy(buffer + size, coords->vertex, 2 * coords->vertices * sizeof(GLfloat));
memcpy(buffer + size, coords->vertex,
2 * coords->vertices * sizeof(GLfloat));
size += 2 * coords->vertices;
}
@ -1091,7 +1123,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
attribs_size++;
attr++;
memcpy(buffer + size, coords->color, 4 * coords->vertices * sizeof(GLfloat));
memcpy(buffer + size, coords->color,
4 * coords->vertices * sizeof(GLfloat));
size += 4 * coords->vertices;
}
@ -1103,7 +1136,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
attribs_size++;
attr++;
memcpy(buffer + size, coords->lut_tex_coord, 2 * coords->vertices * sizeof(GLfloat));
memcpy(buffer + size, coords->lut_tex_coord,
2 * coords->vertices * sizeof(GLfloat));
size += 2 * coords->vertices;
}
@ -1197,7 +1231,8 @@ void gl_glsl_set_get_proc_address(gfx_ctx_proc_t (*proc)(const char*))
glsl_get_proc_address = proc;
}
void gl_glsl_set_context_type(bool core_profile, unsigned major, unsigned minor)
void gl_glsl_set_context_type(bool core_profile,
unsigned major, unsigned minor)
{
glsl_core = core_profile;
glsl_major = major;

View File

@ -18,7 +18,7 @@
#include "shader_parse.h"
#ifdef _XBOX
#include <xtl.h>
#include "../xdk/xdk_d3d.h"
#include "d3d9/xdk_d3d.h"
#endif
static const char *stock_hlsl_program =

View File

@ -57,10 +57,10 @@ static enum gfx_wrap_type wrap_str_to_mode(const char *wrap_mode)
return RARCH_WRAP_DEFAULT;
}
// CGP
/* CGP */
static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass, unsigned i)
{
// Source
/* Source */
char shader_name[64];
print_buf(shader_name, "shader%u", i);
if (!config_get_path(conf, shader_name, pass->source.path, sizeof(pass->source.path)))
@ -69,7 +69,7 @@ static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass,
return false;
}
// Smooth
/* Smooth */
char filter_name_buf[64];
print_buf(filter_name_buf, "filter_linear%u", i);
bool smooth = false;
@ -78,21 +78,22 @@ static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass,
else
pass->filter = RARCH_FILTER_UNSPEC;
// Wrapping mode
/* Wrapping mode */
char wrap_name_buf[64];
print_buf(wrap_name_buf, "wrap_mode%u", i);
char wrap_mode[64];
if (config_get_array(conf, wrap_name_buf, wrap_mode, sizeof(wrap_mode)))
pass->wrap = wrap_str_to_mode(wrap_mode);
// Frame count mod
/* Frame count mod */
char frame_count_mod[64] = {0};
char frame_count_mod_buf[64];
print_buf(frame_count_mod_buf, "frame_count_mod%u", i);
if (config_get_array(conf, frame_count_mod_buf, frame_count_mod, sizeof(frame_count_mod)))
if (config_get_array(conf, frame_count_mod_buf,
frame_count_mod, sizeof(frame_count_mod)))
pass->frame_count_mod = strtoul(frame_count_mod, NULL, 0);
// FBO types and mipmapping
/* FBO types and mipmapping */
char srgb_output_buf[64];
print_buf(srgb_output_buf, "srgb_framebuffer%u", i);
config_get_bool(conf, srgb_output_buf, &pass->fbo.srgb_fbo);
@ -110,7 +111,7 @@ static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass,
if (!config_get_array(conf, alias_buf, pass->alias, sizeof(pass->alias)))
*pass->alias = '\0';
// Scale
/* Scale */
struct gfx_fbo_scale *scale = &pass->fbo;
char scale_type[64] = {0};
char scale_type_x[64] = {0};
@ -225,7 +226,8 @@ static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass,
return true;
}
static bool shader_parse_textures(config_file_t *conf, struct gfx_shader *shader)
static bool shader_parse_textures(config_file_t *conf,
struct gfx_shader *shader)
{
const char *id;
char *save;
@ -238,19 +240,22 @@ static bool shader_parse_textures(config_file_t *conf, struct gfx_shader *shader
id && shader->luts < GFX_MAX_TEXTURES;
shader->luts++, id = strtok_r(NULL, ";", &save))
{
if (!config_get_array(conf, id, shader->lut[shader->luts].path, sizeof(shader->lut[shader->luts].path)))
if (!config_get_array(conf, id, shader->lut[shader->luts].path,
sizeof(shader->lut[shader->luts].path)))
{
RARCH_ERR("Cannot find path to texture \"%s\" ...\n", id);
return false;
}
strlcpy(shader->lut[shader->luts].id, id, sizeof(shader->lut[shader->luts].id));
strlcpy(shader->lut[shader->luts].id, id,
sizeof(shader->lut[shader->luts].id));
char id_filter[64];
print_buf(id_filter, "%s_linear", id);
bool smooth = false;
if (config_get_bool(conf, id_filter, &smooth))
shader->lut[shader->luts].filter = smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST;
shader->lut[shader->luts].filter = smooth ?
RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST;
else
shader->lut[shader->luts].filter = RARCH_FILTER_UNSPEC;
@ -272,7 +277,8 @@ static bool shader_parse_textures(config_file_t *conf, struct gfx_shader *shader
return true;
}
static struct gfx_shader_parameter *find_parameter(struct gfx_shader_parameter *params, unsigned num_params, const char *id)
static struct gfx_shader_parameter *find_parameter(
struct gfx_shader_parameter *params, unsigned num_params, const char *id)
{
unsigned i;
for (i = 0; i < num_params; i++)
@ -283,14 +289,16 @@ static struct gfx_shader_parameter *find_parameter(struct gfx_shader_parameter *
return NULL;
}
bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shader)
bool gfx_shader_resolve_parameters(config_file_t *conf,
struct gfx_shader *shader)
{
unsigned i;
shader->num_parameters = 0;
struct gfx_shader_parameter *param = &shader->parameters[shader->num_parameters];
struct gfx_shader_parameter *param = (struct gfx_shader_parameter*)
&shader->parameters[shader->num_parameters];
// Find all parameters in our shaders.
/* Find all parameters in our shaders. */
for (i = 0; i < shader->passes; i++)
{
char line[2048];
@ -298,10 +306,13 @@ bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shade
if (!file)
continue;
while (shader->num_parameters < ARRAY_SIZE(shader->parameters) && fgets(line, sizeof(line), file))
while (shader->num_parameters < ARRAY_SIZE(shader->parameters)
&& fgets(line, sizeof(line), file))
{
int ret = sscanf(line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
param->id, param->desc, &param->initial, &param->minimum, &param->maximum, &param->step);
int ret = sscanf(line,
"#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
param->id, param->desc, &param->initial,
&param->minimum, &param->maximum, &param->step);
if (ret >= 5)
{
@ -312,7 +323,8 @@ bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shade
param->step = 0.1f * (param->maximum - param->minimum);
RARCH_LOG("Found #pragma parameter %s (%s) %f %f %f %f\n",
param->desc, param->id, param->initial, param->minimum, param->maximum, param->step);
param->desc, param->id, param->initial,
param->minimum, param->maximum, param->step);
param->current = param->initial;
shader->num_parameters++;
@ -323,19 +335,23 @@ bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shade
fclose(file);
}
// Read in parameters which override the defaults.
/* Read in parameters which override the defaults. */
if (conf)
{
char parameters[1024];
char *save = NULL;
const char *id;
if (!config_get_array(conf, "parameters", parameters, sizeof(parameters)))
if (!config_get_array(conf, "parameters",
parameters, sizeof(parameters)))
return true;
for (id = strtok_r(parameters, ";", &save); id; id = strtok_r(NULL, ";", &save))
for (id = strtok_r(parameters, ";", &save); id;
id = strtok_r(NULL, ";", &save))
{
struct gfx_shader_parameter *param = find_parameter(shader->parameters, shader->num_parameters, id);
struct gfx_shader_parameter *param = (struct gfx_shader_parameter*)
find_parameter(shader->parameters, shader->num_parameters, id);
if (!param)
{
RARCH_WARN("[CGP/GLSLP]: Parameter %s is set in the preset, but no shader uses this parameter, ignoring.\n", id);
@ -350,7 +366,8 @@ bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shade
return true;
}
static bool shader_parse_imports(config_file_t *conf, struct gfx_shader *shader)
static bool shader_parse_imports(config_file_t *conf,
struct gfx_shader *shader)
{
char imports[1024];
char *save = NULL;
@ -362,7 +379,9 @@ static bool shader_parse_imports(config_file_t *conf, struct gfx_shader *shader)
id && shader->variables < GFX_MAX_VARIABLES;
shader->variables++, id = strtok_r(NULL, ";", &save))
{
struct state_tracker_uniform_info *var = &shader->variable[shader->variables];
struct state_tracker_uniform_info *var =
(struct state_tracker_uniform_info*)
&shader->variable[shader->variables];
strlcpy(var->id, id, sizeof(var->id));
@ -442,8 +461,10 @@ static bool shader_parse_imports(config_file_t *conf, struct gfx_shader *shader)
var->equal = equal;
}
config_get_path(conf, "import_script", shader->script_path, sizeof(shader->script_path));
config_get_array(conf, "import_script_class", shader->script_class, sizeof(shader->script_class));
config_get_path(conf, "import_script",
shader->script_path, sizeof(shader->script_path));
config_get_array(conf, "import_script_class",
shader->script_class, sizeof(shader->script_class));
return true;
}
@ -483,7 +504,7 @@ bool gfx_shader_read_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
return true;
}
// CGP store
/* CGP store */
static const char *scale_type_to_str(enum gfx_scale_type type)
{
switch (type)
@ -513,7 +534,8 @@ static void shader_write_scale_dim(config_file_t *conf, const char *dim,
config_set_float(conf, key, scale);
}
static void shader_write_fbo(config_file_t *conf, const struct gfx_fbo_scale *fbo, unsigned i)
static void shader_write_fbo(config_file_t *conf,
const struct gfx_fbo_scale *fbo, unsigned i)
{
char key[64];
print_buf(key, "float_framebuffer%u", i);
@ -550,7 +572,8 @@ static const char *import_semantic_to_string(enum state_tracker_type type)
}
}
static void shader_write_variable(config_file_t *conf, const struct state_tracker_uniform_info *info)
static void shader_write_variable(config_file_t *conf,
const struct state_tracker_uniform_info *info)
{
const char *id = info->id;
@ -566,7 +589,8 @@ static void shader_write_variable(config_file_t *conf, const struct state_tracke
print_buf(mask_buf, "%s_mask", id);
print_buf(equal_buf, "%s_equal", id);
config_set_string(conf, semantic_buf, import_semantic_to_string(info->type));
config_set_string(conf, semantic_buf,
import_semantic_to_string(info->type));
config_set_hex(conf, mask_buf, info->mask);
config_set_hex(conf, equal_buf, info->equal);
@ -589,7 +613,8 @@ static void shader_write_variable(config_file_t *conf, const struct state_tracke
}
}
void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
void gfx_shader_write_conf_cgp(config_file_t *conf,
struct gfx_shader *shader)
{
unsigned i;
config_set_int(conf, "shaders", shader->passes);
@ -631,7 +656,7 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
strlcpy(parameters, shader->parameters[0].id, sizeof(parameters));
for (i = 1; i < shader->num_parameters; i++)
{
// O(n^2), but number of parameters is very limited.
/* O(n^2), but number of parameters is very limited. */
strlcat(parameters, ";", sizeof(parameters));
strlcat(parameters, shader->parameters[i].id, sizeof(parameters));
}
@ -639,7 +664,8 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
config_set_string(conf, "parameters", parameters);
for (i = 0; i < shader->num_parameters; i++)
config_set_float(conf, shader->parameters[i].id, shader->parameters[i].current);
config_set_float(conf, shader->parameters[i].id,
shader->parameters[i].current);
}
if (shader->luts)
@ -648,7 +674,7 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
strlcpy(textures, shader->lut[0].id, sizeof(textures));
for (i = 1; i < shader->luts; i++)
{
// O(n^2), but number of textures is very limited.
/* O(n^2), but number of textures is very limited. */
strlcat(textures, ";", sizeof(textures));
strlcat(textures, shader->lut[i].id, sizeof(textures));
}
@ -664,7 +690,8 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
if (shader->lut[i].filter != RARCH_FILTER_UNSPEC)
{
print_buf(key, "%s_linear", shader->lut[i].id);
config_set_bool(conf, key, shader->lut[i].filter == RARCH_FILTER_LINEAR);
config_set_bool(conf, key,
shader->lut[i].filter == RARCH_FILTER_LINEAR);
}
print_buf(key, "%s_wrap_mode", shader->lut[i].id);
@ -697,7 +724,8 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
}
}
enum rarch_shader_type gfx_shader_parse_type(const char *path, enum rarch_shader_type fallback)
enum rarch_shader_type gfx_shader_parse_type(const char *path,
enum rarch_shader_type fallback)
{
if (!path)
return fallback;
@ -712,7 +740,8 @@ enum rarch_shader_type gfx_shader_parse_type(const char *path, enum rarch_shader
return fallback;
}
void gfx_shader_resolve_relative(struct gfx_shader *shader, const char *ref_path)
void gfx_shader_resolve_relative(struct gfx_shader *shader,
const char *ref_path)
{
unsigned i;
char tmp_path[PATH_MAX];

View File

@ -65,7 +65,8 @@ enum
enum gfx_wrap_type
{
RARCH_WRAP_BORDER = 0, // Kinda deprecated, but keep as default. Will be translated to EDGE in GLES.
RARCH_WRAP_BORDER = 0, /* Kinda deprecated, but keep as default.
Will be translated to EDGE in GLES. */
RARCH_WRAP_DEFAULT = RARCH_WRAP_BORDER,
RARCH_WRAP_EDGE,
RARCH_WRAP_REPEAT,
@ -125,13 +126,13 @@ struct gfx_shader_lut
bool mipmap;
};
// This is pretty big, shouldn't be put on the stack.
// Avoid lots of allocation for convenience.
/* This is pretty big, shouldn't be put on the stack.
* Avoid lots of allocation for convenience. */
struct gfx_shader
{
enum rarch_shader_type type;
bool modern; // Only used for XML shaders.
bool modern; /* Only used for XML shaders. */
char prefix[64];
unsigned passes;
@ -146,17 +147,24 @@ struct gfx_shader
unsigned variables;
struct state_tracker_uniform_info variable[GFX_MAX_VARIABLES];
char script_path[PATH_MAX];
char *script; // Dynamically allocated. Must be free'd. Only used by XML.
char *script; /* Dynamically allocated. Must be free'd. Only used by XML. */
char script_class[512];
};
bool gfx_shader_read_conf_cgp(config_file_t *conf, struct gfx_shader *shader);
void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader);
bool gfx_shader_read_conf_cgp(config_file_t *conf,
struct gfx_shader *shader);
void gfx_shader_resolve_relative(struct gfx_shader *shader, const char *ref_path);
bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shader);
void gfx_shader_write_conf_cgp(config_file_t *conf,
struct gfx_shader *shader);
enum rarch_shader_type gfx_shader_parse_type(const char *path, enum rarch_shader_type fallback);
void gfx_shader_resolve_relative(struct gfx_shader *shader,
const char *ref_path);
bool gfx_shader_resolve_parameters(config_file_t *conf,
struct gfx_shader *shader);
enum rarch_shader_type gfx_shader_parse_type(const char *path,
enum rarch_shader_type fallback);
#ifdef __cplusplus
}

View File

@ -71,7 +71,9 @@ state_tracker_t* state_tracker_init(const struct state_tracker_info *info)
#ifdef HAVE_PYTHON
if (info->script)
{
tracker->py = py_state_new(info->script, info->script_is_file, info->script_class ? info->script_class : "GameAware");
tracker->py = py_state_new(info->script, info->script_is_file,
info->script_class ? info->script_class : "GameAware");
if (!tracker->py)
{
free(tracker);
@ -81,15 +83,18 @@ state_tracker_t* state_tracker_init(const struct state_tracker_info *info)
}
#endif
tracker->info = (struct state_tracker_internal*)calloc(info->info_elem, sizeof(struct state_tracker_internal));
tracker->info = (struct state_tracker_internal*)
calloc(info->info_elem, sizeof(struct state_tracker_internal));
tracker->info_elem = info->info_elem;
for (i = 0; i < info->info_elem; i++)
{
strlcpy(tracker->info[i].id, info->info[i].id, sizeof(tracker->info[i].id));
strlcpy(tracker->info[i].id, info->info[i].id,
sizeof(tracker->info[i].id));
tracker->info[i].addr = info->info[i].addr;
tracker->info[i].type = info->info[i].type;
tracker->info[i].mask = (info->info[i].mask == 0) ? 0xffff : info->info[i].mask;
tracker->info[i].mask = (info->info[i].mask == 0)
? 0xffff : info->info[i].mask;
tracker->info[i].equal = info->info[i].equal;
#ifdef HAVE_PYTHON
@ -106,7 +111,7 @@ state_tracker_t* state_tracker_init(const struct state_tracker_info *info)
}
#endif
// If we don't have a valid pointer.
/* If we don't have a valid pointer. */
static const uint8_t empty = 0;
switch (info->info[i].ram_type)
@ -217,7 +222,7 @@ static void update_element(
}
}
// Updates 16-bit input in same format as SNES itself.
/* Updates 16-bit input in same format as SNES itself. */
static void update_input(state_tracker_t *tracker)
{
unsigned i;
@ -239,24 +244,30 @@ static void update_input(state_tracker_t *tracker)
RETRO_DEVICE_ID_JOYPAD_B,
};
// Only bind for up to two players for now.
/* Only bind for up to two players for now. */
static const struct retro_keybind *binds[2] = {
g_settings.input.binds[0],
g_settings.input.binds[1],
};
for (i = 0; i < 2; i++)
input_push_analog_dpad(g_settings.input.binds[i], g_settings.input.analog_dpad_mode[i]);
input_push_analog_dpad(g_settings.input.binds[i],
g_settings.input.analog_dpad_mode[i]);
for (i = 0; i < MAX_PLAYERS; i++)
input_push_analog_dpad(g_settings.input.autoconf_binds[i], g_settings.input.analog_dpad_mode[i]);
input_push_analog_dpad(g_settings.input.autoconf_binds[i],
g_settings.input.analog_dpad_mode[i]);
uint16_t state[2] = {0};
if (!driver.block_libretro_input)
{
for (i = 4; i < 16; i++)
{
state[0] |= (driver.input->input_state(driver.input_data, binds, 0, RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i;
state[1] |= (driver.input->input_state(driver.input_data, binds, 1, RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i;
state[0] |= (driver.input->input_state(
driver.input_data, binds, 0,
RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i;
state[1] |= (driver.input->input_state(
driver.input_data, binds, 1,
RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i;
}
}
@ -269,7 +280,9 @@ static void update_input(state_tracker_t *tracker)
tracker->input_state[i] = state[i];
}
unsigned state_get_uniform(state_tracker_t *tracker, struct state_tracker_uniform *uniforms, unsigned elem, unsigned frame_count)
unsigned state_get_uniform(state_tracker_t *tracker,
struct state_tracker_uniform *uniforms,
unsigned elem, unsigned frame_count)
{
unsigned i, elems;
elems = tracker->info_elem < elem ? tracker->info_elem : elem;

View File

@ -78,9 +78,12 @@ struct state_tracker_uniform
typedef struct state_tracker state_tracker_t;
state_tracker_t* state_tracker_init(const struct state_tracker_info *info);
void state_tracker_free(state_tracker_t *tracker);
unsigned state_get_uniform(state_tracker_t *tracker, struct state_tracker_uniform *uniforms, unsigned elem, unsigned frame_count);
unsigned state_get_uniform(state_tracker_t *tracker,
struct state_tracker_uniform *uniforms,
unsigned elem, unsigned frame_count);
#ifdef __cplusplus
}

View File

@ -19,9 +19,10 @@
#include "../driver.h"
#include "../boolean.h"
// Starts a video driver in a new thread.
// Access to video driver will be mediated through this driver.
bool rarch_threaded_video_init(const video_driver_t **out_driver, void **out_data,
/* Starts a video driver in a new thread.
* Access to video driver will be mediated through this driver. */
bool rarch_threaded_video_init(
const video_driver_t **out_driver, void **out_data,
const input_driver_t **input, void **input_data,
const video_driver_t *driver, const video_info_t *info);

View File

@ -27,7 +27,7 @@ enum thread_cmd
CMD_INIT,
CMD_SET_SHADER,
CMD_FREE,
CMD_ALIVE, // Blocking alive check. Used when paused.
CMD_ALIVE, /* Blocking alive check. Used when paused. */
CMD_SET_ROTATION,
CMD_READ_VIEWPORT,
@ -133,7 +133,7 @@ typedef struct thread_video
} cmd_data;
struct rarch_viewport vp;
struct rarch_viewport read_vp; // Last viewport reported to caller.
struct rarch_viewport read_vp; /* Last viewport reported to caller. */
struct
{
@ -151,7 +151,8 @@ typedef struct thread_video
} thread_video_t;
static void *thread_init_never_call(const video_info_t *video, const input_driver_t **input, void **input_data)
static void *thread_init_never_call(const video_info_t *video,
const input_driver_t **input, void **input_data)
{
(void)video;
(void)input;
@ -184,7 +185,8 @@ static void thread_update_driver_state(thread_video_t *thr)
}
if (thr->poke && thr->poke->set_texture_enable)
thr->poke->set_texture_enable(thr->driver_data, thr->texture.enable, thr->texture.full_screen);
thr->poke->set_texture_enable(thr->driver_data,
thr->texture.enable, thr->texture.full_screen);
#endif
#if defined(HAVE_OVERLAY)
@ -225,13 +227,18 @@ static void thread_loop(void *data)
scond_wait(thr->cond_thread, thr->lock);
if (thr->frame.updated)
updated = true;
enum thread_cmd send_cmd = thr->send_cmd; // To avoid race condition where send_cmd is updated right after the switch is checked.
/* To avoid race condition where send_cmd is updated
* right after the switch is checked. */
enum thread_cmd send_cmd = thr->send_cmd;
slock_unlock(thr->lock);
switch (send_cmd)
{
case CMD_INIT:
thr->driver_data = thr->driver->init(&thr->info, thr->input, thr->input_data);
thr->driver_data = thr->driver->init(&thr->info,
thr->input, thr->input_data);
thr->cmd_data.b = thr->driver_data;
thr->driver->viewport_info(thr->driver_data, &thr->vp);
thread_reply(thr, CMD_INIT);
@ -257,22 +264,34 @@ static void thread_loop(void *data)
{
struct rarch_viewport vp = {0};
thr->driver->viewport_info(thr->driver_data, &vp);
if (memcmp(&vp, &thr->read_vp, sizeof(vp)) == 0) // We can read safely
if (memcmp(&vp, &thr->read_vp, sizeof(vp)) == 0)
{
// read_viewport() in GL driver calls rarch_render_cached_frame() to be able to read from back buffer.
// This means frame() callback in threaded wrapper will be called from this thread, causing a timeout, and no frame to be rendered.
// To avoid this, set a flag so wrapper can see if it's called in this "special" way.
/* We can read safely
*
* read_viewport() in GL driver calls
* rarch_render_cached_frame() to be able to read from
* back buffer.
*
* This means frame() callback in threaded wrapper will
* be called from this thread, causing a timeout, and
* no frame to be rendered.
*
* To avoid this, set a flag so wrapper can see if
* it's called in this "special" way. */
thr->frame.within_thread = true;
if (thr->driver && thr->driver->read_viewport)
ret = thr->driver->read_viewport(thr->driver_data, (uint8_t*)thr->cmd_data.v);
ret = thr->driver->read_viewport(thr->driver_data,
(uint8_t*)thr->cmd_data.v);
thr->cmd_data.b = ret;
thr->frame.within_thread = false;
thread_reply(thr, CMD_READ_VIEWPORT);
}
else // Viewport dimensions changed right after main thread read the async value. Cannot read safely.
else
{
/* Viewport dimensions changed right after main
* thread read the async value. Cannot read safely. */
thr->cmd_data.b = false;
thread_reply(thr, CMD_READ_VIEWPORT);
}
@ -313,9 +332,14 @@ static void thread_loop(void *data)
thr->cmd_data.b = ret;
thr->alpha_mods = thr->cmd_data.image.num;
thr->alpha_mod = (float*)realloc(thr->alpha_mod, thr->alpha_mods * sizeof(float));
for (i = 0; i < thr->alpha_mods; i++) // Avoid temporary garbage data.
thr->alpha_mod = (float*)realloc(thr->alpha_mod,
thr->alpha_mods * sizeof(float));
for (i = 0; i < thr->alpha_mods; i++)
{
/* Avoid temporary garbage data. */
thr->alpha_mod[i] = 1.0f;
}
thread_reply(thr, CMD_OVERLAY_LOAD);
break;
@ -344,7 +368,8 @@ static void thread_loop(void *data)
case CMD_OVERLAY_FULL_SCREEN:
if (thr->overlay && thr->overlay->full_screen)
thr->overlay->full_screen(thr->driver_data, thr->cmd_data.b);
thr->overlay->full_screen(thr->driver_data,
thr->cmd_data.b);
thread_reply(thr, CMD_OVERLAY_FULL_SCREEN);
break;
#endif
@ -364,7 +389,8 @@ static void thread_loop(void *data)
break;
case CMD_NONE:
// Never reply on no command. Possible deadlock if thread sends command right after frame update.
/* Never reply on no command. Possible deadlock if
* thread sends command right after frame update. */
break;
default:
@ -458,20 +484,23 @@ static bool thread_frame(void *data, const void *frame_,
{
thread_video_t *thr = (thread_video_t*)data;
// If called from within read_viewport, we're actually in the driver thread, so just render directly.
/* If called from within read_viewport, we're actually in the
* driver thread, so just render directly. */
if (thr->frame.within_thread)
{
thread_update_driver_state(thr);
if (thr->driver && thr->driver->frame)
return thr->driver->frame(thr->driver_data, frame_, width, height, pitch, msg);
return thr->driver->frame(thr->driver_data, frame_,
width, height, pitch, msg);
return false;
}
RARCH_PERFORMANCE_INIT(thread_frame);
RARCH_PERFORMANCE_START(thread_frame);
unsigned copy_stride = width * (thr->info.rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
unsigned copy_stride = width * (thr->info.rgb32 ?
sizeof(uint32_t) : sizeof(uint16_t));
const uint8_t *src = (const uint8_t*)frame_;
uint8_t *dst = thr->frame.buffer;
@ -480,9 +509,11 @@ static bool thread_frame(void *data, const void *frame_,
if (!thr->nonblock)
{
retro_time_t target_frame_time = (retro_time_t)roundf(1000000LL / g_settings.video.refresh_rate);
retro_time_t target_frame_time = (retro_time_t)
roundf(1000000LL / g_settings.video.refresh_rate);
retro_time_t target = thr->last_time + target_frame_time;
// Ideally, use absolute time, but that is only a good idea on POSIX.
/* Ideally, use absolute time, but that is only a good idea on POSIX. */
while (thr->frame.updated)
{
retro_time_t current = rarch_get_time_usec();
@ -496,7 +527,8 @@ static bool thread_frame(void *data, const void *frame_,
}
}
// Drop frame if updated flag is still set, as thread is still working on last frame.
/* Drop frame if updated flag is still set, as thread is
* still working on last frame. */
if (!thr->frame.updated)
{
if (src)
@ -544,8 +576,8 @@ static void thread_set_nonblock_state(void *data, bool state)
thr->nonblock = state;
}
static bool thread_init(thread_video_t *thr, const video_info_t *info, const input_driver_t **input,
void **input_data)
static bool thread_init(thread_video_t *thr, const video_info_t *info,
const input_driver_t **input, void **input_data)
{
thr->lock = slock_new();
thr->alpha_lock = slock_new();
@ -578,7 +610,8 @@ static bool thread_init(thread_video_t *thr, const video_info_t *info, const inp
return thr->cmd_data.b;
}
static bool thread_set_shader(void *data, enum rarch_shader_type type, const char *path)
static bool thread_set_shader(void *data,
enum rarch_shader_type type, const char *path)
{
thread_video_t *thr = (thread_video_t*)data;
thr->cmd_data.set_shader.type = type;
@ -596,15 +629,18 @@ static void thread_set_rotation(void *data, unsigned rotation)
thread_wait_reply(thr, CMD_SET_ROTATION);
}
// This value is set async as stalling on the video driver for every query is too slow.
// This means this value might not be correct, so viewport reads are not supported for now.
/* This value is set async as stalling on the video driver for
* every query is too slow.
*
* This means this value might not be correct, so viewport
* reads are not supported for now. */
static void thread_viewport_info(void *data, struct rarch_viewport *vp)
{
thread_video_t *thr = (thread_video_t*)data;
slock_lock(thr->lock);
*vp = thr->vp;
// Explicitly mem-copied so we can use memcmp correctly later.
/* Explicitly mem-copied so we can use memcmp correctly later. */
memcpy(&thr->read_vp, &thr->vp, sizeof(thr->vp));
slock_unlock(thr->lock);
}
@ -655,7 +691,8 @@ static void thread_overlay_enable(void *data, bool state)
thread_wait_reply(thr, CMD_OVERLAY_ENABLE);
}
static bool thread_overlay_load(void *data, const struct texture_image *images, unsigned num_images)
static bool thread_overlay_load(void *data,
const struct texture_image *images, unsigned num_images)
{
thread_video_t *thr = (thread_video_t*)data;
thr->cmd_data.image.data = images;
@ -665,7 +702,8 @@ static bool thread_overlay_load(void *data, const struct texture_image *images,
return thr->cmd_data.b;
}
static void thread_overlay_tex_geom(void *data, unsigned index, float x, float y, float w, float h)
static void thread_overlay_tex_geom(void *data,
unsigned index, float x, float y, float w, float h)
{
thread_video_t *thr = (thread_video_t*)data;
thr->cmd_data.rect.index = index;
@ -677,7 +715,8 @@ static void thread_overlay_tex_geom(void *data, unsigned index, float x, float y
thread_wait_reply(thr, CMD_OVERLAY_TEX_GEOM);
}
static void thread_overlay_vertex_geom(void *data, unsigned index, float x, float y, float w, float h)
static void thread_overlay_vertex_geom(void *data,
unsigned index, float x, float y, float w, float h)
{
thread_video_t *thr = (thread_video_t*)data;
thr->cmd_data.rect.index = index;
@ -697,7 +736,7 @@ static void thread_overlay_full_screen(void *data, bool enable)
thread_wait_reply(thr, CMD_OVERLAY_FULL_SCREEN);
}
// We cannot wait for this to complete. Totally blocks the main thread.
/* We cannot wait for this to complete. Totally blocks the main thread. */
static void thread_overlay_set_alpha(void *data, unsigned index, float mod)
{
thread_video_t *thr = (thread_video_t*)data;
@ -716,7 +755,8 @@ static const video_overlay_interface_t thread_overlay = {
thread_overlay_set_alpha,
};
static void thread_get_overlay_interface(void *data, const video_overlay_interface_t **iface)
static void thread_get_overlay_interface(void *data,
const video_overlay_interface_t **iface)
{
thread_video_t *thr = (thread_video_t*)data;
*iface = &thread_overlay;
@ -748,7 +788,9 @@ static void thread_set_texture_frame(void *data, const void *frame,
thread_video_t *thr = (thread_video_t*)data;
slock_lock(thr->frame.lock);
size_t required = width * height * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
size_t required = width * height *
(rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
if (required > thr->texture.frame_cap)
{
thr->texture.frame = realloc(thr->texture.frame, required);
@ -786,7 +828,8 @@ static void thread_apply_state_changes(void *data)
slock_unlock(thr->frame.lock);
}
// This is read-only state which should not have any kind of race condition.
/* This is read-only state which should not
* have any kind of race condition. */
static struct gfx_shader *thread_get_current_shader(void *data)
{
thread_video_t *thr = (thread_video_t*)data;
@ -813,7 +856,8 @@ static const video_poke_interface_t thread_poke = {
thread_get_current_shader,
};
static void thread_get_poke_interface(void *data, const video_poke_interface_t **iface)
static void thread_get_poke_interface(void *data,
const video_poke_interface_t **iface)
{
thread_video_t *thr = (thread_video_t*)data;
@ -827,7 +871,7 @@ static void thread_get_poke_interface(void *data, const video_poke_interface_t *
}
static const video_driver_t video_thread = {
thread_init_never_call, // Should never be called directly.
thread_init_never_call, /* Should never be called directly. */
thread_frame,
thread_set_nonblock_state,
thread_alive,
@ -839,15 +883,17 @@ static const video_driver_t video_thread = {
thread_viewport_info,
thread_read_viewport,
#ifdef HAVE_OVERLAY
thread_get_overlay_interface, // get_overlay_interface
thread_get_overlay_interface, /* get_overlay_interface */
#endif
thread_get_poke_interface,
};
static void thread_set_callbacks(thread_video_t *thr, const video_driver_t *driver)
static void thread_set_callbacks(thread_video_t *thr,
const video_driver_t *driver)
{
thr->video_thread = video_thread;
// Disable optional features if not present.
/* Disable optional features if not present. */
if (!driver->read_viewport)
thr->video_thread.read_viewport = NULL;
if (!driver->set_rotation)
@ -859,13 +905,13 @@ static void thread_set_callbacks(thread_video_t *thr, const video_driver_t *driv
thr->video_thread.overlay_interface = NULL;
#endif
// Might have to optionally disable poke_interface features as well.
/* Might have to optionally disable poke_interface features as well. */
if (!thr->video_thread.poke_interface)
thr->video_thread.poke_interface = NULL;
}
bool rarch_threaded_video_init(const video_driver_t **out_driver, void **out_data,
const input_driver_t **input, void **input_data,
bool rarch_threaded_video_init(const video_driver_t **out_driver,
void **out_data, const input_driver_t **input, void **input_data,
const video_driver_t *driver, const video_info_t *info)
{
thread_video_t *thr = (thread_video_t*)calloc(1, sizeof(*thr));

View File

@ -35,7 +35,8 @@ static void *android_location_init(void)
jclass class;
struct android_app *android_app = (struct android_app*)g_android;
androidlocation_t *androidlocation = (androidlocation_t*)calloc(1, sizeof(androidlocation_t));
androidlocation_t *androidlocation = (androidlocation_t*)
calloc(1, sizeof(androidlocation_t));
if (!androidlocation)
return NULL;
@ -47,43 +48,53 @@ static void *android_location_init(void)
if (class == NULL)
goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationInit, class, "onLocationInit", "()V");
GET_METHOD_ID(env, androidlocation->onLocationInit, class,
"onLocationInit", "()V");
if (!androidlocation->onLocationInit)
goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationFree, class, "onLocationFree", "()V");
GET_METHOD_ID(env, androidlocation->onLocationFree, class,
"onLocationFree", "()V");
if (!androidlocation->onLocationFree)
goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationStart, class, "onLocationStart", "()V");
GET_METHOD_ID(env, androidlocation->onLocationStart, class,
"onLocationStart", "()V");
if (!androidlocation->onLocationStart)
goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationStop, class, "onLocationStop", "()V");
GET_METHOD_ID(env, androidlocation->onLocationStop, class,
"onLocationStop", "()V");
if (!androidlocation->onLocationStop)
goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationGetLatitude, class, "onLocationGetLatitude", "()D");
GET_METHOD_ID(env, androidlocation->onLocationGetLatitude, class,
"onLocationGetLatitude", "()D");
if (!androidlocation->onLocationGetLatitude)
goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationGetLongitude, class, "onLocationGetLongitude", "()D");
GET_METHOD_ID(env, androidlocation->onLocationGetLongitude, class,
"onLocationGetLongitude", "()D");
if (!androidlocation->onLocationGetLongitude)
goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationGetHorizontalAccuracy, class, "onLocationGetHorizontalAccuracy", "()D");
GET_METHOD_ID(env, androidlocation->onLocationGetHorizontalAccuracy,
class, "onLocationGetHorizontalAccuracy", "()D");
if (!androidlocation->onLocationGetHorizontalAccuracy)
goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationSetInterval, class, "onLocationSetInterval", "(II)V");
GET_METHOD_ID(env, androidlocation->onLocationSetInterval,
class, "onLocationSetInterval", "(II)V");
if (!androidlocation->onLocationSetInterval)
goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationHasChanged, class, "onLocationHasChanged", "()Z");
GET_METHOD_ID(env, androidlocation->onLocationHasChanged,
class, "onLocationHasChanged", "()Z");
if (!androidlocation->onLocationHasChanged)
goto dealloc;
CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationInit);
CALL_VOID_METHOD(env, android_app->activity->clazz,
androidlocation->onLocationInit);
return androidlocation;
dealloc:
@ -99,7 +110,8 @@ static void android_location_free(void *data)
if (!env)
return;
CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationFree);
CALL_VOID_METHOD(env, android_app->activity->clazz,
androidlocation->onLocationFree);
free(androidlocation);
}
@ -112,7 +124,8 @@ static bool android_location_start(void *data)
if (!env)
return false;
CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationStart);
CALL_VOID_METHOD(env, android_app->activity->clazz,
androidlocation->onLocationStart);
return true;
}
@ -125,10 +138,12 @@ static void android_location_stop(void *data)
if (!env)
return;
CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationStop);
CALL_VOID_METHOD(env, android_app->activity->clazz,
androidlocation->onLocationStop);
}
static bool android_location_get_position(void *data, double *latitude, double *longitude, double *horiz_accuracy,
static bool android_location_get_position(void *data, double *latitude,
double *longitude, double *horiz_accuracy,
double *vert_accuracy)
{
struct android_app *android_app = (struct android_app*)g_android;
@ -140,14 +155,18 @@ static bool android_location_get_position(void *data, double *latitude, double *
jdouble lat, lon, horiz_accu;
jboolean newLocation;
CALL_BOOLEAN_METHOD(env, newLocation, android_app->activity->clazz, androidlocation->onLocationHasChanged);
CALL_BOOLEAN_METHOD(env, newLocation, android_app->activity->clazz,
androidlocation->onLocationHasChanged);
if (!newLocation)
goto fail;
CALL_DOUBLE_METHOD(env, lat, android_app->activity->clazz, androidlocation->onLocationGetLatitude);
CALL_DOUBLE_METHOD(env, lon, android_app->activity->clazz, androidlocation->onLocationGetLongitude);
CALL_DOUBLE_METHOD(env, horiz_accu, android_app->activity->clazz, androidlocation->onLocationGetHorizontalAccuracy);
CALL_DOUBLE_METHOD(env, lat, android_app->activity->clazz,
androidlocation->onLocationGetLatitude);
CALL_DOUBLE_METHOD(env, lon, android_app->activity->clazz,
androidlocation->onLocationGetLongitude);
CALL_DOUBLE_METHOD(env, horiz_accu, android_app->activity->clazz,
androidlocation->onLocationGetHorizontalAccuracy);
if (lat != 0.0)
*latitude = lat;
@ -156,7 +175,8 @@ static bool android_location_get_position(void *data, double *latitude, double *
if (horiz_accu != 0.0)
*horiz_accuracy = horiz_accu;
/* TODO/FIXME - custom implement vertical accuracy since Android location API does not have it? */
/* TODO/FIXME - custom implement vertical accuracy since
* Android location API does not have it? */
*vert_accuracy = 0.0;
return true;
@ -169,7 +189,8 @@ fail:
return false;
}
static void android_location_set_interval(void *data, unsigned interval_ms, unsigned interval_distance)
static void android_location_set_interval(void *data, unsigned interval_ms,
unsigned interval_distance)
{
struct android_app *android_app = (struct android_app*)g_android;
androidlocation_t *androidlocation = (androidlocation_t*)data;
@ -177,7 +198,9 @@ static void android_location_set_interval(void *data, unsigned interval_ms, unsi
if (!env)
return;
CALL_VOID_METHOD_PARAM(env, android_app->activity->clazz, androidlocation->onLocationSetInterval, (int)interval_ms, (int)interval_distance);
CALL_VOID_METHOD_PARAM(env, android_app->activity->clazz,
androidlocation->onLocationSetInterval, (int)interval_ms,
(int)interval_distance);
}
const location_driver_t location_android = {

View File

@ -37,7 +37,8 @@ static void null_location_stop(void *data)
(void)data;
}
static bool null_location_get_position(void *data, double *latitude, double *longitude, double *horiz_accuracy,
static bool null_location_get_position(void *data, double *latitude,
double *longitude, double *horiz_accuracy,
double *vert_accuracy)
{
*latitude = 0.0;
@ -47,7 +48,8 @@ static bool null_location_get_position(void *data, double *latitude, double *lon
return true;
}
static void null_location_set_interval(void *data, unsigned interval_ms, unsigned interval_distance)
static void null_location_set_interval(void *data,
unsigned interval_ms, unsigned interval_distance)
{
}

View File

@ -74,15 +74,15 @@ struct ff_video_info
uint8_t *outbuf;
size_t outbuf_size;
// Output pixel format.
/* Output pixel format. */
enum PixelFormat pix_fmt;
// Input pixel format. Only used by sws.
/* Input pixel format. Only used by sws. */
enum PixelFormat in_pix_fmt;
unsigned frame_drop_ratio;
unsigned frame_drop_count;
// Input pixel size.
/* Input pixel size. */
size_t pix_size;
AVFormatContext *format;
@ -380,9 +380,11 @@ static bool ffmpeg_init_video(ffmpeg_t *handle)
video->encoder = codec;
/* Don't use swscaler unless format is not something "in-house" scaler supports.
* libswscale doesn't scale RGB -> RGB correctly (goes via YUV first), and it's non-trivial to fix
* upstream as it's heavily geared towards YUV.
/* Don't use swscaler unless format is not something "in-house" scaler
* supports.
*
* libswscale doesn't scale RGB -> RGB correctly (goes via YUV first),
* and it's non-trivial to fix upstream as it's heavily geared towards YUV.
* If we're dealing with strange formats or YUV, just use libswscale.
*/
if (params->out_pix_fmt != PIX_FMT_NONE)
@ -446,8 +448,10 @@ static bool ffmpeg_init_video(ffmpeg_t *handle)
video->codec->codec_type = AVMEDIA_TYPE_VIDEO;
video->codec->width = param->out_width;
video->codec->height = param->out_height;
video->codec->time_base = av_d2q((double)params->frame_drop_ratio /param->fps, 1000000); /* Arbitrary big number. */
video->codec->sample_aspect_ratio = av_d2q(param->aspect_ratio * param->out_height / param->out_width, 255);
video->codec->time_base = av_d2q((double)
params->frame_drop_ratio /param->fps, 1000000); /* Arbitrary big number. */
video->codec->sample_aspect_ratio = av_d2q(
param->aspect_ratio * param->out_height / param->out_width, 255);
video->codec->pix_fmt = video->pix_fmt;
video->codec->thread_count = params->threads;
@ -468,8 +472,7 @@ static bool ffmpeg_init_video(ffmpeg_t *handle)
return false;
/* Allocate a big buffer. ffmpeg API doesn't seem to give us some
* clues how big this buffer should be.
*/
* clues how big this buffer should be. */
video->outbuf_size = 1 << 23;
video->outbuf = (uint8_t*)av_malloc(video->outbuf_size);
@ -769,7 +772,8 @@ static bool ffmpeg_push_video(void *data,
if (!handle || !video_data)
return false;
drop_frame = handle->video.frame_drop_count++ % handle->video.frame_drop_ratio;
drop_frame = handle->video.frame_drop_count++ %
handle->video.frame_drop_ratio;
handle->video.frame_drop_count %= handle->video.frame_drop_ratio;
@ -940,7 +944,8 @@ static void ffmpeg_scale_input(ffmpeg_t *handle,
handle->video.scaler.out_width = handle->params.out_width;
handle->video.scaler.out_height = handle->params.out_height;
handle->video.scaler.out_stride = handle->video.conv_frame->linesize[0];
handle->video.scaler.out_stride =
handle->video.conv_frame->linesize[0];
scaler_ctx_gen_filter(&handle->video.scaler);
}
@ -1010,10 +1015,12 @@ static void planarize_audio(ffmpeg_t *handle)
if (handle->audio.use_float)
planarize_float((float*)handle->audio.planar_buf,
(const float*)handle->audio.buffer, handle->audio.frames_in_buffer);
(const float*)handle->audio.buffer,
handle->audio.frames_in_buffer);
else
planarize_s16((int16_t*)handle->audio.planar_buf,
(const int16_t*)handle->audio.buffer, handle->audio.frames_in_buffer);
(const int16_t*)handle->audio.buffer,
handle->audio.frames_in_buffer);
}
static bool encode_audio(ffmpeg_t *handle, AVPacket *pkt, bool dry)
@ -1152,13 +1159,17 @@ static bool ffmpeg_push_audio_thread(ffmpeg_t *handle,
size_t written_frames = 0;
while (written_frames < data->frames)
{
size_t can_write = handle->audio.codec->frame_size - handle->audio.frames_in_buffer;
size_t can_write = handle->audio.codec->frame_size -
handle->audio.frames_in_buffer;
size_t write_left = data->frames - written_frames;
size_t write_frames = write_left > can_write ? can_write : write_left;
size_t write_size = write_frames * handle->params.channels * handle->audio.sample_size;
size_t write_size = write_frames *
handle->params.channels * handle->audio.sample_size;
size_t bytes_in_buffer = handle->audio.frames_in_buffer * handle->params.channels * handle->audio.sample_size;
size_t written_bytes = written_frames * handle->params.channels * handle->audio.sample_size;
size_t bytes_in_buffer = handle->audio.frames_in_buffer *
handle->params.channels * handle->audio.sample_size;
size_t written_bytes = written_frames *
handle->params.channels * handle->audio.sample_size;
memcpy(handle->audio.buffer + bytes_in_buffer,
(const uint8_t*)data->data + written_bytes,
@ -1167,7 +1178,8 @@ static bool ffmpeg_push_audio_thread(ffmpeg_t *handle,
written_frames += write_frames;
handle->audio.frames_in_buffer += write_frames;
if ((handle->audio.frames_in_buffer < (size_t)handle->audio.codec->frame_size) && require_block)
if ((handle->audio.frames_in_buffer
< (size_t)handle->audio.codec->frame_size) && require_block)
break;
AVPacket pkt;
@ -1224,12 +1236,17 @@ static void ffmpeg_flush_video(ffmpeg_t *handle)
static void ffmpeg_flush_buffers(ffmpeg_t *handle)
{
void *video_buf = av_malloc(2 * handle->params.fb_width * handle->params.fb_height * handle->video.pix_size);
size_t audio_buf_size = handle->config.audio_enable ? (handle->audio.codec->frame_size * handle->params.channels * sizeof(int16_t)) : 0;
void *video_buf = av_malloc(2 * handle->params.fb_width *
handle->params.fb_height * handle->video.pix_size);
size_t audio_buf_size = handle->config.audio_enable ?
(handle->audio.codec->frame_size *
handle->params.channels * sizeof(int16_t)) : 0;
void *audio_buf = audio_buf_size ? av_malloc(audio_buf_size) : NULL;
/* Try pushing data in an interleaving pattern to ease the work of the muxer a bit. */
/* Try pushing data in an interleaving pattern to
* ease the work of the muxer a bit. */
bool did_work;
do
{
did_work = false;
@ -1253,7 +1270,8 @@ static void ffmpeg_flush_buffers(ffmpeg_t *handle)
if (fifo_read_avail(handle->attr_fifo) >= sizeof(attr_buf))
{
fifo_read(handle->attr_fifo, &attr_buf, sizeof(attr_buf));
fifo_read(handle->video_fifo, video_buf, attr_buf.height * attr_buf.pitch);
fifo_read(handle->video_fifo, video_buf,
attr_buf.height * attr_buf.pitch);
attr_buf.data = video_buf;
ffmpeg_push_video_thread(handle, &attr_buf);
@ -1296,11 +1314,14 @@ static void ffmpeg_thread(void *data)
{
ffmpeg_t *ff = (ffmpeg_t*)data;
/* For some reason, FFmpeg has a tendency to crash if we don't overallocate a bit. */
void *video_buf = av_malloc(2 * ff->params.fb_width * ff->params.fb_height * ff->video.pix_size);
/* For some reason, FFmpeg has a tendency to crash
* if we don't overallocate a bit. */
void *video_buf = av_malloc(2 * ff->params.fb_width *
ff->params.fb_height * ff->video.pix_size);
assert(video_buf);
size_t audio_buf_size = ff->config.audio_enable ? (ff->audio.codec->frame_size * ff->params.channels * sizeof(int16_t)) : 0;
size_t audio_buf_size = ff->config.audio_enable ?
(ff->audio.codec->frame_size * ff->params.channels * sizeof(int16_t)) : 0;
void *audio_buf = audio_buf_size ? av_malloc(audio_buf_size) : NULL;
while (ff->alive)
@ -1338,7 +1359,8 @@ static void ffmpeg_thread(void *data)
{
slock_lock(ff->lock);
fifo_read(ff->attr_fifo, &attr_buf, sizeof(attr_buf));
fifo_read(ff->video_fifo, video_buf, attr_buf.height * attr_buf.pitch);
fifo_read(ff->video_fifo, video_buf,
attr_buf.height * attr_buf.pitch);
slock_unlock(ff->lock);
scond_signal(ff->cond);

View File

@ -1507,6 +1507,20 @@ int setting_data_get_description(const char *label, char *msg,
else if (!strcmp(label, "menu_toggle"))
snprintf(msg, sizeof_msg,
" -- Toggles menu.");
else if (!strcmp(label, "input_bind_device_id"))
snprintf(msg, sizeof_msg,
" -- Input Device. \n"
" \n"
"Picks which gamepad to use for player N. \n"
"The name of the pad is available."
);
else if (!strcmp(label, "input_bind_device_type"))
snprintf(msg, sizeof_msg,
" -- Input Device Type. \n"
" \n"
"Picks which device type to use. This is \n"
"relevant for the libretro core itself."
);
else
snprintf(msg, sizeof_msg,
"-- No info on this item is available. --\n");
@ -1732,6 +1746,74 @@ void setting_data_get_label(char *type_str,
driver.menu->shader, type_str, type_str_size,
menu_label, label, type);
}
else if (!strcmp(label, "input_bind_device_id"))
{
int map = g_settings.input.joypad_map
[driver.menu->current_pad];
if (map >= 0 && map < MAX_PLAYERS)
{
const char *device_name =
g_settings.input.device_names[map];
if (*device_name)
strlcpy(type_str, device_name, type_str_size);
else
snprintf(type_str, type_str_size,
"N/A (port #%d)", map);
}
else
strlcpy(type_str, "Disabled", type_str_size);
}
else if (!strcmp(label, "input_bind_device_type"))
{
const struct retro_controller_description *desc = NULL;
if (driver.menu->current_pad < g_extern.system.num_ports)
desc = libretro_find_controller_description(
&g_extern.system.ports[driver.menu->current_pad],
g_settings.input.libretro_device
[driver.menu->current_pad]);
const char *name = desc ? desc->desc : NULL;
if (!name)
{
/* Find generic name. */
switch (g_settings.input.libretro_device
[driver.menu->current_pad])
{
case RETRO_DEVICE_NONE:
name = "None";
break;
case RETRO_DEVICE_JOYPAD:
name = "RetroPad";
break;
case RETRO_DEVICE_ANALOG:
name = "RetroPad w/ Analog";
break;
default:
name = "Unknown";
break;
}
}
strlcpy(type_str, name, type_str_size);
}
else if (!strcmp(label, "input_bind_player_no"))
snprintf(type_str, type_str_size, "#%u",
driver.menu->current_pad + 1);
else if (!strcmp(label, "input_bind_analog_dpad_mode"))
{
static const char *modes[] = {
"None",
"Left Analog",
"Right Analog",
"Dual Analog",
};
strlcpy(type_str, modes[g_settings.input.analog_dpad_mode
[driver.menu->current_pad] % ANALOG_DPAD_LAST],
type_str_size);
}
else if (type >= MENU_SETTINGS_PERF_COUNTERS_BEGIN
&& type <= MENU_SETTINGS_PERF_COUNTERS_END)
menu_common_setting_set_label_perf(type_str, type_str_size, w, type,
@ -1802,78 +1884,6 @@ void setting_data_get_label(char *type_str,
case MENU_SETTINGS_CUSTOM_BIND_DEFAULT_ALL:
strlcpy(type_str, "...", type_str_size);
break;
case MENU_SETTINGS_BIND_PLAYER:
snprintf(type_str, type_str_size, "#%u",
driver.menu->current_pad + 1);
break;
case MENU_SETTINGS_BIND_DEVICE:
{
int map = g_settings.input.joypad_map
[driver.menu->current_pad];
if (map >= 0 && map < MAX_PLAYERS)
{
const char *device_name =
g_settings.input.device_names[map];
if (*device_name)
strlcpy(type_str, device_name, type_str_size);
else
snprintf(type_str, type_str_size,
"N/A (port #%d)", map);
}
else
strlcpy(type_str, "Disabled", type_str_size);
}
break;
case MENU_SETTINGS_BIND_ANALOG_MODE:
{
static const char *modes[] = {
"None",
"Left Analog",
"Right Analog",
"Dual Analog",
};
strlcpy(type_str, modes[g_settings.input.analog_dpad_mode
[driver.menu->current_pad] % ANALOG_DPAD_LAST],
type_str_size);
}
break;
case MENU_SETTINGS_BIND_DEVICE_TYPE:
{
const struct retro_controller_description *desc = NULL;
if (driver.menu->current_pad < g_extern.system.num_ports)
desc = libretro_find_controller_description(
&g_extern.system.ports[driver.menu->current_pad],
g_settings.input.libretro_device
[driver.menu->current_pad]);
const char *name = desc ? desc->desc : NULL;
if (!name)
{
/* Find generic name. */
switch (g_settings.input.libretro_device
[driver.menu->current_pad])
{
case RETRO_DEVICE_NONE:
name = "None";
break;
case RETRO_DEVICE_JOYPAD:
name = "RetroPad";
break;
case RETRO_DEVICE_ANALOG:
name = "RetroPad w/ Analog";
break;
default:
name = "Unknown";
break;
}
}
strlcpy(type_str, name, type_str_size);
}
break;
case MENU_SETTINGS_CUSTOM_BIND_MODE:
strlcpy(type_str, driver.menu->bind_mode_keyboard ?
"RetroKeyboard" : "RetroPad", type_str_size);
@ -2209,39 +2219,43 @@ rarch_setting_t *setting_data_get_mainmenu(bool regenerate)
START_GROUP("Main Menu")
START_SUB_GROUP("State")
#if defined(HAVE_DYNAMIC) || defined(HAVE_LIBRETRO_MANAGEMENT)
CONFIG_BOOL(lists[0], "core_list", "Core", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[0], "core_list", "Core", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
#endif
if (g_extern.history)
{
CONFIG_BOOL(lists[1], "history_list", "Load Content (History)", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[1], "history_list", "Load Content (History)", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
}
if (driver.menu && g_extern.core_info && core_info_list_num_info_files(g_extern.core_info))
{
CONFIG_BOOL(lists[2], "detect_core_list", "Load Content (Detect Core)", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[2], "detect_core_list", "Load Content (Detect Core)", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
}
CONFIG_BOOL(lists[3], "load_content", "Load Content", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[4], "core_options", "Core Options", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[5], "core_information", "Core Information", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[6], "settings", "Settings", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[3], "load_content", "Load Content", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
CONFIG_BOOL(lists[4], "core_options", "Core Options", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
CONFIG_BOOL(lists[5], "core_information", "Core Information", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
if (g_extern.main_is_init && !g_extern.libretro_dummy)
{
CONFIG_BOOL(lists[6], "disk_options", "Core Disk Options", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
}
CONFIG_BOOL(lists[7], "settings", "Settings", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
if (g_extern.perfcnt_enable)
{
CONFIG_BOOL(lists[7], "performance_counters", "Performance Counters", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[8], "performance_counters", "Performance Counters", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
}
if (g_extern.main_is_init && !g_extern.libretro_dummy)
{
CONFIG_BOOL(lists[8], "savestate", "Save State", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[9], "loadstate", "Load State", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[10], "take_screenshot", "Take Screenshot", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[11], "resume_content", "Resume Content", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[12], "restart_content", "Restart Content", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[9], "savestate", "Save State", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[10], "loadstate", "Load State", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[11], "take_screenshot", "Take Screenshot", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
CONFIG_BOOL(lists[12], "resume_content", "Resume Content", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
CONFIG_BOOL(lists[13], "restart_content", "Restart Content", false, "", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
}
#ifndef HAVE_DYNAMIC
CONFIG_BOOL(lists[13], "restart_retroarch", "Restart RetroArch", false, "", "",GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[14], "restart_retroarch", "Restart RetroArch", false, "", "",GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
#endif
CONFIG_BOOL(lists[14], "configurations", "Configurations", false, "", "",GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[15], "save_new_config", "Save New Config", false, "", "",GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[16], "help", "Help", false, "", "",GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[17], "quit_retroarch", "Quit RetroArch", false, "", "",GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[15], "configurations", "Configurations", false, "", "",GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(lists[16], "save_new_config", "Save New Config", false, "", "",GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
CONFIG_BOOL(lists[17], "help", "Help", false, "", "",GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
CONFIG_BOOL(lists[18], "quit_retroarch", "Quit RetroArch", false, "", "",GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_PUSH_ACTION)
END_SUB_GROUP()
END_GROUP()
@ -2293,7 +2307,7 @@ rarch_setting_t *setting_data_get_list(void)
/* General Options */
/*******************/
START_GROUP("General Options")
START_SUB_GROUP("General Options")
START_SUB_GROUP("State")
CONFIG_BOOL(g_extern.verbosity, "log_verbosity", "Logging Verbosity", false, "OFF", "ON", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_UINT(g_settings.libretro_log_level, "libretro_log_level", "Libretro Logging Level", libretro_log_level, GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_RANGE(0, 3, 1.0, true, true)
CONFIG_BOOL(g_extern.perfcnt_enable, "perfcnt_enable", "Performance Counters", false, "OFF", "ON", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
@ -2318,9 +2332,11 @@ rarch_setting_t *setting_data_get_list(void)
CONFIG_INT(g_settings.state_slot, "state_slot", "State Slot", 0, GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
END_SUB_GROUP()
START_SUB_GROUP("Miscellaneous")
#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY)
CONFIG_BOOL(g_settings.network_cmd_enable, "network_cmd_enable", "Network Commands", network_cmd_enable, "OFF", "ON", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
//CONFIG_INT(g_settings.network_cmd_port, "network_cmd_port", "Network Command Port", network_cmd_port, GROUP_NAME, SUBGROUP_NAME, NULL)
CONFIG_BOOL(g_settings.stdin_cmd_enable, "stdin_cmd_enable", "stdin command", stdin_cmd_enable, "OFF", "ON", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
#endif
END_SUB_GROUP()
END_GROUP()
@ -2446,7 +2462,7 @@ rarch_setting_t *setting_data_get_list(void)
END_SUB_GROUP()
START_SUB_GROUP("Miscellaneous")
CONFIG_STRING(g_settings.audio.device, "audio_device", "Device", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_STRING(g_settings.audio.device, "audio_device", "Device", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_ALLOW_INPUT)
CONFIG_UINT(g_settings.audio.out_rate, "audio_out_rate", "Audio Output Rate", out_rate, GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_PATH(g_settings.audio.dsp_plugin, "audio_dsp_plugin", "DSP Plugin", g_settings.audio.filter_dir, GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_ALLOW_EMPTY) WITH_VALUES("dsp")
END_SUB_GROUP()
@ -2532,12 +2548,12 @@ rarch_setting_t *setting_data_get_list(void)
START_SUB_GROUP("State")
CONFIG_BOOL(g_extern.netplay_enable, "netplay_enable", "Netplay Enable", false, "OFF", "ON", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
#ifdef HAVE_NETPLAY
CONFIG_STRING(g_extern.netplay_server, "netplay_ip_address", "IP Address", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_STRING(g_extern.netplay_server, "netplay_ip_address", "IP Address", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_ALLOW_INPUT)
#endif
CONFIG_BOOL(g_extern.netplay_is_client, "netplay_mode", "Netplay Client Enable", false, "OFF", "ON", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_BOOL(g_extern.netplay_is_spectate, "netplay_spectator_mode_enable", "Netplay Spectator Enable", false, "OFF", "ON", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_UINT(g_extern.netplay_sync_frames, "netplay_delay_frames", "Netplay Delay Frames", 0, GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_RANGE(0, 10, 1, true, false)
CONFIG_UINT(g_extern.netplay_port, "netplay_tcp_udp_port", "Netplay TCP/UDP Port", RARCH_DEFAULT_PORT, GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_RANGE(1, 99999, 1, true, true)
CONFIG_UINT(g_extern.netplay_port, "netplay_tcp_udp_port", "Netplay TCP/UDP Port", RARCH_DEFAULT_PORT, GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_RANGE(1, 99999, 1, true, true) WITH_FLAGS(SD_FLAG_ALLOW_INPUT)
END_SUB_GROUP()
END_GROUP()
#endif
@ -2547,8 +2563,8 @@ rarch_setting_t *setting_data_get_list(void)
/*******************/
START_GROUP("User Options")
START_SUB_GROUP("State")
CONFIG_STRING(g_settings.username, "netplay_nickname", "Username", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_UINT(g_settings.user_language, "user_language", "Language", def_user_language, GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_RANGE(0, RETRO_LANGUAGE_LAST-1, 1, true, true)
CONFIG_STRING(g_settings.username, "netplay_nickname", "Username", "", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_FLAGS(SD_FLAG_ALLOW_INPUT)
CONFIG_UINT(g_settings.user_language, "user_language", "Language", def_user_language, GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_RANGE(0, RETRO_LANGUAGE_LAST-1, 1, true, true) WITH_FLAGS(SD_FLAG_ALLOW_INPUT)
END_SUB_GROUP()
END_GROUP()

View File

@ -47,11 +47,13 @@ enum setting_type
enum setting_flags
{
SD_FLAG_PATH_DIR = 1,
SD_FLAG_PATH_FILE = 2,
SD_FLAG_ALLOW_EMPTY = 4,
SD_FLAG_VALUE_DESC = 8,
SD_FLAG_HAS_RANGE = 16
SD_FLAG_PATH_DIR = (1 << 0),
SD_FLAG_PATH_FILE = (1 << 1),
SD_FLAG_ALLOW_EMPTY = (1 << 2),
SD_FLAG_VALUE_DESC = (1 << 3),
SD_FLAG_HAS_RANGE = (1 << 4),
SD_FLAG_ALLOW_INPUT = (1 << 5),
SD_FLAG_PUSH_ACTION = (1 << 6),
};
typedef struct rarch_setting_t

Some files were not shown because too many files have changed in this diff Show More