mirror of
https://github.com/libretro/RetroArch
synced 2025-03-15 22:21:01 +00:00
Merge remote-tracking branch 'upstream/master' into zip_support
This commit is contained in:
commit
4d65063a83
@ -96,7 +96,9 @@
|
||||
96355CE01788E72A0010DBFA /* Products */,
|
||||
96355CE91788E72A0010DBFA /* Supporting Files */,
|
||||
);
|
||||
indentWidth = 3;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 3;
|
||||
};
|
||||
96355CE01788E72A0010DBFA /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
|
@ -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)
|
||||
|
@ -97,7 +97,9 @@
|
||||
96355CE01788E72A0010DBFA /* Products */,
|
||||
96355CE91788E72A0010DBFA /* Supporting Files */,
|
||||
);
|
||||
indentWidth = 3;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 3;
|
||||
};
|
||||
96355CE01788E72A0010DBFA /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
|
@ -150,7 +150,9 @@
|
||||
96AFAE2616C1D4EA009DE44C /* Products */,
|
||||
96AFAE3416C1D4EA009DE44C /* Supporting Files */,
|
||||
);
|
||||
indentWidth = 3;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 3;
|
||||
};
|
||||
96AFAE2616C1D4EA009DE44C /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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); \
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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';
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
245
config.def.h
245
config.def.h
@ -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 },
|
||||
|
@ -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++)
|
||||
|
@ -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;
|
||||
|
30
driver.h
30
driver.h
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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"))
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
18
general.h
18
general.h
@ -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];
|
||||
|
||||
|
@ -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"
|
||||
|
201
gfx/d3d9/d3d.cpp
201
gfx/d3d9/d3d.cpp
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
71
gfx/filter.c
71
gfx/filter.c
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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++)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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++)
|
||||
|
@ -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
|
||||
}
|
||||
|
26
gfx/gl.c
26
gfx/gl.c
@ -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,
|
||||
|
151
gfx/gx/gx_gfx.c
151
gfx/gx/gx_gfx.c
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
145
gfx/rpng/rpng.c
145
gfx/rpng/rpng.c
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
181
gfx/shader_cg.c
181
gfx/shader_cg.c
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 =
|
||||
|
@ -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, ¶m->initial, ¶m->minimum, ¶m->maximum, ¶m->step);
|
||||
int ret = sscanf(line,
|
||||
"#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
|
||||
param->id, param->desc, ¶m->initial,
|
||||
¶m->minimum, ¶m->maximum, ¶m->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];
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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 = {
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
208
settings_data.c
208
settings_data.c
@ -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()
|
||||
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user