diff --git a/Makefile b/Makefile index ed9f5253ad..10c938604b 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,6 @@ endif include config.mk TARGET = retroarch -JTARGET = tools/retroarch-joyconfig OBJDIR := obj-unix @@ -17,7 +16,6 @@ ifeq ($(GLOBAL_CONFIG_DIR),) endif OBJ := -JOYCONFIG_OBJ := LIBS := DEFINES := -DHAVE_CONFIG_H -DRARCH_INTERNAL -DHAVE_OVERLAY DEFINES += -DGLOBAL_CONFIG_DIR='"$(GLOBAL_CONFIG_DIR)"' @@ -96,7 +94,6 @@ ifeq ($(NOUNUSED_VARIABLE), yes) endif RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ)) -RARCH_JOYCONFIG_OBJ := $(addprefix $(OBJDIR)/,$(JOYCONFIG_OBJ)) ifneq ($(SANITIZER),) CFLAGS := -fsanitize=$(SANITIZER) $(CFLAGS) @@ -104,9 +101,9 @@ ifneq ($(SANITIZER),) LDFLAGS := -fsanitize=$(SANITIZER) $(LDLAGS) endif -all: $(TARGET) $(JTARGET) config.mk +all: $(TARGET) config.mk --include $(RARCH_OBJ:.o=.d) $(RARCH_JOYCONFIG_OBJ:.o=.d) +-include $(RARCH_OBJ:.o=.d) config.mk: configure qb/* @echo "config.mk is outdated or non-existing. Run ./configure again." @exit 1 @@ -115,10 +112,6 @@ retroarch: $(RARCH_OBJ) @$(if $(Q), $(shell echo echo LD $@),) $(Q)$(LINK) -o $@ $(RARCH_OBJ) $(LIBS) $(LDFLAGS) $(LIBRARY_DIRS) -$(JTARGET): $(RARCH_JOYCONFIG_OBJ) - @$(if $(Q), $(shell echo echo LD $@),) - $(Q)$(LINK) -o $@ $(RARCH_JOYCONFIG_OBJ) $(JOYCONFIG_LIBS) $(LDFLAGS) $(LIBRARY_DIRS) - $(OBJDIR)/%.o: %.c config.h config.mk @mkdir -p $(dir $@) @$(if $(Q), $(shell echo echo CC $<),) @@ -141,21 +134,6 @@ $(OBJDIR)/git_version.o: git_version.c .FORCE @$(if $(Q), $(shell echo echo CC $<),) $(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -c -o $@ $< -$(OBJDIR)/tools/linuxraw_joypad.o: input/linuxraw_joypad.c - @mkdir -p $(dir $@) - @$(if $(Q), $(shell echo echo CC $<),) - $(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -DIS_JOYCONFIG -c -o $@ $< - -$(OBJDIR)/tools/parport_joypad.o: input/parport_joypad.c - @mkdir -p $(dir $@) - @$(if $(Q), $(shell echo echo CC $<),) - $(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -DIS_JOYCONFIG -c -o $@ $< - -$(OBJDIR)/tools/udev_joypad.o: input/udev_joypad.c - @mkdir -p $(dir $@) - @$(if $(Q), $(shell echo echo CC $<),) - $(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -DIS_JOYCONFIG -c -o $@ $< - $(OBJDIR)/%.o: %.S config.h config.mk $(HEADERS) @mkdir -p $(dir $@) @$(if $(Q), $(shell echo echo AS $<),) @@ -175,29 +153,24 @@ install: $(TARGET) mkdir -p $(DESTDIR)$(PREFIX)/share/pixmaps 2>/dev/null || /bin/true install -m755 $(TARGET) $(DESTDIR)$(PREFIX)/bin install -m755 tools/cg2glsl.py $(DESTDIR)$(PREFIX)/bin/retroarch-cg2glsl - install -m755 $(JTARGET) $(DESTDIR)$(PREFIX)/bin install -m644 retroarch.cfg $(DESTDIR)$(GLOBAL_CONFIG_DIR)/retroarch.cfg install -m644 retroarch.desktop $(DESTDIR)$(PREFIX)/share/applications install -m644 docs/retroarch.1 $(DESTDIR)$(MAN_DIR) install -m644 docs/retroarch-cg2glsl.1 $(DESTDIR)$(MAN_DIR) - install -m644 docs/retroarch-joyconfig.1 $(DESTDIR)$(MAN_DIR) install -m644 media/retroarch.svg $(DESTDIR)$(PREFIX)/share/pixmaps uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/retroarch - rm -f $(DESTDIR)$(PREFIX)/bin/retroarch-joyconfig rm -f $(DESTDIR)$(PREFIX)/bin/retroarch-cg2glsl rm -f $(DESTDIR)$(GLOBAL_CONFIG_DIR)/retroarch.cfg rm -f $(DESTDIR)$(PREFIX)/share/applications/retroarch.desktop rm -f $(DESTDIR)$(MAN_DIR)/retroarch.1 rm -f $(DESTDIR)$(MAN_DIR)/retroarch-cg2glsl.1 - rm -f $(DESTDIR)$(MAN_DIR)/retroarch-joyconfig.1 rm -f $(DESTDIR)$(PREFIX)/share/pixmaps/retroarch.svg clean: rm -rf $(OBJDIR) rm -f $(TARGET) - rm -f $(JTARGET) rm -f *.d .PHONY: all install uninstall clean diff --git a/Makefile.common b/Makefile.common index dcc115e924..5bb123061a 100644 --- a/Makefile.common +++ b/Makefile.common @@ -28,7 +28,6 @@ endif ifeq ($(HAVE_DYLIB), 1) DEFINES += -DHAVE_DYLIB - JOYCONFIG_LIBS += $(DYLIB_LIB) endif ifeq ($(SCALER_NO_SIMD), 1) @@ -71,15 +70,14 @@ endif ifneq ($(findstring Darwin,$(OS)),) OSX := 1 LIBS += -framework AppKit - JOYCONFIG_LIBS += -framework CoreFoundation else OSX := 0 endif ifneq ($(findstring Linux,$(OS)),) LIBS += -lrt - JOYCONFIG_LIBS += -lrt -lpthread OBJ += input/drivers/linuxraw_input.o \ + input/drivers/linux_common.o \ input/drivers_joypad/linuxraw_joypad.o \ frontend/drivers/platform_linux.o endif @@ -499,7 +497,6 @@ ifeq ($(HAVE_DINPUT), 1) DEFINES += -DHAVE_DINPUT OBJ += input/drivers/dinput.o \ input/drivers_joypad/dinput_joypad.o - JOYCONFIG_LIBS += -ldinput8 -ldxguid -lole32 endif ifeq ($(HAVE_XINPUT), 1) @@ -526,7 +523,6 @@ endif ifeq ($(HAVE_UDEV), 1) DEFINES += $(UDEV_CFLAGS) LIBS += $(UDEV_LIBS) - JOYCONFIG_LIBS += $(UDEV_LIBS) OBJ += input/drivers/udev_input.o \ input/drivers_joypad/udev_joypad.o endif @@ -535,7 +531,6 @@ ifeq ($(HAVE_LIBUSB), 1) DEFINES += -DHAVE_LIBUSB OBJ += input/drivers_hid/libusb_hid.o LIBS += -lusb-1.0 - JOYCONFIG_LIBS += -lusb-1.0 HAVE_HID = 1 endif @@ -544,7 +539,6 @@ ifeq ($(HAVE_IOHIDMANAGER), 1) OBJ += input/drivers_hid/iohidmanager_hid.o HAVE_HID = 1 LIBS += -framework IOKit - JOYCONFIG_LIBS += -framework IOKit endif ifeq ($(HAVE_CORELOCATION), 1) @@ -569,14 +563,20 @@ endif OBJ += gfx/video_context_driver.o \ gfx/drivers_context/gfx_null_ctx.o \ gfx/video_state_tracker.o \ - gfx/video_texture.o + libretro-common/gfx/math/matrix_4x4.o \ + libretro-common/gfx/math/matrix_3x3.o + +ifneq ($(findstring Win32,$(OS)),) +OBJ += gfx/video_texture.o +else +OBJ += gfx/video_texture_c.o +endif ifeq ($(HAVE_GL_CONTEXT), 1) DEFINES += -DHAVE_OPENGL -DHAVE_GLSL OBJ += gfx/drivers/gl.o \ gfx/drivers/gl_common.o \ gfx/drivers_font/gl_raster_font.o \ - libretro-common/gfx/math/matrix_4x4.o \ libretro-common/glsym/rglgen.o ifeq ($(HAVE_MENU_COMMON), 1) @@ -668,7 +668,6 @@ ifeq ($(HAVE_SDL), 1) OBJ += gfx/drivers_context/sdl_gl_ctx.o endif - JOYCONFIG_LIBS += $(SDL_LIBS) DEFINES += $(SDL_CFLAGS) $(BSD_LOCAL_INC) LIBS += $(SDL_LIBS) endif @@ -683,7 +682,6 @@ ifeq ($(HAVE_SDL2), 1) OBJ += gfx/drivers_context/sdl_gl_ctx.o endif - JOYCONFIG_LIBS += $(SDL2_LIBS) DEFINES += $(SDL2_CFLAGS) $(BSD_LOCAL_INC) LIBS += $(SDL2_LIBS) HAVE_SDL = 0 @@ -712,8 +710,7 @@ ifeq ($(HAVE_SUNXI), 1) endif ifeq ($(HAVE_VG), 1) - OBJ += gfx/drivers/vg.o \ - libretro-common/gfx/math/matrix_3x3.o + OBJ += gfx/drivers/vg.o DEFINES += $(VG_CFLAGS) LIBS += $(VG_LIBS) endif @@ -746,6 +743,10 @@ ifeq ($(HAVE_D3D9), 1) DEFINES += -DHAVE_D3D -DHAVE_D3D9 LIBS += -ld3d9 -ld3dx9 -ldxguid + ifeq ($(HAVE_MENU_COMMON), 1) + OBJ += menu/drivers_display/menu_display_d3d.o + endif + ifeq ($(HAVE_CG), 1) LIBS += -lcgD3D9 OBJ += gfx/d3d/render_chain_cg.o @@ -918,7 +919,3 @@ ifeq ($(HAVE_COCOA),1) ui/drivers/cocoa/cocoa_common.o \ gfx/drivers_context/cocoa_gl_ctx.o endif - - -# Joyconfig binary -JOYCONFIG_OBJ += tools/retroarch-joyconfig-griffin.o diff --git a/Makefile.ctr b/Makefile.ctr index 1a89ed25fc..44f857144b 100644 --- a/Makefile.ctr +++ b/Makefile.ctr @@ -53,6 +53,8 @@ else OBJS += libretro-common/formats/png/rpng.o OBJS += libretro-common/formats/png/rpng_encode.o OBJS += libretro-common/formats/bmp/rbmp_encode.o + OBJS += libretro-common/gfx/math/matrix_4x4.o + OBJS += libretro-common/gfx/math/matrix_3x3.o OBJS += gfx/drivers/ctr_gfx.o OBJS += gfx/drivers/nullgfx.o OBJS += gfx/font_renderer_driver.o @@ -208,6 +210,7 @@ else OBJS += menu/intl/menu_hash_us.o OBJS += menu/drivers/null.o OBJS += menu/drivers/menu_generic.o + OBJS += menu/drivers_display/menu_display_null.o OBJS += menu/drivers/rgui.o OBJS += command_event.o OBJS += deps/zlib/adler32.o diff --git a/camera/drivers/android.c b/camera/drivers/android.c index acba089ef2..06e923d4e6 100644 --- a/camera/drivers/android.c +++ b/camera/drivers/android.c @@ -17,6 +17,7 @@ #include #include "../../driver.h" +#include "../../gfx/video_texture.h" typedef struct android_camera { @@ -149,7 +150,7 @@ static void android_camera_stop(void *data) androidcamera->onCameraStop); if (androidcamera->tex) - glDeleteTextures(1, &androidcamera->tex); + video_texture_unload(TEXTURE_BACKEND_OPENGL, (uintptr_t*)&androidcamera->tex); } static bool android_camera_poll(void *data, diff --git a/cheevos.c b/cheevos.c index d0572a6eab..df8d5c6bda 100644 --- a/cheevos.c +++ b/cheevos.c @@ -154,8 +154,6 @@ typedef struct cheevoset_t unofficial; char token[32]; - - async_job_t *jobs; } cheevos_locals_t; cheevos_locals_t cheevos_locals = @@ -164,7 +162,6 @@ cheevos_locals_t cheevos_locals = {NULL, 0}, {NULL, 0}, {0}, - NULL }; cheevos_globals_t cheevos_globals = @@ -812,8 +809,6 @@ static int cheevos_parse(const char *json) NULL }; - static int initialize = 1; - unsigned core_count, unofficial_count; cheevos_readud_t ud; settings_t *settings = config_get_ptr(); @@ -860,13 +855,7 @@ static int cheevos_parse(const char *json) return -1; } - if (initialize) - { - initialize = 0; - cheevos_locals.jobs = async_job_new(); - } - - return -(cheevos_locals.jobs == NULL); + return 0; } /***************************************************************************** @@ -1139,10 +1128,43 @@ static int cheevos_test_cheevo(cheevo_t *cheevo) return ret_val && ret_val_sub_cond; } +static void cheevos_url_encode(const char *str, char *encoded, size_t len) +{ + while (*str) + { + if (isalnum(*str) || *str == '-' || *str == '_' || *str == '.' || *str == '~') + { + if (len >= 2) + { + *encoded++ = *str++; + len--; + } + else + break; + } + else + { + if (len >= 4) + { + sprintf(encoded, "%%%02x", (uint8_t)*str); + encoded += 3; + str++; + len -= 3; + } + else + break; + } + } + + *encoded = 0; +} + static int cheevos_login(retro_time_t *timeout) { const char *username; const char *password; + char urle_user[64]; + char urle_pwd[64]; char request[256]; const char *json; int res; @@ -1161,13 +1183,16 @@ static int cheevos_login(retro_time_t *timeout) RARCH_LOG("CHEEVOS username and/or password not informed\n"); return -1; } - + + cheevos_url_encode(username, urle_user, sizeof(urle_user)); + cheevos_url_encode(password, urle_pwd, sizeof(urle_pwd)); + snprintf( request, sizeof(request), "http://retroachievements.org/dorequest.php?r=login&u=%s&p=%s", - username, password + urle_user, urle_pwd ); - + request[sizeof(request) - 1] = 0; if (!cheevos_http_get(&json, NULL, request, timeout)) @@ -1192,8 +1217,9 @@ static void cheevos_unlocker(void *payload) { char request[256]; const char *result; - settings_t *settings = config_get_ptr(); - unsigned cheevo_id = (unsigned)(uintptr_t)payload; + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + unsigned cheevo_id = (unsigned)(uintptr_t)payload; if (!cheevos_login(NULL)) { @@ -1214,13 +1240,14 @@ static void cheevos_unlocker(void *payload) else { RARCH_LOG("CHEEVOS error awarding achievement %u, will retry\n", cheevo_id); - async_job_add(cheevos_locals.jobs, cheevos_unlocker, (void*)(uintptr_t)cheevo_id); + async_job_add(global->async_jobs, cheevos_unlocker, (void*)(uintptr_t)cheevo_id); } } } static void cheevos_test_cheevo_set(const cheevoset_t *set) { + global_t *global = global_get_ptr(); const cheevo_t *end = set->cheevos + set->count; cheevo_t *cheevo; @@ -1234,7 +1261,7 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) rarch_main_msg_queue_push(cheevo->title, 0, 3 * 60, false); rarch_main_msg_queue_push(cheevo->description, 0, 5 * 60, false); - async_job_add(cheevos_locals.jobs, cheevos_unlocker, (void*)(uintptr_t)cheevo->id); + async_job_add(global->async_jobs, cheevos_unlocker, (void*)(uintptr_t)cheevo->id); cheevo->active = 0; } @@ -1243,13 +1270,17 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) void cheevos_test(void) { - settings_t *settings = config_get_ptr(); - if (settings->cheevos.enable && !cheevos_globals.cheats_are_enabled && !cheevos_globals.cheats_were_enabled) + if (cheevos_locals.loaded) { - cheevos_test_cheevo_set(&cheevos_locals.core); + settings_t *settings = config_get_ptr(); + + if (settings->cheevos.enable && !cheevos_globals.cheats_are_enabled && !cheevos_globals.cheats_were_enabled) + { + cheevos_test_cheevo_set(&cheevos_locals.core); - if (settings->cheevos.test_unofficial) - cheevos_test_cheevo_set(&cheevos_locals.unofficial); + if (settings->cheevos.test_unofficial) + cheevos_test_cheevo_set(&cheevos_locals.unofficial); + } } } @@ -1376,8 +1407,9 @@ static void cheevos_playing(void *payload) { char request[256]; const char* json; - unsigned game_id = (unsigned)(uintptr_t)payload; - settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + unsigned game_id = (unsigned)(uintptr_t)payload; + settings_t *settings = config_get_ptr(); if (!cheevos_login(NULL)) { @@ -1398,7 +1430,7 @@ static void cheevos_playing(void *payload) else { RARCH_LOG("CHEEVOS error posting playing game %u activity, will retry\n", game_id); - async_job_add(cheevos_locals.jobs, cheevos_playing, (void*)(uintptr_t)game_id); + async_job_add(global->async_jobs, cheevos_playing, (void*)(uintptr_t)game_id); } } } @@ -1674,7 +1706,7 @@ static unsigned cheevos_find_game_id_nes(const struct retro_game_info *info, ret num_read = retro_fread(file, (void*)&header, sizeof(header)); retro_fclose(file); - if (num_read < sizeof(header)) + if (num_read < (ssize_t)sizeof(header)) return 0; } @@ -1713,7 +1745,7 @@ static unsigned cheevos_find_game_id_nes(const struct retro_game_info *info, ret if (num_read <= 0) break; - if (num_read >= rom_size) + if (num_read >= (ssize_t)rom_size) { MD5_Update(&ctx, (void*)buffer, rom_size); break; @@ -1777,11 +1809,12 @@ int cheevos_load(const struct retro_game_info *info) size_t memory; struct retro_system_info sysinfo; - int i; + unsigned i; const char *json; - retro_time_t timeout = 5000000; - unsigned game_id = 0; - settings_t *settings = config_get_ptr(); + retro_time_t timeout = 5000000; + unsigned game_id = 0; + global_t *global = global_get_ptr(); + settings_t *settings = config_get_ptr(); cheevos_locals.loaded = 0; @@ -1877,7 +1910,7 @@ int cheevos_load(const struct retro_game_info *info) free((void*)json); cheevos_locals.loaded = 1; - async_job_add(cheevos_locals.jobs, cheevos_playing, (void*)(uintptr_t)game_id); + async_job_add(global->async_jobs, cheevos_playing, (void*)(uintptr_t)game_id); return 0; } diff --git a/command_event.c b/command_event.c index 769a24eee1..32b3589a09 100644 --- a/command_event.c +++ b/command_event.c @@ -893,6 +893,34 @@ static bool event_save_core_config(void) return ret; } +/** + * event_save_current_config: + * + * Saves current configuration file to disk, and (optionally) + * autosave state. + **/ +void event_save_current_config(void) +{ + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + + if (settings->config_save_on_exit && *global->path.config) + { + /* Save last core-specific config to the default config location, + * needed on consoles for core switching and reusing last good + * config for new cores. + */ + config_save_file(global->path.config); + + /* Flush out the core specific config. */ + if (*global->path.core_specific_config && + settings->core_specific_config) + config_save_file(global->path.core_specific_config); + } + + event_command(EVENT_CMD_AUTOSAVE_STATE); +} + /** * event_save_state * @path : Path to state. @@ -1440,6 +1468,9 @@ bool event_command(enum event_command cmd) if (driver->frontend_ctx && driver->frontend_ctx->set_fork) driver->frontend_ctx->set_fork(true, false); break; + case EVENT_CMD_MENU_SAVE_CURRENT_CONFIG: + event_save_current_config(); + break; case EVENT_CMD_MENU_SAVE_CONFIG: if (!event_save_core_config()) return false; diff --git a/command_event.h b/command_event.h index 79df12f7d3..02558f7425 100644 --- a/command_event.h +++ b/command_event.h @@ -128,6 +128,7 @@ enum event_command /* Unpauses retroArch. */ EVENT_CMD_PAUSE, EVENT_CMD_PAUSE_CHECKS, + EVENT_CMD_MENU_SAVE_CURRENT_CONFIG, EVENT_CMD_MENU_SAVE_CONFIG, EVENT_CMD_MENU_PAUSE_LIBRETRO, /* Toggles menu on/off. */ diff --git a/configuration.c b/configuration.c index 1a0c50dbd8..f466ef3b27 100644 --- a/configuration.c +++ b/configuration.c @@ -460,6 +460,11 @@ static void config_set_defaults(void) settings->history_list_enable = def_history_list_enable; settings->load_dummy_on_core_shutdown = load_dummy_on_core_shutdown; +#if TARGET_OS_IPHONE + settings->input.small_keyboard_enable = false; +#endif + settings->input.keyboard_gamepad_enable = true; + settings->input.keyboard_gamepad_mapping_type = 1; #ifdef HAVE_FFMPEG settings->multimedia.builtin_mediaplayer_enable = true; #else @@ -1571,6 +1576,12 @@ static bool config_load_file(const char *path, bool set_defaults) CONFIG_GET_BOOL_BASE(conf, global, perfcnt_enable, "perfcnt_enable"); +#if TARGET_OS_IPHONE + CONFIG_GET_BOOL_BASE(conf, settings, input.small_keyboard_enable, "small_keyboard_enable"); +#endif + CONFIG_GET_BOOL_BASE(conf, settings, input.keyboard_gamepad_enable, "keyboard_gamepad_enable"); + CONFIG_GET_INT_BASE(conf, settings, input.keyboard_gamepad_mapping_type, "keyboard_gamepad_mapping_type"); + config_get_path(conf, "recording_output_directory", global->record.output_dir, sizeof(global->record.output_dir)); config_get_path(conf, "recording_config_directory", global->record.config_dir, @@ -2780,6 +2791,12 @@ bool config_save_file(const char *path) config_set_bool(conf, "log_verbosity", global->verbosity); config_set_bool(conf, "perfcnt_enable", global->perfcnt_enable); +#if TARGET_OS_IPHONE + config_set_bool(conf, "small_keyboard_enable", settings->input.small_keyboard_enable); +#endif + config_set_bool(conf, "keyboard_gamepad_enable", settings->input.keyboard_gamepad_enable); + config_set_int(conf, "keyboard_gamepad_mapping_type", settings->input.keyboard_gamepad_mapping_type); + config_set_bool(conf, "core_set_supports_no_game_enable", settings->core.set_supports_no_game_enable); diff --git a/configuration.h b/configuration.h index a1026560ce..25c824c1c4 100644 --- a/configuration.h +++ b/configuration.h @@ -250,6 +250,12 @@ typedef struct settings unsigned menu_toggle_gamepad_combo; bool back_as_menu_toggle_enable; + +#if TARGET_OS_IPHONE + bool small_keyboard_enable; +#endif + bool keyboard_gamepad_enable; + unsigned keyboard_gamepad_mapping_type; } input; struct diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index 2cb36abed2..ba11f400cf 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -75,6 +75,8 @@ static void frontend_ctr_get_environment_settings(int *argc, char *argv[], "playlists", sizeof(g_defaults.dir.playlist)); fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.port, "remaps", sizeof(g_defaults.dir.remap)); + fill_pathname_join(g_defaults.dir.video_filter, g_defaults.dir.port, + "filters", sizeof(g_defaults.dir.remap)); fill_pathname_join(g_defaults.path.config, g_defaults.dir.port, "retroarch.cfg", sizeof(g_defaults.path.config)); @@ -151,7 +153,7 @@ static void frontend_ctr_deinit(void *data) svcCloseHandle(lcd_handle); } - exitCfgu(); + cfguExit(); ndspExit(); csndExit(); gfxExit(); @@ -244,7 +246,7 @@ static void frontend_ctr_init(void *data) ctr_check_dspfirm(); if(ndspInit() != 0) *dsp_audio_driver = audio_null; - initCfgu(); + cfguInit(); #endif } diff --git a/frontend/frontend.c b/frontend/frontend.c index 8cd1dc2a4f..f6e7dfa300 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -17,6 +17,7 @@ #include #include +#include #include "frontend.h" #include "../system.h" @@ -28,34 +29,6 @@ #define MAX_ARGS 32 -/** - * main_exit_save_config: - * - * Saves configuration file to disk, and (optionally) - * autosave state. - **/ -void main_exit_save_config(void) -{ - settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); - - if (settings->config_save_on_exit && *global->path.config) - { - /* Save last core-specific config to the default config location, - * needed on consoles for core switching and reusing last good - * config for new cores. - */ - config_save_file(global->path.config); - - /* Flush out the core specific config. */ - if (*global->path.core_specific_config && - settings->core_specific_config) - config_save_file(global->path.core_specific_config); - } - - event_command(EVENT_CMD_AUTOSAVE_STATE); -} - /** * main_exit: * @@ -72,7 +45,7 @@ void main_exit(void *args) const frontend_ctx_driver_t *frontend = frontend_get_ptr(); const ui_companion_driver_t *ui = ui_companion_get_ptr(); - main_exit_save_config(); + event_command(EVENT_CMD_MENU_SAVE_CURRENT_CONFIG); if (global->inited.main) { @@ -285,6 +258,7 @@ int rarch_main(int argc, char *argv[], void *data) void *args = (void*)data; int ret = 0; settings_t *settings = NULL; + global_t *global = NULL; driver_t *driver = NULL; rarch_main_alloc(); @@ -302,6 +276,11 @@ int rarch_main(int argc, char *argv[], void *data) rarch_main_new(); +#ifdef HAVE_THREADS + global = global_get_ptr(); + global->async_jobs = async_job_new(); +#endif + if (driver->frontend_ctx) { if (!(ret = (main_load_content(argc, argv, args, diff --git a/frontend/frontend.h b/frontend/frontend.h index ce97054a87..92393fe2b1 100644 --- a/frontend/frontend.h +++ b/frontend/frontend.h @@ -37,14 +37,6 @@ extern "C" { **/ void main_exit(void *args); -/** - * main_exit_save_config: - * - * Saves configuration file to disk, and (optionally) - * autosave state. - **/ -void main_exit_save_config(void); - /** * main_entry: * diff --git a/gfx/common/win32_common.c b/gfx/common/win32_common.c deleted file mode 100644 index b1df29772e..0000000000 --- a/gfx/common/win32_common.c +++ /dev/null @@ -1,312 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2011-2015 - 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 "../../general.h" -#include "win32_common.h" - -#if !defined(_XBOX) - -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 //_WIN32_WINNT_WIN2K -#endif - -#include -#include -#include "../../retroarch.h" - -#ifdef HAVE_OPENGL -#include "../drivers_wm/win32_shader_dlg.h" -#endif - -#ifndef _XBOX -/* Power Request APIs */ - -typedef REASON_CONTEXT POWER_REQUEST_CONTEXT, *PPOWER_REQUEST_CONTEXT, *LPPOWER_REQUEST_CONTEXT; - -WINBASEAPI -HANDLE -WINAPI -PowerCreateRequest ( - PREASON_CONTEXT Context - ); - -WINBASEAPI -BOOL -WINAPI -PowerSetRequest ( - HANDLE PowerRequest, - POWER_REQUEST_TYPE RequestType - ); - -WINBASEAPI -BOOL -WINAPI -PowerClearRequest ( - HANDLE PowerRequest, - POWER_REQUEST_TYPE RequestType - ); -#endif - -static bool win32_browser( - HWND owner, - char *filename, - const char *extensions, - const char *title, - const char *initial_dir) -{ - OPENFILENAME ofn; - - memset((void*)&ofn, 0, sizeof(OPENFILENAME)); - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = owner; - ofn.lpstrFilter = extensions; - ofn.lpstrFile = filename; - ofn.lpstrTitle = title; - ofn.lpstrInitialDir = TEXT(initial_dir); - ofn.lpstrDefExt = ""; - ofn.nMaxFile = PATH_MAX; - ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - - if (!GetOpenFileName(&ofn)) - return false; - - return true; -} - -LRESULT win32_menu_loop(HWND owner, WPARAM wparam) -{ - WPARAM mode = wparam & 0xffff; - enum event_command cmd = EVENT_CMD_NONE; - bool do_wm_close = false; - settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); - - (void)global; - - switch (mode) - { - case ID_M_LOAD_CORE: - case ID_M_LOAD_CONTENT: - { - char win32_file[PATH_MAX_LENGTH] = {0}; - const char *extensions = NULL; - const char *title = NULL; - const char *initial_dir = NULL; - - if (mode == ID_M_LOAD_CORE) - { - extensions = "All Files\0*.*\0 Libretro core(.dll)\0*.dll\0"; - title = "Load Core"; - initial_dir = settings->libretro_directory; - } - else if (mode == ID_M_LOAD_CONTENT) - { - extensions = "All Files\0*.*\0\0"; - title = "Load Content"; - initial_dir = settings->menu_content_directory; - } - - if (win32_browser(owner, win32_file, extensions, title, initial_dir)) - { - switch (mode) - { - case ID_M_LOAD_CORE: - strlcpy(settings->libretro, win32_file, sizeof(settings->libretro)); - cmd = EVENT_CMD_LOAD_CORE; - break; - case ID_M_LOAD_CONTENT: - strlcpy(global->path.fullpath, win32_file, sizeof(global->path.fullpath)); - cmd = EVENT_CMD_LOAD_CONTENT; - do_wm_close = true; - break; - } - } - } - break; - case ID_M_RESET: - cmd = EVENT_CMD_RESET; - break; - case ID_M_MUTE_TOGGLE: - cmd = EVENT_CMD_AUDIO_MUTE_TOGGLE; - break; - case ID_M_MENU_TOGGLE: - cmd = EVENT_CMD_MENU_TOGGLE; - break; - case ID_M_PAUSE_TOGGLE: - cmd = EVENT_CMD_PAUSE_TOGGLE; - break; - case ID_M_LOAD_STATE: - cmd = EVENT_CMD_LOAD_STATE; - break; - case ID_M_SAVE_STATE: - cmd = EVENT_CMD_SAVE_STATE; - break; - case ID_M_DISK_CYCLE: - cmd = EVENT_CMD_DISK_EJECT_TOGGLE; - break; - case ID_M_DISK_NEXT: - cmd = EVENT_CMD_DISK_NEXT; - break; - case ID_M_DISK_PREV: - cmd = EVENT_CMD_DISK_PREV; - break; - case ID_M_FULL_SCREEN: - cmd = EVENT_CMD_FULLSCREEN_TOGGLE; - break; -#ifdef HAVE_OPENGL - case ID_M_SHADER_PARAMETERS: - shader_dlg_show(owner); - break; -#endif - case ID_M_MOUSE_GRAB: - cmd = EVENT_CMD_GRAB_MOUSE_TOGGLE; - break; - case ID_M_TAKE_SCREENSHOT: - cmd = EVENT_CMD_TAKE_SCREENSHOT; - break; - case ID_M_QUIT: - do_wm_close = true; - break; - default: - if (mode >= ID_M_WINDOW_SCALE_1X && mode <= ID_M_WINDOW_SCALE_10X) - { - unsigned idx = (mode - (ID_M_WINDOW_SCALE_1X-1)); - global->pending.windowed_scale = idx; - cmd = EVENT_CMD_RESIZE_WINDOWED_SCALE; - } - else if (mode == ID_M_STATE_INDEX_AUTO) - { - signed idx = -1; - settings->state_slot = idx; - } - else if (mode >= (ID_M_STATE_INDEX_AUTO+1) && mode <= (ID_M_STATE_INDEX_AUTO+10)) - { - signed idx = (mode - (ID_M_STATE_INDEX_AUTO+1)); - settings->state_slot = idx; - } - break; - } - - if (cmd != EVENT_CMD_NONE) - event_command(cmd); - - if (do_wm_close) - PostMessage(owner, WM_CLOSE, 0, 0); - - return 0L; -} -#endif - -bool win32_get_metrics(void *data, - enum display_metric_types type, float *value) -{ -#ifdef _XBOX - return false; -#else - HDC monitor = GetDC(NULL); - int pixels_x = GetDeviceCaps(monitor, HORZRES); - int pixels_y = GetDeviceCaps(monitor, VERTRES); - int physical_width = GetDeviceCaps(monitor, HORZSIZE); - int physical_height = GetDeviceCaps(monitor, VERTSIZE); - - ReleaseDC(NULL, monitor); - - switch (type) - { - case DISPLAY_METRIC_MM_WIDTH: - *value = physical_width; - break; - case DISPLAY_METRIC_MM_HEIGHT: - *value = physical_height; - break; - case DISPLAY_METRIC_DPI: - /* 25.4 mm in an inch. */ - *value = 254 * pixels_x / physical_width / 10; - break; - case DISPLAY_METRIC_NONE: - default: - *value = 0; - return false; - } - - return true; -#endif -} - -void win32_show_cursor(bool state) -{ -#ifndef _XBOX - if (state) - while (ShowCursor(TRUE) < 0); - else - while (ShowCursor(FALSE) >= 0); -#endif -} - -void win32_check_window(void) -{ -#ifndef _XBOX - MSG msg; - - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -#endif -} - -bool win32_suppress_screensaver(void *data, bool enable) -{ -#ifdef _XBOX - return false; -#else - typedef HANDLE (WINAPI * PowerCreateRequestPtr)(REASON_CONTEXT *context); - typedef BOOL (WINAPI * PowerSetRequestPtr)(HANDLE PowerRequest, POWER_REQUEST_TYPE RequestType); - HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); - PowerCreateRequestPtr powerCreateRequest = - (PowerCreateRequestPtr)GetProcAddress(kernel32, "PowerCreateRequest"); - PowerSetRequestPtr powerSetRequest = - (PowerSetRequestPtr)GetProcAddress(kernel32, "PowerSetRequest"); - - if(enable) - { - if(powerCreateRequest && powerSetRequest) - { - /* Windows 7, 8, 10 codepath */ - POWER_REQUEST_CONTEXT RequestContext; - HANDLE Request; - - RequestContext.Version = POWER_REQUEST_CONTEXT_VERSION; - RequestContext.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING; - RequestContext.Reason.SimpleReasonString = L"RetroArch running"; - - Request = PowerCreateRequest(&RequestContext); - - powerSetRequest( Request, PowerRequestDisplayRequired); - return true; - } - else - { - /* XP / Vista codepath */ - SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED); - return true; - } - } - - return false; -#endif -} diff --git a/gfx/common/win32_common.cpp b/gfx/common/win32_common.cpp new file mode 100644 index 0000000000..f68e1d48b1 --- /dev/null +++ b/gfx/common/win32_common.cpp @@ -0,0 +1,672 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2015 - 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 "../../general.h" +#include "win32_common.h" + +#if !defined(_XBOX) + +#define IDI_ICON 1 + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0500 //_WIN32_WINNT_WIN2K +#endif + +#include +#include +#include "../../retroarch.h" +#include "../video_thread_wrapper.h" + +#ifdef HAVE_OPENGL +#include "../drivers_wm/win32_shader_dlg.h" +#endif + +#ifdef HAVE_D3D +#include "../d3d/d3d.h" +#endif + +#ifdef __cplusplus +extern "C" +#endif +bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam); + +unsigned g_resize_width; +unsigned g_resize_height; +bool g_restore_desktop; +static unsigned g_pos_x = CW_USEDEFAULT; +static unsigned g_pos_y = CW_USEDEFAULT; +static bool g_resized; +bool g_inited; +bool g_quit; +HWND g_hwnd; + +extern void *dinput_wgl; +extern void *curD3D; +extern void *dinput; + +/* Power Request APIs */ + +typedef REASON_CONTEXT POWER_REQUEST_CONTEXT, *PPOWER_REQUEST_CONTEXT, *LPPOWER_REQUEST_CONTEXT; + +extern "C" WINBASEAPI +HANDLE +WINAPI +PowerCreateRequest ( + PREASON_CONTEXT Context + ); + +WINBASEAPI +BOOL +WINAPI +PowerSetRequest ( + HANDLE PowerRequest, + POWER_REQUEST_TYPE RequestType + ); + +WINBASEAPI +BOOL +WINAPI +PowerClearRequest ( + HANDLE PowerRequest, + POWER_REQUEST_TYPE RequestType + ); + +#ifndef MAX_MONITORS +#define MAX_MONITORS 9 +#endif + +static HMONITOR win32_monitor_last; +static unsigned win32_monitor_count; +static HMONITOR win32_monitor_all[MAX_MONITORS]; + +static BOOL CALLBACK win32_monitor_enum_proc(HMONITOR hMonitor, + HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) +{ + win32_monitor_all[win32_monitor_count++] = hMonitor; + return TRUE; +} + + +void win32_monitor_from_window(HWND data, bool destroy) +{ + win32_monitor_last = MonitorFromWindow(data, MONITOR_DEFAULTTONEAREST); + if (destroy) + DestroyWindow(data); +} + +void win32_monitor_get_info(void) +{ + MONITORINFOEX current_mon; + + memset(¤t_mon, 0, sizeof(current_mon)); + current_mon.cbSize = sizeof(MONITORINFOEX); + + GetMonitorInfo(win32_monitor_last, (MONITORINFO*)¤t_mon); + ChangeDisplaySettingsEx(current_mon.szDevice, NULL, NULL, 0, NULL); +} + +void win32_monitor_info(void *data, void *hm_data, unsigned *mon_id) +{ + unsigned i, fs_monitor; + settings_t *settings = config_get_ptr(); + MONITORINFOEX *mon = (MONITORINFOEX*)data; + HMONITOR *hm_to_use = (HMONITOR*)hm_data; + + if (!win32_monitor_last) + win32_monitor_from_window(GetDesktopWindow(), false); + + *hm_to_use = win32_monitor_last; + fs_monitor = settings->video.monitor_index; + + if (fs_monitor && fs_monitor <= win32_monitor_count + && win32_monitor_all[fs_monitor - 1]) + { + *hm_to_use = win32_monitor_all[fs_monitor - 1]; + *mon_id = fs_monitor - 1; + } + else + { + for (i = 0; i < win32_monitor_count; i++) + { + if (win32_monitor_all[i] != *hm_to_use) + continue; + + *mon_id = i; + break; + } + } + + memset(mon, 0, sizeof(*mon)); + mon->cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(*hm_to_use, (MONITORINFO*)mon); +} + +static const char *win32_video_get_ident(void) +{ +#ifdef HAVE_THREADS + settings_t *settings = config_get_ptr(); + + if (settings->video.threaded) + return rarch_threaded_video_get_ident(); +#endif + return video_driver_get_ident(); +} + +static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam) +{ + settings_t *settings = config_get_ptr(); + driver_t *driver = driver_get_ptr(); + const char *video_driver = win32_video_get_ident(); + + switch (message) + { + case WM_SYSCOMMAND: + /* Prevent screensavers, etc, while running. */ + switch (wparam) + { + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return 0; + } + break; + + case WM_CHAR: + case WM_KEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + return win32_handle_keyboard_event(hwnd, message, wparam, lparam); + + case WM_CREATE: + if (!strcmp(video_driver, "gl")) + create_gl_context(hwnd); + else if (!strcmp(video_driver, "d3d")) + { + LPCREATESTRUCT p_cs = (LPCREATESTRUCT)lparam; + curD3D = p_cs->lpCreateParams; + } + return 0; + + case WM_CLOSE: + case WM_DESTROY: + case WM_QUIT: + { + WINDOWPLACEMENT placement; + GetWindowPlacement(g_hwnd, &placement); + g_pos_x = placement.rcNormalPosition.left; + g_pos_y = placement.rcNormalPosition.top; + g_quit = true; + return 0; + } + case WM_SIZE: + /* Do not send resize message if we minimize. */ + if (wparam != SIZE_MAXHIDE && wparam != SIZE_MINIMIZED) + { + g_resize_width = LOWORD(lparam); + g_resize_height = HIWORD(lparam); + g_resized = true; + } + return 0; + case WM_COMMAND: + if (settings->ui.menubar_enable) + { + HWND d3dr = g_hwnd; + if (!strcmp(video_driver, "d3d")) + { + d3d_video_t *d3d = (d3d_video_t*)driver->video_data; + d3dr = g_hwnd; + } + LRESULT ret = win32_menu_loop(d3dr, wparam); + (void)ret; + } + break; + } + + if (dinput_handle_message((!strcmp(video_driver, "gl")) ? dinput_wgl : dinput, message, wparam, lparam)) + return 0; + return DefWindowProc(hwnd, message, wparam, lparam); +} + +bool win32_window_init(WNDCLASSEX *wndclass, bool fullscreen) +{ +#ifndef _XBOX + wndclass->cbSize = sizeof(WNDCLASSEX); + wndclass->style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wndclass->lpfnWndProc = WndProc; + wndclass->hInstance = GetModuleHandle(NULL); + wndclass->hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass->lpszClassName = "RetroArch"; + wndclass->hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON)); + wndclass->hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), + MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); + if (!fullscreen) + wndclass->hbrBackground = (HBRUSH)COLOR_WINDOW; + + if (!RegisterClassEx(wndclass)) + return false; +#endif + return true; +} + +bool win32_window_create(void *data, unsigned style, + RECT *mon_rect, unsigned width, + unsigned height, bool fullscreen) +{ +#ifndef _XBOX + driver_t *driver = driver_get_ptr(); + g_hwnd = CreateWindowEx(0, "RetroArch", "RetroArch", + style, + fullscreen ? mon_rect->left : g_pos_x, + fullscreen ? mon_rect->top : g_pos_y, + width, height, + NULL, NULL, NULL, data); + if (!g_hwnd) + return false; + + driver->display_type = RARCH_DISPLAY_WIN32; + driver->video_display = 0; + driver->video_window = (uintptr_t)g_hwnd; +#endif + return true; +} + +static bool win32_browser( + HWND owner, + char *filename, + const char *extensions, + const char *title, + const char *initial_dir) +{ + OPENFILENAME ofn; + + memset((void*)&ofn, 0, sizeof(OPENFILENAME)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = owner; + ofn.lpstrFilter = extensions; + ofn.lpstrFile = filename; + ofn.lpstrTitle = title; + ofn.lpstrInitialDir = TEXT(initial_dir); + ofn.lpstrDefExt = ""; + ofn.nMaxFile = PATH_MAX; + ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (!GetOpenFileName(&ofn)) + return false; + + return true; +} + +LRESULT win32_menu_loop(HWND owner, WPARAM wparam) +{ + WPARAM mode = wparam & 0xffff; + enum event_command cmd = EVENT_CMD_NONE; + bool do_wm_close = false; + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + + (void)global; + + switch (mode) + { + case ID_M_LOAD_CORE: + case ID_M_LOAD_CONTENT: + { + char win32_file[PATH_MAX_LENGTH] = {0}; + const char *extensions = NULL; + const char *title = NULL; + const char *initial_dir = NULL; + + if (mode == ID_M_LOAD_CORE) + { + extensions = "All Files\0*.*\0 Libretro core(.dll)\0*.dll\0"; + title = "Load Core"; + initial_dir = settings->libretro_directory; + } + else if (mode == ID_M_LOAD_CONTENT) + { + extensions = "All Files\0*.*\0\0"; + title = "Load Content"; + initial_dir = settings->menu_content_directory; + } + + if (win32_browser(owner, win32_file, extensions, title, initial_dir)) + { + switch (mode) + { + case ID_M_LOAD_CORE: + strlcpy(settings->libretro, win32_file, sizeof(settings->libretro)); + cmd = EVENT_CMD_LOAD_CORE; + break; + case ID_M_LOAD_CONTENT: + strlcpy(global->path.fullpath, win32_file, sizeof(global->path.fullpath)); + cmd = EVENT_CMD_LOAD_CONTENT; + do_wm_close = true; + break; + } + } + } + break; + case ID_M_RESET: + cmd = EVENT_CMD_RESET; + break; + case ID_M_MUTE_TOGGLE: + cmd = EVENT_CMD_AUDIO_MUTE_TOGGLE; + break; + case ID_M_MENU_TOGGLE: + cmd = EVENT_CMD_MENU_TOGGLE; + break; + case ID_M_PAUSE_TOGGLE: + cmd = EVENT_CMD_PAUSE_TOGGLE; + break; + case ID_M_LOAD_STATE: + cmd = EVENT_CMD_LOAD_STATE; + break; + case ID_M_SAVE_STATE: + cmd = EVENT_CMD_SAVE_STATE; + break; + case ID_M_DISK_CYCLE: + cmd = EVENT_CMD_DISK_EJECT_TOGGLE; + break; + case ID_M_DISK_NEXT: + cmd = EVENT_CMD_DISK_NEXT; + break; + case ID_M_DISK_PREV: + cmd = EVENT_CMD_DISK_PREV; + break; + case ID_M_FULL_SCREEN: + cmd = EVENT_CMD_FULLSCREEN_TOGGLE; + break; +#ifdef HAVE_OPENGL + case ID_M_SHADER_PARAMETERS: + shader_dlg_show(owner); + break; +#endif + case ID_M_MOUSE_GRAB: + cmd = EVENT_CMD_GRAB_MOUSE_TOGGLE; + break; + case ID_M_TAKE_SCREENSHOT: + cmd = EVENT_CMD_TAKE_SCREENSHOT; + break; + case ID_M_QUIT: + do_wm_close = true; + break; + default: + if (mode >= ID_M_WINDOW_SCALE_1X && mode <= ID_M_WINDOW_SCALE_10X) + { + unsigned idx = (mode - (ID_M_WINDOW_SCALE_1X-1)); + global->pending.windowed_scale = idx; + cmd = EVENT_CMD_RESIZE_WINDOWED_SCALE; + } + else if (mode == ID_M_STATE_INDEX_AUTO) + { + signed idx = -1; + settings->state_slot = idx; + } + else if (mode >= (ID_M_STATE_INDEX_AUTO+1) && mode <= (ID_M_STATE_INDEX_AUTO+10)) + { + signed idx = (mode - (ID_M_STATE_INDEX_AUTO+1)); + settings->state_slot = idx; + } + break; + } + + if (cmd != EVENT_CMD_NONE) + event_command(cmd); + + if (do_wm_close) + PostMessage(owner, WM_CLOSE, 0, 0); + + return 0L; +} +#endif + +bool win32_get_metrics(void *data, + enum display_metric_types type, float *value) +{ +#ifdef _XBOX + return false; +#else + HDC monitor = GetDC(NULL); + int pixels_x = GetDeviceCaps(monitor, HORZRES); + int pixels_y = GetDeviceCaps(monitor, VERTRES); + int physical_width = GetDeviceCaps(monitor, HORZSIZE); + int physical_height = GetDeviceCaps(monitor, VERTSIZE); + + ReleaseDC(NULL, monitor); + + switch (type) + { + case DISPLAY_METRIC_MM_WIDTH: + *value = physical_width; + break; + case DISPLAY_METRIC_MM_HEIGHT: + *value = physical_height; + break; + case DISPLAY_METRIC_DPI: + /* 25.4 mm in an inch. */ + *value = 254 * pixels_x / physical_width / 10; + break; + case DISPLAY_METRIC_NONE: + default: + *value = 0; + return false; + } + + return true; +#endif +} + +void win32_monitor_init(void) +{ +#ifndef _XBOX + win32_monitor_count = 0; + EnumDisplayMonitors(NULL, NULL, win32_monitor_enum_proc, 0); +#endif + + g_quit = false; +} + +bool win32_monitor_set_fullscreen(unsigned width, unsigned height, unsigned refresh, char *dev_name) +{ +#ifndef _XBOX + DEVMODE devmode; + + memset(&devmode, 0, sizeof(devmode)); + devmode.dmSize = sizeof(DEVMODE); + devmode.dmPelsWidth = width; + devmode.dmPelsHeight = height; + devmode.dmDisplayFrequency = refresh; + devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; + + RARCH_LOG("[WGL]: Setting fullscreen to %ux%u @ %uHz on device %s.\n", width, height, refresh, dev_name); + return ChangeDisplaySettingsEx(dev_name, &devmode, NULL, CDS_FULLSCREEN, NULL) == DISP_CHANGE_SUCCESSFUL; +#endif +} + +void win32_show_cursor(bool state) +{ +#ifndef _XBOX + if (state) + while (ShowCursor(TRUE) < 0); + else + while (ShowCursor(FALSE) >= 0); +#endif +} + +void win32_check_window(bool *quit, bool *resize, unsigned *width, unsigned *height) +{ +#ifndef _XBOX + MSG msg; + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +#endif + *quit = g_quit; + + if (g_resized) + { + *resize = true; + *width = g_resize_width; + *height = g_resize_height; + g_resized = false; + } +} + +bool win32_suppress_screensaver(void *data, bool enable) +{ +#ifdef _XBOX + return false; +#else + typedef HANDLE (WINAPI * PowerCreateRequestPtr)(REASON_CONTEXT *context); + typedef BOOL (WINAPI * PowerSetRequestPtr)(HANDLE PowerRequest, POWER_REQUEST_TYPE RequestType); + HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); + PowerCreateRequestPtr powerCreateRequest = + (PowerCreateRequestPtr)GetProcAddress(kernel32, "PowerCreateRequest"); + PowerSetRequestPtr powerSetRequest = + (PowerSetRequestPtr)GetProcAddress(kernel32, "PowerSetRequest"); + + if(enable) + { + if(powerCreateRequest && powerSetRequest) + { + /* Windows 7, 8, 10 codepath */ + POWER_REQUEST_CONTEXT RequestContext; + HANDLE Request; + + RequestContext.Version = POWER_REQUEST_CONTEXT_VERSION; + RequestContext.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING; + RequestContext.Reason.SimpleReasonString = L"RetroArch running"; + + Request = PowerCreateRequest(&RequestContext); + + powerSetRequest( Request, PowerRequestDisplayRequired); + return true; + } + else + { + /* XP / Vista codepath */ + SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED); + return true; + } + } + + return false; +#endif +} + +bool win32_set_video_mode(void *data, + unsigned width, unsigned height, + bool fullscreen) +{ +#ifndef _XBOX + DWORD style; + MSG msg; + RECT mon_rect; + unsigned mon_id; + MONITORINFOEX current_mon; + float refresh_mod; + unsigned refresh; + bool windowed_full; + RECT rect = {0}; + HMONITOR hm_to_use = NULL; + driver_t *driver = driver_get_ptr(); + settings_t *settings = config_get_ptr(); + + win32_monitor_info(¤t_mon, &hm_to_use, &mon_id); + + mon_rect = current_mon.rcMonitor; + g_resize_width = width; + g_resize_height = height; + + /* Windows only reports the refresh rates for modelines as + * an integer, so video.refresh_rate needs to be rounded. Also, account + * for black frame insertion using video.refresh_rate set to half + * of the display refresh rate, as well as higher vsync swap intervals. */ + refresh_mod = settings->video.black_frame_insertion ? 2.0f : 1.0f; + refresh = roundf(settings->video.refresh_rate * refresh_mod * settings->video.swap_interval); + + windowed_full = settings->video.windowed_fullscreen; + + if (fullscreen) + { + if (windowed_full) + { + style = WS_EX_TOPMOST | WS_POPUP; + g_resize_width = width = mon_rect.right - mon_rect.left; + g_resize_height = height = mon_rect.bottom - mon_rect.top; + } + else + { + style = WS_POPUP | WS_VISIBLE; + + if (!win32_monitor_set_fullscreen(width, height, refresh, current_mon.szDevice)) + return false; + + /* Display settings might have changed, get new coordinates. */ + GetMonitorInfo(hm_to_use, (MONITORINFO*)¤t_mon); + mon_rect = current_mon.rcMonitor; + g_restore_desktop = true; + } + } + else + { + style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + rect.right = width; + rect.bottom = height; + AdjustWindowRect(&rect, style, FALSE); + g_resize_width = width = rect.right - rect.left; + g_resize_height = height = rect.bottom - rect.top; + } + + if (!win32_window_create(NULL, style, &mon_rect, width, height, fullscreen)) + return false; + + if (!fullscreen || windowed_full) + { + if (!fullscreen && settings->ui.menubar_enable) + { + RECT rc_temp = {0, 0, (LONG)height, 0x7FFF}; + SetMenu(g_hwnd, LoadMenu(GetModuleHandle(NULL),MAKEINTRESOURCE(IDR_MENU))); + SendMessage(g_hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rc_temp); + g_resize_height = height += rc_temp.top + rect.top; + SetWindowPos(g_hwnd, NULL, 0, 0, width, height, SWP_NOMOVE); + } + + ShowWindow(g_hwnd, SW_RESTORE); + UpdateWindow(g_hwnd); + SetForegroundWindow(g_hwnd); + SetFocus(g_hwnd); + } + + win32_show_cursor(!fullscreen); + + /* Wait until context is created (or failed to do so ...) */ + while (!g_inited && !g_quit && GetMessage(&msg, g_hwnd, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + if (g_quit) + return false; +#endif + + return true; +} diff --git a/gfx/common/win32_common.h b/gfx/common/win32_common.h index 70322081a6..f9c4015c18 100644 --- a/gfx/common/win32_common.h +++ b/gfx/common/win32_common.h @@ -18,25 +18,56 @@ #define WIN32_COMMON_H__ #include -#include -#include "../../driver.h" -#include "../video_context_driver.h" - -#ifdef __cplusplus -extern "C" { -#endif #ifndef _XBOX #define WIN32_LEAN_AND_MEAN #include +#endif + +#include +#include "../../driver.h" +#include "../video_context_driver.h" + +#ifndef _XBOX #include "../drivers_wm/win32_resource.h" +extern unsigned g_resize_width; +extern unsigned g_resize_height; +extern bool g_quit; +extern bool g_inited; +extern bool g_restore_desktop; +extern HWND g_hwnd; + LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); LRESULT win32_menu_loop(HWND handle, WPARAM wparam); + + +void win32_monitor_from_window(HWND data, bool destroy); + +void win32_monitor_get_info(void); + +void win32_monitor_info(void *data, void *hm_data, unsigned *mon_id); + +void create_gl_context(HWND hwnd); #endif +void win32_monitor_init(void); + +bool win32_set_video_mode(void *data, + unsigned width, unsigned height, + bool fullscreen); + +bool win32_monitor_set_fullscreen(unsigned width, + unsigned height, unsigned refresh, char *dev_name); + +bool win32_window_init(WNDCLASSEX *wndclass, bool fullscreen); + +bool win32_window_create(void *data, unsigned style, + RECT *mon_rect, unsigned width, + unsigned height, bool fullscreen); + bool win32_suppress_screensaver(void *data, bool enable); bool win32_get_metrics(void *data, @@ -44,10 +75,7 @@ bool win32_get_metrics(void *data, void win32_show_cursor(bool state); -void win32_check_window(void); - -#ifdef __cplusplus -} -#endif +void win32_check_window(bool *quit, + bool *resize, unsigned *width, unsigned *height); #endif diff --git a/gfx/d3d/d3d.cpp b/gfx/d3d/d3d.cpp index e9c7758373..d6384a7521 100644 --- a/gfx/d3d/d3d.cpp +++ b/gfx/d3d/d3d.cpp @@ -28,6 +28,7 @@ #include "d3d.h" #include "../video_viewport.h" #include "../video_monitor.h" +#include "../video_common.h" #include "../../dynamic.h" #include "render_chain_driver.h" @@ -54,12 +55,30 @@ #endif /* forward declarations */ -static void d3d_calculate_rect(d3d_video_t *d3d, - unsigned width, unsigned height, - bool keep, float desired_aspect); -static bool d3d_init_luts(d3d_video_t *d3d); -static void d3d_set_font_rect(d3d_video_t *d3d, - const struct font_params *params); +static bool d3d_init_luts(d3d_video_t *d3d) +{ + unsigned i; + settings_t *settings = config_get_ptr(); + + if (!d3d->renderchain_driver->add_lut) + return true; + + for (i = 0; i < d3d->shader.luts; i++) + { + bool ret = d3d->renderchain_driver->add_lut( + d3d->renderchain_data, + d3d->shader.lut[i].id, d3d->shader.lut[i].path, + d3d->shader.lut[i].filter == RARCH_FILTER_UNSPEC ? + settings->video.smooth : + (d3d->shader.lut[i].filter == RARCH_FILTER_LINEAR)); + + if (!ret) + return ret; + } + + return true; +} + static bool d3d_process_shader(d3d_video_t *d3d); static bool d3d_init_chain(d3d_video_t *d3d, const video_info_t *video_info); @@ -69,28 +88,9 @@ static void d3d_free_overlays(d3d_video_t *d3d); static void d3d_free_overlay(d3d_video_t *d3d, overlay_t *overlay); #endif -#ifdef HAVE_WINDOW - -#define IDI_ICON 1 - -#ifndef MAX_MONITORS -#define MAX_MONITORS 9 -#endif - -extern LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, - WPARAM wParam, LPARAM lParam); -static RECT d3d_monitor_rect(d3d_video_t *d3d); -#endif - -#ifdef HAVE_MONITOR -static HMONITOR monitor_last; -static HMONITOR monitor_all[MAX_MONITORS]; -static unsigned monitor_count; -#endif - static void d3d_deinit_chain(d3d_video_t *d3d) { - d3d->renderchain_driver->chain_free(d3d); + d3d->renderchain_driver->chain_free(d3d->renderchain_data); d3d->renderchain_driver = NULL; d3d->renderchain_data = NULL; @@ -161,7 +161,7 @@ void d3d_make_d3dpp(void *data, #endif info->rgb32 ? D3DFMT_X8R8G8B8 : D3DFMT_LIN_R5G6B5; #else - d3dpp->hDeviceWindow = d3d->hWnd; + d3dpp->hDeviceWindow = g_hwnd; d3dpp->BackBufferFormat = !d3dpp->Windowed ? D3DFMT_X8R8G8B8 : D3DFMT_UNKNOWN; #endif @@ -247,7 +247,7 @@ static bool d3d_init_base(void *data, const video_info_t *info) if (FAILED(d3d->d3d_err = d3d->g_pD3D->CreateDevice( d3d->cur_mon_id, D3DDEVTYPE_HAL, - d3d->hWnd, + g_hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &d3d->dev))) @@ -258,7 +258,7 @@ static bool d3d_init_base(void *data, const video_info_t *info) if (FAILED(d3d->d3d_err = d3d->g_pD3D->CreateDevice( d3d->cur_mon_id, D3DDEVTYPE_HAL, - d3d->hWnd, + g_hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3d->dev))) @@ -271,6 +271,91 @@ static bool d3d_init_base(void *data, const video_info_t *info) return true; } +static void d3d_set_viewport(void *data, + unsigned width, unsigned height, + bool force_full, + bool allow_rotate) +{ + D3DVIEWPORT viewport; + d3d_video_t *d3d = (d3d_video_t*)data; + int x = 0; + int y = 0; + float device_aspect = (float)width / height; + settings_t *settings = config_get_ptr(); + float desired_aspect = video_driver_get_aspect_ratio(); + + video_driver_get_size(&width, &height); + + gfx_ctx_translate_aspect(d3d, &device_aspect, width, height); + + if (settings->video.scale_integer && !force_full) + { + struct video_viewport vp = {0}; + video_viewport_get_scaled_integer(&vp, width, height, desired_aspect, d3d->keep_aspect); + x = vp.x; + y = vp.y; + width = vp.width; + height = vp.height; + } + else if (d3d->keep_aspect && !force_full) + { + if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) + { + video_viewport_t *custom = video_viewport_get_custom(); + + if (custom) + { + x = custom->x; + y = custom->y; + width = custom->width; + height = custom->height; + } + } + else + { + float delta; + + if (fabsf(device_aspect - desired_aspect) < 0.0001f) { } + else if (device_aspect > desired_aspect) + { + delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; + x = int(roundf(width * (0.5f - delta))); + y = 0; + width = unsigned(roundf(2.0f * width * delta)); + } + else + { + delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; + x = 0; + y = int(roundf(height * (0.5f - delta))); + height = unsigned(roundf(2.0f * height * delta)); + } + } + } + + + /* D3D doesn't support negative X/Y viewports ... */ + if (x < 0) + x = 0; + if (y < 0) + y = 0; + + viewport.X = x; + viewport.Y = y; + viewport.Width = width; + viewport.Height = height; + viewport.MinZ = 0.0f; + viewport.MaxZ = 1.0f; + + d3d->final_viewport = viewport; + + if (d3d && d3d->renderchain_driver && d3d->renderchain_data) + { + if (d3d->renderchain_driver->set_font_rect) + d3d->renderchain_driver->set_font_rect(d3d, NULL); + } +} + static bool d3d_initialize(d3d_video_t *d3d, const video_info_t *info) { unsigned width, height; @@ -329,17 +414,16 @@ static bool d3d_initialize(d3d_video_t *d3d, const video_info_t *info) if (!ret) return ret; - video_driver_get_size(&width, &height); - - d3d_calculate_rect(d3d, - width, height, info->force_aspect, video_driver_get_aspect_ratio()); - if (!d3d_init_chain(d3d, info)) { RARCH_ERR("Failed to initialize render chain.\n"); return false; } + video_driver_get_size(&width, &height); + d3d_set_viewport(d3d, + width, height, false, true); + #if defined(_XBOX360) strlcpy(settings->video.font_path, "game:\\media\\Arial_12.xpr", sizeof(settings->video.font_path)); @@ -354,52 +438,7 @@ static bool d3d_initialize(d3d_video_t *d3d, const video_info_t *info) return true; } -static void d3d_set_viewport(d3d_video_t *d3d, int x, int y, - unsigned width, unsigned height) -{ - D3DVIEWPORT viewport; - /* D3D doesn't support negative X/Y viewports ... */ - if (x < 0) - x = 0; - if (y < 0) - y = 0; - - viewport.X = x; - viewport.Y = y; - viewport.Width = width; - viewport.Height = height; - viewport.MinZ = 0.0f; - viewport.MaxZ = 1.0f; - - d3d->final_viewport = viewport; - - d3d_set_font_rect(d3d, NULL); -} - -static void d3d_set_viewport_wrap(void *data, - unsigned width, unsigned height, - bool force_fullscreen, - bool allow_rotate) -{ - D3DVIEWPORT vp_full; - LPDIRECT3DDEVICE d3dr; - d3d_video_t *d3d = (d3d_video_t*)data; - - vp_full.X = 0; - vp_full.Y = 0; - vp_full.Width = width; - vp_full.Height = height; - vp_full.MinZ = 0.0f; - vp_full.MaxZ = 1.0f; - - d3dr = (LPDIRECT3DDEVICE)d3d->dev; - - if (force_fullscreen) - d3d_set_viewport(d3dr, &vp_full); - else - d3d_set_viewport(d3dr, &d3d->final_viewport); -} bool d3d_restore(d3d_video_t *d3d) { @@ -412,51 +451,6 @@ bool d3d_restore(d3d_video_t *d3d) return !d3d->needs_restore; } -static void d3d_calculate_rect(d3d_video_t *d3d, - unsigned width, unsigned height, - bool keep, float desired_aspect) -{ - settings_t *settings = config_get_ptr(); - - if (settings->video.scale_integer) - { - struct video_viewport vp = {0}; - video_viewport_get_scaled_integer(&vp, width, height, desired_aspect, keep); - d3d_set_viewport(d3d, vp.x, vp.y, vp.width, vp.height); - } - else if (!keep) - d3d_set_viewport(d3d, 0, 0, width, height); - else - { - if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) - { - video_viewport_t *custom = video_viewport_get_custom(); - - if (custom) - d3d_set_viewport(d3d, custom->x, custom->y, - custom->width, custom->height); - } - else - { - float device_aspect = ((float)width) / ((float)height); - - if (fabsf(device_aspect - desired_aspect) < 0.0001f) - d3d_set_viewport(d3d, 0, 0, width, height); - else if (device_aspect > desired_aspect) - { - float delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; - d3d_set_viewport(d3d, int(roundf(width * (0.5f - delta))), - 0, unsigned(roundf(2.0f * width * delta)), height); - } - else - { - float delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; - d3d_set_viewport(d3d, 0, int(roundf(height * (0.5f - delta))), - width, unsigned(roundf(2.0f * height * delta))); - } - } - } -} static void d3d_set_nonblock_state(void *data, bool state) { @@ -543,7 +537,7 @@ static void d3d_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) if (!d3d) return; - d3d->video_info.force_aspect = true; + d3d->keep_aspect = true; d3d->should_resize = true; } @@ -561,8 +555,8 @@ static void d3d_set_osd_msg(void *data, const char *msg, driver_t *driver = driver_get_ptr(); const font_renderer_t *font_ctx = driver->font_osd_driver; - if (params) - d3d_set_font_rect(d3d, params); + if (d3d->renderchain_driver->set_font_rect && params) + d3d->renderchain_driver->set_font_rect(d3d, params); if (font_ctx->render_msg) font_ctx->render_msg(driver->font_osd_data, msg, params); @@ -589,39 +583,31 @@ static bool d3d_construct(d3d_video_t *d3d, if (!d3d->menu) return false; - d3d->menu->tex_coords.x = 0; - d3d->menu->tex_coords.y = 0; - d3d->menu->tex_coords.w = 1; - d3d->menu->tex_coords.h = 1; - d3d->menu->vert_coords.x = 0; - d3d->menu->vert_coords.y = 1; - d3d->menu->vert_coords.w = 1; - d3d->menu->vert_coords.h = -1; + d3d->menu->tex_coords[0] = 0; + d3d->menu->tex_coords[1] = 0; + d3d->menu->tex_coords[2] = 1; + d3d->menu->tex_coords[3] = 1; + d3d->menu->vert_coords[0] = 0; + d3d->menu->vert_coords[1] = 1; + d3d->menu->vert_coords[2] = 1; + d3d->menu->vert_coords[3] = -1; #endif -#if defined(HAVE_WINDOW) && !defined(_XBOX) memset(&d3d->windowClass, 0, sizeof(d3d->windowClass)); - - d3d->windowClass.cbSize = sizeof(d3d->windowClass); - d3d->windowClass.style = CS_HREDRAW | CS_VREDRAW; - d3d->windowClass.lpfnWndProc = WindowProc; - d3d->windowClass.hInstance = NULL; - d3d->windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - d3d->windowClass.lpszClassName = "RetroArch"; - d3d->windowClass.hIcon = LoadIcon(GetModuleHandle(NULL), - MAKEINTRESOURCE(IDI_ICON)); - d3d->windowClass.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), - MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); - if (!info->fullscreen) - d3d->windowClass.hbrBackground = (HBRUSH)COLOR_WINDOW; - - RegisterClassEx(&d3d->windowClass); -#endif + win32_window_init(&d3d->windowClass, true); #ifdef HAVE_MONITOR - RECT mon_rect = d3d_monitor_rect(d3d); + bool windowed_full; + RECT mon_rect; + MONITORINFOEX current_mon; + HMONITOR hm_to_use; - bool windowed_full = settings->video.windowed_fullscreen; + win32_monitor_info(¤t_mon, &hm_to_use, &d3d->cur_mon_id); + mon_rect = current_mon.rcMonitor; + g_resize_width = info->width; + g_resize_height = info->height; + + windowed_full = settings->video.windowed_fullscreen; full_x = (windowed_full || info->width == 0) ? (mon_rect.right - mon_rect.left) : info->width; @@ -638,64 +624,74 @@ static bool d3d_construct(d3d_video_t *d3d, #ifndef _XBOX #ifdef HAVE_WINDOW + DWORD style; unsigned win_width, win_height; - char buffer[128] = {0}; RECT rect = {0}; + /* Windows only reports the refresh rates for modelines as + * an integer, so video.refresh_rate needs to be rounded. Also, account + * for black frame insertion using video.refresh_rate set to half + * of the display refresh rate, as well as higher vsync swap intervals. */ + float refresh_mod = settings->video.black_frame_insertion ? 2.0f : 1.0f; + unsigned refresh = roundf(settings->video.refresh_rate * refresh_mod * settings->video.swap_interval); video_driver_get_size(&win_width, &win_height); - if (!info->fullscreen) + if (info->fullscreen) { - video_driver_get_size((unsigned*)&rect.right, (unsigned*)&rect.bottom); - AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); - win_width = rect.right - rect.left; - win_height = rect.bottom - rect.top; + if (windowed_full) + { + style = WS_EX_TOPMOST | WS_POPUP; + g_resize_width = win_width = mon_rect.right - mon_rect.left; + g_resize_height = win_height = mon_rect.bottom - mon_rect.top; + } + else + { + style = WS_POPUP | WS_VISIBLE; + + if (!win32_monitor_set_fullscreen(win_width, win_height, + refresh, current_mon.szDevice)) + {} + + /* Display settings might have changed, get new coordinates. */ + GetMonitorInfo(hm_to_use, (MONITORINFO*)¤t_mon); + mon_rect = current_mon.rcMonitor; + } + } + else + { + style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + rect.right = win_width; + rect.bottom = win_height; + AdjustWindowRect(&rect, style, FALSE); + g_resize_width = win_width = rect.right - rect.left; + g_resize_height = win_height = rect.bottom - rect.top; } - video_monitor_get_fps(buffer, sizeof(buffer), NULL, 0); + win32_window_create(d3d, style, &mon_rect, win_width, + win_height, info->fullscreen); - strlcat(buffer, " || Direct3D", sizeof(buffer)); - - d3d->hWnd = CreateWindowEx(0, "RetroArch", buffer, - info->fullscreen ? - (WS_EX_TOPMOST | WS_POPUP) : WS_OVERLAPPEDWINDOW, - info->fullscreen ? mon_rect.left : CW_USEDEFAULT, - info->fullscreen ? mon_rect.top : CW_USEDEFAULT, - win_width, win_height, - NULL, NULL, NULL, d3d); - - driver->display_type = RARCH_DISPLAY_WIN32; - driver->video_display = 0; - driver->video_window = (uintptr_t)d3d->hWnd; -#endif -#endif - - gfx_ctx_show_mouse(d3d, !info->fullscreen -#ifdef HAVE_OVERLAY - || d3d->overlays_enabled -#endif - ); - - -#ifndef _XBOX - -#ifdef HAVE_WINDOW - if (!info->fullscreen && settings->ui.menubar_enable) + if (!info->fullscreen || windowed_full) { - RECT rc_temp = {0, 0, (LONG)win_height, 0x7FFF}; + if (!info->fullscreen && settings->ui.menubar_enable) + { + RECT rc_temp = {0, 0, (LONG)win_height, 0x7FFF}; - SetMenu(d3d->hWnd, LoadMenu(GetModuleHandle(NULL),MAKEINTRESOURCE(IDR_MENU))); - SendMessage(d3d->hWnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rc_temp); - win_height += rc_temp.top + rect.top; - SetWindowPos(d3d->hWnd, NULL, 0, 0, win_width, win_height, SWP_NOMOVE); + SetMenu(g_hwnd, LoadMenu(GetModuleHandle(NULL),MAKEINTRESOURCE(IDR_MENU))); + SendMessage(g_hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rc_temp); + g_resize_height = win_height += rc_temp.top + rect.top; + SetWindowPos(g_hwnd, NULL, 0, 0, win_width, win_height, SWP_NOMOVE); + } + + ShowWindow(g_hwnd, SW_RESTORE); + UpdateWindow(g_hwnd); + SetForegroundWindow(g_hwnd); + SetFocus(g_hwnd); } - - ShowWindow(d3d->hWnd, SW_RESTORE); - UpdateWindow(d3d->hWnd); - SetForegroundWindow(d3d->hWnd); - SetFocus(d3d->hWnd); #endif + win32_show_cursor(!info->fullscreen); + + #ifdef HAVE_SHADERS /* This should only be done once here * to avoid set_shader() to be overridden @@ -708,7 +704,6 @@ static bool d3d_construct(d3d_video_t *d3d, if (!d3d_process_shader(d3d)) return false; #endif - #endif d3d->video_info = *info; @@ -723,28 +718,23 @@ static bool d3d_construct(d3d_video_t *d3d, static void d3d_viewport_info(void *data, struct video_viewport *vp) { - unsigned width, height; - d3d_video_t *d3d = (d3d_video_t*)data; + d3d_video_t *d3d = (d3d_video_t*)data; - if (!d3d || !vp) + if (!d3d || !d3d->renderchain_driver || !d3d->renderchain_driver->viewport_info) return; - video_driver_get_size(&width, &height); - - vp->x = d3d->final_viewport.X; - vp->y = d3d->final_viewport.Y; - vp->width = d3d->final_viewport.Width; - vp->height = d3d->final_viewport.Height; - - vp->full_width = width; - vp->full_height = height; + d3d->renderchain_driver->viewport_info(d3d, vp); } static void d3d_set_rotation(void *data, unsigned rot) { d3d_video_t *d3d = (d3d_video_t*)data; - if (d3d) - d3d->dev_rotation = rot; + struct gfx_ortho ortho = {0, 1, 0, 1, -1, 1}; + + if (!d3d) + return; + + d3d->dev_rotation = rot; } static void d3d_show_mouse(void *data, bool state) @@ -835,6 +825,8 @@ static void *d3d_init(const video_info_t *info, goto error; } + vid->keep_aspect = info->force_aspect; + #ifdef _XBOX driver->video_data_own = true; driver->input_data_own = true; @@ -877,9 +869,7 @@ static void d3d_free(void *data) d3d->g_pD3D->Release(); #ifdef HAVE_MONITOR - monitor_last = MonitorFromWindow(d3d->hWnd, - MONITOR_DEFAULTTONEAREST); - DestroyWindow(d3d->hWnd); + win32_monitor_from_window(g_hwnd, true); #endif if (d3d) @@ -890,60 +880,7 @@ static void d3d_free(void *data) #endif } -#ifdef HAVE_MONITOR -static BOOL CALLBACK d3d_monitor_enum_proc(HMONITOR hMonitor, - HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -{ - monitor_all[monitor_count++] = hMonitor; - return TRUE; -} - -/* Multi-monitor support. */ -static RECT d3d_monitor_rect(d3d_video_t *d3d) -{ - unsigned fs_monitor, i; - MONITORINFOEX current_mon; - HMONITOR hm_to_use; - monitor_count = 0; - settings_t *settings = config_get_ptr(); - - EnumDisplayMonitors(NULL, NULL, d3d_monitor_enum_proc, 0); - - if (!monitor_last) - monitor_last = MonitorFromWindow( - GetDesktopWindow(), MONITOR_DEFAULTTONEAREST); - - hm_to_use = monitor_last; - fs_monitor = settings->video.monitor_index; - - if (fs_monitor && fs_monitor <= monitor_count - && monitor_all[fs_monitor - 1]) - { - hm_to_use = monitor_all[fs_monitor - 1]; - d3d->cur_mon_id = fs_monitor - 1; - } - else - { - for (i = 0; i < monitor_count; i++) - { - if (monitor_all[i] != hm_to_use) - continue; - - d3d->cur_mon_id = i; - break; - } - } - - memset(¤t_mon, 0, sizeof(current_mon)); - current_mon.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(hm_to_use, (MONITORINFO*)¤t_mon); - - return current_mon.rcMonitor; -} -#endif - #ifndef DONT_HAVE_STATE_TRACKER -#ifndef _XBOX static bool d3d_init_imports(d3d_video_t *d3d) { state_tracker_t *state_tracker = NULL; @@ -951,6 +888,8 @@ static bool d3d_init_imports(d3d_video_t *d3d) if (!d3d->shader.variables) return true; + if (!d3d->renderchain_driver->add_state_tracker) + return true; tracker_info.wram = (uint8_t*) core.retro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); @@ -976,10 +915,10 @@ static bool d3d_init_imports(d3d_video_t *d3d) } d3d->renderchain_driver->add_state_tracker(d3d->renderchain_data, state_tracker); + return true; } #endif -#endif static bool d3d_init_chain(d3d_video_t *d3d, const video_info_t *video_info) { @@ -1019,17 +958,13 @@ static bool d3d_init_chain(d3d_video_t *d3d, const video_info_t *video_info) return false; } -#ifdef _XBOX - if (!d3d->renderchain_driver->init(d3d, &d3d->video_info, + if ( + !d3d->renderchain_driver->init( + d3d, + &d3d->video_info, d3dr, &d3d->final_viewport, &link_info, - d3d->video_info.rgb32 ? - RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565)) -#else - if (!d3d->renderchain_driver->init(d3d->renderchain_data, &d3d->video_info, - d3dr, &d3d->final_viewport, &link_info, - d3d->video_info.rgb32 ? - RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565)) -#endif + d3d->video_info.rgb32) + ) { RARCH_ERR("[D3D]: Failed to init render chain.\n"); return false; @@ -1140,16 +1075,7 @@ static bool texture_image_render(d3d_video_t *d3d, d3d_set_vertex_shader(d3dr, D3DFVF_CUSTOMVERTEX, NULL); if (force_fullscreen) - { - D3DVIEWPORT vp = {0}; - vp.Width = w; - vp.Height = h; - vp.X = 0; - vp.Y = 0; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - d3d_set_viewport(d3dr, &vp); - } + d3d_set_viewport(d3d, w, h, force_fullscreen, false); d3d_draw_primitive(d3dr, D3DPT_QUADLIST, 0, 1); return true; @@ -1246,39 +1172,6 @@ static bool d3d_init_multipass(d3d_video_t *d3d) } #endif -static void d3d_set_font_rect(d3d_video_t *d3d, - const struct font_params *params) -{ - settings_t *settings = config_get_ptr(); - float pos_x = settings->video.msg_pos_x; - float pos_y = settings->video.msg_pos_y; - float font_size = settings->video.font_size; - - if (params) - { - pos_x = params->x; - pos_y = params->y; - font_size *= params->scale; - } - - if (!d3d) - return; - - d3d->font_rect.left = d3d->final_viewport.X + - d3d->final_viewport.Width * pos_x; - d3d->font_rect.right = d3d->final_viewport.X + - d3d->final_viewport.Width; - d3d->font_rect.top = d3d->final_viewport.Y + - (1.0f - pos_y) * d3d->final_viewport.Height - font_size; - d3d->font_rect.bottom = d3d->final_viewport.Height; - - d3d->font_rect_shifted = d3d->font_rect; - d3d->font_rect_shifted.left -= 2; - d3d->font_rect_shifted.right -= 2; - d3d->font_rect_shifted.top += 2; - d3d->font_rect_shifted.bottom += 2; -} - static bool d3d_init_singlepass(d3d_video_t *d3d) { #ifndef _XBOX @@ -1315,41 +1208,15 @@ static bool d3d_process_shader(d3d_video_t *d3d) return d3d_init_singlepass(d3d); } -#ifndef _XBOX -static bool d3d_init_luts(d3d_video_t *d3d) -{ - unsigned i; - settings_t *settings = config_get_ptr(); - - for (i = 0; i < d3d->shader.luts; i++) - { - bool ret = d3d->renderchain_driver->add_lut( - d3d->renderchain_data, - d3d->shader.lut[i].id, d3d->shader.lut[i].path, - d3d->shader.lut[i].filter == RARCH_FILTER_UNSPEC ? - settings->video.smooth : - (d3d->shader.lut[i].filter == RARCH_FILTER_LINEAR)); - - if (!ret) - return ret; - } - - return true; -} -#endif #ifdef HAVE_OVERLAY static void d3d_overlay_render(d3d_video_t *d3d, overlay_t *overlay) { + struct video_viewport vp; unsigned width, height; void *verts; unsigned i; - struct overlay_vertex - { - float x, y, z; - float u, v; - float r, g, b, a; - } vert[4]; + float vert[4][9]; float overlay_width, overlay_height; #ifndef _XBOX1 LPDIRECT3DVERTEXDECLARATION vertex_decl; @@ -1372,7 +1239,7 @@ static void d3d_overlay_render(d3d_video_t *d3d, overlay_t *overlay) if (!overlay->vert_buf) { - overlay->vert_buf = (LPDIRECT3DVERTEXBUFFER)d3d_vertex_buffer_new( + overlay->vert_buf = d3d_vertex_buffer_new( d3d->dev, sizeof(vert), 0, 0, D3DPOOL_MANAGED, NULL); if (!overlay->vert_buf) @@ -1381,41 +1248,45 @@ static void d3d_overlay_render(d3d_video_t *d3d, overlay_t *overlay) for (i = 0; i < 4; i++) { - vert[i].z = 0.5f; - vert[i].r = vert[i].g = vert[i].b = 1.0f; - vert[i].a = overlay->alpha_mod; + vert[i][2] = 0.5f; + vert[i][5] = 1.0f; + vert[i][6] = 1.0f; + vert[i][7] = 1.0f; + vert[i][8] = overlay->alpha_mod; } + + d3d_viewport_info(d3d, &vp); - overlay_width = d3d->final_viewport.Width; - overlay_height = d3d->final_viewport.Height; + overlay_width = vp.width; + overlay_height = vp.height; - vert[0].x = overlay->vert_coords.x * overlay_width; - vert[1].x = (overlay->vert_coords.x + overlay->vert_coords.w) + vert[0][0] = overlay->vert_coords[0] * overlay_width; + vert[1][0] = (overlay->vert_coords[0] + overlay->vert_coords[2]) * overlay_width; - vert[2].x = overlay->vert_coords.x * overlay_width; - vert[3].x = (overlay->vert_coords.x + overlay->vert_coords.w) + vert[2][0] = overlay->vert_coords[0] * overlay_width; + vert[3][0] = (overlay->vert_coords[0] + overlay->vert_coords[2]) * overlay_width; - vert[0].y = overlay->vert_coords.y * overlay_height; - vert[1].y = overlay->vert_coords.y * overlay_height; - vert[2].y = (overlay->vert_coords.y + overlay->vert_coords.h) + vert[0][1] = overlay->vert_coords[1] * overlay_height; + vert[1][1] = overlay->vert_coords[1] * overlay_height; + vert[2][1] = (overlay->vert_coords[1] + overlay->vert_coords[3]) * overlay_height; - vert[3].y = (overlay->vert_coords.y + overlay->vert_coords.h) + vert[3][1] = (overlay->vert_coords[1] + overlay->vert_coords[3]) * overlay_height; - vert[0].u = overlay->tex_coords.x; - vert[1].u = overlay->tex_coords.x + overlay->tex_coords.w; - vert[2].u = overlay->tex_coords.x; - vert[3].u = overlay->tex_coords.x + overlay->tex_coords.w; - vert[0].v = overlay->tex_coords.y; - vert[1].v = overlay->tex_coords.y; - vert[2].v = overlay->tex_coords.y + overlay->tex_coords.h; - vert[3].v = overlay->tex_coords.y + overlay->tex_coords.h; + vert[0][3] = overlay->tex_coords[0]; + vert[1][3] = overlay->tex_coords[0] + overlay->tex_coords[2]; + vert[2][3] = overlay->tex_coords[0]; + vert[3][3] = overlay->tex_coords[0] + overlay->tex_coords[2]; + vert[0][4] = overlay->tex_coords[1]; + vert[1][4] = overlay->tex_coords[1]; + vert[2][4] = overlay->tex_coords[1] + overlay->tex_coords[3]; + vert[3][4] = overlay->tex_coords[1] + overlay->tex_coords[3]; /* Align texels and vertices. */ for (i = 0; i < 4; i++) { - vert[i].x -= 0.5f; - vert[i].y += 0.5f; + vert[i][0] -= 0.5f; + vert[i][1] += 0.5f; } overlay->vert_buf->Lock(0, sizeof(vert), &verts, 0); @@ -1426,28 +1297,17 @@ static void d3d_overlay_render(d3d_video_t *d3d, overlay_t *overlay) #ifndef _XBOX1 d3d->dev->CreateVertexDeclaration(vElems, &vertex_decl); - d3d->dev->SetVertexDeclaration(vertex_decl); + d3d_set_vertex_declaration(d3d->dev, vertex_decl); vertex_decl->Release(); #endif d3d_set_stream_source(d3d->dev, 0, overlay->vert_buf, - 0, sizeof(overlay_vertex)); + 0, sizeof(*vert)); video_driver_get_size(&width, &height); if (overlay->fullscreen) - { - /* Set viewport to full window. */ - D3DVIEWPORT vp_full = {0}; - - vp_full.X = 0; - vp_full.Y = 0; - vp_full.Width = width; - vp_full.Height = height; - vp_full.MinZ = 0.0f; - vp_full.MaxZ = 1.0f; - d3d_set_viewport(d3d->dev, &vp_full); - } + d3d_set_viewport(d3d, width, height, true, false); /* Render overlay. */ d3d_set_texture(d3d->dev, 0, overlay->tex); @@ -1459,7 +1319,7 @@ static void d3d_overlay_render(d3d_video_t *d3d, overlay_t *overlay) /* Restore previous state. */ d3d_disable_blend_func(d3d->dev); - d3d_set_viewport(d3d->dev, &d3d->final_viewport); + d3d_set_viewport(d3d->dev, width, height, false, false); } static void d3d_free_overlay(d3d_video_t *d3d, overlay_t *overlay) @@ -1483,38 +1343,38 @@ static void d3d_free_overlays(d3d_video_t *d3d) d3d->overlays.clear(); } -static void d3d_overlay_tex_geom(void *data, +static void d3d_overlay_tex_geom( + void *data, unsigned index, float x, float y, float w, float h) { d3d_video_t *d3d = (d3d_video_t*)data; - if (!d3d) return; - d3d->overlays[index].tex_coords.x = x; - d3d->overlays[index].tex_coords.y = y; - d3d->overlays[index].tex_coords.w = w; - d3d->overlays[index].tex_coords.h = h; + d3d->overlays[index].tex_coords[0] = x; + d3d->overlays[index].tex_coords[1] = y; + d3d->overlays[index].tex_coords[2] = w; + d3d->overlays[index].tex_coords[3] = h; } -static void d3d_overlay_vertex_geom(void *data, +static void d3d_overlay_vertex_geom( + void *data, unsigned index, float x, float y, float w, float h) { d3d_video_t *d3d = (d3d_video_t*)data; - if (!d3d) return; - y = 1.0f - y; - h = -h; - d3d->overlays[index].vert_coords.x = x; - d3d->overlays[index].vert_coords.y = y; - d3d->overlays[index].vert_coords.w = w; - d3d->overlays[index].vert_coords.h = h; + y = 1.0f - y; + h = -h; + d3d->overlays[index].vert_coords[0] = x; + d3d->overlays[index].vert_coords[1] = y; + d3d->overlays[index].vert_coords[2] = w; + d3d->overlays[index].vert_coords[3] = h; } static bool d3d_overlay_load(void *data, @@ -1538,8 +1398,7 @@ static bool d3d_overlay_load(void *data, unsigned height = images[i].height; overlay_t *overlay = (overlay_t*)&d3d->overlays[i]; - overlay->tex = (LPDIRECT3DTEXTURE) - d3d_texture_new(d3d->dev, NULL, + overlay->tex = d3d_texture_new(d3d->dev, NULL, width, height, 1, 0, D3DFMT_A8R8G8B8, @@ -1552,8 +1411,8 @@ static bool d3d_overlay_load(void *data, return false; } - if (SUCCEEDED(overlay->tex->LockRect(0, &d3dlr, - NULL, D3DLOCK_NOSYSLOCK))) + if (d3d_lock_rectangle(overlay->tex, 0, &d3dlr, + NULL, 0, D3DLOCK_NOSYSLOCK)) { uint32_t *dst = (uint32_t*)(d3dlr.pBits); const uint32_t *src = images[i].pixels; @@ -1561,7 +1420,7 @@ static bool d3d_overlay_load(void *data, for (y = 0; y < height; y++, dst += pitch, src += width) memcpy(dst, src, width << 2); - overlay->tex->UnlockRect(0); + d3d_unlock_rectangle(overlay->tex); } overlay->tex_w = width; @@ -1628,7 +1487,6 @@ static bool d3d_frame(void *data, const void *frame, const char *msg) { unsigned width, height; - D3DVIEWPORT screen_vp; static struct retro_perf_counter d3d_frame = {0}; unsigned i = 0; d3d_video_t *d3d = (d3d_video_t*)data; @@ -1649,7 +1507,7 @@ static bool d3d_frame(void *data, const void *frame, #ifndef _XBOX /* We cannot recover in fullscreen. */ - if (d3d->needs_restore && IsIconic(d3d->hWnd)) + if (d3d->needs_restore && IsIconic(g_hwnd)) return true; #endif if (d3d->needs_restore && !d3d_restore(d3d)) @@ -1660,23 +1518,23 @@ static bool d3d_frame(void *data, const void *frame, if (d3d->should_resize) { - d3d_calculate_rect(d3d, width, width, d3d->video_info.force_aspect, - video_driver_get_aspect_ratio()); - - d3d->renderchain_driver->set_final_viewport(d3d, - d3d->renderchain_data, &d3d->final_viewport); + d3d_set_viewport(d3d, width, height, false, true); + if (d3d->renderchain_driver->set_final_viewport) + d3d->renderchain_driver->set_final_viewport(d3d, + d3d->renderchain_data, &d3d->final_viewport); d3d->should_resize = false; } /* render_chain() only clears out viewport, * clear out everything. */ - screen_vp.X = 0; - screen_vp.Y = 0; - screen_vp.MinZ = 0; - screen_vp.MaxZ = 1; - screen_vp.Width = width; - screen_vp.Height = height; + D3DVIEWPORT screen_vp; + screen_vp.X = 0; + screen_vp.Y = 0; + screen_vp.MinZ = 0; + screen_vp.MaxZ = 1; + screen_vp.Width = width; + screen_vp.Height = height; d3d_set_viewport(d3dr, &screen_vp); d3d_clear(d3dr, 0, 0, D3DCLEAR_TARGET, 0, 1, 0); @@ -1684,19 +1542,14 @@ static bool d3d_frame(void *data, const void *frame, * can screenshot, etc. */ if (settings->video.black_frame_insertion) { - d3d_swap(d3d, d3dr); - if (d3d->needs_restore) + if (!d3d_swap(d3d, d3dr) || d3d->needs_restore) return true; d3d_clear(d3dr, 0, 0, D3DCLEAR_TARGET, 0, 1, 0); } if ( !d3d->renderchain_driver->render( -#ifdef _XBOX d3d, -#else - d3d->renderchain_data, -#endif frame, frame_width, frame_height, pitch, d3d->dev_rotation)) { @@ -1723,11 +1576,9 @@ static bool d3d_frame(void *data, const void *frame, } #ifdef HAVE_MENU -#ifndef _XBOX if (d3d->menu && d3d->menu->enabled) d3d_overlay_render(d3d, d3d->menu); #endif -#endif #ifdef HAVE_OVERLAY if (d3d->overlays_enabled) @@ -1761,82 +1612,12 @@ static bool d3d_frame(void *data, const void *frame, static bool d3d_read_viewport(void *data, uint8_t *buffer) { - unsigned width, height; -#ifndef _XBOX - D3DLOCKED_RECT rect; - LPDIRECT3DSURFACE target = NULL; - LPDIRECT3DSURFACE dest = NULL; -#endif - bool ret = true; - d3d_video_t *d3d = (d3d_video_t*)data; - LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev; - static struct retro_perf_counter d3d_read_viewport = {0}; + d3d_video_t *d3d = (d3d_video_t*)data; - video_driver_get_size(&width, &height); + if (!d3d || !d3d->renderchain_driver || !d3d->renderchain_driver->read_viewport) + return false; - rarch_perf_init(&d3d_read_viewport, "d3d_read_viewport"); - retro_perf_start(&d3d_read_viewport); - - (void)data; - (void)buffer; - -#ifdef _XBOX - ret = false; -#else - if (FAILED(d3d->d3d_err = d3dr->GetRenderTarget(0, &target))) - { - ret = false; - goto end; - } - - if (FAILED(d3d->d3d_err = d3dr->CreateOffscreenPlainSurface( - width, height, - D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, - &dest, NULL))) - { - ret = false; - goto end; - } - - if (FAILED(d3d->d3d_err = d3dr->GetRenderTargetData(target, dest))) - { - ret = false; - goto end; - } - - if (SUCCEEDED(dest->LockRect(&rect, NULL, D3DLOCK_READONLY))) - { - unsigned x, y; - unsigned pitchpix = rect.Pitch / 4; - const uint32_t *pixels = (const uint32_t*)rect.pBits; - - pixels += d3d->final_viewport.X; - pixels += (d3d->final_viewport.Height - 1) * pitchpix; - pixels -= d3d->final_viewport.Y * pitchpix; - - for (y = 0; y < d3d->final_viewport.Height; y++, pixels -= pitchpix) - { - for (x = 0; x < d3d->final_viewport.Width; x++) - { - *buffer++ = (pixels[x] >> 0) & 0xff; - *buffer++ = (pixels[x] >> 8) & 0xff; - *buffer++ = (pixels[x] >> 16) & 0xff; - } - } - - dest->UnlockRect(); - } - else - ret = false; - -end: - retro_perf_stop(&d3d_read_viewport); - if (target) - target->Release(); - if (dest) - dest->Release(); -#endif - return ret; + return d3d->renderchain_driver->read_viewport(d3d, buffer); } static bool d3d_set_shader(void *data, @@ -1899,8 +1680,7 @@ static void d3d_set_menu_texture_frame(void *data, if (d3d->menu) d3d_texture_free(d3d->menu->tex); - d3d->menu->tex = (LPDIRECT3DTEXTURE) - d3d_texture_new(d3d->dev, NULL, + d3d->menu->tex = d3d_texture_new(d3d->dev, NULL, width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, 0, 0, 0, NULL, NULL); @@ -1917,11 +1697,8 @@ static void d3d_set_menu_texture_frame(void *data, d3d->menu->alpha_mod = alpha; -#ifdef _XBOX - d3d->menu->tex->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK); -#else - if (SUCCEEDED(d3d->menu->tex->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK))) -#endif + if (d3d_lock_rectangle(d3d->menu->tex, 0, &d3dlr, + NULL, 0, D3DLOCK_NOSYSLOCK)) { unsigned h, w; if (rgb32) @@ -1959,8 +1736,9 @@ static void d3d_set_menu_texture_frame(void *data, } } + if (d3d->menu) - d3d->menu->tex->UnlockRect(0); + d3d_unlock_rectangle(d3d->menu->tex); } } @@ -2017,7 +1795,7 @@ video_driver_t video_d3d = { d3d_set_shader, d3d_free, "d3d", - d3d_set_viewport_wrap, + d3d_set_viewport, d3d_set_rotation, d3d_viewport_info, d3d_read_viewport, diff --git a/gfx/d3d/d3d.h b/gfx/d3d/d3d.h index 8d4189263f..aeac8b959c 100644 --- a/gfx/d3d/d3d.h +++ b/gfx/d3d/d3d.h @@ -54,17 +54,14 @@ #include "../font_driver.h" #include "../font_renderer_driver.h" #include "../video_context_driver.h" +#include "../video_viewport.h" #include "d3d_wrapper.h" #include "render_chain_driver.h" typedef struct { - struct Coords - { - float x, y, w, h; - }; - Coords tex_coords; - Coords vert_coords; + float tex_coords[4]; + float vert_coords[4]; unsigned tex_w, tex_h; bool fullscreen; bool enabled; @@ -96,13 +93,12 @@ typedef struct gl_shader_backend gl_shader_backend_t; typedef struct d3d_video { uint64_t frame_count; + bool keep_aspect; bool should_resize; bool quitting; -#ifdef HAVE_WINDOW + struct video_viewport vp; WNDCLASSEX windowClass; -#endif - HWND hWnd; LPDIRECT3D g_pD3D; LPDIRECT3DDEVICE dev; HRESULT d3d_err; diff --git a/gfx/d3d/d3d_wrapper.cpp b/gfx/d3d/d3d_wrapper.cpp index ccc69791f8..306691325a 100644 --- a/gfx/d3d/d3d_wrapper.cpp +++ b/gfx/d3d/d3d_wrapper.cpp @@ -14,16 +14,28 @@ * If not, see . */ -#include "d3d.h" +#include + #include "d3d_wrapper.h" -#include "render_chain_driver.h" -void d3d_swap(void *data, LPDIRECT3DDEVICE dev) +static LPDIRECT3DDEVICE d3d_wrapper_dev; + +static bool d3d_restore_device(LPDIRECT3DDEVICE dev) { - d3d_video_t *d3d = (d3d_video_t*)data; + if (!dev) + { + if (!d3d_wrapper_dev) + return false; + dev = d3d_wrapper_dev; + } + d3d_wrapper_dev = dev; + return true; +} - if (!d3d) - return; +bool d3d_swap(void *data, LPDIRECT3DDEVICE dev) +{ + if (!d3d_restore_device(dev)) + return false; #if defined(_XBOX1) D3DDevice_Swap(0); @@ -33,14 +45,17 @@ void d3d_swap(void *data, LPDIRECT3DDEVICE dev) if (dev->Present(NULL, NULL, NULL, NULL) != D3D_OK) { RARCH_ERR("[D3D]: Present() failed.\n"); - d3d->needs_restore = true; + return false; } #endif + return true; } void d3d_set_transform(LPDIRECT3DDEVICE dev, D3DTRANSFORMSTATETYPE state, CONST D3DMATRIX *matrix) { + if (!d3d_restore_device(dev)) + return; #ifdef _XBOX1 D3DDevice_SetTransform(state, matrix); #elif !defined(_XBOX360) @@ -59,7 +74,7 @@ LPDIRECT3DTEXTURE d3d_texture_new(LPDIRECT3DDEVICE dev, HRESULT hr; LPDIRECT3DTEXTURE buf; - if (!dev) + if (!d3d_restore_device(dev)) return NULL; if (path) @@ -90,12 +105,27 @@ void d3d_texture_free(LPDIRECT3DTEXTURE tex) tex = NULL; } +bool d3d_vertex_declaration_new(LPDIRECT3DDEVICE dev, + const void *vertex_data, void **decl_data) +{ +#ifndef _XBOX1 + const D3DVERTEXELEMENT *vertex_elements = (const D3DVERTEXELEMENT*)vertex_data; + LPDIRECT3DVERTEXDECLARATION **vertex_decl = (LPDIRECT3DVERTEXDECLARATION**)decl_data; + if (SUCCEEDED(dev->CreateVertexDeclaration(vertex_elements, (IDirect3DVertexDeclaration9**)vertex_decl))) + return true; +#endif + return false; +} + LPDIRECT3DVERTEXBUFFER d3d_vertex_buffer_new(LPDIRECT3DDEVICE dev, unsigned length, unsigned usage, unsigned fvf, D3DPOOL pool, void *handle) { HRESULT hr; LPDIRECT3DVERTEXBUFFER buf; + + if (!d3d_restore_device(dev)) + return NULL; #ifndef _XBOX if (usage == 0) { @@ -175,6 +205,8 @@ void d3d_set_stream_source(LPDIRECT3DDEVICE dev, unsigned stream_no, LPDIRECT3DVERTEXBUFFER stream_vertbuf, unsigned offset_bytes, unsigned stride) { + if (!d3d_restore_device(dev)) + return; #if defined(HAVE_D3D8) IDirect3DDevice8_SetStreamSource(dev, stream_no, stream_vertbuf, stride); #elif defined(_XBOX360) @@ -188,6 +220,8 @@ void d3d_set_stream_source(LPDIRECT3DDEVICE dev, unsigned stream_no, void d3d_set_sampler_address_u(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned value) { + if (!d3d_restore_device(dev)) + return; #if defined(_XBOX1) D3D__DirtyFlags |= (D3DDIRTYFLAG_TEXTURE_STATE_0 << sampler); D3D__TextureState[sampler][D3DTSS_ADDRESSU] = value; @@ -201,6 +235,8 @@ void d3d_set_sampler_address_u(LPDIRECT3DDEVICE dev, void d3d_set_sampler_address_v(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned value) { + if (!d3d_restore_device(dev)) + return; #if defined(_XBOX1) D3D__DirtyFlags |= (D3DDIRTYFLAG_TEXTURE_STATE_0 << sampler); D3D__TextureState[sampler][D3DTSS_ADDRESSV] = value; @@ -214,6 +250,8 @@ void d3d_set_sampler_address_v(LPDIRECT3DDEVICE dev, void d3d_set_sampler_minfilter(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned value) { + if (!d3d_restore_device(dev)) + return; #if defined(_XBOX1) D3D__DirtyFlags |= (D3DDIRTYFLAG_TEXTURE_STATE_0 << sampler); D3D__TextureState[sampler][D3DTSS_MINFILTER] = value; @@ -227,6 +265,8 @@ void d3d_set_sampler_minfilter(LPDIRECT3DDEVICE dev, void d3d_set_sampler_magfilter(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned value) { + if (!d3d_restore_device(dev)) + return; #if defined(_XBOX1) D3D__DirtyFlags |= (D3DDIRTYFLAG_TEXTURE_STATE_0 << sampler); D3D__TextureState[sampler][D3DTSS_MAGFILTER] = value; @@ -240,6 +280,8 @@ void d3d_set_sampler_magfilter(LPDIRECT3DDEVICE dev, void d3d_draw_primitive(LPDIRECT3DDEVICE dev, D3DPRIMITIVETYPE type, unsigned start, unsigned count) { + if (!d3d_restore_device(dev)) + return; #if defined(_XBOX1) D3DDevice_DrawVertices(type, start, D3DVERTEXCOUNT(type, count)); #elif defined(_XBOX360) @@ -257,6 +299,8 @@ void d3d_clear(LPDIRECT3DDEVICE dev, unsigned count, const D3DRECT *rects, unsigned flags, D3DCOLOR color, float z, unsigned stencil) { + if (!d3d_restore_device(dev)) + return; #if defined(_XBOX1) D3DDevice_Clear(count, rects, flags, color, z, stencil); #elif defined(_XBOX360) @@ -267,25 +311,42 @@ void d3d_clear(LPDIRECT3DDEVICE dev, #endif } -void d3d_lockrectangle_clear(LPDIRECT3DTEXTURE tex, +bool d3d_lock_rectangle(LPDIRECT3DTEXTURE tex, unsigned level, D3DLOCKED_RECT *lock_rect, RECT *rect, unsigned rectangle_height, unsigned flags) { #if defined(_XBOX) D3DTexture_LockRect(tex, level, lock_rect, rect, flags); - memset(lock_rect->pBits, 0, rectangle_height * lock_rect->Pitch); + return true; #else if (SUCCEEDED(tex->LockRect(level, lock_rect, rect, flags))) - { - memset(lock_rect->pBits, level, rectangle_height * lock_rect->Pitch); - tex->UnlockRect(0); - } + return true; + return false; #endif } +void d3d_unlock_rectangle(LPDIRECT3DTEXTURE tex) +{ +#ifndef _XBOX + tex->UnlockRect(0); +#endif +} + +void d3d_lock_rectangle_clear(LPDIRECT3DTEXTURE tex, + unsigned level, D3DLOCKED_RECT *lock_rect, RECT *rect, + unsigned rectangle_height, unsigned flags) +{ +#if defined(_XBOX) + level = 0; +#endif + memset(lock_rect->pBits, level, rectangle_height * lock_rect->Pitch); + d3d_unlock_rectangle(tex); +} + void d3d_set_viewport(LPDIRECT3DDEVICE dev, D3DVIEWPORT *vp) { - (void)dev; + if (!d3d_restore_device(dev)) + return; #if defined(_XBOX360) D3DDevice_SetViewport(dev, vp); #elif defined(_XBOX1) @@ -298,6 +359,8 @@ void d3d_set_viewport(LPDIRECT3DDEVICE dev, D3DVIEWPORT *vp) void d3d_set_texture(LPDIRECT3DDEVICE dev, unsigned sampler, LPDIRECT3DTEXTURE tex) { + if (!d3d_restore_device(dev)) + return; #if defined(_XBOX1) D3DDevice_SetTexture(sampler, tex); #elif defined(_XBOX360) @@ -316,6 +379,8 @@ void d3d_set_texture(LPDIRECT3DDEVICE dev, unsigned sampler, HRESULT d3d_set_vertex_shader(LPDIRECT3DDEVICE dev, unsigned index, void *data) { + if (!d3d_restore_device(dev)) + return -1; #if defined(_XBOX1) return dev->SetVertexShader(index); #elif defined(_XBOX360) @@ -365,16 +430,30 @@ void d3d_texture_blit(unsigned pixel_size, #endif } +void d3d_set_render_state(void *data, D3DRENDERSTATETYPE state, DWORD value) +{ + LPDIRECT3DDEVICE dev = (LPDIRECT3DDEVICE)data; + + if (!dev) + return; + if (!d3d_restore_device(dev)) + return; + + dev->SetRenderState(state, value); +} + void d3d_enable_blend_func(void *data) { LPDIRECT3DDEVICE dev = (LPDIRECT3DDEVICE)data; if (!dev) return; + if (!d3d_restore_device(dev)) + return; - dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - dev->SetRenderState(D3DRS_ALPHABLENDENABLE, true); + d3d_set_render_state(dev, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + d3d_set_render_state(dev, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + d3d_set_render_state(dev, D3DRS_ALPHABLENDENABLE, true); } void d3d_enable_alpha_blend_texture_func(void *data) @@ -383,6 +462,8 @@ void d3d_enable_alpha_blend_texture_func(void *data) if (!dev) return; + if (!d3d_restore_device(dev)) + return; #ifndef _XBOX360 /* Also blend the texture with the set alpha value. */ @@ -400,6 +481,8 @@ void d3d_frame_postprocess(void *data) if (!dev) return; + if (!d3d_restore_device(dev)) + return; dev->SetFlickerFilter(global->console.screen.flicker_filter_index); dev->SetSoftDisplayFilter(global->console.softfilter_enable); @@ -412,8 +495,10 @@ void d3d_disable_blend_func(void *data) if (!dev) return; + if (!d3d_restore_device(dev)) + return; - dev->SetRenderState(D3DRS_ALPHABLENDENABLE, false); + d3d_set_render_state(dev, D3DRS_ALPHABLENDENABLE, false); } void d3d_set_vertex_declaration(void *data, void *vertex_data) @@ -424,6 +509,8 @@ void d3d_set_vertex_declaration(void *data, void *vertex_data) #endif if (!dev) return; + if (!d3d_restore_device(dev)) + return; #ifdef _XBOX1 d3d_set_vertex_shader(dev, D3DFVF_XYZ | D3DFVF_TEX1, NULL); #elif defined(HAVE_D3D9) diff --git a/gfx/d3d/d3d_wrapper.h b/gfx/d3d/d3d_wrapper.h index f2465747e2..fddd5a3174 100644 --- a/gfx/d3d/d3d_wrapper.h +++ b/gfx/d3d/d3d_wrapper.h @@ -17,10 +17,16 @@ #ifndef _D3D_WRAPPER_H #define _D3D_WRAPPER_H +#include + #include "../common/win32_common.h" #include "d3d_defines.h" -void d3d_swap(void *data, LPDIRECT3DDEVICE dev); +#ifdef __cplusplus +extern "C" { +#endif + +bool d3d_swap(void *data, LPDIRECT3DDEVICE dev); LPDIRECT3DVERTEXBUFFER d3d_vertex_buffer_new(LPDIRECT3DDEVICE dev, unsigned length, unsigned usage, unsigned fvf, @@ -66,10 +72,16 @@ void d3d_clear(LPDIRECT3DDEVICE dev, unsigned count, const D3DRECT *rects, unsigned flags, D3DCOLOR color, float z, unsigned stencil); -void d3d_lockrectangle_clear(LPDIRECT3DTEXTURE tex, +bool d3d_lock_rectangle(LPDIRECT3DTEXTURE tex, unsigned level, D3DLOCKED_RECT *lock_rect, RECT *rect, unsigned rectangle_height, unsigned flags); +void d3d_lock_rectangle_clear(LPDIRECT3DTEXTURE tex, + unsigned level, D3DLOCKED_RECT *lock_rect, RECT *rect, + unsigned rectangle_height, unsigned flags); + +void d3d_unlock_rectangle(LPDIRECT3DTEXTURE tex); + void d3d_set_texture(LPDIRECT3DDEVICE dev, unsigned sampler, LPDIRECT3DTEXTURE tex); @@ -81,6 +93,9 @@ void d3d_texture_blit(unsigned pixel_size, D3DLOCKED_RECT *lr, const void *frame, unsigned width, unsigned height, unsigned pitch); +bool d3d_vertex_declaration_new(LPDIRECT3DDEVICE dev, + const void *vertex_data, void **decl_data); + void d3d_set_viewport(LPDIRECT3DDEVICE dev, D3DVIEWPORT *vp); void d3d_enable_blend_func(void *data); @@ -93,4 +108,10 @@ void d3d_enable_alpha_blend_texture_func(void *data); void d3d_frame_postprocess(void *data); +void d3d_set_render_state(void *data, D3DRENDERSTATETYPE state, DWORD value); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/gfx/d3d/render_chain_cg.cpp b/gfx/d3d/render_chain_cg.cpp index 9edab74130..7e954e0923 100644 --- a/gfx/d3d/render_chain_cg.cpp +++ b/gfx/d3d/render_chain_cg.cpp @@ -88,21 +88,16 @@ static INLINE D3DTEXTUREFILTERTYPE translate_filter(unsigned type) switch (type) { - case RARCH_FILTER_UNSPEC: - return settings->video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT; - case RARCH_FILTER_LINEAR: - return D3DTEXF_LINEAR; - case RARCH_FILTER_NEAREST: - return D3DTEXF_POINT; + case RARCH_FILTER_UNSPEC: + if (!settings->video.smooth) + break; + /* fall-through */ + case RARCH_FILTER_LINEAR: + return D3DTEXF_LINEAR; + case RARCH_FILTER_NEAREST: + break; } - - return D3DTEXF_POINT; -} -static INLINE D3DTEXTUREFILTERTYPE translate_filter(bool smooth) -{ - if (smooth) - return D3DTEXF_LINEAR; return D3DTEXF_POINT; } @@ -191,12 +186,11 @@ static INLINE CGparameter find_param_from_semantic(CGprogram prog, return find_param_from_semantic(param, sem); } -static bool renderchain_compile_shaders(void *data, +static bool renderchain_compile_shaders(cg_renderchain_t *chain, void *fragment_data, void *vertex_data, const std::string &shader) { CGprogram *fPrg = (CGprogram*)fragment_data; CGprogram *vPrg = (CGprogram*)vertex_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; CGprofile vertex_profile = cgD3D9GetLatestVertexProfile(); CGprofile fragment_profile = cgD3D9GetLatestPixelProfile(); const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile); @@ -245,20 +239,14 @@ static bool renderchain_compile_shaders(void *data, return true; } -static void renderchain_set_shaders(void *data, void *fragment_data, void *vertex_data) +static INLINE void renderchain_set_shaders(void *data, CGprogram *fPrg, CGprogram *vPrg) { - CGprogram *fPrg = (CGprogram*)fragment_data; - CGprogram *vPrg = (CGprogram*)vertex_data; - cgD3D9BindProgram(*fPrg); cgD3D9BindProgram(*vPrg); } -#if 0 -static void cg_d3d9_renderchain_destroy_stock_shader(void *data) +static void cg_d3d9_renderchain_destroy_stock_shader(cg_renderchain_t *chain) { - cg_renderchain_t *chain = (cg_renderchain_t*)data; - if (!chain) return; @@ -268,10 +256,8 @@ static void cg_d3d9_renderchain_destroy_stock_shader(void *data) cgDestroyProgram(chain->vStock); } -static void renderchain_destroy_shader(void *data, int i) +static void renderchain_destroy_shader(cg_renderchain_t *chain, int i) { - cg_renderchain_t *chain = (cg_renderchain_t*)data; - if (!chain) return; @@ -280,10 +266,9 @@ static void renderchain_destroy_shader(void *data, int i) if (chain->passes[i].vPrg) cgDestroyProgram(chain->passes[i].vPrg); } -#endif -static void renderchain_set_shader_mvp(void *data, void *shader_data, void *matrix_data) +static void renderchain_set_shader_mvp(cg_renderchain_t *chain, void *shader_data, void *matrix_data) { CGprogram *vPrg = (CGprogram*)shader_data; const D3DXMATRIX *matrix = (const D3DXMATRIX*)matrix_data; @@ -298,15 +283,18 @@ static void renderchain_set_shader_mvp(void *data, void *shader_data, void *matr cgD3D9SetUniform(cgp, &val); \ } while(0) -static void renderchain_set_shader_params(void *data, void *pass_data, - unsigned video_w, unsigned video_h, - unsigned tex_w, unsigned tex_h, - unsigned viewport_w, unsigned viewport_h) +static void renderchain_set_shader_params(cg_renderchain_t *chain, + Pass *pass, + unsigned video_w, unsigned video_h, + unsigned tex_w, unsigned tex_h, + unsigned viewport_w, unsigned viewport_h) { float frame_cnt; D3DXVECTOR2 video_size, texture_size, output_size; - Pass *pass = (Pass*)pass_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; + + if (!chain || !pass) + return; + video_size.x = video_w; video_size.y = video_h; texture_size.x = tex_w; @@ -330,12 +318,11 @@ static void renderchain_set_shader_params(void *data, void *pass_data, set_cg_param(pass->vPrg, "IN.frame_count", frame_cnt); } -static void renderchain_bind_tracker(void *data, void *pass_data, unsigned pass_index) +static void renderchain_bind_tracker(cg_renderchain_t *chain, + Pass *pass, unsigned pass_index) { unsigned i; - Pass *pass = (Pass*)pass_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; - if (!chain->tracker) + if (!chain || !chain->tracker || !pass) return; if (pass_index == 1) @@ -369,8 +356,8 @@ static bool cg_d3d9_renderchain_init_shader_fvf(void *data, void *pass_data) bool texcoord0_taken = false; bool texcoord1_taken = false; bool stream_taken[4] = {false}; + cg_renderchain_t *chain = (cg_renderchain_t*)data; Pass *pass = (Pass*)pass_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; static const D3DVERTEXELEMENT decl_end = D3DDECL_END(); static const D3DVERTEXELEMENT position_decl = DECL_FVF_POSITION(0); static const D3DVERTEXELEMENT tex_coord0 = DECL_FVF_TEXCOORD(1, 3, 0); @@ -495,13 +482,12 @@ static bool cg_d3d9_renderchain_init_shader_fvf(void *data, void *pass_data) return true; } -static void renderchain_bind_orig(void *data, void *pass_data) +static void renderchain_bind_orig(cg_renderchain_t *chain, void *pass_data) { unsigned index; CGparameter param; D3DXVECTOR2 video_size, texture_size; Pass *pass = (Pass*)pass_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; video_size.x = chain->passes[0].last_width; video_size.y = chain->passes[0].last_height; texture_size.x = chain->passes[0].info.tex_w; @@ -536,7 +522,7 @@ static void renderchain_bind_orig(void *data, void *pass_data) } } -static void renderchain_bind_prev(void *data, void *pass_data) +static void renderchain_bind_prev(cg_renderchain_t *chain, void *pass_data) { unsigned i, index; D3DXVECTOR2 texture_size; @@ -545,7 +531,6 @@ static void renderchain_bind_prev(void *data, void *pass_data) char attr_tex_size[64] = {0}; char attr_coord[64] = {0}; Pass *pass = (Pass*)pass_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; static const char *prev_names[] = { "PREV", "PREV1", @@ -601,11 +586,11 @@ static void renderchain_bind_prev(void *data, void *pass_data) param = cgGetNamedParameter(pass->vPrg, attr_coord); if (param) { - LPDIRECT3DVERTEXBUFFER vert_buf; + LPDIRECT3DVERTEXBUFFER vert_buf = (LPDIRECT3DVERTEXBUFFER) + chain->prev.vertex_buf[(chain->prev.ptr - (i + 1)) & TEXTURESMASK]; index = pass->attrib_map[cgGetParameterResourceIndex(param)]; - vert_buf = (LPDIRECT3DVERTEXBUFFER) - chain->prev.vertex_buf[(chain->prev.ptr - (i + 1)) & TEXTURESMASK]; + chain->bound_vert.push_back(index); d3d_set_stream_source(chain->dev, index, vert_buf, 0, sizeof(Vertex)); @@ -622,19 +607,18 @@ static void cg_d3d9_renderchain_add_lut(void *data, d3d_set_texture(chain->dev, index, chain->luts[i].tex); d3d_set_sampler_magfilter(chain->dev, index, - translate_filter(chain->luts[i].smooth)); + translate_filter(chain->luts[i].smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST)); d3d_set_sampler_minfilter(chain->dev, index, - translate_filter(chain->luts[i].smooth)); + translate_filter(chain->luts[i].smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST)); d3d_set_sampler_address_u(chain->dev, index, D3DTADDRESS_BORDER); d3d_set_sampler_address_v(chain->dev, index, D3DTADDRESS_BORDER); chain->bound_tex.push_back(index); } -static void renderchain_bind_luts(void *data, void *pass_data) +static void renderchain_bind_luts(cg_renderchain_t *chain, + Pass *pass) { unsigned i, index; - Pass *pass = (Pass*)pass_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; for (i = 0; i < chain->luts.size(); i++) { @@ -661,11 +645,10 @@ static void renderchain_bind_luts(void *data, void *pass_data) } } -static void renderchain_bind_pass(void *data, void *pass_data, unsigned pass_index) +static void renderchain_bind_pass(cg_renderchain_t *chain, + Pass *pass, unsigned pass_index) { unsigned i, index; - Pass *pass = (Pass*)pass_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; /* We only bother binding passes which are two indices behind. */ if (pass_index < 3) @@ -724,19 +707,11 @@ static void renderchain_bind_pass(void *data, void *pass_data, unsigned pass_ind } } -#if 0 -static void cg_d3d9_renderchain_clear(void *data) +static void cg_d3d9_renderchain_clear_passes(cg_renderchain_t *chain) { unsigned i; - cg_renderchain_t *chain = (cg_renderchain_t*)data; - - for (i = 0; i < TEXTURES; i++) - { - if (chain->prev.tex[i]) - d3d_texture_free(chain->prev.tex[i]); - if (chain->prev.vertex_buf[i]) - d3d_vertex_buffer_free(chain->prev.vertex_buf[i], NULL); - } + if (chain->passes.size() == 0) + return; d3d_vertex_buffer_free(NULL, chain->passes[0].vertex_decl); @@ -747,6 +722,21 @@ static void cg_d3d9_renderchain_clear(void *data) d3d_vertex_buffer_free(chain->passes[i].vertex_buf, chain->passes[i].vertex_decl); renderchain_destroy_shader(chain, i); } +} + +static void cg_d3d9_renderchain_clear(cg_renderchain_t *chain) +{ + unsigned i; + + for (i = 0; i < TEXTURES; i++) + { + if (chain->prev.tex[i]) + d3d_texture_free(chain->prev.tex[i]); + if (chain->prev.vertex_buf[i]) + d3d_vertex_buffer_free(chain->prev.vertex_buf[i], NULL); + } + + cg_d3d9_renderchain_clear_passes(chain); for (i = 0; i < chain->luts.size(); i++) { @@ -754,15 +744,19 @@ static void cg_d3d9_renderchain_clear(void *data) d3d_texture_free(chain->luts[i].tex); } +#if 0 + if (chain->tracker) + state_tracker_free(chain->tracker); + chain->tracker = NULL; +#endif + chain->passes.clear(); chain->luts.clear(); } -#endif -static void cg_d3d9_renderchain_deinit_shader(void *data) +static void cg_d3d9_renderchain_deinit_shader(cg_renderchain_t *chain) { - cg_renderchain_t *chain = (cg_renderchain_t*)data; - if (!chain->cgCtx) + if (!chain || !chain->cgCtx) return; cgD3D9UnloadAllPrograms(); @@ -771,15 +765,11 @@ static void cg_d3d9_renderchain_deinit_shader(void *data) chain->cgCtx = NULL; } -#if 0 -static void cg_d3d9_renderchain_deinit(void *data) +static void cg_d3d9_renderchain_deinit(cg_renderchain_t *chain) { - cg_renderchain_t *renderchain = (cg_renderchain_t*)data; - - if (renderchain) - free(renderchain); + if (chain) + free(chain); } -#endif void cg_d3d9_renderchain_free(void *data) { @@ -788,17 +778,13 @@ void cg_d3d9_renderchain_free(void *data) if (!chain) return; - cg_d3d9_renderchain_deinit_shader(chain); -#if 0 cg_d3d9_renderchain_clear(chain); + cg_d3d9_renderchain_deinit_shader(chain); cg_d3d9_renderchain_destroy_stock_shader(chain); - if (chain->tracker) - state_tracker_free(chain->tracker); -#endif - //cg_d3d9_renderchain_deinit(); + cg_d3d9_renderchain_deinit(chain); } -void *cg_d3d9_renderchain_new(void) +static void *cg_d3d9_renderchain_new(void) { cg_renderchain_t *renderchain = (cg_renderchain_t*)calloc(1, sizeof(*renderchain)); if (!renderchain) @@ -822,13 +808,12 @@ static bool cg_d3d9_renderchain_init_shader(void *data, RARCH_LOG("[D3D]: Created shader context.\n"); - HRESULT ret = cgD3D9SetDevice(d3d->dev); + HRESULT ret = cgD3D9SetDevice((IDirect3DDevice9*)d3d->dev); if (FAILED(ret)) return false; return true; } - static void renderchain_log_info(void *data, const void *info_data) { const LinkInfo *info = (const LinkInfo*)info_data; @@ -874,14 +859,12 @@ static void renderchain_log_info(void *data, const void *info_data) info->pass->filter == RARCH_FILTER_LINEAR ? "true" : "false"); } -static bool renderchain_create_first_pass(void *data, const void *info_data, - unsigned fmt) +static bool renderchain_create_first_pass(cg_renderchain_t *chain, + const LinkInfo *info, unsigned fmt) { unsigned i; Pass pass; D3DXMATRIX ident; - const LinkInfo *info = (const LinkInfo*)info_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; LPDIRECT3DDEVICE d3dr = NULL; if (!chain) @@ -910,8 +893,8 @@ static bool renderchain_create_first_pass(void *data, const void *info_data, if (!chain->prev.vertex_buf[i]) return false; - chain->prev.tex[i] = (LPDIRECT3DTEXTURE)d3d_texture_new( - d3dr, NULL, info->tex_w, info->tex_h, 1, 0, + chain->prev.tex[i] = d3d_texture_new(d3dr, NULL, + info->tex_w, info->tex_h, 1, 0, (fmt == RETRO_PIXEL_FORMAT_RGB565) ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, 0, 0, 0, NULL, NULL); @@ -941,11 +924,13 @@ static bool cg_d3d9_renderchain_init(void *data, const void *_video_info, void *dev_, const void *final_viewport_, - const void *info_data, unsigned fmt) + const void *info_data, bool rgb32) { const LinkInfo *info = (const LinkInfo*)info_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; + d3d_video_t *d3d = (d3d_video_t*)data; + cg_renderchain_t *chain = (cg_renderchain_t*)d3d->renderchain_data; const video_info_t *video_info = (const video_info_t*)_video_info; + unsigned fmt = (rgb32) ? RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565; if (!chain) return false; @@ -966,10 +951,9 @@ static bool cg_d3d9_renderchain_init(void *data, return true; } -static bool renderchain_set_pass_size(void *data, unsigned pass_index, - unsigned width, unsigned height) +static bool renderchain_set_pass_size(cg_renderchain_t *chain, + unsigned pass_index, unsigned width, unsigned height) { - cg_renderchain_t *chain = (cg_renderchain_t*)data; LPDIRECT3DDEVICE d3dr = chain->dev; Pass *pass = (Pass*)&chain->passes[pass_index]; @@ -979,13 +963,13 @@ static bool renderchain_set_pass_size(void *data, unsigned pass_index, pass->info.tex_w = width; pass->info.tex_h = height; - pass->tex = (LPDIRECT3DTEXTURE)d3d_texture_new( - d3dr, NULL, width, height, 1, - D3DUSAGE_RENDERTARGET, - chain->passes.back().info.pass->fbo.fp_fbo ? - D3DFMT_A32B32G32R32F : D3DFMT_A8R8G8B8, - D3DPOOL_DEFAULT, 0, 0, 0, - NULL, NULL); + pass->tex = d3d_texture_new(d3dr, NULL, + width, height, 1, + D3DUSAGE_RENDERTARGET, + chain->passes.back().info.pass->fbo.fp_fbo ? + D3DFMT_A32B32G32R32F : D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, 0, 0, 0, + NULL, NULL); if (!pass->tex) return false; @@ -1043,8 +1027,8 @@ static void cg_d3d9_renderchain_convert_geometry( } } -static void d3d_recompute_pass_sizes(d3d_video_t *d3d, - void *renderchain_data) +static void d3d_recompute_pass_sizes(cg_renderchain_t *chain, + d3d_video_t *d3d) { unsigned i; LinkInfo link_info = {0}; @@ -1056,7 +1040,6 @@ static void d3d_recompute_pass_sizes(d3d_video_t *d3d, unsigned current_height = link_info.tex_h; unsigned out_width = 0; unsigned out_height = 0; - cg_renderchain_t *chain = (cg_renderchain_t*)renderchain_data; if (!renderchain_set_pass_size(chain, 0, current_width, current_height)) @@ -1099,7 +1082,7 @@ static void cg_d3d9_renderchain_set_final_viewport(void *data, if (chain) chain->final_viewport = (D3DVIEWPORT*)final_viewport; - d3d_recompute_pass_sizes(d3d, chain); + d3d_recompute_pass_sizes(chain, d3d); } static bool cg_d3d9_renderchain_add_pass(void *data, const void *info_data) @@ -1119,7 +1102,7 @@ static bool cg_d3d9_renderchain_add_pass(void *data, const void *info_data) if (!cg_d3d9_renderchain_init_shader_fvf(chain, &pass)) return false; - pass.vertex_buf = (LPDIRECT3DVERTEXBUFFER)d3d_vertex_buffer_new(d3dr, 4 * sizeof(Vertex), + pass.vertex_buf = d3d_vertex_buffer_new(d3dr, 4 * sizeof(Vertex), 0, 0, D3DPOOL_DEFAULT, NULL); if (!pass.vertex_buf) @@ -1149,10 +1132,9 @@ static bool cg_d3d9_renderchain_add_lut(void *data, const char *id, const char *path, bool smooth) { lut_info info; - cg_renderchain_t *chain = (cg_renderchain_t*)data; + cg_renderchain_t *chain = (cg_renderchain_t*)data; LPDIRECT3DDEVICE d3dr = chain->dev; - LPDIRECT3DTEXTURE lut = (LPDIRECT3DTEXTURE) - d3d_texture_new(d3dr, + LPDIRECT3DTEXTURE lut = d3d_texture_new(d3dr, path, D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, @@ -1194,10 +1176,8 @@ static void cg_d3d9_renderchain_add_state_tracker( chain->tracker = tracker; } -static void renderchain_start_render(void *data) +static void renderchain_start_render(cg_renderchain_t *chain) { - cg_renderchain_t *chain = (cg_renderchain_t*)data; - if (!chain) return; @@ -1207,10 +1187,8 @@ static void renderchain_start_render(void *data) chain->passes[0].last_height = chain->prev.last_height[chain->prev.ptr]; } -static void renderchain_end_render(void *data) +static void renderchain_end_render(cg_renderchain_t *chain) { - cg_renderchain_t *chain = (cg_renderchain_t*)data; - if (!chain) return; @@ -1219,13 +1197,14 @@ static void renderchain_end_render(void *data) chain->prev.ptr = (chain->prev.ptr + 1) & TEXTURESMASK; } -static void renderchain_set_mvp(void *data, void *vertex_program, +static void renderchain_set_mvp( + cg_renderchain_t *chain, + void *vertex_program, unsigned vp_width, unsigned vp_height, unsigned rotation) { D3DXMATRIX proj, ortho, rot, tmp; CGprogram vPrg = (CGprogram)vertex_program; - cg_renderchain_t *chain = (cg_renderchain_t*)data; if (!chain) return; @@ -1241,14 +1220,13 @@ static void renderchain_set_mvp(void *data, void *vertex_program, } static void renderchain_set_vertices( - void *data, void *pass_data, + cg_renderchain_t *chain, + Pass *pass, unsigned width, unsigned height, unsigned out_width, unsigned out_height, unsigned vp_width, unsigned vp_height, unsigned rotation) { - Pass *pass = (Pass*)pass_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; const LinkInfo *info = (const LinkInfo*)&pass->info; if (pass->last_width != width || pass->last_height != height) @@ -1327,18 +1305,20 @@ static void renderchain_set_viewport(void *data, void *viewport_data) d3d_set_viewport(d3dr, vp); } -static void renderchain_blit_to_texture(void *data, +static void renderchain_blit_to_texture( + cg_renderchain_t *chain, const void *frame, unsigned width, unsigned height, unsigned pitch) { D3DLOCKED_RECT d3dlr; - cg_renderchain_t *chain = (cg_renderchain_t*)data; Pass *first = (Pass*)&chain->passes[0]; if (first->last_width != width || first->last_height != height) { - d3d_lockrectangle_clear(first->tex, 0, &d3dlr, + d3d_lock_rectangle(first->tex, 0, &d3dlr, + NULL, first->info.tex_h, D3DLOCK_NOSYSLOCK); + d3d_lock_rectangle_clear(first->tex, 0, &d3dlr, NULL, first->info.tex_h, D3DLOCK_NOSYSLOCK); } @@ -1346,10 +1326,9 @@ static void renderchain_blit_to_texture(void *data, &d3dlr, frame, width, height, pitch); } -static void renderchain_unbind_all(void *data) +static void renderchain_unbind_all(cg_renderchain_t *chain) { unsigned i; - cg_renderchain_t *chain = (cg_renderchain_t*)data; LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)chain->dev; /* Have to be a bit anal about it. @@ -1371,12 +1350,18 @@ static void renderchain_unbind_all(void *data) chain->bound_vert.clear(); } -static void renderchain_render_pass(void *data, void *pass_data, unsigned pass_index) +static void renderchain_render_pass( + cg_renderchain_t *chain, + Pass *pass, + unsigned pass_index) { unsigned i; - Pass *pass = (Pass*)pass_data; - cg_renderchain_t *chain = (cg_renderchain_t*)data; - LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)chain->dev; + LPDIRECT3DDEVICE d3dr; + + if (!chain) + return; + + d3dr = (LPDIRECT3DDEVICE)chain->dev; renderchain_set_shaders(chain, &pass->fPrg, &pass->vPrg); @@ -1407,14 +1392,21 @@ static void renderchain_render_pass(void *data, void *pass_data, unsigned pass_i renderchain_unbind_all(chain); } -static bool cg_d3d9_renderchain_render(void *chain_data, const void *data, - unsigned width, unsigned height, unsigned pitch, unsigned rotation) +static bool cg_d3d9_renderchain_render( + void *data, + const void *frame_data, + unsigned width, unsigned height, + unsigned pitch, unsigned rotation) { Pass *last_pass; + LPDIRECT3DDEVICE d3dr; LPDIRECT3DSURFACE back_buffer, target; unsigned i, current_width, current_height, out_width = 0, out_height = 0; - cg_renderchain_t *chain = (cg_renderchain_t*)chain_data; - LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)chain->dev; + d3d_video_t *d3d = (d3d_video_t*)data; + cg_renderchain_t *chain = d3d ? (cg_renderchain_t*)d3d->renderchain_data : NULL; + + if (chain) + d3dr = (LPDIRECT3DDEVICE)chain->dev; renderchain_start_render(chain); @@ -1424,7 +1416,7 @@ static bool cg_d3d9_renderchain_render(void *chain_data, const void *data, &out_width, &out_height, current_width, current_height, chain->final_viewport); - renderchain_blit_to_texture(chain, data, width, height, pitch); + renderchain_blit_to_texture(chain, frame_data, width, height, pitch); /* Grab back buffer. */ d3dr->GetRenderTarget(0, &back_buffer); @@ -1496,6 +1488,132 @@ static bool cg_d3d9_renderchain_render(void *chain_data, const void *data, return true; } +static void cg_d3d9_renderchain_set_font_rect(void *data, const void *font_data) +{ + settings_t *settings = config_get_ptr(); + d3d_video_t *d3d = (d3d_video_t*)data; + float pos_x = settings->video.msg_pos_x; + float pos_y = settings->video.msg_pos_y; + float font_size = settings->video.font_size; + const struct font_params *params = (const struct font_params*)font_data; + + if (params) + { + pos_x = params->x; + pos_y = params->y; + font_size *= params->scale; + } + + if (!d3d) + return; + + d3d->font_rect.left = d3d->final_viewport.X + + d3d->final_viewport.Width * pos_x; + d3d->font_rect.right = d3d->final_viewport.X + + d3d->final_viewport.Width; + d3d->font_rect.top = d3d->final_viewport.Y + + (1.0f - pos_y) * d3d->final_viewport.Height - font_size; + d3d->font_rect.bottom = d3d->final_viewport.Height; + + d3d->font_rect_shifted = d3d->font_rect; + d3d->font_rect_shifted.left -= 2; + d3d->font_rect_shifted.right -= 2; + d3d->font_rect_shifted.top += 2; + d3d->font_rect_shifted.bottom += 2; +} + +static bool cg_d3d9_renderchain_read_viewport(void *data, uint8_t *buffer) +{ + unsigned width, height; + D3DLOCKED_RECT rect; + LPDIRECT3DSURFACE target = NULL; + LPDIRECT3DSURFACE dest = NULL; + bool ret = true; + d3d_video_t *d3d = (d3d_video_t*)data; LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev; + static struct retro_perf_counter d3d_read_viewport = {0}; + + video_driver_get_size(&width, &height); + + rarch_perf_init(&d3d_read_viewport, "d3d_read_viewport"); + retro_perf_start(&d3d_read_viewport); + + (void)data; + (void)buffer; + + if (FAILED(d3d->d3d_err = d3dr->GetRenderTarget(0, &target))) + { + ret = false; + goto end; + } + + if (FAILED(d3d->d3d_err = d3dr->CreateOffscreenPlainSurface( + width, height, + D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, + &dest, NULL))) + { + ret = false; + goto end; + } + + if (FAILED(d3d->d3d_err = d3dr->GetRenderTargetData(target, dest))) + { + ret = false; + goto end; + } + + if (SUCCEEDED(dest->LockRect(&rect, NULL, D3DLOCK_READONLY))) + { + unsigned x, y; + unsigned pitchpix = rect.Pitch / 4; + const uint32_t *pixels = (const uint32_t*)rect.pBits; + + pixels += d3d->final_viewport.X; + pixels += (d3d->final_viewport.Height - 1) * pitchpix; + pixels -= d3d->final_viewport.Y * pitchpix; + + for (y = 0; y < d3d->final_viewport.Height; y++, pixels -= pitchpix) + { + for (x = 0; x < d3d->final_viewport.Width; x++) + { + *buffer++ = (pixels[x] >> 0) & 0xff; + *buffer++ = (pixels[x] >> 8) & 0xff; + *buffer++ = (pixels[x] >> 16) & 0xff; + } + } + + dest->UnlockRect(); + } + else + ret = false; + +end: + retro_perf_stop(&d3d_read_viewport); + if (target) + target->Release(); + if (dest) + dest->Release(); + return ret; +} + +static void cg_d3d9_renderchain_viewport_info(void *data, struct video_viewport *vp) +{ + unsigned width, height; + d3d_video_t *d3d = (d3d_video_t*)data; + + if (!d3d || !vp) + return; + + video_driver_get_size(&width, &height); + + vp->x = d3d->final_viewport.X; + vp->y = d3d->final_viewport.Y; + vp->width = d3d->final_viewport.Width; + vp->height = d3d->final_viewport.Height; + + vp->full_width = width; + vp->full_height = height; +} + renderchain_driver_t cg_d3d9_renderchain = { cg_d3d9_renderchain_free, cg_d3d9_renderchain_new, @@ -1509,5 +1627,8 @@ renderchain_driver_t cg_d3d9_renderchain = { cg_d3d9_renderchain_add_state_tracker, cg_d3d9_renderchain_render, cg_d3d9_renderchain_convert_geometry, + cg_d3d9_renderchain_set_font_rect, + cg_d3d9_renderchain_read_viewport, + cg_d3d9_renderchain_viewport_info, "cg_d3d9", }; diff --git a/gfx/d3d/render_chain_driver.h b/gfx/d3d/render_chain_driver.h index a92012f6bd..836f335871 100644 --- a/gfx/d3d/render_chain_driver.h +++ b/gfx/d3d/render_chain_driver.h @@ -17,8 +17,9 @@ #ifndef __D3D_RENDER_CHAIN_H #define __D3D_RENDER_CHAIN_H -#include "../video_state_tracker.h" #include "../video_shader_parse.h" +#include "../video_state_tracker.h" +#include "../video_viewport.h" #include "../../libretro.h" #include "d3d_defines.h" @@ -52,7 +53,7 @@ typedef struct renderchain_driver void *dev_data, const void *final_viewport_data, const void *info_data, - unsigned fmt); + bool rgb32); void (*set_final_viewport)(void *data, void *renderchain_data, const void *viewport_data); bool (*add_pass)(void *data, const void *info_data); @@ -66,6 +67,9 @@ typedef struct renderchain_driver unsigned *out_width, unsigned *out_height, unsigned width, unsigned height, void *final_viewport); + void (*set_font_rect)(void *data, const void *param_data); + bool (*read_viewport)(void *data, uint8_t *buffer); + void (*viewport_info)(void *data, struct video_viewport *vp); const char *ident; } renderchain_driver_t; diff --git a/gfx/d3d/render_chain_null.c b/gfx/d3d/render_chain_null.c index c178ed90e1..4bb794665a 100644 --- a/gfx/d3d/render_chain_null.c +++ b/gfx/d3d/render_chain_null.c @@ -48,7 +48,7 @@ static bool null_renderchain_init(void *data, void *dev_data, const void *final_viewport_data, const void *info_data, - unsigned fmt + bool rgb32 ) { (void)data; @@ -56,7 +56,7 @@ static bool null_renderchain_init(void *data, (void)dev_data; (void)final_viewport_data; (void)info_data; - (void)fmt; + (void)rgb32; return true; } @@ -144,5 +144,8 @@ renderchain_driver_t null_renderchain = { null_renderchain_add_state_tracker, null_renderchain_render, null_renderchain_convert_geometry, + NULL, + NULL, + NULL, "null", }; diff --git a/gfx/d3d/render_chain_xdk.cpp b/gfx/d3d/render_chain_xdk.cpp index 91efc2ba49..bc6260affd 100644 --- a/gfx/d3d/render_chain_xdk.cpp +++ b/gfx/d3d/render_chain_xdk.cpp @@ -20,7 +20,6 @@ typedef struct xdk_renderchain { - void *empty; unsigned pixel_size; LPDIRECT3DDEVICE dev; const video_info_t *video_info; @@ -105,7 +104,7 @@ static bool renderchain_create_first_pass(void *data, if (!chain->vertex_buf) return false; - chain->tex = (LPDIRECT3DTEXTURE)d3d_texture_new(d3dr, NULL, + chain->tex = d3d_texture_new(d3dr, NULL, chain->tex_w, chain->tex_h, 1, 0, info->rgb32 ? D3DFMT_LIN_X8R8G8B8 : D3DFMT_LIN_R5G6B5, 0, 0, 0, 0, NULL, NULL); @@ -116,10 +115,10 @@ static bool renderchain_create_first_pass(void *data, d3d_set_sampler_address_u(d3dr, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); d3d_set_sampler_address_v(d3dr, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); #ifdef _XBOX1 - d3dr->SetRenderState(D3DRS_LIGHTING, FALSE); + d3d_set_render_state(d3dr, D3DRS_LIGHTING, 0); #endif - d3dr->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - d3dr->SetRenderState(D3DRS_ZENABLE, FALSE); + d3d_set_render_state(d3dr, D3DRS_CULLMODE, D3DCULL_NONE); + d3d_set_render_state(d3dr, D3DRS_ZENABLE, FALSE); if (!xdk_renderchain_init_shader_fvf(chain, chain)) return false; @@ -234,7 +233,9 @@ static void renderchain_blit_to_texture(void *data, const void *frame, if (chain->last_width != width || chain->last_height != height) { - d3d_lockrectangle_clear(chain->tex, + d3d_lock_rectangle(chain->tex, + 0, &d3dlr, NULL, chain->tex_h, D3DLOCK_NOSYSLOCK); + d3d_lock_rectangle_clear(chain->tex, 0, &d3dlr, NULL, chain->tex_h, D3DLOCK_NOSYSLOCK); } @@ -317,7 +318,7 @@ static bool xdk_renderchain_init(void *data, void *dev_data, const void *final_viewport_data, const void *info_data, - unsigned fmt + bool rgb32 ) { unsigned width, height; @@ -327,8 +328,8 @@ static bool xdk_renderchain_init(void *data, const video_info_t *video_info = (const video_info_t*)_video_info; const LinkInfo *link_info = (const LinkInfo*)info_data; xdk_renderchain_t *chain = (xdk_renderchain_t*)d3d->renderchain_data; + unsigned fmt = (rgb32) ? RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565; (void)final_viewport_data; - (void)fmt; video_driver_get_size(&width, &height); @@ -459,6 +460,25 @@ static bool xdk_renderchain_reinit(void *data, return true; } +static void xdk_renderchain_viewport_info(void *data, struct video_viewport *vp) +{ + unsigned width, height; + d3d_video_t *d3d = (d3d_video_t*)data; + + if (!d3d || !vp) + return; + + video_driver_get_size(&width, &height); + + vp->x = d3d->final_viewport.X; + vp->y = d3d->final_viewport.Y; + vp->width = d3d->final_viewport.Width; + vp->height = d3d->final_viewport.Height; + + vp->full_width = width; + vp->full_height = height; +} + renderchain_driver_t xdk_renderchain = { xdk_renderchain_free, xdk_renderchain_new, @@ -472,5 +492,8 @@ renderchain_driver_t xdk_renderchain = { xdk_renderchain_add_state_tracker, xdk_renderchain_render, xdk_renderchain_convert_geometry, + NULL, + NULL, + xdk_renderchain_viewport_info, "xdk", }; diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index 342025926d..8a2f49cedf 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -536,7 +536,8 @@ static bool ctr_frame(void* data, const void* frame, { if(((((u32)(frame)) >= 0x14000000 && ((u32)(frame)) < 0x40000000)) /* frame in linear memory */ && !((u32)frame & 0x7F) /* 128-byte aligned */ - && !((pitch) & 0xF)) /* 16-byte aligned */ + && !(pitch & 0xF) /* 16-byte aligned */ + && (pitch > 0x40)) { /* can copy the buffer directly with the GPU */ ctrGuCopyImage(false, frame, pitch / (ctr->rgb32? 4: 2), height, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, false, @@ -562,6 +563,12 @@ static bool ctr_frame(void* data, const void* frame, } + ctr->frame_coords->u = width; + ctr->frame_coords->v = height; + GSPGPU_FlushDataCache(ctr->frame_coords, sizeof(ctr_vertex_t)); + + ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->frame_coords)); + ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->scale_vector, 1); } ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(ctr->texture_swizzled), ctr->texture_width, ctr->texture_height, @@ -570,13 +577,6 @@ static bool ctr_frame(void* data, const void* frame, GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE), ctr->rgb32 ? GPU_RGBA8: GPU_RGB565); - ctr->frame_coords->u = width; - ctr->frame_coords->v = height; - GSPGPU_FlushDataCache(ctr->frame_coords, sizeof(ctr_vertex_t)); - - ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->frame_coords)); - ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->scale_vector, 1); - /* ARGB --> RGBA */ if (ctr->rgb32) { diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index df14b84dcf..ab254a99ec 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -19,30 +19,33 @@ #pragma comment(lib, "opengl32") #endif +#include +#include +#include +#include + +#include + #include "../../driver.h" #include "../../performance.h" #include +#include #include #include -#include #include "../../libretro.h" -#include -#include #include "../../general.h" #include "../../retroarch.h" -#include #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "gl_common.h" #include "../font_driver.h" #include "../video_viewport.h" #include "../video_pixel_converter.h" #include "../video_context_driver.h" -#include +#include "../video_texture.h" #ifdef HAVE_GLSL #include "../drivers_shader/shader_glsl.h" diff --git a/gfx/drivers/gl_common.c b/gfx/drivers/gl_common.c index 944e132630..9d6a629b06 100644 --- a/gfx/drivers/gl_common.c +++ b/gfx/drivers/gl_common.c @@ -15,6 +15,7 @@ */ #include "gl_common.h" +#include "../video_texture.h" void gl_ff_vertex(const void *data) { @@ -48,68 +49,6 @@ void gl_ff_matrix(const void *data) #endif } -void gl_load_texture_data(GLuint id, - enum gfx_wrap_type wrap_type, - enum texture_filter_type filter_type, - unsigned alignment, - unsigned width, unsigned height, - const void *frame, unsigned base_size) -{ - GLint mag_filter, min_filter; - bool want_mipmap = false; - bool rgb32 = (base_size == (sizeof(uint32_t))); - driver_t *driver = driver_get_ptr(); - GLenum wrap = gl_wrap_type_to_enum(wrap_type); - - glBindTexture(GL_TEXTURE_2D, id); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); - -#if defined(HAVE_OPENGLES2) || defined(HAVE_PSGL) || defined(OSX_PPC) - if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR) - filter_type = TEXTURE_FILTER_LINEAR; - if (filter_type == TEXTURE_FILTER_MIPMAP_NEAREST) - filter_type = TEXTURE_FILTER_NEAREST; -#endif - - switch (filter_type) - { - case TEXTURE_FILTER_MIPMAP_LINEAR: - min_filter = GL_LINEAR_MIPMAP_NEAREST; - mag_filter = GL_LINEAR; - want_mipmap = true; - break; - case TEXTURE_FILTER_MIPMAP_NEAREST: - min_filter = GL_NEAREST_MIPMAP_NEAREST; - mag_filter = GL_NEAREST; - want_mipmap = true; - break; - case TEXTURE_FILTER_NEAREST: - min_filter = GL_NEAREST; - mag_filter = GL_NEAREST; - break; - case TEXTURE_FILTER_LINEAR: - default: - min_filter = GL_LINEAR; - mag_filter = GL_LINEAR; - break; - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); - - glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); - glTexImage2D(GL_TEXTURE_2D, - 0, - (driver->gfx_use_rgba || !rgb32) ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, - width, height, 0, - (driver->gfx_use_rgba || !rgb32) ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, - (rgb32) ? RARCH_GL_FORMAT32 : GL_UNSIGNED_SHORT_4_4_4_4, frame); - - if (want_mipmap) - glGenerateMipmap(GL_TEXTURE_2D); -} - bool gl_load_luts(const struct video_shader *shader, GLuint *textures_lut) { diff --git a/gfx/drivers/gl_common.h b/gfx/drivers/gl_common.h index c4c21a89c6..571115ac80 100644 --- a/gfx/drivers/gl_common.h +++ b/gfx/drivers/gl_common.h @@ -333,14 +333,6 @@ static INLINE bool gl_check_error(void) return false; } -void gl_load_texture_data(GLuint id, - enum gfx_wrap_type wrap_type, - enum texture_filter_type filter_type, - unsigned alignment, - unsigned width, unsigned height, - const void *frame, - unsigned base_size); - bool gl_load_luts(const struct video_shader *generic_shader, GLuint *lut_textures); diff --git a/gfx/drivers/vg.c b/gfx/drivers/vg.c index 17ee516368..694ac737e3 100644 --- a/gfx/drivers/vg.c +++ b/gfx/drivers/vg.c @@ -36,7 +36,7 @@ typedef struct { bool should_resize; float mScreenAspect; - bool mKeepAspect; + bool keep_aspect; bool mEglImageBuf; unsigned mTextureWidth; unsigned mTextureHeight; @@ -111,8 +111,8 @@ static void *vg_init(const video_info_t *video, const input_driver_t **input, vo gfx_ctx_update_window_title(vg); - vg->mTexType = video->rgb32 ? VG_sXRGB_8888 : VG_sRGB_565; - vg->mKeepAspect = video->force_aspect; + vg->mTexType = video->rgb32 ? VG_sXRGB_8888 : VG_sRGB_565; + vg->keep_aspect = video->force_aspect; unsigned win_width = video->width; unsigned win_height = video->height; @@ -233,7 +233,7 @@ static void vg_calculate_quad(vg_t *vg) video_driver_get_size(&width, &height); /* set viewport for aspect ratio, taken from the OpenGL driver. */ - if (vg->mKeepAspect) + if (vg->keep_aspect) { float desired_aspect = video_driver_get_aspect_ratio(); diff --git a/gfx/drivers_context/androidegl_ctx.c b/gfx/drivers_context/androidegl_ctx.c index ba705aea97..206d62227b 100644 --- a/gfx/drivers_context/androidegl_ctx.c +++ b/gfx/drivers_context/androidegl_ctx.c @@ -438,9 +438,8 @@ static void dpi_get_density(char *s, size_t len) static bool android_gfx_ctx_get_metrics(void *data, enum display_metric_types type, float *value) { - int dpi; + static int dpi = -1; char density[PROP_VALUE_MAX] = {0}; - dpi_get_density(density, sizeof(density)); switch (type) { @@ -449,9 +448,13 @@ static bool android_gfx_ctx_get_metrics(void *data, case DISPLAY_METRIC_MM_HEIGHT: return false; case DISPLAY_METRIC_DPI: - if (density[0] == '\0') - return false; - dpi = atoi(density); + if (dpi == -1) + { + dpi_get_density(density, sizeof(density)); + if (density[0] == '\0') + return false; + dpi = atoi(density); + } *value = (float)dpi; break; case DISPLAY_METRIC_NONE: diff --git a/gfx/drivers_context/d3d_ctx.cpp b/gfx/drivers_context/d3d_ctx.cpp index 005e5bcfe9..1ab7fe2720 100644 --- a/gfx/drivers_context/d3d_ctx.cpp +++ b/gfx/drivers_context/d3d_ctx.cpp @@ -45,9 +45,8 @@ static bool widescreen_mode = false; #endif -static d3d_video_t *curD3D = NULL; -static bool d3d_quit = false; -static void *dinput; +void *curD3D = NULL; +void *dinput; extern bool d3d_restore(d3d_video_t *data); @@ -72,56 +71,6 @@ static void d3d_resize(void *data, unsigned new_width, unsigned new_height) } } -#ifdef HAVE_WINDOW -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, - WPARAM wParam, LPARAM lParam) -{ - driver_t *driver = driver_get_ptr(); - settings_t *settings = config_get_ptr(); - - switch (message) - { - case WM_CREATE: - { - LPCREATESTRUCT p_cs = (LPCREATESTRUCT)lParam; - curD3D = (d3d_video_t*)p_cs->lpCreateParams; - } - break; - case WM_CHAR: - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYUP: - case WM_SYSKEYDOWN: - return win32_handle_keyboard_event(hWnd, message, wParam, lParam); - - case WM_DESTROY: - d3d_quit = true; - return 0; - case WM_SIZE: - { - unsigned new_width = LOWORD(lParam); - unsigned new_height = HIWORD(lParam); - - if (new_width && new_height) - d3d_resize(driver->video_data, new_width, new_height); - } - return 0; - case WM_COMMAND: - if (settings->ui.menubar_enable) - { - d3d_video_t *d3d = (d3d_video_t*)driver->video_data; - HWND d3dr = d3d->hWnd; - LRESULT ret = win32_menu_loop(d3dr, wParam); - } - break; - } - - if (dinput_handle_message(dinput, message, wParam, lParam)) - return 0; - return DefWindowProc(hWnd, message, wParam, lParam); -} -#endif - static void gfx_ctx_d3d_swap_buffers(void *data) { d3d_video_t *d3d = (d3d_video_t*)data; @@ -142,7 +91,7 @@ static void gfx_ctx_d3d_update_title(void *data) #ifndef _XBOX d3d_video_t *d3d = (d3d_video_t*)data; - SetWindowText(d3d->hWnd, buf); + SetWindowText(g_hwnd, buf); #endif } @@ -172,19 +121,7 @@ static void gfx_ctx_d3d_check_window(void *data, bool *quit, bool *resize, unsigned *width, unsigned *height, unsigned frame_count) { - d3d_video_t *d3d = (d3d_video_t*)data; - - (void)data; - - *quit = false; - *resize = false; - - if (d3d_quit) - *quit = true; - if (d3d->should_resize) - *resize = true; - - win32_check_window(); + win32_check_window(quit, resize, width, height); } #ifdef _XBOX @@ -201,7 +138,7 @@ static bool gfx_ctx_d3d_has_focus(void *data) d3d_video_t *d3d = (d3d_video_t*)data; if (!d3d) return false; - return GetFocus() == d3d->hWnd; + return GetFocus() == g_hwnd; } static bool gfx_ctx_d3d_suppress_screensaver(void *data, bool enable) @@ -240,7 +177,7 @@ static bool gfx_ctx_d3d_init(void *data) { (void)data; - d3d_quit = false; + win32_monitor_init(); return true; } @@ -265,6 +202,15 @@ static void gfx_ctx_d3d_input_driver(void *data, (void)data; } +static bool gfx_ctx_d3d_set_video_mode(void *data, + unsigned width, unsigned height, + bool fullscreen) +{ + win32_show_cursor(!fullscreen); + + return true; +} + static void gfx_ctx_d3d_get_video_size(void *data, unsigned *width, unsigned *height) { @@ -363,11 +309,10 @@ static void gfx_ctx_d3d_swap_interval(void *data, unsigned interval) { d3d_video_t *d3d = (d3d_video_t*)data; #ifdef _XBOX - LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev; unsigned d3d_interval = interval ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; - d3dr->SetRenderState(XBOX_PRESENTATIONINTERVAL, d3d_interval); + d3d_render_state(d3d->dev, XBOX_PRESENTATIONINTERVAL, d3d_interval); #else d3d_restore(d3d); #endif @@ -384,7 +329,7 @@ const gfx_ctx_driver_t gfx_ctx_d3d = { gfx_ctx_d3d_destroy, gfx_ctx_d3d_bind_api, gfx_ctx_d3d_swap_interval, - NULL, + gfx_ctx_d3d_set_video_mode, gfx_ctx_d3d_get_video_size, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers_context/wgl_ctx.c b/gfx/drivers_context/wgl_ctx.cpp similarity index 57% rename from gfx/drivers_context/wgl_ctx.c rename to gfx/drivers_context/wgl_ctx.cpp index 89af7ef366..9eca74682e 100644 --- a/gfx/drivers_context/wgl_ctx.c +++ b/gfx/drivers_context/wgl_ctx.cpp @@ -40,39 +40,42 @@ #include "../common/win32_common.h" #include "../drivers_wm/win32_shader_dlg.h" -#define IDI_ICON 1 +#ifndef WGL_CONTEXT_MAJOR_VERSION_ARB +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#endif -#ifndef MAX_MONITORS -#define MAX_MONITORS 9 +#ifndef WGL_CONTEXT_MINOR_VERSION_ARB +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#endif + +#ifndef WGL_CONTEXT_PROFILE_MASK_ARB +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#endif + +#ifndef WGL_CONTEXT_CORE_PROFILE_BIT_ARB +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001 +#endif + +#ifndef WGL_CONTEXT_FLAGS_ARB +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#endif + +#ifndef WGL_CONTEXT_DEBUG_BIT_ARB +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 #endif static bool g_use_hw_ctx; -static HWND g_hwnd; static HGLRC g_hrc; static HGLRC g_hw_hrc; static HDC g_hdc; -static HMONITOR g_last_hm; -static HMONITOR g_all_hms[MAX_MONITORS]; -static unsigned g_num_mons; + static unsigned g_major; static unsigned g_minor; -static bool g_quit; -static bool g_inited; static unsigned g_interval; -static unsigned g_resize_width; -static unsigned g_resize_height; -static unsigned g_pos_x = CW_USEDEFAULT; -static unsigned g_pos_y = CW_USEDEFAULT; -static bool g_resized; - static dylib_t dll_handle = NULL; /* Handle to OpenGL32.dll */ -static bool g_restore_desktop; - -static void monitor_info(MONITORINFOEX *mon, HMONITOR *hm_to_use); - static void gfx_ctx_wgl_destroy(void *data); static BOOL (APIENTRY *p_swap_interval)(int); @@ -95,26 +98,7 @@ static void setup_pixel_format(HDC hdc) SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd); } -#ifndef WGL_CONTEXT_MAJOR_VERSION_ARB -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#endif -#ifndef WGL_CONTEXT_MINOR_VERSION_ARB -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#endif -#ifndef WGL_CONTEXT_PROFILE_MASK_ARB -#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 -#endif -#ifndef WGL_CONTEXT_CORE_PROFILE_BIT_ARB -#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001 -#endif -#ifndef WGL_CONTEXT_FLAGS_ARB -#define WGL_CONTEXT_FLAGS_ARB 0x2094 -#endif -#ifndef WGL_CONTEXT_DEBUG_BIT_ARB -#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 -#endif - -static void create_gl_context(HWND hwnd) +void create_gl_context(HWND hwnd) { bool core_context; const struct retro_hw_render_callback *hw_render = @@ -238,74 +222,7 @@ static void create_gl_context(HWND hwnd) } } -#ifdef __cplusplus -extern "C" -#endif -bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam); - -static void *dinput_wgl; - -static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, - WPARAM wparam, LPARAM lparam) -{ - settings_t *settings = config_get_ptr(); - - switch (message) - { - case WM_SYSCOMMAND: - /* Prevent screensavers, etc, while running. */ - switch (wparam) - { - case SC_SCREENSAVE: - case SC_MONITORPOWER: - return 0; - } - break; - - case WM_CHAR: - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYUP: - case WM_SYSKEYDOWN: - return win32_handle_keyboard_event(hwnd, message, wparam, lparam); - - case WM_CREATE: - create_gl_context(hwnd); - return 0; - - case WM_CLOSE: - case WM_DESTROY: - case WM_QUIT: - { - WINDOWPLACEMENT placement; - GetWindowPlacement(g_hwnd, &placement); - g_pos_x = placement.rcNormalPosition.left; - g_pos_y = placement.rcNormalPosition.top; - g_quit = true; - return 0; - } - case WM_SIZE: - /* Do not send resize message if we minimize. */ - if (wparam != SIZE_MAXHIDE && wparam != SIZE_MINIMIZED) - { - g_resize_width = LOWORD(lparam); - g_resize_height = HIWORD(lparam); - g_resized = true; - } - return 0; - case WM_COMMAND: - if (settings->ui.menubar_enable) - { - LRESULT ret = win32_menu_loop(g_hwnd, wparam); - (void)ret; - } - break; - } - - if (dinput_handle_message(dinput_wgl, message, wparam, lparam)) - return 0; - return DefWindowProc(hwnd, message, wparam, lparam); -} +void *dinput_wgl; static void gfx_ctx_wgl_swap_interval(void *data, unsigned interval) { @@ -325,20 +242,7 @@ static void gfx_ctx_wgl_swap_interval(void *data, unsigned interval) static void gfx_ctx_wgl_check_window(void *data, bool *quit, bool *resize, unsigned *width, unsigned *height, unsigned frame_count) { - win32_check_window(); - - (void)data; - (void)frame_count; - - *quit = g_quit; - - if (g_resized) - { - *resize = true; - *width = g_resize_width; - *height = g_resize_height; - g_resized = false; - } + win32_check_window(quit, resize, width, height); } static void gfx_ctx_wgl_swap_buffers(void *data) @@ -376,11 +280,12 @@ static void gfx_ctx_wgl_get_video_size(void *data, unsigned *width, unsigned *he if (!g_hwnd) { + unsigned mon_id; RECT mon_rect; MONITORINFOEX current_mon; HMONITOR hm_to_use = NULL; - monitor_info(¤t_mon, &hm_to_use); + win32_monitor_info(¤t_mon, &hm_to_use, &mon_id); mon_rect = current_mon.rcMonitor; *width = mon_rect.right - mon_rect.left; *height = mon_rect.bottom - mon_rect.top; @@ -392,13 +297,6 @@ static void gfx_ctx_wgl_get_video_size(void *data, unsigned *width, unsigned *he } } -static BOOL CALLBACK monitor_enum_proc(HMONITOR hMonitor, - HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -{ - g_all_hms[g_num_mons++] = hMonitor; - return TRUE; -} - static bool gfx_ctx_wgl_init(void *data) { WNDCLASSEX wndclass = {0}; @@ -408,24 +306,12 @@ static bool gfx_ctx_wgl_init(void *data) if (g_inited) return false; - g_quit = false; - g_restore_desktop = false; + g_quit = false; + g_restore_desktop = false; - g_num_mons = 0; - EnumDisplayMonitors(NULL, NULL, monitor_enum_proc, 0); - - wndclass.cbSize = sizeof(wndclass); - wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wndclass.lpfnWndProc = WndProc; - wndclass.hInstance = GetModuleHandle(NULL); - wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndclass.lpszClassName = "RetroArch"; - wndclass.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON)); - wndclass.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), - MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); - - if (!RegisterClassEx(&wndclass)) - return false; + win32_monitor_init(); + if (!win32_window_init(&wndclass, true)) + return false; if (!wgl_shader_dlg_init()) RARCH_ERR("[WGL]: wgl_shader_dlg_init() failed.\n"); @@ -433,147 +319,17 @@ static bool gfx_ctx_wgl_init(void *data) return true; } -static bool set_fullscreen(unsigned width, unsigned height, unsigned refresh, char *dev_name) -{ - DEVMODE devmode; - - memset(&devmode, 0, sizeof(devmode)); - devmode.dmSize = sizeof(DEVMODE); - devmode.dmPelsWidth = width; - devmode.dmPelsHeight = height; - devmode.dmDisplayFrequency = refresh; - devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; - - RARCH_LOG("[WGL]: Setting fullscreen to %ux%u @ %uHz on device %s.\n", width, height, refresh, dev_name); - return ChangeDisplaySettingsEx(dev_name, &devmode, NULL, CDS_FULLSCREEN, NULL) == DISP_CHANGE_SUCCESSFUL; -} - -static void monitor_info(MONITORINFOEX *mon, HMONITOR *hm_to_use) -{ - unsigned fs_monitor; - settings_t *settings = config_get_ptr(); - - if (!g_last_hm) - g_last_hm = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTONEAREST); - *hm_to_use = g_last_hm; - - fs_monitor = settings->video.monitor_index; - if (fs_monitor && fs_monitor <= g_num_mons && g_all_hms[fs_monitor - 1]) - *hm_to_use = g_all_hms[fs_monitor - 1]; - - memset(mon, 0, sizeof(*mon)); - mon->cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(*hm_to_use, (MONITORINFO*)mon); -} - static bool gfx_ctx_wgl_set_video_mode(void *data, unsigned width, unsigned height, bool fullscreen) { - DWORD style; - MSG msg; - RECT mon_rect; - MONITORINFOEX current_mon; - float refresh_mod; - unsigned refresh; - bool windowed_full; - RECT rect = {0}; - HMONITOR hm_to_use = NULL; - driver_t *driver = driver_get_ptr(); - settings_t *settings = config_get_ptr(); - - monitor_info(¤t_mon, &hm_to_use); - - mon_rect = current_mon.rcMonitor; - g_resize_width = width; - g_resize_height = height; - - /* Windows only reports the refresh rates for modelines as - * an integer, so video.refresh_rate needs to be rounded. Also, account - * for black frame insertion using video.refresh_rate set to half - * of the display refresh rate, as well as higher vsync swap intervals. */ - refresh_mod = settings->video.black_frame_insertion ? 2.0f : 1.0f; - refresh = roundf(settings->video.refresh_rate * refresh_mod * settings->video.swap_interval); - - windowed_full = settings->video.windowed_fullscreen; - - if (fullscreen) - { - if (windowed_full) - { - style = WS_EX_TOPMOST | WS_POPUP; - g_resize_width = width = mon_rect.right - mon_rect.left; - g_resize_height = height = mon_rect.bottom - mon_rect.top; - } - else - { - style = WS_POPUP | WS_VISIBLE; - - if (!set_fullscreen(width, height, refresh, current_mon.szDevice)) - goto error; - - /* Display settings might have changed, get new coordinates. */ - GetMonitorInfo(hm_to_use, (MONITORINFO*)¤t_mon); - mon_rect = current_mon.rcMonitor; - g_restore_desktop = true; - } - } - else - { - style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - rect.right = width; - rect.bottom = height; - AdjustWindowRect(&rect, style, FALSE); - g_resize_width = width = rect.right - rect.left; - g_resize_height = height = rect.bottom - rect.top; - } - - g_hwnd = CreateWindowEx(0, "RetroArch", "RetroArch", style, - fullscreen ? mon_rect.left : g_pos_x, - fullscreen ? mon_rect.top : g_pos_y, - width, height, - NULL, NULL, NULL, NULL); - - if (!g_hwnd) - goto error; - - if (!fullscreen || windowed_full) - { - if (!fullscreen && settings->ui.menubar_enable) - { - RECT rc_temp = {0, 0, (LONG)height, 0x7FFF}; - SetMenu(g_hwnd, LoadMenu(GetModuleHandle(NULL),MAKEINTRESOURCE(IDR_MENU))); - SendMessage(g_hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rc_temp); - g_resize_height = height += rc_temp.top + rect.top; - SetWindowPos(g_hwnd, NULL, 0, 0, width, height, SWP_NOMOVE); - } - - ShowWindow(g_hwnd, SW_RESTORE); - UpdateWindow(g_hwnd); - SetForegroundWindow(g_hwnd); - SetFocus(g_hwnd); - } - - win32_show_cursor(!fullscreen); - - /* Wait until GL context is created (or failed to do so ...) */ - while (!g_inited && !g_quit && GetMessage(&msg, g_hwnd, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - if (g_quit) + if (!win32_set_video_mode(data, width, height, fullscreen)) goto error; p_swap_interval = (BOOL (APIENTRY *)(int))wglGetProcAddress("wglSwapIntervalEXT"); gfx_ctx_wgl_swap_interval(data, g_interval); - driver->display_type = RARCH_DISPLAY_WIN32; - driver->video_display = 0; - driver->video_window = (uintptr_t)g_hwnd; - return true; error: @@ -610,19 +366,14 @@ static void gfx_ctx_wgl_destroy(void *data) if (g_hwnd) { - g_last_hm = MonitorFromWindow(g_hwnd, MONITOR_DEFAULTTONEAREST); - DestroyWindow(g_hwnd); + win32_monitor_from_window(g_hwnd, true); UnregisterClass("RetroArch", GetModuleHandle(NULL)); g_hwnd = NULL; } if (g_restore_desktop) { - MONITORINFOEX current_mon; - memset(¤t_mon, 0, sizeof(current_mon)); - current_mon.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(g_last_hm, (MONITORINFO*)¤t_mon); - ChangeDisplaySettingsEx(current_mon.szDevice, NULL, NULL, 0, NULL); + win32_monitor_get_info(); g_restore_desktop = false; } diff --git a/gfx/drivers_font/gl_raster_font.c b/gfx/drivers_font/gl_raster_font.c index 59cdd5c9cb..9274943509 100644 --- a/gfx/drivers_font/gl_raster_font.c +++ b/gfx/drivers_font/gl_raster_font.c @@ -17,6 +17,7 @@ #include "../drivers/gl_common.h" #include "../font_driver.h" #include "../video_shader_driver.h" +#include "../video_texture.h" /* TODO: Move viewport side effects to the caller: it's a source of bugs. */ @@ -185,7 +186,7 @@ static void gl_raster_font_free_font(void *data) if (font->font_driver && font->font_data) font->font_driver->free(font->font_data); - glDeleteTextures(1, &font->tex); + video_texture_unload(TEXTURE_BACKEND_OPENGL, (uintptr_t*)&font->tex); free(font); } @@ -440,7 +441,7 @@ static void gl_raster_font_render_msg(void *data, const char *msg, x = settings->video.msg_pos_x; y = settings->video.msg_pos_y; scale = 1.0f; - full_screen = false; + full_screen = true; text_align = TEXT_ALIGN_LEFT; color[0] = settings->video.msg_color_r; diff --git a/gfx/drivers_wm/win32_shader_dlg.c b/gfx/drivers_wm/win32_shader_dlg.c index d78fa3afca..842c2b36bb 100644 --- a/gfx/drivers_wm/win32_shader_dlg.c +++ b/gfx/drivers_wm/win32_shader_dlg.c @@ -199,7 +199,7 @@ void shader_dlg_params_reload(void) g_shader_dlg.controls[i].type = SHADER_PARAM_CTRL_CHECKBOX; g_shader_dlg.controls[i].checkbox.hwnd = CreateWindowEx(0, "BUTTON", shader->parameters[i].desc, WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, pos_x, pos_y, SHADER_DLG_CTRL_WIDTH, SHADER_DLG_CHECKBOX_HEIGHT, - g_shader_dlg.hwnd, (HMENU)i, NULL, NULL); + g_shader_dlg.hwnd, (HMENU)(size_t)i, NULL, NULL); SendMessage(g_shader_dlg.controls[i].checkbox.hwnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); pos_y += SHADER_DLG_CHECKBOX_HEIGHT + SHADER_DLG_CTRL_MARGIN; } @@ -215,16 +215,16 @@ void shader_dlg_params_reload(void) g_shader_dlg.controls[i].type = SHADER_PARAM_CTRL_TRACKBAR; g_shader_dlg.controls[i].trackbar.label_title = CreateWindowEx(0, "STATIC", shader->parameters[i].desc, WS_CHILD | WS_VISIBLE | SS_LEFT, pos_x, pos_y, SHADER_DLG_CTRL_WIDTH, SHADER_DLG_LABEL_HEIGHT, g_shader_dlg.hwnd, - (HMENU)i, NULL, NULL); + (HMENU)(size_t)i, NULL, NULL); SendMessage(g_shader_dlg.controls[i].trackbar.label_title, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); pos_y += SHADER_DLG_LABEL_HEIGHT; g_shader_dlg.controls[i].trackbar.hwnd = CreateWindowEx(0, TRACKBAR_CLASS, "", WS_CHILD | WS_VISIBLE | TBS_HORZ | TBS_NOTICKS, pos_x + SHADER_DLG_TRACKBAR_LABEL_WIDTH, pos_y, - SHADER_DLG_TRACKBAR_WIDTH, SHADER_DLG_TRACKBAR_HEIGHT, g_shader_dlg.hwnd, (HMENU)i, NULL, NULL); + SHADER_DLG_TRACKBAR_WIDTH, SHADER_DLG_TRACKBAR_HEIGHT, g_shader_dlg.hwnd, (HMENU)(size_t)i, NULL, NULL); g_shader_dlg.controls[i].trackbar.label_val = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE | SS_LEFT, pos_x, - pos_y, SHADER_DLG_TRACKBAR_LABEL_WIDTH, SHADER_DLG_LABEL_HEIGHT, g_shader_dlg.hwnd, (HMENU)i, NULL, NULL); + pos_y, SHADER_DLG_TRACKBAR_LABEL_WIDTH, SHADER_DLG_LABEL_HEIGHT, g_shader_dlg.hwnd, (HMENU)(size_t)i, NULL, NULL); SendMessage(g_shader_dlg.controls[i].trackbar.label_val, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); SendMessage(g_shader_dlg.controls[i].trackbar.hwnd, TBM_SETBUDDY, (WPARAM)TRUE, diff --git a/gfx/video_common.h b/gfx/video_common.h index 5fed1a829c..632a844b57 100644 --- a/gfx/video_common.h +++ b/gfx/video_common.h @@ -22,9 +22,6 @@ #include -typedef float GRfloat; -typedef unsigned int GRuint; - #ifdef __cplusplus extern "C" { #endif diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 00a96f0e45..1bdc9435f1 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -285,7 +285,11 @@ bool video_driver_set_shader(enum rarch_shader_type type, static void deinit_video_filter(void) { rarch_softfilter_free(video_state.filter.filter); +#ifdef _3DS + linearFree(video_state.filter.buffer); +#else free(video_state.filter.buffer); +#endif memset(&video_state.filter, 0, sizeof(video_state.filter)); } @@ -344,7 +348,11 @@ static void init_video_filter(enum retro_pixel_format colfmt) sizeof(uint32_t) : sizeof(uint16_t); /* TODO: Aligned output. */ +#ifdef _3DS + video_state.filter.buffer = linearMemAlign(width * height * video_state.filter.out_bpp, 0x80); +#else video_state.filter.buffer = malloc(width * height * video_state.filter.out_bpp); +#endif if (!video_state.filter.buffer) goto error; diff --git a/gfx/video_filter.c b/gfx/video_filter.c index c8e2526f61..dca43bd448 100644 --- a/gfx/video_filter.c +++ b/gfx/video_filter.c @@ -216,6 +216,7 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt, return false; } + filt->threads = threads; RARCH_LOG("Using %u threads for softfilter.\n", threads); filt->packets = (struct softfilter_work_packet*) @@ -231,7 +232,6 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt, calloc(threads, sizeof(*filt->thread_data)); if (!filt->thread_data) return false; - filt->threads = threads; for (i = 0; i < threads; i++) { diff --git a/gfx/video_texture.c b/gfx/video_texture.c deleted file mode 100644 index bebe3afa5c..0000000000 --- a/gfx/video_texture.c +++ /dev/null @@ -1,139 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2011-2015 - Daniel De Matteis - * Copyright (C) 2014-2015 - Jean-André Santoni - * - * 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 "video_texture.h" -#include "video_pixel_converter.h" -#include "video_thread_wrapper.h" - -#ifdef HAVE_OPENGL -#include "drivers/gl_common.h" - -static void video_texture_png_load_gl(struct texture_image *ti, - enum texture_filter_type filter_type, - unsigned *id) -{ - /* Generate the OpenGL texture object */ - glGenTextures(1, (GLuint*)id); - gl_load_texture_data((GLuint)*id, - RARCH_WRAP_EDGE, filter_type, - 4 /* TODO/FIXME - dehardcode */, - ti->width, ti->height, ti->pixels, - sizeof(uint32_t) /* TODO/FIXME - dehardcode */ - ); -} -#endif - -static unsigned video_texture_png_load(void *data, - enum texture_backend_type type, - enum texture_filter_type filter_type) -{ - unsigned id = 0; - - if (!data) - return 0; - - switch (type) - { - case TEXTURE_BACKEND_OPENGL: -#ifdef HAVE_OPENGL - video_texture_png_load_gl((struct texture_image*)data, filter_type, &id); -#endif - break; - case TEXTURE_BACKEND_DEFAULT: - default: - break; - } - - return id; -} - -static int video_texture_png_load_wrap(void *data) -{ - return video_texture_png_load(data, TEXTURE_BACKEND_DEFAULT, - TEXTURE_FILTER_LINEAR); -} - -static int video_texture_png_load_wrap_gl_mipmap(void *data) -{ - return video_texture_png_load(data, TEXTURE_BACKEND_OPENGL, - TEXTURE_FILTER_MIPMAP_LINEAR); -} - -static int video_texture_png_load_wrap_gl(void *data) -{ - return video_texture_png_load(data, TEXTURE_BACKEND_OPENGL, - TEXTURE_FILTER_LINEAR); -} - -unsigned video_texture_load(void *data, - enum texture_backend_type type, - enum texture_filter_type filter_type) -{ - settings_t *settings = config_get_ptr(); - const struct retro_hw_render_callback *hw_render = - (const struct retro_hw_render_callback*)video_driver_callback(); - - if (settings->video.threaded && !hw_render->context_type) - { - driver_t *driver = driver_get_ptr(); - thread_video_t *thr = (thread_video_t*)driver->video_data; - thread_packet_t pkt = { CMD_CUSTOM_COMMAND }; - - if (!thr) - return 0; - - switch (type) - { - case TEXTURE_BACKEND_OPENGL: - if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR || - filter_type == TEXTURE_FILTER_MIPMAP_NEAREST) - pkt.data.custom_command.method = video_texture_png_load_wrap_gl_mipmap; - else - pkt.data.custom_command.method = video_texture_png_load_wrap_gl; - break; - case TEXTURE_BACKEND_DEFAULT: - default: - pkt.data.custom_command.method = video_texture_png_load_wrap; - break; - } - - pkt.data.custom_command.data = (void*)data; - - thr->send_and_wait(thr, &pkt); - - return pkt.data.custom_command.return_value; - } - - return video_texture_png_load(data, type, filter_type); -} - -#ifdef HAVE_OPENGL -static void video_texture_gl_unload(uintptr_t *id) -{ - if (id) - glDeleteTextures(1, (const GLuint*)id); - *id = 0; -} -#endif - -void video_texture_unload(uintptr_t *id) -{ -#ifdef HAVE_OPENGL - video_texture_gl_unload(id); -#endif -} diff --git a/gfx/video_texture.cpp b/gfx/video_texture.cpp new file mode 100644 index 0000000000..7c6f27b269 --- /dev/null +++ b/gfx/video_texture.cpp @@ -0,0 +1 @@ +#include "video_texture_c.c" diff --git a/gfx/video_texture.h b/gfx/video_texture.h index fd082cd34f..dfe6699810 100644 --- a/gfx/video_texture.h +++ b/gfx/video_texture.h @@ -22,18 +22,31 @@ enum texture_backend_type { TEXTURE_BACKEND_DEFAULT = 0, - TEXTURE_BACKEND_OPENGL + TEXTURE_BACKEND_OPENGL, + TEXTURE_BACKEND_DIRECT3D }; #ifdef __cplusplus extern "C" { #endif +#ifdef HAVE_OPENGL +#include "drivers/gl_common.h" + +void gl_load_texture_data(GLuint id, + enum gfx_wrap_type wrap_type, + enum texture_filter_type filter_type, + unsigned alignment, + unsigned width, unsigned height, + const void *frame, + unsigned base_size); +#endif + unsigned video_texture_load(void *data, enum texture_backend_type type, enum texture_filter_type filter_type); -void video_texture_unload(uintptr_t *id); +void video_texture_unload(enum texture_backend_type type, uintptr_t *id); #ifdef __cplusplus } diff --git a/gfx/video_texture_c.c b/gfx/video_texture_c.c new file mode 100644 index 0000000000..388a563e4a --- /dev/null +++ b/gfx/video_texture_c.c @@ -0,0 +1,267 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2015 - Daniel De Matteis + * Copyright (C) 2014-2015 - Jean-André Santoni + * + * 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 "video_texture.h" +#include "video_pixel_converter.h" +#include "video_thread_wrapper.h" + +#ifdef HAVE_OPENGL + +#ifdef __cplusplus +extern "C" { +#endif + +void gl_load_texture_data(GLuint id, + enum gfx_wrap_type wrap_type, + enum texture_filter_type filter_type, + unsigned alignment, + unsigned width, unsigned height, + const void *frame, unsigned base_size) +{ + GLint mag_filter, min_filter; + bool want_mipmap = false; + bool rgb32 = (base_size == (sizeof(uint32_t))); + driver_t *driver = driver_get_ptr(); + GLenum wrap = gl_wrap_type_to_enum(wrap_type); + + glBindTexture(GL_TEXTURE_2D, id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + +#if defined(HAVE_OPENGLES2) || defined(HAVE_PSGL) || defined(OSX_PPC) + if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR) + filter_type = TEXTURE_FILTER_LINEAR; + if (filter_type == TEXTURE_FILTER_MIPMAP_NEAREST) + filter_type = TEXTURE_FILTER_NEAREST; +#endif + + switch (filter_type) + { + case TEXTURE_FILTER_MIPMAP_LINEAR: + min_filter = GL_LINEAR_MIPMAP_NEAREST; + mag_filter = GL_LINEAR; + want_mipmap = true; + break; + case TEXTURE_FILTER_MIPMAP_NEAREST: + min_filter = GL_NEAREST_MIPMAP_NEAREST; + mag_filter = GL_NEAREST; + want_mipmap = true; + break; + case TEXTURE_FILTER_NEAREST: + min_filter = GL_NEAREST; + mag_filter = GL_NEAREST; + break; + case TEXTURE_FILTER_LINEAR: + default: + min_filter = GL_LINEAR; + mag_filter = GL_LINEAR; + break; + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + + glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); + glTexImage2D(GL_TEXTURE_2D, + 0, + (driver->gfx_use_rgba || !rgb32) ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, + width, height, 0, + (driver->gfx_use_rgba || !rgb32) ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, + (rgb32) ? RARCH_GL_FORMAT32 : GL_UNSIGNED_SHORT_4_4_4_4, frame); + + if (want_mipmap) + glGenerateMipmap(GL_TEXTURE_2D); +} + +void video_texture_png_load_gl(struct texture_image *ti, + enum texture_filter_type filter_type, + uintptr_t *id) +{ + /* Generate the OpenGL texture object */ + glGenTextures(1, (GLuint*)id); + gl_load_texture_data((GLuint)*id, + RARCH_WRAP_EDGE, filter_type, + 4 /* TODO/FIXME - dehardcode */, + ti->width, ti->height, ti->pixels, + sizeof(uint32_t) /* TODO/FIXME - dehardcode */ + ); +} + +#ifdef __cplusplus +} +#endif + +#endif + +#ifdef HAVE_D3D +#include "d3d/d3d_wrapper.h" + +static void video_texture_png_load_d3d(struct texture_image *ti, + enum texture_filter_type filter_type, + uintptr_t *id) +{ + id = (uintptr_t*)d3d_texture_new(NULL, NULL, + ti->width, ti->height, 1, + 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, 0, 0, 0, + NULL, NULL); +} +#endif + +static unsigned video_texture_png_load(void *data, + enum texture_backend_type type, + enum texture_filter_type filter_type) +{ + uintptr_t id = 0; + + if (!data) + return 0; + + switch (type) + { + case TEXTURE_BACKEND_OPENGL: +#ifdef HAVE_OPENGL + video_texture_png_load_gl((struct texture_image*)data, filter_type, &id); +#endif + break; + case TEXTURE_BACKEND_DIRECT3D: +#ifdef HAVE_D3D + video_texture_png_load_d3d((struct texture_image*)data, filter_type, &id); +#endif + break; + case TEXTURE_BACKEND_DEFAULT: + default: + break; + } + + return id; +} + +static int video_texture_png_load_wrap(void *data) +{ + return video_texture_png_load(data, TEXTURE_BACKEND_DEFAULT, + TEXTURE_FILTER_LINEAR); +} + +static int video_texture_png_load_wrap_gl_mipmap(void *data) +{ + return video_texture_png_load(data, TEXTURE_BACKEND_OPENGL, + TEXTURE_FILTER_MIPMAP_LINEAR); +} + +static int video_texture_png_load_wrap_gl(void *data) +{ + return video_texture_png_load(data, TEXTURE_BACKEND_OPENGL, + TEXTURE_FILTER_LINEAR); +} + +static int video_texture_png_load_wrap_d3d_mipmap(void *data) +{ + return video_texture_png_load(data, TEXTURE_BACKEND_DIRECT3D, + TEXTURE_FILTER_MIPMAP_LINEAR); +} + +static int video_texture_png_load_wrap_d3d(void *data) +{ + return video_texture_png_load(data, TEXTURE_BACKEND_DIRECT3D, + TEXTURE_FILTER_LINEAR); +} + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned video_texture_load(void *data, + enum texture_backend_type type, + enum texture_filter_type filter_type) +{ + settings_t *settings = config_get_ptr(); + const struct retro_hw_render_callback *hw_render = + (const struct retro_hw_render_callback*)video_driver_callback(); + + if (settings->video.threaded && !hw_render->context_type) + { + driver_t *driver = driver_get_ptr(); + thread_video_t *thr = (thread_video_t*)driver->video_data; + thread_packet_t pkt = { CMD_CUSTOM_COMMAND }; + + if (!thr) + return 0; + + switch (type) + { + case TEXTURE_BACKEND_OPENGL: + if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR || + filter_type == TEXTURE_FILTER_MIPMAP_NEAREST) + pkt.data.custom_command.method = video_texture_png_load_wrap_gl_mipmap; + else + pkt.data.custom_command.method = video_texture_png_load_wrap_gl; + break; + case TEXTURE_BACKEND_DIRECT3D: + if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR || + filter_type == TEXTURE_FILTER_MIPMAP_NEAREST) + pkt.data.custom_command.method = video_texture_png_load_wrap_d3d_mipmap; + else + pkt.data.custom_command.method = video_texture_png_load_wrap_d3d; + break; + case TEXTURE_BACKEND_DEFAULT: + default: + pkt.data.custom_command.method = video_texture_png_load_wrap; + break; + } + + pkt.data.custom_command.data = (void*)data; + + thr->send_and_wait(thr, &pkt); + + return pkt.data.custom_command.return_value; + } + + return video_texture_png_load(data, type, filter_type); +} + +#ifdef __cplusplus +} +#endif + +#ifdef HAVE_OPENGL +static void video_texture_gl_unload(uintptr_t *id) +{ + if (id) + glDeleteTextures(1, (const GLuint*)id); + *id = 0; +} +#endif + +void video_texture_unload(enum texture_backend_type type, uintptr_t *id) +{ + switch (type) + { + case TEXTURE_BACKEND_OPENGL: +#ifdef HAVE_OPENGL + video_texture_gl_unload(id); +#endif + break; + case TEXTURE_BACKEND_DIRECT3D: +#ifdef HAVE_D3D + d3d_texture_free((LPDIRECT3DTEXTURE)id); +#endif + break; + case TEXTURE_BACKEND_DEFAULT: + break; + } +} diff --git a/gfx/video_thread_wrapper.h b/gfx/video_thread_wrapper.h index d5bd9de543..22d7ff756d 100644 --- a/gfx/video_thread_wrapper.h +++ b/gfx/video_thread_wrapper.h @@ -23,6 +23,10 @@ #include #include "font_driver.h" +#ifdef __cplusplus +extern "C" { +#endif + enum thread_cmd { CMD_NONE = 0, @@ -59,6 +63,7 @@ enum thread_cmd CMD_DUMMY = INT_MAX }; + typedef struct { enum thread_cmd type; @@ -256,5 +261,8 @@ void *rarch_threaded_video_get_ptr(const video_driver_t **drv); const char *rarch_threaded_video_get_ident(void); +#ifdef __cplusplus +} #endif +#endif diff --git a/griffin/griffin.c b/griffin/griffin.c index 0c8a4ffa6b..ed6638d0ae 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -103,13 +103,6 @@ CHEATS #include "../cheats.c" #include "../libretro-common/hash/rhash.c" -/*============================================================ -UI COMMON CONTEXT -============================================================ */ -#if defined(_WIN32) -#include "../gfx/common/win32_common.c" -#endif - /*============================================================ VIDEO CONTEXT ============================================================ */ @@ -139,12 +132,7 @@ VIDEO CONTEXT #include "../gfx/drivers_context/vc_egl_ctx.c" #endif -#ifdef HAVE_MENU -#include "../menu/drivers_display/menu_display_gl.c" -#endif - #if defined(_WIN32) && !defined(_XBOX) -#include "../gfx/drivers_context/wgl_ctx.c" #include "../gfx/drivers_wm/win32_shader_dlg.c" #endif @@ -195,7 +183,10 @@ VIDEO IMAGE ============================================================ */ #include "../gfx/image/image.c" -#include "../gfx/video_texture.c" + +#if !defined(_WIN32) +#include "../gfx/video_texture_c.c" +#endif #include "../libretro-common/formats/tga/rtga.c" @@ -213,6 +204,9 @@ VIDEO IMAGE VIDEO DRIVER ============================================================ */ +#include "../libretro-common/gfx/math/matrix_4x4.c" +#include "../libretro-common/gfx/math/matrix_3x3.c" + #if defined(GEKKO) #ifdef HW_RVL #include "../gfx/drivers/gx_gfx_vi_encoder.c" @@ -222,7 +216,6 @@ VIDEO DRIVER #ifdef HAVE_VG #include "../gfx/drivers/vg.c" -#include "../libretro-common/gfx/math/matrix_3x3.c" #endif #ifdef HAVE_OMAP @@ -230,8 +223,6 @@ VIDEO DRIVER #endif #ifdef HAVE_OPENGL -#include "../libretro-common/gfx/math/matrix_4x4.c" - #include "../gfx/drivers/gl.c" #include "../gfx/drivers/gl_common.c" @@ -376,6 +367,7 @@ INPUT #endif #if defined(__linux__) && !defined(ANDROID) +#include "../input/drivers/linux_common.c" #include "../input/drivers/linuxraw_input.c" #include "../input/drivers_joypad/linuxraw_joypad.c" #endif @@ -424,10 +416,6 @@ INPUT (HID) KEYBOARD EVENT ============================================================ */ -#if defined(_WIN32) && !defined(_XBOX) -#include "../input/drivers_keyboard/keyboard_event_win32.c" -#endif - #ifdef HAVE_X11 #include "../input/drivers_keyboard/keyboard_event_x11.c" #endif @@ -817,9 +805,15 @@ MENU #include "../menu/intl/menu_hash_pt.c" #include "../menu/intl/menu_hash_us.c" -#include "../menu/drivers_display/menu_display_null.c" #include "../menu/drivers/null.c" #include "../menu/drivers/menu_generic.c" + +#include "../menu/drivers_display/menu_display_null.c" + +#ifdef HAVE_OPENGL +#include "../menu/drivers_display/menu_display_gl.c" +#endif + #endif diff --git a/griffin/griffin_cpp.cpp b/griffin/griffin_cpp.cpp index ae5aead24f..b28331f5c4 100644 --- a/griffin/griffin_cpp.cpp +++ b/griffin/griffin_cpp.cpp @@ -32,6 +32,26 @@ AUDIO #include "../audio/drivers/xaudio.cpp" #endif +/*============================================================ + KEYBOARD EVENT + ============================================================ */ + +#if defined(_WIN32) && !defined(_XBOX) +#include "../input/drivers_keyboard/keyboard_event_win32.cpp" +#endif + +/*============================================================ +UI COMMON CONTEXT +============================================================ */ +#if defined(_WIN32) && !defined(_XBOX) +#include "../gfx/common/win32_common.cpp" + +#ifdef HAVE_OPENGL +#include "../gfx/drivers_context/wgl_ctx.cpp" +#endif +#endif + + /*============================================================ MENU ============================================================ */ @@ -39,6 +59,10 @@ MENU #include "../menu/drivers/rmenu_xui.cpp" #endif +#if defined(HAVE_D3D) +#include "../menu/drivers_display/menu_display_d3d.cpp" +#endif + /*============================================================ VIDEO CONTEXT ============================================================ */ @@ -53,6 +77,9 @@ VIDEO DRIVER #ifdef _XBOX #include "../frontend/drivers/platform_xdk.cpp" #endif +#ifdef _WIN32 +#include "../gfx/video_texture.cpp" +#endif #if defined(HAVE_D3D) #include "../gfx/d3d/d3d_wrapper.cpp" diff --git a/input/drivers/cocoa_input.c b/input/drivers/cocoa_input.c index b680f7d2b9..b2db86f38a 100644 --- a/input/drivers/cocoa_input.c +++ b/input/drivers/cocoa_input.c @@ -125,35 +125,6 @@ const struct apple_key_name_map_entry apple_key_name_map[] = { "nul", 0x00}, }; -void cocoa_input_enable_small_keyboard(bool on) -{ - driver_t *driver = driver_get_ptr(); - cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data; - if (apple) - apple->small_keyboard_enabled = on; -} - -void cocoa_input_enable_icade(bool on) -{ - driver_t *driver = driver_get_ptr(); - cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data; - - if (!apple) - return; - - apple->icade_enabled = on; - apple->icade_buttons = 0; -} - -void cocoa_input_reset_icade_buttons(void) -{ - driver_t *driver = driver_get_ptr(); - cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data; - - if (apple) - apple->icade_buttons = 0; -} - int32_t cocoa_input_find_any_key(void) { unsigned i; @@ -177,8 +148,6 @@ static int cocoa_input_find_any_button_ret(cocoa_input_data_t *apple, unsigned buttons, unsigned port) { unsigned i; - if (port == 0 && apple->icade_enabled) - BIT32_SET(buttons, apple->icade_buttons); if (buttons) for (i = 0; i < 32; i++) @@ -277,9 +246,6 @@ static void cocoa_input_poll(void *data) if (apple->joypad) apple->joypad->poll(); - if (apple->icade_enabled) - BIT32_SET(apple->buttons[0], apple->icade_buttons); - apple->mouse_x_last = apple->mouse_rel_x; apple->mouse_y_last = apple->mouse_rel_y; } diff --git a/input/drivers/cocoa_input.h b/input/drivers/cocoa_input.h index 790296f061..cc8f19996f 100644 --- a/input/drivers/cocoa_input.h +++ b/input/drivers/cocoa_input.h @@ -55,24 +55,17 @@ typedef struct uint32_t key_state[MAX_KEYS]; uint32_t buttons[MAX_USERS]; - uint32_t mfi_buttons[MAX_USERS]; int16_t axes[MAX_USERS][6]; int8_t hats[NUM_HATS][2]; - bool icade_enabled; - bool small_keyboard_enabled; +#if TARGET_OS_IPHONE + uint32_t mfi_buttons[MAX_USERS]; bool small_keyboard_active; - uint32_t icade_buttons; +#endif const input_device_driver_t *joypad; } cocoa_input_data_t; -void cocoa_input_enable_icade(bool on); - -void cocoa_input_enable_small_keyboard(bool on); - -void cocoa_input_reset_icade_buttons(void); - #ifdef __cplusplus extern "C" { #endif diff --git a/input/drivers/dinput.c b/input/drivers/dinput.c index bd0edc91f7..b7e1c15812 100644 --- a/input/drivers/dinput.c +++ b/input/drivers/dinput.c @@ -79,110 +79,6 @@ struct dinput_input struct pointer_status pointer_head; /* dummy head for easier iteration */ }; -const struct rarch_key_map rarch_key_map_dinput[] = { - { DIK_LEFT, RETROK_LEFT }, - { DIK_RIGHT, RETROK_RIGHT }, - { DIK_UP, RETROK_UP }, - { DIK_DOWN, RETROK_DOWN }, - { DIK_RETURN, RETROK_RETURN }, - { DIK_TAB, RETROK_TAB }, - { DIK_INSERT, RETROK_INSERT }, - { DIK_DELETE, RETROK_DELETE }, - { DIK_RSHIFT, RETROK_RSHIFT }, - { DIK_LSHIFT, RETROK_LSHIFT }, - { DIK_LCONTROL, RETROK_LCTRL }, - { DIK_END, RETROK_END }, - { DIK_HOME, RETROK_HOME }, - { DIK_NEXT, RETROK_PAGEDOWN }, - { DIK_PRIOR, RETROK_PAGEUP }, - { DIK_LALT, RETROK_LALT }, - { DIK_SPACE, RETROK_SPACE }, - { DIK_ESCAPE, RETROK_ESCAPE }, - { DIK_BACKSPACE, RETROK_BACKSPACE }, - { DIK_NUMPADENTER, RETROK_KP_ENTER }, - { DIK_NUMPADPLUS, RETROK_KP_PLUS }, - { DIK_NUMPADMINUS, RETROK_KP_MINUS }, - { DIK_NUMPADSTAR, RETROK_KP_MULTIPLY }, - { DIK_DIVIDE, RETROK_KP_DIVIDE }, - { DIK_GRAVE, RETROK_BACKQUOTE }, - { DIK_PAUSE, RETROK_PAUSE }, - { DIK_NUMPAD0, RETROK_KP0 }, - { DIK_NUMPAD1, RETROK_KP1 }, - { DIK_NUMPAD2, RETROK_KP2 }, - { DIK_NUMPAD3, RETROK_KP3 }, - { DIK_NUMPAD4, RETROK_KP4 }, - { DIK_NUMPAD5, RETROK_KP5 }, - { DIK_NUMPAD6, RETROK_KP6 }, - { DIK_NUMPAD7, RETROK_KP7 }, - { DIK_NUMPAD8, RETROK_KP8 }, - { DIK_NUMPAD9, RETROK_KP9 }, - { DIK_0, RETROK_0 }, - { DIK_1, RETROK_1 }, - { DIK_2, RETROK_2 }, - { DIK_3, RETROK_3 }, - { DIK_4, RETROK_4 }, - { DIK_5, RETROK_5 }, - { DIK_6, RETROK_6 }, - { DIK_7, RETROK_7 }, - { DIK_8, RETROK_8 }, - { DIK_9, RETROK_9 }, - { DIK_F1, RETROK_F1 }, - { DIK_F2, RETROK_F2 }, - { DIK_F3, RETROK_F3 }, - { DIK_F4, RETROK_F4 }, - { DIK_F5, RETROK_F5 }, - { DIK_F6, RETROK_F6 }, - { DIK_F7, RETROK_F7 }, - { DIK_F8, RETROK_F8 }, - { DIK_F9, RETROK_F9 }, - { DIK_F10, RETROK_F10 }, - { DIK_F11, RETROK_F11 }, - { DIK_F12, RETROK_F12 }, - { DIK_A, RETROK_a }, - { DIK_B, RETROK_b }, - { DIK_C, RETROK_c }, - { DIK_D, RETROK_d }, - { DIK_E, RETROK_e }, - { DIK_F, RETROK_f }, - { DIK_G, RETROK_g }, - { DIK_H, RETROK_h }, - { DIK_I, RETROK_i }, - { DIK_J, RETROK_j }, - { DIK_K, RETROK_k }, - { DIK_L, RETROK_l }, - { DIK_M, RETROK_m }, - { DIK_N, RETROK_n }, - { DIK_O, RETROK_o }, - { DIK_P, RETROK_p }, - { DIK_Q, RETROK_q }, - { DIK_R, RETROK_r }, - { DIK_S, RETROK_s }, - { DIK_T, RETROK_t }, - { DIK_U, RETROK_u }, - { DIK_V, RETROK_v }, - { DIK_W, RETROK_w }, - { DIK_X, RETROK_x }, - { DIK_Y, RETROK_y }, - { DIK_Z, RETROK_z }, - { DIK_APOSTROPHE, RETROK_QUOTE }, - { DIK_COMMA, RETROK_COMMA }, - { DIK_MINUS, RETROK_MINUS }, - { DIK_SLASH, RETROK_SLASH }, - { DIK_SEMICOLON, RETROK_SEMICOLON }, - { DIK_EQUALS, RETROK_EQUALS }, - { DIK_LBRACKET, RETROK_LEFTBRACKET }, - { DIK_BACKSLASH, RETROK_BACKSLASH }, - { DIK_RBRACKET, RETROK_RIGHTBRACKET }, - { DIK_DECIMAL, RETROK_KP_PERIOD }, - { DIK_RCONTROL, RETROK_RCTRL }, - { DIK_RMENU, RETROK_RALT }, - { DIK_PERIOD, RETROK_PERIOD }, - { DIK_SCROLL, RETROK_SCROLLOCK }, - { DIK_CAPSLOCK, RETROK_CAPSLOCK }, - { DIK_NUMLOCK, RETROK_NUMLOCK }, - { 0, RETROK_UNKNOWN }, -}; - void dinput_destroy_context(void) { if (!g_dinput_ctx) @@ -200,15 +96,13 @@ bool dinput_init_context(void) CoInitialize(NULL); /* Who said we shouldn't have same call signature in a COM API? <_< */ -#ifdef __cplusplus if (FAILED(DirectInput8Create( - GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, - (void**)&g_dinput_ctx, NULL))) -#else - if (FAILED(DirectInput8Create( - GetModuleHandle(NULL), DIRECTINPUT_VERSION, &IID_IDirectInput8, - (void**)&g_dinput_ctx, NULL))) + GetModuleHandle(NULL), DIRECTINPUT_VERSION, +#ifndef __cplusplus + & #endif + IID_IDirectInput8, + (void**)&g_dinput_ctx, NULL))) { RARCH_ERR("Failed to init DirectInput.\n"); return false; @@ -233,30 +127,27 @@ static void *dinput_init(void) if (!di) return NULL; -#ifdef __cplusplus - if (FAILED(IDirectInput8_CreateDevice(g_dinput_ctx, GUID_SysKeyboard, &di->keyboard, NULL))) + if (FAILED(IDirectInput8_CreateDevice(g_dinput_ctx, +#ifndef __cplusplus + & +#endif + GUID_SysKeyboard, + &di->keyboard, NULL))) { RARCH_ERR("Failed to create keyboard device.\n"); di->keyboard = NULL; } - if (FAILED(IDirectInput8_CreateDevice(g_dinput_ctx, GUID_SysMouse, &di->mouse, NULL))) - { - RARCH_ERR("Failed to create mouse device.\n"); - di->mouse = NULL; - } -#else - if (FAILED(IDirectInput8_CreateDevice(g_dinput_ctx, &GUID_SysKeyboard, &di->keyboard, NULL))) - { - RARCH_ERR("Failed to create keyboard device.\n"); - di->keyboard = NULL; - } - if (FAILED(IDirectInput8_CreateDevice(g_dinput_ctx, &GUID_SysMouse, &di->mouse, NULL))) - { - RARCH_ERR("Failed to create mouse device.\n"); - di->mouse = NULL; - } + if (FAILED(IDirectInput8_CreateDevice(g_dinput_ctx, +#ifndef __cplusplus + & #endif + GUID_SysMouse, + &di->mouse, NULL))) + { + RARCH_ERR("Failed to create mouse device.\n"); + di->mouse = NULL; + } if (di->keyboard) { @@ -473,7 +364,7 @@ static int16_t dinput_mouse_state_screen(struct dinput_input *di, unsigned id) case RETRO_DEVICE_ID_MOUSE_Y: return di->mouse_y; default: - break; + break; } return dinput_mouse_state(di, id); @@ -533,8 +424,10 @@ static int16_t dinput_pointer_state(struct dinput_input *di, case RETRO_DEVICE_ID_POINTER_PRESSED: return pointer_down; default: - return 0; + break; } + + return 0; } static int16_t dinput_input_state(void *data, diff --git a/input/drivers/linux_common.c b/input/drivers/linux_common.c new file mode 100644 index 0000000000..1b8863d334 --- /dev/null +++ b/input/drivers/linux_common.c @@ -0,0 +1,82 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - 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 . + */ + +#include +#include +#include + +#include "linux_common.h" + +static struct termios oldTerm, newTerm; +static long oldKbmd = 0xffff; +static bool linux_stdin_claimed = false; + +void linux_terminal_flush(void) +{ + tcsetattr(0, TCSAFLUSH, &oldTerm); +} + +void linux_terminal_restore_input(void) +{ + if (oldKbmd == 0xffff) + return; + + ioctl(0, KDSKBMODE, oldKbmd); + linux_terminal_flush(); + oldKbmd = 0xffff; + + linux_stdin_claimed = false; +} + +/* Disables input */ + +bool linux_terminal_init(void) +{ + if (oldKbmd != 0xffff) + return false; + + if (tcgetattr(0, &oldTerm) < 0) + return false; + + newTerm = oldTerm; + newTerm.c_lflag &= ~(ECHO | ICANON | ISIG); + newTerm.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); + newTerm.c_cc[VMIN] = 0; + newTerm.c_cc[VTIME] = 0; + + /* Be careful about recovering the terminal. */ + if (ioctl(0, KDGKBMODE, &oldKbmd) < 0) + return false; + + if (tcsetattr(0, TCSAFLUSH, &newTerm) < 0) + return false; + + if (ioctl(0, KDSKBMODE, K_MEDIUMRAW) < 0) + return false; + + return true; +} + +void linux_terminal_claim_stdin(void) +{ + /* We need to disable use of stdin command interface if + * stdin is supposed to be used for input. */ + linux_stdin_claimed = true; +} + +bool linux_terminal_grab_stdin(void *data) +{ + return linux_stdin_claimed; +} diff --git a/input/drivers/linux_common.h b/input/drivers/linux_common.h new file mode 100644 index 0000000000..aa68238b88 --- /dev/null +++ b/input/drivers/linux_common.h @@ -0,0 +1,31 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - 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 . + */ + +#ifndef _LINUX_COMMON_H +#define _LINUX_COMMON_H + +#include + +void linux_terminal_flush(void); + +void linux_terminal_restore_input(void); + +bool linux_terminal_init(void); + +void linux_terminal_claim_stdin(void); + +bool linux_terminal_grab_stdin(void *data); + +#endif diff --git a/input/drivers/linuxraw_input.c b/input/drivers/linuxraw_input.c index d3951c517f..64198240c9 100644 --- a/input/drivers/linuxraw_input.c +++ b/input/drivers/linuxraw_input.c @@ -19,21 +19,17 @@ #include #include #include -#include #include #include #include "../../general.h" +#include "linux_common.h" #include "../input_keymaps.h" #include "../input_common.h" #include "../input_joypad.h" -static long oldKbmd = 0xffff; -static bool linuxraw_stdin_claimed = false; -static struct termios oldTerm, newTerm; - typedef struct linuxraw_input { bool blocked; @@ -41,22 +37,9 @@ typedef struct linuxraw_input bool state[0x80]; } linuxraw_input_t; - -static void linuxraw_reset_kbmd(void) -{ - if (oldKbmd != 0xffff) - { - ioctl(0, KDSKBMODE, oldKbmd); - tcsetattr(0, TCSAFLUSH, &oldTerm); - oldKbmd = 0xffff; - } - - linuxraw_stdin_claimed = false; -} - static void linuxraw_exit_gracefully(int sig) { - linuxraw_reset_kbmd(); + linux_terminal_restore_input(); kill(getpid(), sig); } @@ -71,7 +54,7 @@ static void *linuxraw_input_init(void) if (!isatty(0)) return NULL; - if (linuxraw_stdin_claimed) + if (linux_terminal_grab_stdin(NULL)) { RARCH_WARN("stdin is already used for content loading. Cannot use stdin for input.\n"); return NULL; @@ -81,27 +64,10 @@ static void *linuxraw_input_init(void) if (!linuxraw) return NULL; - if (oldKbmd == 0xffff) + + if (!linux_terminal_init()) { - tcgetattr(0, &oldTerm); - newTerm = oldTerm; - newTerm.c_lflag &= ~(ECHO | ICANON | ISIG); - newTerm.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); - newTerm.c_cc[VMIN] = 0; - newTerm.c_cc[VTIME] = 0; - - if (ioctl(0, KDGKBMODE, &oldKbmd) != 0) - { - free(linuxraw); - return NULL; - } - } - - tcsetattr(0, TCSAFLUSH, &newTerm); - - if (ioctl(0, KDSKBMODE, K_MEDIUMRAW) != 0) - { - linuxraw_reset_kbmd(); + linux_terminal_restore_input(); free(linuxraw); return NULL; } @@ -119,24 +85,17 @@ static void *linuxraw_input_init(void) sigaction(SIGQUIT, &sa, NULL); sigaction(SIGSEGV, &sa, NULL); - atexit(linuxraw_reset_kbmd); + atexit(linux_terminal_restore_input); linuxraw->joypad = input_joypad_init_driver( settings->input.joypad_driver, linuxraw); input_keymaps_init_keyboard_lut(rarch_key_map_linux); - /* We need to disable use of stdin command interface if - * stdin is supposed to be used for input. */ - linuxraw_stdin_claimed = true; + linux_terminal_claim_stdin(); return linuxraw; } -static bool linuxraw_grab_stdin(void *data) -{ - return linuxraw_stdin_claimed; -} - static bool linuxraw_key_pressed(linuxraw_input_t *linuxraw, int key) { unsigned sym = input_keymaps_translate_rk_to_keysym((enum retro_key)key); @@ -225,7 +184,7 @@ static void linuxraw_input_free(void *data) if (linuxraw->joypad) linuxraw->joypad->destroy(); - linuxraw_reset_kbmd(); + linux_terminal_restore_input(); free(data); } @@ -319,7 +278,7 @@ input_driver_t input_linuxraw = { linuxraw_get_capabilities, "linuxraw", linuxraw_grab_mouse, - linuxraw_grab_stdin, + linux_terminal_grab_stdin, linuxraw_set_rumble, linuxraw_get_joypad_driver, linuxraw_keyboard_mapping_is_blocked, diff --git a/input/drivers/sdl_input.c b/input/drivers/sdl_input.c index 22deb06dec..c25207a05c 100644 --- a/input/drivers/sdl_input.c +++ b/input/drivers/sdl_input.c @@ -41,183 +41,6 @@ typedef struct sdl_input int mouse_l, mouse_r, mouse_m, mouse_wu, mouse_wd, mouse_wl, mouse_wr; } sdl_input_t; -const struct rarch_key_map rarch_key_map_sdl[] = { - { SDLK_BACKSPACE, RETROK_BACKSPACE }, - { SDLK_TAB, RETROK_TAB }, - { SDLK_CLEAR, RETROK_CLEAR }, - { SDLK_RETURN, RETROK_RETURN }, - { SDLK_PAUSE, RETROK_PAUSE }, - { SDLK_ESCAPE, RETROK_ESCAPE }, - { SDLK_SPACE, RETROK_SPACE }, - { SDLK_EXCLAIM, RETROK_EXCLAIM }, - { SDLK_QUOTEDBL, RETROK_QUOTEDBL }, - { SDLK_HASH, RETROK_HASH }, - { SDLK_DOLLAR, RETROK_DOLLAR }, - { SDLK_AMPERSAND, RETROK_AMPERSAND }, - { SDLK_QUOTE, RETROK_QUOTE }, - { SDLK_LEFTPAREN, RETROK_LEFTPAREN }, - { SDLK_RIGHTPAREN, RETROK_RIGHTPAREN }, - { SDLK_ASTERISK, RETROK_ASTERISK }, - { SDLK_PLUS, RETROK_PLUS }, - { SDLK_COMMA, RETROK_COMMA }, - { SDLK_MINUS, RETROK_MINUS }, - { SDLK_PERIOD, RETROK_PERIOD }, - { SDLK_SLASH, RETROK_SLASH }, - { SDLK_0, RETROK_0 }, - { SDLK_1, RETROK_1 }, - { SDLK_2, RETROK_2 }, - { SDLK_3, RETROK_3 }, - { SDLK_4, RETROK_4 }, - { SDLK_5, RETROK_5 }, - { SDLK_6, RETROK_6 }, - { SDLK_7, RETROK_7 }, - { SDLK_8, RETROK_8 }, - { SDLK_9, RETROK_9 }, - { SDLK_COLON, RETROK_COLON }, - { SDLK_SEMICOLON, RETROK_SEMICOLON }, - { SDLK_LESS, RETROK_LESS }, - { SDLK_EQUALS, RETROK_EQUALS }, - { SDLK_GREATER, RETROK_GREATER }, - { SDLK_QUESTION, RETROK_QUESTION }, - { SDLK_AT, RETROK_AT }, - { SDLK_LEFTBRACKET, RETROK_LEFTBRACKET }, - { SDLK_BACKSLASH, RETROK_BACKSLASH }, - { SDLK_RIGHTBRACKET, RETROK_RIGHTBRACKET }, - { SDLK_CARET, RETROK_CARET }, - { SDLK_UNDERSCORE, RETROK_UNDERSCORE }, - { SDLK_BACKQUOTE, RETROK_BACKQUOTE }, - { SDLK_a, RETROK_a }, - { SDLK_b, RETROK_b }, - { SDLK_c, RETROK_c }, - { SDLK_d, RETROK_d }, - { SDLK_e, RETROK_e }, - { SDLK_f, RETROK_f }, - { SDLK_g, RETROK_g }, - { SDLK_h, RETROK_h }, - { SDLK_i, RETROK_i }, - { SDLK_j, RETROK_j }, - { SDLK_k, RETROK_k }, - { SDLK_l, RETROK_l }, - { SDLK_m, RETROK_m }, - { SDLK_n, RETROK_n }, - { SDLK_o, RETROK_o }, - { SDLK_p, RETROK_p }, - { SDLK_q, RETROK_q }, - { SDLK_r, RETROK_r }, - { SDLK_s, RETROK_s }, - { SDLK_t, RETROK_t }, - { SDLK_u, RETROK_u }, - { SDLK_v, RETROK_v }, - { SDLK_w, RETROK_w }, - { SDLK_x, RETROK_x }, - { SDLK_y, RETROK_y }, - { SDLK_z, RETROK_z }, - { SDLK_DELETE, RETROK_DELETE }, -#ifdef HAVE_SDL2 - { SDLK_KP_0, RETROK_KP0 }, - { SDLK_KP_1, RETROK_KP1 }, - { SDLK_KP_2, RETROK_KP2 }, - { SDLK_KP_3, RETROK_KP3 }, - { SDLK_KP_4, RETROK_KP4 }, - { SDLK_KP_5, RETROK_KP5 }, - { SDLK_KP_6, RETROK_KP6 }, - { SDLK_KP_7, RETROK_KP7 }, - { SDLK_KP_8, RETROK_KP8 }, - { SDLK_KP_9, RETROK_KP9 }, -#else - { SDLK_KP0, RETROK_KP0 }, - { SDLK_KP1, RETROK_KP1 }, - { SDLK_KP2, RETROK_KP2 }, - { SDLK_KP3, RETROK_KP3 }, - { SDLK_KP4, RETROK_KP4 }, - { SDLK_KP5, RETROK_KP5 }, - { SDLK_KP6, RETROK_KP6 }, - { SDLK_KP7, RETROK_KP7 }, - { SDLK_KP8, RETROK_KP8 }, - { SDLK_KP9, RETROK_KP9 }, -#endif - { SDLK_KP_PERIOD, RETROK_KP_PERIOD }, - { SDLK_KP_DIVIDE, RETROK_KP_DIVIDE }, - { SDLK_KP_MULTIPLY, RETROK_KP_MULTIPLY }, - { SDLK_KP_MINUS, RETROK_KP_MINUS }, - { SDLK_KP_PLUS, RETROK_KP_PLUS }, - { SDLK_KP_ENTER, RETROK_KP_ENTER }, - { SDLK_KP_EQUALS, RETROK_KP_EQUALS }, - { SDLK_UP, RETROK_UP }, - { SDLK_DOWN, RETROK_DOWN }, - { SDLK_RIGHT, RETROK_RIGHT }, - { SDLK_LEFT, RETROK_LEFT }, - { SDLK_INSERT, RETROK_INSERT }, - { SDLK_HOME, RETROK_HOME }, - { SDLK_END, RETROK_END }, - { SDLK_PAGEUP, RETROK_PAGEUP }, - { SDLK_PAGEDOWN, RETROK_PAGEDOWN }, - { SDLK_F1, RETROK_F1 }, - { SDLK_F2, RETROK_F2 }, - { SDLK_F3, RETROK_F3 }, - { SDLK_F4, RETROK_F4 }, - { SDLK_F5, RETROK_F5 }, - { SDLK_F6, RETROK_F6 }, - { SDLK_F7, RETROK_F7 }, - { SDLK_F8, RETROK_F8 }, - { SDLK_F9, RETROK_F9 }, - { SDLK_F10, RETROK_F10 }, - { SDLK_F11, RETROK_F11 }, - { SDLK_F12, RETROK_F12 }, - { SDLK_F13, RETROK_F13 }, - { SDLK_F14, RETROK_F14 }, - { SDLK_F15, RETROK_F15 }, -#ifdef HAVE_SDL2 - { SDLK_NUMLOCKCLEAR, RETROK_NUMLOCK }, -#else - { SDLK_NUMLOCK, RETROK_NUMLOCK }, -#endif - { SDLK_CAPSLOCK, RETROK_CAPSLOCK }, -#ifdef HAVE_SDL2 - { SDLK_SCROLLLOCK, RETROK_SCROLLOCK }, -#else - { SDLK_SCROLLOCK, RETROK_SCROLLOCK }, -#endif - { SDLK_RSHIFT, RETROK_RSHIFT }, - { SDLK_LSHIFT, RETROK_LSHIFT }, - { SDLK_RCTRL, RETROK_RCTRL }, - { SDLK_LCTRL, RETROK_LCTRL }, - { SDLK_RALT, RETROK_RALT }, - { SDLK_LALT, RETROK_LALT }, -#ifdef HAVE_SDL2 - /* { ?, RETROK_RMETA }, */ - /* { ?, RETROK_LMETA }, */ - { SDLK_LGUI, RETROK_LSUPER }, - { SDLK_RGUI, RETROK_RSUPER }, -#else - { SDLK_RMETA, RETROK_RMETA }, - { SDLK_LMETA, RETROK_LMETA }, - { SDLK_LSUPER, RETROK_LSUPER }, - { SDLK_RSUPER, RETROK_RSUPER }, -#endif - { SDLK_MODE, RETROK_MODE }, -#ifndef HAVE_SDL2 - { SDLK_COMPOSE, RETROK_COMPOSE }, -#endif - { SDLK_HELP, RETROK_HELP }, -#ifdef HAVE_SDL2 - { SDLK_PRINTSCREEN, RETROK_PRINT }, -#else - { SDLK_PRINT, RETROK_PRINT }, -#endif - { SDLK_SYSREQ, RETROK_SYSREQ }, - { SDLK_PAUSE, RETROK_BREAK }, - { SDLK_MENU, RETROK_MENU }, - { SDLK_POWER, RETROK_POWER }, - -#ifndef HAVE_SDL2 - { SDLK_EURO, RETROK_EURO }, -#endif - { SDLK_UNDO, RETROK_UNDO }, - - { 0, RETROK_UNKNOWN }, -}; - static void *sdl_input_init(void) { settings_t *settings; diff --git a/input/drivers/udev_input.c b/input/drivers/udev_input.c index 2edda346fd..93728c1dfe 100644 --- a/input/drivers/udev_input.c +++ b/input/drivers/udev_input.c @@ -27,12 +27,13 @@ #include #include #include -#include #include #include #include +#include "linux_common.h" + #include "../input_common.h" #include "../input_joypad.h" #include "../input_keymaps.h" @@ -696,22 +697,9 @@ static bool open_devices(udev_input_t *udev, const char *type, device_handle_cb return true; } -static long oldkbmd = 0xffff; -static struct termios oldterm, newterm; - -static void restore_terminal_input(void) -{ - if (oldkbmd == 0xffff) - return; - - ioctl(0, KDSKBMODE, oldkbmd); - tcsetattr(0, TCSAFLUSH, &oldterm); - oldkbmd = 0xffff; -} - static void restore_terminal_signal(int sig) { - restore_terminal_input(); + linux_terminal_restore_input(); kill(getpid(), sig); } @@ -720,26 +708,12 @@ static void disable_terminal_input(void) struct sigaction sa = {{0}}; /* Avoid accidentally typing stuff. */ - if (!isatty(0) || oldkbmd != 0xffff) + if (!isatty(0)) return; - if (tcgetattr(0, &oldterm) < 0) - return; - - newterm = oldterm; - newterm.c_lflag &= ~(ECHO | ICANON | ISIG); - newterm.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); - newterm.c_cc[VMIN] = 0; - newterm.c_cc[VTIME] = 0; - - /* Be careful about recovering the terminal ... */ - if (ioctl(0, KDGKBMODE, &oldkbmd) < 0) - return; - if (tcsetattr(0, TCSAFLUSH, &newterm) < 0) - return; - if (ioctl(0, KDSKBMODE, K_MEDIUMRAW) < 0) + if (!linux_terminal_init()) { - tcsetattr(0, TCSAFLUSH, &oldterm); + linux_terminal_flush(); return; } @@ -755,7 +729,7 @@ static void disable_terminal_input(void) sigaction(SIGQUIT, &sa, NULL); sigaction(SIGSEGV, &sa, NULL); - atexit(restore_terminal_input); + atexit(linux_terminal_restore_input); } static void *udev_input_init(void) @@ -944,7 +918,7 @@ input_driver_t input_udev = { udev_input_get_capabilities, "udev", udev_input_grab_mouse, - NULL, + linux_terminal_grab_stdin, udev_input_set_rumble, udev_input_get_joypad_driver, udev_input_keyboard_mapping_is_blocked, diff --git a/input/drivers/x11_input.c b/input/drivers/x11_input.c index 4df16f847f..273e28bc5d 100644 --- a/input/drivers/x11_input.c +++ b/input/drivers/x11_input.c @@ -46,145 +46,6 @@ typedef struct x11_input bool grab_mouse; } x11_input_t; -const struct rarch_key_map rarch_key_map_x11[] = { - { XK_BackSpace, RETROK_BACKSPACE }, - { XK_Tab, RETROK_TAB }, - { XK_Clear, RETROK_CLEAR }, - { XK_Return, RETROK_RETURN }, - { XK_Pause, RETROK_PAUSE }, - { XK_Escape, RETROK_ESCAPE }, - { XK_space, RETROK_SPACE }, - { XK_exclam, RETROK_EXCLAIM }, - { XK_quotedbl, RETROK_QUOTEDBL }, - { XK_numbersign, RETROK_HASH }, - { XK_dollar, RETROK_DOLLAR }, - { XK_ampersand, RETROK_AMPERSAND }, - { XK_apostrophe, RETROK_QUOTE }, - { XK_parenleft, RETROK_LEFTPAREN }, - { XK_parenright, RETROK_RIGHTPAREN }, - { XK_asterisk, RETROK_ASTERISK }, - { XK_plus, RETROK_PLUS }, - { XK_comma, RETROK_COMMA }, - { XK_minus, RETROK_MINUS }, - { XK_period, RETROK_PERIOD }, - { XK_slash, RETROK_SLASH }, - { XK_0, RETROK_0 }, - { XK_1, RETROK_1 }, - { XK_2, RETROK_2 }, - { XK_3, RETROK_3 }, - { XK_4, RETROK_4 }, - { XK_5, RETROK_5 }, - { XK_6, RETROK_6 }, - { XK_7, RETROK_7 }, - { XK_8, RETROK_8 }, - { XK_9, RETROK_9 }, - { XK_colon, RETROK_COLON }, - { XK_semicolon, RETROK_SEMICOLON }, - { XK_less, RETROK_LESS }, - { XK_equal, RETROK_EQUALS }, - { XK_greater, RETROK_GREATER }, - { XK_question, RETROK_QUESTION }, - { XK_at, RETROK_AT }, - { XK_bracketleft, RETROK_LEFTBRACKET }, - { XK_backslash, RETROK_BACKSLASH }, - { XK_bracketright, RETROK_RIGHTBRACKET }, - { XK_dead_circumflex, RETROK_CARET }, - { XK_underscore, RETROK_UNDERSCORE }, - { XK_grave, RETROK_BACKQUOTE }, - { XK_a, RETROK_a }, - { XK_b, RETROK_b }, - { XK_c, RETROK_c }, - { XK_d, RETROK_d }, - { XK_e, RETROK_e }, - { XK_f, RETROK_f }, - { XK_g, RETROK_g }, - { XK_h, RETROK_h }, - { XK_i, RETROK_i }, - { XK_j, RETROK_j }, - { XK_k, RETROK_k }, - { XK_l, RETROK_l }, - { XK_m, RETROK_m }, - { XK_n, RETROK_n }, - { XK_o, RETROK_o }, - { XK_p, RETROK_p }, - { XK_q, RETROK_q }, - { XK_r, RETROK_r }, - { XK_s, RETROK_s }, - { XK_t, RETROK_t }, - { XK_u, RETROK_u }, - { XK_v, RETROK_v }, - { XK_w, RETROK_w }, - { XK_x, RETROK_x }, - { XK_y, RETROK_y }, - { XK_z, RETROK_z }, - { XK_Delete, RETROK_DELETE }, - { XK_KP_0, RETROK_KP0 }, - { XK_KP_1, RETROK_KP1 }, - { XK_KP_2, RETROK_KP2 }, - { XK_KP_3, RETROK_KP3 }, - { XK_KP_4, RETROK_KP4 }, - { XK_KP_5, RETROK_KP5 }, - { XK_KP_6, RETROK_KP6 }, - { XK_KP_7, RETROK_KP7 }, - { XK_KP_8, RETROK_KP8 }, - { XK_KP_9, RETROK_KP9 }, - { XK_KP_Decimal, RETROK_KP_PERIOD }, - { XK_KP_Divide, RETROK_KP_DIVIDE }, - { XK_KP_Multiply, RETROK_KP_MULTIPLY }, - { XK_KP_Subtract, RETROK_KP_MINUS }, - { XK_KP_Add, RETROK_KP_PLUS }, - { XK_KP_Enter, RETROK_KP_ENTER }, - { XK_KP_Equal, RETROK_KP_EQUALS }, - { XK_Up, RETROK_UP }, - { XK_Down, RETROK_DOWN }, - { XK_Right, RETROK_RIGHT }, - { XK_Left, RETROK_LEFT }, - { XK_Insert, RETROK_INSERT }, - { XK_Home, RETROK_HOME }, - { XK_End, RETROK_END }, - { XK_Page_Up, RETROK_PAGEUP }, - { XK_Page_Down, RETROK_PAGEDOWN }, - { XK_F1, RETROK_F1 }, - { XK_F2, RETROK_F2 }, - { XK_F3, RETROK_F3 }, - { XK_F4, RETROK_F4 }, - { XK_F5, RETROK_F5 }, - { XK_F6, RETROK_F6 }, - { XK_F7, RETROK_F7 }, - { XK_F8, RETROK_F8 }, - { XK_F9, RETROK_F9 }, - { XK_F10, RETROK_F10 }, - { XK_F11, RETROK_F11 }, - { XK_F12, RETROK_F12 }, - { XK_F13, RETROK_F13 }, - { XK_F14, RETROK_F14 }, - { XK_F15, RETROK_F15 }, - { XK_Num_Lock, RETROK_NUMLOCK }, - { XK_Caps_Lock, RETROK_CAPSLOCK }, - { XK_Scroll_Lock, RETROK_SCROLLOCK }, - { XK_Shift_R, RETROK_RSHIFT }, - { XK_Shift_L, RETROK_LSHIFT }, - { XK_Control_R, RETROK_RCTRL }, - { XK_Control_L, RETROK_LCTRL }, - { XK_Alt_R, RETROK_RALT }, - { XK_Alt_L, RETROK_LALT }, - { XK_Meta_R, RETROK_RMETA }, - { XK_Meta_L, RETROK_LMETA }, - { XK_Super_L, RETROK_LSUPER }, - { XK_Super_R, RETROK_RSUPER }, - { XK_Mode_switch, RETROK_MODE }, - { XK_Multi_key, RETROK_COMPOSE }, - { XK_Help, RETROK_HELP }, - { XK_Print, RETROK_PRINT }, - { XK_Sys_Req, RETROK_SYSREQ }, - { XK_Break, RETROK_BREAK }, - { XK_Menu, RETROK_MENU }, - /*{ ?, RETROK_POWER },*/ - { XK_EuroSign, RETROK_EURO }, - { XK_Undo, RETROK_UNDO }, - - { 0, RETROK_UNKNOWN }, -}; static void *x_input_init(void) { diff --git a/input/drivers_keyboard/keyboard_event_apple.c b/input/drivers_keyboard/keyboard_event_apple.c index 9f643a18e7..8441ed731a 100644 --- a/input/drivers_keyboard/keyboard_event_apple.c +++ b/input/drivers_keyboard/keyboard_event_apple.c @@ -36,19 +36,20 @@ * check keycode.h for license. */ static const unsigned char MAC_NATIVE_TO_HID[128] = { - 4, 22, 7, 9, 11, 10, 29, 27, 6, 25,255, 5, 20, 26, 8, 21, - 28, 23, 30, 31, 32, 33, 35, 34, 46, 38, 36, 45, 37, 39, 48, 18, - 24, 47, 12, 19, 40, 15, 13, 52, 14, 51, 49, 54, 56, 17, 16, 55, - 43, 44, 53, 42,255, 41,231,227,225, 57,226,224,229,230,228,255, -108, 99,255, 85,255, 87,255, 83,255,255,255, 84, 88,255, 86,109, -110,103, 98, 89, 90, 91, 92, 93, 94, 95,111, 96, 97,255,255,255, - 62, 63, 64, 60, 65, 66,255, 68,255,104,107,105,255, 67,255, 69, -255,106,117, 74, 75, 76, 61, 77, 59, 78, 58, 80, 79, 81, 82,255 + 4, 22, 7, 9, 11, 10, 29, 27, 6, 25,255, 5, 20, 26, 8, 21, + 28, 23, 30, 31, 32, 33, 35, 34, 46, 38, 36, 45, 37, 39, 48, 18, + 24, 47, 12, 19, 40, 15, 13, 52, 14, 51, 49, 54, 56, 17, 16, 55, + 43, 44, 53, 42,255, 41,231,227,225, 57,226,224,229,230,228,255, + 108, 99,255, 85,255, 87,255, 83,255,255,255, 84, 88,255, 86,109, + 110,103, 98, 89, 90, 91, 92, 93, 94, 95,111, 96, 97,255,255,255, + 62, 63, 64, 60, 65, 66,255, 68,255,104,107,105,255, 67,255, 69, + 255,106,117, 74, 75, 76, 61, 77, 59, 78, 58, 80, 79, 81, 82,255 }; #define HIDKEY(X) (X < 128) ? MAC_NATIVE_TO_HID[X] : 0 #endif +#if TARGET_OS_IPHONE static bool handle_small_keyboard(unsigned* code, bool down) { static uint8_t mapping[128]; @@ -73,7 +74,7 @@ static bool handle_small_keyboard(unsigned* code, bool down) driver_t *driver = driver_get_ptr(); cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data; unsigned translated_code = 0; - + if (!map_initialized) { int i; @@ -88,15 +89,15 @@ static bool handle_small_keyboard(unsigned* code, bool down) *code = 0; return true; } - + translated_code = (*code < 128) ? mapping[*code] : 0; - + /* Allow old keys to be released. */ if (!down && apple->key_state[*code]) return false; if ((!down && apple->key_state[translated_code]) || - apple->small_keyboard_active) + apple->small_keyboard_active) { *code = translated_code; return true; @@ -105,42 +106,134 @@ static bool handle_small_keyboard(unsigned* code, bool down) return false; } -static void handle_icade_event(unsigned keycode) +extern const struct rarch_key_map rarch_key_map_apple_hid[]; + +typedef struct icade_map { - static const struct + bool up; + enum retro_key key; +} icade_map_t; + +#define MAX_ICADE_PROFILES 3 +#define MAX_ICADE_KEYS 0x100 + +static icade_map_t icade_maps[MAX_ICADE_PROFILES][MAX_ICADE_KEYS]; + +static bool handle_icade_event(unsigned *code, bool *keydown) +{ + settings_t *settings = config_get_ptr(); + static bool initialized = false; + bool ret = false; + unsigned kb_type_idx = settings->input.keyboard_gamepad_mapping_type; + + if (!initialized) { - bool up; - int button; - } icade_map[0x20] = - { - { false, -1 }, { false, -1 }, { false, -1 }, { false, -1 }, // 0 - { false, 2 }, { false, -1 }, { true , 3 }, { false, 3 }, // 4 - { true , 0 }, { true, 5 }, { true , 7 }, { false, 8 }, // 8 - { false, 6 }, { false, 9 }, { false, 10 }, { false, 11 }, // C - { true , 6 }, { true , 9 }, { false, 7 }, { true, 10 }, // 0 - { true , 2 }, { true , 8 }, { false, -1 }, { true , 4 }, // 4 - { false, 5 }, { true , 11 }, { false, 0 }, { false, 1 }, // 8 - { false, 4 }, { true , 1 }, { false, -1 }, { false, -1 } // C - }; - driver_t *driver = driver_get_ptr(); - cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data; - - if (apple->icade_enabled && (keycode < 0x20) - && (icade_map[keycode].button >= 0)) - { - const int button = icade_map[keycode].button; - - if (icade_map[keycode].up) - BIT32_CLEAR(apple->icade_buttons, button); - else - BIT32_SET(apple->icade_buttons, button); + unsigned i; + unsigned j = 0; + + for (j = 0; j < MAX_ICADE_PROFILES; j++) + { + for (i = 0; i < MAX_ICADE_KEYS; i++) + { + icade_maps[j][i].key = RETROK_UNKNOWN; + icade_maps[j][i].up = false; + } + } + + /* iPega PG-9017 */ + j = 1; + + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_a)].key = RETROK_LEFT; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_q)].key = RETROK_LEFT; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_c)].key = RETROK_RIGHT; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_d)].key = RETROK_RIGHT; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_e)].key = RETROK_UP; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_w)].key = RETROK_UP; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_x)].key = RETROK_DOWN; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_z)].key = RETROK_DOWN; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_f)].key = RETROK_z; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_u)].key = RETROK_z; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_i)].key = RETROK_q; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_m)].key = RETROK_q; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_j)].key = RETROK_a; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_n)].key = RETROK_a; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_k)].key = RETROK_w; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_p)].key = RETROK_w; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_h)].key = RETROK_x; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_r)].key = RETROK_x; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_y)].key = RETROK_s; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_t)].key = RETROK_s; + + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_e)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_z)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_q)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_c)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_f)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_m)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_t)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_n)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_p)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_r)].up = true; + + /* 8-bitty */ + j = 2; + + initialized = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_a)].key = RETROK_LEFT; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_q)].key = RETROK_LEFT; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_c)].key = RETROK_RIGHT; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_d)].key = RETROK_RIGHT; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_e)].key = RETROK_UP; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_w)].key = RETROK_UP; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_x)].key = RETROK_DOWN; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_z)].key = RETROK_DOWN; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_h)].key = RETROK_q; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_r)].key = RETROK_q; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_j)].key = RETROK_w; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_n)].key = RETROK_w; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_i)].key = RETROK_a; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_m)].key = RETROK_a; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_k)].key = RETROK_z; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_p)].key = RETROK_z; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_y)].key = RETROK_RSHIFT; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_t)].key = RETROK_RSHIFT; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_u)].key = RETROK_RETURN; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_f)].key = RETROK_RETURN; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_l)].key = RETROK_x; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_v)].key = RETROK_x; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_o)].key = RETROK_s; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_g)].key = RETROK_s; + + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_e)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_z)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_q)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_c)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_r)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_n)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_m)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_p)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_t)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_f)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_v)].up = true; + icade_maps[j][input_keymaps_translate_rk_to_keysym(RETROK_g)].up = true; } + + if ((*code < 0x20) && (icade_maps[kb_type_idx][*code].key != RETROK_UNKNOWN)) + { + *keydown = icade_maps[kb_type_idx][*code].up ? false : true; + ret = true; + *code = input_keymaps_translate_rk_to_keysym(icade_maps[kb_type_idx][*code].key); + } + + return ret; } +#endif void cocoa_input_keyboard_event(bool down, unsigned code, uint32_t character, uint32_t mod, unsigned device) { driver_t *driver = driver_get_ptr(); + settings_t *settings = config_get_ptr(); cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data; if (!apple) @@ -148,21 +241,26 @@ void cocoa_input_keyboard_event(bool down, code = HIDKEY(code); - if (apple->icade_enabled) +#if TARGET_OS_IPHONE + if (settings->input.keyboard_gamepad_enable) { - handle_icade_event(code); - return; + if (handle_icade_event(&code, &down)) + character = 0; + else + code = 0; } + else if (settings->input.small_keyboard_enable) + { + if (handle_small_keyboard(&code, down)) + character = 0; + } +#endif - if (apple->small_keyboard_enabled && - handle_small_keyboard(&code, down)) - character = 0; - if (code == 0 || code >= MAX_KEYS) return; apple->key_state[code] = down; - + input_keyboard_event(down, input_keymaps_translate_keysym_to_rk(code), character, (enum retro_mod)mod, device); diff --git a/input/drivers_keyboard/keyboard_event_win32.c b/input/drivers_keyboard/keyboard_event_win32.cpp similarity index 100% rename from input/drivers_keyboard/keyboard_event_win32.c rename to input/drivers_keyboard/keyboard_event_win32.cpp diff --git a/input/input_common.c b/input/input_common.c index 484f514d9b..633e199dd7 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -339,7 +339,6 @@ void input_config_parse_joy_axis(config_file_t *conf, const char *prefix, } } -#if !defined(IS_JOYCONFIG) static void input_get_bind_string_joykey(char *buf, const char *prefix, const struct retro_keybind *bind, size_t size) { @@ -434,7 +433,6 @@ void input_get_bind_string(char *buf, const struct retro_keybind *bind, strlcat(buf, keybuf, size); #endif } -#endif /** * input_push_analog_dpad: diff --git a/input/input_hid_driver.c b/input/input_hid_driver.c index 1c0070f4f8..d86a305624 100644 --- a/input/input_hid_driver.c +++ b/input/input_hid_driver.c @@ -20,9 +20,7 @@ #include "input_hid_driver.h" #include "../general.h" -#ifndef IS_JOYCONFIG #include "../string_list_special.h" -#endif static hid_driver_t *hid_drivers[] = { #if defined(__APPLE__) && defined(IOS) @@ -71,7 +69,6 @@ const char *hid_driver_find_ident(int idx) return drv->ident; } -#ifndef IS_JOYCONFIG /** * config_get_hid_driver_options: * @@ -83,7 +80,6 @@ const char* config_get_hid_driver_options(void) { return char_list_new_special(STRING_LIST_INPUT_HID_DRIVERS, NULL); } -#endif /** * input_hid_init_first: diff --git a/input/input_joypad_driver.c b/input/input_joypad_driver.c index 6e6dd4b7d2..b0af6763ec 100644 --- a/input/input_joypad_driver.c +++ b/input/input_joypad_driver.c @@ -20,9 +20,7 @@ #include "input_keymaps.h" #include "../general.h" -#ifndef IS_JOYCONFIG #include "../string_list_special.h" -#endif static input_device_driver_t *joypad_drivers[] = { #ifdef __CELLOS_LV2__ @@ -99,7 +97,6 @@ const char *joypad_driver_find_ident(int idx) return drv->ident; } -#ifndef IS_JOYCONFIG /** * config_get_joypad_driver_options: * @@ -111,7 +108,6 @@ const char* config_get_joypad_driver_options(void) { return char_list_new_special(STRING_LIST_INPUT_JOYPAD_DRIVERS, NULL); } -#endif /** * input_joypad_init_driver: diff --git a/input/input_keymaps.c b/input/input_keymaps.c index 8c425d64b4..22dde84a38 100644 --- a/input/input_keymaps.c +++ b/input/input_keymaps.c @@ -18,16 +18,34 @@ #include #include +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +#if defined(HAVE_SDL) || defined(HAVE_SDL2) +#include "SDL.h" +#endif + #ifdef __linux__ #include #include #endif +#ifdef HAVE_X11 +#include +#include +#include +#endif + +#ifdef HAVE_DINPUT +#undef DIRECTINPUT_VERSION +#define DIRECTINPUT_VERSION 0x0800 + +#include +#endif + #include "input_keymaps.h" #include "../general.h" -#ifdef HAVE_CONFIG_H -#include "../config.h" -#endif #ifdef __APPLE__ #include "drivers/apple_keycode.h" @@ -159,6 +177,291 @@ const struct input_key_map input_config_key_map[] = { { NULL, RETROK_UNKNOWN }, }; +#if defined(HAVE_SDL) || defined(HAVE_SDL2) +const struct rarch_key_map rarch_key_map_sdl[] = { + { SDLK_BACKSPACE, RETROK_BACKSPACE }, + { SDLK_TAB, RETROK_TAB }, + { SDLK_CLEAR, RETROK_CLEAR }, + { SDLK_RETURN, RETROK_RETURN }, + { SDLK_PAUSE, RETROK_PAUSE }, + { SDLK_ESCAPE, RETROK_ESCAPE }, + { SDLK_SPACE, RETROK_SPACE }, + { SDLK_EXCLAIM, RETROK_EXCLAIM }, + { SDLK_QUOTEDBL, RETROK_QUOTEDBL }, + { SDLK_HASH, RETROK_HASH }, + { SDLK_DOLLAR, RETROK_DOLLAR }, + { SDLK_AMPERSAND, RETROK_AMPERSAND }, + { SDLK_QUOTE, RETROK_QUOTE }, + { SDLK_LEFTPAREN, RETROK_LEFTPAREN }, + { SDLK_RIGHTPAREN, RETROK_RIGHTPAREN }, + { SDLK_ASTERISK, RETROK_ASTERISK }, + { SDLK_PLUS, RETROK_PLUS }, + { SDLK_COMMA, RETROK_COMMA }, + { SDLK_MINUS, RETROK_MINUS }, + { SDLK_PERIOD, RETROK_PERIOD }, + { SDLK_SLASH, RETROK_SLASH }, + { SDLK_0, RETROK_0 }, + { SDLK_1, RETROK_1 }, + { SDLK_2, RETROK_2 }, + { SDLK_3, RETROK_3 }, + { SDLK_4, RETROK_4 }, + { SDLK_5, RETROK_5 }, + { SDLK_6, RETROK_6 }, + { SDLK_7, RETROK_7 }, + { SDLK_8, RETROK_8 }, + { SDLK_9, RETROK_9 }, + { SDLK_COLON, RETROK_COLON }, + { SDLK_SEMICOLON, RETROK_SEMICOLON }, + { SDLK_LESS, RETROK_LESS }, + { SDLK_EQUALS, RETROK_EQUALS }, + { SDLK_GREATER, RETROK_GREATER }, + { SDLK_QUESTION, RETROK_QUESTION }, + { SDLK_AT, RETROK_AT }, + { SDLK_LEFTBRACKET, RETROK_LEFTBRACKET }, + { SDLK_BACKSLASH, RETROK_BACKSLASH }, + { SDLK_RIGHTBRACKET, RETROK_RIGHTBRACKET }, + { SDLK_CARET, RETROK_CARET }, + { SDLK_UNDERSCORE, RETROK_UNDERSCORE }, + { SDLK_BACKQUOTE, RETROK_BACKQUOTE }, + { SDLK_a, RETROK_a }, + { SDLK_b, RETROK_b }, + { SDLK_c, RETROK_c }, + { SDLK_d, RETROK_d }, + { SDLK_e, RETROK_e }, + { SDLK_f, RETROK_f }, + { SDLK_g, RETROK_g }, + { SDLK_h, RETROK_h }, + { SDLK_i, RETROK_i }, + { SDLK_j, RETROK_j }, + { SDLK_k, RETROK_k }, + { SDLK_l, RETROK_l }, + { SDLK_m, RETROK_m }, + { SDLK_n, RETROK_n }, + { SDLK_o, RETROK_o }, + { SDLK_p, RETROK_p }, + { SDLK_q, RETROK_q }, + { SDLK_r, RETROK_r }, + { SDLK_s, RETROK_s }, + { SDLK_t, RETROK_t }, + { SDLK_u, RETROK_u }, + { SDLK_v, RETROK_v }, + { SDLK_w, RETROK_w }, + { SDLK_x, RETROK_x }, + { SDLK_y, RETROK_y }, + { SDLK_z, RETROK_z }, + { SDLK_DELETE, RETROK_DELETE }, +#ifdef HAVE_SDL2 + { SDLK_KP_0, RETROK_KP0 }, + { SDLK_KP_1, RETROK_KP1 }, + { SDLK_KP_2, RETROK_KP2 }, + { SDLK_KP_3, RETROK_KP3 }, + { SDLK_KP_4, RETROK_KP4 }, + { SDLK_KP_5, RETROK_KP5 }, + { SDLK_KP_6, RETROK_KP6 }, + { SDLK_KP_7, RETROK_KP7 }, + { SDLK_KP_8, RETROK_KP8 }, + { SDLK_KP_9, RETROK_KP9 }, +#else + { SDLK_KP0, RETROK_KP0 }, + { SDLK_KP1, RETROK_KP1 }, + { SDLK_KP2, RETROK_KP2 }, + { SDLK_KP3, RETROK_KP3 }, + { SDLK_KP4, RETROK_KP4 }, + { SDLK_KP5, RETROK_KP5 }, + { SDLK_KP6, RETROK_KP6 }, + { SDLK_KP7, RETROK_KP7 }, + { SDLK_KP8, RETROK_KP8 }, + { SDLK_KP9, RETROK_KP9 }, +#endif + { SDLK_KP_PERIOD, RETROK_KP_PERIOD }, + { SDLK_KP_DIVIDE, RETROK_KP_DIVIDE }, + { SDLK_KP_MULTIPLY, RETROK_KP_MULTIPLY }, + { SDLK_KP_MINUS, RETROK_KP_MINUS }, + { SDLK_KP_PLUS, RETROK_KP_PLUS }, + { SDLK_KP_ENTER, RETROK_KP_ENTER }, + { SDLK_KP_EQUALS, RETROK_KP_EQUALS }, + { SDLK_UP, RETROK_UP }, + { SDLK_DOWN, RETROK_DOWN }, + { SDLK_RIGHT, RETROK_RIGHT }, + { SDLK_LEFT, RETROK_LEFT }, + { SDLK_INSERT, RETROK_INSERT }, + { SDLK_HOME, RETROK_HOME }, + { SDLK_END, RETROK_END }, + { SDLK_PAGEUP, RETROK_PAGEUP }, + { SDLK_PAGEDOWN, RETROK_PAGEDOWN }, + { SDLK_F1, RETROK_F1 }, + { SDLK_F2, RETROK_F2 }, + { SDLK_F3, RETROK_F3 }, + { SDLK_F4, RETROK_F4 }, + { SDLK_F5, RETROK_F5 }, + { SDLK_F6, RETROK_F6 }, + { SDLK_F7, RETROK_F7 }, + { SDLK_F8, RETROK_F8 }, + { SDLK_F9, RETROK_F9 }, + { SDLK_F10, RETROK_F10 }, + { SDLK_F11, RETROK_F11 }, + { SDLK_F12, RETROK_F12 }, + { SDLK_F13, RETROK_F13 }, + { SDLK_F14, RETROK_F14 }, + { SDLK_F15, RETROK_F15 }, +#ifdef HAVE_SDL2 + { SDLK_NUMLOCKCLEAR, RETROK_NUMLOCK }, +#else + { SDLK_NUMLOCK, RETROK_NUMLOCK }, +#endif + { SDLK_CAPSLOCK, RETROK_CAPSLOCK }, +#ifdef HAVE_SDL2 + { SDLK_SCROLLLOCK, RETROK_SCROLLOCK }, +#else + { SDLK_SCROLLOCK, RETROK_SCROLLOCK }, +#endif + { SDLK_RSHIFT, RETROK_RSHIFT }, + { SDLK_LSHIFT, RETROK_LSHIFT }, + { SDLK_RCTRL, RETROK_RCTRL }, + { SDLK_LCTRL, RETROK_LCTRL }, + { SDLK_RALT, RETROK_RALT }, + { SDLK_LALT, RETROK_LALT }, +#ifdef HAVE_SDL2 + /* { ?, RETROK_RMETA }, */ + /* { ?, RETROK_LMETA }, */ + { SDLK_LGUI, RETROK_LSUPER }, + { SDLK_RGUI, RETROK_RSUPER }, +#else + { SDLK_RMETA, RETROK_RMETA }, + { SDLK_LMETA, RETROK_LMETA }, + { SDLK_LSUPER, RETROK_LSUPER }, + { SDLK_RSUPER, RETROK_RSUPER }, +#endif + { SDLK_MODE, RETROK_MODE }, +#ifndef HAVE_SDL2 + { SDLK_COMPOSE, RETROK_COMPOSE }, +#endif + { SDLK_HELP, RETROK_HELP }, +#ifdef HAVE_SDL2 + { SDLK_PRINTSCREEN, RETROK_PRINT }, +#else + { SDLK_PRINT, RETROK_PRINT }, +#endif + { SDLK_SYSREQ, RETROK_SYSREQ }, + { SDLK_PAUSE, RETROK_BREAK }, + { SDLK_MENU, RETROK_MENU }, + { SDLK_POWER, RETROK_POWER }, + +#ifndef HAVE_SDL2 + { SDLK_EURO, RETROK_EURO }, +#endif + { SDLK_UNDO, RETROK_UNDO }, + + { 0, RETROK_UNKNOWN }, +}; +#endif + +#ifdef HAVE_DINPUT +const struct rarch_key_map rarch_key_map_dinput[] = { + { DIK_LEFT, RETROK_LEFT }, + { DIK_RIGHT, RETROK_RIGHT }, + { DIK_UP, RETROK_UP }, + { DIK_DOWN, RETROK_DOWN }, + { DIK_RETURN, RETROK_RETURN }, + { DIK_TAB, RETROK_TAB }, + { DIK_INSERT, RETROK_INSERT }, + { DIK_DELETE, RETROK_DELETE }, + { DIK_RSHIFT, RETROK_RSHIFT }, + { DIK_LSHIFT, RETROK_LSHIFT }, + { DIK_LCONTROL, RETROK_LCTRL }, + { DIK_END, RETROK_END }, + { DIK_HOME, RETROK_HOME }, + { DIK_NEXT, RETROK_PAGEDOWN }, + { DIK_PRIOR, RETROK_PAGEUP }, + { DIK_LALT, RETROK_LALT }, + { DIK_SPACE, RETROK_SPACE }, + { DIK_ESCAPE, RETROK_ESCAPE }, + { DIK_BACKSPACE, RETROK_BACKSPACE }, + { DIK_NUMPADENTER, RETROK_KP_ENTER }, + { DIK_NUMPADPLUS, RETROK_KP_PLUS }, + { DIK_NUMPADMINUS, RETROK_KP_MINUS }, + { DIK_NUMPADSTAR, RETROK_KP_MULTIPLY }, + { DIK_DIVIDE, RETROK_KP_DIVIDE }, + { DIK_GRAVE, RETROK_BACKQUOTE }, + { DIK_PAUSE, RETROK_PAUSE }, + { DIK_NUMPAD0, RETROK_KP0 }, + { DIK_NUMPAD1, RETROK_KP1 }, + { DIK_NUMPAD2, RETROK_KP2 }, + { DIK_NUMPAD3, RETROK_KP3 }, + { DIK_NUMPAD4, RETROK_KP4 }, + { DIK_NUMPAD5, RETROK_KP5 }, + { DIK_NUMPAD6, RETROK_KP6 }, + { DIK_NUMPAD7, RETROK_KP7 }, + { DIK_NUMPAD8, RETROK_KP8 }, + { DIK_NUMPAD9, RETROK_KP9 }, + { DIK_0, RETROK_0 }, + { DIK_1, RETROK_1 }, + { DIK_2, RETROK_2 }, + { DIK_3, RETROK_3 }, + { DIK_4, RETROK_4 }, + { DIK_5, RETROK_5 }, + { DIK_6, RETROK_6 }, + { DIK_7, RETROK_7 }, + { DIK_8, RETROK_8 }, + { DIK_9, RETROK_9 }, + { DIK_F1, RETROK_F1 }, + { DIK_F2, RETROK_F2 }, + { DIK_F3, RETROK_F3 }, + { DIK_F4, RETROK_F4 }, + { DIK_F5, RETROK_F5 }, + { DIK_F6, RETROK_F6 }, + { DIK_F7, RETROK_F7 }, + { DIK_F8, RETROK_F8 }, + { DIK_F9, RETROK_F9 }, + { DIK_F10, RETROK_F10 }, + { DIK_F11, RETROK_F11 }, + { DIK_F12, RETROK_F12 }, + { DIK_A, RETROK_a }, + { DIK_B, RETROK_b }, + { DIK_C, RETROK_c }, + { DIK_D, RETROK_d }, + { DIK_E, RETROK_e }, + { DIK_F, RETROK_f }, + { DIK_G, RETROK_g }, + { DIK_H, RETROK_h }, + { DIK_I, RETROK_i }, + { DIK_J, RETROK_j }, + { DIK_K, RETROK_k }, + { DIK_L, RETROK_l }, + { DIK_M, RETROK_m }, + { DIK_N, RETROK_n }, + { DIK_O, RETROK_o }, + { DIK_P, RETROK_p }, + { DIK_Q, RETROK_q }, + { DIK_R, RETROK_r }, + { DIK_S, RETROK_s }, + { DIK_T, RETROK_t }, + { DIK_U, RETROK_u }, + { DIK_V, RETROK_v }, + { DIK_W, RETROK_w }, + { DIK_X, RETROK_x }, + { DIK_Y, RETROK_y }, + { DIK_Z, RETROK_z }, + { DIK_APOSTROPHE, RETROK_QUOTE }, + { DIK_COMMA, RETROK_COMMA }, + { DIK_MINUS, RETROK_MINUS }, + { DIK_SLASH, RETROK_SLASH }, + { DIK_SEMICOLON, RETROK_SEMICOLON }, + { DIK_EQUALS, RETROK_EQUALS }, + { DIK_LBRACKET, RETROK_LEFTBRACKET }, + { DIK_BACKSLASH, RETROK_BACKSLASH }, + { DIK_RBRACKET, RETROK_RIGHTBRACKET }, + { DIK_DECIMAL, RETROK_KP_PERIOD }, + { DIK_RCONTROL, RETROK_RCTRL }, + { DIK_RMENU, RETROK_RALT }, + { DIK_PERIOD, RETROK_PERIOD }, + { DIK_SCROLL, RETROK_SCROLLOCK }, + { DIK_CAPSLOCK, RETROK_CAPSLOCK }, + { DIK_NUMLOCK, RETROK_NUMLOCK }, + { 0, RETROK_UNKNOWN }, +}; +#endif + #ifdef EMSCRIPTEN const struct rarch_key_map rarch_key_map_rwebinput[] = { { 37, RETROK_LEFT }, @@ -265,6 +568,148 @@ const struct rarch_key_map rarch_key_map_rwebinput[] = { }; #endif +#ifdef HAVE_X11 +const struct rarch_key_map rarch_key_map_x11[] = { + { XK_BackSpace, RETROK_BACKSPACE }, + { XK_Tab, RETROK_TAB }, + { XK_Clear, RETROK_CLEAR }, + { XK_Return, RETROK_RETURN }, + { XK_Pause, RETROK_PAUSE }, + { XK_Escape, RETROK_ESCAPE }, + { XK_space, RETROK_SPACE }, + { XK_exclam, RETROK_EXCLAIM }, + { XK_quotedbl, RETROK_QUOTEDBL }, + { XK_numbersign, RETROK_HASH }, + { XK_dollar, RETROK_DOLLAR }, + { XK_ampersand, RETROK_AMPERSAND }, + { XK_apostrophe, RETROK_QUOTE }, + { XK_parenleft, RETROK_LEFTPAREN }, + { XK_parenright, RETROK_RIGHTPAREN }, + { XK_asterisk, RETROK_ASTERISK }, + { XK_plus, RETROK_PLUS }, + { XK_comma, RETROK_COMMA }, + { XK_minus, RETROK_MINUS }, + { XK_period, RETROK_PERIOD }, + { XK_slash, RETROK_SLASH }, + { XK_0, RETROK_0 }, + { XK_1, RETROK_1 }, + { XK_2, RETROK_2 }, + { XK_3, RETROK_3 }, + { XK_4, RETROK_4 }, + { XK_5, RETROK_5 }, + { XK_6, RETROK_6 }, + { XK_7, RETROK_7 }, + { XK_8, RETROK_8 }, + { XK_9, RETROK_9 }, + { XK_colon, RETROK_COLON }, + { XK_semicolon, RETROK_SEMICOLON }, + { XK_less, RETROK_LESS }, + { XK_equal, RETROK_EQUALS }, + { XK_greater, RETROK_GREATER }, + { XK_question, RETROK_QUESTION }, + { XK_at, RETROK_AT }, + { XK_bracketleft, RETROK_LEFTBRACKET }, + { XK_backslash, RETROK_BACKSLASH }, + { XK_bracketright, RETROK_RIGHTBRACKET }, + { XK_dead_circumflex, RETROK_CARET }, + { XK_underscore, RETROK_UNDERSCORE }, + { XK_grave, RETROK_BACKQUOTE }, + { XK_a, RETROK_a }, + { XK_b, RETROK_b }, + { XK_c, RETROK_c }, + { XK_d, RETROK_d }, + { XK_e, RETROK_e }, + { XK_f, RETROK_f }, + { XK_g, RETROK_g }, + { XK_h, RETROK_h }, + { XK_i, RETROK_i }, + { XK_j, RETROK_j }, + { XK_k, RETROK_k }, + { XK_l, RETROK_l }, + { XK_m, RETROK_m }, + { XK_n, RETROK_n }, + { XK_o, RETROK_o }, + { XK_p, RETROK_p }, + { XK_q, RETROK_q }, + { XK_r, RETROK_r }, + { XK_s, RETROK_s }, + { XK_t, RETROK_t }, + { XK_u, RETROK_u }, + { XK_v, RETROK_v }, + { XK_w, RETROK_w }, + { XK_x, RETROK_x }, + { XK_y, RETROK_y }, + { XK_z, RETROK_z }, + { XK_Delete, RETROK_DELETE }, + { XK_KP_0, RETROK_KP0 }, + { XK_KP_1, RETROK_KP1 }, + { XK_KP_2, RETROK_KP2 }, + { XK_KP_3, RETROK_KP3 }, + { XK_KP_4, RETROK_KP4 }, + { XK_KP_5, RETROK_KP5 }, + { XK_KP_6, RETROK_KP6 }, + { XK_KP_7, RETROK_KP7 }, + { XK_KP_8, RETROK_KP8 }, + { XK_KP_9, RETROK_KP9 }, + { XK_KP_Decimal, RETROK_KP_PERIOD }, + { XK_KP_Divide, RETROK_KP_DIVIDE }, + { XK_KP_Multiply, RETROK_KP_MULTIPLY }, + { XK_KP_Subtract, RETROK_KP_MINUS }, + { XK_KP_Add, RETROK_KP_PLUS }, + { XK_KP_Enter, RETROK_KP_ENTER }, + { XK_KP_Equal, RETROK_KP_EQUALS }, + { XK_Up, RETROK_UP }, + { XK_Down, RETROK_DOWN }, + { XK_Right, RETROK_RIGHT }, + { XK_Left, RETROK_LEFT }, + { XK_Insert, RETROK_INSERT }, + { XK_Home, RETROK_HOME }, + { XK_End, RETROK_END }, + { XK_Page_Up, RETROK_PAGEUP }, + { XK_Page_Down, RETROK_PAGEDOWN }, + { XK_F1, RETROK_F1 }, + { XK_F2, RETROK_F2 }, + { XK_F3, RETROK_F3 }, + { XK_F4, RETROK_F4 }, + { XK_F5, RETROK_F5 }, + { XK_F6, RETROK_F6 }, + { XK_F7, RETROK_F7 }, + { XK_F8, RETROK_F8 }, + { XK_F9, RETROK_F9 }, + { XK_F10, RETROK_F10 }, + { XK_F11, RETROK_F11 }, + { XK_F12, RETROK_F12 }, + { XK_F13, RETROK_F13 }, + { XK_F14, RETROK_F14 }, + { XK_F15, RETROK_F15 }, + { XK_Num_Lock, RETROK_NUMLOCK }, + { XK_Caps_Lock, RETROK_CAPSLOCK }, + { XK_Scroll_Lock, RETROK_SCROLLOCK }, + { XK_Shift_R, RETROK_RSHIFT }, + { XK_Shift_L, RETROK_LSHIFT }, + { XK_Control_R, RETROK_RCTRL }, + { XK_Control_L, RETROK_LCTRL }, + { XK_Alt_R, RETROK_RALT }, + { XK_Alt_L, RETROK_LALT }, + { XK_Meta_R, RETROK_RMETA }, + { XK_Meta_L, RETROK_LMETA }, + { XK_Super_L, RETROK_LSUPER }, + { XK_Super_R, RETROK_RSUPER }, + { XK_Mode_switch, RETROK_MODE }, + { XK_Multi_key, RETROK_COMPOSE }, + { XK_Help, RETROK_HELP }, + { XK_Print, RETROK_PRINT }, + { XK_Sys_Req, RETROK_SYSREQ }, + { XK_Break, RETROK_BREAK }, + { XK_Menu, RETROK_MENU }, + /*{ ?, RETROK_POWER },*/ + { XK_EuroSign, RETROK_EURO }, + { XK_Undo, RETROK_UNDO }, + + { 0, RETROK_UNKNOWN }, +}; +#endif + #ifdef __linux__ const struct rarch_key_map rarch_key_map_linux[] = { { KEY_BACKSPACE, RETROK_BACKSPACE }, diff --git a/libretro-common/include/compat/strl.h b/libretro-common/include/compat/strl.h index ddb89c2f98..86d2a39930 100644 --- a/libretro-common/include/compat/strl.h +++ b/libretro-common/include/compat/strl.h @@ -35,8 +35,10 @@ extern "C" { #endif #ifdef __MACH__ +#ifndef HAVE_STRL #define HAVE_STRL #endif +#endif #ifndef HAVE_STRL /* Avoid possible naming collisions during link since diff --git a/libretro-common/include/retro_log.h b/libretro-common/include/retro_log.h index c1b156f9a6..4ffd99fa0a 100644 --- a/libretro-common/include/retro_log.h +++ b/libretro-common/include/retro_log.h @@ -41,7 +41,7 @@ #include #include -#if defined(HAVE_FILE_LOGGER) && defined(RARCH_INTERNAL) && !defined(IS_JOYCONFIG) +#if defined(HAVE_FILE_LOGGER) && defined(RARCH_INTERNAL) #ifdef __cplusplus extern "C" @@ -217,7 +217,8 @@ static INLINE void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) __android_log_vprint(prio, PROGRAM_NAME, fmt, ap); #else fprintf(LOG_FILE, "%s %s :: ", PROGRAM_NAME, tag ? tag : "[INFO]"); - vfprintf(LOG_FILE, fmt, ap); + vfprintf(LOG_FILE, fmt, ap); + fflush(LOG_FILE); #endif } diff --git a/libretro-common/include/retro_stat.h b/libretro-common/include/retro_stat.h index 6429bb60bf..cd83d003a4 100644 --- a/libretro-common/include/retro_stat.h +++ b/libretro-common/include/retro_stat.h @@ -28,10 +28,6 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - /** * path_is_directory: * @path : path @@ -58,8 +54,4 @@ int32_t path_get_size(const char *path); **/ bool mkdir_norecurse(const char *dir); -#ifdef __cplusplus -} -#endif - #endif diff --git a/libretro-common/rthreads/async_job.c b/libretro-common/rthreads/async_job.c index 3aa1778997..7a35fef2c7 100644 --- a/libretro-common/rthreads/async_job.c +++ b/libretro-common/rthreads/async_job.c @@ -111,8 +111,13 @@ void async_job_free(async_job_t *ajob) int async_job_add(async_job_t *ajob, async_task_t task, void *payload) { - async_job_node_t *node = (async_job_node_t*)calloc(1, sizeof(*node)); - + async_job_node_t *node; + + if (!ajob) + return -1; + + node = (async_job_node_t*)calloc(1, sizeof(*node)); + if (!node) return -1; diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 2288dcfc87..7c1cdd5826 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -605,6 +605,40 @@ static void menu_action_setting_disp_set_label_menu_disk_index( snprintf(s, len, "%u", current + 1); } +static void menu_action_setting_disp_set_label_menu_input_keyboard_gamepad_mapping_type( + file_list_t* list, + unsigned *w, unsigned type, unsigned i, + const char *label, + char *s, size_t len, + const char *entry_label, + const char *path, + char *s2, size_t len2) +{ + settings_t *settings = config_get_ptr(); + unsigned width = 0, height = 0; + + *w = 19; + *s = '\0'; + + (void)width; + (void)height; + + strlcpy(s2, path, len2); + + switch (settings->input.keyboard_gamepad_mapping_type) + { + case 0: + strlcpy(s, "None", len); + break; + case 1: + strlcpy(s, "iPega PG-9017", len); + break; + case 2: + strlcpy(s, "8-bitty", len); + break; + } +} + static void menu_action_setting_disp_set_label_menu_video_resolution( file_list_t* list, unsigned *w, unsigned type, unsigned i, @@ -1052,6 +1086,10 @@ static int menu_cbs_init_bind_get_string_representation_compare_label( BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_menu_video_resolution); break; + case MENU_LABEL_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE: + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_disp_set_label_menu_input_keyboard_gamepad_mapping_type); + break; case MENU_LABEL_CONTENT_COLLECTION_LIST: case MENU_LABEL_LOAD_CONTENT_HISTORY: case MENU_LABEL_DOWNLOADED_FILE_DETECT_CORE_LIST: diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index bacca62066..18760517ab 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -1158,6 +1158,7 @@ static int mui_environ(menu_environ_cb_t type, void *data) static void mui_preswitch_tabs(unsigned action) { + size_t idx = 0; size_t stack_size = 0; file_list_t *menu_stack = NULL; menu_handle_t *menu = menu_driver_get_ptr(); @@ -1166,7 +1167,6 @@ static void mui_preswitch_tabs(unsigned action) if (!mui) return; - size_t idx = 0; menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &idx); menu_stack = menu_entries_get_menu_stack_ptr(0); @@ -1309,6 +1309,8 @@ static int mui_list_push(menu_displaylist_info_t *info, unsigned type) #endif menu_displaylist_parse_settings(menu, info, menu_hash_to_str(MENU_LABEL_CONFIGURATIONS), PARSE_ACTION, false); + menu_displaylist_parse_settings(menu, info, + menu_hash_to_str(MENU_LABEL_SAVE_CURRENT_CONFIG), PARSE_ACTION, false); menu_displaylist_parse_settings(menu, info, menu_hash_to_str(MENU_LABEL_SAVE_NEW_CONFIG), PARSE_ACTION, false); menu_displaylist_parse_settings(menu, info, diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index c9f913bd79..49d5c2a988 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2653,6 +2653,8 @@ static int xmb_list_push(menu_displaylist_info_t *info, unsigned type) #endif menu_displaylist_parse_settings(menu, info, menu_hash_to_str(MENU_LABEL_CONFIGURATIONS), PARSE_ACTION, false); + menu_displaylist_parse_settings(menu, info, + menu_hash_to_str(MENU_LABEL_SAVE_CURRENT_CONFIG), PARSE_ACTION, false); menu_displaylist_parse_settings(menu, info, menu_hash_to_str(MENU_LABEL_SAVE_NEW_CONFIG), PARSE_ACTION, false); menu_displaylist_parse_settings(menu, info, diff --git a/menu/drivers/zarch.c b/menu/drivers/zarch.c index 67d6908afc..0977720db3 100644 --- a/menu/drivers/zarch.c +++ b/menu/drivers/zarch.c @@ -52,25 +52,25 @@ #define ZARCH_DEBUG #endif -const GRfloat ZUI_NORMAL[] = { +const float ZUI_NORMAL[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; -const GRfloat ZUI_HILITE[] = { +const float ZUI_HILITE[] = { 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, }; -const GRfloat ZUI_PRESS[] = { +const float ZUI_PRESS[] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, }; -const GRfloat ZUI_BARBG[] = { +const float ZUI_BARBG[] = { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, @@ -78,26 +78,26 @@ const GRfloat ZUI_BARBG[] = { }; const uint32_t ZUI_FG_NORMAL = ~0; -const GRfloat ZUI_BG_PANEL[] = { +const float ZUI_BG_PANEL[] = { 0, 0, 0, 0.25, 0, 0, 0, 0.25, 0, 0, 0, 0.25, 0, 0, 0, 0.25, }; -const GRfloat ZUI_BG_SCREEN[] = { +const float ZUI_BG_SCREEN[] = { 0.07, 0.19, 0.26, 0.75, 0.07, 0.19, 0.26, 0.75, 0.15, 0.31, 0.47, 0.75, 0.15, 0.31, 0.47, 0.75, }; -const GRfloat ZUI_BG_HILITE[] = { +const float ZUI_BG_HILITE[] = { 0.22, 0.60, 0.74, 1, 0.22, 0.60, 0.74, 1, 0.22, 0.60, 0.74, 1, 0.22, 0.60, 0.74, 1, }; -const GRfloat ZUI_BG_PAD_HILITE[] = { +const float ZUI_BG_PAD_HILITE[] = { 0.30, 0.76, 0.93, 1, 0.30, 0.76, 0.93, 1, 0.30, 0.76, 0.93, 1, @@ -145,11 +145,11 @@ typedef struct zarch_handle { struct { - GRuint id; + uintptr_t id; char path[PATH_MAX_LENGTH]; } bg; - GRuint white; + uintptr_t white; } textures; /* LAY_ROOT's "Recent" */ @@ -327,11 +327,11 @@ static void zarch_zui_draw_text(zui_t *zui, uint32_t color, int x, int y, const } static void zarch_zui_push_quad(unsigned width, unsigned height, - const GRfloat *colors, gfx_coord_array_t *ca, int x1, int y1, + const float *colors, gfx_coord_array_t *ca, int x1, int y1, int x2, int y2) { gfx_coords_t coords; - GRfloat vertex[8]; + float vertex[8]; vertex[0] = x1 / (float)width; vertex[1] = y1 / (float)height; @@ -419,8 +419,8 @@ static void zarch_zui_snow(zui_t *zui, gfx_coord_array_t *ca, int width, int hei for (i = 0; i < NPARTICLES; ++i) { unsigned j; - GRfloat alpha; - GRfloat colors[16]; + float alpha; + float colors[16]; part_t *p = &particles[i]; if (!p->alive) @@ -445,7 +445,7 @@ static bool zarch_zui_button_full(zui_t *zui, int x1, int y1, int x2, int y2, co { unsigned id = zarch_zui_hash(zui, label); bool active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2); - const GRfloat *bg = ZUI_BG_PANEL; + const float *bg = ZUI_BG_PANEL; if (zui->item.active == id || zui->item.hot == id) bg = ZUI_BG_HILITE; @@ -471,7 +471,7 @@ static bool zarch_zui_list_item(zui_t *zui, zui_tabbed_t *tab, int x1, int y1, int x2 = x1 + zui->width - 290 - 40; int y2 = y1 + 50; bool active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2); - const GRfloat *bg = ZUI_BG_PANEL; + const float *bg = ZUI_BG_PANEL; uint64_t *frame_count = video_driver_get_frame_count(); if (tab->active_id != tab->prev_id) @@ -534,7 +534,7 @@ static bool zarch_zui_tab(zui_t *zui, zui_tabbed_t *tab, const char *label, unsi int x1, y1, x2, y2; unsigned id = zarch_zui_hash(zui, label); int width = tab->tab_width; - const GRfloat *bg = ZUI_BG_PANEL; + const float *bg = ZUI_BG_PANEL; bool selected = tab->tab_selection == tab_id; /* TODO/FIXME */ if (!width) @@ -962,8 +962,8 @@ static int zarch_zui_render_pick_core(zui_t *zui) static void zarch_frame(void) { unsigned i; - GRfloat coord_color[16]; - GRfloat coord_color2[16]; + float coord_color[16]; + float coord_color2[16]; zui_t *zui = NULL; const struct font_renderer *font_driver = NULL; driver_t *driver = driver_get_ptr(); diff --git a/menu/drivers_display/menu_display_d3d.cpp b/menu/drivers_display/menu_display_d3d.cpp new file mode 100644 index 0000000000..bb176be6ca --- /dev/null +++ b/menu/drivers_display/menu_display_d3d.cpp @@ -0,0 +1,286 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2015 - 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 "../../config.def.h" +#include "../../gfx/font_renderer_driver.h" +#include "../../gfx/video_context_driver.h" +#include "../../gfx/video_thread_wrapper.h" +#include "../../gfx/video_texture.h" +#include "../../gfx/d3d/d3d.h" +#include "../../gfx/d3d/d3d_wrapper.h" + +#include "../menu_display.h" + +#define BYTE_CLAMP(i) (int) ((((i) > 255) ? 255 : (((i) < 0) ? 0 : (i)))) + +static const float d3d_vertexes[] = { + 0, 0, + 1, 0, + 0, 1, + 1, 1 +}; + +static const float d3d_tex_coords[] = { + 0, 1, + 1, 1, + 0, 0, + 1, 0 +}; + +static void *menu_display_d3d_get_default_mvp(void) +{ + d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(NULL); + + if (!d3d) + return NULL; + + return NULL; /* TODO/FIXME */ +} + +static unsigned menu_display_prim_to_d3d_enum(enum menu_display_prim_type prim_type) +{ + switch (prim_type) + { + case MENU_DISPLAY_PRIM_TRIANGLES: + case MENU_DISPLAY_PRIM_TRIANGLESTRIP: + return D3DPT_TRIANGLESTRIP; + case MENU_DISPLAY_PRIM_NONE: + default: + break; + } + + return 0; +} + +static void menu_display_d3d_blend_begin(void) +{ + d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(NULL); + + if (!d3d) + return; + + d3d_enable_blend_func(d3d->dev); + +#if 0 + if (gl->shader && gl->shader->use) + gl->shader->use(gl, GL_SHADER_STOCK_BLEND); +#endif +} + +static void menu_display_d3d_blend_end(void) +{ + d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(NULL); + + if (!d3d) + return; + + d3d_disable_blend_func(d3d->dev); +} + +static void menu_display_d3d_draw( + unsigned x, unsigned y, + unsigned width, unsigned height, + struct gfx_coords *coords, + void *matrix_data, + uintptr_t texture, + enum menu_display_prim_type prim_type + ) +{ + D3DVIEWPORT vp = {0}; + driver_t *driver = driver_get_ptr(); + d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(NULL); + math_matrix_4x4 *mat = (math_matrix_4x4*)matrix_data; + + if (!d3d) + return; + + /* TODO - edge case */ + if (height <= 0) + height = 1; + + if (!mat) + mat = (math_matrix_4x4*)menu_display_d3d_get_default_mvp(); + if (!coords->vertex) + coords->vertex = &d3d_vertexes[0]; + if (!coords->tex_coord) + coords->tex_coord = &d3d_tex_coords[0]; + if (!coords->lut_tex_coord) + coords->lut_tex_coord = &d3d_tex_coords[0]; + + vp.X = x; + vp.Y = y; + vp.Width = width; + vp.Height = height; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + + d3d_set_viewport(d3d->dev, &vp); + d3d_set_texture(d3d->dev, 0, (LPDIRECT3DTEXTURE9)texture); + +#if 0 + gl->shader->set_coords(coords); + gl->shader->set_mvp(driver->video_data, mat); +#endif + + d3d_draw_primitive(d3d->dev, (D3DPRIMITIVETYPE)menu_display_prim_to_d3d_enum(prim_type), 0, coords->vertices); + +#if 0 + gl->coords.color = gl->white_color_ptr; +#endif +} + +static void menu_display_d3d_draw_bg( + unsigned width, + unsigned height, + uintptr_t texture, + float handle_alpha, + bool force_transparency, + GLfloat *coord_color, + GLfloat *coord_color2, + const float *vertex, + const float *tex_coord, + size_t vertex_count, + enum menu_display_prim_type prim_type) +{ + struct gfx_coords coords; + const GLfloat *new_vertex = NULL; + const GLfloat *new_tex_coord = NULL; + global_t *global = global_get_ptr(); + settings_t *settings = config_get_ptr(); + d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(NULL); + + if (!d3d) + return; + + new_vertex = vertex; + new_tex_coord = tex_coord; + + if (!new_vertex) + new_vertex = &d3d_vertexes[0]; + if (!new_tex_coord) + new_tex_coord = &d3d_tex_coords[0]; + + coords.vertices = vertex_count; + coords.vertex = new_vertex; + coords.tex_coord = new_tex_coord; + coords.lut_tex_coord = new_tex_coord; + coords.color = (const float*)coord_color; + + menu_display_d3d_blend_begin(); + + menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); + + if ((settings->menu.pause_libretro + || !global->inited.main || (global->inited.core.type == CORE_TYPE_DUMMY)) + && !force_transparency + && texture) + coords.color = (const float*)coord_color2; + + menu_display_d3d_draw(0, 0, width, height, + &coords, (math_matrix_4x4*)menu_display_d3d_get_default_mvp(), + (GLuint)texture, prim_type); + + menu_display_d3d_blend_end(); + +#if 0 + gl->coords.color = gl->white_color_ptr; +#endif +} + +static void menu_display_d3d_restore_clear_color(void) +{ + d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(NULL); + DWORD clear_color = 0x00000000; + + d3d_clear(d3d->dev, 0, NULL, D3DCLEAR_TARGET, clear_color, 0, 0); +} + +static void menu_display_d3d_clear_color(float r, float g, float b, float a) +{ + d3d_video_t *d3d = (d3d_video_t*)video_driver_get_ptr(NULL); + DWORD clear_color = D3DCOLOR_ARGB(BYTE_CLAMP(a * 255.0f), BYTE_CLAMP(r * 255.0f), BYTE_CLAMP(g * 255.0f), BYTE_CLAMP(b * 255.0f)); + + d3d_clear(d3d->dev, 0, NULL, D3DCLEAR_TARGET, clear_color, 0, 0); +} + +static unsigned menu_display_d3d_texture_load(void *data, enum texture_filter_type type) +{ + return video_texture_load(data, TEXTURE_BACKEND_DIRECT3D, type); +} + +static void menu_display_d3d_texture_unload(uintptr_t *id) +{ + if (!id) + return; + video_texture_unload(TEXTURE_BACKEND_DIRECT3D, id); +} + +static const float *menu_display_d3d_get_tex_coords(void) +{ + return &d3d_tex_coords[0]; +} + +static bool menu_display_d3d_font_init_first(const void **font_driver, + void **font_handle, void *video_data, const char *font_path, + float font_size) +{ + settings_t *settings = config_get_ptr(); + const struct retro_hw_render_callback *hw_render = + (const struct retro_hw_render_callback*)video_driver_callback(); + + if (settings->video.threaded && !hw_render->context_type) + { + thread_packet_t pkt; + driver_t *driver = driver_get_ptr(); + thread_video_t *thr = (thread_video_t*)driver->video_data; + + if (!thr) + return false; + + pkt.type = CMD_FONT_INIT; + pkt.data.font_init.method = font_init_first; + pkt.data.font_init.font_driver = (const void**)font_driver; + pkt.data.font_init.font_handle = font_handle; + pkt.data.font_init.video_data = video_data; + pkt.data.font_init.font_path = font_path; + pkt.data.font_init.font_size = font_size; + pkt.data.font_init.api = FONT_DRIVER_RENDER_DIRECT3D_API; + + thr->send_and_wait(thr, &pkt); + + return pkt.data.font_init.return_value; + } + + return font_init_first(font_driver, font_handle, video_data, + font_path, font_size, FONT_DRIVER_RENDER_DIRECT3D_API); +} + +menu_display_ctx_driver_t menu_display_ctx_d3d = { + menu_display_d3d_draw, + menu_display_d3d_draw_bg, + menu_display_d3d_blend_begin, + menu_display_d3d_blend_end, + menu_display_d3d_restore_clear_color, + menu_display_d3d_clear_color, + menu_display_d3d_get_default_mvp, + menu_display_d3d_get_tex_coords, + menu_display_d3d_texture_load, + menu_display_d3d_texture_unload, + menu_display_d3d_font_init_first, + MENU_VIDEO_DRIVER_DIRECT3D, + "menu_display_d3d", +}; diff --git a/menu/drivers_display/menu_display_gl.c b/menu/drivers_display/menu_display_gl.c index 602f99a01e..bc8dcade2f 100644 --- a/menu/drivers_display/menu_display_gl.c +++ b/menu/drivers_display/menu_display_gl.c @@ -13,11 +13,7 @@ * If not, see . */ -#include - -#include #include -#include #include "../../config.def.h" #include "../../gfx/font_renderer_driver.h" @@ -42,14 +38,14 @@ static const GLfloat gl_tex_coords[] = { 1, 0 }; -static math_matrix_4x4 *menu_display_get_default_mvp(void) +static void *menu_display_gl_get_default_mvp(void) { - gl_t *gl = (gl_t*)video_driver_get_ptr(NULL); + gl_t *gl = (gl_t*)video_driver_get_ptr(NULL); if (!gl) return NULL; - return (math_matrix_4x4*)&gl->mvp_no_rot; + return &gl->mvp_no_rot; } static GLenum menu_display_prim_to_gl_enum(enum menu_display_prim_type prim_type) @@ -108,7 +104,7 @@ static void menu_display_gl_draw( height = 1; if (!mat) - mat = &gl->mvp_no_rot; + mat = (math_matrix_4x4*)menu_display_gl_get_default_mvp(); if (!coords->vertex) coords->vertex = &gl_vertexes[0]; if (!coords->tex_coord) @@ -175,7 +171,7 @@ static void menu_display_gl_draw_bg( coords.color = (const float*)coord_color2; menu_display_gl_draw(0, 0, width, height, - &coords, &gl->mvp_no_rot, + &coords, (math_matrix_4x4*)menu_display_gl_get_default_mvp(), (GLuint)texture, prim_type); menu_display_gl_blend_end(); @@ -194,26 +190,6 @@ static void menu_display_gl_clear_color(float r, float g, float b, float a) glClear(GL_COLOR_BUFFER_BIT); } -static void menu_display_gl_matrix_4x4_rotate_z(void *data, float rotation, - float scale_x, float scale_y, float scale_z, bool scale_enable) -{ - math_matrix_4x4 matrix_rotated; - math_matrix_4x4 matrix_scaled; - math_matrix_4x4 *matrix = (math_matrix_4x4*)data; - math_matrix_4x4 *b = menu_display_get_default_mvp(); - if (!matrix) - return; - - matrix_4x4_rotate_z(&matrix_rotated, rotation); - matrix_4x4_multiply(matrix, &matrix_rotated, b); - - if (!scale_enable) - return; - - matrix_4x4_scale(&matrix_scaled, scale_x, scale_y, scale_z); - matrix_4x4_multiply(matrix, &matrix_scaled, matrix); -} - static unsigned menu_display_gl_texture_load(void *data, enum texture_filter_type type) { return video_texture_load(data, TEXTURE_BACKEND_OPENGL, type); @@ -223,7 +199,7 @@ static void menu_display_gl_texture_unload(uintptr_t *id) { if (!id) return; - video_texture_unload(id); + video_texture_unload(TEXTURE_BACKEND_OPENGL, id); } static const float *menu_display_gl_get_tex_coords(void) @@ -231,6 +207,41 @@ static const float *menu_display_gl_get_tex_coords(void) return &gl_tex_coords[0]; } +static bool menu_display_gl_font_init_first(const void **font_driver, + void **font_handle, void *video_data, const char *font_path, + float font_size) +{ + settings_t *settings = config_get_ptr(); + const struct retro_hw_render_callback *hw_render = + (const struct retro_hw_render_callback*)video_driver_callback(); + + if (settings->video.threaded && !hw_render->context_type) + { + thread_packet_t pkt; + driver_t *driver = driver_get_ptr(); + thread_video_t *thr = (thread_video_t*)driver->video_data; + + if (!thr) + return false; + + pkt.type = CMD_FONT_INIT; + pkt.data.font_init.method = font_init_first; + pkt.data.font_init.font_driver = (const void**)font_driver; + pkt.data.font_init.font_handle = font_handle; + pkt.data.font_init.video_data = video_data; + pkt.data.font_init.font_path = font_path; + pkt.data.font_init.font_size = font_size; + pkt.data.font_init.api = FONT_DRIVER_RENDER_OPENGL_API; + + thr->send_and_wait(thr, &pkt); + + return pkt.data.font_init.return_value; + } + + return font_init_first(font_driver, font_handle, video_data, + font_path, font_size, FONT_DRIVER_RENDER_OPENGL_API); +} + menu_display_ctx_driver_t menu_display_ctx_gl = { menu_display_gl_draw, menu_display_gl_draw_bg, @@ -238,10 +249,11 @@ menu_display_ctx_driver_t menu_display_ctx_gl = { menu_display_gl_blend_end, menu_display_gl_restore_clear_color, menu_display_gl_clear_color, - menu_display_gl_matrix_4x4_rotate_z, + menu_display_gl_get_default_mvp, menu_display_gl_get_tex_coords, menu_display_gl_texture_load, menu_display_gl_texture_unload, + menu_display_gl_font_init_first, MENU_VIDEO_DRIVER_OPENGL, "menu_display_gl", }; diff --git a/menu/drivers_display/menu_display_null.c b/menu/drivers_display/menu_display_null.c index 4b5018b314..8f4b1ca632 100644 --- a/menu/drivers_display/menu_display_null.c +++ b/menu/drivers_display/menu_display_null.c @@ -17,7 +17,6 @@ #include #include -#include #include "../../config.def.h" #include "../../gfx/font_renderer_driver.h" @@ -27,6 +26,11 @@ #include "../menu_display.h" +static void *menu_display_null_get_default_mvp(void) +{ + return NULL; +} + static void menu_display_null_blend_begin(void) { } @@ -69,11 +73,6 @@ static void menu_display_null_clear_color(float r, float g, float b, float a) { } -static void menu_display_null_matrix_4x4_rotate_z(void *data, float rotation, - float scale_x, float scale_y, float scale_z, bool scale_enable) -{ -} - static unsigned menu_display_null_texture_load(void *data, enum texture_filter_type type) { return 0; @@ -89,6 +88,13 @@ static const float *menu_display_null_get_tex_coords(void) return &floats[0]; } +static bool menu_display_null_font_init_first(const void **font_driver, + void **font_handle, void *video_data, const char *font_path, + float font_size) +{ + return true; +} + menu_display_ctx_driver_t menu_display_ctx_null = { menu_display_null_draw, menu_display_null_draw_bg, @@ -96,10 +102,11 @@ menu_display_ctx_driver_t menu_display_ctx_null = { menu_display_null_blend_end, menu_display_null_restore_clear_color, menu_display_null_clear_color, - menu_display_null_matrix_4x4_rotate_z, + menu_display_null_get_default_mvp, menu_display_null_get_tex_coords, menu_display_null_texture_load, menu_display_null_texture_unload, + menu_display_null_font_init_first, MENU_VIDEO_DRIVER_GENERIC, "menu_display_null", }; diff --git a/menu/intl/menu_hash_us.c b/menu/intl/menu_hash_us.c index 97c2bd739b..aaa4fd6eca 100644 --- a/menu/intl/menu_hash_us.c +++ b/menu/intl/menu_hash_us.c @@ -26,6 +26,14 @@ static const char *menu_hash_to_str_us_label(uint32_t hash) { switch (hash) { + case MENU_LABEL_INPUT_ICADE_ENABLE: + return "input_icade_enable"; + case MENU_LABEL_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE: + return "keyboard_gamepad_mapping_type"; + case MENU_LABEL_INPUT_SMALL_KEYBOARD_ENABLE: + return "input_small_keyboard_enable"; + case MENU_LABEL_SAVE_CURRENT_CONFIG: + return "save_current_config"; case MENU_LABEL_STATE_SLOT: return "state_slot"; case MENU_LABEL_CHEEVOS_USERNAME: @@ -688,6 +696,14 @@ const char *menu_hash_to_str_us(uint32_t hash) switch (hash) { + case MENU_LABEL_VALUE_INPUT_ICADE_ENABLE: + return "Keyboard Gamepad Mapping Enable"; + case MENU_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE: + return "Keyboard Gamepad Mapping Type"; + case MENU_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE: + return "Small Keyboard Enable"; + case MENU_LABEL_VALUE_SAVE_CURRENT_CONFIG: + return "Save Current Config"; case MENU_LABEL_VALUE_STATE_SLOT: return "State Slot"; case MENU_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS: diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index d82ad14b13..ab609bd8b6 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -21,10 +21,6 @@ #include "menu_hash.h" -#ifdef __cplusplus -extern "C" { -#endif - enum { ACTION_OK_DL_DEFAULT = 0, @@ -204,8 +200,4 @@ void menu_cbs_init(void *data, bool menu_playlist_find_associated_core(const char *path, char *s, size_t len); -#ifdef __cplusplus -} -#endif - #endif diff --git a/menu/menu_display.c b/menu/menu_display.c index 795aedd197..f4fa474fdc 100644 --- a/menu/menu_display.c +++ b/menu/menu_display.c @@ -60,6 +60,9 @@ typedef struct menu_display static menu_display_ctx_driver_t *menu_display_ctx_drivers[] = { +#ifdef HAVE_DIRECT3D + &menu_display_ctx_d3d, +#endif #ifdef HAVE_OPENGL &menu_display_ctx_gl, #endif @@ -131,35 +134,12 @@ bool menu_display_font_init_first(const void **font_driver, void **font_handle, void *video_data, const char *font_path, float font_size) { - settings_t *settings = config_get_ptr(); - const struct retro_hw_render_callback *hw_render = - (const struct retro_hw_render_callback*)video_driver_callback(); + menu_display_ctx_driver_t *menu_disp = menu_display_context_get_ptr(); + if (!menu_disp || !menu_disp->font_init_first) + return false; - if (settings->video.threaded && !hw_render->context_type) - { - thread_packet_t pkt; - driver_t *driver = driver_get_ptr(); - thread_video_t *thr = (thread_video_t*)driver->video_data; - - if (!thr) - return false; - - pkt.type = CMD_FONT_INIT; - pkt.data.font_init.method = font_init_first; - pkt.data.font_init.font_driver = (const void**)font_driver; - pkt.data.font_init.font_handle = font_handle; - pkt.data.font_init.video_data = video_data; - pkt.data.font_init.font_path = font_path; - pkt.data.font_init.font_size = font_size; - pkt.data.font_init.api = FONT_DRIVER_RENDER_OPENGL_API; - - thr->send_and_wait(thr, &pkt); - - return pkt.data.font_init.return_value; - } - - return font_init_first(font_driver, font_handle, video_data, - font_path, font_size, FONT_DRIVER_RENDER_OPENGL_API); + return menu_disp->font_init_first(font_driver, font_handle, video_data, + font_path, font_size); } bool menu_display_font_bind_block(void *data, const void *font_data, void *userdata) @@ -235,7 +215,7 @@ static bool menu_display_check_compatibility(enum menu_display_driver_type type) return false; } -const bool menu_display_driver_init_first(void) +bool menu_display_driver_init_first(void) { unsigned i; menu_display_t *disp = menu_display_get_ptr(); @@ -574,18 +554,32 @@ void menu_display_blend_end(void) if (!menu_disp || !menu_disp->blend_end) return; - if (menu_disp) - menu_disp->blend_end(); + menu_disp->blend_end(); } void menu_display_matrix_4x4_rotate_z(void *data, float rotation, float scale_x, float scale_y, float scale_z, bool scale_enable) { + math_matrix_4x4 *matrix, *b; + math_matrix_4x4 matrix_rotated; + math_matrix_4x4 matrix_scaled; menu_display_ctx_driver_t *menu_disp = menu_display_context_get_ptr(); - if (!menu_disp) + if (!menu_disp || !menu_disp->get_default_mvp) return; - menu_disp->matrix_4x4_rotate_z(data, rotation, scale_x, scale_y, scale_z, scale_enable); + matrix = (math_matrix_4x4*)data; + b = (math_matrix_4x4*)menu_disp->get_default_mvp(); + if (!matrix) + return; + + matrix_4x4_rotate_z(&matrix_rotated, rotation); + matrix_4x4_multiply(matrix, &matrix_rotated, b); + + if (!scale_enable) + return; + + matrix_4x4_scale(&matrix_scaled, scale_x, scale_y, scale_z); + matrix_4x4_multiply(matrix, &matrix_scaled, matrix); } unsigned menu_display_texture_load(void *data, diff --git a/menu/menu_display.h b/menu/menu_display.h index e28795bfbd..9548830201 100644 --- a/menu/menu_display.h +++ b/menu/menu_display.h @@ -103,11 +103,13 @@ typedef struct menu_display_ctx_driver void (*clear_color)(float r, float g, float b, float a); - void (*matrix_4x4_rotate_z)(void *data, float rotation, - float scale_x, float scale_y, float scale_z, bool scale_enable); + void *(*get_default_mvp)(void); const float *(*get_tex_coords)(void); unsigned (*texture_load)(void *data, enum texture_filter_type type); void (*texture_unload)(uintptr_t *id); + bool (*font_init_first)(const void **font_driver, + void **font_handle, void *video_data, const char *font_path, + float font_size); enum menu_display_driver_type type; const char *ident; } menu_display_ctx_driver_t; @@ -137,7 +139,7 @@ void menu_display_msg_queue_push(const char *msg, unsigned prio, unsigned durati bool flush); -const bool menu_display_driver_init_first(void); +bool menu_display_driver_init_first(void); void menu_display_draw(unsigned x, unsigned y, unsigned width, unsigned height, @@ -179,6 +181,7 @@ void menu_display_texture_unload(uintptr_t *id); const float *menu_display_get_tex_coords(void); extern menu_display_ctx_driver_t menu_display_ctx_gl; +extern menu_display_ctx_driver_t menu_display_ctx_d3d; extern menu_display_ctx_driver_t menu_display_ctx_null; #ifdef __cplusplus diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index e2d1ced89f..f3de686515 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -2527,6 +2527,8 @@ int menu_displaylist_push_list(menu_displaylist_info_t *info, unsigned type) #endif menu_displaylist_parse_settings(menu, info, menu_hash_to_str(MENU_LABEL_CONFIGURATIONS), PARSE_ACTION, false); + menu_displaylist_parse_settings(menu, info, + menu_hash_to_str(MENU_LABEL_SAVE_CURRENT_CONFIG), PARSE_ACTION, false); menu_displaylist_parse_settings(menu, info, menu_hash_to_str(MENU_LABEL_SAVE_NEW_CONFIG), PARSE_ACTION, false); menu_displaylist_parse_settings(menu, info, @@ -2605,6 +2607,14 @@ int menu_displaylist_push_list(menu_displaylist_info_t *info, unsigned type) case DISPLAYLIST_INPUT_SETTINGS_LIST: ret = menu_displaylist_parse_settings(menu, info, menu_hash_to_str(MENU_LABEL_INPUT_MAX_USERS), PARSE_ONLY_UINT, false); +#if TARGET_OS_IPHONE + ret = menu_displaylist_parse_settings(menu, info, + menu_hash_to_str(MENU_LABEL_INPUT_SMALL_KEYBOARD_ENABLE), PARSE_ONLY_BOOL, false); +#endif + ret = menu_displaylist_parse_settings(menu, info, + menu_hash_to_str(MENU_LABEL_INPUT_ICADE_ENABLE), PARSE_ONLY_BOOL, false); + ret = menu_displaylist_parse_settings(menu, info, + menu_hash_to_str(MENU_LABEL_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE), PARSE_ONLY_UINT, false); #ifdef ANDROID ret = menu_displaylist_parse_settings(menu, info, menu_hash_to_str(MENU_LABEL_INPUT_BACK_AS_MENU_TOGGLE_ENABLE), PARSE_ONLY_BOOL, false); @@ -2623,8 +2633,6 @@ int menu_displaylist_push_list(menu_displaylist_info_t *info, unsigned type) menu_hash_to_str(MENU_LABEL_INPUT_AXIS_THRESHOLD), PARSE_ONLY_FLOAT, false); ret = menu_displaylist_parse_settings(menu, info, menu_hash_to_str(MENU_LABEL_INPUT_TURBO_PERIOD), PARSE_ONLY_UINT, false); - ret = menu_displaylist_parse_settings(menu, info, - menu_hash_to_str(MENU_LABEL_INPUT_TURBO_PERIOD), PARSE_ONLY_UINT, false); ret = menu_displaylist_parse_settings(menu, info, menu_hash_to_str(MENU_LABEL_INPUT_DUTY_CYCLE), PARSE_ONLY_UINT, false); ret = menu_displaylist_parse_settings(menu, info, diff --git a/menu/menu_hash.h b/menu/menu_hash.h index 6a472d33f4..eb32a6fc06 100644 --- a/menu/menu_hash.h +++ b/menu/menu_hash.h @@ -22,6 +22,9 @@ extern "C" { #endif +#define MENU_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE 0x507c52f3U +#define MENU_LABEL_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE 0x3665cbb0U + #define MENU_LABEL_CHEEVOS_DESCRIPTION 0x7e00e0f5U #define MENU_LABEL_VALUE_CHEEVOS_DESCRIPTION 0xab3975d6U @@ -1074,6 +1077,15 @@ extern "C" { #define MENU_LABEL_VALUE_HELP_SCANNING_CONTENT 0x74b36f11U #define MENU_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC 0xac947056U +#define MENU_LABEL_SAVE_CURRENT_CONFIG 0x8840ba8bU +#define MENU_LABEL_VALUE_SAVE_CURRENT_CONFIG 0x9a1eb42dU + +#define MENU_LABEL_INPUT_SMALL_KEYBOARD_ENABLE 0xe6736fc3U +#define MENU_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE 0xc5eefd76U + +#define MENU_LABEL_INPUT_ICADE_ENABLE 0xcd534dd0U +#define MENU_LABEL_VALUE_INPUT_ICADE_ENABLE 0x67b18ee2U + const char *menu_hash_to_str_de(uint32_t hash); int menu_hash_get_help_de(uint32_t hash, char *s, size_t len); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index bb5616a11f..e0338ca1d3 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -3146,6 +3146,14 @@ static bool setting_append_list_main_menu_options( subgroup_info.name, parent_group); + CONFIG_ACTION( + menu_hash_to_str(MENU_LABEL_SAVE_CURRENT_CONFIG), + menu_hash_to_str(MENU_LABEL_VALUE_SAVE_CURRENT_CONFIG), + group_info.name, + subgroup_info.name, + parent_group); + menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_MENU_SAVE_CURRENT_CONFIG); + CONFIG_ACTION( menu_hash_to_str(MENU_LABEL_SAVE_NEW_CONFIG), menu_hash_to_str(MENU_LABEL_VALUE_SAVE_NEW_CONFIG), @@ -4507,7 +4515,6 @@ static bool setting_append_list_video_options( EVENT_CMD_VIDEO_APPLY_STATE_CHANGES); #endif -#ifndef HAVE_FILTERS_BUILTIN CONFIG_PATH( settings->video.softfilter_plugin, menu_hash_to_str(MENU_LABEL_VIDEO_FILTER), @@ -4521,7 +4528,6 @@ static bool setting_append_list_video_options( menu_settings_list_current_add_values(list, list_info, "filt"); menu_settings_list_current_add_cmd(list, list_info, EVENT_CMD_REINIT); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_EMPTY); -#endif #ifdef _XBOX1 CONFIG_UINT( @@ -4923,6 +4929,46 @@ static bool setting_append_list_input_options( general_read_handler); menu_settings_list_current_add_range(list, list_info, 1, MAX_USERS, 1, true, true); + CONFIG_BOOL( + settings->input.keyboard_gamepad_enable, + menu_hash_to_str(MENU_LABEL_INPUT_ICADE_ENABLE), + menu_hash_to_str(MENU_LABEL_VALUE_INPUT_ICADE_ENABLE), + false, + menu_hash_to_str(MENU_VALUE_OFF), + menu_hash_to_str(MENU_VALUE_ON), + group_info.name, + subgroup_info.name, + parent_group, + general_write_handler, + general_read_handler); + + CONFIG_UINT( + settings->input.keyboard_gamepad_mapping_type, + menu_hash_to_str(MENU_LABEL_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE), + menu_hash_to_str(MENU_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE), + 1, + group_info.name, + subgroup_info.name, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, 2, 1, true, true); + +#if TARGET_OS_IPHONE + CONFIG_BOOL( + settings->input.small_keyboard_enable, + menu_hash_to_str(MENU_LABEL_INPUT_SMALL_KEYBOARD_ENABLE), + menu_hash_to_str(MENU_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE), + false, + menu_hash_to_str(MENU_VALUE_OFF), + menu_hash_to_str(MENU_VALUE_ON), + group_info.name, + subgroup_info.name, + parent_group, + general_write_handler, + general_read_handler); +#endif + #ifdef ANDROID CONFIG_BOOL( settings->input.back_as_menu_toggle_enable, diff --git a/retroarch.c b/retroarch.c index 90c6d4d2d2..2e343201ca 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1496,9 +1496,6 @@ void rarch_playlist_load_content(void *data, unsigned idx) unsigned i; const char *core_path = NULL; const char *path = NULL; - char *path_check = NULL; - char *path_tolower = NULL; - RFILE *fp = NULL; content_playlist_t *playlist = (content_playlist_t*)data; settings_t *settings = config_get_ptr(); #ifdef HAVE_MENU @@ -1511,32 +1508,37 @@ void rarch_playlist_load_content(void *data, unsigned idx) content_playlist_get_index(playlist, idx, &path, NULL, &core_path, NULL, NULL, NULL); - path_tolower = strdup(path); - - for (i = 0; i < strlen(path_tolower); ++i) - path_tolower[i] = tolower(path_tolower[i]); - - - if (strstr(path_tolower, ".zip")) - strstr(path_tolower, ".zip")[4] = '\0'; - else if (strstr(path_tolower, ".7z")) - strstr(path_tolower, ".7z")[3] = '\0'; - - path_check = (char *)calloc(strlen(path_tolower) + 1, sizeof(char)); - strncpy(path_check, path, strlen(path_tolower)); - - fp = retro_fopen(path_check, RFILE_MODE_READ, -1); - if (!fp) + if (path && path[0] != '\0') { - rarch_main_msg_queue_push("File could not be loaded.\n", 1, 100, true); - RARCH_LOG("File at %s failed to load.\n", path_check); + RFILE *fp = NULL; + char *path_check = NULL; + char *path_tolower = strdup(path); + + for (i = 0; i < strlen(path_tolower); ++i) + path_tolower[i] = tolower(path_tolower[i]); + + + if (strstr(path_tolower, ".zip")) + strstr(path_tolower, ".zip")[4] = '\0'; + else if (strstr(path_tolower, ".7z")) + strstr(path_tolower, ".7z")[3] = '\0'; + + path_check = (char *)calloc(strlen(path_tolower) + 1, sizeof(char)); + strncpy(path_check, path, strlen(path_tolower)); + + fp = retro_fopen(path_check, RFILE_MODE_READ, -1); + if (!fp) + { + rarch_main_msg_queue_push("File could not be loaded.\n", 1, 100, true); + RARCH_LOG("File at %s failed to load.\n", path_check); + free(path_tolower); + free(path_check); + return; + } + retro_fclose(fp); free(path_tolower); free(path_check); - return; } - retro_fclose(fp); - free(path_tolower); - free(path_check); strlcpy(settings->libretro, core_path, sizeof(settings->libretro)); diff --git a/runloop.c b/runloop.c index 88199ef6b0..16785a37bc 100644 --- a/runloop.c +++ b/runloop.c @@ -22,7 +22,9 @@ #include +#ifdef HAVE_CHEEVOS #include "cheevos.h" +#endif #include "configuration.h" #include "performance.h" #include "retroarch.h" diff --git a/runloop.h b/runloop.h index 6314fdc571..e9cb3e4970 100644 --- a/runloop.h +++ b/runloop.h @@ -17,6 +17,7 @@ #define __RETROARCH_RUNLOOP_H #include +#include #include "libretro.h" #include "core_info.h" #include "core_options.h" @@ -299,7 +300,11 @@ typedef struct global bool flickerfilter_enable; bool softfilter_enable; } console; - + +#ifdef HAVE_THREADS + async_job_t *async_jobs; +#endif + /* If this is non-NULL. RARCH_LOG and friends * will write to this file. */ FILE *log_file; diff --git a/tools/retroarch-joyconfig-griffin.c b/tools/retroarch-joyconfig-griffin.c deleted file mode 100644 index af72ce0b51..0000000000 --- a/tools/retroarch-joyconfig-griffin.c +++ /dev/null @@ -1,115 +0,0 @@ -/* RetroArch JoyConfig. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * Copyright (C) 2011-2015 - 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 . - */ - -#define IS_JOYCONFIG - -#include - -#include "retroarch-joyconfig.c" - -#include "../libretro-common/dynamic/dylib.c" -#include "../libretro-common/file/retro_file.c" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "../libretro-common/file/retro_stat.c" - -#ifdef __cplusplus -} -#endif - -#if defined(__linux) && !defined(ANDROID) -#include "../input/drivers/linuxraw_input.c" -#include "../input/drivers_joypad/linuxraw_joypad.c" -#endif - -#if defined(HAVE_DINPUT) -#include "../input/drivers/dinput.c" -#include "../input/drivers_joypad/dinput_joypad.c" -#endif - -#if defined(HAVE_XINPUT) -#include "../input/drivers_joypad/xinput_joypad.c" -#endif - -#if defined(HAVE_UDEV) -#include "../input/drivers_joypad/udev_joypad.c" -#endif - -#if defined(HAVE_PARPORT) -#include "../input/drivers_joypad/parport_joypad.c" -#endif - -#if __cplusplus || __STDC_VERSION__ >= 199901L -#if defined(HAVE_SDL) || defined(HAVE_SDL2) -#include "../input/drivers_joypad/sdl_joypad.c" -#endif -#endif - -#include "../libretro-common/queues/fifo_buffer.c" -#include "../libretro-common/file/config_file.c" -#include "../libretro-common/file/file_path.c" -#include "../libretro-common/hash/rhash.c" -#include "../file_path_special.c" -#include "../libretro-common/string/string_list.c" -#include "../libretro-common/compat/compat_strl.c" -#if defined(_WIN32) && !defined(_XBOX) -#include "../libretro-common/compat/compat_posix_string.c" -#include "../libretro-common/compat/compat_getopt.c" -#endif - -#include "../input/drivers/nullinput.c" -#include "../input/drivers_hid/null_hid.c" - -#include "../libretro-common/rthreads/rthreads.c" - -#if __cplusplus || __STDC_VERSION__ >= 199901L -#ifdef HAVE_LIBUSB -#include "../input/drivers_hid/libusb_hid.c" - -#ifndef HAVE_HID -#define HAVE_HID -#endif -#endif -#endif - -#if defined(__APPLE__) && defined(HAVE_IOHIDMANAGER) -#include "../input/drivers_hid/iohidmanager_hid.c" - -#ifndef HAVE_HID -#define HAVE_HID -#endif -#endif - -#ifdef HAVE_HID -#include "../input/connect/joypad_connection.c" -#include "../input/connect/connect_ps3.c" -#include "../input/connect/connect_ps4.c" -#include "../input/connect/connect_wii.c" -#endif - -#include "../input/drivers_joypad/hid_joypad.c" -#include "../input/drivers_joypad/null_joypad.c" - -#include "../input/input_hid_driver.c" -#include "../input/input_joypad_driver.c" -#include "../input/input_joypad.c" -#include "../input/input_common.c" -#include "../input/input_keymaps.c" - -#include "../libretro-common/queues/message_queue.c" diff --git a/tools/retroarch-joyconfig.c b/tools/retroarch-joyconfig.c deleted file mode 100644 index 12b08920d6..0000000000 --- a/tools/retroarch-joyconfig.c +++ /dev/null @@ -1,538 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - 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 . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include "../input/input_common.h" -#include "../input/input_joypad.h" -#include "../input/input_autodetect.h" -#include "../general.h" -#include "../runloop.h" -#include - -/* Need to be present for build to work, but it's not *really* used. - * Better than having to build special versions of lots of objects - * with special #ifdefs. - */ -struct settings g_config; -struct global g_extern; -driver_t driver; - -static int g_player = 1; -static int g_joypad = 0; -static int g_timeout = 0; -static char *g_in_path = NULL; -static char *g_out_path = NULL; -static char *g_auto_path = NULL; -static char *g_driver = NULL; -static unsigned g_meta_level = 0; - -bool retro_main_verbosity(void) -{ - return true; -} - -settings_t *config_get_ptr(void) -{ - return &g_config; -} - -driver_t *driver_get_ptr(void) -{ - return &driver; -} - -static void print_help(void) -{ - puts("====================="); - puts(" retroarch-joyconfig"); - puts("====================="); - puts("Usage: retroarch-joyconfig [ options ... ]"); - puts(""); - puts("-p/--player: Which player to configure for (1 up to and including 8)."); - puts("-j/--joypad: Which joypad to use when configuring (first joypad is 0)."); - puts("-i/--input: Input file to configure with. Binds will be added on or overwritten."); - puts("\tIf not selected, an empty config will be used as a base."); - puts("-o/--output: Output file to write to. If not selected, config file will be dumped to stdout."); - puts("-a/--autoconfig: Outputs an autoconfig file for joypad which was configured."); - puts("-M/--allmisc: Also configure various keybinds that are not directly libretro related."); - puts("\tThese configurations are for player 1 only."); - puts("-m/--misc: Same as --allmisc, but exposes a smaller subset of misc binds which are deemed most useful for regular use."); - puts("-t/--timeout: Adds a timeout of N seconds to each bind. If timed out, the bind will not be used."); - puts("-d/--driver: Uses a specific joypad driver."); - puts("-h/--help: This help."); -} - -#define MAX_BUTTONS 64 -#define MAX_AXES 32 -#define MAX_HATS 32 -struct poll_data -{ - bool buttons[MAX_BUTTONS]; - int16_t axes[MAX_AXES]; - uint16_t hats[MAX_HATS]; -}; - -static void poll_joypad(const input_device_driver_t *driver, - unsigned pad, - struct poll_data *data) -{ - unsigned i; - - if (driver) - driver->poll(); - - for (i = 0; i < MAX_BUTTONS; i++) - data->buttons[i] = input_joypad_button_raw(driver, pad, i); - - for (i = 0; i < MAX_AXES; i++) - data->axes[i] = input_joypad_axis_raw(driver, pad, i); - - for (i = 0; i < MAX_HATS; i++) - { - uint16_t hat = 0; - hat |= input_joypad_hat_raw(driver, pad, HAT_UP_MASK, i) << HAT_UP_SHIFT; - hat |= input_joypad_hat_raw(driver, pad, HAT_DOWN_MASK, i) << HAT_DOWN_SHIFT; - hat |= input_joypad_hat_raw(driver, pad, HAT_LEFT_MASK, i) << HAT_LEFT_SHIFT; - hat |= input_joypad_hat_raw(driver, pad, HAT_RIGHT_MASK, i) << HAT_RIGHT_SHIFT; - - data->hats[i] = hat; - } -} - -static void get_binds(config_file_t *conf, config_file_t *auto_conf, - int player, int joypad) -{ - int i, timeout_cnt; - const input_device_driver_t *driver = input_joypad_init_driver(g_driver, NULL); - const char *joypad_name; - - int16_t initial_axes[MAX_AXES] = {0}; - struct poll_data old_poll = {{0}}; - struct poll_data new_poll = {{0}}; - - int last_axis = -1; - bool block_axis = false; - - int timeout_ticks = g_timeout * 100; - - if (!driver) - { - fprintf(stderr, "Cannot find any valid input driver.\n"); - exit(1); - } - - if (!driver->query_pad(joypad)) - { - fprintf(stderr, "Couldn't open joystick #%d.\n", joypad); - exit(1); - } - - fprintf(stderr, "Found joypad driver: %s\n", driver->ident); - joypad_name = input_joypad_name(driver, joypad); - fprintf(stderr, "Using joypad: %s\n", joypad_name ? joypad_name : "Unknown"); - - if (joypad_name && auto_conf) - { - config_set_string(auto_conf, "input_device", joypad_name); - config_set_string(auto_conf, "input_driver", driver->ident); - } - - poll_joypad(driver, joypad, &old_poll); - fprintf(stderr, "\nJoypads tend to have stale state after opened.\nPress some buttons and move some axes around to make sure joypad state is completely neutral before proceeding.\nWhen done, press Enter ... "); - getchar(); - poll_joypad(driver, joypad, &old_poll); - - for (i = 0; i < MAX_AXES; i++) - { - int16_t initial = input_joypad_axis_raw(driver, joypad, i); - if (abs(initial) < 20000) - initial = 0; - - /* Certain joypads (such as XBox360 controller on Linux) - * has a default negative axis for shoulder triggers, - * which makes configuration very awkward. - * - * If default negative, we can't trigger on the negative axis, - * and similar with defaulted positive axes. - */ - - if (initial) - fprintf(stderr, "Axis %d is defaulted to %s axis value of %d.\n", i, initial > 0 ? "positive" : "negative", initial); - - initial_axes[i] = initial; - } - - for (i = 0; i < MAX_BUTTONS; i++) - { - if (old_poll.buttons[i]) - fprintf(stderr, "Button %d was initially pressed. This indicates broken initial state.\n", i); - } - - fprintf(stderr, "Configuring binds for player #%d on joypad #%d.\n\n", - player + 1, joypad); - - for (i = 0, timeout_cnt = 0; input_config_bind_map[i].valid; i++, timeout_cnt = 0) - { - unsigned meta_level; - unsigned player_index; - int j; - if (i == RARCH_TURBO_ENABLE) - continue; - - meta_level = input_config_bind_map[i].meta; - if (meta_level > g_meta_level) - continue; - - fprintf(stderr, "%s\n", input_config_bind_map[i].desc); - - player_index = input_config_bind_map[i].meta ? 0 : player; - - for (;;) - { - old_poll = new_poll; - - /* To avoid pegging CPU. - * Ideally use an event-based joypad scheme, - * but it adds far more complexity, so, meh. - */ - retro_sleep(10); - - if (timeout_ticks) - { - timeout_cnt++; - if (timeout_cnt >= timeout_ticks) - { - fprintf(stderr, "\tTimed out ...\n"); - break; - } - } - - poll_joypad(driver, joypad, &new_poll); - for (j = 0; j < MAX_BUTTONS; j++) - { - if (new_poll.buttons[j] && !old_poll.buttons[j]) - { - char key[64] = {0}; - - fprintf(stderr, "\tJoybutton pressed: %d\n", j); - - snprintf(key, sizeof(key), "%s_%s_btn", - input_config_get_prefix(player_index, - input_config_bind_map[i].meta), - input_config_bind_map[i].base); - config_set_int(conf, key, j); - - if (auto_conf) - { - snprintf(key, sizeof(key), "input_%s_btn", - input_config_bind_map[i].base); - config_set_int(auto_conf, key, j); - } - - goto out; - } - } - - for (j = 0; j < MAX_AXES; j++) - { - int16_t value; - bool same_axis; - bool require_negative; - bool require_positive; - - if (new_poll.axes[j] == old_poll.axes[j]) - continue; - - value = new_poll.axes[j]; - same_axis = last_axis == j; - require_negative = initial_axes[j] > 0; - require_positive = initial_axes[j] < 0; - - /* Block the axis config until we're sure - * axes have returned to their neutral state. */ - if (same_axis) - { - if (abs(value) < 10000 || - (require_positive && value < 0) || - (require_negative && value > 0)) - block_axis = false; - } - - /* If axes are in their neutral state, - * we can't allow it. */ - if (require_negative && value >= 0) - continue; - if (require_positive && value <= 0) - continue; - - if (block_axis) - continue; - - if (abs(value) > 20000) - { - char buf[8] = {0}; - char key[64] = {0}; - - last_axis = j; - fprintf(stderr, "\tJoyaxis moved: Axis %d, Value %d\n", - j, value); - - snprintf(buf, sizeof(buf), - value > 0 ? "+%d" : "-%d", j); - - snprintf(key, sizeof(key), "%s_%s_axis", - input_config_get_prefix(player_index, - input_config_bind_map[i].meta), - input_config_bind_map[i].base); - - config_set_string(conf, key, buf); - - if (auto_conf) - { - snprintf(key, sizeof(key), "input_%s_axis", - input_config_bind_map[i].base); - config_set_string(auto_conf, key, buf); - } - - block_axis = true; - goto out; - } - } - - for (j = 0; j < MAX_HATS; j++) - { - const char *quark = NULL; - uint16_t value = new_poll.hats[j]; - uint16_t old_value = old_poll.hats[j]; - - if ((value & HAT_UP_MASK) && !(old_value & HAT_UP_MASK)) - quark = "up"; - else if ((value & HAT_LEFT_MASK) && !(old_value & HAT_LEFT_MASK)) - quark = "left"; - else if ((value & HAT_RIGHT_MASK) && !(old_value & HAT_RIGHT_MASK)) - quark = "right"; - else if ((value & HAT_DOWN_MASK) && !(old_value & HAT_DOWN_MASK)) - quark = "down"; - - if (quark) - { - char buf[16] = {0}; - char key[64] = {0}; - - fprintf(stderr, "\tJoyhat moved: Hat %d, direction %s\n", j, quark); - snprintf(buf, sizeof(buf), "h%d%s", j, quark); - - snprintf(key, sizeof(key), "%s_%s_btn", - input_config_get_prefix(player_index, - input_config_bind_map[i].meta), - input_config_bind_map[i].base); - - config_set_string(conf, key, buf); - - if (auto_conf) - { - snprintf(key, sizeof(key), "input_%s_btn", - input_config_bind_map[i].base); - config_set_string(auto_conf, key, buf); - } - - goto out; - } - } - } -out: - old_poll = new_poll; - } -} - -static void parse_input(int argc, char *argv[]) -{ - char optstring[] = "i:o:a:p:j:t:hmMd:"; - struct option opts[] = { - { "input", 1, NULL, 'i' }, - { "output", 1, NULL, 'o' }, - { "autoconfig", 1, NULL, 'a' }, - { "player", 1, NULL, 'p' }, - { "joypad", 1, NULL, 'j' }, - { "help", 0, NULL, 'h' }, - { "misc", 0, NULL, 'm' }, - { "allmisc", 0, NULL, 'M' }, - { "timeout", 1, NULL, 't' }, - { "driver", 1, NULL, 'd' }, - { NULL, 0, NULL, 0 } - }; - - int option_index = 0; - for (;;) - { - int c = getopt_long(argc, argv, optstring, opts, &option_index); - if (c == -1) - break; - - switch (c) - { - case 'h': - print_help(); - exit(0); - - case 'i': - g_in_path = strdup(optarg); - break; - - case 't': - g_timeout = strtol(optarg, NULL, 0); - break; - - case 'd': - g_driver = strdup(optarg); - break; - - case 'o': - g_out_path = strdup(optarg); - break; - - case 'a': - g_auto_path = strdup(optarg); - break; - - case 'm': - g_meta_level = 1; - break; - - case 'M': - g_meta_level = 2; - break; - - case 'j': - g_joypad = strtol(optarg, NULL, 0); - if (g_joypad < 0) - { - fprintf(stderr, "Joypad number can't be negative.\n"); - exit(1); - } - break; - - case 'p': - g_player = strtol(optarg, NULL, 0); - if (g_player < 1) - { - fprintf(stderr, "User number must be at least 1.\n"); - exit(1); - } - else if (g_player > MAX_USERS) - { - fprintf(stderr, "User number must be from 1 to %d.\n", - MAX_USERS); - exit(1); - } - break; - - default: - break; - } - } - - if (optind < argc) - { - print_help(); - exit(1); - } - -} - -bool input_config_autoconfigure_joypad(autoconfig_params_t *params) -{ - (void)params; - return false; -} - -/* Need SDL_main on OSX. */ -#ifndef __APPLE__ -#undef main -#endif - -int main(int argc, char *argv[]) -{ - config_file_t *conf; - config_file_t *auto_conf = NULL; - - const char *index_list[] = { - "input_player1_joypad_index", - "input_player2_joypad_index", - "input_player3_joypad_index", - "input_player4_joypad_index", - "input_player5_joypad_index", - "input_player6_joypad_index", - "input_player7_joypad_index", - "input_player8_joypad_index", - }; - - parse_input(argc, argv); - - conf = config_file_new(g_in_path); - if (!conf) - { - fprintf(stderr, "Couldn't open config file ...\n"); - return 1; - } - - config_set_int(conf, index_list[g_player - 1], g_joypad); - - if (g_auto_path) - auto_conf = config_file_new(NULL); - - get_binds(conf, auto_conf, g_player - 1, g_joypad); - config_file_write(conf, g_out_path); - config_file_free(conf); - if (auto_conf) - { - fprintf(stderr, "Writing autoconfig profile to: %s.\n", g_auto_path); - config_file_write(auto_conf, g_auto_path); - config_file_free(auto_conf); - } - - free(g_in_path); - free(g_out_path); - free(g_auto_path); - return 0; -} - -void rarch_main_msg_queue_push(const char *msg, unsigned prio, unsigned duration, - bool flush) -{ -} - -bool video_driver_viewport_info(struct video_viewport *vp) -{ - return false; -} - -bool video_driver_read_viewport(uint8_t *buffer) -{ - return false; -} - -void input_config_autoconfigure_disconnect(unsigned id, const char *msg) -{ -} diff --git a/ui/drivers/cocoa/cocoatouch_menu.m b/ui/drivers/cocoa/cocoatouch_menu.m index 9c0ca8a8b2..323ba02bb6 100644 --- a/ui/drivers/cocoa/cocoatouch_menu.m +++ b/ui/drivers/cocoa/cocoatouch_menu.m @@ -261,8 +261,6 @@ static void RunActionSheet(const char* title, const struct string_list* items, [self.bindTimer invalidate]; self.bindTimer = nil; - - cocoa_input_reset_icade_buttons(); } - (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex diff --git a/ui/drivers/ui_cocoatouch.m b/ui/drivers/ui_cocoatouch.m index 08df3ce954..1ca03c4614 100644 --- a/ui/drivers/ui_cocoatouch.m +++ b/ui/drivers/ui_cocoatouch.m @@ -63,6 +63,13 @@ static void rarch_disable_ui(void) rarch_main_ctl(RARCH_MAIN_CTL_SET_IDLE, &boolean); } +static void ui_companion_cocoatouch_event_command( + void *data, enum event_command cmd) +{ + (void)data; + event_command(cmd); +} + static void rarch_draw_observer(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { @@ -76,7 +83,7 @@ static void rarch_draw_observer(CFRunLoopObserverRef observer, if (ret == -1) { - main_exit_save_config(); + ui_companion_cocoatouch_event_command(NULL, EVENT_CMD_MENU_SAVE_CURRENT_CONFIG); main_exit(NULL); return; } @@ -320,7 +327,7 @@ enum { dispatch_async(dispatch_get_main_queue(), ^{ - main_exit_save_config(); + ui_companion_cocoatouch_event_command(NULL, EVENT_CMD_MENU_SAVE_CURRENT_CONFIG); }); [self showPauseMenu: self]; } @@ -340,9 +347,7 @@ enum - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { - cocoa_input_reset_icade_buttons(); [self setToolbarHidden:![[viewController toolbarItems] count] animated:YES]; - [self refreshSystemConfig]; } @@ -368,12 +373,6 @@ enum [self.window setRootViewController:self]; } -static void ui_companion_cocoatouch_event_command(void *data, - enum event_command cmd) -{ - (void)data; - event_command(cmd); -} - (void)toggleUI { @@ -389,7 +388,7 @@ static void ui_companion_cocoatouch_event_command(void *data, - (void)refreshSystemConfig { - bool small_keyboard, is_icade, is_btstack; + bool is_btstack; /* Get enabled orientations */ apple_frontend_settings.orientation_flags = UIInterfaceOrientationMaskAll; @@ -400,12 +399,8 @@ static void ui_companion_cocoatouch_event_command(void *data, apple_frontend_settings.orientation_flags = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; /* Set bluetooth mode */ - small_keyboard = !(strcmp(apple_frontend_settings.bluetooth_mode, "small_keyboard")); - is_icade = !(strcmp(apple_frontend_settings.bluetooth_mode, "icade")); is_btstack = !(strcmp(apple_frontend_settings.bluetooth_mode, "btstack")); - cocoa_input_enable_small_keyboard(small_keyboard); - cocoa_input_enable_icade(is_icade); btstack_set_poweron(is_btstack); }