diff --git a/Makefile.ngc b/Makefile.ngc index 4f240161d3..f094cdd35b 100644 --- a/Makefile.ngc +++ b/Makefile.ngc @@ -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 diff --git a/Makefile.psp1 b/Makefile.psp1 index 71592ead1e..4b03a6b5e2 100644 --- a/Makefile.psp1 +++ b/Makefile.psp1 @@ -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 diff --git a/Makefile.wii b/Makefile.wii index 02661b225a..b0eb0a42ea 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -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 diff --git a/android/native/jni/Android.mk b/android/native/jni/Android.mk index 1039768f1c..dc0b3c436f 100644 --- a/android/native/jni/Android.mk +++ b/android/native/jni/Android.mk @@ -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 diff --git a/android/native/jni/cpufeatures.c b/android/native/jni/cpufeatures.c index 7af2dc6410..f593add252 100644 --- a/android/native/jni/cpufeatures.c +++ b/android/native/jni/cpufeatures.c @@ -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; diff --git a/android/native/jni/input_android.c b/android/native/jni/input_android.c index 91943a4315..05be2cb706 100644 --- a/android/native/jni/input_android.c +++ b/android/native/jni/input_android.c @@ -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) diff --git a/android/native/jni/input_autodetect.c b/android/native/jni/input_autodetect.c index e7a6ca0a90..16c783126d 100644 --- a/android/native/jni/input_autodetect.c +++ b/android/native/jni/input_autodetect.c @@ -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); diff --git a/android/native/jni/input_autodetect.h b/android/native/jni/input_autodetect.h index 5ca7a3cb43..4619106678 100644 --- a/android/native/jni/input_autodetect.h +++ b/android/native/jni/input_autodetect.h @@ -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, diff --git a/android/phoenix/res/values/array.xml b/android/phoenix/res/values/array.xml index fa494636ba..674439d631 100644 --- a/android/phoenix/res/values/array.xml +++ b/android/phoenix/res/values/array.xml @@ -1,5 +1,15 @@ + + Quit + Menu toggle + + + + 0 + 1 + + Full screen Auto diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index 7b1f2ba936..949bba3ea1 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -187,6 +187,14 @@ + + + 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 diff --git a/console/rarch_console_input.c b/console/rarch_console_input.c index a96545883f..c2ab918b7f 100644 --- a/console/rarch_console_input.c +++ b/console/rarch_console_input.c @@ -20,6 +20,7 @@ #include #include "../boolean.h" +#include "../general.h" #include "rarch_console_input.h" struct platform_bind diff --git a/console/rarch_console_video.c b/console/rarch_console_video.c deleted file mode 100644 index ba504c6c9e..0000000000 --- a/console/rarch_console_video.c +++ /dev/null @@ -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 . - */ - -#include - -#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; -} diff --git a/console/rarch_console_video.h b/console/rarch_console_video.h deleted file mode 100644 index c538b1629d..0000000000 --- a/console/rarch_console_video.h +++ /dev/null @@ -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 . - */ - -#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 diff --git a/driver.c b/driver.c index c379a7a5f1..50cedcc592 100644 --- a/driver.c +++ b/driver.c @@ -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); diff --git a/driver.h b/driver.h index 7ff6b8be5b..2b77c2cde5 100644 --- a/driver.h +++ b/driver.h @@ -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); diff --git a/driver_funcs.h b/driver_funcs.h index c2cadb3526..076c3585aa 100644 --- a/driver_funcs.h +++ b/driver_funcs.h @@ -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) diff --git a/dynamic.c b/dynamic.c index 8b7f44c45e..103aae552a 100644 --- a/dynamic.c +++ b/dynamic.c @@ -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; diff --git a/frontend/frontend_android.c b/frontend/frontend_android.c index 6c7e39ba12..2921fc7f17 100644 --- a/frontend/frontend_android.c +++ b/frontend/frontend_android.c @@ -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(); diff --git a/frontend/frontend_android.h b/frontend/frontend_android.h index 71d87e237c..1bf18c91e1 100644 --- a/frontend/frontend_android.h +++ b/frontend/frontend_android.h @@ -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; diff --git a/frontend/frontend_console.c b/frontend/frontend_console.c index cbb2674930..127bd77757 100644 --- a/frontend/frontend_console.c +++ b/frontend/frontend_console.c @@ -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 diff --git a/frontend/frontend_console.h b/frontend/frontend_console.h index 2b6362ffee..0634440469 100644 --- a/frontend/frontend_console.h +++ b/frontend/frontend_console.h @@ -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 diff --git a/frontend/menu/rmenu_settings.c b/frontend/menu/menu_settings.c similarity index 94% rename from frontend/menu/rmenu_settings.c rename to frontend/menu/menu_settings.c index d6698067bd..145d823eec 100644 --- a/frontend/menu/rmenu_settings.c +++ b/frontend/menu/menu_settings.c @@ -19,9 +19,9 @@ #include #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) { diff --git a/frontend/menu/rmenu_settings.h b/frontend/menu/menu_settings.h similarity index 83% rename from frontend/menu/rmenu_settings.h rename to frontend/menu/menu_settings.h index cfd418f0df..19e0c88038 100644 --- a/frontend/menu/rmenu_settings.h +++ b/frontend/menu/menu_settings.h @@ -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 diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index ed035fa0d8..cc6d961e6d 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -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; +} diff --git a/frontend/menu/rgui.h b/frontend/menu/rgui.h index f187d41c2b..7e1ace5055 100644 --- a/frontend/menu/rgui.h +++ b/frontend/menu/rgui.h @@ -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, diff --git a/frontend/menu/rmenu.c b/frontend/menu/rmenu.c index 53c8f2f1a5..cbc5463b45 100644 --- a/frontend/menu/rmenu.c +++ b/frontend/menu/rmenu.c @@ -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(¤t_menu, &rmenu_state); + menu_input_poll(¤t_menu, &rmenu_state); #ifdef HAVE_OSKUTIL if(rmenu_state.osk_init != NULL) diff --git a/frontend/menu/rmenu.h b/frontend/menu/rmenu.h index 566482909e..a4513bba70 100644 --- a/frontend/menu/rmenu.h +++ b/frontend/menu/rmenu.h @@ -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_ */ diff --git a/frontend/menu/rmenu_gx.c b/frontend/menu/rmenu_gx.c deleted file mode 100644 index 57601058a3..0000000000 --- a/frontend/menu/rmenu_gx.c +++ /dev/null @@ -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 . - */ - -#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; -} diff --git a/frontend/menu/rmenu_xui.cpp b/frontend/menu/rmenu_xui.cpp index 4869add564..bcf6727327 100644 --- a/frontend/menu/rmenu_xui.cpp +++ b/frontend/menu/rmenu_xui.cpp @@ -18,15 +18,17 @@ #include #include #include +#include +#include #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; +} \ No newline at end of file diff --git a/frontend/menu/rmenu_xui.h b/frontend/menu/rmenu_xui.h index edcdbf1516..cdf48ce79f 100644 --- a/frontend/menu/rmenu_xui.h +++ b/frontend/menu/rmenu_xui.h @@ -17,9 +17,6 @@ #ifndef _RMENU_XUI_H_ #define _RMENU_XUI_H_ -#include -#include - 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 diff --git a/frontend/menu/utils/file_list.c b/frontend/menu/utils/file_list.c index 98444c7f00..2d43d1aa07 100644 --- a/frontend/menu/utils/file_list.c +++ b/frontend/menu/utils/file_list.c @@ -16,7 +16,6 @@ #include #include #include -#include #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; diff --git a/frontend/menu/utils/file_list.h b/frontend/menu/utils/file_list.h index 10a34cf62f..fe3e96014c 100644 --- a/frontend/menu/utils/file_list.h +++ b/frontend/menu/utils/file_list.h @@ -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); diff --git a/frontend/menu/utils/menu_stack.c b/frontend/menu/utils/menu_stack.c index 0b7f44278c..e198c6713c 100644 --- a/frontend/menu/utils/menu_stack.c +++ b/frontend/menu/utils/menu_stack.c @@ -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) { diff --git a/frontend/menu/utils/menu_stack.h b/frontend/menu/utils/menu_stack.h index 77de9ef324..563e47b55e 100644 --- a/frontend/menu/utils/menu_stack.h +++ b/frontend/menu/utils/menu_stack.h @@ -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); diff --git a/frontend/platform/platform_ps3.c b/frontend/platform/platform_ps3.c index f62599c743..66bde4c0c6 100644 --- a/frontend/platform/platform_ps3.c +++ b/frontend/platform/platform_ps3.c @@ -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); diff --git a/frontend/platform/platform_psp.c b/frontend/platform/platform_psp.c index e5c3005461..f850a3b1fe 100644 --- a/frontend/platform/platform_psp.c +++ b/frontend/platform/platform_psp.c @@ -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"); diff --git a/general.h b/general.h index 2a44f45d69..4e1b4fd66c 100644 --- a/general.h +++ b/general.h @@ -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 diff --git a/gfx/gfx_common.c b/gfx/gfx_common.c index c70bf7af70..67f14f0d1f 100644 --- a/gfx/gfx_common.c +++ b/gfx/gfx_common.c @@ -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; +} + diff --git a/gfx/gfx_common.h b/gfx/gfx_common.h index 90124617f8..f8f454c8dc 100644 --- a/gfx/gfx_common.h +++ b/gfx/gfx_common.h @@ -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 diff --git a/gfx/gfx_context.h b/gfx/gfx_context.h index d236e0b957..00b01388ff 100644 --- a/gfx/gfx_context.h +++ b/gfx/gfx_context.h @@ -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); diff --git a/gfx/gl.c b/gfx/gl.c index b5be966612..f9cdd15602 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -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, }; diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 27c5cb9547..160161e224 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -59,6 +59,7 @@ #include #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 ... <_< diff --git a/gfx/thread_wrapper.c b/gfx/thread_wrapper.c index 39d8397458..7099b30636 100644 --- a/gfx/thread_wrapper.c +++ b/gfx/thread_wrapper.c @@ -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, diff --git a/gx/gx_input.c b/gx/gx_input.c index 318a6eddf2..4cbadde846 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -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); } } diff --git a/gx/gx_video.c b/gx/gx_video.c index c7ddc86e56..e0edcde101 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -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 }; diff --git a/gx/gx_video.h b/gx/gx_video.h index 9a6e38f06c..5bd40ad0e4 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -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 diff --git a/input/input_common.c b/input/input_common.c index 9886591462..f9e0aa5a2a 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -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) diff --git a/input/input_common.h b/input/input_common.h index bb61907b8f..84e9dfbcfa 100644 --- a/input/input_common.h +++ b/input/input_common.h @@ -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); diff --git a/libretro.h b/libretro.h index 21e24eeeff..0c39e6edae 100755 --- a/libretro.h +++ b/libretro.h @@ -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. diff --git a/ps3/ps3_input.c b/ps3/ps3_input.c index 0fd318f67e..43f8638f75 100644 --- a/ps3/ps3_input.c +++ b/ps3/ps3_input.c @@ -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); } } diff --git a/retroarch.c b/retroarch.c index dc3345e5d2..4d864da5aa 100644 --- a/retroarch.c +++ b/retroarch.c @@ -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; } diff --git a/retroarch.cfg b/retroarch.cfg index 9285288f0b..f0189719bf 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -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. diff --git a/settings.c b/settings.c index 731e99e0b7..20351b0dc3 100644 --- a/settings.c +++ b/settings.c @@ -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); diff --git a/tools/retroarch-joyconfig.c b/tools/retroarch-joyconfig.c index fe3ec39d77..48d5f19303 100644 --- a/tools/retroarch-joyconfig.c +++ b/tools/retroarch-joyconfig.c @@ -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 diff --git a/xdk/xdk_d3d.cpp b/xdk/xdk_d3d.cpp index b9ef57c615..481d11d8d0 100644 --- a/xdk/xdk_d3d.cpp +++ b/xdk/xdk_d3d.cpp @@ -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, }; diff --git a/xdk/xdk_xinput_input.c b/xdk/xdk_xinput_input.c index 4e2ec607ce..9792e75a19 100644 --- a/xdk/xdk_xinput_input.c +++ b/xdk/xdk_xinput_input.c @@ -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); } } }