From 49398698b57e25353f1f97de8059d8b97d11c825 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Wed, 17 Jul 2013 20:26:01 -0400 Subject: [PATCH 001/202] initial emscripten port (no audio/files, input broken) --- Makefile.emscripten | 152 ++++++++++++++++++ config.def.h | 4 + driver.c | 2 +- frontend/frontend_emscripten.c | 127 +++++++++++++++ gfx/context/emscriptenegl_ctx.c | 268 ++++++++++++++++++++++++++++++++ gfx/gfx_context.c | 10 +- gfx/gfx_context.h | 1 + input/input_common.c | 3 +- input/sdl_input.c | 15 +- performance.c | 6 + 10 files changed, 581 insertions(+), 7 deletions(-) create mode 100644 Makefile.emscripten create mode 100644 frontend/frontend_emscripten.c create mode 100644 gfx/context/emscriptenegl_ctx.c diff --git a/Makefile.emscripten b/Makefile.emscripten new file mode 100644 index 0000000000..79f77f2c56 --- /dev/null +++ b/Makefile.emscripten @@ -0,0 +1,152 @@ +TARGET = retroarch.html + +OBJ = frontend/frontend_emscripten.o \ + retroarch.o \ + file.o \ + file_path.o \ + driver.o \ + conf/config_file.o \ + settings.o \ + hash.o \ + dynamic.o \ + dynamic_dummy.o \ + message.o \ + rewind.o \ + movie.o \ + gfx/gfx_common.o \ + input/input_common.o \ + core_options.o \ + patch.o \ + compat/compat.o \ + screenshot.o \ + cheats.o \ + audio/utils.o \ + input/overlay.o \ + fifo_buffer.o \ + gfx/scaler/scaler.o \ + gfx/scaler/pixconv.o \ + gfx/scaler/scaler_int.o \ + gfx/scaler/filter.o \ + gfx/state_tracker.o \ + gfx/shader_parse.o \ + gfx/fonts/fonts.o \ + gfx/fonts/bitmapfont.o \ + gfx/image.o \ + audio/resampler.o \ + audio/sinc.o \ + audio/null.o \ + performance.o + +HAVE_OPENGL = 1 +HAVE_RGUI = 1 +HAVE_SDL = 1 +HAVE_SDL_IMAGE = 1 +HAVE_FREETYPE = 1 +HAVE_ZLIB = 1 +HAVE_FBO = 1 + +libretro ?= -lretro + +LIBS = -lm +DEFINES = -I. -DHAVE_SCREENSHOTS -DHAVE_NULLAUDIO -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.9.3\" +LDFLAGS = -L. -static-libgcc -s TOTAL_MEMORY=268435456 -s FULL_ES2=1 + +ifeq ($(SCALER_NO_SIMD), 1) + DEFINES += -DSCALER_NO_SIMD +endif + +ifeq ($(PERF_TEST), 1) + DEFINES += -DPERF_TEST +endif + +ifeq ($(HAVE_RGUI), 1) + DEFINES += -DHAVE_RGUI + OBJ += frontend/menu/menu_common.o frontend/menu/rgui.o frontend/menu/history.o +endif + +ifeq ($(HAVE_SDL), 1) + OBJ += input/sdl_input.o + LIBS += -lSDL + DEFINES += -ISDL -DHAVE_SDL +endif + +ifeq ($(HAVE_THREADS), 1) + OBJ += autosave.o thread.o gfx/thread_wrapper.o + DEFINES += -DHAVE_THREADS +endif + +ifeq ($(HAVE_OPENGL), 1) + OBJ += gfx/gl.o gfx/math/matrix.o gfx/fonts/gl_font.o gfx/fonts/gl_raster_font.o gfx/gfx_context.o gfx/context/emscriptenegl_ctx.o gfx/shader_glsl.o + DEFINES += -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_EGL -DHAVE_OVERLAY -DHAVE_GLSL +endif + +ifeq ($(HAVE_ZLIB), 1) + OBJ += gfx/rpng/rpng.o file_extract.o + DEFINES += -DHAVE_ZLIB + ifeq ($(WANT_MINIZ), 1) + OBJ += deps/miniz/miniz.o + DEFINES += -DWANT_MINIZ + else + LIBS += -lz + DEFINES += -DHAVE_ZLIB_DEFLATE + endif +endif + +LIBS += $(libretro) + +ifeq ($(HAVE_FBO), 1) + DEFINES += -DHAVE_FBO +endif + +ifneq ($(V), 1) + Q := @ +endif + +ifeq ($(DEBUG), 1) + LDFLAGS += -O0 -g -s LABEL_DEBUG=1 +else + LDFLAGS += -O2 -ffast-math +endif + +CFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -I. -std=gnu99 + +all: $(TARGET) + +$(TARGET): $(OBJ) + @$(if $(Q), $(shell echo echo LD $@),) + $(Q)$(LD) -o $@ $(OBJ) $(LIBS) $(LDFLAGS) + +%.o: %.c + @$(if $(Q), $(shell echo echo CC $<),) + $(Q)$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< + +%.o: %.cpp + @$(if $(Q), $(shell echo echo CXX $<),) + $(Q)$(CXX) $(CXXFLAGS) $(DEFINES) -c -o $@ $< + +clean: + rm -f *.o + rm -f deps/miniz/*.o + rm -f frontend/*.o + rm -f frontend/menu/*.o + rm -f audio/*.o + rm -f audio/xaudio-c/*.o + rm -f compat/*.o + rm -f compat/rxml/*.o + rm -f conf/*.o + rm -f gfx/scaler/*.o + rm -f gfx/*.o + rm -f gfx/d3d9/*.o + rm -f gfx/context/*.o + rm -f gfx/math/*.o + rm -f gfx/fonts/*.o + rm -f gfx/py_state/*.o + rm -f gfx/rpng/*.o + rm -f record/*.o + rm -f input/*.o + rm -f $(TARGET) + rm -f retroarch-joyconfig.exe + rm -f tools/*.o + +.PHONY: all clean + diff --git a/config.def.h b/config.def.h index c11957648c..ae2f7523b7 100644 --- a/config.def.h +++ b/config.def.h @@ -128,6 +128,8 @@ enum #define AUDIO_DEFAULT_DRIVER AUDIO_SL #elif defined(HAVE_DSOUND) #define AUDIO_DEFAULT_DRIVER AUDIO_DSOUND +#elif defined(EMSCRIPTEN) +#define AUDIO_DEFAULT_DRIVER AUDIO_NULL #elif defined(HAVE_SDL) #define AUDIO_DEFAULT_DRIVER AUDIO_SDL #elif defined(HAVE_XAUDIO) @@ -195,6 +197,8 @@ enum #define EXT_EXECUTABLES "xex|XEX" #elif defined(GEKKO) #define EXT_EXECUTABLES "dol|DOL" +#else +#define EXT_EXECUTABLES "???" #endif #endif diff --git a/driver.c b/driver.c index 790e23e1f6..338dd28ff6 100644 --- a/driver.c +++ b/driver.c @@ -62,7 +62,7 @@ static const audio_driver_t *audio_drivers[] = { #ifdef HAVE_JACK &audio_jack, #endif -#ifdef HAVE_SDL +#if defined(HAVE_SDL) && !defined(EMSCRIPTEN) &audio_sdl, #endif #ifdef HAVE_XAUDIO diff --git a/frontend/frontend_emscripten.c b/frontend/frontend_emscripten.c new file mode 100644 index 0000000000..949870e0c5 --- /dev/null +++ b/frontend/frontend_emscripten.c @@ -0,0 +1,127 @@ +/* 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 "../conf/config_file.h" +#include "../file.h" + +#ifdef HAVE_RGUI +#include "../frontend/menu/rgui.h" +#endif + +#if defined(HAVE_RGUI) || defined(HAVE_RMENU) || defined(HAVE_RMENU_XUI) +#define HAVE_MENU +#else +#undef HAVE_MENU +#endif + +static bool menuloop; + +void mainloop(void) +{ + if (g_extern.system.shutdown) + { + RARCH_ERR("Exit...\n"); + emscripten_cancel_main_loop(); + } + else if (menuloop) + { + if (!menu_iterate()) + { + menuloop = false; + driver_set_nonblock_state(driver.nonblock_state); + + if (driver.audio_data && !audio_start_func()) + { + RARCH_ERR("Failed to resume audio driver. Will continue without audio.\n"); + g_extern.audio_active = false; + } + + g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU); + } + } + else if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME)) + { + load_menu_game_prepare(); + + // If ROM load fails, we exit RetroArch. On console it might make more sense to go back to menu though ... + if (load_menu_game()) + g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); + else + { +#ifdef RARCH_CONSOLE + g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU); +#else + return; +#endif + } + + g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME); + } + else if (g_extern.lifecycle_mode_state & (1ULL << MODE_GAME)) + { + bool r; + if (g_extern.is_paused && !g_extern.is_oneshot) + r = rarch_main_idle_iterate(); + else + r = rarch_main_iterate(); + if (!r) + g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); + } + else if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU)) + { + g_extern.lifecycle_mode_state |= 1ULL << MODE_MENU_PREINIT; + // Menu should always run with vsync on. + video_set_nonblock_state_func(false); + + if (driver.audio_data) + audio_stop_func(); + + menuloop = true; + } + else + { + g_extern.system.shutdown = true; + } +} + +int main(int argc, char *argv[]) +{ + emscripten_set_canvas_size(800, 600); + + rarch_main_clear_state(); + rarch_init_msg_queue(); + + char *_argv[] = { "retroarch", "--menu", "-v" }; + + int init_ret; + if ((init_ret = rarch_main_init(3, _argv))) return init_ret; + +#ifdef HAVE_MENU + menu_init(); + g_extern.lifecycle_mode_state |= 1ULL << MODE_GAME; + + // If we started a ROM directly from command line, + // push it to ROM history. + if (!g_extern.libretro_dummy) + menu_rom_history_push_current(); +#endif + + emscripten_set_main_loop(mainloop, 0, 0); + + return 0; +} diff --git a/gfx/context/emscriptenegl_ctx.c b/gfx/context/emscriptenegl_ctx.c new file mode 100644 index 0000000000..2674e8bcc6 --- /dev/null +++ b/gfx/context/emscriptenegl_ctx.c @@ -0,0 +1,268 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Hans-Kristian Arntzen + * Copyright (C) 2012 - Michael Lelli + * + * 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 . + */ + +// VideoCore context, for Rasperry Pi. + +#include "../../driver.h" +#include "../gfx_context.h" +#include "../gl_common.h" +#include "../gfx_common.h" + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#include +#include + +#include +#include +#include +#include + +static EGLContext g_egl_ctx; +static EGLSurface g_egl_surf; +static EGLDisplay g_egl_dpy; +static EGLConfig g_config; +static bool g_quit; + +static bool g_inited; + +static unsigned g_fb_width; +static unsigned g_fb_height; + +static void gfx_ctx_swap_interval(unsigned interval) +{ + // no way to control vsync in WebGL + (void)interval; +} + +static void gfx_ctx_check_window(bool *quit, + bool *resize, unsigned *width, unsigned *height, unsigned frame_count) +{ + (void)frame_count; + (void)width; + (void)height; + + *resize = false; + *quit = g_quit; +} + +static void gfx_ctx_swap_buffers(void) +{ + eglSwapBuffers(g_egl_dpy, g_egl_surf); +} + +static void gfx_ctx_set_resize(unsigned width, unsigned height) +{ + (void)width; + (void)height; +} + +static void gfx_ctx_update_window_title(void) +{ + char buf[128]; + gfx_get_fps(buf, sizeof(buf), false); +} + +static void gfx_ctx_get_video_size(unsigned *width, unsigned *height) +{ + *width = g_fb_width; + *height = g_fb_height; +} + +static void gfx_ctx_destroy(void); + +static bool gfx_ctx_init(void) +{ + EGLint width; + EGLint height; + + RARCH_LOG("[VC/EMSCRIPTEN]: Initializing...\n"); + if (g_inited) + { + RARCH_ERR("[VC/EMSCRIPTEN]: Attempted to re-initialize driver.\n"); + return true; + } + + EGLint num_config; + + static const EGLint attribute_list[] = + { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + + static const EGLint context_attributes[] = + { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + // get an EGL display connection + g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (!g_egl_dpy) + goto error; + + // initialize the EGL display connection + if (!eglInitialize(g_egl_dpy, NULL, NULL)) + goto error; + + // get an appropriate EGL frame buffer configuration + if (!eglChooseConfig(g_egl_dpy, attribute_list, &g_config, 1, &num_config)) + goto error; + + // create an EGL rendering context + g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, context_attributes); + if (!g_egl_ctx) + goto error; + + // create an EGL window surface + g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, 0, NULL); + if (!g_egl_surf) + goto error; + + // connect the context to the surface + if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx)) + goto error; + + eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_WIDTH, &width); + eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_HEIGHT, &height); + g_fb_width = width; + g_fb_height = height; + RARCH_LOG("[VC/EMSCRIPTEN]: Dimensions: %ux%u\n", width, height); + + return true; + +error: + gfx_ctx_destroy(); + return false; +} + +static bool gfx_ctx_set_video_mode( + unsigned width, unsigned height, + bool fullscreen) +{ + if (g_inited) + return false; + + g_inited = true; + return true; +} + +static bool gfx_ctx_bind_api(enum gfx_ctx_api api) +{ + switch (api) + { + case GFX_CTX_OPENGL_ES_API: + return eglBindAPI(EGL_OPENGL_ES_API); + default: + return false; + } +} + +static void gfx_ctx_destroy(void) +{ + if (g_egl_dpy) + { + if (g_egl_ctx) + { + eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroyContext(g_egl_dpy, g_egl_ctx); + } + + if (g_egl_surf) + { + eglDestroySurface(g_egl_dpy, g_egl_surf); + } + + eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglTerminate(g_egl_dpy); + } + + g_egl_ctx = NULL; + g_egl_surf = NULL; + g_egl_dpy = NULL; + g_config = 0; + g_inited = false; +} + +static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data) +{ + *input = NULL; + + if (SDL_Init(SDL_INIT_VIDEO) != 0) + return; + + void *sdlinput = input_sdl.init(); + + if (sdlinput) + { + *input = &input_sdl; + *input_data = sdlinput; + } +} + +static bool gfx_ctx_has_focus(void) +{ + return g_inited; +} + +static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol) +{ + return SDL_GL_GetProcAddress(symbol); +} + +static float gfx_ctx_translate_aspect(unsigned width, unsigned height) +{ + return (float)width / height; +} + +static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video) +{ + return false; +} + +static bool gfx_ctx_write_egl_image(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle) +{ + return false; +} + +const gfx_ctx_driver_t gfx_ctx_emscripten = { + gfx_ctx_init, + gfx_ctx_destroy, + gfx_ctx_bind_api, + gfx_ctx_swap_interval, + gfx_ctx_set_video_mode, + gfx_ctx_get_video_size, + gfx_ctx_translate_aspect, + gfx_ctx_update_window_title, + gfx_ctx_check_window, + gfx_ctx_set_resize, + gfx_ctx_has_focus, + gfx_ctx_swap_buffers, + gfx_ctx_input_driver, + gfx_ctx_get_proc_address, + gfx_ctx_init_egl_image_buffer, + gfx_ctx_write_egl_image, + NULL, + "emscripten", +}; diff --git a/gfx/gfx_context.c b/gfx/gfx_context.c index 47745ca3f3..ba0aedd0fe 100644 --- a/gfx/gfx_context.c +++ b/gfx/gfx_context.c @@ -13,6 +13,7 @@ * If not, see . */ +#include "../general.h" #include "gfx_context.h" #include @@ -51,14 +52,17 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = { #if defined(IOS) || defined(OSX) //< Don't use __APPLE__ as it breaks basic SDL builds &gfx_ctx_apple, #endif -#if defined(HAVE_SDL) && defined(HAVE_OPENGL) +#if defined(HAVE_SDL) && defined(HAVE_OPENGL) && !defined(EMSCRIPTEN) &gfx_ctx_sdl_gl, #endif +#ifdef EMSCRIPTEN + &gfx_ctx_emscripten, +#endif }; const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident) { - for (unsigned i = 0; i < sizeof(gfx_ctx_drivers) / sizeof(gfx_ctx_drivers[0]); i++) + for (unsigned i = 0; i < ARRAY_SIZE(gfx_ctx_drivers); i++) { if (strcmp(gfx_ctx_drivers[i]->ident, ident) == 0) return gfx_ctx_drivers[i]; @@ -69,7 +73,7 @@ const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident) const gfx_ctx_driver_t *gfx_ctx_init_first(enum gfx_ctx_api api) { - for (unsigned i = 0; i < sizeof(gfx_ctx_drivers) / sizeof(gfx_ctx_drivers[0]); i++) + for (unsigned i = 0; i < ARRAY_SIZE(gfx_ctx_drivers); i++) { if (gfx_ctx_drivers[i]->bind_api(api)) { diff --git a/gfx/gfx_context.h b/gfx/gfx_context.h index fa70e76e73..6e0219f382 100644 --- a/gfx/gfx_context.h +++ b/gfx/gfx_context.h @@ -108,6 +108,7 @@ extern const gfx_ctx_driver_t gfx_ctx_wgl; extern const gfx_ctx_driver_t gfx_ctx_videocore; extern const gfx_ctx_driver_t gfx_ctx_bbqnx; extern const gfx_ctx_driver_t gfx_ctx_apple; +extern const gfx_ctx_driver_t gfx_ctx_emscripten; extern const gfx_ctx_driver_t gfx_ctx_null; const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize. diff --git a/input/input_common.c b/input/input_common.c index 12be6eaf76..e58eede808 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -16,6 +16,7 @@ #include "input_common.h" #include #include +#include #include "../general.h" #include "../driver.h" @@ -47,7 +48,7 @@ static const rarch_joypad_driver_t *joypad_drivers[] = { #if defined(__linux) && !defined(ANDROID) &linuxraw_joypad, #endif -#ifdef HAVE_SDL +#if defined(HAVE_SDL) && !defined(EMSCRIPTEN) &sdl_joypad, #endif #endif diff --git a/input/sdl_input.c b/input/sdl_input.c index d438c3f8a5..1c332b8396 100644 --- a/input/sdl_input.c +++ b/input/sdl_input.c @@ -24,6 +24,10 @@ #include "../libretro.h" #include "input_common.h" +#if !(SDL_MAJOR_VERSION <= 1 && SDL_MINOR_VERSION <= 2) +#define SDL_GetKeyState SDL_GetKeyboardState +#endif + typedef struct sdl_input { const rarch_joypad_driver_t *joypad; @@ -51,9 +55,8 @@ static bool sdl_key_pressed(int key) int sym = input_translate_rk_to_keysym((enum retro_key)key); - int num_keys; + int num_keys = 0xFFFF; Uint8 *keymap = SDL_GetKeyState(&num_keys); - if (sym < 0 || sym >= num_keys) return false; return keymap[sym]; @@ -216,16 +219,24 @@ static void sdl_input_free(void *data) static void sdl_poll_mouse(sdl_input_t *sdl) { + (void)sdl; +#ifndef EMSCRIPTEN Uint8 btn = SDL_GetRelativeMouseState(&sdl->mouse_x, &sdl->mouse_y); SDL_GetMouseState(&sdl->mouse_abs_x, &sdl->mouse_abs_y); sdl->mouse_l = SDL_BUTTON(SDL_BUTTON_LEFT) & btn ? 1 : 0; sdl->mouse_r = SDL_BUTTON(SDL_BUTTON_RIGHT) & btn ? 1 : 0; sdl->mouse_m = SDL_BUTTON(SDL_BUTTON_MIDDLE) & btn ? 1 : 0; +#endif } static void sdl_input_poll(void *data) { +#ifdef EMSCRIPTEN + SDL_Event event; + while (SDL_PollEvent(&event)); +#else SDL_PumpEvents(); +#endif sdl_input_t *sdl = (sdl_input_t*)data; input_joypad_poll(sdl->joypad); diff --git a/performance.c b/performance.c index 7829fe265d..faad97135d 100644 --- a/performance.c +++ b/performance.c @@ -58,6 +58,10 @@ #include #endif +#ifdef EMSCRIPTEN +#include +#endif + #ifdef PERF_TEST #define MAX_COUNTERS 64 static struct rarch_perf_counter *perf_counters[MAX_COUNTERS]; @@ -145,6 +149,8 @@ rarch_time_t rarch_get_time_usec(void) if (clock_gettime(CLOCK_MONOTONIC, &tv) < 0) return 0; return tv.tv_sec * INT64_C(1000000) + (tv.tv_nsec + 500) / 1000; +#elif defined(EMSCRIPTEN) + return emscripten_get_now() * 1000; #else #error "Your platform does not have a timer function implemented in rarch_get_time_usec(). Cannot continue." #endif From 9486d8154c74a743f3aa478a87fc698c59288405 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Wed, 17 Jul 2013 22:06:52 -0400 Subject: [PATCH 002/202] fix input --- input/sdl_input.c | 1 + 1 file changed, 1 insertion(+) diff --git a/input/sdl_input.c b/input/sdl_input.c index 1c332b8396..a5dd282c85 100644 --- a/input/sdl_input.c +++ b/input/sdl_input.c @@ -57,6 +57,7 @@ static bool sdl_key_pressed(int key) int num_keys = 0xFFFF; Uint8 *keymap = SDL_GetKeyState(&num_keys); + if (sym < 0 || sym >= num_keys) return false; return keymap[sym]; From c77af5739b39c56d47dc789957bef0fb04aa240a Mon Sep 17 00:00:00 2001 From: ToadKing Date: Wed, 17 Jul 2013 23:09:22 -0400 Subject: [PATCH 003/202] fix compile --- file_ext.h | 2 ++ frontend/frontend_emscripten.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/file_ext.h b/file_ext.h index bdfddeea3a..54bfb79cf5 100644 --- a/file_ext.h +++ b/file_ext.h @@ -42,6 +42,8 @@ #define EXT_EXECUTABLES "dol|DOL" #define SALAMANDER_FILE "boot.dol" #define DEFAULT_EXE_EXT ".dol" +#elif defined(EMSCRIPTEN) +#define EXT_EXECUTABLES "" #endif #endif diff --git a/frontend/frontend_emscripten.c b/frontend/frontend_emscripten.c index 949870e0c5..1e90dbd1f1 100644 --- a/frontend/frontend_emscripten.c +++ b/frontend/frontend_emscripten.c @@ -36,7 +36,7 @@ void mainloop(void) if (g_extern.system.shutdown) { RARCH_ERR("Exit...\n"); - emscripten_cancel_main_loop(); + exit(0); } else if (menuloop) { From ff3de2563628046dfc2fe796899223b4f14163d5 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Thu, 18 Jul 2013 23:58:35 -0400 Subject: [PATCH 004/202] fix error on video re-init, other cleanup --- Makefile.emscripten | 4 +++- frontend/frontend_emscripten.c | 4 +--- gfx/context/emscriptenegl_ctx.c | 14 +++++++------- gfx/gl.c | 1 + 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Makefile.emscripten b/Makefile.emscripten index 79f77f2c56..c7e5612320 100644 --- a/Makefile.emscripten +++ b/Makefile.emscripten @@ -1,4 +1,4 @@ -TARGET = retroarch.html +TARGET = retroarch.js OBJ = frontend/frontend_emscripten.o \ retroarch.o \ @@ -18,6 +18,7 @@ OBJ = frontend/frontend_emscripten.o \ core_options.o \ patch.o \ compat/compat.o \ + compat/rxml/rxml.o \ screenshot.o \ cheats.o \ audio/utils.o \ @@ -44,6 +45,7 @@ HAVE_SDL_IMAGE = 1 HAVE_FREETYPE = 1 HAVE_ZLIB = 1 HAVE_FBO = 1 +WANT_MINIZ = 1 libretro ?= -lretro diff --git a/frontend/frontend_emscripten.c b/frontend/frontend_emscripten.c index 1e90dbd1f1..d03c294fb7 100644 --- a/frontend/frontend_emscripten.c +++ b/frontend/frontend_emscripten.c @@ -106,10 +106,8 @@ int main(int argc, char *argv[]) rarch_main_clear_state(); rarch_init_msg_queue(); - char *_argv[] = { "retroarch", "--menu", "-v" }; - int init_ret; - if ((init_ret = rarch_main_init(3, _argv))) return init_ret; + if ((init_ret = rarch_main_init(argc, argv))) return init_ret; #ifdef HAVE_MENU menu_init(); diff --git a/gfx/context/emscriptenegl_ctx.c b/gfx/context/emscriptenegl_ctx.c index 2674e8bcc6..e0778fe973 100644 --- a/gfx/context/emscriptenegl_ctx.c +++ b/gfx/context/emscriptenegl_ctx.c @@ -75,7 +75,8 @@ static void gfx_ctx_set_resize(unsigned width, unsigned height) static void gfx_ctx_update_window_title(void) { char buf[128]; - gfx_get_fps(buf, sizeof(buf), false); + if (gfx_get_fps(buf, sizeof(buf), false)) + RARCH_LOG("%s\n", buf); } static void gfx_ctx_get_video_size(unsigned *width, unsigned *height) @@ -91,10 +92,10 @@ static bool gfx_ctx_init(void) EGLint width; EGLint height; - RARCH_LOG("[VC/EMSCRIPTEN]: Initializing...\n"); + RARCH_LOG("[EMSCRIPTEN/EGL]: Initializing...\n"); if (g_inited) { - RARCH_ERR("[VC/EMSCRIPTEN]: Attempted to re-initialize driver.\n"); + RARCH_LOG("[EMSCRIPTEN/EGL]: Attempted to re-initialize driver.\n"); return true; } @@ -147,7 +148,7 @@ static bool gfx_ctx_init(void) eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_HEIGHT, &height); g_fb_width = width; g_fb_height = height; - RARCH_LOG("[VC/EMSCRIPTEN]: Dimensions: %ux%u\n", width, height); + RARCH_LOG("[EMSCRIPTEN/EGL]: Dimensions: %ux%u\n", width, height); return true; @@ -182,9 +183,10 @@ static void gfx_ctx_destroy(void) { if (g_egl_dpy) { + eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (g_egl_ctx) { - eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(g_egl_dpy, g_egl_ctx); } @@ -193,8 +195,6 @@ static void gfx_ctx_destroy(void) eglDestroySurface(g_egl_dpy, g_egl_surf); } - eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglTerminate(g_egl_dpy); } diff --git a/gfx/gl.c b/gfx/gl.c index bec4389a92..c6a4b571b4 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1844,6 +1844,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo } RARCH_LOG("Found GL context: %s\n", gl->ctx_driver->ident); + while (glGetError() != GL_NO_ERROR); context_get_video_size_func(&gl->full_x, &gl->full_y); RARCH_LOG("Detecting screen resolution %ux%u.\n", gl->full_x, gl->full_y); From b01856d1665586a329b01ba86f444f9dea18bd2a Mon Sep 17 00:00:00 2001 From: ToadKing Date: Sat, 20 Jul 2013 00:30:54 -0400 Subject: [PATCH 005/202] remove reinit hack, turned out to be an emscripten bug --- gfx/gl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gfx/gl.c b/gfx/gl.c index c6a4b571b4..bec4389a92 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1844,7 +1844,6 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo } RARCH_LOG("Found GL context: %s\n", gl->ctx_driver->ident); - while (glGetError() != GL_NO_ERROR); context_get_video_size_func(&gl->full_x, &gl->full_y); RARCH_LOG("Detecting screen resolution %ux%u.\n", gl->full_x, gl->full_y); From 9816334ef4f945135480bfe8bc41a1b76cc2da62 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Sat, 20 Jul 2013 04:23:03 -0400 Subject: [PATCH 006/202] add ability to "disable" v-sync, set FPS limit to max --- frontend/frontend_emscripten.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/frontend_emscripten.c b/frontend/frontend_emscripten.c index d03c294fb7..745096e0b4 100644 --- a/frontend/frontend_emscripten.c +++ b/frontend/frontend_emscripten.c @@ -119,7 +119,7 @@ int main(int argc, char *argv[]) menu_rom_history_push_current(); #endif - emscripten_set_main_loop(mainloop, 0, 0); + emscripten_set_main_loop(mainloop, g_settings.video.vsync ? 0 : INT_MAX, 1); return 0; } From 6bb403c04b47e816df66287d29b06a687f419477 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Sat, 27 Jul 2013 14:17:22 -0400 Subject: [PATCH 007/202] [EMSCRIPTEN] enable openal, change library name to retro_emscripten --- Makefile.emscripten | 17 ++++++++++++++--- config.def.h | 2 -- libretro-test/Makefile | 8 ++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Makefile.emscripten b/Makefile.emscripten index c7e5612320..797e62c0b2 100644 --- a/Makefile.emscripten +++ b/Makefile.emscripten @@ -39,6 +39,7 @@ OBJ = frontend/frontend_emscripten.o \ performance.o HAVE_OPENGL = 1 +HAVE_AL = 1 HAVE_RGUI = 1 HAVE_SDL = 1 HAVE_SDL_IMAGE = 1 @@ -47,10 +48,14 @@ HAVE_ZLIB = 1 HAVE_FBO = 1 WANT_MINIZ = 1 -libretro ?= -lretro +ifneq ($(NATIVE_ZLIB),) + WANT_MINIZ = 0 +endif + +libretro ?= -lretro_emscripten LIBS = -lm -DEFINES = -I. -DHAVE_SCREENSHOTS -DHAVE_NULLAUDIO -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.9.3\" +DEFINES = -DHAVE_SCREENSHOTS -DHAVE_NULLAUDIO -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.9.3\" LDFLAGS = -L. -static-libgcc -s TOTAL_MEMORY=268435456 -s FULL_ES2=1 ifeq ($(SCALER_NO_SIMD), 1) @@ -82,6 +87,12 @@ ifeq ($(HAVE_OPENGL), 1) DEFINES += -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_EGL -DHAVE_OVERLAY -DHAVE_GLSL endif +ifeq ($(HAVE_AL), 1) + OBJ += audio/openal.o + DEFINES += -DHAVE_AL + LIBS += -lopenal +endif + ifeq ($(HAVE_ZLIB), 1) OBJ += gfx/rpng/rpng.o file_extract.o DEFINES += -DHAVE_ZLIB @@ -105,7 +116,7 @@ ifneq ($(V), 1) endif ifeq ($(DEBUG), 1) - LDFLAGS += -O0 -g -s LABEL_DEBUG=1 + LDFLAGS += -O0 -g else LDFLAGS += -O2 -ffast-math endif diff --git a/config.def.h b/config.def.h index 8ec9b8d81d..0d647ad290 100644 --- a/config.def.h +++ b/config.def.h @@ -129,8 +129,6 @@ enum #define AUDIO_DEFAULT_DRIVER AUDIO_SL #elif defined(HAVE_DSOUND) #define AUDIO_DEFAULT_DRIVER AUDIO_DSOUND -#elif defined(EMSCRIPTEN) -#define AUDIO_DEFAULT_DRIVER AUDIO_NULL #elif defined(HAVE_SDL) #define AUDIO_DEFAULT_DRIVER AUDIO_SDL #elif defined(HAVE_XAUDIO) diff --git a/libretro-test/Makefile b/libretro-test/Makefile index 15853aaeeb..1998f05f22 100644 --- a/libretro-test/Makefile +++ b/libretro-test/Makefile @@ -1,4 +1,8 @@ +ifneq ($(EMSCRIPTEN),) + platform = emscripten +endif + ifeq ($(platform),) platform = unix ifeq ($(shell uname -a),) @@ -32,6 +36,10 @@ else ifeq ($(platform), qnx) TARGET := $(TARGET_NAME)_libretro_qnx.so fpic := -fPIC SHARED := -shared -Wl,--version-script=link.T -Wl,--no-undefined +else ifeq ($(platform), emscripten) + TARGET := $(TARGET_NAME)_libretro_emscripten.so + fpic := -fPIC + SHARED := -shared -Wl,--version-script=link.T -Wl,--no-undefined else CC = gcc TARGET := $(TARGET_NAME)_retro.dll From 747927040679dce395a766cd7cdae63ba985f611 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Wed, 7 Aug 2013 18:37:05 -0400 Subject: [PATCH 008/202] makefile changes --- Makefile.emscripten | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile.emscripten b/Makefile.emscripten index 797e62c0b2..f4ba2700a7 100644 --- a/Makefile.emscripten +++ b/Makefile.emscripten @@ -56,7 +56,7 @@ libretro ?= -lretro_emscripten LIBS = -lm DEFINES = -DHAVE_SCREENSHOTS -DHAVE_NULLAUDIO -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.9.3\" -LDFLAGS = -L. -static-libgcc -s TOTAL_MEMORY=268435456 -s FULL_ES2=1 +LDFLAGS = -L. -static-libgcc -s TOTAL_MEMORY=268435456 ifeq ($(SCALER_NO_SIMD), 1) DEFINES += -DSCALER_NO_SIMD @@ -157,9 +157,8 @@ clean: rm -f gfx/rpng/*.o rm -f record/*.o rm -f input/*.o - rm -f $(TARGET) - rm -f retroarch-joyconfig.exe rm -f tools/*.o + rm -f $(TARGET) .PHONY: all clean From 846e72ad1e438f724835645596195a8fc621774c Mon Sep 17 00:00:00 2001 From: Themaister Date: Tue, 13 Aug 2013 16:58:43 +0200 Subject: [PATCH 009/202] Allow spaces for matrix hack. --- tools/cg2glsl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cg2glsl.py b/tools/cg2glsl.py index aa5b279a45..d8e20efe1e 100755 --- a/tools/cg2glsl.py +++ b/tools/cg2glsl.py @@ -537,7 +537,7 @@ def preprocess_vertex(source_data): input_data = source_data.split('\n') ret = [] for line in input_data: - if 'uniform float4x4' in line: + if ('uniform' in line) and ('float4x4' in line): ret.append('#pragma pack_matrix(column_major)\n') ret.append(line) ret.append('#pragma pack_matrix(row_major)\n') From 8286e30b6b34d20a644c7b32b96789f6ae4ba846 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 13 Aug 2013 19:27:13 +0200 Subject: [PATCH 010/202] (Android Phoenix) Some cleanups to CoreSelection.java --- .../src/org/retroarch/browser/CoreSelection.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/CoreSelection.java b/android/phoenix/src/org/retroarch/browser/CoreSelection.java index 44f59f267e..71cc91cca3 100644 --- a/android/phoenix/src/org/retroarch/browser/CoreSelection.java +++ b/android/phoenix/src/org/retroarch/browser/CoreSelection.java @@ -26,8 +26,6 @@ public class CoreSelection extends Activity implements static private final int ACTIVITY_LOAD_ROM = 0; static private String libretro_path; static private final String TAG = "CoreSelection"; - private ConfigFile config; - private ConfigFile core_config; private final double getDisplayRefreshRate() { // Android is *very* likely to screw this up. @@ -87,14 +85,9 @@ public class CoreSelection extends Activity implements @Override public void onCreate(Bundle savedInstanceState) { + ConfigFile core_config; super.onCreate(savedInstanceState); - try { - config = new ConfigFile(new File(getDefaultConfigPath())); - } catch (IOException e) { - config = new ConfigFile(); - } - core_config = new ConfigFile(); try { core_config.append(getAssets().open("libretro_cores.cfg")); @@ -216,6 +209,13 @@ public class CoreSelection extends Activity implements } private void updateConfigFile() { + ConfigFile config; + try { + config = new ConfigFile(new File(getDefaultConfigPath())); + } catch (IOException e) { + config = new ConfigFile(); + } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true)); config.setInt("audio_out_rate", getOptimalSamplingRate()); From b0644e2f717e8016607f2fedeba5ed03d6925057 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 13 Aug 2013 20:26:21 +0200 Subject: [PATCH 011/202] (Android Phoenix) Close CoreSelection activity after having launched a game --- android/phoenix/src/org/retroarch/browser/CoreSelection.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/android/phoenix/src/org/retroarch/browser/CoreSelection.java b/android/phoenix/src/org/retroarch/browser/CoreSelection.java index 71cc91cca3..f0ee1b3802 100644 --- a/android/phoenix/src/org/retroarch/browser/CoreSelection.java +++ b/android/phoenix/src/org/retroarch/browser/CoreSelection.java @@ -317,9 +317,11 @@ public class CoreSelection extends Activity implements myIntent.putExtra("CONFIGFILE", getDefaultConfigPath()); myIntent.putExtra("IME", current_ime); startActivity(myIntent); + finish(); } break; } + } @Override From 0dde2ce7c4de6fe604a3aeaecda190a88de88210 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 14 Aug 2013 03:59:11 +0200 Subject: [PATCH 012/202] Add bsnes performance module info files --- android/phoenix/assets/libretro_cores.cfg | 1 + apple/modules/bsnes_performance_libretro.info | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 apple/modules/bsnes_performance_libretro.info diff --git a/android/phoenix/assets/libretro_cores.cfg b/android/phoenix/assets/libretro_cores.cfg index 468fbf0ae3..f921f2c467 100644 --- a/android/phoenix/assets/libretro_cores.cfg +++ b/android/phoenix/assets/libretro_cores.cfg @@ -24,3 +24,4 @@ libretro_stella = "Stella (Atari 2600)" libretro_scenewalker = "SceneWalker (Objects)" libretro_modelviewer = "ModelViewer (Objects)" libretro_mame078 = "MAME 2003 [0.78] (Arcade)" +libretro_bsnes_performance = "bsnes/higan Performance (Nintendo SNES)" diff --git a/apple/modules/bsnes_performance_libretro.info b/apple/modules/bsnes_performance_libretro.info new file mode 100644 index 0000000000..2db7e92326 --- /dev/null +++ b/apple/modules/bsnes_performance_libretro.info @@ -0,0 +1,5 @@ +display_name = "SNES / Super Famicom (SNES9x Next)" +supported_extensions = "smc|sfc" +corename = "bsnes/higan Performance" +manufacturer = "Nintendo" +systemname = "Super Nintendo Entertainment System" From 6fd04e1e0e99a68a467c189fdc240b84a69af563 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 14 Aug 2013 04:17:30 +0200 Subject: [PATCH 013/202] (Android Phoenix) Add TV mode - boot straight into RGUI --- android/phoenix/AndroidManifest.xml | 1 + android/phoenix/res/xml/prefs.xml | 7 ++++++- .../org/retroarch/browser/RetroTVMode.java | 19 +++++++++++++++++++ frontend/frontend_android.c | 13 ++++++++++--- 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 android/phoenix/src/org/retroarch/browser/RetroTVMode.java diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index d0dc0587b0..4f6243d63f 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -32,6 +32,7 @@ + diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index 0b3142b73c..6a2ae26e9e 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -2,7 +2,12 @@ - + + + + diff --git a/android/phoenix/src/org/retroarch/browser/RetroTVMode.java b/android/phoenix/src/org/retroarch/browser/RetroTVMode.java new file mode 100644 index 0000000000..a2ee4372e3 --- /dev/null +++ b/android/phoenix/src/org/retroarch/browser/RetroTVMode.java @@ -0,0 +1,19 @@ +package org.retroarch.browser; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Intent; +import android.os.Bundle; +import android.provider.Settings; + +public class RetroTVMode extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Intent myIntent = new Intent(this, RetroActivity.class); + startActivity(myIntent); + finish(); + } +} + + diff --git a/frontend/frontend_android.c b/frontend/frontend_android.c index a1b26f45f2..734888ef48 100644 --- a/frontend/frontend_android.c +++ b/frontend/frontend_android.c @@ -153,9 +153,16 @@ static bool android_app_start_main(struct android_app *android_app) config_load(); menu_init(); - ret = load_menu_game(); - if (ret) - g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); + + if *(g_extern.fullpath) + { + ret = load_menu_game(); + if (ret) + g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); + } + else + g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU); + return ret; } From 0bbd9699b44cf07050bac837b98dd144581d4f75 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 14 Aug 2013 04:27:44 +0200 Subject: [PATCH 014/202] (Android Phoenix) TV Mode now loads the config file --- .../org/retroarch/browser/RetroTVMode.java | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/android/phoenix/src/org/retroarch/browser/RetroTVMode.java b/android/phoenix/src/org/retroarch/browser/RetroTVMode.java index a2ee4372e3..e69445b5e9 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroTVMode.java +++ b/android/phoenix/src/org/retroarch/browser/RetroTVMode.java @@ -1,16 +1,48 @@ package org.retroarch.browser; +import java.io.File; + import android.app.Activity; -import android.app.AlertDialog; import android.content.Intent; import android.os.Bundle; import android.provider.Settings; public class RetroTVMode extends Activity { + private String getDefaultConfigPath() { + String internal = System.getenv("INTERNAL_STORAGE"); + String external = System.getenv("EXTERNAL_STORAGE"); + + if (external != null) { + String confPath = external + File.separator + "retroarch.cfg"; + if (new File(confPath).exists()) + return confPath; + } else if (internal != null) { + String confPath = internal + File.separator + "retroarch.cfg"; + if (new File(confPath).exists()) + return confPath; + } else { + String confPath = "/mnt/extsd/retroarch.cfg"; + if (new File(confPath).exists()) + return confPath; + } + + if (internal != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) + return internal + File.separator + "retroarch.cfg"; + else if (external != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) + return external + File.separator + "retroarch.cfg"; + else if ((getApplicationInfo().dataDir) != null) + return (getApplicationInfo().dataDir) + File.separator + "retroarch.cfg"; + else // emergency fallback, all else failed + return "/mnt/sd/retroarch.cfg"; + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent myIntent = new Intent(this, RetroActivity.class); + String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); + myIntent.putExtra("CONFIGFILE", getDefaultConfigPath()); + myIntent.putExtra("IME", current_ime); startActivity(myIntent); finish(); } From 1e14cbafd4383901f7aa7396f504ff8e24ab65b6 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 14 Aug 2013 04:36:47 +0200 Subject: [PATCH 015/202] (frontend_android) Revert --- frontend/frontend_android.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/frontend/frontend_android.c b/frontend/frontend_android.c index 734888ef48..6d578b3691 100644 --- a/frontend/frontend_android.c +++ b/frontend/frontend_android.c @@ -154,14 +154,9 @@ static bool android_app_start_main(struct android_app *android_app) menu_init(); - if *(g_extern.fullpath) - { - ret = load_menu_game(); - if (ret) - g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); - } - else - g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU); + ret = load_menu_game(); + if (ret) + g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); return ret; } From cb6c612b8e1d79d663b18c812b175d5781c6d469 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 13 Aug 2013 13:17:51 -0400 Subject: [PATCH 016/202] (iOS) Only player 1 gets default keyboard bindings --- apple/iOS/settings.m | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index 65b4c025eb..db4ffcc423 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -170,23 +170,26 @@ static RASettingData* custom_action(NSString* action, NSString* value, id data) static NSArray* build_input_port_group(config_file_t* config, uint32_t player) { + // Only player 1 should have default key bindings + #define DEFKEY(val) (player == 1) ? val : @"nul" + return [NSArray arrayWithObjects: [NSArray arrayWithObjects:[NSString stringWithFormat:@"Player %d", player], - button_setting(config, player, @"up", @"Up", @"up"), - button_setting(config, player, @"down", @"Down", @"down"), - button_setting(config, player, @"left", @"Left", @"left"), - button_setting(config, player, @"right", @"Right", @"right"), + button_setting(config, player, @"up", @"Up", DEFKEY(@"up")), + button_setting(config, player, @"down", @"Down", DEFKEY(@"down")), + button_setting(config, player, @"left", @"Left", DEFKEY(@"left")), + button_setting(config, player, @"right", @"Right", DEFKEY(@"right")), - button_setting(config, player, @"start", @"Start", @"enter"), - button_setting(config, player, @"select", @"Select", @"rshift"), + button_setting(config, player, @"start", @"Start", DEFKEY(@"enter")), + button_setting(config, player, @"select", @"Select", DEFKEY(@"rshift")), - button_setting(config, player, @"b", @"B", @"z"), - button_setting(config, player, @"a", @"A", @"x"), - button_setting(config, player, @"x", @"X", @"s"), - button_setting(config, player, @"y", @"Y", @"a"), + button_setting(config, player, @"b", @"B", DEFKEY(@"z")), + button_setting(config, player, @"a", @"A", DEFKEY(@"x")), + button_setting(config, player, @"x", @"X", DEFKEY(@"s")), + button_setting(config, player, @"y", @"Y", DEFKEY(@"a")), - button_setting(config, player, @"l", @"L", @"q"), - button_setting(config, player, @"r", @"R", @"w"), + button_setting(config, player, @"l", @"L", DEFKEY(@"q")), + button_setting(config, player, @"r", @"R", DEFKEY(@"w")), button_setting(config, player, @"l2", @"L2", @"nul"), button_setting(config, player, @"r2", @"R2", @"nul"), button_setting(config, player, @"l3", @"L3", @"nul"), From 4d8570d546342f438afa58ab152d73f5455fde99 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 13 Aug 2013 13:54:24 -0400 Subject: [PATCH 017/202] (iOS) Build script fix for jailbroken devices --- apple/script/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apple/script/build b/apple/script/build index e65f85a422..15d48e7060 100755 --- a/apple/script/build +++ b/apple/script/build @@ -23,7 +23,7 @@ if [ -z "$NOCODESIGN" ] ; then xcrun -sdk iphoneos PackageApplication "$BUILD_PATH/RetroArch.app" -o "$BUILD_PATH/RetroArch.ipa" --sign "$CODE_SIGN_IDENTITY" --embed "$BUILD_PATH/RetroArch.app/embedded.mobileprovision" else - xcodebuild -verbose -sdk iphoneos -configuration Release + xcodebuild -verbose -sdk iphoneos -configuration Release -project $PROJECT_NAME echo "Building for Jailbroken system" fi From 8656b04492e008877ef834b8a35098f9469b20e9 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 13 Aug 2013 14:36:04 -0400 Subject: [PATCH 018/202] (iOS) Some refactoring in settings.m --- apple/RetroArch/main.m | 8 +- apple/iOS/settings.m | 242 ++++++++++++++++++++++++----------------- 2 files changed, 145 insertions(+), 105 deletions(-) diff --git a/apple/RetroArch/main.m b/apple/RetroArch/main.m index 85247654d6..b14f7190f2 100644 --- a/apple/RetroArch/main.m +++ b/apple/RetroArch/main.m @@ -390,10 +390,12 @@ int main(int argc, char *argv[]) _enabledOrientations |= orientationSettings[i].orientation; } - // + // Setup bluetooth mode + NSString* btmode = objc_get_value_from_config(conf, @"ios_btmode", @"keyboard"); + apple_input_enable_icade([btmode isEqualToString:@"icade"]); + btstack_set_poweron([btmode isEqualToString:@"btstack"]); + bool val; - apple_input_enable_icade(config_get_bool(conf, "ios_use_icade", &val) && val); - btstack_set_poweron(config_get_bool(conf, "ios_use_btstack", &val) && val); use_tv_mode = config_get_bool(conf, "ios_tv_mode", & val) && val; config_file_free(conf); diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index db4ffcc423..082f031ed4 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -28,34 +28,65 @@ enum SettingTypes }; @interface RASettingData : NSObject -@property enum SettingTypes type; +{ + @public + enum SettingTypes type; -@property (strong) NSString* label; -@property (strong) NSString* name; -@property (strong) NSString* value; + NSString* label; // < The label displayed in the settings menu + NSString* name; // < The key name of the value in the config file + NSString* value; // < The current state of the setting -@property (strong) NSString* path; -@property (strong) NSArray* subValues; -@property (strong) NSMutableArray* msubValues; - -@property double rangeMin; -@property double rangeMax; - -@property uint32_t player; - -@property bool haveNoneOption; - -- (id)initWithType:(enum SettingTypes)aType label:(NSString*)aLabel name:(NSString*)aName; + uint32_t player; // < The player that a ButtonSetting represents + NSString* button_bind; // < The Gamepad button binding string + NSString* axis_bind; // < The Gamepad axis binding string + + NSString* path; // < The base path for FileListSettings + NSArray* subValues; // < The available options for EnumerationSettings and FileListSettings + bool haveNoneOption; // < Determines if a 'None' option is added to an Enumeration or FileList + bool haveDescriptions; // < Determines if subValues containts friendly descriptions for each value + + double rangeMin; // < The mininum value of a range setting + double rangeMax; // < The maximum value of a range setting +} @end @implementation RASettingData - (id)initWithType:(enum SettingTypes)aType label:(NSString*)aLabel name:(NSString*)aName { - self.type = aType; - self.label = aLabel; - self.name = aName; + type = aType; + label = aLabel; + name = aName; return self; } + +- (uint32_t)enumerationCount +{ + return subValues.count / (haveDescriptions ? 2 : 1); +} + +- (NSString*)valueForEnumerationIndex:(uint32_t)index +{ + return subValues[index * (haveDescriptions ? 2 : 1)]; +} + +- (NSString*)labelForEnumerationIndex:(uint32_t)index +{ + return subValues[index * (haveDescriptions ? 2 : 1) + (haveDescriptions ? 1 : 0)]; +} + +- (NSString*)labelForEnumerationValue +{ + const uint32_t count = self.enumerationCount; + + for (int i = 0; haveDescriptions && i < count; i ++) + { + if ([value isEqualToString:subValues[i * 2]]) + return subValues[i * 2 + 1]; + } + + return value; +} + @end // Helper view definitions @@ -71,7 +102,7 @@ enum SettingTypes static RASettingData* boolean_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue) { RASettingData* result = [[RASettingData alloc] initWithType:BooleanSetting label:label name:name]; - result.value = objc_get_value_from_config(config, name, defaultValue); + result->value = objc_get_value_from_config(config, name, defaultValue); return result; } @@ -80,27 +111,26 @@ static RASettingData* button_setting(config_file_t* config, uint32_t player, NSS NSString* realname = player ? [NSString stringWithFormat:@"input_player%d_%@", player, name] : name; RASettingData* result = [[RASettingData alloc] initWithType:ButtonSetting label:label name:realname]; - result.msubValues = [NSMutableArray arrayWithObjects: - objc_get_value_from_config(config, realname, defaultValue), - objc_get_value_from_config(config, [realname stringByAppendingString:@"_btn"], @"nul"), - objc_get_value_from_config(config, [realname stringByAppendingString:@"_axis"], @"nul"), - nil]; - result.player = player ? player - 1 : 0; + result->player = player ? player - 1 : 0; + result->value = objc_get_value_from_config(config, realname, defaultValue); + result->button_bind = objc_get_value_from_config(config, [realname stringByAppendingString:@"_btn"], @"nul"); + result->axis_bind = objc_get_value_from_config(config, [realname stringByAppendingString:@"_axis"], @"nul"); return result; } static RASettingData* group_setting(NSString* label, NSArray* settings) { RASettingData* result = [[RASettingData alloc] initWithType:GroupSetting label:label name:nil]; - result.subValues = settings; + result->subValues = settings; return result; } -static RASettingData* enumeration_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values) +static RASettingData* enumeration_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, NSArray* values, bool haveDescriptions) { RASettingData* result = [[RASettingData alloc] initWithType:EnumerationSetting label:label name:name]; - result.value = objc_get_value_from_config(config, name, defaultValue); - result.subValues = values; + result->value = objc_get_value_from_config(config, name, defaultValue); + result->subValues = values; + result->haveDescriptions = haveDescriptions; return result; } @@ -113,19 +143,19 @@ static RASettingData* subpath_setting(config_file_t* config, NSString* name, NSS values = [values pathsMatchingExtensions:[NSArray arrayWithObject:extension]]; RASettingData* result = [[RASettingData alloc] initWithType:FileListSetting label:label name:name]; - result.value = value; - result.subValues = values; - result.path = path; - result.haveNoneOption = true; + result->value = value; + result->subValues = values; + result->path = path; + result->haveNoneOption = true; return result; } static RASettingData* range_setting(config_file_t* config, NSString* name, NSString* label, NSString* defaultValue, double minValue, double maxValue) { RASettingData* result = [[RASettingData alloc] initWithType:RangeSetting label:label name:name]; - result.value = objc_get_value_from_config(config, name, defaultValue); - result.rangeMin = minValue; - result.rangeMax = maxValue; + result->value = objc_get_value_from_config(config, name, defaultValue); + result->rangeMin = minValue; + result->rangeMax = maxValue; return result; } @@ -133,8 +163,8 @@ static RASettingData* aspect_setting(config_file_t* config, NSString* label) { // Why does this need to be so difficult? - RASettingData* result = [[RASettingData alloc] initWithType:AspectSetting label:label name:@"fram"]; - result.subValues = [NSArray arrayWithObjects:@"Fill Screen", @"Game Aspect", @"Pixel Aspect", @"4:3", @"16:9", nil]; + RASettingData* result = [[RASettingData alloc] initWithType:AspectSetting label:label name:@""]; + result->subValues = [NSArray arrayWithObjects:@"Fill Screen", @"Game Aspect", @"Pixel Aspect", @"4:3", @"16:9", nil]; bool videoForceAspect = true; bool videoAspectAuto = false; @@ -148,11 +178,11 @@ static RASettingData* aspect_setting(config_file_t* config, NSString* label) } if (!videoForceAspect) - result.value = @"Fill Screen"; + result->value = @"Fill Screen"; else if (videoAspect < 0.0) - result.value = videoAspectAuto ? @"Game Aspect" : @"Pixel Aspect"; + result->value = videoAspectAuto ? @"Game Aspect" : @"Pixel Aspect"; else - result.value = (videoAspect < 1.5) ? @"4:3" : @"16:9"; + result->value = (videoAspect < 1.5) ? @"4:3" : @"16:9"; return result; } @@ -160,7 +190,7 @@ static RASettingData* aspect_setting(config_file_t* config, NSString* label) static RASettingData* custom_action(NSString* action, NSString* value, id data) { RASettingData* result = [[RASettingData alloc] initWithType:CustomAction label:action name:nil]; - result.value = value; + result->value = value; if (data != nil) objc_setAssociatedObject(result, "USERDATA", data, OBJC_ASSOCIATION_RETAIN_NONATOMIC); @@ -254,7 +284,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) [NSArray arrayWithObjects:@"Input", subpath_setting(config, @"input_overlay", @"Input Overlay", @"", overlay_path, @"cfg"), - range_setting(config, @"input_overlay_opacity", @"Overlay Opacity", @"1.0", 0.0, 1.0), + range_setting(config, @"overlay_opacity", @"Overlay Opacity", @"1.0", 0.0, 1.0), group_setting(@"System Keys", [NSArray arrayWithObjects: // TODO: Many of these strings will be cut off on an iPhone [NSArray arrayWithObjects:@"System Keys", @@ -319,7 +349,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (void)handleCustomAction:(RASettingData*)setting { - if ([@"Core Info" isEqualToString:setting.label]) + if ([@"Core Info" isEqualToString:setting->label]) [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:_module] animated:YES]; } @@ -330,15 +360,18 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) { config_file_t* config = config_file_new([[RetroArch_iOS get].systemConfigPath UTF8String]); + NSArray* bluetoothOptions = [NSArray arrayWithObjects:@"keyboard", @"Keyboard", + @"icade", @"iCade Device", + btstack_try_load() ? @"btstack" : nil, @"WiiMote/SixAxis (BTstack)", + nil]; + NSArray* settings = [NSArray arrayWithObjects: [NSArray arrayWithObjects:@"Frontend", custom_action(@"Diagnostic Log", nil, nil), boolean_setting(config, @"ios_tv_mode", @"TV Mode", @"false"), nil], [NSArray arrayWithObjects:@"Bluetooth", - // TODO: Note that with this turned off the native bluetooth is expected to be a real keyboard - boolean_setting(config, @"ios_use_icade", @"Native BT is iCade", @"false"), - btstack_try_load() ? boolean_setting(config, @"ios_use_btstack", @"Enable BTstack", @"false") : nil, + enumeration_setting(config, @"ios_btmode", @"Mode", @"keyboard", bluetoothOptions, true), nil], [NSArray arrayWithObjects:@"Orientations", boolean_setting(config, @"ios_allow_portrait", @"Portrait", @"true"), @@ -378,11 +411,11 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (void)handleCustomAction:(RASettingData*)setting { - if ([@"Diagnostic Log" isEqualToString:setting.label]) + if ([@"Diagnostic Log" isEqualToString:setting->label]) [[RetroArch_iOS get] pushViewController:[RALogView new] animated:YES]; - else if ([@"Enable BTstack" isEqualToString:setting.label]) - btstack_set_poweron([setting.value isEqualToString:@"true"]); - else if([@"Core Configuration" isEqualToString:setting.label]) + else if ([@"Enable BTstack" isEqualToString:setting->label]) + btstack_set_poweron([setting->value isEqualToString:@"true"]); + else if([@"Core Configuration" isEqualToString:setting->label]) [RetroArch_iOS.get pushViewController:[[RASettingsList alloc] initWithModule:nil] animated:YES]; } @@ -423,35 +456,35 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) { RASettingData* setting = [group objectAtIndex:j]; - switch (setting.type) + switch (setting->type) { case GroupSetting: - [self writeSettings:setting.subValues toConfig:config]; + [self writeSettings:setting->subValues toConfig:config]; break; case FileListSetting: - if ([setting.value length] > 0) - config_set_string(config, [setting.name UTF8String], [[setting.path stringByAppendingPathComponent:setting.value] UTF8String]); + if ([setting->value length] > 0) + config_set_string(config, [setting->name UTF8String], [[setting->path stringByAppendingPathComponent:setting->value] UTF8String]); else - config_set_string(config, [setting.name UTF8String], ""); + config_set_string(config, [setting->name UTF8String], ""); break; case ButtonSetting: - if (setting.msubValues[0]) - config_set_string(config, [setting.name UTF8String], [setting.msubValues[0] UTF8String]); - if (setting.msubValues[1]) - config_set_string(config, [[setting.name stringByAppendingString:@"_btn"] UTF8String], [setting.msubValues[1] UTF8String]); - if (setting.msubValues[2]) - config_set_string(config, [[setting.name stringByAppendingString:@"_axis"] UTF8String], [setting.msubValues[2] UTF8String]); + if (setting->value) + config_set_string(config, [setting->name UTF8String], [setting->value UTF8String]); + if (setting->button_bind) + config_set_string(config, [[setting->name stringByAppendingString:@"_btn"] UTF8String], [setting->button_bind UTF8String]); + if (setting->axis_bind) + config_set_string(config, [[setting->name stringByAppendingString:@"_axis"] UTF8String], [setting->axis_bind UTF8String]); break; case AspectSetting: - config_set_string(config, "video_force_aspect", [@"Fill Screen" isEqualToString:setting.value] ? "false" : "true"); - config_set_string(config, "video_aspect_ratio_auto", [@"Game Aspect" isEqualToString:setting.value] ? "true" : "false"); + config_set_string(config, "video_force_aspect", [@"Fill Screen" isEqualToString:setting->value] ? "false" : "true"); + config_set_string(config, "video_aspect_ratio_auto", [@"Game Aspect" isEqualToString:setting->value] ? "true" : "false"); config_set_string(config, "video_aspect_ratio", "-1.0"); - if([@"4:3" isEqualToString:setting.value]) + if([@"4:3" isEqualToString:setting->value]) config_set_string(config, "video_aspect_ratio", "1.33333333"); - else if([@"16:9" isEqualToString:setting.value]) + else if([@"16:9" isEqualToString:setting->value]) config_set_string(config, "video_aspect_ratio", "1.77777777"); break; @@ -459,7 +492,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) break; default: - config_set_string(config, [setting.name UTF8String], [setting.value UTF8String]); + config_set_string(config, [setting->name UTF8String], [setting->value UTF8String]); break; } } @@ -470,7 +503,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) { RASettingData* setting = (RASettingData*)[self itemForIndexPath:indexPath]; - switch (setting.type) + switch (setting->type) { case EnumerationSetting: case FileListSetting: @@ -483,7 +516,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) break; case GroupSetting: - [[RetroArch_iOS get] pushViewController:[[RASettingsSubList alloc] initWithSettings:setting.subValues title:setting.label] animated:YES]; + [[RetroArch_iOS get] pushViewController:[[RASettingsSubList alloc] initWithSettings:setting->subValues title:setting->label] animated:YES]; break; default: @@ -496,7 +529,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (void)handleBooleanSwitch:(UISwitch*)swt { RASettingData* setting = objc_getAssociatedObject(swt, "SETTING"); - setting.value = (swt.on ? @"true" : @"false"); + setting->value = (swt.on ? @"true" : @"false"); [self handleCustomAction:setting]; } @@ -504,7 +537,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (void)handleSlider:(UISlider*)sld { RASettingData* setting = objc_getAssociatedObject(sld, "SETTING"); - setting.value = [NSString stringWithFormat:@"%f", sld.value]; + setting->value = [NSString stringWithFormat:@"%f", sld.value]; [self handleCustomAction:setting]; } @@ -515,7 +548,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) UITableViewCell* cell = nil; - switch (setting.type) + switch (setting->type) { case BooleanSetting: { @@ -532,10 +565,10 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; } - cell.textLabel.text = setting.label; + cell.textLabel.text = setting->label; UISwitch* swt = (UISwitch*)cell.accessoryView; - swt.on = [setting.value isEqualToString:@"true"]; + swt.on = [setting->value isEqualToString:@"true"]; objc_setAssociatedObject(swt, "SETTING", setting, OBJC_ASSOCIATION_RETAIN_NONATOMIC); return cell; @@ -557,12 +590,12 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; } - cell.textLabel.text = setting.label; + cell.textLabel.text = setting->label; UISlider* sld = (UISlider*)cell.accessoryView; - sld.minimumValue = setting.rangeMin; - sld.maximumValue = setting.rangeMax; - sld.value = [setting.value doubleValue]; + sld.minimumValue = setting->rangeMin; + sld.maximumValue = setting->rangeMax; + sld.value = [setting->value doubleValue]; objc_setAssociatedObject(sld, "SETTING", setting, OBJC_ASSOCIATION_RETAIN_NONATOMIC); return cell; @@ -579,15 +612,17 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } - cell.textLabel.text = setting.label; + cell.textLabel.text = setting->label; - if (setting.type != ButtonSetting) - cell.detailTextLabel.text = setting.value; - else + if (setting->type == ButtonSetting) cell.detailTextLabel.text = [NSString stringWithFormat:@"[KB:%@] [JS:%@] [AX:%@]", - [setting.msubValues[0] length] ? setting.msubValues[0] : @"nul", - [setting.msubValues[1] length] ? setting.msubValues[1] : @"nul", - [setting.msubValues[2] length] ? setting.msubValues[2] : @"nul"]; + [setting->value length] ? setting->value : @"nul", + [setting->button_bind length] ? setting->button_bind : @"nul", + [setting->axis_bind length] ? setting->axis_bind : @"nul"]; + else if(setting->type == EnumerationSetting) + cell.detailTextLabel.text = setting.labelForEnumerationValue; + else + cell.detailTextLabel.text = setting->value; return cell; } @@ -609,20 +644,20 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) _value = setting; _view = table; - _mainSection = _value.haveNoneOption ? 1 : 0; + _mainSection = _value->haveNoneOption ? 1 : 0; - [self setTitle: _value.label]; + [self setTitle: _value->label]; return self; } - (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView { - return _value.haveNoneOption ? 2 : 1; + return _value->haveNoneOption ? 2 : 1; } - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { - return (section == _mainSection) ? _value.subValues.count : 1; + return (section == _mainSection) ? _value.enumerationCount : 1; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath @@ -630,14 +665,17 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"option"]; cell = cell ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"option"]; - cell.textLabel.text = (indexPath.section == _mainSection) ? _value.subValues[indexPath.row] : @"None"; + if (indexPath.section == _mainSection) + cell.textLabel.text = [_value labelForEnumerationIndex:indexPath.row]; + else + cell.textLabel.text = @"None"; return cell; } - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - _value.value = (indexPath.section == _mainSection) ? _value.subValues[indexPath.row] : @""; + _value->value = (indexPath.section == _mainSection) ? [_value valueForEnumerationIndex:indexPath.row] : @""; [_view reloadData]; [[RetroArch_iOS get] popViewControllerAnimated:YES]; @@ -664,7 +702,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) _me = self; _alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" - message:_value.label + message:_value->label delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Clear Keyboard", @"Clear Joystick", @"Clear Axis", nil]; @@ -692,11 +730,11 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (void)alertView:(UIAlertView*)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex { if (buttonIndex == _alert.firstOtherButtonIndex) - _value.msubValues[0] = @"nul"; + _value->value = @"nul"; else if(buttonIndex == _alert.firstOtherButtonIndex + 1) - _value.msubValues[1] = @"nul"; + _value->button_bind = @"nul"; else if(buttonIndex == _alert.firstOtherButtonIndex + 2) - _value.msubValues[2] = @"nul"; + _value->axis_bind = @"nul"; [self finish]; } @@ -762,21 +800,21 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) { if (g_current_input_data.keys[ios_key_name_map[i].hid_id]) { - _value.msubValues[0] = [NSString stringWithUTF8String:ios_key_name_map[i].keyname]; + _value->value = [NSString stringWithUTF8String:ios_key_name_map[i].keyname]; [self finish]; return; } } // Pad Buttons - uint32_t buttons = g_current_input_data.pad_buttons[_value.player] | - ((_value.player == 0) ? apple_input_get_icade_buttons() : 0); + uint32_t buttons = g_current_input_data.pad_buttons[_value->player] | + ((_value->player == 0) ? apple_input_get_icade_buttons() : 0); for (int i = 0; buttons && i < sizeof(buttons) * 8; i++) { if (buttons & (1 << i)) { - _value.msubValues[1] = [NSString stringWithFormat:@"%d", i]; + _value->button_bind = [NSString stringWithFormat:@"%d", i]; [self finish]; return; } @@ -785,11 +823,11 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) // Pad Axis for (int i = 0; i < 4; i++) { - int16_t value = g_current_input_data.pad_axis[_value.player][i]; + int16_t value = g_current_input_data.pad_axis[_value->player][i]; if (abs(value) > 0x1000) { - _value.msubValues[2] = [NSString stringWithFormat:@"%s%d", (value > 0x1000) ? "+" : "-", i]; + _value->axis_bind = [NSString stringWithFormat:@"%s%d", (value > 0x1000) ? "+" : "-", i]; [self finish]; break; } From fe08806aa52b194d9cdfedeb7549c686f62e4b26 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 13 Aug 2013 22:42:56 -0400 Subject: [PATCH 019/202] (iOS) Use the nuclear option for life-cycle management. This should fix hangs caused by incoming calls or launching siri, but will cause more driver reinits than before --- apple/RetroArch/RAGameView.m | 20 +------------------- apple/RetroArch/RetroArch_Apple.h | 3 --- apple/RetroArch/main.m | 25 +++++++++++++++++++++---- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/apple/RetroArch/RAGameView.m b/apple/RetroArch/RAGameView.m index a9b8f174a4..daa9fd97e9 100644 --- a/apple/RetroArch/RAGameView.m +++ b/apple/RetroArch/RAGameView.m @@ -189,17 +189,6 @@ static float g_screen_scale = 1.0f; ]; } -- (void)suspend -{ - g_view.context = nil; - [EAGLContext setCurrentContext:nil]; -} - -- (void)resume -{ - g_view.context = g_context; - [EAGLContext setCurrentContext:g_context]; -} #endif @end @@ -215,7 +204,7 @@ bool apple_init_game_view() g_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; [EAGLContext setCurrentContext:g_context]; g_view.context = g_context; - + // Show pause button for a few seconds, so people know it's there g_pause_indicator_view.alpha = 1.0f; [NSObject cancelPreviousPerformRequestsWithTarget:g_instance]; @@ -232,13 +221,6 @@ bool apple_init_game_view() void apple_destroy_game_view() { dispatch_sync(dispatch_get_main_queue(), ^{ - // Clear the view, otherwise the last frame from this game will be displayed - // briefly on the next game. - [g_view bindDrawable]; - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - [g_view display]; - glFinish(); #ifdef IOS diff --git a/apple/RetroArch/RetroArch_Apple.h b/apple/RetroArch/RetroArch_Apple.h index 5302d3a4c2..39096304d5 100644 --- a/apple/RetroArch/RetroArch_Apple.h +++ b/apple/RetroArch/RetroArch_Apple.h @@ -39,9 +39,6 @@ extern id apple_platform; + (RAGameView*)get; - (void)openPauseMenu; - (void)closePauseMenu; - -- (void)suspend; -- (void)resume; @end @interface RetroArch_iOS : UINavigationController diff --git a/apple/RetroArch/main.m b/apple/RetroArch/main.m index b14f7190f2..12e0361392 100644 --- a/apple/RetroArch/main.m +++ b/apple/RetroArch/main.m @@ -83,6 +83,18 @@ static void event_reload_config(void* userdata) init_drivers(); } +static pthread_mutex_t stasis_mutex = PTHREAD_MUTEX_INITIALIZER; + +static void event_stasis(void* userdata) +{ + // HACK: uninit_drivers is the nuclear option; uninit_audio would be better but will + // crash when resuming. + uninit_drivers(); + pthread_mutex_lock(&stasis_mutex); + pthread_mutex_unlock(&stasis_mutex); + init_drivers(); +} + #pragma mark EMULATION static pthread_t apple_retro_thread; static bool apple_is_paused; @@ -258,14 +270,19 @@ int main(int argc, char *argv[]) apple_display_alert(@"No libretro cores were found. You will not be able to play any games.", 0); } -- (void)applicationWillEnterForeground:(UIApplication *)application +- (void)applicationDidBecomeActive:(UIApplication *)application { - [RAGameView.get resume]; + if (apple_is_running) + pthread_mutex_unlock(&stasis_mutex); } -- (void)applicationDidEnterBackground:(UIApplication *)application +- (void)applicationWillResignActive:(UIApplication *)application { - [RAGameView.get suspend]; + if (apple_is_running) + { + pthread_mutex_lock(&stasis_mutex); + apple_frontend_post_event(event_stasis, 0); + } } // UINavigationControllerDelegate From 9e2e135d195fb830e62803f23ec4fdcd7ca5f0a1 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 14 Aug 2013 00:48:58 -0400 Subject: [PATCH 020/202] (Apple) Get rid of some hacks in the frontend code. --- apple/RetroArch/main.m | 44 ++++++++++++++++++++---------- apple/iOS/settings.m | 2 ++ frontend/frontend.c | 26 ++---------------- frontend/platform/platform_apple.c | 32 +--------------------- general.h | 4 --- 5 files changed, 35 insertions(+), 73 deletions(-) diff --git a/apple/RetroArch/main.m b/apple/RetroArch/main.m index 12e0361392..3e00e3c919 100644 --- a/apple/RetroArch/main.m +++ b/apple/RetroArch/main.m @@ -45,7 +45,6 @@ static bool use_tv_mode; id apple_platform; // From frontend/frontend_ios.c -extern void* rarch_main(void* args); extern void apple_frontend_post_event(void (*fn)(void*), void* userdata); @@ -101,6 +100,22 @@ static bool apple_is_paused; static bool apple_is_running; static RAModuleInfo* apple_core; +void* rarch_main_spring(void* args) +{ + char** argv = args; + + uint32_t argc = 0; + while (argv && argv[argc ++]); + + if (rarch_main(argc, argv)) + { + rarch_main_clear_state(); + dispatch_async_f(dispatch_get_main_queue(), (void*)1, apple_rarch_exited); + } + + return 0; +} + void apple_run_core(RAModuleInfo* core, const char* file) { if (!apple_is_running) @@ -110,23 +125,24 @@ void apple_run_core(RAModuleInfo* core, const char* file) apple_core = core; apple_is_running = true; - struct rarch_main_wrap* load_data = malloc(sizeof(struct rarch_main_wrap)); - memset(load_data, 0, sizeof(struct rarch_main_wrap)); - - load_data->config_path = strdup(apple_platform.retroarchConfigPath.UTF8String); - -#ifdef IOS - load_data->sram_path = strdup(RetroArch_iOS.get.systemDirectory.UTF8String); - load_data->state_path = strdup(RetroArch_iOS.get.systemDirectory.UTF8String); -#endif - + static char config_path[PATH_MAX]; + static char core_path[PATH_MAX]; + static char file_path[PATH_MAX]; + + static const char* argv[] = { "retroarch", "-c", config_path, "-L", core_path, file_path, 0 }; + + strlcpy(config_path, apple_platform.retroarchConfigPath.UTF8String, sizeof(config_path)); + if (file && core) { - load_data->libretro_path = strdup(apple_core.path.UTF8String); - load_data->rom_path = strdup(file); + argv[3] = "-L"; + strlcpy(core_path, apple_core.path.UTF8String, sizeof(core_path)); + strlcpy(file_path, file, sizeof(file_path)); } + else + argv[3] = 0; - if (pthread_create(&apple_retro_thread, 0, rarch_main, load_data)) + if (pthread_create(&apple_retro_thread, 0, rarch_main_spring, argv)) { apple_rarch_exited((void*)1); return; diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index 082f031ed4..797fe4c7ce 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -338,6 +338,8 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) if (config) { config_set_string(config, "system_directory", [[RetroArch_iOS get].systemDirectory UTF8String]); + config_set_string(config, "savefile_directory", [[RetroArch_iOS get].systemDirectory UTF8String]); + config_set_string(config, "savestate_directory", [[RetroArch_iOS get].systemDirectory UTF8String]); [self writeSettings:nil toConfig:config]; config_file_write(config, [_configPath UTF8String]); config_file_free(config); diff --git a/frontend/frontend.c b/frontend/frontend.c index 174f1a8084..914b6c0eaa 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -124,20 +124,13 @@ void rarch_get_environment_console(void) } #endif -#if defined(IOS) || defined(OSX) -void* rarch_main(void* args) -{ - int argc = 0; - char *argv = NULL; -#elif defined(HAVE_BB10) +#if defined(IOS) || defined(OSX) || defined(HAVE_BB10) int rarch_main(int argc, char *argv[]) -{ - void* args = NULL; #else int main(int argc, char *argv[]) +#endif { void* args = NULL; -#endif frontend_ctx = (frontend_ctx_driver_t*)frontend_ctx_init_first(); if (frontend_ctx && frontend_ctx->init) @@ -151,31 +144,16 @@ int main(int argc, char *argv[]) frontend_ctx->environment_get(argc, argv, args); #if !defined(RARCH_CONSOLE) && !defined(HAVE_BB10) -#if defined(__APPLE__) - struct rarch_main_wrap* argdata = (struct rarch_main_wrap*)args; - int init_ret = rarch_main_init_wrap(argdata); - apple_free_main_wrap(argdata); - - if (init_ret) - { - rarch_main_clear_state(); - dispatch_async_f(dispatch_get_main_queue(), (void*)1, apple_rarch_exited); - return 0; - } -#else rarch_init_msg_queue(); int init_ret; if ((init_ret = rarch_main_init(argc, argv))) return init_ret; #endif -#endif #if defined(HAVE_MENU) || defined(HAVE_BB10) menu_init(); -#ifndef __APPLE__ if (frontend_ctx && frontend_ctx->process_args) frontend_ctx->process_args(argc, argv, args); -#endif #if defined(RARCH_CONSOLE) || defined(HAVE_BB10) g_extern.lifecycle_mode_state |= 1ULL << MODE_LOAD_GAME; diff --git a/frontend/platform/platform_apple.c b/frontend/platform/platform_apple.c index 5c413ac4d2..1f6234bd82 100644 --- a/frontend/platform/platform_apple.c +++ b/frontend/platform/platform_apple.c @@ -48,20 +48,6 @@ void apple_frontend_post_event(void (*fn)(void*), void* userdata) pthread_mutex_unlock(&apple_event_queue_lock); } -static void apple_free_main_wrap(struct rarch_main_wrap* wrap) -{ - if (wrap) - { - free((char*)wrap->libretro_path); - free((char*)wrap->rom_path); - free((char*)wrap->sram_path); - free((char*)wrap->state_path); - free((char*)wrap->config_path); - } - - free(wrap); -} - static void process_events(void) { pthread_mutex_lock(&apple_event_queue_lock); @@ -83,24 +69,8 @@ static void system_shutdown(bool force) dispatch_async_f(dispatch_get_main_queue(), 0, apple_rarch_exited); } -static void environment_get(int argc, char *argv[], void *args) -{ - (void)argc; - (void)argv; - (void)args; - -#ifdef IOS - char* system_directory = ios_get_rarch_system_directory(); - strlcpy(g_extern.savestate_dir, system_directory, sizeof(g_extern.savestate_dir)); - strlcpy(g_extern.savefile_dir, system_directory, sizeof(g_extern.savefile_dir)); - free(system_directory); - - config_load(); -#endif -} - const frontend_ctx_driver_t frontend_ctx_apple = { - environment_get, /* environment_get */ + NULL, /* environment_get */ NULL, /* init */ NULL, /* deinit */ NULL, /* exitspawn */ diff --git a/general.h b/general.h index ca07012988..cde28f8b35 100644 --- a/general.h +++ b/general.h @@ -676,11 +676,7 @@ bool config_save_keybinds(const char *path); void rarch_game_reset(void); void rarch_main_clear_state(void); void rarch_init_system_info(void); -#ifdef __APPLE__ -void * rarch_main(void *args); -#else int rarch_main(int argc, char *argv[]); -#endif int rarch_main_init_wrap(const struct rarch_main_wrap *args); int rarch_main_init(int argc, char *argv[]); bool rarch_main_idle_iterate(void); From e8555bc1abc40e38a9921430d475fa1a0dc02757 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 14 Aug 2013 14:10:49 +0200 Subject: [PATCH 021/202] (frontend) make macro for main entry point function --- frontend/frontend.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/frontend.c b/frontend/frontend.c index 914b6c0eaa..4a9093d4e1 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -125,10 +125,12 @@ void rarch_get_environment_console(void) #endif #if defined(IOS) || defined(OSX) || defined(HAVE_BB10) -int rarch_main(int argc, char *argv[]) +#define main_entry rarch_main #else -int main(int argc, char *argv[]) +#define main_entry main #endif + +int main_entry(int argc, char *argv[]) { void* args = NULL; frontend_ctx = (frontend_ctx_driver_t*)frontend_ctx_init_first(); From 3b1e65ba08673abd79e84ceb46cebc9356a23be7 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 14 Aug 2013 14:00:21 +0200 Subject: [PATCH 022/202] Add GL_DEBUG ifdef which forces full GL debugging. --- Makefile | 5 ++ Makefile.win | 5 ++ gfx/context/glx_ctx.c | 61 +++++++++++++--------- gfx/gl.c | 115 ++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 156 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index acf4054dbf..f7eb516e70 100644 --- a/Makefile +++ b/Makefile @@ -337,6 +337,11 @@ ifeq ($(DEBUG), 1) OPTIMIZE_FLAG = -O0 endif +ifeq ($(GL_DEBUG), 1) + CFLAGS += -DGL_DEBUG + CXXFLAGS += -DGL_DEBUG +endif + CFLAGS += -Wall $(OPTIMIZE_FLAG) $(INCLUDE_DIRS) -g -I. ifeq ($(CXX_BUILD), 1) LD = $(CXX) diff --git a/Makefile.win b/Makefile.win index 3003c672b1..71036ccf47 100644 --- a/Makefile.win +++ b/Makefile.win @@ -237,6 +237,11 @@ else LDCXXFLAGS += -s endif +ifeq ($(GL_DEBUG), 1) + CFLAGS += -DGL_DEBUG + CXXFLAGS += -DGL_DEBUG +endif + CFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -I. CXXFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -I. -std=c++0x -D__STDC_CONSTANT_MACROS ifeq ($(CXX_BUILD), 1) diff --git a/gfx/context/glx_ctx.c b/gfx/context/glx_ctx.c index a4d08652e1..cc64267351 100644 --- a/gfx/context/glx_ctx.c +++ b/gfx/context/glx_ctx.c @@ -42,6 +42,7 @@ static GLXFBConfig g_fbc; static unsigned g_major; static unsigned g_minor; static bool g_core; +static bool g_debug; typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); @@ -229,24 +230,22 @@ static bool gfx_ctx_init(void) int major, minor; glXQueryVersion(g_dpy, &major, &minor); - if (g_major * 1000 + g_minor >= 3001) // Core context - { - g_core = true; - // GLX 1.4+ required. - if ((major * 1000 + minor) < 1004) - goto error; - glx_create_context_attribs = (glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); - if (!glx_create_context_attribs) - goto error; - } - else - { - g_core = false; - // GLX 1.3+ required. - if ((major * 1000 + minor) < 1003) - goto error; - } + // GLX 1.3+ minimum required. + if ((major * 1000 + minor) < 1003) + goto error; + + glx_create_context_attribs = (glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); + +#ifdef GL_DEBUG + g_debug = true; +#else + g_debug = g_extern.system.hw_render_callback.debug_context; +#endif + + g_core = (g_major * 1000 + g_minor) >= 3001; // Have to use ContextAttribs + if ((g_core || g_debug) && !glx_create_context_attribs) + goto error; int nelements; fbcs = glXChooseFBConfig(g_dpy, DefaultScreen(g_dpy), @@ -376,16 +375,28 @@ static bool gfx_ctx_set_video_mode( if (!g_ctx) { - if (g_core) + if (g_core || g_debug) { - const int attribs[] = { - GLX_CONTEXT_MAJOR_VERSION_ARB, (int)g_major, - GLX_CONTEXT_MINOR_VERSION_ARB, (int)g_minor, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, g_extern.system.hw_render_callback.debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0, - None, - }; + int attribs[16]; + int *aptr = attribs; + if (g_core) + { + *aptr++ = GLX_CONTEXT_MAJOR_VERSION_ARB; + *aptr++ = g_major; + *aptr++ = GLX_CONTEXT_MINOR_VERSION_ARB; + *aptr++ = g_minor; + *aptr++ = GLX_CONTEXT_PROFILE_MASK_ARB; + *aptr++ = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + } + + if (g_debug) + { + *aptr++ = GLX_CONTEXT_FLAGS_ARB; + *aptr++ = GLX_CONTEXT_DEBUG_BIT_ARB; + } + + *aptr = None; g_ctx = glx_create_context_attribs(g_dpy, g_fbc, NULL, True, attribs); } else diff --git a/gfx/gl.c b/gfx/gl.c index 628f743634..3810cd4373 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -23,6 +23,7 @@ #include "../performance.h" #include "scaler/scaler.h" #include "image.h" +#include "../file.h" #include #include "../libretro.h" @@ -1661,11 +1662,33 @@ static bool resolve_extensions(gl_t *gl) } #endif -#if 0 - // Useful for debugging, but kinda obnoxious. - const char *ext = (const char*)glGetString(GL_EXTENSIONS); - if (ext) - RARCH_LOG("[GL] Supported extensions: %s\n", ext); +#ifdef GL_DEBUG + // Useful for debugging, but kinda obnoxious otherwise. + RARCH_LOG("[GL]: Supported extensions:\n"); + if (gl->core_context) + { +#ifdef GL_NUM_EXTENSIONS + GLint exts = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &exts); + for (GLint i = 0; i < exts; i++) + { + const char *ext = (const char*)glGetStringi(GL_EXTENSIONS, i); + if (ext) + RARCH_LOG("\t%s\n", ext); + } +#endif + } + else + { + const char *ext = (const char*)glGetString(GL_EXTENSIONS); + if (ext) + { + struct string_list *list = string_split(ext, " "); + for (size_t i = 0; i < list->size; i++) + RARCH_LOG("\t%s\n", list->elems[i].data); + string_list_free(list); + } + } #endif return true; @@ -1814,6 +1837,84 @@ static const gfx_ctx_driver_t *gl_get_context(void) return gfx_ctx_init_first(api, major, minor); } +#ifdef GL_DEBUG +#ifdef HAVE_OPENGLES2 +#define DEBUG_CALLBACK_TYPE GL_APIENTRY +#else +#define DEBUG_CALLBACK_TYPE APIENTRY +#endif +static void DEBUG_CALLBACK_TYPE gl_debug_cb(GLenum source, GLenum type, + GLuint id, GLenum severity, GLsizei length, + const GLchar *message, void *userParam) +{ + (void)id; + (void)length; + + gl_t *gl = (gl_t*)userParam; // Useful for debugger. + (void)gl; + + const char *src; + switch (source) + { + case GL_DEBUG_SOURCE_API: src = "API"; break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: src = "Window system"; break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: src = "Shader compiler"; break; + case GL_DEBUG_SOURCE_THIRD_PARTY: src = "3rd party"; break; + case GL_DEBUG_SOURCE_APPLICATION: src = "Application"; break; + case GL_DEBUG_SOURCE_OTHER: src = "Other"; break; + default: src = "Unknown"; break; + } + + const char *typestr; + switch (type) + { + case GL_DEBUG_TYPE_ERROR: typestr = "Error"; break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: typestr = "Deprecated behavior"; break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: typestr = "Undefined behavior"; break; + case GL_DEBUG_TYPE_PORTABILITY: typestr = "Portability"; break; + case GL_DEBUG_TYPE_PERFORMANCE: typestr = "Performance"; break; + case GL_DEBUG_TYPE_MARKER: typestr = "Marker"; break; + case GL_DEBUG_TYPE_PUSH_GROUP: typestr = "Push group"; break; + case GL_DEBUG_TYPE_POP_GROUP: typestr = "Pop group"; break; + case GL_DEBUG_TYPE_OTHER: typestr = "Other"; break; + default: typestr = "Unknown"; break; + } + + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: + RARCH_ERR("[GL debug (High, %s, %s)]: %s\n", src, typestr, message); + break; + case GL_DEBUG_SEVERITY_MEDIUM: + RARCH_WARN("[GL debug (Medium, %s, %s)]: %s\n", src, typestr, message); + break; + case GL_DEBUG_SEVERITY_LOW: + RARCH_LOG("[GL debug (Low, %s, %s)]: %s\n", src, typestr, message); + break; + } +} + +static void gl_begin_debug(gl_t *gl) +{ + if (gl_query_extension(gl, "KHR_debug")) + { + glDebugMessageCallback(gl_debug_cb, gl); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + } +#ifndef HAVE_OPENGLES2 + else if (gl_query_extension(gl, "ARB_debug_output")) + { + glDebugMessageCallbackARB(gl_debug_cb, gl); + glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + } +#endif + else + RARCH_ERR("Neither GL_KHR_debug nor GL_ARB_debug_output are implemented. Cannot start GL debugging.\n"); +} +#endif + static void *gl_init(const video_info_t *video, const input_driver_t **input, void **input_data) { #ifdef _WIN32 @@ -1881,6 +1982,10 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo return NULL; } +#ifdef GL_DEBUG + gl_begin_debug(gl); +#endif + gl->vsync = video->vsync; gl->fullscreen = video->fullscreen; From 4d8e9df03d5d94594e9a987f16ae62138fcc2d6f Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 14 Aug 2013 14:04:26 +0200 Subject: [PATCH 023/202] Add forced debug context support to WGL. --- gfx/context/wgl_ctx.c | 37 +++++++++++++++++++++++++++++-------- libretro.h | 2 +- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/gfx/context/wgl_ctx.c b/gfx/context/wgl_ctx.c index b0d70cdc58..ec12ed8411 100644 --- a/gfx/context/wgl_ctx.c +++ b/gfx/context/wgl_ctx.c @@ -104,7 +104,15 @@ static void create_gl_context(HWND hwnd) return; } - if (g_major * 1000 + g_minor >= 3001) // Create core context +#ifdef GL_DEBUG + bool debug = true; +#else + bool debug = g_extern.system.hw_render_callback.debug_context; +#endif + + bool core_context = (g_major * 1000 + g_minor) >= 3001; + + if (core_context || debug) { #ifndef WGL_CONTEXT_MAJOR_VERSION_ARB #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 @@ -124,13 +132,26 @@ static void create_gl_context(HWND hwnd) #ifndef WGL_CONTEXT_DEBUG_BIT_ARB #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 #endif - const int attribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, (int)g_major, - WGL_CONTEXT_MINOR_VERSION_ARB, (int)g_minor, - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - WGL_CONTEXT_FLAGS_ARB, g_extern.system.hw_render_callback.debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, - 0, - }; + int attribs[16]; + int *aptr = attribs; + + if (core_context) + { + *aptr++ = WGL_CONTEXT_MAJOR_VERSION_ARB; + *aptr++ = g_major; + *aptr++ = WGL_CONTEXT_MINOR_VERSION_ARB; + *aptr++ = g_minor; + *aptr++ = WGL_CONTEXT_PROFILE_MASK_ARB; + *aptr++ = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + } + + if (debug) + { + *aptr++ = WGL_CONTEXT_FLAGS_ARB; + *aptr++ = WGL_CONTEXT_DEBUG_BIT_ARB; + } + + *aptr = 0; if (!pcreate_context) pcreate_context = (wglCreateContextAttribsProc)wglGetProcAddress("wglCreateContextAttribsARB"); diff --git a/libretro.h b/libretro.h index 0af84e6548..72050e93d5 100755 --- a/libretro.h +++ b/libretro.h @@ -575,7 +575,7 @@ struct retro_hw_render_callback // The reset callback might still be called in extreme situations such as if the context is lost beyond recovery. // For optimal stability, set this to false, and allow context to be reset at any time. retro_hw_context_reset_t context_destroy; // A callback to be called before the context is destroyed. Resources can be deinitialized at this step. This can be set to NULL, in which resources will just be destroyed without any notification. - bool debug_context; // Creates a debug context. Only takes effect when using GL core. + bool debug_context; // Creates a debug context. }; // Callback type passed in RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK. Called by the frontend in response to keyboard events. From 39edc5379bf63e05debc3d06c11c79b2d88d7829 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 14 Aug 2013 14:52:55 +0200 Subject: [PATCH 024/202] (Android Phoenix) Cleanups - reuse instance from MainMenuActivity to get application info stuff (Android Phoenix) TV Mode now creates a default config file if one wasn't there already - makes it work from startup --- .../org/retroarch/browser/CoreSelection.java | 177 +---------------- .../retroarch/browser/MainMenuActivity.java | 180 ++++++++++++++++++ .../org/retroarch/browser/RetroTVMode.java | 34 +--- 3 files changed, 187 insertions(+), 204 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/CoreSelection.java b/android/phoenix/src/org/retroarch/browser/CoreSelection.java index f0ee1b3802..5040dae1b0 100644 --- a/android/phoenix/src/org/retroarch/browser/CoreSelection.java +++ b/android/phoenix/src/org/retroarch/browser/CoreSelection.java @@ -5,12 +5,9 @@ import org.retroarch.R; import java.io.*; import android.content.*; -import android.annotation.TargetApi; import android.app.*; import android.media.AudioManager; -import android.media.AudioTrack; import android.os.*; -import android.preference.PreferenceManager; import android.provider.Settings; import android.widget.*; import android.util.Log; @@ -27,39 +24,7 @@ public class CoreSelection extends Activity implements static private String libretro_path; static private final String TAG = "CoreSelection"; - private final double getDisplayRefreshRate() { - // Android is *very* likely to screw this up. - // It is rarely a good value to use, so make sure it's not - // completely wrong. Some phones return refresh rates that are completely bogus - // (like 0.3 Hz, etc), so try to be very conservative here. - final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); - final Display display = wm.getDefaultDisplay(); - double rate = display.getRefreshRate(); - if (rate > 61.0 || rate < 58.0) - rate = 59.95; - return rate; - } - private final double getRefreshRate() { - double rate = 0; - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); - String refresh_rate = prefs.getString("video_refresh_rate", ""); - if (!refresh_rate.isEmpty()) { - try { - rate = Double.parseDouble(refresh_rate); - } catch (NumberFormatException e) { - Log.e(TAG, "Cannot parse: " + refresh_rate + " as a double!"); - rate = getDisplayRefreshRate(); - } - } else { - rate = getDisplayRefreshRate(); - } - - Log.i(TAG, "Using refresh rate: " + rate + " Hz."); - return rate; - } - private String readCPUInfo() { String result = ""; @@ -109,7 +74,7 @@ public class CoreSelection extends Activity implements setTitle("Select Libretro core"); // Populate the list - final String modulePath = getApplicationInfo().nativeLibraryDir; + final String modulePath = MainMenuActivity.getInstance().getApplicationInfo().nativeLibraryDir; final File[] libs = new File(modulePath).listFiles(); for (final File lib : libs) { String libName = lib.getName(); @@ -162,148 +127,12 @@ public class CoreSelection extends Activity implements myIntent = new Intent(this, ROMActivity.class); startActivityForResult(myIntent, ACTIVITY_LOAD_ROM); } - - private String getDefaultConfigPath() { - String internal = System.getenv("INTERNAL_STORAGE"); - String external = System.getenv("EXTERNAL_STORAGE"); - - if (external != null) { - String confPath = external + File.separator + "retroarch.cfg"; - if (new File(confPath).exists()) - return confPath; - } else if (internal != null) { - String confPath = internal + File.separator + "retroarch.cfg"; - if (new File(confPath).exists()) - return confPath; - } else { - String confPath = "/mnt/extsd/retroarch.cfg"; - if (new File(confPath).exists()) - return confPath; - } - - if (internal != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) - return internal + File.separator + "retroarch.cfg"; - else if (external != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) - return external + File.separator + "retroarch.cfg"; - else if ((getApplicationInfo().dataDir) != null) - return (getApplicationInfo().dataDir) + File.separator + "retroarch.cfg"; - else // emergency fallback, all else failed - return "/mnt/sd/retroarch.cfg"; - } - - @TargetApi(17) - private int getLowLatencyOptimalSamplingRate() { - AudioManager manager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE); - return Integer.parseInt(manager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); - } - - private int getOptimalSamplingRate() { - int ret; - if (android.os.Build.VERSION.SDK_INT >= 17) - ret = getLowLatencyOptimalSamplingRate(); - else - ret = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC); - - Log.i(TAG, "Using sampling rate: " + ret + " Hz"); - return ret; - } - - private void updateConfigFile() { - ConfigFile config; - try { - config = new ConfigFile(new File(getDefaultConfigPath())); - } catch (IOException e) { - config = new ConfigFile(); - } - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); - config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true)); - config.setInt("audio_out_rate", getOptimalSamplingRate()); - config.setInt("audio_latency", prefs.getBoolean("audio_high_latency", false) ? 160 : 64); - config.setBoolean("audio_enable", prefs.getBoolean("audio_enable", true)); - config.setBoolean("video_smooth", prefs.getBoolean("video_smooth", true)); - config.setBoolean("video_allow_rotate", prefs.getBoolean("video_allow_rotate", true)); - config.setBoolean("savestate_auto_load", prefs.getBoolean("savestate_auto_load", true)); - config.setBoolean("savestate_auto_save", prefs.getBoolean("savestate_auto_save", false)); - config.setBoolean("rewind_enable", prefs.getBoolean("rewind_enable", false)); - config.setBoolean("video_vsync", prefs.getBoolean("video_vsync", true)); - config.setBoolean("input_autodetect_enable", prefs.getBoolean("input_autodetect_enable", true)); - config.setBoolean("input_debug_enable", prefs.getBoolean("input_debug_enable", false)); - config.setInt("input_back_behavior", Integer.valueOf(prefs.getString("input_back_behavior", "0"))); - config.setInt("input_autodetect_icade_profile_pad1", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad1", "0"))); - config.setInt("input_autodetect_icade_profile_pad2", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad2", "0"))); - config.setInt("input_autodetect_icade_profile_pad3", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad3", "0"))); - config.setInt("input_autodetect_icade_profile_pad4", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad4", "0"))); - - config.setDouble("video_refresh_rate", getRefreshRate()); - config.setBoolean("video_threaded", prefs.getBoolean("video_threaded", true)); - - String aspect = prefs.getString("video_aspect_ratio", "auto"); - if (aspect.equals("full")) { - config.setBoolean("video_force_aspect", false); - } else if (aspect.equals("auto")) { - config.setBoolean("video_force_aspect", true); - config.setBoolean("video_force_aspect_auto", true); - config.setDouble("video_aspect_ratio", -1.0); - } else if (aspect.equals("square")) { - config.setBoolean("video_force_aspect", true); - config.setBoolean("video_force_aspect_auto", false); - config.setDouble("video_aspect_ratio", -1.0); - } else { - double aspect_ratio = Double.parseDouble(aspect); - config.setBoolean("video_force_aspect", true); - config.setDouble("video_aspect_ratio", aspect_ratio); - } - - config.setBoolean("video_scale_integer", prefs.getBoolean("video_scale_integer", false)); - - String shaderPath = prefs.getString("video_shader", ""); - config.setString("video_shader", shaderPath); - config.setBoolean("video_shader_enable", - prefs.getBoolean("video_shader_enable", false) - && new File(shaderPath).exists()); - - boolean useOverlay = prefs.getBoolean("input_overlay_enable", true); - if (useOverlay) { - String overlayPath = prefs.getString("input_overlay", (getApplicationInfo().dataDir) + "/overlays/snes-landscape.cfg"); - config.setString("input_overlay", overlayPath); - config.setDouble("input_overlay_opacity", prefs.getFloat("input_overlay_opacity", 1.0f)); - } else { - config.setString("input_overlay", ""); - } - - config.setString("savefile_directory", prefs.getBoolean("savefile_directory_enable", false) ? - prefs.getString("savefile_directory", "") : ""); - config.setString("savestate_directory", prefs.getBoolean("savestate_directory_enable", false) ? - prefs.getString("savestate_directory", "") : ""); - config.setString("system_directory", prefs.getBoolean("system_directory_enable", false) ? - prefs.getString("system_directory", "") : ""); - - config.setBoolean("video_font_enable", prefs.getBoolean("video_font_enable", true)); - - for (int i = 1; i <= 4; i++) - { - final String btns[] = {"up", "down", "left", "right", "a", "b", "x", "y", "start", "select", "l", "r", "l2", "r2", "l3", "r3" }; - for (String b : btns) - { - String p = "input_player" + String.valueOf(i) + "_" + b + "_btn"; - config.setInt(p, prefs.getInt(p, 0)); - } - } - - String confPath = getDefaultConfigPath(); - try { - config.write(new File(confPath)); - } catch (IOException e) { - Log.e(TAG, "Failed to save config file to: " + confPath); - } - } protected void onActivityResult(int requestCode, int resultCode, Intent data) { Intent myIntent; String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); - updateConfigFile(); + MainMenuActivity.updateConfigFile(); switch (requestCode) { case ACTIVITY_LOAD_ROM: @@ -314,7 +143,7 @@ public class CoreSelection extends Activity implements myIntent = new Intent(this, RetroActivity.class); myIntent.putExtra("ROM", data.getStringExtra("PATH")); myIntent.putExtra("LIBRETRO", libretro_path); - myIntent.putExtra("CONFIGFILE", getDefaultConfigPath()); + myIntent.putExtra("CONFIGFILE", MainMenuActivity.getDefaultConfigPath()); myIntent.putExtra("IME", current_ime); startActivity(myIntent); finish(); diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 1e8f81284f..759d093c4e 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -11,24 +11,31 @@ import java.io.InputStream; import org.retroarch.R; +import android.annotation.TargetApi; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetManager; import android.media.AudioManager; +import android.media.AudioTrack; import android.os.Bundle; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; import android.util.Log; +import android.view.Display; +import android.view.WindowManager; import android.widget.Toast; public class MainMenuActivity extends PreferenceActivity { + private static MainMenuActivity instance = null; static private final String TAG = "MainMenu"; @SuppressWarnings("deprecation") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + instance = this; addPreferencesFromResource(R.xml.prefs); PreferenceManager.setDefaultValues(this, R.xml.prefs, false); this.setVolumeControlStream(AudioManager.STREAM_MUSIC); @@ -66,6 +73,179 @@ public class MainMenuActivity extends PreferenceActivity { } } + public static MainMenuActivity getInstance() { + return instance; + } + + private final double getDisplayRefreshRate() { + // Android is *very* likely to screw this up. + // It is rarely a good value to use, so make sure it's not + // completely wrong. Some phones return refresh rates that are completely bogus + // (like 0.3 Hz, etc), so try to be very conservative here. + final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); + final Display display = wm.getDefaultDisplay(); + double rate = display.getRefreshRate(); + if (rate > 61.0 || rate < 58.0) + rate = 59.95; + return rate; + } + + public static final double getRefreshRate() { + double rate = 0; + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(MainMenuActivity.getInstance().getBaseContext()); + String refresh_rate = prefs.getString("video_refresh_rate", ""); + if (!refresh_rate.isEmpty()) { + try { + rate = Double.parseDouble(refresh_rate); + } catch (NumberFormatException e) { + Log.e(TAG, "Cannot parse: " + refresh_rate + " as a double!"); + rate = MainMenuActivity.getInstance().getDisplayRefreshRate(); + } + } else { + rate = MainMenuActivity.getInstance().getDisplayRefreshRate(); + } + + Log.i(TAG, "Using refresh rate: " + rate + " Hz."); + return rate; + } + + @TargetApi(17) + public static int getLowLatencyOptimalSamplingRate() { + AudioManager manager = (AudioManager)MainMenuActivity.getInstance().getApplicationContext().getSystemService(Context.AUDIO_SERVICE); + return Integer.parseInt(manager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); + } + + public static int getOptimalSamplingRate() { + int ret; + if (android.os.Build.VERSION.SDK_INT >= 17) + ret = getLowLatencyOptimalSamplingRate(); + else + ret = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC); + + Log.i(TAG, "Using sampling rate: " + ret + " Hz"); + return ret; + } + + public static String getDefaultConfigPath() { + String internal = System.getenv("INTERNAL_STORAGE"); + String external = System.getenv("EXTERNAL_STORAGE"); + + if (external != null) { + String confPath = external + File.separator + "retroarch.cfg"; + if (new File(confPath).exists()) + return confPath; + } else if (internal != null) { + String confPath = internal + File.separator + "retroarch.cfg"; + if (new File(confPath).exists()) + return confPath; + } else { + String confPath = "/mnt/extsd/retroarch.cfg"; + if (new File(confPath).exists()) + return confPath; + } + + if (internal != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) + return internal + File.separator + "retroarch.cfg"; + else if (external != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) + return external + File.separator + "retroarch.cfg"; + else if ((MainMenuActivity.getInstance().getApplicationInfo().dataDir) != null) + return (MainMenuActivity.getInstance().getApplicationInfo().dataDir) + File.separator + "retroarch.cfg"; + else // emergency fallback, all else failed + return "/mnt/sd/retroarch.cfg"; + } + + public static void updateConfigFile() { + ConfigFile config; + try { + config = new ConfigFile(new File(getDefaultConfigPath())); + } catch (IOException e) { + config = new ConfigFile(); + } + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainMenuActivity.getInstance().getBaseContext()); + config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true)); + config.setInt("audio_out_rate", MainMenuActivity.getOptimalSamplingRate()); + config.setInt("audio_latency", prefs.getBoolean("audio_high_latency", false) ? 160 : 64); + config.setBoolean("audio_enable", prefs.getBoolean("audio_enable", true)); + config.setBoolean("video_smooth", prefs.getBoolean("video_smooth", true)); + config.setBoolean("video_allow_rotate", prefs.getBoolean("video_allow_rotate", true)); + config.setBoolean("savestate_auto_load", prefs.getBoolean("savestate_auto_load", true)); + config.setBoolean("savestate_auto_save", prefs.getBoolean("savestate_auto_save", false)); + config.setBoolean("rewind_enable", prefs.getBoolean("rewind_enable", false)); + config.setBoolean("video_vsync", prefs.getBoolean("video_vsync", true)); + config.setBoolean("input_autodetect_enable", prefs.getBoolean("input_autodetect_enable", true)); + config.setBoolean("input_debug_enable", prefs.getBoolean("input_debug_enable", false)); + config.setInt("input_back_behavior", Integer.valueOf(prefs.getString("input_back_behavior", "0"))); + config.setInt("input_autodetect_icade_profile_pad1", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad1", "0"))); + config.setInt("input_autodetect_icade_profile_pad2", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad2", "0"))); + config.setInt("input_autodetect_icade_profile_pad3", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad3", "0"))); + config.setInt("input_autodetect_icade_profile_pad4", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad4", "0"))); + + config.setDouble("video_refresh_rate", MainMenuActivity.getRefreshRate()); + config.setBoolean("video_threaded", prefs.getBoolean("video_threaded", true)); + + String aspect = prefs.getString("video_aspect_ratio", "auto"); + if (aspect.equals("full")) { + config.setBoolean("video_force_aspect", false); + } else if (aspect.equals("auto")) { + config.setBoolean("video_force_aspect", true); + config.setBoolean("video_force_aspect_auto", true); + config.setDouble("video_aspect_ratio", -1.0); + } else if (aspect.equals("square")) { + config.setBoolean("video_force_aspect", true); + config.setBoolean("video_force_aspect_auto", false); + config.setDouble("video_aspect_ratio", -1.0); + } else { + double aspect_ratio = Double.parseDouble(aspect); + config.setBoolean("video_force_aspect", true); + config.setDouble("video_aspect_ratio", aspect_ratio); + } + + config.setBoolean("video_scale_integer", prefs.getBoolean("video_scale_integer", false)); + + String shaderPath = prefs.getString("video_shader", ""); + config.setString("video_shader", shaderPath); + config.setBoolean("video_shader_enable", + prefs.getBoolean("video_shader_enable", false) + && new File(shaderPath).exists()); + + boolean useOverlay = prefs.getBoolean("input_overlay_enable", true); + if (useOverlay) { + String overlayPath = prefs.getString("input_overlay", (MainMenuActivity.getInstance().getApplicationInfo().dataDir) + "/overlays/snes-landscape.cfg"); + config.setString("input_overlay", overlayPath); + config.setDouble("input_overlay_opacity", prefs.getFloat("input_overlay_opacity", 1.0f)); + } else { + config.setString("input_overlay", ""); + } + + config.setString("savefile_directory", prefs.getBoolean("savefile_directory_enable", false) ? + prefs.getString("savefile_directory", "") : ""); + config.setString("savestate_directory", prefs.getBoolean("savestate_directory_enable", false) ? + prefs.getString("savestate_directory", "") : ""); + config.setString("system_directory", prefs.getBoolean("system_directory_enable", false) ? + prefs.getString("system_directory", "") : ""); + + config.setBoolean("video_font_enable", prefs.getBoolean("video_font_enable", true)); + + for (int i = 1; i <= 4; i++) + { + final String btns[] = {"up", "down", "left", "right", "a", "b", "x", "y", "start", "select", "l", "r", "l2", "r2", "l3", "r3" }; + for (String b : btns) + { + String p = "input_player" + String.valueOf(i) + "_" + b + "_btn"; + config.setInt(p, prefs.getInt(p, 0)); + } + } + + String confPath = getDefaultConfigPath(); + try { + config.write(new File(confPath)); + } catch (IOException e) { + Log.e(TAG, "Failed to save config file to: " + confPath); + } + } + private byte[] loadAsset(String asset) throws IOException { String path = asset; InputStream stream = getAssets().open(path); diff --git a/android/phoenix/src/org/retroarch/browser/RetroTVMode.java b/android/phoenix/src/org/retroarch/browser/RetroTVMode.java index e69445b5e9..23ffcfe30e 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroTVMode.java +++ b/android/phoenix/src/org/retroarch/browser/RetroTVMode.java @@ -1,47 +1,21 @@ package org.retroarch.browser; -import java.io.File; - import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.provider.Settings; public class RetroTVMode extends Activity { - private String getDefaultConfigPath() { - String internal = System.getenv("INTERNAL_STORAGE"); - String external = System.getenv("EXTERNAL_STORAGE"); - - if (external != null) { - String confPath = external + File.separator + "retroarch.cfg"; - if (new File(confPath).exists()) - return confPath; - } else if (internal != null) { - String confPath = internal + File.separator + "retroarch.cfg"; - if (new File(confPath).exists()) - return confPath; - } else { - String confPath = "/mnt/extsd/retroarch.cfg"; - if (new File(confPath).exists()) - return confPath; - } - - if (internal != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) - return internal + File.separator + "retroarch.cfg"; - else if (external != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) - return external + File.separator + "retroarch.cfg"; - else if ((getApplicationInfo().dataDir) != null) - return (getApplicationInfo().dataDir) + File.separator + "retroarch.cfg"; - else // emergency fallback, all else failed - return "/mnt/sd/retroarch.cfg"; - } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + MainMenuActivity.updateConfigFile(); + Intent myIntent = new Intent(this, RetroActivity.class); String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); - myIntent.putExtra("CONFIGFILE", getDefaultConfigPath()); + myIntent.putExtra("CONFIGFILE", MainMenuActivity.getDefaultConfigPath()); myIntent.putExtra("IME", current_ime); startActivity(myIntent); finish(); From 7236e51af06311057fdf7f2e14d196b0e213b5ca Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 14 Aug 2013 14:57:39 +0200 Subject: [PATCH 025/202] Clear out GL error on driver init for robustness. In case we used cached GL context, we'd error out if a single GL error has been generated. --- gfx/gl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gfx/gl.c b/gfx/gl.c index 3810cd4373..9ed67c79b6 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1965,6 +1965,8 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo return NULL; } + glGetError(); // Clear out potential error flags incase we use cached context. + const char *vendor = (const char*)glGetString(GL_VENDOR); const char *renderer = (const char*)glGetString(GL_RENDERER); RARCH_LOG("[GL]: Vendor: %s, Renderer: %s.\n", vendor, renderer); From 4f70bdeab5c6805c0334bb124a8c75e7a438f9a0 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 14 Aug 2013 10:07:36 -0400 Subject: [PATCH 026/202] (Apple) Split platform specific code out of main.m --- apple/OSX/platform.h | 42 ++ apple/OSX/platform.m | 264 +++++++ apple/RetroArch/RetroArch_Apple.h | 76 +-- apple/RetroArch/main.m | 643 +----------------- apple/RetroArch_OSX.xcodeproj/project.pbxproj | 6 + apple/RetroArch_iOS.xcodeproj/project.pbxproj | 4 + apple/iOS/platform.h | 42 ++ apple/iOS/platform.m | 346 ++++++++++ apple/iOS/settings.m | 2 +- 9 files changed, 767 insertions(+), 658 deletions(-) create mode 100644 apple/OSX/platform.h create mode 100644 apple/OSX/platform.m create mode 100644 apple/iOS/platform.h create mode 100644 apple/iOS/platform.m diff --git a/apple/OSX/platform.h b/apple/OSX/platform.h new file mode 100644 index 0000000000..f858ade962 --- /dev/null +++ b/apple/OSX/platform.h @@ -0,0 +1,42 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * 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_OSX_PLATFORM_H +#define __RARCH_OSX_PLATFORM_H + +#import + +@interface RAGameView : NSOpenGLView + ++ (RAGameView*)get; +- (void)display; + +@end + +@interface RetroArch_OSX : NSObject +{ +@public + NSWindow IBOutlet *window; +} + ++ (RetroArch_OSX*)get; + +- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; +- (void)unloadingCore:(RAModuleInfo*)core; + +@end + +#endif diff --git a/apple/OSX/platform.m b/apple/OSX/platform.m new file mode 100644 index 0000000000..b15d053e14 --- /dev/null +++ b/apple/OSX/platform.m @@ -0,0 +1,264 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * 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 + +#import "RetroArch_Apple.h" +#include "rarch_wrapper.h" +#include "../RetroArch/apple_input.h" + +// If USE_XATTR is defined any loaded file will get a com.RetroArch.Core extended attribute +// specifying which core was used to load. +//#define USE_XATTR + +#if defined(USE_XATTR) +#include "sys/xattr.h" +#endif + +#include "file.h" + +@interface RApplication : NSApplication +@end + +@implementation RApplication + +- (void)sendEvent:(NSEvent *)event +{ + [super sendEvent:event]; + + if (event.type == GSEVENT_TYPE_KEYDOWN || event.type == GSEVENT_TYPE_KEYUP) + apple_input_handle_key_event(event.keyCode, event.type == GSEVENT_TYPE_KEYDOWN); +} + +@end + +@implementation RetroArch_OSX +{ + NSWindow IBOutlet* _coreSelectSheet; + + bool _isTerminating; + bool _loaded; + bool _wantReload; + NSString* _file; + RAModuleInfo* _core; +} + ++ (RetroArch_OSX*)get +{ + return (RetroArch_OSX*)[[NSApplication sharedApplication] delegate]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + apple_platform = self; + _loaded = true; + + [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + + RAGameView.get.frame = [window.contentView bounds]; + [window.contentView setAutoresizesSubviews:YES]; + [window.contentView addSubview:RAGameView.get]; + [window makeFirstResponder:RAGameView.get]; + + // Create core select list + NSComboBox* cb = (NSComboBox*)[_coreSelectSheet.contentView viewWithTag:1]; + + for (RAModuleInfo* i in RAModuleInfo.getModules) + [cb addItemWithObjectValue:i]; + + if (cb.numberOfItems) + [cb selectItemAtIndex:0]; + else + apple_display_alert(@"No libretro cores were found.", @"RetroArch"); + + // Run RGUI if needed + if (!_wantReload) + apple_run_core(nil, 0); + else + [self chooseCore]; + + _wantReload = false; + + extern void osx_pad_init(); + osx_pad_init(); +} + +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication +{ + return YES; +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender +{ + _isTerminating = true; + + if (apple_is_running) + apple_frontend_post_event(apple_event_basic_command, (void*)QUIT); + + return apple_is_running ? NSTerminateCancel : NSTerminateNow; +} + + +- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames +{ + if (filenames.count == 1 && filenames[0]) + { + _file = filenames[0]; + + if (!_loaded) + _wantReload = true; + else + [self chooseCore]; + + [sender replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; + } + else + { + apple_display_alert(@"Cannot open multiple files", @"RetroArch"); + [sender replyToOpenOrPrint:NSApplicationDelegateReplyFailure]; + } +} + +- (void)openDocument:(id)sender +{ + NSOpenPanel* panel = [NSOpenPanel openPanel]; + [panel beginSheetModalForWindow:window completionHandler:^(NSInteger result) + { + [NSApplication.sharedApplication stopModal]; + + if (result == NSOKButton && panel.URL) + { + _file = panel.URL.path; + [self performSelector:@selector(chooseCore) withObject:nil afterDelay:.5f]; + } + }]; + [NSApplication.sharedApplication runModalForWindow:panel]; +} + +// This utility function will queue the _core and _file instance values for running. +// If the emulator thread is already running it will tell it to quit. +- (void)runCore +{ + _wantReload = apple_is_running; + + if (!apple_is_running) + apple_run_core(_core, _file.UTF8String); + else + apple_frontend_post_event(apple_event_basic_command, (void*)QUIT); +} + +- (void)chooseCore +{ +#ifdef USE_XATTR + char stored_name[PATH_MAX]; + if (getxattr(_file.UTF8String, "com.RetroArch.Core", stored_name, PATH_MAX, 0, 0) > 0) + { + for (RAModuleInfo* i in RAModuleInfo.getModules) + { + const char* core_name = i.path.lastPathComponent.UTF8String; + if (strcmp(core_name, stored_name) == 0) + { + _core = i; + [self runCore]; + return; + } + } + } +#endif + + [NSApplication.sharedApplication beginSheet:_coreSelectSheet modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil]; + [NSApplication.sharedApplication runModalForWindow:_coreSelectSheet]; +} + +- (IBAction)coreWasChosen:(id)sender +{ + [NSApplication.sharedApplication stopModal]; + [NSApplication.sharedApplication endSheet:_coreSelectSheet returnCode:0]; + [_coreSelectSheet orderOut:self]; + + if (_isTerminating) + return; + + NSComboBox* cb = (NSComboBox*)[_coreSelectSheet.contentView viewWithTag:1]; + _core = (RAModuleInfo*)cb.objectValueOfSelectedItem; + + [self runCore]; +} + +#pragma mark RetroArch_Platform +- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file +{ + if (file) + { + [NSDocumentController.sharedDocumentController noteNewRecentDocumentURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:file]]]; + +#ifdef USE_XATTR + const char* core_name = core.path.lastPathComponent.UTF8String; + setxattr(file, "com.RetroArch.Core", core_name, strlen(core_name) + 1, 0, 0); +#endif + } +} + +- (void)unloadingCore:(RAModuleInfo*)core +{ + if (_isTerminating) + [NSApplication.sharedApplication terminate:nil]; + + if (_wantReload) + apple_run_core(_core, _file.UTF8String); + else if(apple_use_tv_mode) + apple_run_core(nil, 0); + else + [NSApplication.sharedApplication terminate:nil]; + + _wantReload = false; +} + +- (NSString*)retroarchConfigPath +{ + NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); + return [paths[0] stringByAppendingPathComponent:@"RetroArch/retroarch.cfg"]; +} + +- (NSString*)corePath +{ + return [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"Contents/Resources/modules"]; +} + +#pragma mark Menus +- (IBAction)showPreferences:(id)sender +{ + [[[NSWindowController alloc] initWithWindowNibName:@"Settings"] window]; +} + +- (IBAction)basicEvent:(id)sender +{ + if (apple_is_running) + apple_frontend_post_event(&apple_event_basic_command, (void*)((NSMenuItem*)sender).tag); +} + +- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ + [NSApplication.sharedApplication stopModal]; +} + +@end + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **) argv); +} + diff --git a/apple/RetroArch/RetroArch_Apple.h b/apple/RetroArch/RetroArch_Apple.h index 39096304d5..a714bb70c1 100644 --- a/apple/RetroArch/RetroArch_Apple.h +++ b/apple/RetroArch/RetroArch_Apple.h @@ -21,7 +21,8 @@ #import #import "RAModuleInfo.h" -void apple_run_core(RAModuleInfo* core, const char* file); +#define GSEVENT_TYPE_KEYDOWN 10 +#define GSEVENT_TYPE_KEYUP 11 @protocol RetroArch_Platform - (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; @@ -30,59 +31,29 @@ void apple_run_core(RAModuleInfo* core, const char* file); - (NSString*)corePath; @end +#ifdef IOS +#import "../iOS/platform.h" +#elif defined(OSX) +#import "../OSX/platform.h" +#endif + +extern bool apple_is_paused; +extern bool apple_is_running; +extern bool apple_use_tv_mode; +extern RAModuleInfo* apple_core; + extern id apple_platform; -#ifdef IOS +// main.m +enum basic_event_t { RESET = 1, LOAD_STATE = 2, SAVE_STATE = 3, QUIT = 4 }; +extern void apple_event_basic_command(void* userdata); +extern void apple_event_set_state_slot(void* userdata); +extern void apple_event_show_rgui(void* userdata); -// RAGameView.m -@interface RAGameView : UIViewController -+ (RAGameView*)get; -- (void)openPauseMenu; -- (void)closePauseMenu; -@end - -@interface RetroArch_iOS : UINavigationController - -+ (RetroArch_iOS*)get; - -- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; -- (void)unloadingCore:(RAModuleInfo*)core; -- (NSString*)retroarchConfigPath; - -- (void)refreshConfig; -- (void)refreshSystemConfig; - -@property (strong, nonatomic) NSString* documentsDirectory; // e.g. /var/mobile/Documents -@property (strong, nonatomic) NSString* systemDirectory; // e.g. /var/mobile/Documents/.RetroArch -@property (strong, nonatomic) NSString* systemConfigPath; // e.g. /var/mobile/Documents/.RetroArch/frontend.cfg - -@end - -#elif defined(OSX) - -#import - -@interface RAGameView : NSOpenGLView - -+ (RAGameView*)get; -- (void)display; - -@end - -@interface RetroArch_OSX : NSObject -{ -@public - NSWindow IBOutlet *window; -} - -+ (RetroArch_OSX*)get; - -- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; -- (void)unloadingCore:(RAModuleInfo*)core; - -@end - -#endif +extern void apple_refresh_config(); +extern void apple_enter_stasis(); +extern void apple_exit_stasis(); +extern void apple_run_core(RAModuleInfo* core, const char* file); // utility.m extern void apple_display_alert(NSString* message, NSString* title); @@ -90,4 +61,7 @@ extern void objc_clear_config_hack(); extern bool path_make_and_check_directory(const char* path, mode_t mode, int amode); extern NSString* objc_get_value_from_config(config_file_t* config, NSString* name, NSString* defaultValue); +// frontend/platform/platform_apple.c +extern void apple_frontend_post_event(void (*fn)(void*), void* userdata); + #endif diff --git a/apple/RetroArch/main.m b/apple/RetroArch/main.m index 3e00e3c919..7d9f392040 100644 --- a/apple/RetroArch/main.m +++ b/apple/RetroArch/main.m @@ -21,36 +21,14 @@ #include "apple_input.h" -// If USE_XATTR is defined any loaded file will get a com.RetroArch.Core extended attribute -// specifying which core was used to load. -//#define USE_XATTR - -#ifdef IOS -#import "views.h" -#include "../iOS/input/BTStack/btpad.h" -#include "../iOS/input/BTStack/btdynamic.h" -#include "../iOS/input/BTStack/btpad.h" -#elif defined(USE_XATTR) -#include "sys/xattr.h" -#endif - #include "file.h" -#define GSEVENT_TYPE_KEYDOWN 10 -#define GSEVENT_TYPE_KEYUP 11 - //#define HAVE_DEBUG_FILELOG static bool use_tv_mode; id apple_platform; -// From frontend/frontend_ios.c -extern void apple_frontend_post_event(void (*fn)(void*), void* userdata); - - -// These are based on the tag property of the button used to trigger the event -enum basic_event_t { RESET = 1, LOAD_STATE = 2, SAVE_STATE = 3, QUIT = 4 }; -static void event_basic_command(void* userdata) +void apple_event_basic_command(void* userdata) { switch ((enum basic_event_t)userdata) { @@ -61,12 +39,12 @@ static void event_basic_command(void* userdata) } } -static void event_set_state_slot(void* userdata) +void apple_event_set_state_slot(void* userdata) { g_extern.state_slot = (uint32_t)userdata; } -static void event_show_rgui(void* userdata) +void apple_event_show_rgui(void* userdata) { const bool in_menu = g_extern.lifecycle_mode_state & (1 << MODE_MENU); g_extern.lifecycle_mode_state &= ~(1ULL << (in_menu ? MODE_MENU : MODE_GAME)); @@ -82,7 +60,15 @@ static void event_reload_config(void* userdata) init_drivers(); } -static pthread_mutex_t stasis_mutex = PTHREAD_MUTEX_INITIALIZER; +void apple_refresh_config() +{ + if (apple_is_running) + apple_frontend_post_event(&event_reload_config, 0); + else + objc_clear_config_hack(); +} + +pthread_mutex_t stasis_mutex = PTHREAD_MUTEX_INITIALIZER; static void event_stasis(void* userdata) { @@ -94,18 +80,34 @@ static void event_stasis(void* userdata) init_drivers(); } +void apple_enter_stasis() +{ + if (apple_is_running) + { + pthread_mutex_lock(&stasis_mutex); + apple_frontend_post_event(event_stasis, 0); + } +} + +void apple_exit_stasis() +{ + if (apple_is_running) + pthread_mutex_unlock(&stasis_mutex); +} + #pragma mark EMULATION static pthread_t apple_retro_thread; -static bool apple_is_paused; -static bool apple_is_running; -static RAModuleInfo* apple_core; +bool apple_is_paused; +bool apple_is_running; +bool apple_use_tv_mode; +RAModuleInfo* apple_core; void* rarch_main_spring(void* args) { char** argv = args; uint32_t argc = 0; - while (argv && argv[argc ++]); + while (argv && argv[argc]) argc++; if (rarch_main(argc, argv)) { @@ -136,11 +138,15 @@ void apple_run_core(RAModuleInfo* core, const char* file) if (file && core) { argv[3] = "-L"; + argv[4] = core_path; strlcpy(core_path, apple_core.path.UTF8String, sizeof(core_path)); strlcpy(file_path, file, sizeof(file_path)); } else - argv[3] = 0; + { + argv[3] = "--menu"; + argv[4] = 0; + } if (pthread_create(&apple_retro_thread, 0, rarch_main_spring, argv)) { @@ -169,578 +175,3 @@ void apple_rarch_exited(void* result) if (use_tv_mode) apple_run_core(nil, 0); } - -// -// IOS -// -#pragma mark IOS -#ifdef IOS -// Input helpers: This is kept here because it needs objective-c -static void handle_touch_event(NSArray* touches) -{ - const int numTouches = [touches count]; - const float scale = [[UIScreen mainScreen] scale]; - - g_current_input_data.touch_count = 0; - - for(int i = 0; i != numTouches && g_current_input_data.touch_count < MAX_TOUCHES; i ++) - { - UITouch* touch = [touches objectAtIndex:i]; - const CGPoint coord = [touch locationInView:touch.view]; - - if (touch.phase != UITouchPhaseEnded && touch.phase != UITouchPhaseCancelled) - { - g_current_input_data.touches[g_current_input_data.touch_count ].screen_x = coord.x * scale; - g_current_input_data.touches[g_current_input_data.touch_count ++].screen_y = coord.y * scale; - } - } -} - -@interface RApplication : UIApplication -@end - -@implementation RApplication - -- (void)sendEvent:(UIEvent *)event -{ - [super sendEvent:event]; - - if ([[event allTouches] count]) - handle_touch_event(event.allTouches.allObjects); - else if ([event respondsToSelector:@selector(_gsEvent)]) - { - // Stolen from: http://nacho4d-nacho4d.blogspot.com/2012/01/catching-keyboard-events-in-ios.html - uint8_t* eventMem = (uint8_t*)(void*)CFBridgingRetain([event performSelector:@selector(_gsEvent)]); - int eventType = eventMem ? *(int*)&eventMem[8] : 0; - - if (eventType == GSEVENT_TYPE_KEYDOWN || eventType == GSEVENT_TYPE_KEYUP) - apple_input_handle_key_event(*(uint16_t*)&eventMem[0x3C], eventType == GSEVENT_TYPE_KEYDOWN); - - CFBridgingRelease(eventMem); - } -} - -int main(int argc, char *argv[]) -{ - @autoreleasepool { -#if defined(HAVE_DEBUG_FILELOG) && (TARGET_IPHONE_SIMULATOR == 0) - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString *documentsDirectory = [paths objectAtIndex:0]; - NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console_stdout.log"]; - freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "a", stdout); - freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "a", stderr); -#endif - return UIApplicationMain(argc, argv, NSStringFromClass([RApplication class]), NSStringFromClass([RetroArch_iOS class])); - } -} - -@end - -@implementation RetroArch_iOS -{ - UIWindow* _window; - - bool _isGameTop, _isRomList; - uint32_t _settingMenusInBackStack; - uint32_t _enabledOrientations; - - RAModuleInfo* _module; -} - -+ (RetroArch_iOS*)get -{ - return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate]; -} - -// UIApplicationDelegate -- (void)applicationDidFinishLaunching:(UIApplication *)application -{ - apple_platform = self; - self.delegate = self; - - // Setup window - _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - _window.rootViewController = self; - [_window makeKeyAndVisible]; - - // Build system paths and test permissions - self.documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; - self.systemDirectory = [self.documentsDirectory stringByAppendingPathComponent:@".RetroArch"]; - self.systemConfigPath = [self.systemDirectory stringByAppendingPathComponent:@"frontend.cfg"]; - - if (!path_make_and_check_directory(self.documentsDirectory.UTF8String, 0755, R_OK | W_OK | X_OK)) - apple_display_alert([NSString stringWithFormat:@"Failed to create or access base directory: %@", self.documentsDirectory], 0); - else if (!path_make_and_check_directory(self.systemDirectory.UTF8String, 0755, R_OK | W_OK | X_OK)) - apple_display_alert([NSString stringWithFormat:@"Failed to create or access system directory: %@", self.systemDirectory], 0); - else - { - [self pushViewController:[RADirectoryList directoryListAtBrowseRoot] animated:YES]; - [self refreshSystemConfig]; - - if (use_tv_mode) - apple_run_core(nil, 0); - } - - // Warn if there are no cores present - if ([RAModuleInfo getModules].count == 0) - apple_display_alert(@"No libretro cores were found. You will not be able to play any games.", 0); -} - -- (void)applicationDidBecomeActive:(UIApplication *)application -{ - if (apple_is_running) - pthread_mutex_unlock(&stasis_mutex); -} - -- (void)applicationWillResignActive:(UIApplication *)application -{ - if (apple_is_running) - { - pthread_mutex_lock(&stasis_mutex); - apple_frontend_post_event(event_stasis, 0); - } -} - -// UINavigationControllerDelegate -- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated -{ - _isGameTop = [viewController isKindOfClass:[RAGameView class]]; - _isRomList = [viewController isKindOfClass:[RADirectoryList class]]; - - [[UIApplication sharedApplication] setStatusBarHidden:_isGameTop withAnimation:UIStatusBarAnimationNone]; - [[UIApplication sharedApplication] setIdleTimerDisabled:_isGameTop]; - - self.navigationBarHidden = _isGameTop; - [self setToolbarHidden:!_isRomList animated:YES]; - self.topViewController.navigationItem.rightBarButtonItem = [self createSettingsButton]; -} - -// UINavigationController: Never animate when pushing onto, or popping, an RAGameView -- (void)pushViewController:(UIViewController*)theView animated:(BOOL)animated -{ - if ([theView respondsToSelector:@selector(isSettingsView)] && [(id)theView isSettingsView]) - _settingMenusInBackStack ++; - - [super pushViewController:theView animated:animated && !_isGameTop]; -} - -- (UIViewController*)popViewControllerAnimated:(BOOL)animated -{ - if ([self.topViewController respondsToSelector:@selector(isSettingsView)] && [(id)self.topViewController isSettingsView]) - _settingMenusInBackStack --; - - return [super popViewControllerAnimated:animated && !_isGameTop]; -} - -// NOTE: This version only runs on iOS6 -- (NSUInteger)supportedInterfaceOrientations -{ - return _isGameTop ? _enabledOrientations - : UIInterfaceOrientationMaskAll; -} - -// NOTE: This version runs on iOS2-iOS5, but not iOS6 -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - if (_isGameTop) - switch (interfaceOrientation) - { - case UIInterfaceOrientationPortrait: - return (_enabledOrientations & UIInterfaceOrientationMaskPortrait); - case UIInterfaceOrientationPortraitUpsideDown: - return (_enabledOrientations & UIInterfaceOrientationMaskPortraitUpsideDown); - case UIInterfaceOrientationLandscapeLeft: - return (_enabledOrientations & UIInterfaceOrientationMaskLandscapeLeft); - case UIInterfaceOrientationLandscapeRight: - return (_enabledOrientations & UIInterfaceOrientationMaskLandscapeRight); - } - - return YES; -} - - -#pragma mark RetroArch_Platform -- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file -{ - [self pushViewController:RAGameView.get animated:NO]; - [RASettingsList refreshModuleConfig:core]; - - btpad_set_inquiry_state(false); - - [self refreshSystemConfig]; -} - -- (void)unloadingCore:(RAModuleInfo*)core -{ - [self popToViewController:[RAGameView get] animated:NO]; - [self popViewControllerAnimated:NO]; - - btpad_set_inquiry_state(true); -} - -- (NSString*)retroarchConfigPath -{ - return [NSString stringWithFormat:@"%@/retroarch.cfg", self.systemDirectory]; -} - -- (NSString*)corePath -{ - return [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"modules"]; -} - -- (void)refreshConfig -{ - if (apple_is_running) - apple_frontend_post_event(&event_reload_config, 0); - else - objc_clear_config_hack(); -} - -- (void)refreshSystemConfig -{ - // Read load time settings - config_file_t* conf = config_file_new([self.systemConfigPath UTF8String]); - - if (conf) - { - // Get enabled orientations - static const struct { const char* setting; uint32_t orientation; } orientationSettings[4] = - { - { "ios_allow_portrait", UIInterfaceOrientationMaskPortrait }, - { "ios_allow_portrait_upside_down", UIInterfaceOrientationMaskPortraitUpsideDown }, - { "ios_allow_landscape_left", UIInterfaceOrientationMaskLandscapeLeft }, - { "ios_allow_landscape_right", UIInterfaceOrientationMaskLandscapeRight } - }; - - _enabledOrientations = 0; - - for (int i = 0; i < 4; i ++) - { - bool enabled = false; - bool found = config_get_bool(conf, orientationSettings[i].setting, &enabled); - - if (!found || enabled) - _enabledOrientations |= orientationSettings[i].orientation; - } - - // Setup bluetooth mode - NSString* btmode = objc_get_value_from_config(conf, @"ios_btmode", @"keyboard"); - apple_input_enable_icade([btmode isEqualToString:@"icade"]); - btstack_set_poweron([btmode isEqualToString:@"btstack"]); - - bool val; - use_tv_mode = config_get_bool(conf, "ios_tv_mode", & val) && val; - - config_file_free(conf); - } -} - -#pragma mark PAUSE MENU -- (UIBarButtonItem*)createSettingsButton -{ - if (_settingMenusInBackStack == 0) - return [[UIBarButtonItem alloc] - initWithTitle:@"Settings" - style:UIBarButtonItemStyleBordered - target:[RetroArch_iOS get] - action:@selector(showSystemSettings)]; - - else - return nil; -} - -- (IBAction)showPauseMenu:(id)sender -{ - if (apple_is_running && !apple_is_paused && _isGameTop) - { - apple_is_paused = true; - [[RAGameView get] openPauseMenu]; - - btpad_set_inquiry_state(true); - } -} - -- (IBAction)basicEvent:(id)sender -{ - if (apple_is_running) - apple_frontend_post_event(&event_basic_command, ((UIView*)sender).tag); - - [self closePauseMenu:sender]; -} - -- (IBAction)chooseState:(id)sender -{ - if (apple_is_running) - apple_frontend_post_event(event_set_state_slot, (void*)((UISegmentedControl*)sender).selectedSegmentIndex); -} - -- (IBAction)showRGUI:(id)sender -{ - if (apple_is_running) - apple_frontend_post_event(event_show_rgui, 0); - - [self closePauseMenu:sender]; -} - -- (IBAction)closePauseMenu:(id)sender -{ - [[RAGameView get] closePauseMenu]; - apple_is_paused = false; - - btpad_set_inquiry_state(false); -} - -- (IBAction)showSettings -{ - [self pushViewController:[[RASettingsList alloc] initWithModule:_module] animated:YES]; -} - -- (IBAction)showSystemSettings -{ - [self pushViewController:[RASystemSettingsList new] animated:YES]; -} - -@end - - -#endif - -// -// OSX -// -#pragma mark OSX -#ifdef OSX - -@interface RApplication : NSApplication -@end - -@implementation RApplication - -- (void)sendEvent:(NSEvent *)event -{ - [super sendEvent:event]; - - if (event.type == GSEVENT_TYPE_KEYDOWN || event.type == GSEVENT_TYPE_KEYUP) - apple_input_handle_key_event(event.keyCode, event.type == GSEVENT_TYPE_KEYDOWN); -} - -@end - -@implementation RetroArch_OSX -{ - NSWindow IBOutlet* _coreSelectSheet; - - bool _isTerminating; - bool _loaded; - bool _wantReload; - NSString* _file; - RAModuleInfo* _core; -} - -+ (RetroArch_OSX*)get -{ - return (RetroArch_OSX*)[[NSApplication sharedApplication] delegate]; -} - -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification -{ - apple_platform = self; - _loaded = true; - - [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; - - RAGameView.get.frame = [window.contentView bounds]; - [window.contentView setAutoresizesSubviews:YES]; - [window.contentView addSubview:RAGameView.get]; - [window makeFirstResponder:RAGameView.get]; - - // Create core select list - NSComboBox* cb = (NSComboBox*)[_coreSelectSheet.contentView viewWithTag:1]; - - for (RAModuleInfo* i in RAModuleInfo.getModules) - [cb addItemWithObjectValue:i]; - - if (cb.numberOfItems) - [cb selectItemAtIndex:0]; - else - apple_display_alert(@"No libretro cores were found.", @"RetroArch"); - - // Run RGUI if needed - if (!_wantReload) - apple_run_core(nil, 0); - else - [self chooseCore]; - - _wantReload = false; - - extern void osx_pad_init(); - osx_pad_init(); -} - -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication -{ - return YES; -} - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender -{ - _isTerminating = true; - - if (apple_is_running) - apple_frontend_post_event(event_basic_command, (void*)QUIT); - - return apple_is_running ? NSTerminateCancel : NSTerminateNow; -} - - -- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames -{ - if (filenames.count == 1 && filenames[0]) - { - _file = filenames[0]; - - if (!_loaded) - _wantReload = true; - else - [self chooseCore]; - - [sender replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; - } - else - { - apple_display_alert(@"Cannot open multiple files", @"RetroArch"); - [sender replyToOpenOrPrint:NSApplicationDelegateReplyFailure]; - } -} - -- (void)openDocument:(id)sender -{ - NSOpenPanel* panel = [NSOpenPanel openPanel]; - [panel beginSheetModalForWindow:window completionHandler:^(NSInteger result) - { - [NSApplication.sharedApplication stopModal]; - - if (result == NSOKButton && panel.URL) - { - _file = panel.URL.path; - [self performSelector:@selector(chooseCore) withObject:nil afterDelay:.5f]; - } - }]; - [NSApplication.sharedApplication runModalForWindow:panel]; -} - -// This utility function will queue the _core and _file instance values for running. -// If the emulator thread is already running it will tell it to quit. -- (void)runCore -{ - _wantReload = apple_is_running; - - if (!apple_is_running) - apple_run_core(_core, _file.UTF8String); - else - apple_frontend_post_event(event_basic_command, (void*)QUIT); -} - -- (void)chooseCore -{ -#ifdef USE_XATTR - char stored_name[PATH_MAX]; - if (getxattr(_file.UTF8String, "com.RetroArch.Core", stored_name, PATH_MAX, 0, 0) > 0) - { - for (RAModuleInfo* i in RAModuleInfo.getModules) - { - const char* core_name = i.path.lastPathComponent.UTF8String; - if (strcmp(core_name, stored_name) == 0) - { - _core = i; - [self runCore]; - return; - } - } - } -#endif - - [NSApplication.sharedApplication beginSheet:_coreSelectSheet modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil]; - [NSApplication.sharedApplication runModalForWindow:_coreSelectSheet]; -} - -- (IBAction)coreWasChosen:(id)sender -{ - [NSApplication.sharedApplication stopModal]; - [NSApplication.sharedApplication endSheet:_coreSelectSheet returnCode:0]; - [_coreSelectSheet orderOut:self]; - - if (_isTerminating) - return; - - NSComboBox* cb = (NSComboBox*)[_coreSelectSheet.contentView viewWithTag:1]; - _core = (RAModuleInfo*)cb.objectValueOfSelectedItem; - - [self runCore]; -} - -#pragma mark RetroArch_Platform -- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file -{ - if (file) - { - [NSDocumentController.sharedDocumentController noteNewRecentDocumentURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:file]]]; - -#ifdef USE_XATTR - const char* core_name = core.path.lastPathComponent.UTF8String; - setxattr(file, "com.RetroArch.Core", core_name, strlen(core_name) + 1, 0, 0); -#endif - } -} - -- (void)unloadingCore:(RAModuleInfo*)core -{ - if (_isTerminating) - [NSApplication.sharedApplication terminate:nil]; - - if (_wantReload) - apple_run_core(_core, _file.UTF8String); - else if(use_tv_mode) - apple_run_core(nil, 0); - else - [NSApplication.sharedApplication terminate:nil]; - - _wantReload = false; -} - -- (NSString*)retroarchConfigPath -{ - NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - return [paths[0] stringByAppendingPathComponent:@"RetroArch/retroarch.cfg"]; -} - -- (NSString*)corePath -{ - return [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"Contents/Resources/modules"]; -} - -#pragma mark Menus -- (IBAction)showPreferences:(id)sender -{ - [[[NSWindowController alloc] initWithWindowNibName:@"Settings"] window]; -} - -- (IBAction)basicEvent:(id)sender -{ - if (apple_is_running) - apple_frontend_post_event(&event_basic_command, (void*)((NSMenuItem*)sender).tag); -} - -- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo -{ - [NSApplication.sharedApplication stopModal]; -} - -@end - -int main(int argc, char *argv[]) -{ - return NSApplicationMain(argc, (const char **) argv); -} - -#endif diff --git a/apple/RetroArch_OSX.xcodeproj/project.pbxproj b/apple/RetroArch_OSX.xcodeproj/project.pbxproj index e4b16ceb4a..6a1101970c 100644 --- a/apple/RetroArch_OSX.xcodeproj/project.pbxproj +++ b/apple/RetroArch_OSX.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 9620F6651790004F001B3B81 /* Settings.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9620F6641790004F001B3B81 /* Settings.xib */; }; 962EE0E2178B3DF6004224FF /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 962EE0E1178B3DF6004224FF /* IOKit.framework */; }; 96355CE31788E72A0010DBFA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96355CE21788E72A0010DBFA /* Cocoa.framework */; }; + 9646869817BBC14E00C5EA69 /* platform.m in Sources */ = {isa = PBXBuildFile; fileRef = 9646869617BBC14E00C5EA69 /* platform.m */; }; 967894931788ECDB00D6CA69 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9678948F1788ECDB00D6CA69 /* InfoPlist.strings */; }; 967894941788ECDB00D6CA69 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 967894911788ECDB00D6CA69 /* MainMenu.xib */; }; 967894961788ED1100D6CA69 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 967894951788ED1100D6CA69 /* main.m */; }; @@ -35,6 +36,8 @@ 96355CE51788E72A0010DBFA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 96355CE61788E72A0010DBFA /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 96355CE71788E72A0010DBFA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 9646869617BBC14E00C5EA69 /* platform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = platform.m; path = OSX/platform.m; sourceTree = SOURCE_ROOT; }; + 9646869717BBC14E00C5EA69 /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = platform.h; path = OSX/platform.h; sourceTree = SOURCE_ROOT; }; 9678948D1788ECCA00D6CA69 /* RetroArch-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "RetroArch-Info.plist"; path = "OSX/RetroArch-Info.plist"; sourceTree = SOURCE_ROOT; }; 967894901788ECDB00D6CA69 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = OSX/en.lproj/InfoPlist.strings; sourceTree = SOURCE_ROOT; }; 967894921788ECDB00D6CA69 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = OSX/en.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; }; @@ -109,6 +112,8 @@ 96355CE81788E72A0010DBFA /* RetroArch */ = { isa = PBXGroup; children = ( + 9646869617BBC14E00C5EA69 /* platform.m */, + 9646869717BBC14E00C5EA69 /* platform.h */, 9620F662178FD4D3001B3B81 /* settings.m */, 967894A01788F07D00D6CA69 /* griffin.c */, 967894971788F02600D6CA69 /* RAGameView.m */, @@ -214,6 +219,7 @@ 9678949F1788F02600D6CA69 /* utility.m in Sources */, 967894A11788F07D00D6CA69 /* griffin.c in Sources */, 9620F663178FD4D3001B3B81 /* settings.m in Sources */, + 9646869817BBC14E00C5EA69 /* platform.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/apple/RetroArch_iOS.xcodeproj/project.pbxproj b/apple/RetroArch_iOS.xcodeproj/project.pbxproj index 15081fd2eb..f94d43b805 100644 --- a/apple/RetroArch_iOS.xcodeproj/project.pbxproj +++ b/apple/RetroArch_iOS.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5416C9AC3300D64A22 /* CoreAudio.framework */; }; 96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */; }; 963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; }; + 9646869517BBBEAE00C5EA69 /* platform.m in Sources */ = {isa = PBXBuildFile; fileRef = 9646869417BBBEAE00C5EA69 /* platform.m */; }; 966B9CBD16E41E7A005B61E1 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */; }; 966B9CBF16E41E7A005B61E1 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CB916E41E7A005B61E1 /* Default.png */; }; 966B9CC116E41E7A005B61E1 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CBA16E41E7A005B61E1 /* Default@2x.png */; }; @@ -49,6 +50,7 @@ 96366C5416C9AC3300D64A22 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 963F5AC516CC523B009BBD19 /* RAGameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAGameView.m; sourceTree = ""; }; + 9646869417BBBEAE00C5EA69 /* platform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = platform.m; path = iOS/platform.m; sourceTree = SOURCE_ROOT; }; 966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 966B9CB916E41E7A005B61E1 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 966B9CBA16E41E7A005B61E1 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; @@ -152,6 +154,7 @@ 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { isa = PBXGroup; children = ( + 9646869417BBBEAE00C5EA69 /* platform.m */, 967894571788EAAE00D6CA69 /* browser.m */, 967894581788EAAE00D6CA69 /* RALogView.m */, 967894591788EAAE00D6CA69 /* settings.m */, @@ -305,6 +308,7 @@ 9678945B1788EAAE00D6CA69 /* browser.m in Sources */, 9678945C1788EAAE00D6CA69 /* RALogView.m in Sources */, 9678945D1788EAAE00D6CA69 /* settings.m in Sources */, + 9646869517BBBEAE00C5EA69 /* platform.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/apple/iOS/platform.h b/apple/iOS/platform.h new file mode 100644 index 0000000000..42c168884f --- /dev/null +++ b/apple/iOS/platform.h @@ -0,0 +1,42 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * 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_IOS_PLATFORM_H +#define __RARCH_IOS_PLATFORM_H + +@interface RAGameView : UIViewController ++ (RAGameView*)get; +- (void)openPauseMenu; +- (void)closePauseMenu; +@end + +@interface RetroArch_iOS : UINavigationController + ++ (RetroArch_iOS*)get; + +- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; +- (void)unloadingCore:(RAModuleInfo*)core; +- (NSString*)retroarchConfigPath; + +- (void)refreshSystemConfig; + +@property (strong, nonatomic) NSString* documentsDirectory; // e.g. /var/mobile/Documents +@property (strong, nonatomic) NSString* systemDirectory; // e.g. /var/mobile/Documents/.RetroArch +@property (strong, nonatomic) NSString* systemConfigPath; // e.g. /var/mobile/Documents/.RetroArch/frontend.cfg + +@end + +#endif \ No newline at end of file diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m new file mode 100644 index 0000000000..74b6d5f16c --- /dev/null +++ b/apple/iOS/platform.m @@ -0,0 +1,346 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * 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 + +#import "RetroArch_Apple.h" +#include "rarch_wrapper.h" + +#include "../RetroArch/apple_input.h" + +#import "views.h" +#include "input/BTStack/btpad.h" +#include "input/BTStack/btdynamic.h" +#include "input/BTStack/btpad.h" + +#include "file.h" + +//#define HAVE_DEBUG_FILELOG + +// Input helpers: This is kept here because it needs objective-c +static void handle_touch_event(NSArray* touches) +{ + const int numTouches = [touches count]; + const float scale = [[UIScreen mainScreen] scale]; + + g_current_input_data.touch_count = 0; + + for(int i = 0; i != numTouches && g_current_input_data.touch_count < MAX_TOUCHES; i ++) + { + UITouch* touch = [touches objectAtIndex:i]; + const CGPoint coord = [touch locationInView:touch.view]; + + if (touch.phase != UITouchPhaseEnded && touch.phase != UITouchPhaseCancelled) + { + g_current_input_data.touches[g_current_input_data.touch_count ].screen_x = coord.x * scale; + g_current_input_data.touches[g_current_input_data.touch_count ++].screen_y = coord.y * scale; + } + } +} + +@interface RApplication : UIApplication +@end + +@implementation RApplication + +- (void)sendEvent:(UIEvent *)event +{ + [super sendEvent:event]; + + if ([[event allTouches] count]) + handle_touch_event(event.allTouches.allObjects); + else if ([event respondsToSelector:@selector(_gsEvent)]) + { + // Stolen from: http://nacho4d-nacho4d.blogspot.com/2012/01/catching-keyboard-events-in-ios.html + uint8_t* eventMem = (uint8_t*)(void*)CFBridgingRetain([event performSelector:@selector(_gsEvent)]); + int eventType = eventMem ? *(int*)&eventMem[8] : 0; + + if (eventType == GSEVENT_TYPE_KEYDOWN || eventType == GSEVENT_TYPE_KEYUP) + apple_input_handle_key_event(*(uint16_t*)&eventMem[0x3C], eventType == GSEVENT_TYPE_KEYDOWN); + + CFBridgingRelease(eventMem); + } +} + +@end + +@implementation RetroArch_iOS +{ + UIWindow* _window; + + bool _isGameTop, _isRomList; + uint32_t _settingMenusInBackStack; + uint32_t _enabledOrientations; + + RAModuleInfo* _module; +} + ++ (RetroArch_iOS*)get +{ + return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate]; +} + +#pragma mark LIFECYCLE (UIApplicationDelegate) +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + apple_platform = self; + self.delegate = self; + + // Setup window + _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + _window.rootViewController = self; + [_window makeKeyAndVisible]; + + // Build system paths and test permissions + self.documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; + self.systemDirectory = [self.documentsDirectory stringByAppendingPathComponent:@".RetroArch"]; + self.systemConfigPath = [self.systemDirectory stringByAppendingPathComponent:@"frontend.cfg"]; + + if (!path_make_and_check_directory(self.documentsDirectory.UTF8String, 0755, R_OK | W_OK | X_OK)) + apple_display_alert([NSString stringWithFormat:@"Failed to create or access base directory: %@", self.documentsDirectory], 0); + else if (!path_make_and_check_directory(self.systemDirectory.UTF8String, 0755, R_OK | W_OK | X_OK)) + apple_display_alert([NSString stringWithFormat:@"Failed to create or access system directory: %@", self.systemDirectory], 0); + else + { + [self pushViewController:[RADirectoryList directoryListAtBrowseRoot] animated:YES]; + [self refreshSystemConfig]; + + if (apple_use_tv_mode) + apple_run_core(nil, 0); + } + + // Warn if there are no cores present + if ([RAModuleInfo getModules].count == 0) + apple_display_alert(@"No libretro cores were found. You will not be able to play any games.", 0); +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + apple_enter_stasis(); +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + apple_exit_stasis(); +} + +// UINavigationControllerDelegate +- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated +{ + _isGameTop = [viewController isKindOfClass:[RAGameView class]]; + _isRomList = [viewController isKindOfClass:[RADirectoryList class]]; + + [[UIApplication sharedApplication] setStatusBarHidden:_isGameTop withAnimation:UIStatusBarAnimationNone]; + [[UIApplication sharedApplication] setIdleTimerDisabled:_isGameTop]; + + self.navigationBarHidden = _isGameTop; + [self setToolbarHidden:!_isRomList animated:YES]; + self.topViewController.navigationItem.rightBarButtonItem = [self createSettingsButton]; +} + +// UINavigationController: Never animate when pushing onto, or popping, an RAGameView +- (void)pushViewController:(UIViewController*)theView animated:(BOOL)animated +{ + if ([theView respondsToSelector:@selector(isSettingsView)] && [(id)theView isSettingsView]) + _settingMenusInBackStack ++; + + [super pushViewController:theView animated:animated && !_isGameTop]; +} + +- (UIViewController*)popViewControllerAnimated:(BOOL)animated +{ + if ([self.topViewController respondsToSelector:@selector(isSettingsView)] && [(id)self.topViewController isSettingsView]) + _settingMenusInBackStack --; + + return [super popViewControllerAnimated:animated && !_isGameTop]; +} + +// NOTE: This version only runs on iOS6 +- (NSUInteger)supportedInterfaceOrientations +{ + return _isGameTop ? _enabledOrientations + : UIInterfaceOrientationMaskAll; +} + +// NOTE: This version runs on iOS2-iOS5, but not iOS6 +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + if (_isGameTop) + switch (interfaceOrientation) + { + case UIInterfaceOrientationPortrait: + return (_enabledOrientations & UIInterfaceOrientationMaskPortrait); + case UIInterfaceOrientationPortraitUpsideDown: + return (_enabledOrientations & UIInterfaceOrientationMaskPortraitUpsideDown); + case UIInterfaceOrientationLandscapeLeft: + return (_enabledOrientations & UIInterfaceOrientationMaskLandscapeLeft); + case UIInterfaceOrientationLandscapeRight: + return (_enabledOrientations & UIInterfaceOrientationMaskLandscapeRight); + } + + return YES; +} + + +#pragma mark RetroArch_Platform +- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file +{ + [self pushViewController:RAGameView.get animated:NO]; + [RASettingsList refreshModuleConfig:core]; + + btpad_set_inquiry_state(false); + + [self refreshSystemConfig]; +} + +- (void)unloadingCore:(RAModuleInfo*)core +{ + [self popToViewController:[RAGameView get] animated:NO]; + [self popViewControllerAnimated:NO]; + + btpad_set_inquiry_state(true); +} + +- (NSString*)retroarchConfigPath +{ + return [NSString stringWithFormat:@"%@/retroarch.cfg", self.systemDirectory]; +} + +- (NSString*)corePath +{ + return [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"modules"]; +} + +#pragma mark FRONTEND CONFIG +- (void)refreshSystemConfig +{ + // Read load time settings + config_file_t* conf = config_file_new([self.systemConfigPath UTF8String]); + + if (conf) + { + // Get enabled orientations + static const struct { const char* setting; uint32_t orientation; } orientationSettings[4] = + { + { "ios_allow_portrait", UIInterfaceOrientationMaskPortrait }, + { "ios_allow_portrait_upside_down", UIInterfaceOrientationMaskPortraitUpsideDown }, + { "ios_allow_landscape_left", UIInterfaceOrientationMaskLandscapeLeft }, + { "ios_allow_landscape_right", UIInterfaceOrientationMaskLandscapeRight } + }; + + _enabledOrientations = 0; + + for (int i = 0; i < 4; i ++) + { + bool enabled = false; + bool found = config_get_bool(conf, orientationSettings[i].setting, &enabled); + + if (!found || enabled) + _enabledOrientations |= orientationSettings[i].orientation; + } + + // Setup bluetooth mode + NSString* btmode = objc_get_value_from_config(conf, @"ios_btmode", @"keyboard"); + apple_input_enable_icade([btmode isEqualToString:@"icade"]); + btstack_set_poweron([btmode isEqualToString:@"btstack"]); + + bool val; + apple_use_tv_mode = config_get_bool(conf, "ios_tv_mode", & val) && val; + + config_file_free(conf); + } +} + +#pragma mark PAUSE MENU +- (UIBarButtonItem*)createSettingsButton +{ + if (_settingMenusInBackStack == 0) + return [[UIBarButtonItem alloc] + initWithTitle:@"Settings" + style:UIBarButtonItemStyleBordered + target:[RetroArch_iOS get] + action:@selector(showSystemSettings)]; + + else + return nil; +} + +- (IBAction)showPauseMenu:(id)sender +{ + if (apple_is_running && !apple_is_paused && _isGameTop) + { + apple_is_paused = true; + [[RAGameView get] openPauseMenu]; + + btpad_set_inquiry_state(true); + } +} + +- (IBAction)basicEvent:(id)sender +{ + if (apple_is_running) + apple_frontend_post_event(&apple_event_basic_command, ((UIView*)sender).tag); + + [self closePauseMenu:sender]; +} + +- (IBAction)chooseState:(id)sender +{ + if (apple_is_running) + apple_frontend_post_event(apple_event_set_state_slot, (void*)((UISegmentedControl*)sender).selectedSegmentIndex); +} + +- (IBAction)showRGUI:(id)sender +{ + if (apple_is_running) + apple_frontend_post_event(apple_event_show_rgui, 0); + + [self closePauseMenu:sender]; +} + +- (IBAction)closePauseMenu:(id)sender +{ + [[RAGameView get] closePauseMenu]; + apple_is_paused = false; + + btpad_set_inquiry_state(false); +} + +- (IBAction)showSettings +{ + [self pushViewController:[[RASettingsList alloc] initWithModule:_module] animated:YES]; +} + +- (IBAction)showSystemSettings +{ + [self pushViewController:[RASystemSettingsList new] animated:YES]; +} + +@end + +int main(int argc, char *argv[]) +{ + @autoreleasepool { +#if defined(HAVE_DEBUG_FILELOG) && (TARGET_IPHONE_SIMULATOR == 0) + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex:0]; + NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console_stdout.log"]; + freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "a", stdout); + freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "a", stderr); +#endif + return UIApplicationMain(argc, argv, NSStringFromClass([RApplication class]), NSStringFromClass([RetroArch_iOS class])); + } +} diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index 797fe4c7ce..b386204a4c 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -345,7 +345,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) config_file_free(config); } - [[RetroArch_iOS get] refreshConfig]; + apple_refresh_config(); } } From 7d6b4cdd268793155e6b412cab4e6c83187e337f Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 14 Aug 2013 12:50:31 -0400 Subject: [PATCH 027/202] (iOS) Bring back per-core configurations --- apple/OSX/platform.m | 2 +- apple/RetroArch/RAModuleInfo.h | 8 ++++ apple/RetroArch/RAModuleInfo.m | 34 +++++++++++++ apple/RetroArch/RetroArch_Apple.h | 3 +- apple/RetroArch/main.m | 2 +- apple/iOS/platform.m | 6 +-- apple/iOS/settings.m | 80 +++++++++++++++++++++++++++---- 7 files changed, 119 insertions(+), 16 deletions(-) diff --git a/apple/OSX/platform.m b/apple/OSX/platform.m index b15d053e14..09580ca852 100644 --- a/apple/OSX/platform.m +++ b/apple/OSX/platform.m @@ -230,7 +230,7 @@ - (NSString*)retroarchConfigPath { NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - return [paths[0] stringByAppendingPathComponent:@"RetroArch/retroarch.cfg"]; + return [paths[0] stringByAppendingPathComponent:@"RetroArch"]; } - (NSString*)corePath diff --git a/apple/RetroArch/RAModuleInfo.h b/apple/RetroArch/RAModuleInfo.h index 5370b97f6a..063143a5cb 100644 --- a/apple/RetroArch/RAModuleInfo.h +++ b/apple/RetroArch/RAModuleInfo.h @@ -27,10 +27,18 @@ @property core_info_t* info; @property config_file_t* data; @property (strong) NSString* description; +@property (strong) NSString* customConfigPath; + (NSArray*)getModules; - (bool)supportsFileAtPath:(NSString*)path; ++ (NSString*)globalConfigPath; + +- (void)createCustomConfig; +- (void)deleteCustomConfig; +- (bool)hasCustomConfig; +- (NSString*)configPath; + @end #endif diff --git a/apple/RetroArch/RAModuleInfo.m b/apple/RetroArch/RAModuleInfo.m index f4ffe70784..bd148684bb 100644 --- a/apple/RetroArch/RAModuleInfo.m +++ b/apple/RetroArch/RAModuleInfo.m @@ -44,6 +44,9 @@ static core_info_list_t* coreList; newInfo.data = core->data; newInfo.description = [NSString stringWithUTF8String:core->display_name]; + NSString* baseName = newInfo.path.lastPathComponent.stringByDeletingPathExtension; + newInfo.customConfigPath = [NSString stringWithFormat:@"%@/%@.cfg", apple_platform.retroarchConfigPath, baseName]; + [moduleList addObject:newInfo]; } @@ -70,6 +73,37 @@ static core_info_list_t* coreList; return does_core_support_file(self.info, path.UTF8String); } ++ (NSString*)globalConfigPath +{ + static NSString* path; + if (!path) + path = [NSString stringWithFormat:@"%@/retroarch.cfg", apple_platform.retroarchConfigPath]; + + return path; +} + +- (void)createCustomConfig +{ + if (!self.hasCustomConfig) + [NSFileManager.defaultManager copyItemAtPath:RAModuleInfo.globalConfigPath toPath:self.customConfigPath error:nil]; +} + +- (void)deleteCustomConfig +{ + if (self.hasCustomConfig) + [NSFileManager.defaultManager removeItemAtPath:self.customConfigPath error:nil]; +} + +- (bool)hasCustomConfig +{ + return path_file_exists(self.customConfigPath.UTF8String); +} + +- (NSString*)configPath +{ + return self.hasCustomConfig ? self.customConfigPath : RAModuleInfo.globalConfigPath; +} + @end #ifdef IOS diff --git a/apple/RetroArch/RetroArch_Apple.h b/apple/RetroArch/RetroArch_Apple.h index a714bb70c1..90dccbb0da 100644 --- a/apple/RetroArch/RetroArch_Apple.h +++ b/apple/RetroArch/RetroArch_Apple.h @@ -27,7 +27,8 @@ @protocol RetroArch_Platform - (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; - (void)unloadingCore:(RAModuleInfo*)core; -- (NSString*)retroarchConfigPath; + +- (NSString*)retroarchConfigPath; // < This returns the directory that contains retroarch.cfg and other custom configs - (NSString*)corePath; @end diff --git a/apple/RetroArch/main.m b/apple/RetroArch/main.m index 7d9f392040..3680400c9d 100644 --- a/apple/RetroArch/main.m +++ b/apple/RetroArch/main.m @@ -133,7 +133,7 @@ void apple_run_core(RAModuleInfo* core, const char* file) static const char* argv[] = { "retroarch", "-c", config_path, "-L", core_path, file_path, 0 }; - strlcpy(config_path, apple_platform.retroarchConfigPath.UTF8String, sizeof(config_path)); + strlcpy(config_path, apple_core.configPath.UTF8String, sizeof(config_path)); if (file && core) { diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index 74b6d5f16c..1642e00189 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -84,8 +84,6 @@ static void handle_touch_event(NSArray* touches) bool _isGameTop, _isRomList; uint32_t _settingMenusInBackStack; uint32_t _enabledOrientations; - - RAModuleInfo* _module; } + (RetroArch_iOS*)get @@ -216,7 +214,7 @@ static void handle_touch_event(NSArray* touches) - (NSString*)retroarchConfigPath { - return [NSString stringWithFormat:@"%@/retroarch.cfg", self.systemDirectory]; + return self.systemDirectory; } - (NSString*)corePath @@ -321,7 +319,7 @@ static void handle_touch_event(NSArray* touches) - (IBAction)showSettings { - [self pushViewController:[[RASettingsList alloc] initWithModule:_module] animated:YES]; + [self pushViewController:[[RASettingsList alloc] initWithModule:apple_core] animated:YES]; } - (IBAction)showSystemSettings diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index b386204a4c..af5a4cbc06 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -47,6 +47,8 @@ enum SettingTypes double rangeMin; // < The mininum value of a range setting double rangeMax; // < The maximum value of a range setting + + void (^reload)(RASettingData* action, id userdata); } @end @@ -187,10 +189,11 @@ static RASettingData* aspect_setting(config_file_t* config, NSString* label) return result; } -static RASettingData* custom_action(NSString* action, NSString* value, id data) +static RASettingData* custom_action(NSString* action, NSString* value, id data, void (^reload_func)(RASettingData* action, id userdata)) { RASettingData* result = [[RASettingData alloc] initWithType:CustomAction label:action name:nil]; result->value = value; + result->reload = reload_func; if (data != nil) objc_setAssociatedObject(result, "USERDATA", data, OBJC_ASSOCIATION_RETAIN_NONATOMIC); @@ -252,7 +255,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (id)initWithModule:(RAModuleInfo*)module { _module = module; - _configPath = RetroArch_iOS.get.retroarchConfigPath; + _configPath = _module ? _module.configPath : RAModuleInfo.globalConfigPath; config_file_t* config = config_file_new([_configPath UTF8String]); @@ -261,7 +264,8 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) NSArray* settings = [NSArray arrayWithObjects: [NSArray arrayWithObjects:@"Core", - custom_action(@"Core Info", nil, nil), + custom_action(@"Core Info", nil, nil, 0), + _module.hasCustomConfig ? custom_action(@"Delete Custom Config", nil, nil, 0) : nil, nil], [NSArray arrayWithObjects:@"Video", @@ -353,6 +357,12 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) { if ([@"Core Info" isEqualToString:setting->label]) [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:_module] animated:YES]; + else if([@"Delete Custom Config" isEqualToString:setting->label]) + { + [_module deleteCustomConfig]; + _cancelSave = true; + [self.navigationController popViewControllerAnimated:YES]; + } } @end @@ -361,6 +371,20 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (id)init { config_file_t* config = config_file_new([[RetroArch_iOS get].systemConfigPath UTF8String]); + + NSMutableArray* modules = [NSMutableArray array]; + [modules addObject:@"Cores"]; + [modules addObject:custom_action(@"Global Core Config", nil, nil, 0)]; + + NSArray* moduleList = [RAModuleInfo getModules]; + for (RAModuleInfo* i in moduleList) + { + [modules addObject:custom_action(i.description, nil, i, ^(RASettingData* action, RAModuleInfo* userdata) + { + action->value = userdata.hasCustomConfig ? @"[Custom]" : @"[Global]"; + })]; + } + NSArray* bluetoothOptions = [NSArray arrayWithObjects:@"keyboard", @"Keyboard", @"icade", @"iCade Device", @@ -369,7 +393,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) NSArray* settings = [NSArray arrayWithObjects: [NSArray arrayWithObjects:@"Frontend", - custom_action(@"Diagnostic Log", nil, nil), + custom_action(@"Diagnostic Log", nil, nil, 0), boolean_setting(config, @"ios_tv_mode", @"TV Mode", @"false"), nil], [NSArray arrayWithObjects:@"Bluetooth", @@ -381,9 +405,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) boolean_setting(config, @"ios_allow_landscape_left", @"Landscape Left", @"true"), boolean_setting(config, @"ios_allow_landscape_right", @"Landscape Right", @"true"), nil], - [NSArray arrayWithObjects:@"Cores", - custom_action(@"Core Configuration", nil, nil), - nil], + modules, nil ]; @@ -417,8 +439,45 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) [[RetroArch_iOS get] pushViewController:[RALogView new] animated:YES]; else if ([@"Enable BTstack" isEqualToString:setting->label]) btstack_set_poweron([setting->value isEqualToString:@"true"]); - else if([@"Core Configuration" isEqualToString:setting->label]) + else if([@"Global Core Config" isEqualToString:setting->label]) [RetroArch_iOS.get pushViewController:[[RASettingsList alloc] initWithModule:nil] animated:YES]; + else + { + RAModuleInfo* data = (RAModuleInfo*)objc_getAssociatedObject(setting, "USERDATA"); + if (data) + { + if (!data.hasCustomConfig) + { + UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" + message:@"No custom configuration for this core exists, " + "would you like to create one?" + delegate:self + cancelButtonTitle:@"No" + otherButtonTitles:@"Yes", nil]; + objc_setAssociatedObject(alert, "MODULE", data, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + [alert show]; + } + else + [RetroArch_iOS.get pushViewController:[[RASettingsList alloc] initWithModule:data] animated:YES]; + } + } +} + +- (void)alertView:(UIAlertView*)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex +{ + RAModuleInfo* data = (RAModuleInfo*)objc_getAssociatedObject(alertView, "MODULE"); + + if (data) + { + if (buttonIndex == alertView.firstOtherButtonIndex) + { + [data createCustomConfig]; + [self.tableView reloadData]; + } + + [RetroArch_iOS.get pushViewController:[[RASettingsList alloc] initWithModule:data] animated:YES]; + } + } @end @@ -613,7 +672,10 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"default"]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } - + + if (setting->reload) + setting->reload(setting, objc_getAssociatedObject(setting, "USERDATA")); + cell.textLabel.text = setting->label; if (setting->type == ButtonSetting) From 1eb78a94814a2ee91393e867eec00259d045ddfd Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 14 Aug 2013 13:48:57 -0400 Subject: [PATCH 028/202] (Apple) Fix issue when loading RGUI with the dummy core --- apple/RetroArch/main.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apple/RetroArch/main.m b/apple/RetroArch/main.m index 3680400c9d..cb425a37b3 100644 --- a/apple/RetroArch/main.m +++ b/apple/RetroArch/main.m @@ -132,8 +132,11 @@ void apple_run_core(RAModuleInfo* core, const char* file) static char file_path[PATH_MAX]; static const char* argv[] = { "retroarch", "-c", config_path, "-L", core_path, file_path, 0 }; - - strlcpy(config_path, apple_core.configPath.UTF8String, sizeof(config_path)); + + if (apple_core) + strlcpy(config_path, apple_core.configPath.UTF8String, sizeof(config_path)); + else + strlcpy(config_path, RAModuleInfo.globalConfigPath.UTF8String, sizeof(config_path)); if (file && core) { From b0799be6ba58a0d2be97c9c44938322965f20ad1 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 14 Aug 2013 22:17:21 +0200 Subject: [PATCH 029/202] (Android Phoenix) Set default libretro path (for TV Mode) --- .../org/retroarch/browser/CoreSelection.java | 28 ++----------------- .../retroarch/browser/MainMenuActivity.java | 27 ++++++++++++------ 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/CoreSelection.java b/android/phoenix/src/org/retroarch/browser/CoreSelection.java index 5040dae1b0..4853aa177b 100644 --- a/android/phoenix/src/org/retroarch/browser/CoreSelection.java +++ b/android/phoenix/src/org/retroarch/browser/CoreSelection.java @@ -23,30 +23,6 @@ public class CoreSelection extends Activity implements static private final int ACTIVITY_LOAD_ROM = 0; static private String libretro_path; static private final String TAG = "CoreSelection"; - - - private String readCPUInfo() { - String result = ""; - - try { - BufferedReader br = new BufferedReader(new InputStreamReader( - new FileInputStream("/proc/cpuinfo"))); - - String line; - while ((line = br.readLine()) != null) - result += line + "\n"; - br.close(); - } catch (IOException ex) { - ex.printStackTrace(); - } - return result; - } - - private boolean cpuInfoIsNeon(String info) { - return info.contains("neon"); - } - - @Override public void onCreate(Bundle savedInstanceState) { @@ -60,8 +36,8 @@ public class CoreSelection extends Activity implements Log.e(TAG, "Failed to load libretro_cores.cfg from assets."); } - String cpuInfo = readCPUInfo(); - boolean cpuIsNeon = cpuInfoIsNeon(cpuInfo); + String cpuInfo = MainMenuActivity.readCPUInfo(); + boolean cpuIsNeon = cpuInfo.contains("neon"); setContentView(R.layout.line_list); diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 759d093c4e..395bd33bfd 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -1,13 +1,6 @@ package org.retroarch.browser; -import java.io.BufferedOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import org.retroarch.R; @@ -110,6 +103,23 @@ public class MainMenuActivity extends PreferenceActivity { return rate; } + public static String readCPUInfo() { + String result = ""; + + try { + BufferedReader br = new BufferedReader(new InputStreamReader( + new FileInputStream("/proc/cpuinfo"))); + + String line; + while ((line = br.readLine()) != null) + result += line + "\n"; + br.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + return result; + } + @TargetApi(17) public static int getLowLatencyOptimalSamplingRate() { AudioManager manager = (AudioManager)MainMenuActivity.getInstance().getApplicationContext().getSystemService(Context.AUDIO_SERVICE); @@ -164,6 +174,7 @@ public class MainMenuActivity extends PreferenceActivity { } SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainMenuActivity.getInstance().getBaseContext()); + config.setString("libretro_path", MainMenuActivity.getInstance().getApplicationInfo().nativeLibraryDir); config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true)); config.setInt("audio_out_rate", MainMenuActivity.getOptimalSamplingRate()); config.setInt("audio_latency", prefs.getBoolean("audio_high_latency", false) ? 160 : 64); From 2b614c952e37500b6fe415b8fdf04ef63909e2bc Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 14 Aug 2013 17:38:32 -0400 Subject: [PATCH 030/202] (iOS) Put the file icon back; the file lists look odd with just a directory icon --- apple/iOS/browser.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apple/iOS/browser.m b/apple/iOS/browser.m index 5f70ed1d9a..62b2808745 100644 --- a/apple/iOS/browser.m +++ b/apple/iOS/browser.m @@ -155,7 +155,7 @@ cell.imageView.image = [UIImage imageNamed:@"ic_dir"]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } else { - cell.imageView.image = nil; + cell.imageView.image = [UIImage imageNamed:@"ic_file"]; cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; } From 6de6a793ab90de60af5aa06efdb89bdf6d1b81ee Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 15 Aug 2013 00:12:35 +0200 Subject: [PATCH 031/202] (Android Phoenix) Include popup about asset extraction Bump up to version 0.9.9.5 --- .../src/org/retroarch/browser/MainMenuActivity.java | 12 ++++++++++-- general.h | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 395bd33bfd..008c609073 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -49,9 +49,9 @@ public class MainMenuActivity extends PreferenceActivity { if (!detectDevice(false)) { - AlertDialog.Builder alert = new AlertDialog.Builder(this) + AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("Welcome to RetroArch") - .setMessage("This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience. Please be aware that it might take some time until all shader and overlay assets are extracted.\n\nNOTE: Advanced users who want to finetune for the best possible audio/video experience should use static synchronization and turn off threaded video. Be aware that this is hard to configure right and might result in unpleasant audio crackles when it has been configured wrong.\n\nThreaded video should work fine on most devices, but applies some adaptive video jittering to achieve this. ") + .setMessage("This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience. Please be aware that it might take some time until all shader and overlay assets are extracted...") .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -63,6 +63,14 @@ public class MainMenuActivity extends PreferenceActivity { }); alert.show(); } + else + { + AlertDialog.Builder alert = new AlertDialog.Builder(this) + .setTitle("Welcome to RetroArch") + .setMessage("This is your first time starting up RetroArch. Please be aware that it might take some time until all shader and overlay assets are extracted...") + .setPositiveButton("OK", null); + alert.show(); + } } } diff --git a/general.h b/general.h index cde28f8b35..0d662853be 100644 --- a/general.h +++ b/general.h @@ -41,9 +41,9 @@ #ifndef PACKAGE_VERSION #ifdef __QNX__ /* FIXME - avoid too many decimal points in number error */ -#define PACKAGE_VERSION "0994" +#define PACKAGE_VERSION "0995" #else -#define PACKAGE_VERSION "0.9.9.4" +#define PACKAGE_VERSION "0.9.9.5" #endif #endif From fc564c2bd6278ed97bcff46d694551dcb82f478b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 15 Aug 2013 00:57:13 +0200 Subject: [PATCH 032/202] Add 0.9.9.5 changelog --- android/phoenix/res/layout/faq_whats_new.xml | 38 ++++++++++++++++++ dist-scripts/retroarch-CHANGELOG.txt | 41 ++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/android/phoenix/res/layout/faq_whats_new.xml b/android/phoenix/res/layout/faq_whats_new.xml index 6465cc312d..3dec74f5c8 100644 --- a/android/phoenix/res/layout/faq_whats_new.xml +++ b/android/phoenix/res/layout/faq_whats_new.xml @@ -10,6 +10,44 @@ android:layout_height="wrap_content" android:layout_margin="40px" android:text=" + r19 (August 15, 2013)\n\n + * [Android] Input autodetection fixes -\n + - DualShock3 pad controls fixed\n + * [Android] It should now be possible to map D-pad to analog on several gamepads, such as:\n + - Xbox 360\n + - PlayStation3\n + - Shield\n + * [Android] Threaded video is now the default due to positive user feedback. Purists and accuracy\n + people can still go for static syncing for best results - although for PCSX ReARMed threaded\n + video is essential. With the combination of threaded video and dynamic audio rate control,\n + most of the audio pops and sync issues should be a thing of the past now. Yay.\n + * [Android] UI has been reorganized and made less shitty (yes, we know). Still a long way to go.\n + The entire menu should be gamepad-controllable now at least - handy for Shield/Ouya.\n + * [Android] Shaders that were broken on Nexus 7/4/10 etc. should now work.\n + * [Android] Added some additional autodetection rules:\n + - Ouya: Input overlays are disabled by default\n + * [Android] Added high-latency audio option for crappy/old Android devices that can't handle\n + the lower-latency audio that is the default since 0.9.9.4. This should give you the same\n + performance as 0.9.9.3 (r17). Turn this on if you get bad sound/performance (and it's not your\n + device simply being slow). This might also apply for some of the newer devices - perhaps \n + OpenSL driver has not been updated/optimized there.\n +* [Android] Added a TV mode. This will launch you straight into RGUI mode. This mode +is identical to what you get from the Wii and PC ports of RetroArch at startup. First +you select a core, then you select a game to go with it. +* [SNES9x] Fixes by Alcaro to libretro port +* [SNES9x Next] Fixes savestates from not being able to be loaded. + * (LIBRETRO) Added bsnes/higan performance core [v0.92] (Android).\n + - bsnes/higan performance core will run all non-coprocessor games at fullspeed on an\n + nVidia Shield.\n + - Co-processor games (SuperFX/SA-1/DSP/Cx4/SA1) will run between ~40fps and 55-57fps\n + on an nVidia Shield - depending on the specific co-processor. Note - you will need\n + BIOS files for these games - see byuu boards for information on them.\n + * [Mednafen NGP] Fixes input issues in a number of games, such as:\n + - Card Fighters games\n + - Etc.\n + * [Picodrive] Updates/32X compatibility/accuracy improvements\n + * [NEStopia] Updated to 1.46 WIP - added ability to load NstDatabase.xml, fixes Vs. System games\n + and Startropics 1/2\n r18 (August 7, 2013)\n\n * [Android] ANR issues fixed - Google bug (as ever).\n * [Android] Input autodetection expanded -\n diff --git a/dist-scripts/retroarch-CHANGELOG.txt b/dist-scripts/retroarch-CHANGELOG.txt index 4dcf4951d9..621982471f 100644 --- a/dist-scripts/retroarch-CHANGELOG.txt +++ b/dist-scripts/retroarch-CHANGELOG.txt @@ -1,3 +1,44 @@ +------------------------------------------------------------------------------ +v0.9.9.5 +------------------------------------------------------------------------------ +* [Android] Input autodetection fixes - + - DualShock3 pad controls fixed +* [Android] It should now be possible to map D-pad to analog on several gamepads, such as: + - Xbox 360 + - PlayStation3 + - Shield +* [Android] Threaded video is now the default due to positive user feedback. Purists and accuracy +people can still go for static syncing for best results - although for PCSX ReARMed threaded +video is essential. With the combination of threaded video and dynamic audio rate control, +most of the audio pops and sync issues should be a thing of the past now. Yay. +* [Android] UI has been reorganized and made less shitty (yes, we know). Still a long +way to go there. The entire menu should be gamepad-controllable now at least. +* [Android] Shaders that were broken on Nexus 7/4/10 etc. should now work +* [Android] Added some additional autodetection rules: + - Ouya: Input overlays are disabled by default +* [Android] Added high-latency audio option for crappy/old Android devices that +can't handle the lower-latency audio that is the default since 0.9.9.4. This should +give you the same performance as 0.9.9.3 (r17). Turn this on if you get bad sound/performance +(and it's not your device simply being slow). This might also apply for some of the newer +devices - perhaps OpenSL driver has not been updated/optimized there. +* [Android] Added a TV mode. This will launch you straight into RGUI mode. This mode +is identical to what you get from the Wii and PC ports of RetroArch at startup. First +you select a core, then you select a game to go with it. +* [SNES9x] Fixes by Alcaro to libretro port +* [SNES9x Next] Fixes savestates from not being able to be loaded. +* (LIBRETRO) Added bsnes/higan performance core [v0.92] (Android). + - bsnes/higan performance core will run all non-coprocessor games at fullspeed on an + nVidia Shield. + - Co-processor games (SuperFX/SA-1/DSP/Cx4/SA1) will run between ~40fps and 55-57fps + on an nVidia Shield - depending on the specific co-processor. Note - you will need + BIOS files for these games - see byuu boards for information on them. +* [Mednafen NGP] Fixes input issues in a number of games, such as: + - Card Fighters games + - Etc. +* [Picodrive] Updates/32X compatibility/accuracy improvements +* [NEStopia] Updated to 1.46 WIP - added ability to load NstDatabase.xml, fixes Vs. System games +and Startropics 1/2 + ------------------------------------------------------------------------------ v0.9.9.3 ------------------------------------------------------------------------------ From 1da7c129789462e20f9f3a11b3b81695e0821da6 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 15 Aug 2013 11:34:28 +0200 Subject: [PATCH 033/202] (0.9.9.5) Add iOS changelog --- dist-scripts/retroarch-CHANGELOG.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dist-scripts/retroarch-CHANGELOG.txt b/dist-scripts/retroarch-CHANGELOG.txt index 621982471f..8234786c06 100644 --- a/dist-scripts/retroarch-CHANGELOG.txt +++ b/dist-scripts/retroarch-CHANGELOG.txt @@ -38,6 +38,12 @@ you select a core, then you select a game to go with it. * [Picodrive] Updates/32X compatibility/accuracy improvements * [NEStopia] Updated to 1.46 WIP - added ability to load NstDatabase.xml, fixes Vs. System games and Startropics 1/2 +* [iOS] Only player 1 gets default keyboard bindings +* [iOS] Fixes PS3 gamepad bindings in RGUI +* [iOS] Fixes iCade button mappings +* [iOS] UI additions - Refresh / New Folder / Move options. +* [iOS] Some lifecycle management fixes - should deal better now with phone calls +received and then returning back to RA, etc. ------------------------------------------------------------------------------ v0.9.9.3 From 9dc946900ec51e210c77588f8292cbf04549fa50 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 15 Aug 2013 12:33:19 +0200 Subject: [PATCH 034/202] (Module info files) Update module info files for naming consistency's sake --- apple/modules/desmume_libretro.info | 2 +- apple/modules/genesis_plus_gx_libretro.info | 2 +- apple/modules/instancingviewer_libretro.info | 2 +- apple/modules/mednafen_ngp_libretro.info | 2 +- apple/modules/mednafen_pce_fast_libretro.info | 2 +- apple/modules/mednafen_vb_libretro.info | 2 +- apple/modules/mednafen_wswan_libretro.info | 4 ++-- apple/modules/modelviewer_libretro.info | 2 +- apple/modules/picodrive_libretro.info | 2 +- apple/modules/prboom_libretro.info | 2 +- apple/modules/scenewalker_libretro.info | 2 +- apple/modules/stella_libretro.info | 2 +- apple/modules/tyrquake_libretro.info | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apple/modules/desmume_libretro.info b/apple/modules/desmume_libretro.info index 9fc1326c95..7f7dcf1381 100644 --- a/apple/modules/desmume_libretro.info +++ b/apple/modules/desmume_libretro.info @@ -1,4 +1,4 @@ -display_name = "Nintendo DS" +display_name = "Nintendo DS (DeSmuME)" supported_extensions = "nds" corename = "DeSmuME" manufacturer = "Nintendo" diff --git a/apple/modules/genesis_plus_gx_libretro.info b/apple/modules/genesis_plus_gx_libretro.info index 17d4f786c8..4f71a60403 100644 --- a/apple/modules/genesis_plus_gx_libretro.info +++ b/apple/modules/genesis_plus_gx_libretro.info @@ -1,4 +1,4 @@ -display_name = "Sega (MS/GG/MD/CD)" +display_name = "Sega MS/GG/MD/CD (Genesis Plus GX)" supported_extensions = "md|smd|gen|sms|gg|sg|bin|cue|ios" corename = "Genesis Plus GX" manufacturer = "Sega" diff --git a/apple/modules/instancingviewer_libretro.info b/apple/modules/instancingviewer_libretro.info index 5f2a20f83b..4650def429 100644 --- a/apple/modules/instancingviewer_libretro.info +++ b/apple/modules/instancingviewer_libretro.info @@ -1,4 +1,4 @@ -display_name = "InstancingViewer" +display_name = "PNG Images (InstancingViewer)" recommended_extensions = "png" corename = "InstancingViewer" manufacturer = "Various" diff --git a/apple/modules/mednafen_ngp_libretro.info b/apple/modules/mednafen_ngp_libretro.info index 9213f37e69..40e35e45e0 100644 --- a/apple/modules/mednafen_ngp_libretro.info +++ b/apple/modules/mednafen_ngp_libretro.info @@ -1,4 +1,4 @@ -display_name = "Neo Geo Pocket (Color)" +display_name = "Neo Geo Pocket/Color (Mednafen Neopop)" supported_extensions = "ngp|ngc" corename = "Mednafen Neopop" manufacturer = "SNK" diff --git a/apple/modules/mednafen_pce_fast_libretro.info b/apple/modules/mednafen_pce_fast_libretro.info index a1b27d5ba4..9fb9b8f7a6 100644 --- a/apple/modules/mednafen_pce_fast_libretro.info +++ b/apple/modules/mednafen_pce_fast_libretro.info @@ -1,4 +1,4 @@ -display_name = "PC Engine/TurboGrafx-16" +display_name = "PC Engine/TurboGrafx-16 (Mednafen PCE Fast)" supported_extensions = "pce|sgx|cue" corename = "Mednafen PCE Fast" manufacturer = "NEC" diff --git a/apple/modules/mednafen_vb_libretro.info b/apple/modules/mednafen_vb_libretro.info index 3df42a5e14..bb7d8bd298 100644 --- a/apple/modules/mednafen_vb_libretro.info +++ b/apple/modules/mednafen_vb_libretro.info @@ -1,4 +1,4 @@ -display_name = "Virtual Boy" +display_name = "Virtual Boy (Mednafen VB)" supported_extensions = "vb|vboy|bin" corename = "Mednafen VB" manufacturer = "Nintendo" diff --git a/apple/modules/mednafen_wswan_libretro.info b/apple/modules/mednafen_wswan_libretro.info index ec1f5b9344..320e9cd941 100644 --- a/apple/modules/mednafen_wswan_libretro.info +++ b/apple/modules/mednafen_wswan_libretro.info @@ -1,6 +1,6 @@ -display_name = "WonderSwan (Color)" +display_name = "WonderSwan/Color (Mednafen Cygne)" supported_extensions = "ws|wsc" corename = "Mednafen WonderSwan" manufacturer = "Bandai" -systemname = "WonderSwan (Color)" +systemname = "WonderSwan/Color" diff --git a/apple/modules/modelviewer_libretro.info b/apple/modules/modelviewer_libretro.info index f6bba3967b..87fdf0fdf3 100644 --- a/apple/modules/modelviewer_libretro.info +++ b/apple/modules/modelviewer_libretro.info @@ -1,4 +1,4 @@ -display_name = "Modelviewer" +display_name = "3D Models (Modelviewer)" recommended_extensions = "obj" corename = "Modelviewer" manufacturer = "Various" diff --git a/apple/modules/picodrive_libretro.info b/apple/modules/picodrive_libretro.info index eeea21589b..0784a12369 100644 --- a/apple/modules/picodrive_libretro.info +++ b/apple/modules/picodrive_libretro.info @@ -1,4 +1,4 @@ -display_name = "Sega (MS/GG/MD/CD/32X)" +display_name = "Sega MS/GG/MD/CD/32X (Picodrive)" supported_extensions = "md|smd|gen|sms|gg|sg|bin|cue|ios|32x" corename = "Picodrive" manufacturer = "Sega" diff --git a/apple/modules/prboom_libretro.info b/apple/modules/prboom_libretro.info index c1a416515a..f21bb605b3 100644 --- a/apple/modules/prboom_libretro.info +++ b/apple/modules/prboom_libretro.info @@ -1,3 +1,3 @@ -display_name = "PrBoom (DOOM)" +display_name = "Doom (PrBoom)" supported_extensions = "wad|iwad" corename = "prboom" diff --git a/apple/modules/scenewalker_libretro.info b/apple/modules/scenewalker_libretro.info index 3cc5318f43..6edf3d7af3 100644 --- a/apple/modules/scenewalker_libretro.info +++ b/apple/modules/scenewalker_libretro.info @@ -1,4 +1,4 @@ -display_name = "SceneWalker" +display_name = "3D Models (SceneWalker)" recommended_extensions = "obj" corename = "SceneWalker" manufacturer = "Various" diff --git a/apple/modules/stella_libretro.info b/apple/modules/stella_libretro.info index a45de89830..0abb91f63a 100644 --- a/apple/modules/stella_libretro.info +++ b/apple/modules/stella_libretro.info @@ -1,4 +1,4 @@ -display_name = "Atari 2600" +display_name = "Atari 2600 (Stella)" supported_extensions = "a26|bin" corename = "Stella" manufacturer = "Atari" diff --git a/apple/modules/tyrquake_libretro.info b/apple/modules/tyrquake_libretro.info index a12b75da38..a1ca2f94e9 100644 --- a/apple/modules/tyrquake_libretro.info +++ b/apple/modules/tyrquake_libretro.info @@ -1,3 +1,3 @@ -display_name = "TyrQuake" +display_name = "Quake 1 (TyrQuake)" supported_extensions = "pak" corename = "prboom" From 0a082795361cca39df690dcfef81f543376bff0b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 15 Aug 2013 12:35:01 +0200 Subject: [PATCH 035/202] (Module info) Fix nxengine info file name --- apple/modules/nxengine_libretro.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apple/modules/nxengine_libretro.info b/apple/modules/nxengine_libretro.info index 81ac6073fd..8ec2d1b466 100644 --- a/apple/modules/nxengine_libretro.info +++ b/apple/modules/nxengine_libretro.info @@ -1,3 +1,3 @@ -display_name = "NXEngine (Cave Story)" +display_name = "Cave Story (NXEngine)" supported_extensions = "exe" corename = "NXEngine" From 7ac8636842eb9d3da56e63f406acbfcfa3cc3437 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 15 Aug 2013 12:40:51 +0200 Subject: [PATCH 036/202] (Module info) Update gambatte info file --- apple/modules/gambatte_libretro.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apple/modules/gambatte_libretro.info b/apple/modules/gambatte_libretro.info index 123ac1c9cf..810695f3b1 100644 --- a/apple/modules/gambatte_libretro.info +++ b/apple/modules/gambatte_libretro.info @@ -1,4 +1,4 @@ -display_name = "Game Boy / Game Boy Color" +display_name = "Game Boy / Game Boy Color (Gambatte)" supported_extensions = "gb|gbc|dmg" corename = "gambatte" manufacturer = "Nintendo" From 0d291e809ae268e97a2c37fa55e9688a119b4063 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 15 Aug 2013 09:50:22 -0400 Subject: [PATCH 037/202] (iOS) Fix major hanging bug --- apple/RetroArch/main.m | 3 +-- apple/iOS/platform.m | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apple/RetroArch/main.m b/apple/RetroArch/main.m index cb425a37b3..4ba48c1933 100644 --- a/apple/RetroArch/main.m +++ b/apple/RetroArch/main.m @@ -24,7 +24,6 @@ #include "file.h" //#define HAVE_DEBUG_FILELOG -static bool use_tv_mode; id apple_platform; @@ -175,6 +174,6 @@ void apple_rarch_exited(void* result) [apple_platform unloadingCore:used_core]; } - if (use_tv_mode) + if (apple_use_tv_mode) apple_run_core(nil, 0); } diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index 1642e00189..c70e167fe0 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -127,12 +127,12 @@ static void handle_touch_event(NSArray* touches) - (void)applicationDidBecomeActive:(UIApplication *)application { - apple_enter_stasis(); + apple_exit_stasis(); } - (void)applicationWillResignActive:(UIApplication *)application { - apple_exit_stasis(); + apple_enter_stasis(); } // UINavigationControllerDelegate From 26df85f02073322899d5da9278d23c1007877d19 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 15 Aug 2013 12:47:13 -0400 Subject: [PATCH 038/202] (iOS) Some settings menu polish: The bluetooth mode is updated immediately, previously you had to hit the back button on the frontend settings before it would be applied. The custom config state label in the frontend settings menu is updated properly. --- apple/iOS/platform.h | 3 +++ apple/iOS/platform.m | 9 +++++--- apple/iOS/settings.m | 55 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/apple/iOS/platform.h b/apple/iOS/platform.h index 42c168884f..d7a55f4668 100644 --- a/apple/iOS/platform.h +++ b/apple/iOS/platform.h @@ -39,4 +39,7 @@ @end +// modes are: keyboard, icade and btstack +void ios_set_bluetooth_mode(NSString* mode); + #endif \ No newline at end of file diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index c70e167fe0..cfe1d8b391 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -29,6 +29,11 @@ #include "file.h" //#define HAVE_DEBUG_FILELOG +void ios_set_bluetooth_mode(NSString* mode) +{ + apple_input_enable_icade([mode isEqualToString:@"icade"]); + btstack_set_poweron([mode isEqualToString:@"btstack"]); +} // Input helpers: This is kept here because it needs objective-c static void handle_touch_event(NSArray* touches) @@ -251,9 +256,7 @@ static void handle_touch_event(NSArray* touches) } // Setup bluetooth mode - NSString* btmode = objc_get_value_from_config(conf, @"ios_btmode", @"keyboard"); - apple_input_enable_icade([btmode isEqualToString:@"icade"]); - btstack_set_poweron([btmode isEqualToString:@"btstack"]); + ios_set_bluetooth_mode(objc_get_value_from_config(conf, @"ios_btmode", @"keyboard")); bool val; apple_use_tv_mode = config_get_bool(conf, "ios_tv_mode", & val) && val; diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index af5a4cbc06..54c860eaeb 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -48,8 +48,12 @@ enum SettingTypes double rangeMin; // < The mininum value of a range setting double rangeMax; // < The maximum value of a range setting - void (^reload)(RASettingData* action, id userdata); + void (*changed)(RASettingData* action); + void (*reload)(RASettingData* action, id userdata); } + +- (void)setValue:(NSString*)aValue; + @end @implementation RASettingData @@ -61,6 +65,14 @@ enum SettingTypes return self; } +- (void)setValue:(NSString*)aValue; +{ + value = aValue; + + if (changed) + changed(self); +} + - (uint32_t)enumerationCount { return subValues.count / (haveDescriptions ? 2 : 1); @@ -189,7 +201,7 @@ static RASettingData* aspect_setting(config_file_t* config, NSString* label) return result; } -static RASettingData* custom_action(NSString* action, NSString* value, id data, void (^reload_func)(RASettingData* action, id userdata)) +static RASettingData* custom_action(NSString* action, NSString* value, id data, void (*reload_func)(RASettingData* action, id userdata)) { RASettingData* result = [[RASettingData alloc] initWithType:CustomAction label:action name:nil]; result->value = value; @@ -201,6 +213,14 @@ static RASettingData* custom_action(NSString* action, NSString* value, id data, return result; } +// This adds a change notify function to a setting and returns it; done this way so it can be used in NSArray +// init lists. +static RASettingData* change_notify(RASettingData* setting, void (*change_func)(RASettingData* setting)) +{ + setting->changed = change_func; + return setting; +} + static NSArray* build_input_port_group(config_file_t* config, uint32_t player) { // Only player 1 should have default key bindings @@ -367,6 +387,18 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) @end +#pragma mark System Settings + +static void reload_core_config_state(RASettingData* action, RAModuleInfo* userdata) +{ + [action setValue:userdata.hasCustomConfig ? @"[Custom]" : @"[Global]"]; +} + +static void bluetooth_option_changed(RASettingData* setting) +{ + ios_set_bluetooth_mode(setting->value); +} + @implementation RASystemSettingsList - (id)init { @@ -379,10 +411,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) NSArray* moduleList = [RAModuleInfo getModules]; for (RAModuleInfo* i in moduleList) { - [modules addObject:custom_action(i.description, nil, i, ^(RASettingData* action, RAModuleInfo* userdata) - { - action->value = userdata.hasCustomConfig ? @"[Custom]" : @"[Global]"; - })]; + [modules addObject:custom_action(i.description, nil, i, reload_core_config_state)]; } @@ -397,7 +426,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) boolean_setting(config, @"ios_tv_mode", @"TV Mode", @"false"), nil], [NSArray arrayWithObjects:@"Bluetooth", - enumeration_setting(config, @"ios_btmode", @"Mode", @"keyboard", bluetoothOptions, true), + change_notify(enumeration_setting(config, @"ios_btmode", @"Mode", @"keyboard", bluetoothOptions, true), bluetooth_option_changed), nil], [NSArray arrayWithObjects:@"Orientations", boolean_setting(config, @"ios_allow_portrait", @"Portrait", @"true"), @@ -416,6 +445,12 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) return self; } +- (void)viewDidAppear:(BOOL)animated +{ + [self.tableView reloadData]; + [super viewDidAppear:animated]; +} + - (void)dealloc { config_file_t* config = config_file_new([[RetroArch_iOS get].systemConfigPath UTF8String]); @@ -590,7 +625,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (void)handleBooleanSwitch:(UISwitch*)swt { RASettingData* setting = objc_getAssociatedObject(swt, "SETTING"); - setting->value = (swt.on ? @"true" : @"false"); + [setting setValue:swt.on ? @"true" : @"false"]; [self handleCustomAction:setting]; } @@ -598,7 +633,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (void)handleSlider:(UISlider*)sld { RASettingData* setting = objc_getAssociatedObject(sld, "SETTING"); - setting->value = [NSString stringWithFormat:@"%f", sld.value]; + [setting setValue:[NSString stringWithFormat:@"%f", sld.value]]; [self handleCustomAction:setting]; } @@ -739,7 +774,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - _value->value = (indexPath.section == _mainSection) ? [_value valueForEnumerationIndex:indexPath.row] : @""; + [_value setValue: (indexPath.section == _mainSection) ? [_value valueForEnumerationIndex:indexPath.row] : @""]; [_view reloadData]; [[RetroArch_iOS get] popViewControllerAnimated:YES]; From 551fd27204f8e19d2d09e0b574041a9b65b2b82e Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 16 Aug 2013 00:30:54 +0200 Subject: [PATCH 039/202] Add support for wrapping modes. Not terribly useful atm due to POT, but at least it's there. Has some use mostly with LUTs ... NPOT + REPEAT requires extension on GLES2 at least. --- gfx/gl.c | 35 +++++++++++++++-------------- gfx/gl_common.h | 23 ++++++++++++++++++- gfx/shader_cg.c | 24 +++++++++++--------- gfx/shader_common.h | 1 + gfx/shader_glsl.c | 9 ++++++++ gfx/shader_parse.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ gfx/shader_parse.h | 13 ++++++++++- 7 files changed, 130 insertions(+), 29 deletions(-) diff --git a/gfx/gl.c b/gfx/gl.c index 9ed67c79b6..3518c5e3a6 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -347,6 +347,7 @@ void gl_shader_set_coords(void *data, const struct gl_coords *coords, const math #define gl_shader_num(gl) ((gl->shader) ? gl->shader->num_shaders() : 0) #define gl_shader_filter_type(gl, index, smooth) ((gl->shader) ? gl->shader->filter_type(index, smooth) : false) +#define gl_shader_wrap_type(gl, index) ((gl->shader) ? gl->shader->wrap_type(index) : RARCH_WRAP_BORDER) #ifdef IOS // There is no default frame buffer on IOS. @@ -465,16 +466,18 @@ static void gl_create_fbo_textures(void *data) { glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl->border_type); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl->border_type); - GLuint filter_type = base_filt; bool smooth = false; if (gl_shader_filter_type(gl, i + 2, &smooth)) filter_type = smooth ? GL_LINEAR : GL_NEAREST; + enum gfx_wrap_type wrap = gl_shader_wrap_type(gl, i + 2); + GLenum wrap_enum = gl_wrap_type_to_enum(wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_type); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_type); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_enum); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_enum); bool fp_fbo = gl->fbo_scale[i].valid && gl->fbo_scale[i].fp_fbo; @@ -1156,8 +1159,8 @@ static void gl_init_textures(void *data, const video_info_t *video) { glBindTexture(GL_TEXTURE_2D, gl->texture[i]); - 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_WRAP_S, gl->wrap_mode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl->wrap_mode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl->tex_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl->tex_filter); @@ -1643,13 +1646,6 @@ static bool resolve_extensions(gl_t *gl) RARCH_LOG("[GL]: Using ARB_sync to reduce latency.\n"); #endif -#ifdef NO_GL_CLAMP_TO_BORDER - // NOTE: This will be a serious problem for some shaders. - gl->border_type = GL_CLAMP_TO_EDGE; -#else - gl->border_type = GL_CLAMP_TO_BORDER; -#endif - driver.gfx_use_rgba = false; #ifdef HAVE_OPENGLES2 if (gl_query_extension(gl, "BGRA8888")) @@ -2055,6 +2051,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo gl->tex_filter = force_smooth ? GL_LINEAR : GL_NEAREST; else gl->tex_filter = video->smooth ? GL_LINEAR : GL_NEAREST; + gl->wrap_mode = gl_wrap_type_to_enum(gl_shader_wrap_type(gl, 1)); gl_set_texture_fmts(gl, video->rgb32); @@ -2155,18 +2152,22 @@ static void gl_update_tex_filter_frame(gl_t *gl) bool smooth = false; if (!gl_shader_filter_type(gl, 1, &smooth)) smooth = g_settings.video.smooth; + GLenum wrap_mode = gl_wrap_type_to_enum(gl_shader_wrap_type(gl, 1)); gl->video_info.smooth = smooth; GLuint new_filt = smooth ? GL_LINEAR : GL_NEAREST; - if (new_filt == gl->tex_filter) + if (new_filt == gl->tex_filter && wrap_mode == gl->wrap_mode) return; gl->tex_filter = new_filt; + gl->wrap_mode = wrap_mode; for (unsigned i = 0; i < gl->textures; i++) { if (gl->texture[i]) { glBindTexture(GL_TEXTURE_2D, gl->texture[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl->wrap_mode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl->wrap_mode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl->tex_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl->tex_filter); } @@ -2394,8 +2395,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->border_type); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl->border_type); + 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_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -2567,8 +2568,8 @@ static void gl_set_texture_frame(void *data, { 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_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 3da0b5d53c..5e97a0a540 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -199,7 +199,7 @@ typedef struct gl GLenum internal_fmt; GLenum texture_type; // RGB565 or ARGB GLenum texture_fmt; - GLenum border_type; + GLenum wrap_mode; unsigned base_size; // 2 or 4 // Fonts @@ -314,5 +314,26 @@ void gl_shader_set_coords(void *data, const struct gl_coords *coords, const math void gl_init_fbo(void *data, unsigned width, unsigned height); void gl_deinit_fbo(void *data); +static inline GLenum gl_wrap_type_to_enum(enum gfx_wrap_type type) +{ + switch (type) + { +#ifndef HAVE_OPENGLES + case RARCH_WRAP_BORDER: + return GL_CLAMP_TO_BORDER; +#else + case RARCH_WRAP_BORDER: +#endif + case RARCH_WRAP_EDGE: + return GL_CLAMP_TO_EDGE; + case RARCH_WRAP_REPEAT: + return GL_REPEAT; + case RARCH_WRAP_MIRRORED_REPEAT: + return GL_MIRRORED_REPEAT; + default: + return 0; + } +} + #endif diff --git a/gfx/shader_cg.c b/gfx/shader_cg.c index a634d99253..7f00885b20 100644 --- a/gfx/shader_cg.c +++ b/gfx/shader_cg.c @@ -493,18 +493,12 @@ static bool load_plain(const char *path) #define print_buf(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__) -#ifdef HAVE_OPENGLES2 -#define BORDER_FUNC GL_CLAMP_TO_EDGE -#else -#define BORDER_FUNC GL_CLAMP_TO_BORDER -#endif - -static void load_texture_data(GLuint obj, const struct texture_image *img, bool smooth) +static void load_texture_data(GLuint obj, const struct texture_image *img, bool smooth, GLenum wrap) { glBindTexture(GL_TEXTURE_2D, obj); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, BORDER_FUNC); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, BORDER_FUNC); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, smooth ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, smooth ? GL_LINEAR : GL_NEAREST); @@ -538,7 +532,8 @@ static bool load_textures(void) } load_texture_data(lut_textures[i], &img, - cg_shader->lut[i].filter != RARCH_FILTER_NEAREST); + cg_shader->lut[i].filter != RARCH_FILTER_NEAREST, + gl_wrap_type_to_enum(cg_shader->lut[i].wrap)); } glBindTexture(GL_TEXTURE_2D, 0); @@ -903,6 +898,14 @@ static bool gl_cg_filter_type(unsigned index, bool *smooth) return false; } +static enum gfx_wrap_type gl_cg_wrap_type(unsigned index) +{ + if (cg_active && index) + return cg_shader->pass[index - 1].wrap; + else + return RARCH_WRAP_BORDER; +} + static void gl_cg_shader_scale(unsigned index, struct gfx_fbo_scale *scale) { if (cg_active && index) @@ -942,6 +945,7 @@ const gl_shader_backend_t gl_cg_backend = { gl_cg_use, gl_cg_num, gl_cg_filter_type, + gl_cg_wrap_type, gl_cg_shader_scale, gl_cg_set_coords, gl_cg_set_mvp, diff --git a/gfx/shader_common.h b/gfx/shader_common.h index 2b72da2bed..dae07b2608 100644 --- a/gfx/shader_common.h +++ b/gfx/shader_common.h @@ -47,6 +47,7 @@ struct gl_shader_backend void (*use)(unsigned index); unsigned (*num_shaders)(void); bool (*filter_type)(unsigned index, bool *smooth); + enum gfx_wrap_type (*wrap_type)(unsigned index); void (*shader_scale)(unsigned index, struct gfx_fbo_scale *scale); bool (*set_coords)(const struct gl_coords *coords); bool (*set_mvp)(const math_matrix *mat); diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index a15d2ef0e5..06c25ca322 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -1180,6 +1180,14 @@ static bool gl_glsl_filter_type(unsigned index, bool *smooth) return false; } +static enum gfx_wrap_type gl_glsl_wrap_type(unsigned index) +{ + if (glsl_enable && index) + return glsl_shader->pass[index - 1].wrap; + else + return RARCH_WRAP_BORDER; +} + static void gl_glsl_shader_scale(unsigned index, struct gfx_fbo_scale *scale) { if (glsl_enable && index) @@ -1221,6 +1229,7 @@ const gl_shader_backend_t gl_glsl_backend = { gl_glsl_use, gl_glsl_num, gl_glsl_filter_type, + gl_glsl_wrap_type, gl_glsl_shader_scale, gl_glsl_set_coords, gl_glsl_set_mvp, diff --git a/gfx/shader_parse.c b/gfx/shader_parse.c index 4ac92499ea..b92d68b8a7 100644 --- a/gfx/shader_parse.c +++ b/gfx/shader_parse.c @@ -30,6 +30,41 @@ #define print_buf(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__) +static const char *wrap_mode_to_str(enum gfx_wrap_type type) +{ + switch (type) + { + case RARCH_WRAP_BORDER: + return "clamp_to_border"; + case RARCH_WRAP_EDGE: + return "clamp_to_edge"; + case RARCH_WRAP_REPEAT: + return "repeat"; + case RARCH_WRAP_MIRRORED_REPEAT: + return "mirrored_repeat"; + default: + return "???"; + } +} + +static enum gfx_wrap_type wrap_str_to_mode(const char *wrap_mode) +{ + if (strcmp(wrap_mode, "clamp_to_border") == 0) + return RARCH_WRAP_BORDER; + else if (strcmp(wrap_mode, "clamp_to_edge") == 0) + return RARCH_WRAP_EDGE; + else if (strcmp(wrap_mode, "repeat") == 0) + return RARCH_WRAP_REPEAT; + else if (strcmp(wrap_mode, "mirrored_repeat") == 0) + return RARCH_WRAP_MIRRORED_REPEAT; + else + { + RARCH_WARN("Invalid wrapping type %s. Valid ones are: clamp_to_border (default), clamp_to_edge, repeat and mirrored_repeat. Falling back to default.\n", + wrap_mode); + return RARCH_WRAP_DEFAULT; + } +} + // CGP static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass, unsigned i) { @@ -52,6 +87,13 @@ static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass, else pass->filter = RARCH_FILTER_UNSPEC; + // Wrapping mode + char wrap_name_buf[64]; + print_buf(wrap_name_buf, "wrap_mode%u", i); + char wrap_mode[64]; + if (config_get_array(conf, wrap_name_buf, wrap_mode, sizeof(wrap_mode))) + pass->wrap = wrap_str_to_mode(wrap_mode); + // Frame count mod char frame_count_mod[64] = {0}; char frame_count_mod_buf[64]; @@ -207,6 +249,12 @@ static bool shader_parse_textures(config_file_t *conf, struct gfx_shader *shader shader->lut[shader->luts].filter = smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST; else shader->lut[shader->luts].filter = RARCH_FILTER_UNSPEC; + + char id_wrap[64]; + print_buf(id_wrap, "%s_wrap_mode", id); + char wrap_mode[64]; + if (config_get_array(conf, id_wrap, wrap_mode, sizeof(wrap_mode))) + shader->lut[shader->luts].wrap = wrap_str_to_mode(wrap_mode); } return true; @@ -998,6 +1046,9 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, const struct gfx_shader *sha config_set_bool(conf, key, pass->filter == RARCH_FILTER_LINEAR); } + print_buf(key, "wrap_mode%u", i); + config_set_string(conf, key, wrap_mode_to_str(pass->wrap)); + if (pass->frame_count_mod) { print_buf(key, "frame_count_mod%u", i); @@ -1031,6 +1082,9 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, const struct gfx_shader *sha print_buf(key, "%s_linear", shader->lut[i].id); config_set_bool(conf, key, shader->lut[i].filter != RARCH_FILTER_LINEAR); } + + print_buf(key, "%s_wrap_mode", shader->lut[i].id); + config_set_string(conf, key, wrap_mode_to_str(shader->lut[i].wrap)); } } diff --git a/gfx/shader_parse.h b/gfx/shader_parse.h index dcbda69b20..0822dc7c41 100644 --- a/gfx/shader_parse.h +++ b/gfx/shader_parse.h @@ -40,7 +40,16 @@ enum gfx_filter_type { RARCH_FILTER_UNSPEC = 0, RARCH_FILTER_LINEAR, - RARCH_FILTER_NEAREST, + RARCH_FILTER_NEAREST +}; + +enum gfx_wrap_type +{ + RARCH_WRAP_BORDER = 0, // Kinda deprecated, but keep as default. Will be translated to EDGE in GLES. + RARCH_WRAP_DEFAULT = RARCH_WRAP_BORDER, + RARCH_WRAP_EDGE, + RARCH_WRAP_REPEAT, + RARCH_WRAP_MIRRORED_REPEAT }; struct gfx_fbo_scale @@ -69,6 +78,7 @@ struct gfx_shader_pass struct gfx_fbo_scale fbo; enum gfx_filter_type filter; + enum gfx_wrap_type wrap; unsigned frame_count_mod; }; @@ -77,6 +87,7 @@ struct gfx_shader_lut char id[64]; char path[PATH_MAX]; enum gfx_filter_type filter; + enum gfx_wrap_type wrap; }; // This is pretty big, shouldn't be put on the stack. From 963f206456747537dbbf0aed32bd7151d79672be Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 16 Aug 2013 03:57:09 +0200 Subject: [PATCH 040/202] Bump to version 0.9.9.6 --- android/phoenix/AndroidManifest.xml | 4 ++-- android/phoenix/res/layout/faq_whats_new.xml | 5 +++++ android/phoenix/res/xml/prefs.xml | 2 +- dist-scripts/retroarch-CHANGELOG.txt | 8 ++++++++ general.h | 4 ++-- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index 4f6243d63f..60c19f7578 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -1,7 +1,7 @@ + android:versionCode="21" + android:versionName="0.9.9.6" > + android:title="RetroArch 0.9.9.6 - Main Menu" > Date: Fri, 16 Aug 2013 10:18:58 +0200 Subject: [PATCH 041/202] Log GL version as well. --- gfx/gl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gfx/gl.c b/gfx/gl.c index 3518c5e3a6..768e79631c 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1967,6 +1967,9 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo const char *renderer = (const char*)glGetString(GL_RENDERER); RARCH_LOG("[GL]: Vendor: %s, Renderer: %s.\n", vendor, renderer); + const char *version = (const char*)glGetString(GL_VERSION); + RARCH_LOG("[GL]: Version: %s.\n", version); + #ifndef RARCH_CONSOLE rglgen_resolve_symbols(gl->ctx_driver->get_proc_address); #endif From 758dc7e196c99442caef2f9cd74906324776b544 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 16 Aug 2013 12:16:19 +0200 Subject: [PATCH 042/202] Add Load Game (History) to Android frontend. Also cleanup core selection list a bit to be more readable. --- android/phoenix/AndroidManifest.xml | 1 + android/phoenix/assets/libretro_cores.cfg | 108 +++-- android/phoenix/res/layout/line_list_item.xml | 30 +- android/phoenix/res/xml/prefs.xml | 5 + .../org/retroarch/browser/CoreSelection.java | 65 +-- .../org/retroarch/browser/FileWrapper.java | 5 + .../retroarch/browser/HistorySelection.java | 83 ++++ .../org/retroarch/browser/HistoryWrapper.java | 63 +++ .../org/retroarch/browser/IconAdapter.java | 15 +- .../retroarch/browser/MainMenuActivity.java | 446 +++++++++++------- .../org/retroarch/browser/ModuleWrapper.java | 9 + 11 files changed, 581 insertions(+), 249 deletions(-) create mode 100644 android/phoenix/src/org/retroarch/browser/HistorySelection.java create mode 100644 android/phoenix/src/org/retroarch/browser/HistoryWrapper.java diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index 60c19f7578..c8cbc8ecf4 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -16,6 +16,7 @@ android:label="@string/app_name" android:hasCode="true"> + diff --git a/android/phoenix/assets/libretro_cores.cfg b/android/phoenix/assets/libretro_cores.cfg index f921f2c467..9255e899f4 100644 --- a/android/phoenix/assets/libretro_cores.cfg +++ b/android/phoenix/assets/libretro_cores.cfg @@ -1,27 +1,81 @@ -libretro_mednafen_pce_fast = "Mednafen PCE-fast (PC Engine/PC Engine CD)" -libretro_mednafen_wswan = "Mednafen WSwan (Wonderswan)" -libretro_fceumm = "FCEUmm (Nintendo NES)" -libretro_mednafen_vb = "Mednafen VB (Virtual Boy)" -libretro_fba = "Final Burn Alpha (Arcade)" -libretro_mednafen_ngp = "Mednafen NGP (Neo-Geo Pocket)" -libretro_mednafen_psx = "Mednafen PSX (PlayStation1)" -libretro_gambatte = "Gambatte (GameBoy/GameBoy Color)" -libretro_genesis_plus_gx = "Genesis Plus GX (Sega Genesis/Sega CD/Master System)" -libretro_picodrive = "Picodrive (Sega Genesis/Sega CD/Master System/32X)" -libretro_vba_next = "VBA Next (GameBoy Advance)" -libretro_prboom = "PrBoom (DOOM)" -libretro_snes9x = "SNES9x (Nintendo SNES)" -libretro_snes9x_next = "SNES9x Next (Nintendo SNES)" -libretro_nestopia = "Nestopia (Nintendo NES)" -libretro_pcsx_rearmed-neon = "PCSX-reARMed (PlayStation1) [NEON]" -libretro_pcsx_rearmed = "PCSX-reARMed (PlayStation1)" -libretro_nxengine = "NXEngine (Cave Story/Doukutsu Monogatari)" -libretro_quicknes = "QuickNES (Nintendo NES)" -libretro_tyrquake = "TyrQuake (Quake 1)" -libretro_instancingviewer = "InstancingViewer (Images)" -libretro_desmume = "Desmume (Nintendo DS)" -libretro_stella = "Stella (Atari 2600)" -libretro_scenewalker = "SceneWalker (Objects)" -libretro_modelviewer = "ModelViewer (Objects)" -libretro_mame078 = "MAME 2003 [0.78] (Arcade)" -libretro_bsnes_performance = "bsnes/higan Performance (Nintendo SNES)" +libretro_mednafen_pce_fast = "Mednafen PCE-fast" +libretro_mednafen_pce_fast_system = "PC Engine/PC Engine CD" + +libretro_mednafen_wswan = "Mednafen WSwan" +libretro_mednafen_wswan_system = "Wonderswan" + +libretro_fceumm = "FCEUmm" +libretro_fceumm_system = "Nintendo NES" + +libretro_mednafen_vb = "Mednafen VB" +libretro_mednafen_vb_system = "Virtual Boy" + +libretro_fba = "Final Burn Alpha" +libretro_fba_system = "Arcade" + +libretro_mednafen_ngp = "Mednafen NGP" +libretro_mednafen_ngp_system = "Neo-Geo Pocket" + +libretro_mednafen_psx = "Mednafen PSX" +libretro_mednafen_psx_system = "PlayStation1" + +libretro_gambatte = "Gambatte" +libretro_gambatte_system = "GameBoy/GameBoy Color" + +libretro_genesis_plus_gx = "Genesis Plus GX" +libretro_genesis_plus_gx_system = "Sega Genesis/Sega CD/Master System" + +libretro_picodrive = "Picodrive" +libretro_picodrive_system = "Sega Genesis/Sega CD/Master System/32X" + +libretro_vba_next = "VBA Next" +libretro_vba_next_system = "GameBoy Advance" + +libretro_prboom = "PrBoom" +libretro_prboom_system = "DOOM" + +libretro_snes9x = "SNES9x" +libretro_snes9x_system = "Nintendo SNES" + +libretro_snes9x_next = "SNES9x Next" +libretro_snes9x_next_system = "Nintendo SNES" + +libretro_nestopia = "Nestopia" +libretro_nestopia_system = "Nintendo NES" + +libretro_pcsx_rearmed-neon = "PCSX-reARMed [NEON]" +libretro_pcsx_rearmed-neon_system = "PlayStation1" + +libretro_pcsx_rearmed = "PCSX-reARMed" +libretro_pcsx_rearmed_system = "PlayStation1" + +libretro_nxengine = "NXEngine" +libretro_nxengine_system = "Cave Story/Doukutsu Monogatari" + +libretro_quicknes = "QuickNES" +libretro_quicknes_system = "Nintendo NES" + +libretro_tyrquake = "TyrQuake" +libretro_tyrquake_system = "Quake 1" + +libretro_instancingviewer = "InstancingViewer" +libretro_instancingviewer_system = "Images" + +libretro_desmume = "Desmume" +libretro_desmume_system = "Nintendo DS" + +libretro_stella = "Stella" +libretro_stella_system = "Atari 2600" + +libretro_scenewalker = "SceneWalker" +libretro_scenewalker_system = "Objects" + +libretro_modelviewer = "ModelViewer" +libretro_modelviewer_system = "Objects" + +libretro_mame078 = "MAME 2003 [0.78]" +libretro_mame078_system = "Arcade" + +libretro_bsnes_performance = "bsnes/higan Performance" +libretro_bsnes_performance_system = "Nintendo SNES" + diff --git a/android/phoenix/res/layout/line_list_item.xml b/android/phoenix/res/layout/line_list_item.xml index 46ebf2dec1..6c9d14e3d3 100644 --- a/android/phoenix/res/layout/line_list_item.xml +++ b/android/phoenix/res/layout/line_list_item.xml @@ -3,7 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" - android:layout_height="48dp"> + android:layout_height="wrap_content"> - - + android:layout_gravity="center_vertical" + android:orientation="vertical" > + + + + + diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index 83b58c25b0..40f7d2c65f 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -12,6 +12,11 @@ android:targetClass="org.retroarch.browser.CoreSelection" android:targetPackage="org.retroarch" /> + + + = Build.VERSION_CODES.HONEYCOMB) - { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { PopupMenuAbstract menu = new PopupMenuAbstract(this, v); MenuInflater inflater = menu.getMenuInflater(); inflater.inflate(R.menu.context_menu, menu.getMenu()); - menu.setOnMenuItemClickListener(new PopupMenuAbstract.OnMenuItemClickListener() - { + menu.setOnMenuItemClickListener(new PopupMenuAbstract.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { return onContextItemSelected(item); } - + }); menu.show(); - } - else - { + } else { this.openContextMenu(findViewById(android.R.id.content)); } } - + @Override public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.context_menu, menu); + ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.context_menu, menu); } - + @Override public boolean onOptionsItemSelected(MenuItem aItem) { switch (aItem.getItemId()) { @@ -177,7 +178,7 @@ public class CoreSelection extends Activity implements return super.onOptionsItemSelected(aItem); } } - + @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { diff --git a/android/phoenix/src/org/retroarch/browser/FileWrapper.java b/android/phoenix/src/org/retroarch/browser/FileWrapper.java index 8af274db16..afbd0fbd54 100644 --- a/android/phoenix/src/org/retroarch/browser/FileWrapper.java +++ b/android/phoenix/src/org/retroarch/browser/FileWrapper.java @@ -43,6 +43,11 @@ class FileWrapper implements IconAdapterItem { else return file.getName(); } + + @Override + public String getSubText() { + return null; + } @Override public int getIconResourceId() { diff --git a/android/phoenix/src/org/retroarch/browser/HistorySelection.java b/android/phoenix/src/org/retroarch/browser/HistorySelection.java new file mode 100644 index 0000000000..8426570f6d --- /dev/null +++ b/android/phoenix/src/org/retroarch/browser/HistorySelection.java @@ -0,0 +1,83 @@ +package org.retroarch.browser; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +import org.retroarch.R; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.provider.Settings; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.Toast; + +public class HistorySelection extends Activity implements + AdapterView.OnItemClickListener { + + private IconAdapter adapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.line_list); + + // Setup the list + adapter = new IconAdapter(this, R.layout.line_list_item); + ListView list = (ListView) findViewById(R.id.list); + list.setAdapter(adapter); + list.setOnItemClickListener(this); + + setTitle("Recently played games"); + + File history = new File(getApplicationInfo().dataDir, "retroarch-history.txt"); + + try { + BufferedReader br = new BufferedReader(new InputStreamReader( + new FileInputStream(history))); + + for (;;) { + String game = br.readLine(); + String core = br.readLine(); + String name = br.readLine(); + if (game == null || core == null || name == null) + break; + + adapter.add(new HistoryWrapper(game, core, name)); + } + br.close(); + } catch (IOException ex) { + } + } + + @Override + public void onItemClick(AdapterView aListView, View aView, + int aPosition, long aID) { + final HistoryWrapper item = adapter.getItem(aPosition); + final String gamePath = item.getGamePath(); + final String corePath = item.getCorePath(); + + Intent myIntent; + String current_ime = Settings.Secure.getString(getContentResolver(), + Settings.Secure.DEFAULT_INPUT_METHOD); + + MainMenuActivity.updateConfigFile(); + MainMenuActivity.waitAssetThread(); + + Toast.makeText(this, "Loading: [" + gamePath + "] ...", + Toast.LENGTH_SHORT).show(); + myIntent = new Intent(this, RetroActivity.class); + myIntent.putExtra("ROM", gamePath); + myIntent.putExtra("LIBRETRO", corePath); + myIntent.putExtra("CONFIGFILE", MainMenuActivity.getDefaultConfigPath()); + myIntent.putExtra("IME", current_ime); + startActivity(myIntent); + finish(); + } +} diff --git a/android/phoenix/src/org/retroarch/browser/HistoryWrapper.java b/android/phoenix/src/org/retroarch/browser/HistoryWrapper.java new file mode 100644 index 0000000000..ae57f1c149 --- /dev/null +++ b/android/phoenix/src/org/retroarch/browser/HistoryWrapper.java @@ -0,0 +1,63 @@ +package org.retroarch.browser; + +import java.io.File; + +import android.graphics.drawable.Drawable; + +public class HistoryWrapper implements IconAdapterItem { + + private String gamePath; + private String gamePathShort; + private String corePath; + private String coreName; + + public HistoryWrapper(String gamePath, String corePath, String coreName) { + this.gamePath = gamePath; + this.corePath = corePath; + this.coreName = coreName; + + File file = new File(gamePath); + gamePathShort = file.getName(); + try { + gamePathShort = gamePathShort.substring(0, gamePathShort.lastIndexOf('.')); + } catch (Exception e) { + } + } + + public String getGamePath() { + return gamePath; + } + + public String getCorePath() { + return corePath; + } + + public String getCoreName() { + return coreName; + } + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public String getText() { + return gamePathShort; + } + + @Override + public String getSubText() { + return coreName; + } + + @Override + public int getIconResourceId() { + return 0; + } + + @Override + public Drawable getIconDrawable() { + return null; + } +} diff --git a/android/phoenix/src/org/retroarch/browser/IconAdapter.java b/android/phoenix/src/org/retroarch/browser/IconAdapter.java index 72314daf0f..5d1a2c9f64 100644 --- a/android/phoenix/src/org/retroarch/browser/IconAdapter.java +++ b/android/phoenix/src/org/retroarch/browser/IconAdapter.java @@ -10,11 +10,9 @@ import android.widget.*; interface IconAdapterItem { public abstract boolean isEnabled(); - public abstract String getText(); - + public abstract String getSubText(); public abstract int getIconResourceId(); - public abstract Drawable getIconDrawable(); } @@ -23,7 +21,6 @@ class IconAdapter extends ArrayAdapter { public IconAdapter(Activity aContext, int aLayout) { super(aContext, aLayout); - layout = aLayout; } @@ -45,6 +42,16 @@ class IconAdapter extends ArrayAdapter { textView.setText(item.getText()); textView.setEnabled(enabled); } + + textView = (TextView) aConvertView.findViewById(R.id.sub_name); + if (null != textView) { + String subText = item.getSubText(); + if (null != subText) { + textView.setVisibility(View.VISIBLE); + textView.setEnabled(item.isEnabled()); + textView.setText(subText); + } + } ImageView imageView = (ImageView) aConvertView.findViewById(R.id.icon); if (null != imageView) { diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 008c609073..df1104d48f 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -24,6 +24,19 @@ import android.widget.Toast; public class MainMenuActivity extends PreferenceActivity { private static MainMenuActivity instance = null; static private final String TAG = "MainMenu"; + static private Thread assetThread = null; + + public static void waitAssetThread() { + if (assetThread != null) { + try { + assetThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + assetThread = null; + } + } + @SuppressWarnings("deprecation") @Override public void onCreate(Bundle savedInstanceState) { @@ -32,56 +45,62 @@ public class MainMenuActivity extends PreferenceActivity { addPreferencesFromResource(R.xml.prefs); PreferenceManager.setDefaultValues(this, R.xml.prefs, false); this.setVolumeControlStream(AudioManager.STREAM_MUSIC); - + // Extracting assets appears to take considerable amount of time, so // move extraction to a thread. - Thread assetThread = new Thread(new Runnable() { + assetThread = new Thread(new Runnable() { public void run() { extractAssets(); } }); assetThread.start(); - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); - + + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getBaseContext()); + if (!prefs.getBoolean("first_time_refreshrate_calculate", false)) { - prefs.edit().putBoolean("first_time_refreshrate_calculate", true).commit(); - - if (!detectDevice(false)) - { + prefs.edit().putBoolean("first_time_refreshrate_calculate", true) + .commit(); + + if (!detectDevice(false)) { AlertDialog.Builder alert = new AlertDialog.Builder(this) - .setTitle("Welcome to RetroArch") - .setMessage("This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience. Please be aware that it might take some time until all shader and overlay assets are extracted...") - .setPositiveButton("OK", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); - SharedPreferences.Editor edit = prefs.edit(); - edit.putBoolean("video_threaded", true); - edit.commit(); - } - }); - alert.show(); - } - else - { + .setTitle("Welcome to RetroArch") + .setMessage( + "This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience. Please be aware that it might take some time until all shader and overlay assets are extracted...") + .setPositiveButton("OK", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor edit = prefs + .edit(); + edit.putBoolean("video_threaded", true); + edit.commit(); + } + }); + alert.show(); + } else { AlertDialog.Builder alert = new AlertDialog.Builder(this) - .setTitle("Welcome to RetroArch") - .setMessage("This is your first time starting up RetroArch. Please be aware that it might take some time until all shader and overlay assets are extracted...") - .setPositiveButton("OK", null); - alert.show(); + .setTitle("Welcome to RetroArch") + .setMessage( + "This is your first time starting up RetroArch. Please be aware that it might take some time until all shader and overlay assets are extracted...") + .setPositiveButton("OK", null); + alert.show(); } } } - + public static MainMenuActivity getInstance() { - return instance; - } - + return instance; + } + private final double getDisplayRefreshRate() { // Android is *very* likely to screw this up. // It is rarely a good value to use, so make sure it's not - // completely wrong. Some phones return refresh rates that are completely bogus + // completely wrong. Some phones return refresh rates that are + // completely bogus // (like 0.3 Hz, etc), so try to be very conservative here. final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); final Display display = wm.getDefaultDisplay(); @@ -94,7 +113,8 @@ public class MainMenuActivity extends PreferenceActivity { public static final double getRefreshRate() { double rate = 0; SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(MainMenuActivity.getInstance().getBaseContext()); + .getDefaultSharedPreferences(MainMenuActivity.getInstance() + .getBaseContext()); String refresh_rate = prefs.getString("video_refresh_rate", ""); if (!refresh_rate.isEmpty()) { try { @@ -106,11 +126,11 @@ public class MainMenuActivity extends PreferenceActivity { } else { rate = MainMenuActivity.getInstance().getDisplayRefreshRate(); } - + Log.i(TAG, "Using refresh rate: " + rate + " Hz."); return rate; } - + public static String readCPUInfo() { String result = ""; @@ -127,28 +147,32 @@ public class MainMenuActivity extends PreferenceActivity { } return result; } - + @TargetApi(17) public static int getLowLatencyOptimalSamplingRate() { - AudioManager manager = (AudioManager)MainMenuActivity.getInstance().getApplicationContext().getSystemService(Context.AUDIO_SERVICE); - return Integer.parseInt(manager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); + AudioManager manager = (AudioManager) MainMenuActivity.getInstance() + .getApplicationContext() + .getSystemService(Context.AUDIO_SERVICE); + return Integer.parseInt(manager + .getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); } - + public static int getOptimalSamplingRate() { int ret; if (android.os.Build.VERSION.SDK_INT >= 17) ret = getLowLatencyOptimalSamplingRate(); else - ret = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC); - + ret = AudioTrack + .getNativeOutputSampleRate(AudioManager.STREAM_MUSIC); + Log.i(TAG, "Using sampling rate: " + ret + " Hz"); return ret; } - + public static String getDefaultConfigPath() { String internal = System.getenv("INTERNAL_STORAGE"); String external = System.getenv("EXTERNAL_STORAGE"); - + if (external != null) { String confPath = external + File.separator + "retroarch.cfg"; if (new File(confPath).exists()) @@ -162,17 +186,23 @@ public class MainMenuActivity extends PreferenceActivity { if (new File(confPath).exists()) return confPath; } - - if (internal != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) + + if (internal != null + && new File(internal + File.separator + "retroarch.cfg") + .canWrite()) return internal + File.separator + "retroarch.cfg"; - else if (external != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) + else if (external != null + && new File(internal + File.separator + "retroarch.cfg") + .canWrite()) return external + File.separator + "retroarch.cfg"; else if ((MainMenuActivity.getInstance().getApplicationInfo().dataDir) != null) - return (MainMenuActivity.getInstance().getApplicationInfo().dataDir) + File.separator + "retroarch.cfg"; - else // emergency fallback, all else failed + return (MainMenuActivity.getInstance().getApplicationInfo().dataDir) + + File.separator + "retroarch.cfg"; + else + // emergency fallback, all else failed return "/mnt/sd/retroarch.cfg"; } - + public static void updateConfigFile() { ConfigFile config; try { @@ -180,30 +210,55 @@ public class MainMenuActivity extends PreferenceActivity { } catch (IOException e) { config = new ConfigFile(); } - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainMenuActivity.getInstance().getBaseContext()); - config.setString("libretro_path", MainMenuActivity.getInstance().getApplicationInfo().nativeLibraryDir); - config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true)); - config.setInt("audio_out_rate", MainMenuActivity.getOptimalSamplingRate()); - config.setInt("audio_latency", prefs.getBoolean("audio_high_latency", false) ? 160 : 64); - config.setBoolean("audio_enable", prefs.getBoolean("audio_enable", true)); - config.setBoolean("video_smooth", prefs.getBoolean("video_smooth", true)); - config.setBoolean("video_allow_rotate", prefs.getBoolean("video_allow_rotate", true)); - config.setBoolean("savestate_auto_load", prefs.getBoolean("savestate_auto_load", true)); - config.setBoolean("savestate_auto_save", prefs.getBoolean("savestate_auto_save", false)); - config.setBoolean("rewind_enable", prefs.getBoolean("rewind_enable", false)); + + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(MainMenuActivity.getInstance() + .getBaseContext()); + config.setString("libretro_path", MainMenuActivity.getInstance() + .getApplicationInfo().nativeLibraryDir); + config.setBoolean("audio_rate_control", + prefs.getBoolean("audio_rate_control", true)); + config.setInt("audio_out_rate", + MainMenuActivity.getOptimalSamplingRate()); + config.setInt("audio_latency", + prefs.getBoolean("audio_high_latency", false) ? 160 : 64); + config.setBoolean("audio_enable", + prefs.getBoolean("audio_enable", true)); + config.setBoolean("video_smooth", + prefs.getBoolean("video_smooth", true)); + config.setBoolean("video_allow_rotate", + prefs.getBoolean("video_allow_rotate", true)); + config.setBoolean("savestate_auto_load", + prefs.getBoolean("savestate_auto_load", true)); + config.setBoolean("savestate_auto_save", + prefs.getBoolean("savestate_auto_save", false)); + config.setBoolean("rewind_enable", + prefs.getBoolean("rewind_enable", false)); config.setBoolean("video_vsync", prefs.getBoolean("video_vsync", true)); - config.setBoolean("input_autodetect_enable", prefs.getBoolean("input_autodetect_enable", true)); - config.setBoolean("input_debug_enable", prefs.getBoolean("input_debug_enable", false)); - config.setInt("input_back_behavior", Integer.valueOf(prefs.getString("input_back_behavior", "0"))); - config.setInt("input_autodetect_icade_profile_pad1", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad1", "0"))); - config.setInt("input_autodetect_icade_profile_pad2", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad2", "0"))); - config.setInt("input_autodetect_icade_profile_pad3", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad3", "0"))); - config.setInt("input_autodetect_icade_profile_pad4", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad4", "0"))); - - config.setDouble("video_refresh_rate", MainMenuActivity.getRefreshRate()); - config.setBoolean("video_threaded", prefs.getBoolean("video_threaded", true)); - + config.setBoolean("input_autodetect_enable", + prefs.getBoolean("input_autodetect_enable", true)); + config.setBoolean("input_debug_enable", + prefs.getBoolean("input_debug_enable", false)); + config.setInt("input_back_behavior", + Integer.valueOf(prefs.getString("input_back_behavior", "0"))); + config.setInt("input_autodetect_icade_profile_pad1", Integer + .valueOf(prefs.getString("input_autodetect_icade_profile_pad1", + "0"))); + config.setInt("input_autodetect_icade_profile_pad2", Integer + .valueOf(prefs.getString("input_autodetect_icade_profile_pad2", + "0"))); + config.setInt("input_autodetect_icade_profile_pad3", Integer + .valueOf(prefs.getString("input_autodetect_icade_profile_pad3", + "0"))); + config.setInt("input_autodetect_icade_profile_pad4", Integer + .valueOf(prefs.getString("input_autodetect_icade_profile_pad4", + "0"))); + + config.setDouble("video_refresh_rate", + MainMenuActivity.getRefreshRate()); + config.setBoolean("video_threaded", + prefs.getBoolean("video_threaded", true)); + String aspect = prefs.getString("video_aspect_ratio", "auto"); if (aspect.equals("full")) { config.setBoolean("video_force_aspect", false); @@ -220,9 +275,10 @@ public class MainMenuActivity extends PreferenceActivity { config.setBoolean("video_force_aspect", true); config.setDouble("video_aspect_ratio", aspect_ratio); } - - config.setBoolean("video_scale_integer", prefs.getBoolean("video_scale_integer", false)); - + + config.setBoolean("video_scale_integer", + prefs.getBoolean("video_scale_integer", false)); + String shaderPath = prefs.getString("video_shader", ""); config.setString("video_shader", shaderPath); config.setBoolean("video_shader_enable", @@ -231,28 +287,42 @@ public class MainMenuActivity extends PreferenceActivity { boolean useOverlay = prefs.getBoolean("input_overlay_enable", true); if (useOverlay) { - String overlayPath = prefs.getString("input_overlay", (MainMenuActivity.getInstance().getApplicationInfo().dataDir) + "/overlays/snes-landscape.cfg"); + String overlayPath = prefs + .getString("input_overlay", (MainMenuActivity.getInstance() + .getApplicationInfo().dataDir) + + "/overlays/snes-landscape.cfg"); config.setString("input_overlay", overlayPath); - config.setDouble("input_overlay_opacity", prefs.getFloat("input_overlay_opacity", 1.0f)); + config.setDouble("input_overlay_opacity", + prefs.getFloat("input_overlay_opacity", 1.0f)); } else { config.setString("input_overlay", ""); } + + config.setString( + "savefile_directory", + prefs.getBoolean("savefile_directory_enable", false) ? prefs + .getString("savefile_directory", "") : ""); + config.setString( + "savestate_directory", + prefs.getBoolean("savestate_directory_enable", false) ? prefs + .getString("savestate_directory", "") : ""); + config.setString( + "system_directory", + prefs.getBoolean("system_directory_enable", false) ? prefs + .getString("system_directory", "") : ""); + + config.setBoolean("video_font_enable", + prefs.getBoolean("video_font_enable", true)); - config.setString("savefile_directory", prefs.getBoolean("savefile_directory_enable", false) ? - prefs.getString("savefile_directory", "") : ""); - config.setString("savestate_directory", prefs.getBoolean("savestate_directory_enable", false) ? - prefs.getString("savestate_directory", "") : ""); - config.setString("system_directory", prefs.getBoolean("system_directory_enable", false) ? - prefs.getString("system_directory", "") : ""); - - config.setBoolean("video_font_enable", prefs.getBoolean("video_font_enable", true)); - - for (int i = 1; i <= 4; i++) - { - final String btns[] = {"up", "down", "left", "right", "a", "b", "x", "y", "start", "select", "l", "r", "l2", "r2", "l3", "r3" }; - for (String b : btns) - { - String p = "input_player" + String.valueOf(i) + "_" + b + "_btn"; + config.setString("game_history_path", MainMenuActivity.getInstance().getApplicationInfo().dataDir + "/retroarch-history.txt"); + + for (int i = 1; i <= 4; i++) { + final String btns[] = { "up", "down", "left", "right", "a", "b", + "x", "y", "start", "select", "l", "r", "l2", "r2", "l3", + "r3" }; + for (String b : btns) { + String p = "input_player" + String.valueOf(i) + "_" + b + + "_btn"; config.setInt(p, prefs.getInt(p, 0)); } } @@ -264,7 +334,7 @@ public class MainMenuActivity extends PreferenceActivity { Log.e(TAG, "Failed to save config file to: " + confPath); } } - + private byte[] loadAsset(String asset) throws IOException { String path = asset; InputStream stream = getAssets().open(path); @@ -273,22 +343,24 @@ public class MainMenuActivity extends PreferenceActivity { stream.read(buf, 0, len); return buf; } - - private void extractAssets(AssetManager manager, String dataDir, String relativePath, int level) throws IOException { + + private void extractAssets(AssetManager manager, String dataDir, + String relativePath, int level) throws IOException { final String[] paths = manager.list(relativePath); if (paths != null && paths.length > 0) { // Directory - //Log.d(TAG, "Extracting assets directory: " + relativePath); + // Log.d(TAG, "Extracting assets directory: " + relativePath); for (final String path : paths) - extractAssets(manager, dataDir, relativePath + (level > 0 ? File.separator : "") + path, level + 1); + extractAssets(manager, dataDir, relativePath + + (level > 0 ? File.separator : "") + path, level + 1); } else { // File, extract. - //Log.d(TAG, "Extracting assets file: " + relativePath); - + // Log.d(TAG, "Extracting assets file: " + relativePath); + String parentPath = new File(relativePath).getParent(); if (parentPath != null) { File parentFile = new File(dataDir, parentPath); parentFile.mkdirs(); // Doesn't throw. } - + byte[] asset = loadAsset(relativePath); BufferedOutputStream writer = new BufferedOutputStream( new FileOutputStream(new File(dataDir, relativePath))); @@ -298,128 +370,146 @@ public class MainMenuActivity extends PreferenceActivity { writer.close(); } } - + private void extractAssets() { int version = 0; try { version = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; - } catch(NameNotFoundException e) { + } catch (NameNotFoundException e) { // weird exception, shouldn't happen } - + try { AssetManager assets = getAssets(); String dataDir = getApplicationInfo().dataDir; File cacheVersion = new File(dataDir, ".cacheversion"); - if (cacheVersion != null && cacheVersion.isFile() && cacheVersion.canRead() && cacheVersion.canWrite()) - { - DataInputStream cacheStream = new DataInputStream(new FileInputStream(cacheVersion)); + if (cacheVersion != null && cacheVersion.isFile() + && cacheVersion.canRead() && cacheVersion.canWrite()) { + DataInputStream cacheStream = new DataInputStream( + new FileInputStream(cacheVersion)); int currentCacheVersion = 0; try { currentCacheVersion = cacheStream.readInt(); - } catch (IOException e) {} - cacheStream.close(); - - if (currentCacheVersion == version) - { + } catch (IOException e) { + } + cacheStream.close(); + + if (currentCacheVersion == version) { Log.i("ASSETS", "Assets already extracted, skipping..."); return; } } - - //extractAssets(assets, cacheDir, "", 0); + + // extractAssets(assets, cacheDir, "", 0); Log.i("ASSETS", "Extracting shader assets now ..."); try { extractAssets(assets, dataDir, "shaders_glsl", 1); } catch (IOException e) { Log.i("ASSETS", "Failed to extract shaders ..."); } - + Log.i("ASSETS", "Extracting overlay assets now ..."); try { extractAssets(assets, dataDir, "overlays", 1); } catch (IOException e) { Log.i("ASSETS", "Failed to extract overlays ..."); } - - DataOutputStream outputCacheVersion = new DataOutputStream(new FileOutputStream(cacheVersion, false)); + + DataOutputStream outputCacheVersion = new DataOutputStream( + new FileOutputStream(cacheVersion, false)); outputCacheVersion.writeInt(version); outputCacheVersion.close(); } catch (IOException e) { - Log.e(TAG, "Failed to extract assets to cache."); + Log.e(TAG, "Failed to extract assets to cache."); } } - - boolean detectDevice(boolean show_dialog) - { + + boolean detectDevice(boolean show_dialog) { boolean retval = false; - + Log.i("Device MODEL", android.os.Build.MODEL); - if (android.os.Build.MODEL.equals("SHIELD")) - { + if (android.os.Build.MODEL.equals("SHIELD")) { AlertDialog.Builder alert = new AlertDialog.Builder(this) - .setTitle("NVidia Shield detected") - .setMessage("The ideal configuration options for your device will now be preconfigured.\nNOTE: For optimal performance, turn off Google Account sync, Google Play Store auto-updates, GPS and Wifi in your Android settings menu.") - .setPositiveButton("OK", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); - SharedPreferences.Editor edit = prefs.edit(); - edit.putString("video_refresh_rate", Double.valueOf(60.00d).toString()); - edit.putBoolean("input_overlay_enable", false); - edit.putBoolean("input_autodetect_enable", true); - edit.commit(); - } - }); + .setTitle("NVidia Shield detected") + .setMessage( + "The ideal configuration options for your device will now be preconfigured.\nNOTE: For optimal performance, turn off Google Account sync, Google Play Store auto-updates, GPS and Wifi in your Android settings menu.") + .setPositiveButton("OK", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor edit = prefs + .edit(); + edit.putString("video_refresh_rate", Double + .valueOf(60.00d).toString()); + edit.putBoolean("input_overlay_enable", + false); + edit.putBoolean("input_autodetect_enable", + true); + edit.commit(); + } + }); + alert.show(); + retval = true; + } else if (android.os.Build.MODEL.equals("OUYA Console")) { + AlertDialog.Builder alert = new AlertDialog.Builder(this) + .setTitle("OUYA detected") + .setMessage( + "The ideal configuration options for your device will now be preconfigured.\nNOTE: For optimal performance, turn off Google Account sync, GPS and Wifi in your Android settings menu.") + .setPositiveButton("OK", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor edit = prefs + .edit(); + edit.putBoolean("input_overlay_enable", + false); + edit.putBoolean("input_autodetect_enable", + true); + edit.commit(); + } + }); + alert.show(); + retval = true; + } else if (android.os.Build.ID.equals("JSS15J")) { + AlertDialog.Builder alert = new AlertDialog.Builder(this) + .setTitle("Nexus 7 2013 detected") + .setMessage( + "The ideal configuration options for your device will now be preconfigured.\nNOTE: For optimal performance, turn off Google Account sync, Google Play Store auto-updates, GPS and Wifi in your Android settings menu.") + .setPositiveButton("OK", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor edit = prefs + .edit(); + edit.putString("video_refresh_rate", Double + .valueOf(59.65).toString()); + edit.commit(); + } + }); alert.show(); retval = true; } - else if (android.os.Build.MODEL.equals( "OUYA Console")) - { - AlertDialog.Builder alert = new AlertDialog.Builder(this) - .setTitle("OUYA detected") - .setMessage("The ideal configuration options for your device will now be preconfigured.\nNOTE: For optimal performance, turn off Google Account sync, GPS and Wifi in your Android settings menu.") - .setPositiveButton("OK", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); - SharedPreferences.Editor edit = prefs.edit(); - edit.putBoolean("input_overlay_enable", false); - edit.putBoolean("input_autodetect_enable", true); - edit.commit(); - } - }); - alert.show(); - retval = true; - } - else if (android.os.Build.ID.equals("JSS15J")) - { - AlertDialog.Builder alert = new AlertDialog.Builder(this) - .setTitle("Nexus 7 2013 detected") - .setMessage("The ideal configuration options for your device will now be preconfigured.\nNOTE: For optimal performance, turn off Google Account sync, Google Play Store auto-updates, GPS and Wifi in your Android settings menu.") - .setPositiveButton("OK", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); - SharedPreferences.Editor edit = prefs.edit(); - edit.putString("video_refresh_rate", Double.valueOf(59.65).toString()); - edit.commit(); - } - }); - alert.show(); - retval = true; - } - + if (show_dialog) { - Toast.makeText(this, - "Device either not detected in list or doesn't have any optimal settings in our database.", - Toast.LENGTH_SHORT).show(); + Toast.makeText( + this, + "Device either not detected in list or doesn't have any optimal settings in our database.", + Toast.LENGTH_SHORT).show(); } - + return retval; } - + @Override protected void onStart() { super.onStart(); diff --git a/android/phoenix/src/org/retroarch/browser/ModuleWrapper.java b/android/phoenix/src/org/retroarch/browser/ModuleWrapper.java index c741c28af5..f029edb0cc 100644 --- a/android/phoenix/src/org/retroarch/browser/ModuleWrapper.java +++ b/android/phoenix/src/org/retroarch/browser/ModuleWrapper.java @@ -28,6 +28,15 @@ class ModuleWrapper implements IconAdapterItem { } else return stripped; } + + @Override + public String getSubText() { + String stripped = file.getName().replace(".so", "") + "_system"; + if (config.keyExists(stripped)) { + return config.getString(stripped); + } else + return null; + } @Override public int getIconResourceId() { From 2dcc133cabbe3a693ccbad7b27c4c8d5588a3ff4 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 16 Aug 2013 12:25:34 +0200 Subject: [PATCH 043/202] Wait for asset thread when selecting overlay and/or shader. --- android/phoenix/src/org/retroarch/browser/OverlayActivity.java | 1 + android/phoenix/src/org/retroarch/browser/ShaderActivity.java | 1 + 2 files changed, 2 insertions(+) diff --git a/android/phoenix/src/org/retroarch/browser/OverlayActivity.java b/android/phoenix/src/org/retroarch/browser/OverlayActivity.java index 38981f6b87..b92b190a14 100644 --- a/android/phoenix/src/org/retroarch/browser/OverlayActivity.java +++ b/android/phoenix/src/org/retroarch/browser/OverlayActivity.java @@ -7,6 +7,7 @@ import android.os.Bundle; public class OverlayActivity extends DirectoryActivity { @Override public void onCreate(Bundle savedInstanceState) { + MainMenuActivity.waitAssetThread(); File overlayDir = new File(getBaseContext().getApplicationInfo().dataDir, "overlays"); if (overlayDir.exists()) super.setStartDirectory(overlayDir.getAbsolutePath()); diff --git a/android/phoenix/src/org/retroarch/browser/ShaderActivity.java b/android/phoenix/src/org/retroarch/browser/ShaderActivity.java index 3fb705de94..707363b19e 100644 --- a/android/phoenix/src/org/retroarch/browser/ShaderActivity.java +++ b/android/phoenix/src/org/retroarch/browser/ShaderActivity.java @@ -7,6 +7,7 @@ import android.os.Bundle; public class ShaderActivity extends DirectoryActivity { @Override public void onCreate(Bundle savedInstanceState) { + MainMenuActivity.waitAssetThread(); File shaderDir = new File(getBaseContext().getApplicationInfo().dataDir, "shaders_glsl"); if (shaderDir.exists()) super.setStartDirectory(shaderDir.getAbsolutePath()); From dd2d8009ca539440ce5172345c7e341e0104d480 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 16 Aug 2013 14:46:36 +0200 Subject: [PATCH 044/202] Add ProgressBar for asset extraction. --- android/phoenix/res/layout/assets.xml | 22 +++++ android/phoenix/res/values/strings.xml | 1 + .../org/retroarch/browser/CoreSelection.java | 1 - .../retroarch/browser/HistorySelection.java | 1 - .../retroarch/browser/MainMenuActivity.java | 99 ++++++++++++------- .../retroarch/browser/OverlayActivity.java | 1 - .../org/retroarch/browser/ShaderActivity.java | 1 - 7 files changed, 86 insertions(+), 40 deletions(-) create mode 100644 android/phoenix/res/layout/assets.xml diff --git a/android/phoenix/res/layout/assets.xml b/android/phoenix/res/layout/assets.xml new file mode 100644 index 0000000000..afb702997c --- /dev/null +++ b/android/phoenix/res/layout/assets.xml @@ -0,0 +1,22 @@ + + + + + + + + + diff --git a/android/phoenix/res/values/strings.xml b/android/phoenix/res/values/strings.xml index e37ebf04c3..530ed1c704 100644 --- a/android/phoenix/res/values/strings.xml +++ b/android/phoenix/res/values/strings.xml @@ -9,5 +9,6 @@ Report Refresh Rate Detect Optimal device settings + Extracting assets, please wait ... diff --git a/android/phoenix/src/org/retroarch/browser/CoreSelection.java b/android/phoenix/src/org/retroarch/browser/CoreSelection.java index 224ee799c9..72f5e67beb 100644 --- a/android/phoenix/src/org/retroarch/browser/CoreSelection.java +++ b/android/phoenix/src/org/retroarch/browser/CoreSelection.java @@ -113,7 +113,6 @@ public class CoreSelection extends Activity implements Settings.Secure.DEFAULT_INPUT_METHOD); MainMenuActivity.updateConfigFile(); - MainMenuActivity.waitAssetThread(); switch (requestCode) { case ACTIVITY_LOAD_ROM: diff --git a/android/phoenix/src/org/retroarch/browser/HistorySelection.java b/android/phoenix/src/org/retroarch/browser/HistorySelection.java index 8426570f6d..5e416469dd 100644 --- a/android/phoenix/src/org/retroarch/browser/HistorySelection.java +++ b/android/phoenix/src/org/retroarch/browser/HistorySelection.java @@ -68,7 +68,6 @@ public class HistorySelection extends Activity implements Settings.Secure.DEFAULT_INPUT_METHOD); MainMenuActivity.updateConfigFile(); - MainMenuActivity.waitAssetThread(); Toast.makeText(this, "Loading: [" + gamePath + "] ...", Toast.LENGTH_SHORT).show(); diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index df1104d48f..037cee4b1b 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -6,6 +6,7 @@ import org.retroarch.R; import android.annotation.TargetApi; import android.app.AlertDialog; +import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; @@ -14,6 +15,7 @@ import android.content.res.AssetManager; import android.media.AudioManager; import android.media.AudioTrack; import android.os.Bundle; +import android.os.Handler; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; import android.util.Log; @@ -24,18 +26,6 @@ import android.widget.Toast; public class MainMenuActivity extends PreferenceActivity { private static MainMenuActivity instance = null; static private final String TAG = "MainMenu"; - static private Thread assetThread = null; - - public static void waitAssetThread() { - if (assetThread != null) { - try { - assetThread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - assetThread = null; - } - } @SuppressWarnings("deprecation") @Override @@ -46,18 +36,11 @@ public class MainMenuActivity extends PreferenceActivity { PreferenceManager.setDefaultValues(this, R.xml.prefs, false); this.setVolumeControlStream(AudioManager.STREAM_MUSIC); - // Extracting assets appears to take considerable amount of time, so - // move extraction to a thread. - assetThread = new Thread(new Runnable() { - public void run() { - extractAssets(); - } - }); - assetThread.start(); - SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(getBaseContext()); + extractAssets(); + if (!prefs.getBoolean("first_time_refreshrate_calculate", false)) { prefs.edit().putBoolean("first_time_refreshrate_calculate", true) .commit(); @@ -66,7 +49,7 @@ public class MainMenuActivity extends PreferenceActivity { AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("Welcome to RetroArch") .setMessage( - "This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience. Please be aware that it might take some time until all shader and overlay assets are extracted...") + "This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience. Please be aware that it might take some time until all shader and overlay assets are extracted ...") .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override @@ -85,7 +68,7 @@ public class MainMenuActivity extends PreferenceActivity { AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("Welcome to RetroArch") .setMessage( - "This is your first time starting up RetroArch. Please be aware that it might take some time until all shader and overlay assets are extracted...") + "This is your first time starting up RetroArch. Please be aware that it might take some time until all shader and overlay assets are extracted ...") .setPositiveButton("OK", null); alert.show(); } @@ -370,17 +353,21 @@ public class MainMenuActivity extends PreferenceActivity { writer.close(); } } - - private void extractAssets() { + + private int getVersionCode() { int version = 0; try { version = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; } catch (NameNotFoundException e) { - // weird exception, shouldn't happen } - + + return version; + } + + private boolean areAssetsExtracted() { + int version = getVersionCode(); + try { - AssetManager assets = getAssets(); String dataDir = getApplicationInfo().dataDir; File cacheVersion = new File(dataDir, ".cacheversion"); if (cacheVersion != null && cacheVersion.isFile() @@ -397,9 +384,22 @@ public class MainMenuActivity extends PreferenceActivity { if (currentCacheVersion == version) { Log.i("ASSETS", "Assets already extracted, skipping..."); - return; + return true; } } + } catch (IOException e) { + Log.e(TAG, "Failed to extract assets to cache."); + return false; + } + + return false; + } + + private void extractAssetsThread() { + try { + AssetManager assets = getAssets(); + String dataDir = getApplicationInfo().dataDir; + File cacheVersion = new File(dataDir, ".cacheversion"); // extractAssets(assets, cacheDir, "", 0); Log.i("ASSETS", "Extracting shader assets now ..."); @@ -418,22 +418,51 @@ public class MainMenuActivity extends PreferenceActivity { DataOutputStream outputCacheVersion = new DataOutputStream( new FileOutputStream(cacheVersion, false)); - outputCacheVersion.writeInt(version); + outputCacheVersion.writeInt(getVersionCode()); outputCacheVersion.close(); } catch (IOException e) { Log.e(TAG, "Failed to extract assets to cache."); } } + private void extractAssets() { + if (areAssetsExtracted()) + return; + + final Dialog dialog = new Dialog(this); + final Handler handler = new Handler(); + dialog.setContentView(R.layout.assets); + dialog.setCancelable(false); + + // Java is fun :) + Thread assetsThread = new Thread(new Runnable() { + public void run() { + extractAssetsThread(); + handler.post(new Runnable() { + public void run() { + dialog.dismiss(); + } + }); + } + }); + assetsThread.start(); + + dialog.show(); + } + boolean detectDevice(boolean show_dialog) { boolean retval = false; + + boolean mentionPlayStore = !android.os.Build.MODEL.equals("OUYA Console"); + final String message = "The ideal configuration options for your device will now be preconfigured.\n\nNOTE: For optimal performance, turn off Google Account sync, " + + (mentionPlayStore ? "Google Play Store auto-updates, " : "") + + "GPS and Wi-Fi in your Android settings menu."; Log.i("Device MODEL", android.os.Build.MODEL); if (android.os.Build.MODEL.equals("SHIELD")) { AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("NVidia Shield detected") - .setMessage( - "The ideal configuration options for your device will now be preconfigured.\nNOTE: For optimal performance, turn off Google Account sync, Google Play Store auto-updates, GPS and Wifi in your Android settings menu.") + .setMessage(message) .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override @@ -457,8 +486,7 @@ public class MainMenuActivity extends PreferenceActivity { } else if (android.os.Build.MODEL.equals("OUYA Console")) { AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("OUYA detected") - .setMessage( - "The ideal configuration options for your device will now be preconfigured.\nNOTE: For optimal performance, turn off Google Account sync, GPS and Wifi in your Android settings menu.") + .setMessage(message) .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override @@ -480,8 +508,7 @@ public class MainMenuActivity extends PreferenceActivity { } else if (android.os.Build.ID.equals("JSS15J")) { AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("Nexus 7 2013 detected") - .setMessage( - "The ideal configuration options for your device will now be preconfigured.\nNOTE: For optimal performance, turn off Google Account sync, Google Play Store auto-updates, GPS and Wifi in your Android settings menu.") + .setMessage(message) .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override diff --git a/android/phoenix/src/org/retroarch/browser/OverlayActivity.java b/android/phoenix/src/org/retroarch/browser/OverlayActivity.java index b92b190a14..38981f6b87 100644 --- a/android/phoenix/src/org/retroarch/browser/OverlayActivity.java +++ b/android/phoenix/src/org/retroarch/browser/OverlayActivity.java @@ -7,7 +7,6 @@ import android.os.Bundle; public class OverlayActivity extends DirectoryActivity { @Override public void onCreate(Bundle savedInstanceState) { - MainMenuActivity.waitAssetThread(); File overlayDir = new File(getBaseContext().getApplicationInfo().dataDir, "overlays"); if (overlayDir.exists()) super.setStartDirectory(overlayDir.getAbsolutePath()); diff --git a/android/phoenix/src/org/retroarch/browser/ShaderActivity.java b/android/phoenix/src/org/retroarch/browser/ShaderActivity.java index 707363b19e..3fb705de94 100644 --- a/android/phoenix/src/org/retroarch/browser/ShaderActivity.java +++ b/android/phoenix/src/org/retroarch/browser/ShaderActivity.java @@ -7,7 +7,6 @@ import android.os.Bundle; public class ShaderActivity extends DirectoryActivity { @Override public void onCreate(Bundle savedInstanceState) { - MainMenuActivity.waitAssetThread(); File shaderDir = new File(getBaseContext().getApplicationInfo().dataDir, "shaders_glsl"); if (shaderDir.exists()) super.setStartDirectory(shaderDir.getAbsolutePath()); From c539b82a70afb2460a3bd17eaffe3d2d79fcfef7 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 16 Aug 2013 15:46:37 +0200 Subject: [PATCH 045/202] Display dialog title. --- android/phoenix/src/org/retroarch/browser/MainMenuActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 037cee4b1b..e668b40757 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -433,6 +433,7 @@ public class MainMenuActivity extends PreferenceActivity { final Handler handler = new Handler(); dialog.setContentView(R.layout.assets); dialog.setCancelable(false); + dialog.setTitle("Asset extraction"); // Java is fun :) Thread assetsThread = new Thread(new Runnable() { From 849c14d8a202d194c3e223d0823efabb93441755 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 16 Aug 2013 17:07:09 +0200 Subject: [PATCH 046/202] (Android) Bumped up to r22 --- android/phoenix/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index c8cbc8ecf4..f934fc894c 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -1,6 +1,6 @@ From 7d25e64fb446af37ccc50693e5662d8d48b655e5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 16 Aug 2013 17:08:53 +0200 Subject: [PATCH 047/202] (Android) Update CHANGELOG for version 0.9.9.6 --- dist-scripts/retroarch-CHANGELOG.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dist-scripts/retroarch-CHANGELOG.txt b/dist-scripts/retroarch-CHANGELOG.txt index 8263a4e4c0..1d15c41024 100644 --- a/dist-scripts/retroarch-CHANGELOG.txt +++ b/dist-scripts/retroarch-CHANGELOG.txt @@ -5,6 +5,9 @@ v0.9.9.6 battle screens etc. * [VBA Next] Add a core option to change the control button layout from (left to right) B to A to (left to right) A to B. +* [Android] Added Load Game History to Android Java UI +* [Android] Will show a progressbar dialog during asset extraction so that the +user knows what is happening. ------------------------------------------------------------------------------ v0.9.9.5 From a4dfd35ab72b6f6e2f94331fe12ec17b2728fe29 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 15 Aug 2013 19:28:51 -0400 Subject: [PATCH 048/202] (Apple) Improvements: Add core gl context support on OSX Add support for multiple game pads on OSX Remove block on analog input for Player 2-4's game pads --- apple/OSX/hid_pad.c | 12 ++++++- apple/OSX/platform.h | 2 +- apple/RetroArch/RAGameView.m | 60 +++++++++++++++++++++++++--------- apple/RetroArch/apple_joypad.c | 2 +- gfx/context/apple_gl_ctx.c | 2 +- gfx/gl.c | 4 +-- 6 files changed, 61 insertions(+), 21 deletions(-) diff --git a/apple/OSX/hid_pad.c b/apple/OSX/hid_pad.c index 79c453e9b3..33bb819b9e 100644 --- a/apple/OSX/hid_pad.c +++ b/apple/OSX/hid_pad.c @@ -19,6 +19,7 @@ // NOTE: I pieced this together through trial and error, any corrections are welcome static IOHIDManagerRef g_hid_manager; +static uint32_t g_num_pads; static void hid_input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef inIOHIDValueRef) { @@ -83,9 +84,18 @@ static void hid_input_callback(void* inContext, IOReturn inResult, void* inSende static void hid_device_attached(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice) { + void* context = 0; + + if (IOHIDDeviceConformsTo(inDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)) + { + if (g_num_pads > 4) + return; + context = (void*)(g_num_pads++); + } + IOHIDDeviceOpen(inDevice, kIOHIDOptionsTypeNone); IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - IOHIDDeviceRegisterInputValueCallback(inDevice, hid_input_callback, 0); + IOHIDDeviceRegisterInputValueCallback(inDevice, hid_input_callback, context); } static void hid_device_removed(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice) diff --git a/apple/OSX/platform.h b/apple/OSX/platform.h index f858ade962..b35cf774af 100644 --- a/apple/OSX/platform.h +++ b/apple/OSX/platform.h @@ -19,7 +19,7 @@ #import -@interface RAGameView : NSOpenGLView +@interface RAGameView : NSView + (RAGameView*)get; - (void)display; diff --git a/apple/RetroArch/RAGameView.m b/apple/RetroArch/RAGameView.m index daa9fd97e9..4b9c592f33 100644 --- a/apple/RetroArch/RAGameView.m +++ b/apple/RetroArch/RAGameView.m @@ -35,6 +35,7 @@ static UIView* g_pause_indicator_view; static RAGameView* g_instance; static NSOpenGLContext* g_context; +static NSOpenGLPixelFormat* g_format; #define g_view g_instance // < RAGameView is a container on iOS; on OSX these are both the same object @@ -57,25 +58,22 @@ static float g_screen_scale = 1.0f; - (id)init { - static const NSOpenGLPixelFormatAttribute attributes [] = { - NSOpenGLPFAWindow, - NSOpenGLPFADoubleBuffer, // double buffered - NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)16, // 16 bit depth buffer - (NSOpenGLPixelFormatAttribute)nil - }; - - self = [super initWithFrame:CGRectMake(0, 0, 100, 100) pixelFormat:[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]]; - self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; - - g_context = self.openGLContext; - [g_context makeCurrentContext]; - + self = [super init]; + self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; return self; } +- (void)setFrame:(NSRect)frameRect +{ + [super setFrame:frameRect]; + + if (g_view && g_context) + [g_context update]; +} + - (void)display { - [self.openGLContext flushBuffer]; + [g_context flushBuffer]; } - (void)bindDrawable @@ -237,6 +235,38 @@ void apple_destroy_game_view() #endif } +bool apple_create_gl_context(uint32_t version) +{ +#ifdef OSX + [NSOpenGLContext clearCurrentContext]; + + dispatch_sync(dispatch_get_main_queue(), ^{ + [NSOpenGLContext clearCurrentContext]; + [g_context clearDrawable]; + g_context = nil; + g_format = nil; + + NSOpenGLPixelFormatAttribute attributes [] = { + NSOpenGLPFADoubleBuffer, // double buffered + NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)16, // 16 bit depth buffer + version ? NSOpenGLPFAOpenGLProfile : 0, version, + (NSOpenGLPixelFormatAttribute)nil + }; + + g_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; + g_context = [[NSOpenGLContext alloc] initWithFormat:g_format shareContext:nil]; + g_context.view = g_view; + [g_context makeCurrentContext]; + }); + + [g_context makeCurrentContext]; + +#endif + + return true; + +} + void apple_flip_game_view() { if (--g_fast_forward_skips < 0) @@ -255,7 +285,7 @@ void apple_set_game_view_sync(unsigned interval) g_fast_forward_skips = interval ? 0 : 3; #elif defined(OSX) GLint value = interval ? 1 : 0; - [g_view.openGLContext setValues:&value forParameter:NSOpenGLCPSwapInterval]; + [g_context setValues:&value forParameter:NSOpenGLCPSwapInterval]; #endif } diff --git a/apple/RetroArch/apple_joypad.c b/apple/RetroArch/apple_joypad.c index 312f245b43..76a8dc2853 100644 --- a/apple/RetroArch/apple_joypad.c +++ b/apple/RetroArch/apple_joypad.c @@ -56,7 +56,7 @@ static bool apple_joypad_button(unsigned port, uint16_t joykey) static int16_t apple_joypad_axis(unsigned port, uint32_t joyaxis) { - if (joyaxis == AXIS_NONE || port != 0) + if (joyaxis == AXIS_NONE) return 0; int16_t val = 0; diff --git a/gfx/context/apple_gl_ctx.c b/gfx/context/apple_gl_ctx.c index 3fc50861b2..d8db42630f 100644 --- a/gfx/context/apple_gl_ctx.c +++ b/gfx/context/apple_gl_ctx.c @@ -34,7 +34,7 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned mino #ifdef IOS return api == GFX_CTX_OPENGL_ES_API; #else - return api == GFX_CTX_OPENGL_API; + return apple_create_gl_context((major << 12) | (minor << 8)); #endif } diff --git a/gfx/gl.c b/gfx/gl.c index 768e79631c..7a62910a78 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -153,7 +153,7 @@ static bool check_sync_proc(gl_t *gl) #ifndef HAVE_OPENGLES static bool init_vao(gl_t *gl) { - if (!gl_query_extension(gl, "ARB_vertex_array_object")) + if (!gl->core_context && !gl_query_extension(gl, "ARB_vertex_array_object")) return false; bool present = glGenVertexArrays && glBindVertexArray && glDeleteVertexArrays; @@ -184,7 +184,7 @@ static bool init_vao(gl_t *gl) #elif !defined(HAVE_OPENGLES2) static bool check_fbo_proc(gl_t *gl) { - if (!gl_query_extension(gl, "ARB_framebuffer_object")) + if (!gl->core_context && !gl_query_extension(gl, "ARB_framebuffer_object")) return false; return glGenFramebuffers && glBindFramebuffer && glFramebufferTexture2D && From 7f480342a4f9d27dce5b210725d178ce0983c3d7 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 17 Aug 2013 23:35:32 +0200 Subject: [PATCH 049/202] (Android Phoenix) Add GameMID BT autodetection --- .../retroarch/browser/MainMenuActivity.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index e668b40757..e5662fbec7 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -484,6 +484,29 @@ public class MainMenuActivity extends PreferenceActivity { }); alert.show(); retval = true; + } else if (android.os.Build.MODEL.equals("GAMEMID_BT")) { + AlertDialog.Builder alert = new AlertDialog.Builder(this) + .setTitle("GameMID detected") + .setMessage(message) + .setPositiveButton("OK", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor edit = prefs + .edit(); + edit.putBoolean("input_overlay_enable", + false); + edit.putBoolean("input_autodetect_enable", + true); + edit.putBoolean("audio_high_latency", true); + edit.commit(); + } + }); + alert.show(); + retval = true; } else if (android.os.Build.MODEL.equals("OUYA Console")) { AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("OUYA detected") From 744d2d169e544ba6540d8bfaffe5c080fcdc9a6e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 18 Aug 2013 03:04:03 +0200 Subject: [PATCH 050/202] (Android Phoenix) Take out 'welcome to Android' popup --- android/phoenix/AndroidManifest.xml | 2 +- .../src/org/retroarch/browser/MainMenuActivity.java | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index f934fc894c..0d6ebfe3a9 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -1,6 +1,6 @@ diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index e5662fbec7..fd89186fee 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -49,7 +49,7 @@ public class MainMenuActivity extends PreferenceActivity { AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("Welcome to RetroArch") .setMessage( - "This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience. Please be aware that it might take some time until all shader and overlay assets are extracted ...") + "This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience.") .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override @@ -64,13 +64,6 @@ public class MainMenuActivity extends PreferenceActivity { } }); alert.show(); - } else { - AlertDialog.Builder alert = new AlertDialog.Builder(this) - .setTitle("Welcome to RetroArch") - .setMessage( - "This is your first time starting up RetroArch. Please be aware that it might take some time until all shader and overlay assets are extracted ...") - .setPositiveButton("OK", null); - alert.show(); } } } From 6018b4b9de59dcafdf0fc466418f0311d09a127d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 18 Aug 2013 07:12:23 +0200 Subject: [PATCH 051/202] (Android) Set GameMID analog mode to 'Dual analog' at startup --- android/native/jni/input_android.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/native/jni/input_android.c b/android/native/jni/input_android.c index f34b69c8ff..af59fbdb3b 100644 --- a/android/native/jni/input_android.c +++ b/android/native/jni/input_android.c @@ -423,7 +423,7 @@ static void android_input_set_keybinds(void *data, unsigned device, break; case DEVICE_GAMEMID: g_settings.input.device[port] = device; - g_settings.input.dpad_emulation[port] = ANALOG_DPAD_NONE; + g_settings.input.dpad_emulation[port] = ANALOG_DPAD_DUALANALOG; strlcpy(g_settings.input.device_names[port], "GameMID", sizeof(g_settings.input.device_names[port])); From f4ff5f3ea3d11452f0b9c5a28665fcf3687ef4d2 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Sun, 18 Aug 2013 02:50:10 -0400 Subject: [PATCH 052/202] [EMSCRIPTEN] less workarounds due to fixes in emscripten, enable more optimizations --- Makefile.emscripten | 22 ++++++++++++++++------ frontend/frontend_emscripten.c | 27 ++++++++++++++++++++++++--- gfx/context/emscriptenegl_ctx.c | 11 +++++------ input/sdl_input.c | 7 +------ 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/Makefile.emscripten b/Makefile.emscripten index f4ba2700a7..52f9711060 100644 --- a/Makefile.emscripten +++ b/Makefile.emscripten @@ -47,16 +47,19 @@ HAVE_FREETYPE = 1 HAVE_ZLIB = 1 HAVE_FBO = 1 WANT_MINIZ = 1 +MEMORY = 67108864 +LTO = 0 +FAST_DOUBLES = 1 ifneq ($(NATIVE_ZLIB),) WANT_MINIZ = 0 endif -libretro ?= -lretro_emscripten +libretro = libretro_emscripten.bc LIBS = -lm DEFINES = -DHAVE_SCREENSHOTS -DHAVE_NULLAUDIO -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.9.3\" -LDFLAGS = -L. -static-libgcc -s TOTAL_MEMORY=268435456 +LDFLAGS = -L. -s TOTAL_MEMORY=$(MEMORY) ifeq ($(SCALER_NO_SIMD), 1) DEFINES += -DSCALER_NO_SIMD @@ -105,8 +108,6 @@ ifeq ($(HAVE_ZLIB), 1) endif endif -LIBS += $(libretro) - ifeq ($(HAVE_FBO), 1) DEFINES += -DHAVE_FBO endif @@ -117,8 +118,17 @@ endif ifeq ($(DEBUG), 1) LDFLAGS += -O0 -g + CFLAGS += -O0 -g else - LDFLAGS += -O2 -ffast-math + LDFLAGS += -O2 + # WARNING: some optimizations can break some cores (ex: LTO breaks tyrquake) + ifeq ($(FAST_DOUBLES), 1) + LDFLAGS += -s DOUBLE_MODE=0 + endif + ifeq ($(LTO), 1) + LDFLAGS += --llvm-lto 3 + endif + CFLAGS += -O2 endif CFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -I. -std=gnu99 @@ -127,7 +137,7 @@ all: $(TARGET) $(TARGET): $(OBJ) @$(if $(Q), $(shell echo echo LD $@),) - $(Q)$(LD) -o $@ $(OBJ) $(LIBS) $(LDFLAGS) + $(Q)$(LD) -o $@ $(OBJ) $(libretro) $(LIBS) $(LDFLAGS) %.o: %.c @$(if $(Q), $(shell echo echo CC $<),) diff --git a/frontend/frontend_emscripten.c b/frontend/frontend_emscripten.c index 745096e0b4..cfa762ae1f 100644 --- a/frontend/frontend_emscripten.c +++ b/frontend/frontend_emscripten.c @@ -31,12 +31,33 @@ static bool menuloop; -void mainloop(void) +static void endloop(void) +{ + g_extern.system.shutdown = false; + menu_free(); + + if (g_extern.config_save_on_exit && *g_extern.config_path) + config_save_file(g_extern.config_path); + + if (g_extern.main_is_init) + rarch_main_deinit(); + + rarch_deinit_msg_queue(); + +#ifdef PERF_TEST + rarch_perf_log(); +#endif + + rarch_main_clear_state(); + + exit(0); +} + +static void mainloop(void) { if (g_extern.system.shutdown) { - RARCH_ERR("Exit...\n"); - exit(0); + endloop(); } else if (menuloop) { diff --git a/gfx/context/emscriptenegl_ctx.c b/gfx/context/emscriptenegl_ctx.c index e0778fe973..9c5f2516bd 100644 --- a/gfx/context/emscriptenegl_ctx.c +++ b/gfx/context/emscriptenegl_ctx.c @@ -30,14 +30,12 @@ #include #include -#include #include static EGLContext g_egl_ctx; static EGLSurface g_egl_surf; static EGLDisplay g_egl_dpy; static EGLConfig g_config; -static bool g_quit; static bool g_inited; @@ -58,12 +56,13 @@ static void gfx_ctx_check_window(bool *quit, (void)height; *resize = false; - *quit = g_quit; + *quit = false; } static void gfx_ctx_swap_buffers(void) { - eglSwapBuffers(g_egl_dpy, g_egl_surf); + // no-op in emscripten, no way to force swap/wait for vsync in browsers + //eglSwapBuffers(g_egl_dpy, g_egl_surf); } static void gfx_ctx_set_resize(unsigned width, unsigned height) @@ -209,7 +208,7 @@ static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data { *input = NULL; - if (SDL_Init(SDL_INIT_VIDEO) != 0) + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) != 0) return; void *sdlinput = input_sdl.init(); @@ -228,7 +227,7 @@ static bool gfx_ctx_has_focus(void) static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol) { - return SDL_GL_GetProcAddress(symbol); + return eglGetProcAddress(symbol); } static float gfx_ctx_translate_aspect(unsigned width, unsigned height) diff --git a/input/sdl_input.c b/input/sdl_input.c index a5dd282c85..57c9a32b91 100644 --- a/input/sdl_input.c +++ b/input/sdl_input.c @@ -24,7 +24,7 @@ #include "../libretro.h" #include "input_common.h" -#if !(SDL_MAJOR_VERSION <= 1 && SDL_MINOR_VERSION <= 2) +#ifdef EMSCRIPTEN #define SDL_GetKeyState SDL_GetKeyboardState #endif @@ -232,12 +232,7 @@ static void sdl_poll_mouse(sdl_input_t *sdl) static void sdl_input_poll(void *data) { -#ifdef EMSCRIPTEN - SDL_Event event; - while (SDL_PollEvent(&event)); -#else SDL_PumpEvents(); -#endif sdl_input_t *sdl = (sdl_input_t*)data; input_joypad_poll(sdl->joypad); From 12f4b48e84956009dc20aa9241d71f301f4b5258 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Sun, 18 Aug 2013 03:02:42 -0400 Subject: [PATCH 053/202] query for OES_EGL_image before trying to load symbol --- gfx/gl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gfx/gl.c b/gfx/gl.c index bec4389a92..cd96295c9a 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -115,6 +115,9 @@ static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC pglEGLImageTargetTexture2DOES; static bool load_eglimage_proc(gl_t *gl) { + if (!gl_query_extension("OES_EGL_image")) + return false; + LOAD_GL_SYM(EGLImageTargetTexture2DOES); return pglEGLImageTargetTexture2DOES; } From 8614c349f35831b395ce393380ad30875d67f9bf Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 18 Aug 2013 14:00:18 +0200 Subject: [PATCH 054/202] Use correct overlay configs. Saves input_overlay as well on exit. --- retroarch.cfg | 6 ++++++ settings.c | 13 ++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/retroarch.cfg b/retroarch.cfg index 0e09db086e..dafd3b0847 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -210,6 +210,12 @@ # Path to input overlay # input_overlay = +# Overlay opacity +# input_overlay_opacity = 1.0 + +# Overlay scale +# input_overlay_scale = 1.0 + # Enable input auto-detection. Will attempt to autoconfigure # joypads, Plug-and-Play style. # input_autodetect_enable = true diff --git a/settings.c b/settings.c index 4cfc84e2da..4b9dd32237 100644 --- a/settings.c +++ b/settings.c @@ -664,8 +664,9 @@ bool config_load_file(const char *path) if (!strcmp(g_extern.overlay_dir, "default")) *g_extern.overlay_dir = '\0'; - CONFIG_GET_FLOAT(input.overlay_opacity, "overlay_opacity"); - CONFIG_GET_FLOAT(input.overlay_scale, "overlay_scale"); + CONFIG_GET_PATH(input.overlay, "input_overlay"); + CONFIG_GET_FLOAT(input.overlay_opacity, "input_overlay_opacity"); + CONFIG_GET_FLOAT(input.overlay_scale, "input_overlay_scale"); #endif CONFIG_GET_BOOL(rewind_enable, "rewind_enable"); @@ -702,9 +703,6 @@ bool config_load_file(const char *path) CONFIG_GET_INT(input.turbo_period, "input_turbo_period"); CONFIG_GET_INT(input.turbo_duty_cycle, "input_duty_cycle"); - CONFIG_GET_PATH(input.overlay, "input_overlay"); - CONFIG_GET_FLOAT(input.overlay_opacity, "input_overlay_opacity"); - CONFIG_GET_FLOAT(input.overlay_scale, "input_overlay_scale"); CONFIG_GET_BOOL(input.debug_enable, "input_debug_enable"); CONFIG_GET_BOOL(input.autodetect_enable, "input_autodetect_enable"); @@ -1014,8 +1012,9 @@ bool config_save_file(const char *path) else config_set_string(conf, "overlay_directory", "default"); - config_set_float(conf, "overlay_opacity", g_settings.input.overlay_opacity); - config_set_float(conf, "overlay_scale", g_settings.input.overlay_scale); + config_set_string(conf, "input_overlay", g_settings.input.overlay); + config_set_float(conf, "input_overlay_opacity", g_settings.input.overlay_opacity); + config_set_float(conf, "input_overlay_scale", g_settings.input.overlay_scale); #endif #ifdef ANDROID From f8c385a28c19290a5eafa8d0636c451ee6aa3ccb Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 18 Aug 2013 18:06:55 +0200 Subject: [PATCH 055/202] Fix cg2glsl when uniform half4x4 is used. --- tools/cg2glsl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cg2glsl.py b/tools/cg2glsl.py index d8e20efe1e..7f2f341f29 100755 --- a/tools/cg2glsl.py +++ b/tools/cg2glsl.py @@ -537,7 +537,7 @@ def preprocess_vertex(source_data): input_data = source_data.split('\n') ret = [] for line in input_data: - if ('uniform' in line) and ('float4x4' in line): + if ('uniform' in line) and (('float4x4' in line) or ('half4x4' in line)): ret.append('#pragma pack_matrix(column_major)\n') ret.append(line) ret.append('#pragma pack_matrix(row_major)\n') From 8b8e33ed9220475d54dea6c12df158825484fd9b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 18 Aug 2013 18:20:03 +0200 Subject: [PATCH 056/202] (Android) Take out context menu in CoreSelection - also reduces code bloat - IME selector should go in Input Settings menu --- .../org/retroarch/browser/CoreSelection.java | 63 ------------------- .../retroarch/browser/HoneycombPopupMenu.java | 49 --------------- .../org/retroarch/browser/LazyPopupMenu.java | 15 ----- .../retroarch/browser/PopupMenuAbstract.java | 60 ------------------ 4 files changed, 187 deletions(-) delete mode 100644 android/phoenix/src/org/retroarch/browser/HoneycombPopupMenu.java delete mode 100644 android/phoenix/src/org/retroarch/browser/LazyPopupMenu.java delete mode 100644 android/phoenix/src/org/retroarch/browser/PopupMenuAbstract.java diff --git a/android/phoenix/src/org/retroarch/browser/CoreSelection.java b/android/phoenix/src/org/retroarch/browser/CoreSelection.java index 72f5e67beb..bba173ce90 100644 --- a/android/phoenix/src/org/retroarch/browser/CoreSelection.java +++ b/android/phoenix/src/org/retroarch/browser/CoreSelection.java @@ -12,8 +12,6 @@ import android.provider.Settings; import android.widget.*; import android.util.Log; import android.view.*; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.inputmethod.*; // JELLY_BEAN_MR1 = 17 @@ -90,10 +88,6 @@ public class CoreSelection extends Activity implements } this.setVolumeControlStream(AudioManager.STREAM_MUSIC); - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - this.registerForContextMenu(findViewById(android.R.id.content)); - } } @Override @@ -132,61 +126,4 @@ public class CoreSelection extends Activity implements break; } } - - @Override - public boolean onCreateOptionsMenu(Menu aMenu) { - super.onCreateOptionsMenu(aMenu); - getMenuInflater().inflate(R.menu.directory_list, aMenu); - return true; - } - - public void showPopup(View v) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - PopupMenuAbstract menu = new PopupMenuAbstract(this, v); - MenuInflater inflater = menu.getMenuInflater(); - inflater.inflate(R.menu.context_menu, menu.getMenu()); - menu.setOnMenuItemClickListener(new PopupMenuAbstract.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - return onContextItemSelected(item); - } - - }); - menu.show(); - } else { - this.openContextMenu(findViewById(android.R.id.content)); - } - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.context_menu, menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem aItem) { - switch (aItem.getItemId()) { - case R.id.settings: - showPopup(findViewById(R.id.settings)); - return true; - - default: - return super.onOptionsItemSelected(aItem); - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.input_method_select: - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showInputMethodPicker(); - return true; - default: - return false; - } - } } diff --git a/android/phoenix/src/org/retroarch/browser/HoneycombPopupMenu.java b/android/phoenix/src/org/retroarch/browser/HoneycombPopupMenu.java deleted file mode 100644 index ca4026a913..0000000000 --- a/android/phoenix/src/org/retroarch/browser/HoneycombPopupMenu.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.retroarch.browser; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.widget.PopupMenu; - -@TargetApi(Build.VERSION_CODES.HONEYCOMB) -class HoneycombPopupMenu extends LazyPopupMenu { - private PopupMenu instance; - HoneycombPopupMenu.OnMenuItemClickListener listen; - - public HoneycombPopupMenu(Context context, View anchor) - { - instance = new PopupMenu(context, anchor); - } - - @Override - public void setOnMenuItemClickListener(HoneycombPopupMenu.OnMenuItemClickListener listener) - { - listen = listener; - instance.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - return listen.onMenuItemClick(item); - } - - }); - } - - @Override - public Menu getMenu() { - return instance.getMenu(); - } - - @Override - public MenuInflater getMenuInflater() { - return instance.getMenuInflater(); - } - - @Override - public void show() { - instance.show(); - } -} diff --git a/android/phoenix/src/org/retroarch/browser/LazyPopupMenu.java b/android/phoenix/src/org/retroarch/browser/LazyPopupMenu.java deleted file mode 100644 index 9e72cb5622..0000000000 --- a/android/phoenix/src/org/retroarch/browser/LazyPopupMenu.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.retroarch.browser; - -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; - -abstract class LazyPopupMenu { - public abstract Menu getMenu(); - public abstract MenuInflater getMenuInflater(); - public abstract void setOnMenuItemClickListener(LazyPopupMenu.OnMenuItemClickListener listener); - public abstract void show(); - public interface OnMenuItemClickListener { - public abstract boolean onMenuItemClick(MenuItem item); - } -} \ No newline at end of file diff --git a/android/phoenix/src/org/retroarch/browser/PopupMenuAbstract.java b/android/phoenix/src/org/retroarch/browser/PopupMenuAbstract.java deleted file mode 100644 index 5477a187d7..0000000000 --- a/android/phoenix/src/org/retroarch/browser/PopupMenuAbstract.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.retroarch.browser; - -import android.content.Context; -import android.os.Build; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.View; - -class PopupMenuAbstract extends LazyPopupMenu -{ - private LazyPopupMenu lazy; - - public PopupMenuAbstract(Context context, View anchor) - { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) - { - lazy = new HoneycombPopupMenu(context, anchor); - } - } - - @Override - public Menu getMenu() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) - { - return lazy.getMenu(); - } - else - { - return null; - } - } - - @Override - public MenuInflater getMenuInflater() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) - { - return lazy.getMenuInflater(); - } - else - { - return null; - } - } - - @Override - public void setOnMenuItemClickListener(PopupMenuAbstract.OnMenuItemClickListener listener) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) - { - lazy.setOnMenuItemClickListener(listener); - } - } - - @Override - public void show() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) - { - lazy.show(); - } - } -} From 05ae971aae679a2be4f5d164e2271b871dd1ad96 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 18 Aug 2013 21:02:41 +0200 Subject: [PATCH 057/202] (Android) We now select a core first with 'Load Core', then select a game. Opens the door for per-core config files - also remembers the core from the last previous session --- android/phoenix/res/xml/prefs.xml | 9 +- .../org/retroarch/browser/CoreSelection.java | 38 +-------- .../retroarch/browser/HistorySelection.java | 4 +- .../retroarch/browser/MainMenuActivity.java | 85 ++++++++++++++++++- .../org/retroarch/browser/RetroTVMode.java | 2 +- 5 files changed, 96 insertions(+), 42 deletions(-) diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index 40f7d2c65f..bec349baa9 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -1,17 +1,22 @@ + android:title="RetroArch - Main Menu" > - + + + + adapter; - static private final int ACTIVITY_LOAD_ROM = 0; - static private String libretro_path; static private final String TAG = "CoreSelection"; @Override @@ -94,36 +90,8 @@ public class CoreSelection extends Activity implements public void onItemClick(AdapterView aListView, View aView, int aPosition, long aID) { final ModuleWrapper item = adapter.getItem(aPosition); - libretro_path = item.file.getAbsolutePath(); - - Intent myIntent; - myIntent = new Intent(this, ROMActivity.class); - startActivityForResult(myIntent, ACTIVITY_LOAD_ROM); - } - - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - Intent myIntent; - String current_ime = Settings.Secure.getString(getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD); - - MainMenuActivity.updateConfigFile(); - - switch (requestCode) { - case ACTIVITY_LOAD_ROM: - if (data.getStringExtra("PATH") != null) { - Toast.makeText(this, - "Loading: [" + data.getStringExtra("PATH") + "]...", - Toast.LENGTH_SHORT).show(); - myIntent = new Intent(this, RetroActivity.class); - myIntent.putExtra("ROM", data.getStringExtra("PATH")); - myIntent.putExtra("LIBRETRO", libretro_path); - myIntent.putExtra("CONFIGFILE", - MainMenuActivity.getDefaultConfigPath()); - myIntent.putExtra("IME", current_ime); - startActivity(myIntent); - finish(); - } - break; - } + MainMenuActivity.getInstance().setModule(item.file.getAbsolutePath(), item.getText()); + MainMenuActivity.getInstance().updateConfigFile(); + finish(); } } diff --git a/android/phoenix/src/org/retroarch/browser/HistorySelection.java b/android/phoenix/src/org/retroarch/browser/HistorySelection.java index 5e416469dd..f35b32c26d 100644 --- a/android/phoenix/src/org/retroarch/browser/HistorySelection.java +++ b/android/phoenix/src/org/retroarch/browser/HistorySelection.java @@ -62,12 +62,14 @@ public class HistorySelection extends Activity implements final HistoryWrapper item = adapter.getItem(aPosition); final String gamePath = item.getGamePath(); final String corePath = item.getCorePath(); + + MainMenuActivity.getInstance().setModule(corePath, item.getCoreName()); Intent myIntent; String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); - MainMenuActivity.updateConfigFile(); + MainMenuActivity.getInstance().updateConfigFile(); Toast.makeText(this, "Loading: [" + gamePath + "] ...", Toast.LENGTH_SHORT).show(); diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index fd89186fee..ea995f8808 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -9,6 +9,7 @@ import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetManager; @@ -18,6 +19,7 @@ import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; +import android.provider.Settings; import android.util.Log; import android.view.Display; import android.view.WindowManager; @@ -25,7 +27,10 @@ import android.widget.Toast; public class MainMenuActivity extends PreferenceActivity { private static MainMenuActivity instance = null; + static private final int ACTIVITY_LOAD_ROM = 0; static private final String TAG = "MainMenu"; + static private String libretro_path; + static private String libretro_name; @SuppressWarnings("deprecation") @Override @@ -66,6 +71,21 @@ public class MainMenuActivity extends PreferenceActivity { alert.show(); } } + + if (prefs.getString("libretro_path", "").isEmpty() == false) { + libretro_path = prefs.getString("libretro_path", ""); + setCoreTitle("No core"); + + if (prefs.getString("libretro_name", "").isEmpty() == false) { + libretro_name = prefs.getString("libretro_name", "No core"); + setCoreTitle(libretro_name); + } + } + else { + libretro_path = MainMenuActivity.getInstance().getApplicationInfo().nativeLibraryDir; + libretro_name = "No core"; + setCoreTitle("No core"); + } } public static MainMenuActivity getInstance() { @@ -179,7 +199,7 @@ public class MainMenuActivity extends PreferenceActivity { return "/mnt/sd/retroarch.cfg"; } - public static void updateConfigFile() { + public void updateConfigFile() { ConfigFile config; try { config = new ConfigFile(new File(getDefaultConfigPath())); @@ -190,8 +210,11 @@ public class MainMenuActivity extends PreferenceActivity { SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(MainMenuActivity.getInstance() .getBaseContext()); - config.setString("libretro_path", MainMenuActivity.getInstance() - .getApplicationInfo().nativeLibraryDir); + + config.setString("libretro_path", libretro_path); + config.setString("libretro_name", libretro_name); + setCoreTitle(libretro_name); + config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true)); config.setInt("audio_out_rate", @@ -443,6 +466,25 @@ public class MainMenuActivity extends PreferenceActivity { dialog.show(); } + + public void setModule(String core_path, String core_name) { + libretro_path = core_path; + libretro_name = core_name; + File libretro_path_file = new File(core_path); + setCoreTitle((libretro_path_file.isDirectory() == true) ? "No core" : core_name); + + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor edit = prefs + .edit(); + edit.putString("libretro_path", libretro_path); + edit.putString("libretro_name", libretro_name); + edit.commit(); + } + + public void setCoreTitle(String core_name) { + setTitle("RetroArch : " + core_name); + } boolean detectDevice(boolean show_dialog) { boolean retval = false; @@ -558,4 +600,41 @@ public class MainMenuActivity extends PreferenceActivity { protected void onStart() { super.onStart(); } + + @Override + public void startActivity(Intent intent) { + if (intent.getComponent().getClassName().equals("org.retroarch.browser.ROMActivity")) { + if (new File(libretro_path).isDirectory() == false) { + super.startActivityForResult(intent, ACTIVITY_LOAD_ROM); + } else { + Toast.makeText(this, + "Go to 'Load Core' and select a core first.", + Toast.LENGTH_SHORT).show(); + } + } else { + super.startActivity(intent); + } + } + + @Override + protected void onActivityResult(int reqCode, int resCode, Intent data) { + if (reqCode == ACTIVITY_LOAD_ROM) { + if (data.getStringExtra("PATH") != null) { + updateConfigFile(); + Intent myIntent; + String current_ime = Settings.Secure.getString(getContentResolver(), + Settings.Secure.DEFAULT_INPUT_METHOD); + Toast.makeText(this, + "Loading: [" + data.getStringExtra("PATH") + "]...", + Toast.LENGTH_SHORT).show(); + myIntent = new Intent(this, RetroActivity.class); + myIntent.putExtra("ROM", data.getStringExtra("PATH")); + myIntent.putExtra("LIBRETRO", libretro_path); + myIntent.putExtra("CONFIGFILE", + MainMenuActivity.getDefaultConfigPath()); + myIntent.putExtra("IME", current_ime); + startActivity(myIntent); + } + } + } } diff --git a/android/phoenix/src/org/retroarch/browser/RetroTVMode.java b/android/phoenix/src/org/retroarch/browser/RetroTVMode.java index 23ffcfe30e..60e84b9998 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroTVMode.java +++ b/android/phoenix/src/org/retroarch/browser/RetroTVMode.java @@ -11,7 +11,7 @@ public class RetroTVMode extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - MainMenuActivity.updateConfigFile(); + MainMenuActivity.getInstance().updateConfigFile(); Intent myIntent = new Intent(this, RetroActivity.class); String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); From 220411be67d94c6cffd165fe0e993b17edb987a2 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 19 Aug 2013 01:14:01 +0200 Subject: [PATCH 058/202] (Android Phoenix) Preliminary per-core config settings - maister: things like ROM path don't currently work correctly per core when configured individually - please look at it --- android/phoenix/res/xml/prefs.xml | 4 ++ .../retroarch/browser/MainMenuActivity.java | 39 ++++++++++++++----- .../org/retroarch/browser/ROMActivity.java | 2 +- .../org/retroarch/browser/ROMDirActivity.java | 2 +- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index bec349baa9..4d696d8411 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -123,6 +123,10 @@ + Date: Mon, 19 Aug 2013 15:55:53 +0200 Subject: [PATCH 059/202] (Android) Set RetroActivity to android:exported="true" --- android/phoenix/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index 0d6ebfe3a9..73af32ec05 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -42,7 +42,7 @@ - + From 9ce4684e14e699bf8ce450a9e9e15f9a711d8635 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 19 Aug 2013 22:59:54 +0200 Subject: [PATCH 060/202] Make sure ASPECT_RATIO_CUSTOM is set to something sane. --- frontend/menu/rgui.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index b95cea36e7..3edeec1b08 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -266,6 +266,10 @@ rgui_handle_t *rgui_init(void) aspectratio_lut[ASPECT_RATIO_CUSTOM].value = (float)custom->width / custom->height; } + else if (DEFAULT_ASPECT_RATIO > 0.0f) + aspectratio_lut[ASPECT_RATIO_CUSTOM].value = DEFAULT_ASPECT_RATIO; + else + aspectratio_lut[ASPECT_RATIO_CUSTOM].value = 4.0f / 3.0f; // Something arbitrary return rgui; } From 56674fb7f01903edc9ec72d2b1578ea08ac900f3 Mon Sep 17 00:00:00 2001 From: zevektor Date: Mon, 19 Aug 2013 23:23:39 +0200 Subject: [PATCH 061/202] Allow to load roms from external apps. --- .project | 11 + android/phoenix/AndroidManifest.xml | 4 +- .../retroarch/browser/MainMenuActivity.java | 203 ++++++++++-------- 3 files changed, 129 insertions(+), 89 deletions(-) create mode 100644 .project diff --git a/.project b/.project new file mode 100644 index 0000000000..871dee54b0 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + RetroArch_ + + + + + + + + diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index 73af32ec05..c44b3a1e1e 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -19,7 +19,7 @@ - + @@ -42,7 +42,7 @@ - + diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 45d1f6be74..35fe1c56b9 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -36,6 +36,13 @@ public class MainMenuActivity extends PreferenceActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Intent startedByIntent = getIntent(); + if (null != startedByIntent.getStringExtra("ROM") + && null != startedByIntent.getStringExtra("LIBRETRO")) { + loadRomExternal(startedByIntent.getStringExtra("ROM"), + startedByIntent.getStringExtra("LIBRETRO")); + return; + } instance = this; addPreferencesFromResource(R.xml.prefs); PreferenceManager.setDefaultValues(this, R.xml.prefs, false); @@ -45,7 +52,7 @@ public class MainMenuActivity extends PreferenceActivity { .getDefaultSharedPreferences(getBaseContext()); extractAssets(); - + if (!prefs.getBoolean("first_time_refreshrate_calculate", false)) { prefs.edit().putBoolean("first_time_refreshrate_calculate", true) .commit(); @@ -71,17 +78,16 @@ public class MainMenuActivity extends PreferenceActivity { alert.show(); } } - + if (prefs.getString("libretro_path", "").isEmpty() == false) { libretro_path = prefs.getString("libretro_path", ""); setCoreTitle("No core"); - + if (prefs.getString("libretro_name", "").isEmpty() == false) { libretro_name = prefs.getString("libretro_name", "No core"); setCoreTitle(libretro_name); } - } - else { + } else { libretro_path = MainMenuActivity.getInstance().getApplicationInfo().nativeLibraryDir; libretro_name = "No core"; setCoreTitle("No core"); @@ -168,21 +174,24 @@ public class MainMenuActivity extends PreferenceActivity { public static String getDefaultConfigPath() { String internal = System.getenv("INTERNAL_STORAGE"); String external = System.getenv("EXTERNAL_STORAGE"); - + SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(MainMenuActivity.getInstance() .getBaseContext()); - - boolean global_config_enable = prefs.getBoolean("global_config_enable", true); - boolean config_same_as_native_lib_dir = libretro_path.equals(MainMenuActivity.getInstance().getApplicationInfo().nativeLibraryDir); + + boolean global_config_enable = prefs.getBoolean("global_config_enable", + true); + boolean config_same_as_native_lib_dir = libretro_path + .equals(MainMenuActivity.getInstance().getApplicationInfo().nativeLibraryDir); String append_path; if (!global_config_enable && (config_same_as_native_lib_dir == false)) { - String sanitized_name = libretro_path.substring(libretro_path.lastIndexOf("/")+1,libretro_path.lastIndexOf(".")); + String sanitized_name = libretro_path.substring( + libretro_path.lastIndexOf("/") + 1, + libretro_path.lastIndexOf(".")); sanitized_name = sanitized_name.replace("neon", ""); - sanitized_name = sanitized_name.replace("libretro_",""); + sanitized_name = sanitized_name.replace("libretro_", ""); append_path = File.separator + sanitized_name + "retroarch.cfg"; - } - else { + } else { append_path = File.separator + "retroarch.cfg"; } @@ -200,13 +209,10 @@ public class MainMenuActivity extends PreferenceActivity { return confPath; } - if (internal != null - && new File(internal + append_path) - .canWrite()) + if (internal != null && new File(internal + append_path).canWrite()) return internal + append_path; else if (external != null - && new File(internal + append_path) - .canWrite()) + && new File(internal + append_path).canWrite()) return external + append_path; else if ((MainMenuActivity.getInstance().getApplicationInfo().dataDir) != null) return (MainMenuActivity.getInstance().getApplicationInfo().dataDir) @@ -227,11 +233,11 @@ public class MainMenuActivity extends PreferenceActivity { SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(MainMenuActivity.getInstance() .getBaseContext()); - + config.setString("libretro_path", libretro_path); config.setString("libretro_name", libretro_name); setCoreTitle(libretro_name); - + config.setString("rgui_browser_directory", prefs.getString("rgui_browser_directory", "")); config.setBoolean("global_config_enable", @@ -333,8 +339,9 @@ public class MainMenuActivity extends PreferenceActivity { config.setBoolean("video_font_enable", prefs.getBoolean("video_font_enable", true)); - - config.setString("game_history_path", MainMenuActivity.getInstance().getApplicationInfo().dataDir + "/retroarch-history.txt"); + + config.setString("game_history_path", MainMenuActivity.getInstance() + .getApplicationInfo().dataDir + "/retroarch-history.txt"); for (int i = 1; i <= 4; i++) { final String btns[] = { "up", "down", "left", "right", "a", "b", @@ -390,20 +397,20 @@ public class MainMenuActivity extends PreferenceActivity { writer.close(); } } - + private int getVersionCode() { int version = 0; try { version = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; } catch (NameNotFoundException e) { } - + return version; } - + private boolean areAssetsExtracted() { int version = getVersionCode(); - + try { String dataDir = getApplicationInfo().dataDir; File cacheVersion = new File(dataDir, ".cacheversion"); @@ -428,10 +435,10 @@ public class MainMenuActivity extends PreferenceActivity { Log.e(TAG, "Failed to extract assets to cache."); return false; } - + return false; } - + private void extractAssetsThread() { try { AssetManager assets = getAssets(); @@ -465,13 +472,13 @@ public class MainMenuActivity extends PreferenceActivity { private void extractAssets() { if (areAssetsExtracted()) return; - + final Dialog dialog = new Dialog(this); final Handler handler = new Handler(); dialog.setContentView(R.layout.assets); dialog.setCancelable(false); dialog.setTitle("Asset extraction"); - + // Java is fun :) Thread assetsThread = new Thread(new Runnable() { public void run() { @@ -484,36 +491,37 @@ public class MainMenuActivity extends PreferenceActivity { } }); assetsThread.start(); - + dialog.show(); } - + public void setModule(String core_path, String core_name) { - libretro_path = core_path; - libretro_name = core_name; + libretro_path = core_path; + libretro_name = core_name; File libretro_path_file = new File(core_path); - setCoreTitle((libretro_path_file.isDirectory() == true) ? "No core" : core_name); - + setCoreTitle((libretro_path_file.isDirectory() == true) ? "No core" + : core_name); + SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(getBaseContext()); - SharedPreferences.Editor edit = prefs - .edit(); + SharedPreferences.Editor edit = prefs.edit(); edit.putString("libretro_path", libretro_path); edit.putString("libretro_name", libretro_name); edit.commit(); } - + public void setCoreTitle(String core_name) { setTitle("RetroArch : " + core_name); } boolean detectDevice(boolean show_dialog) { boolean retval = false; - - boolean mentionPlayStore = !android.os.Build.MODEL.equals("OUYA Console"); - final String message = "The ideal configuration options for your device will now be preconfigured.\n\nNOTE: For optimal performance, turn off Google Account sync, " + - (mentionPlayStore ? "Google Play Store auto-updates, " : "") + - "GPS and Wi-Fi in your Android settings menu."; + + boolean mentionPlayStore = !android.os.Build.MODEL + .equals("OUYA Console"); + final String message = "The ideal configuration options for your device will now be preconfigured.\n\nNOTE: For optimal performance, turn off Google Account sync, " + + (mentionPlayStore ? "Google Play Store auto-updates, " : "") + + "GPS and Wi-Fi in your Android settings menu."; Log.i("Device MODEL", android.os.Build.MODEL); if (android.os.Build.MODEL.equals("SHIELD")) { @@ -542,27 +550,27 @@ public class MainMenuActivity extends PreferenceActivity { retval = true; } else if (android.os.Build.MODEL.equals("GAMEMID_BT")) { AlertDialog.Builder alert = new AlertDialog.Builder(this) - .setTitle("GameMID detected") - .setMessage(message) - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, - int which) { - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); - SharedPreferences.Editor edit = prefs - .edit(); - edit.putBoolean("input_overlay_enable", - false); - edit.putBoolean("input_autodetect_enable", - true); - edit.putBoolean("audio_high_latency", true); - edit.commit(); - } - }); - alert.show(); - retval = true; + .setTitle("GameMID detected") + .setMessage(message) + .setPositiveButton("OK", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor edit = prefs + .edit(); + edit.putBoolean("input_overlay_enable", + false); + edit.putBoolean("input_autodetect_enable", + true); + edit.putBoolean("audio_high_latency", true); + edit.commit(); + } + }); + alert.show(); + retval = true; } else if (android.os.Build.MODEL.equals("OUYA Console")) { AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("OUYA detected") @@ -621,30 +629,33 @@ public class MainMenuActivity extends PreferenceActivity { protected void onStart() { super.onStart(); } - - @Override - public void startActivity(Intent intent) { - if (intent.getComponent().getClassName().equals("org.retroarch.browser.ROMActivity")) { - if (new File(libretro_path).isDirectory() == false) { - super.startActivityForResult(intent, ACTIVITY_LOAD_ROM); - } else { + + @Override + public void startActivity(Intent intent) { + if (intent.getComponent().getClassName() + .equals("org.retroarch.browser.ROMActivity")) { + if (new File(libretro_path).isDirectory() == false) { + super.startActivityForResult(intent, ACTIVITY_LOAD_ROM); + } else { Toast.makeText(this, "Go to 'Load Core' and select a core first.", Toast.LENGTH_SHORT).show(); - } - } else { - super.startActivity(intent); - } - } + } + } else { + super.startActivity(intent); + } + } - @Override - protected void onActivityResult(int reqCode, int resCode, Intent data) { - if (reqCode == ACTIVITY_LOAD_ROM) { - if (data.getStringExtra("PATH") != null) { - updateConfigFile(); - Intent myIntent; - String current_ime = Settings.Secure.getString(getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD); + @Override + protected void onActivityResult(int reqCode, int resCode, Intent data) { + switch (reqCode) { + case ACTIVITY_LOAD_ROM: { + if (data.getStringExtra("PATH") != null) { + updateConfigFile(); + Intent myIntent; + String current_ime = Settings.Secure.getString( + getContentResolver(), + Settings.Secure.DEFAULT_INPUT_METHOD); Toast.makeText(this, "Loading: [" + data.getStringExtra("PATH") + "]...", Toast.LENGTH_SHORT).show(); @@ -656,6 +667,24 @@ public class MainMenuActivity extends PreferenceActivity { myIntent.putExtra("IME", current_ime); startActivity(myIntent); } - } - } + } + break; + } + } + + private void loadRomExternal(String rom, String core) { + + updateConfigFile(); + Intent myIntent = new Intent(this, RetroActivity.class); + String current_ime = Settings.Secure.getString(getContentResolver(), + Settings.Secure.DEFAULT_INPUT_METHOD); + Toast.makeText(this, "Loading: [" + rom + "]...", Toast.LENGTH_SHORT) + .show(); + myIntent.putExtra("ROM", rom); + myIntent.putExtra("LIBRETRO", core); + myIntent.putExtra("CONFIGFILE", MainMenuActivity.getDefaultConfigPath()); + myIntent.putExtra("IME", current_ime); + startActivity(myIntent); + + } } From 3409a6366646f492b98af3760da80c4d9cb9dd21 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Tue, 20 Aug 2013 14:55:44 -0500 Subject: [PATCH 062/202] enlarge dpad for snes-landscape --- media/overlays/snes-landscape.cfg | 34 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/media/overlays/snes-landscape.cfg b/media/overlays/snes-landscape.cfg index cac51d5d6f..700c8741ce 100644 --- a/media/overlays/snes-landscape.cfg +++ b/media/overlays/snes-landscape.cfg @@ -8,23 +8,23 @@ overlay0_full_screen = true overlay1_full_screen = true overlay0_descs = 18 -overlay0_desc0 = "left,28,389,rect,30,30" -overlay0_desc1 = "right,117,389,rect,30,30" -overlay0_desc2 = "up,73,344,rect,30,30" -overlay0_desc3 = "down,73,434,rect,30,30" -overlay0_desc4 = "select,71,218,rect,30,30" -overlay0_desc5 = "start,71,148,rect,30,30" -overlay0_desc6 = "b,707,432,radial,30,30" -overlay0_desc7 = "a,764,386,radial,30,30" -overlay0_desc8 = "x,707,338,radial,30,30" -overlay0_desc9 = "y,653,386,radial,30,30" -overlay0_desc10 = "l,70,31,rect,70,30" -overlay0_desc11 = "r,731,31,rect,70,30" +overlay0_desc0 = "left,12,389,rect,56,46" +overlay0_desc1 = "right,134,389,rect,56,46" +overlay0_desc2 = "up,71,334,rect,46,56" +overlay0_desc3 = "down,71,444,rect,46,56" +overlay0_desc4 = "select,71,218,rect,30,30" +overlay0_desc5 = "start,71,148,rect,30,30" +overlay0_desc6 = "b,707,444,radial,50,50" +overlay0_desc7 = "a,774,386,radial,50,50" +overlay0_desc8 = "x,707,320,radial,50,50" +overlay0_desc9 = "y,636,386,radial,50,50" +overlay0_desc10 = "l,70,31,rect,70,30" +overlay0_desc11 = "r,731,31,rect,70,30" overlay0_desc12 = "overlay_next,730,171,radial,30,30" -overlay0_desc13 = "left|up,28,344,radial,20,20" -overlay0_desc14 = "left|down,28,434,radial,20,20" -overlay0_desc15 = "right|up,117,344,radial,20,20" -overlay0_desc16 = "right|down,117,434,radial,20,20" +overlay0_desc13 = "left|up,18,324,radial,28,28" +overlay0_desc14 = "left|down,18,454,radial,28,28" +overlay0_desc15 = "right|up,140,324,radial,28,28" +overlay0_desc16 = "right|down,140,454,radial,28,28" overlay0_desc17 = "menu_toggle,401,443,radial,20,20" overlay1_descs = 11 @@ -42,4 +42,4 @@ overlay1_desc10 = "overlay_next,400,452,radial,22,22" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.07,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From 81b7c49fed795f8026ba18e216a2f0babe45184d Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Tue, 20 Aug 2013 14:56:17 -0500 Subject: [PATCH 063/202] enlarge dpad hitboxes for psx-landscape --- media/overlays/psx-landscape.cfg | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/media/overlays/psx-landscape.cfg b/media/overlays/psx-landscape.cfg index 18ea569070..efd92f8471 100644 --- a/media/overlays/psx-landscape.cfg +++ b/media/overlays/psx-landscape.cfg @@ -8,25 +8,25 @@ overlay0_full_screen = true overlay1_full_screen = true overlay0_descs = 20 -overlay0_desc0 = "left,34,395,rect,25,25" -overlay0_desc1 = "right,112,395,rect,25,25" -overlay0_desc2 = "up,70,356,rect,25,25" -overlay0_desc3 = "down,70,432,rect,25,25" +overlay0_desc0 = "left,8,384,rect,50,40" +overlay0_desc1 = "right,134,384,rect,50,40" +overlay0_desc2 = "up,72,334,rect,40,50" +overlay0_desc3 = "down,72,444,rect,40,50" overlay0_desc4 = "start,434,33,rect,30,17" overlay0_desc5 = "select,369,33,rect,30,17" -overlay0_desc6 = "a,776,390,radial,25,25" -overlay0_desc7 = "b,726,438,radial,25,25" -overlay0_desc8 = "x,726,338,radial,25,25" -overlay0_desc9 = "y,677,390,radial,25,25" +overlay0_desc6 = "a,776,390,radial,30,30" +overlay0_desc7 = "b,726,438,radial,30,30" +overlay0_desc8 = "x,726,338,radial,30,30" +overlay0_desc9 = "y,677,390,radial,30,30" overlay0_desc10 = "l,71,110,rect,47,27" overlay0_desc11 = "l2,70,37,rect,47,27" overlay0_desc12 = "r,730,110,rect,47,27" overlay0_desc13 = "r2,730,37,rect,47,27" overlay0_desc14 = "overlay_next,401,437,radial,20,20" -overlay0_desc15 = "left|up,34,356,radial,20,20" -overlay0_desc16 = "left|down,34,432,radial,20,20" -overlay0_desc17 = "right|up,112,356,radial,20,20" -overlay0_desc18 = "right|down,112,432,radial,20,20" +overlay0_desc15 = "left|up,10,324,radial,28,28" +overlay0_desc16 = "left|down,10,454,radial,28,28" +overlay0_desc17 = "right|up,140,324,radial,28,28" +overlay0_desc18 = "right|down,140,454,radial,28,28" overlay0_desc19 = "menu_toggle,732,217,rect,25,20" overlay1_descs = 11 @@ -44,4 +44,4 @@ overlay1_desc10 = "overlay_next,403,453,radial,25,25" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.07,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From 1e23c119e43116d4feea9d80b7e1dafb70164696 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Tue, 20 Aug 2013 14:57:30 -0500 Subject: [PATCH 064/202] enlarge dpad hitboxes for nes-landscape --- media/overlays/nes-landscape.cfg | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/media/overlays/nes-landscape.cfg b/media/overlays/nes-landscape.cfg index 8f3d94ef33..a7111e5729 100644 --- a/media/overlays/nes-landscape.cfg +++ b/media/overlays/nes-landscape.cfg @@ -8,19 +8,19 @@ overlay0_full_screen = true overlay1_full_screen = true overlay0_descs = 14 -overlay0_desc0 = "left,33,399,rect,20,20" -overlay0_desc1 = "right,122,399,rect,20,20" -overlay0_desc2 = "up,77,355,rect,20,20" -overlay0_desc3 = "down,77,443,rect,20,20" +overlay0_desc0 = "left,12,388,rect,50,36" +overlay0_desc1 = "right,134,388,rect,50,36" +overlay0_desc2 = "up,76,334,rect,40,50" +overlay0_desc3 = "down,76,444,rect,40,50" overlay0_desc4 = "select,54,35,rect,45,20" overlay0_desc5 = "start,745,35,rect,45,20" -overlay0_desc6 = "b,685,424,radial,30,30" -overlay0_desc7 = "a,759,424,radial,30,30" +overlay0_desc6 = "b,685,424,radial,46,46" +overlay0_desc7 = "a,759,424,radial,46,46" overlay0_desc8 = "overlay_next,743,204,radial,30,30" -overlay0_desc9 = "left|up,29,350,radial,20,20" -overlay0_desc10 = "left|down,29,440,radial,20,20" -overlay0_desc11 = "right|up,121,350,radial,20,20" -overlay0_desc12 = "right|down,121,440,radial,20,20" +overlay0_desc9 = "left|up,10,328,radial,26,26" +overlay0_desc10 = "left|down,10,454,radial,26,26" +overlay0_desc11 = "right|up,140,328,radial,26,26" +overlay0_desc12 = "right|down,140,454,radial,26,26" overlay0_desc13 = "menu_toggle,76,205,radial,20,20" overlay1_descs = 11 @@ -38,4 +38,4 @@ overlay1_desc10 = "overlay_next,400,452,radial,22,22" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.07,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From c0023d6cd15cb05d3dd7f2377f62285d88eb9fc5 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Tue, 20 Aug 2013 14:58:00 -0500 Subject: [PATCH 065/202] enlarge dpad hitboxes for genesis6-landscape --- media/overlays/genesis6-landscape.cfg | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/media/overlays/genesis6-landscape.cfg b/media/overlays/genesis6-landscape.cfg index 37c09a69d4..23318ea7c5 100644 --- a/media/overlays/genesis6-landscape.cfg +++ b/media/overlays/genesis6-landscape.cfg @@ -8,10 +8,10 @@ overlay0_full_screen = true overlay1_full_screen = true overlay0_descs = 17 -overlay0_desc0 = "left,34,393,rect,25,25" -overlay0_desc1 = "right,110,393,rect,25,25" -overlay0_desc2 = "up,70,360,rect,25,25" -overlay0_desc3 = "down,70,432,rect,25,25" +overlay0_desc0 = "left,12,389,rect,50,40" +overlay0_desc1 = "right,134,389,rect,50,40" +overlay0_desc2 = "up,76,334,rect,40,50" +overlay0_desc3 = "down,76,444,rect,40,50" overlay0_desc4 = "start,730,48,rect,30,30" overlay0_desc5 = "a,764,388,rect,26,26" overlay0_desc6 = "b,697,412,radial,26,26" @@ -20,10 +20,10 @@ overlay0_desc8 = "l,608,374,rect,24,24" overlay0_desc9 = "x,670,350,radial,24,24" overlay0_desc10 = "r,736,326,radial,24,17" overlay0_desc11 = "overlay_next,728,186,radial,30,30" -overlay0_desc12 = "left|up,32,354,radial,20,20" -overlay0_desc13 = "left|down,32,432,radial,20,20" -overlay0_desc14 = "right|up,111,354,radial,20,20" -overlay0_desc15 = "right|down,111,432,radial,20,20" +overlay0_desc12 = "left|up,10,324,radial,22,22" +overlay0_desc13 = "left|down,10,454,radial,22,22" +overlay0_desc14 = "right|up,140,324,radial,22,22" +overlay0_desc15 = "right|down,140,454,radial,22,22" overlay0_desc16 = "menu_toggle,73,50,radial,20,20" overlay1_descs = 11 @@ -41,4 +41,4 @@ overlay1_desc10 = "overlay_next,400,452,radial,22,22" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.07,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From cb99d953c636ac345382b3be8029d3b88c63405d Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Tue, 20 Aug 2013 14:59:16 -0500 Subject: [PATCH 066/202] enlarge hitboxes for genesis3-landscape --- media/overlays/genesis3-landscape.cfg | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/media/overlays/genesis3-landscape.cfg b/media/overlays/genesis3-landscape.cfg index 2c7322b46e..af01859583 100644 --- a/media/overlays/genesis3-landscape.cfg +++ b/media/overlays/genesis3-landscape.cfg @@ -8,19 +8,19 @@ overlay0_full_screen = true overlay1_full_screen = true overlay0_descs = 14 -overlay0_desc0 = "left,34,393,rect,25,25" -overlay0_desc1 = "right,110,393,rect,25,25" -overlay0_desc2 = "up,70,360,rect,25,25" -overlay0_desc3 = "down,70,432,rect,25,25" +overlay0_desc0 = "left,12,389,rect,50,40" +overlay0_desc1 = "right,134,389,rect,50,40" +overlay0_desc2 = "up,76,334,rect,40,50" +overlay0_desc3 = "down,76,444,rect,40,50" overlay0_desc4 = "start,730,48,rect,30,30" -overlay0_desc5 = "a,764,388,rect,26,26" -overlay0_desc6 = "b,697,412,radial,26,26" -overlay0_desc7 = "y,634,439,radial,26,26" +overlay0_desc5 = "a,764,388,rect,30,30" +overlay0_desc6 = "b,697,412,radial,30,30" +overlay0_desc7 = "y,634,439,radial,30,30" overlay0_desc8 = "overlay_next,728,186,radial,30,30" -overlay0_desc9 = "left|up,32,354,radial,20,20" -overlay0_desc10 = "left|down,32,432,radial,20,20" -overlay0_desc11 = "right|up,111,354,radial,20,20" -overlay0_desc12 = "right|down,111,432,radial,20,20" +overlay0_desc9 = "left|up,10,324,radial,22,22" +overlay0_desc10 = "left|down,10,454,radial,22,22" +overlay0_desc11 = "right|up,140,324,radial,22,22" +overlay0_desc12 = "right|down,140,454,radial,22,22" overlay0_desc13 = "menu_toggle,73,50,radial,20,20" overlay1_descs = 11 @@ -38,4 +38,4 @@ overlay1_desc10 = "overlay_next,400,452,radial,22,22" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.07,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From 4a6d497a5c2850f36220cdbbbec0225a6fc52a75 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Tue, 20 Aug 2013 14:59:50 -0500 Subject: [PATCH 067/202] enlarge dpad hitboxes for gameboy-landscape --- media/overlays/gameboy-landscape.cfg | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/media/overlays/gameboy-landscape.cfg b/media/overlays/gameboy-landscape.cfg index e2964c61f6..bc7e838c11 100644 --- a/media/overlays/gameboy-landscape.cfg +++ b/media/overlays/gameboy-landscape.cfg @@ -8,19 +8,19 @@ overlay0_full_screen = true overlay1_full_screen = true overlay0_descs = 14 -overlay0_desc0 = "left,32,393,rect,25,25" -overlay0_desc1 = "right,113,393,rect,25,25" -overlay0_desc2 = "up,73,349,rect,25,25" -overlay0_desc3 = "down,73,436,rect,25,25" +overlay0_desc0 = "left,12,389,rect,50,40" +overlay0_desc1 = "right,134,389,rect,50,40" +overlay0_desc2 = "up,76,334,rect,40,50" +overlay0_desc3 = "down,76,444,rect,40,50" overlay0_desc4 = "select,730,115,rect,30,30" overlay0_desc5 = "start,730,48,rect,30,30" -overlay0_desc6 = "b,697,418,radial,30,30" -overlay0_desc7 = "a,762,370,radial,30,30" +overlay0_desc6 = "b,690,418,radial,46,46" +overlay0_desc7 = "a,772,370,radial,46,46" overlay0_desc8 = "overlay_next,731,239,radial,30,30" -overlay0_desc9 = "left|up,28,348,radial,20,20" -overlay0_desc10 = "left|down,28,435,radial,20,20" -overlay0_desc11 = "right|up,117,348,radial,20,20" -overlay0_desc12 = "right|down,117,435,radial,20,20" +overlay0_desc9 = "left|up,10,324,radial,22,22" +overlay0_desc10 = "left|down,10,454,radial,22,22" +overlay0_desc11 = "right|up,140,324,radial,22,22" +overlay0_desc12 = "right|down,140,454,radial,22,22" overlay0_desc13 = "menu_toggle,73,49,radial,20,20" overlay1_descs = 11 @@ -38,4 +38,4 @@ overlay1_desc10 = "overlay_next,400,452,radial,22,22" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.07,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From fe84dbb12174c62d4741f6fe1d6ab4fc8d48daaf Mon Sep 17 00:00:00 2001 From: zevektor Date: Wed, 21 Aug 2013 12:46:57 +0200 Subject: [PATCH 068/202] Fixes --- android/phoenix/src/org/retroarch/browser/MainMenuActivity.java | 1 - 1 file changed, 1 deletion(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 35fe1c56b9..013a9d215c 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -41,7 +41,6 @@ public class MainMenuActivity extends PreferenceActivity { && null != startedByIntent.getStringExtra("LIBRETRO")) { loadRomExternal(startedByIntent.getStringExtra("ROM"), startedByIntent.getStringExtra("LIBRETRO")); - return; } instance = this; addPreferencesFromResource(R.xml.prefs); From f854f4785513724a2ee9a9c9fca3d626dd4d1163 Mon Sep 17 00:00:00 2001 From: zevektor Date: Wed, 21 Aug 2013 12:57:40 +0200 Subject: [PATCH 069/202] Fixed bug when back button is pressed. --- .../retroarch/browser/MainMenuActivity.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 013a9d215c..7025923bd0 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -36,12 +36,6 @@ public class MainMenuActivity extends PreferenceActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Intent startedByIntent = getIntent(); - if (null != startedByIntent.getStringExtra("ROM") - && null != startedByIntent.getStringExtra("LIBRETRO")) { - loadRomExternal(startedByIntent.getStringExtra("ROM"), - startedByIntent.getStringExtra("LIBRETRO")); - } instance = this; addPreferencesFromResource(R.xml.prefs); PreferenceManager.setDefaultValues(this, R.xml.prefs, false); @@ -91,6 +85,18 @@ public class MainMenuActivity extends PreferenceActivity { libretro_name = "No core"; setCoreTitle("No core"); } + Intent startedByIntent = getIntent(); + if (null != startedByIntent.getStringExtra("ROM") + && null != startedByIntent.getStringExtra("LIBRETRO")) { + if (prefs.getInt("loadRomExternal", 0) == 0) { + loadRomExternal(startedByIntent.getStringExtra("ROM"), + startedByIntent.getStringExtra("LIBRETRO")); + prefs.edit().putInt("loadRomExternal", 1).commit(); + } else{ + prefs.edit().putInt("loadRomExternal", 0).commit(); + super.onBackPressed(); + } + } } public static MainMenuActivity getInstance() { From 6deb38c07d440aeda191a527e5eb13b8c13377c9 Mon Sep 17 00:00:00 2001 From: zevektor Date: Wed, 21 Aug 2013 14:04:43 +0200 Subject: [PATCH 070/202] Checks on load rom from external app changed. --- .../org/retroarch/browser/MainMenuActivity.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 7025923bd0..abc10d52a5 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -37,6 +37,7 @@ public class MainMenuActivity extends PreferenceActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); instance = this; + addPreferencesFromResource(R.xml.prefs); PreferenceManager.setDefaultValues(this, R.xml.prefs, false); this.setVolumeControlStream(AudioManager.STREAM_MUSIC); @@ -85,18 +86,18 @@ public class MainMenuActivity extends PreferenceActivity { libretro_name = "No core"; setCoreTitle("No core"); } + Intent startedByIntent = getIntent(); if (null != startedByIntent.getStringExtra("ROM") && null != startedByIntent.getStringExtra("LIBRETRO")) { - if (prefs.getInt("loadRomExternal", 0) == 0) { + if (null==savedInstanceState || !savedInstanceState.getBoolean("romexec")) loadRomExternal(startedByIntent.getStringExtra("ROM"), startedByIntent.getStringExtra("LIBRETRO")); - prefs.edit().putInt("loadRomExternal", 1).commit(); - } else{ - prefs.edit().putInt("loadRomExternal", 0).commit(); + else super.onBackPressed(); - } + // return; } + } public static MainMenuActivity getInstance() { @@ -677,6 +678,12 @@ public class MainMenuActivity extends PreferenceActivity { } } + @Override + protected void onSaveInstanceState(Bundle data) { + super.onSaveInstanceState(data); + data.putBoolean("romexec", true); + } + private void loadRomExternal(String rom, String core) { updateConfigFile(); From 8b0124ba2af2d393b5cf99e3b0527d2f522a89a8 Mon Sep 17 00:00:00 2001 From: zevektor Date: Wed, 21 Aug 2013 14:08:06 +0200 Subject: [PATCH 071/202] Load roms from external app - #3 --- .../phoenix/src/org/retroarch/browser/MainMenuActivity.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index abc10d52a5..5924298ebe 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -93,9 +93,7 @@ public class MainMenuActivity extends PreferenceActivity { if (null==savedInstanceState || !savedInstanceState.getBoolean("romexec")) loadRomExternal(startedByIntent.getStringExtra("ROM"), startedByIntent.getStringExtra("LIBRETRO")); - else - super.onBackPressed(); - // return; + else finish(); } } From 6ab81b648e9cc4bd671f7f59b40facd17be0fbdd Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 21 Aug 2013 18:57:27 +0200 Subject: [PATCH 072/202] Style nits. --- .../src/org/retroarch/browser/MainMenuActivity.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 5924298ebe..d0fa8531c8 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -90,12 +90,13 @@ public class MainMenuActivity extends PreferenceActivity { Intent startedByIntent = getIntent(); if (null != startedByIntent.getStringExtra("ROM") && null != startedByIntent.getStringExtra("LIBRETRO")) { - if (null==savedInstanceState || !savedInstanceState.getBoolean("romexec")) + if (null == savedInstanceState + || !savedInstanceState.getBoolean("romexec")) loadRomExternal(startedByIntent.getStringExtra("ROM"), startedByIntent.getStringExtra("LIBRETRO")); - else finish(); + else + finish(); } - } public static MainMenuActivity getInstance() { @@ -683,7 +684,6 @@ public class MainMenuActivity extends PreferenceActivity { } private void loadRomExternal(String rom, String core) { - updateConfigFile(); Intent myIntent = new Intent(this, RetroActivity.class); String current_ime = Settings.Secure.getString(getContentResolver(), @@ -692,9 +692,8 @@ public class MainMenuActivity extends PreferenceActivity { .show(); myIntent.putExtra("ROM", rom); myIntent.putExtra("LIBRETRO", core); - myIntent.putExtra("CONFIGFILE", MainMenuActivity.getDefaultConfigPath()); + myIntent.putExtra("CONFIGFILE", getDefaultConfigPath()); myIntent.putExtra("IME", current_ime); startActivity(myIntent); - } } From 5d413c480b925edc982059ef0712c33e1d879322 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Wed, 21 Aug 2013 12:41:13 -0500 Subject: [PATCH 073/202] enlarged button/dpad hitboxes for gb-portrait --- media/overlays/gameboy-portrait.cfg | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/media/overlays/gameboy-portrait.cfg b/media/overlays/gameboy-portrait.cfg index caa4266788..6239aa4105 100644 --- a/media/overlays/gameboy-portrait.cfg +++ b/media/overlays/gameboy-portrait.cfg @@ -9,19 +9,19 @@ overlay1_full_screen = true overlay2_full_screen = true overlay0_descs = 14 -overlay0_desc0 = "left,44,702,rect,25,25" -overlay0_desc1 = "right,162,702,rect,25,25" -overlay0_desc2 = "up,102,643,rect,25,25" -overlay0_desc3 = "down,102,761,rect,25,25" +overlay0_desc0 = "left,42,700,rect,56,46" +overlay0_desc1 = "right,148,700,rect,56,46" +overlay0_desc2 = "up,96,646,rect,46,56" +overlay0_desc3 = "down,96,758,rect,46,56" overlay0_desc4 = "select,55,491,rect,40,40" overlay0_desc5 = "start,423,491,rect,40,40" -overlay0_desc6 = "b,317,726,radial,45,45" -overlay0_desc7 = "a,420,655,radial,45,45" +overlay0_desc6 = "b,317,726,radial,65,65" +overlay0_desc7 = "a,420,655,radial,65,65" overlay0_desc8 = "overlay_next,240,490,radial,30,30" -overlay0_desc9 = "left|up,44,643,radial,20,20" -overlay0_desc10 = "left|down,44,761,radial,20,20" -overlay0_desc11 = "right|up,162,643,radial,20,20" -overlay0_desc12 = "right|down,162,761,radial,20,20" +overlay0_desc9 = "left|up,24,634,radial,45,45" +overlay0_desc10 = "left|down,24,772,radial,45,45" +overlay0_desc11 = "right|up,160,634,radial,45,45" +overlay0_desc12 = "right|down,160,772,radial,45,45" overlay0_desc13 = "menu_toggle,240,595,rect,40,28" overlay1_descs = 11 @@ -39,4 +39,4 @@ overlay1_desc10 = "overlay_next,240,683,radial,25,25" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.11,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From 52ebe38931395959e6028f4253ec72b3c82b4e0d Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Wed, 21 Aug 2013 12:50:58 -0500 Subject: [PATCH 074/202] Enlarged dpad hitboxes and vertically extended button hitboxes for gen3-portrait --- media/overlays/genesis3-portrait.cfg | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/media/overlays/genesis3-portrait.cfg b/media/overlays/genesis3-portrait.cfg index 86276708a4..36c148248e 100644 --- a/media/overlays/genesis3-portrait.cfg +++ b/media/overlays/genesis3-portrait.cfg @@ -9,19 +9,19 @@ overlay1_full_screen = true overlay2_full_screen = true overlay0_descs = 14 -overlay0_desc0 = "left,52,695,rect,25,25" -overlay0_desc1 = "right,159,695,rect,25,25" -overlay0_desc2 = "up,107,638,rect,25,25" -overlay0_desc3 = "down,107,744,rect,25,25" +overlay0_desc0 = "left,42,700,rect,56,46" +overlay0_desc1 = "right,148,700,rect,56,46" +overlay0_desc2 = "up,96,646,rect,46,56" +overlay0_desc3 = "down,96,758,rect,46,56" overlay0_desc4 = "start,427,507,rect,40,40" -overlay0_desc5 = "a,449,720,radial,25,25" -overlay0_desc6 = "b,374,736,radial,25,25" -overlay0_desc7 = "y,301,755,rect,25,25" +overlay0_desc5 = "a,445,715,radial,35,55" +overlay0_desc6 = "b,374,736,radial,35,55" +overlay0_desc7 = "y,301,755,rect,35,55" overlay0_desc8 = "overlay_next,107,508,radial,40,40" -overlay0_desc9 = "left|up,52,638,radial,25,25" -overlay0_desc10 = "left|down,52,744,radial,25,25" -overlay0_desc11 = "right|up,159,638,radial,25,25" -overlay0_desc12 = "right|down,159,744,radial,25,25" +overlay0_desc9 = "left|up,24,634,radial,45,45" +overlay0_desc10 = "left|down,24,772,radial,45,45" +overlay0_desc11 = "right|up,160,634,radial,45,45" +overlay0_desc12 = "right|down,160,772,radial,45,45" overlay0_desc13 = "menu_toggle,240,575,rect,40,28" overlay1_descs = 11 @@ -39,4 +39,4 @@ overlay1_desc10 = "overlay_next,240,683,radial,30,30" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.11,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From 7d55b115a1878e13fb3f0964f162d71b0af2fb25 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Wed, 21 Aug 2013 12:56:02 -0500 Subject: [PATCH 075/202] enlarged dpad hitboxes; left the buttons alone, since they're close together --- media/overlays/genesis6-portrait.cfg | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/media/overlays/genesis6-portrait.cfg b/media/overlays/genesis6-portrait.cfg index 8636715429..bdea9ec72d 100644 --- a/media/overlays/genesis6-portrait.cfg +++ b/media/overlays/genesis6-portrait.cfg @@ -9,10 +9,10 @@ overlay1_full_screen = true overlay2_full_screen = true overlay0_descs = 17 -overlay0_desc0 = "left,52,695,rect,25,25" -overlay0_desc1 = "right,159,695,rect,25,25" -overlay0_desc2 = "up,107,638,rect,25,25" -overlay0_desc3 = "down,107,744,rect,25,25" +overlay0_desc0 = "left,42,700,rect,56,46" +overlay0_desc1 = "right,148,700,rect,56,46" +overlay0_desc2 = "up,96,646,rect,46,56" +overlay0_desc3 = "down,96,758,rect,46,56" overlay0_desc4 = "start,427,507,rect,40,40" overlay0_desc5 = "a,449,720,radial,25,25" overlay0_desc6 = "b,374,736,radial,25,25" @@ -21,10 +21,10 @@ overlay0_desc8 = "l,283,684,rect,21,21" overlay0_desc9 = "x,352,666,radial,21,21" overlay0_desc10 = "r,426,648,radial,21,21" overlay0_desc11 = "overlay_next,107,508,radial,40,40" -overlay0_desc12 = "left|up,52,638,radial,25,25" -overlay0_desc13 = "left|down,52,744,radial,25,25" -overlay0_desc14 = "right|up,159,638,radial,25,25" -overlay0_desc15 = "right|down,159,744,radial,25,25" +overlay0_desc12 = "left|up,24,634,radial,45,45" +overlay0_desc13 = "left|down,24,772,radial,45,45" +overlay0_desc14 = "right|up,160,634,radial,45,45" +overlay0_desc15 = "right|down,160,772,radial,45,45" overlay0_desc16 = "menu_toggle,240,575,rect,40,28" overlay1_descs = 11 @@ -42,4 +42,4 @@ overlay1_desc10 = "overlay_next,240,683,radial,30,30" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.11,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From 1763be49acbbff4531b14fca0c7010f773a008f2 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Wed, 21 Aug 2013 13:12:21 -0500 Subject: [PATCH 076/202] Enlarge dpad hitboxes for psx-portrait --- media/overlays/psx-portrait.cfg | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/media/overlays/psx-portrait.cfg b/media/overlays/psx-portrait.cfg index a62183d0fa..2a5716a882 100644 --- a/media/overlays/psx-portrait.cfg +++ b/media/overlays/psx-portrait.cfg @@ -9,10 +9,10 @@ overlay1_full_screen = true overlay2_full_screen = true overlay0_descs = 20 -overlay0_desc0 = "left,41,695,rect,25,25" -overlay0_desc1 = "right,157,695,rect,25,25" -overlay0_desc2 = "up,98,637,rect,25,25" -overlay0_desc3 = "down,98,751,rect,25,25" +overlay0_desc0 = "left,42,700,rect,56,46" +overlay0_desc1 = "right,148,700,rect,56,46" +overlay0_desc2 = "up,96,646,rect,46,56" +overlay0_desc3 = "down,96,758,rect,46,56" overlay0_desc4 = "start,286,497,rect,35,17" overlay0_desc5 = "select,197,497,rect,35,17" overlay0_desc6 = "a,436,699,radial,35,35" @@ -24,10 +24,10 @@ overlay0_desc11 = "l2,50,479,rect,50,27" overlay0_desc12 = "r,430,537,rect,50,27" overlay0_desc13 = "r2,430,479,rect,50,27" overlay0_desc14 = "overlay_next,240,578,radial,30,30" -overlay0_desc15 = "left|up,41,637,radial,20,20" -overlay0_desc16 = "left|down,41,751,radial,20,20" -overlay0_desc17 = "right|up,157,637,radial,20,20" -overlay0_desc18 = "right|down,157,751,radial,20,20" +overlay0_desc15 = "left|up,20,638,radial,45,45" +overlay0_desc16 = "left|down,20,768,radial,45,45" +overlay0_desc17 = "right|up,160,638,radial,45,45" +overlay0_desc18 = "right|down,166,768,radial,45,45" overlay0_desc19 = "menu_toggle,240,764,rect,25,20" overlay1_descs = 11 @@ -45,4 +45,4 @@ overlay1_desc10 = "overlay_next,240,683,radial,25,25" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.11,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From 8bbffc63865e5abb2ac765c25475bbb37463990f Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Wed, 21 Aug 2013 13:14:03 -0500 Subject: [PATCH 077/202] enlarge dpad hitboxes for nes-portrait --- media/overlays/nes-portrait.cfg | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/media/overlays/nes-portrait.cfg b/media/overlays/nes-portrait.cfg index cdab629f09..ff940f1194 100644 --- a/media/overlays/nes-portrait.cfg +++ b/media/overlays/nes-portrait.cfg @@ -9,19 +9,19 @@ overlay1_full_screen = true overlay2_full_screen = true overlay0_descs = 14 -overlay0_desc0 = "left,39,701,rect,30,30" -overlay0_desc1 = "right,156,701,rect,30,30" -overlay0_desc2 = "up,97,641,rect,30,30" -overlay0_desc3 = "down,97,758,rect,30,30" -overlay0_desc4 = "select,55,485,rect,45,20" -overlay0_desc5 = "start,425,485,rect,45,20" -overlay0_desc6 = "b,309,702,radial,48,48" -overlay0_desc7 = "a,424,702,radial,48,48" +overlay0_desc0 = "left,42,700,rect,56,46" +overlay0_desc1 = "right,148,700,rect,56,46" +overlay0_desc2 = "up,96,646,rect,46,56" +overlay0_desc3 = "down,96,758,rect,46,56" +overlay0_desc4 = "select,55,485,rect,45,20" +overlay0_desc5 = "start,425,485,rect,45,20" +overlay0_desc6 = "b,309,698,radial,48,54" +overlay0_desc7 = "a,424,698,radial,48,54" overlay0_desc8 = "overlay_next,241,492,radial,30,30" -overlay0_desc9 = "left|up,39,641,radial,30,30" -overlay0_desc10 = "left|down,39,758,radial,30,30" -overlay0_desc11 = "right|up,156,641,radial,30,30" -overlay0_desc12 = "right|down,156,758,radial,30,30" +overlay0_desc9 = "left|up,28,638,radial,45,45" +overlay0_desc10 = "left|down,28,768,radial,45,45" +overlay0_desc11 = "right|up,160,638,radial,45,45" +overlay0_desc12 = "right|down,160,768,radial,45,45" overlay0_desc13 = "menu_toggle,240,595,rect,40,28" overlay1_descs = 11 @@ -39,4 +39,4 @@ overlay1_desc10 = "overlay_next,240,683,radial,25,25" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.11,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From ad75b5b006133bf736e6caa00b6cde39f4bbbaf6 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Wed, 21 Aug 2013 13:14:57 -0500 Subject: [PATCH 078/202] enlarge dpad and button hitboxes for snes-portrait --- media/overlays/snes-portrait.cfg | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/media/overlays/snes-portrait.cfg b/media/overlays/snes-portrait.cfg index 4eab5c8159..4426b49e91 100644 --- a/media/overlays/snes-portrait.cfg +++ b/media/overlays/snes-portrait.cfg @@ -9,23 +9,23 @@ overlay1_full_screen = true overlay2_full_screen = true overlay0_descs = 18 -overlay0_desc0 = "left,40,703,rect,30,30" -overlay0_desc1 = "right,156,703,rect,30,30" -overlay0_desc2 = "up,98,644,rect,30,30" -overlay0_desc3 = "down,98,761,rect,30,30" -overlay0_desc4 = "select,206,494,rect,30,30" -overlay0_desc5 = "start,285,494,rect,30,30" -overlay0_desc6 = "b,372,751,radial,35,35" -overlay0_desc7 = "a,439,692,radial,35,35" -overlay0_desc8 = "x,372,626,radial,35,35" -overlay0_desc9 = "y,308,692,radial,35,35" -overlay0_desc10 = "l,70,482,rect,70,30" -overlay0_desc11 = "r,410,482,rect,70,30" +overlay0_desc0 = "left,42,700,rect,56,46" +overlay0_desc1 = "right,148,700,rect,56,46" +overlay0_desc2 = "up,96,646,rect,46,56" +overlay0_desc3 = "down,96,758,rect,46,56" +overlay0_desc4 = "select,206,494,rect,30,30" +overlay0_desc5 = "start,285,494,rect,30,30" +overlay0_desc6 = "b,372,756,radial,90,90" +overlay0_desc7 = "a,446,686,radial,90,90" +overlay0_desc8 = "x,370,622,radial,90,90" +overlay0_desc9 = "y,296,692,radial,90,90" +overlay0_desc10 = "l,70,482,rect,70,30" +overlay0_desc11 = "r,410,482,rect,70,30" overlay0_desc12 = "overlay_next,241,587,radial,30,30" -overlay0_desc13 = "left|up,40,644,radial,30,30" -overlay0_desc14 = "left|down,40,761,radial,30,30" -overlay0_desc15 = "right|up,156,644,radial,30,30" -overlay0_desc16 = "right|down,156,761,radial,30,30" +overlay0_desc13 = "left|up,28,638,radial,45,45" +overlay0_desc14 = "left|down,28,768,radial,45,45" +overlay0_desc15 = "right|up,160,638,radial,45,45" +overlay0_desc16 = "right|down,160,768,radial,45,45" overlay0_desc17 = "menu_toggle,240,760,radial,20,20" overlay1_descs = 11 @@ -43,4 +43,4 @@ overlay1_desc10 = "overlay_next,240,683,radial,25,25" overlay2_descs = 1 overlay2_rect = "0.47,0.9,0.11,0.08" -overlay2_desc0 = "overlay_next,16,16,radial,16,16" \ No newline at end of file +overlay2_desc0 = "overlay_next,16,16,radial,16,16" From 1c4c9436045181a8b1e23a4cd571aed25636b5a0 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 22 Aug 2013 22:12:16 +0200 Subject: [PATCH 079/202] [Pi] Build fixes. --- gfx/context/vc_egl_ctx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gfx/context/vc_egl_ctx.c b/gfx/context/vc_egl_ctx.c index b9097751ff..1db9a28f8b 100644 --- a/gfx/context/vc_egl_ctx.c +++ b/gfx/context/vc_egl_ctx.c @@ -284,7 +284,7 @@ static void gfx_ctx_destroy(void) if (g_egl_ctx) { - gfx_ctx_bind_api(g_api); + gfx_ctx_bind_api(g_api, 0, 0); eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(g_egl_dpy, g_egl_ctx); } @@ -298,7 +298,7 @@ static void gfx_ctx_destroy(void) if (g_egl_surf) { - gfx_ctx_bind_api(g_api); + gfx_ctx_bind_api(g_api, 0, 0); eglDestroySurface(g_egl_dpy, g_egl_surf); } @@ -310,7 +310,7 @@ static void gfx_ctx_destroy(void) eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - gfx_ctx_bind_api(g_api); + gfx_ctx_bind_api(g_api, 0, 0); eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglTerminate(g_egl_dpy); } @@ -405,7 +405,7 @@ static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video) goto fail; } - gfx_ctx_bind_api(g_api); + gfx_ctx_bind_api(g_api, 0, 0); eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx); g_smooth = video->smooth; @@ -424,7 +424,7 @@ fail: g_pbuff_surf = EGL_NO_CONTEXT; } - gfx_ctx_bind_api(g_api); + gfx_ctx_bind_api(g_api, 0, 0); eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx); return false; @@ -453,7 +453,7 @@ static bool gfx_ctx_write_egl_image(const void *frame, unsigned width, unsigned vgImageSubData(g_egl_vgimage[index], frame, pitch, (rgb32 ? VG_sXRGB_8888 : VG_sRGB_565), 0, 0, width, height); *image_handle = eglBuffer[index]; - gfx_ctx_bind_api(g_api); + gfx_ctx_bind_api(g_api, 0, 0); eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx); return ret; From 0fea1c9473e874ae97889e4d928c970624c58829 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Thu, 22 Aug 2013 18:14:10 -0400 Subject: [PATCH 080/202] [Android] handle certain "special" buttons on some controllers better, fixes menu button on Ouya controller --- android/native/jni/input_android.c | 21 ++++++++++++--------- android/phoenix/.classpath | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/android/native/jni/input_android.c b/android/native/jni/input_android.c index af59fbdb3b..527a159e3d 100644 --- a/android/native/jni/input_android.c +++ b/android/native/jni/input_android.c @@ -1592,8 +1592,9 @@ static void android_input_set_keybinds(void *data, unsigned device, static void android_input_poll(void *data) { int ident; + uint64_t lifecycle_mask = (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); 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)); + *lifecycle_state &= ~lifecycle_mask; while ((ident = ALooper_pollAll((input_key_pressed_func(RARCH_PAUSE_TOGGLE)) ? -1 : 0, NULL, NULL, NULL)) >= 0) @@ -1752,9 +1753,6 @@ static void android_input_poll(void *data) } 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 @@ -1764,20 +1762,25 @@ static void android_input_poll(void *data) int action = AKeyEvent_getAction(event); uint64_t *key = NULL; - if(input_state < (1ULL << RARCH_FIRST_META_KEY)) + if (debug_enable) + snprintf(msg, sizeof(msg), "Pad %d : %d, ac = %d, src = %d.\n", state_id, keycode, action, source); + + if (input_state < (1ULL << RARCH_FIRST_META_KEY)) key = &state[state_id]; - else if(input_state) + else if (input_state/* && action == AKEY_EVENT_ACTION_DOWN*/) key = &g_extern.lifecycle_state; - if(key != NULL) + if (key != NULL) { - if (action == AKEY_EVENT_ACTION_UP) + // some controllers send both the up and down events at once when the button is released for "special" buttons, like menu buttons + // work around that by only using down events for meta keys (which get cleared every poll anyway) + if (action == AKEY_EVENT_ACTION_UP && !(input_state & lifecycle_mask)) *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) + if ((keycode == AKEYCODE_VOLUME_UP || keycode == AKEYCODE_VOLUME_DOWN) && keycode_lut[keycode] == 0) handled = 0; } diff --git a/android/phoenix/.classpath b/android/phoenix/.classpath index c06dfcb8e5..51769745b2 100644 --- a/android/phoenix/.classpath +++ b/android/phoenix/.classpath @@ -1,7 +1,7 @@ - + From 0cdd3de8352e7d1198d7261231518a80b1a2a04d Mon Sep 17 00:00:00 2001 From: ToadKing Date: Thu, 22 Aug 2013 20:24:47 -0400 Subject: [PATCH 081/202] [Android] make Ouya controller reports itself as dual analog --- android/native/jni/input_android.c | 1 + 1 file changed, 1 insertion(+) diff --git a/android/native/jni/input_android.c b/android/native/jni/input_android.c index 527a159e3d..a6410eaf40 100644 --- a/android/native/jni/input_android.c +++ b/android/native/jni/input_android.c @@ -1190,6 +1190,7 @@ static void android_input_set_keybinds(void *data, unsigned device, strlcpy(g_settings.input.device_names[port], "OUYA", sizeof(g_settings.input.device_names[port])); + g_settings.input.dpad_emulation[port] = ANALOG_DPAD_DUALANALOG; 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); From be08d003c9163b93db6f73e192b10b32ab80f3e7 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Thu, 22 Aug 2013 23:21:52 -0400 Subject: [PATCH 082/202] [GL] fix OSD messages breaking if one was too long --- gfx/fonts/gl_raster_font.c | 6 ++++++ gfx/gl_common.h | 1 + 2 files changed, 7 insertions(+) diff --git a/gfx/fonts/gl_raster_font.c b/gfx/fonts/gl_raster_font.c index 644184e20e..657ad4a96c 100644 --- a/gfx/fonts/gl_raster_font.c +++ b/gfx/fonts/gl_raster_font.c @@ -35,6 +35,7 @@ static bool gl_init_font(void *data, const char *font_path, float font_size) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl->max_font_size); } else { @@ -124,6 +125,11 @@ static void adjust_power_of_two(gl_t *gl, struct font_rect *geom) geom->pot_width = next_pow2(geom->width); geom->pot_height = next_pow2(geom->height); + if (geom->pot_width > gl->max_font_size) + geom->pot_width = gl->max_font_size; + if (geom->pot_height > gl->max_font_size) + geom->pot_height = gl->max_font_size; + if ((geom->pot_width > gl->font_tex_w) || (geom->pot_height > gl->font_tex_h)) { gl->font_tex_buf = (uint32_t*)realloc(gl->font_tex_buf, diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 5e97a0a540..1d5f308d92 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -207,6 +207,7 @@ typedef struct gl const gl_font_renderer_t *font_ctx; const font_renderer_driver_t *font_driver; GLuint font_tex; + GLint max_font_size; int font_tex_w, font_tex_h; uint32_t *font_tex_buf; char font_last_msg[256]; From f5454cd4462492ecadcd58dda616d7f993b40e39 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Fri, 23 Aug 2013 13:09:59 +0100 Subject: [PATCH 083/202] Initial xinput support, fix msvc build --- Makefile.win | 10 +- frontend/frontend_context.c | 3 + input/dinput.c | 25 +- input/input_common.c | 3 + input/input_common.h | 1 + input/sdl_joypad.c | 29 +- input/winxinput_joypad.c | 361 ++++++++++++++++++++++ msvc/msvc-2010/RetroArch-msvc2010.vcxproj | 10 +- 8 files changed, 434 insertions(+), 8 deletions(-) create mode 100644 input/winxinput_joypad.c diff --git a/Makefile.win b/Makefile.win index 71036ccf47..df300fb4f7 100644 --- a/Makefile.win +++ b/Makefile.win @@ -44,7 +44,8 @@ JOBJ := conf/config_file.o \ compat/compat.o \ file_path.o \ tools/input_common_joyconfig.o \ - input/dinput.o + input/dinput.o \ + input/winxinput_joypad.o CC = gcc CXX = g++ @@ -63,6 +64,8 @@ HAVE_THREADS = 1 HAVE_RGUI = 1 DYNAMIC = 1 +USE_WINXINPUT = 1 + ifeq ($(SLIM),) HAVE_SDL = 1 HAVE_SDL_IMAGE = 1 @@ -212,6 +215,11 @@ ifeq ($(HAVE_PYTHON), 1) OBJ += gfx/py_state/py_state.o endif +ifeq ($(USE_WINXINPUT), 1) + DEFINES += -DUSE_WINXINPUT + OBJ += input/winxinput_joypad.o +endif + ifeq ($(HAVE_DINPUT), 1) LIBS += -ldinput8 -ldxguid -lole32 DEFINES += -DHAVE_DINPUT diff --git a/frontend/frontend_context.c b/frontend/frontend_context.c index 24fa1dd161..93fd0260b0 100644 --- a/frontend/frontend_context.c +++ b/frontend/frontend_context.c @@ -36,12 +36,15 @@ static const frontend_ctx_driver_t *frontend_ctx_drivers[] = { #if defined(IOS) || defined(OSX) &frontend_ctx_apple, #endif + NULL // zero length array is not valid }; const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident) { for (unsigned i = 0; i < sizeof(frontend_ctx_drivers) / sizeof(frontend_ctx_drivers[0]); i++) { + if (!frontend_ctx_drivers[i]) // could be the dummy NULL + continue; if (strcmp(frontend_ctx_drivers[i]->ident, ident) == 0) return frontend_ctx_drivers[i]; } diff --git a/input/dinput.c b/input/dinput.c index 024f323ba9..620d3e645a 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -386,6 +386,8 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p) return DIENUM_CONTINUE; } +extern const LPCTSTR XBOX_PAD_NAMES_TO_REJECT[]; + static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) { (void)p; @@ -399,7 +401,28 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) #else if (FAILED(IDirectInput8_CreateDevice(g_ctx, &inst->guidInstance, pad, NULL))) #endif - return DIENUM_CONTINUE; + return DIENUM_CONTINUE; + +#ifdef USE_WINXINPUT + // Reject xbox 360 controllers, the xinput driver will take care of them + DIDEVICEINSTANCE info; + ZeroMemory(&info, sizeof(DIDEVICEINSTANCE)); + info.dwSize = sizeof(DIDEVICEINSTANCE); + IDirectInputDevice8_GetDeviceInfo(*pad, &info); + + unsigned test_name_index = 0; + while(1) + { + if (XBOX_PAD_NAMES_TO_REJECT[test_name_index] == NULL) + break; + if (lstrcmpi(info.tszProductName, XBOX_PAD_NAMES_TO_REJECT[test_name_index]) == 0) + { + RARCH_LOG("dinput: Rejected XInput controller \"%s\"", info.tszProductName); + return DIENUM_CONTINUE; + } + ++test_name_index; + } +#endif IDirectInputDevice8_SetDataFormat(*pad, &c_dfDIJoystick2); IDirectInputDevice8_SetCooperativeLevel(*pad, (HWND)driver.video_window, diff --git a/input/input_common.c b/input/input_common.c index 12be6eaf76..cc7ab96e80 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -41,6 +41,9 @@ static const rarch_joypad_driver_t *joypad_drivers[] = { #ifndef IS_RETROLAUNCH +#ifdef USE_WINXINPUT + &winxinput_joypad, +#endif #ifdef HAVE_DINPUT &dinput_joypad, #endif diff --git a/input/input_common.h b/input/input_common.h index 2ce912e98a..dc118ff4e1 100644 --- a/input/input_common.h +++ b/input/input_common.h @@ -93,6 +93,7 @@ const char *input_joypad_name(const rarch_joypad_driver_t *driver, unsigned joyp extern const rarch_joypad_driver_t dinput_joypad; extern const rarch_joypad_driver_t linuxraw_joypad; +extern const rarch_joypad_driver_t winxinput_joypad; // Named as such to avoid confusion with xb1/360 port code extern const rarch_joypad_driver_t sdl_joypad; diff --git a/input/sdl_joypad.c b/input/sdl_joypad.c index 812936be56..0ed9411be8 100644 --- a/input/sdl_joypad.c +++ b/input/sdl_joypad.c @@ -39,6 +39,8 @@ static void sdl_joypad_destroy(void) memset(g_pads, 0, sizeof(g_pads)); } +extern const LPCTSTR XBOX_PAD_NAMES_TO_REJECT[]; + static bool sdl_joypad_init(void) { if (SDL_Init(SDL_INIT_JOYSTICK) < 0) @@ -54,9 +56,32 @@ static bool sdl_joypad_init(void) pad->joypad = SDL_JoystickOpen(i); if (!pad->joypad) { - RARCH_ERR("Couldn't open SDL joystick #%u.\n", i); - goto error; + RARCH_ERR("Couldn't open SDL joystick #%u.\n", i); + goto error; } + + + #ifdef USE_WINXINPUT + // Reject xbox 360 controllers, the xinput driver will take care of them. + unsigned test_name_index = 0; + while(1) + { + if (XBOX_PAD_NAMES_TO_REJECT[test_name_index] == NULL) + break; + if (lstrcmpi(SDL_JoystickName(i), XBOX_PAD_NAMES_TO_REJECT[test_name_index]) == 0) + { + RARCH_LOG("sdl joypad: Rejected XInput controller \"%s\"", SDL_JoystickName(i)); + pad->joypad = NULL; pad->num_axes = 0; pad->num_buttons = 0; pad->num_hats = 0; + + goto continue_after_xinput_rejection; + } + ++test_name_index; + } + #endif + + continue_after_xinput_rejection: + + // RARCH_LOG("Opened Joystick: %s (#%u).\n", SDL_JoystickName(i), i); diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c new file mode 100644 index 0000000000..0310b24c5b --- /dev/null +++ b/input/winxinput_joypad.c @@ -0,0 +1,361 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Hans-Kristian Arntzen + * + * 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 . + */ + +// Support 360 controllers on Windows. +// Said controllers do show under DInput but they have limitations in this mode; +// The triggers are combined rather than seperate and it is not possible to use +// the guide button. + +// Some wrappers for other controllers also simulate xinput (as it is easier to implement) +// so this may be useful for those also. + +// Note: if rumble is ever added (for psx and n64 cores), add rumble support to this +// as well as dinput. +#include "input_common.h" + +#include "../general.h" +#include "../boolean.h" + +#include +#include +#include + +//#include + +// There is no need to require the xinput headers and libs since +// we shall be dynamically loading them anyway. But first check that +// it hasn't been included anyway. +// official and mingw xinput headers have different include guards +#if ((!_XINPUT_H_) && (!__WINE_XINPUT_H)) + + #define XINPUT_GAMEPAD_DPAD_UP 0x0001 + #define XINPUT_GAMEPAD_DPAD_DOWN 0x0002 + #define XINPUT_GAMEPAD_DPAD_LEFT 0x0004 + #define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008 + #define XINPUT_GAMEPAD_START 0x0010 + #define XINPUT_GAMEPAD_BACK 0x0020 + #define XINPUT_GAMEPAD_LEFT_THUMB 0x0040 + #define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080 + #define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 + #define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 + #define XINPUT_GAMEPAD_A 0x1000 + #define XINPUT_GAMEPAD_B 0x2000 + #define XINPUT_GAMEPAD_X 0x4000 + #define XINPUT_GAMEPAD_Y 0x8000 + + typedef struct + { + WORD wButtons; + BYTE bLeftTrigger; + BYTE bRightTrigger; + SHORT sThumbLX; + SHORT sThumbLY; + SHORT sThumbRX; + SHORT sThumbRY; + } XINPUT_GAMEPAD; + + typedef struct + { + DWORD dwPacketNumber; + XINPUT_GAMEPAD Gamepad; + } XINPUT_STATE; + +#endif + +// Guide constant is not officially documented +#define XINPUT_GAMEPAD_GUIDE 0x0400 + +#ifndef ERROR_DEVICE_NOT_CONNECTED + #define ERROR_DEVICE_NOT_CONNECTED 1167 +#endif + +// To load xinput1_3.dll +static HINSTANCE g_winxinput_dll; + +// Function pointer, to be assigned with GetProcAddress +typedef __stdcall DWORD (*XInputGetStateEx_t)(DWORD, XINPUT_STATE*); +static XInputGetStateEx_t g_XInputGetStateEx; + +// Guide button may or may not be available, +// but if it is available +static bool g_winxinput_guide_button_supported; + +typedef struct +{ + XINPUT_STATE xstate; + bool connected; +} winxinput_joypad_state; + +static winxinput_joypad_state g_winxinput_states[4]; + +static bool winxinput_joypad_init(void) +{ + g_winxinput_dll = NULL; + + // Find the correct path to load the DLL from. + // Usually this will be from the system directory, + // but occasionally a user may wish to use a third-party + // wrapper DLL (such as x360ce); support these by checking + // the working directory first. + + // No need to check for existance as we will be checking LoadLibrary's + // success anyway. + TCHAR dll_path[MAX_PATH]; + strcpy(dll_path, "xinput1_3.dll"); + g_winxinput_dll = LoadLibrary(dll_path); + if (!g_winxinput_dll) + { + // Loading from working dir failed, try to load from system. + GetSystemDirectory(dll_path, sizeof(dll_path)); + strcpy(dll_path, "xinput1_3.dll"); + g_winxinput_dll = LoadLibrary(dll_path); + + if (!g_winxinput_dll) + { + RARCH_ERR("Failed to init XInput, ensure DirectX and controller drivers are up to date.\n"); + return false; // DLL does not exist or is invalid + } + + } + + // If we get here then an xinput DLL is correctly loaded. + // First try to load ordinal 100 (XInputGetStateEx). + // Cast to make C++ happy. + g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, (LPCSTR)100); + g_winxinput_guide_button_supported = true; + + if (!g_XInputGetStateEx) + { + // no ordinal 100. (old version of x360ce perhaps). Load the ordinary XInputGetState, + // at the cost of losing guide button support. + g_winxinput_guide_button_supported = false; + g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState"); + if (!g_XInputGetStateEx) + { + RARCH_ERR("Failed to init XInput.\n"); + return false; // DLL was loaded but did not contain the correct function. + } + } + + // zero out the states + for (unsigned i = 0; i < 4; ++i) + ZeroMemory(&g_winxinput_states[i], sizeof(winxinput_joypad_state)); + + // Do a dummy poll to check which controllers are connected. + XINPUT_STATE dummy_state; + for (unsigned i = 0; i < 4; ++i) + { + g_winxinput_states[i].connected = !(g_XInputGetStateEx(i, &dummy_state) == ERROR_DEVICE_NOT_CONNECTED); + if (g_winxinput_states[i].connected) + RARCH_LOG("Found XInput controller, player #%u\n", i); + } + + + return true; +} + +static bool winxinput_joypad_query_pad(unsigned pad) +{ + if (pad >= 4) + return false; + else + return g_winxinput_states[pad].connected; +} + +static void winxinput_joypad_destroy(void) +{ + for (unsigned i = 0; i < 4; ++i) + ZeroMemory(&g_winxinput_states[i], sizeof(winxinput_joypad_state)); + + FreeLibrary(g_winxinput_dll); + g_winxinput_dll = NULL; + g_XInputGetStateEx = NULL; +} + +// Buttons are provided by XInput as bits of a uint16. +// Map from button index (0..10) to mask to AND against. +// dpad is handled seperately. +// Order: +// a, b, x, y, leftbump, rightbump, back, start, leftstick, rightstick, guide. +static const WORD button_index_to_bitmap_code[] = { + 0x1000, 0x2000, 0x4000, 0x8000, 0x0100, 0x0200, 0x0020, 0x0010, + 0x0040, 0x0080, 0x0400 +}; + +static bool winxinput_joypad_button (unsigned port_num, uint16_t joykey) +{ + if (joykey == NO_BTN) + return false; + + if (!(g_winxinput_states[port_num].connected)) + return false; + + + + uint16_t btn_word = g_winxinput_states[port_num].xstate.Gamepad.wButtons; + + + if (GET_HAT_DIR(joykey)) + { + + switch (GET_HAT_DIR(joykey)) + { + case HAT_UP_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_UP; + case HAT_DOWN_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_DOWN; + case HAT_LEFT_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_LEFT; + case HAT_RIGHT_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_RIGHT; + } + + return false; // hat requested and no hat button down + } + else + { + // non-hat button + unsigned num_buttons = g_winxinput_guide_button_supported ? 11 : 10; + + if (joykey >= num_buttons) + return false; + else + return btn_word & button_index_to_bitmap_code[joykey]; + } + + return false; + +} +//#include +static int16_t winxinput_joypad_axis (unsigned port_num, uint32_t joyaxis) +{ + //printf("Requested axis: %u\n", joyaxis); + if (joyaxis == AXIS_NONE) + return 0; + + if (!(g_winxinput_states[port_num].connected)) + return 0; + + /*switch (joyaxis) + { + case 0: return(g_winxinput_states[port_num].xstate.Gamepad.sThumbLX); + case 1: return (g_winxinput_states[port_num].xstate.Gamepad.sThumbLX); + case 2: return 0; + case 3: return 0; //do axes now + case 4: return 0; + case 5: return 0; + default: return 0; + }*/ + + + int16_t val = 0; + int axis = -1; + + bool is_neg = false; + bool is_pos = false; + + if (AXIS_NEG_GET(joyaxis) <= 3) + { + axis = AXIS_NEG_GET(joyaxis); + is_neg = true; + } + else if (AXIS_POS_GET(joyaxis) <= 5) + { + axis = AXIS_POS_GET(joyaxis); + is_pos = true; + } + + XINPUT_GAMEPAD* pad = &(g_winxinput_states[port_num].xstate.Gamepad); + switch (axis) + { + case 0: val = pad->sThumbLX; break; + case 1: val = pad->sThumbLY; break; + case 2: val = pad->sThumbRX; break; + case 3: val = pad->sThumbRY; break; + + case 4: val = pad->bLeftTrigger * 32767 / 255; break; + case 5: val = pad->bRightTrigger * 32767 / 255; break; + } + + if (is_neg && val > 0) + val = 0; + else if (is_pos && val < 0) + val = 0; + + return val; + +} + +static void winxinput_joypad_poll(void) +{ + for (unsigned i = 0; i < 4; ++i) + if (g_XInputGetStateEx(i, &(g_winxinput_states[i].xstate)) == ERROR_DEVICE_NOT_CONNECTED) + g_winxinput_states[i].connected = false; +} + +static const char* const XBOX_CONTROLLER_NAMES[4] = +{ + "Xbox 360 Controller (Player 1)", + "Xbox 360 Controller (Player 2)", + "Xbox 360 Controller (Player 3)", + "Xbox 360 Controller (Player 4)" +}; + +const char* winxinput_joypad_name (unsigned pad) +{ + if (pad > 3) + return NULL; + else + return XBOX_CONTROLLER_NAMES[pad]; +} + + +const rarch_joypad_driver_t winxinput_joypad = { + winxinput_joypad_init, + winxinput_joypad_query_pad, + winxinput_joypad_destroy, + winxinput_joypad_button, + winxinput_joypad_axis, + winxinput_joypad_poll, + winxinput_joypad_name, + "winxinput", +}; + +// A list of names for other (dinput) drivers to reject. +const LPCTSTR XBOX_PAD_NAMES_TO_REJECT[] = +{ + "Controller (Gamepad for Xbox 360)", + "Controller (XBOX 360 For Windows)", + "Controller (Xbox 360 Wireless Receiver for Windows)", + "Controller (Xbox wireless receiver for windows)", + "XBOX 360 For Windows (Controller)", + "Xbox 360 Wireless Receiver", + "Xbox Receiver for Windows (Wireless Controller)", + "Xbox wireless receiver for windows (Controller)", + NULL +}; + + +/* +typedef struct rarch_joypad_driver +{ + bool (*init)(void); + bool (*query_pad)(unsigned); + void (*destroy)(void); + bool (*button)(unsigned, uint16_t); + int16_t (*axis)(unsigned, uint32_t); + void (*poll)(void); + const char *(*name)(unsigned); + + const char *ident; +} rarch_joypad_driver_t; + +*/ \ No newline at end of file diff --git a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj index 17c46dec6d..3a7d4085ad 100644 --- a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj +++ b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj @@ -88,7 +88,7 @@ Level3 Disabled - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;USE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -108,7 +108,7 @@ Level3 Disabled - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;USE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -130,7 +130,7 @@ MaxSpeed true true - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;USE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -154,7 +154,7 @@ MaxSpeed true true - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_ZLIB;WANT_MINIZ;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;USE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_ZLIB;WANT_MINIZ;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -250,6 +250,8 @@ + + From 704a937ae7dd7a930dc6f4c56d2f1540fe9f4d25 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 23 Aug 2013 17:31:18 +0200 Subject: [PATCH 084/202] [WGL] Fix window size calculation. --- gfx/context/wgl_ctx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gfx/context/wgl_ctx.c b/gfx/context/wgl_ctx.c index ec12ed8411..cb925263ea 100644 --- a/gfx/context/wgl_ctx.c +++ b/gfx/context/wgl_ctx.c @@ -472,10 +472,10 @@ static bool gfx_ctx_set_video_mode( if (!fullscreen) { SetMenu(g_hwnd, LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MENU))); - RECT rcTemp = {0, 0, g_resize_height, 0x7FFF}; // 0x7FFF="Infinite" height + RECT rcTemp = {0, 0, width, 0x7FFF}; // 0x7FFF = "Infinite" height SendMessage(g_hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rcTemp); // recalculate margin, taking possible menu wrap into account - g_resize_height += rcTemp.top + rect.top; // extend by new top margin and substract previous margin - SetWindowPos(g_hwnd, NULL, 0, 0, g_resize_width, g_resize_height, SWP_NOMOVE); + unsigned menu_height = rcTemp.top + rect.top; // rect.top is negative after AdjustWindowRect(). + SetWindowPos(g_hwnd, NULL, 0, 0, width, height + menu_height, SWP_NOMOVE); } if (!fullscreen || windowed_full) From 67f4f1b3ed8bd0b88ef7597791f676e8e4f1844c Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 23 Aug 2013 17:31:18 +0200 Subject: [PATCH 085/202] [WGL] Fix window size calculation. --- gfx/context/wgl_ctx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gfx/context/wgl_ctx.c b/gfx/context/wgl_ctx.c index ec12ed8411..cb925263ea 100644 --- a/gfx/context/wgl_ctx.c +++ b/gfx/context/wgl_ctx.c @@ -472,10 +472,10 @@ static bool gfx_ctx_set_video_mode( if (!fullscreen) { SetMenu(g_hwnd, LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MENU))); - RECT rcTemp = {0, 0, g_resize_height, 0x7FFF}; // 0x7FFF="Infinite" height + RECT rcTemp = {0, 0, width, 0x7FFF}; // 0x7FFF = "Infinite" height SendMessage(g_hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rcTemp); // recalculate margin, taking possible menu wrap into account - g_resize_height += rcTemp.top + rect.top; // extend by new top margin and substract previous margin - SetWindowPos(g_hwnd, NULL, 0, 0, g_resize_width, g_resize_height, SWP_NOMOVE); + unsigned menu_height = rcTemp.top + rect.top; // rect.top is negative after AdjustWindowRect(). + SetWindowPos(g_hwnd, NULL, 0, 0, width, height + menu_height, SWP_NOMOVE); } if (!fullscreen || windowed_full) From d13542f12be58ec3dd4381cf25cc59c951c110e7 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 24 Aug 2013 05:10:14 +0200 Subject: [PATCH 086/202] (Android) Detects buffer size properly now on Android 4.2 and up - bases requested latency on this. Old fallback applies for non-4.2 --- .../retroarch/browser/MainMenuActivity.java | 28 +++++++++++++++++-- audio/opensl.c | 2 ++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index d0fa8531c8..1c0491ec53 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -163,6 +163,18 @@ public class MainMenuActivity extends PreferenceActivity { return Integer.parseInt(manager .getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); } + + @TargetApi(17) + public static int getLowLatencyBufferSize() { + AudioManager manager = (AudioManager) MainMenuActivity.getInstance() + .getApplicationContext() + .getSystemService(Context.AUDIO_SERVICE); + int buffersize = Integer.parseInt(manager + .getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER)); + + Log.i(TAG, "Queried ideal buffer size: " + buffersize); + return buffersize; + } public static int getOptimalSamplingRate() { int ret; @@ -251,8 +263,20 @@ public class MainMenuActivity extends PreferenceActivity { prefs.getBoolean("audio_rate_control", true)); config.setInt("audio_out_rate", MainMenuActivity.getOptimalSamplingRate()); - config.setInt("audio_latency", - prefs.getBoolean("audio_high_latency", false) ? 160 : 64); + + int buffersize = 0; + + if (android.os.Build.VERSION.SDK_INT >= 17) { + buffersize = getLowLatencyBufferSize(); + if (config.getBoolean("audio_high_latency") == false) { + config.setInt("audio_latency", buffersize / 32); + } + } + else { + config.setInt("audio_latency", + prefs.getBoolean("audio_high_latency", false) ? 160 : 64); + } + config.setBoolean("audio_enable", prefs.getBoolean("audio_enable", true)); config.setBoolean("video_smooth", diff --git a/audio/opensl.c b/audio/opensl.c index 068e42a7a2..06362baab9 100644 --- a/audio/opensl.c +++ b/audio/opensl.c @@ -115,6 +115,8 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency) if (!sl) goto error; + RARCH_LOG("[SLES ] : Requested audio latency: %dms...", latency); + GOTO_IF_FAIL(slCreateEngine(&sl->engine_object, 0, NULL, 0, NULL, NULL)); GOTO_IF_FAIL(SLObjectItf_Realize(sl->engine_object, SL_BOOLEAN_FALSE)); GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->engine_object, SL_IID_ENGINE, &sl->engine)); From 692f8892aa29ac491b433690237288b40e5aa30c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 24 Aug 2013 05:22:25 +0200 Subject: [PATCH 087/202] (Android) Add fallback for API level 17 audio buffer size path if high audio latency is enabled --- .../phoenix/src/org/retroarch/browser/MainMenuActivity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 1c0491ec53..1a9fe970f7 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -270,6 +270,9 @@ public class MainMenuActivity extends PreferenceActivity { buffersize = getLowLatencyBufferSize(); if (config.getBoolean("audio_high_latency") == false) { config.setInt("audio_latency", buffersize / 32); + } else { + config.setInt("audio_latency", + prefs.getBoolean("audio_high_latency", false) ? 160 : 64); } } else { From 73cb5666207707c175cdbebab5ae16c4d350ad60 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 24 Aug 2013 12:04:47 +0200 Subject: [PATCH 088/202] "Revert" audio buffer behavior on Android. Add audio_block_frames setting (only used by OpenSL atm). --- .../retroarch/browser/MainMenuActivity.java | 38 ++++++++++++------- audio/opensl.c | 10 +++-- general.h | 1 + settings.c | 2 + 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 1a9fe970f7..296f9d90be 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -11,6 +11,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetManager; import android.media.AudioManager; @@ -157,7 +158,7 @@ public class MainMenuActivity extends PreferenceActivity { @TargetApi(17) public static int getLowLatencyOptimalSamplingRate() { - AudioManager manager = (AudioManager) MainMenuActivity.getInstance() + AudioManager manager = (AudioManager) getInstance() .getApplicationContext() .getSystemService(Context.AUDIO_SERVICE); return Integer.parseInt(manager @@ -166,15 +167,20 @@ public class MainMenuActivity extends PreferenceActivity { @TargetApi(17) public static int getLowLatencyBufferSize() { - AudioManager manager = (AudioManager) MainMenuActivity.getInstance() + AudioManager manager = (AudioManager) getInstance() .getApplicationContext() .getSystemService(Context.AUDIO_SERVICE); int buffersize = Integer.parseInt(manager .getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER)); - - Log.i(TAG, "Queried ideal buffer size: " + buffersize); + Log.i(TAG, "Queried ideal buffer size (frames): " + buffersize); return buffersize; } + + @TargetApi(17) + public static boolean hasLowLatencyAudio() { + PackageManager pm = getInstance().getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY); + } public static int getOptimalSamplingRate() { int ret; @@ -261,21 +267,25 @@ public class MainMenuActivity extends PreferenceActivity { prefs.getBoolean("global_config_enable", true)); config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true)); - config.setInt("audio_out_rate", - MainMenuActivity.getOptimalSamplingRate()); - int buffersize = 0; + int optimalRate = getOptimalSamplingRate(); + config.setInt("audio_out_rate", optimalRate); if (android.os.Build.VERSION.SDK_INT >= 17) { - buffersize = getLowLatencyBufferSize(); - if (config.getBoolean("audio_high_latency") == false) { - config.setInt("audio_latency", buffersize / 32); + int buffersize = getLowLatencyBufferSize(); + + boolean lowLatency = hasLowLatencyAudio(); + Log.i(TAG, "Audio is low latency: " + (lowLatency ? "yes" : "no")); + + if (lowLatency && !prefs.getBoolean("audio_high_latency", false)) { + config.setInt("audio_latency", 64); + config.setInt("audio_block_frames", buffersize); } else { - config.setInt("audio_latency", - prefs.getBoolean("audio_high_latency", false) ? 160 : 64); + config.setInt("audio_latency", prefs.getBoolean( + "audio_high_latency", false) ? 160 : 64); + config.setInt("audio_block_frames", 0); } - } - else { + } else { config.setInt("audio_latency", prefs.getBoolean("audio_high_latency", false) ? 160 : 64); } diff --git a/audio/opensl.c b/audio/opensl.c index 06362baab9..beffc5456b 100644 --- a/audio/opensl.c +++ b/audio/opensl.c @@ -115,7 +115,7 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency) if (!sl) goto error; - RARCH_LOG("[SLES ] : Requested audio latency: %dms...", latency); + RARCH_LOG("[SLES]: Requested audio latency: %d ms.", latency); GOTO_IF_FAIL(slCreateEngine(&sl->engine_object, 0, NULL, 0, NULL, NULL)); GOTO_IF_FAIL(SLObjectItf_Realize(sl->engine_object, SL_BOOLEAN_FALSE)); @@ -124,7 +124,11 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency) GOTO_IF_FAIL(SLEngineItf_CreateOutputMix(sl->engine, &sl->output_mix, 0, NULL, NULL)); GOTO_IF_FAIL(SLObjectItf_Realize(sl->output_mix, SL_BOOLEAN_FALSE)); - sl->buf_size = next_pow2(32 * latency); + if (g_settings.audio.block_frames) + sl->buf_size = g_settings.audio.block_frames * 4; + else + sl->buf_size = next_pow2(32 * latency); + sl->buf_count = (latency * 4 * out_rate + 500) / 1000; sl->buf_count = (sl->buf_count + sl->buf_size / 2) / sl->buf_size; @@ -139,7 +143,7 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency) for (unsigned i = 0; i < sl->buf_count; i++) sl->buffer[i] = sl->buffer_chunk + i * sl->buf_size; - RARCH_LOG("[SLES] : Setting audio latency: Block size = %u, Blocks = %u, Total = %u ...\n", + RARCH_LOG("[SLES]: Setting audio latency: Block size = %u, Blocks = %u, Total = %u ...\n", sl->buf_size, sl->buf_count, sl->buf_size * sl->buf_count); fmt_pcm.formatType = SL_DATAFORMAT_PCM; diff --git a/general.h b/general.h index 702b8928f8..85a97eeb4c 100644 --- a/general.h +++ b/general.h @@ -201,6 +201,7 @@ struct settings char driver[32]; bool enable; unsigned out_rate; + unsigned block_frames; float in_rate; char device[PATH_MAX]; unsigned latency; diff --git a/settings.c b/settings.c index 4b9dd32237..8a9563e2e5 100644 --- a/settings.c +++ b/settings.c @@ -196,6 +196,7 @@ void config_set_defaults(void) g_settings.audio.enable = audio_enable; g_settings.audio.out_rate = out_rate; + g_settings.audio.block_frames = 0; g_settings.audio.in_rate = out_rate; if (audio_device) strlcpy(g_settings.audio.device, audio_device, sizeof(g_settings.audio.device)); @@ -628,6 +629,7 @@ bool config_load_file(const char *path) // Audio settings. CONFIG_GET_BOOL(audio.enable, "audio_enable"); CONFIG_GET_INT(audio.out_rate, "audio_out_rate"); + CONFIG_GET_INT(audio.block_frames, "audio_block_frames"); CONFIG_GET_STRING(audio.device, "audio_device"); CONFIG_GET_INT(audio.latency, "audio_latency"); CONFIG_GET_BOOL(audio.sync, "audio_sync"); From ae5221947a898a0963ba3a54ad7faad2a390fa83 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 24 Aug 2013 12:52:47 +0200 Subject: [PATCH 089/202] IME config fixups. --- android/phoenix/AndroidManifest.xml | 1 + android/phoenix/res/xml/prefs.xml | 23 +++++++++++++--- .../org/retroarch/browser/IMEActivity.java | 16 ++++++++++++ .../retroarch/browser/MainMenuActivity.java | 26 +++++++++---------- .../src/org/retroarch/browser/ReportIME.java | 25 ++++++++++++++++-- 5 files changed, 72 insertions(+), 19 deletions(-) create mode 100644 android/phoenix/src/org/retroarch/browser/IMEActivity.java diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index c44b3a1e1e..63935e0297 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -29,6 +29,7 @@ + diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index 4d696d8411..a63a383471 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -123,10 +123,6 @@ - + + + + + + + + + + + Date: Sat, 24 Aug 2013 15:13:44 +0200 Subject: [PATCH 090/202] Minor code cleanups. --- .../retroarch/browser/DirectoryActivity.java | 3 +- .../browser/DisplayRefreshRateTest.java | 5 +- .../retroarch/browser/MainMenuActivity.java | 117 ++++++++---------- .../org/retroarch/browser/ROMActivity.java | 3 +- .../retroarch/browser/RefreshRateSetOS.java | 3 +- 5 files changed, 56 insertions(+), 75 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/DirectoryActivity.java b/android/phoenix/src/org/retroarch/browser/DirectoryActivity.java index 5199054ff1..4ba900fe0a 100644 --- a/android/phoenix/src/org/retroarch/browser/DirectoryActivity.java +++ b/android/phoenix/src/org/retroarch/browser/DirectoryActivity.java @@ -9,7 +9,6 @@ import android.content.*; import android.app.*; import android.media.AudioManager; import android.os.*; -import android.preference.PreferenceManager; import android.widget.*; import android.view.*; @@ -107,7 +106,7 @@ public class DirectoryActivity extends Activity implements private void finishWithPath(String path) { if (pathSettingKey != null && !pathSettingKey.isEmpty()) { - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + SharedPreferences settings = MainMenuActivity.getPreferences(); SharedPreferences.Editor editor = settings.edit(); editor.putString(pathSettingKey, path); editor.commit(); diff --git a/android/phoenix/src/org/retroarch/browser/DisplayRefreshRateTest.java b/android/phoenix/src/org/retroarch/browser/DisplayRefreshRateTest.java index 7b25728792..22df6cedbd 100644 --- a/android/phoenix/src/org/retroarch/browser/DisplayRefreshRateTest.java +++ b/android/phoenix/src/org/retroarch/browser/DisplayRefreshRateTest.java @@ -8,7 +8,6 @@ import android.content.SharedPreferences; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.os.Bundle; -import android.preference.PreferenceManager; import android.util.Log; import android.view.WindowManager; import android.widget.Toast; @@ -36,7 +35,7 @@ public class DisplayRefreshRateTest extends Activity { } private void setFPSSetting(double fps) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + SharedPreferences prefs = MainMenuActivity.getPreferences(); SharedPreferences.Editor edit = prefs.edit(); edit.putString("video_refresh_rate", Double.valueOf(fps).toString()); edit.commit(); @@ -117,7 +116,7 @@ public class DisplayRefreshRateTest extends Activity { @Override protected void onDestroy() { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + SharedPreferences prefs = MainMenuActivity.getPreferences(); String fps = prefs.getString("video_refresh_rate", "ERROR"); Toast.makeText(this, "Refresh rate measured to: " + fps + " Hz.", Toast.LENGTH_LONG).show(); super.onDestroy(); diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 79d7aa4d88..51e4a4c885 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -32,20 +32,40 @@ public class MainMenuActivity extends PreferenceActivity { static private final String TAG = "MainMenu"; static private String libretro_path; static private String libretro_name; - + @SuppressWarnings("deprecation") + private void refreshPreferenceScreen() { + setPreferenceScreen(null); + addPreferencesFromResource(R.xml.prefs); + + setCoreTitle(libretro_name); + PreferenceManager.setDefaultValues(this, R.xml.prefs, true); + } + + private boolean usePerCoreConfig() { + SharedPreferences prefs = getPreferences(); + + boolean global_config_enable = prefs.getBoolean("global_config_enable", true); + boolean config_same_as_native_lib_dir = libretro_path + .equals(getApplicationInfo().nativeLibraryDir); + + return !global_config_enable && !config_same_as_native_lib_dir; + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); instance = this; + + SharedPreferences prefs = getPreferences(); + + libretro_path = prefs.getString("libretro_path", getApplicationInfo().nativeLibraryDir); + libretro_name = prefs.getString("libretro_name", "No core"); - addPreferencesFromResource(R.xml.prefs); - PreferenceManager.setDefaultValues(this, R.xml.prefs, false); + refreshPreferenceScreen(); + this.setVolumeControlStream(AudioManager.STREAM_MUSIC); - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); - extractAssets(); if (!prefs.getBoolean("first_time_refreshrate_calculate", false)) { @@ -57,37 +77,11 @@ public class MainMenuActivity extends PreferenceActivity { .setTitle("Welcome to RetroArch") .setMessage( "This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience.") - .setPositiveButton("OK", - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, - int which) { - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); - SharedPreferences.Editor edit = prefs - .edit(); - edit.putBoolean("video_threaded", true); - edit.commit(); - } - }); + .setPositiveButton("OK", null); alert.show(); } } - if (prefs.getString("libretro_path", "").isEmpty() == false) { - libretro_path = prefs.getString("libretro_path", ""); - setCoreTitle("No core"); - - if (prefs.getString("libretro_name", "").isEmpty() == false) { - libretro_name = prefs.getString("libretro_name", "No core"); - setCoreTitle(libretro_name); - } - } else { - libretro_path = getInstance().getApplicationInfo().nativeLibraryDir; - libretro_name = "No core"; - setCoreTitle("No core"); - } - Intent startedByIntent = getIntent(); if (null != startedByIntent.getStringExtra("ROM") && null != startedByIntent.getStringExtra("LIBRETRO")) { @@ -120,9 +114,7 @@ public class MainMenuActivity extends PreferenceActivity { public static final double getRefreshRate() { double rate = 0; - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getInstance() - .getBaseContext()); + SharedPreferences prefs = getPreferences(); String refresh_rate = prefs.getString("video_refresh_rate", ""); if (!refresh_rate.isEmpty()) { try { @@ -193,26 +185,23 @@ public class MainMenuActivity extends PreferenceActivity { Log.i(TAG, "Using sampling rate: " + ret + " Hz"); return ret; } + + private static String sanitizeLibretroPath(String path) { + String sanitized_name = path.substring( + path.lastIndexOf("/") + 1, + path.lastIndexOf(".")); + sanitized_name = sanitized_name.replace("neon", ""); + sanitized_name = sanitized_name.replace("libretro_", ""); + return sanitized_name; + } public static String getDefaultConfigPath() { String internal = System.getenv("INTERNAL_STORAGE"); String external = System.getenv("EXTERNAL_STORAGE"); - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getInstance() - .getBaseContext()); - - boolean global_config_enable = prefs.getBoolean("global_config_enable", - true); - boolean config_same_as_native_lib_dir = libretro_path - .equals(getInstance().getApplicationInfo().nativeLibraryDir); String append_path; - if (!global_config_enable && (config_same_as_native_lib_dir == false)) { - String sanitized_name = libretro_path.substring( - libretro_path.lastIndexOf("/") + 1, - libretro_path.lastIndexOf(".")); - sanitized_name = sanitized_name.replace("neon", ""); - sanitized_name = sanitized_name.replace("libretro_", ""); + if (getInstance().usePerCoreConfig()) { + String sanitized_name = sanitizeLibretroPath(libretro_path); append_path = File.separator + sanitized_name + "retroarch.cfg"; } else { append_path = File.separator + "retroarch.cfg"; @@ -253,9 +242,7 @@ public class MainMenuActivity extends PreferenceActivity { config = new ConfigFile(); } - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getInstance() - .getBaseContext()); + SharedPreferences prefs = getPreferences(); config.setString("libretro_path", libretro_path); config.setString("libretro_name", libretro_name); @@ -536,16 +523,16 @@ public class MainMenuActivity extends PreferenceActivity { dialog.show(); } + + public static SharedPreferences getPreferences() { + return PreferenceManager.getDefaultSharedPreferences(getInstance().getBaseContext()); + } public void setModule(String core_path, String core_name) { libretro_path = core_path; libretro_name = core_name; - File libretro_path_file = new File(core_path); - setCoreTitle((libretro_path_file.isDirectory() == true) ? "No core" - : core_name); - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences prefs = getPreferences(); SharedPreferences.Editor edit = prefs.edit(); edit.putString("libretro_path", libretro_path); edit.putString("libretro_name", libretro_name); @@ -575,8 +562,7 @@ public class MainMenuActivity extends PreferenceActivity { @Override public void onClick(DialogInterface dialog, int which) { - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences prefs = getPreferences(); SharedPreferences.Editor edit = prefs .edit(); edit.putString("video_refresh_rate", Double @@ -599,8 +585,7 @@ public class MainMenuActivity extends PreferenceActivity { @Override public void onClick(DialogInterface dialog, int which) { - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences prefs = getPreferences(); SharedPreferences.Editor edit = prefs .edit(); edit.putBoolean("input_overlay_enable", @@ -622,8 +607,7 @@ public class MainMenuActivity extends PreferenceActivity { @Override public void onClick(DialogInterface dialog, int which) { - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences prefs = getPreferences(); SharedPreferences.Editor edit = prefs .edit(); edit.putBoolean("input_overlay_enable", @@ -644,8 +628,7 @@ public class MainMenuActivity extends PreferenceActivity { @Override public void onClick(DialogInterface dialog, int which) { - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); + SharedPreferences prefs = getPreferences(); SharedPreferences.Editor edit = prefs .edit(); edit.putString("video_refresh_rate", Double @@ -663,6 +646,8 @@ public class MainMenuActivity extends PreferenceActivity { "Device either not detected in list or doesn't have any optimal settings in our database.", Toast.LENGTH_SHORT).show(); } + + refreshPreferenceScreen(); return retval; } diff --git a/android/phoenix/src/org/retroarch/browser/ROMActivity.java b/android/phoenix/src/org/retroarch/browser/ROMActivity.java index ed6cf81412..27a9e084b2 100644 --- a/android/phoenix/src/org/retroarch/browser/ROMActivity.java +++ b/android/phoenix/src/org/retroarch/browser/ROMActivity.java @@ -4,13 +4,12 @@ import java.io.File; import android.content.SharedPreferences; import android.os.Bundle; -import android.preference.PreferenceManager; public class ROMActivity extends DirectoryActivity { @Override public void onCreate(Bundle savedInstanceState) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + SharedPreferences prefs = MainMenuActivity.getPreferences(); String startPath = prefs.getString("rgui_browser_directory", ""); if (!startPath.isEmpty() && new File(startPath).exists()) super.setStartDirectory(startPath); diff --git a/android/phoenix/src/org/retroarch/browser/RefreshRateSetOS.java b/android/phoenix/src/org/retroarch/browser/RefreshRateSetOS.java index b9479c80eb..cbef30d588 100644 --- a/android/phoenix/src/org/retroarch/browser/RefreshRateSetOS.java +++ b/android/phoenix/src/org/retroarch/browser/RefreshRateSetOS.java @@ -4,7 +4,6 @@ import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; -import android.preference.PreferenceManager; import android.view.Display; import android.view.WindowManager; import android.widget.Toast; @@ -18,7 +17,7 @@ public class RefreshRateSetOS extends Activity { final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); final Display display = wm.getDefaultDisplay(); double rate = display.getRefreshRate(); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + SharedPreferences prefs = MainMenuActivity.getPreferences(); SharedPreferences.Editor edit = prefs.edit(); edit.putString("video_refresh_rate", Double.valueOf(rate).toString()); edit.commit(); From b6539dc879b6098dcf29c5e2cc2a352a88d8fbdc Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 24 Aug 2013 16:26:19 +0200 Subject: [PATCH 091/202] Initial start for per-core configs. Dirty, but only real way to do this on Android it seems. --- .../retroarch/browser/MainMenuActivity.java | 110 +++++++++++++++--- 1 file changed, 94 insertions(+), 16 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 51e4a4c885..7e6301ca24 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -18,6 +18,8 @@ import android.media.AudioManager; import android.media.AudioTrack; import android.os.Bundle; import android.os.Handler; +import android.preference.CheckBoxPreference; +import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; import android.provider.Settings; @@ -33,23 +35,41 @@ public class MainMenuActivity extends PreferenceActivity { static private String libretro_path; static private String libretro_name; + private boolean globalConfigEnable = true; + @SuppressWarnings("deprecation") private void refreshPreferenceScreen() { + readbackConfigFile(); + setPreferenceScreen(null); addPreferencesFromResource(R.xml.prefs); setCoreTitle(libretro_name); - PreferenceManager.setDefaultValues(this, R.xml.prefs, true); + PreferenceManager.setDefaultValues(this, R.xml.prefs, false); + + final CheckBoxPreference param = (CheckBoxPreference) findPreference("global_config_enable"); + globalConfigEnable = param.isChecked(); + param.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + updateConfigFile(); + globalConfigEnable = param.isChecked(); + SharedPreferences prefs = MainMenuActivity.getPreferences(); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("global_config_enable", param.isChecked()); + edit.commit(); + + refreshPreferenceScreen(); + return true; + } + }); } private boolean usePerCoreConfig() { - SharedPreferences prefs = getPreferences(); - - boolean global_config_enable = prefs.getBoolean("global_config_enable", true); boolean config_same_as_native_lib_dir = libretro_path .equals(getApplicationInfo().nativeLibraryDir); - return !global_config_enable && !config_same_as_native_lib_dir; + return !globalConfigEnable && !config_same_as_native_lib_dir; } @Override @@ -202,7 +222,7 @@ public class MainMenuActivity extends PreferenceActivity { String append_path; if (getInstance().usePerCoreConfig()) { String sanitized_name = sanitizeLibretroPath(libretro_path); - append_path = File.separator + sanitized_name + "retroarch.cfg"; + append_path = File.separator + sanitized_name + ".cfg"; } else { append_path = File.separator + "retroarch.cfg"; } @@ -233,25 +253,78 @@ public class MainMenuActivity extends PreferenceActivity { // emergency fallback, all else failed return "/mnt/sd" + append_path; } - - public void updateConfigFile() { + + private void readbackString(ConfigFile cfg, SharedPreferences.Editor edit, String key) { + if (cfg.keyExists(key)) + edit.putString(key, cfg.getString(key)); + else + edit.remove(key); + } + + private void readbackBool(ConfigFile cfg, SharedPreferences.Editor edit, String key) { + if (cfg.keyExists(key)) + edit.putBoolean(key, cfg.getBoolean(key)); + else + edit.remove(key); + } + + private void readbackDouble(ConfigFile cfg, SharedPreferences.Editor edit, String key) { + if (cfg.keyExists(key)) + edit.putFloat(key, (float)cfg.getDouble(key)); + else + edit.remove(key); + } + + public void readbackConfigFile() { + String path = getDefaultConfigPath(); ConfigFile config; try { - config = new ConfigFile(new File(getDefaultConfigPath())); + config = new ConfigFile(new File(path)); + } catch (IOException e) { + return; + } + + Log.i(TAG, "Config readback from: " + path); + + SharedPreferences prefs = getPreferences(); + SharedPreferences.Editor edit = prefs.edit(); + + readbackString(config, edit, "rgui_browser_directory"); + readbackString(config, edit, "savefile_directory"); + readbackString(config, edit, "savestate_directory"); + readbackBool(config, edit, "savefile_directory_enable"); // Ignored by RetroArch + readbackBool(config, edit, "savestate_directory_enable"); // Ignored by RetroArch + + readbackString(config, edit, "input_overlay"); + readbackBool(config, edit, "input_overlay_enable"); + readbackBool(config, edit, "video_scale_integer"); + readbackBool(config, edit, "video_smooth"); + readbackBool(config, edit, "rewind_enable"); + readbackBool(config, edit, "savestate_auto_load"); + readbackBool(config, edit, "savestate_auto_save"); + + readbackDouble(config, edit, "input_overlay_opacity"); + + edit.commit(); + } + + public void updateConfigFile() { + String path = getDefaultConfigPath(); + ConfigFile config; + try { + config = new ConfigFile(new File(path)); } catch (IOException e) { config = new ConfigFile(); } + + Log.i(TAG, "Writing config to: " + path); SharedPreferences prefs = getPreferences(); config.setString("libretro_path", libretro_path); - config.setString("libretro_name", libretro_name); - setCoreTitle(libretro_name); config.setString("rgui_browser_directory", prefs.getString("rgui_browser_directory", "")); - config.setBoolean("global_config_enable", - prefs.getBoolean("global_config_enable", true)); config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true)); @@ -341,6 +414,7 @@ public class MainMenuActivity extends PreferenceActivity { && new File(shaderPath).exists()); boolean useOverlay = prefs.getBoolean("input_overlay_enable", true); + config.setBoolean("input_overlay_enable", useOverlay); // Not used by RetroArch directly. if (useOverlay) { String overlayPath = prefs .getString("input_overlay", (getInstance() @@ -383,11 +457,10 @@ public class MainMenuActivity extends PreferenceActivity { } } - String confPath = getDefaultConfigPath(); try { - config.write(new File(confPath)); + config.write(new File(path)); } catch (IOException e) { - Log.e(TAG, "Failed to save config file to: " + confPath); + Log.e(TAG, "Failed to save config file to: " + path); } } @@ -529,6 +602,8 @@ public class MainMenuActivity extends PreferenceActivity { } public void setModule(String core_path, String core_name) { + updateConfigFile(); + libretro_path = core_path; libretro_name = core_name; @@ -537,6 +612,9 @@ public class MainMenuActivity extends PreferenceActivity { edit.putString("libretro_path", libretro_path); edit.putString("libretro_name", libretro_name); edit.commit(); + + if (usePerCoreConfig()) + refreshPreferenceScreen(); } public void setCoreTitle(String core_name) { From 23faaba1f141508ff75f11d5a1c4cb3dfb93e309 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 24 Aug 2013 16:37:04 +0200 Subject: [PATCH 092/202] (Android) Add getFloat/setFloat to ConfigFile.java --- .../src/org/retroarch/browser/ConfigFile.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/android/phoenix/src/org/retroarch/browser/ConfigFile.java b/android/phoenix/src/org/retroarch/browser/ConfigFile.java index 4868ee55a3..2aec2b2859 100644 --- a/android/phoenix/src/org/retroarch/browser/ConfigFile.java +++ b/android/phoenix/src/org/retroarch/browser/ConfigFile.java @@ -80,6 +80,10 @@ public class ConfigFile { public void setDouble(String key, double value) { map.put(key, Double.toString(value)); } + + public void setFloat(String key, float value) { + map.put(key, Float.toString(value)); + } public boolean keyExists(String key) { return map.containsKey(key); @@ -108,6 +112,14 @@ public class ConfigFile { else throw new NumberFormatException(); } + + public float getFloat(String key) throws NumberFormatException { + String str = getString(key); + if (str != null) + return Float.parseFloat(str); + else + throw new NumberFormatException(); + } public boolean getBoolean(String key) { String str = getString(key); From a1abd8aaa7632572c977e114a07e9e74b3e7f0b0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 24 Aug 2013 16:39:23 +0200 Subject: [PATCH 093/202] (Android Java) Add readBackFloat --- .../src/org/retroarch/browser/MainMenuActivity.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 7e6301ca24..ccf779439a 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -275,6 +275,13 @@ public class MainMenuActivity extends PreferenceActivity { edit.remove(key); } + private void readbackFloat(ConfigFile cfg, SharedPreferences.Editor edit, String key) { + if (cfg.keyExists(key)) + edit.putFloat(key, cfg.getFloat(key)); + else + edit.remove(key); + } + public void readbackConfigFile() { String path = getDefaultConfigPath(); ConfigFile config; From fa32fca53d7a2ccf13a4ff482178a7c4743f7472 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 24 Aug 2013 17:30:09 +0200 Subject: [PATCH 094/202] (Android Java) Add some more settings to per-core config --- .../org/retroarch/browser/MainMenuActivity.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index ccf779439a..2828995f9e 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -302,15 +302,28 @@ public class MainMenuActivity extends PreferenceActivity { readbackBool(config, edit, "savefile_directory_enable"); // Ignored by RetroArch readbackBool(config, edit, "savestate_directory_enable"); // Ignored by RetroArch + String input_overlay = config.getString("input_overlay"); + + readbackString(config, edit, "input_overlay"); readbackBool(config, edit, "input_overlay_enable"); readbackBool(config, edit, "video_scale_integer"); readbackBool(config, edit, "video_smooth"); + readbackBool(config, edit, "video_threaded"); readbackBool(config, edit, "rewind_enable"); readbackBool(config, edit, "savestate_auto_load"); readbackBool(config, edit, "savestate_auto_save"); + readbackBool(config, edit, "audio_rate_control"); + readbackBool(config, edit, "audio_enable"); + // TODO: other audio settings + readbackDouble(config, edit, "input_overlay_opacity"); + readbackBool(config, edit, "input_autodetect_enable"); + + readbackBool(config, edit, "video_allow_rotate"); + + readbackBool(config, edit, "video_vsync"); edit.commit(); } @@ -433,7 +446,6 @@ public class MainMenuActivity extends PreferenceActivity { } else { config.setString("input_overlay", ""); } - config.setString( "savefile_directory", prefs.getBoolean("savefile_directory_enable", false) ? prefs From 8f72a8aa468063f3546e845530312620d73bd1ed Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 24 Aug 2013 20:24:40 +0200 Subject: [PATCH 095/202] (Android Java) Apply setCoreTitle even when per-core configs is not enabled --- .../phoenix/src/org/retroarch/browser/MainMenuActivity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 2828995f9e..ab418e21f7 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -634,6 +634,9 @@ public class MainMenuActivity extends PreferenceActivity { if (usePerCoreConfig()) refreshPreferenceScreen(); + else { + setCoreTitle(libretro_name); // this still needs to be applied + } } public void setCoreTitle(String core_name) { From 7c81f554af0660f664125874e8ff340d6955e30e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 24 Aug 2013 22:35:54 +0200 Subject: [PATCH 096/202] Add RETRO_ENVIRONMENT_SET_LIBRETRO_PATH to libretro API. Also gives us opportunity to write internal code - other libretro implementations can now just implement this environ callback and have other external frontends of their own be able to swap in/out libretro cores from outside --- dynamic.c | 13 ++++++++----- dynamic.h | 2 ++ frontend/frontend.c | 7 +++++-- frontend/menu/menu_common.c | 8 +++++--- frontend/menu/rgui.c | 8 +++++++- frontend/menu/rmenu.c | 16 +++++++++++----- libretro.h | 4 +++- 7 files changed, 41 insertions(+), 17 deletions(-) diff --git a/dynamic.c b/dynamic.c index 401b1f4e46..ec7a0cd77a 100644 --- a/dynamic.c +++ b/dynamic.c @@ -93,8 +93,6 @@ unsigned (*pretro_get_region)(void); void *(*pretro_get_memory_data)(unsigned); size_t (*pretro_get_memory_size)(unsigned); -static bool environment_cb(unsigned cmd, void *data); - #ifdef HAVE_DYNAMIC #if defined(__APPLE__) #define DYNAMIC_EXT "dylib" @@ -397,7 +395,7 @@ void init_libretro_sym(bool dummy) load_symbols(dummy); - pretro_set_environment(environment_cb); + pretro_set_environment(rarch_environment_cb); } void uninit_libretro_sym(void) @@ -471,7 +469,7 @@ void dylib_close(dylib_t lib) } #endif -static bool environment_cb(unsigned cmd, void *data) +bool rarch_environment_cb(unsigned cmd, void *data) { switch (cmd) { @@ -757,7 +755,12 @@ static bool environment_cb(unsigned cmd, void *data) g_extern.system.frame_time = *info; break; } - + case RETRO_ENVIRONMENT_SET_LIBRETRO_PATH: + { + struct retro_variable *var = (struct retro_variable*)data; + strlcpy(g_settings.libretro, var->value, sizeof(g_settings.libretro)); + break; + } default: RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd); return false; diff --git a/dynamic.h b/dynamic.h index 6efa2722fb..198f81e39e 100644 --- a/dynamic.h +++ b/dynamic.h @@ -101,6 +101,8 @@ extern unsigned (*pretro_get_region)(void); extern void *(*pretro_get_memory_data)(unsigned); extern size_t (*pretro_get_memory_size)(unsigned); +extern bool rarch_environment_cb(unsigned cmd, void *data); + #ifdef __cplusplus } #endif diff --git a/frontend/frontend.c b/frontend/frontend.c index 4a9093d4e1..9ddd54eecb 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -63,8 +63,11 @@ static bool libretro_install_core(const char *path_prefix, return false; } - strlcpy(g_settings.libretro, new_path, - sizeof(g_settings.libretro)); + struct retro_variable var; + var.key = "core_path"; + var.value = new_path; + + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); return true; } diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 69c66818a8..39046d2443 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -438,13 +438,15 @@ void load_menu_game_prepare(void) void load_menu_game_history(unsigned game_index) { const char *path = NULL; - const char *core_path = NULL; const char *core_name = NULL; + struct retro_variable var; + + var.key = "core_path"; rom_history_get_index(rgui->history, - game_index, &path, &core_path, &core_name); + game_index, &path, &var.value, &core_name); - strlcpy(g_settings.libretro, core_path, sizeof(g_settings.libretro)); + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); if (path) { diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 3edeec1b08..c7b5aedd23 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -2654,7 +2654,13 @@ int rgui_iterate(rgui_handle_t *rgui) // Core selection on non-console just updates directory listing. // Will take affect on new ROM load. #elif defined(GEKKO) && defined(HW_RVL) - strlcpy(g_settings.libretro, path, sizeof(g_settings.libretro)); // Is this supposed to be here? + struct retro_variable var; + + var.key = "core_path"; + var.value = path; + + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); + fill_pathname_join(g_extern.fullpath, default_paths.core_dir, SALAMANDER_FILE, sizeof(g_extern.fullpath)); g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); diff --git a/frontend/menu/rmenu.c b/frontend/menu/rmenu.c index 691232bad3..f956c1f4e4 100644 --- a/frontend/menu/rmenu.c +++ b/frontend/menu/rmenu.c @@ -460,7 +460,6 @@ static int select_file(void *data, uint64_t input) char extensions[128]; char comment[128]; char path[PATH_MAX]; - bool ret = true; bool pop_menu_stack = false; font_params_t font_parms = {0}; @@ -495,7 +494,7 @@ static int select_file(void *data, uint64_t input) if (input & (1ULL << DEVICE_NAV_B)) { if (filebrowser_iterate(rgui->browser, FILEBROWSER_ACTION_PATH_ISDIR)) - ret = filebrowser_iterate(rgui->browser, FILEBROWSER_ACTION_OK); + filebrowser_iterate(rgui->browser, FILEBROWSER_ACTION_OK); else { strlcpy(path, rgui->browser->current_dir.path, sizeof(path)); @@ -560,9 +559,16 @@ static int select_file(void *data, uint64_t input) true, menu_texture->width, menu_texture->height, 1.0f); break; case LIBRETRO_CHOICE: - strlcpy(g_settings.libretro, path, sizeof(g_settings.libretro)); - g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); - return -1; + { + struct retro_variable var; + + var.key = "core_path"; + var.value = path; + + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); + g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); + return -1; + } } pop_menu_stack = true; diff --git a/libretro.h b/libretro.h index 72050e93d5..aeb9e4ad2a 100755 --- a/libretro.h +++ b/libretro.h @@ -509,7 +509,9 @@ enum retro_mod // Lets the core know how much time has passed since last invocation of retro_run(). // The frontend can tamper with the timing to fake fast-forward, slow-motion, frame stepping, etc. // In this case the delta time will use the reference value in frame_time_callback.. - +#define RETRO_ENVIRONMENT_SET_LIBRETRO_PATH 22 + // const char ** -- + // Sets the absolute path for the libretro core pointed to. // Notifies libretro that audio data should be written. typedef void (*retro_audio_callback_t)(void); From 08ae8226eb05199265b345d30cdf8f63c0df4e49 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 24 Aug 2013 22:56:34 +0200 Subject: [PATCH 097/202] Update libretro header --- libretro.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro.h b/libretro.h index aeb9e4ad2a..06cbc3abb4 100755 --- a/libretro.h +++ b/libretro.h @@ -510,7 +510,7 @@ enum retro_mod // The frontend can tamper with the timing to fake fast-forward, slow-motion, frame stepping, etc. // In this case the delta time will use the reference value in frame_time_callback.. #define RETRO_ENVIRONMENT_SET_LIBRETRO_PATH 22 - // const char ** -- + // struct retro_variable * -- // Sets the absolute path for the libretro core pointed to. // Notifies libretro that audio data should be written. From b26fcfb4a6d704627db299016a2b04e815fdc49b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 24 Aug 2013 22:59:29 +0200 Subject: [PATCH 098/202] Libretro header - Typo - aquire -> acquire --- libretro.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro.h b/libretro.h index 06cbc3abb4..36baa0d14b 100755 --- a/libretro.h +++ b/libretro.h @@ -445,7 +445,7 @@ enum retro_mod // If HW rendering is used, pass only RETRO_HW_FRAME_BUFFER_VALID or NULL to retro_video_refresh_t. #define RETRO_ENVIRONMENT_GET_VARIABLE 15 // struct retro_variable * -- - // Interface to aquire user-defined information from environment + // Interface to acquire user-defined information from environment // that cannot feasibly be supported in a multi-system way. // 'key' should be set to a key which has already been set by SET_VARIABLES. // 'data' will be set to a value or NULL. From 8aef9f4c64a234a7be4fd7526186d6bee99d225d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 24 Aug 2013 23:08:40 +0200 Subject: [PATCH 099/202] Hide away g_settings.libretro mutation and do calls to environment callback action instead - frontends should do it this way as well --- frontend/menu/rmenu_xui.cpp | 7 +++++-- frontend/platform/platform_gx.c | 7 ++++++- frontend/platform/platform_qnx.c | 7 ++++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/frontend/menu/rmenu_xui.cpp b/frontend/menu/rmenu_xui.cpp index 8b41252f44..815d7ca2fa 100644 --- a/frontend/menu/rmenu_xui.cpp +++ b/frontend/menu/rmenu_xui.cpp @@ -1222,8 +1222,11 @@ HRESULT CRetroArchCoreBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandle wcstombs(str_buffer, (const wchar_t *)XuiListGetText(m_menulist, index), sizeof(str_buffer)); if(path_file_exists(rgui->browser->list->elems[index].data)) { - snprintf(g_settings.libretro, sizeof(g_settings.libretro), "%s\\%s", - rgui->browser->current_dir.directory_path, str_buffer); + struct retro_variable var; + var.key = "core_path"; + snprintf(var.value, sizeof(var.value), "%s\\%s", rgui->browser->current_dir.directory_path, str_buffer); + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); + g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); process_input_ret = -1; } diff --git a/frontend/platform/platform_gx.c b/frontend/platform/platform_gx.c index 102514d0ab..807c309a6c 100644 --- a/frontend/platform/platform_gx.c +++ b/frontend/platform/platform_gx.c @@ -367,7 +367,12 @@ static int system_process_args(int argc, char *argv[], void *args) // a big hack: sometimes salamander doesn't save the new core it loads on first boot, // so we make sure g_settings.libretro is set here if (!g_settings.libretro[0] && argc >= 1 && strrchr(argv[0], '/')) - strlcpy(g_settings.libretro, strrchr(argv[0], '/') + 1, sizeof(g_settings.libretro)); + { + struct retro_variable var; + var.key = "core_path"; + strlcpy(var.value, strrchr(argv[0], '/') + 1, sizeof(var.value)); + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); + } if (argc > 2 && argv[1] != NULL && argv[2] != NULL) { diff --git a/frontend/platform/platform_qnx.c b/frontend/platform/platform_qnx.c index 1f2e4f3080..3250dc13ae 100644 --- a/frontend/platform/platform_qnx.c +++ b/frontend/platform/platform_qnx.c @@ -28,7 +28,12 @@ static void get_environment_settings(int argc, char *argv[], void *args) /* FIXME - should this apply for both BB10 and PB? */ #if defined(__QNX__) && !defined(HAVE_BB10) - strlcpy(g_settings.libretro, "app/native/lib", sizeof(g_settings.libretro)); + struct retro_variable var; + + var.key = "core_path"; + strlcpy(var.value, "app/native/lib", sizeof(var.value)); + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); + strlcpy(g_extern.config_path, "app/native/retroarch.cfg", sizeof(g_extern.config_path)); strlcpy(g_settings.video.shader_dir, "app/native/shaders_glsl", sizeof(g_settings.video.shader_dir)); #endif From edfab9630aeea3b8ed90de1ef7240a1f251fec92 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 25 Aug 2013 01:37:15 +0200 Subject: [PATCH 100/202] Add RETRO_ENVIRONMENT_EXEC - refactor some stuff internally in libretro frontend to implement this new functionality --- dynamic.c | 25 +++++++++++++++++++++++++ frontend/menu/menu_common.c | 18 ++++++------------ libretro.h | 7 +++++++ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/dynamic.c b/dynamic.c index ec7a0cd77a..b24ef9b2c1 100644 --- a/dynamic.c +++ b/dynamic.c @@ -757,10 +757,35 @@ bool rarch_environment_cb(unsigned cmd, void *data) } case RETRO_ENVIRONMENT_SET_LIBRETRO_PATH: { + RARCH_LOG("Environ SET_LIBRETRO_PATH.\n"); + struct retro_variable *var = (struct retro_variable*)data; strlcpy(g_settings.libretro, var->value, sizeof(g_settings.libretro)); break; } + case RETRO_ENVIRONMENT_EXEC: + { + RARCH_LOG("Environ EXEC.\n"); + + struct retro_variable *var = (struct retro_variable*)data; + if (var->value) + strlcpy(g_extern.fullpath, var->value, sizeof(g_extern.fullpath)); + else + *g_extern.fullpath = '\0'; + + if (strcasecmp(var->key, "EXEC_RELOAD") == 0) + { +#if !defined( HAVE_DYNAMIC) && defined(RARCH_CONSOLE) + g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); + g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); + g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN_START_GAME); +#elif defined(HAVE_DYNAMIC) + g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME); +#endif + } + + break; + } default: RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd); return false; diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 39046d2443..ef1ff7e72e 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -449,24 +449,18 @@ void load_menu_game_history(unsigned game_index) rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); if (path) - { rgui->load_no_rom = false; - strlcpy(g_extern.fullpath, path, sizeof(g_extern.fullpath)); - } else - { rgui->load_no_rom = true; - *g_extern.fullpath = '\0'; - } -#if !defined( HAVE_DYNAMIC) && defined(RARCH_CONSOLE) - g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); - g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); - g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN_START_GAME); -#elif defined(HAVE_DYNAMIC) + var.key = "EXEC_RELOAD"; + var.value = path; + + rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, &var); + +#if defined(HAVE_DYNAMIC) libretro_free_system_info(&rgui->info); libretro_get_system_info(g_settings.libretro, &rgui->info, NULL); - g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME); #endif } diff --git a/libretro.h b/libretro.h index 36baa0d14b..2d84aaf1b3 100755 --- a/libretro.h +++ b/libretro.h @@ -512,6 +512,13 @@ enum retro_mod #define RETRO_ENVIRONMENT_SET_LIBRETRO_PATH 22 // struct retro_variable * -- // Sets the absolute path for the libretro core pointed to. +#define RETRO_ENVIRONMENT_EXEC 23 + // struct retro_variable * -- + // Sets an input file for the libretro core to execute with, and (based on key name) will determine what + // exec method to follow. + // "EXEC_LOAD" : will start the input file whose path was passed from the parameter to RETRO_ENVIRONMENT_EXEC. + // "EXEC_RELOAD" : will set the current libretro core, deinitialize the currently running media and then + // start the input file whose path was passed from the parameter to RETRO_ENVIRONMENT_EXEC. // Notifies libretro that audio data should be written. typedef void (*retro_audio_callback_t)(void); From 7a72899c15cf9f7570e8902edb6b958fd9df20e5 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 24 Aug 2013 20:27:04 -0400 Subject: [PATCH 101/202] (iOS) Move browser logic into platform.m --- apple/iOS/browser.m | 65 ++++++++++++++------------------------------ apple/iOS/platform.h | 5 +++- apple/iOS/platform.m | 49 ++++++++++++++++++++++++++++----- apple/iOS/views.h | 15 ++++++---- 4 files changed, 77 insertions(+), 57 deletions(-) diff --git a/apple/iOS/browser.m b/apple/iOS/browser.m index 62b2808745..6530c87bfd 100644 --- a/apple/iOS/browser.m +++ b/apple/iOS/browser.m @@ -29,44 +29,33 @@ { NSString* _path; NSMutableArray* _sectionNames; + id _delegate; } -+ (id)directoryListAtBrowseRoot -{ - NSString* rootPath = RetroArch_iOS.get.documentsDirectory; - NSString* ragPath = [rootPath stringByAppendingPathComponent:@"RetroArchGames"]; - RADirectoryList* list = [RADirectoryList directoryListForPath:path_is_directory(ragPath.UTF8String) ? ragPath : rootPath]; - return list; -} -+ (id)directoryListForPath:(NSString*)path -{ - // NOTE: Don't remove or ignore this abstraction, this function will be expanded when cover art comes back. - return [[RADirectoryList alloc] initWithPath:path]; -} - -- (id)initWithPath:(NSString*)path +- (id)initWithPath:(NSString*)path delegate:(id)delegate { _path = path; + _delegate = delegate; self = [super initWithStyle:UITableViewStylePlain]; self.title = path.lastPathComponent; self.hidesHeaders = YES; - NSMutableArray *toolbarButtons = [[NSMutableArray alloc] initWithCapacity:3]; + NSMutableArray *toolbarButtons = [[NSMutableArray alloc] initWithCapacity:3]; - UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refresh)]; - refreshButton.style = UIBarButtonItemStyleBordered; - [toolbarButtons addObject:refreshButton]; + UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refresh)]; + refreshButton.style = UIBarButtonItemStyleBordered; + [toolbarButtons addObject:refreshButton]; - UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil]; - [toolbarButtons addObject:flexibleSpace]; + UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil]; + [toolbarButtons addObject:flexibleSpace]; - UIBarButtonItem *newFolderButton = [[UIBarButtonItem alloc] initWithTitle:@"New Folder" style:UIBarButtonItemStyleBordered target:self action:@selector(createNewFolder)]; - [toolbarButtons addObject:newFolderButton]; + UIBarButtonItem *newFolderButton = [[UIBarButtonItem alloc] initWithTitle:@"New Folder" style:UIBarButtonItemStyleBordered target:self action:@selector(createNewFolder)]; + [toolbarButtons addObject:newFolderButton]; - [[[RetroArch_iOS get] toolbar] setItems:toolbarButtons]; - [self setToolbarItems:toolbarButtons]; + [[[RetroArch_iOS get] toolbar] setItems:toolbarButtons]; + [self setToolbarItems:toolbarButtons]; [self refresh]; @@ -127,18 +116,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - RADirectoryItem* path = (RADirectoryItem*)[self itemForIndexPath:indexPath]; - - if(path.isDirectory) - [[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListForPath:path.path] animated:YES]; - else - { - if (access(_path.UTF8String, R_OK | W_OK | X_OK)) - apple_display_alert(@"The directory containing the selected file has limited permissions. This may " - "prevent zipped games from loading, and will cause some cores to not function.", 0); - - [[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] animated:YES]; - } + [_delegate directoryList:self itemWasSelected:[self itemForIndexPath:indexPath]]; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath @@ -224,15 +202,14 @@ @implementation RAModuleList { - NSString* _game; + id _delegate; } -- (id)initWithGame:(NSString*)path +- (id)initWithGame:(NSString*)path delegate:(id)delegate { self = [super initWithStyle:UITableViewStyleGrouped]; - [self setTitle:[path lastPathComponent]]; - - _game = path; + [self setTitle:path ? [path lastPathComponent] : @"Cores"]; + _delegate = delegate; // Load the modules with their data NSArray* moduleList = [RAModuleInfo getModules]; @@ -242,8 +219,8 @@ for (RAModuleInfo* i in moduleList) { - if ([i supportsFileAtPath:_game]) [supported addObject:i]; - else [other addObject:i]; + if (path && [i supportsFileAtPath:path]) [supported addObject:i]; + else [other addObject:i]; } if (supported.count > 1) @@ -257,7 +234,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - apple_run_core((RAModuleInfo*)[self itemForIndexPath:indexPath], _game.UTF8String); + [_delegate moduleList:self itemWasSelected:[self itemForIndexPath:indexPath]]; } - (void)infoButtonTapped:(id)sender diff --git a/apple/iOS/platform.h b/apple/iOS/platform.h index d7a55f4668..c7d01d7756 100644 --- a/apple/iOS/platform.h +++ b/apple/iOS/platform.h @@ -17,13 +17,16 @@ #ifndef __RARCH_IOS_PLATFORM_H #define __RARCH_IOS_PLATFORM_H +#include "views.h" + @interface RAGameView : UIViewController + (RAGameView*)get; - (void)openPauseMenu; - (void)closePauseMenu; @end -@interface RetroArch_iOS : UINavigationController +@interface RetroArch_iOS : UINavigationController + (RetroArch_iOS*)get; diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index cfe1d8b391..3921d3f37f 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -85,6 +85,7 @@ static void handle_touch_event(NSArray* touches) @implementation RetroArch_iOS { UIWindow* _window; + NSString* _path; bool _isGameTop, _isRomList; uint32_t _settingMenusInBackStack; @@ -117,13 +118,8 @@ static void handle_touch_event(NSArray* touches) else if (!path_make_and_check_directory(self.systemDirectory.UTF8String, 0755, R_OK | W_OK | X_OK)) apple_display_alert([NSString stringWithFormat:@"Failed to create or access system directory: %@", self.systemDirectory], 0); else - { - [self pushViewController:[RADirectoryList directoryListAtBrowseRoot] animated:YES]; - [self refreshSystemConfig]; - - if (apple_use_tv_mode) - apple_run_core(nil, 0); - } + [self beginBrowsingForFile]; + // Warn if there are no cores present if ([RAModuleInfo getModules].count == 0) @@ -140,6 +136,45 @@ static void handle_touch_event(NSArray* touches) apple_enter_stasis(); } +#pragma mark Frontend Browsing Logic +- (void)beginBrowsingForFile +{ + NSString* rootPath = RetroArch_iOS.get.documentsDirectory; + NSString* ragPath = [rootPath stringByAppendingPathComponent:@"RetroArchGames"]; + NSString* target = path_is_directory(ragPath.UTF8String) ? ragPath : rootPath; + + [self pushViewController:[[RADirectoryList alloc] initWithPath:target delegate:self] animated:YES]; + + [self refreshSystemConfig]; + if (apple_use_tv_mode) + apple_run_core(nil, 0); + +} + +- (bool)directoryList:(id)list itemWasSelected:(RADirectoryItem*)path +{ + if(path.isDirectory) + [[RetroArch_iOS get] pushViewController:[[RADirectoryList alloc] initWithPath:path.path delegate:self] animated:YES]; + else + { + _path = path.path; + + if (access([path.path stringByDeletingLastPathComponent].UTF8String, R_OK | W_OK | X_OK)) + apple_display_alert(@"The directory containing the selected file has limited permissions. This may " + "prevent zipped games from loading, and will cause some cores to not function.", 0); + + [[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path delegate:self] animated:YES]; + } + + return true; +} + +- (bool)moduleList:(id)list itemWasSelected:(RAModuleInfo*)module +{ + apple_run_core(module, _path.UTF8String); + return true; +} + // UINavigationControllerDelegate - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { diff --git a/apple/iOS/views.h b/apple/iOS/views.h index 5b058b2ede..694ce88439 100644 --- a/apple/iOS/views.h +++ b/apple/iOS/views.h @@ -38,17 +38,22 @@ @end // browser.m +@protocol RADirectoryListDelegate +- (bool)directoryList:(id)list itemWasSelected:(RADirectoryItem*)path; +@end + @interface RADirectoryList : RATableViewController @property (nonatomic, weak) RADirectoryItem *selectedItem; - -+ (id)directoryListAtBrowseRoot; -+ (id)directoryListForPath:(NSString*)path; -- (id)initWithPath:(NSString*)path; +- (id)initWithPath:(NSString*)path delegate:(id)delegate; @end // browser.m +@protocol RAModuleListDelegate +- (bool)moduleList:(id)list itemWasSelected:(RAModuleInfo*)module; +@end + @interface RAModuleList : RATableViewController -- (id)initWithGame:(NSString*)path; +- (id)initWithGame:(NSString*)path delegate:(id)delegate; @end // browser.m From f83b40cd548becca0dc375ffc7d33bfed7d373ea Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 24 Aug 2013 20:36:03 -0400 Subject: [PATCH 102/202] (iOS) Help prevent file browser lists from going stale --- apple/RetroArch/utility.m | 5 ++++ apple/iOS/browser.m | 54 ++++++++++++++++++--------------------- apple/iOS/platform.m | 2 +- apple/iOS/views.h | 1 + 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/apple/RetroArch/utility.m b/apple/RetroArch/utility.m index 0836e9fdec..7875e69594 100644 --- a/apple/RetroArch/utility.m +++ b/apple/RetroArch/utility.m @@ -110,6 +110,11 @@ char* ios_get_rarch_system_directory() return self.sections[indexPath.section][indexPath.row + 1]; } +- (void)reset +{ + self.sections = [NSMutableArray array]; + [self.tableView reloadData]; +} @end #endif diff --git a/apple/iOS/browser.m b/apple/iOS/browser.m index 6530c87bfd..df557dda47 100644 --- a/apple/iOS/browser.m +++ b/apple/iOS/browser.m @@ -56,12 +56,20 @@ [[[RetroArch_iOS get] toolbar] setItems:toolbarButtons]; [self setToolbarItems:toolbarButtons]; - - [self refresh]; return self; } +- (void)viewWillAppear:(BOOL)animated +{ + [self refresh]; +} + +- (void)viewDidDisappear:(BOOL)animated +{ + [self reset]; +} + - (void)refresh { static const char sectionNames[28] = { '/', '#', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', @@ -121,21 +129,22 @@ - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - RADirectoryItem* path = (RADirectoryItem*)[self itemForIndexPath:indexPath]; - static NSString *CellIdentifier = @"path"; + static NSString* const cell_types[2] = { @"file", @"folder" }; + static NSString* const icon_types[2] = { @"ic_file", @"ic_dir" }; + static const UITableViewCellAccessoryType accessory_types[2] = { UITableViewCellAccessoryDetailDisclosureButton, + UITableViewCellAccessoryDisclosureIndicator }; + RADirectoryItem* path = [self itemForIndexPath:indexPath]; + uint32_t type_id = path.isDirectory ? 1 : 0; - UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier]; - cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; - cell.textLabel.text = [path.path lastPathComponent]; - cell.accessoryType = (path.isDirectory) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; - - if (path.isDirectory) { - cell.imageView.image = [UIImage imageNamed:@"ic_dir"]; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - } else { - cell.imageView.image = [UIImage imageNamed:@"ic_file"]; - cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; + UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:cell_types[type_id]]; + if (!cell) + { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cell_types[type_id]]; + cell.imageView.image = [UIImage imageNamed:icon_types[type_id]]; + cell.accessoryType = accessory_types[type_id]; } + + cell.textLabel.text = [path.path lastPathComponent]; return cell; } @@ -340,21 +349,8 @@ NSString *directoryPath = [currentDirectoryPath stringByAppendingPathComponent:cell.textLabel.text]; NSString *newPath = [directoryPath stringByAppendingPathComponent:fileName]; - BOOL didMove = [[NSFileManager defaultManager] moveItemAtPath:selectedFilePath toPath:newPath error:nil]; - - if (didMove) { - NSArray *viewsControllers = [[self presentingViewController] childViewControllers]; - - // Searches for RADirectoryList instance and call the refresh method - for (int i = 0; i < viewsControllers.count; i++) { - if ([viewsControllers[i] isKindOfClass:[RADirectoryList class]]) { - [viewsControllers[i] refresh]; - break; - } - } - } else { + if (![[NSFileManager defaultManager] moveItemAtPath:selectedFilePath toPath:newPath error:nil]) apple_display_alert(@"It was not possible to move the file", 0); - } [self dismissViewController]; } diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index 3921d3f37f..e285f65e28 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -294,7 +294,7 @@ static void handle_touch_event(NSArray* touches) ios_set_bluetooth_mode(objc_get_value_from_config(conf, @"ios_btmode", @"keyboard")); bool val; - apple_use_tv_mode = config_get_bool(conf, "ios_tv_mode", & val) && val; + apple_use_tv_mode = config_get_bool(conf, "ios_tv_mode", &val) && val; config_file_free(conf); } diff --git a/apple/iOS/views.h b/apple/iOS/views.h index 694ce88439..b2b5b887f5 100644 --- a/apple/iOS/views.h +++ b/apple/iOS/views.h @@ -29,6 +29,7 @@ - (id)initWithStyle:(UITableViewStyle)style; - (id)itemForIndexPath:(NSIndexPath*)indexPath; +- (void)reset; @end // browser.m From 32cae444a0987b05e5d14f5b52263c8973588b20 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 25 Aug 2013 11:07:06 +0200 Subject: [PATCH 103/202] Fixup new private extensions. Moved private stuff to libretro_private.h. Dropped use of retro_variable (redundant and wrong type). Didn't understand difference between EXEC_LOAD and EXEC_RELOAD at all. Only one was used anyways ... --- driver.h | 2 +- dynamic.c | 35 ++++++++++++---------------- frontend/frontend.c | 7 +----- frontend/menu/menu_common.c | 13 ++++------- frontend/menu/rgui.c | 7 +----- frontend/menu/rmenu.c | 13 +++-------- frontend/platform/platform_gx.c | 9 ++++---- frontend/platform/platform_qnx.c | 8 +++---- libretro.h | 13 +++-------- libretro_private.h | 39 ++++++++++++++++++++++++++++++++ 10 files changed, 73 insertions(+), 73 deletions(-) create mode 100644 libretro_private.h diff --git a/driver.h b/driver.h index bc4cdd7d1a..026a6df0b4 100644 --- a/driver.h +++ b/driver.h @@ -19,7 +19,7 @@ #include #include "boolean.h" -#include "libretro.h" +#include "libretro_private.h" #include #include #include "msvc/msvc_compat.h" diff --git a/dynamic.c b/dynamic.c index b24ef9b2c1..34d4ea48a9 100644 --- a/dynamic.c +++ b/dynamic.c @@ -30,7 +30,7 @@ #endif #include "boolean.h" -#include "libretro.h" +#include "libretro_private.h" #include "dynamic_dummy.h" #ifdef NEED_DYNAMIC @@ -755,37 +755,30 @@ bool rarch_environment_cb(unsigned cmd, void *data) g_extern.system.frame_time = *info; break; } + case RETRO_ENVIRONMENT_SET_LIBRETRO_PATH: - { - RARCH_LOG("Environ SET_LIBRETRO_PATH.\n"); - - struct retro_variable *var = (struct retro_variable*)data; - strlcpy(g_settings.libretro, var->value, sizeof(g_settings.libretro)); + RARCH_LOG("Environ (Private) SET_LIBRETRO_PATH.\n"); + strlcpy(g_settings.libretro, (const char*)data, sizeof(g_settings.libretro)); break; - } - case RETRO_ENVIRONMENT_EXEC: - { - RARCH_LOG("Environ EXEC.\n"); - struct retro_variable *var = (struct retro_variable*)data; - if (var->value) - strlcpy(g_extern.fullpath, var->value, sizeof(g_extern.fullpath)); + case RETRO_ENVIRONMENT_EXEC: + RARCH_LOG("Environ (Private) EXEC.\n"); + + if (data) + strlcpy(g_extern.fullpath, (const char*)data, sizeof(g_extern.fullpath)); else *g_extern.fullpath = '\0'; - if (strcasecmp(var->key, "EXEC_RELOAD") == 0) - { #if !defined( HAVE_DYNAMIC) && defined(RARCH_CONSOLE) - g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); - g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); - g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN_START_GAME); + g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); + g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); + g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN_START_GAME); #elif defined(HAVE_DYNAMIC) - g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME); + g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME); #endif - } break; - } + default: RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd); return false; diff --git a/frontend/frontend.c b/frontend/frontend.c index 9ddd54eecb..4102b07fbb 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -63,12 +63,7 @@ static bool libretro_install_core(const char *path_prefix, return false; } - struct retro_variable var; - var.key = "core_path"; - var.value = new_path; - - rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); - + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)new_path); return true; } diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index ef1ff7e72e..780be57a29 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -438,25 +438,20 @@ void load_menu_game_prepare(void) void load_menu_game_history(unsigned game_index) { const char *path = NULL; + const char *core_path = NULL; const char *core_name = NULL; - struct retro_variable var; - - var.key = "core_path"; rom_history_get_index(rgui->history, - game_index, &path, &var.value, &core_name); + game_index, &path, &core_path, &core_name); - rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)core_path); if (path) rgui->load_no_rom = false; else rgui->load_no_rom = true; - var.key = "EXEC_RELOAD"; - var.value = path; - - rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, &var); + rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)path); #if defined(HAVE_DYNAMIC) libretro_free_system_info(&rgui->info); diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index c7b5aedd23..27bb84c5e3 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -2654,12 +2654,7 @@ int rgui_iterate(rgui_handle_t *rgui) // Core selection on non-console just updates directory listing. // Will take affect on new ROM load. #elif defined(GEKKO) && defined(HW_RVL) - struct retro_variable var; - - var.key = "core_path"; - var.value = path; - - rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)path); fill_pathname_join(g_extern.fullpath, default_paths.core_dir, SALAMANDER_FILE, sizeof(g_extern.fullpath)); diff --git a/frontend/menu/rmenu.c b/frontend/menu/rmenu.c index f956c1f4e4..19aad8e7f3 100644 --- a/frontend/menu/rmenu.c +++ b/frontend/menu/rmenu.c @@ -559,16 +559,9 @@ static int select_file(void *data, uint64_t input) true, menu_texture->width, menu_texture->height, 1.0f); break; case LIBRETRO_CHOICE: - { - struct retro_variable var; - - var.key = "core_path"; - var.value = path; - - rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); - g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); - return -1; - } + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)path); + g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); + return -1; } pop_menu_stack = true; diff --git a/frontend/platform/platform_gx.c b/frontend/platform/platform_gx.c index 807c309a6c..2851e55b38 100644 --- a/frontend/platform/platform_gx.c +++ b/frontend/platform/platform_gx.c @@ -18,7 +18,7 @@ #include #include "../../driver.h" #include "../../general.h" -#include "../../libretro.h" +#include "../../libretro_private.h" #include "../../console/rarch_console.h" #include "../../file.h" @@ -368,10 +368,9 @@ static int system_process_args(int argc, char *argv[], void *args) // so we make sure g_settings.libretro is set here if (!g_settings.libretro[0] && argc >= 1 && strrchr(argv[0], '/')) { - struct retro_variable var; - var.key = "core_path"; - strlcpy(var.value, strrchr(argv[0], '/') + 1, sizeof(var.value)); - rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); + char path[PATH_MAX]; + strlcpy(path, strrchr(argv[0], '/') + 1, sizeof(path)); + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, path); } if (argc > 2 && argv[1] != NULL && argv[2] != NULL) diff --git a/frontend/platform/platform_qnx.c b/frontend/platform/platform_qnx.c index 3250dc13ae..d0864d7a0d 100644 --- a/frontend/platform/platform_qnx.c +++ b/frontend/platform/platform_qnx.c @@ -20,6 +20,8 @@ #include "../../boolean.h" #include #include +#include "../../dynamic.h" +#include "../../libretro_private.h" static void get_environment_settings(int argc, char *argv[], void *args) { @@ -28,11 +30,7 @@ static void get_environment_settings(int argc, char *argv[], void *args) /* FIXME - should this apply for both BB10 and PB? */ #if defined(__QNX__) && !defined(HAVE_BB10) - struct retro_variable var; - - var.key = "core_path"; - strlcpy(var.value, "app/native/lib", sizeof(var.value)); - rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var); + rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)"app/native/lib"); strlcpy(g_extern.config_path, "app/native/retroarch.cfg", sizeof(g_extern.config_path)); strlcpy(g_settings.video.shader_dir, "app/native/shaders_glsl", sizeof(g_settings.video.shader_dir)); diff --git a/libretro.h b/libretro.h index 2d84aaf1b3..7b767fe6eb 100755 --- a/libretro.h +++ b/libretro.h @@ -357,6 +357,8 @@ enum retro_mod // If set, this call is not part of the public libretro API yet. It can change or be removed at any time. #define RETRO_ENVIRONMENT_EXPERIMENTAL 0x10000 +// Environment callback to be used internally in frontend. +#define RETRO_ENVIRONMENT_PRIVATE 0x20000 // Environment commands. #define RETRO_ENVIRONMENT_SET_ROTATION 1 // const unsigned * -- @@ -509,16 +511,7 @@ enum retro_mod // Lets the core know how much time has passed since last invocation of retro_run(). // The frontend can tamper with the timing to fake fast-forward, slow-motion, frame stepping, etc. // In this case the delta time will use the reference value in frame_time_callback.. -#define RETRO_ENVIRONMENT_SET_LIBRETRO_PATH 22 - // struct retro_variable * -- - // Sets the absolute path for the libretro core pointed to. -#define RETRO_ENVIRONMENT_EXEC 23 - // struct retro_variable * -- - // Sets an input file for the libretro core to execute with, and (based on key name) will determine what - // exec method to follow. - // "EXEC_LOAD" : will start the input file whose path was passed from the parameter to RETRO_ENVIRONMENT_EXEC. - // "EXEC_RELOAD" : will set the current libretro core, deinitialize the currently running media and then - // start the input file whose path was passed from the parameter to RETRO_ENVIRONMENT_EXEC. + // Notifies libretro that audio data should be written. typedef void (*retro_audio_callback_t)(void); diff --git a/libretro_private.h b/libretro_private.h new file mode 100644 index 0000000000..6e41efcbfa --- /dev/null +++ b/libretro_private.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2010-2013 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this libretro API header (libretro_private.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIBRETRO_PRIVATE_H__ +#define LIBRETRO_PRIVATE_H__ + +// Private additions to libretro. No API/ABI stability guaranteed. + +#include "libretro.h" + +#define RETRO_ENVIRONMENT_SET_LIBRETRO_PATH (RETRO_ENVIRONMENT_PRIVATE | 0) + // const char * -- + // Sets the absolute path for the libretro core pointed to. RETRO_ENVIRONMENT_EXEC will use the last libretro core set with this call. +#define RETRO_ENVIRONMENT_EXEC (RETRO_ENVIRONMENT_PRIVATE | 1) + // const char * -- + // Requests that this core is deinitialized, and a new core is loaded. + // The libretro core used is set with SET_LIBRETRO_PATH, and path to game is passed in _EXEC. NULL means no game. + +#endif + From e1cc0c3160a7337649d431cf642b47d03704e20a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 25 Aug 2013 13:17:11 +0200 Subject: [PATCH 104/202] RETRO_ENVIRONMENT_SET_LIBRETRO_PATH - returns false if path file doesn't exist --- dynamic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dynamic.c b/dynamic.c index 34d4ea48a9..17cc937d83 100644 --- a/dynamic.c +++ b/dynamic.c @@ -758,7 +758,11 @@ bool rarch_environment_cb(unsigned cmd, void *data) case RETRO_ENVIRONMENT_SET_LIBRETRO_PATH: RARCH_LOG("Environ (Private) SET_LIBRETRO_PATH.\n"); - strlcpy(g_settings.libretro, (const char*)data, sizeof(g_settings.libretro)); + + if (path_file_exists((const char*)data)) + strlcpy(g_settings.libretro, (const char*)data, sizeof(g_settings.libretro)); + else + return false; break; case RETRO_ENVIRONMENT_EXEC: From 31946847db6abf48619452279a14371ab5a279dd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 25 Aug 2013 13:28:41 +0200 Subject: [PATCH 105/202] RETRO_ENVIRONMENT_SET_LIBRETRO_PATH - explain false return value --- libretro_private.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libretro_private.h b/libretro_private.h index 6e41efcbfa..c602b39327 100644 --- a/libretro_private.h +++ b/libretro_private.h @@ -30,6 +30,7 @@ #define RETRO_ENVIRONMENT_SET_LIBRETRO_PATH (RETRO_ENVIRONMENT_PRIVATE | 0) // const char * -- // Sets the absolute path for the libretro core pointed to. RETRO_ENVIRONMENT_EXEC will use the last libretro core set with this call. + // Returns false if file for absolute path could not be found. #define RETRO_ENVIRONMENT_EXEC (RETRO_ENVIRONMENT_PRIVATE | 1) // const char * -- // Requests that this core is deinitialized, and a new core is loaded. From 6a3303d2b413858a563ab141c19e2f0ae1283e10 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 25 Aug 2013 15:51:42 +0200 Subject: [PATCH 106/202] Need to put extra conditional in when triggering ENVIRON EXEC to get out of the main iterate loop once so that it can start up the next core with params --- dynamic.c | 1 + general.h | 2 ++ retroarch.c | 6 ++++++ 3 files changed, 9 insertions(+) diff --git a/dynamic.c b/dynamic.c index 17cc937d83..5713e8ecec 100644 --- a/dynamic.c +++ b/dynamic.c @@ -780,6 +780,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) #elif defined(HAVE_DYNAMIC) g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME); #endif + g_extern.exec = true; break; diff --git a/general.h b/general.h index 85a97eeb4c..09364943c7 100644 --- a/general.h +++ b/general.h @@ -472,6 +472,8 @@ struct global msg_queue_t *msg_queue; + bool exec; + // Rewind support. state_manager_t *state_manager; void *state_buf; diff --git a/retroarch.c b/retroarch.c index 8c1ceed1cd..ce73bb23f8 100644 --- a/retroarch.c +++ b/retroarch.c @@ -3059,6 +3059,12 @@ bool rarch_main_iterate(void) if (check_enter_rgui()) return false; // Enter menu, don't exit. + if (g_extern.exec) + { + g_extern.exec = false; + return false; + } + #ifdef HAVE_COMMAND if (driver.command) rarch_cmd_pre_frame(driver.command); From 3370684a06a9b9d69ab549110eb522d196a02815 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Sun, 25 Aug 2013 17:17:23 +0100 Subject: [PATCH 107/202] Improved XInput support, misc tweaks --- frontend/frontend_context.c | 2 +- input/dinput.c | 57 +++++--- input/sdl_joypad.c | 29 +--- input/winxinput_joypad.c | 188 ++++++++++++-------------- msvc/msvc-2010/RetroArch-msvc2010.sln | 20 +++ 5 files changed, 152 insertions(+), 144 deletions(-) create mode 100644 msvc/msvc-2010/RetroArch-msvc2010.sln diff --git a/frontend/frontend_context.c b/frontend/frontend_context.c index 93fd0260b0..fcb03e084f 100644 --- a/frontend/frontend_context.c +++ b/frontend/frontend_context.c @@ -43,7 +43,7 @@ const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident) { for (unsigned i = 0; i < sizeof(frontend_ctx_drivers) / sizeof(frontend_ctx_drivers[0]); i++) { - if (!frontend_ctx_drivers[i]) // could be the dummy NULL + if (!frontend_ctx_drivers[i]) // check for dummy NULL continue; if (strcmp(frontend_ctx_drivers[i]->ident, ident) == 0) return frontend_ctx_drivers[i]; diff --git a/input/dinput.c b/input/dinput.c index 620d3e645a..237a09f9d4 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -68,11 +68,11 @@ static bool dinput_init_context(void) if (g_ctx) return true; - if (driver.display_type != RARCH_DISPLAY_WIN32) + /*if (driver.display_type != RARCH_DISPLAY_WIN32) { RARCH_ERR("Cannot open DInput as no Win32 window is present.\n"); return false; - } + }*/ // Not needed, interferes with joyconfig CoInitialize(NULL); @@ -386,7 +386,35 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p) return DIENUM_CONTINUE; } -extern const LPCTSTR XBOX_PAD_NAMES_TO_REJECT[]; +static const LPCTSTR XBOX_PAD_NAMES[] = +{ + "Controller (Gamepad for Xbox 360)", + "Controller (XBOX 360 For Windows)", + "Controller (Xbox 360 Wireless Receiver for Windows)", + "Controller (Xbox wireless receiver for windows)", + "XBOX 360 For Windows (Controller)", + "Xbox 360 Wireless Receiver", + "Xbox Receiver for Windows (Wireless Controller)", + "Xbox wireless receiver for windows (Controller)", + NULL +}; + +static bool name_is_360_pad(LPCSTR name) +{ + for (unsigned i = 0; ; ++i) + { + LPCSTR t = XBOX_PAD_NAMES[i]; + if (t == NULL) + return false; + else if (lstrcmpi(name, t) == 0) + return true; + } +} + +// Keep track of which pad indexes are 360 controllers +// not static, will be read in winxinput_joypad.c +// -1 = not xbox pad, otherwise 0..3 +int g_xbox_pad_indexes[MAX_PLAYERS]; static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) { @@ -404,23 +432,13 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) return DIENUM_CONTINUE; #ifdef USE_WINXINPUT - // Reject xbox 360 controllers, the xinput driver will take care of them - DIDEVICEINSTANCE info; - ZeroMemory(&info, sizeof(DIDEVICEINSTANCE)); - info.dwSize = sizeof(DIDEVICEINSTANCE); - IDirectInputDevice8_GetDeviceInfo(*pad, &info); + int last_xbox_pad_index = 0; - unsigned test_name_index = 0; - while(1) + if (name_is_360_pad(inst->tszProductName)) { - if (XBOX_PAD_NAMES_TO_REJECT[test_name_index] == NULL) - break; - if (lstrcmpi(info.tszProductName, XBOX_PAD_NAMES_TO_REJECT[test_name_index]) == 0) - { - RARCH_LOG("dinput: Rejected XInput controller \"%s\"", info.tszProductName); - return DIENUM_CONTINUE; - } - ++test_name_index; + if (last_xbox_pad_index < 4) + g_xbox_pad_indexes[g_joypad_cnt] = last_xbox_pad_index; + ++last_xbox_pad_index; } #endif @@ -440,6 +458,9 @@ static bool dinput_joypad_init(void) { if (!dinput_init_context()) return false; + + for (unsigned i = 0; i < MAX_PLAYERS; ++i) + g_xbox_pad_indexes[i] = -1; RARCH_LOG("Enumerating DInput joypads ...\n"); IDirectInput8_EnumDevices(g_ctx, DI8DEVCLASS_GAMECTRL, diff --git a/input/sdl_joypad.c b/input/sdl_joypad.c index 0ed9411be8..812936be56 100644 --- a/input/sdl_joypad.c +++ b/input/sdl_joypad.c @@ -39,8 +39,6 @@ static void sdl_joypad_destroy(void) memset(g_pads, 0, sizeof(g_pads)); } -extern const LPCTSTR XBOX_PAD_NAMES_TO_REJECT[]; - static bool sdl_joypad_init(void) { if (SDL_Init(SDL_INIT_JOYSTICK) < 0) @@ -56,32 +54,9 @@ static bool sdl_joypad_init(void) pad->joypad = SDL_JoystickOpen(i); if (!pad->joypad) { - RARCH_ERR("Couldn't open SDL joystick #%u.\n", i); - goto error; + RARCH_ERR("Couldn't open SDL joystick #%u.\n", i); + goto error; } - - - #ifdef USE_WINXINPUT - // Reject xbox 360 controllers, the xinput driver will take care of them. - unsigned test_name_index = 0; - while(1) - { - if (XBOX_PAD_NAMES_TO_REJECT[test_name_index] == NULL) - break; - if (lstrcmpi(SDL_JoystickName(i), XBOX_PAD_NAMES_TO_REJECT[test_name_index]) == 0) - { - RARCH_LOG("sdl joypad: Rejected XInput controller \"%s\"", SDL_JoystickName(i)); - pad->joypad = NULL; pad->num_axes = 0; pad->num_buttons = 0; pad->num_hats = 0; - - goto continue_after_xinput_rejection; - } - ++test_name_index; - } - #endif - - continue_after_xinput_rejection: - - // RARCH_LOG("Opened Joystick: %s (#%u).\n", SDL_JoystickName(i), i); diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index 0310b24c5b..234e57ac53 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -20,9 +20,6 @@ // Some wrappers for other controllers also simulate xinput (as it is easier to implement) // so this may be useful for those also. - -// Note: if rumble is ever added (for psx and n64 cores), add rumble support to this -// as well as dinput. #include "input_common.h" #include "../general.h" @@ -32,12 +29,8 @@ #include #include -//#include - -// There is no need to require the xinput headers and libs since -// we shall be dynamically loading them anyway. But first check that -// it hasn't been included anyway. -// official and mingw xinput headers have different include guards +// Check the definitions do not already exist. +// Official and mingw xinput headers have different include guards #if ((!_XINPUT_H_) && (!__WINE_XINPUT_H)) #define XINPUT_GAMEPAD_DPAD_UP 0x0001 @@ -81,25 +74,40 @@ #define ERROR_DEVICE_NOT_CONNECTED 1167 #endif -// To load xinput1_3.dll +#ifndef HAVE_DINPUT + #error Cannot compile xinput without dinput. +#endif + +// Due to 360 pads showing up under both XI and DI, and since we are going +// to have to pass through unhandled joypad numbers to DI, a slightly ugly +// hack is required here. dinput_joypad_init will fill this. +// For each pad index, the appropriate entry will be set to -1 if it is not +// a 360 pad, or the correct XInput player number (0..3 inclusive) if it is. +extern int g_xbox_pad_indexes[MAX_PLAYERS]; + +// For xinput1_3.dll static HINSTANCE g_winxinput_dll; // Function pointer, to be assigned with GetProcAddress -typedef __stdcall DWORD (*XInputGetStateEx_t)(DWORD, XINPUT_STATE*); +typedef DWORD (__stdcall *XInputGetStateEx_t)(DWORD, XINPUT_STATE*); static XInputGetStateEx_t g_XInputGetStateEx; -// Guide button may or may not be available, -// but if it is available +// Guide button may or may not be available static bool g_winxinput_guide_button_supported; typedef struct { XINPUT_STATE xstate; - bool connected; + bool connected; } winxinput_joypad_state; static winxinput_joypad_state g_winxinput_states[4]; +static int pad_index_to_xplayer_index(unsigned pad) +{ + return g_xbox_pad_indexes[pad]; +} + static bool winxinput_joypad_init(void) { g_winxinput_dll = NULL; @@ -119,12 +127,13 @@ static bool winxinput_joypad_init(void) { // Loading from working dir failed, try to load from system. GetSystemDirectory(dll_path, sizeof(dll_path)); - strcpy(dll_path, "xinput1_3.dll"); + strcat(dll_path, "\\xinput1_3.dll"); g_winxinput_dll = LoadLibrary(dll_path); if (!g_winxinput_dll) { RARCH_ERR("Failed to init XInput, ensure DirectX and controller drivers are up to date.\n"); + //g_dinput_should_filter_xinput_controllers = false; return false; // DLL does not exist or is invalid } @@ -132,21 +141,22 @@ static bool winxinput_joypad_init(void) // If we get here then an xinput DLL is correctly loaded. // First try to load ordinal 100 (XInputGetStateEx). - // Cast to make C++ happy. g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, (LPCSTR)100); g_winxinput_guide_button_supported = true; if (!g_XInputGetStateEx) { - // no ordinal 100. (old version of x360ce perhaps). Load the ordinary XInputGetState, + // no ordinal 100. (old version of x360ce perhaps?) Load the ordinary XInputGetState, // at the cost of losing guide button support. g_winxinput_guide_button_supported = false; g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState"); if (!g_XInputGetStateEx) { - RARCH_ERR("Failed to init XInput.\n"); + RARCH_ERR("Failed to init XInput: Found an XInput DLL but it is invalid or corrupt.\n"); + //g_dinput_should_filter_xinput_controllers = false; return false; // DLL was loaded but did not contain the correct function. } + RARCH_WARN("XInput: No guide button support.\n"); } // zero out the states @@ -161,17 +171,26 @@ static bool winxinput_joypad_init(void) if (g_winxinput_states[i].connected) RARCH_LOG("Found XInput controller, player #%u\n", i); } - - return true; + if ((!g_winxinput_states[0].connected) && + (!g_winxinput_states[1].connected) && + (!g_winxinput_states[2].connected) && + (!g_winxinput_states[3].connected)) + return false; + + + // We're going to have to be buddies with dinput if we want to be able + // to use XI and non-XI controllers together. + return dinput_joypad.init(); } static bool winxinput_joypad_query_pad(unsigned pad) { - if (pad >= 4) - return false; + int xplayer = pad_index_to_xplayer_index(pad); + if (xplayer > -1) + return g_winxinput_states[0].connected; else - return g_winxinput_states[pad].connected; + return dinput_joypad.query_pad(pad); } static void winxinput_joypad_destroy(void) @@ -180,36 +199,45 @@ static void winxinput_joypad_destroy(void) ZeroMemory(&g_winxinput_states[i], sizeof(winxinput_joypad_state)); FreeLibrary(g_winxinput_dll); - g_winxinput_dll = NULL; + g_winxinput_dll = NULL; g_XInputGetStateEx = NULL; + + dinput_joypad.destroy(); } // Buttons are provided by XInput as bits of a uint16. -// Map from button index (0..10) to mask to AND against. +// Map from rarch button index (0..10) to a mask to bitwise-& the buttons against. // dpad is handled seperately. -// Order: -// a, b, x, y, leftbump, rightbump, back, start, leftstick, rightstick, guide. static const WORD button_index_to_bitmap_code[] = { - 0x1000, 0x2000, 0x4000, 0x8000, 0x0100, 0x0200, 0x0020, 0x0010, - 0x0040, 0x0080, 0x0400 + XINPUT_GAMEPAD_A , + XINPUT_GAMEPAD_B , + XINPUT_GAMEPAD_X , + XINPUT_GAMEPAD_Y , + XINPUT_GAMEPAD_LEFT_SHOULDER , + XINPUT_GAMEPAD_RIGHT_SHOULDER, + XINPUT_GAMEPAD_START , + XINPUT_GAMEPAD_BACK , + XINPUT_GAMEPAD_LEFT_THUMB , + XINPUT_GAMEPAD_RIGHT_THUMB , + XINPUT_GAMEPAD_GUIDE }; static bool winxinput_joypad_button (unsigned port_num, uint16_t joykey) { if (joykey == NO_BTN) return false; - - if (!(g_winxinput_states[port_num].connected)) + + int xplayer = pad_index_to_xplayer_index(port_num); + if (xplayer == -1) + return dinput_joypad.button(port_num, joykey); + + if (!(g_winxinput_states[xplayer].connected)) return false; - - - - uint16_t btn_word = g_winxinput_states[port_num].xstate.Gamepad.wButtons; - + + uint16_t btn_word = g_winxinput_states[xplayer].xstate.Gamepad.wButtons; if (GET_HAT_DIR(joykey)) { - switch (GET_HAT_DIR(joykey)) { case HAT_UP_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_UP; @@ -217,7 +245,6 @@ static bool winxinput_joypad_button (unsigned port_num, uint16_t joykey) case HAT_LEFT_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_LEFT; case HAT_RIGHT_MASK: return btn_word & XINPUT_GAMEPAD_DPAD_RIGHT; } - return false; // hat requested and no hat button down } else @@ -225,44 +252,32 @@ static bool winxinput_joypad_button (unsigned port_num, uint16_t joykey) // non-hat button unsigned num_buttons = g_winxinput_guide_button_supported ? 11 : 10; - if (joykey >= num_buttons) - return false; - else + if (joykey < num_buttons) return btn_word & button_index_to_bitmap_code[joykey]; } - return false; - } -//#include + static int16_t winxinput_joypad_axis (unsigned port_num, uint32_t joyaxis) { - //printf("Requested axis: %u\n", joyaxis); if (joyaxis == AXIS_NONE) return 0; - if (!(g_winxinput_states[port_num].connected)) - return 0; - - /*switch (joyaxis) - { - case 0: return(g_winxinput_states[port_num].xstate.Gamepad.sThumbLX); - case 1: return (g_winxinput_states[port_num].xstate.Gamepad.sThumbLX); - case 2: return 0; - case 3: return 0; //do axes now - case 4: return 0; - case 5: return 0; - default: return 0; - }*/ + int xplayer = pad_index_to_xplayer_index(port_num); + if (xplayer == -1) + return dinput_joypad.axis(port_num, joyaxis); + + if (!(g_winxinput_states[xplayer].connected)) + return false; int16_t val = 0; - int axis = -1; + int axis = -1; bool is_neg = false; bool is_pos = false; - if (AXIS_NEG_GET(joyaxis) <= 3) + if (AXIS_NEG_GET(joyaxis) <= 3) // triggers (axes 4,5) cannot be negative { axis = AXIS_NEG_GET(joyaxis); is_neg = true; @@ -273,7 +288,8 @@ static int16_t winxinput_joypad_axis (unsigned port_num, uint32_t joyaxis) is_pos = true; } - XINPUT_GAMEPAD* pad = &(g_winxinput_states[port_num].xstate.Gamepad); + XINPUT_GAMEPAD* pad = &(g_winxinput_states[xplayer].xstate.Gamepad); + switch (axis) { case 0: val = pad->sThumbLX; break; @@ -281,7 +297,7 @@ static int16_t winxinput_joypad_axis (unsigned port_num, uint32_t joyaxis) case 2: val = pad->sThumbRX; break; case 3: val = pad->sThumbRY; break; - case 4: val = pad->bLeftTrigger * 32767 / 255; break; + case 4: val = pad->bLeftTrigger * 32767 / 255; break; // map 0..255 to 0..32767 case 5: val = pad->bRightTrigger * 32767 / 255; break; } @@ -289,9 +305,12 @@ static int16_t winxinput_joypad_axis (unsigned port_num, uint32_t joyaxis) val = 0; else if (is_pos && val < 0) val = 0; + + // Clamp to avoid overflow error + if (val == -32768) + val = -32767; return val; - } static void winxinput_joypad_poll(void) @@ -299,6 +318,8 @@ static void winxinput_joypad_poll(void) for (unsigned i = 0; i < 4; ++i) if (g_XInputGetStateEx(i, &(g_winxinput_states[i].xstate)) == ERROR_DEVICE_NOT_CONNECTED) g_winxinput_states[i].connected = false; + + dinput_joypad.poll(); } static const char* const XBOX_CONTROLLER_NAMES[4] = @@ -311,13 +332,15 @@ static const char* const XBOX_CONTROLLER_NAMES[4] = const char* winxinput_joypad_name (unsigned pad) { - if (pad > 3) - return NULL; + int xplayer = pad_index_to_xplayer_index(pad); + + if (xplayer < 0) + return dinput_joypad.name(pad); else - return XBOX_CONTROLLER_NAMES[pad]; + // TODO: Different name if disconnected? + return XBOX_CONTROLLER_NAMES[xplayer]; } - const rarch_joypad_driver_t winxinput_joypad = { winxinput_joypad_init, winxinput_joypad_query_pad, @@ -328,34 +351,3 @@ const rarch_joypad_driver_t winxinput_joypad = { winxinput_joypad_name, "winxinput", }; - -// A list of names for other (dinput) drivers to reject. -const LPCTSTR XBOX_PAD_NAMES_TO_REJECT[] = -{ - "Controller (Gamepad for Xbox 360)", - "Controller (XBOX 360 For Windows)", - "Controller (Xbox 360 Wireless Receiver for Windows)", - "Controller (Xbox wireless receiver for windows)", - "XBOX 360 For Windows (Controller)", - "Xbox 360 Wireless Receiver", - "Xbox Receiver for Windows (Wireless Controller)", - "Xbox wireless receiver for windows (Controller)", - NULL -}; - - -/* -typedef struct rarch_joypad_driver -{ - bool (*init)(void); - bool (*query_pad)(unsigned); - void (*destroy)(void); - bool (*button)(unsigned, uint16_t); - int16_t (*axis)(unsigned, uint32_t); - void (*poll)(void); - const char *(*name)(unsigned); - - const char *ident; -} rarch_joypad_driver_t; - -*/ \ No newline at end of file diff --git a/msvc/msvc-2010/RetroArch-msvc2010.sln b/msvc/msvc-2010/RetroArch-msvc2010.sln new file mode 100644 index 0000000000..6bb4b9c199 --- /dev/null +++ b/msvc/msvc-2010/RetroArch-msvc2010.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-msvc2010", "RetroArch-msvc2010.vcxproj", "{27FF7CE1-4059-4AA1-8062-FD529560FA54}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.ActiveCfg = Debug|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.Build.0 = Debug|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.ActiveCfg = Release|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal From 95f5e6aa9685a676ec4a26c3a24bf79ec228217f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 25 Aug 2013 19:42:24 +0200 Subject: [PATCH 108/202] Add RETRO_ENVIRONMENT_EXEC_ESCAPE -yes, I need this - when we are in retro_run - we need to escape first before we can get the next libretro core with input data running. This is not needed when we do exec without being in the main program loop. Anyway, one does not work for the other - so we need both. --- dynamic.c | 11 +++++++++-- libretro_private.h | 5 +++++ retroarch.c | 2 -- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/dynamic.c b/dynamic.c index 5713e8ecec..2f789ee5d6 100644 --- a/dynamic.c +++ b/dynamic.c @@ -766,7 +766,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) break; case RETRO_ENVIRONMENT_EXEC: - RARCH_LOG("Environ (Private) EXEC.\n"); + case RETRO_ENVIRONMENT_EXEC_ESCAPE: if (data) strlcpy(g_extern.fullpath, (const char*)data, sizeof(g_extern.fullpath)); @@ -780,7 +780,14 @@ bool rarch_environment_cb(unsigned cmd, void *data) #elif defined(HAVE_DYNAMIC) g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME); #endif - g_extern.exec = true; + + if (cmd == RETRO_ENVIRONMENT_EXEC_ESCAPE) + { + RARCH_LOG("Environ (Private) EXEC_ESCAPE.\n"); + g_extern.exec = true; + } + else + RARCH_LOG("Environ (Private) EXEC.\n"); break; diff --git a/libretro_private.h b/libretro_private.h index c602b39327..a393412911 100644 --- a/libretro_private.h +++ b/libretro_private.h @@ -35,6 +35,11 @@ // const char * -- // Requests that this core is deinitialized, and a new core is loaded. // The libretro core used is set with SET_LIBRETRO_PATH, and path to game is passed in _EXEC. NULL means no game. +#define RETRO_ENVIRONMENT_EXEC_ESCAPE (RETRO_ENVIRONMENT_PRIVATE | 2) + // const char * -- + // Requests that this core is deinitialized, and a new core is loaded. It also escapes the main loop the core is currently + // bound to. + // The libretro core used is set with SET_LIBRETRO_PATH, and path to game is passed in _EXEC. NULL means no game. #endif diff --git a/retroarch.c b/retroarch.c index ce73bb23f8..64544f6a30 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2719,7 +2719,6 @@ static void do_state_checks(void) if (!g_extern.netplay) { #endif -#if !defined(RARCH_PERFORMANCE_MODE) check_pause(); check_oneshot(); @@ -2728,7 +2727,6 @@ static void do_state_checks(void) if (g_extern.is_paused && !g_extern.is_oneshot) return; -#endif check_fast_forward_button(); From f3de828444328cc9ae16c7088fc39e27bf80487d Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Sun, 25 Aug 2013 18:54:20 +0100 Subject: [PATCH 109/202] Eradicated some win32 macros/typedefs --- input/dinput.c | 4 ++-- input/winxinput_joypad.c | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/input/dinput.c b/input/dinput.c index 237a09f9d4..cb10f3b788 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -399,11 +399,11 @@ static const LPCTSTR XBOX_PAD_NAMES[] = NULL }; -static bool name_is_360_pad(LPCSTR name) +static bool name_is_360_pad(const char* name) { for (unsigned i = 0; ; ++i) { - LPCSTR t = XBOX_PAD_NAMES[i]; + const char* t = XBOX_PAD_NAMES[i]; if (t == NULL) return false; else if (lstrcmpi(name, t) == 0) diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index 234e57ac53..d7666140e9 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -50,18 +50,18 @@ typedef struct { - WORD wButtons; - BYTE bLeftTrigger; - BYTE bRightTrigger; - SHORT sThumbLX; - SHORT sThumbLY; - SHORT sThumbRX; - SHORT sThumbRY; + uint16_t wButtons; + uint8_t bLeftTrigger; + uint8_t bRightTrigger; + int16_t sThumbLX; + int16_t sThumbLY; + int16_t sThumbRX; + int16_t sThumbRY; } XINPUT_GAMEPAD; typedef struct { - DWORD dwPacketNumber; + uint32_t dwPacketNumber; XINPUT_GAMEPAD Gamepad; } XINPUT_STATE; @@ -89,7 +89,7 @@ extern int g_xbox_pad_indexes[MAX_PLAYERS]; static HINSTANCE g_winxinput_dll; // Function pointer, to be assigned with GetProcAddress -typedef DWORD (__stdcall *XInputGetStateEx_t)(DWORD, XINPUT_STATE*); +typedef uint32_t (__stdcall *XInputGetStateEx_t)(uint32_t, XINPUT_STATE*); static XInputGetStateEx_t g_XInputGetStateEx; // Guide button may or may not be available @@ -120,7 +120,7 @@ static bool winxinput_joypad_init(void) // No need to check for existance as we will be checking LoadLibrary's // success anyway. - TCHAR dll_path[MAX_PATH]; + char dll_path[MAX_PATH]; strcpy(dll_path, "xinput1_3.dll"); g_winxinput_dll = LoadLibrary(dll_path); if (!g_winxinput_dll) @@ -141,7 +141,7 @@ static bool winxinput_joypad_init(void) // If we get here then an xinput DLL is correctly loaded. // First try to load ordinal 100 (XInputGetStateEx). - g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, (LPCSTR)100); + g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, (const char*)100); g_winxinput_guide_button_supported = true; if (!g_XInputGetStateEx) @@ -161,7 +161,7 @@ static bool winxinput_joypad_init(void) // zero out the states for (unsigned i = 0; i < 4; ++i) - ZeroMemory(&g_winxinput_states[i], sizeof(winxinput_joypad_state)); + memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state)); // Do a dummy poll to check which controllers are connected. XINPUT_STATE dummy_state; @@ -196,7 +196,7 @@ static bool winxinput_joypad_query_pad(unsigned pad) static void winxinput_joypad_destroy(void) { for (unsigned i = 0; i < 4; ++i) - ZeroMemory(&g_winxinput_states[i], sizeof(winxinput_joypad_state)); + memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state)); FreeLibrary(g_winxinput_dll); g_winxinput_dll = NULL; @@ -208,7 +208,7 @@ static void winxinput_joypad_destroy(void) // Buttons are provided by XInput as bits of a uint16. // Map from rarch button index (0..10) to a mask to bitwise-& the buttons against. // dpad is handled seperately. -static const WORD button_index_to_bitmap_code[] = { +static const uint16_t button_index_to_bitmap_code[] = { XINPUT_GAMEPAD_A , XINPUT_GAMEPAD_B , XINPUT_GAMEPAD_X , From ef8a86e794e40a451f0cfb654aa62ae8e2cc142d Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Sun, 25 Aug 2013 18:57:23 +0100 Subject: [PATCH 110/202] more win32 typedef removal --- input/dinput.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/dinput.c b/input/dinput.c index cb10f3b788..9df0386b52 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -386,7 +386,7 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p) return DIENUM_CONTINUE; } -static const LPCTSTR XBOX_PAD_NAMES[] = +static const char* const XBOX_PAD_NAMES[] = { "Controller (Gamepad for Xbox 360)", "Controller (XBOX 360 For Windows)", From c30d0287d1455eb8f8dfda36f678bea3307579c4 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Sun, 25 Aug 2013 15:39:50 -0400 Subject: [PATCH 111/202] [EMSCRIPTEN] buildfix, implement detecting canvas size changes --- Makefile.emscripten | 2 +- gfx/context/emscriptenegl_ctx.c | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Makefile.emscripten b/Makefile.emscripten index 52f9711060..0c15c8bd81 100644 --- a/Makefile.emscripten +++ b/Makefile.emscripten @@ -86,7 +86,7 @@ ifeq ($(HAVE_THREADS), 1) endif ifeq ($(HAVE_OPENGL), 1) - OBJ += gfx/gl.o gfx/math/matrix.o gfx/fonts/gl_font.o gfx/fonts/gl_raster_font.o gfx/gfx_context.o gfx/context/emscriptenegl_ctx.o gfx/shader_glsl.o + OBJ += gfx/gl.o gfx/math/matrix.o gfx/fonts/gl_font.o gfx/fonts/gl_raster_font.o gfx/gfx_context.o gfx/context/emscriptenegl_ctx.o gfx/shader_glsl.o gfx/glsym/rglgen.o gfx/glsym/glsym_es2.o DEFINES += -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_EGL -DHAVE_OVERLAY -DHAVE_GLSL endif diff --git a/gfx/context/emscriptenegl_ctx.c b/gfx/context/emscriptenegl_ctx.c index 9c5f2516bd..363152c358 100644 --- a/gfx/context/emscriptenegl_ctx.c +++ b/gfx/context/emscriptenegl_ctx.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -52,10 +53,19 @@ static void gfx_ctx_check_window(bool *quit, bool *resize, unsigned *width, unsigned *height, unsigned frame_count) { (void)frame_count; - (void)width; - (void)height; + int iWidth, iHeight, isFullscreen; - *resize = false; + emscripten_get_canvas_size(&iWidth, &iHeight, &isFullscreen); + *width = (unsigned) iWidth; + *height = (unsigned) iHeight; + + if (*width != g_fb_width || *height != g_fb_height) + *resize = true; + else + *resize = false; + + g_fb_width = (unsigned) iWidth; + g_fb_height = (unsigned) iHeight; *quit = false; } @@ -167,8 +177,10 @@ static bool gfx_ctx_set_video_mode( return true; } -static bool gfx_ctx_bind_api(enum gfx_ctx_api api) +static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor) { + (void)major; + (void)minor; switch (api) { case GFX_CTX_OPENGL_ES_API: From add527e3d286bc5fa0ea2584c073e822c69032fc Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 25 Aug 2013 22:18:57 +0200 Subject: [PATCH 112/202] Get rid of RARCH_PERFORMANCE_MODE --- retroarch.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/retroarch.c b/retroarch.c index 64544f6a30..b83ff18653 100644 --- a/retroarch.c +++ b/retroarch.c @@ -45,10 +45,6 @@ #include "msvc/msvc_compat.h" #endif -#if defined(RARCH_CONSOLE) && !defined(RARCH_PERFORMANCE_MODE) -#define RARCH_PERFORMANCE_MODE -#endif - // To avoid continous switching if we hold the button down, we require that the button must go from pressed, // unpressed back to pressed to be able to toggle between then. static void check_fast_forward_button(void) @@ -1935,7 +1931,6 @@ static void check_savestates(bool immutable) } } -#if !defined(RARCH_PERFORMANCE_MODE) void rarch_set_fullscreen(bool fullscreen) { g_settings.video.fullscreen = fullscreen; @@ -2193,7 +2188,6 @@ static void check_movie(void) } #endif -#if !defined(RARCH_PERFORMANCE_MODE) static void check_pause(void) { static bool old_state = false; @@ -2266,7 +2260,6 @@ static void check_oneshot(void) g_extern.is_oneshot |= new_rewind_state && !old_rewind_state; old_rewind_state = new_rewind_state; } -#endif void rarch_game_reset(void) { @@ -2565,7 +2558,6 @@ static void check_dsp_config(void) } #endif -#if !defined(RARCH_PERFORMANCE_MODE) static void check_mute(void) { if (!g_extern.audio_active) @@ -2700,10 +2692,8 @@ static void do_state_checks(void) #if defined(HAVE_SCREENSHOTS) && !defined(_XBOX) check_screenshot(); #endif -#if !defined(RARCH_PERFORMANCE_MODE) check_mute(); check_volume(); -#endif check_turbo(); @@ -2757,9 +2747,7 @@ static void do_state_checks(void) else { check_netplay_flip(); -#if !defined(RARCH_PERFORMANCE_MODE) check_fullscreen(); -#endif } #endif } From 7ad663c5f268b795a33985298a4632b565eece9c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 25 Aug 2013 22:21:23 +0200 Subject: [PATCH 113/202] Get rid of RARCH_PERFORMANCE_MODE everywhere --- android/native/jni/Android.mk | 2 +- apple/RetroArch_OSX.xcodeproj/project.pbxproj | 2 -- apple/RetroArch_iOS.xcodeproj/project.pbxproj | 4 ---- frontend/menu/rgui.c | 4 ---- 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/android/native/jni/Android.mk b/android/native/jni/Android.mk index 7a2e6b963c..063c0aeb2e 100644 --- a/android/native/jni/Android.mk +++ b/android/native/jni/Android.mk @@ -48,7 +48,7 @@ ifeq ($(PERF_TEST), 1) LOCAL_CFLAGS += -DPERF_TEST endif -LOCAL_CFLAGS += -Wall -pthread -Wno-unused-function -O3 -fno-stack-protector -funroll-loops -DNDEBUG -DRARCH_MOBILE -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 -std=gnu99 -I../../../deps/miniz +LOCAL_CFLAGS += -Wall -pthread -Wno-unused-function -O3 -fno-stack-protector -funroll-loops -DNDEBUG -DRARCH_MOBILE -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__ -std=gnu99 -I../../../deps/miniz LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -landroid -lEGL -lGLESv2 $(LOGGER_LDLIBS) -ldl diff --git a/apple/RetroArch_OSX.xcodeproj/project.pbxproj b/apple/RetroArch_OSX.xcodeproj/project.pbxproj index 6a1101970c..67e0df9ae7 100644 --- a/apple/RetroArch_OSX.xcodeproj/project.pbxproj +++ b/apple/RetroArch_OSX.xcodeproj/project.pbxproj @@ -303,7 +303,6 @@ "-DINLINE=inline", "-DLSB_FIRST", "-D__LIBRETRO__", - "-DRARCH_PERFORMANCE_MODE", "-DWANT_RPNG", "-DHAVE_COREAUDIO", "-DHAVE_DYNAMIC", @@ -358,7 +357,6 @@ "-DINLINE=inline", "-DLSB_FIRST", "-D__LIBRETRO__", - "-DRARCH_PERFORMANCE_MODE", "-DRARCH_MOBILE", "-DHAVE_COREAUDIO", "-DHAVE_DYNAMIC", diff --git a/apple/RetroArch_iOS.xcodeproj/project.pbxproj b/apple/RetroArch_iOS.xcodeproj/project.pbxproj index f94d43b805..f959691eb8 100644 --- a/apple/RetroArch_iOS.xcodeproj/project.pbxproj +++ b/apple/RetroArch_iOS.xcodeproj/project.pbxproj @@ -367,7 +367,6 @@ "-DLSB_FIRST", "-DHAVE_THREAD", "-D__LIBRETRO__", - "-DRARCH_PERFORMANCE_MODE", "-DRARCH_MOBILE", "-std=gnu99", "-DHAVE_COREAUDIO", @@ -417,7 +416,6 @@ "-DLSB_FIRST", "-DHAVE_THREAD", "-D__LIBRETRO__", - "-DRARCH_PERFORMANCE_MODE", "-DRARCH_MOBILE", "-std=gnu99", "-DHAVE_COREAUDIO", @@ -458,7 +456,6 @@ "-DINLINE=inline", "-DLSB_FIRST", "-D__LIBRETRO__", - "-DRARCH_PERFORMANCE_MODE", "-DRARCH_MOBILE", "-DHAVE_COREAUDIO", "-DHAVE_DYNAMIC", @@ -501,7 +498,6 @@ "-DINLINE=inline", "-DLSB_FIRST", "-D__LIBRETRO__", - "-DRARCH_PERFORMANCE_MODE", "-DRARCH_MOBILE", "-DHAVE_COREAUDIO", "-DHAVE_DYNAMIC", diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 27bb84c5e3..7ae5533490 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -1500,9 +1500,7 @@ static void rgui_settings_video_options_populate_entries(rgui_handle_t *rgui) rgui_list_push(rgui->selection_buf, "Integer Scale", RGUI_SETTINGS_VIDEO_INTEGER_SCALE, 0); rgui_list_push(rgui->selection_buf, "Aspect Ratio", RGUI_SETTINGS_VIDEO_ASPECT_RATIO, 0); rgui_list_push(rgui->selection_buf, "Custom Ratio", RGUI_SETTINGS_CUSTOM_VIEWPORT, 0); -#ifndef RARCH_PERFORMANCE_MODE rgui_list_push(rgui->selection_buf, "Toggle Fullscreen", RGUI_SETTINGS_TOGGLE_FULLSCREEN, 0); -#endif rgui_list_push(rgui->selection_buf, "Rotation", RGUI_SETTINGS_VIDEO_ROTATION, 0); rgui_list_push(rgui->selection_buf, "VSync", RGUI_SETTINGS_VIDEO_VSYNC, 0); rgui_list_push(rgui->selection_buf, "Hard GPU Sync", RGUI_SETTINGS_VIDEO_HARD_SYNC, 0); @@ -1854,12 +1852,10 @@ static int video_option_toggle_setting(rgui_handle_t *rgui, unsigned setting, rg driver.video_poke->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx); break; -#ifndef RARCH_PERFORMANCE_MODE case RGUI_SETTINGS_TOGGLE_FULLSCREEN: if (action == RGUI_ACTION_OK) rarch_set_fullscreen(!g_settings.video.fullscreen); break; -#endif #ifdef GEKKO case RGUI_SETTINGS_VIDEO_RESOLUTION: From 3adfefed24522964c2d76772681cf61116bb184b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 25 Aug 2013 23:38:43 +0200 Subject: [PATCH 114/202] Fix build (to do with removing RARCH_PERFORMANCE_MODE ifdefs) --- retroarch.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/retroarch.c b/retroarch.c index b83ff18653..e759fc99f4 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1961,7 +1961,6 @@ static bool check_fullscreen(void) was_pressed = pressed; return toggle; } -#endif void rarch_state_slot_increase(void) { @@ -2620,7 +2619,6 @@ static void check_volume(void) g_extern.audio_data.volume_gain = db_to_gain(g_extern.audio_data.volume_db); } -#endif #ifdef HAVE_NETPLAY static void check_netplay_flip(void) From 6e7c641ae0a655e6023ac445f9bb924f55e44379 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 25 Aug 2013 18:03:24 -0400 Subject: [PATCH 115/202] (iOS) Fix the overlay opacity setting --- apple/iOS/settings.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index 54c860eaeb..ad84b67bfd 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -308,7 +308,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) [NSArray arrayWithObjects:@"Input", subpath_setting(config, @"input_overlay", @"Input Overlay", @"", overlay_path, @"cfg"), - range_setting(config, @"overlay_opacity", @"Overlay Opacity", @"1.0", 0.0, 1.0), + range_setting(config, @"input_overlay_opacity", @"Overlay Opacity", @"1.0", 0.0, 1.0), group_setting(@"System Keys", [NSArray arrayWithObjects: // TODO: Many of these strings will be cut off on an iPhone [NSArray arrayWithObjects:@"System Keys", From da8b19c25c277afdff9127fce5ac8f26dcb94cff Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 26 Aug 2013 00:10:53 +0200 Subject: [PATCH 116/202] (Android Phoenix) Add some TODO notes to settings saving and add an entry to per-core config state --- .../phoenix/src/org/retroarch/browser/MainMenuActivity.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index ab418e21f7..6b0b519a09 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -313,6 +313,7 @@ public class MainMenuActivity extends PreferenceActivity { readbackBool(config, edit, "rewind_enable"); readbackBool(config, edit, "savestate_auto_load"); readbackBool(config, edit, "savestate_auto_save"); + readbackDouble(config, edit, "video_refresh_rate"); readbackBool(config, edit, "audio_rate_control"); readbackBool(config, edit, "audio_enable"); @@ -322,6 +323,7 @@ public class MainMenuActivity extends PreferenceActivity { readbackBool(config, edit, "input_autodetect_enable"); readbackBool(config, edit, "video_allow_rotate"); + readbackBool(config, edit, "video_font_enable"); readbackBool(config, edit, "video_vsync"); @@ -351,6 +353,7 @@ public class MainMenuActivity extends PreferenceActivity { int optimalRate = getOptimalSamplingRate(); config.setInt("audio_out_rate", optimalRate); + // Refactor this entire mess and make this usable for per-core config if (android.os.Build.VERSION.SDK_INT >= 17) { int buffersize = getLowLatencyBufferSize(); @@ -407,6 +410,8 @@ public class MainMenuActivity extends PreferenceActivity { config.setBoolean("video_threaded", prefs.getBoolean("video_threaded", true)); + // Refactor these weird values - 'full', 'auto', 'square', whatever - + // go by what we have in RGUI - makes maintaining state easier too String aspect = prefs.getString("video_aspect_ratio", "auto"); if (aspect.equals("full")) { config.setBoolean("video_force_aspect", false); From 72057ab9be8b86b612cea3532a8fb94abada2134 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 26 Aug 2013 00:21:09 +0200 Subject: [PATCH 117/202] (Android Phoenix) Add readBackInt - now saves input_back_behavior for per-core config as well --- .../src/org/retroarch/browser/MainMenuActivity.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 6b0b519a09..47b1b4bae2 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -282,6 +282,13 @@ public class MainMenuActivity extends PreferenceActivity { edit.remove(key); } + private void readbackInt(ConfigFile cfg, SharedPreferences.Editor edit, String key) { + if (cfg.keyExists(key)) + edit.putInt(key, cfg.getInt(key)); + else + edit.remove(key); + } + public void readbackConfigFile() { String path = getDefaultConfigPath(); ConfigFile config; @@ -301,9 +308,6 @@ public class MainMenuActivity extends PreferenceActivity { readbackString(config, edit, "savestate_directory"); readbackBool(config, edit, "savefile_directory_enable"); // Ignored by RetroArch readbackBool(config, edit, "savestate_directory_enable"); // Ignored by RetroArch - - String input_overlay = config.getString("input_overlay"); - readbackString(config, edit, "input_overlay"); readbackBool(config, edit, "input_overlay_enable"); @@ -321,6 +325,7 @@ public class MainMenuActivity extends PreferenceActivity { readbackDouble(config, edit, "input_overlay_opacity"); readbackBool(config, edit, "input_autodetect_enable"); + readbackInt(config, edit, "input_back_behavior"); readbackBool(config, edit, "video_allow_rotate"); readbackBool(config, edit, "video_font_enable"); From 2c20644ecb7099270b964849b2228bf783b357b3 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 25 Aug 2013 19:28:57 -0400 Subject: [PATCH 118/202] (OSX) Some setting menu work --- apple/OSX/settings.m | 59 ++++++++++++++++++++++++++++++++-- apple/RetroArch/setting_data.h | 40 +++++++++++++++-------- 2 files changed, 83 insertions(+), 16 deletions(-) diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 4bebfb07ec..98d4f1cd4f 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -17,6 +17,9 @@ #import "../RetroArch/RetroArch_Apple.h" #include "../RetroArch/setting_data.h" +struct settings fake_settings; +struct global fake_extern; + @interface RASettingsDelegate : NSObject @end @@ -37,6 +40,9 @@ NSMutableArray* thisSubGroup = nil; _settings = [NSMutableArray array]; + memcpy(&fake_settings, &g_settings, sizeof(struct settings)); + memcpy(&fake_extern, &g_extern, sizeof(struct global)); + for (int i = 0; setting_data[i].type; i ++) { switch (setting_data[i].type) @@ -83,11 +89,51 @@ - (IBAction)close:(id)sender { +#if 0 + config_file_t* conf = config_file_new(0); + for (int i = 0; setting_data[i].type; i ++) + { + switch (setting_data[i].type) + { + case ST_BOOL: config_set_bool (conf, setting_data[i].name, * (bool*)setting_data[i].value); break; + case ST_INT: config_set_int (conf, setting_data[i].name, * (int*)setting_data[i].value); break; + case ST_FLOAT: config_set_float (conf, setting_data[i].name, *(float*)setting_data[i].value); break; + case ST_PATH: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break; + case ST_STRING: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break; + case ST_HEX: break; + default: break; + } + } + config_file_free(conf); +#endif + [NSApplication.sharedApplication stopModal]; [NSApplication.sharedApplication endSheet:_window returnCode:0]; [_window orderOut:nil]; } +- (void)readConfigFile:(const char*)path +{ + config_file_t* conf = config_file_new(path); + if (conf) + { + for (int i = 0; setting_data[i].type; i ++) + { + switch (setting_data[i].type) + { + case ST_BOOL: config_get_bool (conf, setting_data[i].name, (bool*)setting_data[i].value); break; + case ST_INT: config_get_int (conf, setting_data[i].name, (int*)setting_data[i].value); break; + case ST_FLOAT: config_get_float(conf, setting_data[i].name, (float*)setting_data[i].value); break; + case ST_PATH: config_get_array(conf, setting_data[i].name, (char*)setting_data[i].value, setting_data[i].size); break; + case ST_STRING: config_get_array(conf, setting_data[i].name, (char*)setting_data[i].value, setting_data[i].size); break; + case ST_HEX: break; + default: break; + } + } + + config_file_free(conf); + } +} #pragma mark View Builders - (NSView*)labelAccessoryFor:(NSString*)text onTable:(NSTableView*)table @@ -105,7 +151,7 @@ return result; } -- (NSView*)booleanAccessoryFor:(const rarch_setting_t*)setting onTable:(NSTableView*)table +- (NSView*)booleanAccessoryFor:(const rarch_setting_t*)setting index:(NSNumber*)index onTable:(NSTableView*)table { NSButton* result = [table makeViewWithIdentifier:@"boolean" owner:self]; @@ -114,12 +160,21 @@ result = [NSButton new]; result.buttonType = NSSwitchButton; result.title = @""; + result.target = self; + result.action = @selector(booleanChanged:); } result.state = *(bool*)setting->value; + objc_setAssociatedObject(result, "INDEX", index, OBJC_ASSOCIATION_RETAIN_NONATOMIC); return result; } +- (void)booleanChanged:(NSButton*)sender +{ + int index = [objc_getAssociatedObject(sender, "INDEX") intValue]; + *(bool*)setting_data[index].value = sender.state; +} + #pragma mark Section Table - (NSInteger)numberOfRowsInTableView:(NSTableView*)view { @@ -172,7 +227,7 @@ { switch (setting->type) { - case ST_BOOL: return [self booleanAccessoryFor:setting onTable:outlineView]; + case ST_BOOL: return [self booleanAccessoryFor:setting index:item onTable:outlineView]; case ST_PATH: case ST_STRING: diff --git a/apple/RetroArch/setting_data.h b/apple/RetroArch/setting_data.h index e7f8246dc5..409c22e24b 100644 --- a/apple/RetroArch/setting_data.h +++ b/apple/RetroArch/setting_data.h @@ -28,6 +28,7 @@ typedef struct const char* name; void* value; + uint32_t size; const char* short_description; const char* long_description; @@ -40,18 +41,25 @@ typedef struct bool allow_blank; } rarch_setting_t; -#define START_GROUP(NAME) { ST_GROUP, NAME, 0, 0, 0, 0, 0, 0.0, 0.0, false }, -#define END_GROUP() { ST_END_GROUP, 0, 0, 0, 0, 0, 0, 0.0, 0.0, false }, -#define START_SUB_GROUP(NAME) { ST_SUB_GROUP, NAME, 0, 0, 0, 0, 0, 0.0, 0.0, false }, -#define END_SUB_GROUP() { ST_END_SUB_GROUP, 0, 0, 0, 0, 0, 0, 0.0, 0.0, false }, -#define START_GROUP(NAME) { ST_GROUP, NAME, 0, 0, 0, 0, 0, 0.0, 0.0, false }, -#define END_GROUP() { ST_END_GROUP, 0, 0, 0, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_BOOL(TARGET, NAME, SHORT) { ST_BOOL, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_INT(TARGET, NAME, SHORT) { ST_INT, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_FLOAT(TARGET, NAME, SHORT) { ST_FLOAT, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_PATH(TARGET, NAME, SHORT) { ST_PATH, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_STRING(TARGET, NAME, SHORT) { ST_STRING, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_HEX(TARGET, NAME, SHORT) { ST_HEX, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false }, +extern struct settings fake_settings; +extern struct global fake_extern; + +// HACK +#define g_settings fake_settings +#define g_extern fake_extern + +#define START_GROUP(NAME) { ST_GROUP, NAME }, +#define END_GROUP() { ST_END_GROUP }, +#define START_SUB_GROUP(NAME) { ST_SUB_GROUP, NAME }, +#define END_SUB_GROUP() { ST_END_SUB_GROUP }, +#define START_GROUP(NAME) { ST_GROUP, NAME, 0, 0, 0, 0, 0, 0, 0.0, 0.0, false }, +#define END_GROUP() { ST_END_GROUP, 0, 0, 0, 0, 0, 0, 0, 0.0, 0.0, false }, +#define CONFIG_BOOL(TARGET, NAME, SHORT) { ST_BOOL, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, +#define CONFIG_INT(TARGET, NAME, SHORT) { ST_INT, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, +#define CONFIG_FLOAT(TARGET, NAME, SHORT) { ST_FLOAT, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, +#define CONFIG_PATH(TARGET, NAME, SHORT) { ST_PATH, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, +#define CONFIG_STRING(TARGET, NAME, SHORT) { ST_STRING, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, +#define CONFIG_HEX(TARGET, NAME, SHORT) { ST_HEX, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, const rarch_setting_t setting_data[] = { @@ -162,8 +170,8 @@ const rarch_setting_t setting_data[] = /* Input: Overlay */ #ifdef HAVE_OVERLAY CONFIG_PATH(g_settings.input.overlay, "input_overlay", "Input Overlay") - CONFIG_FLOAT(g_settings.input.overlay_opacity, "overlay_opacity", "Overlay Opacity") - CONFIG_FLOAT(g_settings.input.overlay_scale, "overlay_scale", "Overlay Scale") + CONFIG_FLOAT(g_settings.input.overlay_opacity, "input_overlay_opacity", "Overlay Opacity") + CONFIG_FLOAT(g_settings.input.overlay_scale, "input_overlay_scale", "Overlay Scale") #endif /* Input: Android */ @@ -266,4 +274,8 @@ const rarch_setting_t setting_data[] = { 0 } }; +// HACK +#undef g_settings fake_settings +#undef g_extern fake_extern + #endif \ No newline at end of file From 2ef2b4e778a3b811c29a3a57ebc6cc1c9cd8fdcb Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 25 Aug 2013 19:40:31 -0400 Subject: [PATCH 119/202] (OSX) Add a menu option that opens the directory where cores should be placed --- apple/OSX/en.lproj/MainMenu.xib | 111 +++++++++++++++++++++++++++----- apple/OSX/platform.m | 7 +- 2 files changed, 102 insertions(+), 16 deletions(-) diff --git a/apple/OSX/en.lproj/MainMenu.xib b/apple/OSX/en.lproj/MainMenu.xib index 4ebd04b3f9..908154abc8 100644 --- a/apple/OSX/en.lproj/MainMenu.xib +++ b/apple/OSX/en.lproj/MainMenu.xib @@ -2,9 +2,9 @@ 1080 - 12D78 + 12E55 3084 - 1187.37 + 1187.39 626.00 com.apple.InterfaceBuilder.CocoaPlugin @@ -297,6 +297,28 @@ + + + Go + + 2147483647 + + + submenuAction: + + Go + + + + Cores Directory + + 2147483647 + + + + + + Window @@ -397,11 +419,9 @@ - + 256 {480, 360} - - {{0, 0}, {2560, 1418}} {10000000000000, 10000000000000} @@ -420,7 +440,7 @@ - + 256 @@ -428,7 +448,6 @@ 268 {{17, 72}, {242, 17}} - _NS:1535 YES @@ -470,7 +489,6 @@ 268 {{20, 45}, {239, 26}} - _NS:9 1 @@ -499,7 +517,7 @@ 274 - {13, 0} + {15, 0} _NS:24 @@ -508,7 +526,7 @@ YES - 10 + 12 10 1000 @@ -559,7 +577,7 @@ 19 tableViewAction: - -765427712 + -767524864 @@ -578,7 +596,6 @@ 268 {{180, 13}, {82, 32}} - _NS:9 YES @@ -599,8 +616,6 @@ {276, 89} - - _NS:21 @@ -787,6 +802,14 @@ 584 + + + showCoresDirectory: + + + + 588 + @@ -823,6 +846,7 @@ + @@ -1339,6 +1363,27 @@ + + 585 + + + + + + + + 586 + + + + + + + + 587 + + + @@ -1417,6 +1462,9 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1428,7 +1476,7 @@ - 584 + 588 @@ -1443,6 +1491,39 @@ RetroArch_OSX NSObject + + id + id + id + + + + coreWasChosen: + id + + + showCoresDirectory: + id + + + showPreferences: + id + + + + NSWindow + NSWindow + + + + _coreSelectSheet + NSWindow + + + window + NSWindow + + IBProjectSource ./Classes/RetroArch_OSX.h diff --git a/apple/OSX/platform.m b/apple/OSX/platform.m index 09580ca852..1f21d5aae8 100644 --- a/apple/OSX/platform.m +++ b/apple/OSX/platform.m @@ -82,7 +82,7 @@ if (cb.numberOfItems) [cb selectItemAtIndex:0]; else - apple_display_alert(@"No libretro cores were found.", @"RetroArch"); + apple_display_alert(@"No libretro cores were found.\nSelect \"Go->Cores Directory\" from the menu and place libretro dylib files there.", @"RetroArch"); // Run RGUI if needed if (!_wantReload) @@ -239,6 +239,11 @@ } #pragma mark Menus +- (IBAction)showCoresDirectory:(id)sender +{ + [[NSWorkspace sharedWorkspace] openFile:self.corePath]; +} + - (IBAction)showPreferences:(id)sender { [[[NSWindowController alloc] initWithWindowNibName:@"Settings"] window]; From 54b672d6b7cc6275817538917e3b32b8f32ab5fc Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 26 Aug 2013 00:37:17 -0400 Subject: [PATCH 120/202] (OSX) More settings menu work --- apple/OSX/Settings.xib | 1297 ++++++++++++++++++++++++++++++---------- apple/OSX/settings.m | 113 ++-- 2 files changed, 1058 insertions(+), 352 deletions(-) diff --git a/apple/OSX/Settings.xib b/apple/OSX/Settings.xib index 1d5c744237..4d9255c61f 100644 --- a/apple/OSX/Settings.xib +++ b/apple/OSX/Settings.xib @@ -2,9 +2,9 @@ 1080 - 12D78 + 12E55 3084 - 1187.37 + 1187.39 626.00 com.apple.InterfaceBuilder.CocoaPlugin @@ -72,7 +72,7 @@ {148, 514} - + _NS:13 YES NO @@ -164,7 +164,7 @@ MC41AA - 17 + 30 104857600 @@ -222,7 +222,7 @@ - QSAAAEEgAABBmAAAQZgAAA + QSAAAEEgAABCAAAAQgAAAA 0.25 4 1 @@ -233,6 +233,7 @@ {{582, 13}, {75, 32}} + _NS:9 YES @@ -277,13 +278,15 @@ {471, 17} - + - - + + -2147483392 {{224, 0}, {16, 17}} + + _NS:18 @@ -350,7 +353,7 @@ 2 - 17 + 30 306216960 @@ -413,6 +416,7 @@ 4 + {{178, 61}, {473, 516}} @@ -424,7 +428,8 @@ - QSAAAEEgAABBmAAAQZgAAA + + QSAAAEEgAABCAAAAQgAAAA 0.25 4 1 @@ -493,45 +498,6 @@ 180 - - - textField - - - 274 - - - - 266 - {145, 17} - - - {250, 750} - YES - - 67108928 - 272631808 - Table View Cell - - - - 6 - System - controlColor - - - - - NO - - - {{1, 1}, {145, 17}} - - - - - 108 - dataSource @@ -558,7 +524,7 @@ 266 - {101, 17} + {{0, 7}, {101, 17}} {250, 750} @@ -566,22 +532,43 @@ 67108928 272631808 - Table View Cell + - + + 6 + System + controlColor + + NO - {{1, 1}, {101, 17}} + {{1, 1}, {101, 30}} 168 + + + value: stringValue + + + + + + value: stringValue + value + stringValue + 2 + + + 319 + textField @@ -592,15 +579,15 @@ 266 - {364, 17} + {{0, 7}, {364, 17}} - + {250, 750} YES - 67108928 - 272631808 - Table View Cell + 337641537 + 272631872 + String @@ -609,13 +596,265 @@ NO - {{105, 1}, {364, 17}} + {{105, 1}, {364, 30}} 172 + + + value: stringValue + + + + + + value: stringValue + value + stringValue + 2 + + + 240 + + + + textField + + + 274 + + + + 266 + {{0, 7}, {364, 17}} + + + {250, 750} + YES + + 337641537 + 272631872 + Int + + + + + + NO + + + {{105, 65}, {364, 30}} + + + + + 227 + + + + value: numericValue + + + + + + value: numericValue + value + numericValue + 2 + + + 241 + + + + value: booleanValue + + + 268 + {{1, 6}, {61, 18}} + + + _NS:9 + YES + + -2080374784 + 268435456 + + + _NS:9 + + 1211912448 + 2 + + NSImage + NSSwitch + + + NSSwitch + + + + 200 + 25 + + NO + + + + 274 + + + + {{105, 33}, {364, 30}} + + + + + + value: booleanValue + value + booleanValue + 2 + + + 255 + + + + textField + + + 274 + + + + 266 + {{0, 7}, {320, 17}} + + + {250, 750} + YES + + 337641537 + 272631872 + + + + + + + NO + + + + 268 + {{319, -2}, {48, 32}} + + + _NS:9 + YES + + 67108864 + 134217728 + ... + + _NS:9 + + -2038284288 + 129 + + + 200 + 25 + + NO + + + {{105, 97}, {364, 30}} + + + + + 298 + + + + doBrowse: + + + + 312 + + + + value: stringValue + + + + + + value: stringValue + value + stringValue + 2 + + + 314 + + + + textField + + + 274 + + + + 266 + {{0, 7}, {145, 17}} + + + {250, 750} + YES + + 67108928 + 272631808 + + + + + + + NO + + + {{1, 1}, {145, 30}} + + + + + 326 + + + + value: stringValue + + + + + + value: stringValue + value + stringValue + 2 + + + 327 + @@ -658,22 +897,6 @@ - - - 6 - 0 - - 6 - 1 - - 20 - - 1000 - - 8 - 29 - 3 - 4 @@ -706,6 +929,38 @@ 24 3 + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + 4 @@ -722,20 +977,20 @@ 24 2 - - - 6 + + + 5 0 - + 6 1 - 20 + 8 1000 - 8 - 29 + 6 + 24 3 @@ -770,28 +1025,12 @@ 29 3 - - + + 5 0 - - 6 - 1 - - 8 - - 1000 - - 6 - 24 - 3 - - - - 3 - 0 - 3 + 5 1 20 @@ -802,12 +1041,12 @@ 29 3 - + - 5 + 3 0 - 5 + 3 1 20 @@ -854,7 +1093,7 @@ - + @@ -868,75 +1107,6 @@ - - 105 - - - - - - 10 - 0 - - 10 - 1 - - 0.0 - - 1000 - - 5 - 22 - 2 - - - - 6 - 0 - - 6 - 1 - - 3 - - 1000 - - 8 - 29 - 3 - - - - 5 - 0 - - 5 - 1 - - 3 - - 1000 - - 8 - 29 - 3 - - - - - - 106 - - - - - - - - 107 - - - 116 @@ -994,7 +1164,10 @@ + + + @@ -1013,23 +1186,23 @@ - - - 10 + + + 6 0 - - 10 + + 6 1 - 0.0 + 3 1000 - 5 - 22 - 2 + 8 + 29 + 3 - + 5 0 @@ -1045,6 +1218,22 @@ 29 3 + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 5 + 22 + 2 + @@ -1066,23 +1255,7 @@ - - - 6 - 0 - - 6 - 1 - - 3 - - 1000 - - 8 - 29 - 3 - - + 5 0 @@ -1098,7 +1271,7 @@ 29 3 - + 10 0 @@ -1114,6 +1287,22 @@ 22 2 + + + 6 + 0 + + 6 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + @@ -1136,94 +1325,497 @@ - 195 - - + 224 + + + + + + 6 + 0 + + 6 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 5 + 22 + 2 + + + + 5 + 0 + + 5 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + - 196 + 225 + + + + + + + + 226 + + + + + 242 + + + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 5 + 22 + 2 + + + + 5 + 0 + + 5 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + + + + 249 + + + + + + 7 + 0 + + 0 + 1 + + 57 + + 1000 + + 3 + 9 + 1 + + + + + + 250 + + + + + 267 - 197 - + 268 + - 198 - - - - - 199 - - - - - 200 - - - - - 201 - - - - - 202 - - - - - 203 - - - - - 204 + 269 - 205 - - + 270 + + - 206 + 271 + + + + + 272 + + + + + 273 + + + + + 274 + + + + + 275 + + + + + 276 + + + + + 280 + + + + + 281 + + + + + 285 + + + + + 287 + + + + + 288 + + + + + 289 + + + + + 290 + + + + + 291 + + + + + 292 + + + + + 293 + + + + + 294 + + + + + 295 + + + + + 5 + 0 + + 6 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 6 + 0 + + 6 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 5 + 22 + 2 + + + + 5 + 0 + + 5 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + + + + + + 296 + + + + + + + + 297 + + + + + 300 + + + + + 303 + + + + + + 7 + 0 + + 0 + 1 + + 36 + + 1000 + + 3 + 9 + 1 + + + + + + 304 + + + + + 308 + + + + + 309 + + + + + 310 + + + + + 311 + + + + + 316 + + + + + 317 - + - 207 + 320 + + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 5 + 22 + 2 + + + + 5 + 0 + + 5 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + + + + + 321 - + - 208 - - + 322 + + - 209 - - + 323 + + - 210 - - + 324 + + + + + - 211 - - - - - 212 - - + 325 + + @@ -1234,15 +1826,6 @@ com.apple.InterfaceBuilder.CocoaPlugin {{357, 418}, {480, 270}} - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1261,58 +1844,133 @@ + + + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + RASettingCell - - + + + com.apple.InterfaceBuilder.CocoaPlugin + RALabelSetting com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + RASettingCell - - - + + + com.apple.InterfaceBuilder.CocoaPlugin + RAStringSetting com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin + - - - + + + - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin + RASettingCell + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + RANumericSetting + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + RASettingCell + + + + + com.apple.InterfaceBuilder.CocoaPlugin + RABooleanSetting + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + RASettingCell + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + RAPathSetting + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + RASettingCell + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + RALabelSetting + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1322,7 +1980,7 @@ com.apple.InterfaceBuilder.CocoaPlugin - + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1331,7 +1989,7 @@ - 212 + 327 @@ -1343,6 +2001,39 @@ ./Classes/NSLayoutConstraint.h + + RASettingCell + NSTableCellView + + id + id + + + + doBrowse: + id + + + valueChanged: + id + + + + numericValue + NSNumber + + + numericValue + + numericValue + NSNumber + + + + IBProjectSource + ./Classes/RASettingCell.h + + RASettingsDelegate NSObject @@ -1387,6 +2078,10 @@ IBCocoaFramework YES 3 + + NSSwitch + {15, 15} + YES diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 98d4f1cd4f..e24d3bf7f9 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -20,6 +20,50 @@ struct settings fake_settings; struct global fake_extern; +static const void* associated_name_tag = (void*)&associated_name_tag; + +@interface RASettingCell : NSTableCellView +@property (strong) NSString* stringValue; +@property (nonatomic) IBOutlet NSNumber* numericValue; +@property (nonatomic) bool booleanValue; +@property (nonatomic) const rarch_setting_t* setting; +@end + +@implementation RASettingCell +- (void)setSetting:(const rarch_setting_t *)aSetting +{ + _setting = aSetting; + + switch (aSetting->type) + { + case ST_INT: self.numericValue = @(*(int*)aSetting->value); break; + case ST_FLOAT: self.numericValue = @(*(float*)aSetting->value); break; + case ST_STRING: self.stringValue = @((const char*)aSetting->value); break; + case ST_PATH: self.stringValue = @((const char*)aSetting->value); break; + case ST_BOOL: self.booleanValue = *(bool*)aSetting->value; break; + } +} + +- (IBAction)doBrowse:(id)sender +{ + NSOpenPanel* panel = [NSOpenPanel new]; + [panel runModal]; + + if (panel.URLs.count == 1) + self.stringValue = panel.URL.path; +} + +- (IBAction)valueChanged:(id)sender +{ + printf("GABOR\n"); +} + +@end + +@protocol RASettingView +@property const rarch_setting_t* setting; +@end + @interface RASettingsDelegate : NSObject @end @@ -50,7 +94,7 @@ struct global fake_extern; case ST_GROUP: { thisGroup = [NSMutableArray array]; - objc_setAssociatedObject(thisGroup, "NAME", [NSString stringWithFormat:@"%s", setting_data[i].name], OBJC_ASSOCIATION_RETAIN_NONATOMIC); + objc_setAssociatedObject(thisGroup, associated_name_tag, [NSString stringWithFormat:@"%s", setting_data[i].name], OBJC_ASSOCIATION_RETAIN_NONATOMIC); break; } @@ -64,7 +108,7 @@ struct global fake_extern; case ST_SUB_GROUP: { thisSubGroup = [NSMutableArray array]; - objc_setAssociatedObject(thisSubGroup, "NAME", [NSString stringWithFormat:@"%s", setting_data[i].name], OBJC_ASSOCIATION_RETAIN_NONATOMIC); + objc_setAssociatedObject(thisSubGroup, associated_name_tag, [NSString stringWithFormat:@"%s", setting_data[i].name], OBJC_ASSOCIATION_RETAIN_NONATOMIC); break; } @@ -138,43 +182,11 @@ struct global fake_extern; #pragma mark View Builders - (NSView*)labelAccessoryFor:(NSString*)text onTable:(NSTableView*)table { - NSTextField* result = [table makeViewWithIdentifier:@"label" owner:self]; - if (result == nil) - { - result = [NSTextField new]; - result.bordered = NO; - result.drawsBackground = NO; - result.identifier = @"label"; - } - + RASettingCell* result = [table makeViewWithIdentifier:@"RALabelSetting" owner:nil]; result.stringValue = text; return result; } -- (NSView*)booleanAccessoryFor:(const rarch_setting_t*)setting index:(NSNumber*)index onTable:(NSTableView*)table -{ - NSButton* result = [table makeViewWithIdentifier:@"boolean" owner:self]; - - if (!result) - { - result = [NSButton new]; - result.buttonType = NSSwitchButton; - result.title = @""; - result.target = self; - result.action = @selector(booleanChanged:); - } - - result.state = *(bool*)setting->value; - objc_setAssociatedObject(result, "INDEX", index, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - return result; -} - -- (void)booleanChanged:(NSButton*)sender -{ - int index = [objc_getAssociatedObject(sender, "INDEX") intValue]; - *(bool*)setting_data[index].value = sender.state; -} - #pragma mark Section Table - (NSInteger)numberOfRowsInTableView:(NSTableView*)view { @@ -183,7 +195,7 @@ struct global fake_extern; - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { - return [self labelAccessoryFor:objc_getAssociatedObject(_settings[row], "NAME") onTable:tableView]; + return [self labelAccessoryFor:objc_getAssociatedObject(_settings[row], associated_name_tag) onTable:tableView]; } - (void)tableViewSelectionDidChange:(NSNotification *)aNotification @@ -208,12 +220,16 @@ struct global fake_extern; return [item isKindOfClass:[NSArray class]]; } +- (BOOL)validateProposedFirstResponder:(NSResponder *)responder forEvent:(NSEvent *)event { + return YES; +} + - (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item { if ([item isKindOfClass:[NSArray class]]) { if ([tableColumn.identifier isEqualToString:@"title"]) - return [self labelAccessoryFor:objc_getAssociatedObject(item, "NAME") onTable:outlineView]; + return [self labelAccessoryFor:objc_getAssociatedObject(item, associated_name_tag) onTable:outlineView]; else return [self labelAccessoryFor:[NSString stringWithFormat:@"%d items", (int)[item count]] onTable:outlineView]; } @@ -222,25 +238,20 @@ struct global fake_extern; const rarch_setting_t* setting = &setting_data[[item intValue]]; if ([tableColumn.identifier isEqualToString:@"title"]) - return [self labelAccessoryFor:[NSString stringWithFormat:@"%s", setting->short_description] onTable:outlineView]; // < The outlineView will fill the value + return [self labelAccessoryFor:@(setting->short_description) onTable:outlineView]; else if([tableColumn.identifier isEqualToString:@"accessory"]) { + RASettingCell* s = nil; switch (setting->type) { - case ST_BOOL: return [self booleanAccessoryFor:setting index:item onTable:outlineView]; - - case ST_PATH: - case ST_STRING: - return [self labelAccessoryFor:[NSString stringWithFormat:@"%s", (const char*)setting->value] onTable:outlineView]; - - case ST_INT: - return [self labelAccessoryFor:[NSString stringWithFormat:@"%d", *(int*)setting->value] onTable:outlineView]; - - case ST_FLOAT: - return [self labelAccessoryFor:[NSString stringWithFormat:@"%f", *(float*)setting->value] onTable:outlineView]; - - default: abort(); + case ST_BOOL: s = [outlineView makeViewWithIdentifier:@"RABooleanSetting" owner:nil]; break; + case ST_INT: s = [outlineView makeViewWithIdentifier:@"RANumericSetting" owner:nil]; break; + case ST_FLOAT: s = [outlineView makeViewWithIdentifier:@"RANumericSetting" owner:nil]; break; + case ST_PATH: s = [outlineView makeViewWithIdentifier:@"RAPathSetting" owner:nil]; break; + case ST_STRING: s = [outlineView makeViewWithIdentifier:@"RAStringSetting" owner:nil]; break; } + s.setting = setting; + return s; } } From 333ae68163e95c1dc2cccda56450ad99cf42938a Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Mon, 26 Aug 2013 12:13:41 +0100 Subject: [PATCH 121/202] more small style tweaks --- Makefile.win | 6 +- frontend/frontend_context.c | 6 +- input/dinput.c | 8 +- input/input_common.c | 2 +- input/winxinput_joypad.c | 109 +++++++++++----------- msvc/msvc-2010/RetroArch-msvc2010.vcxproj | 8 +- 6 files changed, 64 insertions(+), 75 deletions(-) diff --git a/Makefile.win b/Makefile.win index df300fb4f7..27cdb3cc11 100644 --- a/Makefile.win +++ b/Makefile.win @@ -64,7 +64,7 @@ HAVE_THREADS = 1 HAVE_RGUI = 1 DYNAMIC = 1 -USE_WINXINPUT = 1 +HAVE_WINXINPUT = 1 ifeq ($(SLIM),) HAVE_SDL = 1 @@ -215,8 +215,8 @@ ifeq ($(HAVE_PYTHON), 1) OBJ += gfx/py_state/py_state.o endif -ifeq ($(USE_WINXINPUT), 1) - DEFINES += -DUSE_WINXINPUT +ifeq ($(HAVE_WINXINPUT), 1) + DEFINES += -DHAVE_WINXINPUT OBJ += input/winxinput_joypad.o endif diff --git a/frontend/frontend_context.c b/frontend/frontend_context.c index fcb03e084f..3072732b4c 100644 --- a/frontend/frontend_context.c +++ b/frontend/frontend_context.c @@ -41,10 +41,8 @@ static const frontend_ctx_driver_t *frontend_ctx_drivers[] = { const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident) { - for (unsigned i = 0; i < sizeof(frontend_ctx_drivers) / sizeof(frontend_ctx_drivers[0]); i++) + for (unsigned i = 0; frontend_ctx_drivers[i]; i++) { - if (!frontend_ctx_drivers[i]) // check for dummy NULL - continue; if (strcmp(frontend_ctx_drivers[i]->ident, ident) == 0) return frontend_ctx_drivers[i]; } @@ -54,7 +52,7 @@ const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident) const frontend_ctx_driver_t *frontend_ctx_init_first(void) { - for (unsigned i = 0; i < sizeof(frontend_ctx_drivers) / sizeof(frontend_ctx_drivers[0]); i++) + for (unsigned i = 0; frontend_ctx_drivers[i]; i++) return frontend_ctx_drivers[i]; return NULL; diff --git a/input/dinput.c b/input/dinput.c index 9df0386b52..972772da75 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -68,12 +68,6 @@ static bool dinput_init_context(void) if (g_ctx) return true; - /*if (driver.display_type != RARCH_DISPLAY_WIN32) - { - RARCH_ERR("Cannot open DInput as no Win32 window is present.\n"); - return false; - }*/ // Not needed, interferes with joyconfig - CoInitialize(NULL); // Who said we shouldn't have same call signature in a COM API? <_< @@ -431,7 +425,7 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) #endif return DIENUM_CONTINUE; -#ifdef USE_WINXINPUT +#ifdef HAVE_WINXINPUT int last_xbox_pad_index = 0; if (name_is_360_pad(inst->tszProductName)) diff --git a/input/input_common.c b/input/input_common.c index cc7ab96e80..fb799e3884 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -41,7 +41,7 @@ static const rarch_joypad_driver_t *joypad_drivers[] = { #ifndef IS_RETROLAUNCH -#ifdef USE_WINXINPUT +#ifdef HAVE_WINXINPUT &winxinput_joypad, #endif #ifdef HAVE_DINPUT diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index d7666140e9..d07af3a1cb 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -1,6 +1,5 @@ /* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2013 - Hans-Kristian Arntzen - * + * * 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. @@ -33,37 +32,37 @@ // Official and mingw xinput headers have different include guards #if ((!_XINPUT_H_) && (!__WINE_XINPUT_H)) - #define XINPUT_GAMEPAD_DPAD_UP 0x0001 - #define XINPUT_GAMEPAD_DPAD_DOWN 0x0002 - #define XINPUT_GAMEPAD_DPAD_LEFT 0x0004 - #define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008 - #define XINPUT_GAMEPAD_START 0x0010 - #define XINPUT_GAMEPAD_BACK 0x0020 - #define XINPUT_GAMEPAD_LEFT_THUMB 0x0040 - #define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080 - #define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 - #define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 - #define XINPUT_GAMEPAD_A 0x1000 - #define XINPUT_GAMEPAD_B 0x2000 - #define XINPUT_GAMEPAD_X 0x4000 - #define XINPUT_GAMEPAD_Y 0x8000 - - typedef struct - { - uint16_t wButtons; - uint8_t bLeftTrigger; - uint8_t bRightTrigger; - int16_t sThumbLX; - int16_t sThumbLY; - int16_t sThumbRX; - int16_t sThumbRY; - } XINPUT_GAMEPAD; +#define XINPUT_GAMEPAD_DPAD_UP 0x0001 +#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002 +#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004 +#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008 +#define XINPUT_GAMEPAD_START 0x0010 +#define XINPUT_GAMEPAD_BACK 0x0020 +#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040 +#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080 +#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 +#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 +#define XINPUT_GAMEPAD_A 0x1000 +#define XINPUT_GAMEPAD_B 0x2000 +#define XINPUT_GAMEPAD_X 0x4000 +#define XINPUT_GAMEPAD_Y 0x8000 - typedef struct - { - uint32_t dwPacketNumber; - XINPUT_GAMEPAD Gamepad; - } XINPUT_STATE; +typedef struct +{ + uint16_t wButtons; + uint8_t bLeftTrigger; + uint8_t bRightTrigger; + int16_t sThumbLX; + int16_t sThumbLY; + int16_t sThumbRX; + int16_t sThumbRY; +} XINPUT_GAMEPAD; + +typedef struct +{ + uint32_t dwPacketNumber; + XINPUT_GAMEPAD Gamepad; +} XINPUT_STATE; #endif @@ -71,11 +70,11 @@ #define XINPUT_GAMEPAD_GUIDE 0x0400 #ifndef ERROR_DEVICE_NOT_CONNECTED - #define ERROR_DEVICE_NOT_CONNECTED 1167 +#define ERROR_DEVICE_NOT_CONNECTED 1167 #endif #ifndef HAVE_DINPUT - #error Cannot compile xinput without dinput. +#error Cannot compile xinput without dinput. #endif // Due to 360 pads showing up under both XI and DI, and since we are going @@ -120,20 +119,20 @@ static bool winxinput_joypad_init(void) // No need to check for existance as we will be checking LoadLibrary's // success anyway. - char dll_path[MAX_PATH]; - strcpy(dll_path, "xinput1_3.dll"); - g_winxinput_dll = LoadLibrary(dll_path); + const char* DLL_NAME = "xinput1_3.dll"; + g_winxinput_dll = LoadLibrary(DLL_NAME); // Using dylib_* complicates building joyconfig. if (!g_winxinput_dll) { // Loading from working dir failed, try to load from system. + char dll_path[MAX_PATH]; GetSystemDirectory(dll_path, sizeof(dll_path)); - strcat(dll_path, "\\xinput1_3.dll"); + strlcat(dll_path, "\\", 1); + strlcat(dll_path, DLL_NAME, sizeof(DLL_NAME)); g_winxinput_dll = LoadLibrary(dll_path); if (!g_winxinput_dll) { - RARCH_ERR("Failed to init XInput, ensure DirectX and controller drivers are up to date.\n"); - //g_dinput_should_filter_xinput_controllers = false; + RARCH_ERR("Failed to load xinput1_3.dll, ensure DirectX and controller drivers are up to date.\n"); return false; // DLL does not exist or is invalid } @@ -152,8 +151,7 @@ static bool winxinput_joypad_init(void) g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState"); if (!g_XInputGetStateEx) { - RARCH_ERR("Failed to init XInput: Found an XInput DLL but it is invalid or corrupt.\n"); - //g_dinput_should_filter_xinput_controllers = false; + RARCH_ERR("Failed to init XInput: xinput1_3.dll is invalid or corrupt.\n"); return false; // DLL was loaded but did not contain the correct function. } RARCH_WARN("XInput: No guide button support.\n"); @@ -173,12 +171,11 @@ static bool winxinput_joypad_init(void) } if ((!g_winxinput_states[0].connected) && - (!g_winxinput_states[1].connected) && - (!g_winxinput_states[2].connected) && - (!g_winxinput_states[3].connected)) - return false; + (!g_winxinput_states[1].connected) && + (!g_winxinput_states[2].connected) && + (!g_winxinput_states[3].connected)) + return false; - // We're going to have to be buddies with dinput if we want to be able // to use XI and non-XI controllers together. return dinput_joypad.init(); @@ -209,16 +206,16 @@ static void winxinput_joypad_destroy(void) // Map from rarch button index (0..10) to a mask to bitwise-& the buttons against. // dpad is handled seperately. static const uint16_t button_index_to_bitmap_code[] = { - XINPUT_GAMEPAD_A , - XINPUT_GAMEPAD_B , - XINPUT_GAMEPAD_X , - XINPUT_GAMEPAD_Y , - XINPUT_GAMEPAD_LEFT_SHOULDER , + XINPUT_GAMEPAD_A, + XINPUT_GAMEPAD_B, + XINPUT_GAMEPAD_X, + XINPUT_GAMEPAD_Y, + XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, - XINPUT_GAMEPAD_START , - XINPUT_GAMEPAD_BACK , - XINPUT_GAMEPAD_LEFT_THUMB , - XINPUT_GAMEPAD_RIGHT_THUMB , + XINPUT_GAMEPAD_START, + XINPUT_GAMEPAD_BACK, + XINPUT_GAMEPAD_LEFT_THUMB, + XINPUT_GAMEPAD_RIGHT_THUMB, XINPUT_GAMEPAD_GUIDE }; diff --git a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj index 3a7d4085ad..45bbb6b6cd 100644 --- a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj +++ b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj @@ -88,7 +88,7 @@ Level3 Disabled - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;USE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -108,7 +108,7 @@ Level3 Disabled - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;USE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -130,7 +130,7 @@ MaxSpeed true true - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;USE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -154,7 +154,7 @@ MaxSpeed true true - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;USE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_ZLIB;WANT_MINIZ;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_ZLIB;WANT_MINIZ;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp From d5eea1e575dcf2840a827a6cf4ca5b9aa4a14b7d Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Mon, 26 Aug 2013 15:37:01 +0100 Subject: [PATCH 122/202] fixed attribution --- input/winxinput_joypad.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index d07af3a1cb..00ab50c60b 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -1,5 +1,6 @@ /* RetroArch - A frontend for libretro. - * + * Copyright (C) 2013 - pinumbernumber + * * 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. From 5411646504c0d5dff806a02dbc57076680c94078 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 26 Aug 2013 18:27:36 +0200 Subject: [PATCH 123/202] Clone from upstream with MinGW build script. --- retroarch-mingw-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroarch-mingw-build.sh b/retroarch-mingw-build.sh index 3f9640a4f4..1f6135a03c 100755 --- a/retroarch-mingw-build.sh +++ b/retroarch-mingw-build.sh @@ -83,7 +83,7 @@ do_build() BUILDTYPE="$3" if [ ! -d "$RetroArch_DIR" ]; then - git clone git://github.com/Themaister/RetroArch.git "$RetroArch_DIR" + git clone git://github.com/libretro/RetroArch.git "$RetroArch_DIR" cd "$RetroArch_DIR" else cd "$RetroArch_DIR" From dbc1758a990d0324d031ff5bf1205bc01fb259ec Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 26 Aug 2013 14:05:16 -0400 Subject: [PATCH 124/202] (OSX) The settings panel now works --- apple/OSX/platform.h | 1 + apple/OSX/platform.m | 5 ++++ apple/OSX/settings.m | 60 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/apple/OSX/platform.h b/apple/OSX/platform.h index b35cf774af..8078979caf 100644 --- a/apple/OSX/platform.h +++ b/apple/OSX/platform.h @@ -36,6 +36,7 @@ - (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; - (void)unloadingCore:(RAModuleInfo*)core; +- (NSString*)configPath; @end diff --git a/apple/OSX/platform.m b/apple/OSX/platform.m index 1f21d5aae8..e263afbf4a 100644 --- a/apple/OSX/platform.m +++ b/apple/OSX/platform.m @@ -227,6 +227,11 @@ _wantReload = false; } +- (NSString*)configPath +{ + return [[self retroarchConfigPath] stringByAppendingPathComponent:@"retroarch.cfg"]; +} + - (NSString*)retroarchConfigPath { NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index e24d3bf7f9..3875346cbf 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -23,7 +23,7 @@ struct global fake_extern; static const void* associated_name_tag = (void*)&associated_name_tag; @interface RASettingCell : NSTableCellView -@property (strong) NSString* stringValue; +@property (nonatomic) NSString* stringValue; @property (nonatomic) IBOutlet NSNumber* numericValue; @property (nonatomic) bool booleanValue; @property (nonatomic) const rarch_setting_t* setting; @@ -34,6 +34,9 @@ static const void* associated_name_tag = (void*)&associated_name_tag; { _setting = aSetting; + if (!_setting) + return; + switch (aSetting->type) { case ST_INT: self.numericValue = @(*(int*)aSetting->value); break; @@ -53,9 +56,30 @@ static const void* associated_name_tag = (void*)&associated_name_tag; self.stringValue = panel.URL.path; } -- (IBAction)valueChanged:(id)sender +- (void)setNumericValue:(NSNumber *)numericValue { - printf("GABOR\n"); + _numericValue = numericValue; + + if (_setting && _setting->type == ST_INT) + *(int*)_setting->value = [_numericValue intValue]; + else if (_setting && _setting->type == ST_FLOAT) + *(float*)_setting->value = [_numericValue floatValue]; +} + +- (void)setBooleanValue:(bool)booleanValue +{ + _booleanValue = booleanValue; + + if (_setting && _setting->type == ST_BOOL) + *(bool*)_setting->value = _booleanValue; +} + +- (void)setStringValue:(NSString *)stringValue +{ + _stringValue = stringValue; + + if (_setting && (_setting->type == ST_STRING || _setting->type == ST_PATH)) + strlcpy(_setting->value, _stringValue.UTF8String, _setting->size); } @end @@ -127,14 +151,15 @@ static const void* associated_name_tag = (void*)&associated_name_tag; } } + [self load]; + [NSApplication.sharedApplication beginSheet:_window modalForWindow:RetroArch_OSX.get->window modalDelegate:nil didEndSelector:nil contextInfo:nil]; [NSApplication.sharedApplication runModalForWindow:_window]; } -- (IBAction)close:(id)sender +- (void)load { -#if 0 - config_file_t* conf = config_file_new(0); + config_file_t* conf = config_file_new([RetroArch_OSX get].configPath.UTF8String); for (int i = 0; setting_data[i].type; i ++) { switch (setting_data[i].type) @@ -149,7 +174,28 @@ static const void* associated_name_tag = (void*)&associated_name_tag; } } config_file_free(conf); -#endif +} + +- (IBAction)close:(id)sender +{ + config_file_t* conf = config_file_new(0); + for (int i = 0; setting_data[i].type; i ++) + { + switch (setting_data[i].type) + { + case ST_BOOL: config_set_bool (conf, setting_data[i].name, * (bool*)setting_data[i].value); break; + case ST_INT: config_set_int (conf, setting_data[i].name, * (int*)setting_data[i].value); break; + case ST_FLOAT: config_set_float (conf, setting_data[i].name, *(float*)setting_data[i].value); break; + case ST_PATH: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break; + case ST_STRING: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break; + case ST_HEX: break; + default: break; + } + } + config_file_write(conf, [RetroArch_OSX get].configPath.UTF8String); + config_file_free(conf); + + apple_refresh_config(); [NSApplication.sharedApplication stopModal]; [NSApplication.sharedApplication endSheet:_window returnCode:0]; From 29b8a6f8e4be9658dab4d031029b89447f184d44 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 26 Aug 2013 22:12:22 -0400 Subject: [PATCH 125/202] (OSX) Start keybind setting support --- apple/OSX/InputBinder.xib | 384 ++++++ apple/OSX/Settings.xib | 1115 ++++++++++------- apple/OSX/hid_pad.c | 6 +- apple/OSX/platform.m | 3 +- apple/OSX/settings.m | 163 ++- apple/RetroArch/setting_data.h | 87 +- apple/RetroArch_OSX.xcodeproj/project.pbxproj | 4 + 7 files changed, 1238 insertions(+), 524 deletions(-) create mode 100644 apple/OSX/InputBinder.xib diff --git a/apple/OSX/InputBinder.xib b/apple/OSX/InputBinder.xib new file mode 100644 index 0000000000..1dc324d900 --- /dev/null +++ b/apple/OSX/InputBinder.xib @@ -0,0 +1,384 @@ + + + + 1080 + 12E55 + 3084 + 1187.39 + 626.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 3084 + + + IBNSLayoutConstraint + NSButton + NSButtonCell + NSCustomObject + NSTextField + NSTextFieldCell + NSView + NSWindowTemplate + + + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + + NSWindowController + + + FirstResponder + + + NSApplication + + + 15 + 2 + {{196, 240}, {480, 109}} + 544735232 + Window + RAInputBinder + + + + + 256 + + + + 268 + {{17, 72}, {446, 17}} + + + + _NS:1535 + YES + + 68157504 + 138413056 + Press a Key, Joystick Button, or move a Joystick Axis + + LucidaGrande + 13 + 1044 + + _NS:1535 + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2NjY3AA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + NO + + + + 268 + {{384, 13}, {82, 32}} + + + _NS:9 + YES + + 67108864 + 134217728 + Cancel + + _NS:9 + + -2038284288 + 129 + + + Gw + 200 + 25 + + NO + + + {480, 109} + + + + + {{0, 0}, {2560, 1418}} + {10000000000000, 10000000000000} + YES + + + + + + + window + + + + 3 + + + + goAway: + + + + 20 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 1 + + + + + + + + 2 + + + + + 4 + 0 + + 4 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 3 + 0 + + 3 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + + + + + 4 + + + + + + + + 5 + + + + + 9 + + + + + 10 + + + + + 11 + + + + + 12 + + + + + + + + 13 + + + + + 14 + + + + + 15 + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{357, 418}, {480, 270}} + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 20 + + + + + NSLayoutConstraint + NSObject + + IBProjectSource + ./Classes/NSLayoutConstraint.h + + + + RAInputBinder + NSWindow + + IBProjectSource + ./Classes/RAInputBinder.h + + + + + 0 + IBCocoaFramework + YES + 3 + YES + + diff --git a/apple/OSX/Settings.xib b/apple/OSX/Settings.xib index 4d9255c61f..03a3147273 100644 --- a/apple/OSX/Settings.xib +++ b/apple/OSX/Settings.xib @@ -36,7 +36,7 @@ - NSObject + NSWindowController FirstResponder @@ -45,11 +45,11 @@ NSApplication - 15 + 3 2 - {{196, 240}, {671, 597}} + {{196, 240}, {759, 597}} 544735232 - Window + RetroArch Settings NSWindow @@ -69,10 +69,10 @@ 256 - {148, 514} + {148, 555} - + _NS:13 YES NO @@ -176,7 +176,7 @@ 1 - {{1, 1}, {148, 514}} + {{1, 1}, {148, 555}} @@ -213,7 +213,7 @@ 0.99404761904761907 - {{20, 61}, {150, 516}} + {{20, 20}, {150, 557}} @@ -227,31 +227,6 @@ 4 1 - - - 268 - {{582, 13}, {75, 32}} - - - - _NS:9 - YES - - 67108864 - 134217728 - Close - - _NS:9 - - -2038284288 - 129 - - - 200 - 25 - - NO - 268 @@ -264,7 +239,7 @@ 256 - {471, 498} + {559, 539} @@ -273,10 +248,10 @@ NO YES - + 256 - {471, 17} - + {559, 17} + @@ -293,7 +268,7 @@ title - 101 + 276 16 1000 @@ -323,7 +298,7 @@ accessory - 364 + 277 40 1000 @@ -364,9 +339,10 @@ 0 1 NO + 4 - {{1, 17}, {471, 498}} + {{1, 17}, {559, 539}} @@ -386,29 +362,29 @@ NO _doScroller: - 0.99799599198396793 + 0.9721706864564007 -2147483392 - {{1, 499}, {471, 16}} + {{1, 541}, {486, 15}} - + _NS:60 NO 1 _doScroller: - 0.82055749128919864 + 0.55290102389078499 - + 2304 - {{1, 0}, {471, 17}} + {{1, 0}, {559, 17}} @@ -418,16 +394,16 @@ - {{178, 61}, {473, 516}} + {{178, 20}, {561, 557}} - + _NS:9 133682 - + QSAAAEEgAABCAAAAQgAAAA 0.25 @@ -435,7 +411,7 @@ 1 - {671, 597} + {759, 597} @@ -450,6 +426,22 @@ + + + window + + + + 422 + + + + delegate + + + + 356 + dataSource @@ -482,14 +474,6 @@ 104 - - - close: - - - - 122 - _outline @@ -524,7 +508,7 @@ 266 - {{0, 7}, {101, 17}} + {{0, 7}, {276, 17}} {250, 750} @@ -546,7 +530,7 @@ NO - {{1, 1}, {101, 30}} + {{1, 1}, {276, 30}} @@ -579,7 +563,7 @@ 266 - {{0, 7}, {364, 17}} + {{0, 7}, {277, 17}} {250, 750} @@ -596,7 +580,7 @@ NO - {{105, 1}, {364, 30}} + {{280, 1}, {277, 30}} @@ -629,7 +613,7 @@ 266 - {{0, 7}, {364, 17}} + {{0, 7}, {277, 17}} {250, 750} @@ -646,7 +630,7 @@ NO - {{105, 65}, {364, 30}} + {{280, 65}, {277, 30}} @@ -709,7 +693,7 @@ - {{105, 33}, {364, 30}} + {{280, 33}, {277, 30}} @@ -733,7 +717,7 @@ 266 - {{0, 7}, {320, 17}} + {{0, 7}, {233, 17}} {250, 750} @@ -752,9 +736,9 @@ 268 - {{319, -2}, {48, 32}} + {{232, -2}, {48, 32}} - + _NS:9 YES @@ -774,7 +758,7 @@ NO - {{105, 97}, {364, 30}} + {{280, 97}, {277, 30}} @@ -808,24 +792,24 @@ textField - + 274 - - + + 266 {{0, 7}, {145, 17}} - + {250, 750} YES - + 67108928 272631808 - + @@ -833,20 +817,20 @@ {{1, 1}, {145, 30}} - + - + 326 value: stringValue - - + + - - + + value: stringValue value stringValue @@ -855,6 +839,80 @@ 327 + + + doGetBind: + + + 274 + + + + 268 + {{232, -2}, {48, 32}} + + + _NS:9 + YES + + 67108864 + 134217728 + ... + + _NS:9 + + -2038284288 + 129 + + + 200 + 25 + + NO + + + + 266 + {{0, 7}, {233, 17}} + + + {250, 750} + YES + + 67108928 + 272631872 + + + + + + + NO + + + {{280, 129}, {277, 30}} + + + + + 564 + + + + value: stringValue + + + + + + value: stringValue + value + stringValue + 2 + + + 578 + @@ -894,29 +952,11 @@ 2 - - 4 0 - - 4 - 1 - - 20 - - 1000 - - 8 - 29 - 3 - - - - 3 - 0 4 1 @@ -925,22 +965,6 @@ 1000 - 6 - 24 - 3 - - - - 6 - 0 - - 6 - 1 - - 20 - - 1000 - 8 29 3 @@ -961,22 +985,6 @@ 29 3 - - - 4 - 0 - - 4 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - 5 @@ -1025,6 +1033,22 @@ 29 3 + + + 4 + 0 + + 4 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + 5 @@ -1057,6 +1081,7 @@ 29 3 + @@ -1093,7 +1118,7 @@ - + @@ -1107,19 +1132,6 @@ - - 116 - - - - - - - - 117 - - - 148 @@ -1159,23 +1171,6 @@ - - 154 - - - - - - - - - - - - 155 - - - 156 @@ -1251,73 +1246,73 @@ - 169 - + 320 + - - - - 5 - 0 - - 5 - 1 - - 3 - - 1000 - - 8 - 29 - 3 - - - + + 10 0 - + 10 1 0.0 1000 - + 5 22 2 - - + + + 5 + 0 + + 5 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + 6 0 - + 6 1 3 1000 - + 8 29 3 + - + - 170 - + 324 + - + - + - 171 - - + 325 + + 179 @@ -1325,73 +1320,210 @@ - 224 - + 353 + + + + + 276 + + + + + 272 + + + + + 271 + + + + + 267 + + + + + 354 + + + + + 273 + + + + + 268 + + + + + 317 + + + + + 281 + + + + + 280 + + + + + 323 + + + + + 322 + + + + + 321 + + + + + 154 + - - - + + + + + + + + + + + 328 + + + + + 5 + 0 + + 6 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + 6 0 - + 6 1 3 1000 - + 8 29 3 - - + + 10 0 - + 10 1 0.0 1000 - + 5 22 2 - - + + 5 0 - + 5 1 3 1000 - + 8 29 3 + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + - 225 - + 335 + - + + + + 7 + 0 + + 0 + 1 + + 36 + + 1000 + + 3 + 9 + 1 + - + - 226 - - + 345 + + + + + 336 + + 242 @@ -1458,120 +1590,30 @@ - 250 - - - - - 267 - - - - - 268 - - - - - 269 - - - - - 270 - - - - - 271 - - - - - 272 - - - - - 273 - - - - - 274 - - - - - 275 - - - - - 276 - - - - - 280 - - - - - 281 - - - - - 285 - - - - - 287 - - - - - 288 - - - - - 289 - - + 291 + + 290 - - 291 - - - 292 - 293 - - - - - 294 - - + 250 + + 295 - + 5 0 @@ -1587,7 +1629,7 @@ 24 3 - + 6 0 @@ -1603,6 +1645,22 @@ 29 3 + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 5 + 22 + 2 + 10 @@ -1619,22 +1677,6 @@ 24 2 - - - 10 - 0 - - 10 - 1 - - 0.0 - - 1000 - - 5 - 22 - 2 - 5 @@ -1651,8 +1693,8 @@ 29 3 - + @@ -1669,11 +1711,6 @@ - - 300 - - - 303 @@ -1698,25 +1735,188 @@ - - 304 - - - - - 308 - - - 309 - 310 - - + 304 + + + + + 169 + + + + + + 5 + 0 + + 5 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 5 + 22 + 2 + + + + 6 + 0 + + 6 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + + + + 170 + + + + + + + + 289 + + + + + 288 + + + + + 287 + + + + + 171 + + + + + 224 + + + + + + 6 + 0 + + 6 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 5 + 22 + 2 + + + + 5 + 0 + + 5 + 1 + + 3 + + 1000 + + 8 + 29 + 3 + + + + + + 225 + + + + + + + + 294 + + + + + 293 + + + + + 285 + + + + + 226 + + + + + 155 + + 311 @@ -1724,98 +1924,62 @@ - 316 - + 300 + - 317 - - + 476 + + - 320 - + 547 + + + + + 548 + + + + + 561 + + + + + 565 + - - - 10 - 0 - - 10 - 1 - - 0.0 - - 1000 - - 5 - 22 - 2 - - - - 5 - 0 - - 5 - 1 - - 3 - - 1000 - - 8 - 29 - 3 - - - - 6 - 0 - - 6 - 1 - - 3 - - 1000 - - 8 - 29 - 3 - - + - + - 321 - - + 566 + + - 322 - - + 574 + + - 323 - - + 575 + + - 324 - - - - - + 576 + + - 325 - - + 572 + + @@ -1826,9 +1990,6 @@ com.apple.InterfaceBuilder.CocoaPlugin {{357, 418}, {480, 270}} - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1847,6 +2008,7 @@ + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1873,16 +2035,14 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - + + - - - com.apple.InterfaceBuilder.CocoaPlugin @@ -1912,13 +2072,9 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1932,12 +2088,12 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin RASettingCell - + - - - + + + com.apple.InterfaceBuilder.CocoaPlugin RAPathSetting @@ -1951,17 +2107,14 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin RASettingCell - + com.apple.InterfaceBuilder.CocoaPlugin RALabelSetting @@ -1971,6 +2124,27 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + RASettingCell + + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + RABindSetting + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1980,16 +2154,26 @@ com.apple.InterfaceBuilder.CocoaPlugin - + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - 327 + 581 @@ -2004,20 +2188,6 @@ RASettingCell NSTableCellView - - id - id - - - - doBrowse: - id - - - valueChanged: - id - - numericValue NSNumber @@ -2037,23 +2207,16 @@ RASettingsDelegate NSObject - - close: - id - - - close: - - close: - id - - + NSWindow NSOutlineView NSTableView - NSWindow + + _inputWindow + NSWindow + _outline NSOutlineView @@ -2062,10 +2225,6 @@ _table NSTableView - - _window - NSWindow - IBProjectSource diff --git a/apple/OSX/hid_pad.c b/apple/OSX/hid_pad.c index 33bb819b9e..59904f8996 100644 --- a/apple/OSX/hid_pad.c +++ b/apple/OSX/hid_pad.c @@ -94,7 +94,7 @@ static void hid_device_attached(void* inContext, IOReturn inResult, void* inSend } IOHIDDeviceOpen(inDevice, kIOHIDOptionsTypeNone); - IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); IOHIDDeviceRegisterInputValueCallback(inDevice, hid_input_callback, context); } @@ -139,7 +139,7 @@ void osx_pad_init() IOHIDManagerRegisterDeviceMatchingCallback(g_hid_manager, hid_device_attached, 0); IOHIDManagerRegisterDeviceRemovalCallback(g_hid_manager, hid_device_removed, 0); - IOHIDManagerScheduleWithRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + IOHIDManagerScheduleWithRunLoop(g_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes); IOHIDManagerOpen(g_hid_manager, kIOHIDOptionsTypeNone); } @@ -150,7 +150,7 @@ void osx_pad_quit() if (g_hid_manager) { IOHIDManagerClose(g_hid_manager, kIOHIDOptionsTypeNone); - IOHIDManagerUnscheduleFromRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + IOHIDManagerUnscheduleFromRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); CFRelease(g_hid_manager); } diff --git a/apple/OSX/platform.m b/apple/OSX/platform.m index e263afbf4a..41f1c6e516 100644 --- a/apple/OSX/platform.m +++ b/apple/OSX/platform.m @@ -251,7 +251,8 @@ - (IBAction)showPreferences:(id)sender { - [[[NSWindowController alloc] initWithWindowNibName:@"Settings"] window]; + NSWindowController* wc = [[NSWindowController alloc] initWithWindowNibName:@"Settings"]; + [NSApp runModalForWindow:wc.window]; } - (IBAction)basicEvent:(id)sender diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 3875346cbf..5d248a2b26 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -16,17 +16,65 @@ #import #import "../RetroArch/RetroArch_Apple.h" #include "../RetroArch/setting_data.h" +#include "../RetroArch/apple_input.h" + +#include "driver.h" +#include "input/input_common.h" struct settings fake_settings; struct global fake_extern; static const void* associated_name_tag = (void*)&associated_name_tag; +#define BINDFOR(s) (*(struct retro_keybind*)(&s)->value) + +static const char* key_name_for_id(uint32_t hidkey) +{ + for (int i = 0; apple_key_name_map[i].hid_id; i ++) + if (apple_key_name_map[i].hid_id == hidkey) + return apple_key_name_map[i].keyname; + + return "nul"; +} + +static uint32_t key_id_for_name(const char* name) +{ + for (int i = 0; apple_key_name_map[i].hid_id; i ++) + if (strcmp(name, apple_key_name_map[i].keyname) == 0) + return apple_key_name_map[i].hid_id; + + return 0; +} + +#define key_name_for_rk(X) key_name_for_id(input_translate_rk_to_keysym(X)) +#define key_rk_for_name(X) input_translate_keysym_to_rk(key_id_for_name(X)) + +@interface RAInputBinder : NSWindow +@end + +@implementation RAInputBinder + +- (IBAction)goAway:(id)sender +{ + [NSApp endSheet:self]; + [self orderOut:nil]; +} + +// Stop the annoying sound when pressing a key +- (void)keyDown:(NSEvent*)theEvent +{ +} + +@end + @interface RASettingCell : NSTableCellView +@property (nonatomic) const rarch_setting_t* setting; + @property (nonatomic) NSString* stringValue; @property (nonatomic) IBOutlet NSNumber* numericValue; @property (nonatomic) bool booleanValue; -@property (nonatomic) const rarch_setting_t* setting; + +@property (nonatomic) NSTimer* bindTimer; @end @implementation RASettingCell @@ -44,6 +92,7 @@ static const void* associated_name_tag = (void*)&associated_name_tag; case ST_STRING: self.stringValue = @((const char*)aSetting->value); break; case ST_PATH: self.stringValue = @((const char*)aSetting->value); break; case ST_BOOL: self.booleanValue = *(bool*)aSetting->value; break; + case ST_BIND: [self updateInputString]; break; } } @@ -61,9 +110,9 @@ static const void* associated_name_tag = (void*)&associated_name_tag; _numericValue = numericValue; if (_setting && _setting->type == ST_INT) - *(int*)_setting->value = [_numericValue intValue]; + *(int*)_setting->value = _numericValue.intValue; else if (_setting && _setting->type == ST_FLOAT) - *(float*)_setting->value = [_numericValue floatValue]; + *(float*)_setting->value = _numericValue.floatValue; } - (void)setBooleanValue:(bool)booleanValue @@ -82,6 +131,63 @@ static const void* associated_name_tag = (void*)&associated_name_tag; strlcpy(_setting->value, _stringValue.UTF8String, _setting->size); } +// Input Binding +- (void)updateInputString +{ + self.stringValue = [NSString stringWithFormat:@"[KB:%s] [JS:%lld] [AX:nul]", key_name_for_rk(BINDFOR(*_setting).key), + BINDFOR(*_setting).joykey]; +} + +- (void)dismissBinder +{ + [self.bindTimer invalidate]; + self.bindTimer = nil; + + [self updateInputString]; + + [(id)self.window.attachedSheet goAway:nil]; +} + +- (void)checkBind:(NSTimer*)send +{ + // Keyboard + for (int i = 0; apple_key_name_map[i].hid_id; i++) + { + if (g_current_input_data.keys[apple_key_name_map[i].hid_id]) + { + BINDFOR(*_setting).key = input_translate_keysym_to_rk(apple_key_name_map[i].hid_id); + [self dismissBinder]; + return; + } + } + + // Joystick + if (g_current_input_data.pad_buttons[0]) + { + for (int i = 0; i != 32; i ++) + { + if (g_current_input_data.pad_buttons[0] & (1 << i)) + { + BINDFOR(*_setting).joykey = i; + [self dismissBinder]; + return; + } + } + } +} + +- (IBAction)doGetBind:(id)sender +{ + static NSWindowController* controller; + if (!controller) + controller = [[NSWindowController alloc] initWithWindowNibName:@"InputBinder"]; + + self.bindTimer = [NSTimer timerWithTimeInterval:.1f target:self selector:@selector(checkBind:) userInfo:nil repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:self.bindTimer forMode:NSModalPanelRunLoopMode]; + + [NSApp beginSheet:controller.window modalForWindow:self.window modalDelegate:nil didEndSelector:nil contextInfo:nil]; +} + @end @protocol RASettingView @@ -89,12 +195,13 @@ static const void* associated_name_tag = (void*)&associated_name_tag; @end @interface RASettingsDelegate : NSObject + NSOutlineViewDataSource, NSOutlineViewDelegate, + NSWindowDelegate> @end @implementation RASettingsDelegate { - NSWindow IBOutlet* _window; + NSWindow IBOutlet* _inputWindow; NSTableView IBOutlet* _table; NSOutlineView IBOutlet* _outline; @@ -152,9 +259,6 @@ static const void* associated_name_tag = (void*)&associated_name_tag; } [self load]; - - [NSApplication.sharedApplication beginSheet:_window modalForWindow:RetroArch_OSX.get->window modalDelegate:nil didEndSelector:nil contextInfo:nil]; - [NSApplication.sharedApplication runModalForWindow:_window]; } - (void)load @@ -169,6 +273,12 @@ static const void* associated_name_tag = (void*)&associated_name_tag; case ST_FLOAT: config_set_float (conf, setting_data[i].name, *(float*)setting_data[i].value); break; case ST_PATH: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break; case ST_STRING: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break; + + case ST_BIND: input_config_parse_key(conf, "input_player1", input_config_bind_map[0].base, setting_data[i].value); + input_config_parse_joy_button(conf, "input_player1", input_config_bind_map[0].base, setting_data[i].value); + input_config_parse_joy_axis(conf, "input_player1", input_config_bind_map[0].base, setting_data[i].value); + break; + case ST_HEX: break; default: break; } @@ -176,7 +286,7 @@ static const void* associated_name_tag = (void*)&associated_name_tag; config_file_free(conf); } -- (IBAction)close:(id)sender +- (void)windowWillClose:(NSNotification *)notification { config_file_t* conf = config_file_new(0); for (int i = 0; setting_data[i].type; i ++) @@ -188,6 +298,13 @@ static const void* associated_name_tag = (void*)&associated_name_tag; case ST_FLOAT: config_set_float (conf, setting_data[i].name, *(float*)setting_data[i].value); break; case ST_PATH: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break; case ST_STRING: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break; + + case ST_BIND: + { + config_set_string(conf, setting_data[i].name, key_name_for_rk(BINDFOR(setting_data[i]).key)); + break; + } + case ST_HEX: break; default: break; } @@ -197,32 +314,7 @@ static const void* associated_name_tag = (void*)&associated_name_tag; apple_refresh_config(); - [NSApplication.sharedApplication stopModal]; - [NSApplication.sharedApplication endSheet:_window returnCode:0]; - [_window orderOut:nil]; -} - -- (void)readConfigFile:(const char*)path -{ - config_file_t* conf = config_file_new(path); - if (conf) - { - for (int i = 0; setting_data[i].type; i ++) - { - switch (setting_data[i].type) - { - case ST_BOOL: config_get_bool (conf, setting_data[i].name, (bool*)setting_data[i].value); break; - case ST_INT: config_get_int (conf, setting_data[i].name, (int*)setting_data[i].value); break; - case ST_FLOAT: config_get_float(conf, setting_data[i].name, (float*)setting_data[i].value); break; - case ST_PATH: config_get_array(conf, setting_data[i].name, (char*)setting_data[i].value, setting_data[i].size); break; - case ST_STRING: config_get_array(conf, setting_data[i].name, (char*)setting_data[i].value, setting_data[i].size); break; - case ST_HEX: break; - default: break; - } - } - - config_file_free(conf); - } + [NSApp stopModal]; } #pragma mark View Builders @@ -295,6 +387,7 @@ static const void* associated_name_tag = (void*)&associated_name_tag; case ST_FLOAT: s = [outlineView makeViewWithIdentifier:@"RANumericSetting" owner:nil]; break; case ST_PATH: s = [outlineView makeViewWithIdentifier:@"RAPathSetting" owner:nil]; break; case ST_STRING: s = [outlineView makeViewWithIdentifier:@"RAStringSetting" owner:nil]; break; + case ST_BIND: s = [outlineView makeViewWithIdentifier:@"RABindSetting" owner:nil]; break; } s.setting = setting; return s; diff --git a/apple/RetroArch/setting_data.h b/apple/RetroArch/setting_data.h index 409c22e24b..a1faaddd44 100644 --- a/apple/RetroArch/setting_data.h +++ b/apple/RetroArch/setting_data.h @@ -18,8 +18,8 @@ #include "general.h" -enum setting_type { ST_NONE, ST_BOOL, ST_INT, ST_FLOAT, ST_PATH, ST_STRING, ST_HEX, ST_GROUP, ST_SUB_GROUP, - ST_END_GROUP, ST_END_SUB_GROUP }; +enum setting_type { ST_NONE, ST_BOOL, ST_INT, ST_FLOAT, ST_PATH, ST_STRING, ST_HEX, ST_BIND, + ST_GROUP, ST_SUB_GROUP, ST_END_GROUP, ST_END_SUB_GROUP }; typedef struct { @@ -52,14 +52,13 @@ extern struct global fake_extern; #define END_GROUP() { ST_END_GROUP }, #define START_SUB_GROUP(NAME) { ST_SUB_GROUP, NAME }, #define END_SUB_GROUP() { ST_END_SUB_GROUP }, -#define START_GROUP(NAME) { ST_GROUP, NAME, 0, 0, 0, 0, 0, 0, 0.0, 0.0, false }, -#define END_GROUP() { ST_END_GROUP, 0, 0, 0, 0, 0, 0, 0, 0.0, 0.0, false }, #define CONFIG_BOOL(TARGET, NAME, SHORT) { ST_BOOL, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, #define CONFIG_INT(TARGET, NAME, SHORT) { ST_INT, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, #define CONFIG_FLOAT(TARGET, NAME, SHORT) { ST_FLOAT, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, #define CONFIG_PATH(TARGET, NAME, SHORT) { ST_PATH, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, #define CONFIG_STRING(TARGET, NAME, SHORT) { ST_STRING, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, #define CONFIG_HEX(TARGET, NAME, SHORT) { ST_HEX, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, +#define CONFIG_BIND(TARGET, NAME, SHORT) { ST_BIND, NAME, &TARGET, sizeof(TARGET), SHORT }, const rarch_setting_t setting_data[] = { @@ -100,7 +99,6 @@ const rarch_setting_t setting_data[] = END_GROUP() - /*************/ /* EMULATION */ /*************/ @@ -183,6 +181,25 @@ const rarch_setting_t setting_data[] = CONFIG_INT(g_settings.input.icade_profile[3], "input_autodetect_icade_profile_pad4", "iCade 4") #endif END_SUB_GROUP() + + START_SUB_GROUP("Player 1") + CONFIG_BIND(g_settings.input.binds[0][ 0], "input_player1_b", "B button (down)") + CONFIG_BIND(g_settings.input.binds[0][ 1], "input_player1_y", "Y button (left)") + CONFIG_BIND(g_settings.input.binds[0][ 2], "input_player1_select", "Select button") + CONFIG_BIND(g_settings.input.binds[0][ 3], "input_player1_start", "Start button") + CONFIG_BIND(g_settings.input.binds[0][ 4], "input_player1_up", "Up D-pad") + CONFIG_BIND(g_settings.input.binds[0][ 5], "input_player1_down", "Down D-pad") + CONFIG_BIND(g_settings.input.binds[0][ 6], "input_player1_left", "Left D-pad") + CONFIG_BIND(g_settings.input.binds[0][ 7], "input_player1_right", "Right D-pad") + CONFIG_BIND(g_settings.input.binds[0][ 8], "input_player1_a", "A button (right)") + CONFIG_BIND(g_settings.input.binds[0][ 9], "input_player1_x", "X button (top)") + CONFIG_BIND(g_settings.input.binds[0][10], "input_player1_l", "L button (left shoulder)") + CONFIG_BIND(g_settings.input.binds[0][11], "input_player1_r", "R button (right shoulder)") + CONFIG_BIND(g_settings.input.binds[0][12], "input_player1_l2", "L2 button (left shoulder #2)") + CONFIG_BIND(g_settings.input.binds[0][13], "input_player1_r2", "R2 button (right shoulder #2)") + CONFIG_BIND(g_settings.input.binds[0][14], "input_player1_l3", "L3 button (left analog button)") + CONFIG_BIND(g_settings.input.binds[0][15], "input_player1_r3", "R3 button (right analog button)") + END_SUB_GROUP() END_GROUP() /*********/ @@ -275,7 +292,63 @@ const rarch_setting_t setting_data[] = }; // HACK -#undef g_settings fake_settings -#undef g_extern fake_extern +#undef g_settings +#undef g_extern + +// Keyboard +#include "keycode.h" +static const struct +{ + const char* const keyname; + const uint32_t hid_id; +} apple_key_name_map[] = { + { "left", KEY_Left }, { "right", KEY_Right }, + { "up", KEY_Up }, { "down", KEY_Down }, + { "enter", KEY_Enter }, { "kp_enter", KP_Enter }, + { "space", KEY_Space }, { "tab", KEY_Tab }, + { "shift", KEY_LeftShift }, { "rshift", KEY_RightShift }, + { "ctrl", KEY_LeftControl }, { "alt", KEY_LeftAlt }, + { "escape", KEY_Escape }, { "backspace", KEY_DeleteForward }, + { "backquote", KEY_Grave }, { "pause", KEY_Pause }, + + { "f1", KEY_F1 }, { "f2", KEY_F2 }, + { "f3", KEY_F3 }, { "f4", KEY_F4 }, + { "f5", KEY_F5 }, { "f6", KEY_F6 }, + { "f7", KEY_F7 }, { "f8", KEY_F8 }, + { "f9", KEY_F9 }, { "f10", KEY_F10 }, + { "f11", KEY_F11 }, { "f12", KEY_F12 }, + + { "num0", KEY_0 }, { "num1", KEY_1 }, + { "num2", KEY_2 }, { "num3", KEY_3 }, + { "num4", KEY_4 }, { "num5", KEY_5 }, + { "num6", KEY_6 }, { "num7", KEY_7 }, + { "num8", KEY_8 }, { "num9", KEY_9 }, + + { "insert", KEY_Insert }, { "del", KEY_DeleteForward }, + { "home", KEY_Home }, { "end", KEY_End }, + { "pageup", KEY_PageUp }, { "pagedown", KEY_PageDown }, + + { "add", KP_Add }, { "subtract", KP_Subtract }, + { "multiply", KP_Multiply }, { "divide", KP_Divide }, + { "keypad0", KP_0 }, { "keypad1", KP_1 }, + { "keypad2", KP_2 }, { "keypad3", KP_3 }, + { "keypad4", KP_4 }, { "keypad5", KP_5 }, + { "keypad6", KP_6 }, { "keypad7", KP_7 }, + { "keypad8", KP_8 }, { "keypad9", KP_9 }, + + { "period", KEY_Period }, { "capslock", KEY_CapsLock }, + { "numlock", KP_NumLock }, { "print_screen", KEY_PrintScreen }, + { "scroll_lock", KEY_ScrollLock }, + + { "a", KEY_A }, { "b", KEY_B }, { "c", KEY_C }, { "d", KEY_D }, + { "e", KEY_E }, { "f", KEY_F }, { "g", KEY_G }, { "h", KEY_H }, + { "i", KEY_I }, { "j", KEY_J }, { "k", KEY_K }, { "l", KEY_L }, + { "m", KEY_M }, { "n", KEY_N }, { "o", KEY_O }, { "p", KEY_P }, + { "q", KEY_Q }, { "r", KEY_R }, { "s", KEY_S }, { "t", KEY_T }, + { "u", KEY_U }, { "v", KEY_V }, { "w", KEY_W }, { "x", KEY_X }, + { "y", KEY_Y }, { "z", KEY_Z }, + + { "nul", 0x00}, +}; #endif \ No newline at end of file diff --git a/apple/RetroArch_OSX.xcodeproj/project.pbxproj b/apple/RetroArch_OSX.xcodeproj/project.pbxproj index 67e0df9ae7..c67900681c 100644 --- a/apple/RetroArch_OSX.xcodeproj/project.pbxproj +++ b/apple/RetroArch_OSX.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 962EE0E2178B3DF6004224FF /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 962EE0E1178B3DF6004224FF /* IOKit.framework */; }; 96355CE31788E72A0010DBFA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96355CE21788E72A0010DBFA /* Cocoa.framework */; }; 9646869817BBC14E00C5EA69 /* platform.m in Sources */ = {isa = PBXBuildFile; fileRef = 9646869617BBC14E00C5EA69 /* platform.m */; }; + 965A44C817CC114D0086F78F /* InputBinder.xib in Resources */ = {isa = PBXBuildFile; fileRef = 965A44C717CC114D0086F78F /* InputBinder.xib */; }; 967894931788ECDB00D6CA69 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9678948F1788ECDB00D6CA69 /* InfoPlist.strings */; }; 967894941788ECDB00D6CA69 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 967894911788ECDB00D6CA69 /* MainMenu.xib */; }; 967894961788ED1100D6CA69 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 967894951788ED1100D6CA69 /* main.m */; }; @@ -38,6 +39,7 @@ 96355CE71788E72A0010DBFA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 9646869617BBC14E00C5EA69 /* platform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = platform.m; path = OSX/platform.m; sourceTree = SOURCE_ROOT; }; 9646869717BBC14E00C5EA69 /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = platform.h; path = OSX/platform.h; sourceTree = SOURCE_ROOT; }; + 965A44C717CC114D0086F78F /* InputBinder.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = InputBinder.xib; path = OSX/InputBinder.xib; sourceTree = ""; }; 9678948D1788ECCA00D6CA69 /* RetroArch-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "RetroArch-Info.plist"; path = "OSX/RetroArch-Info.plist"; sourceTree = SOURCE_ROOT; }; 967894901788ECDB00D6CA69 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = OSX/en.lproj/InfoPlist.strings; sourceTree = SOURCE_ROOT; }; 967894921788ECDB00D6CA69 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = OSX/en.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; }; @@ -144,6 +146,7 @@ 967894911788ECDB00D6CA69 /* MainMenu.xib */, C15874EE178F2094001171D4 /* RetroArch.icns */, 9620F6641790004F001B3B81 /* Settings.xib */, + 965A44C717CC114D0086F78F /* InputBinder.xib */, ); name = Assets; sourceTree = ""; @@ -203,6 +206,7 @@ 967894E9178A2EB400D6CA69 /* modules in Resources */, C15874EF178F2094001171D4 /* RetroArch.icns in Resources */, 9620F6651790004F001B3B81 /* Settings.xib in Resources */, + 965A44C817CC114D0086F78F /* InputBinder.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 253bb88bfce016c981530eb352f27898e0be26c5 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 26 Aug 2013 23:56:26 -0400 Subject: [PATCH 126/202] (OSX) More settings menu work (now supports all input bindings for player 1) --- apple/OSX/settings.m | 86 ++++++++++++++++++++++++++++------ apple/RetroArch/setting_data.h | 60 ++++++++++++++---------- 2 files changed, 105 insertions(+), 41 deletions(-) diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 5d248a2b26..1bf695befc 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -49,6 +49,40 @@ static uint32_t key_id_for_name(const char* name) #define key_name_for_rk(X) key_name_for_id(input_translate_rk_to_keysym(X)) #define key_rk_for_name(X) input_translate_keysym_to_rk(key_id_for_name(X)) +static const char* get_input_config_key(const rarch_setting_t* setting, const char* type) +{ + static char buffer[32]; + snprintf(buffer, 32, "input_player%d_%s%c%s", setting->input_player, setting->name, type ? '_' : '\0', type); + return buffer; +} + +static const char* get_button_name(const rarch_setting_t* setting) +{ + static char buffer[32]; + + if (BINDFOR(*setting).joykey == NO_BTN) + return "nul"; + + snprintf(buffer, 32, "%lld", BINDFOR(*setting).joykey); + return buffer; +} + +static const char* get_axis_name(const rarch_setting_t* setting) +{ + static char buffer[32]; + + uint32_t joyaxis = BINDFOR(*setting).joyaxis; + + if (AXIS_NEG_GET(joyaxis) != AXIS_DIR_NONE) + snprintf(buffer, 8, "-%d", AXIS_NEG_GET(joyaxis)); + else if (AXIS_POS_GET(joyaxis) != AXIS_DIR_NONE) + snprintf(buffer, 8, "+%d", AXIS_POS_GET(joyaxis)); + else + return "nul"; + + return buffer; +} + @interface RAInputBinder : NSWindow @end @@ -134,8 +168,9 @@ static uint32_t key_id_for_name(const char* name) // Input Binding - (void)updateInputString { - self.stringValue = [NSString stringWithFormat:@"[KB:%s] [JS:%lld] [AX:nul]", key_name_for_rk(BINDFOR(*_setting).key), - BINDFOR(*_setting).joykey]; + self.stringValue = [NSString stringWithFormat:@"[KB:%s] [JS:%s] [AX:%s]", key_name_for_rk(BINDFOR(*_setting).key), + get_button_name(_setting), + get_axis_name(_setting)]; } - (void)dismissBinder @@ -174,6 +209,19 @@ static uint32_t key_id_for_name(const char* name) } } } + + // Pad Axis + for (int i = 0; i < 4; i++) + { + int16_t value = g_current_input_data.pad_axis[0][i]; + + if (abs(value) > 0x4000) + { + BINDFOR(*_setting).joyaxis = (value > 0x1000) ? AXIS_POS(i) : AXIS_NEG(i); + [self dismissBinder]; + break; + } + } } - (IBAction)doGetBind:(id)sender @@ -214,10 +262,10 @@ static uint32_t key_id_for_name(const char* name) NSMutableArray* thisGroup = nil; NSMutableArray* thisSubGroup = nil; _settings = [NSMutableArray array]; - + memcpy(&fake_settings, &g_settings, sizeof(struct settings)); memcpy(&fake_extern, &g_extern, sizeof(struct global)); - + for (int i = 0; setting_data[i].type; i ++) { switch (setting_data[i].type) @@ -264,20 +312,24 @@ static uint32_t key_id_for_name(const char* name) - (void)load { config_file_t* conf = config_file_new([RetroArch_OSX get].configPath.UTF8String); + for (int i = 0; setting_data[i].type; i ++) { switch (setting_data[i].type) { - case ST_BOOL: config_set_bool (conf, setting_data[i].name, * (bool*)setting_data[i].value); break; - case ST_INT: config_set_int (conf, setting_data[i].name, * (int*)setting_data[i].value); break; - case ST_FLOAT: config_set_float (conf, setting_data[i].name, *(float*)setting_data[i].value); break; - case ST_PATH: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break; - case ST_STRING: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break; + case ST_BOOL: config_get_bool (conf, setting_data[i].name, (bool*)setting_data[i].value); break; + case ST_INT: config_get_int (conf, setting_data[i].name, (int*)setting_data[i].value); break; + case ST_FLOAT: config_get_float (conf, setting_data[i].name, (float*)setting_data[i].value); break; + case ST_PATH: config_get_array (conf, setting_data[i].name, (char*)setting_data[i].value, setting_data[i].size); break; + case ST_STRING: config_get_array (conf, setting_data[i].name, (char*)setting_data[i].value, setting_data[i].size); break; - case ST_BIND: input_config_parse_key(conf, "input_player1", input_config_bind_map[0].base, setting_data[i].value); - input_config_parse_joy_button(conf, "input_player1", input_config_bind_map[0].base, setting_data[i].value); - input_config_parse_joy_axis(conf, "input_player1", input_config_bind_map[0].base, setting_data[i].value); - break; + case ST_BIND: + { + input_config_parse_key (conf, "input_player1", setting_data[i].name, setting_data[i].value); + input_config_parse_joy_button(conf, "input_player1", setting_data[i].name, setting_data[i].value); + input_config_parse_joy_axis (conf, "input_player1", setting_data[i].name, setting_data[i].value); + break; + } case ST_HEX: break; default: break; @@ -288,7 +340,9 @@ static uint32_t key_id_for_name(const char* name) - (void)windowWillClose:(NSNotification *)notification { - config_file_t* conf = config_file_new(0); + config_file_t* conf = config_file_new([RetroArch_OSX get].configPath.UTF8String); + conf = conf ? conf : config_file_new(0); + for (int i = 0; setting_data[i].type; i ++) { switch (setting_data[i].type) @@ -301,7 +355,9 @@ static uint32_t key_id_for_name(const char* name) case ST_BIND: { - config_set_string(conf, setting_data[i].name, key_name_for_rk(BINDFOR(setting_data[i]).key)); + config_set_string(conf, get_input_config_key(&setting_data[i], 0 ), key_name_for_rk(BINDFOR(setting_data[i]).key)); + config_set_string(conf, get_input_config_key(&setting_data[i], "btn" ), get_button_name(&setting_data[i])); + config_set_string(conf, get_input_config_key(&setting_data[i], "axis"), get_axis_name(&setting_data[i])); break; } diff --git a/apple/RetroArch/setting_data.h b/apple/RetroArch/setting_data.h index a1faaddd44..3fcac23459 100644 --- a/apple/RetroArch/setting_data.h +++ b/apple/RetroArch/setting_data.h @@ -31,11 +31,9 @@ typedef struct uint32_t size; const char* short_description; - const char* long_description; - - const char** values; uint32_t input_player; + double min; double max; bool allow_blank; @@ -52,13 +50,14 @@ extern struct global fake_extern; #define END_GROUP() { ST_END_GROUP }, #define START_SUB_GROUP(NAME) { ST_SUB_GROUP, NAME }, #define END_SUB_GROUP() { ST_END_SUB_GROUP }, -#define CONFIG_BOOL(TARGET, NAME, SHORT) { ST_BOOL, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_INT(TARGET, NAME, SHORT) { ST_INT, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_FLOAT(TARGET, NAME, SHORT) { ST_FLOAT, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_PATH(TARGET, NAME, SHORT) { ST_PATH, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_STRING(TARGET, NAME, SHORT) { ST_STRING, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_HEX(TARGET, NAME, SHORT) { ST_HEX, NAME, &TARGET, sizeof(TARGET), SHORT, 0, 0, 0, 0.0, 0.0, false }, -#define CONFIG_BIND(TARGET, NAME, SHORT) { ST_BIND, NAME, &TARGET, sizeof(TARGET), SHORT }, +#define CONFIG_BOOL(TARGET, NAME, SHORT) { ST_BOOL, NAME, &TARGET, sizeof(TARGET), SHORT }, +#define CONFIG_INT(TARGET, NAME, SHORT) { ST_INT, NAME, &TARGET, sizeof(TARGET), SHORT }, +#define CONFIG_FLOAT(TARGET, NAME, SHORT) { ST_FLOAT, NAME, &TARGET, sizeof(TARGET), SHORT }, +#define CONFIG_PATH(TARGET, NAME, SHORT) { ST_PATH, NAME, &TARGET, sizeof(TARGET), SHORT }, +#define CONFIG_STRING(TARGET, NAME, SHORT) { ST_STRING, NAME, &TARGET, sizeof(TARGET), SHORT }, +#define CONFIG_HEX(TARGET, NAME, SHORT) { ST_HEX, NAME, &TARGET, sizeof(TARGET), SHORT }, + +#define CONFIG_BIND(TARGET, PLAYER, NAME, SHORT) { ST_BIND, NAME, &TARGET, sizeof(TARGET), SHORT, PLAYER }, const rarch_setting_t setting_data[] = { @@ -183,22 +182,31 @@ const rarch_setting_t setting_data[] = END_SUB_GROUP() START_SUB_GROUP("Player 1") - CONFIG_BIND(g_settings.input.binds[0][ 0], "input_player1_b", "B button (down)") - CONFIG_BIND(g_settings.input.binds[0][ 1], "input_player1_y", "Y button (left)") - CONFIG_BIND(g_settings.input.binds[0][ 2], "input_player1_select", "Select button") - CONFIG_BIND(g_settings.input.binds[0][ 3], "input_player1_start", "Start button") - CONFIG_BIND(g_settings.input.binds[0][ 4], "input_player1_up", "Up D-pad") - CONFIG_BIND(g_settings.input.binds[0][ 5], "input_player1_down", "Down D-pad") - CONFIG_BIND(g_settings.input.binds[0][ 6], "input_player1_left", "Left D-pad") - CONFIG_BIND(g_settings.input.binds[0][ 7], "input_player1_right", "Right D-pad") - CONFIG_BIND(g_settings.input.binds[0][ 8], "input_player1_a", "A button (right)") - CONFIG_BIND(g_settings.input.binds[0][ 9], "input_player1_x", "X button (top)") - CONFIG_BIND(g_settings.input.binds[0][10], "input_player1_l", "L button (left shoulder)") - CONFIG_BIND(g_settings.input.binds[0][11], "input_player1_r", "R button (right shoulder)") - CONFIG_BIND(g_settings.input.binds[0][12], "input_player1_l2", "L2 button (left shoulder #2)") - CONFIG_BIND(g_settings.input.binds[0][13], "input_player1_r2", "R2 button (right shoulder #2)") - CONFIG_BIND(g_settings.input.binds[0][14], "input_player1_l3", "L3 button (left analog button)") - CONFIG_BIND(g_settings.input.binds[0][15], "input_player1_r3", "R3 button (right analog button)") + CONFIG_BIND(g_settings.input.binds[0][ 0], 1, "b", "B button (down)") + CONFIG_BIND(g_settings.input.binds[0][ 1], 1, "y", "Y button (left)") + CONFIG_BIND(g_settings.input.binds[0][ 2], 1, "select", "Select button") + CONFIG_BIND(g_settings.input.binds[0][ 3], 1, "start", "Start button") + CONFIG_BIND(g_settings.input.binds[0][ 4], 1, "up", "Up D-pad") + CONFIG_BIND(g_settings.input.binds[0][ 5], 1, "down", "Down D-pad") + CONFIG_BIND(g_settings.input.binds[0][ 6], 1, "left", "Left D-pad") + CONFIG_BIND(g_settings.input.binds[0][ 7], 1, "right", "Right D-pad") + CONFIG_BIND(g_settings.input.binds[0][ 8], 1, "a", "A button (right)") + CONFIG_BIND(g_settings.input.binds[0][ 9], 1, "x", "X button (top)") + CONFIG_BIND(g_settings.input.binds[0][10], 1, "l", "L button (left shoulder)") + CONFIG_BIND(g_settings.input.binds[0][11], 1, "r", "R button (right shoulder)") + CONFIG_BIND(g_settings.input.binds[0][12], 1, "l2", "L2 button (left shoulder #2)") + CONFIG_BIND(g_settings.input.binds[0][13], 1, "r2", "R2 button (right shoulder #2)") + CONFIG_BIND(g_settings.input.binds[0][14], 1, "l3", "L3 button (left analog button)") + CONFIG_BIND(g_settings.input.binds[0][15], 1, "r3", "R3 button (right analog button)") + CONFIG_BIND(g_settings.input.binds[0][16], 1, "turbo", "Turbo enable") + CONFIG_BIND(g_settings.input.binds[0][17], 1, "l_x_plus", "Left analog X+ (right)") + CONFIG_BIND(g_settings.input.binds[0][18], 1, "l_x_minus", "Left analog X- (left)") + CONFIG_BIND(g_settings.input.binds[0][19], 1, "l_y_plus", "Left analog Y+ (down)") + CONFIG_BIND(g_settings.input.binds[0][20], 1, "l_y_minus", "Left analog Y- (up)") + CONFIG_BIND(g_settings.input.binds[0][21], 1, "r_x_plus", "Right analog X+ (right)") + CONFIG_BIND(g_settings.input.binds[0][22], 1, "r_x_minus", "Right analog X- (left)") + CONFIG_BIND(g_settings.input.binds[0][23], 1, "r_y_plus", "Right analog Y+ (down)") + CONFIG_BIND(g_settings.input.binds[0][24], 1, "r_y_minus", "Right analog Y- (up)") END_SUB_GROUP() END_GROUP() From 905e7679830ff042040cb2342ee89956fc3e80fb Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Tue, 27 Aug 2013 12:14:56 +0100 Subject: [PATCH 127/202] Add autoconfig support to xinput and dinput --- input/dinput.c | 53 +++++++++++++++++++++++++++++------- input/winxinput_joypad.c | 58 ++++++++++++++++++++++++---------------- 2 files changed, 79 insertions(+), 32 deletions(-) diff --git a/input/dinput.c b/input/dinput.c index 972772da75..487a179e5a 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -345,6 +345,14 @@ const input_driver_t input_dinput = { dinput_grab_mouse, }; +// Keep track of which pad indexes are 360 controllers +// not static, will be read in winxinput_joypad.c +// -1 = not xbox pad, otherwise 0..3 +int g_xbox_pad_indexes[MAX_PLAYERS]; + +// TODO: Move the name string to struct dinput_joypad +static char *g_pad_names[MAX_PLAYERS]; + static void dinput_joypad_destroy(void) { for (unsigned i = 0; i < MAX_PLAYERS; i++) @@ -358,6 +366,12 @@ static void dinput_joypad_destroy(void) g_joypad_cnt = 0; memset(g_pads, 0, sizeof(g_pads)); + + for (unsigned i = 0; i < MAX_PLAYERS; i++) + { + free (g_pad_names[i]); + g_pad_names[i] = NULL; + } // Can be blocked by global Dinput context. dinput_destroy_context(); @@ -380,7 +394,9 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p) return DIENUM_CONTINUE; } -static const char* const XBOX_PAD_NAMES[] = +// Is there a better way of detecting dual XInput/DInput pads? This is going to get +// outdated, for example when the Xbox One controller becomes available. +static const char* const XINPUT_PAD_NAMES[] = { "Controller (Gamepad for Xbox 360)", "Controller (XBOX 360 For Windows)", @@ -397,7 +413,7 @@ static bool name_is_360_pad(const char* name) { for (unsigned i = 0; ; ++i) { - const char* t = XBOX_PAD_NAMES[i]; + const char* t = XINPUT_PAD_NAMES[i]; if (t == NULL) return false; else if (lstrcmpi(name, t) == 0) @@ -405,10 +421,8 @@ static bool name_is_360_pad(const char* name) } } -// Keep track of which pad indexes are 360 controllers -// not static, will be read in winxinput_joypad.c -// -1 = not xbox pad, otherwise 0..3 -int g_xbox_pad_indexes[MAX_PLAYERS]; +// Forward declaration +static const char *dinput_joypad_name(unsigned pad); static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) { @@ -425,10 +439,15 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) #endif return DIENUM_CONTINUE; + size_t name_len = strlen(inst->tszProductName) + 1; + g_pad_names[g_joypad_cnt] = malloc(name_len); + strncpy(g_pad_names[g_joypad_cnt], inst->tszProductName, name_len); + #ifdef HAVE_WINXINPUT int last_xbox_pad_index = 0; + bool is_360_pad = name_is_360_pad(inst->tszProductName); - if (name_is_360_pad(inst->tszProductName)) + if (is_360_pad) { if (last_xbox_pad_index < 4) g_xbox_pad_indexes[g_joypad_cnt] = last_xbox_pad_index; @@ -442,6 +461,17 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) IDirectInputDevice8_EnumObjects(*pad, enum_axes_cb, *pad, DIDFT_ABSAXIS); + +#ifdef HAVE_WINXINPUT + if (!is_360_pad) +#else + if (1) +#endif + { + + input_config_autoconfigure_joypad(g_joypad_cnt, dinput_joypad_name(g_joypad_cnt), dinput_joypad.ident); + } + g_joypad_cnt++; @@ -455,6 +485,8 @@ static bool dinput_joypad_init(void) for (unsigned i = 0; i < MAX_PLAYERS; ++i) g_xbox_pad_indexes[i] = -1; + + memset(&g_pad_names, 0, sizeof(g_pad_names)); RARCH_LOG("Enumerating DInput joypads ...\n"); IDirectInput8_EnumDevices(g_ctx, DI8DEVCLASS_GAMECTRL, @@ -593,10 +625,13 @@ static bool dinput_joypad_query_pad(unsigned pad) return pad < MAX_PLAYERS && g_pads[pad].joypad; } + + static const char *dinput_joypad_name(unsigned pad) { - (void)pad; - // FIXME + if ((pad < MAX_PLAYERS) && (g_pad_names[pad])) + return g_pad_names[pad]; + return NULL; } diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index 00ab50c60b..2f0956bb3f 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -108,6 +108,27 @@ static int pad_index_to_xplayer_index(unsigned pad) return g_xbox_pad_indexes[pad]; } +static const char* const XBOX_CONTROLLER_NAMES[4] = +{ + "Xbox 360 Controller (Player 1)", + "Xbox 360 Controller (Player 2)", + "Xbox 360 Controller (Player 3)", + "Xbox 360 Controller (Player 4)" +}; + +const char* winxinput_joypad_name (unsigned pad) +{ + int xplayer = pad_index_to_xplayer_index(pad); + + if (xplayer < 0) + return dinput_joypad.name(pad); + else + // TODO: Different name if disconnected? + return XBOX_CONTROLLER_NAMES[xplayer]; +} + + + static bool winxinput_joypad_init(void) { g_winxinput_dll = NULL; @@ -120,6 +141,9 @@ static bool winxinput_joypad_init(void) // No need to check for existance as we will be checking LoadLibrary's // success anyway. + + // Note: Windows 8 ships with 1.4 but there doesn't + // seem to be any compelling reason to use it. const char* DLL_NAME = "xinput1_3.dll"; g_winxinput_dll = LoadLibrary(DLL_NAME); // Using dylib_* complicates building joyconfig. if (!g_winxinput_dll) @@ -136,7 +160,6 @@ static bool winxinput_joypad_init(void) RARCH_ERR("Failed to load xinput1_3.dll, ensure DirectX and controller drivers are up to date.\n"); return false; // DLL does not exist or is invalid } - } // If we get here then an xinput DLL is correctly loaded. @@ -146,7 +169,7 @@ static bool winxinput_joypad_init(void) if (!g_XInputGetStateEx) { - // no ordinal 100. (old version of x360ce perhaps?) Load the ordinary XInputGetState, + // no ordinal 100. (Old version of x360ce perhaps?) Load the ordinary XInputGetState, // at the cost of losing guide button support. g_winxinput_guide_button_supported = false; g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState"); @@ -158,7 +181,7 @@ static bool winxinput_joypad_init(void) RARCH_WARN("XInput: No guide button support.\n"); } - // zero out the states + // Zero out the states for (unsigned i = 0; i < 4; ++i) memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state)); @@ -179,7 +202,15 @@ static bool winxinput_joypad_init(void) // We're going to have to be buddies with dinput if we want to be able // to use XI and non-XI controllers together. - return dinput_joypad.init(); + if (!dinput_joypad.init()) + return false; + + for (unsigned autoconf_pad = 0; autoconf_pad < MAX_PLAYERS; autoconf_pad++) + if (pad_index_to_xplayer_index(autoconf_pad) > -1) + input_config_autoconfigure_joypad(autoconf_pad, winxinput_joypad_name(autoconf_pad), winxinput_joypad.ident); + + return true; + } static bool winxinput_joypad_query_pad(unsigned pad) @@ -320,25 +351,6 @@ static void winxinput_joypad_poll(void) dinput_joypad.poll(); } -static const char* const XBOX_CONTROLLER_NAMES[4] = -{ - "Xbox 360 Controller (Player 1)", - "Xbox 360 Controller (Player 2)", - "Xbox 360 Controller (Player 3)", - "Xbox 360 Controller (Player 4)" -}; - -const char* winxinput_joypad_name (unsigned pad) -{ - int xplayer = pad_index_to_xplayer_index(pad); - - if (xplayer < 0) - return dinput_joypad.name(pad); - else - // TODO: Different name if disconnected? - return XBOX_CONTROLLER_NAMES[xplayer]; -} - const rarch_joypad_driver_t winxinput_joypad = { winxinput_joypad_init, winxinput_joypad_query_pad, From 6bed0cfa659271a80b286ed47db0f1dafb977dc6 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Tue, 27 Aug 2013 14:38:20 +0100 Subject: [PATCH 128/202] More small adjustments to joypad drivers --- input/dinput.c | 12 ++++++++---- input/winxinput_joypad.c | 14 ++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/input/dinput.c b/input/dinput.c index 487a179e5a..f71d690ae0 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -394,8 +394,11 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p) return DIENUM_CONTINUE; } -// Is there a better way of detecting dual XInput/DInput pads? This is going to get -// outdated, for example when the Xbox One controller becomes available. +// TODO: Use a better way of detecting dual XInput/DInput pads. This current method +// will not work correctly for third-party controllers or future MS pads (Xbox One?). +// An example of this is provided in the DX SDK, which advises "Enum each PNP device +// using WMI and check each device ID to see if it contains "IG_"". Unfortunately the +// example code is a horrible unsightly mess. static const char* const XINPUT_PAD_NAMES[] = { "Controller (Gamepad for Xbox 360)", @@ -452,6 +455,8 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) if (last_xbox_pad_index < 4) g_xbox_pad_indexes[g_joypad_cnt] = last_xbox_pad_index; ++last_xbox_pad_index; + + goto enum_iteration_done; } #endif @@ -472,9 +477,8 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) input_config_autoconfigure_joypad(g_joypad_cnt, dinput_joypad_name(g_joypad_cnt), dinput_joypad.ident); } - +enum_iteration_done: g_joypad_cnt++; - return DIENUM_CONTINUE; } diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index 2f0956bb3f..48b8e8dceb 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -108,12 +108,14 @@ static int pad_index_to_xplayer_index(unsigned pad) return g_xbox_pad_indexes[pad]; } +// Generic "XInput" instead of "Xbox 360", because there are +// some other non-xbox third party PC controllers. static const char* const XBOX_CONTROLLER_NAMES[4] = { - "Xbox 360 Controller (Player 1)", - "Xbox 360 Controller (Player 2)", - "Xbox 360 Controller (Player 3)", - "Xbox 360 Controller (Player 4)" + "XInput Controller (Player 1)", + "XInput Controller (Player 2)", + "XInput Controller (Player 3)", + "XInput Controller (Player 4)" }; const char* winxinput_joypad_name (unsigned pad) @@ -169,8 +171,8 @@ static bool winxinput_joypad_init(void) if (!g_XInputGetStateEx) { - // no ordinal 100. (Old version of x360ce perhaps?) Load the ordinary XInputGetState, - // at the cost of losing guide button support. + // no ordinal 100. (Presumably a wrapper.) Load the ordinary + // XInputGetState, at the cost of losing guide button support. g_winxinput_guide_button_supported = false; g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState"); if (!g_XInputGetStateEx) From 6372e755c49597cf630365e604f064e0c748a94c Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 27 Aug 2013 11:37:21 -0400 Subject: [PATCH 129/202] (OSX) Add proper full screen tracking --- apple/RetroArch/RAGameView.m | 25 +++++++++++++++++++++++++ apple/RetroArch/rarch_wrapper.h | 1 + gfx/context/apple_gl_ctx.c | 5 +---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/apple/RetroArch/RAGameView.m b/apple/RetroArch/RAGameView.m index 4b9c592f33..5064083985 100644 --- a/apple/RetroArch/RAGameView.m +++ b/apple/RetroArch/RAGameView.m @@ -312,6 +312,31 @@ void *apple_get_proc_address(const char *symbol_name) #endif } +bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) +{ + __block bool result = true; + +#ifdef OSX + dispatch_sync(dispatch_get_main_queue(), + ^{ + // TODO: Multi-monitor support + // TODO: Sceen mode support + + if (fullscreen) + result = [g_view enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; + else + { + [g_view exitFullScreenModeWithOptions:nil]; + [g_view.window makeFirstResponder:g_view]; + } + }); +#endif + + // TODO: Maybe iOS users should be apple to show/hide the status bar here? + + return result; +} + #ifdef IOS void apple_bind_game_view_fbo(void) { diff --git a/apple/RetroArch/rarch_wrapper.h b/apple/RetroArch/rarch_wrapper.h index b92cf5eb83..3537360da5 100644 --- a/apple/RetroArch/rarch_wrapper.h +++ b/apple/RetroArch/rarch_wrapper.h @@ -26,6 +26,7 @@ void apple_rarch_exited (void* result); // These functions must only be called in gfx/context/ioseagl_ctx.c bool apple_init_game_view(void); void apple_destroy_game_view(void); +bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen); void apple_flip_game_view(void); void apple_set_game_view_sync(unsigned interval); void apple_get_game_view_size(unsigned *width, unsigned *height); diff --git a/gfx/context/apple_gl_ctx.c b/gfx/context/apple_gl_ctx.c index d8db42630f..29d0bfeb35 100644 --- a/gfx/context/apple_gl_ctx.c +++ b/gfx/context/apple_gl_ctx.c @@ -42,10 +42,7 @@ static bool gfx_ctx_set_video_mode( unsigned width, unsigned height, bool fullscreen) { - (void)width; - (void)height; - (void)fullscreen; - return true; + return apple_set_video_mode(width, height, fullscreen); } static void gfx_ctx_update_window_title(void) From 851a56195afb56d141c2251888def1738831b4e2 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 27 Aug 2013 12:07:59 -0400 Subject: [PATCH 130/202] (OSX) Add command line support; only arguments passed after an -- argument are passed to retroarch (eg retroarch -- /path/to/game) --- apple/OSX/platform.m | 19 +++++++++++- apple/RetroArch/RetroArch_Apple.h | 1 + apple/RetroArch/main.m | 49 +++++++++++++++++++------------ 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/apple/OSX/platform.m b/apple/OSX/platform.m index 41f1c6e516..c860edeac0 100644 --- a/apple/OSX/platform.m +++ b/apple/OSX/platform.m @@ -85,7 +85,7 @@ apple_display_alert(@"No libretro cores were found.\nSelect \"Go->Cores Directory\" from the menu and place libretro dylib files there.", @"RetroArch"); // Run RGUI if needed - if (!_wantReload) + if (!_wantReload || apple_argv) apple_run_core(nil, 0); else [self chooseCore]; @@ -270,6 +270,23 @@ int main(int argc, char *argv[]) { + uint32_t current_argc = 0; + + for (int i = 0; i != argc; i ++) + { + if (strcmp(argv[i], "--") == 0) + { + current_argc = 1; + apple_argv = malloc(sizeof(char*) * (argc + 1)); + memset(apple_argv, 0, sizeof(char*) * (argc + 1)); + apple_argv[0] = argv[0]; + } + else if (current_argc) + { + apple_argv[current_argc ++] = argv[i]; + } + } + return NSApplicationMain(argc, (const char **) argv); } diff --git a/apple/RetroArch/RetroArch_Apple.h b/apple/RetroArch/RetroArch_Apple.h index 90dccbb0da..96be99f0c7 100644 --- a/apple/RetroArch/RetroArch_Apple.h +++ b/apple/RetroArch/RetroArch_Apple.h @@ -38,6 +38,7 @@ #import "../OSX/platform.h" #endif +extern char** apple_argv; extern bool apple_is_paused; extern bool apple_is_running; extern bool apple_use_tv_mode; diff --git a/apple/RetroArch/main.m b/apple/RetroArch/main.m index 4ba48c1933..b8c85f2fff 100644 --- a/apple/RetroArch/main.m +++ b/apple/RetroArch/main.m @@ -23,6 +23,8 @@ #include "file.h" +char** apple_argv; + //#define HAVE_DEBUG_FILELOG id apple_platform; @@ -125,37 +127,46 @@ void apple_run_core(RAModuleInfo* core, const char* file) apple_core = core; apple_is_running = true; - + static char config_path[PATH_MAX]; static char core_path[PATH_MAX]; static char file_path[PATH_MAX]; - - static const char* argv[] = { "retroarch", "-c", config_path, "-L", core_path, file_path, 0 }; - if (apple_core) - strlcpy(config_path, apple_core.configPath.UTF8String, sizeof(config_path)); - else - strlcpy(config_path, RAModuleInfo.globalConfigPath.UTF8String, sizeof(config_path)); + if (!apple_argv) + { + static const char* argv[] = { "retroarch", "-c", config_path, "-L", core_path, file_path, 0 }; + + if (apple_core) + strlcpy(config_path, apple_core.configPath.UTF8String, sizeof(config_path)); + else + strlcpy(config_path, RAModuleInfo.globalConfigPath.UTF8String, sizeof(config_path)); - if (file && core) - { - argv[3] = "-L"; - argv[4] = core_path; - strlcpy(core_path, apple_core.path.UTF8String, sizeof(core_path)); - strlcpy(file_path, file, sizeof(file_path)); - } - else - { - argv[3] = "--menu"; - argv[4] = 0; + if (file && core) + { + argv[3] = "-L"; + argv[4] = core_path; + strlcpy(core_path, apple_core.path.UTF8String, sizeof(core_path)); + strlcpy(file_path, file, sizeof(file_path)); + } + else + { + argv[3] = "--menu"; + argv[4] = 0; + } + + apple_argv = (char**)argv; } - if (pthread_create(&apple_retro_thread, 0, rarch_main_spring, argv)) + if (pthread_create(&apple_retro_thread, 0, rarch_main_spring, apple_argv)) { + apple_argv = 0; + apple_rarch_exited((void*)1); return; } + apple_argv = 0; + pthread_detach(apple_retro_thread); } } From 2b6907e0abac51d2960fcfa7213813d8fb4b257f Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Tue, 27 Aug 2013 19:26:01 +0100 Subject: [PATCH 131/202] fix C++ (MSVC) build --- input/dinput.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/dinput.c b/input/dinput.c index f71d690ae0..989279df5c 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -443,7 +443,7 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) return DIENUM_CONTINUE; size_t name_len = strlen(inst->tszProductName) + 1; - g_pad_names[g_joypad_cnt] = malloc(name_len); + g_pad_names[g_joypad_cnt] = (char*)malloc(name_len); strncpy(g_pad_names[g_joypad_cnt], inst->tszProductName, name_len); #ifdef HAVE_WINXINPUT From dca8dd0f3ba46f4c91e3d6db3ede7ba0dc10b4c7 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Tue, 27 Aug 2013 19:28:34 +0100 Subject: [PATCH 132/202] fix XInput performance bug --- input/winxinput_joypad.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index 00ab50c60b..f993e89860 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -314,8 +314,9 @@ static int16_t winxinput_joypad_axis (unsigned port_num, uint32_t joyaxis) static void winxinput_joypad_poll(void) { for (unsigned i = 0; i < 4; ++i) - if (g_XInputGetStateEx(i, &(g_winxinput_states[i].xstate)) == ERROR_DEVICE_NOT_CONNECTED) - g_winxinput_states[i].connected = false; + if (g_winxinput_states[i].connected) + if (g_XInputGetStateEx(i, &(g_winxinput_states[i].xstate)) == ERROR_DEVICE_NOT_CONNECTED) + g_winxinput_states[i].connected = false; dinput_joypad.poll(); } From fee0bdd228140dfe08758cf62da98ce020357de4 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Tue, 27 Aug 2013 20:25:50 +0100 Subject: [PATCH 133/202] more XI/DI tweaking --- input/dinput.c | 2 +- input/winxinput_joypad.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/input/dinput.c b/input/dinput.c index 972772da75..0d690044c4 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -562,7 +562,7 @@ static void dinput_joypad_poll(void) { struct dinput_joypad *pad = &g_pads[i]; - if (pad->joypad) + if ((pad->joypad) && (g_xbox_pad_indexes[i] == -1)) { memset(&pad->joy_state, 0, sizeof(pad->joy_state)); diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index f993e89860..86446c10ed 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -315,7 +315,7 @@ static void winxinput_joypad_poll(void) { for (unsigned i = 0; i < 4; ++i) if (g_winxinput_states[i].connected) - if (g_XInputGetStateEx(i, &(g_winxinput_states[i].xstate)) == ERROR_DEVICE_NOT_CONNECTED) + if (g_XInputGetStateEx(i, &(g_winxinput_states[i].xstate)) != ERROR_SUCCESS) g_winxinput_states[i].connected = false; dinput_joypad.poll(); From cce58a829a8deacd4c48225553c102b80f470546 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 27 Aug 2013 18:31:07 -0400 Subject: [PATCH 134/202] (OSX) Fix XCode release flags --- apple/RetroArch_OSX.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apple/RetroArch_OSX.xcodeproj/project.pbxproj b/apple/RetroArch_OSX.xcodeproj/project.pbxproj index c67900681c..217f63a153 100644 --- a/apple/RetroArch_OSX.xcodeproj/project.pbxproj +++ b/apple/RetroArch_OSX.xcodeproj/project.pbxproj @@ -352,22 +352,22 @@ "-DHAVE_RARCH_MAIN_WRAP", "-DHAVE_GRIFFIN", "-DHAVE_RGUI", - "-DIOS", + "-DOSX", "-DHAVE_OPENGL", "-DHAVE_FBO", "-DHAVE_VID_CONTEXT", - "-DHAVE_OPENGLES2", "-DHAVE_GLSL", "-DINLINE=inline", "-DLSB_FIRST", "-D__LIBRETRO__", - "-DRARCH_MOBILE", + "-DWANT_RPNG", "-DHAVE_COREAUDIO", "-DHAVE_DYNAMIC", "-DHAVE_OVERLAY", "-DHAVE_ZLIB", "-DWANT_MINIZ", "-DSINC_LOWER_QUALITY", + "-DHAVE_NETPLAY", ); PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = ""; From ead5a3b3ac96e722f095edcd0085b6f33dee26b7 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 28 Aug 2013 02:11:44 +0200 Subject: [PATCH 135/202] (Android) comment readBackInt for input_back_behavior - this crashes hard for now --- .../phoenix/src/org/retroarch/browser/MainMenuActivity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 47b1b4bae2..24e97ea143 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -317,7 +317,7 @@ public class MainMenuActivity extends PreferenceActivity { readbackBool(config, edit, "rewind_enable"); readbackBool(config, edit, "savestate_auto_load"); readbackBool(config, edit, "savestate_auto_save"); - readbackDouble(config, edit, "video_refresh_rate"); + //readbackDouble(config, edit, "video_refresh_rate"); readbackBool(config, edit, "audio_rate_control"); readbackBool(config, edit, "audio_enable"); @@ -325,7 +325,7 @@ public class MainMenuActivity extends PreferenceActivity { readbackDouble(config, edit, "input_overlay_opacity"); readbackBool(config, edit, "input_autodetect_enable"); - readbackInt(config, edit, "input_back_behavior"); + //readbackInt(config, edit, "input_back_behavior"); readbackBool(config, edit, "video_allow_rotate"); readbackBool(config, edit, "video_font_enable"); From 04be8cbee209c333932aa951d5caf5147f487d2b Mon Sep 17 00:00:00 2001 From: ToadKing Date: Wed, 28 Aug 2013 00:03:25 -0400 Subject: [PATCH 136/202] new audio core, RWebAudio. Glitchy, but works well, even with requestAnimationFrame callbacks --- Makefile.emscripten | 11 +-- config.def.h | 5 + driver.c | 3 + driver.h | 1 + emscripten/RWebAudio.c | 90 ++++++++++++++++++ emscripten/RWebAudio.h | 29 ++++++ emscripten/library_rwebaudio.js | 161 ++++++++++++++++++++++++++++++++ frontend/frontend_emscripten.c | 6 ++ settings.c | 2 + 9 files changed, 300 insertions(+), 8 deletions(-) create mode 100644 emscripten/RWebAudio.c create mode 100644 emscripten/RWebAudio.h create mode 100644 emscripten/library_rwebaudio.js diff --git a/Makefile.emscripten b/Makefile.emscripten index 0c15c8bd81..559638ab75 100644 --- a/Makefile.emscripten +++ b/Makefile.emscripten @@ -22,6 +22,7 @@ OBJ = frontend/frontend_emscripten.o \ screenshot.o \ cheats.o \ audio/utils.o \ + emscripten/RWebAudio.o \ input/overlay.o \ fifo_buffer.o \ gfx/scaler/scaler.o \ @@ -39,7 +40,6 @@ OBJ = frontend/frontend_emscripten.o \ performance.o HAVE_OPENGL = 1 -HAVE_AL = 1 HAVE_RGUI = 1 HAVE_SDL = 1 HAVE_SDL_IMAGE = 1 @@ -59,7 +59,7 @@ libretro = libretro_emscripten.bc LIBS = -lm DEFINES = -DHAVE_SCREENSHOTS -DHAVE_NULLAUDIO -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.9.3\" -LDFLAGS = -L. -s TOTAL_MEMORY=$(MEMORY) +LDFLAGS = -L. -s TOTAL_MEMORY=$(MEMORY) --js-library emscripten/library_rwebaudio.js ifeq ($(SCALER_NO_SIMD), 1) DEFINES += -DSCALER_NO_SIMD @@ -90,12 +90,6 @@ ifeq ($(HAVE_OPENGL), 1) DEFINES += -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_EGL -DHAVE_OVERLAY -DHAVE_GLSL endif -ifeq ($(HAVE_AL), 1) - OBJ += audio/openal.o - DEFINES += -DHAVE_AL - LIBS += -lopenal -endif - ifeq ($(HAVE_ZLIB), 1) OBJ += gfx/rpng/rpng.o file_extract.o DEFINES += -DHAVE_ZLIB @@ -165,6 +159,7 @@ clean: rm -f gfx/fonts/*.o rm -f gfx/py_state/*.o rm -f gfx/rpng/*.o + rm -f gfx/glsym/*.o rm -f record/*.o rm -f input/*.o rm -f tools/*.o diff --git a/config.def.h b/config.def.h index a677cc2778..3294cd73b2 100644 --- a/config.def.h +++ b/config.def.h @@ -63,6 +63,7 @@ enum AUDIO_PS3, AUDIO_XENON360, AUDIO_WII, + AUDIO_RWEBAUDIO, AUDIO_NULL, INPUT_ANDROID, @@ -130,6 +131,8 @@ enum #define AUDIO_DEFAULT_DRIVER AUDIO_SL #elif defined(HAVE_DSOUND) #define AUDIO_DEFAULT_DRIVER AUDIO_DSOUND +#elif defined(EMSCRIPTEN) +#define AUDIO_DEFAULT_DRIVER AUDIO_RWEBAUDIO #elif defined(HAVE_SDL) #define AUDIO_DEFAULT_DRIVER AUDIO_SDL #elif defined(HAVE_XAUDIO) @@ -335,6 +338,8 @@ static const bool rate_control = false; // Rate control delta. Defines how much rate_control is allowed to adjust input rate. #if defined(__QNX__) static const float rate_control_delta = 0.000; +#elif defined(EMSCRIPTEN) +static const float rate_control_delta = 0.002; #else static const float rate_control_delta = 0.005; #endif diff --git a/driver.c b/driver.c index 761e8cdbdb..51e8e6a577 100644 --- a/driver.c +++ b/driver.c @@ -84,6 +84,9 @@ static const audio_driver_t *audio_drivers[] = { #ifdef GEKKO &audio_gx, #endif +#ifdef EMSCRIPTEN + &audio_rwebaudio, +#endif #ifdef HAVE_NULLAUDIO &audio_null, #endif diff --git a/driver.h b/driver.h index bc4cdd7d1a..91dd004005 100644 --- a/driver.h +++ b/driver.h @@ -511,6 +511,7 @@ extern const audio_driver_t audio_coreaudio; extern const audio_driver_t audio_xenon360; extern const audio_driver_t audio_ps3; extern const audio_driver_t audio_gx; +extern const audio_driver_t audio_rwebaudio; extern const audio_driver_t audio_null; extern const video_driver_t video_gl; extern const video_driver_t video_psp1; diff --git a/emscripten/RWebAudio.c b/emscripten/RWebAudio.c new file mode 100644 index 0000000000..b384c828a8 --- /dev/null +++ b/emscripten/RWebAudio.c @@ -0,0 +1,90 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Michael Lelli + * + * 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 "../driver.h" +#include "../general.h" + +#include "RWebAudio.h" + +static void ra_free(void *data) +{ + RWebAudioFree(); +} + +static void *ra_init(const char *device, unsigned rate, unsigned latency) +{ + (void)device; + (void)rate; + void *data = RWebAudioInit(latency); + g_settings.audio.out_rate = RWebAudioSampleRate(); + RARCH_LOG("audio out rate: %u\n", g_settings.audio.out_rate); + return data; +} + +static ssize_t ra_write(void *data, const void *buf, size_t size) +{ + (void)data; + return RWebAudioWrite(buf, size); +} + +static bool ra_stop(void *data) +{ + (void)data; + return RWebAudioStop(); +} + +static void ra_set_nonblock_state(void *data, bool state) +{ + (void)data; + RWebAudioSetNonblockState(state); +} + +static bool ra_start(void *data) +{ + (void)data; + return RWebAudioStart(); +} + +static bool ra_use_float(void *data) +{ + (void)data; + return true; +} + +static size_t ra_write_avail(void *data) +{ + (void)data; + return RWebAudioWriteAvail(); +} + +static size_t ra_buffer_size(void *data) +{ + (void)data; + return RWebAudioBufferSize(); +} + +const audio_driver_t audio_rwebaudio = { + ra_init, + ra_write, + ra_stop, + ra_start, + ra_set_nonblock_state, + ra_free, + ra_use_float, + "rwebaudio", + ra_write_avail, + ra_buffer_size, +}; + diff --git a/emscripten/RWebAudio.h b/emscripten/RWebAudio.h new file mode 100644 index 0000000000..fd928cd3d6 --- /dev/null +++ b/emscripten/RWebAudio.h @@ -0,0 +1,29 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Michael Lelli + * + * 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 +#include + +unsigned RWebAudioSampleRate(void); +void *RWebAudioInit(unsigned latency); +ssize_t RWebAudioWrite(const void *buf, size_t size); +bool RWebAudioStop(void); +bool RWebAudioStart(void); +void RWebAudioSetNonblockState(bool state); +void RWebAudioFree(void); +size_t RWebAudioWriteAvail(void); +size_t RWebAudioBufferSize(void); +int RWebAudioEnoughSpace(void); diff --git a/emscripten/library_rwebaudio.js b/emscripten/library_rwebaudio.js new file mode 100644 index 0000000000..d2197ceccb --- /dev/null +++ b/emscripten/library_rwebaudio.js @@ -0,0 +1,161 @@ +//"use strict"; + +var LibraryRWebAudio = { + $RA__deps: ['$Browser'], + $RA: { + SCRIPTNODE_BUFFER: 1024, + + context: null, + leftBuffer: null, + rightBuffer: null, + blank: null, + scriptNode: null, + bufferNode: null, + start: 0, + end: 0, + size: 0, + lastWrite: 0, + nonblock: false, + + npot: function(n) { + n--; + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + n++; + return n; + }, + + process: function(e) { + var left = e.outputBuffer.getChannelData(0); + var right = e.outputBuffer.getChannelData(1); + var samples1 = RA.size; + var samples2 = 0; + samples1 = e.outputBuffer.length > samples1 ? samples1 : e.outputBuffer.length; + + if (samples1 + RA.start > RA.leftBuffer.length) { + samples2 = samples1 + RA.start - RA.leftBuffer.length; + samples1 = samples1 - samples2; + } + + var remaining = e.outputBuffer.length - (samples1 + samples2); + + if (samples1) { + left.set(RA.leftBuffer.subarray(RA.start, RA.start + samples1), 0); + right.set(RA.rightBuffer.subarray(RA.start, RA.start + samples1), 0); + } + + if (samples2) { + left.set(RA.leftBuffer.subarray(0, samples2), samples1); + right.set(RA.rightBuffer.subarray(0, samples2), samples1); + } + + /*if (remaining) { + left.set(RA.blank.subarray(0, remaining), samples1 + samples2); + right.set(RA.blank.subarray(0, remaining), samples1 + samples2); + }*/ + + RA.start = (RA.start + samples1 + samples2) % RA.leftBuffer.length; + RA.size -= samples1 + samples2; + } + }, + + RWebAudioSampleRate: function() { + return RA.context.sampleRate; + }, + + RWebAudioInit: function(latency) { + var ac = window['AudioContext'] || window['webkitAudioContext']; + var bufferSize; + + if (!ac) return 0; + + RA.context = new ac(); + // account for script processor overhead + latency -= 32; + // because we have to guess on how many samples the core will send when + // returning early, we double the buffer size to account for times when it + // sends more than we expect it to without losing samples + bufferSize = RA.npot(RA.context.sampleRate * latency / 1000) * 2; + RA.leftBuffer = new Float32Array(bufferSize); + RA.rightBuffer = new Float32Array(bufferSize); + RA.blank = new Float32Array(RA.SCRIPTNODE_BUFFER); + RA.bufferNode = RA.context.createBufferSource(); + RA.bufferNode.buffer = RA.context.createBuffer(2, RA.SCRIPTNODE_BUFFER, RA.context.sampleRate); + RA.bufferNode.loop = true; + RA.scriptNode = RA.context.createScriptProcessor(RA.SCRIPTNODE_BUFFER, 2, 2); + RA.scriptNode.onaudioprocess = RA.process; + RA.bufferNode.connect(RA.scriptNode); + RA.scriptNode.connect(RA.context.destination); + RA.bufferNode.start(0); + RA.start = RA.end = RA.size = 0; + RA.nonblock = false; + return 1; + }, + + RWebAudioWrite: function (buf, size) { + var samples = size / 8; + var free = RA.leftBuffer.length - RA.size; + if (free < samples) + RA.start = (RA.start + free) % RA.leftBuffer.length; + + for (var i = 0; i < samples; i++) { + RA.leftBuffer[RA.end] = {{{ makeGetValue('buf', 'i * 8', 'float') }}}; + RA.rightBuffer[RA.end] = {{{ makeGetValue('buf', 'i * 8 + 4', 'float') }}}; + RA.end = (RA.end + 1) % RA.leftBuffer.length; + } + + RA.lastWrite = size; + RA.size += samples; + return size; + }, + + RWebAudioStop: function() { + RA.scriptNode.onaudioprocess = null; + return true; + }, + + RWebAudioStart: function() { + RA.scriptNode.onaudioprocess = RA.process; + return true; + }, + + RWebAudioSetNonblockState: function(state) { + RA.nonblock = state; + }, + + RWebAudioFree: function() { + RA.scriptNode.onaudioprocess = null; + RA.start = RA.end = RA.size = RA.lastWrite = 0; + return; + }, + + RWebAudioWriteAvail: function() { + var free = (RA.leftBuffer.length / 2) - RA.size; + // 4 byte samples, 2 channels + free *= 8; + + if (free < 0) + return 0; + else + return free; + }, + + RWebAudioBufferSize: function() { + return RA.leftBuffer.length / 2; + }, + + RWebAudioEnoughSpace__deps: ['RWebAudioWriteAvail'], + RWebAudioEnoughSpace: function() { + var guess = RA.lastWrite; + var available = _RWebAudioWriteAvail(); + if (RA.nonblock) return true; + if (!guess) return true; + return (guess < available) ? 1 : 0; + } +}; + +autoAddDeps(LibraryRWebAudio, '$RA'); +mergeInto(LibraryManager.library, LibraryRWebAudio); diff --git a/frontend/frontend_emscripten.c b/frontend/frontend_emscripten.c index cfa762ae1f..452c7f41ea 100644 --- a/frontend/frontend_emscripten.c +++ b/frontend/frontend_emscripten.c @@ -18,6 +18,7 @@ #include "../general.h" #include "../conf/config_file.h" #include "../file.h" +#include "../emscripten/RWebAudio.h" #ifdef HAVE_RGUI #include "../frontend/menu/rgui.h" @@ -55,6 +56,11 @@ static void endloop(void) static void mainloop(void) { + if (!RWebAudioEnoughSpace()) + { + return; + } + if (g_extern.system.shutdown) { endloop(); diff --git a/settings.c b/settings.c index 4b9dd32237..682774941a 100644 --- a/settings.c +++ b/settings.c @@ -67,6 +67,8 @@ const char *config_get_default_audio(void) return "ps3"; case AUDIO_WII: return "gx"; + case AUDIO_RWEBAUDIO: + return "rwebaudio"; case AUDIO_NULL: return "null"; default: From a2d5d201257c5c37a4067e4c1b26ebabe523ebd6 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Wed, 28 Aug 2013 16:08:44 +0100 Subject: [PATCH 137/202] tiny XI tweak/fix --- input/winxinput_joypad.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index 0083b17baa..abf7ec9fb7 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -103,7 +103,7 @@ typedef struct static winxinput_joypad_state g_winxinput_states[4]; -static int pad_index_to_xplayer_index(unsigned pad) +static inline int pad_index_to_xplayer_index(unsigned pad) { return g_xbox_pad_indexes[pad]; } @@ -219,7 +219,7 @@ static bool winxinput_joypad_query_pad(unsigned pad) { int xplayer = pad_index_to_xplayer_index(pad); if (xplayer > -1) - return g_winxinput_states[0].connected; + return g_winxinput_states[xplayer].connected; else return dinput_joypad.query_pad(pad); } @@ -264,6 +264,8 @@ static bool winxinput_joypad_button (unsigned port_num, uint16_t joykey) if (!(g_winxinput_states[xplayer].connected)) return false; + + //return false; uint16_t btn_word = g_winxinput_states[xplayer].xstate.Gamepad.wButtons; @@ -348,7 +350,7 @@ static void winxinput_joypad_poll(void) { for (unsigned i = 0; i < 4; ++i) if (g_winxinput_states[i].connected) - if (g_XInputGetStateEx(i, &(g_winxinput_states[i].xstate)) != ERROR_SUCCESS) + if (g_XInputGetStateEx(i, &(g_winxinput_states[i].xstate)) == ERROR_DEVICE_NOT_CONNECTED) g_winxinput_states[i].connected = false; dinput_joypad.poll(); From 37ebdcdec774a730f08062b3c6f9bcb38bf70e97 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Wed, 28 Aug 2013 21:16:27 +0100 Subject: [PATCH 138/202] Add correct joypad name reporting to RGUI (for xi and di), also cleanup dinput name variables --- input/dinput.c | 32 ++++++++++++++++---------------- input/winxinput_joypad.c | 5 +++++ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/input/dinput.c b/input/dinput.c index 9971f5bd93..0f787633a0 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -49,6 +49,7 @@ struct dinput_joypad { LPDIRECTINPUTDEVICE8 joypad; DIJOYSTATE2 joy_state; + char* joy_name; }; static unsigned g_joypad_cnt; @@ -350,9 +351,6 @@ const input_driver_t input_dinput = { // -1 = not xbox pad, otherwise 0..3 int g_xbox_pad_indexes[MAX_PLAYERS]; -// TODO: Move the name string to struct dinput_joypad -static char *g_pad_names[MAX_PLAYERS]; - static void dinput_joypad_destroy(void) { for (unsigned i = 0; i < MAX_PLAYERS; i++) @@ -362,16 +360,17 @@ static void dinput_joypad_destroy(void) IDirectInputDevice8_Unacquire(g_pads[i].joypad); IDirectInputDevice8_Release(g_pads[i].joypad); } + + if (g_pads[i].joy_name) + { + free(g_pads[i].joy_name); + g_pads[i].joy_name = NULL; + } + } g_joypad_cnt = 0; memset(g_pads, 0, sizeof(g_pads)); - - for (unsigned i = 0; i < MAX_PLAYERS; i++) - { - free (g_pad_names[i]); - g_pad_names[i] = NULL; - } // Can be blocked by global Dinput context. dinput_destroy_context(); @@ -443,8 +442,8 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) return DIENUM_CONTINUE; size_t name_len = strlen(inst->tszProductName) + 1; - g_pad_names[g_joypad_cnt] = (char*)malloc(name_len); - strncpy(g_pad_names[g_joypad_cnt], inst->tszProductName, name_len); + g_pads[g_joypad_cnt].joy_name = (char*)malloc(name_len); + strncpy(g_pads[g_joypad_cnt].joy_name, inst->tszProductName, name_len); #ifdef HAVE_WINXINPUT int last_xbox_pad_index = 0; @@ -473,7 +472,7 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) if (1) #endif { - + strlcpy(g_settings.input.device_names[g_joypad_cnt], dinput_joypad_name(g_joypad_cnt), sizeof(g_settings.input.device_names[g_joypad_cnt])); input_config_autoconfigure_joypad(g_joypad_cnt, dinput_joypad_name(g_joypad_cnt), dinput_joypad.ident); } @@ -488,9 +487,10 @@ static bool dinput_joypad_init(void) return false; for (unsigned i = 0; i < MAX_PLAYERS; ++i) + { g_xbox_pad_indexes[i] = -1; - - memset(&g_pad_names, 0, sizeof(g_pad_names)); + g_pads[i].joy_name = NULL; + } RARCH_LOG("Enumerating DInput joypads ...\n"); IDirectInput8_EnumDevices(g_ctx, DI8DEVCLASS_GAMECTRL, @@ -633,8 +633,8 @@ static bool dinput_joypad_query_pad(unsigned pad) static const char *dinput_joypad_name(unsigned pad) { - if ((pad < MAX_PLAYERS) && (g_pad_names[pad])) - return g_pad_names[pad]; + if (pad < MAX_PLAYERS) + return g_pads[pad].joy_name; return NULL; } diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index abf7ec9fb7..535e8b62ea 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -208,8 +208,13 @@ static bool winxinput_joypad_init(void) return false; for (unsigned autoconf_pad = 0; autoconf_pad < MAX_PLAYERS; autoconf_pad++) + { if (pad_index_to_xplayer_index(autoconf_pad) > -1) + { + strlcpy(g_settings.input.device_names[autoconf_pad], winxinput_joypad_name(autoconf_pad), sizeof(g_settings.input.device_names[autoconf_pad])); input_config_autoconfigure_joypad(autoconf_pad, winxinput_joypad_name(autoconf_pad), winxinput_joypad.ident); + } + } return true; From 0fb0d0e891ec168eca3a9f5d4185ea3cb3ce9818 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Thu, 29 Aug 2013 09:27:13 +0100 Subject: [PATCH 139/202] coding style corrections --- input/dinput.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/input/dinput.c b/input/dinput.c index 0f787633a0..b3e15b2e67 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -361,11 +361,8 @@ static void dinput_joypad_destroy(void) IDirectInputDevice8_Release(g_pads[i].joypad); } - if (g_pads[i].joy_name) - { - free(g_pads[i].joy_name); - g_pads[i].joy_name = NULL; - } + free(g_pads[i].joy_name); + g_pads[i].joy_name = NULL; } @@ -418,7 +415,7 @@ static bool name_is_360_pad(const char* name) const char* t = XINPUT_PAD_NAMES[i]; if (t == NULL) return false; - else if (lstrcmpi(name, t) == 0) + else if (strcasecmp(name, t) == 0) return true; } } @@ -441,9 +438,7 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) #endif return DIENUM_CONTINUE; - size_t name_len = strlen(inst->tszProductName) + 1; - g_pads[g_joypad_cnt].joy_name = (char*)malloc(name_len); - strncpy(g_pads[g_joypad_cnt].joy_name, inst->tszProductName, name_len); + g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName); #ifdef HAVE_WINXINPUT int last_xbox_pad_index = 0; @@ -468,8 +463,6 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) #ifdef HAVE_WINXINPUT if (!is_360_pad) -#else - if (1) #endif { strlcpy(g_settings.input.device_names[g_joypad_cnt], dinput_joypad_name(g_joypad_cnt), sizeof(g_settings.input.device_names[g_joypad_cnt])); From ce026a3ba08da1fc583e9668831d2fff2cb169ea Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 29 Aug 2013 18:35:43 +0200 Subject: [PATCH 140/202] [OpenVG] Fix build. --- gfx/vg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/vg.c b/gfx/vg.c index bbfc3a8264..1297cf4063 100644 --- a/gfx/vg.c +++ b/gfx/vg.c @@ -87,7 +87,7 @@ static void *vg_init(const video_info_t *video, const input_driver_t **input, vo if (!vg) return NULL; - vg->driver = gfx_ctx_init_first(GFX_CTX_OPENVG_API); + vg->driver = gfx_ctx_init_first(GFX_CTX_OPENVG_API, 0, 0); if (!vg->driver) { From 62c34c7871aa960eec51e6b8e0ec810deb3aceeb Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 30 Aug 2013 09:35:13 +0200 Subject: [PATCH 141/202] Add black_frame_insertion support for 120 Hz monitors. --- config.def.h | 4 ++++ frontend/menu/menu_common.h | 1 + frontend/menu/rgui.c | 22 ++++++++++++++++++++++ general.h | 1 + gfx/d3d9/d3d9.cpp | 11 +++++++++++ gfx/gl.c | 5 +++++ retroarch.cfg | 5 +++++ settings.c | 3 +++ 8 files changed, 52 insertions(+) diff --git a/config.def.h b/config.def.h index a677cc2778..f86e82610a 100644 --- a/config.def.h +++ b/config.def.h @@ -215,6 +215,10 @@ static const bool hard_sync = false; // 2: Etc ... static const unsigned hard_sync_frames = 0; +// Inserts a black frame inbetween frames. +// Useful for 120 Hz monitors who want to play 60 Hz material with eliminated ghosting. video_refresh_rate should still be configured as if it is a 60 Hz monitor (divide refresh rate by 2). +static bool black_frame_insertion = false; + // Threaded video. Will possibly increase performance significantly at cost of worse synchronization and latency. static const bool video_threaded = false; diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index a3293785ed..9839c7718b 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -118,6 +118,7 @@ typedef enum RGUI_SETTINGS_VIDEO_VSYNC, RGUI_SETTINGS_VIDEO_HARD_SYNC, RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES, + RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION, RGUI_SETTINGS_VIDEO_REFRESH_RATE_AUTO, RGUI_SETTINGS_VIDEO_OPTIONS_LAST, #ifdef HAVE_SHADER_MANAGER diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 7ae5533490..47779775bc 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -598,6 +598,9 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_VIDEO_HARD_SYNC: strlcpy(type_str, g_settings.video.hard_sync ? "ON" : "OFF", sizeof(type_str)); break; + case RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION: + strlcpy(type_str, g_settings.video.black_frame_insertion ? "ON" : "OFF", sizeof(type_str)); + break; case RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES: snprintf(type_str, sizeof(type_str), "%u", g_settings.video.hard_sync_frames); break; @@ -1505,6 +1508,7 @@ static void rgui_settings_video_options_populate_entries(rgui_handle_t *rgui) rgui_list_push(rgui->selection_buf, "VSync", RGUI_SETTINGS_VIDEO_VSYNC, 0); rgui_list_push(rgui->selection_buf, "Hard GPU Sync", RGUI_SETTINGS_VIDEO_HARD_SYNC, 0); rgui_list_push(rgui->selection_buf, "Hard GPU Sync Frames", RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES, 0); + rgui_list_push(rgui->selection_buf, "Black Frame Insertion", RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION, 0); rgui_list_push(rgui->selection_buf, "Estimated Monitor FPS", RGUI_SETTINGS_VIDEO_REFRESH_RATE_AUTO, 0); } @@ -1932,6 +1936,24 @@ static int video_option_toggle_setting(rgui_handle_t *rgui, unsigned setting, rg } break; + case RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION: + switch (action) + { + case RGUI_ACTION_START: + g_settings.video.black_frame_insertion = false; + break; + + case RGUI_ACTION_LEFT: + case RGUI_ACTION_RIGHT: + case RGUI_ACTION_OK: + g_settings.video.black_frame_insertion = !g_settings.video.black_frame_insertion; + break; + + default: + break; + } + break; + case RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES: switch (action) { diff --git a/general.h b/general.h index 09364943c7..34b52acdfb 100644 --- a/general.h +++ b/general.h @@ -159,6 +159,7 @@ struct settings unsigned fullscreen_y; bool vsync; bool hard_sync; + bool black_frame_insertion; unsigned hard_sync_frames; bool smooth; bool force_aspect; diff --git a/gfx/d3d9/d3d9.cpp b/gfx/d3d9/d3d9.cpp index c4de8cf9c1..31eeb062be 100644 --- a/gfx/d3d9/d3d9.cpp +++ b/gfx/d3d9/d3d9.cpp @@ -614,6 +614,17 @@ bool D3DVideo::frame(const void *frame, dev->SetViewport(&screen_vp); dev->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0); + // Insert black frame first, so we can screenshot, etc. + if (g_settings.video.black_frame_insertion) + { + if (dev->Present(nullptr, nullptr, nullptr, nullptr) != D3D_OK) + { + needs_restore = true; + return true; + } + dev->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0); + } + if (!chain->render(frame, width, height, pitch, rotation)) { RARCH_ERR("[D3D9]: Failed to render scene.\n"); diff --git a/gfx/gl.c b/gfx/gl.c index 7a62910a78..fc8d5904ed 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1454,6 +1454,11 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei memcpy(tex_info.coord, gl->tex_coords, sizeof(gl->tex_coords)); glClear(GL_COLOR_BUFFER_BIT); + if (g_settings.video.black_frame_insertion) + { + context_swap_buffers_func(); + glClear(GL_COLOR_BUFFER_BIT); + } if (gl->shader) gl->shader->set_params(width, height, diff --git a/retroarch.cfg b/retroarch.cfg index dafd3b0847..ebf66a1b85 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -89,6 +89,11 @@ # Maximum is 3. # video_hard_sync_frames = 0 +# Inserts a black frame inbetween frames. +# Useful for 120 Hz monitors who want to play 60 Hz material with eliminated ghosting. +# video_refresh_rate should still be configured as if it is a 60 Hz monitor (divide refresh rate by 2). +# video_black_frame_insertion = false + # Use threaded video driver. Using this might improve performance at possible cost of latency and more video stuttering. # video_threaded = false diff --git a/settings.c b/settings.c index 8a9563e2e5..b68df94c86 100644 --- a/settings.c +++ b/settings.c @@ -168,6 +168,7 @@ void config_set_defaults(void) g_settings.video.vsync = vsync; g_settings.video.hard_sync = hard_sync; g_settings.video.hard_sync_frames = hard_sync_frames; + g_settings.video.black_frame_insertion = black_frame_insertion; g_settings.video.threaded = video_threaded; g_settings.video.smooth = video_smooth; g_settings.video.force_aspect = force_aspect; @@ -491,6 +492,7 @@ bool config_load_file(const char *path) if (g_settings.video.hard_sync_frames > 3) g_settings.video.hard_sync_frames = 3; + CONFIG_GET_BOOL(video.black_frame_insertion, "video_black_frame_insertion"); CONFIG_GET_BOOL(video.threaded, "video_threaded"); CONFIG_GET_BOOL(video.smooth, "video_smooth"); CONFIG_GET_BOOL(video.force_aspect, "video_force_aspect"); @@ -976,6 +978,7 @@ bool config_save_file(const char *path) config_set_bool(conf, "video_vsync", g_settings.video.vsync); config_set_bool(conf, "video_hard_sync", g_settings.video.hard_sync); config_set_int(conf, "video_hard_sync_frames", g_settings.video.hard_sync_frames); + config_set_bool(conf, "video_black_frame_insertion", g_settings.video.black_frame_insertion); config_set_int(conf, "aspect_ratio_index", g_settings.video.aspect_ratio_idx); config_set_string(conf, "audio_device", g_settings.audio.device); config_set_bool(conf, "audio_rate_control", g_settings.audio.rate_control); From b3b92ee563d6926502d05c3d44090c34adfd622b Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Fri, 30 Aug 2013 11:29:54 +0100 Subject: [PATCH 142/202] RGUI: Do not scroll if all items are visible at once --- frontend/menu/rgui.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 47779775bc..4fbec52210 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -418,6 +418,10 @@ static void render_text(rgui_handle_t *rgui) rgui->selection_ptr - TERM_HEIGHT / 2 : 0; size_t end = rgui->selection_ptr + TERM_HEIGHT <= rgui->selection_buf->size ? rgui->selection_ptr + TERM_HEIGHT : rgui->selection_buf->size; + + // Do not scroll if all items are visible. + if (rgui->selection_buf->size <= TERM_HEIGHT) + begin = 0; if (end - begin > TERM_HEIGHT) end = begin + TERM_HEIGHT; From 45cfc584f980928383d8658d11f259ce0755aa16 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 31 Aug 2013 11:43:14 +0200 Subject: [PATCH 143/202] Allow disabling building Win32 "GUI". --- Makefile.win | 5 +++++ gfx/context/wgl_ctx.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/Makefile.win b/Makefile.win index 27cdb3cc11..635e573ff4 100644 --- a/Makefile.win +++ b/Makefile.win @@ -63,6 +63,7 @@ HAVE_STDIN_CMD = 1 HAVE_THREADS = 1 HAVE_RGUI = 1 DYNAMIC = 1 +HAVE_WIN32GUI = 1 HAVE_WINXINPUT = 1 @@ -103,6 +104,10 @@ ifeq ($(HAVE_RGUI), 1) OBJ += frontend/menu/menu_common.o frontend/menu/rgui.o frontend/menu/history.o endif +ifeq ($(HAVE_WIN32GUI), 1) + DEFINES += -DHAVE_WIN32GUI +endif + ifeq ($(HAVE_SDL), 1) OBJ += gfx/sdl_gfx.o input/sdl_input.o input/sdl_joypad.o audio/sdl_audio.o JOBJ += input/sdl_joypad.o diff --git a/gfx/context/wgl_ctx.c b/gfx/context/wgl_ctx.c index cb925263ea..e8667ff66e 100644 --- a/gfx/context/wgl_ctx.c +++ b/gfx/context/wgl_ctx.c @@ -469,6 +469,7 @@ static bool gfx_ctx_set_video_mode( if (!g_hwnd) goto error; +#ifdef HAVE_WIN32GUI if (!fullscreen) { SetMenu(g_hwnd, LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MENU))); @@ -477,6 +478,7 @@ static bool gfx_ctx_set_video_mode( unsigned menu_height = rcTemp.top + rect.top; // rect.top is negative after AdjustWindowRect(). SetWindowPos(g_hwnd, NULL, 0, 0, width, height + menu_height, SWP_NOMOVE); } +#endif if (!fullscreen || windowed_full) { From b2bf3c12de10888cb175d93cd50ac2acb79fcbd1 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 1 Sep 2013 13:20:10 +0200 Subject: [PATCH 144/202] Add swap_interval support. Again, mostly useful for 120Hz monitors, and/or playing content which is a fraction of monitor refresh rate. --- config.def.h | 4 ++++ frontend/menu/menu_common.h | 1 + frontend/menu/rgui.c | 34 ++++++++++++++++++++++++++++++++++ general.h | 1 + gfx/context/drm_egl_ctx.c | 2 ++ gfx/d3d9/d3d9.cpp | 15 ++++++++++++++- gfx/gl.c | 2 +- settings.c | 5 +++++ 8 files changed, 62 insertions(+), 2 deletions(-) diff --git a/config.def.h b/config.def.h index f86e82610a..909f386bca 100644 --- a/config.def.h +++ b/config.def.h @@ -219,6 +219,10 @@ static const unsigned hard_sync_frames = 0; // Useful for 120 Hz monitors who want to play 60 Hz material with eliminated ghosting. video_refresh_rate should still be configured as if it is a 60 Hz monitor (divide refresh rate by 2). static bool black_frame_insertion = false; +// Uses a custom swap interval for VSync. +// Set this to effectively halve monitor refresh rate. +static unsigned swap_interval = 1; + // Threaded video. Will possibly increase performance significantly at cost of worse synchronization and latency. static const bool video_threaded = false; diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 9839c7718b..8a3a552ae5 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -119,6 +119,7 @@ typedef enum RGUI_SETTINGS_VIDEO_HARD_SYNC, RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES, RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION, + RGUI_SETTINGS_VIDEO_SWAP_INTERVAL, RGUI_SETTINGS_VIDEO_REFRESH_RATE_AUTO, RGUI_SETTINGS_VIDEO_OPTIONS_LAST, #ifdef HAVE_SHADER_MANAGER diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 4fbec52210..9bb5c70d08 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -605,6 +605,9 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION: strlcpy(type_str, g_settings.video.black_frame_insertion ? "ON" : "OFF", sizeof(type_str)); break; + case RGUI_SETTINGS_VIDEO_SWAP_INTERVAL: + snprintf(type_str, sizeof(type_str), "%u", g_settings.video.swap_interval); + break; case RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES: snprintf(type_str, sizeof(type_str), "%u", g_settings.video.hard_sync_frames); break; @@ -1513,6 +1516,7 @@ static void rgui_settings_video_options_populate_entries(rgui_handle_t *rgui) rgui_list_push(rgui->selection_buf, "Hard GPU Sync", RGUI_SETTINGS_VIDEO_HARD_SYNC, 0); rgui_list_push(rgui->selection_buf, "Hard GPU Sync Frames", RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES, 0); rgui_list_push(rgui->selection_buf, "Black Frame Insertion", RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION, 0); + rgui_list_push(rgui->selection_buf, "VSync Swap Interval", RGUI_SETTINGS_VIDEO_SWAP_INTERVAL, 0); rgui_list_push(rgui->selection_buf, "Estimated Monitor FPS", RGUI_SETTINGS_VIDEO_REFRESH_RATE_AUTO, 0); } @@ -1958,6 +1962,36 @@ static int video_option_toggle_setting(rgui_handle_t *rgui, unsigned setting, rg } break; + case RGUI_SETTINGS_VIDEO_SWAP_INTERVAL: + { + unsigned old = g_settings.video.swap_interval; + switch (action) + { + case RGUI_ACTION_START: + g_settings.video.swap_interval = 1; + break; + + case RGUI_ACTION_LEFT: + g_settings.video.swap_interval--; + break; + + case RGUI_ACTION_RIGHT: + case RGUI_ACTION_OK: + g_settings.video.swap_interval++; + break; + + default: + break; + } + + g_settings.video.swap_interval = min(g_settings.video.swap_interval, 4); + g_settings.video.swap_interval = max(g_settings.video.swap_interval, 1); + if (old != g_settings.video.swap_interval && driver.video && driver.video_data) + video_set_nonblock_state_func(false); // This will update the current swap interval. Since we're in RGUI now, always apply VSync. + + break; + } + case RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES: switch (action) { diff --git a/general.h b/general.h index 34b52acdfb..0d187b688b 100644 --- a/general.h +++ b/general.h @@ -160,6 +160,7 @@ struct settings bool vsync; bool hard_sync; bool black_frame_insertion; + unsigned swap_interval; unsigned hard_sync_frames; bool smooth; bool force_aspect; diff --git a/gfx/context/drm_egl_ctx.c b/gfx/context/drm_egl_ctx.c index 67bda39585..995a9301c2 100644 --- a/gfx/context/drm_egl_ctx.c +++ b/gfx/context/drm_egl_ctx.c @@ -93,6 +93,8 @@ static void sighandler(int sig) static void gfx_ctx_swap_interval(unsigned interval) { g_interval = interval; + if (interval > 1) + RARCH_WARN("[KMS/EGL]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n"); } static void gfx_ctx_check_window(bool *quit, diff --git a/gfx/d3d9/d3d9.cpp b/gfx/d3d9/d3d9.cpp index 31eeb062be..a59aa5647c 100644 --- a/gfx/d3d9/d3d9.cpp +++ b/gfx/d3d9/d3d9.cpp @@ -145,7 +145,20 @@ void D3DVideo::make_d3dpp(const video_info_t &info, D3DPRESENT_PARAMETERS &d3dpp d3dpp.Windowed = g_settings.video.windowed_fullscreen || !info.fullscreen; - d3dpp.PresentationInterval = info.vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; + if (info.vsync) + { + switch (g_settings.video.swap_interval) + { + default: + case 1: d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; break; + case 2: d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO; break; + case 3: d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_THREE; break; + case 4: d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_FOUR; break; + } + } + else + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hWnd; d3dpp.BackBufferCount = 2; diff --git a/gfx/gl.c b/gfx/gl.c index fc8d5904ed..cc622d5726 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1628,7 +1628,7 @@ static void gl_set_nonblock_state(void *data, bool state) gl_t *gl = (gl_t*)data; (void)gl; - context_swap_interval_func(state ? 0 : 1); + context_swap_interval_func(state ? 0 : g_settings.video.swap_interval); } static bool resolve_extensions(gl_t *gl) diff --git a/settings.c b/settings.c index b68df94c86..fd95524334 100644 --- a/settings.c +++ b/settings.c @@ -169,6 +169,7 @@ void config_set_defaults(void) g_settings.video.hard_sync = hard_sync; g_settings.video.hard_sync_frames = hard_sync_frames; g_settings.video.black_frame_insertion = black_frame_insertion; + g_settings.video.swap_interval = swap_interval; g_settings.video.threaded = video_threaded; g_settings.video.smooth = video_smooth; g_settings.video.force_aspect = force_aspect; @@ -493,6 +494,9 @@ bool config_load_file(const char *path) g_settings.video.hard_sync_frames = 3; CONFIG_GET_BOOL(video.black_frame_insertion, "video_black_frame_insertion"); + CONFIG_GET_INT(video.swap_interval, "video_swap_interval"); + g_settings.video.swap_interval = max(g_settings.video.swap_interval, 1); + g_settings.video.swap_interval = min(g_settings.video.swap_interval, 4); CONFIG_GET_BOOL(video.threaded, "video_threaded"); CONFIG_GET_BOOL(video.smooth, "video_smooth"); CONFIG_GET_BOOL(video.force_aspect, "video_force_aspect"); @@ -979,6 +983,7 @@ bool config_save_file(const char *path) config_set_bool(conf, "video_hard_sync", g_settings.video.hard_sync); config_set_int(conf, "video_hard_sync_frames", g_settings.video.hard_sync_frames); config_set_bool(conf, "video_black_frame_insertion", g_settings.video.black_frame_insertion); + config_set_int(conf, "video_swap_interval", g_settings.video.swap_interval); config_set_int(conf, "aspect_ratio_index", g_settings.video.aspect_ratio_idx); config_set_string(conf, "audio_device", g_settings.audio.device); config_set_bool(conf, "audio_rate_control", g_settings.audio.rate_control); From a6268692b64671c9317f827551c94bd538974d68 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 1 Sep 2013 13:46:35 +0200 Subject: [PATCH 145/202] Add window scale x/y and crop overscan options. --- frontend/menu/menu_common.h | 3 ++ frontend/menu/rgui.c | 67 +++++++++++++++++++++++++++++++++++++ retroarch.cfg | 2 +- settings.c | 3 ++ 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 8a3a552ae5..4b465bd718 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -120,6 +120,9 @@ typedef enum RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES, RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION, RGUI_SETTINGS_VIDEO_SWAP_INTERVAL, + RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X, + RGUI_SETTINGS_VIDEO_WINDOW_SCALE_Y, + RGUI_SETTINGS_VIDEO_CROP_OVERSCAN, RGUI_SETTINGS_VIDEO_REFRESH_RATE_AUTO, RGUI_SETTINGS_VIDEO_OPTIONS_LAST, #ifdef HAVE_SHADER_MANAGER diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 9bb5c70d08..754d24b63e 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -608,6 +608,15 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_VIDEO_SWAP_INTERVAL: snprintf(type_str, sizeof(type_str), "%u", g_settings.video.swap_interval); break; + case RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X: + snprintf(type_str, sizeof(type_str), "%.1fx", g_settings.video.xscale); + break; + case RGUI_SETTINGS_VIDEO_WINDOW_SCALE_Y: + snprintf(type_str, sizeof(type_str), "%.1fx", g_settings.video.yscale); + break; + case RGUI_SETTINGS_VIDEO_CROP_OVERSCAN: + strlcpy(type_str, g_settings.video.crop_overscan ? "ON" : "OFF", sizeof(type_str)); + break; case RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES: snprintf(type_str, sizeof(type_str), "%u", g_settings.video.hard_sync_frames); break; @@ -1510,13 +1519,20 @@ static void rgui_settings_video_options_populate_entries(rgui_handle_t *rgui) rgui_list_push(rgui->selection_buf, "Integer Scale", RGUI_SETTINGS_VIDEO_INTEGER_SCALE, 0); rgui_list_push(rgui->selection_buf, "Aspect Ratio", RGUI_SETTINGS_VIDEO_ASPECT_RATIO, 0); rgui_list_push(rgui->selection_buf, "Custom Ratio", RGUI_SETTINGS_CUSTOM_VIEWPORT, 0); +#if !defined(RARCH_CONSOLE) && !defined(RARCH_MOBILE) rgui_list_push(rgui->selection_buf, "Toggle Fullscreen", RGUI_SETTINGS_TOGGLE_FULLSCREEN, 0); +#endif rgui_list_push(rgui->selection_buf, "Rotation", RGUI_SETTINGS_VIDEO_ROTATION, 0); rgui_list_push(rgui->selection_buf, "VSync", RGUI_SETTINGS_VIDEO_VSYNC, 0); rgui_list_push(rgui->selection_buf, "Hard GPU Sync", RGUI_SETTINGS_VIDEO_HARD_SYNC, 0); rgui_list_push(rgui->selection_buf, "Hard GPU Sync Frames", RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES, 0); rgui_list_push(rgui->selection_buf, "Black Frame Insertion", RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION, 0); rgui_list_push(rgui->selection_buf, "VSync Swap Interval", RGUI_SETTINGS_VIDEO_SWAP_INTERVAL, 0); +#if !defined(RARCH_CONSOLE) && !defined(RARCH_MOBILE) + rgui_list_push(rgui->selection_buf, "Windowed Scale (X)", RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X, 0); + rgui_list_push(rgui->selection_buf, "Windowed Scale (Y)", RGUI_SETTINGS_VIDEO_WINDOW_SCALE_Y, 0); +#endif + rgui_list_push(rgui->selection_buf, "Crop Overscan (reload)", RGUI_SETTINGS_VIDEO_CROP_OVERSCAN, 0); rgui_list_push(rgui->selection_buf, "Estimated Monitor FPS", RGUI_SETTINGS_VIDEO_REFRESH_RATE_AUTO, 0); } @@ -1962,6 +1978,57 @@ static int video_option_toggle_setting(rgui_handle_t *rgui, unsigned setting, rg } break; + case RGUI_SETTINGS_VIDEO_CROP_OVERSCAN: + switch (action) + { + case RGUI_ACTION_START: + g_settings.video.crop_overscan = true; + break; + + case RGUI_ACTION_LEFT: + case RGUI_ACTION_RIGHT: + case RGUI_ACTION_OK: + g_settings.video.crop_overscan = !g_settings.video.crop_overscan; + break; + + default: + break; + } + break; + + case RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X: + case RGUI_SETTINGS_VIDEO_WINDOW_SCALE_Y: + { + float *scale = setting == RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X ? &g_settings.video.xscale : &g_settings.video.yscale; + float old_scale = *scale; + + switch (action) + { + case RGUI_ACTION_START: + *scale = 3.0f; + break; + + case RGUI_ACTION_LEFT: + *scale -= 1.0f; + break; + + case RGUI_ACTION_RIGHT: + *scale += 1.0f; + break; + + default: + break; + } + + *scale = roundf(*scale); + *scale = max(*scale, 1.0f); + + if (old_scale != *scale && !g_settings.video.fullscreen) + rarch_set_fullscreen(g_settings.video.fullscreen); // Reinit video driver. + + break; + } + case RGUI_SETTINGS_VIDEO_SWAP_INTERVAL: { unsigned old = g_settings.video.swap_interval; diff --git a/retroarch.cfg b/retroarch.cfg index ebf66a1b85..29494888c1 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -120,7 +120,7 @@ # Forces cropping of overscanned frames. # Exact behavior of this option is implementation specific. -# video_crop_overscan = false +# video_crop_overscan = true # Path to shader. Shader can be either Cg, CGP (Cg preset) or XML/GLSL format if support is enabled. # video_shader = "/path/to/shader.{cg,cgp,shader}" diff --git a/settings.c b/settings.c index fd95524334..eca070c127 100644 --- a/settings.c +++ b/settings.c @@ -976,6 +976,9 @@ bool config_save_file(const char *path) config_set_string(conf, "video_shader", g_settings.video.shader_path); config_set_bool(conf, "video_shader_enable", g_settings.video.shader_enable); config_set_float(conf, "video_aspect_ratio", g_settings.video.aspect_ratio); + config_set_float(conf, "video_xscale", g_settings.video.xscale); + config_set_float(conf, "video_yscale", g_settings.video.yscale); + config_set_bool(conf, "video_crop_overscan", g_settings.video.crop_overscan); config_set_bool(conf, "video_scale_integer", g_settings.video.scale_integer); config_set_bool(conf, "video_smooth", g_settings.video.smooth); config_set_float(conf, "video_refresh_rate", g_settings.video.refresh_rate); From 98c9da9dda0659fae2a3cc9dcde70c937dfaae3e Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 2 Sep 2013 09:20:51 +0200 Subject: [PATCH 146/202] Set swap interval correctly in gl_init(). --- gfx/gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/gl.c b/gfx/gl.c index cc622d5726..8179728f8b 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1950,7 +1950,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo context_get_video_size_func(&gl->full_x, &gl->full_y); RARCH_LOG("Detecting screen resolution %ux%u.\n", gl->full_x, gl->full_y); - context_swap_interval_func(video->vsync ? 1 : 0); + context_swap_interval_func(video->vsync ? g_settings.video.swap_interval : 0); unsigned win_width = video->width; unsigned win_height = video->height; From c16d0e54e19b2b44fd2a527587ba33d3666b2971 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Mon, 2 Sep 2013 11:50:04 +0100 Subject: [PATCH 147/202] fix xinput (again)- repair multiple pads support --- input/dinput.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/input/dinput.c b/input/dinput.c index b3e15b2e67..8343a4865a 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -423,6 +423,8 @@ static bool name_is_360_pad(const char* name) // Forward declaration static const char *dinput_joypad_name(unsigned pad); +static int g_last_xbox_pad_index; + static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) { (void)p; @@ -441,14 +443,13 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName); #ifdef HAVE_WINXINPUT - int last_xbox_pad_index = 0; bool is_360_pad = name_is_360_pad(inst->tszProductName); if (is_360_pad) { - if (last_xbox_pad_index < 4) - g_xbox_pad_indexes[g_joypad_cnt] = last_xbox_pad_index; - ++last_xbox_pad_index; + if (g_last_xbox_pad_index < 4) + g_xbox_pad_indexes[g_joypad_cnt] = g_last_xbox_pad_index; + ++g_last_xbox_pad_index; goto enum_iteration_done; } @@ -478,7 +479,9 @@ static bool dinput_joypad_init(void) { if (!dinput_init_context()) return false; - + + g_last_xbox_pad_index = 0; + for (unsigned i = 0; i < MAX_PLAYERS; ++i) { g_xbox_pad_indexes[i] = -1; From 336e1eeb51ffda3ae3999f01f26ed57074795ba6 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Mon, 2 Sep 2013 21:29:40 -0400 Subject: [PATCH 148/202] [EMSCRIPTEN] more audio fixes, revert to busywait method --- config.def.h | 2 - emscripten/RWebAudio.c | 4 +- emscripten/RWebAudio.h | 1 - emscripten/library_rwebaudio.js | 284 ++++++++++++++++---------------- frontend/frontend_emscripten.c | 5 - 5 files changed, 143 insertions(+), 153 deletions(-) diff --git a/config.def.h b/config.def.h index 3294cd73b2..32d263a623 100644 --- a/config.def.h +++ b/config.def.h @@ -338,8 +338,6 @@ static const bool rate_control = false; // Rate control delta. Defines how much rate_control is allowed to adjust input rate. #if defined(__QNX__) static const float rate_control_delta = 0.000; -#elif defined(EMSCRIPTEN) -static const float rate_control_delta = 0.002; #else static const float rate_control_delta = 0.005; #endif diff --git a/emscripten/RWebAudio.c b/emscripten/RWebAudio.c index b384c828a8..1040da32d7 100644 --- a/emscripten/RWebAudio.c +++ b/emscripten/RWebAudio.c @@ -28,8 +28,8 @@ static void *ra_init(const char *device, unsigned rate, unsigned latency) (void)device; (void)rate; void *data = RWebAudioInit(latency); - g_settings.audio.out_rate = RWebAudioSampleRate(); - RARCH_LOG("audio out rate: %u\n", g_settings.audio.out_rate); + if (data) + g_settings.audio.out_rate = RWebAudioSampleRate(); return data; } diff --git a/emscripten/RWebAudio.h b/emscripten/RWebAudio.h index fd928cd3d6..6911753923 100644 --- a/emscripten/RWebAudio.h +++ b/emscripten/RWebAudio.h @@ -26,4 +26,3 @@ void RWebAudioSetNonblockState(bool state); void RWebAudioFree(void); size_t RWebAudioWriteAvail(void); size_t RWebAudioBufferSize(void); -int RWebAudioEnoughSpace(void); diff --git a/emscripten/library_rwebaudio.js b/emscripten/library_rwebaudio.js index d2197ceccb..73448afbf9 100644 --- a/emscripten/library_rwebaudio.js +++ b/emscripten/library_rwebaudio.js @@ -1,160 +1,158 @@ //"use strict"; var LibraryRWebAudio = { - $RA__deps: ['$Browser'], - $RA: { - SCRIPTNODE_BUFFER: 1024, + $RA__deps: ['$Browser'], + $RA: { + BUFFER_SIZE: 256, - context: null, - leftBuffer: null, - rightBuffer: null, - blank: null, - scriptNode: null, - bufferNode: null, - start: 0, - end: 0, - size: 0, - lastWrite: 0, - nonblock: false, - - npot: function(n) { - n--; - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; - n++; - return n; - }, + context: null, + buffers: [], + numBuffers: 0, + bufIndex: 0, + bufOffset: 0, + startTime: 0, + nonblock: false, - process: function(e) { - var left = e.outputBuffer.getChannelData(0); - var right = e.outputBuffer.getChannelData(1); - var samples1 = RA.size; - var samples2 = 0; - samples1 = e.outputBuffer.length > samples1 ? samples1 : e.outputBuffer.length; + setStartTime: function() { + if (RA.context.currentTime) { + RA.startTime = window['performance']['now']() - RA.context.currentTime * 1000; + if (RA.startTime === 0) throw 'startTime is 0'; + Module["resumeMainLoop"](); + } else window['setTimeout'](RA.setStartTime, 0); + }, - if (samples1 + RA.start > RA.leftBuffer.length) { - samples2 = samples1 + RA.start - RA.leftBuffer.length; - samples1 = samples1 - samples2; + getCurrentPerfTime: function() { + if (RA.startTime) return (window['performance']['now']() - RA.startTime) / 1000; + else throw 'getCurrentPerfTime() called before start time set'; + }, + + process: function(queueBuffers) { + var currentTime = RA.getCurrentPerfTime(); + for (var i = 0; i < RA.bufIndex; i++) { + if (RA.buffers[i].endTime < currentTime) { + var buf = RA.buffers.splice(i, 1); + RA.buffers[RA.numBuffers - 1] = buf[0]; + i--; + RA.bufIndex--; + } + } + }, + + fillBuffer: function(buf, samples) { + var count = 0; + var leftBuffer = RA.buffers[RA.bufIndex].getChannelData(0); + var rightBuffer = RA.buffers[RA.bufIndex].getChannelData(1); + while (samples && RA.bufOffset !== RA.BUFFER_SIZE) { + leftBuffer[RA.bufOffset] = {{{ makeGetValue('buf', 'count * 8', 'float') }}}; + rightBuffer[RA.bufOffset] = {{{ makeGetValue('buf', 'count * 8 + 4', 'float') }}}; + RA.bufOffset++; + count++; + samples--; + } + + return count; + }, + + queueAudio: function() { + var index = RA.bufIndex; + + var startTime; + if (RA.bufIndex) startTime = RA.buffers[RA.bufIndex - 1].endTime; + else startTime = RA.context.currentTime; + RA.buffers[index].endTime = startTime + RA.buffers[index].duration; + + var bufferSource = RA.context.createBufferSource(); + bufferSource.buffer = RA.buffers[index]; + bufferSource.connect(RA.context.destination); + bufferSource.start(startTime); + + RA.bufIndex++; + RA.bufOffset = 0; + }, + + block: function() { + do { + RA.process(); + } while (RA.bufIndex === RA.numBuffers - 1); + } + }, + + RWebAudioInit: function(latency) { + var ac = window['AudioContext'] || window['webkitAudioContext']; + + if (!ac) return 0; + + RA.context = new ac(); + + RA.numBuffers = ((latency * RA.context.sampleRate) / (1000 * RA.BUFFER_SIZE))|0; + if (RA.numBuffers < 2) RA.numBuffers = 2; + + for (var i = 0; i < RA.numBuffers; i++) RA.buffers[i] = RA.context.createBuffer(2, RA.BUFFER_SIZE, RA.context.sampleRate); + + RA.nonblock = false; + RA.startTime = 0; + // chrome hack to get currentTime running + RA.context.createGain(); + window['setTimeout'](RA.setStartTime, 0); + Module["pauseMainLoop"](); + return 1; + }, + + RWebAudioSampleRate: function() { + return RA.context.sampleRate; + }, + + RWebAudioWrite: function (buf, size) { + RA.process(); + var samples = size / 8; + var count = 0; + + while (samples) { + var fill = RA.fillBuffer(buf, samples); + samples -= fill; + count += fill; + buf += fill * 8; + + if (RA.bufOffset === RA.BUFFER_SIZE) { + if (RA.bufIndex === RA.numBuffers - 1) { + if (RA.nonblock) break; + else RA.block(); + } + RA.queueAudio(); + } } - var remaining = e.outputBuffer.length - (samples1 + samples2); + return count * 8; + }, - if (samples1) { - left.set(RA.leftBuffer.subarray(RA.start, RA.start + samples1), 0); - right.set(RA.rightBuffer.subarray(RA.start, RA.start + samples1), 0); - } + RWebAudioStop: function() { + RA.bufIndex = 0; + RA.bufOffset = 0; + return true; + }, - if (samples2) { - left.set(RA.leftBuffer.subarray(0, samples2), samples1); - right.set(RA.rightBuffer.subarray(0, samples2), samples1); - } + RWebAudioStart: function() { + return true; + }, - /*if (remaining) { - left.set(RA.blank.subarray(0, remaining), samples1 + samples2); - right.set(RA.blank.subarray(0, remaining), samples1 + samples2); - }*/ + RWebAudioSetNonblockState: function(state) { + RA.nonblock = state; + }, - RA.start = (RA.start + samples1 + samples2) % RA.leftBuffer.length; - RA.size -= samples1 + samples2; - } - }, - - RWebAudioSampleRate: function() { - return RA.context.sampleRate; - }, + RWebAudioFree: function() { + RA.bufIndex = 0; + RA.bufOffset = 0; + return; + }, - RWebAudioInit: function(latency) { - var ac = window['AudioContext'] || window['webkitAudioContext']; - var bufferSize; + RWebAudioBufferSize: function() { + return RA.numBuffers * RA.BUFFER_SIZE + RA.BUFFER_SIZE; + }, - if (!ac) return 0; - - RA.context = new ac(); - // account for script processor overhead - latency -= 32; - // because we have to guess on how many samples the core will send when - // returning early, we double the buffer size to account for times when it - // sends more than we expect it to without losing samples - bufferSize = RA.npot(RA.context.sampleRate * latency / 1000) * 2; - RA.leftBuffer = new Float32Array(bufferSize); - RA.rightBuffer = new Float32Array(bufferSize); - RA.blank = new Float32Array(RA.SCRIPTNODE_BUFFER); - RA.bufferNode = RA.context.createBufferSource(); - RA.bufferNode.buffer = RA.context.createBuffer(2, RA.SCRIPTNODE_BUFFER, RA.context.sampleRate); - RA.bufferNode.loop = true; - RA.scriptNode = RA.context.createScriptProcessor(RA.SCRIPTNODE_BUFFER, 2, 2); - RA.scriptNode.onaudioprocess = RA.process; - RA.bufferNode.connect(RA.scriptNode); - RA.scriptNode.connect(RA.context.destination); - RA.bufferNode.start(0); - RA.start = RA.end = RA.size = 0; - RA.nonblock = false; - return 1; - }, - - RWebAudioWrite: function (buf, size) { - var samples = size / 8; - var free = RA.leftBuffer.length - RA.size; - if (free < samples) - RA.start = (RA.start + free) % RA.leftBuffer.length; - - for (var i = 0; i < samples; i++) { - RA.leftBuffer[RA.end] = {{{ makeGetValue('buf', 'i * 8', 'float') }}}; - RA.rightBuffer[RA.end] = {{{ makeGetValue('buf', 'i * 8 + 4', 'float') }}}; - RA.end = (RA.end + 1) % RA.leftBuffer.length; - } - - RA.lastWrite = size; - RA.size += samples; - return size; - }, - - RWebAudioStop: function() { - RA.scriptNode.onaudioprocess = null; - return true; - }, - - RWebAudioStart: function() { - RA.scriptNode.onaudioprocess = RA.process; - return true; - }, - - RWebAudioSetNonblockState: function(state) { - RA.nonblock = state; - }, - - RWebAudioFree: function() { - RA.scriptNode.onaudioprocess = null; - RA.start = RA.end = RA.size = RA.lastWrite = 0; - return; - }, - - RWebAudioWriteAvail: function() { - var free = (RA.leftBuffer.length / 2) - RA.size; - // 4 byte samples, 2 channels - free *= 8; - - if (free < 0) - return 0; - else - return free; - }, - - RWebAudioBufferSize: function() { - return RA.leftBuffer.length / 2; - }, - - RWebAudioEnoughSpace__deps: ['RWebAudioWriteAvail'], - RWebAudioEnoughSpace: function() { - var guess = RA.lastWrite; - var available = _RWebAudioWriteAvail(); - if (RA.nonblock) return true; - if (!guess) return true; - return (guess < available) ? 1 : 0; - } + RWebAudioWriteAvail: function() { + RA.process(); + return ((RA.numBuffers - RA.bufIndex) * RA.BUFFER_SIZE - RA.bufOffset) * 8; + } }; autoAddDeps(LibraryRWebAudio, '$RA'); diff --git a/frontend/frontend_emscripten.c b/frontend/frontend_emscripten.c index 452c7f41ea..1941e49984 100644 --- a/frontend/frontend_emscripten.c +++ b/frontend/frontend_emscripten.c @@ -56,11 +56,6 @@ static void endloop(void) static void mainloop(void) { - if (!RWebAudioEnoughSpace()) - { - return; - } - if (g_extern.system.shutdown) { endloop(); From 14f3d11dc239742db3e91dc1faaceb4a15310d8a Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Tue, 3 Sep 2013 13:30:25 +0100 Subject: [PATCH 149/202] Save input_playern_joypad_index on exit --- settings.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/settings.c b/settings.c index eca070c127..c13ad20b91 100644 --- a/settings.c +++ b/settings.c @@ -1093,6 +1093,8 @@ bool config_save_file(const char *path) config_set_int(conf, cfg, g_settings.input.dpad_emulation[i]); snprintf(cfg, sizeof(cfg), "input_device_p%u", i + 1); config_set_int(conf, cfg, g_settings.input.device[i]); + snprintf(cfg, sizeof(cfg), "input_player%u_joypad_index", i + 1); + config_set_int(conf, cfg, g_settings.input.joypad_map[i]); } config_file_write(conf, path); From cb55a1d45a673f6b23a4163238de55e3f8eb8c80 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 5 Sep 2013 01:20:56 -0400 Subject: [PATCH 150/202] (Apple) Reorganize source tree --- apple/OSX/{ => en.lproj}/InputBinder.xib | 0 apple/OSX/{ => en.lproj}/Settings.xib | 0 apple/OSX/hid_pad.c | 2 +- apple/OSX/platform.m | 2 +- apple/OSX/settings.m | 6 +-- apple/RetroArch_OSX.xcodeproj/project.pbxproj | 40 ++++++++++++++----- apple/RetroArch_iOS.xcodeproj/project.pbxproj | 6 +-- apple/{RetroArch => common}/RAGameView.m | 0 apple/{RetroArch => common}/RAModuleInfo.h | 0 apple/{RetroArch => common}/RAModuleInfo.m | 0 apple/{RetroArch => common}/RetroArch_Apple.h | 0 apple/{RetroArch => common}/apple_input.c | 0 apple/{RetroArch => common}/apple_input.h | 0 apple/{RetroArch => common}/apple_joypad.c | 12 +++--- apple/{RetroArch => common}/keycode.h | 0 apple/{RetroArch => common}/main.m | 0 apple/{RetroArch => common}/rarch_wrapper.h | 0 apple/{RetroArch => common}/setting_data.h | 0 apple/{RetroArch => common}/utility.m | 0 .../{input/BTStack => bluetooth}/btdynamic.c | 2 +- .../{input/BTStack => bluetooth}/btdynamic.h | 0 .../iOS/{input/BTStack => bluetooth}/btpad.c | 2 +- .../iOS/{input/BTStack => bluetooth}/btpad.h | 0 .../{input/BTStack => bluetooth}/btpad_ps3.c | 4 +- .../BTStack => bluetooth}/btpad_queue.c | 0 .../BTStack => bluetooth}/btpad_queue.h | 0 .../{input/BTStack => bluetooth}/btpad_wii.c | 2 +- .../BTStack => bluetooth}/btstack/btstack.h | 0 .../BTStack => bluetooth}/btstack/hci_cmds.h | 0 .../btstack/linked_list.h | 0 .../BTStack => bluetooth}/btstack/run_loop.h | 0 .../BTStack => bluetooth}/btstack/sdp_util.h | 0 .../BTStack => bluetooth}/btstack/utils.h | 0 .../{input/BTStack => bluetooth}/wiimote.c | 0 .../{input/BTStack => bluetooth}/wiimote.h | 0 apple/iOS/browser.m | 2 +- apple/iOS/platform.m | 8 ++-- apple/iOS/settings.m | 10 ++--- frontend/platform/platform_apple.c | 2 +- gfx/context/apple_gl_ctx.c | 2 +- griffin/griffin.c | 4 +- 41 files changed, 62 insertions(+), 44 deletions(-) rename apple/OSX/{ => en.lproj}/InputBinder.xib (100%) rename apple/OSX/{ => en.lproj}/Settings.xib (100%) rename apple/{RetroArch => common}/RAGameView.m (100%) rename apple/{RetroArch => common}/RAModuleInfo.h (100%) rename apple/{RetroArch => common}/RAModuleInfo.m (100%) rename apple/{RetroArch => common}/RetroArch_Apple.h (100%) rename apple/{RetroArch => common}/apple_input.c (100%) rename apple/{RetroArch => common}/apple_input.h (100%) rename apple/{RetroArch => common}/apple_joypad.c (89%) rename apple/{RetroArch => common}/keycode.h (100%) rename apple/{RetroArch => common}/main.m (100%) rename apple/{RetroArch => common}/rarch_wrapper.h (100%) rename apple/{RetroArch => common}/setting_data.h (100%) rename apple/{RetroArch => common}/utility.m (100%) rename apple/iOS/{input/BTStack => bluetooth}/btdynamic.c (98%) rename apple/iOS/{input/BTStack => bluetooth}/btdynamic.h (100%) rename apple/iOS/{input/BTStack => bluetooth}/btpad.c (99%) rename apple/iOS/{input/BTStack => bluetooth}/btpad.h (100%) rename apple/iOS/{input/BTStack => bluetooth}/btpad_ps3.c (97%) rename apple/iOS/{input/BTStack => bluetooth}/btpad_queue.c (100%) rename apple/iOS/{input/BTStack => bluetooth}/btpad_queue.h (100%) rename apple/iOS/{input/BTStack => bluetooth}/btpad_wii.c (98%) rename apple/iOS/{input/BTStack => bluetooth}/btstack/btstack.h (100%) rename apple/iOS/{input/BTStack => bluetooth}/btstack/hci_cmds.h (100%) rename apple/iOS/{input/BTStack => bluetooth}/btstack/linked_list.h (100%) rename apple/iOS/{input/BTStack => bluetooth}/btstack/run_loop.h (100%) rename apple/iOS/{input/BTStack => bluetooth}/btstack/sdp_util.h (100%) rename apple/iOS/{input/BTStack => bluetooth}/btstack/utils.h (100%) rename apple/iOS/{input/BTStack => bluetooth}/wiimote.c (100%) rename apple/iOS/{input/BTStack => bluetooth}/wiimote.h (100%) diff --git a/apple/OSX/InputBinder.xib b/apple/OSX/en.lproj/InputBinder.xib similarity index 100% rename from apple/OSX/InputBinder.xib rename to apple/OSX/en.lproj/InputBinder.xib diff --git a/apple/OSX/Settings.xib b/apple/OSX/en.lproj/Settings.xib similarity index 100% rename from apple/OSX/Settings.xib rename to apple/OSX/en.lproj/Settings.xib diff --git a/apple/OSX/hid_pad.c b/apple/OSX/hid_pad.c index 59904f8996..cd0ec238ab 100644 --- a/apple/OSX/hid_pad.c +++ b/apple/OSX/hid_pad.c @@ -14,7 +14,7 @@ */ #include -#include "../RetroArch/apple_input.h" +#include "apple/common/apple_input.h" // NOTE: I pieced this together through trial and error, any corrections are welcome diff --git a/apple/OSX/platform.m b/apple/OSX/platform.m index c860edeac0..38b641e801 100644 --- a/apple/OSX/platform.m +++ b/apple/OSX/platform.m @@ -18,7 +18,7 @@ #import "RetroArch_Apple.h" #include "rarch_wrapper.h" -#include "../RetroArch/apple_input.h" +#include "apple/common/apple_input.h" // If USE_XATTR is defined any loaded file will get a com.RetroArch.Core extended attribute // specifying which core was used to load. diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 1bf695befc..6b20a58357 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -14,9 +14,9 @@ */ #import -#import "../RetroArch/RetroArch_Apple.h" -#include "../RetroArch/setting_data.h" -#include "../RetroArch/apple_input.h" +#import "apple/common/RetroArch_Apple.h" +#include "apple/common/setting_data.h" +#include "apple/common/apple_input.h" #include "driver.h" #include "input/input_common.h" diff --git a/apple/RetroArch_OSX.xcodeproj/project.pbxproj b/apple/RetroArch_OSX.xcodeproj/project.pbxproj index 217f63a153..c70055652d 100644 --- a/apple/RetroArch_OSX.xcodeproj/project.pbxproj +++ b/apple/RetroArch_OSX.xcodeproj/project.pbxproj @@ -8,11 +8,11 @@ /* Begin PBXBuildFile section */ 9620F663178FD4D3001B3B81 /* settings.m in Sources */ = {isa = PBXBuildFile; fileRef = 9620F662178FD4D3001B3B81 /* settings.m */; }; - 9620F6651790004F001B3B81 /* Settings.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9620F6641790004F001B3B81 /* Settings.xib */; }; 962EE0E2178B3DF6004224FF /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 962EE0E1178B3DF6004224FF /* IOKit.framework */; }; 96355CE31788E72A0010DBFA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96355CE21788E72A0010DBFA /* Cocoa.framework */; }; 9646869817BBC14E00C5EA69 /* platform.m in Sources */ = {isa = PBXBuildFile; fileRef = 9646869617BBC14E00C5EA69 /* platform.m */; }; - 965A44C817CC114D0086F78F /* InputBinder.xib in Resources */ = {isa = PBXBuildFile; fileRef = 965A44C717CC114D0086F78F /* InputBinder.xib */; }; + 964DE7C117D84B34001CBB6C /* InputBinder.xib in Resources */ = {isa = PBXBuildFile; fileRef = 964DE7C317D84B34001CBB6C /* InputBinder.xib */; }; + 964DE7C417D84B57001CBB6C /* Settings.xib in Resources */ = {isa = PBXBuildFile; fileRef = 964DE7C617D84B57001CBB6C /* Settings.xib */; }; 967894931788ECDB00D6CA69 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9678948F1788ECDB00D6CA69 /* InfoPlist.strings */; }; 967894941788ECDB00D6CA69 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 967894911788ECDB00D6CA69 /* MainMenu.xib */; }; 967894961788ED1100D6CA69 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 967894951788ED1100D6CA69 /* main.m */; }; @@ -30,7 +30,6 @@ /* Begin PBXFileReference section */ 9620F662178FD4D3001B3B81 /* settings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = settings.m; path = OSX/settings.m; sourceTree = SOURCE_ROOT; }; - 9620F6641790004F001B3B81 /* Settings.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = Settings.xib; path = OSX/Settings.xib; sourceTree = ""; }; 962EE0E1178B3DF6004224FF /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = ../../../../../../../System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; 96355CDF1788E72A0010DBFA /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96355CE21788E72A0010DBFA /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; @@ -39,7 +38,8 @@ 96355CE71788E72A0010DBFA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 9646869617BBC14E00C5EA69 /* platform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = platform.m; path = OSX/platform.m; sourceTree = SOURCE_ROOT; }; 9646869717BBC14E00C5EA69 /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = platform.h; path = OSX/platform.h; sourceTree = SOURCE_ROOT; }; - 965A44C717CC114D0086F78F /* InputBinder.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = InputBinder.xib; path = OSX/InputBinder.xib; sourceTree = ""; }; + 964DE7C217D84B34001CBB6C /* en */ = {isa = PBXFileReference; lastKnownFileType = file; name = en; path = en.lproj/InputBinder.xib; sourceTree = ""; }; + 964DE7C517D84B57001CBB6C /* en */ = {isa = PBXFileReference; lastKnownFileType = file; name = en; path = en.lproj/Settings.xib; sourceTree = ""; }; 9678948D1788ECCA00D6CA69 /* RetroArch-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "RetroArch-Info.plist"; path = "OSX/RetroArch-Info.plist"; sourceTree = SOURCE_ROOT; }; 967894901788ECDB00D6CA69 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = OSX/en.lproj/InfoPlist.strings; sourceTree = SOURCE_ROOT; }; 967894921788ECDB00D6CA69 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = OSX/en.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; }; @@ -80,7 +80,7 @@ isa = PBXGroup; children = ( 962EE0E1178B3DF6004224FF /* IOKit.framework */, - 96355CE81788E72A0010DBFA /* RetroArch */, + 96355CE81788E72A0010DBFA /* common */, 967894E7178A2E9B00D6CA69 /* Assets */, 96355CE11788E72A0010DBFA /* Frameworks */, 96355CE01788E72A0010DBFA /* Products */, @@ -111,7 +111,7 @@ name = Frameworks; sourceTree = ""; }; - 96355CE81788E72A0010DBFA /* RetroArch */ = { + 96355CE81788E72A0010DBFA /* common */ = { isa = PBXGroup; children = ( 9646869617BBC14E00C5EA69 /* platform.m */, @@ -126,7 +126,7 @@ 9678949C1788F02600D6CA69 /* utility.m */, 967894951788ED1100D6CA69 /* main.m */, ); - path = RetroArch; + path = common; sourceTree = ""; }; 96355CE91788E72A0010DBFA /* Supporting Files */ = { @@ -145,8 +145,8 @@ 967894E8178A2EB400D6CA69 /* modules */, 967894911788ECDB00D6CA69 /* MainMenu.xib */, C15874EE178F2094001171D4 /* RetroArch.icns */, - 9620F6641790004F001B3B81 /* Settings.xib */, - 965A44C717CC114D0086F78F /* InputBinder.xib */, + 964DE7C617D84B57001CBB6C /* Settings.xib */, + 964DE7C317D84B34001CBB6C /* InputBinder.xib */, ); name = Assets; sourceTree = ""; @@ -205,8 +205,8 @@ 967894941788ECDB00D6CA69 /* MainMenu.xib in Resources */, 967894E9178A2EB400D6CA69 /* modules in Resources */, C15874EF178F2094001171D4 /* RetroArch.icns in Resources */, - 9620F6651790004F001B3B81 /* Settings.xib in Resources */, - 965A44C817CC114D0086F78F /* InputBinder.xib in Resources */, + 964DE7C417D84B57001CBB6C /* Settings.xib in Resources */, + 964DE7C117D84B34001CBB6C /* InputBinder.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -230,6 +230,24 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ + 964DE7C317D84B34001CBB6C /* InputBinder.xib */ = { + isa = PBXVariantGroup; + children = ( + 964DE7C217D84B34001CBB6C /* en */, + ); + name = InputBinder.xib; + path = OSX; + sourceTree = ""; + }; + 964DE7C617D84B57001CBB6C /* Settings.xib */ = { + isa = PBXVariantGroup; + children = ( + 964DE7C517D84B57001CBB6C /* en */, + ); + name = Settings.xib; + path = OSX; + sourceTree = ""; + }; 9678948F1788ECDB00D6CA69 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( diff --git a/apple/RetroArch_iOS.xcodeproj/project.pbxproj b/apple/RetroArch_iOS.xcodeproj/project.pbxproj index f959691eb8..a603b05390 100644 --- a/apple/RetroArch_iOS.xcodeproj/project.pbxproj +++ b/apple/RetroArch_iOS.xcodeproj/project.pbxproj @@ -120,7 +120,7 @@ 96AFAE1A16C1D4EA009DE44C = { isa = PBXGroup; children = ( - 96AFAE3316C1D4EA009DE44C /* RetroArch */, + 96AFAE3316C1D4EA009DE44C /* common */, 96AFAE9C16C1D976009DE44C /* core */, 966B9CB716E41E7A005B61E1 /* Assets */, 96AFAE2816C1D4EA009DE44C /* Frameworks */, @@ -151,7 +151,7 @@ name = Frameworks; sourceTree = ""; }; - 96AFAE3316C1D4EA009DE44C /* RetroArch */ = { + 96AFAE3316C1D4EA009DE44C /* common */ = { isa = PBXGroup; children = ( 9646869417BBBEAE00C5EA69 /* platform.m */, @@ -167,7 +167,7 @@ 96355CD11788CF190010DBFA /* RetroArch_Apple.h */, 96337E81176AC6E5004685F3 /* utility.m */, ); - path = RetroArch; + path = common; sourceTree = ""; }; 96AFAE3416C1D4EA009DE44C /* Supporting Files */ = { diff --git a/apple/RetroArch/RAGameView.m b/apple/common/RAGameView.m similarity index 100% rename from apple/RetroArch/RAGameView.m rename to apple/common/RAGameView.m diff --git a/apple/RetroArch/RAModuleInfo.h b/apple/common/RAModuleInfo.h similarity index 100% rename from apple/RetroArch/RAModuleInfo.h rename to apple/common/RAModuleInfo.h diff --git a/apple/RetroArch/RAModuleInfo.m b/apple/common/RAModuleInfo.m similarity index 100% rename from apple/RetroArch/RAModuleInfo.m rename to apple/common/RAModuleInfo.m diff --git a/apple/RetroArch/RetroArch_Apple.h b/apple/common/RetroArch_Apple.h similarity index 100% rename from apple/RetroArch/RetroArch_Apple.h rename to apple/common/RetroArch_Apple.h diff --git a/apple/RetroArch/apple_input.c b/apple/common/apple_input.c similarity index 100% rename from apple/RetroArch/apple_input.c rename to apple/common/apple_input.c diff --git a/apple/RetroArch/apple_input.h b/apple/common/apple_input.h similarity index 100% rename from apple/RetroArch/apple_input.h rename to apple/common/apple_input.h diff --git a/apple/RetroArch/apple_joypad.c b/apple/common/apple_joypad.c similarity index 89% rename from apple/RetroArch/apple_joypad.c rename to apple/common/apple_joypad.c index 76a8dc2853..0f5807441e 100644 --- a/apple/RetroArch/apple_joypad.c +++ b/apple/common/apple_joypad.c @@ -17,12 +17,12 @@ #include "general.h" #ifdef IOS -#include "../iOS/input/BTStack/btdynamic.c" -#include "../iOS/input/BTStack/wiimote.c" -#include "../iOS/input/BTStack/btpad.c" -#include "../iOS/input/BTStack/btpad_ps3.c" -#include "../iOS/input/BTStack/btpad_wii.c" -#include "../iOS/input/BTStack/btpad_queue.c" +#include "apple/iOS/bluetooth/btdynamic.c" +#include "apple/iOS/bluetooth/wiimote.c" +#include "apple/iOS/bluetooth/btpad.c" +#include "apple/iOS/bluetooth/btpad_ps3.c" +#include "apple/iOS/bluetooth/btpad_wii.c" +#include "apple/iOS/bluetooth/btpad_queue.c" #elif defined(OSX) #include "../OSX/hid_pad.c" #endif diff --git a/apple/RetroArch/keycode.h b/apple/common/keycode.h similarity index 100% rename from apple/RetroArch/keycode.h rename to apple/common/keycode.h diff --git a/apple/RetroArch/main.m b/apple/common/main.m similarity index 100% rename from apple/RetroArch/main.m rename to apple/common/main.m diff --git a/apple/RetroArch/rarch_wrapper.h b/apple/common/rarch_wrapper.h similarity index 100% rename from apple/RetroArch/rarch_wrapper.h rename to apple/common/rarch_wrapper.h diff --git a/apple/RetroArch/setting_data.h b/apple/common/setting_data.h similarity index 100% rename from apple/RetroArch/setting_data.h rename to apple/common/setting_data.h diff --git a/apple/RetroArch/utility.m b/apple/common/utility.m similarity index 100% rename from apple/RetroArch/utility.m rename to apple/common/utility.m diff --git a/apple/iOS/input/BTStack/btdynamic.c b/apple/iOS/bluetooth/btdynamic.c similarity index 98% rename from apple/iOS/input/BTStack/btdynamic.c rename to apple/iOS/bluetooth/btdynamic.c index 9dfa1a95b6..bfdcde2857 100644 --- a/apple/iOS/input/BTStack/btdynamic.c +++ b/apple/iOS/bluetooth/btdynamic.c @@ -17,7 +17,7 @@ #include #include -#include "../../../RetroArch/rarch_wrapper.h" +#include "apple/common/rarch_wrapper.h" #define BUILDING_BTDYNAMIC #include "btdynamic.h" diff --git a/apple/iOS/input/BTStack/btdynamic.h b/apple/iOS/bluetooth/btdynamic.h similarity index 100% rename from apple/iOS/input/BTStack/btdynamic.h rename to apple/iOS/bluetooth/btdynamic.h diff --git a/apple/iOS/input/BTStack/btpad.c b/apple/iOS/bluetooth/btpad.c similarity index 99% rename from apple/iOS/input/BTStack/btpad.c rename to apple/iOS/bluetooth/btpad.c index babb0ba3fc..0a6335df3e 100644 --- a/apple/iOS/input/BTStack/btpad.c +++ b/apple/iOS/bluetooth/btpad.c @@ -20,7 +20,7 @@ #include #include -#include "../../../RetroArch/rarch_wrapper.h" +#include "apple/common/rarch_wrapper.h" #include "btdynamic.h" #include "btpad.h" #include "btpad_queue.h" diff --git a/apple/iOS/input/BTStack/btpad.h b/apple/iOS/bluetooth/btpad.h similarity index 100% rename from apple/iOS/input/BTStack/btpad.h rename to apple/iOS/bluetooth/btpad.h diff --git a/apple/iOS/input/BTStack/btpad_ps3.c b/apple/iOS/bluetooth/btpad_ps3.c similarity index 97% rename from apple/iOS/input/BTStack/btpad_ps3.c rename to apple/iOS/bluetooth/btpad_ps3.c index e2079ef6ea..d681358e62 100644 --- a/apple/iOS/input/BTStack/btpad_ps3.c +++ b/apple/iOS/bluetooth/btpad_ps3.c @@ -18,7 +18,7 @@ #include #include "boolean.h" -#include "../../../RetroArch/rarch_wrapper.h" +#include "apple/common/rarch_wrapper.h" #include "btdynamic.h" #include "btpad.h" @@ -37,7 +37,7 @@ struct btpad_ps3_data static void btpad_ps3_send_control(struct btpad_ps3_data* device) { - // TODO: Can this be modified to turn of motion tracking? + // TODO: Can this be modified to turn off motion tracking? static uint8_t report_buffer[] = { 0x52, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/apple/iOS/input/BTStack/btpad_queue.c b/apple/iOS/bluetooth/btpad_queue.c similarity index 100% rename from apple/iOS/input/BTStack/btpad_queue.c rename to apple/iOS/bluetooth/btpad_queue.c diff --git a/apple/iOS/input/BTStack/btpad_queue.h b/apple/iOS/bluetooth/btpad_queue.h similarity index 100% rename from apple/iOS/input/BTStack/btpad_queue.h rename to apple/iOS/bluetooth/btpad_queue.h diff --git a/apple/iOS/input/BTStack/btpad_wii.c b/apple/iOS/bluetooth/btpad_wii.c similarity index 98% rename from apple/iOS/input/BTStack/btpad_wii.c rename to apple/iOS/bluetooth/btpad_wii.c index 8f4bbc569c..c8475fb4ab 100644 --- a/apple/iOS/input/BTStack/btpad_wii.c +++ b/apple/iOS/bluetooth/btpad_wii.c @@ -18,7 +18,7 @@ #include #include "boolean.h" -#include "../../../RetroArch/rarch_wrapper.h" +#include "apple/common/rarch_wrapper.h" #include "btdynamic.h" #include "btpad.h" diff --git a/apple/iOS/input/BTStack/btstack/btstack.h b/apple/iOS/bluetooth/btstack/btstack.h similarity index 100% rename from apple/iOS/input/BTStack/btstack/btstack.h rename to apple/iOS/bluetooth/btstack/btstack.h diff --git a/apple/iOS/input/BTStack/btstack/hci_cmds.h b/apple/iOS/bluetooth/btstack/hci_cmds.h similarity index 100% rename from apple/iOS/input/BTStack/btstack/hci_cmds.h rename to apple/iOS/bluetooth/btstack/hci_cmds.h diff --git a/apple/iOS/input/BTStack/btstack/linked_list.h b/apple/iOS/bluetooth/btstack/linked_list.h similarity index 100% rename from apple/iOS/input/BTStack/btstack/linked_list.h rename to apple/iOS/bluetooth/btstack/linked_list.h diff --git a/apple/iOS/input/BTStack/btstack/run_loop.h b/apple/iOS/bluetooth/btstack/run_loop.h similarity index 100% rename from apple/iOS/input/BTStack/btstack/run_loop.h rename to apple/iOS/bluetooth/btstack/run_loop.h diff --git a/apple/iOS/input/BTStack/btstack/sdp_util.h b/apple/iOS/bluetooth/btstack/sdp_util.h similarity index 100% rename from apple/iOS/input/BTStack/btstack/sdp_util.h rename to apple/iOS/bluetooth/btstack/sdp_util.h diff --git a/apple/iOS/input/BTStack/btstack/utils.h b/apple/iOS/bluetooth/btstack/utils.h similarity index 100% rename from apple/iOS/input/BTStack/btstack/utils.h rename to apple/iOS/bluetooth/btstack/utils.h diff --git a/apple/iOS/input/BTStack/wiimote.c b/apple/iOS/bluetooth/wiimote.c similarity index 100% rename from apple/iOS/input/BTStack/wiimote.c rename to apple/iOS/bluetooth/wiimote.c diff --git a/apple/iOS/input/BTStack/wiimote.h b/apple/iOS/bluetooth/wiimote.h similarity index 100% rename from apple/iOS/input/BTStack/wiimote.h rename to apple/iOS/bluetooth/wiimote.h diff --git a/apple/iOS/browser.m b/apple/iOS/browser.m index df557dda47..72ec640458 100644 --- a/apple/iOS/browser.m +++ b/apple/iOS/browser.m @@ -16,7 +16,7 @@ #include #include -#import "../RetroArch/RetroArch_Apple.h" +#import "apple/common/RetroArch_Apple.h" #import "views.h" #include "conf/config_file.h" diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index e285f65e28..22bd544d74 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -19,12 +19,12 @@ #import "RetroArch_Apple.h" #include "rarch_wrapper.h" -#include "../RetroArch/apple_input.h" +#include "apple/common/apple_input.h" #import "views.h" -#include "input/BTStack/btpad.h" -#include "input/BTStack/btdynamic.h" -#include "input/BTStack/btpad.h" +#include "bluetooth/btpad.h" +#include "bluetooth/btdynamic.h" +#include "bluetooth/btpad.h" #include "file.h" diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index ad84b67bfd..a0fbd31ff6 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -13,13 +13,13 @@ * If not, see . */ -#import "../RetroArch/RetroArch_Apple.h" +#import "apple/common/RetroArch_Apple.h" #import "views.h" -#include "../RetroArch/apple_input.h" -#include "../RetroArch/keycode.h" -#include "input/BTStack/btdynamic.h" -#include "input/BTStack/btpad.h" +#include "apple/common/apple_input.h" +#include "apple/common/keycode.h" +#include "bluetooth/btdynamic.h" +#include "bluetooth/btpad.h" enum SettingTypes { diff --git a/frontend/platform/platform_apple.c b/frontend/platform/platform_apple.c index 1f6234bd82..a35ec8a1f2 100644 --- a/frontend/platform/platform_apple.c +++ b/frontend/platform/platform_apple.c @@ -15,7 +15,7 @@ #include #include -#include "../../apple/RetroArch/rarch_wrapper.h" +#include "../../apple/common/rarch_wrapper.h" #include "../frontend_context.h" diff --git a/gfx/context/apple_gl_ctx.c b/gfx/context/apple_gl_ctx.c index 29d0bfeb35..a54e875ee6 100644 --- a/gfx/context/apple_gl_ctx.c +++ b/gfx/context/apple_gl_ctx.c @@ -25,7 +25,7 @@ #include "../shader_glsl.h" #endif -#include "../../apple/RetroArch/rarch_wrapper.h" +#include "../../apple/common/rarch_wrapper.h" static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor) { diff --git a/griffin/griffin.c b/griffin/griffin.c index cbb9cc1f0e..5ff04b6ea9 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -298,8 +298,8 @@ INPUT #include "../android/native/jni/input_autodetect.c" #include "../android/native/jni/input_android.c" #elif defined(IOS) || defined(OSX) -#include "../apple/RetroArch/apple_input.c" -#include "../apple/RetroArch/apple_joypad.c" +#include "../apple/common/apple_input.c" +#include "../apple/common/apple_joypad.c" #elif defined(__BLACKBERRY_QNX__) #include "../blackberry-qnx/qnx_input.c" #endif From 21388592ea1acf37f32dac5392b4590be82b0b2b Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 5 Sep 2013 11:38:00 -0400 Subject: [PATCH 151/202] (Overlay) Add basic analog support --- driver.h | 1 + input/overlay.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- retroarch.c | 7 +++++++ 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/driver.h b/driver.h index 026a6df0b4..e2e5244097 100644 --- a/driver.h +++ b/driver.h @@ -463,6 +463,7 @@ typedef struct driver #ifdef HAVE_OVERLAY input_overlay_t *overlay; uint64_t overlay_state; + int16_t overlay_analog_state[4]; #endif // Interface for "poking". diff --git a/input/overlay.c b/input/overlay.c index 9696fa5767..53a7e5c9a1 100644 --- a/input/overlay.c +++ b/input/overlay.c @@ -31,6 +31,13 @@ enum overlay_hitbox OVERLAY_HITBOX_RECT }; +enum overlay_type +{ + OVERLAY_TYPE_BUTTONS = 0, + OVERLAY_TYPE_ANALOG_LEFT, + OVERLAY_TYPE_ANALOG_RIGHT +}; + struct overlay_desc { float x; @@ -39,6 +46,7 @@ struct overlay_desc enum overlay_hitbox hitbox; float range_x, range_y; + enum overlay_type type; uint64_t key_mask; unsigned next_index; @@ -234,14 +242,23 @@ static bool input_overlay_load_desc(config_file_t *conf, struct overlay_desc *de char *key = list->elems[0].data; char *save; desc->key_mask = 0; - for (const char *tmp = strtok_r(key, "|", &save); tmp; tmp = strtok_r(NULL, "|", &save)) - desc->key_mask |= UINT64_C(1) << input_str_to_bind(tmp); - if (desc->key_mask & (UINT64_C(1) << RARCH_OVERLAY_NEXT)) + if (strcmp(key, "analog_left") == 0) + desc->type = OVERLAY_TYPE_ANALOG_LEFT; + else if (strcmp(key, "analog_right") == 0) + desc->type = OVERLAY_TYPE_ANALOG_RIGHT; + else { - char overlay_target_key[64]; - snprintf(overlay_target_key, sizeof(overlay_target_key), "overlay%u_desc%u_next_target", ol_index, desc_index); - config_get_array(conf, overlay_target_key, desc->next_index_name, sizeof(desc->next_index_name)); + desc->type = OVERLAY_TYPE_BUTTONS; + for (const char *tmp = strtok_r(key, "|", &save); tmp; tmp = strtok_r(NULL, "|", &save)) + desc->key_mask |= UINT64_C(1) << input_str_to_bind(tmp); + + if (desc->key_mask & (UINT64_C(1) << RARCH_OVERLAY_NEXT)) + { + char overlay_target_key[64]; + snprintf(overlay_target_key, sizeof(overlay_target_key), "overlay%u_desc%u_next_target", ol_index, desc_index); + config_get_array(conf, overlay_target_key, desc->next_index_name, sizeof(desc->next_index_name)); + } } desc->x = strtod(x, NULL) / width; @@ -258,6 +275,13 @@ static bool input_overlay_load_desc(config_file_t *conf, struct overlay_desc *de goto end; } + if (desc->hitbox != OVERLAY_HITBOX_RADIAL && desc->type != OVERLAY_TYPE_BUTTONS) + { + RARCH_ERR("[Overlay]: Analog hitbox type must be \"radial\".\n"); + ret = false; + goto end; + } + desc->range_x = strtod(list->elems[4].data, NULL) / width; desc->range_y = strtod(list->elems[5].data, NULL) / height; @@ -550,7 +574,10 @@ uint64_t input_overlay_poll(input_overlay_t *ol, int16_t norm_x, int16_t norm_y) uint64_t state = 0; for (size_t i = 0; i < ol->active->size; i++) { - if (inside_hitbox(&ol->active->descs[i], x, y)) + if (!inside_hitbox(&ol->active->descs[i], x, y)) + continue; + + if (ol->active->descs[i].type == OVERLAY_TYPE_BUTTONS) { uint64_t mask = ol->active->descs[i].key_mask; state |= mask; @@ -558,6 +585,14 @@ uint64_t input_overlay_poll(input_overlay_t *ol, int16_t norm_x, int16_t norm_y) if (mask & (UINT64_C(1) << RARCH_OVERLAY_NEXT)) ol->next_index = ol->active->descs[i].next_index; } + else + { + float tgt_x = (x - ol->active->descs[i].x) / ol->active->descs[i].range_x; + float tgt_y = (y - ol->active->descs[i].y) / ol->active->descs[i].range_y; + unsigned base = (ol->active->descs[i].type == OVERLAY_TYPE_ANALOG_RIGHT) ? 2 : 0; + driver.overlay_analog_state[base + 0] = tgt_x * 32767.0f; + driver.overlay_analog_state[base + 1] = tgt_y * 32767.0f; + } } if (!state) diff --git a/retroarch.c b/retroarch.c index e759fc99f4..a5d88d8e12 100644 --- a/retroarch.c +++ b/retroarch.c @@ -462,6 +462,7 @@ size_t audio_sample_batch(const int16_t *data, size_t frames) static inline void input_poll_overlay(void) { driver.overlay_state = 0; + memset(driver.overlay_analog_state, 0, sizeof(driver.overlay_analog_state)); unsigned device = input_overlay_full_screen(driver.overlay) ? RARCH_DEVICE_POINTER_SCREEN : RETRO_DEVICE_POINTER; @@ -544,6 +545,12 @@ static int16_t input_state(unsigned port, unsigned device, unsigned index, unsig #ifdef HAVE_OVERLAY if (device == RETRO_DEVICE_JOYPAD && port == 0) res |= driver.overlay_state & (UINT64_C(1) << id) ? 1 : 0; + else if (device == RETRO_DEVICE_ANALOG && port == 0) + { + unsigned base = (index == RETRO_DEVICE_INDEX_ANALOG_RIGHT) ? 2 : 0; + base += (id == RETRO_DEVICE_ID_ANALOG_Y) ? 1 : 0; + res += driver.overlay_analog_state[base]; + } #endif // Don't allow turbo for D-pad. From d031d38e49fb082c90212d5c63f203bdd4a47afa Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 5 Sep 2013 13:03:37 -0400 Subject: [PATCH 152/202] (OSX) Set player ID LEDs on connected PS3 pads --- apple/OSX/hid_pad.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/apple/OSX/hid_pad.c b/apple/OSX/hid_pad.c index cd0ec238ab..d4d0a472f6 100644 --- a/apple/OSX/hid_pad.c +++ b/apple/OSX/hid_pad.c @@ -96,6 +96,32 @@ static void hid_device_attached(void* inContext, IOReturn inResult, void* inSend IOHIDDeviceOpen(inDevice, kIOHIDOptionsTypeNone); IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); IOHIDDeviceRegisterInputValueCallback(inDevice, hid_input_callback, context); + + // Set PS3 LEDs + CFStringRef device_name = IOHIDDeviceGetProperty(inDevice, CFSTR(kIOHIDProductKey)); + if (!device_name) + return; + + char buffer[1024]; + CFStringGetCString(device_name, buffer, 1024, kCFStringEncodingUTF8); + if (strncmp(buffer, "PLAYSTATION(R)3 Controller", 1024) == 0) + { + static uint8_t report_buffer[] = { + 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + report_buffer[10] = 1 << (((int)context) + 1); + + IOHIDDeviceSetReport(inDevice, kIOHIDReportTypeOutput, 0x01, report_buffer, sizeof(report_buffer)); + } } static void hid_device_removed(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice) From 20001489ac650401e4d2445c1a08ef63f27a97d2 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 5 Sep 2013 14:38:40 -0400 Subject: [PATCH 153/202] (OSX) Update gfx_context: Now resizes window when asked Displays proper title in window No longen prints Cocoa warning at start up Now supports the pause_nonactive feature --- apple/common/RAGameView.m | 49 +++++++++++++++++++++++++++++++++--- apple/common/rarch_wrapper.h | 4 ++- gfx/context/apple_gl_ctx.c | 29 +++------------------ 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/apple/common/RAGameView.m b/apple/common/RAGameView.m index 5064083985..8cd78a9b2f 100644 --- a/apple/common/RAGameView.m +++ b/apple/common/RAGameView.m @@ -33,6 +33,7 @@ static UIView* g_pause_indicator_view; #include "apple_input.h" +static bool g_has_went_fullscreen; static RAGameView* g_instance; static NSOpenGLContext* g_context; static NSOpenGLPixelFormat* g_format; @@ -312,10 +313,38 @@ void *apple_get_proc_address(const char *symbol_name) #endif } +void apple_update_window_title(void) +{ + static char buf[128]; + bool got_text = gfx_get_fps(buf, sizeof(buf), false); +#ifdef OSX + static const char* const text = buf; // < Can't access buf directly in the block + + if (got_text) + { + // NOTE: This could go bad if buf is updated again before this completes. + // If it poses a problem it should be changed to dispatch_sync. + dispatch_async(dispatch_get_main_queue(), ^ + { + g_view.window.title = @(text); + }); + } +#endif +} + +bool apple_game_view_has_focus(void) +{ +#ifdef OSX + return [NSApp isActive]; +#else + return true; +#endif +} + bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) { __block bool result = true; - + #ifdef OSX dispatch_sync(dispatch_get_main_queue(), ^{ @@ -323,12 +352,24 @@ bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) // TODO: Sceen mode support if (fullscreen) - result = [g_view enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; + { + if (!g_has_went_fullscreen) + result = [g_view enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; + g_has_went_fullscreen = true; + } else { - [g_view exitFullScreenModeWithOptions:nil]; - [g_view.window makeFirstResponder:g_view]; + if (g_has_went_fullscreen) + { + [g_view exitFullScreenModeWithOptions:nil]; + [g_view.window makeFirstResponder:g_view]; + } + g_has_went_fullscreen = false; + + [g_view.window setContentSize:NSMakeSize(width, height)]; } + + g_has_went_fullscreen = fullscreen; }); #endif diff --git a/apple/common/rarch_wrapper.h b/apple/common/rarch_wrapper.h index 3537360da5..92bce93c5e 100644 --- a/apple/common/rarch_wrapper.h +++ b/apple/common/rarch_wrapper.h @@ -23,13 +23,15 @@ char* ios_get_rarch_system_directory(); // These functions should only be called as arguments to dispatch_sync void apple_rarch_exited (void* result); -// These functions must only be called in gfx/context/ioseagl_ctx.c +// These functions must only be called in gfx/context/apple_gl_context.c bool apple_init_game_view(void); void apple_destroy_game_view(void); bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen); void apple_flip_game_view(void); void apple_set_game_view_sync(unsigned interval); void apple_get_game_view_size(unsigned *width, unsigned *height); +void apple_update_window_title(void); +bool apple_game_view_has_focus(void); void *apple_get_proc_address(const char *symbol_name); #ifdef IOS diff --git a/gfx/context/apple_gl_ctx.c b/gfx/context/apple_gl_ctx.c index a54e875ee6..fb7e6333aa 100644 --- a/gfx/context/apple_gl_ctx.c +++ b/gfx/context/apple_gl_ctx.c @@ -38,19 +38,6 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned mino #endif } -static bool gfx_ctx_set_video_mode( - unsigned width, unsigned height, - bool fullscreen) -{ - return apple_set_video_mode(width, height, fullscreen); -} - -static void gfx_ctx_update_window_title(void) -{ - char buf[128]; - gfx_get_fps(buf, sizeof(buf), false); -} - static void gfx_ctx_check_window(bool *quit, bool *resize, unsigned *width, unsigned *height, unsigned frame_count) { @@ -74,16 +61,6 @@ static void gfx_ctx_set_resize(unsigned width, unsigned height) (void)height; } -static bool gfx_ctx_has_focus(void) -{ - return true; -} - -static void gfx_ctx_swap_buffers(void) -{ - apple_flip_game_view(); -} - static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data) { *input = NULL; @@ -102,13 +79,13 @@ const gfx_ctx_driver_t gfx_ctx_apple = { apple_destroy_game_view, gfx_ctx_bind_api, apple_set_game_view_sync, - gfx_ctx_set_video_mode, + apple_set_video_mode, apple_get_game_view_size, NULL, - gfx_ctx_update_window_title, + apple_update_window_title, gfx_ctx_check_window, gfx_ctx_set_resize, - gfx_ctx_has_focus, + apple_game_view_has_focus, apple_flip_game_view, gfx_ctx_input_driver, gfx_ctx_get_proc_address, From 8fd84fa46cb2f1a0bb1c179f55ce9428ce249b59 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Wed, 4 Sep 2013 21:57:13 +0100 Subject: [PATCH 154/202] Hardcoded joypad config fallbacks, and required changes to config_file --- Makefile.win | 1 + conf/config_file.c | 56 ++++++++ conf/config_file.h | 2 + input/autoconf_builtin.c | 153 ++++++++++++++++++++++ input/input_common.c | 53 ++++++-- input/input_common.h | 2 + msvc/msvc-2010/RetroArch-msvc2010.vcxproj | 2 + 7 files changed, 261 insertions(+), 8 deletions(-) create mode 100644 input/autoconf_builtin.c diff --git a/Makefile.win b/Makefile.win index 635e573ff4..f4ea879abf 100644 --- a/Makefile.win +++ b/Makefile.win @@ -17,6 +17,7 @@ OBJ = frontend/frontend.o \ movie.o \ gfx/gfx_common.o \ input/input_common.o \ + input/autoconf_builtin.o \ core_options.o \ patch.o \ compat/compat.o \ diff --git a/conf/config_file.c b/conf/config_file.c index 8fcbd92ceb..7ecf97e60a 100644 --- a/conf/config_file.c +++ b/conf/config_file.c @@ -355,6 +355,62 @@ static config_file_t *config_file_new_internal(const char *path, unsigned depth) return conf; } +config_file_t *config_file_new_from_string(const char *from_string) +{ + struct config_file *conf = (struct config_file*)calloc(1, sizeof(*conf)); + if (!conf) + return NULL; + + if (!from_string) + return conf; + + conf->path = NULL; + + conf->include_depth = 0; + + size_t pos = 0; + size_t len = strlen(from_string); + + while (pos < len) + { + struct config_entry_list *list = (struct config_entry_list*)calloc(1, sizeof(*list)); + + size_t next_newline_pos = strchr(from_string + pos, '\n') - (char*)from_string; + if (next_newline_pos > len) + next_newline_pos = len; + size_t line_len = next_newline_pos - pos; + char *line = (char*)malloc(line_len + 1); + strncpy(line, from_string+pos, line_len); + line[line_len] = '\0'; + + if (line) + { + if (parse_line(conf, list, line)) + { + if (conf->entries) + { + conf->tail->next = list; + conf->tail = list; + } + else + { + conf->entries = list; + conf->tail = list; + } + } + + free(line); + } + + if (list != conf->tail) + free(list); + + pos += line_len + 1; + } + + return conf; +} + config_file_t *config_file_new(const char *path) { return config_file_new_internal(path, 0); diff --git a/conf/config_file.h b/conf/config_file.h index 8ae7554181..ad366e84ca 100644 --- a/conf/config_file.h +++ b/conf/config_file.h @@ -41,6 +41,8 @@ typedef struct config_file config_file_t; // Loads a config file. Returns NULL if file doesn't exist. // NULL path will create an empty config file. config_file_t *config_file_new(const char *path); +// Load a config file from a string. +config_file_t *config_file_new_from_string(const char *from_string); // Frees config file. void config_file_free(config_file_t *conf); diff --git a/input/autoconf_builtin.c b/input/autoconf_builtin.c new file mode 100644 index 0000000000..fea7a4ce91 --- /dev/null +++ b/input/autoconf_builtin.c @@ -0,0 +1,153 @@ +#include "input_common.h" + +// Some hardcoded autoconfig information. Will be used for pads with no autoconfig cfg files. +// All 4 almost-identical 360 pads are included, could be reduced with some fiddling. +const char* const input_builtin_autoconfs[] = +{ +"\ +input_device = \"XInput Controller (Player 1)\" \n\ +input_driver = \"winxinput\" \n\ +input_b_btn = \"0\" \n\ +input_y_btn = \"2\" \n\ +input_select_btn = \"7\" \n\ +input_start_btn = \"6\" \n\ +input_up_btn = \"h0up\" \n\ +input_down_btn = \"h0down\" \n\ +input_left_btn = \"h0left\" \n\ +input_right_btn = \"h0right\" \n\ +input_a_btn = \"1\" \n\ +input_x_btn = \"3\" \n\ +input_l_btn = \"4\" \n\ +input_r_btn = \"5\" \n\ +input_l2_axis = \"+4\" \n\ +input_r2_axis = \"+5\" \n\ +input_l3_btn = \"8\" \n\ +input_r3_btn = \"9\" \n\ +input_l_x_plus_axis = \"+0\" \n\ +input_l_x_minus_axis = \"-0\" \n\ +input_l_y_plus_axis = \"-1\" \n\ +input_l_y_minus_axis = \"+1\" \n\ +input_r_x_plus_axis = \"+2\" \n\ +input_r_x_minus_axis = \"-2\" \n\ +input_r_y_plus_axis = \"-3\" \n\ +input_r_y_minus_axis = \"+3\" \n\ +", + +"\ +input_device = \"XInput Controller (Player 2)\" \n\ +input_driver = \"winxinput\" \n\ +input_b_btn = \"0\" \n\ +input_y_btn = \"2\" \n\ +input_select_btn = \"7\" \n\ +input_start_btn = \"6\" \n\ +input_up_btn = \"h0up\" \n\ +input_down_btn = \"h0down\" \n\ +input_left_btn = \"h0left\" \n\ +input_right_btn = \"h0right\" \n\ +input_a_btn = \"1\" \n\ +input_x_btn = \"3\" \n\ +input_l_btn = \"4\" \n\ +input_r_btn = \"5\" \n\ +input_l2_axis = \"+4\" \n\ +input_r2_axis = \"+5\" \n\ +input_l3_btn = \"8\" \n\ +input_r3_btn = \"9\" \n\ +input_l_x_plus_axis = \"+0\" \n\ +input_l_x_minus_axis = \"-0\" \n\ +input_l_y_plus_axis = \"-1\" \n\ +input_l_y_minus_axis = \"+1\" \n\ +input_r_x_plus_axis = \"+2\" \n\ +input_r_x_minus_axis = \"-2\" \n\ +input_r_y_plus_axis = \"-3\" \n\ +input_r_y_minus_axis = \"+3\" \n\ +", + +"\ +input_device = \"XInput Controller (Player 3)\" \n\ +input_driver = \"winxinput\" \n\ +input_b_btn = \"0\" \n\ +input_y_btn = \"2\" \n\ +input_select_btn = \"7\" \n\ +input_start_btn = \"6\" \n\ +input_up_btn = \"h0up\" \n\ +input_down_btn = \"h0down\" \n\ +input_left_btn = \"h0left\" \n\ +input_right_btn = \"h0right\" \n\ +input_a_btn = \"1\" \n\ +input_x_btn = \"3\" \n\ +input_l_btn = \"4\" \n\ +input_r_btn = \"5\" \n\ +input_l2_axis = \"+4\" \n\ +input_r2_axis = \"+5\" \n\ +input_l3_btn = \"8\" \n\ +input_r3_btn = \"9\" \n\ +input_l_x_plus_axis = \"+0\" \n\ +input_l_x_minus_axis = \"-0\" \n\ +input_l_y_plus_axis = \"-1\" \n\ +input_l_y_minus_axis = \"+1\" \n\ +input_r_x_plus_axis = \"+2\" \n\ +input_r_x_minus_axis = \"-2\" \n\ +input_r_y_plus_axis = \"-3\" \n\ +input_r_y_minus_axis = \"+3\" \n\ +", + +"\ +input_device = \"XInput Controller (Player 4)\" \n\ +input_driver = \"winxinput\" \n\ +input_b_btn = \"0\" \n\ +input_y_btn = \"2\" \n\ +input_select_btn = \"7\" \n\ +input_start_btn = \"6\" \n\ +input_up_btn = \"h0up\" \n\ +input_down_btn = \"h0down\" \n\ +input_left_btn = \"h0left\" \n\ +input_right_btn = \"h0right\" \n\ +input_a_btn = \"1\" \n\ +input_x_btn = \"3\" \n\ +input_l_btn = \"4\" \n\ +input_r_btn = \"5\" \n\ +input_l2_axis = \"+4\" \n\ +input_r2_axis = \"+5\" \n\ +input_l3_btn = \"8\" \n\ +input_r3_btn = \"9\" \n\ +input_l_x_plus_axis = \"+0\" \n\ +input_l_x_minus_axis = \"-0\" \n\ +input_l_y_plus_axis = \"-1\" \n\ +input_l_y_minus_axis = \"+1\" \n\ +input_r_x_plus_axis = \"+2\" \n\ +input_r_x_minus_axis = \"-2\" \n\ +input_r_y_plus_axis = \"-3\" \n\ +input_r_y_minus_axis = \"+3\" \n\ +", + +"\ +input_device = \"Dual Trigger 3-in-1\" \n\ +input_driver = \"dinput\" \n\ +input_b_btn = \"1\" \n\ +input_y_btn = \"0\" \n\ +input_select_btn = \"8\" \n\ +input_start_btn = \"9\" \n\ +input_up_btn = \"h0up\" \n\ +input_down_btn = \"h0down\" \n\ +input_left_btn = \"h0left\" \n\ +input_right_btn = \"h0right\" \n\ +input_a_btn = \"2\" \n\ +input_x_btn = \"3\" \n\ +input_l_btn = \"4\" \n\ +input_r_btn = \"5\" \n\ +input_l2_btn = \"6\" \n\ +input_r2_btn = \"7\" \n\ +input_l3_btn = \"10\" \n\ +input_r3_btn = \"11\" \n\ +input_l_x_plus_axis = \"+0\" \n\ +input_l_x_minus_axis = \"-0\" \n\ +input_l_y_plus_axis = \"+1\" \n\ +input_l_y_minus_axis = \"-1\" \n\ +input_r_x_plus_axis = \"+2\" \n\ +input_r_x_minus_axis = \"-2\" \n\ +input_r_y_plus_axis = \"+5\" \n\ +input_r_y_minus_axis = \"-5\" \n\ +", + +NULL +}; diff --git a/input/input_common.c b/input/input_common.c index fb799e3884..52b1f2a67f 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -829,25 +829,23 @@ void input_config_autoconfigure_joypad(unsigned index, const char *name, const c if (!name) return; - if (!*g_settings.input.autoconfig_dir) - return; - - struct string_list *list = dir_list_new(g_settings.input.autoconfig_dir, "cfg", false); - if (!list) - return; + // false = load from both cfg files and internal + bool internal_only = (!*g_settings.input.autoconfig_dir); char ident[1024]; char input_driver[1024]; - for (size_t i = 0; i < list->size; i++) + + for (size_t i = 0; input_builtin_autoconfs[i] /* array is NULL terminated */; i++) { *ident = *input_driver = '\0'; - config_file_t *conf = config_file_new(list->elems[i].data); + config_file_t *conf = config_file_new_from_string(input_builtin_autoconfs[i]); if (!conf) continue; config_get_array(conf, "input_device", ident, sizeof(ident)); config_get_array(conf, "input_driver", input_driver, sizeof(input_driver)); + if (!strcmp(ident, name) && !strcmp(driver, input_driver)) { @@ -868,6 +866,45 @@ void input_config_autoconfigure_joypad(unsigned index, const char *name, const c else config_file_free(conf); } + + struct string_list *list = dir_list_new(g_settings.input.autoconfig_dir, "cfg", false); + if ((!list) && (!internal_only)) + return; + + if (!internal_only) + { + for (size_t i = 0; i < list->size; i++) + { + *ident = *input_driver = '\0'; + + config_file_t *conf = config_file_new(list->elems[i].data); + if (!conf) + continue; + + config_get_array(conf, "input_device", ident, sizeof(ident)); + config_get_array(conf, "input_driver", input_driver, sizeof(input_driver)); + + if (!strcmp(ident, name) && !strcmp(driver, input_driver)) + { + g_settings.input.autoconfigured[index] = true; + input_autoconfigure_joypad_conf(conf, g_settings.input.autoconf_binds[index]); + + char msg[512]; + snprintf(msg, sizeof(msg), "Joypad port #%u (%s) configured.", + index, name); + + if (!block_osd_spam) + msg_queue_push(g_extern.msg_queue, msg, 0, 60); + RARCH_LOG("%s\n", msg); + + config_file_free(conf); + break; + } + else + config_file_free(conf); + } + } + string_list_free(list); } diff --git a/input/input_common.h b/input/input_common.h index dc118ff4e1..ffc08d99a3 100644 --- a/input/input_common.h +++ b/input/input_common.h @@ -135,6 +135,8 @@ struct input_key_map }; extern const struct input_key_map input_config_key_map[]; +extern const char* const input_builtin_autoconfs[]; + const char *input_config_get_prefix(unsigned player, bool meta); void input_config_parse_key(config_file_t *conf, const char *prefix, const char *btn, diff --git a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj index 45bbb6b6cd..9ebc1423fc 100644 --- a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj +++ b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj @@ -254,6 +254,8 @@ + + From 149a0f37d0a30885a8c50109f779c4c9e8455872 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 5 Sep 2013 18:19:07 -0400 Subject: [PATCH 155/202] (Overlay Analog) Coding style fixes --- driver.c | 2 +- driver.h | 3 +-- driver_funcs.h | 2 +- frontend/menu/menu_common.c | 2 +- input/overlay.c | 26 +++++++++++++------------- input/overlay.h | 9 +++++++-- retroarch.c | 17 ++++++++++++----- 7 files changed, 36 insertions(+), 25 deletions(-) diff --git a/driver.c b/driver.c index b9795818af..3b041229ea 100644 --- a/driver.c +++ b/driver.c @@ -1058,7 +1058,7 @@ void uninit_video_input(void) { input_overlay_free(driver.overlay); driver.overlay = NULL; - driver.overlay_state = 0; + memset(&driver.overlay_state, 0, sizeof(driver.overlay_state)); } #endif diff --git a/driver.h b/driver.h index e2e5244097..a5dead5df2 100644 --- a/driver.h +++ b/driver.h @@ -462,8 +462,7 @@ typedef struct driver #ifdef HAVE_OVERLAY input_overlay_t *overlay; - uint64_t overlay_state; - int16_t overlay_analog_state[4]; + input_overlay_state_t overlay_state; #endif // Interface for "poking". diff --git a/driver_funcs.h b/driver_funcs.h index 69319e2104..56237a9cd6 100644 --- a/driver_funcs.h +++ b/driver_funcs.h @@ -56,7 +56,7 @@ static inline bool input_key_pressed_func(int key) bool ret = driver.input->key_pressed(driver.input_data, key); #ifdef HAVE_OVERLAY - ret |= driver.overlay_state & (UINT64_C(1) << key); + ret |= driver.overlay_state.buttons & (UINT64_C(1) << key); #endif #ifdef HAVE_COMMAND diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 780be57a29..2651a2fc36 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -725,7 +725,7 @@ static uint64_t rgui_input(void) input_state |= input_input_state_func(binds, 0, RETRO_DEVICE_JOYPAD, 0, maps[i + 0]) ? (1ULL << maps[i + 1]) : 0; #ifdef HAVE_OVERLAY - input_state |= (driver.overlay_state & (UINT64_C(1) << maps[i + 0])) ? (1ULL << maps[i + 1]) : 0; + input_state |= (driver.overlay_state.buttons & (UINT64_C(1) << maps[i + 0])) ? (1ULL << maps[i + 1]) : 0; #endif } diff --git a/input/overlay.c b/input/overlay.c index 53a7e5c9a1..5f3bf68dec 100644 --- a/input/overlay.c +++ b/input/overlay.c @@ -554,12 +554,14 @@ static bool inside_hitbox(const struct overlay_desc *desc, float x, float y) } } -uint64_t input_overlay_poll(input_overlay_t *ol, int16_t norm_x, int16_t norm_y) +void input_overlay_poll(input_overlay_t *ol, input_overlay_state_t *out, int16_t norm_x, int16_t norm_y) { + memset(out, 0, sizeof(*out)); + if (!ol->enable) { ol->blocked = false; - return 0; + return; } // norm_x and norm_y is in [-0x7fff, 0x7fff] range, like RETRO_DEVICE_POINTER. @@ -571,7 +573,6 @@ uint64_t input_overlay_poll(input_overlay_t *ol, int16_t norm_x, int16_t norm_y) x /= ol->active->mod_w; y /= ol->active->mod_h; - uint64_t state = 0; for (size_t i = 0; i < ol->active->size; i++) { if (!inside_hitbox(&ol->active->descs[i], x, y)) @@ -580,27 +581,26 @@ uint64_t input_overlay_poll(input_overlay_t *ol, int16_t norm_x, int16_t norm_y) if (ol->active->descs[i].type == OVERLAY_TYPE_BUTTONS) { uint64_t mask = ol->active->descs[i].key_mask; - state |= mask; + out->buttons |= mask; if (mask & (UINT64_C(1) << RARCH_OVERLAY_NEXT)) ol->next_index = ol->active->descs[i].next_index; } else { - float tgt_x = (x - ol->active->descs[i].x) / ol->active->descs[i].range_x; - float tgt_y = (y - ol->active->descs[i].y) / ol->active->descs[i].range_y; - unsigned base = (ol->active->descs[i].type == OVERLAY_TYPE_ANALOG_RIGHT) ? 2 : 0; - driver.overlay_analog_state[base + 0] = tgt_x * 32767.0f; - driver.overlay_analog_state[base + 1] = tgt_y * 32767.0f; + float x_val = (x - ol->active->descs[i].x) / ol->active->descs[i].range_x * 32767.0f; + float y_val = (y - ol->active->descs[i].y) / ol->active->descs[i].range_y * 32767.0f; + + unsigned int base = (ol->active->descs[i].type == OVERLAY_TYPE_ANALOG_RIGHT) ? 2 : 0; + out->analog[base + 0] = x_val; + out->analog[base + 1] = y_val; } } - if (!state) + if (!out->buttons) ol->blocked = false; else if (ol->blocked) - state = 0; - - return state; + memset(out, 0, sizeof(*out)); } void input_overlay_poll_clear(input_overlay_t *ol) diff --git a/input/overlay.h b/input/overlay.h index c5f08491cb..399cb896cf 100644 --- a/input/overlay.h +++ b/input/overlay.h @@ -30,6 +30,12 @@ extern "C" { // This interface requires that the video driver has support for the overlay interface. typedef struct input_overlay input_overlay_t; +typedef struct input_overlay_state +{ + uint64_t buttons; // This is a bitmask of (1 << key_bind_id). + int16_t analog[4]; // Left X, Left Y, Right X, Right Y +} input_overlay_state_t; + input_overlay_t *input_overlay_new(const char *overlay); void input_overlay_free(input_overlay_t *ol); @@ -38,8 +44,7 @@ void input_overlay_enable(input_overlay_t *ol, bool enable); bool input_overlay_full_screen(input_overlay_t *ol); // norm_x and norm_y are the result of input_translate_coord_viewport(). -// Resulting state is a bitmask of (1 << key_bind_id). -uint64_t input_overlay_poll(input_overlay_t *ol, int16_t norm_x, int16_t norm_y); +void input_overlay_poll(input_overlay_t *ol, input_overlay_state_t *out, int16_t norm_x, int16_t norm_y); // Call when there is nothing to poll. Allows overlay to clear certain state. void input_overlay_poll_clear(input_overlay_t *ol); diff --git a/retroarch.c b/retroarch.c index a5d88d8e12..2c119948ff 100644 --- a/retroarch.c +++ b/retroarch.c @@ -461,8 +461,7 @@ size_t audio_sample_batch(const int16_t *data, size_t frames) #ifdef HAVE_OVERLAY static inline void input_poll_overlay(void) { - driver.overlay_state = 0; - memset(driver.overlay_analog_state, 0, sizeof(driver.overlay_analog_state)); + memset(&driver.overlay_state, 0, sizeof(driver.overlay_state)); unsigned device = input_overlay_full_screen(driver.overlay) ? RARCH_DEVICE_POINTER_SCREEN : RETRO_DEVICE_POINTER; @@ -477,7 +476,15 @@ static inline void input_poll_overlay(void) 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); + input_overlay_state_t polled_data; + input_overlay_poll(driver.overlay, &polled_data, x, y); + + driver.overlay_state.buttons |= polled_data.buttons; + + for (unsigned j = 0; j < 4; j ++) + if (driver.overlay_state.analog[j] == 0) + driver.overlay_state.analog[j] = polled_data.analog[j]; + polled = true; } @@ -544,12 +551,12 @@ static int16_t input_state(unsigned port, unsigned device, unsigned index, unsig #ifdef HAVE_OVERLAY if (device == RETRO_DEVICE_JOYPAD && port == 0) - res |= driver.overlay_state & (UINT64_C(1) << id) ? 1 : 0; + res |= driver.overlay_state.buttons & (UINT64_C(1) << id) ? 1 : 0; else if (device == RETRO_DEVICE_ANALOG && port == 0) { unsigned base = (index == RETRO_DEVICE_INDEX_ANALOG_RIGHT) ? 2 : 0; base += (id == RETRO_DEVICE_ID_ANALOG_Y) ? 1 : 0; - res += driver.overlay_analog_state[base]; + res += driver.overlay_state.analog[base]; } #endif From f1d0a2223132ff5028086efba994bf3b8f31ea75 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 5 Sep 2013 18:52:17 -0400 Subject: [PATCH 156/202] (Analog Overlay) Add a saturate_pct key to descibe the point at which an analog hitbox will return the max analog range --- input/overlay.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/input/overlay.c b/input/overlay.c index 5f3bf68dec..3854ea11a0 100644 --- a/input/overlay.c +++ b/input/overlay.c @@ -48,6 +48,7 @@ struct overlay_desc enum overlay_type type; uint64_t key_mask; + float analog_saturate_pct; unsigned next_index; char next_index_name[64]; @@ -275,11 +276,19 @@ static bool input_overlay_load_desc(config_file_t *conf, struct overlay_desc *de goto end; } - if (desc->hitbox != OVERLAY_HITBOX_RADIAL && desc->type != OVERLAY_TYPE_BUTTONS) + if (desc->type != OVERLAY_TYPE_BUTTONS) { - RARCH_ERR("[Overlay]: Analog hitbox type must be \"radial\".\n"); - ret = false; - goto end; + if (desc->hitbox != OVERLAY_HITBOX_RADIAL) + { + RARCH_ERR("[Overlay]: Analog hitbox type must be \"radial\".\n"); + ret = false; + goto end; + } + + char overlay_analog_saturate_key[64]; + snprintf(overlay_analog_saturate_key, sizeof(overlay_analog_saturate_key), "overlay%u_desc%u_saturate_pct", ol_index, desc_index); + if (!config_get_float(conf, overlay_analog_saturate_key, &desc->analog_saturate_pct)) + desc->analog_saturate_pct = 1.0f; } desc->range_x = strtod(list->elems[4].data, NULL) / width; @@ -588,12 +597,18 @@ void input_overlay_poll(input_overlay_t *ol, input_overlay_state_t *out, int16_t } else { - float x_val = (x - ol->active->descs[i].x) / ol->active->descs[i].range_x * 32767.0f; - float y_val = (y - ol->active->descs[i].y) / ol->active->descs[i].range_y * 32767.0f; + float x_val = (x - ol->active->descs[i].x) / ol->active->descs[i].range_x / ol->active->descs[i].analog_saturate_pct; + float y_val = (y - ol->active->descs[i].y) / ol->active->descs[i].range_y / ol->active->descs[i].analog_saturate_pct; + + if (fabs(x_val) > 1.0f) + x_val = (x_val > 0.0f) ? 1.0f : -1.0f; + + if (fabs(y_val) > 1.0f) + y_val = (y_val > 0.0f) ? 1.0f : -1.0f; unsigned int base = (ol->active->descs[i].type == OVERLAY_TYPE_ANALOG_RIGHT) ? 2 : 0; - out->analog[base + 0] = x_val; - out->analog[base + 1] = y_val; + out->analog[base + 0] = x_val * 32767.0f; + out->analog[base + 1] = y_val * 32767.0f; } } From ba095dca79d13d02d4b1f2348846dabbe5b5a0e5 Mon Sep 17 00:00:00 2001 From: Cray Elliott Date: Fri, 6 Sep 2013 01:43:55 -0700 Subject: [PATCH 157/202] Fix compilation error introduced by analog overlay changes --- android/native/jni/input_android.c | 2 +- frontend/menu/menu_common.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/native/jni/input_android.c b/android/native/jni/input_android.c index a6410eaf40..625f172d77 100644 --- a/android/native/jni/input_android.c +++ b/android/native/jni/input_android.c @@ -1855,7 +1855,7 @@ static int16_t android_input_state(void *data, const struct retro_keybind **bind static bool android_input_key_pressed(void *data, int key) { - return ((g_extern.lifecycle_state | driver.overlay_state) & (1ULL << key)); + return ((g_extern.lifecycle_state | driver.overlay_state.buttons) & (1ULL << key)); } static void android_input_free_input(void *data) diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 2651a2fc36..582daeb3ff 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -704,7 +704,7 @@ static uint64_t rgui_input(void) #ifdef HAVE_OVERLAY for (unsigned i = 0; i < DEVICE_NAV_LAST; i++) - input_state |= driver.overlay_state & menu_nav_binds[0][i].joykey ? (1ULL << i) : 0; + input_state |= driver.overlay_state.buttons & menu_nav_binds[0][i].joykey ? (1ULL << i) : 0; #endif #else static const int maps[] = { From 50e4dfb57cee16b159190aeba59d05a609cfde41 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Fri, 6 Sep 2013 13:36:29 +0100 Subject: [PATCH 158/202] Various fixups to the internal autoconf system --- conf/config_file.c | 22 ++--- input/autoconf_builtin.c | 209 +++++++++++++-------------------------- input/input_common.c | 95 ++++++++---------- 3 files changed, 116 insertions(+), 210 deletions(-) diff --git a/conf/config_file.c b/conf/config_file.c index 7ecf97e60a..05327d6cc3 100644 --- a/conf/config_file.c +++ b/conf/config_file.c @@ -365,23 +365,17 @@ config_file_t *config_file_new_from_string(const char *from_string) return conf; conf->path = NULL; - conf->include_depth = 0; - size_t pos = 0; - size_t len = strlen(from_string); + struct string_list *lines = string_split(from_string, "\n"); + if (!lines) + return conf; - while (pos < len) + for (size_t i = 0; i < lines->size; i++) { struct config_entry_list *list = (struct config_entry_list*)calloc(1, sizeof(*list)); - size_t next_newline_pos = strchr(from_string + pos, '\n') - (char*)from_string; - if (next_newline_pos > len) - next_newline_pos = len; - size_t line_len = next_newline_pos - pos; - char *line = (char*)malloc(line_len + 1); - strncpy(line, from_string+pos, line_len); - line[line_len] = '\0'; + char* line = lines->elems[i].data; if (line) { @@ -398,15 +392,13 @@ config_file_t *config_file_new_from_string(const char *from_string) conf->tail = list; } } - - free(line); } if (list != conf->tail) free(list); - - pos += line_len + 1; } + + string_list_free(lines); return conf; } diff --git a/input/autoconf_builtin.c b/input/autoconf_builtin.c index fea7a4ce91..ba919a7f02 100644 --- a/input/autoconf_builtin.c +++ b/input/autoconf_builtin.c @@ -1,153 +1,80 @@ #include "input_common.h" +#define DECL_BTN(btn, bind) "input_" #btn "_btn = " #bind "\n" +#define DECL_AXIS(axis, bind) "input_" #axis "_axis = " #bind "\n" + +#define XINPUT_DEFAULT_BINDS \ +DECL_BTN(a,1)\ +DECL_BTN(b,0)\ +DECL_BTN(x,3)\ +DECL_BTN(y,2)\ +DECL_BTN(start, 6)\ +DECL_BTN(select,7)\ +DECL_BTN(up,h0up)\ +DECL_BTN(down,h0down)\ +DECL_BTN(left,h0left)\ +DECL_BTN(right,h0right)\ +DECL_BTN(l, 4)\ +DECL_BTN(r, 5)\ +DECL_BTN(l3,8)\ +DECL_BTN(r3,9)\ +DECL_AXIS(l2, +4)\ +DECL_AXIS(r2, +5)\ +DECL_AXIS(l_x_plus, +0)\ +DECL_AXIS(l_x_minus, -0)\ +DECL_AXIS(l_y_plus, -1)\ +DECL_AXIS(l_y_minus, +1)\ +DECL_AXIS(r_x_plus, +2)\ +DECL_AXIS(r_x_minus, -2)\ +DECL_AXIS(r_y_plus, -3)\ +DECL_AXIS(r_y_minus, +3) + // Some hardcoded autoconfig information. Will be used for pads with no autoconfig cfg files. -// All 4 almost-identical 360 pads are included, could be reduced with some fiddling. const char* const input_builtin_autoconfs[] = { -"\ -input_device = \"XInput Controller (Player 1)\" \n\ -input_driver = \"winxinput\" \n\ -input_b_btn = \"0\" \n\ -input_y_btn = \"2\" \n\ -input_select_btn = \"7\" \n\ -input_start_btn = \"6\" \n\ -input_up_btn = \"h0up\" \n\ -input_down_btn = \"h0down\" \n\ -input_left_btn = \"h0left\" \n\ -input_right_btn = \"h0right\" \n\ -input_a_btn = \"1\" \n\ -input_x_btn = \"3\" \n\ -input_l_btn = \"4\" \n\ -input_r_btn = \"5\" \n\ -input_l2_axis = \"+4\" \n\ -input_r2_axis = \"+5\" \n\ -input_l3_btn = \"8\" \n\ -input_r3_btn = \"9\" \n\ -input_l_x_plus_axis = \"+0\" \n\ -input_l_x_minus_axis = \"-0\" \n\ -input_l_y_plus_axis = \"-1\" \n\ -input_l_y_minus_axis = \"+1\" \n\ -input_r_x_plus_axis = \"+2\" \n\ -input_r_x_minus_axis = \"-2\" \n\ -input_r_y_plus_axis = \"-3\" \n\ -input_r_y_minus_axis = \"+3\" \n\ -", +"input_device = \"XInput Controller (Player 1)\" \n" +"input_driver = \"winxinput\" \n" +XINPUT_DEFAULT_BINDS, -"\ -input_device = \"XInput Controller (Player 2)\" \n\ -input_driver = \"winxinput\" \n\ -input_b_btn = \"0\" \n\ -input_y_btn = \"2\" \n\ -input_select_btn = \"7\" \n\ -input_start_btn = \"6\" \n\ -input_up_btn = \"h0up\" \n\ -input_down_btn = \"h0down\" \n\ -input_left_btn = \"h0left\" \n\ -input_right_btn = \"h0right\" \n\ -input_a_btn = \"1\" \n\ -input_x_btn = \"3\" \n\ -input_l_btn = \"4\" \n\ -input_r_btn = \"5\" \n\ -input_l2_axis = \"+4\" \n\ -input_r2_axis = \"+5\" \n\ -input_l3_btn = \"8\" \n\ -input_r3_btn = \"9\" \n\ -input_l_x_plus_axis = \"+0\" \n\ -input_l_x_minus_axis = \"-0\" \n\ -input_l_y_plus_axis = \"-1\" \n\ -input_l_y_minus_axis = \"+1\" \n\ -input_r_x_plus_axis = \"+2\" \n\ -input_r_x_minus_axis = \"-2\" \n\ -input_r_y_plus_axis = \"-3\" \n\ -input_r_y_minus_axis = \"+3\" \n\ -", +"input_device = \"XInput Controller (Player 2)\" \n" +"input_driver = \"winxinput\" \n" +XINPUT_DEFAULT_BINDS, -"\ -input_device = \"XInput Controller (Player 3)\" \n\ -input_driver = \"winxinput\" \n\ -input_b_btn = \"0\" \n\ -input_y_btn = \"2\" \n\ -input_select_btn = \"7\" \n\ -input_start_btn = \"6\" \n\ -input_up_btn = \"h0up\" \n\ -input_down_btn = \"h0down\" \n\ -input_left_btn = \"h0left\" \n\ -input_right_btn = \"h0right\" \n\ -input_a_btn = \"1\" \n\ -input_x_btn = \"3\" \n\ -input_l_btn = \"4\" \n\ -input_r_btn = \"5\" \n\ -input_l2_axis = \"+4\" \n\ -input_r2_axis = \"+5\" \n\ -input_l3_btn = \"8\" \n\ -input_r3_btn = \"9\" \n\ -input_l_x_plus_axis = \"+0\" \n\ -input_l_x_minus_axis = \"-0\" \n\ -input_l_y_plus_axis = \"-1\" \n\ -input_l_y_minus_axis = \"+1\" \n\ -input_r_x_plus_axis = \"+2\" \n\ -input_r_x_minus_axis = \"-2\" \n\ -input_r_y_plus_axis = \"-3\" \n\ -input_r_y_minus_axis = \"+3\" \n\ -", +"input_device = \"XInput Controller (Player 3)\" \n" +"input_driver = \"winxinput\" \n" +XINPUT_DEFAULT_BINDS, -"\ -input_device = \"XInput Controller (Player 4)\" \n\ -input_driver = \"winxinput\" \n\ -input_b_btn = \"0\" \n\ -input_y_btn = \"2\" \n\ -input_select_btn = \"7\" \n\ -input_start_btn = \"6\" \n\ -input_up_btn = \"h0up\" \n\ -input_down_btn = \"h0down\" \n\ -input_left_btn = \"h0left\" \n\ -input_right_btn = \"h0right\" \n\ -input_a_btn = \"1\" \n\ -input_x_btn = \"3\" \n\ -input_l_btn = \"4\" \n\ -input_r_btn = \"5\" \n\ -input_l2_axis = \"+4\" \n\ -input_r2_axis = \"+5\" \n\ -input_l3_btn = \"8\" \n\ -input_r3_btn = \"9\" \n\ -input_l_x_plus_axis = \"+0\" \n\ -input_l_x_minus_axis = \"-0\" \n\ -input_l_y_plus_axis = \"-1\" \n\ -input_l_y_minus_axis = \"+1\" \n\ -input_r_x_plus_axis = \"+2\" \n\ -input_r_x_minus_axis = \"-2\" \n\ -input_r_y_plus_axis = \"-3\" \n\ -input_r_y_minus_axis = \"+3\" \n\ -", +"input_device = \"XInput Controller (Player 4)\" \n" +"input_driver = \"winxinput\" \n" +XINPUT_DEFAULT_BINDS, -"\ -input_device = \"Dual Trigger 3-in-1\" \n\ -input_driver = \"dinput\" \n\ -input_b_btn = \"1\" \n\ -input_y_btn = \"0\" \n\ -input_select_btn = \"8\" \n\ -input_start_btn = \"9\" \n\ -input_up_btn = \"h0up\" \n\ -input_down_btn = \"h0down\" \n\ -input_left_btn = \"h0left\" \n\ -input_right_btn = \"h0right\" \n\ -input_a_btn = \"2\" \n\ -input_x_btn = \"3\" \n\ -input_l_btn = \"4\" \n\ -input_r_btn = \"5\" \n\ -input_l2_btn = \"6\" \n\ -input_r2_btn = \"7\" \n\ -input_l3_btn = \"10\" \n\ -input_r3_btn = \"11\" \n\ -input_l_x_plus_axis = \"+0\" \n\ -input_l_x_minus_axis = \"-0\" \n\ -input_l_y_plus_axis = \"+1\" \n\ -input_l_y_minus_axis = \"-1\" \n\ -input_r_x_plus_axis = \"+2\" \n\ -input_r_x_minus_axis = \"-2\" \n\ -input_r_y_plus_axis = \"+5\" \n\ -input_r_y_minus_axis = \"-5\" \n\ -", +"input_device = \"Dual Trigger 3-in-1\" \n" +"input_driver = \"dinput\" \n" +DECL_BTN(a,2) +DECL_BTN(b,1) +DECL_BTN(x,3) +DECL_BTN(y,0) +DECL_BTN(start, 9) +DECL_BTN(select,8) +DECL_BTN(up,h0up) +DECL_BTN(down,h0down) +DECL_BTN(left,h0left) +DECL_BTN(right,h0right) +DECL_BTN(l, 4) +DECL_BTN(r, 5) +DECL_BTN(l2, 6) +DECL_BTN(r2, 7) +DECL_BTN(l3,10) +DECL_BTN(r3,11) +DECL_AXIS(l_x_plus, +0) +DECL_AXIS(l_x_minus, -0) +DECL_AXIS(l_y_plus, +1) +DECL_AXIS(l_y_minus, -1) +DECL_AXIS(r_x_plus, +2) +DECL_AXIS(r_x_minus, -2) +DECL_AXIS(r_y_plus, +5) +DECL_AXIS(r_y_minus, -5) +, NULL }; diff --git a/input/input_common.c b/input/input_common.c index 52b1f2a67f..5138224c3e 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -810,6 +810,38 @@ static void input_autoconfigure_joypad_conf(config_file_t *conf, struct retro_ke } } +static bool input_try_autoconfigure_joypad_from_conf(config_file_t *conf, unsigned index, const char *name, const char *driver, bool block_osd_spam) +{ + if (!conf) + return false; + + char ident[1024]; + char input_driver[1024]; + + *ident = *input_driver = '\0'; + + config_get_array(conf, "input_device", ident, sizeof(ident)); + config_get_array(conf, "input_driver", input_driver, sizeof(input_driver)); + + if (!strcmp(ident, name) && !strcmp(driver, input_driver)) + { + g_settings.input.autoconfigured[index] = true; + input_autoconfigure_joypad_conf(conf, g_settings.input.autoconf_binds[index]); + + char msg[512]; + snprintf(msg, sizeof(msg), "Joypad port #%u (%s) configured.", + index, name); + + if (!block_osd_spam) + msg_queue_push(g_extern.msg_queue, msg, 0, 60); + RARCH_LOG("%s\n", msg); + + return true; + } + + return false; +} + void input_config_autoconfigure_joypad(unsigned index, const char *name, const char *driver) { if (!g_settings.input.autodetect_enable) @@ -832,80 +864,35 @@ void input_config_autoconfigure_joypad(unsigned index, const char *name, const c // false = load from both cfg files and internal bool internal_only = (!*g_settings.input.autoconfig_dir); - char ident[1024]; - char input_driver[1024]; - + // First internal for (size_t i = 0; input_builtin_autoconfs[i] /* array is NULL terminated */; i++) { - *ident = *input_driver = '\0'; - config_file_t *conf = config_file_new_from_string(input_builtin_autoconfs[i]); - if (!conf) - continue; - - config_get_array(conf, "input_device", ident, sizeof(ident)); - config_get_array(conf, "input_driver", input_driver, sizeof(input_driver)); - - - if (!strcmp(ident, name) && !strcmp(driver, input_driver)) - { - g_settings.input.autoconfigured[index] = true; - input_autoconfigure_joypad_conf(conf, g_settings.input.autoconf_binds[index]); - - char msg[512]; - snprintf(msg, sizeof(msg), "Joypad port #%u (%s) configured.", - index, name); - - if (!block_osd_spam) - msg_queue_push(g_extern.msg_queue, msg, 0, 60); - RARCH_LOG("%s\n", msg); - - config_file_free(conf); + bool success = input_try_autoconfigure_joypad_from_conf(conf, index, name, driver, block_osd_spam); + config_file_free(conf); + if (success) break; - } - else - config_file_free(conf); } + // Now try files struct string_list *list = dir_list_new(g_settings.input.autoconfig_dir, "cfg", false); - if ((!list) && (!internal_only)) + if (!list) return; if (!internal_only) { for (size_t i = 0; i < list->size; i++) { - *ident = *input_driver = '\0'; - config_file_t *conf = config_file_new(list->elems[i].data); if (!conf) continue; - - config_get_array(conf, "input_device", ident, sizeof(ident)); - config_get_array(conf, "input_driver", input_driver, sizeof(input_driver)); - - if (!strcmp(ident, name) && !strcmp(driver, input_driver)) - { - g_settings.input.autoconfigured[index] = true; - input_autoconfigure_joypad_conf(conf, g_settings.input.autoconf_binds[index]); - - char msg[512]; - snprintf(msg, sizeof(msg), "Joypad port #%u (%s) configured.", - index, name); - - if (!block_osd_spam) - msg_queue_push(g_extern.msg_queue, msg, 0, 60); - RARCH_LOG("%s\n", msg); - - config_file_free(conf); + bool success = input_try_autoconfigure_joypad_from_conf(conf, index, name, driver, block_osd_spam); + config_file_free(conf); + if (success) break; - } - else - config_file_free(conf); } } - string_list_free(list); } #else From 09b45e1b6865469679ebb3626a1806bb6be2e09e Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 6 Sep 2013 10:36:12 -0400 Subject: [PATCH 159/202] (QNX) Build Fix --- blackberry-qnx/qnx_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blackberry-qnx/qnx_input.c b/blackberry-qnx/qnx_input.c index d6f6985886..362837846d 100644 --- a/blackberry-qnx/qnx_input.c +++ b/blackberry-qnx/qnx_input.c @@ -627,7 +627,7 @@ static int16_t qnx_input_state(void *data, const struct retro_keybind **retro_ke static bool qnx_input_key_pressed(void *data, int key) { - return ((g_extern.lifecycle_state | driver.overlay_state ) & (1ULL << key)); + return ((g_extern.lifecycle_state.buttons | driver.overlay_state ) & (1ULL << key)); } static void qnx_input_free_input(void *data) From 3bf398f38e08e2d29ef6754e594c054585e970bb Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 6 Sep 2013 10:37:28 -0400 Subject: [PATCH 160/202] (QNX) Fix the build fix, I am an idiot --- blackberry-qnx/qnx_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blackberry-qnx/qnx_input.c b/blackberry-qnx/qnx_input.c index 362837846d..52957a6222 100644 --- a/blackberry-qnx/qnx_input.c +++ b/blackberry-qnx/qnx_input.c @@ -627,7 +627,7 @@ static int16_t qnx_input_state(void *data, const struct retro_keybind **retro_ke static bool qnx_input_key_pressed(void *data, int key) { - return ((g_extern.lifecycle_state.buttons | driver.overlay_state ) & (1ULL << key)); + return ((g_extern.lifecycle_state | driver.overlay_state.buttons ) & (1ULL << key)); } static void qnx_input_free_input(void *data) From a180b589b1fc27b40ce185d2de44942d72d9f912 Mon Sep 17 00:00:00 2001 From: meancoot Date: Fri, 6 Sep 2013 15:11:00 -0400 Subject: [PATCH 161/202] (OSX) Hide mouse cursor in fullscreen mode --- apple/common/RAGameView.m | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/apple/common/RAGameView.m b/apple/common/RAGameView.m index 8cd78a9b2f..15773b7262 100644 --- a/apple/common/RAGameView.m +++ b/apple/common/RAGameView.m @@ -343,39 +343,33 @@ bool apple_game_view_has_focus(void) bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) { - __block bool result = true; - #ifdef OSX dispatch_sync(dispatch_get_main_queue(), ^{ // TODO: Multi-monitor support // TODO: Sceen mode support - if (fullscreen) + if (fullscreen && !g_has_went_fullscreen) { - if (!g_has_went_fullscreen) - result = [g_view enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; - g_has_went_fullscreen = true; + [g_view enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; + [NSCursor hide]; } - else + else if (!fullscreen && g_has_went_fullscreen) { - if (g_has_went_fullscreen) - { - [g_view exitFullScreenModeWithOptions:nil]; - [g_view.window makeFirstResponder:g_view]; - } - g_has_went_fullscreen = false; - - [g_view.window setContentSize:NSMakeSize(width, height)]; + [g_view exitFullScreenModeWithOptions:nil]; + [g_view.window makeFirstResponder:g_view]; + [NSCursor unhide]; } g_has_went_fullscreen = fullscreen; + if (!g_has_went_fullscreen) + [g_view.window setContentSize:NSMakeSize(width, height)]; }); #endif // TODO: Maybe iOS users should be apple to show/hide the status bar here? - return result; + return true; } #ifdef IOS From d2472eb8cb86d289c98dc2c15d8715ce1823c8c8 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Fri, 6 Sep 2013 20:53:26 +0100 Subject: [PATCH 162/202] indentation fix --- input/input_common.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/input/input_common.c b/input/input_common.c index 5138224c3e..14a39c4cd0 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -812,8 +812,8 @@ static void input_autoconfigure_joypad_conf(config_file_t *conf, struct retro_ke static bool input_try_autoconfigure_joypad_from_conf(config_file_t *conf, unsigned index, const char *name, const char *driver, bool block_osd_spam) { - if (!conf) - return false; + if (!conf) + return false; char ident[1024]; char input_driver[1024]; @@ -875,12 +875,12 @@ void input_config_autoconfigure_joypad(unsigned index, const char *name, const c } // Now try files - struct string_list *list = dir_list_new(g_settings.input.autoconfig_dir, "cfg", false); - if (!list) - return; - if (!internal_only) { + struct string_list *list = dir_list_new(g_settings.input.autoconfig_dir, "cfg", false); + if (!list) + return; + for (size_t i = 0; i < list->size; i++) { config_file_t *conf = config_file_new(list->elems[i].data); @@ -891,9 +891,9 @@ void input_config_autoconfigure_joypad(unsigned index, const char *name, const c if (success) break; } + + string_list_free(list); } - - string_list_free(list); } #else void input_config_autoconfigure_joypad(unsigned index, const char *name, const char *driver) From 99dbd6bd1cbd4f427968ac4d5e6c9afb1367e446 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 6 Sep 2013 23:24:21 +0200 Subject: [PATCH 163/202] Clean up autoconfig stuff a bit, add headers. --- Makefile.win | 4 +- input/autoconf/builtin.h | 24 ++++++ input/autoconf/builtin_win.c | 91 +++++++++++++++++++++++ input/autoconf_builtin.c | 80 -------------------- input/input_common.c | 6 +- msvc/msvc-2010/RetroArch-msvc2010.vcxproj | 10 +-- 6 files changed, 126 insertions(+), 89 deletions(-) create mode 100644 input/autoconf/builtin.h create mode 100644 input/autoconf/builtin_win.c delete mode 100644 input/autoconf_builtin.c diff --git a/Makefile.win b/Makefile.win index f4ea879abf..020d5478eb 100644 --- a/Makefile.win +++ b/Makefile.win @@ -17,7 +17,7 @@ OBJ = frontend/frontend.o \ movie.o \ gfx/gfx_common.o \ input/input_common.o \ - input/autoconf_builtin.o \ + input/autoconf/builtin_win.o \ core_options.o \ patch.o \ compat/compat.o \ @@ -83,7 +83,7 @@ endif libretro ?= -lretro LIBS = -lm -DEFINES = -I. -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE +DEFINES = -I. -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE -DHAVE_BUILTIN_AUTOCONFIG LDFLAGS = -L. -static-libgcc ifeq ($(TDM_GCC),) diff --git a/input/autoconf/builtin.h b/input/autoconf/builtin.h new file mode 100644 index 0000000000..c5a5519eb1 --- /dev/null +++ b/input/autoconf/builtin.h @@ -0,0 +1,24 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - pinumbernumber + * + * 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 AUTOCONF_BUILTIN_H__ +#define AUTOCONF_BUILTIN_H__ + +#include "input_common.h" +#define DECL_BTN(btn, bind) "input_" #btn "_btn = " #bind "\n" +#define DECL_AXIS(axis, bind) "input_" #axis "_axis = " #bind "\n" + +#endif + diff --git a/input/autoconf/builtin_win.c b/input/autoconf/builtin_win.c new file mode 100644 index 0000000000..39540bb467 --- /dev/null +++ b/input/autoconf/builtin_win.c @@ -0,0 +1,91 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - pinumbernumber + * + * 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 "builtin.h" + +#define XINPUT_DEFAULT_BINDS \ +DECL_BTN(a, 1) \ +DECL_BTN(b, 0) \ +DECL_BTN(x, 3) \ +DECL_BTN(y, 2) \ +DECL_BTN(start, 6) \ +DECL_BTN(select, 7) \ +DECL_BTN(up, h0up) \ +DECL_BTN(down, h0down) \ +DECL_BTN(left, h0left) \ +DECL_BTN(right, h0right) \ +DECL_BTN(l, 4) \ +DECL_BTN(r, 5) \ +DECL_BTN(l3, 8 )\ +DECL_BTN(r3, 9) \ +DECL_AXIS(l2, +4) \ +DECL_AXIS(r2, +5) \ +DECL_AXIS(l_x_plus, +0) \ +DECL_AXIS(l_x_minus, -0) \ +DECL_AXIS(l_y_plus, -1) \ +DECL_AXIS(l_y_minus, +1) \ +DECL_AXIS(r_x_plus, +2) \ +DECL_AXIS(r_x_minus, -2) \ +DECL_AXIS(r_y_plus, -3) \ +DECL_AXIS(r_y_minus, +3) + +// Some hardcoded autoconfig information. Will be used for pads with no autoconfig cfg files. +const char* const input_builtin_autoconfs[] = +{ + "input_device = \"XInput Controller (Player 1)\" \n" + "input_driver = \"winxinput\" \n" + XINPUT_DEFAULT_BINDS, + + "input_device = \"XInput Controller (Player 2)\" \n" + "input_driver = \"winxinput\" \n" + XINPUT_DEFAULT_BINDS, + + "input_device = \"XInput Controller (Player 3)\" \n" + "input_driver = \"winxinput\" \n" + XINPUT_DEFAULT_BINDS, + + "input_device = \"XInput Controller (Player 4)\" \n" + "input_driver = \"winxinput\" \n" + XINPUT_DEFAULT_BINDS, + + "input_device = \"Dual Trigger 3-in-1\" \n" + "input_driver = \"dinput\" \n" + DECL_BTN(a, 2) + DECL_BTN(b, 1) + DECL_BTN(x, 3) + DECL_BTN(y, 0) + DECL_BTN(start, 9) + DECL_BTN(select, 8) + DECL_BTN(up, h0up) + DECL_BTN(down, h0down) + DECL_BTN(left, h0left) + DECL_BTN(right, h0right) + DECL_BTN(l, 4) + DECL_BTN(r, 5) + DECL_BTN(l2, 6) + DECL_BTN(r2, 7) + DECL_BTN(l3, 10) + DECL_BTN(r3, 11) + DECL_AXIS(l_x_plus, +0) + DECL_AXIS(l_x_minus, -0) + DECL_AXIS(l_y_plus, +1) + DECL_AXIS(l_y_minus, -1) + DECL_AXIS(r_x_plus, +2) + DECL_AXIS(r_x_minus, -2) + DECL_AXIS(r_y_plus, +5) + DECL_AXIS(r_y_minus, -5), + + NULL +}; diff --git a/input/autoconf_builtin.c b/input/autoconf_builtin.c deleted file mode 100644 index ba919a7f02..0000000000 --- a/input/autoconf_builtin.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "input_common.h" - -#define DECL_BTN(btn, bind) "input_" #btn "_btn = " #bind "\n" -#define DECL_AXIS(axis, bind) "input_" #axis "_axis = " #bind "\n" - -#define XINPUT_DEFAULT_BINDS \ -DECL_BTN(a,1)\ -DECL_BTN(b,0)\ -DECL_BTN(x,3)\ -DECL_BTN(y,2)\ -DECL_BTN(start, 6)\ -DECL_BTN(select,7)\ -DECL_BTN(up,h0up)\ -DECL_BTN(down,h0down)\ -DECL_BTN(left,h0left)\ -DECL_BTN(right,h0right)\ -DECL_BTN(l, 4)\ -DECL_BTN(r, 5)\ -DECL_BTN(l3,8)\ -DECL_BTN(r3,9)\ -DECL_AXIS(l2, +4)\ -DECL_AXIS(r2, +5)\ -DECL_AXIS(l_x_plus, +0)\ -DECL_AXIS(l_x_minus, -0)\ -DECL_AXIS(l_y_plus, -1)\ -DECL_AXIS(l_y_minus, +1)\ -DECL_AXIS(r_x_plus, +2)\ -DECL_AXIS(r_x_minus, -2)\ -DECL_AXIS(r_y_plus, -3)\ -DECL_AXIS(r_y_minus, +3) - -// Some hardcoded autoconfig information. Will be used for pads with no autoconfig cfg files. -const char* const input_builtin_autoconfs[] = -{ -"input_device = \"XInput Controller (Player 1)\" \n" -"input_driver = \"winxinput\" \n" -XINPUT_DEFAULT_BINDS, - -"input_device = \"XInput Controller (Player 2)\" \n" -"input_driver = \"winxinput\" \n" -XINPUT_DEFAULT_BINDS, - -"input_device = \"XInput Controller (Player 3)\" \n" -"input_driver = \"winxinput\" \n" -XINPUT_DEFAULT_BINDS, - -"input_device = \"XInput Controller (Player 4)\" \n" -"input_driver = \"winxinput\" \n" -XINPUT_DEFAULT_BINDS, - -"input_device = \"Dual Trigger 3-in-1\" \n" -"input_driver = \"dinput\" \n" -DECL_BTN(a,2) -DECL_BTN(b,1) -DECL_BTN(x,3) -DECL_BTN(y,0) -DECL_BTN(start, 9) -DECL_BTN(select,8) -DECL_BTN(up,h0up) -DECL_BTN(down,h0down) -DECL_BTN(left,h0left) -DECL_BTN(right,h0right) -DECL_BTN(l, 4) -DECL_BTN(r, 5) -DECL_BTN(l2, 6) -DECL_BTN(r2, 7) -DECL_BTN(l3,10) -DECL_BTN(r3,11) -DECL_AXIS(l_x_plus, +0) -DECL_AXIS(l_x_minus, -0) -DECL_AXIS(l_y_plus, +1) -DECL_AXIS(l_y_minus, -1) -DECL_AXIS(r_x_plus, +2) -DECL_AXIS(r_x_minus, -2) -DECL_AXIS(r_y_plus, +5) -DECL_AXIS(r_y_minus, -5) -, - -NULL -}; diff --git a/input/input_common.c b/input/input_common.c index 14a39c4cd0..a623f52d80 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -862,10 +862,11 @@ void input_config_autoconfigure_joypad(unsigned index, const char *name, const c return; // false = load from both cfg files and internal - bool internal_only = (!*g_settings.input.autoconfig_dir); + bool internal_only = !*g_settings.input.autoconfig_dir; +#ifdef HAVE_BUILTIN_AUTOCONFIG // First internal - for (size_t i = 0; input_builtin_autoconfs[i] /* array is NULL terminated */; i++) + for (size_t i = 0; input_builtin_autoconfs[i]; i++) { config_file_t *conf = config_file_new_from_string(input_builtin_autoconfs[i]); bool success = input_try_autoconfigure_joypad_from_conf(conf, index, name, driver, block_osd_spam); @@ -873,6 +874,7 @@ void input_config_autoconfigure_joypad(unsigned index, const char *name, const c if (success) break; } +#endif // Now try files if (!internal_only) diff --git a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj index 9ebc1423fc..4b037e80ea 100644 --- a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj +++ b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj @@ -88,7 +88,7 @@ Level3 Disabled - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_BUILTIN_AUTOCONFIG;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -108,7 +108,7 @@ Level3 Disabled - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_BUILTIN_AUTOCONFIG;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -130,7 +130,7 @@ MaxSpeed true true - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;HAVE_ZLIB;WANT_MINIZ;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_BUILTIN_AUTOCONFIG;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -154,7 +154,7 @@ MaxSpeed true true - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_ZLIB;WANT_MINIZ;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_BUILTIN_AUTOCONFIG;HAVE_DINPUT;HAVE_WINXINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_ZLIB;WANT_MINIZ;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -254,7 +254,7 @@ - + From c76fc068dc7256be480ec15bc63aba22e7b1ceea Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 6 Sep 2013 23:25:29 +0200 Subject: [PATCH 164/202] Build fix. --- input/autoconf/builtin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/autoconf/builtin.h b/input/autoconf/builtin.h index c5a5519eb1..be4d9f1d4e 100644 --- a/input/autoconf/builtin.h +++ b/input/autoconf/builtin.h @@ -16,7 +16,7 @@ #ifndef AUTOCONF_BUILTIN_H__ #define AUTOCONF_BUILTIN_H__ -#include "input_common.h" +#include "../input_common.h" #define DECL_BTN(btn, bind) "input_" #btn "_btn = " #bind "\n" #define DECL_AXIS(axis, bind) "input_" #axis "_axis = " #bind "\n" From 870ef372584d1bcbebb9e308def90f82ae18e19b Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 7 Sep 2013 15:04:40 +0200 Subject: [PATCH 165/202] Fix libretro GL state bug on frame dupe. Need to force backbuffer and viewport on duped frames. --- gfx/gl.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/gfx/gl.c b/gfx/gl.c index 8179728f8b..fe78f872c0 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1402,18 +1402,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); #ifdef HAVE_FBO - // Data is already on GPU :) Have to reset some state however incase core changed it. - if (gl->hw_render_fbo_init) - { - gl_update_input_size(gl, width, height, pitch, false); - - if (!gl->fbo_inited) - { - gl_bind_backbuffer(); - gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); - } - } - else + if (!gl->hw_render_fbo_init) #endif { gl_update_input_size(gl, width, height, pitch, true); @@ -1426,6 +1415,19 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei else glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); +#ifdef HAVE_FBO + // Data is already on GPU :) Have to reset some state however incase core changed it. + if (gl->hw_render_fbo_init) + { + gl_update_input_size(gl, width, height, pitch, false); + if (!gl->fbo_inited) + { + gl_bind_backbuffer(); + gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); + } + } +#endif + // Have to reset rendering state which libretro core could easily have overridden. #ifdef HAVE_FBO if (gl->hw_render_fbo_init) From 46c214f9646f0ce5485faec8367be7acb0782782 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 7 Sep 2013 15:23:09 +0200 Subject: [PATCH 166/202] Small cleanup. --- gfx/gl.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/gfx/gl.c b/gfx/gl.c index fe78f872c0..0a0e03887f 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1415,8 +1415,8 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei else glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); + // Have to reset rendering state which libretro core could easily have overridden. #ifdef HAVE_FBO - // Data is already on GPU :) Have to reset some state however incase core changed it. if (gl->hw_render_fbo_init) { gl_update_input_size(gl, width, height, pitch, false); @@ -1425,13 +1425,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei gl_bind_backbuffer(); gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); } - } -#endif - // Have to reset rendering state which libretro core could easily have overridden. -#ifdef HAVE_FBO - if (gl->hw_render_fbo_init) - { #ifndef HAVE_OPENGLES if (!gl->core_context) glEnable(GL_TEXTURE_2D); From 5d0b435d472d360c544e9d0e9f731b07daf58d81 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Sat, 7 Sep 2013 14:37:32 +0100 Subject: [PATCH 167/202] add 360 guide button->menu_toggle autoconf --- input/autoconf/builtin_win.c | 1 + 1 file changed, 1 insertion(+) diff --git a/input/autoconf/builtin_win.c b/input/autoconf/builtin_win.c index 39540bb467..b359dcc102 100644 --- a/input/autoconf/builtin_win.c +++ b/input/autoconf/builtin_win.c @@ -30,6 +30,7 @@ DECL_BTN(l, 4) \ DECL_BTN(r, 5) \ DECL_BTN(l3, 8 )\ DECL_BTN(r3, 9) \ +DECL_BTN(menu_toggle, 10) \ DECL_AXIS(l2, +4) \ DECL_AXIS(r2, +5) \ DECL_AXIS(l_x_plus, +0) \ From de5270a65174505aa0afdabf1f4cf23a637ab424 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Sat, 7 Sep 2013 21:40:14 +0100 Subject: [PATCH 168/202] Fix support for logitech f310 on windows --- input/dinput.c | 1 + 1 file changed, 1 insertion(+) diff --git a/input/dinput.c b/input/dinput.c index 8343a4865a..a1143e6525 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -405,6 +405,7 @@ static const char* const XINPUT_PAD_NAMES[] = "Xbox 360 Wireless Receiver", "Xbox Receiver for Windows (Wireless Controller)", "Xbox wireless receiver for windows (Controller)", + "Controller (Gamepad F310)", NULL }; From 914f6fcf3372cb2bbaa35bbbfd09d2784a878d00 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Sat, 7 Sep 2013 22:17:31 +0100 Subject: [PATCH 169/202] add more variants of the 360 pad and third-party XI pads --- input/dinput.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/input/dinput.c b/input/dinput.c index a1143e6525..cc28a228d7 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -397,15 +397,26 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p) // example code is a horrible unsightly mess. static const char* const XINPUT_PAD_NAMES[] = { + "XBOX 360 For Windows", "Controller (Gamepad for Xbox 360)", "Controller (XBOX 360 For Windows)", "Controller (Xbox 360 Wireless Receiver for Windows)", "Controller (Xbox wireless receiver for windows)", "XBOX 360 For Windows (Controller)", "Xbox 360 Wireless Receiver", + "Xbox 360 Wireless Controller", "Xbox Receiver for Windows (Wireless Controller)", "Xbox wireless receiver for windows (Controller)", + "Gamepad F310 (Controller)", "Controller (Gamepad F310)", + "Wireless Gamepad F710 (Controller)", + "Controller (Batarang wired controller (XBOX))", + "Afterglow Gamepad for Xbox 360 (Controller)" + "Controller (Rumble Gamepad F510)", + "Controller (Wireless Gamepad F710)", + "Controller (Xbox 360 Wireless Receiver for Windows)", + "Controller (Xbox wireless receiver for windows)", + "Controller (XBOX360 GAMEPAD)", NULL }; From 86c4458f357907d6b352e377ce93b8108fcd5744 Mon Sep 17 00:00:00 2001 From: pinumbernumber <1337rz@gmail.com> Date: Sat, 7 Sep 2013 22:51:23 +0100 Subject: [PATCH 170/202] add madcatz pad --- input/dinput.c | 1 + 1 file changed, 1 insertion(+) diff --git a/input/dinput.c b/input/dinput.c index cc28a228d7..b9a366d71f 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -417,6 +417,7 @@ static const char* const XINPUT_PAD_NAMES[] = "Controller (Xbox 360 Wireless Receiver for Windows)", "Controller (Xbox wireless receiver for windows)", "Controller (XBOX360 GAMEPAD)", + "MadCatz GamePad", NULL }; From 081e526bf906ad5b65be4f63e70163c6d7b309f0 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sat, 7 Sep 2013 21:29:58 -0400 Subject: [PATCH 171/202] (OSX) Support video_monitor_index and audio_device settings --- apple/common/RAGameView.m | 14 ++++++++--- audio/coreaudio.c | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/apple/common/RAGameView.m b/apple/common/RAGameView.m index 15773b7262..3dfb76a0d0 100644 --- a/apple/common/RAGameView.m +++ b/apple/common/RAGameView.m @@ -343,15 +343,23 @@ bool apple_game_view_has_focus(void) bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) { + __block bool result = true; + #ifdef OSX dispatch_sync(dispatch_get_main_queue(), ^{ - // TODO: Multi-monitor support // TODO: Sceen mode support if (fullscreen && !g_has_went_fullscreen) { - [g_view enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; + if (g_settings.video.monitor_index >= [NSScreen screens].count) + { + apple_display_alert(@"Could not go fullscreen: Monitor index out of range.", nil); + result = false; + return; + } + + [g_view enterFullScreenMode:[NSScreen screens][g_settings.video.monitor_index] withOptions:nil]; [NSCursor hide]; } else if (!fullscreen && g_has_went_fullscreen) @@ -369,7 +377,7 @@ bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) // TODO: Maybe iOS users should be apple to show/hide the status bar here? - return true; + return result; } #ifdef IOS diff --git a/audio/coreaudio.c b/audio/coreaudio.c index b396e6a1e3..4d71eb4b8a 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -22,6 +22,10 @@ #include "../boolean.h" #include +#ifdef OSX +#include +#endif + #include #include #include @@ -93,6 +97,48 @@ static OSStatus audio_write_cb(void *userdata, AudioUnitRenderActionFlags *actio return noErr; } +#ifdef OSX +static void choose_output_device(coreaudio_t *dev, const char* device) +{ + AudioObjectPropertyAddress propaddr = + { + kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster + }; + + UInt32 size = 0; + + if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propaddr, 0, 0, &size) != noErr) + return; + + UInt32 deviceCount = size / sizeof(AudioDeviceID); + AudioDeviceID *devices = malloc(size); + + if (!devices || AudioObjectGetPropertyData(kAudioObjectSystemObject, &propaddr, 0, 0, &size, devices) != noErr) + goto done; + + propaddr.mScope = kAudioDevicePropertyScopeOutput; + propaddr.mSelector = kAudioDevicePropertyDeviceName; + size = 1024; + + for (unsigned i = 0; i < deviceCount; i ++) + { + char device_name[1024]; + device_name[0] = 0; + + if (AudioObjectGetPropertyData(devices[i], &propaddr, 0, 0, &size, device_name) == noErr && strcmp(device_name, device) == 0) + { + AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &devices[i], sizeof(AudioDeviceID)); + goto done; + } + } + +done: + free(devices); +} +#endif + static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) { (void)device; @@ -121,6 +167,11 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) if (AudioComponentInstanceNew(comp, &dev->dev) != noErr) goto error; +#ifdef OSX + if (device) + choose_output_device(dev, device); +#endif + dev->dev_alive = true; // Set audio format From 837c96bbc8942daf329d5afdb53b702923c363e2 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 8 Sep 2013 19:39:28 -0400 Subject: [PATCH 172/202] (OSX) Add system key items to the settings menu; fix a few warnings --- apple/OSX/settings.m | 7 +- apple/common/RAGameView.m | 1 + apple/common/setting_data.h | 236 +++++++++++++++++++++--------------- 3 files changed, 144 insertions(+), 100 deletions(-) diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 6b20a58357..939fe4765c 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -52,7 +52,10 @@ static uint32_t key_id_for_name(const char* name) static const char* get_input_config_key(const rarch_setting_t* setting, const char* type) { static char buffer[32]; - snprintf(buffer, 32, "input_player%d_%s%c%s", setting->input_player, setting->name, type ? '_' : '\0', type); + if (setting->input_player) + snprintf(buffer, 32, "input_player%d_%s%c%s", setting->input_player, setting->name, type ? '_' : '\0', type); + else + snprintf(buffer, 32, "input_%s%c%s", setting->name, type ? '_' : '\0', type); return buffer; } @@ -127,6 +130,7 @@ static const char* get_axis_name(const rarch_setting_t* setting) case ST_PATH: self.stringValue = @((const char*)aSetting->value); break; case ST_BOOL: self.booleanValue = *(bool*)aSetting->value; break; case ST_BIND: [self updateInputString]; break; + default: break; } } @@ -444,6 +448,7 @@ static const char* get_axis_name(const rarch_setting_t* setting) case ST_PATH: s = [outlineView makeViewWithIdentifier:@"RAPathSetting" owner:nil]; break; case ST_STRING: s = [outlineView makeViewWithIdentifier:@"RAStringSetting" owner:nil]; break; case ST_BIND: s = [outlineView makeViewWithIdentifier:@"RABindSetting" owner:nil]; break; + default: break; } s.setting = setting; return s; diff --git a/apple/common/RAGameView.m b/apple/common/RAGameView.m index 3dfb76a0d0..8fec390435 100644 --- a/apple/common/RAGameView.m +++ b/apple/common/RAGameView.m @@ -17,6 +17,7 @@ #include "rarch_wrapper.h" #include "general.h" +#include "gfx/gfx_common.h" #ifdef IOS diff --git a/apple/common/setting_data.h b/apple/common/setting_data.h index 3fcac23459..0f91eb5825 100644 --- a/apple/common/setting_data.h +++ b/apple/common/setting_data.h @@ -64,6 +64,7 @@ const rarch_setting_t setting_data[] = /***********/ /* DRIVERS */ /***********/ +#if 0 START_GROUP("Drivers") START_SUB_GROUP("Drivers") CONFIG_STRING(g_settings.video.driver, "video_driver", "Video Driver") @@ -73,6 +74,7 @@ const rarch_setting_t setting_data[] = CONFIG_STRING(g_settings.input.joypad_driver, "input_joypad_driver", "Joypad Driver") END_SUB_GROUP() END_GROUP() +#endif /*********/ /* PATHS */ @@ -118,6 +120,82 @@ const rarch_setting_t setting_data[] = END_SUB_GROUP() END_GROUP() + /*********/ + /* VIDEO */ + /*********/ + START_GROUP("Video") + START_SUB_GROUP("Monitor") + CONFIG_INT(g_settings.video.monitor_index, "video_monitor_index", "Monitor Index") + CONFIG_BOOL(g_settings.video.fullscreen, "video_fullscreen", "Use Fullscreen mode") // if (!g_extern.force_fullscreen) + CONFIG_BOOL(g_settings.video.windowed_fullscreen, "video_windowed_fullscreen", "Windowed Fullscreen Mode") + CONFIG_INT(g_settings.video.fullscreen_x, "video_fullscreen_x", "Fullscreen Width") + CONFIG_INT(g_settings.video.fullscreen_y, "video_fullscreen_y", "Fullscreen Height") + CONFIG_FLOAT(g_settings.video.refresh_rate, "video_refresh_rate", "Refresh Rate") + END_SUB_GROUP() + +#if 0 + /* Video: Window Manager */ + START_SUB_GROUP("Window Manager") + CONFIG_BOOL(g_settings.video.disable_composition, "video_disable_composition", "Disable WM Composition") + END_SUB_GROUP() +#endif + + START_SUB_GROUP("Aspect") + CONFIG_BOOL(g_settings.video.force_aspect, "video_force_aspect", "Force aspect ratio") + CONFIG_FLOAT(g_settings.video.aspect_ratio, "video_aspect_ratio", "Aspect Ratio") + CONFIG_BOOL(g_settings.video.aspect_ratio_auto, "video_aspect_ratio_auto", "Use Auto Aspect Ratio") + CONFIG_INT(g_settings.video.aspect_ratio_idx, "aspect_ratio_index", "Aspect Ratio Index") + END_SUB_GROUP() + + START_SUB_GROUP("Scaling") + CONFIG_FLOAT(g_settings.video.xscale, "video_xscale", "X Scale") + CONFIG_FLOAT(g_settings.video.yscale, "video_yscale", "Y Scale") + CONFIG_BOOL(g_settings.video.scale_integer, "video_scale_integer", "Force integer scaling") + + CONFIG_INT(g_extern.console.screen.viewports.custom_vp.x, "custom_viewport_x", "Custom Viewport X") + CONFIG_INT(g_extern.console.screen.viewports.custom_vp.y, "custom_viewport_y", "Custom Viewport Y") + CONFIG_INT(g_extern.console.screen.viewports.custom_vp.width, "custom_viewport_width", "Custom Viewport Width") + CONFIG_INT(g_extern.console.screen.viewports.custom_vp.height, "custom_viewport_height", "Custom Viewport Height") + + CONFIG_BOOL(g_settings.video.smooth, "video_smooth", "Use bilinear filtering") + END_SUB_GROUP() + + START_SUB_GROUP("Shader") + CONFIG_BOOL(g_settings.video.shader_enable, "video_shader_enable", "Enable Shaders") + CONFIG_PATH(g_settings.video.shader_dir, "video_shader_dir", "Shader Directory") + CONFIG_PATH(g_settings.video.shader_path, "video_shader", "Shader") + END_SUB_GROUP() + + START_SUB_GROUP("Sync") + CONFIG_BOOL(g_settings.video.threaded, "video_threaded", "Use threaded video") + CONFIG_BOOL(g_settings.video.vsync, "video_vsync", "Use VSync") + CONFIG_BOOL(g_settings.video.hard_sync, "video_hard_sync", "Use OpenGL Hard Sync") + CONFIG_INT(g_settings.video.hard_sync_frames, "video_hard_sync_frames", "Number of Hard Sync frames") // 0 - 3 + END_SUB_GROUP() + + START_SUB_GROUP("Misc") + CONFIG_BOOL(g_settings.video.post_filter_record, "video_post_filter_record", "Post filter record") + CONFIG_BOOL(g_settings.video.gpu_record, "video_gpu_record", "GPU Record") + CONFIG_BOOL(g_settings.video.gpu_screenshot, "video_gpu_screenshot", "GPU Screenshot") + CONFIG_BOOL(g_settings.video.allow_rotate, "video_allow_rotate", "Allow rotation") + CONFIG_BOOL(g_settings.video.crop_overscan, "video_crop_overscan", "Crop Overscan") + + #ifdef HAVE_DYLIB + CONFIG_PATH(g_settings.video.filter_path, "video_filter", "Software filter"), + #endif + END_SUB_GROUP() + + START_SUB_GROUP("Messages") + CONFIG_PATH(g_settings.video.font_path, "video_font_path", "Font Path") + CONFIG_FLOAT(g_settings.video.font_size, "video_font_size", "Font Size") + CONFIG_BOOL(g_settings.video.font_enable, "video_font_enable", "Font Enable") + CONFIG_BOOL(g_settings.video.font_scale, "video_font_scale", "Font Scale") + CONFIG_FLOAT(g_settings.video.msg_pos_x, "video_message_pos_x", "Message X Position") + CONFIG_FLOAT(g_settings.video.msg_pos_y, "video_message_pos_y", "Message Y Position") + /* message color */ + END_SUB_GROUP() + END_GROUP() + /*********/ /* AUDIO */ /*********/ @@ -181,106 +259,66 @@ const rarch_setting_t setting_data[] = #endif END_SUB_GROUP() + START_SUB_GROUP("Meta Keys") + CONFIG_BIND(g_settings.input.binds[0][RARCH_FAST_FORWARD_KEY], 0, "toggle_fast_forward", "Fast forward toggle") + CONFIG_BIND(g_settings.input.binds[0][RARCH_FAST_FORWARD_HOLD_KEY], 0, "hold_fast_forward", "Fast forward hold") + CONFIG_BIND(g_settings.input.binds[0][RARCH_LOAD_STATE_KEY], 0, "load_state", "Load state") + CONFIG_BIND(g_settings.input.binds[0][RARCH_SAVE_STATE_KEY], 0, "save_state", "Save state") + CONFIG_BIND(g_settings.input.binds[0][RARCH_FULLSCREEN_TOGGLE_KEY], 0, "toggle_fullscreen", "Fullscreen toggle") + CONFIG_BIND(g_settings.input.binds[0][RARCH_QUIT_KEY], 0, "exit_emulator", "Quit RetroArch") + CONFIG_BIND(g_settings.input.binds[0][RARCH_STATE_SLOT_PLUS], 0, "state_slot_increase", "Savestate slot +") + CONFIG_BIND(g_settings.input.binds[0][RARCH_STATE_SLOT_MINUS], 0, "state_slot_decrease", "Savestate slot -") + CONFIG_BIND(g_settings.input.binds[0][RARCH_REWIND], 0, "rewind", "Rewind") + CONFIG_BIND(g_settings.input.binds[0][RARCH_MOVIE_RECORD_TOGGLE], 0, "movie_record_toggle", "Movie record toggle") + CONFIG_BIND(g_settings.input.binds[0][RARCH_PAUSE_TOGGLE], 0, "pause_toggle", "Pause toggle") + CONFIG_BIND(g_settings.input.binds[0][RARCH_FRAMEADVANCE], 0, "frame_advance", "Frameadvance") + CONFIG_BIND(g_settings.input.binds[0][RARCH_RESET], 0, "reset", "Reset game") + CONFIG_BIND(g_settings.input.binds[0][RARCH_SHADER_NEXT], 0, "shader_next", "Next shader") + CONFIG_BIND(g_settings.input.binds[0][RARCH_SHADER_PREV], 0, "shader_prev", "Previous shader") + CONFIG_BIND(g_settings.input.binds[0][RARCH_CHEAT_INDEX_PLUS], 0, "cheat_index_plus", "Cheat index +") + CONFIG_BIND(g_settings.input.binds[0][RARCH_CHEAT_INDEX_MINUS], 0, "cheat_index_minus", "Cheat index -") + CONFIG_BIND(g_settings.input.binds[0][RARCH_CHEAT_TOGGLE], 0, "cheat_toggle", "Cheat toggle") + CONFIG_BIND(g_settings.input.binds[0][RARCH_SCREENSHOT], 0, "screenshot", "Take screenshot") + CONFIG_BIND(g_settings.input.binds[0][RARCH_DSP_CONFIG], 0, "dsp_config", "DSP config") + CONFIG_BIND(g_settings.input.binds[0][RARCH_MUTE], 0, "audio_mute", "Audio mute toggle") + CONFIG_BIND(g_settings.input.binds[0][RARCH_NETPLAY_FLIP], 0, "netplay_flip_players", "Netplay flip players") + CONFIG_BIND(g_settings.input.binds[0][RARCH_SLOWMOTION], 0, "slowmotion", "Slow motion") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ENABLE_HOTKEY], 0, "enable_hotkey", "Enable hotkeys") + CONFIG_BIND(g_settings.input.binds[0][RARCH_VOLUME_UP], 0, "volume_up", "Volume +") + CONFIG_BIND(g_settings.input.binds[0][RARCH_VOLUME_DOWN], 0, "volume_down", "Volume -") + CONFIG_BIND(g_settings.input.binds[0][RARCH_OVERLAY_NEXT], 0, "overlay_next", "Overlay next") + CONFIG_BIND(g_settings.input.binds[0][RARCH_DISK_EJECT_TOGGLE], 0, "disk_eject_toggle", "Disk eject toggle") + CONFIG_BIND(g_settings.input.binds[0][RARCH_DISK_NEXT], 0, "disk_next", "Disk next") + CONFIG_BIND(g_settings.input.binds[0][RARCH_GRAB_MOUSE_TOGGLE], 0, "grab_mouse_toggle", "Grab mouse toggle") + CONFIG_BIND(g_settings.input.binds[0][RARCH_MENU_TOGGLE], 0, "menu_toggle", "RGUI menu toggle") + END_SUB_GROUP() + START_SUB_GROUP("Player 1") - CONFIG_BIND(g_settings.input.binds[0][ 0], 1, "b", "B button (down)") - CONFIG_BIND(g_settings.input.binds[0][ 1], 1, "y", "Y button (left)") - CONFIG_BIND(g_settings.input.binds[0][ 2], 1, "select", "Select button") - CONFIG_BIND(g_settings.input.binds[0][ 3], 1, "start", "Start button") - CONFIG_BIND(g_settings.input.binds[0][ 4], 1, "up", "Up D-pad") - CONFIG_BIND(g_settings.input.binds[0][ 5], 1, "down", "Down D-pad") - CONFIG_BIND(g_settings.input.binds[0][ 6], 1, "left", "Left D-pad") - CONFIG_BIND(g_settings.input.binds[0][ 7], 1, "right", "Right D-pad") - CONFIG_BIND(g_settings.input.binds[0][ 8], 1, "a", "A button (right)") - CONFIG_BIND(g_settings.input.binds[0][ 9], 1, "x", "X button (top)") - CONFIG_BIND(g_settings.input.binds[0][10], 1, "l", "L button (left shoulder)") - CONFIG_BIND(g_settings.input.binds[0][11], 1, "r", "R button (right shoulder)") - CONFIG_BIND(g_settings.input.binds[0][12], 1, "l2", "L2 button (left shoulder #2)") - CONFIG_BIND(g_settings.input.binds[0][13], 1, "r2", "R2 button (right shoulder #2)") - CONFIG_BIND(g_settings.input.binds[0][14], 1, "l3", "L3 button (left analog button)") - CONFIG_BIND(g_settings.input.binds[0][15], 1, "r3", "R3 button (right analog button)") - CONFIG_BIND(g_settings.input.binds[0][16], 1, "turbo", "Turbo enable") - CONFIG_BIND(g_settings.input.binds[0][17], 1, "l_x_plus", "Left analog X+ (right)") - CONFIG_BIND(g_settings.input.binds[0][18], 1, "l_x_minus", "Left analog X- (left)") - CONFIG_BIND(g_settings.input.binds[0][19], 1, "l_y_plus", "Left analog Y+ (down)") - CONFIG_BIND(g_settings.input.binds[0][20], 1, "l_y_minus", "Left analog Y- (up)") - CONFIG_BIND(g_settings.input.binds[0][21], 1, "r_x_plus", "Right analog X+ (right)") - CONFIG_BIND(g_settings.input.binds[0][22], 1, "r_x_minus", "Right analog X- (left)") - CONFIG_BIND(g_settings.input.binds[0][23], 1, "r_y_plus", "Right analog Y+ (down)") - CONFIG_BIND(g_settings.input.binds[0][24], 1, "r_y_minus", "Right analog Y- (up)") - END_SUB_GROUP() - END_GROUP() - - /*********/ - /* VIDEO */ - /*********/ - START_GROUP("Video") - START_SUB_GROUP("Monitor") - CONFIG_INT(g_settings.video.monitor_index, "video_monitor_index", "Monitor Index") - CONFIG_BOOL(g_settings.video.fullscreen, "video_fullscreen", "Use Fullscreen mode") // if (!g_extern.force_fullscreen) - CONFIG_BOOL(g_settings.video.windowed_fullscreen, "video_windowed_fullscreen", "Windowed Fullscreen Mode") - CONFIG_INT(g_settings.video.fullscreen_x, "video_fullscreen_x", "Fullscreen Width") - CONFIG_INT(g_settings.video.fullscreen_y, "video_fullscreen_y", "Fullscreen Height") - CONFIG_FLOAT(g_settings.video.refresh_rate, "video_refresh_rate", "Refresh Rate") - END_SUB_GROUP() - - /* Video: Window Manager */ - START_SUB_GROUP("Window Manager") - CONFIG_BOOL(g_settings.video.disable_composition, "video_disable_composition", "Disable WM Composition") - END_SUB_GROUP() - - START_SUB_GROUP("Aspect") - CONFIG_BOOL(g_settings.video.force_aspect, "video_force_aspect", "Force aspect ratio") - CONFIG_FLOAT(g_settings.video.aspect_ratio, "video_aspect_ratio", "Aspect Ratio") - CONFIG_INT(g_settings.video.aspect_ratio_idx, "aspect_ratio_index", "Aspect Ratio Index") - CONFIG_BOOL(g_settings.video.aspect_ratio_auto, "video_aspect_ratio_auto", "Use Auto Aspect Ratio") - END_SUB_GROUP() - - START_SUB_GROUP("Scaling") - CONFIG_FLOAT(g_settings.video.xscale, "video_xscale", "X Scale") - CONFIG_FLOAT(g_settings.video.yscale, "video_yscale", "Y Scale") - CONFIG_BOOL(g_settings.video.scale_integer, "video_scale_integer", "Force integer scaling") - - CONFIG_INT(g_extern.console.screen.viewports.custom_vp.x, "custom_viewport_x", "Custom Viewport X") - CONFIG_INT(g_extern.console.screen.viewports.custom_vp.y, "custom_viewport_y", "Custom Viewport Y") - CONFIG_INT(g_extern.console.screen.viewports.custom_vp.width, "custom_viewport_width", "Custom Viewport Width") - CONFIG_INT(g_extern.console.screen.viewports.custom_vp.height, "custom_viewport_height", "Custom Viewport Height") - - CONFIG_BOOL(g_settings.video.smooth, "video_smooth", "Use bilinear filtering") - END_SUB_GROUP() - - START_SUB_GROUP("Shader") - CONFIG_BOOL(g_settings.video.shader_enable, "video_shader_enable", "Enable Shaders") - CONFIG_PATH(g_settings.video.shader_dir, "video_shader_dir", "Shader Directory") - CONFIG_PATH(g_settings.video.shader_path, "video_shader", "Shader") - END_SUB_GROUP() - - START_SUB_GROUP("Sync") - CONFIG_BOOL(g_settings.video.threaded, "video_threaded", "Use threaded video") - CONFIG_BOOL(g_settings.video.vsync, "video_vsync", "Use VSync") - CONFIG_BOOL(g_settings.video.hard_sync, "video_hard_sync", "Use OpenGL Hard Sync") - CONFIG_INT(g_settings.video.hard_sync_frames, "video_hard_sync_frames", "Number of Hard Sync frames") // 0 - 3 - END_SUB_GROUP() - - START_SUB_GROUP("Misc") - CONFIG_BOOL(g_settings.video.post_filter_record, "video_post_filter_record", "Post filter record") - CONFIG_BOOL(g_settings.video.gpu_record, "video_gpu_record", "GPU Record") - CONFIG_BOOL(g_settings.video.gpu_screenshot, "video_gpu_screenshot", "GPU Screenshot") - CONFIG_BOOL(g_settings.video.allow_rotate, "video_allow_rotate", "Allow rotation") - CONFIG_BOOL(g_settings.video.crop_overscan, "video_crop_overscan", "Crop Overscan") - - #ifdef HAVE_DYLIB - CONFIG_PATH(g_settings.video.filter_path, "video_filter", "Software filter"), - #endif - END_SUB_GROUP() - - START_SUB_GROUP("Messages") - CONFIG_PATH(g_settings.video.font_path, "video_font_path", "Font Path") - CONFIG_FLOAT(g_settings.video.font_size, "video_font_size", "Font Size") - CONFIG_BOOL(g_settings.video.font_enable, "video_font_enable", "Font Enable") - CONFIG_BOOL(g_settings.video.font_scale, "video_font_scale", "Font Scale") - CONFIG_FLOAT(g_settings.video.msg_pos_x, "video_message_pos_x", "Message X Position") - CONFIG_FLOAT(g_settings.video.msg_pos_y, "video_message_pos_y", "Message Y Position") - /* message color */ + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_B], 1, "b", "B button (down)") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_Y], 1, "y", "Y button (left)") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_SELECT],1, "select", "Select button") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_START], 1, "start", "Start button") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_UP], 1, "up", "Up D-pad") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_DOWN], 1, "down", "Down D-pad") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_LEFT], 1, "left", "Left D-pad") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_RIGHT], 1, "right", "Right D-pad") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_A], 1, "a", "A button (right)") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_X], 1, "x", "X button (top)") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L], 1, "l", "L button (left shoulder)") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R], 1, "r", "R button (right shoulder)") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L2], 1, "l2", "L2 button (left shoulder #2)") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R2], 1, "r2", "R2 button (right shoulder #2)") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L3], 1, "l3", "L3 button (left analog button)") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R3], 1, "r3", "R3 button (right analog button)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_TURBO_ENABLE], 1, "turbo", "Turbo enable") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_PLUS], 1, "l_x_plus", "Left analog X+ (right)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_MINUS], 1, "l_x_minus", "Left analog X- (left)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_Y_PLUS], 1, "l_y_plus", "Left analog Y+ (down)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_Y_MINUS], 1, "l_y_minus", "Left analog Y- (up)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_PLUS], 1, "r_x_plus", "Right analog X+ (right)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_MINUS], 1, "r_x_minus", "Right analog X- (left)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_Y_PLUS], 1, "r_y_plus", "Right analog Y+ (down)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_Y_MINUS], 1, "r_y_minus", "Right analog Y- (up)") END_SUB_GROUP() END_GROUP() From 0b7de206de64486d32291ecdcf57435cdf4c16a5 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 8 Sep 2013 22:41:01 -0400 Subject: [PATCH 173/202] (OSX) Only allow numeric input for integer and float settings --- apple/OSX/settings.m | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 939fe4765c..650983a4c2 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -86,6 +86,49 @@ static const char* get_axis_name(const rarch_setting_t* setting) return buffer; } +@interface RANumberFormatter : NSNumberFormatter +@end + +@implementation RANumberFormatter +- (id)initWithFloatSupport:(bool)allowFloat minimum:(double)min maximum:(double)max +{ + self = [super init]; + self.allowsFloats = allowFloat; + self.maximumFractionDigits = 10; + + if (min || max) + { + self.minimum = @(min); + self.maximum = @(max); + } + + return self; +} + +- (BOOL)isPartialStringValid:(NSString*)partialString newEditingString:(NSString**)newString errorDescription:(NSString**)error +{ + bool hasDot = false; + + if (partialString.length) + for (int i = 0; i != partialString.length; i ++) + { + unichar ch = [partialString characterAtIndex:i]; + + if (self.allowsFloats && !hasDot && ch == '.') + { + hasDot = true; + continue; + } + + if (!isnumber(ch)) + return NO; + } + + return YES; +} +@end + + @interface RAInputBinder : NSWindow @end @@ -122,6 +165,16 @@ static const char* get_axis_name(const rarch_setting_t* setting) if (!_setting) return; + if (aSetting->type == ST_INT || aSetting->type == ST_FLOAT) + { + self.textField.formatter = [[RANumberFormatter alloc] initWithFloatSupport:aSetting->type == ST_FLOAT + minimum:aSetting->min + maximum:aSetting->max]; + } + else + self.textField.formatter = nil; + + // Set value switch (aSetting->type) { case ST_INT: self.numericValue = @(*(int*)aSetting->value); break; From 29fdf1fd7ea19e65f7a93b27b359bc1997f6dab4 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 9 Sep 2013 17:52:02 -0400 Subject: [PATCH 174/202] (OSX/iOS) Consolodate key map tables and binding routines --- apple/OSX/settings.m | 45 ++------ apple/common/apple_input.c | 189 +++++++----------------------- apple/common/apple_input.h | 4 + apple/common/keycode.h | 17 +++ apple/common/keycode.inc | 222 ++++++++++++++++++++++++++++++++++++ apple/common/setting_data.h | 53 --------- apple/iOS/settings.m | 99 ++-------------- 7 files changed, 302 insertions(+), 327 deletions(-) create mode 100644 apple/common/keycode.inc diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 650983a4c2..9059dd9fb2 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -242,43 +242,18 @@ static const char* get_axis_name(const rarch_setting_t* setting) - (void)checkBind:(NSTimer*)send { - // Keyboard - for (int i = 0; apple_key_name_map[i].hid_id; i++) - { - if (g_current_input_data.keys[apple_key_name_map[i].hid_id]) - { - BINDFOR(*_setting).key = input_translate_keysym_to_rk(apple_key_name_map[i].hid_id); - [self dismissBinder]; - return; - } - } + int32_t value = 0; - // Joystick - if (g_current_input_data.pad_buttons[0]) - { - for (int i = 0; i != 32; i ++) - { - if (g_current_input_data.pad_buttons[0] & (1 << i)) - { - BINDFOR(*_setting).joykey = i; - [self dismissBinder]; - return; - } - } - } + if ((value = apple_input_find_any_key())) + BINDFOR(*_setting).key = input_translate_keysym_to_rk(value); + else if ((value = apple_input_find_any_button(0)) >= 0) + BINDFOR(*_setting).joykey = value; + else if ((value = apple_input_find_any_axis(0))) + BINDFOR(*_setting).joyaxis = (value > 0) ? AXIS_POS(value - 1) : AXIS_NEG(value - 1); + else + return; - // Pad Axis - for (int i = 0; i < 4; i++) - { - int16_t value = g_current_input_data.pad_axis[0][i]; - - if (abs(value) > 0x4000) - { - BINDFOR(*_setting).joyaxis = (value > 0x1000) ? AXIS_POS(i) : AXIS_NEG(i); - [self dismissBinder]; - break; - } - } + [self dismissBinder]; } - (IBAction)doGetBind:(id)sender diff --git a/apple/common/apple_input.c b/apple/common/apple_input.c index 07a1bdecfa..152acb13a0 100644 --- a/apple/common/apple_input.c +++ b/apple/common/apple_input.c @@ -22,14 +22,14 @@ #include "general.h" #include "driver.h" +#include "keycode.inc" + extern const rarch_joypad_driver_t apple_joypad; static const rarch_joypad_driver_t* const g_joydriver = &apple_joypad; apple_input_data_t g_current_input_data; apple_input_data_t g_polled_input_data; -static const struct rarch_key_map rarch_key_map_hidusage[]; - #ifdef OSX // Taken from https://github.com/depp/keycode, check keycode.h for license const unsigned char MAC_NATIVE_TO_HID[128] = { 4, 22, 7, 9, 11, 10, 29, 27, 6, 25,255, 5, 20, 26, 8, 21, @@ -101,6 +101,42 @@ void apple_input_handle_key_event(unsigned keycode, bool down) g_current_input_data.keys[keycode] = down; } + +int32_t apple_input_find_any_key() +{ + for (int i = 0; apple_key_name_map[i].hid_id; i++) + if (g_current_input_data.keys[apple_key_name_map[i].hid_id]) + return apple_key_name_map[i].hid_id; + + return 0; +} + +int32_t apple_input_find_any_button(uint32_t port) +{ + uint32_t buttons = g_current_input_data.pad_buttons[port] | + ((port == 0) ? apple_input_get_icade_buttons() : 0); + + if (g_current_input_data.pad_buttons[port]) + for (int i = 0; i != 32; i ++) + if (buttons & (1 << i)) + return i; + + return -1; +} + +int32_t apple_input_find_any_axis(uint32_t port) +{ + for (int i = 0; i < 4; i++) + { + int16_t value = g_current_input_data.pad_axis[port][i]; + + if (abs(value) > 0x4000) + return (value < 0) ? -(i + 1) : i + 1; + } + + return 0; +} + // Game thread interface static bool apple_key_pressed(enum retro_key key) { @@ -118,7 +154,7 @@ static bool apple_is_pressed(unsigned port_num, const struct retro_keybind *bind // Exported input driver static void *apple_input_init(void) { - input_init_keyboard_lut(rarch_key_map_hidusage); + input_init_keyboard_lut(apple_key_map_hidusage); memset(&g_polled_input_data, 0, sizeof(g_polled_input_data)); return (void*)-1; } @@ -273,150 +309,3 @@ const input_driver_t input_apple = { apple_input_set_keybinds, "apple_input", }; - - -// Key table -#include "keycode.h" -static const struct rarch_key_map rarch_key_map_hidusage[] = { - { KEY_Delete, RETROK_BACKSPACE }, - { KEY_Tab, RETROK_TAB }, -// RETROK_CLEAR }, - { KEY_Enter, RETROK_RETURN }, - { KEY_Pause, RETROK_PAUSE }, - { KEY_Escape, RETROK_ESCAPE }, - { KEY_Space, RETROK_SPACE }, -// RETROK_EXCLAIM }, -// RETROK_QUOTEDBL }, -// RETROK_HASH }, -// RETROK_DOLLAR }, -// RETROK_AMPERSAND }, - { KEY_Quote, RETROK_QUOTE }, -// RETROK_LEFTPAREN }, -// RETROK_RIGHTPAREN }, -// RETROK_ASTERISK }, -// RETROK_PLUS }, - { KEY_Comma, RETROK_COMMA }, - { KEY_Minus, RETROK_MINUS }, - { KEY_Period, RETROK_PERIOD }, - { KEY_Slash, RETROK_SLASH }, - { KEY_0, RETROK_0 }, - { KEY_1, RETROK_1 }, - { KEY_2, RETROK_2 }, - { KEY_3, RETROK_3 }, - { KEY_4, RETROK_4 }, - { KEY_5, RETROK_5 }, - { KEY_6, RETROK_6 }, - { KEY_7, RETROK_7 }, - { KEY_8, RETROK_8 }, - { KEY_9, RETROK_9 }, -// RETROK_COLON }, - { KEY_Semicolon, RETROK_SEMICOLON }, -// RETROK_LESS }, - { KEY_Equals, RETROK_EQUALS }, -// RETROK_GREATER }, -// RETROK_QUESTION }, -// RETROK_AT }, - { KEY_LeftBracket, RETROK_LEFTBRACKET }, - { KEY_Backslash, RETROK_BACKSLASH }, - { KEY_RightBracket, RETROK_RIGHTBRACKET }, -// RETROK_CARET }, -// RETROK_UNDERSCORE }, - { KEY_Grave, RETROK_BACKQUOTE }, - { KEY_A, RETROK_a }, - { KEY_B, RETROK_b }, - { KEY_C, RETROK_c }, - { KEY_D, RETROK_d }, - { KEY_E, RETROK_e }, - { KEY_F, RETROK_f }, - { KEY_G, RETROK_g }, - { KEY_H, RETROK_h }, - { KEY_I, RETROK_i }, - { KEY_J, RETROK_j }, - { KEY_K, RETROK_k }, - { KEY_L, RETROK_l }, - { KEY_M, RETROK_m }, - { KEY_N, RETROK_n }, - { KEY_O, RETROK_o }, - { KEY_P, RETROK_p }, - { KEY_Q, RETROK_q }, - { KEY_R, RETROK_r }, - { KEY_S, RETROK_s }, - { KEY_T, RETROK_t }, - { KEY_U, RETROK_u }, - { KEY_V, RETROK_v }, - { KEY_W, RETROK_w }, - { KEY_X, RETROK_x }, - { KEY_Y, RETROK_y }, - { KEY_Z, RETROK_z }, - { KEY_DeleteForward, RETROK_DELETE }, - - { KP_0, RETROK_KP0 }, - { KP_1, RETROK_KP1 }, - { KP_2, RETROK_KP2 }, - { KP_3, RETROK_KP3 }, - { KP_4, RETROK_KP4 }, - { KP_5, RETROK_KP5 }, - { KP_6, RETROK_KP6 }, - { KP_7, RETROK_KP7 }, - { KP_8, RETROK_KP8 }, - { KP_9, RETROK_KP9 }, - { KP_Point, RETROK_KP_PERIOD }, - { KP_Divide, RETROK_KP_DIVIDE }, - { KP_Multiply, RETROK_KP_MULTIPLY }, - { KP_Subtract, RETROK_KP_MINUS }, - { KP_Add, RETROK_KP_PLUS }, - { KP_Enter, RETROK_KP_ENTER }, - { KP_Equals, RETROK_KP_EQUALS }, - - { KEY_Up, RETROK_UP }, - { KEY_Down, RETROK_DOWN }, - { KEY_Right, RETROK_RIGHT }, - { KEY_Left, RETROK_LEFT }, - { KEY_Insert, RETROK_INSERT }, - { KEY_Home, RETROK_HOME }, - { KEY_End, RETROK_END }, - { KEY_PageUp, RETROK_PAGEUP }, - { KEY_PageDown, RETROK_PAGEDOWN }, - - { KEY_F1, RETROK_F1 }, - { KEY_F2, RETROK_F2 }, - { KEY_F3, RETROK_F3 }, - { KEY_F4, RETROK_F4 }, - { KEY_F5, RETROK_F5 }, - { KEY_F6, RETROK_F6 }, - { KEY_F7, RETROK_F7 }, - { KEY_F8, RETROK_F8 }, - { KEY_F9, RETROK_F9 }, - { KEY_F10, RETROK_F10 }, - { KEY_F11, RETROK_F11 }, - { KEY_F12, RETROK_F12 }, - { KEY_F13, RETROK_F13 }, - { KEY_F14, RETROK_F14 }, - { KEY_F15, RETROK_F15 }, - -// RETROK_NUMLOCK }, - { KEY_CapsLock, RETROK_CAPSLOCK }, -// RETROK_SCROLLOCK }, - { KEY_RightShift, RETROK_RSHIFT }, - { KEY_LeftShift, RETROK_LSHIFT }, - { KEY_RightControl, RETROK_RCTRL }, - { KEY_LeftControl, RETROK_LCTRL }, - { KEY_RightAlt, RETROK_RALT }, - { KEY_LeftAlt, RETROK_LALT }, - { KEY_RightGUI, RETROK_RMETA }, - { KEY_LeftGUI, RETROK_RMETA }, -// RETROK_LSUPER }, -// RETROK_RSUPER }, -// RETROK_MODE }, -// RETROK_COMPOSE }, - -// RETROK_HELP }, - { KEY_PrintScreen, RETROK_PRINT }, -// RETROK_SYSREQ }, -// RETROK_BREAK }, - { KEY_Menu, RETROK_MENU }, -// RETROK_POWER }, -// RETROK_EURO }, -// RETROK_UNDO }, - { 0, RETROK_UNKNOWN } -}; diff --git a/apple/common/apple_input.h b/apple/common/apple_input.h index 4a1ee13788..8d95746597 100644 --- a/apple/common/apple_input.h +++ b/apple/common/apple_input.h @@ -50,4 +50,8 @@ void apple_input_enable_icade(bool on); uint32_t apple_input_get_icade_buttons(); void apple_input_handle_key_event(unsigned keycode, bool down); +extern int32_t apple_input_find_any_key(); +extern int32_t apple_input_find_any_button(uint32_t port); +extern int32_t apple_input_find_any_axis(uint32_t port); + #endif diff --git a/apple/common/keycode.h b/apple/common/keycode.h index e24fe023d4..f0b8a1219a 100644 --- a/apple/common/keycode.h +++ b/apple/common/keycode.h @@ -153,4 +153,21 @@ enum { KEY_RightAlt = 230, KEY_RightGUI = 231 }; + +// + +#include "input/input_common.h" // < For rarch_key_map + +struct apple_key_name_map_entry +{ + const char* const keyname; + const uint32_t hid_id; +}; + +extern const struct apple_key_name_map_entry apple_key_name_map[]; +extern const struct rarch_key_map apple_key_map_hidusage[]; + + +const char* apple_keycode_hidusage_to_name(uint32_t hid_usage); + #endif diff --git a/apple/common/keycode.inc b/apple/common/keycode.inc new file mode 100644 index 0000000000..f9d7363113 --- /dev/null +++ b/apple/common/keycode.inc @@ -0,0 +1,222 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * 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 "keycode.h" + +const struct apple_key_name_map_entry apple_key_name_map[] = +{ + { "left", KEY_Left }, { "right", KEY_Right }, + { "up", KEY_Up }, { "down", KEY_Down }, + { "enter", KEY_Enter }, { "kp_enter", KP_Enter }, + { "space", KEY_Space }, { "tab", KEY_Tab }, + { "shift", KEY_LeftShift }, { "rshift", KEY_RightShift }, + { "ctrl", KEY_LeftControl }, { "alt", KEY_LeftAlt }, + { "escape", KEY_Escape }, { "backspace", KEY_DeleteForward }, + { "backquote", KEY_Grave }, { "pause", KEY_Pause }, + + { "f1", KEY_F1 }, { "f2", KEY_F2 }, + { "f3", KEY_F3 }, { "f4", KEY_F4 }, + { "f5", KEY_F5 }, { "f6", KEY_F6 }, + { "f7", KEY_F7 }, { "f8", KEY_F8 }, + { "f9", KEY_F9 }, { "f10", KEY_F10 }, + { "f11", KEY_F11 }, { "f12", KEY_F12 }, + + { "num0", KEY_0 }, { "num1", KEY_1 }, + { "num2", KEY_2 }, { "num3", KEY_3 }, + { "num4", KEY_4 }, { "num5", KEY_5 }, + { "num6", KEY_6 }, { "num7", KEY_7 }, + { "num8", KEY_8 }, { "num9", KEY_9 }, + + { "insert", KEY_Insert }, { "del", KEY_DeleteForward }, + { "home", KEY_Home }, { "end", KEY_End }, + { "pageup", KEY_PageUp }, { "pagedown", KEY_PageDown }, + + { "add", KP_Add }, { "subtract", KP_Subtract }, + { "multiply", KP_Multiply }, { "divide", KP_Divide }, + { "keypad0", KP_0 }, { "keypad1", KP_1 }, + { "keypad2", KP_2 }, { "keypad3", KP_3 }, + { "keypad4", KP_4 }, { "keypad5", KP_5 }, + { "keypad6", KP_6 }, { "keypad7", KP_7 }, + { "keypad8", KP_8 }, { "keypad9", KP_9 }, + + { "period", KEY_Period }, { "capslock", KEY_CapsLock }, + { "numlock", KP_NumLock }, { "print_screen", KEY_PrintScreen }, + { "scroll_lock", KEY_ScrollLock }, + + { "a", KEY_A }, { "b", KEY_B }, { "c", KEY_C }, { "d", KEY_D }, + { "e", KEY_E }, { "f", KEY_F }, { "g", KEY_G }, { "h", KEY_H }, + { "i", KEY_I }, { "j", KEY_J }, { "k", KEY_K }, { "l", KEY_L }, + { "m", KEY_M }, { "n", KEY_N }, { "o", KEY_O }, { "p", KEY_P }, + { "q", KEY_Q }, { "r", KEY_R }, { "s", KEY_S }, { "t", KEY_T }, + { "u", KEY_U }, { "v", KEY_V }, { "w", KEY_W }, { "x", KEY_X }, + { "y", KEY_Y }, { "z", KEY_Z }, + + { "nul", 0x00}, +}; + +const struct rarch_key_map apple_key_map_hidusage[] = +{ + { KEY_Delete, RETROK_BACKSPACE }, + { KEY_Tab, RETROK_TAB }, +// RETROK_CLEAR }, + { KEY_Enter, RETROK_RETURN }, + { KEY_Pause, RETROK_PAUSE }, + { KEY_Escape, RETROK_ESCAPE }, + { KEY_Space, RETROK_SPACE }, +// RETROK_EXCLAIM }, +// RETROK_QUOTEDBL }, +// RETROK_HASH }, +// RETROK_DOLLAR }, +// RETROK_AMPERSAND }, + { KEY_Quote, RETROK_QUOTE }, +// RETROK_LEFTPAREN }, +// RETROK_RIGHTPAREN }, +// RETROK_ASTERISK }, +// RETROK_PLUS }, + { KEY_Comma, RETROK_COMMA }, + { KEY_Minus, RETROK_MINUS }, + { KEY_Period, RETROK_PERIOD }, + { KEY_Slash, RETROK_SLASH }, + { KEY_0, RETROK_0 }, + { KEY_1, RETROK_1 }, + { KEY_2, RETROK_2 }, + { KEY_3, RETROK_3 }, + { KEY_4, RETROK_4 }, + { KEY_5, RETROK_5 }, + { KEY_6, RETROK_6 }, + { KEY_7, RETROK_7 }, + { KEY_8, RETROK_8 }, + { KEY_9, RETROK_9 }, +// RETROK_COLON }, + { KEY_Semicolon, RETROK_SEMICOLON }, +// RETROK_LESS }, + { KEY_Equals, RETROK_EQUALS }, +// RETROK_GREATER }, +// RETROK_QUESTION }, +// RETROK_AT }, + { KEY_LeftBracket, RETROK_LEFTBRACKET }, + { KEY_Backslash, RETROK_BACKSLASH }, + { KEY_RightBracket, RETROK_RIGHTBRACKET }, +// RETROK_CARET }, +// RETROK_UNDERSCORE }, + { KEY_Grave, RETROK_BACKQUOTE }, + { KEY_A, RETROK_a }, + { KEY_B, RETROK_b }, + { KEY_C, RETROK_c }, + { KEY_D, RETROK_d }, + { KEY_E, RETROK_e }, + { KEY_F, RETROK_f }, + { KEY_G, RETROK_g }, + { KEY_H, RETROK_h }, + { KEY_I, RETROK_i }, + { KEY_J, RETROK_j }, + { KEY_K, RETROK_k }, + { KEY_L, RETROK_l }, + { KEY_M, RETROK_m }, + { KEY_N, RETROK_n }, + { KEY_O, RETROK_o }, + { KEY_P, RETROK_p }, + { KEY_Q, RETROK_q }, + { KEY_R, RETROK_r }, + { KEY_S, RETROK_s }, + { KEY_T, RETROK_t }, + { KEY_U, RETROK_u }, + { KEY_V, RETROK_v }, + { KEY_W, RETROK_w }, + { KEY_X, RETROK_x }, + { KEY_Y, RETROK_y }, + { KEY_Z, RETROK_z }, + { KEY_DeleteForward, RETROK_DELETE }, + + { KP_0, RETROK_KP0 }, + { KP_1, RETROK_KP1 }, + { KP_2, RETROK_KP2 }, + { KP_3, RETROK_KP3 }, + { KP_4, RETROK_KP4 }, + { KP_5, RETROK_KP5 }, + { KP_6, RETROK_KP6 }, + { KP_7, RETROK_KP7 }, + { KP_8, RETROK_KP8 }, + { KP_9, RETROK_KP9 }, + { KP_Point, RETROK_KP_PERIOD }, + { KP_Divide, RETROK_KP_DIVIDE }, + { KP_Multiply, RETROK_KP_MULTIPLY }, + { KP_Subtract, RETROK_KP_MINUS }, + { KP_Add, RETROK_KP_PLUS }, + { KP_Enter, RETROK_KP_ENTER }, + { KP_Equals, RETROK_KP_EQUALS }, + + { KEY_Up, RETROK_UP }, + { KEY_Down, RETROK_DOWN }, + { KEY_Right, RETROK_RIGHT }, + { KEY_Left, RETROK_LEFT }, + { KEY_Insert, RETROK_INSERT }, + { KEY_Home, RETROK_HOME }, + { KEY_End, RETROK_END }, + { KEY_PageUp, RETROK_PAGEUP }, + { KEY_PageDown, RETROK_PAGEDOWN }, + + { KEY_F1, RETROK_F1 }, + { KEY_F2, RETROK_F2 }, + { KEY_F3, RETROK_F3 }, + { KEY_F4, RETROK_F4 }, + { KEY_F5, RETROK_F5 }, + { KEY_F6, RETROK_F6 }, + { KEY_F7, RETROK_F7 }, + { KEY_F8, RETROK_F8 }, + { KEY_F9, RETROK_F9 }, + { KEY_F10, RETROK_F10 }, + { KEY_F11, RETROK_F11 }, + { KEY_F12, RETROK_F12 }, + { KEY_F13, RETROK_F13 }, + { KEY_F14, RETROK_F14 }, + { KEY_F15, RETROK_F15 }, + +// RETROK_NUMLOCK }, + { KEY_CapsLock, RETROK_CAPSLOCK }, +// RETROK_SCROLLOCK }, + { KEY_RightShift, RETROK_RSHIFT }, + { KEY_LeftShift, RETROK_LSHIFT }, + { KEY_RightControl, RETROK_RCTRL }, + { KEY_LeftControl, RETROK_LCTRL }, + { KEY_RightAlt, RETROK_RALT }, + { KEY_LeftAlt, RETROK_LALT }, + { KEY_RightGUI, RETROK_RMETA }, + { KEY_LeftGUI, RETROK_RMETA }, +// RETROK_LSUPER }, +// RETROK_RSUPER }, +// RETROK_MODE }, +// RETROK_COMPOSE }, + +// RETROK_HELP }, + { KEY_PrintScreen, RETROK_PRINT }, +// RETROK_SYSREQ }, +// RETROK_BREAK }, + { KEY_Menu, RETROK_MENU }, +// RETROK_POWER }, +// RETROK_EURO }, +// RETROK_UNDO }, + { 0, RETROK_UNKNOWN } +}; + + +const char* apple_keycode_hidusage_to_name(uint32_t hid_usage) +{ + for (int i = 0; apple_key_name_map[i].hid_id; i ++) + if (apple_key_name_map[i].hid_id == hid_usage) + return apple_key_name_map[i].keyname; + + return "nul"; +} diff --git a/apple/common/setting_data.h b/apple/common/setting_data.h index 0f91eb5825..208fb8ea73 100644 --- a/apple/common/setting_data.h +++ b/apple/common/setting_data.h @@ -343,58 +343,5 @@ const rarch_setting_t setting_data[] = // Keyboard #include "keycode.h" -static const struct -{ - const char* const keyname; - const uint32_t hid_id; -} apple_key_name_map[] = { - { "left", KEY_Left }, { "right", KEY_Right }, - { "up", KEY_Up }, { "down", KEY_Down }, - { "enter", KEY_Enter }, { "kp_enter", KP_Enter }, - { "space", KEY_Space }, { "tab", KEY_Tab }, - { "shift", KEY_LeftShift }, { "rshift", KEY_RightShift }, - { "ctrl", KEY_LeftControl }, { "alt", KEY_LeftAlt }, - { "escape", KEY_Escape }, { "backspace", KEY_DeleteForward }, - { "backquote", KEY_Grave }, { "pause", KEY_Pause }, - - { "f1", KEY_F1 }, { "f2", KEY_F2 }, - { "f3", KEY_F3 }, { "f4", KEY_F4 }, - { "f5", KEY_F5 }, { "f6", KEY_F6 }, - { "f7", KEY_F7 }, { "f8", KEY_F8 }, - { "f9", KEY_F9 }, { "f10", KEY_F10 }, - { "f11", KEY_F11 }, { "f12", KEY_F12 }, - - { "num0", KEY_0 }, { "num1", KEY_1 }, - { "num2", KEY_2 }, { "num3", KEY_3 }, - { "num4", KEY_4 }, { "num5", KEY_5 }, - { "num6", KEY_6 }, { "num7", KEY_7 }, - { "num8", KEY_8 }, { "num9", KEY_9 }, - - { "insert", KEY_Insert }, { "del", KEY_DeleteForward }, - { "home", KEY_Home }, { "end", KEY_End }, - { "pageup", KEY_PageUp }, { "pagedown", KEY_PageDown }, - - { "add", KP_Add }, { "subtract", KP_Subtract }, - { "multiply", KP_Multiply }, { "divide", KP_Divide }, - { "keypad0", KP_0 }, { "keypad1", KP_1 }, - { "keypad2", KP_2 }, { "keypad3", KP_3 }, - { "keypad4", KP_4 }, { "keypad5", KP_5 }, - { "keypad6", KP_6 }, { "keypad7", KP_7 }, - { "keypad8", KP_8 }, { "keypad9", KP_9 }, - - { "period", KEY_Period }, { "capslock", KEY_CapsLock }, - { "numlock", KP_NumLock }, { "print_screen", KEY_PrintScreen }, - { "scroll_lock", KEY_ScrollLock }, - - { "a", KEY_A }, { "b", KEY_B }, { "c", KEY_C }, { "d", KEY_D }, - { "e", KEY_E }, { "f", KEY_F }, { "g", KEY_G }, { "h", KEY_H }, - { "i", KEY_I }, { "j", KEY_J }, { "k", KEY_K }, { "l", KEY_L }, - { "m", KEY_M }, { "n", KEY_N }, { "o", KEY_O }, { "p", KEY_P }, - { "q", KEY_Q }, { "r", KEY_R }, { "s", KEY_S }, { "t", KEY_T }, - { "u", KEY_U }, { "v", KEY_V }, { "w", KEY_W }, { "x", KEY_X }, - { "y", KEY_Y }, { "z", KEY_Z }, - - { "nul", 0x00}, -}; #endif \ No newline at end of file diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index a0fbd31ff6..e36c6181ad 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -840,97 +840,18 @@ static void bluetooth_option_changed(RASettingData* setting) - (void)checkInput { - // Keyboard - static const struct - { - const char* const keyname; - const uint32_t hid_id; - } ios_key_name_map[] = { - { "left", KEY_Left }, { "right", KEY_Right }, - { "up", KEY_Up }, { "down", KEY_Down }, - { "enter", KEY_Enter }, { "kp_enter", KP_Enter }, - { "space", KEY_Space }, { "tab", KEY_Tab }, - { "shift", KEY_LeftShift }, { "rshift", KEY_RightShift }, - { "ctrl", KEY_LeftControl }, { "alt", KEY_LeftAlt }, - { "escape", KEY_Escape }, { "backspace", KEY_DeleteForward }, - { "backquote", KEY_Grave }, { "pause", KEY_Pause }, + int32_t value = 0; - { "f1", KEY_F1 }, { "f2", KEY_F2 }, - { "f3", KEY_F3 }, { "f4", KEY_F4 }, - { "f5", KEY_F5 }, { "f6", KEY_F6 }, - { "f7", KEY_F7 }, { "f8", KEY_F8 }, - { "f9", KEY_F9 }, { "f10", KEY_F10 }, - { "f11", KEY_F11 }, { "f12", KEY_F12 }, - - { "num0", KEY_0 }, { "num1", KEY_1 }, - { "num2", KEY_2 }, { "num3", KEY_3 }, - { "num4", KEY_4 }, { "num5", KEY_5 }, - { "num6", KEY_6 }, { "num7", KEY_7 }, - { "num8", KEY_8 }, { "num9", KEY_9 }, + if ((value = apple_input_find_any_key())) + _value->value = [NSString stringWithUTF8String:apple_keycode_hidusage_to_name(value)]; + else if ((value = apple_input_find_any_button(0)) >= 0) + _value->button_bind = [NSString stringWithFormat:@"%d", value]; + else if ((value = apple_input_find_any_axis(0))) + _value->axis_bind = [NSString stringWithFormat:@"%s%d", (value > 0) ? "+" : "-", value - 1]; + else + return; - { "insert", KEY_Insert }, { "del", KEY_DeleteForward }, - { "home", KEY_Home }, { "end", KEY_End }, - { "pageup", KEY_PageUp }, { "pagedown", KEY_PageDown }, - - { "add", KP_Add }, { "subtract", KP_Subtract }, - { "multiply", KP_Multiply }, { "divide", KP_Divide }, - { "keypad0", KP_0 }, { "keypad1", KP_1 }, - { "keypad2", KP_2 }, { "keypad3", KP_3 }, - { "keypad4", KP_4 }, { "keypad5", KP_5 }, - { "keypad6", KP_6 }, { "keypad7", KP_7 }, - { "keypad8", KP_8 }, { "keypad9", KP_9 }, - - { "period", KEY_Period }, { "capslock", KEY_CapsLock }, - { "numlock", KP_NumLock }, { "print_screen", KEY_PrintScreen }, - { "scroll_lock", KEY_ScrollLock }, - - { "a", KEY_A }, { "b", KEY_B }, { "c", KEY_C }, { "d", KEY_D }, - { "e", KEY_E }, { "f", KEY_F }, { "g", KEY_G }, { "h", KEY_H }, - { "i", KEY_I }, { "j", KEY_J }, { "k", KEY_K }, { "l", KEY_L }, - { "m", KEY_M }, { "n", KEY_N }, { "o", KEY_O }, { "p", KEY_P }, - { "q", KEY_Q }, { "r", KEY_R }, { "s", KEY_S }, { "t", KEY_T }, - { "u", KEY_U }, { "v", KEY_V }, { "w", KEY_W }, { "x", KEY_X }, - { "y", KEY_Y }, { "z", KEY_Z }, - - { "nul", 0x00}, - }; - - for (int i = 0; ios_key_name_map[i].hid_id; i++) - { - if (g_current_input_data.keys[ios_key_name_map[i].hid_id]) - { - _value->value = [NSString stringWithUTF8String:ios_key_name_map[i].keyname]; - [self finish]; - return; - } - } - - // Pad Buttons - uint32_t buttons = g_current_input_data.pad_buttons[_value->player] | - ((_value->player == 0) ? apple_input_get_icade_buttons() : 0); - - for (int i = 0; buttons && i < sizeof(buttons) * 8; i++) - { - if (buttons & (1 << i)) - { - _value->button_bind = [NSString stringWithFormat:@"%d", i]; - [self finish]; - return; - } - } - - // Pad Axis - for (int i = 0; i < 4; i++) - { - int16_t value = g_current_input_data.pad_axis[_value->player][i]; - - if (abs(value) > 0x1000) - { - _value->axis_bind = [NSString stringWithFormat:@"%s%d", (value > 0x1000) ? "+" : "-", i]; - [self finish]; - break; - } - } + [self finish]; } @end From ad7c442e8c3b5012a2577bd47c8fe11825a0a72f Mon Sep 17 00:00:00 2001 From: ToadKing Date: Mon, 9 Sep 2013 19:28:50 -0400 Subject: [PATCH 175/202] [Android] bump version number --- android/phoenix/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index 63935e0297..051ccabc81 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -1,6 +1,6 @@ From c3909c6468c347adbda1e77ca585aac3aae520e8 Mon Sep 17 00:00:00 2001 From: meancoot Date: Mon, 9 Sep 2013 19:25:34 -0400 Subject: [PATCH 176/202] (Apple) Start to clean the objective-c code --- apple/OSX/platform.h | 5 ++- apple/OSX/platform.m | 59 +++++----------------------------- apple/OSX/settings.m | 6 ++-- apple/common/RAModuleInfo.h | 14 ++++---- apple/common/RAModuleInfo.m | 45 ++++++++------------------ apple/common/RetroArch_Apple.h | 5 +-- apple/common/main.m | 20 +++--------- apple/common/utility.m | 2 +- apple/iOS/RALogView.m | 2 +- apple/iOS/browser.m | 4 +-- apple/iOS/platform.h | 5 ++- apple/iOS/platform.m | 16 +++------ apple/iOS/settings.m | 6 ++-- 13 files changed, 60 insertions(+), 129 deletions(-) diff --git a/apple/OSX/platform.h b/apple/OSX/platform.h index 8078979caf..b01f6526f5 100644 --- a/apple/OSX/platform.h +++ b/apple/OSX/platform.h @@ -36,7 +36,10 @@ - (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; - (void)unloadingCore:(RAModuleInfo*)core; -- (NSString*)configPath; + +@property (strong, nonatomic) NSString* configDirectory; // e.g. /var/mobile/Documents/.RetroArch +@property (strong, nonatomic) NSString* globalConfigFile; // e.g. /var/mobile/Documents/.RetroArch/retroarch.cfg +@property (strong, nonatomic) NSString* coreDirectory; // e.g. /Applications/RetroArch.app/modules @end diff --git a/apple/OSX/platform.m b/apple/OSX/platform.m index 38b641e801..f911432227 100644 --- a/apple/OSX/platform.m +++ b/apple/OSX/platform.m @@ -20,14 +20,6 @@ #include "rarch_wrapper.h" #include "apple/common/apple_input.h" -// If USE_XATTR is defined any loaded file will get a com.RetroArch.Core extended attribute -// specifying which core was used to load. -//#define USE_XATTR - -#if defined(USE_XATTR) -#include "sys/xattr.h" -#endif - #include "file.h" @interface RApplication : NSApplication @@ -66,6 +58,11 @@ apple_platform = self; _loaded = true; + NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); + self.configDirectory = [paths[0] stringByAppendingPathComponent:@"RetroArch"]; + self.globalConfigFile = [NSString stringWithFormat:@"%@/retroarch.cfg", self.configDirectory]; + self.coreDirectory = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"Contents/Resources/modules"]; + [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; RAGameView.get.frame = [window.contentView bounds]; @@ -76,7 +73,7 @@ // Create core select list NSComboBox* cb = (NSComboBox*)[_coreSelectSheet.contentView viewWithTag:1]; - for (RAModuleInfo* i in RAModuleInfo.getModules) + for (RAModuleInfo* i in apple_get_modules()) [cb addItemWithObjectValue:i]; if (cb.numberOfItems) @@ -162,23 +159,6 @@ - (void)chooseCore { -#ifdef USE_XATTR - char stored_name[PATH_MAX]; - if (getxattr(_file.UTF8String, "com.RetroArch.Core", stored_name, PATH_MAX, 0, 0) > 0) - { - for (RAModuleInfo* i in RAModuleInfo.getModules) - { - const char* core_name = i.path.lastPathComponent.UTF8String; - if (strcmp(core_name, stored_name) == 0) - { - _core = i; - [self runCore]; - return; - } - } - } -#endif - [NSApplication.sharedApplication beginSheet:_coreSelectSheet modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil]; [NSApplication.sharedApplication runModalForWindow:_coreSelectSheet]; } @@ -202,14 +182,7 @@ - (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file { if (file) - { - [NSDocumentController.sharedDocumentController noteNewRecentDocumentURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:file]]]; - -#ifdef USE_XATTR - const char* core_name = core.path.lastPathComponent.UTF8String; - setxattr(file, "com.RetroArch.Core", core_name, strlen(core_name) + 1, 0, 0); -#endif - } + [NSDocumentController.sharedDocumentController noteNewRecentDocumentURL:[NSURL fileURLWithPath:@(file)]]; } - (void)unloadingCore:(RAModuleInfo*)core @@ -227,26 +200,10 @@ _wantReload = false; } -- (NSString*)configPath -{ - return [[self retroarchConfigPath] stringByAppendingPathComponent:@"retroarch.cfg"]; -} - -- (NSString*)retroarchConfigPath -{ - NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - return [paths[0] stringByAppendingPathComponent:@"RetroArch"]; -} - -- (NSString*)corePath -{ - return [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"Contents/Resources/modules"]; -} - #pragma mark Menus - (IBAction)showCoresDirectory:(id)sender { - [[NSWorkspace sharedWorkspace] openFile:self.corePath]; + [[NSWorkspace sharedWorkspace] openFile:self.coreDirectory]; } - (IBAction)showPreferences:(id)sender diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 9059dd9fb2..5973bcf6dd 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -343,7 +343,7 @@ static const char* get_axis_name(const rarch_setting_t* setting) - (void)load { - config_file_t* conf = config_file_new([RetroArch_OSX get].configPath.UTF8String); + config_file_t* conf = config_file_new(apple_platform.globalConfigFile.UTF8String); for (int i = 0; setting_data[i].type; i ++) { @@ -372,7 +372,7 @@ static const char* get_axis_name(const rarch_setting_t* setting) - (void)windowWillClose:(NSNotification *)notification { - config_file_t* conf = config_file_new([RetroArch_OSX get].configPath.UTF8String); + config_file_t* conf = config_file_new(apple_platform.globalConfigFile.UTF8String); conf = conf ? conf : config_file_new(0); for (int i = 0; setting_data[i].type; i ++) @@ -397,7 +397,7 @@ static const char* get_axis_name(const rarch_setting_t* setting) default: break; } } - config_file_write(conf, [RetroArch_OSX get].configPath.UTF8String); + config_file_write(conf, apple_platform.globalConfigFile.UTF8String); config_file_free(conf); apple_refresh_config(); diff --git a/apple/common/RAModuleInfo.h b/apple/common/RAModuleInfo.h index 063143a5cb..39173ec473 100644 --- a/apple/common/RAModuleInfo.h +++ b/apple/common/RAModuleInfo.h @@ -22,22 +22,22 @@ #include "conf/config_file.h" #include "core_info.h" +extern NSArray* apple_get_modules(); + @interface RAModuleInfo : NSObject -@property (strong) NSString* path; +@property NSString* path; // e.g. /path/to/corename_libretro.dylib +@property NSString* baseName; // e.g. corename_libretro @property core_info_t* info; @property config_file_t* data; -@property (strong) NSString* description; -@property (strong) NSString* customConfigPath; +@property NSString* description; // Friendly name from config file, else just the filename +@property NSString* customConfigFile; // Path where custom config file would reside +@property NSString* configFile; // Path to effective config file -+ (NSArray*)getModules; - (bool)supportsFileAtPath:(NSString*)path; -+ (NSString*)globalConfigPath; - - (void)createCustomConfig; - (void)deleteCustomConfig; - (bool)hasCustomConfig; -- (NSString*)configPath; @end diff --git a/apple/common/RAModuleInfo.m b/apple/common/RAModuleInfo.m index bd148684bb..985cfcb9c7 100644 --- a/apple/common/RAModuleInfo.m +++ b/apple/common/RAModuleInfo.m @@ -22,30 +22,29 @@ static NSMutableArray* moduleList; static core_info_list_t* coreList; -@implementation RAModuleInfo -+ (NSArray*)getModules +NSArray* apple_get_modules() { if (!moduleList) { - coreList = get_core_info_list(apple_platform.corePath.UTF8String); + coreList = get_core_info_list(apple_platform.coreDirectory.UTF8String); if (!coreList) return nil; - - moduleList = [NSMutableArray arrayWithCapacity:coreList->count]; + moduleList = [NSMutableArray arrayWithCapacity:coreList->count]; + for (int i = 0; coreList && i < coreList->count; i ++) { core_info_t* core = &coreList->list[i]; RAModuleInfo* newInfo = [RAModuleInfo new]; - newInfo.path = [NSString stringWithUTF8String:core->path]; + newInfo.path = @(core->path); + newInfo.baseName = newInfo.path.lastPathComponent.stringByDeletingPathExtension; newInfo.info = core; newInfo.data = core->data; - newInfo.description = [NSString stringWithUTF8String:core->display_name]; - - NSString* baseName = newInfo.path.lastPathComponent.stringByDeletingPathExtension; - newInfo.customConfigPath = [NSString stringWithFormat:@"%@/%@.cfg", apple_platform.retroarchConfigPath, baseName]; + newInfo.description = @(core->display_name); + newInfo.customConfigFile = [NSString stringWithFormat:@"%@/%@.cfg", apple_platform.configDirectory, newInfo.baseName]; + newInfo.configFile = newInfo.hasCustomConfig ? newInfo.customConfigFile : apple_platform.globalConfigFile; [moduleList addObject:newInfo]; } @@ -59,9 +58,7 @@ static core_info_list_t* coreList; return moduleList; } -- (void)dealloc -{ -} +@implementation RAModuleInfo - (id)copyWithZone:(NSZone *)zone { @@ -73,35 +70,21 @@ static core_info_list_t* coreList; return does_core_support_file(self.info, path.UTF8String); } -+ (NSString*)globalConfigPath -{ - static NSString* path; - if (!path) - path = [NSString stringWithFormat:@"%@/retroarch.cfg", apple_platform.retroarchConfigPath]; - - return path; -} - - (void)createCustomConfig { if (!self.hasCustomConfig) - [NSFileManager.defaultManager copyItemAtPath:RAModuleInfo.globalConfigPath toPath:self.customConfigPath error:nil]; + [NSFileManager.defaultManager copyItemAtPath:apple_platform.globalConfigFile toPath:self.customConfigFile error:nil]; } - (void)deleteCustomConfig { if (self.hasCustomConfig) - [NSFileManager.defaultManager removeItemAtPath:self.customConfigPath error:nil]; + [NSFileManager.defaultManager removeItemAtPath:self.customConfigFile error:nil]; } - (bool)hasCustomConfig { - return path_file_exists(self.customConfigPath.UTF8String); -} - -- (NSString*)configPath -{ - return self.hasCustomConfig ? self.customConfigPath : RAModuleInfo.globalConfigPath; + return path_file_exists(self.customConfigFile.UTF8String); } @end @@ -148,7 +131,7 @@ static NSString* build_string_pair(NSString* stringA, NSString* stringB) for (int i = 0; i < firmwareCount; i ++) { NSString* path = objc_get_value_from_config(_data.data, [NSString stringWithFormat:@"firmware%d_path", i + 1], @"Unspecified"); - path = [path stringByReplacingOccurrencesOfString:@"%sysdir%" withString:RetroArch_iOS.get.systemDirectory]; + path = [path stringByReplacingOccurrencesOfString:@"%sysdir%" withString:[RetroArch_iOS get].systemDirectory]; [firmwareSection addObject:build_string_pair(objc_get_value_from_config(_data.data, [NSString stringWithFormat:@"firmware%d_desc", i + 1], @"Unspecified"), path)]; } diff --git a/apple/common/RetroArch_Apple.h b/apple/common/RetroArch_Apple.h index 96be99f0c7..f3dd9f0ab1 100644 --- a/apple/common/RetroArch_Apple.h +++ b/apple/common/RetroArch_Apple.h @@ -28,8 +28,9 @@ - (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; - (void)unloadingCore:(RAModuleInfo*)core; -- (NSString*)retroarchConfigPath; // < This returns the directory that contains retroarch.cfg and other custom configs -- (NSString*)corePath; +- (NSString*)configDirectory; // < This returns the directory that contains retroarch.cfg and other custom configs +- (NSString*)globalConfigFile; // < This is the full path to retroarch.cfg +- (NSString*)coreDirectory; // < This is the default path to where libretro cores are installed @end #ifdef IOS diff --git a/apple/common/main.m b/apple/common/main.m index b8c85f2fff..bc3a1e4d8e 100644 --- a/apple/common/main.m +++ b/apple/common/main.m @@ -25,8 +25,6 @@ char** apple_argv; -//#define HAVE_DEBUG_FILELOG - id apple_platform; void apple_event_basic_command(void* userdata) @@ -134,27 +132,19 @@ void apple_run_core(RAModuleInfo* core, const char* file) if (!apple_argv) { - static const char* argv[] = { "retroarch", "-c", config_path, "-L", core_path, file_path, 0 }; + NSString* config_to_use = apple_core ? apple_core.configFile : apple_platform.globalConfigFile; + strlcpy(config_path, config_to_use.UTF8String, sizeof(config_path)); - if (apple_core) - strlcpy(config_path, apple_core.configPath.UTF8String, sizeof(config_path)); - else - strlcpy(config_path, RAModuleInfo.globalConfigPath.UTF8String, sizeof(config_path)); + static const char* const argv_game[] = { "retroarch", "-c", config_path, "-L", core_path, file_path, 0 }; + static const char* const argv_menu[] = { "retroarch", "-c", config_path, "--menu", 0 }; if (file && core) { - argv[3] = "-L"; - argv[4] = core_path; strlcpy(core_path, apple_core.path.UTF8String, sizeof(core_path)); strlcpy(file_path, file, sizeof(file_path)); } - else - { - argv[3] = "--menu"; - argv[4] = 0; - } - apple_argv = (char**)argv; + apple_argv = (char**)((file && core) ? argv_game : argv_menu); } if (pthread_create(&apple_retro_thread, 0, rarch_main_spring, apple_argv)) diff --git a/apple/common/utility.m b/apple/common/utility.m index 7875e69594..1c8ffb8608 100644 --- a/apple/common/utility.m +++ b/apple/common/utility.m @@ -57,7 +57,7 @@ NSString* objc_get_value_from_config(config_file_t* config, NSString* name, NSSt if (config) config_get_string(config, [name UTF8String], &data); - NSString* result = data ? [NSString stringWithUTF8String:data] : defaultValue; + NSString* result = data ? @(data) : defaultValue; free(data); return result; } diff --git a/apple/iOS/RALogView.m b/apple/iOS/RALogView.m index d384515334..af802dceca 100644 --- a/apple/iOS/RALogView.m +++ b/apple/iOS/RALogView.m @@ -34,7 +34,7 @@ void ios_add_log_message(const char* format, ...) va_start(args, format); vsnprintf(buffer, 512, format, args); va_end(args); - [g_messages addObject:[NSString stringWithUTF8String: buffer]]; + [g_messages addObject:@(buffer)]; pthread_mutex_unlock(&g_lock); } diff --git a/apple/iOS/browser.m b/apple/iOS/browser.m index 72ec640458..c0aa8410e2 100644 --- a/apple/iOS/browser.m +++ b/apple/iOS/browser.m @@ -101,7 +101,7 @@ section = contents->elems[i].attr.b ? 0 : section; RADirectoryItem* item = RADirectoryItem.new; - item.path = [NSString stringWithUTF8String:contents->elems[i].data]; + item.path = @(contents->elems[i].data); item.isDirectory = contents->elems[i].attr.b; [sectionLists[section] addObject:item]; } @@ -221,7 +221,7 @@ _delegate = delegate; // Load the modules with their data - NSArray* moduleList = [RAModuleInfo getModules]; + NSArray* moduleList = apple_get_modules(); NSMutableArray* supported = [NSMutableArray arrayWithObject:@"Suggested Cores"]; NSMutableArray* other = [NSMutableArray arrayWithObject:@"Other Cores"]; diff --git a/apple/iOS/platform.h b/apple/iOS/platform.h index c7d01d7756..d8675259c6 100644 --- a/apple/iOS/platform.h +++ b/apple/iOS/platform.h @@ -32,10 +32,13 @@ - (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; - (void)unloadingCore:(RAModuleInfo*)core; -- (NSString*)retroarchConfigPath; - (void)refreshSystemConfig; +@property (strong, nonatomic) NSString* configDirectory; // e.g. /var/mobile/Documents/.RetroArch +@property (strong, nonatomic) NSString* globalConfigFile; // e.g. /var/mobile/Documents/.RetroArch/retroarch.cfg +@property (strong, nonatomic) NSString* coreDirectory; // e.g. /Applications/RetroArch.app/modules + @property (strong, nonatomic) NSString* documentsDirectory; // e.g. /var/mobile/Documents @property (strong, nonatomic) NSString* systemDirectory; // e.g. /var/mobile/Documents/.RetroArch @property (strong, nonatomic) NSString* systemConfigPath; // e.g. /var/mobile/Documents/.RetroArch/frontend.cfg diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index 22bd544d74..dccb06c76e 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -112,6 +112,10 @@ static void handle_touch_event(NSArray* touches) self.documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; self.systemDirectory = [self.documentsDirectory stringByAppendingPathComponent:@".RetroArch"]; self.systemConfigPath = [self.systemDirectory stringByAppendingPathComponent:@"frontend.cfg"]; + + self.configDirectory = self.systemDirectory; + self.globalConfigFile = [NSString stringWithFormat:@"%@/retroarch.cfg", self.configDirectory]; + self.coreDirectory = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"modules"]; if (!path_make_and_check_directory(self.documentsDirectory.UTF8String, 0755, R_OK | W_OK | X_OK)) apple_display_alert([NSString stringWithFormat:@"Failed to create or access base directory: %@", self.documentsDirectory], 0); @@ -122,7 +126,7 @@ static void handle_touch_event(NSArray* touches) // Warn if there are no cores present - if ([RAModuleInfo getModules].count == 0) + if (apple_get_modules().count == 0) apple_display_alert(@"No libretro cores were found. You will not be able to play any games.", 0); } @@ -252,16 +256,6 @@ static void handle_touch_event(NSArray* touches) btpad_set_inquiry_state(true); } -- (NSString*)retroarchConfigPath -{ - return self.systemDirectory; -} - -- (NSString*)corePath -{ - return [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"modules"]; -} - #pragma mark FRONTEND CONFIG - (void)refreshSystemConfig { diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index e36c6181ad..11d3b73509 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -275,7 +275,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (id)initWithModule:(RAModuleInfo*)module { _module = module; - _configPath = _module ? _module.configPath : RAModuleInfo.globalConfigPath; + _configPath = _module ? _module.configFile : apple_platform.globalConfigFile; config_file_t* config = config_file_new([_configPath UTF8String]); @@ -408,7 +408,7 @@ static void bluetooth_option_changed(RASettingData* setting) [modules addObject:@"Cores"]; [modules addObject:custom_action(@"Global Core Config", nil, nil, 0)]; - NSArray* moduleList = [RAModuleInfo getModules]; + NSArray* moduleList = apple_get_modules(); for (RAModuleInfo* i in moduleList) { [modules addObject:custom_action(i.description, nil, i, reload_core_config_state)]; @@ -843,7 +843,7 @@ static void bluetooth_option_changed(RASettingData* setting) int32_t value = 0; if ((value = apple_input_find_any_key())) - _value->value = [NSString stringWithUTF8String:apple_keycode_hidusage_to_name(value)]; + _value->value = @(apple_keycode_hidusage_to_name(value)); else if ((value = apple_input_find_any_button(0)) >= 0) _value->button_bind = [NSString stringWithFormat:@"%d", value]; else if ((value = apple_input_find_any_axis(0))) From ff61d97a060b04a3bc0bc7a81578cf6e970dfa41 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 10 Sep 2013 19:22:13 -0400 Subject: [PATCH 177/202] (OSX) Clear state when a gamepad is disconnected while running; any newly connected pad will occupy the lowest open slot --- apple/OSX/hid_pad.c | 107 +++++++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/apple/OSX/hid_pad.c b/apple/OSX/hid_pad.c index d4d0a472f6..39cee0feed 100644 --- a/apple/OSX/hid_pad.c +++ b/apple/OSX/hid_pad.c @@ -19,9 +19,39 @@ // NOTE: I pieced this together through trial and error, any corrections are welcome static IOHIDManagerRef g_hid_manager; -static uint32_t g_num_pads; +static uint32_t g_pad_slots; -static void hid_input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef inIOHIDValueRef) +#define HID_ISSET(t, x) (t & (1 << x)) +#define HID_SET(t, x) { t |= (1 << x); } +#define HID_CLEAR(t, x) { t &= ~(1 << x); } + +// Set the LEDs on PS3 controllers, if slot >= MAX_PADS the LEDs will be cleared +static void osx_pad_set_leds(IOHIDDeviceRef device, uint32_t slot) +{ + char buffer[1024]; + + CFStringRef device_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); + if (device_name) + { + CFStringGetCString(device_name, buffer, 1024, kCFStringEncodingUTF8); + + if (strncmp(buffer, "PLAYSTATION(R)3 Controller", 1024) == 0) + { + static uint8_t report_buffer[] = { + 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x27, + 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00, + 0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + report_buffer[10] = (slot >= MAX_PADS) ? 0 : (1 << (slot + 1)); + + IOHIDDeviceSetReport(device, kIOHIDReportTypeOutput, 0x01, report_buffer, sizeof(report_buffer)); + } + } +} + +static void hid_device_input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef inIOHIDValueRef) { IOHIDElementRef element = IOHIDValueGetElement(inIOHIDValueRef); IOHIDDeviceRef device = IOHIDElementGetDevice(element); @@ -82,51 +112,49 @@ static void hid_input_callback(void* inContext, IOReturn inResult, void* inSende } } -static void hid_device_attached(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice) +static void hid_device_removed(void* inContext, IOReturn inResult, void* inSender) { - void* context = 0; + IOHIDDeviceRef inDevice = (IOHIDDeviceRef)inSender; if (IOHIDDeviceConformsTo(inDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)) { - if (g_num_pads > 4) - return; - context = (void*)(g_num_pads++); + uint32_t pad_index = (uint32_t)inContext; + + if (pad_index < MAX_PADS) + { + HID_CLEAR(g_pad_slots, pad_index); + + g_current_input_data.pad_buttons[pad_index] = 0; + memset(g_current_input_data.pad_axis[pad_index], 0, sizeof(g_current_input_data.pad_axis)); + } } - IOHIDDeviceOpen(inDevice, kIOHIDOptionsTypeNone); - IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); - IOHIDDeviceRegisterInputValueCallback(inDevice, hid_input_callback, context); - - // Set PS3 LEDs - CFStringRef device_name = IOHIDDeviceGetProperty(inDevice, CFSTR(kIOHIDProductKey)); - if (!device_name) - return; - - char buffer[1024]; - CFStringGetCString(device_name, buffer, 1024, kCFStringEncodingUTF8); - if (strncmp(buffer, "PLAYSTATION(R)3 Controller", 1024) == 0) - { - static uint8_t report_buffer[] = { - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x27, 0x10, 0x00, 0x32, - 0xff, 0x27, 0x10, 0x00, 0x32, - 0xff, 0x27, 0x10, 0x00, 0x32, - 0xff, 0x27, 0x10, 0x00, 0x32, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - report_buffer[10] = 1 << (((int)context) + 1); - - IOHIDDeviceSetReport(inDevice, kIOHIDReportTypeOutput, 0x01, report_buffer, sizeof(report_buffer)); - } + osx_pad_set_leds(inDevice, MAX_PADS); + IOHIDDeviceClose(inDevice, kIOHIDOptionsTypeNone); } -static void hid_device_removed(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice) +static void hid_manager_device_attached(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice) { - IOHIDDeviceClose(inDevice, kIOHIDOptionsTypeNone); + uint32_t pad_index = 0; + if (IOHIDDeviceConformsTo(inDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)) + { + if ((g_pad_slots & 0xF) == 0xF) + return; + + for (pad_index = 0; pad_index != MAX_PADS; pad_index ++) + if (!HID_ISSET(g_pad_slots, pad_index)) + { + HID_SET(g_pad_slots, pad_index); + break; + } + } + + IOHIDDeviceOpen(inDevice, kIOHIDOptionsTypeNone); + IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); + IOHIDDeviceRegisterInputValueCallback(inDevice, hid_device_input_callback, (void*)pad_index); + IOHIDDeviceRegisterRemovalCallback(inDevice, hid_device_removed, (void*)pad_index); + + osx_pad_set_leds(inDevice, pad_index); } static CFMutableDictionaryRef build_matching_dictionary(uint32_t page, uint32_t use) @@ -163,8 +191,7 @@ void osx_pad_init() IOHIDManagerSetDeviceMatchingMultiple(g_hid_manager, matcher); CFRelease(matcher); - IOHIDManagerRegisterDeviceMatchingCallback(g_hid_manager, hid_device_attached, 0); - IOHIDManagerRegisterDeviceRemovalCallback(g_hid_manager, hid_device_removed, 0); + IOHIDManagerRegisterDeviceMatchingCallback(g_hid_manager, hid_manager_device_attached, 0); IOHIDManagerScheduleWithRunLoop(g_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes); IOHIDManagerOpen(g_hid_manager, kIOHIDOptionsTypeNone); From 3b27a5062545372d3eb77586cf44bce535f24397 Mon Sep 17 00:00:00 2001 From: meancoot Date: Tue, 10 Sep 2013 19:29:49 -0400 Subject: [PATCH 178/202] (OSX) Improvements: Pause emulation while settings window is open Allow negative numbers to be input in the settings list Don't crash when changing a setting value to an empty string --- apple/OSX/settings.m | 16 ++++++++-------- apple/common/RetroArch_Apple.h | 2 +- apple/common/main.m | 10 +++++++--- apple/iOS/platform.m | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 5973bcf6dd..66ce2bf1cd 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -114,13 +114,11 @@ static const char* get_axis_name(const rarch_setting_t* setting) { unichar ch = [partialString characterAtIndex:i]; - if (self.allowsFloats && !hasDot && ch == '.') - { - hasDot = true; + if (i == 0 && (!self.minimum || self.minimum.intValue < 0) && ch == '-') continue; - } - - if (!isnumber(ch)) + else if (self.allowsFloats && !hasDot && ch == '.') + hasDot = true; + else if (!isdigit(ch)) return NO; } @@ -216,7 +214,7 @@ static const char* get_axis_name(const rarch_setting_t* setting) - (void)setStringValue:(NSString *)stringValue { - _stringValue = stringValue; + _stringValue = stringValue ? stringValue : @""; if (_setting && (_setting->type == ST_STRING || _setting->type == ST_PATH)) strlcpy(_setting->value, _stringValue.UTF8String, _setting->size); @@ -291,6 +289,8 @@ static const char* get_axis_name(const rarch_setting_t* setting) - (void)awakeFromNib { + apple_enter_stasis(); + NSMutableArray* thisGroup = nil; NSMutableArray* thisSubGroup = nil; _settings = [NSMutableArray array]; @@ -400,7 +400,7 @@ static const char* get_axis_name(const rarch_setting_t* setting) config_file_write(conf, apple_platform.globalConfigFile.UTF8String); config_file_free(conf); - apple_refresh_config(); + apple_exit_stasis(true); [NSApp stopModal]; } diff --git a/apple/common/RetroArch_Apple.h b/apple/common/RetroArch_Apple.h index f3dd9f0ab1..b8616ae78e 100644 --- a/apple/common/RetroArch_Apple.h +++ b/apple/common/RetroArch_Apple.h @@ -55,7 +55,7 @@ extern void apple_event_show_rgui(void* userdata); extern void apple_refresh_config(); extern void apple_enter_stasis(); -extern void apple_exit_stasis(); +extern void apple_exit_stasis(bool reload_config); extern void apple_run_core(RAModuleInfo* core, const char* file); // utility.m diff --git a/apple/common/main.m b/apple/common/main.m index bc3a1e4d8e..211f6f7f30 100644 --- a/apple/common/main.m +++ b/apple/common/main.m @@ -71,8 +71,6 @@ pthread_mutex_t stasis_mutex = PTHREAD_MUTEX_INITIALIZER; static void event_stasis(void* userdata) { - // HACK: uninit_drivers is the nuclear option; uninit_audio would be better but will - // crash when resuming. uninit_drivers(); pthread_mutex_lock(&stasis_mutex); pthread_mutex_unlock(&stasis_mutex); @@ -88,8 +86,14 @@ void apple_enter_stasis() } } -void apple_exit_stasis() +void apple_exit_stasis(bool reload_config) { + if (reload_config) + { + objc_clear_config_hack(); + config_load(); + } + if (apple_is_running) pthread_mutex_unlock(&stasis_mutex); } diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index dccb06c76e..06e0c349b8 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -132,7 +132,7 @@ static void handle_touch_event(NSArray* touches) - (void)applicationDidBecomeActive:(UIApplication *)application { - apple_exit_stasis(); + apple_exit_stasis(false); } - (void)applicationWillResignActive:(UIApplication *)application From a09dda3a9da71a1f00e07dd1c9e1efbb1b381988 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Tue, 10 Sep 2013 20:21:48 -0400 Subject: [PATCH 179/202] [EMSCRIPTEN] add custom input driver, removes SDL dependency + adds mouse support --- Makefile.emscripten | 18 +-- emscripten/RWebAudio.c => audio/rwebaudio.c | 2 +- config.def.h | 3 + driver.c | 5 +- driver.h | 1 + emscripten/RWebInput.h | 29 ++++ emscripten/library_rwebinput.js | 115 +++++++++++++++ gfx/context/emscriptenegl_ctx.c | 12 +- input/input_common.c | 90 ++++++++++++ input/input_common.h | 1 + input/rwebinput_input.c | 149 ++++++++++++++++++++ settings.c | 2 + 12 files changed, 403 insertions(+), 24 deletions(-) rename emscripten/RWebAudio.c => audio/rwebaudio.c (98%) create mode 100644 emscripten/RWebInput.h create mode 100644 emscripten/library_rwebinput.js create mode 100644 input/rwebinput_input.c diff --git a/Makefile.emscripten b/Makefile.emscripten index 559638ab75..c1e913419c 100644 --- a/Makefile.emscripten +++ b/Makefile.emscripten @@ -15,6 +15,7 @@ OBJ = frontend/frontend_emscripten.o \ movie.o \ gfx/gfx_common.o \ input/input_common.o \ + input/rwebinput_input.o \ core_options.o \ patch.o \ compat/compat.o \ @@ -22,7 +23,7 @@ OBJ = frontend/frontend_emscripten.o \ screenshot.o \ cheats.o \ audio/utils.o \ - emscripten/RWebAudio.o \ + audio/rwebaudio.o \ input/overlay.o \ fifo_buffer.o \ gfx/scaler/scaler.o \ @@ -41,9 +42,7 @@ OBJ = frontend/frontend_emscripten.o \ HAVE_OPENGL = 1 HAVE_RGUI = 1 -HAVE_SDL = 1 -HAVE_SDL_IMAGE = 1 -HAVE_FREETYPE = 1 +HAVE_SDL = 0 HAVE_ZLIB = 1 HAVE_FBO = 1 WANT_MINIZ = 1 @@ -59,11 +58,7 @@ libretro = libretro_emscripten.bc LIBS = -lm DEFINES = -DHAVE_SCREENSHOTS -DHAVE_NULLAUDIO -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.9.3\" -LDFLAGS = -L. -s TOTAL_MEMORY=$(MEMORY) --js-library emscripten/library_rwebaudio.js - -ifeq ($(SCALER_NO_SIMD), 1) - DEFINES += -DSCALER_NO_SIMD -endif +LDFLAGS = -L. -s TOTAL_MEMORY=$(MEMORY) --js-library emscripten/library_rwebaudio.js --js-library emscripten/library_rwebinput.js ifeq ($(PERF_TEST), 1) DEFINES += -DPERF_TEST @@ -80,11 +75,6 @@ ifeq ($(HAVE_SDL), 1) DEFINES += -ISDL -DHAVE_SDL endif -ifeq ($(HAVE_THREADS), 1) - OBJ += autosave.o thread.o gfx/thread_wrapper.o - DEFINES += -DHAVE_THREADS -endif - ifeq ($(HAVE_OPENGL), 1) OBJ += gfx/gl.o gfx/math/matrix.o gfx/fonts/gl_font.o gfx/fonts/gl_raster_font.o gfx/gfx_context.o gfx/context/emscriptenegl_ctx.o gfx/shader_glsl.o gfx/glsym/rglgen.o gfx/glsym/glsym_es2.o DEFINES += -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_EGL -DHAVE_OVERLAY -DHAVE_GLSL diff --git a/emscripten/RWebAudio.c b/audio/rwebaudio.c similarity index 98% rename from emscripten/RWebAudio.c rename to audio/rwebaudio.c index 1040da32d7..7139a88de4 100644 --- a/emscripten/RWebAudio.c +++ b/audio/rwebaudio.c @@ -16,7 +16,7 @@ #include "../driver.h" #include "../general.h" -#include "RWebAudio.h" +#include "../emscripten/RWebAudio.h" static void ra_free(void *data) { diff --git a/config.def.h b/config.def.h index 32d263a623..9e6903f4e4 100644 --- a/config.def.h +++ b/config.def.h @@ -78,6 +78,7 @@ enum INPUT_LINUXRAW, INPUT_APPLE, INPUT_QNX, + INPUT_RWEBINPUT, INPUT_NULL }; @@ -155,6 +156,8 @@ enum #define INPUT_DEFAULT_DRIVER INPUT_ANDROID #elif defined(_WIN32) #define INPUT_DEFAULT_DRIVER INPUT_DINPUT +#elif defined(EMSCRIPTEN) +#define INPUT_DEFAULT_DRIVER INPUT_RWEBINPUT #elif defined(HAVE_SDL) #define INPUT_DEFAULT_DRIVER INPUT_SDL #elif defined(__CELLOS_LV2__) diff --git a/driver.c b/driver.c index 51e8e6a577..cc5ea7f253 100644 --- a/driver.c +++ b/driver.c @@ -63,7 +63,7 @@ static const audio_driver_t *audio_drivers[] = { #ifdef HAVE_JACK &audio_jack, #endif -#if defined(HAVE_SDL) && !defined(EMSCRIPTEN) +#ifdef HAVE_SDL &audio_sdl, #endif #ifdef HAVE_XAUDIO @@ -168,6 +168,9 @@ static const input_driver_t *input_drivers[] = { #ifdef __BLACKBERRY_QNX__ &input_qnx, #endif +#ifdef EMSCRIPTEN + &input_rwebinput, +#endif #ifdef HAVE_NULLINPUT &input_null, #endif diff --git a/driver.h b/driver.h index 91dd004005..8bf5cc4f6b 100644 --- a/driver.h +++ b/driver.h @@ -537,6 +537,7 @@ extern const input_driver_t input_xinput; extern const input_driver_t input_linuxraw; extern const input_driver_t input_apple; extern const input_driver_t input_qnx; +extern const input_driver_t input_rwebinput; extern const input_driver_t input_null; #include "driver_funcs.h" diff --git a/emscripten/RWebInput.h b/emscripten/RWebInput.h new file mode 100644 index 0000000000..103cc7a0cd --- /dev/null +++ b/emscripten/RWebInput.h @@ -0,0 +1,29 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Michael Lelli + * + * 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 + +typedef struct rwebinput_state +{ + char keys[32]; + int mouse_x; + int mouse_y; + char mouse_l; + char mouse_r; +} rwebinput_state_t; + +int RWebInputInit(void); +rwebinput_state_t *RWebInputPoll(int context); +void RWebInputDestroy(int context); diff --git a/emscripten/library_rwebinput.js b/emscripten/library_rwebinput.js new file mode 100644 index 0000000000..3ca2fd9cd1 --- /dev/null +++ b/emscripten/library_rwebinput.js @@ -0,0 +1,115 @@ +//"use strict"; + +var LibraryRWebInput = { + $RI__deps: ['$Browser'], + $RI: { + temp: null, + contexts: [], + + eventHandler: function(event) { + var i; + switch (event.type) { + case 'mousemove': + var x = event['movementX'] || event['mozMovementX'] || event['webkitMovementX']; + var y = event['movementY'] || event['mozMovementY'] || event['webkitMovementY']; + for (i = 0; i < RI.contexts.length; i++) { + var oldX = {{{ makeGetValue('RI.contexts[i].state', '32', 'i32') }}}; + var oldY = {{{ makeGetValue('RI.contexts[i].state', '36', 'i32') }}}; + x += oldX; + y += oldY; + {{{ makeSetValue('RI.contexts[i].state', '32', 'x', 'i32') }}}; + {{{ makeSetValue('RI.contexts[i].state', '36', 'y', 'i32') }}}; + } + break; + case 'mouseup': + case 'mousedown': + var l, r; + + if (event.buttons & 1) l = 1; + else l = 0; + + if (event.buttons & 2) r = 1; + else r = 0; + + for (i = 0; i < RI.contexts.length; i++) { + {{{ makeSetValue('RI.contexts[i].state', '40', 'l', 'i8') }}}; + {{{ makeSetValue('RI.contexts[i].state', '41', 'r', 'i8') }}}; + } + break; + case 'click': + e.preventDefault(); + break; + case 'keyup': + case 'keydown': + var key = event.keyCode; + var offset = key >> 3; + var bit = 1 << (key & 7); + if (offset >= 32) throw 'key code error! bad code: ' + key; + for (i = 0; i < RI.contexts.length; i++) { + var value = {{{ makeGetValue('RI.contexts[i].state', 'offset', 'i8') }}}; + if (event.type === 'keyup') value &= ~bit; + else value |= bit; + {{{ makeSetValue('RI.contexts[i].state', 'offset', 'value', 'i8') }}}; + } + event.preventDefault(); + break; + case 'blur': + case 'visibilitychange': + for (i = 0; i < RI.contexts.length; i++) { + _memset(RI.contexts[i].state, 0, 42); + } + break; + } + } + }, + + RWebInputInit: function(latency) { + if (RI.contexts.length === 0) { + document.addEventListener('keyup', RI.eventHandler, false); + document.addEventListener('keydown', RI.eventHandler, false); + document.addEventListener('mousemove', RI.eventHandler, false); + document.addEventListener('mouseup', RI.eventHandler, false); + document.addEventListener('mousedown', RI.eventHandler, false); + document.addEventListener('click', RI.eventHandler, false); + document.addEventListener('blur', RI.eventHandler, false); + document.addEventListener('onvisbilitychange', RI.eventHandler, false); + } + if (RI.temp === null) RI.temp = _malloc(42); + + var s = _malloc(42); + _memset(s, 0, 42); + RI.contexts.push({ + state: s + }); + return RI.contexts.length; + }, + + RWebInputPoll: function(context) { + context -= 1; + var state = RI.contexts[context].state; + _memcpy(RI.temp, state, 42); + // reset mouse movements + {{{ makeSetValue('RI.contexts[context].state', '32', '0', 'i32') }}}; + {{{ makeSetValue('RI.contexts[context].state', '36', '0', 'i32') }}}; + return RI.temp; + }, + + RWebInputDestroy: function (context) { + if (context === RI.contexts.length) { + RI.contexts.pop(); + if (RI.contexts.length === 0) { + document.removeEventListener('keyup', RI.eventHandler, false); + document.removeEventListener('keydown', RI.eventHandler, false); + document.removeEventListener('mousemove', RI.eventHandler, false); + document.removeEventListener('mouseup', RI.eventHandler, false); + document.removeEventListener('mousedown', RI.eventHandler, false); + document.removeEventListener('click', RI.eventHandler, false); + document.removeEventListener('blur', RI.eventHandler, false); + document.removeEventListener('onvisbilitychange', RI.eventHandler, false); + } + } + } +}; + +autoAddDeps(LibraryRWebInput, '$RI'); +mergeInto(LibraryManager.library, LibraryRWebInput); diff --git a/gfx/context/emscriptenegl_ctx.c b/gfx/context/emscriptenegl_ctx.c index 363152c358..f9b89a42ca 100644 --- a/gfx/context/emscriptenegl_ctx.c +++ b/gfx/context/emscriptenegl_ctx.c @@ -31,7 +31,6 @@ #include #include #include -#include static EGLContext g_egl_ctx; static EGLSurface g_egl_surf; @@ -220,15 +219,12 @@ static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data { *input = NULL; - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) != 0) - return; + void *rwebinput = input_rwebinput.init(); - void *sdlinput = input_sdl.init(); - - if (sdlinput) + if (rwebinput) { - *input = &input_sdl; - *input_data = sdlinput; + *input = &input_rwebinput; + *input_data = rwebinput; } } diff --git a/input/input_common.c b/input/input_common.c index e58eede808..9993a99f13 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -513,6 +513,96 @@ const struct rarch_key_map rarch_key_map_dinput[] = { }; #endif +#ifdef EMSCRIPTEN +const struct rarch_key_map rarch_key_map_rwebinput[] = { + { 37, RETROK_LEFT }, + { 39, RETROK_RIGHT }, + { 38, RETROK_UP }, + { 40, RETROK_DOWN }, + { 13, RETROK_RETURN }, + { 9, RETROK_TAB }, + { 45, RETROK_INSERT }, + { 46, RETROK_DELETE }, + { 16, RETROK_RSHIFT }, + { 16, RETROK_LSHIFT }, + { 17, RETROK_LCTRL }, + { 35, RETROK_END }, + { 36, RETROK_HOME }, + { 34, RETROK_PAGEDOWN }, + { 33, RETROK_PAGEUP }, + { 18, RETROK_LALT }, + { 32, RETROK_SPACE }, + { 27, RETROK_ESCAPE }, + { 8, RETROK_BACKSPACE }, + { 13, RETROK_KP_ENTER }, + { 107, RETROK_KP_PLUS }, + { 109, RETROK_KP_MINUS }, + { 106, RETROK_KP_MULTIPLY }, + { 111, RETROK_KP_DIVIDE }, + { 192, RETROK_BACKQUOTE }, + { 19, RETROK_PAUSE }, + { 96, RETROK_KP0 }, + { 97, RETROK_KP1 }, + { 98, RETROK_KP2 }, + { 99, RETROK_KP3 }, + { 100, RETROK_KP4 }, + { 101, RETROK_KP5 }, + { 102, RETROK_KP6 }, + { 103, RETROK_KP7 }, + { 104, RETROK_KP8 }, + { 105, RETROK_KP9 }, + { 48, RETROK_0 }, + { 49, RETROK_1 }, + { 50, RETROK_2 }, + { 51, RETROK_3 }, + { 52, RETROK_4 }, + { 53, RETROK_5 }, + { 54, RETROK_6 }, + { 55, RETROK_7 }, + { 56, RETROK_8 }, + { 57, RETROK_9 }, + { 112, RETROK_F1 }, + { 113, RETROK_F2 }, + { 114, RETROK_F3 }, + { 115, RETROK_F4 }, + { 116, RETROK_F5 }, + { 117, RETROK_F6 }, + { 118, RETROK_F7 }, + { 119, RETROK_F8 }, + { 120, RETROK_F9 }, + { 121, RETROK_F10 }, + { 122, RETROK_F11 }, + { 123, RETROK_F12 }, + { 65, RETROK_a }, + { 66, RETROK_b }, + { 67, RETROK_c }, + { 68, RETROK_d }, + { 69, RETROK_e }, + { 70, RETROK_f }, + { 71, RETROK_g }, + { 72, RETROK_h }, + { 73, RETROK_i }, + { 74, RETROK_j }, + { 75, RETROK_k }, + { 76, RETROK_l }, + { 77, RETROK_m }, + { 78, RETROK_n }, + { 79, RETROK_o }, + { 80, RETROK_p }, + { 81, RETROK_q }, + { 82, RETROK_r }, + { 83, RETROK_s }, + { 84, RETROK_t }, + { 85, RETROK_u }, + { 86, RETROK_v }, + { 87, RETROK_w }, + { 88, RETROK_x }, + { 89, RETROK_y }, + { 90, RETROK_z }, + { 0, RETROK_UNKNOWN }, +}; +#endif + static enum retro_key rarch_keysym_lut[RETROK_LAST]; void input_init_keyboard_lut(const struct rarch_key_map *map) diff --git a/input/input_common.h b/input/input_common.h index 2ce912e98a..64b6447062 100644 --- a/input/input_common.h +++ b/input/input_common.h @@ -105,6 +105,7 @@ struct rarch_key_map extern const struct rarch_key_map rarch_key_map_x11[]; extern const struct rarch_key_map rarch_key_map_sdl[]; extern const struct rarch_key_map rarch_key_map_dinput[]; +extern const struct rarch_key_map rarch_key_map_rwebinput[]; void input_init_keyboard_lut(const struct rarch_key_map *map); enum retro_key input_translate_keysym_to_rk(unsigned sym); diff --git a/input/rwebinput_input.c b/input/rwebinput_input.c new file mode 100644 index 0000000000..1a65eec7d3 --- /dev/null +++ b/input/rwebinput_input.c @@ -0,0 +1,149 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Michael Lelli + * + * 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 "input_common.h" + +#include "../driver.h" + +#include "../boolean.h" +#include "../general.h" + +#include "../emscripten/RWebInput.h" + +static bool uninited = false; + +typedef struct rwebinput_input +{ + rwebinput_state_t state; + int context; +} rwebinput_input_t; + +static void *rwebinput_input_init(void) +{ + rwebinput_input_t *rwebinput = (rwebinput_input_t*)calloc(1, sizeof(*rwebinput)); + if (!rwebinput) + return NULL; + + rwebinput->context = RWebInputInit(); + if (!rwebinput->context) + { + free(rwebinput); + return NULL; + } + + input_init_keyboard_lut(rarch_key_map_rwebinput); + + return rwebinput; +} + +static bool rwebinput_key_pressed(rwebinput_input_t *rwebinput, int key) +{ + if (key >= RETROK_LAST) + return false; + + unsigned sym = input_translate_rk_to_keysym((enum retro_key)key); + bool ret = rwebinput->state.keys[sym >> 3] & (1 << (sym & 7)); + return ret; +} + +static bool rwebinput_is_pressed(rwebinput_input_t *rwebinput, const struct retro_keybind *binds, unsigned id) +{ + if (id < RARCH_BIND_LIST_END) + { + const struct retro_keybind *bind = &binds[id]; + return bind->valid && rwebinput_key_pressed(rwebinput, binds[id].key); + } + else + return false; +} + +static bool rwebinput_bind_button_pressed(void *data, int key) +{ + rwebinput_input_t *rwebinput = (rwebinput_input_t*)data; + return rwebinput_is_pressed(rwebinput, g_settings.input.binds[0], key); +} + +static int16_t rwebinput_mouse_state(rwebinput_input_t *rwebinput, unsigned id) +{ + switch (id) + { + case RETRO_DEVICE_ID_MOUSE_X: + return (int16_t) rwebinput->state.mouse_x; + case RETRO_DEVICE_ID_MOUSE_Y: + return (int16_t) rwebinput->state.mouse_y; + case RETRO_DEVICE_ID_MOUSE_LEFT: + return rwebinput->state.mouse_l; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + return rwebinput->state.mouse_r; + default: + return 0; + } +} + +static int16_t rwebinput_input_state(void *data, const struct retro_keybind **binds, unsigned port, unsigned device, unsigned index, unsigned id) +{ + rwebinput_input_t *rwebinput = (rwebinput_input_t*)data; + + switch (device) + { + case RETRO_DEVICE_JOYPAD: + return rwebinput_is_pressed(rwebinput, binds[port], id); + + case RETRO_DEVICE_KEYBOARD: + return rwebinput_key_pressed(rwebinput, id); + + case RETRO_DEVICE_MOUSE: + return rwebinput_mouse_state(rwebinput, id); + + default: + return 0; + } +} + +static void rwebinput_input_free(void *data) +{ + rwebinput_input_t *rwebinput = (rwebinput_input_t*)data; + uninited = true; + + RWebInputDestroy(rwebinput->context); + + free(data); +} + +static void rwebinput_input_poll(void *data) +{ + rwebinput_input_t *rwebinput = (rwebinput_input_t*)data; + + rwebinput_state_t *state = RWebInputPoll(rwebinput->context); + memcpy(&rwebinput->state, state, sizeof(rwebinput->state)); +} + +static void rwebinput_grab_mouse(void *data, bool state) +{ + (void)data; + (void)state; +} + +const input_driver_t input_rwebinput = { + rwebinput_input_init, + rwebinput_input_poll, + rwebinput_input_state, + rwebinput_bind_button_pressed, + rwebinput_input_free, + NULL, + "rwebinput", + rwebinput_grab_mouse, +}; + diff --git a/settings.c b/settings.c index 682774941a..4e4331bc63 100644 --- a/settings.c +++ b/settings.c @@ -139,6 +139,8 @@ const char *config_get_default_input(void) return "apple_input"; case INPUT_QNX: return "qnx_input"; + case INPUT_RWEBINPUT: + return "rwebinput"; case INPUT_NULL: return "null"; default: From b874f003ff4335fe13f26e12d5990646beaf7809 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Tue, 10 Sep 2013 22:02:54 -0400 Subject: [PATCH 180/202] [EMSCRIPTEN] undo SDL workarounds no longer needed --- input/input_common.c | 2 +- input/sdl_input.c | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/input/input_common.c b/input/input_common.c index 9993a99f13..cf632e1de9 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -48,7 +48,7 @@ static const rarch_joypad_driver_t *joypad_drivers[] = { #if defined(__linux) && !defined(ANDROID) &linuxraw_joypad, #endif -#if defined(HAVE_SDL) && !defined(EMSCRIPTEN) +#ifdef HAVE_SDL &sdl_joypad, #endif #endif diff --git a/input/sdl_input.c b/input/sdl_input.c index 57c9a32b91..d438c3f8a5 100644 --- a/input/sdl_input.c +++ b/input/sdl_input.c @@ -24,10 +24,6 @@ #include "../libretro.h" #include "input_common.h" -#ifdef EMSCRIPTEN -#define SDL_GetKeyState SDL_GetKeyboardState -#endif - typedef struct sdl_input { const rarch_joypad_driver_t *joypad; @@ -55,7 +51,7 @@ static bool sdl_key_pressed(int key) int sym = input_translate_rk_to_keysym((enum retro_key)key); - int num_keys = 0xFFFF; + int num_keys; Uint8 *keymap = SDL_GetKeyState(&num_keys); if (sym < 0 || sym >= num_keys) return false; @@ -220,14 +216,11 @@ static void sdl_input_free(void *data) static void sdl_poll_mouse(sdl_input_t *sdl) { - (void)sdl; -#ifndef EMSCRIPTEN Uint8 btn = SDL_GetRelativeMouseState(&sdl->mouse_x, &sdl->mouse_y); SDL_GetMouseState(&sdl->mouse_abs_x, &sdl->mouse_abs_y); sdl->mouse_l = SDL_BUTTON(SDL_BUTTON_LEFT) & btn ? 1 : 0; sdl->mouse_r = SDL_BUTTON(SDL_BUTTON_RIGHT) & btn ? 1 : 0; sdl->mouse_m = SDL_BUTTON(SDL_BUTTON_MIDDLE) & btn ? 1 : 0; -#endif } static void sdl_input_poll(void *data) From e6389f991914fa19a62322627c368204ee30fede Mon Sep 17 00:00:00 2001 From: ToadKing Date: Tue, 10 Sep 2013 22:48:24 -0400 Subject: [PATCH 181/202] [EMSCRIPTEN] chrome fixes --- emscripten/library_rwebaudio.js | 13 ++++++++++--- emscripten/library_rwebinput.js | 23 ++++++++--------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/emscripten/library_rwebaudio.js b/emscripten/library_rwebaudio.js index 73448afbf9..4e7594ec45 100644 --- a/emscripten/library_rwebaudio.js +++ b/emscripten/library_rwebaudio.js @@ -1,7 +1,7 @@ //"use strict"; var LibraryRWebAudio = { - $RA__deps: ['$Browser'], + $RA__deps: ['$Browser', 'usleep'], $RA: { BUFFER_SIZE: 256, @@ -12,17 +12,24 @@ var LibraryRWebAudio = { bufOffset: 0, startTime: 0, nonblock: false, + currentTimeWorkaround: false, setStartTime: function() { if (RA.context.currentTime) { RA.startTime = window['performance']['now']() - RA.context.currentTime * 1000; - if (RA.startTime === 0) throw 'startTime is 0'; + var time1 = RA.context.currentTime; + _usleep(50); + if (time1 === RA.context.currentTime) { + RA.currentTimeWorkaround = true; + if (RA.startTime === 0) throw 'startTime is 0'; + } Module["resumeMainLoop"](); } else window['setTimeout'](RA.setStartTime, 0); }, getCurrentPerfTime: function() { - if (RA.startTime) return (window['performance']['now']() - RA.startTime) / 1000; + if (!RA.currentTimeWorkaround) return RA.context.currentTime; + else if (RA.startTime) return (window['performance']['now']() - RA.startTime) / 1000; else throw 'getCurrentPerfTime() called before start time set'; }, diff --git a/emscripten/library_rwebinput.js b/emscripten/library_rwebinput.js index 3ca2fd9cd1..7f45a747d8 100644 --- a/emscripten/library_rwebinput.js +++ b/emscripten/library_rwebinput.js @@ -23,22 +23,17 @@ var LibraryRWebInput = { break; case 'mouseup': case 'mousedown': - var l, r; - - if (event.buttons & 1) l = 1; - else l = 0; - - if (event.buttons & 2) r = 1; - else r = 0; - + var value; + var offset; + if (event.button === 0) offset = 40; + else if (event.button === 2) offset = 41; + else break; + if (event.type === 'mouseup') value = 0; + else value = 1; for (i = 0; i < RI.contexts.length; i++) { - {{{ makeSetValue('RI.contexts[i].state', '40', 'l', 'i8') }}}; - {{{ makeSetValue('RI.contexts[i].state', '41', 'r', 'i8') }}}; + {{{ makeSetValue('RI.contexts[i].state', 'offset', 'value', 'i8') }}}; } break; - case 'click': - e.preventDefault(); - break; case 'keyup': case 'keydown': var key = event.keyCode; @@ -70,7 +65,6 @@ var LibraryRWebInput = { document.addEventListener('mousemove', RI.eventHandler, false); document.addEventListener('mouseup', RI.eventHandler, false); document.addEventListener('mousedown', RI.eventHandler, false); - document.addEventListener('click', RI.eventHandler, false); document.addEventListener('blur', RI.eventHandler, false); document.addEventListener('onvisbilitychange', RI.eventHandler, false); } @@ -103,7 +97,6 @@ var LibraryRWebInput = { document.removeEventListener('mousemove', RI.eventHandler, false); document.removeEventListener('mouseup', RI.eventHandler, false); document.removeEventListener('mousedown', RI.eventHandler, false); - document.removeEventListener('click', RI.eventHandler, false); document.removeEventListener('blur', RI.eventHandler, false); document.removeEventListener('onvisbilitychange', RI.eventHandler, false); } From 0b45fb1483f25265918684bfc3f8bd7c71708567 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 11 Sep 2013 11:00:09 +0200 Subject: [PATCH 182/202] (Android Phoenix) Set default values for ListPreferences --- android/phoenix/res/xml/prefs.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index a63a383471..94c6e5b452 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -43,6 +43,7 @@ @@ -126,6 +127,7 @@ From 0d873654cc00febbdf4ca4619f820e254df0e2dd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 11 Sep 2013 14:07:54 +0200 Subject: [PATCH 183/202] (Android Phoenix) Add Xperia Play detection based on MODEL string --- .../retroarch/browser/MainMenuActivity.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 24e97ea143..b0e81963ab 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -729,6 +729,27 @@ public class MainMenuActivity extends PreferenceActivity { }); alert.show(); retval = true; + } else if (android.os.Build.MODEL.equals("R800x")) { + AlertDialog.Builder alert = new AlertDialog.Builder(this) + .setTitle("Xperia Play detected") + .setMessage(message) + .setPositiveButton("OK", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + SharedPreferences prefs = getPreferences(); + SharedPreferences.Editor edit = prefs + .edit(); + edit.putBoolean("input_overlay_enable", + false); + edit.putBoolean("input_autodetect_enable", + true); + edit.commit(); + } + }); + alert.show(); + retval = true; } else if (android.os.Build.ID.equals("JSS15J")) { AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("Nexus 7 2013 detected") From bcac9ded7862d5042fdb9cf3a44e21ce550accb2 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 11 Sep 2013 17:06:06 +0200 Subject: [PATCH 184/202] DInput/XInput fixups. - Fix DInput if XInput failed to load and you're using an XInput device. - Try to load XInput 1.4 first. It's installed by default on Win8. - Don't bother checking "system directory" explicitly, it already does. --- input/autoconf/builtin_win.c | 2 +- input/dinput.c | 28 +++++++++++--------------- input/winxinput_joypad.c | 39 +++++++++++++++++++----------------- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/input/autoconf/builtin_win.c b/input/autoconf/builtin_win.c index b359dcc102..d28e9de1df 100644 --- a/input/autoconf/builtin_win.c +++ b/input/autoconf/builtin_win.c @@ -28,7 +28,7 @@ DECL_BTN(left, h0left) \ DECL_BTN(right, h0right) \ DECL_BTN(l, 4) \ DECL_BTN(r, 5) \ -DECL_BTN(l3, 8 )\ +DECL_BTN(l3, 8) \ DECL_BTN(r3, 9) \ DECL_BTN(menu_toggle, 10) \ DECL_AXIS(l2, +4) \ diff --git a/input/dinput.c b/input/dinput.c index b9a366d71f..2639970c28 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -349,7 +349,8 @@ const input_driver_t input_dinput = { // Keep track of which pad indexes are 360 controllers // not static, will be read in winxinput_joypad.c // -1 = not xbox pad, otherwise 0..3 -int g_xbox_pad_indexes[MAX_PLAYERS]; +int g_xinput_pad_indexes[MAX_PLAYERS]; +bool g_xinput_block_pads; static void dinput_joypad_destroy(void) { @@ -421,7 +422,7 @@ static const char* const XINPUT_PAD_NAMES[] = NULL }; -static bool name_is_360_pad(const char* name) +static bool name_is_xinput_pad(const char* name) { for (unsigned i = 0; ; ++i) { @@ -435,8 +436,7 @@ static bool name_is_360_pad(const char* name) // Forward declaration static const char *dinput_joypad_name(unsigned pad); - -static int g_last_xbox_pad_index; +static unsigned g_last_xinput_pad_index; static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) { @@ -456,14 +456,12 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName); #ifdef HAVE_WINXINPUT - bool is_360_pad = name_is_360_pad(inst->tszProductName); + bool is_xinput_pad = g_xinput_block_pads && name_is_xinput_pad(inst->tszProductName); - if (is_360_pad) + if (is_xinput_pad) { - if (g_last_xbox_pad_index < 4) - g_xbox_pad_indexes[g_joypad_cnt] = g_last_xbox_pad_index; - ++g_last_xbox_pad_index; - + if (g_last_xinput_pad_index < 4) + g_xinput_pad_indexes[g_joypad_cnt] = g_last_xinput_pad_index++; goto enum_iteration_done; } #endif @@ -476,7 +474,7 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p) *pad, DIDFT_ABSAXIS); #ifdef HAVE_WINXINPUT - if (!is_360_pad) + if (!is_xinput_pad) #endif { strlcpy(g_settings.input.device_names[g_joypad_cnt], dinput_joypad_name(g_joypad_cnt), sizeof(g_settings.input.device_names[g_joypad_cnt])); @@ -493,11 +491,11 @@ static bool dinput_joypad_init(void) if (!dinput_init_context()) return false; - g_last_xbox_pad_index = 0; + g_last_xinput_pad_index = 0; for (unsigned i = 0; i < MAX_PLAYERS; ++i) { - g_xbox_pad_indexes[i] = -1; + g_xinput_pad_indexes[i] = -1; g_pads[i].joy_name = NULL; } @@ -607,7 +605,7 @@ static void dinput_joypad_poll(void) { struct dinput_joypad *pad = &g_pads[i]; - if ((pad->joypad) && (g_xbox_pad_indexes[i] == -1)) + if (pad->joypad && g_xinput_pad_indexes[i] < 0) { memset(&pad->joy_state, 0, sizeof(pad->joy_state)); @@ -638,8 +636,6 @@ static bool dinput_joypad_query_pad(unsigned pad) return pad < MAX_PLAYERS && g_pads[pad].joypad; } - - static const char *dinput_joypad_name(unsigned pad) { if (pad < MAX_PLAYERS) diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index 535e8b62ea..40114cb320 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -83,7 +83,8 @@ typedef struct // hack is required here. dinput_joypad_init will fill this. // For each pad index, the appropriate entry will be set to -1 if it is not // a 360 pad, or the correct XInput player number (0..3 inclusive) if it is. -extern int g_xbox_pad_indexes[MAX_PLAYERS]; +extern int g_xinput_pad_indexes[MAX_PLAYERS]; +extern bool g_xinput_block_pads; // For xinput1_3.dll static HINSTANCE g_winxinput_dll; @@ -105,7 +106,7 @@ static winxinput_joypad_state g_winxinput_states[4]; static inline int pad_index_to_xplayer_index(unsigned pad) { - return g_xbox_pad_indexes[pad]; + return g_xinput_pad_indexes[pad]; } // Generic "XInput" instead of "Xbox 360", because there are @@ -144,25 +145,21 @@ static bool winxinput_joypad_init(void) // No need to check for existance as we will be checking LoadLibrary's // success anyway. - // Note: Windows 8 ships with 1.4 but there doesn't - // seem to be any compelling reason to use it. - const char* DLL_NAME = "xinput1_3.dll"; - g_winxinput_dll = LoadLibrary(DLL_NAME); // Using dylib_* complicates building joyconfig. + const char *version = "1.4"; + g_winxinput_dll = LoadLibrary("xinput1_4.dll"); // Using dylib_* complicates building joyconfig. if (!g_winxinput_dll) { - // Loading from working dir failed, try to load from system. - char dll_path[MAX_PATH]; - GetSystemDirectory(dll_path, sizeof(dll_path)); - strlcat(dll_path, "\\", 1); - strlcat(dll_path, DLL_NAME, sizeof(DLL_NAME)); - g_winxinput_dll = LoadLibrary(dll_path); - - if (!g_winxinput_dll) - { - RARCH_ERR("Failed to load xinput1_3.dll, ensure DirectX and controller drivers are up to date.\n"); - return false; // DLL does not exist or is invalid - } + g_winxinput_dll = LoadLibrary("xinput1_3.dll"); + version = "1.3"; } + + if (!g_winxinput_dll) + { + RARCH_ERR("Failed to load xinput1_3.dll, ensure DirectX and controller drivers are up to date.\n"); + return false; // DLL does not exist or is invalid + } + + RARCH_LOG("Found XInput v%s.\n", version); // If we get here then an xinput DLL is correctly loaded. // First try to load ordinal 100 (XInputGetStateEx). @@ -201,11 +198,16 @@ static bool winxinput_joypad_init(void) (!g_winxinput_states[2].connected) && (!g_winxinput_states[3].connected)) return false; + + g_xinput_block_pads = true; // We're going to have to be buddies with dinput if we want to be able // to use XI and non-XI controllers together. if (!dinput_joypad.init()) + { + g_xinput_block_pads = false; return false; + } for (unsigned autoconf_pad = 0; autoconf_pad < MAX_PLAYERS; autoconf_pad++) { @@ -239,6 +241,7 @@ static void winxinput_joypad_destroy(void) g_XInputGetStateEx = NULL; dinput_joypad.destroy(); + g_xinput_block_pads = false; } // Buttons are provided by XInput as bits of a uint16. From 1ea1f723b417c8a54ff3a464ca9e3e435a260867 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 11 Sep 2013 17:12:55 +0200 Subject: [PATCH 185/202] Clarify error message a bit. --- input/winxinput_joypad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/input/winxinput_joypad.c b/input/winxinput_joypad.c index 40114cb320..bc9f419df0 100644 --- a/input/winxinput_joypad.c +++ b/input/winxinput_joypad.c @@ -155,8 +155,8 @@ static bool winxinput_joypad_init(void) if (!g_winxinput_dll) { - RARCH_ERR("Failed to load xinput1_3.dll, ensure DirectX and controller drivers are up to date.\n"); - return false; // DLL does not exist or is invalid + RARCH_ERR("Failed to load XInput, ensure DirectX and controller drivers are up to date.\n"); + return false; } RARCH_LOG("Found XInput v%s.\n", version); From 083f1cdffe79639153e656f71369402445385462 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 11 Sep 2013 19:16:47 -0400 Subject: [PATCH 186/202] (OSX/iOS) Move Wii and PS3 hid drivers into the common source directory. Use the Wii and PS3 hid drivers on OSX when appropriate. Notably OSX now has WiiMote support. --- apple/OSX/hid_pad.c | 187 ++++++++++-------- apple/common/apple_joypad.c | 7 +- apple/common/hidpad/hidpad.h | 32 +++ .../hidpad/hidpad_ps3.c} | 82 ++++---- apple/common/hidpad/hidpad_wii.c | 113 +++++++++++ .../bluetooth => common/hidpad}/wiimote.c | 8 +- .../bluetooth => common/hidpad}/wiimote.h | 8 +- apple/common/setting_data.h | 22 +-- apple/iOS/bluetooth/btpad.c | 130 ++++++------ apple/iOS/bluetooth/btpad.h | 35 ---- apple/iOS/bluetooth/btpad_wii.c | 123 ------------ 11 files changed, 379 insertions(+), 368 deletions(-) create mode 100644 apple/common/hidpad/hidpad.h rename apple/{iOS/bluetooth/btpad_ps3.c => common/hidpad/hidpad_ps3.c} (58%) create mode 100644 apple/common/hidpad/hidpad_wii.c rename apple/{iOS/bluetooth => common/hidpad}/wiimote.c (99%) rename apple/{iOS/bluetooth => common/hidpad}/wiimote.h (98%) delete mode 100644 apple/iOS/bluetooth/btpad_wii.c diff --git a/apple/OSX/hid_pad.c b/apple/OSX/hid_pad.c index 39cee0feed..47085a2873 100644 --- a/apple/OSX/hid_pad.c +++ b/apple/OSX/hid_pad.c @@ -15,57 +15,48 @@ #include #include "apple/common/apple_input.h" +#include "apple/common/hidpad/hidpad.h" -// NOTE: I pieced this together through trial and error, any corrections are welcome +#include "apple/common/hidpad/hidpad_ps3.c" +#include "apple/common/hidpad/hidpad_wii.c" +#include "apple/common/hidpad/wiimote.c" + +struct hidpad_connection +{ + uint32_t slot; + + struct hidpad_interface* interface; + void* hidpad; + + IOHIDDeviceRef device; + + uint8_t data[2048]; +}; static IOHIDManagerRef g_hid_manager; -static uint32_t g_pad_slots; +static struct hidpad_connection g_connected_pads[MAX_PADS]; -#define HID_ISSET(t, x) (t & (1 << x)) -#define HID_SET(t, x) { t |= (1 << x); } -#define HID_CLEAR(t, x) { t &= ~(1 << x); } - -// Set the LEDs on PS3 controllers, if slot >= MAX_PADS the LEDs will be cleared -static void osx_pad_set_leds(IOHIDDeviceRef device, uint32_t slot) +void hidpad_send_control(struct hidpad_connection* connection, uint8_t* data, size_t size) { - char buffer[1024]; - - CFStringRef device_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); - if (device_name) - { - CFStringGetCString(device_name, buffer, 1024, kCFStringEncodingUTF8); - - if (strncmp(buffer, "PLAYSTATION(R)3 Controller", 1024) == 0) - { - static uint8_t report_buffer[] = { - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x27, - 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00, - 0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - report_buffer[10] = (slot >= MAX_PADS) ? 0 : (1 << (slot + 1)); - - IOHIDDeviceSetReport(device, kIOHIDReportTypeOutput, 0x01, report_buffer, sizeof(report_buffer)); - } - } + IOHIDDeviceSetReport(connection->device, kIOHIDReportTypeOutput, 0x01, data, size); } -static void hid_device_input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef inIOHIDValueRef) +// NOTE: I pieced this together through trial and error, any corrections are welcome +static void hid_device_input_callback(void* context, IOReturn result, void* sender, IOHIDValueRef value) { - IOHIDElementRef element = IOHIDValueGetElement(inIOHIDValueRef); - IOHIDDeviceRef device = IOHIDElementGetDevice(element); + struct hidpad_connection* connection = context; + IOHIDElementRef element = IOHIDValueGetElement(value); uint32_t type = IOHIDElementGetType(element); uint32_t page = IOHIDElementGetUsagePage(element); uint32_t use = IOHIDElementGetUsage(element); // Mouse handler - if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) + if (!connection) { if (type == kIOHIDElementTypeInput_Button && page == kHIDPage_Button) { - CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef); + CFIndex state = IOHIDValueGetIntegerValue(value); if (state) g_current_input_data.mouse_buttons |= (1 << (use - 1)); else g_current_input_data.mouse_buttons &= ~(1 << (use - 1)); @@ -76,22 +67,18 @@ static void hid_device_input_callback(void* inContext, IOReturn inResult, void* for (int i = 0; i < 2; i ++) if (use == axis_use_ids[i]) - g_current_input_data.mouse_delta[i] += IOHIDValueGetIntegerValue(inIOHIDValueRef); + g_current_input_data.mouse_delta[i] += IOHIDValueGetIntegerValue(value); } } - // Joystick handler - else if (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)) + // Joystick handler: TODO: Can GamePad work the same? + else if (IOHIDDeviceConformsTo(connection->device, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)) { - uint32_t slot = (uint32_t)inContext; - if (slot >= 4) - return; - if (type == kIOHIDElementTypeInput_Button && page == kHIDPage_Button) { - CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef); + CFIndex state = IOHIDValueGetIntegerValue(value); - if (state) g_current_input_data.pad_buttons[slot] |= (1 << (use - 1)); - else g_current_input_data.pad_buttons[slot] &= ~(1 << (use - 1)); + if (state) g_current_input_data.pad_buttons[connection->slot] |= (1 << (use - 1)); + else g_current_input_data.pad_buttons[connection->slot] &= ~(1 << (use - 1)); } else if (type == kIOHIDElementTypeInput_Misc && page == kHIDPage_GenericDesktop) { @@ -102,62 +89,94 @@ static void hid_device_input_callback(void* inContext, IOReturn inResult, void* { CFIndex min = IOHIDElementGetPhysicalMin(element); CFIndex max = IOHIDElementGetPhysicalMax(element) - min; - CFIndex state = IOHIDValueGetIntegerValue(inIOHIDValueRef) - min; + CFIndex state = IOHIDValueGetIntegerValue(value) - min; float val = (float)state / (float)max; - g_current_input_data.pad_axis[slot][i] = ((val * 2.0f) - 1.0f) * 32767.0f; + g_current_input_data.pad_axis[connection->slot][i] = ((val * 2.0f) - 1.0f) * 32767.0f; } } } } } -static void hid_device_removed(void* inContext, IOReturn inResult, void* inSender) +static void hid_device_removed(void* context, IOReturn result, void* sender) { - IOHIDDeviceRef inDevice = (IOHIDDeviceRef)inSender; + struct hidpad_connection* connection = (struct hidpad_connection*)context; - if (IOHIDDeviceConformsTo(inDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)) + if (connection && connection->slot < MAX_PADS) { - uint32_t pad_index = (uint32_t)inContext; - - if (pad_index < MAX_PADS) - { - HID_CLEAR(g_pad_slots, pad_index); - - g_current_input_data.pad_buttons[pad_index] = 0; - memset(g_current_input_data.pad_axis[pad_index], 0, sizeof(g_current_input_data.pad_axis)); - } + g_current_input_data.pad_buttons[connection->slot] = 0; + memset(g_current_input_data.pad_axis[connection->slot], 0, sizeof(g_current_input_data.pad_axis)); + + if (connection->interface) + connection->interface->disconnect(connection->hidpad); + memset(connection, 0, sizeof(*connection)); } - osx_pad_set_leds(inDevice, MAX_PADS); - IOHIDDeviceClose(inDevice, kIOHIDOptionsTypeNone); + IOHIDDeviceClose(sender, kIOHIDOptionsTypeNone); } -static void hid_manager_device_attached(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice) +static void hid_device_report(void* context, IOReturn result, void *sender, IOHIDReportType type, uint32_t reportID, uint8_t *report, CFIndex reportLength) { - uint32_t pad_index = 0; - if (IOHIDDeviceConformsTo(inDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick)) + struct hidpad_connection* connection = (struct hidpad_connection*)context; + connection->interface->packet_handler(connection->hidpad, report, reportLength); +} + +static void hid_manager_device_attached(void* context, IOReturn result, void* sender, IOHIDDeviceRef device) +{ + bool is_pad = (IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick) || + IOHIDDeviceConformsTo(device, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)); + + struct hidpad_connection* connection = 0; + + if (is_pad) { - if ((g_pad_slots & 0xF) == 0xF) - return; - - for (pad_index = 0; pad_index != MAX_PADS; pad_index ++) - if (!HID_ISSET(g_pad_slots, pad_index)) + for (int i = 0; i != MAX_PADS; i ++) + { + if (!g_connected_pads[i].device) { - HID_SET(g_pad_slots, pad_index); + connection = &g_connected_pads[i]; + connection->device = device; + connection->slot = i; break; } - } - - IOHIDDeviceOpen(inDevice, kIOHIDOptionsTypeNone); - IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); - IOHIDDeviceRegisterInputValueCallback(inDevice, hid_device_input_callback, (void*)pad_index); - IOHIDDeviceRegisterRemovalCallback(inDevice, hid_device_removed, (void*)pad_index); + } - osx_pad_set_leds(inDevice, pad_index); + if (!connection) + return; + } + + IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone); + IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); + IOHIDDeviceRegisterRemovalCallback(device, hid_device_removed, connection); + + CFStringRef device_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); + if (is_pad && device_name) + { + static const struct { const char* name; struct hidpad_interface* iface; } hidpad_map[] = { + { "Nintendo RVL-CNT-01", &hidpad_wii }, + { "PLAYSTATION(R)3 Controller", &hidpad_ps3 }, + { 0, 0} }; + + char buffer[1024]; + CFStringGetCString(device_name, buffer, 1024, kCFStringEncodingUTF8); + + for (int i = 0; hidpad_map[i].name; i ++) + { + if (strstr(buffer, hidpad_map[i].name)) + { + connection->interface = hidpad_map[i].iface; + IOHIDDeviceRegisterInputReportCallback(device, connection->data, 2048, hid_device_report, connection); + connection->hidpad = connection->interface->connect(connection, connection->slot); + return; + } + } + } + + IOHIDDeviceRegisterInputValueCallback(device, hid_device_input_callback, connection); } -static CFMutableDictionaryRef build_matching_dictionary(uint32_t page, uint32_t use) +static void append_matching_dictionary(CFMutableArrayRef array, uint32_t page, uint32_t use) { CFMutableDictionaryRef matcher = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -169,7 +188,8 @@ static CFMutableDictionaryRef build_matching_dictionary(uint32_t page, uint32_t CFDictionarySetValue(matcher, CFSTR(kIOHIDDeviceUsageKey), usen); CFRelease(usen); - return matcher; + CFArrayAppendValue(array, matcher); + CFRelease(matcher); } void osx_pad_init() @@ -179,14 +199,9 @@ void osx_pad_init() g_hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); CFMutableArrayRef matcher = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - - CFMutableDictionaryRef mouse = build_matching_dictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse); - CFArrayAppendValue(matcher, mouse); - CFRelease(mouse); - - CFMutableDictionaryRef joystick = build_matching_dictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); - CFArrayAppendValue(matcher, joystick); - CFRelease(joystick); + append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse); + append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); + append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); IOHIDManagerSetDeviceMatchingMultiple(g_hid_manager, matcher); CFRelease(matcher); diff --git a/apple/common/apple_joypad.c b/apple/common/apple_joypad.c index 0f5807441e..96ed6812ba 100644 --- a/apple/common/apple_joypad.c +++ b/apple/common/apple_joypad.c @@ -18,15 +18,16 @@ #ifdef IOS #include "apple/iOS/bluetooth/btdynamic.c" -#include "apple/iOS/bluetooth/wiimote.c" #include "apple/iOS/bluetooth/btpad.c" -#include "apple/iOS/bluetooth/btpad_ps3.c" -#include "apple/iOS/bluetooth/btpad_wii.c" #include "apple/iOS/bluetooth/btpad_queue.c" #elif defined(OSX) #include "../OSX/hid_pad.c" #endif +#include "apple/common/hidpad/wiimote.c" +#include "apple/common/hidpad/hidpad_ps3.c" +#include "apple/common/hidpad/hidpad_wii.c" + static bool apple_joypad_init(void) { diff --git a/apple/common/hidpad/hidpad.h b/apple/common/hidpad/hidpad.h new file mode 100644 index 0000000000..4002c8d060 --- /dev/null +++ b/apple/common/hidpad/hidpad.h @@ -0,0 +1,32 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * 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 __IOS_RARCH_HIDPAD_H__ +#define __IOS_RARCH_HIDPAD_H__ + +struct hidpad_connection; +void hidpad_send_control(struct hidpad_connection* connection, uint8_t* data, size_t size); + +struct hidpad_interface +{ + void* (*connect)(struct hidpad_connection* connection, uint32_t slot); + void (*disconnect)(void* device); + void (*packet_handler)(void* device, uint8_t *packet, uint16_t size); +}; + +extern struct hidpad_interface hidpad_wii; +extern struct hidpad_interface hidpad_ps3; + +#endif diff --git a/apple/iOS/bluetooth/btpad_ps3.c b/apple/common/hidpad/hidpad_ps3.c similarity index 58% rename from apple/iOS/bluetooth/btpad_ps3.c rename to apple/common/hidpad/hidpad_ps3.c index d681358e62..d68411269d 100644 --- a/apple/iOS/bluetooth/btpad_ps3.c +++ b/apple/common/hidpad/hidpad_ps3.c @@ -20,22 +20,19 @@ #include "boolean.h" #include "apple/common/rarch_wrapper.h" -#include "btdynamic.h" -#include "btpad.h" +#include "hidpad.h" -struct btpad_ps3_data +struct hidpad_ps3_data { + struct hidpad_connection* connection; + uint8_t data[512]; - - bd_addr_t address; - uint32_t handle; - uint32_t channels[2]; - + uint32_t slot; bool have_led; }; -static void btpad_ps3_send_control(struct btpad_ps3_data* device) +static void hidpad_ps3_send_control(struct hidpad_ps3_data* device) { // TODO: Can this be modified to turn off motion tracking? static uint8_t report_buffer[] = { @@ -52,35 +49,38 @@ static void btpad_ps3_send_control(struct btpad_ps3_data* device) }; report_buffer[11] = 1 << ((device->slot % 4) + 1); - bt_send_l2cap_ptr(device->channels[0], report_buffer, sizeof(report_buffer)); +#ifdef IOS + hidpad_send_control(device->connection, report_buffer, sizeof(report_buffer)); +#else + hidpad_send_control(device->connection, report_buffer + 1, sizeof(report_buffer) - 1); +#endif } -static void* btpad_ps3_connect(const btpad_connection_t* connection) +static void* hidpad_ps3_connect(struct hidpad_connection* connection, uint32_t slot) { - struct btpad_ps3_data* device = malloc(sizeof(struct btpad_ps3_data)); + struct hidpad_ps3_data* device = malloc(sizeof(struct hidpad_ps3_data)); memset(device, 0, sizeof(*device)); - - memcpy(device->address, connection->address, BD_ADDR_LEN); - device->handle = connection->handle; - device->channels[0] = connection->channels[0]; - device->channels[1] = connection->channels[1]; - device->slot = connection->slot; + device->connection = connection; + device->slot = slot; // Magic packet to start reports +#ifdef IOS static uint8_t data[] = {0x53, 0xF4, 0x42, 0x03, 0x00, 0x00}; - bt_send_l2cap_ptr(device->channels[0], data, 6); + hidpad_send_control(device->connection, data, 6); +#endif // Without this the digital buttons won't be reported - btpad_ps3_send_control(device); + hidpad_ps3_send_control(device); return device; } -static void btpad_ps3_disconnect(struct btpad_ps3_data* device) +static void hidpad_ps3_disconnect(struct hidpad_ps3_data* device) { + free(device); } -static uint32_t btpad_ps3_get_buttons(struct btpad_ps3_data* device) +static uint32_t hidpad_ps3_get_buttons(struct hidpad_ps3_data* device) { #define KEY(X) RETRO_DEVICE_ID_JOYPAD_##X static const uint32_t button_mapping[17] = @@ -102,7 +102,7 @@ static uint32_t btpad_ps3_get_buttons(struct btpad_ps3_data* device) return result; } -static int16_t btpad_ps3_get_axis(struct btpad_ps3_data* device, unsigned axis) +static int16_t hidpad_ps3_get_axis(struct hidpad_ps3_data* device, unsigned axis) { if (axis < 4) { @@ -114,28 +114,28 @@ static int16_t btpad_ps3_get_axis(struct btpad_ps3_data* device, unsigned axis) return 0; } -static void btpad_ps3_packet_handler(struct btpad_ps3_data* device, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) +static void hidpad_ps3_packet_handler(struct hidpad_ps3_data* device, uint8_t *packet, uint16_t size) { - if (packet_type == L2CAP_DATA_PACKET && packet[0] == 0xA1) + if (!device->have_led) { - if (!device->have_led) - { - btpad_ps3_send_control(device); - device->have_led = true; - } - - memcpy(device->data, packet, size); - g_current_input_data.pad_buttons[device->slot] = btpad_ps3_get_buttons(device); - for (int i = 0; i < 4; i ++) - g_current_input_data.pad_axis[device->slot][i] = btpad_ps3_get_axis(device, i); + hidpad_ps3_send_control(device); + device->have_led = true; } + +#ifdef IOS + memcpy(device->data, packet, size); +#else + memcpy(device->data + 1, packet, size); +#endif + + g_current_input_data.pad_buttons[device->slot] = hidpad_ps3_get_buttons(device); + for (int i = 0; i < 4; i ++) + g_current_input_data.pad_axis[device->slot][i] = hidpad_ps3_get_axis(device, i); } -struct btpad_interface btpad_ps3 = +struct hidpad_interface hidpad_ps3 = { - (void*)&btpad_ps3_connect, - (void*)&btpad_ps3_disconnect, - (void*)&btpad_ps3_get_buttons, - (void*)&btpad_ps3_get_axis, - (void*)&btpad_ps3_packet_handler + (void*)&hidpad_ps3_connect, + (void*)&hidpad_ps3_disconnect, + (void*)&hidpad_ps3_packet_handler }; diff --git a/apple/common/hidpad/hidpad_wii.c b/apple/common/hidpad/hidpad_wii.c new file mode 100644 index 0000000000..5d54bd4860 --- /dev/null +++ b/apple/common/hidpad/hidpad_wii.c @@ -0,0 +1,113 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * 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 +#include + +#include "boolean.h" +#include "apple/common/rarch_wrapper.h" + +#include "wiimote.h" +#include "hidpad.h" + +static void* hidpad_wii_connect(struct hidpad_connection* connection, uint32_t slot) +{ + struct wiimote_t* device = malloc(sizeof(struct wiimote_t)); + memset(device, 0, sizeof(struct wiimote_t)); + + device->connection = connection; + device->unid = slot; + device->state = WIIMOTE_STATE_CONNECTED; + device->exp.type = EXP_NONE; + + wiimote_handshake(device, -1, NULL, -1); + + return device; +} + +static void hidpad_wii_disconnect(struct wiimote_t* device) +{ + free(device); +} + +static int16_t hidpad_wii_get_axis(struct wiimote_t* device, unsigned axis) +{ +/* TODO + if (device->.exp.type == EXP_CLASSIC) + { + switch (axis) + { + case 0: return device->wiimote.exp.classic.ljs.rx * 0x7FFF; + case 1: return device->wiimote.exp.classic.ljs.ry * 0x7FFF; + case 2: return device->wiimote.exp.classic.rjs.rx * 0x7FFF; + case 3: return device->wiimote.exp.classic.rjs.ry * 0x7FFF; + default: return 0; + } + } +*/ + + return 0; +} + +static void hidpad_wii_packet_handler(struct wiimote_t* device, uint8_t *packet, uint16_t size) +{ +#ifdef IOS + byte* msg = packet + 2; + switch (packet[1]) +#else + byte* msg = packet + 1; + switch (packet[0]) +#endif + { + case WM_RPT_BTN: + { + wiimote_pressed_buttons(device, msg); + break; + } + + case WM_RPT_READ: + { + wiimote_pressed_buttons(device, msg); + wiimote_handshake(device, WM_RPT_READ, msg + 5, ((msg[2] & 0xF0) >> 4) + 1); + break; + } + + case WM_RPT_CTRL_STATUS: + { + wiimote_pressed_buttons(device, msg); + wiimote_handshake(device,WM_RPT_CTRL_STATUS,msg,-1); + break; + } + + case WM_RPT_BTN_EXP: + { + wiimote_pressed_buttons(device, msg); + wiimote_handle_expansion(device, msg+2); + break; + } + } + + g_current_input_data.pad_buttons[device->unid] = device->btns | (device->exp.classic.btns << 16); + for (int i = 0; i < 4; i ++) + g_current_input_data.pad_axis[device->unid][i] = hidpad_wii_get_axis(device, i); +} + +struct hidpad_interface hidpad_wii = +{ + (void*)&hidpad_wii_connect, + (void*)&hidpad_wii_disconnect, + (void*)&hidpad_wii_packet_handler +}; diff --git a/apple/iOS/bluetooth/wiimote.c b/apple/common/hidpad/wiimote.c similarity index 99% rename from apple/iOS/bluetooth/wiimote.c rename to apple/common/hidpad/wiimote.c index c168ce2ca2..35dadfa65a 100644 --- a/apple/iOS/bluetooth/wiimote.c +++ b/apple/common/hidpad/wiimote.c @@ -45,8 +45,6 @@ #include #include "boolean.h" -#include "btdynamic.h" -#include "btstack/btstack.h" #include "wiimote.h" int wiimote_send(struct wiimote_t* wm, byte report_type, byte* msg, int len); @@ -360,7 +358,11 @@ int wiimote_send(struct wiimote_t* wm, byte report_type, byte* msg, int len) printf("\n"); #endif - bt_send_l2cap_ptr( wm->c_source_cid, buf, len+2); +#ifdef IOS + hidpad_send_control(wm->connection, buf, len + 2); +#else + hidpad_send_control(wm->connection, buf + 1, len + 1); +#endif return 1; } diff --git a/apple/iOS/bluetooth/wiimote.h b/apple/common/hidpad/wiimote.h similarity index 98% rename from apple/iOS/bluetooth/wiimote.h rename to apple/common/hidpad/wiimote.h index b6e46a0dd3..c2d985f52e 100644 --- a/apple/iOS/bluetooth/wiimote.h +++ b/apple/common/hidpad/wiimote.h @@ -41,7 +41,7 @@ #ifndef __WIIMOTE_H__ #define __WIIMOTE_H__ -#include "btstack/utils.h" +#include "hidpad.h" #if defined(__cplusplus) extern "C" { @@ -232,11 +232,7 @@ extern "C" { typedef struct wiimote_t { int unid; /**< user specified id */ - uint16_t wiiMoteConHandle; - uint16_t i_source_cid; - uint16_t c_source_cid; - bd_addr_t addr; - + struct hidpad_connection* connection; int state; /**< various state flags */ byte leds; /**< currently lit leds */ float battery_level; /**< battery level */ diff --git a/apple/common/setting_data.h b/apple/common/setting_data.h index 208fb8ea73..dc5fa2c39e 100644 --- a/apple/common/setting_data.h +++ b/apple/common/setting_data.h @@ -294,31 +294,31 @@ const rarch_setting_t setting_data[] = END_SUB_GROUP() START_SUB_GROUP("Player 1") - CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_B], 1, "b", "B button (down)") - CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_Y], 1, "y", "Y button (left)") - CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_SELECT],1, "select", "Select button") - CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_START], 1, "start", "Start button") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_UP], 1, "up", "Up D-pad") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_DOWN], 1, "down", "Down D-pad") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_LEFT], 1, "left", "Left D-pad") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_RIGHT], 1, "right", "Right D-pad") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_SELECT],1, "select", "Select button") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_START], 1, "start", "Start button") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_B], 1, "b", "B button (down)") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_A], 1, "a", "A button (right)") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_X], 1, "x", "X button (top)") + CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_Y], 1, "y", "Y button (left)") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L], 1, "l", "L button (left shoulder)") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R], 1, "r", "R button (right shoulder)") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L2], 1, "l2", "L2 button (left shoulder #2)") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R2], 1, "r2", "R2 button (right shoulder #2)") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L3], 1, "l3", "L3 button (left analog button)") CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R3], 1, "r3", "R3 button (right analog button)") - CONFIG_BIND(g_settings.input.binds[0][RARCH_TURBO_ENABLE], 1, "turbo", "Turbo enable") - CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_PLUS], 1, "l_x_plus", "Left analog X+ (right)") - CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_MINUS], 1, "l_x_minus", "Left analog X- (left)") - CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_Y_PLUS], 1, "l_y_plus", "Left analog Y+ (down)") CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_Y_MINUS], 1, "l_y_minus", "Left analog Y- (up)") - CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_PLUS], 1, "r_x_plus", "Right analog X+ (right)") - CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_MINUS], 1, "r_x_minus", "Right analog X- (left)") - CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_Y_PLUS], 1, "r_y_plus", "Right analog Y+ (down)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_Y_PLUS], 1, "l_y_plus", "Left analog Y+ (down)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_MINUS], 1, "l_x_minus", "Left analog X- (left)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_PLUS], 1, "l_x_plus", "Left analog X+ (right)") CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_Y_MINUS], 1, "r_y_minus", "Right analog Y- (up)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_Y_PLUS], 1, "r_y_plus", "Right analog Y+ (down)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_MINUS], 1, "r_x_minus", "Right analog X- (left)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_PLUS], 1, "r_x_plus", "Right analog X+ (right)") + CONFIG_BIND(g_settings.input.binds[0][RARCH_TURBO_ENABLE], 1, "turbo", "Turbo enable") END_SUB_GROUP() END_GROUP() diff --git a/apple/iOS/bluetooth/btpad.c b/apple/iOS/bluetooth/btpad.c index 0a6335df3e..abb6333ded 100644 --- a/apple/iOS/bluetooth/btpad.c +++ b/apple/iOS/bluetooth/btpad.c @@ -21,14 +21,38 @@ #include #include "apple/common/rarch_wrapper.h" +#include "apple/common/hidpad/hidpad.h" #include "btdynamic.h" #include "btpad.h" #include "btpad_queue.h" -#include "wiimote.h" -static btpad_connection_t btpad_connection[MAX_PADS]; -static struct btpad_interface* btpad_iface[MAX_PADS]; -static void* btpad_device[MAX_PADS]; +// Private interface +enum btpad_state { BTPAD_EMPTY, BTPAD_CONNECTING, BTPAD_CONNECTED }; + +struct hidpad_connection +{ + uint32_t slot; + + struct hidpad_interface* interface; + void* hidpad; + + enum btpad_state state; + + bool has_address; + bd_addr_t address; + + uint16_t handle; + uint16_t channels[2]; //0: Control, 1: Interrupt +}; + +static struct hidpad_connection g_connected_pads[MAX_PADS]; + +void hidpad_send_control(struct hidpad_connection* connection, uint8_t* data, size_t size) +{ + bt_send_l2cap_ptr(connection->channels[0], data, size); +} + + static bool inquiry_off; static bool inquiry_running; @@ -41,35 +65,18 @@ void btpad_set_inquiry_state(bool on) btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1); } -// MAIN THREAD ONLY -uint32_t btpad_get_buttons(uint32_t slot) -{ - if (slot < MAX_PADS && btpad_device[slot] && btpad_iface[slot]) - return btpad_iface[slot]->get_buttons(btpad_device[slot]); - - return 0; -} - -int16_t btpad_get_axis(uint32_t slot, unsigned axis) -{ - if (slot < MAX_PADS && btpad_device[slot] && btpad_iface[slot]) - return btpad_iface[slot]->get_axis(btpad_device[slot], axis); - - return 0; -} - // Internal interface: static int32_t btpad_find_slot_for(uint16_t handle, bd_addr_t address) { for (int i = 0; i < MAX_PADS; i ++) { - if (!btpad_connection[i].handle && !btpad_connection[i].has_address) + if (!g_connected_pads[i].handle && !g_connected_pads[i].has_address) continue; - if (handle && btpad_connection[i].handle && handle != btpad_connection[i].handle) + if (handle && g_connected_pads[i].handle && handle != g_connected_pads[i].handle) continue; - if (address && btpad_connection[i].has_address && (BD_ADDR_CMP(address, btpad_connection[i].address))) + if (address && g_connected_pads[i].has_address && (BD_ADDR_CMP(address, g_connected_pads[i].address))) continue; return i; @@ -81,7 +88,7 @@ static int32_t btpad_find_slot_for(uint16_t handle, bd_addr_t address) static int32_t btpad_find_slot_with_state(enum btpad_state state) { for (int i = 0; i < MAX_PADS; i ++) - if (btpad_connection[i].state == state) + if (g_connected_pads[i].state == state) return i; return -1; @@ -92,19 +99,16 @@ static void btpad_disconnect_pad(uint32_t slot) if (slot > MAX_PADS) return; - if (btpad_iface[slot] && btpad_device[slot]) + if (g_connected_pads[slot].interface && g_connected_pads[slot].hidpad) { ios_add_log_message("BTpad: Disconnecting slot %d", slot); - - btpad_iface[slot]->disconnect(btpad_device[slot]); - btpad_device[slot] = 0; - btpad_iface[slot] = 0; + g_connected_pads[slot].interface->disconnect(g_connected_pads[slot].hidpad); } - if (btpad_connection[slot].handle) - btpad_queue_hci_disconnect(btpad_connection[slot].handle, 0x15); + if (g_connected_pads[slot].handle) + btpad_queue_hci_disconnect(g_connected_pads[slot].handle, 0x15); - memset(&btpad_connection[slot], 0, sizeof(btpad_connection_t)); + memset(&g_connected_pads[slot], 0, sizeof(struct hidpad_connection)); } static void btpad_disconnect_all_pads() @@ -134,7 +138,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet btpad_queue_run(1); } - else if(packet[2] > HCI_STATE_WORKING && btpad_iface && btpad_device) + else if(packet[2] > HCI_STATE_WORKING) { btpad_disconnect_all_pads(); } @@ -171,14 +175,14 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet { ios_add_log_message("BTpad: Inquiry found device (Slot %d)", slot); - memcpy(btpad_connection[slot].address, event_addr, sizeof(bd_addr_t)); + memcpy(g_connected_pads[slot].address, event_addr, sizeof(bd_addr_t)); - btpad_connection[slot].has_address = true; - btpad_connection[slot].state = BTPAD_CONNECTING; - btpad_connection[slot].slot = slot; + g_connected_pads[slot].has_address = true; + g_connected_pads[slot].state = BTPAD_CONNECTING; + g_connected_pads[slot].slot = slot; - bt_send_cmd_ptr(l2cap_create_channel_ptr, btpad_connection[slot].address, PSM_HID_CONTROL); - bt_send_cmd_ptr(l2cap_create_channel_ptr, btpad_connection[slot].address, PSM_HID_INTERRUPT); + bt_send_cmd_ptr(l2cap_create_channel_ptr, g_connected_pads[slot].address, PSM_HID_CONTROL); + bt_send_cmd_ptr(l2cap_create_channel_ptr, g_connected_pads[slot].address, PSM_HID_INTERRUPT); } } } @@ -213,19 +217,19 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet } ios_add_log_message("BTpad: L2CAP channel opened: (Slot: %d, PSM: %02X)", slot, psm); - btpad_connection[slot].handle = handle; + g_connected_pads[slot].handle = handle; if (psm == PSM_HID_CONTROL) - btpad_connection[slot].channels[0] = channel_id; + g_connected_pads[slot].channels[0] = channel_id; else if (psm == PSM_HID_INTERRUPT) - btpad_connection[slot].channels[1] = channel_id; + g_connected_pads[slot].channels[1] = channel_id; else ios_add_log_message("BTpad: Got unknown L2CAP PSM, ignoring (Slot: %d, PSM: %02X)", slot, psm); - if (btpad_connection[slot].channels[0] && btpad_connection[slot].channels[1]) + if (g_connected_pads[slot].channels[0] && g_connected_pads[slot].channels[1]) { ios_add_log_message("BTpad: Got both L2CAP channels, requesting name (Slot: %d)", slot); - btpad_queue_hci_remote_name_request(btpad_connection[slot].address, 0, 0, 0); + btpad_queue_hci_remote_name_request(g_connected_pads[slot].address, 0, 0, 0); } } else @@ -249,12 +253,12 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet { ios_add_log_message("BTpad: Got new incoming connection (Slot: %d)", slot); - memcpy(btpad_connection[slot].address, event_addr, sizeof(bd_addr_t)); + memcpy(g_connected_pads[slot].address, event_addr, sizeof(bd_addr_t)); - btpad_connection[slot].has_address = true; - btpad_connection[slot].handle = handle; - btpad_connection[slot].state = BTPAD_CONNECTING; - btpad_connection[slot].slot = slot; + g_connected_pads[slot].has_address = true; + g_connected_pads[slot].handle = handle; + g_connected_pads[slot].state = BTPAD_CONNECTING; + g_connected_pads[slot].slot = slot; } else break; } @@ -277,14 +281,14 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet ios_add_log_message("BTpad: Got %.200s (Slot: %d)", (char*)&packet[9], slot); if (strncmp((char*)&packet[9], "PLAYSTATION(R)3 Controller", 26) == 0) - btpad_iface[slot] = &btpad_ps3; + g_connected_pads[slot].interface = &hidpad_ps3; else if (strncmp((char*)&packet[9], "Nintendo RVL-CNT-01", 19) == 0) - btpad_iface[slot] = &btpad_wii; + g_connected_pads[slot].interface = &hidpad_wii; - if (btpad_iface[slot]) + if (g_connected_pads[slot].interface) { - btpad_device[slot] = btpad_iface[slot]->connect(&btpad_connection[slot]); - btpad_connection[slot].state = BTPAD_CONNECTED; + g_connected_pads[slot].hidpad = g_connected_pads[slot].interface->connect(&g_connected_pads[slot], slot); + g_connected_pads[slot].state = BTPAD_CONNECTED; } } break; @@ -307,7 +311,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet const int32_t slot = btpad_find_slot_for(handle, 0); if (slot >= 0) { - btpad_connection[slot].handle = 0; + g_connected_pads[slot].handle = 0; btpad_disconnect_pad(slot); ios_add_log_message("BTpad: Device disconnected (Slot: %d)", slot); @@ -326,8 +330,14 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet break; } } - - for (int i = 0; i < MAX_PADS; i ++) - if (btpad_device[i] && btpad_iface[i] && (btpad_connection[i].channels[0] == channel || btpad_connection[i].channels[1] == channel)) - btpad_iface[i]->packet_handler(btpad_device[i], packet_type, channel, packet, size); + else if (packet_type == L2CAP_DATA_PACKET) + { + for (int i = 0; i < MAX_PADS; i ++) + { + struct hidpad_connection* connection = &g_connected_pads[i]; + + if (connection->hidpad && connection->interface && (connection->channels[0] == channel || connection->channels[1] == channel)) + connection->interface->packet_handler(connection->hidpad, packet, size); + } + } } diff --git a/apple/iOS/bluetooth/btpad.h b/apple/iOS/bluetooth/btpad.h index 0bc70d060e..cf92d40ba7 100644 --- a/apple/iOS/bluetooth/btpad.h +++ b/apple/iOS/bluetooth/btpad.h @@ -20,39 +20,4 @@ void btpad_set_inquiry_state(bool on); -uint32_t btpad_get_buttons(uint32_t slot); -int16_t btpad_get_axis(uint32_t slot, unsigned axis); - -// Private interface -enum btpad_state { BTPAD_EMPTY, BTPAD_CONNECTING, BTPAD_CONNECTED }; - -typedef struct -{ - enum btpad_state state; - - uint32_t slot; - uint16_t handle; - - bool has_address; - bd_addr_t address; - - uint16_t channels[2]; //0: Control, 1: Interrupt - - bool connected; -} btpad_connection_t; - -struct btpad_interface -{ - void* (*connect)(const btpad_connection_t* connection); - void (*disconnect)(void* device); - - uint32_t (*get_buttons)(void* device); - int16_t (*get_axis)(void* device, unsigned axis); - - void (*packet_handler)(void* device, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); -}; - -extern struct btpad_interface btpad_ps3; -extern struct btpad_interface btpad_wii; - #endif diff --git a/apple/iOS/bluetooth/btpad_wii.c b/apple/iOS/bluetooth/btpad_wii.c deleted file mode 100644 index c8475fb4ab..0000000000 --- a/apple/iOS/bluetooth/btpad_wii.c +++ /dev/null @@ -1,123 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2013 - Jason Fetters - * - * 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 -#include - -#include "boolean.h" -#include "apple/common/rarch_wrapper.h" - -#include "btdynamic.h" -#include "btpad.h" -#include "wiimote.h" - -static void* btpad_wii_connect(const btpad_connection_t* connection) -{ - struct wiimote_t* device = malloc(sizeof(struct wiimote_t)); - memset(device, 0, sizeof(struct wiimote_t)); - - memcpy(device->addr, connection->address, BD_ADDR_LEN); - - device->unid = connection->slot; - device->wiiMoteConHandle = connection->handle; - device->c_source_cid = connection->channels[0]; - device->i_source_cid = connection->channels[1]; - device->state = WIIMOTE_STATE_CONNECTED; - device->exp.type = EXP_NONE; - - wiimote_handshake(device, -1, NULL, -1); - - return device; -} - -static void btpad_wii_disconnect(struct wiimote_t* device) -{ -} - -static uint32_t btpad_wii_get_buttons(struct wiimote_t* device) -{ - return device->btns | (device->exp.classic.btns << 16); -} - -static int16_t btpad_wii_get_axis(struct wiimote_t* device, unsigned axis) -{ -/* TODO - if (device->.exp.type == EXP_CLASSIC) - { - switch (axis) - { - case 0: return device->wiimote.exp.classic.ljs.rx * 0x7FFF; - case 1: return device->wiimote.exp.classic.ljs.ry * 0x7FFF; - case 2: return device->wiimote.exp.classic.rjs.rx * 0x7FFF; - case 3: return device->wiimote.exp.classic.rjs.ry * 0x7FFF; - default: return 0; - } - } -*/ - - return 0; -} - -static void btpad_wii_packet_handler(struct wiimote_t* device, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) -{ - if(packet_type == L2CAP_DATA_PACKET) - { - byte* msg = packet + 2; - - switch (packet[1]) - { - case WM_RPT_BTN: - { - wiimote_pressed_buttons(device, msg); - break; - } - - case WM_RPT_READ: - { - wiimote_pressed_buttons(device, msg); - wiimote_handshake(device, WM_RPT_READ, msg + 5, ((msg[2] & 0xF0) >> 4) + 1); - break; - } - - case WM_RPT_CTRL_STATUS: - { - wiimote_pressed_buttons(device, msg); - wiimote_handshake(device,WM_RPT_CTRL_STATUS,msg,-1); - break; - } - - case WM_RPT_BTN_EXP: - { - wiimote_pressed_buttons(device, msg); - wiimote_handle_expansion(device, msg+2); - break; - } - } - - g_current_input_data.pad_buttons[device->unid] = btpad_wii_get_buttons(device); - for (int i = 0; i < 4; i ++) - g_current_input_data.pad_axis[device->unid][i] = btpad_wii_get_axis(device, i); - } -} - -struct btpad_interface btpad_wii = -{ - (void*)&btpad_wii_connect, - (void*)&btpad_wii_disconnect, - (void*)&btpad_wii_get_buttons, - (void*)&btpad_wii_get_axis, - (void*)&btpad_wii_packet_handler -}; From 52d62741a9494d263713a7b00c66d7f21c0af960 Mon Sep 17 00:00:00 2001 From: meancoot Date: Wed, 11 Sep 2013 19:22:12 -0400 Subject: [PATCH 187/202] (OSX) Fix build --- apple/OSX/hid_pad.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apple/OSX/hid_pad.c b/apple/OSX/hid_pad.c index 47085a2873..4d0b50eb66 100644 --- a/apple/OSX/hid_pad.c +++ b/apple/OSX/hid_pad.c @@ -17,10 +17,6 @@ #include "apple/common/apple_input.h" #include "apple/common/hidpad/hidpad.h" -#include "apple/common/hidpad/hidpad_ps3.c" -#include "apple/common/hidpad/hidpad_wii.c" -#include "apple/common/hidpad/wiimote.c" - struct hidpad_connection { uint32_t slot; From 847f7f8d05d2f49a3c1b6549b77b836827a92a1a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 12 Sep 2013 20:02:36 +0200 Subject: [PATCH 188/202] (Android Phoenix) Set video_threaded to false and set refresh rate of 59.19Hz for Xperia Play --- .../phoenix/src/org/retroarch/browser/MainMenuActivity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index b0e81963ab..e3a42d0064 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -741,10 +741,13 @@ public class MainMenuActivity extends PreferenceActivity { SharedPreferences prefs = getPreferences(); SharedPreferences.Editor edit = prefs .edit(); + edit.putBoolean("video_threaded", false); edit.putBoolean("input_overlay_enable", false); edit.putBoolean("input_autodetect_enable", true); + edit.putString("video_refresh_rate", Double + .valueOf(59.19132938771038).toString()); edit.commit(); } }); From 04a1b4b6528aaa4a66c2b56f89ec360faa9a919a Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 12 Sep 2013 22:00:59 +0200 Subject: [PATCH 189/202] Add Core Directory option to RGUI. Also clean up some useless branches to ternaries. --- frontend/menu/menu_common.h | 1 + frontend/menu/rgui.c | 58 +++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 4b465bd718..efa08046f0 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -162,6 +162,7 @@ typedef enum RGUI_SHADER_DIR_PATH, RGUI_SAVESTATE_DIR_PATH, RGUI_SAVEFILE_DIR_PATH, + RGUI_LIBRETRO_DIR_PATH, #ifdef HAVE_OVERLAY RGUI_OVERLAY_DIR_PATH, #endif diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 754d24b63e..8357f27774 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -215,6 +215,7 @@ static bool menu_type_is_directory_browser(unsigned type) type == RGUI_SHADER_DIR_PATH || #endif type == RGUI_SAVESTATE_DIR_PATH || + type == RGUI_LIBRETRO_DIR_PATH || type == RGUI_SAVEFILE_DIR_PATH || #ifdef HAVE_OVERLAY type == RGUI_OVERLAY_DIR_PATH || @@ -471,6 +472,8 @@ static void render_text(rgui_handle_t *rgui) snprintf(title, sizeof(title), "SHADER DIR %s", dir); else if (menu_type == RGUI_SAVESTATE_DIR_PATH) snprintf(title, sizeof(title), "SAVESTATE DIR %s", dir); + else if (menu_type == RGUI_LIBRETRO_DIR_PATH) + snprintf(title, sizeof(title), "LIBRETRO DIR %s", dir); else if (menu_type == RGUI_SAVEFILE_DIR_PATH) snprintf(title, sizeof(title), "SAVEFILE DIR %s", dir); #ifdef HAVE_OVERLAY @@ -652,10 +655,7 @@ static void render_text(rgui_handle_t *rgui) w = 5; break; case RGUI_SETTINGS_REWIND_ENABLE: - if (g_settings.rewind_enable) - strlcpy(type_str, "ON", sizeof(type_str)); - else - strlcpy(type_str, "OFF", sizeof(type_str)); + strlcpy(type_str, g_settings.rewind_enable ? "ON" : "OFF", sizeof(type_str)); break; case RGUI_SETTINGS_REWIND_GRANULARITY: snprintf(type_str, sizeof(type_str), "%u", g_settings.rewind_granularity); @@ -671,10 +671,7 @@ static void render_text(rgui_handle_t *rgui) snprintf(type_str, sizeof(type_str), "%d", g_extern.state_slot); break; case RGUI_SETTINGS_AUDIO_MUTE: - if (g_extern.audio_data.mute) - strlcpy(type_str, "ON", sizeof(type_str)); - else - strlcpy(type_str, "OFF", sizeof(type_str)); + strlcpy(type_str, g_extern.audio_data.mute ? "ON" : "OFF", sizeof(type_str)); break; case RGUI_SETTINGS_AUDIO_CONTROL_RATE_DELTA: snprintf(type_str, sizeof(type_str), "%.3f", g_settings.audio.rate_control_delta); @@ -683,42 +680,27 @@ static void render_text(rgui_handle_t *rgui) snprintf(type_str, sizeof(type_str), (g_extern.lifecycle_mode_state & (1ULL << MODE_FPS_DRAW)) ? "ON" : "OFF"); break; case RGUI_BROWSER_DIR_PATH: - if (*g_settings.rgui_browser_directory) - strlcpy(type_str, g_settings.rgui_browser_directory, sizeof(type_str)); - else - strlcpy(type_str, "", sizeof(type_str)); + strlcpy(type_str, *g_settings.rgui_browser_directory ? g_settings.rgui_browser_directory : "", sizeof(type_str)); break; case RGUI_SAVEFILE_DIR_PATH: - if (*g_extern.savefile_dir) - strlcpy(type_str, g_extern.savefile_dir, sizeof(type_str)); - else - strlcpy(type_str, "", sizeof(type_str)); + strlcpy(type_str, *g_extern.savefile_dir ? g_extern.savefile_dir : "", sizeof(type_str)); break; #ifdef HAVE_OVERLAY case RGUI_OVERLAY_DIR_PATH: - if (*g_extern.overlay_dir) - strlcpy(type_str, g_extern.overlay_dir, sizeof(type_str)); - else - strlcpy(type_str, "", sizeof(type_str)); + strlcpy(type_str, *g_extern.overlay_dir ? g_extern.overlay_dir : "", sizeof(type_str)); break; #endif case RGUI_SAVESTATE_DIR_PATH: - if (*g_extern.savestate_dir) - strlcpy(type_str, g_extern.savestate_dir, sizeof(type_str)); - else - strlcpy(type_str, "", sizeof(type_str)); + strlcpy(type_str, *g_extern.savestate_dir ? g_extern.savestate_dir : "", sizeof(type_str)); + break; + case RGUI_LIBRETRO_DIR_PATH: + strlcpy(type_str, *rgui->libretro_dir ? rgui->libretro_dir : "", sizeof(type_str)); break; case RGUI_SHADER_DIR_PATH: - if (*g_settings.video.shader_dir) - strlcpy(type_str, g_settings.video.shader_dir, sizeof(type_str)); - else - strlcpy(type_str, "", sizeof(type_str)); + strlcpy(type_str, *g_settings.video.shader_dir ? g_settings.video.shader_dir : "", sizeof(type_str)); break; case RGUI_SYSTEM_DIR_PATH: - if (*g_settings.system_directory) - strlcpy(type_str, g_settings.system_directory, sizeof(type_str)); - else - strlcpy(type_str, "", sizeof(type_str)); + strlcpy(type_str, *g_settings.system_directory ? g_settings.system_directory : "", sizeof(type_str)); break; case RGUI_SETTINGS_DISK_INDEX: { @@ -1408,6 +1390,10 @@ static int rgui_settings_toggle_setting(rgui_handle_t *rgui, unsigned setting, r if (action == RGUI_ACTION_START) *g_extern.savestate_dir = '\0'; break; + case RGUI_LIBRETRO_DIR_PATH: + if (action == RGUI_ACTION_START) + *rgui->libretro_dir = '\0'; + break; case RGUI_SHADER_DIR_PATH: if (action == RGUI_ACTION_START) *g_settings.video.shader_dir = '\0'; @@ -2119,6 +2105,9 @@ static void rgui_settings_path_populate_entries(rgui_handle_t *rgui) { rgui_list_clear(rgui->selection_buf); rgui_list_push(rgui->selection_buf, "Browser Directory", RGUI_BROWSER_DIR_PATH, 0); +#ifdef HAVE_DYNAMIC + rgui_list_push(rgui->selection_buf, "Core Directory", RGUI_LIBRETRO_DIR_PATH, 0); +#endif #ifdef HAVE_SHADER_MANAGER rgui_list_push(rgui->selection_buf, "Shader Directory", RGUI_SHADER_DIR_PATH, 0); #endif @@ -2842,6 +2831,11 @@ int rgui_iterate(rgui_handle_t *rgui) strlcpy(g_extern.savestate_dir, dir, sizeof(g_extern.savestate_dir)); rgui_flush_menu_stack_type(rgui, RGUI_SETTINGS_PATH_OPTIONS); } + else if (menu_type == RGUI_LIBRETRO_DIR_PATH) + { + strlcpy(rgui->libretro_dir, dir, sizeof(g_extern.savestate_dir)); + rgui_flush_menu_stack_type(rgui, RGUI_SETTINGS_PATH_OPTIONS); + } else if (menu_type == RGUI_SHADER_DIR_PATH) { strlcpy(g_settings.video.shader_dir, dir, sizeof(g_settings.video.shader_dir)); From 178dc692c7ccb640090c813ce0ed78e07eec28e1 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 12 Sep 2013 22:23:56 +0200 Subject: [PATCH 190/202] Do proper rounding in set_viewport. Avoids edge cases where viewport sizes are miscalculated with -1 pixel due to rounding errors. --- gfx/d3d9/d3d9.cpp | 10 +++++----- gfx/gl.c | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gfx/d3d9/d3d9.cpp b/gfx/d3d9/d3d9.cpp index a59aa5647c..608a676dba 100644 --- a/gfx/d3d9/d3d9.cpp +++ b/gfx/d3d9/d3d9.cpp @@ -363,17 +363,17 @@ void D3DVideo::calculate_rect(unsigned width, unsigned height, else { float device_aspect = static_cast(width) / static_cast(height); - if (fabs(device_aspect - desired_aspect) < 0.0001) + if (fabsf(device_aspect - desired_aspect) < 0.0001f) set_viewport(0, 0, width, height); else if (device_aspect > desired_aspect) { - float delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5; - set_viewport(width * (0.5 - delta), 0, 2.0 * width * delta, height); + float delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; + set_viewport(int(roundf(width * (0.5f - delta))), 0, unsigned(roundf(2.0f * width * delta)), height); } else { - float delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5; - set_viewport(0, height * (0.5 - delta), width, 2.0 * height * delta); + float delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; + set_viewport(0, int(roundf(height * (0.5f - delta))), width, unsigned(roundf(2.0f * height * delta))); } } } diff --git a/gfx/gl.c b/gfx/gl.c index 0a0e03887f..bc55404724 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -783,22 +783,22 @@ void gl_set_viewport(void *data, unsigned width, unsigned height, bool force_ful else #endif { - if (fabs(device_aspect - desired_aspect) < 0.0001) + if (fabsf(device_aspect - desired_aspect) < 0.0001f) { // If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff), // assume they are actually equal. } else if (device_aspect > desired_aspect) { - delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5; - x = (unsigned)(width * (0.5 - delta)); - width = (unsigned)(2.0 * width * delta); + delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; + x = (int)roundf(width * (0.5f - delta)); + width = (unsigned)roundf(2.0f * width * delta); } else { - delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5; - y = (unsigned)(height * (0.5 - delta)); - height = (unsigned)(2.0 * height * delta); + delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; + y = (int)roundf(height * (0.5f - delta)); + height = (unsigned)roundf(2.0f * height * delta); } } From 3e7f1011375b5ab26f052336be3be910ec7277c3 Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 12 Sep 2013 22:40:11 +0200 Subject: [PATCH 191/202] Make sure we're reading from backbuffer. --- gfx/gl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gfx/gl.c b/gfx/gl.c index bc55404724..e9975a7589 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -2291,6 +2291,12 @@ static bool gl_read_viewport(void *data, uint8_t *buffer) RARCH_PERFORMANCE_INIT(read_viewport); RARCH_PERFORMANCE_START(read_viewport); +#ifdef HAVE_FBO + // Make sure we're reading from backbuffer incase some state has been overridden. + if (gl->hw_render_fbo_init || gl->fbo_inited) + gl_bind_backbuffer(); +#endif + #ifdef HAVE_OPENGLES glPixelStorei(GL_PACK_ALIGNMENT, get_alignment(gl->vp.width * 3)); // GLES doesn't support glReadBuffer ... Take a chance that it'll work out right. From d92fb6ac9c631804dfdb1416efb94bc917c5ffda Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 12 Sep 2013 18:42:39 -0400 Subject: [PATCH 192/202] (OSX) Now when video_monitor_index is out of range a warning is logged and the main screen is used instead. Previously a modal error was displayed and retroarch would exit when it was dismissed. --- apple/OSX/settings.m | 4 ---- apple/common/RAGameView.m | 17 ++++++++--------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/apple/OSX/settings.m b/apple/OSX/settings.m index 66ce2bf1cd..51226fee4b 100644 --- a/apple/OSX/settings.m +++ b/apple/OSX/settings.m @@ -268,10 +268,6 @@ static const char* get_axis_name(const rarch_setting_t* setting) @end -@protocol RASettingView -@property const rarch_setting_t* setting; -@end - @interface RASettingsDelegate : NSObject diff --git a/apple/common/RAGameView.m b/apple/common/RAGameView.m index 8fec390435..30a4e01d0e 100644 --- a/apple/common/RAGameView.m +++ b/apple/common/RAGameView.m @@ -344,8 +344,6 @@ bool apple_game_view_has_focus(void) bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) { - __block bool result = true; - #ifdef OSX dispatch_sync(dispatch_get_main_queue(), ^{ @@ -353,14 +351,15 @@ bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) if (fullscreen && !g_has_went_fullscreen) { - if (g_settings.video.monitor_index >= [NSScreen screens].count) + unsigned monitor = g_settings.video.monitor_index; + + if (monitor >= [NSScreen screens].count) { - apple_display_alert(@"Could not go fullscreen: Monitor index out of range.", nil); - result = false; - return; + RARCH_WARN("video_monitor_index is greater than the number of connected monitors; using main screen instead.\n"); + monitor = 0; } - - [g_view enterFullScreenMode:[NSScreen screens][g_settings.video.monitor_index] withOptions:nil]; + + [g_view enterFullScreenMode:[NSScreen screens][monitor] withOptions:nil]; [NSCursor hide]; } else if (!fullscreen && g_has_went_fullscreen) @@ -378,7 +377,7 @@ bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) // TODO: Maybe iOS users should be apple to show/hide the status bar here? - return result; + return true; } #ifdef IOS From 9a2a7854ea601ae042f8a0e3e595ddc0529dcc71 Mon Sep 17 00:00:00 2001 From: meancoot Date: Thu, 12 Sep 2013 22:12:51 -0400 Subject: [PATCH 193/202] (OSX) Disable two warnings (shorten-64-to-32 and constant-conversion) that together accounted for over 100 warning messages. Mostly caused by mixing size_t and 'unsigned' types. --- apple/RetroArch_OSX.xcodeproj/project.pbxproj | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/apple/RetroArch_OSX.xcodeproj/project.pbxproj b/apple/RetroArch_OSX.xcodeproj/project.pbxproj index c70055652d..11fc233503 100644 --- a/apple/RetroArch_OSX.xcodeproj/project.pbxproj +++ b/apple/RetroArch_OSX.xcodeproj/project.pbxproj @@ -38,8 +38,8 @@ 96355CE71788E72A0010DBFA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 9646869617BBC14E00C5EA69 /* platform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = platform.m; path = OSX/platform.m; sourceTree = SOURCE_ROOT; }; 9646869717BBC14E00C5EA69 /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = platform.h; path = OSX/platform.h; sourceTree = SOURCE_ROOT; }; - 964DE7C217D84B34001CBB6C /* en */ = {isa = PBXFileReference; lastKnownFileType = file; name = en; path = en.lproj/InputBinder.xib; sourceTree = ""; }; - 964DE7C517D84B57001CBB6C /* en */ = {isa = PBXFileReference; lastKnownFileType = file; name = en; path = en.lproj/Settings.xib; sourceTree = ""; }; + 964DE7C217D84B34001CBB6C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/InputBinder.xib; sourceTree = ""; }; + 964DE7C517D84B57001CBB6C /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Settings.xib; sourceTree = ""; }; 9678948D1788ECCA00D6CA69 /* RetroArch-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "RetroArch-Info.plist"; path = "OSX/RetroArch-Info.plist"; sourceTree = SOURCE_ROOT; }; 967894901788ECDB00D6CA69 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = OSX/en.lproj/InfoPlist.strings; sourceTree = SOURCE_ROOT; }; 967894921788ECDB00D6CA69 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = OSX/en.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; }; @@ -290,7 +290,6 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -306,7 +305,6 @@ "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; @@ -348,7 +346,6 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; @@ -358,7 +355,6 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; From e6f527e992ce5e248f274ea4863fec8d8ad20d37 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 13 Sep 2013 15:17:09 +0200 Subject: [PATCH 194/202] (Android Phoenix) Add ability to set automatic audio latency option on/off --- android/phoenix/res/xml/prefs.xml | 6 ++++++ .../phoenix/src/org/retroarch/browser/MainMenuActivity.java | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index 94c6e5b452..7be204e611 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -120,6 +120,12 @@ android:summary="Use (very) high latency audio. Necessary for older Android devices with poor audio drivers." android:title="High latency audio" android:dependency="audio_enable" /> + diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index e3a42d0064..710f799649 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -359,7 +359,8 @@ public class MainMenuActivity extends PreferenceActivity { config.setInt("audio_out_rate", optimalRate); // Refactor this entire mess and make this usable for per-core config - if (android.os.Build.VERSION.SDK_INT >= 17) { + if (android.os.Build.VERSION.SDK_INT >= 17 && + prefs.getBoolean("audio_latency_auto", true) == true) { int buffersize = getLowLatencyBufferSize(); boolean lowLatency = hasLowLatencyAudio(); From 0245f926d12174261a77dd8fba9636ad2382251c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 13 Sep 2013 15:57:13 +0200 Subject: [PATCH 195/202] (Android Phoenix) Set configurable audio latency --- android/phoenix/res/values/array.xml | 12 ++++++++ android/phoenix/res/xml/prefs.xml | 12 ++++---- .../retroarch/browser/MainMenuActivity.java | 28 ++++++++++++++----- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/android/phoenix/res/values/array.xml b/android/phoenix/res/values/array.xml index 823710ca5f..6fc8d82643 100644 --- a/android/phoenix/res/values/array.xml +++ b/android/phoenix/res/values/array.xml @@ -10,6 +10,18 @@ 1 + + 64ms (Low) + 128ms (Medium) + 160ms (High) + + + + 64 + 128 + 160 + + Full screen Auto diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index 7be204e611..91a0b3c118 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -114,11 +114,13 @@ android:summary="Enable dynamic rate control (recommended)." android:title="Dynamic Rate Control" android:dependency="audio_enable" /> - Date: Fri, 13 Sep 2013 16:22:04 -0400 Subject: [PATCH 196/202] (OSX/iOS) Refactor RAGameView.m to be more straightforward. --- apple/common/RAGameView.m | 268 +++++++++++++++++++---------------- apple/common/rarch_wrapper.h | 21 +-- gfx/context/apple_gl_ctx.c | 41 ++---- 3 files changed, 168 insertions(+), 162 deletions(-) diff --git a/apple/common/RAGameView.m b/apple/common/RAGameView.m index 30a4e01d0e..0527bf565c 100644 --- a/apple/common/RAGameView.m +++ b/apple/common/RAGameView.m @@ -18,15 +18,47 @@ #include "general.h" #include "gfx/gfx_common.h" +#include "gfx/gfx_context.h" + +// Define compatibility symbols and categories +#ifdef IOS +#define APP_HAS_FOCUS ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) + +#define GLContextClass EAGLContext +#define GLAPIType GFX_CTX_OPENGL_ES_API +#define GLFrameworkID CFSTR("com.apple.opengles") +#define RAScreen UIScreen + +@interface EAGLContext (OSXCompat) @end +@implementation EAGLContext (OSXCompat) ++ (void)clearCurrentContext { EAGLContext.currentContext = nil; } +- (void)makeCurrentContext { EAGLContext.currentContext = self; } +@end + +#elif defined(OSX) +#define APP_HAS_FOCUS ([NSApp isActive]) + +#define GLContextClass NSOpenGLContext +#define GLAPIType GFX_CTX_OPENGL_API +#define GLFrameworkID CFSTR("com.apple.opengl") +#define RAScreen NSScreen + +#define g_view g_instance // < RAGameView is a container on iOS; on OSX these are both the same object + +@interface NSScreen (IOSCompat) @end +@implementation NSScreen (IOSCompat) +- (CGRect)bounds { return CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)); } +- (float) scale { return 1.0f; } +@end + +#endif + #ifdef IOS #import "views.h" - static const float ALMOST_INVISIBLE = .021f; -static RAGameView* g_instance; static GLKView* g_view; -static EAGLContext* g_context; static UIView* g_pause_view; static UIView* g_pause_indicator_view; @@ -35,17 +67,18 @@ static UIView* g_pause_indicator_view; #include "apple_input.h" static bool g_has_went_fullscreen; -static RAGameView* g_instance; -static NSOpenGLContext* g_context; static NSOpenGLPixelFormat* g_format; -#define g_view g_instance // < RAGameView is a container on iOS; on OSX these are both the same object - #endif + +static bool g_initialized; +static RAGameView* g_instance; +static GLContextClass* g_context; + static int g_fast_forward_skips; static bool g_is_syncing = true; -static float g_screen_scale = 1.0f; + @implementation RAGameView + (RAGameView*)get @@ -78,11 +111,6 @@ static float g_screen_scale = 1.0f; [g_context flushBuffer]; } -- (void)bindDrawable -{ - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - // Stop the annoying sound when pressing a key - (BOOL)acceptsFirstResponder { @@ -121,8 +149,6 @@ static float g_screen_scale = 1.0f; { self = [super init]; - g_screen_scale = [[UIScreen mainScreen] scale]; - UINib* xib = [UINib nibWithNibName:@"PauseView" bundle:nil]; g_pause_view = [[xib instantiateWithOwner:[RetroArch_iOS get] options:nil] lastObject]; @@ -193,57 +219,67 @@ static float g_screen_scale = 1.0f; @end -// Realistically these functions don't create or destroy the view; just the OpenGL context. -bool apple_init_game_view() +static RAScreen* get_chosen_screen() { -#ifdef IOS - dispatch_sync(dispatch_get_main_queue(), ^{ - // Make sure the view was created - [RAGameView get]; + unsigned monitor = g_settings.video.monitor_index; + + if (monitor >= RAScreen.screens.count) + { + RARCH_WARN("video_monitor_index is greater than the number of connected monitors; using main screen instead.\n"); + return RAScreen.mainScreen; + } + + return RAScreen.screens[monitor]; +} - g_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - [EAGLContext setCurrentContext:g_context]; - g_view.context = g_context; +bool apple_gfx_ctx_init() +{ + dispatch_sync(dispatch_get_main_queue(), + ^{ + // Make sure the view was created + [RAGameView get]; - // Show pause button for a few seconds, so people know it's there +#ifdef IOS // Show pause button for a few seconds, so people know it's there g_pause_indicator_view.alpha = 1.0f; [NSObject cancelPreviousPerformRequestsWithTarget:g_instance]; [g_instance performSelector:@selector(hidePauseButton) withObject:g_instance afterDelay:3.0f]; +#endif }); - [EAGLContext setCurrentContext:g_context]; -#else - [g_context makeCurrentContext]; -#endif + g_initialized = true; + return true; } -void apple_destroy_game_view() +void apple_gfx_ctx_destroy() { - dispatch_sync(dispatch_get_main_queue(), ^{ - glFinish(); - + g_initialized = false; + + [GLContextClass clearCurrentContext]; + + dispatch_sync(dispatch_get_main_queue(), + ^{ #ifdef IOS g_view.context = nil; - [EAGLContext setCurrentContext:nil]; +#endif + [GLContextClass clearCurrentContext]; g_context = nil; -#endif }); - -#ifdef IOS - [EAGLContext setCurrentContext:nil]; -#else - [NSOpenGLContext clearCurrentContext]; -#endif } -bool apple_create_gl_context(uint32_t version) +bool apple_gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor) { -#ifdef OSX - [NSOpenGLContext clearCurrentContext]; + if (api != GLAPIType) + return false; + + + [GLContextClass clearCurrentContext]; + + dispatch_sync(dispatch_get_main_queue(), + ^{ + [GLContextClass clearCurrentContext]; - dispatch_sync(dispatch_get_main_queue(), ^{ - [NSOpenGLContext clearCurrentContext]; +#ifdef OSX [g_context clearDrawable]; g_context = nil; g_format = nil; @@ -251,38 +287,29 @@ bool apple_create_gl_context(uint32_t version) NSOpenGLPixelFormatAttribute attributes [] = { NSOpenGLPFADoubleBuffer, // double buffered NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)16, // 16 bit depth buffer - version ? NSOpenGLPFAOpenGLProfile : 0, version, + (major || minor) ? NSOpenGLPFAOpenGLProfile : 0, (major << 12) | (minor << 8), (NSOpenGLPixelFormatAttribute)nil }; g_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; g_context = [[NSOpenGLContext alloc] initWithFormat:g_format shareContext:nil]; g_context.view = g_view; +#else + g_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + g_view.context = g_context; +#endif + [g_context makeCurrentContext]; }); [g_context makeCurrentContext]; - -#endif - return true; - } -void apple_flip_game_view() -{ - if (--g_fast_forward_skips < 0) - { - dispatch_sync(dispatch_get_main_queue(), ^{ - [g_view display]; - }); - g_fast_forward_skips = g_is_syncing ? 0 : 3; - } -} - -void apple_set_game_view_sync(unsigned interval) +void apple_gfx_ctx_swap_interval(unsigned interval) { #ifdef IOS // < No way to disable Vsync on iOS? + // Just skip presents so fast forward still works. g_is_syncing = interval ? true : false; g_fast_forward_skips = interval ? 0 : 3; #elif defined(OSX) @@ -291,58 +318,7 @@ void apple_set_game_view_sync(unsigned interval) #endif } -void apple_get_game_view_size(unsigned *width, unsigned *height) -{ - *width = g_view.bounds.size.width * g_screen_scale; - *width = *width ? *width : 640; - - *height = g_view.bounds.size.height * g_screen_scale; - *height = *height ? *height : 480; -} - -void *apple_get_proc_address(const char *symbol_name) -{ -#ifdef IOS - (void)symbol_name; // We don't need symbols above GLES2 on iOS. - return NULL; -#else - CFStringRef symbol = CFStringCreateWithCString(kCFAllocatorDefault, symbol_name, kCFStringEncodingASCII); - void *proc = CFBundleGetFunctionPointerForName(CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")), - symbol); - CFRelease(symbol); - return proc; -#endif -} - -void apple_update_window_title(void) -{ - static char buf[128]; - bool got_text = gfx_get_fps(buf, sizeof(buf), false); -#ifdef OSX - static const char* const text = buf; // < Can't access buf directly in the block - - if (got_text) - { - // NOTE: This could go bad if buf is updated again before this completes. - // If it poses a problem it should be changed to dispatch_sync. - dispatch_async(dispatch_get_main_queue(), ^ - { - g_view.window.title = @(text); - }); - } -#endif -} - -bool apple_game_view_has_focus(void) -{ -#ifdef OSX - return [NSApp isActive]; -#else - return true; -#endif -} - -bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) +bool apple_gfx_ctx_set_video_mode(unsigned width, unsigned height, bool fullscreen) { #ifdef OSX dispatch_sync(dispatch_get_main_queue(), @@ -351,15 +327,7 @@ bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) if (fullscreen && !g_has_went_fullscreen) { - unsigned monitor = g_settings.video.monitor_index; - - if (monitor >= [NSScreen screens].count) - { - RARCH_WARN("video_monitor_index is greater than the number of connected monitors; using main screen instead.\n"); - monitor = 0; - } - - [g_view enterFullScreenMode:[NSScreen screens][monitor] withOptions:nil]; + [g_view enterFullScreenMode:get_chosen_screen() withOptions:nil]; [NSCursor hide]; } else if (!fullscreen && g_has_went_fullscreen) @@ -380,6 +348,58 @@ bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen) return true; } +void apple_gfx_ctx_get_video_size(unsigned* width, unsigned* height) +{ + RAScreen* screen = get_chosen_screen(); + CGRect size = g_initialized ? g_view.bounds : screen.bounds; + + *width = CGRectGetWidth(size) * screen.scale; + *height = CGRectGetHeight(size) * screen.scale; +} + +void apple_gfx_ctx_update_window_title(void) +{ +#ifdef OSX + static char buf[128]; + bool got_text = gfx_get_fps(buf, sizeof(buf), false); + static const char* const text = buf; // < Can't access buf directly in the block + + if (got_text) + { + // NOTE: This could go bad if buf is updated again before this completes. + // If it poses a problem it should be changed to dispatch_sync. + dispatch_async(dispatch_get_main_queue(), + ^{ + g_view.window.title = @(text); + }); + } +#endif +} + +bool apple_gfx_ctx_has_focus(void) +{ + return APP_HAS_FOCUS; +} + +void apple_gfx_ctx_swap_buffers() +{ + if (--g_fast_forward_skips < 0) + { + dispatch_sync(dispatch_get_main_queue(), + ^{ + [g_view display]; + }); + + g_fast_forward_skips = g_is_syncing ? 0 : 3; + } +} + +gfx_ctx_proc_t apple_gfx_ctx_get_proc_address(const char *symbol_name) +{ + return (gfx_ctx_proc_t)CFBundleGetFunctionPointerForName(CFBundleGetBundleWithIdentifier(GLFrameworkID), + (__bridge CFStringRef)(@(symbol_name))); +} + #ifdef IOS void apple_bind_game_view_fbo(void) { diff --git a/apple/common/rarch_wrapper.h b/apple/common/rarch_wrapper.h index 92bce93c5e..4217f79fff 100644 --- a/apple/common/rarch_wrapper.h +++ b/apple/common/rarch_wrapper.h @@ -17,6 +17,8 @@ #ifndef __APPLE_RARCH_WRAPPER_H__ #define __APPLE_RARCH_WRAPPER_H__ +#include "gfx/gfx_context.h" + // The result needs to be free()'d char* ios_get_rarch_system_directory(); @@ -24,15 +26,16 @@ char* ios_get_rarch_system_directory(); void apple_rarch_exited (void* result); // These functions must only be called in gfx/context/apple_gl_context.c -bool apple_init_game_view(void); -void apple_destroy_game_view(void); -bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen); -void apple_flip_game_view(void); -void apple_set_game_view_sync(unsigned interval); -void apple_get_game_view_size(unsigned *width, unsigned *height); -void apple_update_window_title(void); -bool apple_game_view_has_focus(void); -void *apple_get_proc_address(const char *symbol_name); +bool apple_gfx_ctx_init(); +void apple_gfx_ctx_destroy(); +bool apple_gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor); +void apple_gfx_ctx_swap_interval(unsigned interval); +bool apple_gfx_ctx_set_video_mode(unsigned width, unsigned height, bool fullscreen); +void apple_gfx_ctx_get_video_size(unsigned* width, unsigned* height); +void apple_gfx_ctx_update_window_title(void); +bool apple_gfx_ctx_has_focus(void); +void apple_gfx_ctx_swap_buffers(); +gfx_ctx_proc_t apple_gfx_ctx_get_proc_address(const char *symbol_name); #ifdef IOS void apple_bind_game_view_fbo(void); diff --git a/gfx/context/apple_gl_ctx.c b/gfx/context/apple_gl_ctx.c index fb7e6333aa..2b0b13cb8f 100644 --- a/gfx/context/apple_gl_ctx.c +++ b/gfx/context/apple_gl_ctx.c @@ -27,17 +27,6 @@ #include "../../apple/common/rarch_wrapper.h" -static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor) -{ - (void)major; - (void)minor; -#ifdef IOS - return api == GFX_CTX_OPENGL_ES_API; -#else - return apple_create_gl_context((major << 12) | (minor << 8)); -#endif -} - static void gfx_ctx_check_window(bool *quit, bool *resize, unsigned *width, unsigned *height, unsigned frame_count) { @@ -46,7 +35,7 @@ static void gfx_ctx_check_window(bool *quit, *quit = false; unsigned new_width, new_height; - apple_get_game_view_size(&new_width, &new_height); + apple_gfx_ctx_get_video_size(&new_width, &new_height); if (new_width != *width || new_height != *height) { *width = new_width; @@ -67,28 +56,22 @@ static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data *input_data = NULL; } -static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol_name) -{ - return (gfx_ctx_proc_t)apple_get_proc_address(symbol_name); -} - // The apple_* functions are implemented in apple/RetroArch/RAGameView.m - const gfx_ctx_driver_t gfx_ctx_apple = { - apple_init_game_view, - apple_destroy_game_view, - gfx_ctx_bind_api, - apple_set_game_view_sync, - apple_set_video_mode, - apple_get_game_view_size, + apple_gfx_ctx_init, + apple_gfx_ctx_destroy, + apple_gfx_ctx_bind_api, + apple_gfx_ctx_swap_interval, + apple_gfx_ctx_set_video_mode, + apple_gfx_ctx_get_video_size, NULL, - apple_update_window_title, + apple_gfx_ctx_update_window_title, gfx_ctx_check_window, gfx_ctx_set_resize, - apple_game_view_has_focus, - apple_flip_game_view, + apple_gfx_ctx_has_focus, + apple_gfx_ctx_swap_buffers, gfx_ctx_input_driver, - gfx_ctx_get_proc_address, + apple_gfx_ctx_get_proc_address, NULL, - "ios", + "apple", }; From 55c4fe672642d125fdb4b699639f0129ead32a58 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 14 Sep 2013 12:57:48 +0200 Subject: [PATCH 197/202] Update Win builds to 0.9.9.6. --- Makefile.win | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.win b/Makefile.win index 020d5478eb..c05e716ab4 100644 --- a/Makefile.win +++ b/Makefile.win @@ -320,10 +320,10 @@ clean: rm -f tools/*.o dist_x86: all - zip -r retroarch-win32-0.9.9.4.zip $(TARGET) $(JTARGET) retroarch.cfg + zip -r retroarch-win32-0.9.9.6.zip $(TARGET) $(JTARGET) retroarch.cfg dist_x86_64: all - zip -r retroarch-win64-0.9.9.4.zip $(TARGET) $(JTARGET) retroarch.cfg + zip -r retroarch-win64-0.9.9.6.zip $(TARGET) $(JTARGET) retroarch.cfg libs_x86: wget http://themaister.net/retroarch-dl/RetroArch-win32-libs.zip From 7683efcec4f75de7cb554898f7678c937705e3e5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 14 Sep 2013 14:55:09 +0200 Subject: [PATCH 198/202] (Android) Set ANALOG_DPAD_NONE for Xperia Play --- android/native/jni/input_android.c | 1 + 1 file changed, 1 insertion(+) diff --git a/android/native/jni/input_android.c b/android/native/jni/input_android.c index 625f172d77..65c13625f2 100644 --- a/android/native/jni/input_android.c +++ b/android/native/jni/input_android.c @@ -1229,6 +1229,7 @@ static void android_input_set_keybinds(void *data, unsigned device, g_settings.input.device[port] = device; strlcpy(g_settings.input.device_names[port], "Xperia Play", sizeof(g_settings.input.device_names[port])); + g_settings.input.dpad_emulation[port] = ANALOG_DPAD_NONE; if ((zeus_second_id != -1 && (zeus_second_id == id))) { From ac9e0025e25cac0fb91aa7b087424cdffa780219 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 14 Sep 2013 15:03:20 +0200 Subject: [PATCH 199/202] (Android Phoenix) Add 96ms audio latency option as well --- android/phoenix/res/values/array.xml | 2 ++ android/phoenix/src/org/retroarch/browser/MainMenuActivity.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/android/phoenix/res/values/array.xml b/android/phoenix/res/values/array.xml index 6fc8d82643..d25dc54553 100644 --- a/android/phoenix/res/values/array.xml +++ b/android/phoenix/res/values/array.xml @@ -12,12 +12,14 @@ 64ms (Low) + 96ms (Medium) 128ms (Medium) 160ms (High) 64 + 96 128 160 diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 31e8d48ccf..4638b2312b 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -377,6 +377,8 @@ public class MainMenuActivity extends PreferenceActivity { if (latency_audio.equals("64")) { config.setInt("audio_latency", 64); + } else if (latency_audio.equals("96")) { + config.setInt("audio_latency", 96); } else if (latency_audio.equals("128")) { config.setInt("audio_latency", 128); } else if (latency_audio.equals("160")) { From 8489440d7e2af8cea37b2fc205a301751e7acc6a Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 14 Sep 2013 15:46:19 +0200 Subject: [PATCH 200/202] Use Integer.parseInt. --- .../src/org/retroarch/browser/MainMenuActivity.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 4638b2312b..679fae917d 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -374,16 +374,7 @@ public class MainMenuActivity extends PreferenceActivity { } } else { String latency_audio = prefs.getString("audio_latency", "64"); - - if (latency_audio.equals("64")) { - config.setInt("audio_latency", 64); - } else if (latency_audio.equals("96")) { - config.setInt("audio_latency", 96); - } else if (latency_audio.equals("128")) { - config.setInt("audio_latency", 128); - } else if (latency_audio.equals("160")) { - config.setInt("audio_latency", 160); - } + config.setInt("audio_latency", Integer.parseInt(latency_audio)); } config.setBoolean("audio_enable", From 38ec55573c50179a05dfd7012120fd34094e8c08 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 14 Sep 2013 17:26:10 +0200 Subject: [PATCH 201/202] Rework SET_AUDIO_CALLBACK. When disabling audio and/or muting, the core has no way of knowing this, causing potential issues in a threaded mixer. This environ is not used by any public core to my knowledge so the old API has been removed and replaced with a change to environment number (20 -> 22). --- audio/thread_wrapper.c | 4 +++- driver.c | 6 +++--- dynamic.c | 2 +- general.h | 3 ++- libretro.h | 11 ++++++++++- retroarch.c | 2 +- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/audio/thread_wrapper.c b/audio/thread_wrapper.c index 0c762aa15f..f507ff89ee 100644 --- a/audio/thread_wrapper.c +++ b/audio/thread_wrapper.c @@ -57,7 +57,7 @@ static void audio_thread_loop(void *data) } slock_unlock(thr->lock); - g_extern.system.audio_callback(); + g_extern.system.audio_callback.callback(); } } @@ -98,12 +98,14 @@ static bool audio_thread_stop(void *data) { audio_thread_t *thr = (audio_thread_t*)data; audio_thread_block(thr); + g_extern.system.audio_callback.set_state(false); return true; } static bool audio_thread_start(void *data) { audio_thread_t *thr = (audio_thread_t*)data; + g_extern.system.audio_callback.set_state(true); audio_thread_unblock(thr); return true; } diff --git a/driver.c b/driver.c index 20273357bd..5397b3629b 100644 --- a/driver.c +++ b/driver.c @@ -512,7 +512,7 @@ void init_audio(void) #ifdef HAVE_THREADS find_audio_driver(); - if (g_extern.system.audio_callback) + if (g_extern.system.audio_callback.callback) { RARCH_LOG("Starting threaded audio driver ...\n"); if (!rarch_threaded_audio_init(&driver.audio, &driver.audio_data, @@ -566,7 +566,7 @@ void init_audio(void) rarch_assert(g_extern.audio_data.outsamples = (float*)malloc(outsamples_max * sizeof(float))); g_extern.audio_data.rate_control = false; - if (!g_extern.system.audio_callback && g_extern.audio_active && g_settings.audio.rate_control) + if (!g_extern.system.audio_callback.callback && g_extern.audio_active && g_settings.audio.rate_control) { if (driver.audio->buffer_size && driver.audio->write_avail) { @@ -586,7 +586,7 @@ void init_audio(void) g_extern.measure_data.buffer_free_samples_count = 0; - if (g_extern.audio_active && !g_extern.audio_data.mute && g_extern.system.audio_callback) // Threaded driver is initially stopped. + if (g_extern.audio_active && !g_extern.audio_data.mute && g_extern.system.audio_callback.callback) // Threaded driver is initially stopped. audio_start_func(); } diff --git a/dynamic.c b/dynamic.c index 2f789ee5d6..d1b356e067 100644 --- a/dynamic.c +++ b/dynamic.c @@ -737,7 +737,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) return false; #endif - g_extern.system.audio_callback = info->callback; + g_extern.system.audio_callback = *info; break; } #endif diff --git a/general.h b/general.h index 0d187b688b..5632ba6086 100644 --- a/general.h +++ b/general.h @@ -396,7 +396,8 @@ struct global char valid_extensions[PATH_MAX]; retro_keyboard_event_t key_event; - retro_audio_callback_t audio_callback; + + struct retro_audio_callback audio_callback; struct retro_disk_control_callback disk_control; struct retro_hw_render_callback hw_render_callback; diff --git a/libretro.h b/libretro.h index 7b767fe6eb..8d23356138 100755 --- a/libretro.h +++ b/libretro.h @@ -489,7 +489,10 @@ enum retro_mod // NULL is returned if the libretro was loaded statically (i.e. linked statically to frontend), or if the path cannot be determined. // Mostly useful in cooperation with SET_SUPPORT_NO_GAME as assets can be loaded without ugly hacks. // -#define RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK 20 + // +// Environment 20 was an obsolete version of SET_AUDIO_CALLBACK. It was not used by any known core at the time, +// and was removed from the API. +#define RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK 22 // const struct retro_audio_callback * -- // Sets an interface which is used to notify a libretro core about audio being available for writing. // The callback can be called from any thread, so a core using this must have a thread safe audio implementation. @@ -515,9 +518,15 @@ enum retro_mod // Notifies libretro that audio data should be written. typedef void (*retro_audio_callback_t)(void); + +// True: Audio driver in frontend is active, and callback is expected to be called regularily. +// False: Audio driver in frontend is paused or inactive. Audio callback will not be called until set_state has been called with true. +// Initial state is false (inactive). +typedef void (*retro_audio_set_state_callback_t)(bool enabled); struct retro_audio_callback { retro_audio_callback_t callback; + retro_audio_set_state_callback_t set_state; }; // Notifies a libretro core of time spent since last invocation of retro_run() in microseconds. diff --git a/retroarch.c b/retroarch.c index 2c119948ff..2cc5a7e750 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1434,7 +1434,7 @@ void rarch_init_rewind(void) if (!g_settings.rewind_enable || g_extern.state_manager) return; - if (g_extern.system.audio_callback) + if (g_extern.system.audio_callback.callback) { RARCH_ERR("Implementation uses threaded audio. Cannot use rewind.\n"); return; From e540413880a0a764ba8b80b67083a9359e376010 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 14 Sep 2013 23:19:06 +0200 Subject: [PATCH 202/202] Be more clear if a core doesn't support save states. For cores which do not support save states, log to OSD in a more clear way. --- retroarch.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/retroarch.c b/retroarch.c index 2cc5a7e750..db8231a93c 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1892,14 +1892,22 @@ void rarch_load_state(void) else snprintf(load_path, sizeof(load_path), "%s", g_extern.savestate_name); + size_t size = pretro_serialize_size(); char msg[512]; - if (load_state(load_path)) - snprintf(msg, sizeof(msg), "Loaded state from slot #%u.", g_extern.state_slot); + + if (size) + { + if (load_state(load_path)) + snprintf(msg, sizeof(msg), "Loaded state from slot #%u.", g_extern.state_slot); + else + snprintf(msg, sizeof(msg), "Failed to load state from \"%s\".", load_path); + } else - snprintf(msg, sizeof(msg), "Failed to load state from \"%s\".", load_path); + strlcpy(msg, "Core does not support save states.", sizeof(msg)); msg_queue_clear(g_extern.msg_queue); msg_queue_push(g_extern.msg_queue, msg, 2, 180); + RARCH_LOG("%s\n", msg); } void rarch_save_state(void) @@ -1914,14 +1922,22 @@ void rarch_save_state(void) else snprintf(save_path, sizeof(save_path), "%s", g_extern.savestate_name); + size_t size = pretro_serialize_size(); char msg[512]; - if (save_state(save_path)) - snprintf(msg, sizeof(msg), "Saved state to slot #%u.", g_extern.state_slot); + + if (size) + { + if (save_state(save_path)) + snprintf(msg, sizeof(msg), "Saved state to slot #%u.", g_extern.state_slot); + else + snprintf(msg, sizeof(msg), "Failed to save state to \"%s\".", save_path); + } else - snprintf(msg, sizeof(msg), "Failed to save state to \"%s\".", save_path); + strlcpy(msg, "Core does not support save states.", sizeof(msg)); msg_queue_clear(g_extern.msg_queue); msg_queue_push(g_extern.msg_queue, msg, 2, 180); + RARCH_LOG("%s\n", msg); } // Save or load state here.