This commit is contained in:
meancoot 2013-03-09 20:09:32 -05:00
commit 9fadca2a54
62 changed files with 2053 additions and 1533 deletions

View File

@ -62,7 +62,7 @@ CFLAGS += -DHAVE_FILE_LOGGER
CFLAGS += -Iconsole/logger
endif
CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RMENU -DHAVE_RGUI -DRARCH_CONSOLE -DGEKKO -DHAVE_ZLIB -DWANT_MINIZ -DHAVE_RARCH_MAIN_WRAP -DHAVE_RARCH_MAIN_IMPLEMENTATION -DHAVE_GRIFFIN=1 -DHAVE_SCREENSHOTS -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Wno-char-subscripts
CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DGEKKO -DHAVE_ZLIB -DWANT_MINIZ -DHAVE_RARCH_MAIN_WRAP -DHAVE_RARCH_MAIN_IMPLEMENTATION -DHAVE_GRIFFIN=1 -DHAVE_SCREENSHOTS -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Wno-char-subscripts
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g

View File

@ -8,7 +8,7 @@ INCDIR =
CFLAGS = -O2 -G0 -g -std=gnu99 -ffast-math
ASFLAGS = $(CFLAGS)
RARCH_DEFINES = -DPSP -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_FILEBROWSER -DHAVE_RARCH_MAIN_WRAP -DHAVE_RARCH_MAIN_IMPLEMENTATION -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_ZLIB -DWANT_MINIZ -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -DHAVE_NULLVIDEO -DHAVE_NULLAUDIO -DHAVE_RMENU
RARCH_DEFINES = -DPSP -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_FILEBROWSER -DHAVE_RARCH_MAIN_WRAP -DHAVE_RARCH_MAIN_IMPLEMENTATION -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_ZLIB -DWANT_MINIZ -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -DHAVE_NULLVIDEO -DHAVE_NULLAUDIO
ifeq ($(HAVE_FILE_LOGGER), 1)
CFLAGS += -DHAVE_FILE_LOGGER

View File

@ -65,7 +65,7 @@ CFLAGS += -Iconsole/logger
endif
CFLAGS += -std=gnu99 -DHAVE_SINC -DSINC_LOWER_QUALITY -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DHAVE_RMENU -DGEKKO -DHAVE_ZLIB -DWANT_MINIZ -DHAVE_RARCH_MAIN_WRAP -DHAVE_RARCH_MAIN_IMPLEMENTATION -DHAVE_GRIFFIN=1 -DHAVE_SCREENSHOTS -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Wno-char-subscripts
CFLAGS += -std=gnu99 -DHAVE_SINC -DSINC_LOWER_QUALITY -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RGUI -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DGEKKO -DHAVE_ZLIB -DWANT_MINIZ -DHAVE_RARCH_MAIN_WRAP -DHAVE_RARCH_MAIN_IMPLEMENTATION -DHAVE_GRIFFIN=1 -DHAVE_SCREENSHOTS -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Wno-char-subscripts
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g -DDEBUG

View File

@ -51,7 +51,7 @@ ifeq ($(PERF_TEST), 1)
LOCAL_CFLAGS += -DPERF_TEST
endif
LOCAL_CFLAGS += -Wall -pthread -Wno-unused-function -O3 -fno-stack-protector -funroll-loops -DNDEBUG -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_FBO -DHAVE_OVERLAY -DHAVE_OPENGLES -DHAVE_VID_CONTEXT -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_GLSL -DWANT_MINIZ -DHAVE_ZLIB -DINLINE=inline -DLSB_FIRST -DHAVE_THREADS -D__LIBRETRO__ -DRARCH_PERFORMANCE_MODE -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -std=gnu99 -I../../../deps/miniz
LOCAL_CFLAGS += -Wall -pthread -Wno-unused-function -O3 -fno-stack-protector -funroll-loops -DNDEBUG -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_FBO -DHAVE_OVERLAY -DHAVE_OPENGLES -DHAVE_VID_CONTEXT -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_GLSL -DHAVE_RGUI -DHAVE_SCREENSHOTS -DWANT_MINIZ -DHAVE_ZLIB -DINLINE=inline -DLSB_FIRST -DHAVE_THREADS -D__LIBRETRO__ -DRARCH_PERFORMANCE_MODE -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -std=gnu99 -I../../../deps/miniz
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -landroid -lEGL -lGLESv2 $(LOGGER_LDLIBS) -ldl

View File

@ -69,10 +69,6 @@ static int g_cpuCount;
# define DEFAULT_CPU_FAMILY ANDROID_CPU_FAMILY_UNKNOWN
#endif
#define D(...) \
do { \
} while (0)
#ifdef __i386__
static __inline__ void cpu_x86_cpuid(int func, int values[4])
{
@ -126,56 +122,53 @@ cpu_read_file(const char* pathname, char* buffer, size_t buffsize)
static char*
extract_cpuinfo_field(char* buffer, int buflen, const char* field)
{
int fieldlen = strlen(field);
char* bufend = buffer + buflen;
char* result = NULL;
int len;
const char *p, *q;
int fieldlen = strlen(field);
char* bufend = buffer + buflen;
char* result = NULL;
int len;
const char *p, *q;
/* Look for first field occurence, and ensures it starts the line.
*/
p = buffer;
bufend = buffer + buflen;
for (;;) {
p = memmem(p, bufend-p, field, fieldlen);
if (p == NULL)
goto EXIT;
/* Look for first field occurence, and ensures it starts the line.
*/
p = buffer;
bufend = buffer + buflen;
for (;;)
{
p = memmem(p, bufend-p, field, fieldlen);
if (p == NULL)
goto EXIT;
if (p == buffer || p[-1] == '\n')
break;
if (p == buffer || p[-1] == '\n')
break;
p += fieldlen;
}
p += fieldlen;
}
/* Skip to the first column followed by a space */
p += fieldlen;
p = memchr(p, ':', bufend-p);
if (p == NULL || p[1] != ' ')
goto EXIT;
/* Skip to the first column followed by a space */
p += fieldlen;
p = memchr(p, ':', bufend-p);
if (p == NULL || p[1] != ' ')
goto EXIT;
/* Find the end of the line */
p += 2;
q = memchr(p, '\n', bufend-p);
if (q == NULL)
q = bufend;
/* Find the end of the line */
p += 2;
q = memchr(p, '\n', bufend-p);
if (q == NULL)
q = bufend;
/* Copy the line into a heap-allocated buffer */
len = q-p;
result = malloc(len+1);
if (result == NULL)
goto EXIT;
/* Copy the line into a heap-allocated buffer */
len = q-p;
result = malloc(len+1);
if (result == NULL)
goto EXIT;
memcpy(result, p, len);
result[len] = '\0';
memcpy(result, p, len);
result[len] = '\0';
EXIT:
return result;
return result;
}
/* Like strlen(), but for constant string literals */
#define STRLEN_CONST(x) ((sizeof(x)-1)
/* Checks that a space-separated list of items contains one given 'item'.
* Returns 1 if found, 0 otherwise.
*/
@ -188,7 +181,8 @@ has_list_item(const char* list, const char* item)
if (list == NULL)
return 0;
while (*p) {
while (*p)
{
const char* q;
/* skip spaces */
@ -224,7 +218,8 @@ parse_decimal(const char* input, const char* limit, int* result)
{
const char* p = input;
int val = 0;
while (p < limit) {
while (p < limit)
{
int d = (*p - '0');
if ((unsigned)d >= 10U)
break;
@ -248,28 +243,6 @@ typedef struct {
uint32_t mask;
} CpuList;
static __inline__ void
cpulist_init(CpuList* list) {
list->mask = 0;
}
static __inline__ void
cpulist_and(CpuList* list1, CpuList* list2) {
list1->mask &= list2->mask;
}
static __inline__ void
cpulist_set(CpuList* list, int index) {
if ((unsigned)index < 32) {
list->mask |= (uint32_t)(1U << index);
}
}
static __inline__ int
cpulist_count(CpuList* list) {
return __builtin_popcount(list->mask);
}
/* Parse a textual list of cpus and store the result inside a CpuList object.
* Input format is the following:
* - comma-separated list of items (no spaces)
@ -280,73 +253,76 @@ cpulist_count(CpuList* list) {
* 2,4-127,128-143
* 0-1
*/
static void
cpulist_parse(CpuList* list, const char* line, int line_len)
static void cpulist_parse(CpuList* list, const char* line, int line_len)
{
const char* p = line;
const char* end = p + line_len;
const char* q;
const char* p = line;
const char* end = p + line_len;
const char* q;
/* NOTE: the input line coming from sysfs typically contains a
* trailing newline, so take care of it in the code below
*/
while (p < end && *p != '\n')
{
int val, start_value, end_value;
/* NOTE: the input line coming from sysfs typically contains a
* trailing newline, so take care of it in the code below
*/
while (p < end && *p != '\n')
{
int val, start_value, end_value;
/* Find the end of current item, and put it into 'q' */
q = memchr(p, ',', end-p);
if (q == NULL) {
q = end;
}
/* Find the end of current item, and put it into 'q' */
q = memchr(p, ',', end-p);
if (q == NULL)
q = end;
/* Get first value */
p = parse_decimal(p, q, &start_value);
if (p == NULL)
/* Get first value */
p = parse_decimal(p, q, &start_value);
if (p == NULL)
goto BAD_FORMAT;
end_value = start_value;
/* If we're not at the end of the item, expect a dash and
* and integer; extract end value.
*/
if (p < q && *p == '-')
{
p = parse_decimal(p+1, q, &end_value);
if (p == NULL)
goto BAD_FORMAT;
}
end_value = start_value;
/* Set bits CPU list bits */
for (val = start_value; val <= end_value; val++)
{
if ((unsigned)val < 32)
list->mask |= (uint32_t)(1U << val);
}
/* If we're not at the end of the item, expect a dash and
* and integer; extract end value.
*/
if (p < q && *p == '-') {
p = parse_decimal(p+1, q, &end_value);
if (p == NULL)
goto BAD_FORMAT;
}
/* Set bits CPU list bits */
for (val = start_value; val <= end_value; val++) {
cpulist_set(list, val);
}
/* Jump to next item */
p = q;
if (p < end)
p++;
}
/* Jump to next item */
p = q;
if (p < end)
p++;
}
BAD_FORMAT:
;
;
}
/* Read a CPU list from one sysfs file */
static void
cpulist_read_from(CpuList* list, const char* filename)
{
char file[64];
int filelen;
char file[64];
int filelen;
cpulist_init(list);
list->mask = 0;
filelen = cpu_read_file(filename, file, sizeof file);
if (filelen < 0) {
D("Could not read %s: %s\n", filename, strerror(errno));
return;
}
filelen = cpu_read_file(filename, file, sizeof file);
cpulist_parse(list, file, filelen);
if (filelen < 0)
{
RARCH_ERR("Could not read %s: %s\n", filename, strerror(errno));
return;
}
cpulist_parse(list, file, filelen);
}
/* Return the number of cpus present on a given device.
@ -355,192 +331,179 @@ cpulist_read_from(CpuList* list, const char* filename)
* intersection of the 'present' and 'possible' CPU lists and count
* the result.
*/
static int
get_cpu_count(void)
static int get_cpu_count(void)
{
CpuList cpus_present[1];
CpuList cpus_possible[1];
CpuList cpus_present[1];
CpuList cpus_possible[1];
cpulist_read_from(cpus_present, "/sys/devices/system/cpu/present");
cpulist_read_from(cpus_possible, "/sys/devices/system/cpu/possible");
cpulist_read_from(cpus_present, "/sys/devices/system/cpu/present");
cpulist_read_from(cpus_possible, "/sys/devices/system/cpu/possible");
/* Compute the intersection of both sets to get the actual number of
* CPU cores that can be used on this device by the kernel.
*/
cpulist_and(cpus_present, cpus_possible);
/* Compute the intersection of both sets to get the actual number of
* CPU cores that can be used on this device by the kernel.
*/
cpus_present->mask &= cpus_possible->mask;
return cpulist_count(cpus_present);
return __builtin_popcount(cpus_present->mask);
}
static void
android_cpuInit(void)
static void android_cpuInit(void)
{
char cpuinfo[4096];
int cpuinfo_len;
char cpuinfo[4096];
int cpuinfo_len;
g_cpuFamily = DEFAULT_CPU_FAMILY;
g_cpuFeatures = 0;
g_cpuCount = 1;
g_cpuFamily = DEFAULT_CPU_FAMILY;
g_cpuFeatures = 0;
g_cpuCount = 1;
cpuinfo_len = cpu_read_file("/proc/cpuinfo", cpuinfo, sizeof cpuinfo);
D("cpuinfo_len is (%d):\n%.*s\n", cpuinfo_len,
cpuinfo_len >= 0 ? cpuinfo_len : 0, cpuinfo);
cpuinfo_len = cpu_read_file("/proc/cpuinfo", cpuinfo, sizeof cpuinfo);
RARCH_LOG("cpuinfo_len is (%d):\n%.*s\n", cpuinfo_len,
cpuinfo_len >= 0 ? cpuinfo_len : 0, cpuinfo);
if (cpuinfo_len < 0) /* should not happen */ {
return;
}
if (cpuinfo_len < 0)
return;
/* Count the CPU cores, the value may be 0 for single-core CPUs */
g_cpuCount = get_cpu_count();
if (g_cpuCount == 0) {
g_cpuCount = 1;
}
/* Count the CPU cores, the value may be 0 for single-core CPUs */
g_cpuCount = get_cpu_count();
if (g_cpuCount == 0)
g_cpuCount = 1;
D("found cpuCount = %d\n", g_cpuCount);
RARCH_LOG("found cpuCount = %d\n", g_cpuCount);
#ifdef __ARM_ARCH__
{
/* Extract architecture from the "CPU Architecture" field.
* The list is well-known, unlike the the output of
* the 'Processor' field which can vary greatly.
*
* See the definition of the 'proc_arch' array in
* $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in
* same file.
*/
char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture");
/* Extract architecture from the "CPU Architecture" field.
* The list is well-known, unlike the the output of
* the 'Processor' field which can vary greatly.
*
* See the definition of the 'proc_arch' array in
* $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in
* same file.
*/
char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture");
if (cpuArch != NULL) {
char* end;
long archNumber;
int hasARMv7 = 0;
if (cpuArch != NULL)
{
char* end;
long archNumber;
int hasARMv7 = 0;
D("found cpuArch = '%s'\n", cpuArch);
RARCH_LOG("found cpuArch = '%s'\n", cpuArch);
/* read the initial decimal number, ignore the rest */
archNumber = strtol(cpuArch, &end, 10);
/* read the initial decimal number, ignore the rest */
archNumber = strtol(cpuArch, &end, 10);
/* Here we assume that ARMv8 will be upwards compatible with v7
* in the future. Unfortunately, there is no 'Features' field to
* indicate that Thumb-2 is supported.
*/
if (end > cpuArch && archNumber >= 7) {
hasARMv7 = 1;
/* Here we assume that ARMv8 will be upwards compatible with v7
* in the future. Unfortunately, there is no 'Features' field to
* indicate that Thumb-2 is supported.
*/
if (end > cpuArch && archNumber >= 7)
hasARMv7 = 1;
/* Unfortunately, it seems that certain ARMv6-based CPUs
* report an incorrect architecture number of 7!
*
* See http://code.google.com/p/android/issues/detail?id=10812
*
* We try to correct this by looking at the 'elf_format'
* field reported by the 'Processor' field, which is of the
* form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
* an ARMv6-one.
*/
if (hasARMv7)
{
char* cpuProc = extract_cpuinfo_field(cpuinfo, cpuinfo_len,
"Processor");
if (cpuProc != NULL)
{
RARCH_LOG("found cpuProc = '%s'\n", cpuProc);
if (has_list_item(cpuProc, "(v6l)"))
{
RARCH_ERR("CPU processor and architecture mismatch!!\n");
hasARMv7 = 0;
}
free(cpuProc);
}
}
/* Unfortunately, it seems that certain ARMv6-based CPUs
* report an incorrect architecture number of 7!
*
* See http://code.google.com/p/android/issues/detail?id=10812
*
* We try to correct this by looking at the 'elf_format'
* field reported by the 'Processor' field, which is of the
* form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
* an ARMv6-one.
*/
if (hasARMv7) {
char* cpuProc = extract_cpuinfo_field(cpuinfo, cpuinfo_len,
"Processor");
if (cpuProc != NULL) {
D("found cpuProc = '%s'\n", cpuProc);
if (has_list_item(cpuProc, "(v6l)")) {
D("CPU processor and architecture mismatch!!\n");
hasARMv7 = 0;
}
free(cpuProc);
}
}
if (hasARMv7)
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv7;
if (hasARMv7) {
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv7;
}
/* The LDREX / STREX instructions are available from ARMv6 */
if (archNumber >= 6)
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_LDREX_STREX;
/* The LDREX / STREX instructions are available from ARMv6 */
if (archNumber >= 6) {
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_LDREX_STREX;
}
free(cpuArch);
}
free(cpuArch);
}
/* Extract the list of CPU features from 'Features' field */
char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features");
/* Extract the list of CPU features from 'Features' field */
char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features");
if (cpuFeatures != NULL)
{
RARCH_LOG("found cpuFeatures = '%s'\n", cpuFeatures);
if (cpuFeatures != NULL) {
if (has_list_item(cpuFeatures, "vfpv3"))
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;
D("found cpuFeatures = '%s'\n", cpuFeatures);
else if (has_list_item(cpuFeatures, "vfpv3d16"))
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;
if (has_list_item(cpuFeatures, "vfpv3"))
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;
else if (has_list_item(cpuFeatures, "vfpv3d16"))
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;
if (has_list_item(cpuFeatures, "neon")) {
/* Note: Certain kernels only report neon but not vfpv3
* in their features list. However, ARM mandates
* that if Neon is implemented, so must be VFPv3
* so always set the flag.
*/
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON |
ANDROID_CPU_ARM_FEATURE_VFPv3;
}
free(cpuFeatures);
}
}
if (has_list_item(cpuFeatures, "neon"))
{
/* Note: Certain kernels only report neon but not vfpv3
* in their features list. However, ARM mandates
* that if Neon is implemented, so must be VFPv3
* so always set the flag.
*/
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON |
ANDROID_CPU_ARM_FEATURE_VFPv3;
}
free(cpuFeatures);
}
#endif /* __ARM_ARCH__ */
#ifdef __i386__
g_cpuFamily = ANDROID_CPU_FAMILY_X86;
g_cpuFamily = ANDROID_CPU_FAMILY_X86;
int regs[4];
int regs[4];
/* According to http://en.wikipedia.org/wiki/CPUID */
/* According to http://en.wikipedia.org/wiki/CPUID */
#define VENDOR_INTEL_b 0x756e6547
#define VENDOR_INTEL_c 0x6c65746e
#define VENDOR_INTEL_d 0x49656e69
cpu_x86_cpuid(0, regs);
int vendorIsIntel = (regs[1] == VENDOR_INTEL_b &&
regs[2] == VENDOR_INTEL_c &&
regs[3] == VENDOR_INTEL_d);
cpu_x86_cpuid(0, regs);
int vendorIsIntel = (regs[1] == VENDOR_INTEL_b &&
regs[2] == VENDOR_INTEL_c &&
regs[3] == VENDOR_INTEL_d);
cpu_x86_cpuid(1, regs);
if ((regs[2] & (1 << 9)) != 0) {
g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSSE3;
}
if ((regs[2] & (1 << 23)) != 0) {
g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_POPCNT;
}
if (vendorIsIntel && (regs[2] & (1 << 22)) != 0) {
g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_MOVBE;
}
cpu_x86_cpuid(1, regs);
if ((regs[2] & (1 << 9)) != 0)
g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSSE3;
if ((regs[2] & (1 << 23)) != 0)
g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_POPCNT;
if (vendorIsIntel && (regs[2] & (1 << 22)) != 0)
g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_MOVBE;
#endif
#ifdef _MIPS_ARCH
g_cpuFamily = ANDROID_CPU_FAMILY_MIPS;
g_cpuFamily = ANDROID_CPU_FAMILY_MIPS;
#endif /* _MIPS_ARCH */
}
AndroidCpuFamily
android_getCpuFamily(void)
AndroidCpuFamily android_getCpuFamily(void)
{
pthread_once(&g_once, android_cpuInit);
return g_cpuFamily;
}
uint64_t
android_getCpuFeatures(void)
uint64_t android_getCpuFeatures(void)
{
pthread_once(&g_once, android_cpuInit);
return g_cpuFeatures;
}
int
android_getCpuCount(void)
int android_getCpuCount(void)
{
pthread_once(&g_once, android_cpuInit);
return g_cpuCount;

View File

@ -54,19 +54,15 @@ enum
AXIS_RZ = 14
};
extern float AMotionEvent_getAxisValue(
const AInputEvent* motion_event, int32_t axis, size_t pointer_index);
void (*engine_handle_dpad)(AInputEvent*, size_t, int, char*, size_t, int, bool);
extern float AMotionEvent_getAxisValue(const AInputEvent* motion_event,
int32_t axis, size_t pointer_index);
static typeof(AMotionEvent_getAxisValue) *p_AMotionEvent_getAxisValue;
#define AMotionEvent_getAxisValue (*p_AMotionEvent_getAxisValue)
float getAxis(AInputEvent *event, int stick, int axis, int pointer)
{
int axis_arg[2][2] = {{AXIS_X, AXIS_Y}, {AXIS_Z, AXIS_RZ}};
return AMotionEvent_getAxisValue(event, axis_arg[stick][axis], pointer);
}
/**
* Process the next main command.
*/
@ -81,8 +77,6 @@ void engine_handle_cmd(void)
switch (cmd)
{
case APP_CMD_INPUT_CHANGED:
RARCH_LOG("APP_CMD_INPUT_CHANGED\n");
pthread_mutex_lock(&android_app->mutex);
if (android_app->inputQueue != NULL)
@ -104,8 +98,6 @@ void engine_handle_cmd(void)
break;
case APP_CMD_INIT_WINDOW:
RARCH_LOG("engine_handle_cmd: APP_CMD_INIT_WINDOW.\n");
pthread_mutex_lock(&android_app->mutex);
android_app->window = android_app->pendingWindow;
pthread_cond_broadcast(&android_app->cond);
@ -116,8 +108,6 @@ void engine_handle_cmd(void)
break;
case APP_CMD_RESUME:
RARCH_LOG("engine_handle_cmd: APP_CMD_RESUME.\n");
pthread_mutex_lock(&android_app->mutex);
android_app->activityState = cmd;
pthread_cond_broadcast(&android_app->cond);
@ -125,8 +115,6 @@ void engine_handle_cmd(void)
break;
case APP_CMD_START:
RARCH_LOG("engine_handle_cmd: APP_CMD_START.\n");
pthread_mutex_lock(&android_app->mutex);
android_app->activityState = cmd;
pthread_cond_broadcast(&android_app->cond);
@ -134,8 +122,6 @@ void engine_handle_cmd(void)
break;
case APP_CMD_PAUSE:
RARCH_LOG("engine_handle_cmd: APP_CMD_PAUSE.\n");
pthread_mutex_lock(&android_app->mutex);
android_app->activityState = cmd;
pthread_cond_broadcast(&android_app->cond);
@ -149,8 +135,6 @@ void engine_handle_cmd(void)
break;
case APP_CMD_STOP:
RARCH_LOG("engine_handle_cmd: APP_CMD_STOP.\n");
pthread_mutex_lock(&android_app->mutex);
android_app->activityState = cmd;
pthread_cond_broadcast(&android_app->cond);
@ -158,12 +142,8 @@ void engine_handle_cmd(void)
break;
case APP_CMD_CONFIG_CHANGED:
RARCH_LOG("engine_handle_cmd: APP_CMD_CONFIG_CHANGED.\n");
break;
case APP_CMD_TERM_WINDOW:
RARCH_LOG("engine_handle_cmd: APP_CMD_TERM_WINDOW.\n");
pthread_mutex_lock(&android_app->mutex);
/* The window is being hidden or closed, clean it up. */
@ -179,213 +159,64 @@ void engine_handle_cmd(void)
break;
case APP_CMD_GAINED_FOCUS:
RARCH_LOG("engine_handle_cmd: APP_CMD_GAINED_FOCUS.\n");
g_extern.lifecycle_state &= ~(1ULL << RARCH_PAUSE_TOGGLE);
break;
case APP_CMD_LOST_FOCUS:
RARCH_LOG("engine_handle_cmd: APP_CMD_LOST_FOCUS.\n");
break;
case APP_CMD_DESTROY:
RARCH_LOG("engine_handle_cmd: APP_CMD_DESTROY\n");
g_extern.lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
break;
}
}
static inline void engine_handle_input(void)
static void engine_handle_dpad_default(AInputEvent *event,
size_t motion_pointer, int state_id, char *msg, size_t msg_sizeof,
int source, bool debug_enable)
{
bool debug_enable = g_settings.input.debug_enable;
struct android_app *android_app = (struct android_app*)g_android;
uint64_t *lifecycle_state = &g_extern.lifecycle_state;
AInputEvent* event = NULL;
uint64_t *state_cur = &state[state_id];
float dzone_min = dpad_state[state_id].dzone_min;
float dzone_max = dpad_state[state_id].dzone_max;
float x = AMotionEvent_getX(event, motion_pointer);
float y = AMotionEvent_getY(event, motion_pointer);
*lifecycle_state &= ~((1ULL << RARCH_RESET) | (1ULL << RARCH_REWIND) | (1ULL << RARCH_FAST_FORWARD_KEY) | (1ULL << RARCH_FAST_FORWARD_HOLD_KEY) | (1ULL << RARCH_MUTE) | (1ULL << RARCH_SAVE_STATE_KEY) | (1ULL << RARCH_LOAD_STATE_KEY) | (1ULL << RARCH_STATE_SLOT_PLUS) | (1ULL << RARCH_STATE_SLOT_MINUS));
*state_cur &= ~((1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) |
(1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) |
(1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN));
*state_cur |= PRESSED_LEFT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
*state_cur |= PRESSED_RIGHT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
*state_cur |= PRESSED_UP(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
*state_cur |= PRESSED_DOWN(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
// Read all pending events.
while (AInputQueue_hasEvents(android_app->inputQueue))
{
if (AInputQueue_getEvent(android_app->inputQueue, &event) >= 0)
{
bool long_msg_enable = false;
int32_t handled = 1;
int action = 0;
char msg[128];
int source, id, keycode, type_event, state_id;
//int predispatched;
msg[0] = 0;
//predispatched =AInputQueue_preDispatchEvent(android_app->inputQueue,event);
//if (predispatched)
//continue;
source = AInputEvent_getSource(event);
id = AInputEvent_getDeviceId(event);
if (id == zeus_second_id)
id = zeus_id;
keycode = AKeyEvent_getKeyCode(event);
type_event = AInputEvent_getType(event);
state_id = -1;
if (source & (AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD))
state_id = 0; // touch overlay is always player 1
else
{
for (unsigned i = 0; i < pads_connected; i++)
if (state_device_ids[i] == id)
state_id = i;
}
if (state_id < 0)
{
state_id = pads_connected;
state_device_ids[pads_connected++] = id;
input_autodetect_setup(android_app, msg, sizeof(msg), state_id, id, source);
long_msg_enable = true;
}
if (keycode == AKEYCODE_BACK)
{
uint8_t unpacked = (keycode_lut[AKEYCODE_BACK] >> ((state_id+1) << 3)) - 1;
uint64_t input_state = (1ULL << unpacked);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INPUT_XPERIA_PLAY_HACK))
{
int meta = AKeyEvent_getMetaState(event);
if (!(meta & AMETA_ALT_ON))
{
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
break;
}
}
else if (type_event == AINPUT_EVENT_TYPE_KEY && input_state < (1ULL << RARCH_FIRST_META_KEY)
&& input_state > 0)
{
}
else
{
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
break;
}
}
if (type_event == AINPUT_EVENT_TYPE_MOTION)
{
float x = 0.0f;
float y = 0.0f;
action = AMotionEvent_getAction(event);
size_t motion_pointer = action >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
action &= AMOTION_EVENT_ACTION_MASK;
if (source & ~(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_MOUSE))
{
if (g_settings.input.dpad_emulation[state_id] != DPAD_EMULATION_NONE)
{
uint64_t *state_cur = &state[state_id];
float dzone_min = dpad_state[state_id].dzone_min;
float dzone_max = dpad_state[state_id].dzone_max;
x = AMotionEvent_getX(event, motion_pointer);
y = AMotionEvent_getY(event, motion_pointer);
//float axis = AMotionEvent_getAxisValue(event, AXIS_Z, motion_pointer);
//RARCH_LOG("axis: %.2f\n", axis);
*state_cur &= ~((1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) |
(1ULL << RETRO_DEVICE_ID_JOYPAD_UP) | (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN));
*state_cur |= PRESSED_LEFT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
*state_cur |= PRESSED_RIGHT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
*state_cur |= PRESSED_UP(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
*state_cur |= PRESSED_DOWN(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
}
}
else
{
bool keyup = (action == AMOTION_EVENT_ACTION_UP ||
action == AMOTION_EVENT_ACTION_CANCEL || action == AMOTION_EVENT_ACTION_POINTER_UP) ||
(source == AINPUT_SOURCE_MOUSE && action != AMOTION_EVENT_ACTION_DOWN);
if (keyup && motion_pointer < MAX_TOUCH)
{
memmove(pointer + motion_pointer, pointer + motion_pointer + 1, (MAX_TOUCH - motion_pointer - 1) * sizeof(struct input_pointer));
if (pointer_count > 0)
pointer_count--;
}
else
{
int pointer_max = min(AMotionEvent_getPointerCount(event), MAX_TOUCH);
for (motion_pointer = 0; motion_pointer < pointer_max; motion_pointer++)
{
x = AMotionEvent_getX(event, motion_pointer);
y = AMotionEvent_getY(event, motion_pointer);
input_translate_coord_viewport(x, y,
&pointer[motion_pointer].x, &pointer[motion_pointer].y,
&pointer[motion_pointer].full_x, &pointer[motion_pointer].full_y);
pointer_count = max(pointer_count, motion_pointer + 1);
}
}
}
if (debug_enable)
snprintf(msg, sizeof(msg), "Pad %d : x = %.2f, y = %.2f, src %d.\n", state_id, x, y, source);
}
else if (type_event == AINPUT_EVENT_TYPE_KEY)
{
if (debug_enable)
snprintf(msg, sizeof(msg), "Pad %d : %d, ac = %d, src = %d.\n", state_id, keycode, action, source);
/* Hack - we have to decrease the unpacked value by 1
* because we 'added' 1 to each entry in the LUT -
* RETRO_DEVICE_ID_JOYPAD_B is 0
*/
uint8_t unpacked = (keycode_lut[keycode] >> ((state_id+1) << 3)) - 1;
uint64_t input_state = (1ULL << unpacked);
int action = AKeyEvent_getAction(event);
uint64_t *key = NULL;
if(input_state < (1ULL << RARCH_FIRST_META_KEY))
key = &state[state_id];
else if(input_state)
key = &g_extern.lifecycle_state;
if(key != NULL)
{
if (action == AKEY_EVENT_ACTION_UP)
*key &= ~(input_state);
else if (action == AKEY_EVENT_ACTION_DOWN)
*key |= input_state;
}
if((keycode == AKEYCODE_VOLUME_UP || keycode == AKEYCODE_VOLUME_DOWN) && keycode_lut[keycode] == 0)
handled = 0;
}
if (msg[0] != 0)
msg_queue_push(g_extern.msg_queue, msg, 0, long_msg_enable ? 180 : 30);
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
}
}
if (debug_enable)
snprintf(msg, msg_sizeof, "Pad %d : x = %.2f, y = %.2f, src %d.\n",
state_id, x, y, source);
}
// Handle all events. If our activity is in pause state, block until we're unpaused.
void android_handle_events(void)
static void engine_handle_dpad_getaxisvalue(AInputEvent *event,
size_t motion_pointer, int state_id, char *msg, size_t msg_sizeof, int source,
bool debug_enable)
{
int ident;
while ((ident = ALooper_pollAll((input_key_pressed_func(RARCH_PAUSE_TOGGLE)) ? -1 : 0,
NULL, NULL, NULL)) >= 0)
{
if (ident == LOOPER_ID_MAIN)
engine_handle_cmd();
else if (!input_key_pressed_func(RARCH_PAUSE_TOGGLE))
engine_handle_input();
}
uint64_t *state_cur = &state[state_id];
float dzone_min = dpad_state[state_id].dzone_min;
float dzone_max = dpad_state[state_id].dzone_max;
float x = AMotionEvent_getAxisValue(event, AXIS_X, motion_pointer);
float y = AMotionEvent_getAxisValue(event, AXIS_Y, motion_pointer);
float z = AMotionEvent_getAxisValue(event, AXIS_Z, motion_pointer);
float rz = AMotionEvent_getAxisValue(event, AXIS_RZ, motion_pointer);
*state_cur &= ~((1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) |
(1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) |
(1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN));
*state_cur |= PRESSED_LEFT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
*state_cur |= PRESSED_RIGHT(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
*state_cur |= PRESSED_UP(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
*state_cur |= PRESSED_DOWN(x, y) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
if (debug_enable)
snprintf(msg, msg_sizeof, "Pad %d : x %.2f, y %.2f, z %.2f, rz %.2f, src %d.\n",
state_id, x, y, z, rz, source);
}
static void *android_input_init(void)
@ -422,16 +253,214 @@ static void *android_input_init(void)
dpad_state[i].dzone_min = -0.99f;
dpad_state[i].dzone_max = 0.99f;
g_settings.input.dpad_emulation[i] = DPAD_EMULATION_LSTICK;
}
g_settings.input.dpad_emulation[0] = DPAD_EMULATION_LSTICK;
//p_AMotionEvent_getAxisValue = dlsym(RTLD_DEFAULT, "AMotionEvent_getAxisValue");
if ((dlopen("/system/lib/libandroid.so", RTLD_LOCAL | RTLD_LAZY)) == 0)
{
RARCH_WARN("Unable to open libandroid.so\n");
return (void*)-1;
}
else
{
p_AMotionEvent_getAxisValue = dlsym(RTLD_DEFAULT, "AMotionEvent_getAxisValue");
if (p_AMotionEvent_getAxisValue != NULL)
{
RARCH_LOG("Setting engine_handle_dpad to 'Get Axis Value' (for reading extra analog sticks)");
engine_handle_dpad = engine_handle_dpad_getaxisvalue;
}
else
{
RARCH_LOG("Setting engine_handle_dpad to 'Default'");
engine_handle_dpad = engine_handle_dpad_default;
}
}
return (void*)-1;
}
// Handle all events. If our activity is in pause state, block until we're unpaused.
static void android_input_poll(void *data)
{
int ident;
uint64_t *lifecycle_state = &g_extern.lifecycle_state;
*lifecycle_state &= ~((1ULL << RARCH_RESET) | (1ULL << RARCH_REWIND) | (1ULL << RARCH_FAST_FORWARD_KEY) | (1ULL << RARCH_FAST_FORWARD_HOLD_KEY) | (1ULL << RARCH_MUTE) | (1ULL << RARCH_SAVE_STATE_KEY) | (1ULL << RARCH_LOAD_STATE_KEY) | (1ULL << RARCH_STATE_SLOT_PLUS) | (1ULL << RARCH_STATE_SLOT_MINUS) | (1ULL << RARCH_QUIT_KEY) | (1ULL << RARCH_MENU_TOGGLE));
while ((ident = ALooper_pollAll((input_key_pressed_func(RARCH_PAUSE_TOGGLE)) ? -1 : 0,
NULL, NULL, NULL)) >= 0)
{
if (ident == LOOPER_ID_INPUT)
{
bool debug_enable = g_settings.input.debug_enable;
struct android_app *android_app = (struct android_app*)g_android;
AInputEvent* event = NULL;
// Read all pending events.
while (AInputQueue_hasEvents(android_app->inputQueue))
{
if (AInputQueue_getEvent(android_app->inputQueue, &event) >= 0)
{
bool long_msg_enable = false;
int32_t handled = 1;
int action = 0;
char msg[128];
int source, id, keycode, type_event, state_id;
//int predispatched;
msg[0] = 0;
//predispatched =AInputQueue_preDispatchEvent(android_app->inputQueue,event);
//if (predispatched)
//continue;
source = AInputEvent_getSource(event);
id = AInputEvent_getDeviceId(event);
if (id == zeus_second_id)
id = zeus_id;
keycode = AKeyEvent_getKeyCode(event);
type_event = AInputEvent_getType(event);
state_id = -1;
if (source & (AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD))
state_id = 0; // touch overlay is always player 1
else
{
for (unsigned i = 0; i < pads_connected; i++)
if (state_device_ids[i] == id)
state_id = i;
}
if (state_id < 0)
{
state_id = pads_connected;
state_device_ids[pads_connected++] = id;
input_autodetect_setup(android_app, msg, sizeof(msg), state_id, id, source);
long_msg_enable = true;
}
if (keycode == AKEYCODE_BACK)
{
uint8_t unpacked = (keycode_lut[AKEYCODE_BACK] >> ((state_id+1) << 3)) - 1;
uint64_t input_state = (1ULL << unpacked);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INPUT_XPERIA_PLAY_HACK))
{
int meta = AKeyEvent_getMetaState(event);
if (!(meta & AMETA_ALT_ON))
{
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
break;
}
}
else if (type_event == AINPUT_EVENT_TYPE_KEY && input_state < (1ULL << RARCH_FIRST_META_KEY)
&& input_state > 0)
{
}
else if (g_settings.input.back_behavior == BACK_BUTTON_MENU_TOGGLE)
{
*lifecycle_state |= (1ULL << RARCH_MENU_TOGGLE);
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
break;
}
else
{
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
break;
}
}
if (type_event == AINPUT_EVENT_TYPE_MOTION)
{
action = AMotionEvent_getAction(event);
size_t motion_pointer = action >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
action &= AMOTION_EVENT_ACTION_MASK;
if (source & ~(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_MOUSE))
{
if (g_settings.input.dpad_emulation[state_id] != DPAD_EMULATION_NONE)
engine_handle_dpad(event, motion_pointer, state_id, msg, sizeof(msg), source, debug_enable);
}
else
{
float x = 0.0f;
float y = 0.0f;
bool keyup = (action == AMOTION_EVENT_ACTION_UP ||
action == AMOTION_EVENT_ACTION_CANCEL || action == AMOTION_EVENT_ACTION_POINTER_UP) ||
(source == AINPUT_SOURCE_MOUSE && action != AMOTION_EVENT_ACTION_DOWN);
if (keyup && motion_pointer < MAX_TOUCH)
{
memmove(pointer + motion_pointer, pointer + motion_pointer + 1, (MAX_TOUCH - motion_pointer - 1) * sizeof(struct input_pointer));
if (pointer_count > 0)
pointer_count--;
}
else
{
int pointer_max = min(AMotionEvent_getPointerCount(event), MAX_TOUCH);
for (motion_pointer = 0; motion_pointer < pointer_max; motion_pointer++)
{
x = AMotionEvent_getX(event, motion_pointer);
y = AMotionEvent_getY(event, motion_pointer);
input_translate_coord_viewport(x, y,
&pointer[motion_pointer].x, &pointer[motion_pointer].y,
&pointer[motion_pointer].full_x, &pointer[motion_pointer].full_y);
pointer_count = max(pointer_count, motion_pointer + 1);
}
}
if (debug_enable)
snprintf(msg, sizeof(msg), "Pad %d : x = %.2f, y = %.2f, src %d.\n", state_id, x, y, source);
}
}
else if (type_event == AINPUT_EVENT_TYPE_KEY)
{
if (debug_enable)
snprintf(msg, sizeof(msg), "Pad %d : %d, ac = %d, src = %d.\n", state_id, keycode, action, source);
/* Hack - we have to decrease the unpacked value by 1
* because we 'added' 1 to each entry in the LUT -
* RETRO_DEVICE_ID_JOYPAD_B is 0
*/
uint8_t unpacked = (keycode_lut[keycode] >> ((state_id+1) << 3)) - 1;
uint64_t input_state = (1ULL << unpacked);
int action = AKeyEvent_getAction(event);
uint64_t *key = NULL;
if(input_state < (1ULL << RARCH_FIRST_META_KEY))
key = &state[state_id];
else if(input_state)
key = &g_extern.lifecycle_state;
if(key != NULL)
{
if (action == AKEY_EVENT_ACTION_UP)
*key &= ~(input_state);
else if (action == AKEY_EVENT_ACTION_DOWN)
*key |= input_state;
}
if((keycode == AKEYCODE_VOLUME_UP || keycode == AKEYCODE_VOLUME_DOWN) && keycode_lut[keycode] == 0)
handled = 0;
}
if (msg[0] != 0)
msg_queue_push(g_extern.msg_queue, msg, 0, long_msg_enable ? 180 : 30);
AInputQueue_finishEvent(android_app->inputQueue, event, handled);
}
}
}
else if (ident == LOOPER_ID_MAIN)
engine_handle_cmd();
}
}
static int16_t android_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id)

View File

@ -139,6 +139,8 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned
}
}
keycode_lut[AKEYCODE_MENU] |= ((RARCH_MENU_TOGGLE + 1) << shift);
if (g_settings.input.autodetect_enable)
{
@ -211,18 +213,20 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned
dpad_state[id].dzone_max = 1.00f;
/* same as Rumblepad 2 - merge? */
//keycode_lut[AKEYCODE_BUTTON_7] |= ((RETRO_DEVICE_ID_JOYPAD_L2+1) << shift);
keycode_lut[AKEYCODE_BUTTON_1] |= ((RETRO_DEVICE_ID_JOYPAD_Y+1) << shift);
keycode_lut[AKEYCODE_BUTTON_2] |= ((RETRO_DEVICE_ID_JOYPAD_B+1) << shift);
keycode_lut[AKEYCODE_BUTTON_3] |= ((RETRO_DEVICE_ID_JOYPAD_A+1) << shift);
keycode_lut[AKEYCODE_BUTTON_4] |= ((RETRO_DEVICE_ID_JOYPAD_X+1) << shift);
keycode_lut[AKEYCODE_BUTTON_5] |= ((RETRO_DEVICE_ID_JOYPAD_L+1) << shift);
keycode_lut[AKEYCODE_BUTTON_6] |= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift);
keycode_lut[AKEYCODE_BUTTON_7] |= ((RETRO_DEVICE_ID_JOYPAD_L2+1) << shift);
keycode_lut[AKEYCODE_BUTTON_8] |= ((RETRO_DEVICE_ID_JOYPAD_R2+1) << shift);
keycode_lut[AKEYCODE_BUTTON_9] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift);
keycode_lut[AKEYCODE_BUTTON_10] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift);
keycode_lut[AKEYCODE_BUTTON_2] |= ((RETRO_DEVICE_ID_JOYPAD_X+1) << shift);
keycode_lut[AKEYCODE_BUTTON_5] |= ((RETRO_DEVICE_ID_JOYPAD_B+1) << shift);
keycode_lut[AKEYCODE_BUTTON_6] |= ((RETRO_DEVICE_ID_JOYPAD_A+1) << shift);
keycode_lut[AKEYCODE_BUTTON_3] |= ((RETRO_DEVICE_ID_JOYPAD_L+1) << shift);
keycode_lut[AKEYCODE_BUTTON_7] |= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift);
keycode_lut[AKEYCODE_BUTTON_4] |= ((RETRO_DEVICE_ID_JOYPAD_R2+1) << shift);
keycode_lut[AKEYCODE_BUTTON_8] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift);
keycode_lut[AKEYCODE_BUTTON_9] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift);
/* TODO - unsure about pad 2 still */
#if 0
keycode_lut[AKEYCODE_BUTTON_Z] |= ((RETRO_DEVICE_ID_JOYPAD_UP+1) << shift);
keycode_lut[AKEYCODE_BUTTON_Y] |= ((RETRO_DEVICE_ID_JOYPAD_DOWN+1) << shift);
keycode_lut[AKEYCODE_BUTTON_C] |= ((RETRO_DEVICE_ID_JOYPAD_LEFT+1) << shift);
@ -238,10 +242,11 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned
keycode_lut[AKEYCODE_BUTTON_B] |= ((RETRO_DEVICE_ID_JOYPAD_R2+1) << shift);
keycode_lut[AKEYCODE_BUTTON_C] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift);
keycode_lut[AKEYCODE_BUTTON_X] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift);
#endif
}
else if (strstr(name_buf, "TOMMO NEOGEOX Arcade Stick"))
{
/* TODO - Start/select */
g_settings.input.dpad_emulation[port] = DPAD_EMULATION_NONE;
keycode_lut[AKEYCODE_DPAD_UP] |= ((RETRO_DEVICE_ID_JOYPAD_UP+1) << shift);
keycode_lut[AKEYCODE_DPAD_DOWN] |= ((RETRO_DEVICE_ID_JOYPAD_DOWN+1) << shift);
keycode_lut[AKEYCODE_DPAD_LEFT] |= ((RETRO_DEVICE_ID_JOYPAD_LEFT+1) << shift);
@ -250,8 +255,8 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned
keycode_lut[AKEYCODE_BUTTON_B] |= ((RETRO_DEVICE_ID_JOYPAD_A+1) << shift);
keycode_lut[AKEYCODE_BUTTON_X] |= ((RETRO_DEVICE_ID_JOYPAD_Y+1) << shift);
keycode_lut[AKEYCODE_BUTTON_C] |= ((RETRO_DEVICE_ID_JOYPAD_X+1) << shift);
//keycode_lut[AKEYCODE_BUTTON_R2] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift);
//keycode_lut[AKEYCODE_BUTTON_R2] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift);
keycode_lut[AKEYCODE_BUTTON_R2] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift);
keycode_lut[AKEYCODE_BUTTON_L2] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift);
}
else if (strstr(name_buf, "MadCatz"))
{
@ -296,6 +301,40 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned
keycode_lut[AKEYCODE_BUTTON_R1] |= ((RETRO_DEVICE_ID_JOYPAD_R2+1) << shift);
}
}
else if (strstr(name_buf, "Sun4i-keypad"))
{
// iDroid x360
g_settings.input.dpad_emulation[port] = DPAD_EMULATION_NONE;
keycode_lut[AKEYCODE_DPAD_UP] |= ((RETRO_DEVICE_ID_JOYPAD_UP+1) << shift);
keycode_lut[AKEYCODE_DPAD_DOWN] |= ((RETRO_DEVICE_ID_JOYPAD_DOWN+1) << shift);
keycode_lut[AKEYCODE_DPAD_LEFT] |= ((RETRO_DEVICE_ID_JOYPAD_LEFT+1) << shift);
keycode_lut[AKEYCODE_DPAD_RIGHT] |= ((RETRO_DEVICE_ID_JOYPAD_RIGHT+1) << shift);
keycode_lut[AKEYCODE_INSERT] |= ((RETRO_DEVICE_ID_JOYPAD_B+1) << shift);
keycode_lut[AKEYCODE_MINUS] |= ((RETRO_DEVICE_ID_JOYPAD_A+1) << shift);
keycode_lut[AKEYCODE_SLASH] |= ((RETRO_DEVICE_ID_JOYPAD_X+1) << shift);
keycode_lut[AKEYCODE_MOVE_END] |= ((RETRO_DEVICE_ID_JOYPAD_Y+1) << shift);
keycode_lut[AKEYCODE_LEFT_BRACKET] |= ((RETRO_DEVICE_ID_JOYPAD_L+1) << shift);
keycode_lut[AKEYCODE_FORWARD_DEL] |= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift);
keycode_lut[AKEYCODE_MEDIA_PLAY] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift);
keycode_lut[AKEYCODE_EQUALS] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift);
// use this for the RGUI toggle
keycode_lut[AKEYCODE_MENU] |= ((RARCH_MENU_TOGGLE+1) << shift);
// Left Analog Up: 152
// Left Analog Down: 146
// Left Analog Right: 150
// Left Analog Left: 148
// Right Analog Up: 92 (AKEYCODE_PAGE_UP)
// Right Analog Down: 93 (AKEYCODE_PAGE_DOWN)
// Right Analog Right: 113 (AKEYCODE_CTRL_LEFT)
// Right Analog Left: 72 (AKEYCODE_RIGHT_BRACKET)
keycode_lut[AKEYCODE_NUMPAD_8] |= ((RETRO_DEVICE_ID_JOYPAD_UP+1) << shift);
keycode_lut[AKEYCODE_NUMPAD_2] |= ((RETRO_DEVICE_ID_JOYPAD_DOWN+1) << shift);
keycode_lut[AKEYCODE_NUMPAD_6] |= ((RETRO_DEVICE_ID_JOYPAD_RIGHT+1) << shift);
keycode_lut[AKEYCODE_NUMPAD_4] |= ((RETRO_DEVICE_ID_JOYPAD_LEFT+1) << shift);
}
else if (strstr(name_buf, "Zeemote"))
{
if (strstr(name_buf, "Steelseries free"))
@ -409,13 +448,18 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned
keycode_lut[AKEYCODE_BUTTON_14] |= ((RETRO_DEVICE_ID_JOYPAD_RIGHT+1) << shift);
keycode_lut[AKEYCODE_BUTTON_4] |= ((RETRO_DEVICE_ID_JOYPAD_Y+1) << shift);
keycode_lut[AKEYCODE_BUTTON_1] |= ((RETRO_DEVICE_ID_JOYPAD_X+1) << shift);
keycode_lut[AKEYCODE_BUTTON_5] |= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift);
if (strstr(name_buf, "WiseGroup"))
keycode_lut[AKEYCODE_BUTTON_5] |= ((RETRO_DEVICE_ID_JOYPAD_L2+1) << shift);
else
keycode_lut[AKEYCODE_BUTTON_5] |= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift);
keycode_lut[AKEYCODE_BUTTON_7] |= ((RETRO_DEVICE_ID_JOYPAD_L+1) << shift);
keycode_lut[AKEYCODE_BUTTON_3] |= ((RETRO_DEVICE_ID_JOYPAD_B+1) << shift);
keycode_lut[AKEYCODE_BUTTON_2] |= ((RETRO_DEVICE_ID_JOYPAD_A+1) << shift);
keycode_lut[AKEYCODE_BUTTON_6] |= ((RETRO_DEVICE_ID_JOYPAD_R2+1) << shift);
if (strstr(name_buf, "JC-PS102U"))
if (strstr(name_buf, "JC-PS102U") || strstr(name_buf, "WiseGroup"))
keycode_lut[AKEYCODE_BUTTON_8] |= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift);
else
keycode_lut[AKEYCODE_BUTTON_8] |= ((RETRO_DEVICE_ID_JOYPAD_L2+1) << shift);
@ -447,6 +491,8 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned
}
else
{
//PS button will be used for RGUI toggle
keycode_lut[AKEYCODE_BUTTON_1] |= ((RARCH_MENU_TOGGLE+1) << shift);
keycode_lut[AKEYCODE_BUTTON_X] |= ((RETRO_DEVICE_ID_JOYPAD_B+1) << shift);
keycode_lut[AKEYCODE_BUTTON_A] |= ((RETRO_DEVICE_ID_JOYPAD_Y+1) << shift);
}
@ -500,6 +546,31 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned
keycode_lut[AKEYCODE_BUTTON_14] |= ((RETRO_DEVICE_ID_JOYPAD_R2+1) << shift);
keycode_lut[AKEYCODE_UNKNOWN] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift);
}
else if (strstr(name_buf, "adc joystick"))
{
/* JXD S7300B */
g_settings.input.dpad_emulation[port] = DPAD_EMULATION_NONE;
keycode_lut[AKEYCODE_DPAD_UP] |= ((RETRO_DEVICE_ID_JOYPAD_UP+1) << shift);
keycode_lut[AKEYCODE_DPAD_DOWN] |= ((RETRO_DEVICE_ID_JOYPAD_DOWN+1) << shift);
keycode_lut[AKEYCODE_DPAD_LEFT] |= ((RETRO_DEVICE_ID_JOYPAD_LEFT+1) << shift);
keycode_lut[AKEYCODE_DPAD_RIGHT] |= ((RETRO_DEVICE_ID_JOYPAD_RIGHT+1) << shift);
keycode_lut[AKEYCODE_BUTTON_A] |= ((RETRO_DEVICE_ID_JOYPAD_A+1) << shift);
keycode_lut[AKEYCODE_BUTTON_B] |= ((RETRO_DEVICE_ID_JOYPAD_B+1) << shift);
keycode_lut[AKEYCODE_BUTTON_Y] |= ((RETRO_DEVICE_ID_JOYPAD_Y+1) << shift);
keycode_lut[AKEYCODE_BUTTON_X] |= ((RETRO_DEVICE_ID_JOYPAD_X+1) << shift);
keycode_lut[AKEYCODE_BUTTON_L1] |= ((RETRO_DEVICE_ID_JOYPAD_L+1) << shift);
keycode_lut[AKEYCODE_BUTTON_R1] |= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift);
keycode_lut[AKEYCODE_BUTTON_L2] |= ((RETRO_DEVICE_ID_JOYPAD_L2+1) << shift);
keycode_lut[AKEYCODE_BUTTON_R2] |= ((RETRO_DEVICE_ID_JOYPAD_R2+1) << shift);
keycode_lut[AKEYCODE_ENTER] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift);
keycode_lut[AKEYCODE_SPACE] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift);
//keycode_lut[AKEYCODE_VOLUME_UP] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift);
//keycode_lut[AKEYCODE_VOLUME_DOWN] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift);
}
else if (strstr(name_buf, "idroid:con"))
{
keycode_lut[AKEYCODE_BUTTON_2] |= ((RETRO_DEVICE_ID_JOYPAD_B+1) << shift);

View File

@ -29,11 +29,17 @@ enum {
enum {
AKEYCODE_META_FUNCTION_ON = 8,
AKEYCODE_ESCAPE = 111,
AKEYCODE_FORWARD_DEL = 112,
AKEYCODE_CTRL_LEFT = 113,
AKEYCODE_CTRL_RIGHT = 114,
AKEYCODE_CAPS_LOCK = 115,
AKEYCODE_SCROLL_LOCK = 116,
AKEYCODE_SYSRQ = 120,
AKEYCODE_BREAK = 121,
AKEYCODE_MOVE_HOME = 122,
AKEYCODE_MOVE_END = 123,
AKEYCODE_INSERT = 124,
AKEYCODE_FORWARD = 125,
AKEYCODE_MEDIA_PLAY = 126,
AKEYCODE_MEDIA_PAUSE = 127,
AKEYCODE_F2 = 132,
@ -44,6 +50,15 @@ enum {
AKEYCODE_F7 = 137,
AKEYCODE_F8 = 138,
AKEYCODE_F9 = 139,
AKEYCODE_NUMPAD_1 = 145,
AKEYCODE_NUMPAD_2 = 146,
AKEYCODE_NUMPAD_3 = 147,
AKEYCODE_NUMPAD_4 = 148,
AKEYCODE_NUMPAD_5 = 149,
AKEYCODE_NUMPAD_6 = 150,
AKEYCODE_NUMPAD_7 = 151,
AKEYCODE_NUMPAD_8 = 152,
AKEYCODE_NUMPAD_9 = 153,
AKEYCODE_BUTTON_1 = 188,
AKEYCODE_BUTTON_2 = 189,
AKEYCODE_BUTTON_3 = 190,

View File

@ -1,5 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="back_options">
<item>Quit</item>
<item>Menu toggle</item>
</string-array>
<string-array name="back_options_values">
<item>0</item>
<item>1</item>
</string-array>
<string-array name="aspect_ratios">
<item>Full screen</item>
<item>Auto</item>

View File

@ -187,6 +187,14 @@
</PreferenceCategory>
</PreferenceScreen>
<PreferenceScreen android:title="Input Settings" >
<PreferenceCategory android:title="General" >
<ListPreference
android:entries="@array/back_options"
android:entryValues="@array/back_options_values"
android:key="input_back_behavior"
android:summary="Select how you want the Back button to behave."
android:title="Back behavior" />
</PreferenceCategory>
<PreferenceCategory android:title="Configuration Autodetect" >
<CheckBoxPreference
android:defaultValue="true"

View File

@ -363,6 +363,7 @@ public class RetroArch extends Activity implements
config.setBoolean("video_vsync", prefs.getBoolean("video_vsync", true));
config.setBoolean("input_autodetect_enable", prefs.getBoolean("input_autodetect_enable", true));
config.setBoolean("input_debug_enable", prefs.getBoolean("input_debug_enable", false));
config.setInt("input_back_behavior", Integer.valueOf(prefs.getString("input_back_behavior", "0")));
config.setInt("input_autodetect_icade_profile_pad1", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad1", "0")));
config.setInt("input_autodetect_icade_profile_pad2", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad2", "0")));
config.setInt("input_autodetect_icade_profile_pad3", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad3", "0")));

View File

@ -71,7 +71,7 @@
#elif defined(SINC_HIGHEST_QUALITY)
#define SINC_WINDOW_KAISER
#define SINC_WINDOW_KAISER_BETA 14.5
#define CUTOFF 0.95
#define CUTOFF 0.962
#define PHASE_BITS 10
#define SUBPHASE_BITS 14
#define SINC_COEFF_LERP 1

View File

@ -12,9 +12,10 @@ subplot(2, 1, 2), plot(rarch_kaiser - real_kaiser), title('Error');
%%
% 4-tap and 8-tap are Lanczos windowed, but include here for completeness.
phases = 256;
bw = 0.375;
downsample = round(phases / bw);
cutoffs = bw * [0.65 0.75 0.825 0.90 0.95];
ratio = 2.0;
bw = min(1.0, ratio);
downsample = round(phases / ratio);
cutoffs = bw * [0.65 0.75 0.825 0.90 0.962];
betas = [2.0 3.0 5.5 10.5 14.5];
sidelobes = round([2 4 8 32 128] / bw);
@ -22,28 +23,29 @@ taps = sidelobes * 2;
freqs = 0.05 : 0.02 : 0.99;
filters = length(taps);
for i = 1 : filters
%filters = length(taps);
%for i = 1 : filters
for i = 5
filter_length = taps(i) * phases;
% Generate SINC.
sinc_indices = 2 * ((0 : (filter_length - 1)) / (filter_length - 1)) - 1;
sinc_indices = 2 * ((0 : (filter_length - 1)) / filter_length) - 1;
s = cutoffs(i) * sinc(cutoffs(i) * sinc_indices * sidelobes(i));
win = kaiser(filter_length, betas(i))';
filter = s .* win;
impulse_response_half = 0.5 * upfirdn(1, filter, phases, downsample);
impulse_response_half = upfirdn(1, filter, phases, downsample) / bw;
figure('name', sprintf('Response SINC: %d taps', taps(i)));
freqz(impulse_response_half);
ylim([-200 0]);
signal = zeros(1, 8001);
signal = zeros(1, 80001);
for freq = freqs
signal = signal + sin(pi * freq * (0 : 8000));
signal = signal + sin(pi * freq * (0 : 80000));
end
resampled = upfirdn(signal, filter, phases, downsample);
figure('name', sprintf('Kaiser SINC: %d taps, w = %.f', taps(i), freq));
freqz(resampled .* kaiser(length(resampled), 40.0)');
ylim([-80 70]);
freqz(resampled .* kaiser(length(resampled), 40.0)', 1, 16 * 1024);
ylim([-180 100]);
end

View File

@ -184,6 +184,15 @@ enum
#define DEFAULT_SHADER_TYPE RARCH_SHADER_AUTO
#endif
#ifdef HAVE_DYNAMIC
#ifdef _WIN32
#define EXT_EXECUTABLES "dll|DLL"
#elif defined(__APPLE__)
#define EXT_EXECUTABLES "dylib"
#else
#define EXT_EXECUTABLES "so|SO"
#endif
#else
#if defined(__CELLOS_LV2__)
#define EXT_EXECUTABLES "self|SELF|bin|BIN"
#elif defined(_XBOX1)
@ -193,6 +202,7 @@ enum
#elif defined(GEKKO)
#define EXT_EXECUTABLES "dol|DOL"
#endif
#endif
////////////////
// Video
@ -243,7 +253,7 @@ static const bool aspect_ratio_auto = false; // 1:1 PAR
static const bool crop_overscan = true;
// Font size for on-screen messages.
#ifdef HAVE_RMENU
#if defined(HAVE_RMENU)
static const float font_size = 1.0f;
#else
static const float font_size = 48;
@ -518,6 +528,8 @@ static const bool input_autodetect_enable = true;
#define RETRO_LBL_VOLUME_UP "Volume Up"
#define RETRO_LBL_VOLUME_DOWN "Volume Down"
#define RETRO_LBL_OVERLAY_NEXT "Next Overlay"
#define RETRO_LBL_DISK_EJECT_TOGGLE "Disk Eject Toggle"
#define RETRO_LBL_DISK_NEXT "Disk Swap Next"
// Player 1
static const struct retro_keybind retro_keybinds_1[] = {
@ -586,6 +598,8 @@ static const struct retro_keybind retro_keybinds_1[] = {
{ true, RARCH_VOLUME_UP, RETRO_LBL_VOLUME_UP, RETROK_KP_PLUS, NO_BTN, AXIS_NONE },
{ true, RARCH_VOLUME_DOWN, RETRO_LBL_VOLUME_DOWN, RETROK_KP_MINUS,NO_BTN, AXIS_NONE },
{ true, RARCH_OVERLAY_NEXT, RETRO_LBL_OVERLAY_NEXT, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RARCH_DISK_EJECT_TOGGLE, RETRO_LBL_DISK_EJECT_TOGGLE, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
{ true, RARCH_DISK_NEXT, RETRO_LBL_DISK_NEXT, RETROK_UNKNOWN, NO_BTN, AXIS_NONE },
};
// Player 2-5

View File

@ -33,8 +33,6 @@ CONSOLE EXTENSIONS
============================================================ */
#ifdef RARCH_CONSOLE
#include "../rarch_console_video.c"
#ifdef HW_DOL
#include "../../ngc/ssaram.c"
#endif
@ -439,16 +437,11 @@ MENU
#include "../../frontend/menu/rgui.c"
#endif
#ifdef HAVE_RMENU
#include "../../frontend/menu/rmenu_settings.c"
#if defined(_XBOX360)
#include "../../frontend/menu/rmenu_xui.cpp"
#elif defined(GEKKO)
#include "../../frontend/menu/rmenu_gx.c"
#endif
#endif
#include "../../frontend/menu/menu_settings.c"
#ifdef __cplusplus
extern "C" {

View File

@ -42,6 +42,7 @@
#ifdef HAVE_RMENU
#define context_rmenu_init_func() gl->ctx_driver->rmenu_init()
#define context_rmenu_frame_func(ctx) gl->ctx_driver->rmenu_frame(ctx)
#define context_rmenu_free_func() gl->ctx_driver->rmenu_free()
#endif
#ifdef HAVE_EGL

View File

@ -20,6 +20,7 @@
#include <string.h>
#include "../boolean.h"
#include "../general.h"
#include "rarch_console_input.h"
struct platform_bind

View File

@ -1,88 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
* Copyright (C) 2011-2013 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "../general.h"
#include "rarch_console_video.h"
struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END] = {
{ "1:1", 1.0f },
{ "2:1", 2.0f },
{ "3:2", 1.5f },
{ "3:4", 0.75f },
{ "4:1", 4.0f },
{ "4:3", 1.3333f },
{ "4:4", 1.0f },
{ "5:4", 1.25f },
{ "6:5", 1.2f },
{ "7:9", 0.7777f },
{ "8:3", 2.6666f },
{ "8:7", 1.1428f },
{ "16:9", 1.7778f },
{ "16:10", 1.6f },
{ "16:15", 3.2f },
{ "19:12", 1.5833f },
{ "19:14", 1.3571f },
{ "30:17", 1.7647f },
{ "32:9", 3.5555f },
{ "Auto", 1.0f },
{ "Core Provided", 1.0f },
{ "Custom", 0.0f }
};
char rotation_lut[ASPECT_RATIO_END][32] =
{
"Normal",
"Vertical",
"Flipped",
"Flipped Rotated"
};
void rarch_set_auto_viewport(unsigned width, unsigned height)
{
if(width == 0 || height == 0)
return;
unsigned aspect_x, aspect_y, len, highest, i;
len = width < height ? width : height;
highest = 1;
for (i = 1; i < len; i++)
{
if ((width % i) == 0 && (height % i) == 0)
highest = i;
}
aspect_x = width / highest;
aspect_y = height / highest;
snprintf(aspectratio_lut[ASPECT_RATIO_AUTO].name, sizeof(aspectratio_lut[ASPECT_RATIO_AUTO].name), "%d:%d (Auto)", aspect_x, aspect_y);
aspectratio_lut[ASPECT_RATIO_AUTO].value = (float) aspect_x / aspect_y;
}
void rarch_set_core_viewport(void)
{
if (!g_extern.main_is_init)
return;
// fallback to 1:1 pixel ratio if none provided
if (g_extern.system.av_info.geometry.aspect_ratio == 0.0)
aspectratio_lut[ASPECT_RATIO_CORE].value = (float) g_extern.system.av_info.geometry.base_width / g_extern.system.av_info.geometry.base_height;
else
aspectratio_lut[ASPECT_RATIO_CORE].value = g_extern.system.av_info.geometry.aspect_ratio;
}

View File

@ -1,103 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
* Copyright (C) 2011-2013 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RARCH_CONSOLE_VIDEO_H__
#define RARCH_CONSOLE_VIDEO_H__
#define MIN_SCALING_FACTOR (1.0f)
#if defined(__CELLOS_LV2__)
#define MAX_SCALING_FACTOR (5.0f)
#else
#define MAX_SCALING_FACTOR (2.0f)
#endif
enum
{
FBO_DEINIT = 0,
FBO_INIT,
FBO_REINIT
};
enum aspect_ratio
{
ASPECT_RATIO_1_1 = 0,
ASPECT_RATIO_2_1,
ASPECT_RATIO_3_2,
ASPECT_RATIO_3_4,
ASPECT_RATIO_4_1,
ASPECT_RATIO_4_3,
ASPECT_RATIO_4_4,
ASPECT_RATIO_5_4,
ASPECT_RATIO_6_5,
ASPECT_RATIO_7_9,
ASPECT_RATIO_8_3,
ASPECT_RATIO_8_7,
ASPECT_RATIO_16_9,
ASPECT_RATIO_16_10,
ASPECT_RATIO_16_15,
ASPECT_RATIO_19_12,
ASPECT_RATIO_19_14,
ASPECT_RATIO_30_17,
ASPECT_RATIO_32_9,
ASPECT_RATIO_AUTO,
ASPECT_RATIO_CORE,
ASPECT_RATIO_CUSTOM,
ASPECT_RATIO_END,
};
#define LAST_ASPECT_RATIO ASPECT_RATIO_CUSTOM
enum rotation
{
ORIENTATION_NORMAL = 0,
ORIENTATION_VERTICAL,
ORIENTATION_FLIPPED,
ORIENTATION_FLIPPED_ROTATED,
ORIENTATION_END
};
#define LAST_ORIENTATION (ORIENTATION_END-1)
extern char rotation_lut[ASPECT_RATIO_END][32];
/* ABGR color format defines */
#define WHITE 0xffffffffu
#define RED 0xff0000ffu
#define GREEN 0xff00ff00u
#define BLUE 0xffff0000u
#define YELLOW 0xff00ffffu
#define PURPLE 0xffff00ffu
#define CYAN 0xffffff00u
#define ORANGE 0xff0063ffu
#define SILVER 0xff8c848cu
#define LIGHTBLUE 0xFFFFE0E0U
#define LIGHTORANGE 0xFFE0EEFFu
struct aspect_ratio_elem
{
char name[64];
float value;
};
extern struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END];
extern void rarch_set_auto_viewport(unsigned width, unsigned height);
extern void rarch_set_core_viewport(void);
#endif

View File

@ -833,6 +833,10 @@ void init_video_input(void)
rarch_fail(1, "init_video_input()");
}
driver.video_poke = NULL;
if (driver.video->poke_interface)
driver.video->poke_interface(driver.video_data, &driver.video_poke);
if (driver.video->set_rotation && g_extern.system.rotation)
video_set_rotation_func(g_extern.system.rotation);

View File

@ -105,15 +105,11 @@ enum // RetroArch specific bind IDs.
RARCH_VOLUME_UP,
RARCH_VOLUME_DOWN,
RARCH_OVERLAY_NEXT,
RARCH_DISK_EJECT_TOGGLE,
RARCH_DISK_NEXT,
#ifdef RARCH_CONSOLE
RARCH_CHEAT_INPUT,
RARCH_SRAM_WRITE_PROTECT,
#endif
#ifdef HAVE_RMENU
RARCH_RMENU_TOGGLE,
RARCH_RMENU_QUICKMENU_TOGGLE,
#endif
RARCH_MENU_TOGGLE,
RARCH_MENU_QUICKMENU_TOGGLE,
RARCH_BIND_LIST_END,
RARCH_BIND_LIST_END_NULL
@ -230,6 +226,15 @@ typedef struct video_overlay_interface
} video_overlay_interface_t;
#endif
// Optionally implemented interface to poke more deeply into video driver.
// Only used by RGUI atm.
typedef struct video_poke_interface
{
void (*set_filtering)(void *data, unsigned index, bool smooth);
void (*set_fbo_state)(void *data, unsigned state);
void (*set_aspect_ratio)(void *data, unsigned aspectratio_index);
} video_poke_interface_t;
typedef struct video_driver
{
void *(*init)(const video_info_t *video, const input_driver_t **input, void **input_data);
@ -244,12 +249,10 @@ typedef struct video_driver
const char *ident;
// Callbacks essentially useless on PC, but useful on consoles where the drivers are used for more stuff.
#if defined(HAVE_RMENU)
#if defined(RARCH_CONSOLE)
void (*start)(void);
void (*stop)(void);
void (*restart)(void);
void (*apply_state_changes)(void);
void (*set_aspect_ratio)(void *data, unsigned aspectratio_index);
#endif
void (*set_rotation)(void *data, unsigned rotation);
@ -261,6 +264,7 @@ typedef struct video_driver
#ifdef HAVE_OVERLAY
void (*overlay_interface)(void *data, const video_overlay_interface_t **iface);
#endif
void (*poke_interface)(void *data, const video_poke_interface_t **iface);
} video_driver_t;
enum rarch_display_type
@ -321,6 +325,9 @@ typedef struct driver
input_overlay_t *overlay;
uint64_t overlay_state;
#endif
// Interface for "poking".
const video_poke_interface_t *video_poke;
} driver_t;
void init_drivers(void);

View File

@ -45,7 +45,13 @@
#define video_overlay_interface_func(iface) driver.video->overlay_interface(driver.video_data, iface)
#define video_free_func() driver.video->free(driver.video_data)
#define input_init_func() driver.input->init()
#ifdef HAVE_ASYNC_POLL
#define input_async_poll_func() driver.input->poll(driver.input_data)
#define input_poll_func()
#else
#define input_poll_func() driver.input->poll(driver.input_data)
#define input_async_poll_func()
#endif
#define input_input_state_func(retro_keybinds, port, device, index, id) \
driver.input->input_state(driver.input_data, retro_keybinds, port, device, index, id)
#define input_free_func() driver.input->free(driver.input_data)
@ -149,6 +155,7 @@ static inline bool input_key_pressed_func(int key)
#define gfx_ctx_window_has_focus() (true)
#define input_init_func() MAKENAME_INPUT(_input_init)()
#define input_async_poll_func()
#define input_poll_func() MAKENAME_INPUT(_input_poll)(driver.input_data)
#define input_input_state_func(retro_keybinds, port, device, index, id) \
MAKENAME_INPUT(_input_state)(driver.input_data, retro_keybinds, port, device, index, id)

View File

@ -485,13 +485,17 @@ static bool environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK:
{
RARCH_LOG("Environ SET_KEYBOARD_CALLBACK.\n");
const struct retro_keyboard_callback *info = (const struct retro_keyboard_callback*)data;
g_extern.system.key_event = info->callback;
break;
}
case RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE:
RARCH_LOG("Environ SET_DISK_CONTROL_INTERFACE.\n");
g_extern.system.disk_control = *(const struct retro_disk_control_callback*)data;
break;
default:
RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd);
return false;
@ -505,7 +509,6 @@ static void set_environment(void)
pretro_set_environment(environment_cb);
}
// Assume SNES as defaults.
static void set_environment_defaults(void)
{
char *save;

View File

@ -25,6 +25,7 @@
#include "../general.h"
#include "../performance.h"
#include "../driver.h"
#include "menu/rmenu.h"
#include "../config.def.h"
@ -106,12 +107,10 @@ static void jni_get (void *data_in, void *data_out)
static bool android_app_start_main(struct android_app *android_app, int *init_ret)
{
char rom_path[PATH_MAX];
char libretro_path[PATH_MAX];
char config_file[PATH_MAX];
struct jni_params in_params;
struct jni_out_params_char out_args;
struct rarch_main_wrap args = {0};
bool ret = false;
in_params.java_vm = android_app->activity->vm;
in_params.class_obj = android_app->activity->clazz;
@ -122,20 +121,20 @@ static bool android_app_start_main(struct android_app *android_app, int *init_re
(*in_params.java_vm)->AttachCurrentThread(in_params.java_vm, &in_params.env, 0);
// ROM
out_args.out = rom_path;
out_args.out_sizeof = sizeof(rom_path);
out_args.out = g_extern.fullpath;
out_args.out_sizeof = sizeof(g_extern.fullpath);
strlcpy(out_args.in, "ROM", sizeof(out_args.in));
jni_get(&in_params, &out_args);
// libretro
out_args.out = libretro_path;
out_args.out_sizeof = sizeof(libretro_path);
out_args.out = g_settings.libretro;
out_args.out_sizeof = sizeof(g_settings.libretro);
strlcpy(out_args.in, "LIBRETRO", sizeof(out_args.in));
jni_get(&in_params, &out_args);
// Config file
out_args.out = config_file;
out_args.out_sizeof = sizeof(config_file);
out_args.out = g_extern.config_path;
out_args.out_sizeof = sizeof(g_extern.config_path);
strlcpy(out_args.in, "CONFIGFILE", sizeof(out_args.in));
jni_get(&in_params, &out_args);
@ -148,32 +147,36 @@ static bool android_app_start_main(struct android_app *android_app, int *init_re
(*in_params.java_vm)->DetachCurrentThread(in_params.java_vm);
RARCH_LOG("Checking arguments passed ...\n");
RARCH_LOG("ROM Filename: [%s].\n", rom_path);
RARCH_LOG("Libretro path: [%s].\n", libretro_path);
RARCH_LOG("Config file: [%s].\n", config_file);
RARCH_LOG("ROM Filename: [%s].\n", g_extern.fullpath);
RARCH_LOG("Libretro path: [%s].\n", g_settings.libretro);
RARCH_LOG("Config file: [%s].\n", g_extern.config_path);
RARCH_LOG("Current IME: [%s].\n", android_app->current_ime);
struct rarch_main_wrap args = {0};
g_extern.lifecycle_mode_state |= (1ULL << MODE_INIT);
args.verbose = true;
args.config_path = config_file;
args.config_path = g_extern.config_path;
args.sram_path = NULL;
args.state_path = NULL;
args.rom_path = rom_path;
args.libretro_path = libretro_path;
args.rom_path = g_extern.fullpath;
args.libretro_path = g_settings.libretro;
*init_ret = rarch_main_init_wrap(&args);
ret = rarch_main_init_wrap(&args);
if (*init_ret == 0)
if (ret == 0)
{
RARCH_LOG("rarch_main_init succeeded.\n");
return true;
g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
}
else
{
RARCH_ERR("rarch_main_init failed.\n");
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_INIT);
if (ret == 0)
return true;
else
return false;
}
}
static void *android_app_entry(void *data)
@ -212,23 +215,75 @@ static void *android_app_entry(void *data)
if (!android_app_start_main(android_app, &init_ret))
goto exit;
if (g_extern.main_is_init)
menu_init();
begin_loop:
if(g_extern.lifecycle_mode_state & (1ULL << MODE_GAME))
{
RARCH_LOG("RetroArch started.\n");
driver.input->poll(NULL);
driver.video->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_THROTTLE_ENABLE))
audio_start_func();
// Main loop
do
{
android_handle_events();
input_async_poll_func();
} while (rarch_main_iterate());
RARCH_LOG("RetroArch stopped.\n");
if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_THROTTLE_ENABLE))
audio_stop_func();
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
}
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_INIT))
{
if (g_extern.main_is_init)
rarch_main_deinit();
struct rarch_main_wrap args = {0};
args.verbose = true;
args.config_path = g_extern.config_path;
args.sram_path = NULL;
args.state_path = NULL;
args.rom_path = g_extern.fullpath;
args.libretro_path = g_settings.libretro;
init_ret = rarch_main_init_wrap(&args);
if (init_ret == 0)
{
RARCH_LOG("rarch_main_init succeeded.\n");
g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
}
else
{
RARCH_ERR("rarch_main_init failed.\n");
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU);
}
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_INIT);
}
else if(g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))
{
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_PREINIT);
while((input_key_pressed_func(RARCH_PAUSE_TOGGLE)) ?
android_run_events(android_app) : menu_iterate());
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU);
}
else
goto exit;
goto begin_loop;
exit:
android_app->activityState = APP_CMD_DEAD;
RARCH_LOG("Deinitializing RetroArch...\n");
menu_free();
if (g_extern.main_is_init)
rarch_main_deinit();

View File

@ -153,10 +153,7 @@ enum {
APP_CMD_DEAD,
};
int8_t android_app_read_cmd (void *data);
extern void engine_app_read_cmd(void);
extern void engine_handle_cmd(void);
extern void android_handle_events(void);
extern struct android_app *g_android;

View File

@ -21,19 +21,19 @@
#include "frontend_console.h"
#include "menu/rmenu.h"
#include "menu/rmenu_settings.h"
#include "menu/menu_settings.h"
#if defined(__CELLOS_LV2__)
#include "platform/platform_ps3.c"
#include "platform/platform_ps3_exec.c"
#include "platform/platform_ps3.c"
#elif defined(GEKKO)
#include "platform/platform_gx.c"
#ifdef HW_RVL
#include "platform/platform_gx_exec.c"
#endif
#include "platform/platform_gx.c"
#elif defined(_XBOX)
#include "platform/platform_xdk.c"
#include "platform/platform_xdk_exec.c"
#include "platform/platform_xdk.c"
#elif defined(PSP)
#include "platform/platform_psp.c"
#endif
@ -312,14 +312,14 @@ begin_loop:
{
RARCH_ERR("rarch_main_init failed.\n");
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU);
rmenu_settings_msg(S_MSG_ROM_LOADING_ERROR, S_DELAY_180);
menu_settings_msg(S_MSG_ROM_LOADING_ERROR, 180);
}
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_INIT);
}
else if(g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))
{
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_PREINIT);
while(rmenu_iterate());
while (menu_iterate());
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU);
}
else

View File

@ -18,9 +18,6 @@
#define _FRONTEND_CONSOLE_H
//optional RetroArch forward declarations
#ifdef HAVE_RARCH_EXEC
static void rarch_console_exec(const char *path);
#endif
static void verbose_log_init(void);
#ifdef IS_SALAMANDER

View File

@ -19,9 +19,9 @@
#include <string.h>
#include "../../general.h"
#include "rmenu_settings.h"
#include "menu_settings.h"
void rmenu_settings_set(unsigned setting)
void menu_settings_set(unsigned setting)
{
switch(setting)
{
@ -148,11 +148,11 @@ void rmenu_settings_set(unsigned setting)
g_extern.lifecycle_mode_state |= (1ULL << MODE_INFO_DRAW);
break;
default:
RARCH_WARN("rmenu_settings_set - unhandled action.\n");
RARCH_WARN("menu_settings_set - unhandled action.\n");
}
}
void rmenu_settings_set_default(unsigned setting)
void menu_settings_set_default(unsigned setting)
{
switch(setting)
{
@ -217,11 +217,11 @@ void rmenu_settings_set_default(unsigned setting)
g_extern.lifecycle_mode_state |= (1ULL << MODE_INFO_DRAW);
break;
default:
RARCH_WARN("rmenu_settings_set_default: unhandled action.\n");
RARCH_WARN("menu_settings_set_default: unhandled action.\n");
}
}
void rmenu_settings_msg(unsigned setting, unsigned delay)
void menu_settings_msg(unsigned setting, unsigned delay)
{
char str[PATH_MAX], tmp[PATH_MAX];
msg_queue_clear(g_extern.msg_queue);
@ -269,15 +269,7 @@ void rmenu_settings_msg(unsigned setting, unsigned delay)
msg_queue_push(g_extern.msg_queue, str, 1, delay);
}
void rmenu_settings_create_menu_item_label_w(wchar_t *strwbuf, unsigned setting, size_t size)
{
char str[PATH_MAX];
rmenu_settings_create_menu_item_label(str, setting, sizeof(str));
convert_char_to_wchar(strwbuf, str, size);
}
void rmenu_settings_create_menu_item_label(char * str, unsigned setting, size_t size)
void menu_settings_create_menu_item_label(char * str, unsigned setting, size_t size)
{
switch (setting)
{

View File

@ -17,16 +17,6 @@
#ifndef CONSOLE_SETTINGS_H
#define CONSOLE_SETTINGS_H
enum
{
S_DELAY_0 = 0,
S_DELAY_1 = 1,
S_DELAY_45 = 45,
S_DELAY_90 = 90,
S_DELAY_180 = 180,
S_DELAY_270 = 270
};
enum
{
S_ASPECT_RATIO_DECREMENT = 0,
@ -104,11 +94,10 @@ enum
S_LBL_REWIND_GRANULARITY,
};
void rmenu_settings_set(unsigned setting);
void rmenu_settings_set_default(unsigned setting);
void rmenu_settings_msg(unsigned setting, unsigned delay);
void menu_settings_set(unsigned setting);
void menu_settings_set_default(unsigned setting);
void menu_settings_msg(unsigned setting, unsigned delay);
void rmenu_settings_create_menu_item_label(char * str, unsigned setting, size_t size);
void rmenu_settings_create_menu_item_label_w(wchar_t *strwbuf, unsigned setting, size_t size);
void menu_settings_create_menu_item_label(char * str, unsigned setting, size_t size);
#endif

View File

@ -21,8 +21,15 @@
#include "rgui.h"
#include "utils/file_list.h"
#include "rmenu_settings.h"
#include "../../console/rarch_console_video.h"
#include "menu_settings.h"
#include "../../general.h"
#include "../../gfx/gfx_common.h"
#ifdef HAVE_OPENGL
#include "../../gfx/gl_common.h"
#endif
#include "../../gfx/fonts/bitmap.h"
#include "../../screenshot.h"
#define TERM_START_X 15
@ -30,6 +37,14 @@
#define TERM_WIDTH (((RGUI_WIDTH - TERM_START_X - 15) / (FONT_WIDTH_STRIDE)))
#define TERM_HEIGHT (((RGUI_HEIGHT - TERM_START_Y - 15) / (FONT_HEIGHT_STRIDE)) - 1)
#if defined(HAVE_OPENGL)
#define DECLARE_DEVICE_PTR() gl_t *device_ptr = (gl_t*)driver.video_data
#elif defined(GEKKO)
#define DECLARE_DEVICE_PTR() gx_video_t *device_ptr = (gx_video_t*)driver.video_data
#elif defined(HAVE_D3D8) || defined(HAVE_D3D9)
#define DECLARE_DEVICE_PTR() xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data
#endif
#ifdef GEKKO
enum
{
@ -116,10 +131,19 @@ unsigned rgui_gx_resolutions[GX_RESOLUTIONS_LAST][2] = {
};
unsigned rgui_current_gx_resolution = GX_RESOLUTIONS_640_480;
static const char *rgui_device_labels[] = {
"GameCube Controller",
"Wiimote",
"Wiimote + Nunchuk",
"Classic Controller",
};
#endif
unsigned RGUI_WIDTH = 320;
unsigned RGUI_HEIGHT = 240;
uint16_t menu_framebuf[400 * 240];
rgui_handle_t *rgui;
struct rgui_handle
{
@ -136,18 +160,12 @@ struct rgui_handle
bool msg_force;
char path_buf[PATH_MAX];
char base_path[PATH_MAX];
const uint8_t *font;
bool alloc_font;
};
static const char *rgui_device_labels[] = {
"GameCube Controller",
"Wiimote",
"Wiimote + Nunchuk",
"Classic Controller",
};
static const unsigned rgui_controller_lut[] = {
RETRO_DEVICE_ID_JOYPAD_UP,
RETRO_DEVICE_ID_JOYPAD_DOWN,
@ -177,7 +195,7 @@ static inline bool rgui_is_viewport_menu(rgui_file_type_t menu_type)
return (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT || menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT_2);
}
static void copy_glyph(uint8_t *glyph, const uint8_t *buf)
static void rgui_copy_glyph(uint8_t *glyph, const uint8_t *buf)
{
for (int y = 0; y < FONT_HEIGHT; y++)
{
@ -205,7 +223,7 @@ static void init_font(rgui_handle_t *rgui, const uint8_t *font_bmp_buf)
{
unsigned y = i / 16;
unsigned x = i % 16;
copy_glyph(&font[FONT_OFFSET(i)],
rgui_copy_glyph(&font[FONT_OFFSET(i)],
font_bmp_buf + 54 + 3 * (256 * (255 - 16 * y) + 16 * x));
}
@ -221,9 +239,9 @@ rgui_handle_t *rgui_init(const char *base_path,
rgui->frame_buf = framebuf;
rgui->frame_buf_pitch = framebuf_pitch;
rgui->folder_cb = folder_cb;
rgui->userdata = userdata;
strlcpy(rgui->base_path, base_path, sizeof(rgui->base_path));
rgui->path_stack = rgui_list_new();
rgui->folder_buf = rgui_list_new();
@ -257,7 +275,11 @@ static uint16_t gray_filler(unsigned x, unsigned y)
x >>= 1;
y >>= 1;
unsigned col = ((x + y) & 1) + 1;
#ifdef GEKKO
return (6 << 12) | (col << 8) | (col << 4) | (col << 0);
#else
return (col << 13) | (col << 9) | (col << 5) | (12 << 0);
#endif
}
static uint16_t green_filler(unsigned x, unsigned y)
@ -265,7 +287,11 @@ static uint16_t green_filler(unsigned x, unsigned y)
x >>= 1;
y >>= 1;
unsigned col = ((x + y) & 1) + 1;
#ifdef GEKKO
return (6 << 12) | (col << 8) | (col << 5) | (col << 0);
#else
return (col << 13) | (col << 10) | (col << 5) | (12 << 0);
#endif
}
static void fill_rect(uint16_t *buf, unsigned pitch,
@ -293,7 +319,11 @@ static void blit_line(rgui_handle_t *rgui,
if (col)
rgui->frame_buf[(y + j) * (rgui->frame_buf_pitch >> 1) + (x + i)] = green ?
#ifdef GEKKO
(3 << 0) | (10 << 4) | (3 << 8) | (7 << 12) : 0x7FFF;
#else
(15 << 0) | (7 << 4) | (15 << 8) | (7 << 12) : 0xFFFF;
#endif
}
}
@ -406,7 +436,9 @@ static void render_text(rgui_handle_t *rgui)
char message[TERM_WIDTH + 1];
char type_str[TERM_WIDTH + 1];
int w = rgui_is_controller_menu(menu_type) ? 26 : 19;
#ifdef RARCH_CONSOLE
unsigned port = menu_type - RGUI_SETTINGS_CONTROLLER_1;
#endif
switch (type)
{
case RGUI_FILE_PLAIN:
@ -456,7 +488,7 @@ static void render_text(rgui_handle_t *rgui)
case RGUI_SETTINGS_VIDEO_ROTATION:
{
char rotate_msg[64];
rmenu_settings_create_menu_item_label(rotate_msg, S_LBL_ROTATION, sizeof(rotate_msg));
menu_settings_create_menu_item_label(rotate_msg, S_LBL_ROTATION, sizeof(rotate_msg));
snprintf(type_str, sizeof(type_str), rotate_msg);
}
break;
@ -483,6 +515,7 @@ static void render_text(rgui_handle_t *rgui)
case RGUI_SETTINGS_DEBUG_TEXT:
snprintf(type_str, sizeof(type_str), (g_extern.lifecycle_mode_state & (1ULL << MODE_FPS_DRAW)) ? "ON" : "OFF");
break;
case RGUI_SETTINGS_OPEN_FILEBROWSER:
case RGUI_SETTINGS_CUSTOM_VIEWPORT:
#ifdef HAVE_LIBRETRO_MANAGEMENT
case RGUI_SETTINGS_CORE:
@ -493,9 +526,12 @@ static void render_text(rgui_handle_t *rgui)
case RGUI_SETTINGS_CONTROLLER_4:
snprintf(type_str, sizeof(type_str), "...");
break;
#ifdef GEKKO
case RGUI_SETTINGS_BIND_DEVICE:
snprintf(type_str, sizeof(type_str), "%s", rgui_device_labels[g_settings.input.device[port]]);
break;
#endif
#ifdef RARCH_CONSOLE
case RGUI_SETTINGS_BIND_DPAD_EMULATION:
snprintf(type_str, sizeof(type_str), "%s", rarch_dpad_emulation_name_lut[g_settings.input.dpad_emulation[port]]);
break;
@ -517,6 +553,7 @@ static void render_text(rgui_handle_t *rgui)
case RGUI_SETTINGS_BIND_R3:
snprintf(type_str, sizeof(type_str), "%s", rarch_input_find_platform_key_label(g_settings.input.binds[port][rgui_controller_lut[type - RGUI_SETTINGS_BIND_UP]].joykey));
break;
#endif
default:
type_str[0] = 0;
w = 0;
@ -547,9 +584,10 @@ static void render_text(rgui_handle_t *rgui)
blit_line(rgui, x, y, message, i == rgui->directory_ptr);
}
const char *message_queue;
#ifdef GEKKO
gx_video_t *gx = (gx_video_t*)driver.video_data;
const char *message_queue;
DECLARE_DEVICE_PTR();
if (rgui->msg_force)
{
message_queue = msg_queue_pull(g_extern.msg_queue);
@ -557,12 +595,10 @@ static void render_text(rgui_handle_t *rgui)
}
else
{
message_queue = gx->msg;
message_queue = device_ptr->msg;
}
#else
message_queue = msg_queue_pull(g_extern.msg_queue);
#endif
render_messagebox(rgui, message_queue);
#endif
}
#ifdef GEKKO
@ -573,17 +609,20 @@ static void render_text(rgui_handle_t *rgui)
static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t action, rgui_file_type_t menu_type)
{
unsigned port = menu_type - RGUI_SETTINGS_CONTROLLER_1;
DECLARE_DEVICE_PTR();
#ifdef RARCH_CONSOLE
unsigned port = menu_type - RGUI_SETTINGS_CONTROLLER_1;
#endif
switch (setting)
{
case RGUI_SETTINGS_REWIND_ENABLE:
if (action == RGUI_ACTION_OK || action == RGUI_ACTION_LEFT || action == RGUI_ACTION_RIGHT)
{
rmenu_settings_set(S_REWIND);
menu_settings_set(S_REWIND);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
menu_settings_msg(S_MSG_RESTART_RARCH, 180);
}
else if (action == RGUI_ACTION_START)
g_settings.rewind_enable = false;
@ -611,11 +650,11 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
return -1;
}
else if (action == RGUI_ACTION_START)
rmenu_settings_set_default(S_DEF_SAVE_STATE);
menu_settings_set_default(S_DEF_SAVE_STATE);
else if (action == RGUI_ACTION_LEFT)
rmenu_settings_set(S_SAVESTATE_DECREMENT);
menu_settings_set(S_SAVESTATE_DECREMENT);
else if (action == RGUI_ACTION_RIGHT)
rmenu_settings_set(S_SAVESTATE_INCREMENT);
menu_settings_set(S_SAVESTATE_INCREMENT);
break;
case RGUI_SETTINGS_SCREENSHOT:
if (action == RGUI_ACTION_OK)
@ -625,15 +664,22 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
unsigned height = g_extern.frame_cache.height;
int pitch = g_extern.frame_cache.pitch;
#ifdef RARCH_CONSOLE
const char *screenshot_dir = default_paths.port_dir;
#else
const char *screenshot_dir = g_settings.screenshot_directory;
#endif
// Negative pitch is needed as screenshot takes bottom-up,
// but we use top-down.
bool r = screenshot_dump(default_paths.port_dir,
bool r = screenshot_dump(screenshot_dir,
data + (height - 1) * (pitch >> 1),
width, height, -pitch, false);
msg_queue_push(g_extern.msg_queue, r ? "Screenshot saved" : "Screenshot failed to save", 1, S_DELAY_90);
msg_queue_push(g_extern.msg_queue, r ? "Screenshot saved" : "Screenshot failed to save", 1, 90);
}
break;
#ifndef HAVE_DYNAMIC
case RGUI_SETTINGS_RESTART_GAME:
if (action == RGUI_ACTION_OK)
{
@ -642,11 +688,12 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
return -1;
}
break;
#endif
case RGUI_SETTINGS_VIDEO_FILTER:
if (action == RGUI_ACTION_START)
rmenu_settings_set_default(S_DEF_HW_TEXTURE_FILTER);
menu_settings_set_default(S_DEF_HW_TEXTURE_FILTER);
else
rmenu_settings_set(S_HW_TEXTURE_FILTER);
menu_settings_set(S_HW_TEXTURE_FILTER);
break;
#ifdef HW_RVL
case RGUI_SETTINGS_VIDEO_SOFT_FILTER:
@ -655,7 +702,7 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_VIDEO_SOFT_FILTER_ENABLE);
else
g_extern.lifecycle_mode_state |= (1ULL << MODE_VIDEO_SOFT_FILTER_ENABLE);
driver.video->apply_state_changes();
device_ptr->should_resize = true;
}
break;
#endif
@ -689,14 +736,14 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
if (action == RGUI_ACTION_START)
{
g_extern.console.screen.gamma_correction = 0;
driver.video->apply_state_changes();
device_ptr->should_resize = true;
}
else if (action == RGUI_ACTION_LEFT)
{
if(g_extern.console.screen.gamma_correction > 0)
{
g_extern.console.screen.gamma_correction--;
driver.video->apply_state_changes();
device_ptr->should_resize = true;
}
}
else if (action == RGUI_ACTION_RIGHT)
@ -704,66 +751,66 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
if(g_extern.console.screen.gamma_correction < MAX_GAMMA_SETTING)
{
g_extern.console.screen.gamma_correction++;
driver.video->apply_state_changes();
device_ptr->should_resize = true;
}
}
break;
case RGUI_SETTINGS_VIDEO_ASPECT_RATIO:
if (action == RGUI_ACTION_START)
rmenu_settings_set_default(S_DEF_ASPECT_RATIO);
menu_settings_set_default(S_DEF_ASPECT_RATIO);
else if (action == RGUI_ACTION_LEFT)
rmenu_settings_set(S_ASPECT_RATIO_DECREMENT);
menu_settings_set(S_ASPECT_RATIO_DECREMENT);
else if (action == RGUI_ACTION_RIGHT)
rmenu_settings_set(S_ASPECT_RATIO_INCREMENT);
menu_settings_set(S_ASPECT_RATIO_INCREMENT);
video_set_aspect_ratio_func(g_settings.video.aspect_ratio_idx);
break;
case RGUI_SETTINGS_VIDEO_ROTATION:
if (action == RGUI_ACTION_START)
{
rmenu_settings_set_default(S_DEF_AUDIO_CONTROL_RATE);
menu_settings_set_default(S_DEF_AUDIO_CONTROL_RATE);
video_set_rotation_func(g_extern.console.screen.orientation);
}
else if (action == RGUI_ACTION_LEFT)
{
rmenu_settings_set(S_ROTATION_DECREMENT);
menu_settings_set(S_ROTATION_DECREMENT);
video_set_rotation_func(g_extern.console.screen.orientation);
}
else if (action == RGUI_ACTION_RIGHT)
{
rmenu_settings_set(S_ROTATION_INCREMENT);
menu_settings_set(S_ROTATION_INCREMENT);
video_set_rotation_func(g_extern.console.screen.orientation);
}
break;
case RGUI_SETTINGS_VIDEO_OVERSCAN:
if (action == RGUI_ACTION_START)
{
rmenu_settings_set_default(S_DEF_OVERSCAN);
driver.video->apply_state_changes();
menu_settings_set_default(S_DEF_OVERSCAN);
device_ptr->should_resize = true;
}
else if (action == RGUI_ACTION_LEFT)
{
rmenu_settings_set(S_OVERSCAN_DECREMENT);
driver.video->apply_state_changes();
menu_settings_set(S_OVERSCAN_DECREMENT);
device_ptr->should_resize = true;
}
else if (action == RGUI_ACTION_RIGHT)
{
rmenu_settings_set(S_OVERSCAN_INCREMENT);
driver.video->apply_state_changes();
menu_settings_set(S_OVERSCAN_INCREMENT);
device_ptr->should_resize = true;
}
break;
case RGUI_SETTINGS_AUDIO_MUTE:
if (action == RGUI_ACTION_START)
rmenu_settings_set_default(S_DEF_AUDIO_MUTE);
menu_settings_set_default(S_DEF_AUDIO_MUTE);
else
rmenu_settings_set(S_AUDIO_MUTE);
menu_settings_set(S_AUDIO_MUTE);
break;
case RGUI_SETTINGS_AUDIO_CONTROL_RATE:
if (action == RGUI_ACTION_START)
rmenu_settings_set_default(S_DEF_AUDIO_CONTROL_RATE);
menu_settings_set_default(S_DEF_AUDIO_CONTROL_RATE);
else if (action == RGUI_ACTION_LEFT)
rmenu_settings_set(S_AUDIO_CONTROL_RATE_DECREMENT);
menu_settings_set(S_AUDIO_CONTROL_RATE_DECREMENT);
else if (action == RGUI_ACTION_RIGHT)
rmenu_settings_set(S_AUDIO_CONTROL_RATE_INCREMENT);
menu_settings_set(S_AUDIO_CONTROL_RATE_INCREMENT);
break;
case RGUI_SETTINGS_RESAMPLER_TYPE:
{
@ -817,6 +864,7 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
else if (action == RGUI_ACTION_RIGHT)
g_extern.lifecycle_mode_state |= (1ULL << MODE_FPS_DRAW);
break;
#ifndef HAVE_DYNAMIC
case RGUI_SETTINGS_RESTART_EMULATOR:
if (action == RGUI_ACTION_OK)
{
@ -829,6 +877,7 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
return -1;
}
break;
#endif
case RGUI_SETTINGS_QUIT_EMULATOR:
if (action == RGUI_ACTION_OK)
{
@ -838,6 +887,7 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
}
break;
// controllers
#ifdef GEKKO
case RGUI_SETTINGS_BIND_DEVICE:
g_settings.input.device[port] += RARCH_DEVICE_LAST;
if (action == RGUI_ACTION_START)
@ -851,6 +901,8 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
rarch_input_set_default_keybinds(port);
driver.input->set_analog_dpad_mapping(g_settings.input.device[port], g_settings.input.dpad_emulation[port], port);
break;
#endif
#ifdef RARCH_CONSOLE
case RGUI_SETTINGS_BIND_DPAD_EMULATION:
g_settings.input.dpad_emulation[port] += DPAD_EMULATION_LAST;
if (action == RGUI_ACTION_START)
@ -892,6 +944,7 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t
rarch_input_set_keybind(port, keybind_action, rgui_controller_lut[setting - RGUI_SETTINGS_BIND_UP]);
}
#endif
default:
break;
}
@ -920,8 +973,8 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui)
#endif
#ifdef GEKKO
RGUI_MENU_ITEM("Screen Resolution", RGUI_SETTINGS_VIDEO_RESOLUTION);
#endif
RGUI_MENU_ITEM("Gamma", RGUI_SETTINGS_VIDEO_GAMMA);
#endif
RGUI_MENU_ITEM("Aspect Ratio", RGUI_SETTINGS_VIDEO_ASPECT_RATIO);
RGUI_MENU_ITEM("Custom Ratio", RGUI_SETTINGS_CUSTOM_VIEWPORT);
RGUI_MENU_ITEM("Overscan", RGUI_SETTINGS_VIDEO_OVERSCAN);
@ -929,22 +982,29 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui)
RGUI_MENU_ITEM("Mute Audio", RGUI_SETTINGS_AUDIO_MUTE);
RGUI_MENU_ITEM("Audio Control Rate", RGUI_SETTINGS_AUDIO_CONTROL_RATE);
RGUI_MENU_ITEM("Audio Resampler", RGUI_SETTINGS_RESAMPLER_TYPE);
#ifdef GEKKO
RGUI_MENU_ITEM("SRAM Saves in \"sram\" Dir", RGUI_SETTINGS_SRAM_DIR);
RGUI_MENU_ITEM("State Saves in \"state\" Dir", RGUI_SETTINGS_STATE_DIR);
#endif
#ifdef HAVE_LIBRETRO_MANAGEMENT
RGUI_MENU_ITEM("Core", RGUI_SETTINGS_CORE);
#endif
#ifdef GEKKO
RGUI_MENU_ITEM("Controller #1 Config", RGUI_SETTINGS_CONTROLLER_1);
RGUI_MENU_ITEM("Controller #2 Config", RGUI_SETTINGS_CONTROLLER_2);
RGUI_MENU_ITEM("Controller #3 Config", RGUI_SETTINGS_CONTROLLER_3);
RGUI_MENU_ITEM("Controller #4 Config", RGUI_SETTINGS_CONTROLLER_4);
#endif
RGUI_MENU_ITEM("Debug Text", RGUI_SETTINGS_DEBUG_TEXT);
#ifndef HAVE_DYNAMIC
RGUI_MENU_ITEM("Restart RetroArch", RGUI_SETTINGS_RESTART_EMULATOR);
#endif
RGUI_MENU_ITEM("Exit RetroArch", RGUI_SETTINGS_QUIT_EMULATOR);
}
static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui)
{
#ifdef RARCH_CONSOLE
rgui_list_clear(rgui->folder_buf);
RGUI_MENU_ITEM("Device", RGUI_SETTINGS_BIND_DEVICE);
@ -965,14 +1025,12 @@ static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui)
RGUI_MENU_ITEM("R2", RGUI_SETTINGS_BIND_R2);
RGUI_MENU_ITEM("L3", RGUI_SETTINGS_BIND_L3);
RGUI_MENU_ITEM("R3", RGUI_SETTINGS_BIND_R3);
#endif
}
int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
static int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
{
#ifdef GEKKO
gx_video_t *gx = (gx_video_t*)driver.video_data;
#endif
DECLARE_DEVICE_PTR();
rgui_file_type_t menu_type = 0;
rgui_list_back(rgui->path_stack, NULL, &menu_type, NULL);
@ -986,7 +1044,7 @@ int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
}
else
g_extern.console.screen.viewports.custom_vp.height -= 1;
driver.video->apply_state_changes();
device_ptr->should_resize = true;
break;
case RGUI_ACTION_DOWN:
@ -997,7 +1055,7 @@ int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
}
else
g_extern.console.screen.viewports.custom_vp.height += 1;
driver.video->apply_state_changes();
device_ptr->should_resize = true;
break;
case RGUI_ACTION_LEFT:
@ -1008,7 +1066,7 @@ int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
}
else
g_extern.console.screen.viewports.custom_vp.width -= 1;
driver.video->apply_state_changes();
device_ptr->should_resize = true;
break;
case RGUI_ACTION_RIGHT:
@ -1019,7 +1077,7 @@ int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
}
else
g_extern.console.screen.viewports.custom_vp.width += 1;
driver.video->apply_state_changes();
device_ptr->should_resize = true;
break;
case RGUI_ACTION_CANCEL:
@ -1057,11 +1115,11 @@ int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
}
else
{
g_extern.console.screen.viewports.custom_vp.width = gx->win_width - g_extern.console.screen.viewports.custom_vp.x;
g_extern.console.screen.viewports.custom_vp.height = gx->win_height - g_extern.console.screen.viewports.custom_vp.y;
g_extern.console.screen.viewports.custom_vp.width = device_ptr->win_width - g_extern.console.screen.viewports.custom_vp.x;
g_extern.console.screen.viewports.custom_vp.height = device_ptr->win_height - g_extern.console.screen.viewports.custom_vp.y;
}
#endif
driver.video->apply_state_changes();
device_ptr->should_resize = true;
break;
case RGUI_ACTION_SETTINGS:
@ -1088,12 +1146,13 @@ int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action)
return 0;
}
int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action)
static int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action)
{
rgui->frame_buf_pitch = RGUI_WIDTH * 2;
rgui_file_type_t type = 0;
const char *label = 0;
rgui_list_at(rgui->folder_buf, rgui->directory_ptr, &label, &type, NULL);
if (action != RGUI_ACTION_REFRESH)
rgui_list_at(rgui->folder_buf, rgui->directory_ptr, &label, &type, NULL);
#ifdef HAVE_LIBRETRO_MANAGEMENT
if (type == RGUI_SETTINGS_CORE)
label = default_paths.core_dir;
@ -1124,9 +1183,12 @@ int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action)
case RGUI_ACTION_CANCEL:
case RGUI_ACTION_SETTINGS:
rgui_list_pop(rgui->path_stack);
rgui->directory_ptr = directory_ptr;
rgui->need_refresh = true;
if (rgui_list_size(rgui->path_stack) > 1)
{
rgui_list_pop(rgui->path_stack);
rgui->directory_ptr = directory_ptr;
rgui->need_refresh = true;
}
break;
case RGUI_ACTION_LEFT:
@ -1150,6 +1212,11 @@ int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action)
g_settings.video.aspect_ratio_idx = ASPECT_RATIO_CUSTOM;
video_set_aspect_ratio_func(g_settings.video.aspect_ratio_idx);
}
else if (type == RGUI_SETTINGS_OPEN_FILEBROWSER && action == RGUI_ACTION_OK)
{
rgui_list_push(rgui->path_stack, rgui->base_path, RGUI_FILE_DIRECTORY, rgui->directory_ptr);
rgui->need_refresh = true;
}
else
{
int ret = rgui_settings_toggle_setting(type, action, menu_type);
@ -1303,7 +1370,7 @@ int rgui_iterate(rgui_handle_t *rgui, rgui_action_t action)
strlcpy(g_extern.fullpath, rgui->path_buf, sizeof(g_extern.fullpath));
g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME);
rmenu_settings_msg(S_MSG_LOADING_ROM, S_DELAY_1);
menu_settings_msg(S_MSG_LOADING_ROM, 1);
rgui->need_refresh = true; // in case of zip extract
rgui->msg_force = true;
}
@ -1365,3 +1432,341 @@ int rgui_iterate(rgui_handle_t *rgui, rgui_action_t action)
return ret;
}
static const struct retro_keybind _menu_nav_binds[] = {
#if defined(HW_RVL)
{ 0, 0, NULL, 0, GX_GC_UP | GX_GC_LSTICK_UP | GX_GC_RSTICK_UP | GX_CLASSIC_UP | GX_CLASSIC_LSTICK_UP | GX_CLASSIC_RSTICK_UP | GX_WIIMOTE_UP | GX_NUNCHUK_UP, 0 },
{ 0, 0, NULL, 0, GX_GC_DOWN | GX_GC_LSTICK_DOWN | GX_GC_RSTICK_DOWN | GX_CLASSIC_DOWN | GX_CLASSIC_LSTICK_DOWN | GX_CLASSIC_RSTICK_DOWN | GX_WIIMOTE_DOWN | GX_NUNCHUK_DOWN, 0 },
{ 0, 0, NULL, 0, GX_GC_LEFT | GX_GC_LSTICK_LEFT | GX_GC_RSTICK_LEFT | GX_CLASSIC_LEFT | GX_CLASSIC_LSTICK_LEFT | GX_CLASSIC_RSTICK_LEFT | GX_WIIMOTE_LEFT | GX_NUNCHUK_LEFT, 0 },
{ 0, 0, NULL, 0, GX_GC_RIGHT | GX_GC_LSTICK_RIGHT | GX_GC_RSTICK_RIGHT | GX_CLASSIC_RIGHT | GX_CLASSIC_LSTICK_RIGHT | GX_CLASSIC_RSTICK_RIGHT | GX_WIIMOTE_RIGHT | GX_NUNCHUK_RIGHT, 0 },
{ 0, 0, NULL, 0, GX_GC_A | GX_CLASSIC_A | GX_WIIMOTE_A | GX_WIIMOTE_2, 0 },
{ 0, 0, NULL, 0, GX_GC_B | GX_CLASSIC_B | GX_WIIMOTE_B | GX_WIIMOTE_1, 0 },
{ 0, 0, NULL, 0, GX_GC_START | GX_CLASSIC_PLUS | GX_WIIMOTE_PLUS, 0 },
{ 0, 0, NULL, 0, GX_GC_Z_TRIGGER | GX_CLASSIC_MINUS | GX_WIIMOTE_MINUS, 0 },
{ 0, 0, NULL, 0, GX_WIIMOTE_HOME | GX_CLASSIC_HOME, 0 },
#elif defined(HW_DOL)
{ 0, 0, NULL, 0, GX_GC_UP | GX_GC_LSTICK_UP | GX_GC_RSTICK_UP, 0 },
{ 0, 0, NULL, 0, GX_GC_DOWN | GX_GC_LSTICK_DOWN | GX_GC_RSTICK_DOWN, 0 },
{ 0, 0, NULL, 0, GX_GC_LEFT | GX_GC_LSTICK_LEFT | GX_GC_RSTICK_LEFT, 0 },
{ 0, 0, NULL, 0, GX_GC_RIGHT | GX_GC_LSTICK_RIGHT | GX_GC_RSTICK_RIGHT, 0 },
{ 0, 0, NULL, 0, GX_GC_A, 0 },
{ 0, 0, NULL, 0, GX_GC_B, 0 },
{ 0, 0, NULL, 0, GX_GC_START, 0 },
{ 0, 0, NULL, 0, GX_GC_Z_TRIGGER, 0 },
{ 0, 0, NULL, 0, GX_WIIMOTE_HOME, 0 },
{ 0, 0, NULL, 0, GX_QUIT_KEY, 0 },
#else
{ 0, 0, NULL, 0, (1ULL << RETRO_DEVICE_ID_JOYPAD_UP), 0 },
{ 0, 0, NULL, 0, (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN), 0 },
{ 0, 0, NULL, 0, (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT), 0 },
{ 0, 0, NULL, 0, (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT), 0 },
{ 0, 0, NULL, 0, (1ULL << RETRO_DEVICE_ID_JOYPAD_A), 0 },
{ 0, 0, NULL, 0, (1ULL << RETRO_DEVICE_ID_JOYPAD_B), 0 },
{ 0, 0, NULL, 0, (1ULL << RETRO_DEVICE_ID_JOYPAD_START), 0 },
{ 0, 0, NULL, 0, (1ULL << RETRO_DEVICE_ID_JOYPAD_SELECT), 0 },
{ 0, 0, NULL, 0, (1ULL << RARCH_MENU_TOGGLE), 0 },
{ 0, 0, NULL, 0, (1ULL << RARCH_QUIT_KEY), 0 },
#endif
};
static const struct retro_keybind *menu_nav_binds[] = {
_menu_nav_binds
};
enum
{
GX_DEVICE_NAV_UP = 0,
GX_DEVICE_NAV_DOWN,
GX_DEVICE_NAV_LEFT,
GX_DEVICE_NAV_RIGHT,
GX_DEVICE_NAV_A,
GX_DEVICE_NAV_B,
GX_DEVICE_NAV_START,
GX_DEVICE_NAV_SELECT,
GX_DEVICE_NAV_MENU,
GX_DEVICE_NAV_QUIT,
RMENU_DEVICE_NAV_LAST
};
static bool folder_cb(const char *directory, rgui_file_enum_cb_t file_cb,
void *userdata, void *ctx)
{
#ifdef HAVE_LIBRETRO_MANAGEMENT
bool core_chooser = (userdata) ? *(rgui_file_type_t *)userdata == RGUI_SETTINGS_CORE : false;
#else
bool core_chooser = false;
#endif
if (!*directory)
{
#ifdef GEKKO
#ifdef HW_RVL
file_cb(ctx, "sd:", RGUI_FILE_DEVICE, 0);
file_cb(ctx, "usb:", RGUI_FILE_DEVICE, 0);
#endif
file_cb(ctx, "carda:", RGUI_FILE_DEVICE, 0);
file_cb(ctx, "cardb:", RGUI_FILE_DEVICE, 0);
return true;
#endif
}
#if defined(GEKKO) && defined(HW_RVL)
LWP_MutexLock(gx_device_mutex);
int dev = gx_get_device_from_path(directory);
if (dev != -1 && !gx_devices[dev].mounted && gx_devices[dev].interface->isInserted())
fatMountSimple(gx_devices[dev].name, gx_devices[dev].interface);
LWP_MutexUnlock(gx_device_mutex);
#endif
char exts[256];
if (core_chooser)
strlcpy(exts, EXT_EXECUTABLES, sizeof(exts));
else
strlcpy(exts, g_extern.system.valid_extensions, sizeof(exts));
struct string_list *ext_list = string_split(exts, "|");
char _dir[PATH_MAX];
snprintf(_dir, sizeof(_dir), "%s/", directory);
DIR *dir = opendir(_dir);
if (!dir)
return false;
struct dirent *entry;
while ((entry = readdir(dir)))
{
char stat_path[PATH_MAX];
const char *file_ext = path_get_extension(entry->d_name);
snprintf(stat_path, sizeof(stat_path), "%s/%s", directory, entry->d_name);
bool is_dir;
#ifdef _DIRENT_HAVE_D_TYPE
is_dir = (entry->d_type == DT_DIR);
if (entry->d_type != DT_REG && !is_dir)
continue;
#else
struct stat st;
if (stat(stat_path, &st) < 0)
continue;
is_dir = S_ISDIR(st.st_mode);
if (!S_ISREG(st.st_mode) && !is_dir)
continue;
#endif
#ifdef HAVE_LIBRETRO_MANAGEMENT
if (core_chooser && (is_dir || strcasecmp(entry->d_name, default_paths.salamander_file) == 0))
continue;
#endif
if (!is_dir && ext_list && !string_list_find_elem_prefix(ext_list, ".", file_ext))
continue;
file_cb(ctx,
entry->d_name,
is_dir ? RGUI_FILE_DIRECTORY : RGUI_FILE_PLAIN, 0);
}
closedir(dir);
string_list_free(ext_list);
return true;
}
/*============================================================
RMENU API
============================================================ */
void menu_init(void)
{
DECLARE_DEVICE_PTR();
device_ptr->menu_data = (uint32_t *) menu_framebuf;
rgui = rgui_init("",
menu_framebuf, RGUI_WIDTH * sizeof(uint16_t),
NULL, bitmap_bin, folder_cb, NULL);
rgui_iterate(rgui, RGUI_ACTION_REFRESH);
}
void menu_free(void)
{
rgui_free(rgui);
}
static uint16_t trigger_state = 0;
static int menu_input_process(void *data, void *state)
{
if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME))
{
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
menu_settings_msg(S_MSG_LOADING_ROM, 100);
if (g_extern.fullpath)
g_extern.lifecycle_mode_state |= (1ULL << MODE_INIT);
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME);
return -1;
}
if (!(g_extern.frame_count < g_extern.delay_timer[0]))
{
bool return_to_game_enable = ((trigger_state & (1ULL << GX_DEVICE_NAV_MENU)) && g_extern.main_is_init);
if (return_to_game_enable)
{
g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
return -1;
}
}
return 0;
}
bool menu_iterate(void)
{
DECLARE_DEVICE_PTR();
static uint16_t old_input_state = 0;
static bool initial_held = true;
static bool first_held = false;
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_DRAW);
device_ptr->should_resize = true;
g_extern.frame_count++;
uint16_t input_state = 0;
driver.input->poll(NULL);
#ifdef HAVE_OVERLAY
if (driver.overlay)
{
driver.overlay_state = 0;
unsigned device = input_overlay_full_screen(driver.overlay) ?
RARCH_DEVICE_POINTER_SCREEN : RETRO_DEVICE_POINTER;
bool polled = false;
for (unsigned i = 0;
input_input_state_func(NULL, 0, device, i, RETRO_DEVICE_ID_POINTER_PRESSED);
i++)
{
int16_t x = input_input_state_func(NULL, 0,
device, i, RETRO_DEVICE_ID_POINTER_X);
int16_t y = input_input_state_func(NULL, 0,
device, i, RETRO_DEVICE_ID_POINTER_Y);
driver.overlay_state |= input_overlay_poll(driver.overlay, x, y);
polled = true;
}
if (!polled)
input_overlay_poll_clear(driver.overlay);
}
#endif
#ifndef GEKKO
/* TODO - not sure if correct regarding RARCH_QUIT_KEY */
if (input_key_pressed_func(RARCH_QUIT_KEY) || !video_alive_func())
{
g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
goto deinit;
}
#endif
for (unsigned i = 0; i < RMENU_DEVICE_NAV_LAST; i++)
input_state |= driver.input->input_state(NULL, menu_nav_binds, 0,
RETRO_DEVICE_JOYPAD, 0, i) ? (1ULL << i) : 0;
input_state |= driver.input->key_pressed(driver.input_data, RARCH_MENU_TOGGLE) ? (1ULL << GX_DEVICE_NAV_MENU) : 0;
input_state |= driver.input->key_pressed(driver.input_data, RARCH_QUIT_KEY) ? (1ULL << GX_DEVICE_NAV_QUIT) : 0;
#ifdef HAVE_OVERLAY
for (unsigned i = 0; i < RMENU_DEVICE_NAV_LAST; i++)
input_state |= driver.overlay_state & menu_nav_binds[0][i].joykey ? (1ULL << i) : 0;
#endif
trigger_state = input_state & ~old_input_state;
bool do_held = (input_state & ((1ULL << GX_DEVICE_NAV_UP) | (1ULL << GX_DEVICE_NAV_DOWN) | (1ULL << GX_DEVICE_NAV_LEFT) | (1ULL << GX_DEVICE_NAV_RIGHT))) && !(input_state & ((1ULL << GX_DEVICE_NAV_MENU) | (1ULL << GX_DEVICE_NAV_QUIT)));
if(do_held)
{
if(!first_held)
{
first_held = true;
g_extern.delay_timer[1] = g_extern.frame_count + (initial_held ? 15 : 7);
}
if (!(g_extern.frame_count < g_extern.delay_timer[1]))
{
first_held = false;
trigger_state = input_state; //second input frame set as current frame
}
initial_held = false;
}
else
{
first_held = false;
initial_held = true;
}
old_input_state = input_state;
rgui_action_t action = RGUI_ACTION_NOOP;
// don't run anything first frame, only capture held inputs for old_input_state
if (trigger_state & (1ULL << GX_DEVICE_NAV_UP))
action = RGUI_ACTION_UP;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_DOWN))
action = RGUI_ACTION_DOWN;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_LEFT))
action = RGUI_ACTION_LEFT;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_RIGHT))
action = RGUI_ACTION_RIGHT;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_B))
action = RGUI_ACTION_CANCEL;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_A))
action = RGUI_ACTION_OK;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_START))
action = RGUI_ACTION_START;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_SELECT))
action = RGUI_ACTION_SETTINGS;
#ifdef GEKKO
else if (trigger_state & (1ULL << GX_DEVICE_NAV_QUIT))
{
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXIT);
goto deinit;
}
#endif
int input_entry_ret = 0;
int input_process_ret = 0;
input_entry_ret = rgui_iterate(rgui, action);
// draw last frame for loading messages
rarch_render_cached_frame();
input_process_ret = menu_input_process(NULL, NULL);
if (input_entry_ret != 0 || input_process_ret != 0)
goto deinit;
return true;
deinit:
// set a timer delay so that we don't instantly switch back to the menu when
// press and holding QUIT in the emulation loop (lasts for 30 frame ticks)
if (!(g_extern.lifecycle_state & (1ULL << RARCH_FRAMEADVANCE)))
g_extern.delay_timer[0] = g_extern.frame_count + 30;
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU_DRAW);
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU_INGAME);
return false;
}

View File

@ -33,6 +33,7 @@ typedef enum
RGUI_SETTINGS,
// settings options are done here too
RGUI_SETTINGS_OPEN_FILEBROWSER,
RGUI_SETTINGS_REWIND_ENABLE,
RGUI_SETTINGS_REWIND_GRANULARITY,
RGUI_SETTINGS_SAVESTATE_SAVE,

View File

@ -29,12 +29,11 @@
#include "../../console/rarch_console.h"
#include "../../console/rarch_console_input.h"
#include "rmenu_settings.h"
#include "menu_settings.h"
#include "../../gfx/image.h"
#include "../../console/rarch_console_video.h"
#include "../../gfx/gfx_common.h"
#include "../../gfx/gfx_context.h"
#include "../../file.h"
@ -626,7 +625,7 @@ static void browser_update(void *data, uint64_t input, const char *extensions)
ret = filebrowser_iterate(b, action);
if(!ret)
rmenu_settings_msg(S_MSG_DIR_LOADING_ERROR, S_DELAY_180);
menu_settings_msg(S_MSG_DIR_LOADING_ERROR, 180);
}
void browser_render(void *data)
@ -725,7 +724,7 @@ int select_file(void *data, void *state)
{
driver.video->set_shader(driver.video_data, (enum rarch_shader_type)g_settings.video.shader_type, path, RARCH_SHADER_INDEX_PASS0);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, S_DELAY_180);
menu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, 180);
}
else
RARCH_ERR("Shaders are unsupported on this platform.\n");
@ -741,7 +740,7 @@ int select_file(void *data, void *state)
{
driver.video->set_shader(driver.video_data, (enum rarch_shader_type)g_settings.video.shader_type, path, RARCH_SHADER_INDEX_PASS1);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, S_DELAY_180);
menu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, 180);
}
else
RARCH_ERR("Shaders are unsupported on this platform.\n");
@ -783,7 +782,7 @@ int select_file(void *data, void *state)
else
{
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
menu_settings_msg(S_MSG_RESTART_RARCH, 180);
}
break;
}
@ -792,7 +791,7 @@ int select_file(void *data, void *state)
}
if(!ret)
rmenu_settings_msg(S_MSG_DIR_LOADING_ERROR, S_DELAY_180);
menu_settings_msg(S_MSG_DIR_LOADING_ERROR, 180);
}
else if (input & (1ULL << RMENU_DEVICE_NAV_X))
menu_stack_pop();
@ -890,7 +889,7 @@ int select_directory(void *data, void *state)
}
if(!ret)
rmenu_settings_msg(S_MSG_DIR_LOADING_ERROR, S_DELAY_180);
menu_settings_msg(S_MSG_DIR_LOADING_ERROR, 180);
display_menubar(current_menu);
@ -1029,9 +1028,9 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
#ifdef __CELLOS_LV2__
case SETTING_CHANGE_RESOLUTION:
if(input & (1ULL << RMENU_DEVICE_NAV_RIGHT))
rmenu_settings_set(S_RESOLUTION_NEXT);
menu_settings_set(S_RESOLUTION_NEXT);
if(input & (1ULL << RMENU_DEVICE_NAV_LEFT))
rmenu_settings_set(S_RESOLUTION_PREVIOUS);
menu_settings_set(S_RESOLUTION_PREVIOUS);
if(input & (1ULL << RMENU_DEVICE_NAV_B))
{
if (g_extern.console.screen.resolutions.list[g_extern.console.screen.resolutions.current.idx] == CELL_VIDEO_OUT_RESOLUTION_576)
@ -1107,7 +1106,7 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
{
driver.video->set_shader(driver.video_data, (enum rarch_shader_type)g_settings.video.shader_type, NULL, RARCH_SHADER_INDEX_PASS0);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, S_DELAY_180);
menu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, 180);
}
else
RARCH_ERR("Shaders are unsupported on this platform.\n");
@ -1127,7 +1126,7 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
{
driver.video->set_shader(driver.video_data, (enum rarch_shader_type)g_settings.video.shader_type, NULL, RARCH_SHADER_INDEX_PASS1);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, S_DELAY_180);
menu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, 180);
}
else
RARCH_ERR("Shaders are unsupported on this platform.\n");
@ -1160,7 +1159,7 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_LOW_RAM_MODE_ENABLE_PENDING);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
menu_settings_msg(S_MSG_RESTART_RARCH, 180);
}
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
@ -1173,7 +1172,7 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_LOW_RAM_MODE_ENABLE_PENDING);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
menu_settings_msg(S_MSG_RESTART_RARCH, 180);
}
}
}
@ -1195,29 +1194,29 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
case SETTING_KEEP_ASPECT_RATIO:
if(input & (1ULL << RMENU_DEVICE_NAV_LEFT))
{
rmenu_settings_set(S_ASPECT_RATIO_DECREMENT);
menu_settings_set(S_ASPECT_RATIO_DECREMENT);
driver.video->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx);
}
if(input & (1ULL << RMENU_DEVICE_NAV_RIGHT))
{
rmenu_settings_set(S_ASPECT_RATIO_INCREMENT);
menu_settings_set(S_ASPECT_RATIO_INCREMENT);
driver.video->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx);
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
{
rmenu_settings_set_default(S_DEF_ASPECT_RATIO);
menu_settings_set_default(S_DEF_ASPECT_RATIO);
driver.video->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx);
}
break;
case SETTING_HW_TEXTURE_FILTER:
if((input & (1ULL << RMENU_DEVICE_NAV_LEFT)) || (input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
{
rmenu_settings_set(S_HW_TEXTURE_FILTER);
menu_settings_set(S_HW_TEXTURE_FILTER);
device_ptr->ctx_driver->set_filtering(1, g_settings.video.smooth);
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
{
rmenu_settings_set(S_DEF_HW_TEXTURE_FILTER);
menu_settings_set(S_DEF_HW_TEXTURE_FILTER);
device_ptr->ctx_driver->set_filtering(1, g_settings.video.smooth);
}
break;
@ -1225,19 +1224,19 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
case SETTING_HW_TEXTURE_FILTER_2:
if((input & (1ULL << RMENU_DEVICE_NAV_LEFT)) || (input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
{
rmenu_settings_set(S_HW_TEXTURE_FILTER_2);
menu_settings_set(S_HW_TEXTURE_FILTER_2);
device_ptr->ctx_driver->set_filtering(2, g_settings.video.second_pass_smooth);
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
{
rmenu_settings_set(S_DEF_HW_TEXTURE_FILTER_2);
menu_settings_set(S_DEF_HW_TEXTURE_FILTER_2);
device_ptr->ctx_driver->set_filtering(2, g_settings.video.second_pass_smooth);
}
break;
case SETTING_SCALE_ENABLED:
if((input & (1ULL << RMENU_DEVICE_NAV_LEFT)) || (input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
{
rmenu_settings_set(S_SCALE_ENABLED);
menu_settings_set(S_SCALE_ENABLED);
if(g_settings.video.render_to_texture)
device_ptr->ctx_driver->set_fbo(FBO_INIT);
@ -1246,7 +1245,7 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
{
rmenu_settings_set_default(S_DEF_SCALE_ENABLED);
menu_settings_set_default(S_DEF_SCALE_ENABLED);
device_ptr->ctx_driver->set_fbo(FBO_REINIT);
}
break;
@ -1259,7 +1258,7 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
if(should_decrement)
{
rmenu_settings_set(S_SCALE_FACTOR_DECREMENT);
menu_settings_set(S_SCALE_FACTOR_DECREMENT);
device_ptr->ctx_driver->set_fbo(FBO_REINIT);
}
}
@ -1271,14 +1270,14 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
bool should_increment = g_settings.video.fbo.scale_x < MAX_SCALING_FACTOR;
if(should_increment)
{
rmenu_settings_set(S_SCALE_FACTOR_INCREMENT);
menu_settings_set(S_SCALE_FACTOR_INCREMENT);
device_ptr->ctx_driver->set_fbo(FBO_REINIT);
}
}
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
{
rmenu_settings_set_default(S_DEF_SCALE_FACTOR);
menu_settings_set_default(S_DEF_SCALE_FACTOR);
device_ptr->ctx_driver->set_fbo(FBO_REINIT);
}
break;
@ -1313,34 +1312,34 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
case SETTING_HW_OVERSCAN_AMOUNT:
if(input & (1ULL << RMENU_DEVICE_NAV_LEFT))
{
rmenu_settings_set(S_OVERSCAN_DECREMENT);
menu_settings_set(S_OVERSCAN_DECREMENT);
gfx_ctx_set_overscan();
}
if((input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
{
rmenu_settings_set(S_OVERSCAN_INCREMENT);
menu_settings_set(S_OVERSCAN_INCREMENT);
gfx_ctx_set_overscan();
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
{
rmenu_settings_set_default(S_DEF_OVERSCAN);
menu_settings_set_default(S_DEF_OVERSCAN);
gfx_ctx_set_overscan();
}
break;
case SETTING_REFRESH_RATE:
if(input & (1ULL << RMENU_DEVICE_NAV_LEFT))
{
rmenu_settings_set(S_REFRESH_RATE_DECREMENT);
menu_settings_set(S_REFRESH_RATE_DECREMENT);
driver_set_monitor_refresh_rate(g_settings.video.refresh_rate);
}
if((input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
{
rmenu_settings_set(S_REFRESH_RATE_INCREMENT);
menu_settings_set(S_REFRESH_RATE_INCREMENT);
driver_set_monitor_refresh_rate(g_settings.video.refresh_rate);
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
{
rmenu_settings_set_default(S_DEF_REFRESH_RATE);
menu_settings_set_default(S_DEF_REFRESH_RATE);
driver_set_monitor_refresh_rate(g_settings.video.refresh_rate);
}
break;
@ -1349,7 +1348,7 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
{
if (!(g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_PAL_VSYNC_BLOCK)))
{
rmenu_settings_set(S_THROTTLE);
menu_settings_set(S_THROTTLE);
device_ptr->ctx_driver->swap_interval((g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_THROTTLE_ENABLE)) ? true : false);
}
}
@ -1357,7 +1356,7 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
{
if (!(g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_PAL_VSYNC_BLOCK)))
{
rmenu_settings_set_default(S_DEF_THROTTLE);
menu_settings_set_default(S_DEF_THROTTLE);
device_ptr->ctx_driver->swap_interval((g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_THROTTLE_ENABLE)) ? true : false);
}
}
@ -1365,12 +1364,12 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
case SETTING_TRIPLE_BUFFERING:
if((input & (1ULL << RMENU_DEVICE_NAV_LEFT)) || (input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
{
rmenu_settings_set(S_TRIPLE_BUFFERING);
menu_settings_set(S_TRIPLE_BUFFERING);
driver.video->restart();
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
{
rmenu_settings_set_default(S_DEF_TRIPLE_BUFFERING);
menu_settings_set_default(S_DEF_TRIPLE_BUFFERING);
if(!(g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_TRIPLE_BUFFERING_ENABLE)))
driver.video->restart();
@ -1462,31 +1461,31 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
break;
case SETTING_EMU_CURRENT_SAVE_STATE_SLOT:
if(input & (1ULL << RMENU_DEVICE_NAV_LEFT))
rmenu_settings_set(S_SAVESTATE_DECREMENT);
menu_settings_set(S_SAVESTATE_DECREMENT);
if((input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
rmenu_settings_set(S_SAVESTATE_INCREMENT);
menu_settings_set(S_SAVESTATE_INCREMENT);
if(input & (1ULL << RMENU_DEVICE_NAV_START))
rmenu_settings_set_default(S_DEF_SAVE_STATE);
menu_settings_set_default(S_DEF_SAVE_STATE);
break;
case SETTING_EMU_SHOW_DEBUG_INFO_MSG:
if((input & (1ULL << RMENU_DEVICE_NAV_LEFT)) || (input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
rmenu_settings_set(S_INFO_DEBUG_MSG_TOGGLE);
menu_settings_set(S_INFO_DEBUG_MSG_TOGGLE);
if(input & (1ULL << RMENU_DEVICE_NAV_START))
rmenu_settings_set_default(S_DEF_INFO_DEBUG_MSG);
menu_settings_set_default(S_DEF_INFO_DEBUG_MSG);
break;
case SETTING_EMU_SHOW_INFO_MSG:
if((input & (1ULL << RMENU_DEVICE_NAV_LEFT)) || (input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
rmenu_settings_set(S_INFO_MSG_TOGGLE);
menu_settings_set(S_INFO_MSG_TOGGLE);
if(input & (1ULL << RMENU_DEVICE_NAV_START))
rmenu_settings_set_default(S_DEF_INFO_MSG);
menu_settings_set_default(S_DEF_INFO_MSG);
break;
case SETTING_EMU_REWIND_ENABLED:
if((input & (1ULL << RMENU_DEVICE_NAV_LEFT)) || (input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
{
rmenu_settings_set(S_REWIND);
menu_settings_set(S_REWIND);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
menu_settings_msg(S_MSG_RESTART_RARCH, 180);
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
g_settings.rewind_enable = false;
@ -1563,10 +1562,10 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
break;
case SETTING_EMU_AUDIO_MUTE:
if((input & (1ULL << RMENU_DEVICE_NAV_LEFT)) || (input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
rmenu_settings_set(S_AUDIO_MUTE);
menu_settings_set(S_AUDIO_MUTE);
if(input & (1ULL << RMENU_DEVICE_NAV_START))
rmenu_settings_set_default(S_DEF_AUDIO_MUTE);
menu_settings_set_default(S_DEF_AUDIO_MUTE);
break;
#ifdef _XBOX1
case SETTING_EMU_AUDIO_SOUND_VOLUME_LEVEL:
@ -1574,14 +1573,14 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input)
{
g_extern.console.sound.volume_level = !g_extern.console.sound.volume_level;
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
menu_settings_msg(S_MSG_RESTART_RARCH, 180);
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
{
g_extern.console.sound.volume_level = 0;
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
menu_settings_msg(S_MSG_RESTART_RARCH, 180);
}
break;
#endif
@ -1962,7 +1961,7 @@ int select_rom(void *data, void *state)
bool ret = filebrowser_iterate(filebrowser, FILEBROWSER_ACTION_OK);
if(!ret)
rmenu_settings_msg(S_MSG_DIR_LOADING_ERROR, S_DELAY_180);
menu_settings_msg(S_MSG_DIR_LOADING_ERROR, 180);
}
else
{
@ -2298,19 +2297,19 @@ int ingame_menu(void *data, void *state)
case MENU_ITEM_ORIENTATION:
if(input & (1ULL << RMENU_DEVICE_NAV_LEFT))
{
rmenu_settings_set(S_ROTATION_DECREMENT);
menu_settings_set(S_ROTATION_DECREMENT);
driver.video->set_rotation(NULL, g_extern.console.screen.orientation);
}
if((input & (1ULL << RMENU_DEVICE_NAV_RIGHT)) || (input & (1ULL << RMENU_DEVICE_NAV_B)))
{
rmenu_settings_set(S_ROTATION_INCREMENT);
menu_settings_set(S_ROTATION_INCREMENT);
driver.video->set_rotation(NULL, g_extern.console.screen.orientation);
}
if(input & (1ULL << RMENU_DEVICE_NAV_START))
{
rmenu_settings_set_default(S_DEF_ROTATION);
menu_settings_set_default(S_DEF_ROTATION);
driver.video->set_rotation(NULL, g_extern.console.screen.orientation);
}
snprintf(strw_buffer, sizeof(strw_buffer), "Press [%s] to reset back to default values.", rarch_input_find_platform_key_label(1ULL << RETRO_DEVICE_ID_JOYPAD_START));
@ -2330,7 +2329,7 @@ int ingame_menu(void *data, void *state)
{
g_extern.lifecycle_state |= (1ULL << RARCH_FRAMEADVANCE);
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_INGAME_EXIT);
rmenu_settings_set(S_FRAME_ADVANCE);
menu_settings_set(S_FRAME_ADVANCE);
menu_idx = MENU_ITEM_FRAME_ADVANCE;
return -1;
}
@ -2433,23 +2432,23 @@ int ingame_menu(void *data, void *state)
device_ptr->font_ctx->render_msg_place(device_ptr,default_pos.x_position, default_pos.comment_y_position, default_pos.font_size, WHITE, strw_buffer);
rmenu_settings_create_menu_item_label(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
menu_settings_create_menu_item_label(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
device_ptr->font_ctx->render_msg_place(device_ptr, default_pos.x_position, default_pos.y_position, default_pos.font_size, MENU_ITEM_SELECTED(MENU_ITEM_LOAD_STATE), strw_buffer);
rmenu_settings_create_menu_item_label(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
menu_settings_create_menu_item_label(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
device_ptr->font_ctx->render_msg_place(device_ptr, default_pos.x_position, default_pos.y_position+(default_pos.y_position_increment*MENU_ITEM_SAVE_STATE), default_pos.font_size, MENU_ITEM_SELECTED(MENU_ITEM_SAVE_STATE), strw_buffer);
rmenu_settings_create_menu_item_label(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
menu_settings_create_menu_item_label(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
device_ptr->font_ctx->render_msg_place(device_ptr, default_pos.x_position, (default_pos.y_position+(default_pos.y_position_increment*MENU_ITEM_KEEP_ASPECT_RATIO)), default_pos.font_size, MENU_ITEM_SELECTED(MENU_ITEM_KEEP_ASPECT_RATIO), strw_buffer);
snprintf(strw_buffer, sizeof(strw_buffer), "Overscan: %f", g_extern.console.screen.overscan_amount);
device_ptr->font_ctx->render_msg_place(device_ptr, default_pos.x_position, (default_pos.y_position+(default_pos.y_position_increment*MENU_ITEM_OVERSCAN_AMOUNT)), default_pos.font_size, MENU_ITEM_SELECTED(MENU_ITEM_OVERSCAN_AMOUNT), strw_buffer);
rmenu_settings_create_menu_item_label(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
menu_settings_create_menu_item_label(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
device_ptr->font_ctx->render_msg_place(device_ptr, default_pos.x_position, (default_pos.y_position+(default_pos.y_position_increment*MENU_ITEM_ORIENTATION)), default_pos.font_size, MENU_ITEM_SELECTED(MENU_ITEM_ORIENTATION), strw_buffer);
#ifdef HAVE_FBO
rmenu_settings_create_menu_item_label(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
menu_settings_create_menu_item_label(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
device_ptr->font_ctx->render_msg_place(device_ptr, default_pos.x_position, (default_pos.y_position+(default_pos.y_position_increment*MENU_ITEM_SCALE_FACTOR)), default_pos.font_size, MENU_ITEM_SELECTED(MENU_ITEM_SCALE_FACTOR), strw_buffer);
#endif
@ -2488,7 +2487,7 @@ int ingame_menu(void *data, void *state)
INPUT POLL CALLBACK
============================================================ */
void rmenu_input_poll(void *data, void *state)
void menu_input_poll(void *data, void *state)
{
menu *current_menu = (menu*)data;
@ -2544,7 +2543,7 @@ void rmenu_input_poll(void *data, void *state)
INPUT PROCESS CALLBACK
============================================================ */
int rmenu_input_process(void *data, void *state)
int menu_input_process(void *data, void *state)
{
(void)data;
DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data;
@ -2553,7 +2552,7 @@ int rmenu_input_process(void *data, void *state)
if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME))
{
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_LOADING_ROM, 100);
menu_settings_msg(S_MSG_LOADING_ROM, 100);
g_extern.lifecycle_mode_state |= (1ULL << MODE_INIT);
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME);
@ -2638,7 +2637,7 @@ void menu_free(void)
rmenu_state.free_resources(&rmenu_state);
}
bool rmenu_iterate(void)
bool menu_iterate(void)
{
const char *msg;
@ -2686,7 +2685,7 @@ bool rmenu_iterate(void)
}
if(current_menu.input_poll)
rmenu_input_poll(&current_menu, &rmenu_state);
menu_input_poll(&current_menu, &rmenu_state);
#ifdef HAVE_OSKUTIL
if(rmenu_state.osk_init != NULL)

View File

@ -205,7 +205,7 @@ enum
#define MAX_NO_OF_CONTROLS_SETTINGS SETTING_CONTROLS_DEFAULT_ALL+1
void menu_init (void);
bool rmenu_iterate(void);
bool menu_iterate(void);
void menu_free (void);
#endif /* MENU_H_ */

View File

@ -1,297 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
* Copyright (C) 2011-2013 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "rmenu.h"
#include "rgui.h"
#include "../../gfx/fonts/bitmap.h"
uint16_t menu_framebuf[400 * 240];
static const struct retro_keybind _rmenu_nav_binds[] = {
#ifdef HW_RVL
{ 0, 0, NULL, 0, GX_GC_UP | GX_GC_LSTICK_UP | GX_GC_RSTICK_UP | GX_CLASSIC_UP | GX_CLASSIC_LSTICK_UP | GX_CLASSIC_RSTICK_UP | GX_WIIMOTE_UP | GX_NUNCHUK_UP, 0 },
{ 0, 0, NULL, 0, GX_GC_DOWN | GX_GC_LSTICK_DOWN | GX_GC_RSTICK_DOWN | GX_CLASSIC_DOWN | GX_CLASSIC_LSTICK_DOWN | GX_CLASSIC_RSTICK_DOWN | GX_WIIMOTE_DOWN | GX_NUNCHUK_DOWN, 0 },
{ 0, 0, NULL, 0, GX_GC_LEFT | GX_GC_LSTICK_LEFT | GX_GC_RSTICK_LEFT | GX_CLASSIC_LEFT | GX_CLASSIC_LSTICK_LEFT | GX_CLASSIC_RSTICK_LEFT | GX_WIIMOTE_LEFT | GX_NUNCHUK_LEFT, 0 },
{ 0, 0, NULL, 0, GX_GC_RIGHT | GX_GC_LSTICK_RIGHT | GX_GC_RSTICK_RIGHT | GX_CLASSIC_RIGHT | GX_CLASSIC_LSTICK_RIGHT | GX_CLASSIC_RSTICK_RIGHT | GX_WIIMOTE_RIGHT | GX_NUNCHUK_RIGHT, 0 },
{ 0, 0, NULL, 0, GX_GC_A | GX_CLASSIC_A | GX_WIIMOTE_A | GX_WIIMOTE_2, 0 },
{ 0, 0, NULL, 0, GX_GC_B | GX_CLASSIC_B | GX_WIIMOTE_B | GX_WIIMOTE_1, 0 },
{ 0, 0, NULL, 0, GX_GC_START | GX_CLASSIC_PLUS | GX_WIIMOTE_PLUS, 0 },
{ 0, 0, NULL, 0, GX_GC_Z_TRIGGER | GX_CLASSIC_MINUS | GX_WIIMOTE_MINUS, 0 },
{ 0, 0, NULL, 0, GX_WIIMOTE_HOME | GX_CLASSIC_HOME, 0 },
#else
{ 0, 0, NULL, 0, GX_GC_UP | GX_GC_LSTICK_UP | GX_GC_RSTICK_UP, 0 },
{ 0, 0, NULL, 0, GX_GC_DOWN | GX_GC_LSTICK_DOWN | GX_GC_RSTICK_DOWN, 0 },
{ 0, 0, NULL, 0, GX_GC_LEFT | GX_GC_LSTICK_LEFT | GX_GC_RSTICK_LEFT, 0 },
{ 0, 0, NULL, 0, GX_GC_RIGHT | GX_GC_LSTICK_RIGHT | GX_GC_RSTICK_RIGHT, 0 },
{ 0, 0, NULL, 0, GX_GC_A, 0 },
{ 0, 0, NULL, 0, GX_GC_B, 0 },
{ 0, 0, NULL, 0, GX_GC_START, 0 },
{ 0, 0, NULL, 0, GX_GC_Z_TRIGGER, 0 },
{ 0, 0, NULL, 0, GX_WIIMOTE_HOME, 0 },
#endif
{ 0, 0, NULL, 0, GX_QUIT_KEY, 0 },
};
static const struct retro_keybind *rmenu_nav_binds[] = {
_rmenu_nav_binds
};
enum
{
GX_DEVICE_NAV_UP = 0,
GX_DEVICE_NAV_DOWN,
GX_DEVICE_NAV_LEFT,
GX_DEVICE_NAV_RIGHT,
GX_DEVICE_NAV_A,
GX_DEVICE_NAV_B,
GX_DEVICE_NAV_START,
GX_DEVICE_NAV_SELECT,
GX_DEVICE_NAV_MENU,
GX_DEVICE_NAV_QUIT,
RMENU_DEVICE_NAV_LAST
};
static bool folder_cb(const char *directory, rgui_file_enum_cb_t file_cb,
void *userdata, void *ctx)
{
#ifdef HAVE_LIBRETRO_MANAGEMENT
bool core_chooser = (userdata) ? *(rgui_file_type_t *)userdata == RGUI_SETTINGS_CORE : false;
#else
bool core_chooser = false;
#endif
if (!*directory)
{
#ifdef HW_RVL
file_cb(ctx, "sd:", RGUI_FILE_DEVICE, 0);
file_cb(ctx, "usb:", RGUI_FILE_DEVICE, 0);
#endif
file_cb(ctx, "carda:", RGUI_FILE_DEVICE, 0);
file_cb(ctx, "cardb:", RGUI_FILE_DEVICE, 0);
return true;
}
#ifdef HW_RVL
LWP_MutexLock(gx_device_mutex);
int dev = gx_get_device_from_path(directory);
if (dev != -1 && !gx_devices[dev].mounted && gx_devices[dev].interface->isInserted())
fatMountSimple(gx_devices[dev].name, gx_devices[dev].interface);
LWP_MutexUnlock(gx_device_mutex);
#endif
char exts[256];
if (core_chooser)
strlcpy(exts, "dol|DOL", sizeof(exts));
else
strlcpy(exts, g_extern.system.valid_extensions, sizeof(exts));
struct string_list *ext_list = string_split(exts, "|");
char _dir[PATH_MAX];
snprintf(_dir, sizeof(_dir), "%s/", directory);
DIR *dir = opendir(_dir);
if (!dir)
return false;
struct dirent *entry;
while ((entry = readdir(dir)))
{
char stat_path[PATH_MAX];
const char *file_ext = path_get_extension(entry->d_name);
snprintf(stat_path, sizeof(stat_path), "%s/%s", directory, entry->d_name);
bool is_dir;
#ifdef _DIRENT_HAVE_D_TYPE
is_dir = (entry->d_type == DT_DIR);
if (entry->d_type != DT_REG && !is_dir)
continue;
#else
struct stat st;
if (stat(stat_path, &st) < 0)
continue;
is_dir = S_ISDIR(st.st_mode);
if (!S_ISREG(st.st_mode) && !is_dir)
continue;
#endif
if (core_chooser && (is_dir || strcasecmp(entry->d_name, default_paths.salamander_file) == 0))
continue;
if (!is_dir && ext_list && !string_list_find_elem_prefix(ext_list, ".", file_ext))
continue;
file_cb(ctx,
entry->d_name,
is_dir ? RGUI_FILE_DIRECTORY : RGUI_FILE_PLAIN, 0);
}
closedir(dir);
string_list_free(ext_list);
return true;
}
/*============================================================
RMENU API
============================================================ */
void menu_init(void)
{
gx_video_t *gx = (gx_video_t*)driver.video_data;
gx->menu_data = (uint32_t *) menu_framebuf;
rgui = rgui_init("",
menu_framebuf, RGUI_WIDTH * sizeof(uint16_t),
NULL /* _binary_console_font_bmp_start */, bitmap_bin, folder_cb, NULL);
rgui_iterate(rgui, RGUI_ACTION_REFRESH);
}
void menu_free(void)
{
rgui_free(rgui);
}
static uint16_t trigger_state = 0;
int rmenu_input_process(void *data, void *state)
{
if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME))
{
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_LOADING_ROM, 100);
if (g_extern.fullpath)
g_extern.lifecycle_mode_state |= (1ULL << MODE_INIT);
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME);
return -1;
}
if (!(g_extern.frame_count < g_extern.delay_timer[0]))
{
bool return_to_game_enable = ((trigger_state & (1ULL << GX_DEVICE_NAV_MENU)) && g_extern.main_is_init);
if (return_to_game_enable)
{
g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
return -1;
}
}
return 0;
}
bool rmenu_iterate(void)
{
static uint16_t old_input_state = 0;
static bool initial_held = true;
static bool first_held = false;
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_DRAW);
driver.video->apply_state_changes();
g_extern.frame_count++;
uint16_t input_state = 0;
driver.input->poll(NULL);
for (unsigned i = 0; i < RMENU_DEVICE_NAV_LAST; i++)
input_state |= driver.input->input_state(NULL, rmenu_nav_binds, 0,
RETRO_DEVICE_JOYPAD, 0, i) ? (1ULL << i) : 0;
trigger_state = input_state & ~old_input_state;
bool do_held = (input_state & ((1ULL << GX_DEVICE_NAV_UP) | (1ULL << GX_DEVICE_NAV_DOWN) | (1ULL << GX_DEVICE_NAV_LEFT) | (1ULL << GX_DEVICE_NAV_RIGHT))) && !(input_state & ((1ULL << GX_DEVICE_NAV_MENU) | (1ULL << GX_DEVICE_NAV_QUIT)));
if(do_held)
{
if(!first_held)
{
first_held = true;
g_extern.delay_timer[1] = g_extern.frame_count + (initial_held ? 15 : 7);
}
if (!(g_extern.frame_count < g_extern.delay_timer[1]))
{
first_held = false;
trigger_state = input_state; //second input frame set as current frame
}
initial_held = false;
}
else
{
first_held = false;
initial_held = true;
}
old_input_state = input_state;
rgui_action_t action = RGUI_ACTION_NOOP;
// don't run anything first frame, only capture held inputs for old_input_state
if (trigger_state & (1ULL << GX_DEVICE_NAV_UP))
action = RGUI_ACTION_UP;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_DOWN))
action = RGUI_ACTION_DOWN;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_LEFT))
action = RGUI_ACTION_LEFT;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_RIGHT))
action = RGUI_ACTION_RIGHT;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_B))
action = RGUI_ACTION_CANCEL;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_A))
action = RGUI_ACTION_OK;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_START))
action = RGUI_ACTION_START;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_SELECT))
action = RGUI_ACTION_SETTINGS;
else if (trigger_state & (1ULL << GX_DEVICE_NAV_QUIT))
{
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXIT);
goto deinit;
}
int input_entry_ret = 0;
int input_process_ret = 0;
input_entry_ret = rgui_iterate(rgui, action);
// draw last frame for loading messages
rarch_render_cached_frame();
input_process_ret = rmenu_input_process(NULL, NULL);
if (input_entry_ret != 0 || input_process_ret != 0)
goto deinit;
return true;
deinit:
// set a timer delay so that we don't instantly switch back to the menu when
// press and holding QUIT in the emulation loop (lasts for 30 frame ticks)
if (!(g_extern.lifecycle_state & (1ULL << RARCH_FRAMEADVANCE)))
g_extern.delay_timer[0] = g_extern.frame_count + 30;
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU_DRAW);
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU_INGAME);
return false;
}

View File

@ -18,15 +18,17 @@
#include <crtdefs.h>
#include <tchar.h>
#include <xtl.h>
#include <xui.h>
#include <xuiapp.h>
#include "rmenu_xui.h"
#include "utils/file_browser.h"
#include "../../console/rarch_console.h"
#include "rmenu_settings.h"
#include "../../console/rarch_console_video.h"
#include "menu_settings.h"
#include "../../gfx/gfx_common.h"
#include "../../gfx/gfx_context.h"
#include "../../message.h"
@ -46,6 +48,152 @@ enum {
MENU_XUI_ITEM_QUIT_RARCH,
};
class CRetroArch : public CXuiModule
{
public:
HXUIOBJ hMainScene;
HXUIOBJ hControlsMenu;
HXUIOBJ hFileBrowser;
HXUIOBJ hCoreBrowser;
HXUIOBJ hShaderBrowser;
HXUIOBJ hQuickMenu;
HXUIOBJ hRetroArchSettings;
protected:
virtual HRESULT RegisterXuiClasses();
virtual HRESULT UnregisterXuiClasses();
};
class CRetroArchMain: public CXuiSceneImpl
{
protected:
CXuiControl m_filebrowser;
CXuiControl m_quick_menu;
CXuiControl m_controls;
CXuiControl m_settings;
CXuiControl m_change_libretro_core;
CXuiControl m_quit;
CXuiTextElement m_title;
CXuiTextElement m_core;
CXuiControl m_logoimage;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchMain, L"RetroArchMain", XUI_CLASS_SCENE)
};
class CRetroArchFileBrowser: public CXuiSceneImpl
{
protected:
CXuiControl m_back;
CXuiControl m_dir_game;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchFileBrowser, L"RetroArchFileBrowser", XUI_CLASS_SCENE)
};
class CRetroArchCoreBrowser: public CXuiSceneImpl
{
protected:
CXuiControl m_back;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchCoreBrowser, L"RetroArchCoreBrowser", XUI_CLASS_SCENE)
};
class CRetroArchShaderBrowser: public CXuiSceneImpl
{
protected:
CXuiControl m_back;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchShaderBrowser, L"RetroArchShaderBrowser", XUI_CLASS_SCENE)
};
class CRetroArchQuickMenu: public CXuiSceneImpl
{
protected:
CXuiList m_quickmenulist;
CXuiControl m_back;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
HRESULT OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled);
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_CONTROL_NAVIGATE( OnControlNavigate )
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchQuickMenu, L"RetroArchQuickMenu", XUI_CLASS_SCENE)
};
class CRetroArchSettings: public CXuiSceneImpl
{
protected:
CXuiList m_settingslist;
CXuiControl m_back;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
HRESULT OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled);
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_CONTROL_NAVIGATE( OnControlNavigate )
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchSettings, L"RetroArchSettings", XUI_CLASS_SCENE)
};
class CRetroArchControls: public CXuiSceneImpl
{
protected:
CXuiList m_controlslist;
CXuiControl m_back;
CXuiSlider m_controlnoslider;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
HRESULT OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled);
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_CONTROL_NAVIGATE( OnControlNavigate )
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchControls, L"RetroArchControls", XUI_CLASS_SCENE)
};
CRetroArch app;
CXuiList m_list;
CXuiTextElement m_list_path;
@ -116,6 +264,14 @@ HRESULT CRetroArch::UnregisterXuiClasses (void)
return 0;
}
static void menu_settings_create_menu_item_label_w(wchar_t *strwbuf, unsigned setting, size_t size)
{
char str[PATH_MAX];
menu_settings_create_menu_item_label(str, setting, sizeof(str));
convert_char_to_wchar(strwbuf, str, size);
}
static void browser_update(filebrowser_t * b, uint64_t input, const char *extensions);
static void filebrowser_fetch_directory_entries(filebrowser_t * browser, uint64_t action)
@ -171,7 +327,7 @@ static void browser_update(filebrowser_t * b, uint64_t input, const char *extens
ret = filebrowser_iterate(b, action);
if(!ret)
rmenu_settings_msg(S_MSG_DIR_LOADING_ERROR, S_DELAY_180);
menu_settings_msg(S_MSG_DIR_LOADING_ERROR, 180);
}
HRESULT CRetroArchFileBrowser::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
@ -400,13 +556,13 @@ HRESULT CRetroArchSettings::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
m_settingslist.SetText(SETTING_HW_TEXTURE_FILTER, g_settings.video.smooth ? L"Hardware filtering shader #1: Linear interpolation" : L"Hardware filtering shader #1: Point filtering");
m_settingslist.SetText(SETTING_HW_TEXTURE_FILTER_2, g_settings.video.second_pass_smooth ? L"Hardware filtering shader #2: Linear interpolation" : L"Hardware filtering shader #2: Point filtering");
m_settingslist.SetText(SETTING_SCALE_ENABLED, g_settings.video.render_to_texture ? L"Custom Scaling/Dual Shaders: ON" : L"Custom Scaling/Dual Shaders: OFF");
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SHADER, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SHADER, sizeof(strw_buffer));
m_settingslist.SetText(SETTING_SHADER, strw_buffer);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SHADER_2, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SHADER_2, sizeof(strw_buffer));
m_settingslist.SetText(SETTING_SHADER_2, strw_buffer);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
m_settingslist.SetText(SETTING_SCALE_FACTOR, strw_buffer);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_REWIND_GRANULARITY, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_REWIND_GRANULARITY, sizeof(strw_buffer));
m_settingslist.SetText(SETTING_EMU_REWIND_GRANULARITY, strw_buffer);
m_settingslist.SetText(SETTING_ENABLE_SRAM_PATH, (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME_SRAM_DIR_ENABLE)) ? L"SRAM Path Enable: ON" : L"SRAM Path Enable: OFF");
m_settingslist.SetText(SETTING_ENABLE_STATE_PATH, (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME_STATE_DIR_ENABLE)) ? L"Savestate Path Enable: ON" : L"Savestate Path Enable: OFF");
@ -428,16 +584,16 @@ HRESULT CRetroArchSettings::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled
switch(current_index)
{
case SETTING_EMU_REWIND_ENABLED:
rmenu_settings_set(S_REWIND);
menu_settings_set(S_REWIND);
m_settingslist.SetText(SETTING_EMU_REWIND_ENABLED, g_settings.rewind_enable ? L"Rewind: ON" : L"Rewind: OFF");
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
menu_settings_msg(S_MSG_RESTART_RARCH, 180);
break;
case SETTING_EMU_REWIND_GRANULARITY:
g_settings.rewind_granularity++;
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_REWIND_GRANULARITY, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_REWIND_GRANULARITY, sizeof(strw_buffer));
m_settingslist.SetText(SETTING_EMU_REWIND_GRANULARITY, strw_buffer);
break;
case SETTING_ENABLE_SRAM_PATH:
@ -502,7 +658,7 @@ HRESULT CRetroArchSettings::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled
hCur = app.hShaderBrowser;
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_SELECT_SHADER, S_DELAY_180);
menu_settings_msg(S_MSG_SELECT_SHADER, 180);
NavigateForward(app.hShaderBrowser);
break;
@ -515,7 +671,7 @@ HRESULT CRetroArchSettings::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled
hCur = app.hShaderBrowser;
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_SELECT_SHADER, S_DELAY_180);
menu_settings_msg(S_MSG_SELECT_SHADER, 180);
NavigateForward(app.hShaderBrowser);
break;
@ -556,17 +712,17 @@ HRESULT CRetroArchSettings::OnControlNavigate(XUIMessageControlNavigate *pContro
switch(current_index)
{
case SETTING_EMU_REWIND_ENABLED:
rmenu_settings_set(S_REWIND);
menu_settings_set(S_REWIND);
m_settingslist.SetText(SETTING_EMU_REWIND_ENABLED, g_settings.rewind_enable ? L"Rewind: ON" : L"Rewind: OFF");
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
menu_settings_msg(S_MSG_RESTART_RARCH, 180);
break;
case SETTING_EMU_REWIND_GRANULARITY:
if (g_settings.rewind_granularity > 1)
g_settings.rewind_granularity--;
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_REWIND_GRANULARITY, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_REWIND_GRANULARITY, sizeof(strw_buffer));
m_settingslist.SetText(SETTING_EMU_REWIND_GRANULARITY, strw_buffer);
break;
case SETTING_ENABLE_SRAM_PATH:
@ -626,9 +782,9 @@ HRESULT CRetroArchSettings::OnControlNavigate(XUIMessageControlNavigate *pContro
{
if((g_settings.video.fbo.scale_x > MIN_SCALING_FACTOR))
{
rmenu_settings_set(S_SCALE_FACTOR_DECREMENT);
menu_settings_set(S_SCALE_FACTOR_DECREMENT);
device_ptr->ctx_driver->set_fbo(FBO_REINIT);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
m_settingslist.SetText(SETTING_SCALE_FACTOR, strw_buffer);
}
}
@ -695,16 +851,16 @@ HRESULT CRetroArchSettings::OnControlNavigate(XUIMessageControlNavigate *pContro
m_settingslist.SetText(SETTING_GAMMA_CORRECTION_ENABLED, g_extern.console.screen.gamma_correction ? L"Gamma correction: ON" : L"Gamma correction: OFF");
break;
case SETTING_EMU_REWIND_ENABLED:
rmenu_settings_set(S_REWIND);
menu_settings_set(S_REWIND);
m_settingslist.SetText(SETTING_EMU_REWIND_ENABLED, g_settings.rewind_enable ? L"Rewind: ON" : L"Rewind: OFF");
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
menu_settings_msg(S_MSG_RESTART_RARCH, 180);
break;
case SETTING_EMU_REWIND_GRANULARITY:
g_settings.rewind_granularity++;
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_REWIND_GRANULARITY, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_REWIND_GRANULARITY, sizeof(strw_buffer));
m_settingslist.SetText(SETTING_EMU_REWIND_GRANULARITY, strw_buffer);
break;
case SETTING_ENABLE_SRAM_PATH:
@ -726,9 +882,9 @@ HRESULT CRetroArchSettings::OnControlNavigate(XUIMessageControlNavigate *pContro
{
if((g_settings.video.fbo.scale_x < MAX_SCALING_FACTOR))
{
rmenu_settings_set(S_SCALE_FACTOR_INCREMENT);
menu_settings_set(S_SCALE_FACTOR_INCREMENT);
device_ptr->ctx_driver->set_fbo(FBO_REINIT);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
m_settingslist.SetText(SETTING_SCALE_FACTOR, strw_buffer);
}
}
@ -781,16 +937,16 @@ HRESULT CRetroArchQuickMenu::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
GetChildById(L"XuiQuickMenuList", &m_quickmenulist);
GetChildById(L"XuiBackButton", &m_back);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_ORIENTATION, strw_buffer);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_ASPECT_RATIO, strw_buffer);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_LOAD_STATE, strw_buffer);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_SAVE_STATE, strw_buffer);
return 0;
@ -811,18 +967,18 @@ HRESULT CRetroArchQuickMenu::OnControlNavigate(XUIMessageControlNavigate *pContr
case MENU_XUI_ITEM_LOAD_STATE:
case MENU_XUI_ITEM_SAVE_STATE:
rarch_state_slot_decrease();
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_LOAD_STATE, strw_buffer);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_SAVE_STATE, strw_buffer);
break;
case MENU_XUI_ITEM_ASPECT_RATIO:
rmenu_settings_set(S_ASPECT_RATIO_DECREMENT);
menu_settings_set(S_ASPECT_RATIO_DECREMENT);
aspectratio_changed = true;
break;
case MENU_XUI_ITEM_ORIENTATION:
rmenu_settings_set(S_ROTATION_DECREMENT);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
menu_settings_set(S_ROTATION_DECREMENT);
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_ORIENTATION, strw_buffer);
driver.video->set_rotation(driver.video_data, g_extern.console.screen.orientation);
break;
@ -836,18 +992,18 @@ HRESULT CRetroArchQuickMenu::OnControlNavigate(XUIMessageControlNavigate *pContr
case MENU_XUI_ITEM_LOAD_STATE:
case MENU_XUI_ITEM_SAVE_STATE:
rarch_state_slot_increase();
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_LOAD_STATE, strw_buffer);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_SAVE_STATE, strw_buffer);
break;
case MENU_XUI_ITEM_ASPECT_RATIO:
rmenu_settings_set(S_ASPECT_RATIO_INCREMENT);
menu_settings_set(S_ASPECT_RATIO_INCREMENT);
aspectratio_changed = true;
break;
case MENU_XUI_ITEM_ORIENTATION:
rmenu_settings_set(S_ROTATION_INCREMENT);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
menu_settings_set(S_ROTATION_INCREMENT);
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_ORIENTATION, strw_buffer);
driver.video->set_rotation(driver.video_data, g_extern.console.screen.orientation);
break;
@ -863,7 +1019,7 @@ HRESULT CRetroArchQuickMenu::OnControlNavigate(XUIMessageControlNavigate *pContr
if(aspectratio_changed)
{
driver.video->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_ASPECT_RATIO, strw_buffer);
}
@ -913,31 +1069,31 @@ HRESULT CRetroArchQuickMenu::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled
}
break;
case MENU_XUI_ITEM_ASPECT_RATIO:
rmenu_settings_set_default(S_DEF_ASPECT_RATIO);
menu_settings_set_default(S_DEF_ASPECT_RATIO);
driver.video->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_ASPECT_RATIO, strw_buffer);
break;
case MENU_XUI_ITEM_ORIENTATION:
rmenu_settings_set_default(S_DEF_ROTATION);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
menu_settings_set_default(S_DEF_ROTATION);
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_ORIENTATION, strw_buffer);
driver.video->set_rotation(driver.video_data, g_extern.console.screen.orientation);
break;
case MENU_XUI_ITEM_RESIZE_MODE:
input_loop = INPUT_LOOP_RESIZE_MODE;
g_settings.video.aspect_ratio_idx = ASPECT_RATIO_CUSTOM;
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
m_quickmenulist.SetText(MENU_XUI_ITEM_ASPECT_RATIO, strw_buffer);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_RESIZE_SCREEN, S_DELAY_270);
menu_settings_msg(S_MSG_RESIZE_SCREEN, 270);
break;
case MENU_XUI_ITEM_FRAME_ADVANCE:
if (g_extern.main_is_init)
{
g_extern.lifecycle_state |= (1ULL << RARCH_FRAMEADVANCE);
rmenu_settings_set(S_FRAME_ADVANCE);
menu_settings_set(S_FRAME_ADVANCE);
process_input_ret = -1;
}
break;
@ -1005,7 +1161,7 @@ HRESULT CRetroArchShaderBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHand
{
driver.video->set_shader(driver.video_data, (enum rarch_shader_type)g_settings.video.shader_type, g_settings.video.cg_shader_path, RARCH_SHADER_INDEX_PASS0);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, S_DELAY_180);
menu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, 180);
XuiSceneNavigateBack(hCur, app.hMainScene, XUSER_INDEX_ANY);
}
else
@ -1020,7 +1176,7 @@ HRESULT CRetroArchShaderBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHand
{
driver.video->set_shader(driver.video_data, (enum rarch_shader_type)g_settings.video.shader_type, g_settings.video.second_pass_shader, RARCH_SHADER_INDEX_PASS1);
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, S_DELAY_180);
menu_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, 180);
}
else
RARCH_ERR("Shaders are unsupported on this platform.\n");
@ -1099,7 +1255,7 @@ HRESULT CRetroArchMain::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
convert_char_to_wchar(strw_buffer, g_extern.title_buf, sizeof(strw_buffer));
m_core.SetText(strw_buffer);
rmenu_settings_create_menu_item_label_w(strw_buffer, S_LBL_RARCH_VERSION, sizeof(strw_buffer));
menu_settings_create_menu_item_label_w(strw_buffer, S_LBL_RARCH_VERSION, sizeof(strw_buffer));
m_title.SetText(strw_buffer);
return 0;
@ -1144,7 +1300,7 @@ HRESULT CRetroArchMain::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled )
hCur = app.hControlsMenu;
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_CHANGE_CONTROLS, S_DELAY_180);
menu_settings_msg(S_MSG_CHANGE_CONTROLS, 180);
NavigateForward(app.hControlsMenu);
}
@ -1157,7 +1313,7 @@ HRESULT CRetroArchMain::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled )
hCur = app.hCoreBrowser;
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_SELECT_LIBRETRO_CORE, S_DELAY_180);
menu_settings_msg(S_MSG_SELECT_LIBRETRO_CORE, 180);
NavigateForward(app.hCoreBrowser);
}
@ -1291,7 +1447,7 @@ static void ingame_menu_resize (void)
input_loop = INPUT_LOOP_MENU;
}
bool rmenu_iterate(void)
bool menu_iterate(void)
{
const char *msg;
@ -1312,7 +1468,7 @@ bool rmenu_iterate(void)
if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME))
{
if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW))
rmenu_settings_msg(S_MSG_LOADING_ROM, 100);
menu_settings_msg(S_MSG_LOADING_ROM, 100);
g_extern.lifecycle_mode_state |= (1ULL << MODE_INIT);
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME);
@ -1375,3 +1531,10 @@ deinit:
return false;
}
bool menu_iterate_xui(void)
{
app.Render();
XuiTimersRun();
return true;
}

View File

@ -17,9 +17,6 @@
#ifndef _RMENU_XUI_H_
#define _RMENU_XUI_H_
#include <xui.h>
#include <xuiapp.h>
enum
{
SETTING_EMU_REWIND_ENABLED = 0,
@ -68,150 +65,6 @@ enum
INPUT_LOOP_FILEBROWSER
};
class CRetroArch : public CXuiModule
{
public:
HXUIOBJ hMainScene;
HXUIOBJ hControlsMenu;
HXUIOBJ hFileBrowser;
HXUIOBJ hCoreBrowser;
HXUIOBJ hShaderBrowser;
HXUIOBJ hQuickMenu;
HXUIOBJ hRetroArchSettings;
protected:
virtual HRESULT RegisterXuiClasses();
virtual HRESULT UnregisterXuiClasses();
};
class CRetroArchMain: public CXuiSceneImpl
{
protected:
CXuiControl m_filebrowser;
CXuiControl m_quick_menu;
CXuiControl m_controls;
CXuiControl m_settings;
CXuiControl m_change_libretro_core;
CXuiControl m_quit;
CXuiTextElement m_title;
CXuiTextElement m_core;
CXuiControl m_logoimage;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchMain, L"RetroArchMain", XUI_CLASS_SCENE)
};
class CRetroArchFileBrowser: public CXuiSceneImpl
{
protected:
CXuiControl m_back;
CXuiControl m_dir_game;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchFileBrowser, L"RetroArchFileBrowser", XUI_CLASS_SCENE)
};
class CRetroArchCoreBrowser: public CXuiSceneImpl
{
protected:
CXuiControl m_back;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchCoreBrowser, L"RetroArchCoreBrowser", XUI_CLASS_SCENE)
};
class CRetroArchShaderBrowser: public CXuiSceneImpl
{
protected:
CXuiControl m_back;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchShaderBrowser, L"RetroArchShaderBrowser", XUI_CLASS_SCENE)
};
class CRetroArchQuickMenu: public CXuiSceneImpl
{
protected:
CXuiList m_quickmenulist;
CXuiControl m_back;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
HRESULT OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled);
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_CONTROL_NAVIGATE( OnControlNavigate )
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchQuickMenu, L"RetroArchQuickMenu", XUI_CLASS_SCENE)
};
class CRetroArchSettings: public CXuiSceneImpl
{
protected:
CXuiList m_settingslist;
CXuiControl m_back;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
HRESULT OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled);
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_CONTROL_NAVIGATE( OnControlNavigate )
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchSettings, L"RetroArchSettings", XUI_CLASS_SCENE)
};
class CRetroArchControls: public CXuiSceneImpl
{
protected:
CXuiList m_controlslist;
CXuiControl m_back;
CXuiSlider m_controlnoslider;
public:
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
HRESULT OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled);
XUI_BEGIN_MSG_MAP()
XUI_ON_XM_INIT( OnInit)
XUI_ON_XM_CONTROL_NAVIGATE( OnControlNavigate )
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
XUI_END_MSG_MAP();
XUI_IMPLEMENT_CLASS(CRetroArchControls, L"RetroArchControls", XUI_CLASS_SCENE)
};
bool menu_iterate_xui(void);
#endif

View File

@ -16,7 +16,6 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "file_list.h"
#include "../rgui.h"
@ -24,7 +23,7 @@
struct rgui_file
{
char *path;
rgui_file_type_t type;
unsigned type;
size_t directory_ptr;
};
@ -47,7 +46,7 @@ bool rgui_list_empty(const rgui_list_t *list)
}
void rgui_list_push(rgui_list_t *list,
const char *path, rgui_file_type_t type, size_t directory_ptr)
const char *path, unsigned type, size_t directory_ptr)
{
if (list->ptr >= list->capacity)
{
@ -84,7 +83,7 @@ void rgui_list_clear(rgui_list_t *list)
}
void rgui_list_back(const rgui_list_t *list,
const char **path, rgui_file_type_t *file_type, size_t *directory_ptr)
const char **path, unsigned *file_type, size_t *directory_ptr)
{
if (rgui_list_size(list) > 0)
rgui_list_at(list, rgui_list_size(list) - 1, path, file_type, directory_ptr);
@ -96,7 +95,7 @@ size_t rgui_list_size(const rgui_list_t *list)
}
void rgui_list_at(const rgui_list_t *list, size_t index,
const char **path, rgui_file_type_t *file_type, size_t *directory_ptr)
const char **path, unsigned *file_type, size_t *directory_ptr)
{
if (path)
*path = list->list[index].path;

View File

@ -26,17 +26,17 @@ rgui_list_t *rgui_list_new(void);
void rgui_list_free(rgui_list_t *list);
void rgui_list_push(rgui_list_t *list,
const char *path, rgui_file_type_t type, size_t directory_ptr);
const char *path, unsigned type, size_t directory_ptr);
void rgui_list_pop(rgui_list_t *list);
void rgui_list_clear(rgui_list_t *list);
bool rgui_list_empty(const rgui_list_t *list);
void rgui_list_back(const rgui_list_t *list,
const char **path, rgui_file_type_t *type, size_t *directory_ptr);
const char **path, unsigned *type, size_t *directory_ptr);
size_t rgui_list_size(const rgui_list_t *list);
void rgui_list_at(const rgui_list_t *list, size_t index,
const char **path, rgui_file_type_t *type, size_t *directory_ptr);
const char **path, unsigned *type, size_t *directory_ptr);
void rgui_list_sort(rgui_list_t *list);

View File

@ -53,8 +53,8 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->browser_draw = NULL;
current_menu->input_process = NULL;
current_menu->input_poll = rmenu_input_poll;
current_menu->input_process = rmenu_input_process;
current_menu->input_poll = menu_input_poll;
current_menu->input_process = menu_input_process;
switch(menu_id)
{

View File

@ -54,11 +54,8 @@ int ingame_menu_resize(void *data, void *state);
int ingame_menu_screenshot(void *data, void *state);
int ingame_menu(void *data, void *state);
// input poll forward declarations
void rmenu_input_poll(void *data, void *state);
// input process forward declarations
int rmenu_input_process(void *data, void *state);
void menu_input_poll(void *data, void *state);
int menu_input_process(void *data, void *state);
// browser_draw forward declarations
void browser_render(void *data);

View File

@ -194,7 +194,7 @@ void menu_init (void)
{
}
bool rmenu_iterate(void)
bool menu_iterate(void)
{
strlcpy(g_extern.fullpath, "/dev_hdd0/game/SSNE10000/USRDIR/mm3.nes", sizeof(g_extern.fullpath));
g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME);

View File

@ -94,7 +94,7 @@ static int setup_callback(void)
void menu_init (void) {}
bool rmenu_iterate(void)
bool menu_iterate(void)
{
char path[256];
snprintf(path, sizeof(path), "%s%s", default_paths.port_dir, "dkc.sfc");

View File

@ -242,6 +242,7 @@ struct settings
bool debug_enable;
#ifdef ANDROID
bool autodetect_enable;
unsigned back_behavior;
unsigned icade_profile[MAX_PLAYERS];
unsigned icade_count;
#endif
@ -384,6 +385,8 @@ struct global
char valid_extensions[PATH_MAX];
retro_keyboard_event_t key_event;
struct retro_disk_control_callback disk_control;
} system;
struct
@ -788,6 +791,18 @@ static inline void rarch_fail(int error_code, const char *error)
longjmp(g_extern.error_sjlj_context, error_code);
}
// Helper macros and struct to keep track of many booleans.
// To check for multiple bits, use &&, not &.
// For OR, | can be used.
typedef struct
{
uint32_t data[8];
} rarch_bits_t;
#define BIT_SET(a, bit) ((a).data[(bit) >> 5] |= 1 << ((bit) & 31))
#define BIT_CLEAR(a, bit) ((a).data[(bit) >> 5] &= ~(1 << ((bit) & 31)))
#define BIT_GET(a, bit) ((a).data[(bit) >> 5] & (1 << ((bit) & 31)))
#define BIT_CLEAR_ALL(a) memset(&(a), 0, sizeof(a));
#endif

View File

@ -169,3 +169,73 @@ void gfx_scale_integer(struct rarch_viewport *vp, unsigned width, unsigned heigh
vp->y = padding_y >> 1;
}
struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END] = {
{ "1:1", 1.0f },
{ "2:1", 2.0f },
{ "3:2", 1.5f },
{ "3:4", 0.75f },
{ "4:1", 4.0f },
{ "4:3", 1.3333f },
{ "4:4", 1.0f },
{ "5:4", 1.25f },
{ "6:5", 1.2f },
{ "7:9", 0.7777f },
{ "8:3", 2.6666f },
{ "8:7", 1.1428f },
{ "16:9", 1.7778f },
{ "16:10", 1.6f },
{ "16:15", 3.2f },
{ "19:12", 1.5833f },
{ "19:14", 1.3571f },
{ "30:17", 1.7647f },
{ "32:9", 3.5555f },
{ "Auto", 1.0f },
{ "Core Provided", 1.0f },
{ "Custom", 0.0f }
};
char rotation_lut[ASPECT_RATIO_END][32] =
{
"Normal",
"Vertical",
"Flipped",
"Flipped Rotated"
};
void gfx_set_auto_viewport(unsigned width, unsigned height)
{
if (width == 0 || height == 0)
return;
unsigned aspect_x, aspect_y, len, highest, i;
len = width < height ? width : height;
highest = 1;
for (i = 1; i < len; i++)
{
if ((width % i) == 0 && (height % i) == 0)
highest = i;
}
aspect_x = width / highest;
aspect_y = height / highest;
snprintf(aspectratio_lut[ASPECT_RATIO_AUTO].name,
sizeof(aspectratio_lut[ASPECT_RATIO_AUTO].name),
"%d:%d (Auto)", aspect_x, aspect_y);
aspectratio_lut[ASPECT_RATIO_AUTO].value = (float)aspect_x / aspect_y;
}
void gfx_set_core_viewport(void)
{
if (!g_extern.main_is_init)
return;
// fallback to 1:1 pixel ratio if none provided
if (g_extern.system.av_info.geometry.aspect_ratio == 0.0)
aspectratio_lut[ASPECT_RATIO_CORE].value = (float)g_extern.system.av_info.geometry.base_width / g_extern.system.av_info.geometry.base_height;
else
aspectratio_lut[ASPECT_RATIO_CORE].value = g_extern.system.av_info.geometry.aspect_ratio;
}

View File

@ -40,6 +40,83 @@ void gfx_set_dwm(void);
void gfx_scale_integer(struct rarch_viewport *vp, unsigned win_width, unsigned win_height,
float aspect_ratio, bool keep_aspect);
#define MIN_SCALING_FACTOR (1.0f)
#if defined(__CELLOS_LV2__)
#define MAX_SCALING_FACTOR (5.0f)
#else
#define MAX_SCALING_FACTOR (2.0f)
#endif
enum aspect_ratio
{
ASPECT_RATIO_1_1 = 0,
ASPECT_RATIO_2_1,
ASPECT_RATIO_3_2,
ASPECT_RATIO_3_4,
ASPECT_RATIO_4_1,
ASPECT_RATIO_4_3,
ASPECT_RATIO_4_4,
ASPECT_RATIO_5_4,
ASPECT_RATIO_6_5,
ASPECT_RATIO_7_9,
ASPECT_RATIO_8_3,
ASPECT_RATIO_8_7,
ASPECT_RATIO_16_9,
ASPECT_RATIO_16_10,
ASPECT_RATIO_16_15,
ASPECT_RATIO_19_12,
ASPECT_RATIO_19_14,
ASPECT_RATIO_30_17,
ASPECT_RATIO_32_9,
ASPECT_RATIO_AUTO,
ASPECT_RATIO_CORE,
ASPECT_RATIO_CUSTOM,
ASPECT_RATIO_END,
};
#define LAST_ASPECT_RATIO ASPECT_RATIO_CUSTOM
enum rotation
{
ORIENTATION_NORMAL = 0,
ORIENTATION_VERTICAL,
ORIENTATION_FLIPPED,
ORIENTATION_FLIPPED_ROTATED,
ORIENTATION_END
};
#define LAST_ORIENTATION (ORIENTATION_END - 1)
extern char rotation_lut[ASPECT_RATIO_END][32];
/* ABGR color format defines */
#define WHITE 0xffffffffu
#define RED 0xff0000ffu
#define GREEN 0xff00ff00u
#define BLUE 0xffff0000u
#define YELLOW 0xff00ffffu
#define PURPLE 0xffff00ffu
#define CYAN 0xffffff00u
#define ORANGE 0xff0063ffu
#define SILVER 0xff8c848cu
#define LIGHTBLUE 0xFFFFE0E0U
#define LIGHTORANGE 0xFFE0EEFFu
struct aspect_ratio_elem
{
char name[64];
float value;
};
extern struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END];
extern void gfx_set_auto_viewport(unsigned width, unsigned height);
extern void gfx_set_core_viewport(void);
#ifdef __cplusplus
}
#endif

View File

@ -23,12 +23,21 @@
#include "../config.h"
#endif
#if defined(RARCH_CONSOLE) || defined(HAVE_RMENU)
#if defined(HAVE_RMENU)
#include "../frontend/menu/rmenu.h"
#endif
#define MAX_EGLIMAGE_TEXTURES 32
#ifdef HAVE_FBO
enum fbo_option
{
FBO_DEINIT = 0,
FBO_INIT,
FBO_REINIT
};
#endif
enum gfx_ctx_api
{
GFX_CTX_OPENGL_API,
@ -108,7 +117,7 @@ typedef struct gfx_ctx_driver
// Human readable string.
const char *ident;
#if defined(HAVE_RMENU) || defined(_XBOX360)
#if defined(HAVE_RMENU)
void (*set_blend)(bool enable);
void (*set_filtering)(unsigned index, bool set_smooth);
void (*get_available_resolutions)(void);

200
gfx/gl.c
View File

@ -57,6 +57,10 @@
#include "../frontend/frontend_android.h"
#endif
#ifdef HAVE_RGUI
#include "../frontend/menu/rgui.h"
#endif
// Used for the last pass when rendering to the back buffer.
const GLfloat vertexes_flipped[] = {
0, 1,
@ -668,14 +672,12 @@ void gl_init_fbo(void *data, unsigned width, unsigned height)
void gl_set_projection(void *data, struct gl_ortho *ortho, bool allow_rotate)
{
gl_t *gl = (gl_t*)data;
#ifdef RARCH_CONSOLE
if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_OVERSCAN_ENABLE))
{
ortho->left = -g_extern.console.screen.overscan_amount / 2;
ortho->right = 1 + g_extern.console.screen.overscan_amount / 2;
ortho->bottom = -g_extern.console.screen.overscan_amount / 2;
}
#endif
// Calculate projection.
matrix_ortho(&gl->mvp_no_rot, ortho->left, ortho->right,
@ -715,7 +717,7 @@ void gl_set_viewport(void *data, unsigned width, unsigned height, bool force_ful
float desired_aspect = g_settings.video.aspect_ratio;
float delta;
#ifdef RARCH_CONSOLE
#ifdef HAVE_RGUI
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
{
x = g_extern.console.screen.viewports.custom_vp.x;
@ -1050,23 +1052,17 @@ static void gl_init_textures_data(void *data)
#if defined(HAVE_PSGL)
static inline void gl_copy_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch)
{
gl_t *gl = (gl_t*)data;
gl_t *gl = (gl_t*)data;
size_t buffer_addr = gl->tex_w * gl->tex_h * gl->tex_index * gl->base_size;
size_t buffer_stride = gl->tex_w * gl->base_size;
const uint8_t *frame_copy = frame;
size_t frame_copy_size = width * gl->base_size;
for (unsigned h = 0; h < height; h++)
{
glBufferSubData(GL_TEXTURE_REFERENCE_BUFFER_SCE,
buffer_addr,
frame_copy_size,
frame_copy);
uint8_t *buffer = (uint8_t*)glMapBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, GL_READ_WRITE) + buffer_addr;
for (unsigned h = 0; h < height; h++, buffer += buffer_stride, frame_copy += pitch)
memcpy(buffer, frame_copy, frame_copy_size);
frame_copy += pitch;
buffer_addr += buffer_stride;
}
glUnmapBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE);
}
static void gl_init_textures(void *data, const video_info_t *video)
@ -1082,6 +1078,15 @@ static void gl_init_textures(void *data, const video_info_t *video)
glGenTextures(TEXTURES, gl->texture);
#ifdef HAVE_RGUI
glGenTextures(1, &gl->rgui_texture);
glBindTexture(GL_TEXTURE_2D, gl->rgui_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl->border_type);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl->border_type);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
#endif
for (unsigned i = 0; i < TEXTURES; i++)
{
glBindTexture(GL_TEXTURE_2D, gl->texture[i]);
@ -1190,6 +1195,16 @@ static void gl_init_textures(void *data, const video_info_t *video)
#endif
glGenTextures(TEXTURES, gl->texture);
#ifdef HAVE_RGUI
glGenTextures(1, &gl->rgui_texture);
glBindTexture(GL_TEXTURE_2D, gl->rgui_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl->border_type);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl->border_type);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
#endif
for (unsigned i = 0; i < TEXTURES; i++)
{
glBindTexture(GL_TEXTURE_2D, gl->texture[i]);
@ -1249,15 +1264,39 @@ static void gl_pbo_async_readback(void *data)
}
#endif
#ifdef HAVE_RGUI
static inline void gl_draw_rgui(void *data)
{
gl_t *gl = (gl_t*)data;
gl->coords.tex_coord = tex_coords;
glBindTexture(GL_TEXTURE_2D, gl->rgui_texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(RGUI_WIDTH * 2));
// RGUI is always packed so pitch = width * bpp
glTexImage2D(GL_TEXTURE_2D,
0, GL_RGBA, RGUI_WIDTH, RGUI_HEIGHT, 0, GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4, gl->menu_data);
gl_shader_use_func(gl, 0);
gl_shader_set_coords_func(gl, &gl->coords, &gl->mvp_no_rot);
glEnable(GL_BLEND);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisable(GL_BLEND);
gl->coords.tex_coord = gl->tex_coords;
}
#endif
static bool gl_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg)
{
RARCH_PERFORMANCE_INIT(frame_run);
RARCH_PERFORMANCE_START(frame_run);
gl_t *gl = (gl_t*)data;
#ifdef HAVE_RMENU
uint64_t lifecycle_mode_state = g_extern.lifecycle_mode_state;
#endif
(void)lifecycle_mode_state;
gl_shader_use_func(gl, 1);
@ -1326,6 +1365,11 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
gl_set_prev_texture(gl, &tex_info);
#ifdef HAVE_RGUI
if (lifecycle_mode_state & (1ULL << MODE_MENU_DRAW))
gl_draw_rgui(gl);
#endif
#ifdef FPS_COUNTER
if (lifecycle_mode_state & (1ULL << MODE_FPS_DRAW))
{
@ -1353,7 +1397,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
RARCH_PERFORMANCE_STOP(frame_run);
#ifdef HAVE_RMENU
#if defined(HAVE_RMENU)
if (lifecycle_mode_state & (1ULL << MODE_MENU_DRAW))
context_rmenu_frame_func(gl);
else
@ -1401,6 +1445,10 @@ static void gl_free(void *data)
glDeleteTextures(TEXTURES, gl->texture);
#ifdef HAVE_RGUI
glDeleteTextures(1, &gl->rgui_texture);
#endif
#ifdef HAVE_OVERLAY
if (gl->tex_overlay)
glDeleteTextures(1, &gl->tex_overlay);
@ -1523,6 +1571,10 @@ static inline void gl_reinit_textures(void *data, const video_info_t *video)
glBindTexture(GL_TEXTURE_2D, 0);
glDeleteTextures(TEXTURES, gl->texture);
#ifdef HAVE_RGUI
glDeleteTextures(1, &gl->rgui_texture);
#endif
gl_init_textures(gl, video);
gl_init_textures_data(gl);
@ -1771,7 +1823,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
if (input && input_data)
context_input_driver_func(input, input_data);
#ifndef HAVE_RMENU
#if !defined(HAVE_RMENU)
// Comes too early for console - moved to gl_start
if (g_settings.video.font_enable)
gl->font_ctx = gl_font_init_first(gl, g_settings.video.font_path, g_settings.video.font_size);
@ -1980,6 +2032,8 @@ static bool gl_read_viewport(void *data, uint8_t *buffer)
#endif
#ifdef HAVE_RMENU
static void gl_get_poke_interface(void *data, const video_poke_interface **iface);
static void gl_start(void)
{
video_info_t video_info = {0};
@ -2000,6 +2054,7 @@ static void gl_start(void)
driver.video_data = gl_init(&video_info, NULL, NULL);
gl_t *gl = (gl_t*)driver.video_data;
gl_get_poke_interface(gl, &driver.video_poke);
#ifdef RARCH_CONSOLE
// Comes too early for console - moved to gl_start
@ -2037,28 +2092,6 @@ static void gl_restart(void)
#endif
gl_start();
}
static void gl_apply_state_changes(void)
{
gl_t *gl = (gl_t*)driver.video_data;
gl->should_resize = true;
}
static void gl_set_aspect_ratio(void *data, unsigned aspectratio_index)
{
(void)data;
gl_t *gl = driver.video_data;
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_AUTO)
rarch_set_auto_viewport(g_extern.frame_cache.width, g_extern.frame_cache.height);
else if(g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CORE)
rarch_set_core_viewport();
g_settings.video.aspect_ratio = aspectratio_lut[g_settings.video.aspect_ratio_idx].value;
g_settings.video.force_aspect = false;
gl->keep_aspect = true;
gl->should_resize = true;
}
#endif
#ifdef HAVE_OVERLAY
@ -2070,8 +2103,8 @@ static bool gl_overlay_load(void *data, const uint32_t *image, unsigned width, u
glGenTextures(1, &gl->tex_overlay);
glBindTexture(GL_TEXTURE_2D, gl->tex_overlay);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl->border_type);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl->border_type);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@ -2185,6 +2218,85 @@ static void gl_get_overlay_interface(void *data, const video_overlay_interface_t
}
#endif
static void gl_set_filtering(void *data, unsigned index, bool smooth)
{
gl_t *gl = (gl_t*)data;
GLuint filter = smooth ? GL_LINEAR : GL_NEAREST;
if (index == 1)
{
gl->tex_filter = filter;
// Apply to all PREV textures.
for (unsigned i = 0; i < TEXTURES; i++)
{
glBindTexture(GL_TEXTURE_2D, gl->texture[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
}
}
#ifdef HAVE_FBO
else if (index >= 2 && gl->fbo_inited)
{
glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[index - 2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
}
#endif
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
}
static void gl_set_fbo_state(void *data, unsigned mode)
{
#ifdef HAVE_FBO
gl_t *gl = (gl_t*)data;
switch (mode)
{
case FBO_DEINIT:
gl_deinit_fbo(gl);
break;
case FBO_REINIT:
gl_deinit_fbo(gl);
// Fallthrough
case FBO_INIT:
gl_init_fbo(gl, gl->tex_w, gl->tex_h);
break;
}
#else
(void)data;
(void)mode;
#endif
}
static void gl_set_aspect_ratio(void *data, unsigned aspectratio_index)
{
gl_t *gl = (gl_t*)data;
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_AUTO)
gfx_set_auto_viewport(g_extern.frame_cache.width, g_extern.frame_cache.height);
else if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CORE)
gfx_set_core_viewport();
g_settings.video.aspect_ratio = aspectratio_lut[g_settings.video.aspect_ratio_idx].value;
g_settings.video.force_aspect = false;
gl->keep_aspect = true;
gl->should_resize = true;
}
static const video_poke_interface_t gl_poke_interface = {
gl_set_filtering,
gl_set_fbo_state,
gl_set_aspect_ratio,
};
static void gl_get_poke_interface(void *data, const video_poke_interface_t **iface)
{
(void)data;
*iface = &gl_poke_interface;
}
const video_driver_t video_gl = {
gl_init,
gl_frame,
@ -2205,10 +2317,7 @@ const video_driver_t video_gl = {
gl_start,
gl_stop,
gl_restart,
gl_apply_state_changes,
gl_set_aspect_ratio,
#endif
gl_set_rotation,
#ifndef NO_GL_READ_VIEWPORT
@ -2222,6 +2331,7 @@ const video_driver_t video_gl = {
#ifdef HAVE_OVERLAY
gl_get_overlay_interface,
#endif
gl_get_poke_interface,
};

View File

@ -59,6 +59,7 @@
#include <GL/glext.h>
#endif
#if defined(ANDROID) && defined(HAVE_GRIFFIN)
#include "../console/griffin/hook_context.h"
#else
@ -304,6 +305,11 @@ typedef struct gl
struct scaler_ctx pbo_readback_scaler;
#endif
#ifdef HAVE_RGUI
GLuint rgui_texture;
uint32_t *menu_data;
#endif
} gl_t;
// Windows ... <_<

View File

@ -535,6 +535,17 @@ static void thread_get_overlay_interface(void *data, const video_overlay_interfa
}
#endif
#if defined(HAVE_RMENU)
// all stubs for now, might not have to implement them unless we want to port this to consoles
static void thread_start(void) {}
static void thread_stop(void) {}
static void thread_restart(void) {}
#endif
#if defined(HAVE_RMENU) || defined(HAVE_RGUI)
static void thread_set_aspect_ratio(void *data, unsigned aspectratio_index) {}
#endif
static const video_driver_t video_thread = {
thread_init_never_call, // Should never be called directly.
thread_frame,
@ -544,6 +555,14 @@ static const video_driver_t video_thread = {
thread_set_shader,
thread_free,
"Thread wrapper",
#if defined(HAVE_RMENU)
thread_start,
thread_stop,
thread_restart,
#endif
#if defined(HAVE_RMENU) || defined(HAVE_RGUI)
thread_set_aspect_ratio,
#endif
thread_set_rotation,
thread_viewport_info,
thread_read_viewport,

View File

@ -460,8 +460,8 @@ static void gx_input_poll(void *data)
(1ULL << RARCH_STATE_SLOT_MINUS) |
(1ULL << RARCH_REWIND) |
(1ULL << RARCH_QUIT_KEY) |
(1ULL << RARCH_RMENU_TOGGLE) |
(1ULL << RARCH_RMENU_QUICKMENU_TOGGLE));
(1ULL << RARCH_MENU_TOGGLE) |
(1ULL << RARCH_MENU_QUICKMENU_TOGGLE));
if (
#ifdef HW_RVL
@ -528,10 +528,7 @@ static void gx_input_poll(void *data)
| GX_CLASSIC_HOME
#endif
))
{
*lifecycle_state |= (1ULL << RARCH_RMENU_TOGGLE);
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
}
*lifecycle_state |= (1ULL << RARCH_MENU_TOGGLE);
}
}

View File

@ -17,7 +17,6 @@
#include "../driver.h"
#include "../general.h"
#include "../console/rarch_console_video.h"
#include "../gfx/fonts/bitmap.h"
#include "../frontend/menu/rgui.h"
#include "../gfx/gfx_common.h"
@ -271,14 +270,14 @@ const char *gx_get_video_mode(void)
return format;
}
void gx_set_aspect_ratio(void *data, unsigned aspectratio_idx)
static void gx_set_aspect_ratio(void *data, unsigned aspectratio_idx)
{
gx_video_t *gx = (gx_video_t*)driver.video_data;
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_AUTO)
rarch_set_auto_viewport(g_extern.frame_cache.width, g_extern.frame_cache.height);
gfx_set_auto_viewport(g_extern.frame_cache.width, g_extern.frame_cache.height);
else if(g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CORE)
rarch_set_core_viewport();
gfx_set_core_viewport();
g_settings.video.aspect_ratio = aspectratio_lut[g_settings.video.aspect_ratio_idx].value;
g_settings.video.force_aspect = false;
@ -1013,12 +1012,6 @@ static void gx_set_rotation(void *data, unsigned orientation)
gx->should_resize = true;
}
static void gx_apply_state_changes(void)
{
gx_video_t *gx = (gx_video_t*)driver.video_data;
gx->should_resize = true;
}
static bool gx_set_shader(void *data, enum rarch_shader_type type, const char *path, unsigned index)
{
(void)data;
@ -1042,6 +1035,5 @@ const video_driver_t video_gx = {
.start = gx_start,
.stop = gx_stop,
.restart = gx_restart,
.apply_state_changes = gx_apply_state_changes,
.set_aspect_ratio = gx_set_aspect_ratio
};

View File

@ -32,8 +32,7 @@ typedef struct gx_video
} gx_video_t;
void gx_set_video_mode(unsigned fbWidth, unsigned lines);
const char *gx_get_video_mode();
void gx_set_aspect_ratio(void *data, unsigned aspectratio_idx);
const char *gx_get_video_mode(void);
#endif

View File

@ -549,6 +549,8 @@ static const struct str_to_bind_map str_to_bind[] = {
{ "volume_up", RARCH_VOLUME_UP },
{ "volume_down", RARCH_VOLUME_DOWN },
{ "overlay_next", RARCH_OVERLAY_NEXT },
{ "disk_eject_toggle", RARCH_DISK_EJECT_TOGGLE },
{ "disk_next", RARCH_DISK_NEXT },
};
unsigned input_str_to_bind(const char *str)

View File

@ -49,6 +49,14 @@ static inline void input_conv_analog_id_to_bind_id(unsigned index, unsigned id,
bool input_translate_coord_viewport(int mouse_x, int mouse_y,
int16_t *res_x, int16_t *res_y, int16_t *res_screen_x, int16_t *res_screen_y);
#ifdef ANDROID
enum back_button_enums
{
BACK_BUTTON_QUIT = 0,
BACK_BUTTON_MENU_TOGGLE,
};
#endif
typedef struct rarch_joypad_driver
{
bool (*init)(void);

View File

@ -415,6 +415,12 @@ enum retro_mod
#define RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK 12
// const struct retro_keyboard_callback * --
// Sets a callback function used to notify core about keyboard events.
//
#define RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE 13
// const struct retro_disk_control_callback * --
// Sets an interface which frontend can use to eject and insert disk images.
// This is used for games which consist of multiple images and must be manually
// swapped out by the user (e.g. PSX).
// Callback type passed in RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK. Called by the frontend in response to keyboard events.
@ -429,6 +435,56 @@ struct retro_keyboard_callback
retro_keyboard_event_t callback;
};
// Callbacks for RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE.
// Should be set for implementations which can swap out multiple disk images in runtime.
// If the implementation can do this automatically, it should strive to do so.
// However, there are cases where the user must manually do so.
//
// Overview: To swap a disk image, eject the disk image with set_eject_state(true).
// Set the disk index with set_image_index(index). Insert the disk again with set_eject_state(false).
// If ejected is true, "ejects" the virtual disk tray.
// When ejected, the disk image index can be set.
typedef bool (*retro_set_eject_state_t)(bool ejected);
// Gets current eject state. The initial state is 'not ejected'.
typedef bool (*retro_get_eject_state_t)(void);
// Gets current disk index. First disk is index 0.
// If return value is >= get_num_images(), no disk is currently inserted.
typedef unsigned (*retro_get_image_index_t)(void);
// Sets image index. Can only be called when disk is ejected.
// The implementation supports setting "no disk" by using an index >= get_num_images().
typedef bool (*retro_set_image_index_t)(unsigned index);
// Gets total number of images which are available to use.
typedef unsigned (*retro_get_num_images_t)(void);
//
// Replaces the disk image associated with index.
// Arguments to pass in info have same requirements as retro_load_game().
// Virtual disk tray must be ejected when calling this.
// Replacing a disk image with info = NULL will remove the disk image from the internal list.
// As a result, calls to get_image_index() can change.
//
// E.g. replace_image_index(1, NULL), and previous get_image_index() returned 4 before.
// Index 1 will be removed, and the new index is 3.
struct retro_game_info;
typedef bool (*retro_replace_image_index_t)(unsigned index, const struct retro_game_info *info);
// Adds a new valid index (get_num_images()) to the internal disk list.
// This will increment subsequent return values from get_num_images() by 1.
// This image index cannot be used until a disk image has been set with replace_image_index.
typedef bool (*retro_add_image_index_t)(void);
struct retro_disk_control_callback
{
retro_set_eject_state_t set_eject_state;
retro_get_eject_state_t get_eject_state;
retro_get_image_index_t get_image_index;
retro_set_image_index_t set_image_index;
retro_get_num_images_t get_num_images;
retro_replace_image_index_t replace_image_index;
retro_add_image_index_t add_image_index;
};
enum retro_pixel_format
{
// 0RGB1555, native endian. 0 bit must be set to 0.

View File

@ -191,8 +191,8 @@ static void ps3_input_poll(void *data)
(1ULL << RARCH_STATE_SLOT_MINUS) |
(1ULL << RARCH_REWIND) |
(1ULL << RARCH_QUIT_KEY) |
(1ULL << RARCH_RMENU_TOGGLE) |
(1ULL << RARCH_RMENU_QUICKMENU_TOGGLE));
(1ULL << RARCH_MENU_TOGGLE) |
(1ULL << RARCH_MENU_QUICKMENU_TOGGLE));
if ((*state_p1 & (1ULL << RARCH_ANALOG_RIGHT_Y_DPAD_DOWN)) && !(*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_R2)))
*lifecycle_state |= (1ULL << RARCH_FAST_FORWARD_HOLD_KEY);
@ -210,14 +210,11 @@ static void ps3_input_poll(void *data)
if (!(g_extern.frame_count < g_extern.delay_timer[0]))
{
if ((*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_L3)) && (*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_R3)))
{
*lifecycle_state |= (1ULL << RARCH_RMENU_TOGGLE);
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
}
*lifecycle_state |= (1ULL << RARCH_MENU_TOGGLE);
if (!(*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_L3)) && (*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_R3)))
{
*lifecycle_state |= (1ULL << RARCH_RMENU_QUICKMENU_TOGGLE);
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
*lifecycle_state |= (1ULL << RARCH_MENU_TOGGLE);
*lifecycle_state |= (1ULL << RARCH_MENU_QUICKMENU_TOGGLE);
}
}

View File

@ -2384,6 +2384,77 @@ static void check_cheats(void)
old_pressed_toggle = pressed_toggle;
}
static void check_disk(void)
{
const struct retro_disk_control_callback *control = &g_extern.system.disk_control;
if (!control->get_num_images)
return;
static bool old_pressed_eject;
static bool old_pressed_next;
bool pressed_eject = input_key_pressed_func(RARCH_DISK_EJECT_TOGGLE);
bool pressed_next = input_key_pressed_func(RARCH_DISK_NEXT);
bool error = false;
char msg[256];
*msg = '\0';
if (pressed_eject && !old_pressed_eject)
{
bool new_state = !control->get_eject_state();
if (control->set_eject_state(new_state))
snprintf(msg, sizeof(msg), "%s virtual disk tray.", new_state ? "Ejected" : "Closed");
else
{
error = true;
snprintf(msg, sizeof(msg), "Failed to %s virtual disk tray.", new_state ? "eject" : "close");
}
}
else if (pressed_next && !old_pressed_next)
{
unsigned num_disks = control->get_num_images();
unsigned current = control->get_image_index();
if (num_disks && num_disks != UINT_MAX)
{
// Use "no disk" state when index == num_disks.
unsigned next_index = current >= num_disks ? 0 : ((current + 1) % (num_disks + 1));
if (control->set_image_index(next_index))
{
if (next_index < num_disks)
snprintf(msg, sizeof(msg), "Setting disk %u of %u in tray.", next_index + 1, num_disks);
else
snprintf(msg, sizeof(msg), "Removed disk from tray.");
}
else
{
if (next_index < num_disks)
snprintf(msg, sizeof(msg), "Failed to set disk %u of %u.", next_index + 1, num_disks);
else
snprintf(msg, sizeof(msg), "Failed to remove disk from tray.");
error = true;
}
}
else
{
snprintf(msg, sizeof(msg), "Got invalid disk index from libretro.");
error = true;
}
}
if (*msg)
{
if (error)
RARCH_ERR("%s\n", msg);
else
RARCH_LOG("%s\n", msg);
msg_queue_clear(g_extern.msg_queue);
msg_queue_push(g_extern.msg_queue, msg, 1, 180);
}
old_pressed_eject = pressed_eject;
old_pressed_next = pressed_next;
}
#if defined(HAVE_SCREENSHOTS) && !defined(_XBOX)
static void check_screenshot(void)
{
@ -2556,6 +2627,7 @@ static void do_state_checks(void)
check_shader_dir();
check_cheats();
check_disk();
#ifdef HAVE_DYLIB
check_dsp_config();
@ -2786,29 +2858,24 @@ bool rarch_main_iterate(void)
// SHUTDOWN on consoles should exit RetroArch completely.
if (g_extern.system.shutdown)
{
#ifdef HAVE_RMENU
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXIT);
#endif
return false;
}
// Time to drop?
if (input_key_pressed_func(RARCH_QUIT_KEY) ||
!video_alive_func())
if (input_key_pressed_func(RARCH_QUIT_KEY) || !video_alive_func())
{
#ifdef HAVE_RMENU
bool rmenu_enable = input_key_pressed_func(RARCH_RMENU_TOGGLE);
if (input_key_pressed_func(RARCH_RMENU_QUICKMENU_TOGGLE))
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXIT);
return false;
}
if (input_key_pressed_func(RARCH_MENU_TOGGLE) && g_extern.frame_count >= g_extern.delay_timer[0])
{
if (input_key_pressed_func(RARCH_MENU_QUICKMENU_TOGGLE))
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_INGAME);
if (rmenu_enable || ((g_extern.lifecycle_mode_state & (1ULL << MODE_MENU_INGAME)) && !rmenu_enable))
{
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU);
g_extern.delay_timer[0] = g_extern.frame_count + 30;
}
else
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXIT);
#endif
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU);
g_extern.delay_timer[0] = g_extern.frame_count + 30;
return false;
}

View File

@ -385,6 +385,13 @@
# Toggles to next overlay. Wraps around.
# input_overlay_next =
# Toggles eject for disks. Used for multiple-disk games.
# input_disk_eject_toggle =
# Cycles through disk images. Use after ejecting.
# Complete by toggling eject again.
# input_disk_next =
#### Misc
# Enable rewinding. This will take a performance hit when playing, so it is disabled by default.

View File

@ -241,6 +241,7 @@ void config_set_defaults(void)
g_settings.input.debug_enable = input_debug_enable;
#ifdef ANDROID
g_settings.input.autodetect_enable = input_autodetect_enable;
g_settings.input.back_behavior = BACK_BUTTON_QUIT;
#endif
for (int i = 0; i < MAX_PLAYERS; i++)
@ -275,7 +276,9 @@ void config_set_defaults(void)
g_extern.console.screen.resolutions.current.id = 0;
strlcpy(g_extern.console.main_wrap.default_rom_startup_dir, default_paths.filebrowser_startup_dir, sizeof(g_extern.console.main_wrap.default_rom_startup_dir));
strlcpy(g_extern.console.main_wrap.default_savestate_dir, default_paths.savestate_dir, sizeof(g_extern.console.main_wrap.default_savestate_dir));
#ifdef HAVE_RMENU
strlcpy(g_extern.console.menu_texture_path, default_paths.menu_border_file, sizeof(g_extern.console.menu_texture_path));
#endif
#if defined(__CELLOS_LV2) || defined(_XBOX360)
g_settings.video.aspect_ratio_idx = ASPECT_RATIO_16_9;
@ -498,8 +501,10 @@ bool config_load_file(const char *path)
if (config_get_path(conf, "default_rom_startup_dir", tmp_str, sizeof(tmp_str)))
strlcpy(g_extern.console.main_wrap.default_rom_startup_dir, tmp_str, sizeof(g_extern.console.main_wrap.default_rom_startup_dir));
#ifdef HAVE_RMENU
if (config_get_path(conf, "menu_texture_path", tmp_str, sizeof(tmp_str)))
strlcpy(g_extern.console.menu_texture_path, tmp_str, sizeof(g_extern.console.menu_texture_path));
#endif
if (config_get_bool(conf, "info_msg_enable", &msg_enable))
{
@ -701,6 +706,7 @@ bool config_load_file(const char *path)
#ifdef ANDROID
CONFIG_GET_BOOL(input.autodetect_enable, "input_autodetect_enable");
CONFIG_GET_INT(input.back_behavior, "input_back_behavior");
CONFIG_GET_INT(input.icade_profile[0], "input_autodetect_icade_profile_pad1");
CONFIG_GET_INT(input.icade_profile[1], "input_autodetect_icade_profile_pad2");
CONFIG_GET_INT(input.icade_profile[2], "input_autodetect_icade_profile_pad3");
@ -829,6 +835,8 @@ static const struct bind_map bind_maps[MAX_PLAYERS][RARCH_BIND_LIST_END_NULL] =
DECLARE_BIND(volume_up, RARCH_VOLUME_UP),
DECLARE_BIND(volume_down, RARCH_VOLUME_DOWN),
DECLARE_BIND(overlay_next, RARCH_OVERLAY_NEXT),
DECLARE_BIND(disk_eject_toggle, RARCH_DISK_EJECT_TOGGLE),
DECLARE_BIND(disk_next, RARCH_DISK_NEXT),
},
{ DECL_PLAYER(2) },
@ -1199,6 +1207,7 @@ bool config_save_file(const char *path)
config_set_string(conf, "audio_resampler", g_settings.audio.resampler);
#ifdef ANDROID
config_set_int(conf, "input_back_behavior", input.back_behavior);
config_set_int(conf, "input_autodetect_icade_profile_pad1", input.icade_profile[0]);
config_set_int(conf, "input_autodetect_icade_profile_pad2", input.icade_profile[1]);
config_set_int(conf, "input_autodetect_icade_profile_pad3", input.icade_profile[2]);
@ -1261,7 +1270,9 @@ bool config_save_file(const char *path)
config_set_int(conf, "custom_viewport_x", g_extern.console.screen.viewports.custom_vp.x);
config_set_int(conf, "custom_viewport_y", g_extern.console.screen.viewports.custom_vp.y);
config_set_string(conf, "default_rom_startup_dir", g_extern.console.main_wrap.default_rom_startup_dir);
#ifdef HAVE_RMENU
config_set_string(conf, "menu_texture_path", g_extern.console.menu_texture_path);
#endif
config_set_float(conf, "overscan_amount", g_extern.console.screen.overscan_amount);
config_set_float(conf, "video_font_size", g_settings.video.font_size);

View File

@ -123,6 +123,8 @@ static struct bind binds[] = {
MISC_BIND("Volume up", volume_up),
MISC_BIND("Volume down", volume_down),
MISC_BIND("Next overlay", overlay_next),
MISC_BIND("Disk eject toggle", disk_eject_toggle),
MISC_BIND("Disk next cycle", disk_next),
};
#define MAX_BUTTONS 32

View File

@ -40,7 +40,6 @@
unsigned font_x, font_y;
#elif defined(_XBOX360)
#include "../frontend/menu/rmenu_xui.h"
extern CRetroArch app;
const DWORD g_MapLinearToSrgbGpuFormat[] =
{
GPUTEXTUREFORMAT_1_REVERSE,
@ -892,8 +891,7 @@ static bool xdk_d3d_frame(void *data, const void *frame,
if (lifecycle_mode_state & (1ULL << MODE_MENU_DRAW))
{
#ifdef _XBOX360
app.Render();
XuiTimersRun();
menu_iterate_xui();
#endif
}
else
@ -981,21 +979,15 @@ static void xdk_d3d_restart(void)
d3dr->Reset(&d3dpp);
}
static void xdk_d3d_apply_state_changes(void)
{
xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data;
d3d->should_resize = true;
}
static void xdk_d3d_set_aspect_ratio(void *data, unsigned aspectratio_index)
{
(void)data;
xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data;
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_AUTO)
rarch_set_auto_viewport(g_extern.frame_cache.width, g_extern.frame_cache.height);
gfx_set_auto_viewport(g_extern.frame_cache.width, g_extern.frame_cache.height);
else if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CORE)
rarch_set_core_viewport();
gfx_set_core_viewport();
g_settings.video.aspect_ratio = aspectratio_lut[g_settings.video.aspect_ratio_idx].value;
g_settings.video.force_aspect = false;
@ -1014,7 +1006,6 @@ const video_driver_t video_xdk_d3d = {
xdk_d3d_start,
xdk_d3d_stop,
xdk_d3d_restart,
xdk_d3d_apply_state_changes,
xdk_d3d_set_aspect_ratio,
xdk_d3d_set_rotation,
};

View File

@ -212,8 +212,8 @@ static void xdk_input_poll(void *data)
(1ULL << RARCH_STATE_SLOT_MINUS) |
(1ULL << RARCH_REWIND) |
(1ULL << RARCH_QUIT_KEY) |
(1ULL << RARCH_RMENU_TOGGLE) |
(1ULL << RARCH_RMENU_QUICKMENU_TOGGLE));
(1ULL << RARCH_MENU_TOGGLE) |
(1ULL << RARCH_MENU_QUICKMENU_TOGGLE));
if ((*state_p1 & (1ULL << RARCH_ANALOG_RIGHT_Y_DPAD_DOWN)) && !(*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_R2)))
*lifecycle_state |= (1ULL << RARCH_FAST_FORWARD_HOLD_KEY);
@ -231,14 +231,11 @@ static void xdk_input_poll(void *data)
if (!(g_extern.frame_count < g_extern.delay_timer[0]))
{
if((*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_L3)) && (*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_R3)))
{
*lifecycle_state |= (1ULL << RARCH_RMENU_TOGGLE);
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
}
*lifecycle_state |= (1ULL << RARCH_MENU_TOGGLE);
if(!(*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_L3)) && (*state_p1 & (1ULL << RETRO_DEVICE_ID_JOYPAD_R3)))
{
*lifecycle_state |= (1ULL << RARCH_RMENU_QUICKMENU_TOGGLE);
*lifecycle_state |= (1ULL << RARCH_QUIT_KEY);
*lifecycle_state |= (1ULL << RARCH_MENU_TOGGLE);
*lifecycle_state |= (1ULL << RARCH_MENU_QUICKMENU_TOGGLE);
}
}
}