mirror of
https://github.com/libretro/RetroArch
synced 2025-03-30 07:20:36 +00:00
commit
621567e0e6
2
.gitignore
vendored
2
.gitignore
vendored
@ -95,8 +95,6 @@ pkg/apple/iOS/modules/
|
||||
obj-unix/
|
||||
.vagrant/
|
||||
|
||||
.MAKEFILE_DEFINES
|
||||
.CONFIG_DEFINES
|
||||
/pkg/msvc/Release Cg/*.exe
|
||||
/pkg/msvc/Release Cg/*.iobj
|
||||
/pkg/msvc/Release Cg/*.ipdb
|
||||
|
16
CHANGES.md
16
CHANGES.md
@ -1,5 +1,14 @@
|
||||
# 1.6.8 (future)
|
||||
# 1.7.0 (future)
|
||||
- CHEEVOS: Add badges
|
||||
|
||||
# 1.6.9
|
||||
- COMMON: Small memory leak.
|
||||
- NETPLAY: Fix network command only working once.
|
||||
|
||||
# 1.6.8
|
||||
- Audio: Fix the Audio DSP picker
|
||||
- CHEEVOS: Add support for Atari Lynx cheevos.
|
||||
- CHEEVOS: Add support for RetroAchievements Leaderboards.
|
||||
- GUI: (MaterialUI) Fix crash that happened on context reset with Vulkan.
|
||||
- GUI: (MaterialUI) Skip querying and drawing items that are not visible; Cache content height and bbox calculation.
|
||||
- GUI: (MaterialUI) Fix entry box highlight calculation.
|
||||
@ -10,6 +19,8 @@
|
||||
- GUI: Add menu option for OSD text color.
|
||||
- GUI: Add menu option to remove frame count from OSD.
|
||||
- GUI: Allow wraparound of int/float settings when pressing the left key
|
||||
- INPUT/LIBRETRO: Add support for more mouse buttons (buttons 4/5)
|
||||
- INPUT/LIBRETRO: Add support for analog buttons
|
||||
- INPUT: Always show the controls menu even if descriptors are not set
|
||||
- INPUT: Fix input descriptors not being set on cores that don't implement the controllers interface
|
||||
- INPUT: Apply descriptors only for the amount of cores the core supports
|
||||
@ -27,6 +38,8 @@
|
||||
- LINUX/PI: Broadcom VC4: Add Videocore config option
|
||||
- LINUX/UDEV: Fix - RetroArch reads keyboard input when not focused with the udev input driver.
|
||||
- NETPLAY: Fix disconnection not fully deinitializing Netplay.
|
||||
- NETPLAY: Fix lan rooms when there is more than one room
|
||||
- NETPLAY: Fix lan rooms on systems where all addresses are treated as IPv6
|
||||
- COMMON: Fix clear/free loop conditionals in playlists.
|
||||
- WINDOWS/GDI: Fix flickering of text.
|
||||
- WINDOWS/GDI: Fix graphics corruption on Windows 98
|
||||
@ -43,6 +56,7 @@
|
||||
- SCANNER: Support CHD files.
|
||||
- SCANNER: Support Gamecube ISO scanning.
|
||||
- SCANNER: Use primary data track of disc images for CRC lookups rather than cue files. This is slower but finds matches more reliably, and is necessary for CHD files to work at all. Update your databases!
|
||||
- SCANNER: Fall back on looking inside archives when matching MAME/FBA content (most recent cores only). If you had difficulty with content being detected before, you may have better luck now. Update your databases and core info!
|
||||
|
||||
# 1.6.7
|
||||
- SCANNER: Fix directory scanning.
|
||||
|
14
Makefile
14
Makefile
@ -119,10 +119,16 @@ endif
|
||||
|
||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||
|
||||
ifneq ($(X86),)
|
||||
CFLAGS += -m32
|
||||
CXXLAGS += -m32
|
||||
LDFLAGS += -m32
|
||||
endif
|
||||
|
||||
ifneq ($(SANITIZER),)
|
||||
CFLAGS := -fsanitize=$(SANITIZER) $(CFLAGS)
|
||||
CXXFLAGS := -fsanitize=$(SANITIZER) $(CXXFLAGS)
|
||||
LDFLAGS := -fsanitize=$(SANITIZER) $(LDFLAGS)
|
||||
CFLAGS := -fsanitize=$(SANITIZER) $(CFLAGS)
|
||||
CXXFLAGS := -fsanitize=$(SANITIZER) $(CXXFLAGS)
|
||||
LDFLAGS := -fsanitize=$(SANITIZER) $(LDFLAGS)
|
||||
endif
|
||||
|
||||
ifneq ($(findstring $(GPERFTOOLS),profiler),)
|
||||
@ -204,7 +210,7 @@ install: $(TARGET)
|
||||
rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/monochrome/src; \
|
||||
rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/retroactive/src; \
|
||||
rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/neoactive/src; \
|
||||
rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/retroactive_marked/src; \
|
||||
rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/retrosystem/src; \
|
||||
rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/dot-art/src; \
|
||||
echo "Asset copying done."; \
|
||||
fi
|
||||
|
@ -184,6 +184,10 @@ OBJ += frontend/frontend.o \
|
||||
setting_list.o \
|
||||
list_special.o \
|
||||
$(LIBRETRO_COMM_DIR)/file/nbio/nbio_stdio.o \
|
||||
$(LIBRETRO_COMM_DIR)/file/nbio/nbio_linux.o \
|
||||
$(LIBRETRO_COMM_DIR)/file/nbio/nbio_unixmmap.o \
|
||||
$(LIBRETRO_COMM_DIR)/file/nbio/nbio_windowsmmap.o \
|
||||
$(LIBRETRO_COMM_DIR)/file/nbio/nbio_intf.o \
|
||||
$(LIBRETRO_COMM_DIR)/file/file_path.o \
|
||||
file_path_special.o \
|
||||
file_path_str.o \
|
||||
@ -318,7 +322,7 @@ endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SSA),1)
|
||||
LIBS += -lass
|
||||
LIBS += $(SSA_LIBS)
|
||||
endif
|
||||
|
||||
# LibretroDB
|
||||
@ -597,7 +601,7 @@ ifeq ($(HAVE_AL), 1)
|
||||
ifeq ($(OSX),1)
|
||||
LIBS += -framework OpenAL
|
||||
else
|
||||
LIBS += -lopenal
|
||||
LIBS += $(AL_LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -808,7 +812,7 @@ ifeq ($(HAVE_THREADS), 1)
|
||||
audio/audio_thread_wrapper.o
|
||||
DEFINES += -DHAVE_THREADS
|
||||
ifeq ($(findstring Haiku,$(OS)),)
|
||||
LIBS += -lpthread
|
||||
LIBS += $(THREADS_LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -1062,7 +1066,7 @@ endif
|
||||
else
|
||||
DEFINES += -DHAVE_GL_SYNC
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/glsym/glsym_gl.o
|
||||
GL_LIBS := -lGL
|
||||
GL_LIBS := $(OPENGL_LIBS)
|
||||
ifeq ($(OSX), 1)
|
||||
GL_LIBS := -framework OpenGL
|
||||
OBJ += gfx/drivers_context/cgl_ctx.o
|
||||
@ -1476,6 +1480,7 @@ ifeq ($(HAVE_NETWORKING), 1)
|
||||
OBJ += cheevos/cheevos.o \
|
||||
cheevos/var.o \
|
||||
cheevos/cond.o \
|
||||
cheevos/badges.o \
|
||||
$(LIBRETRO_COMM_DIR)/utils/md5.o
|
||||
endif
|
||||
|
||||
@ -1507,7 +1512,7 @@ ifeq ($(HAVE_NETWORKING), 1)
|
||||
$(DEPS_DIR)/miniupnpc/minixml.o \
|
||||
$(DEPS_DIR)/miniupnpc/minisoap.o
|
||||
else
|
||||
LIBS += -lminiupnpc
|
||||
LIBS += $(MINIUPNPC_LIBS)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
54
cheevos/badges.c
Normal file
54
cheevos/badges.c
Normal file
@ -0,0 +1,54 @@
|
||||
#include <file/file_path.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <streams/file_stream.h>
|
||||
|
||||
#include "../file_path_special.h"
|
||||
#include "../configuration.h"
|
||||
#include "../verbosity.h"
|
||||
#include "../network/net_http_special.h"
|
||||
|
||||
#include "badges.h"
|
||||
|
||||
badges_ctx_t badges_ctx;
|
||||
|
||||
bool badge_exists(const char* filepath)
|
||||
{
|
||||
if(path_file_exists(filepath))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void set_badge_menu_texture(badges_ctx_t * badges, int i)
|
||||
{
|
||||
const char * locked_suffix = (badges->badge_locked[i] == true) ? "_lock.png" : ".png";
|
||||
|
||||
unsigned int bufferSize = 16;
|
||||
char badge_file[bufferSize];
|
||||
|
||||
snprintf(badge_file, bufferSize, "%s", badges->badge_id_list[i]);
|
||||
strcat(badge_file, locked_suffix);
|
||||
|
||||
char fullpath[PATH_MAX_LENGTH];
|
||||
fill_pathname_application_special(fullpath,
|
||||
PATH_MAX_LENGTH * sizeof(char),
|
||||
APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES);
|
||||
|
||||
menu_display_reset_textures_list(badge_file, fullpath, &badges->menu_texture_list[i],TEXTURE_FILTER_MIPMAP_LINEAR);
|
||||
}
|
||||
|
||||
void set_badge_info (badges_ctx_t *badge_struct, int id, const char *badge_id, bool active)
|
||||
{
|
||||
badge_struct->badge_id_list[id] = badge_id;
|
||||
badge_struct->badge_locked[id] = active;
|
||||
set_badge_menu_texture(badge_struct, id);
|
||||
}
|
||||
|
||||
menu_texture_item get_badge_texture (int id)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
if (!settings->bools.cheevos_badges_enable)
|
||||
return (menu_texture_item)NULL;
|
||||
|
||||
return badges_ctx.menu_texture_list[id];
|
||||
}
|
29
cheevos/badges.h
Normal file
29
cheevos/badges.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef __RARCH_BADGE_H
|
||||
#define __RARCH_BADGE_H
|
||||
|
||||
#include "../menu/menu_driver.h"
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define CHEEVOS_BADGE_LIMIT 256
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool badge_locked[CHEEVOS_BADGE_LIMIT];
|
||||
const char * badge_id_list[CHEEVOS_BADGE_LIMIT];
|
||||
menu_texture_item menu_texture_list[CHEEVOS_BADGE_LIMIT];
|
||||
} badges_ctx_t;
|
||||
|
||||
bool badge_exists(const char* filepath);
|
||||
void set_badge_menu_texture(badges_ctx_t * badges, int i);
|
||||
extern void set_badge_info (badges_ctx_t *badge_struct, int id, const char *badge_id, bool active);
|
||||
extern menu_texture_item get_badge_texture(int id);
|
||||
|
||||
extern badges_ctx_t badges_ctx;
|
||||
static badges_ctx_t new_badges_ctx;
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
@ -16,6 +16,8 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <file/file_path.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <formats/jsonsax.h>
|
||||
#include <streams/file_stream.h>
|
||||
#include <features/features_cpu.h>
|
||||
@ -35,10 +37,12 @@
|
||||
#include "../menu/menu_entries.h"
|
||||
#endif
|
||||
|
||||
#include "badges.h"
|
||||
#include "cheevos.h"
|
||||
#include "var.h"
|
||||
#include "cond.h"
|
||||
|
||||
#include "../file_path_special.h"
|
||||
#include "../command.h"
|
||||
#include "../dynamic.h"
|
||||
#include "../configuration.h"
|
||||
@ -76,6 +80,9 @@
|
||||
* THE USER'S PASSWORD, TAKE CARE! */
|
||||
#undef CHEEVOS_LOG_PASSWORD
|
||||
|
||||
/* Define this macro to log downloaded badge images. */
|
||||
#undef CHEEVOS_LOG_BADGES
|
||||
|
||||
/* C89 wants only int values in enums. */
|
||||
#define CHEEVOS_JSON_KEY_GAMEID 0xb4960eecU
|
||||
#define CHEEVOS_JSON_KEY_ACHIEVEMENTS 0x69749ae1U
|
||||
@ -534,6 +541,8 @@ static void cheevos_add_var(const cheevos_var_t* var, char** memaddr,
|
||||
{
|
||||
if (var->type == CHEEVOS_VAR_TYPE_DELTA_MEM)
|
||||
cheevos_add_char(memaddr, left, 'd');
|
||||
else if (var->is_bcd)
|
||||
cheevos_add_char(memaddr, left, 'b');
|
||||
|
||||
cheevos_add_string(memaddr, left, "0x");
|
||||
cheevos_add_var_size(memaddr, left, var);
|
||||
@ -876,24 +885,27 @@ static unsigned cheevos_count_cond_sets(const char *memaddr)
|
||||
|
||||
static int cheevos_parse_condition(cheevos_condition_t *condition, const char* memaddr)
|
||||
{
|
||||
if (!condition)
|
||||
return 0;
|
||||
|
||||
condition->count = cheevos_count_cond_sets(memaddr);
|
||||
|
||||
if (condition->count)
|
||||
{
|
||||
unsigned set = 0;
|
||||
cheevos_condset_t *condset = NULL;
|
||||
cheevos_condset_t *conds = NULL;
|
||||
const cheevos_condset_t* end = NULL;
|
||||
|
||||
(void)conds;
|
||||
|
||||
condition->condsets = (cheevos_condset_t*)
|
||||
cheevos_condset_t *conds = NULL;
|
||||
cheevos_condset_t *condset = NULL;
|
||||
cheevos_condset_t *condsets = (cheevos_condset_t*)
|
||||
calloc(condition->count, sizeof(cheevos_condset_t));
|
||||
|
||||
if (!condition->condsets)
|
||||
(void)conds;
|
||||
|
||||
if (!condsets)
|
||||
return -1;
|
||||
|
||||
end = condition->condsets + condition->count;
|
||||
condition->condsets = condsets;
|
||||
end = condition->condsets + condition->count;
|
||||
|
||||
for (condset = condition->condsets; condset < end; condset++, set++)
|
||||
{
|
||||
@ -915,9 +927,10 @@ static int cheevos_parse_condition(cheevos_condition_t *condition, const char* m
|
||||
{
|
||||
while (--condset >= condition->condsets)
|
||||
{
|
||||
free((void*)condset->conds);
|
||||
if ((void*)condset->conds)
|
||||
free((void*)condset->conds);
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -937,9 +950,19 @@ static void cheevos_free_condition(cheevos_condition_t* condition)
|
||||
if (condition->condsets)
|
||||
{
|
||||
for (i = 0; i < condition->count; i++)
|
||||
free((void*)condition->condsets[i].conds);
|
||||
{
|
||||
if (condition->condsets[i].conds)
|
||||
{
|
||||
free(condition->condsets[i].conds);
|
||||
condition->condsets[i].conds = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free((void*)condition->condsets);
|
||||
if (condition->condsets)
|
||||
{
|
||||
free(condition->condsets);
|
||||
condition->condsets = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -955,8 +978,12 @@ static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem)
|
||||
expr->count = 1;
|
||||
expr->compare_count = 1;
|
||||
|
||||
for (aux = mem; *aux != '"'; aux++)
|
||||
for (aux = mem;; aux++)
|
||||
{
|
||||
if(*aux == '"' || *aux == ':')
|
||||
break;
|
||||
expr->count += *aux == '_';
|
||||
}
|
||||
|
||||
expr->terms = (cheevos_term_t*)calloc(expr->count, sizeof(cheevos_term_t));
|
||||
|
||||
@ -990,13 +1017,17 @@ static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem)
|
||||
}
|
||||
|
||||
/* no multiplier at end of string */
|
||||
else if (*aux == '\0' || *aux == '"' || *aux == ',')
|
||||
else if (*aux == '\0' || *aux == '"' || *aux == ',')
|
||||
return 0;
|
||||
|
||||
/* invalid character in expression */
|
||||
else
|
||||
{
|
||||
free((void*)expr->terms);
|
||||
if (expr->terms)
|
||||
{
|
||||
free(expr->terms);
|
||||
expr->terms = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1026,10 +1057,10 @@ static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem)
|
||||
|
||||
static int cheevos_parse_mem(cheevos_leaderboard_t *lb, const char* mem)
|
||||
{
|
||||
lb->start.condsets = NULL;
|
||||
lb->start.condsets = NULL;
|
||||
lb->cancel.condsets = NULL;
|
||||
lb->submit.condsets = NULL;
|
||||
lb->value.terms = NULL;
|
||||
lb->value.terms = NULL;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -1053,8 +1084,6 @@ static int cheevos_parse_mem(cheevos_leaderboard_t *lb, const char* mem)
|
||||
if (cheevos_parse_expression(&lb->value, mem + 4))
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
goto error;
|
||||
|
||||
for (mem += 4;; mem++)
|
||||
{
|
||||
@ -1072,7 +1101,11 @@ error:
|
||||
cheevos_free_condition(&lb->start);
|
||||
cheevos_free_condition(&lb->cancel);
|
||||
cheevos_free_condition(&lb->submit);
|
||||
free((void*)lb->value.terms);
|
||||
if (lb->value.terms)
|
||||
{
|
||||
free((void*)lb->value.terms);
|
||||
lb->value.terms = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1130,10 +1163,26 @@ static int cheevos_new_cheevo(cheevos_readud_t *ud)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free((void*)cheevo->title);
|
||||
free((void*)cheevo->description);
|
||||
free((void*)cheevo->author);
|
||||
free((void*)cheevo->badge);
|
||||
if (cheevo->title)
|
||||
{
|
||||
free((void*)cheevo->title);
|
||||
cheevo->title = NULL;
|
||||
}
|
||||
if (cheevo->description)
|
||||
{
|
||||
free((void*)cheevo->description);
|
||||
cheevo->description = NULL;
|
||||
}
|
||||
if (cheevo->author)
|
||||
{
|
||||
free((void*)cheevo->author);
|
||||
cheevo->author = NULL;
|
||||
}
|
||||
if (cheevo->badge)
|
||||
{
|
||||
free((void*)cheevo->badge);
|
||||
cheevo->badge = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1228,8 +1277,10 @@ static int cheevos_new_lboard(cheevos_readud_t *ud)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free((void*)lboard->title);
|
||||
free((void*)lboard->description);
|
||||
if ((void*)lboard->title)
|
||||
free((void*)lboard->title);
|
||||
if ((void*)lboard->description)
|
||||
free((void*)lboard->description);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1405,9 +1456,12 @@ static int cheevos_parse(const char *json)
|
||||
if ( !cheevos_locals.core.cheevos || !cheevos_locals.unofficial.cheevos
|
||||
|| !cheevos_locals.leaderboards)
|
||||
{
|
||||
free((void*)cheevos_locals.core.cheevos);
|
||||
free((void*)cheevos_locals.unofficial.cheevos);
|
||||
free((void*)cheevos_locals.leaderboards);
|
||||
if ((void*)cheevos_locals.core.cheevos)
|
||||
free((void*)cheevos_locals.core.cheevos);
|
||||
if ((void*)cheevos_locals.unofficial.cheevos)
|
||||
free((void*)cheevos_locals.unofficial.cheevos);
|
||||
if ((void*)cheevos_locals.leaderboards)
|
||||
free((void*)cheevos_locals.leaderboards);
|
||||
cheevos_locals.core.count = cheevos_locals.unofficial.count =
|
||||
cheevos_locals.lboard_count = 0;
|
||||
|
||||
@ -1930,7 +1984,7 @@ static void cheevos_test_leaderboards(void)
|
||||
snprintf(msg, sizeof(msg), "Submitted %s for %s", formatted_value, lboard->title);
|
||||
msg[sizeof(msg) - 1] = 0;
|
||||
runloop_msg_queue_push(msg, 0, 2 * 60, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cheevos_test_lboard_condition(&lboard->cancel))
|
||||
@ -1964,15 +2018,20 @@ Free the loaded achievements.
|
||||
|
||||
static void cheevos_free_condset(const cheevos_condset_t *set)
|
||||
{
|
||||
free((void*)set->conds);
|
||||
if (set->conds)
|
||||
free((void*)set->conds);
|
||||
}
|
||||
|
||||
static void cheevos_free_cheevo(const cheevo_t *cheevo)
|
||||
{
|
||||
free((void*)cheevo->title);
|
||||
free((void*)cheevo->description);
|
||||
free((void*)cheevo->author);
|
||||
free((void*)cheevo->badge);
|
||||
if (cheevo->title)
|
||||
free((void*)cheevo->title);
|
||||
if (cheevo->description)
|
||||
free((void*)cheevo->description);
|
||||
if (cheevo->author)
|
||||
free((void*)cheevo->author);
|
||||
if (cheevo->badge)
|
||||
free((void*)cheevo->badge);
|
||||
cheevos_free_condset(cheevo->condition.condsets);
|
||||
}
|
||||
|
||||
@ -1984,7 +2043,8 @@ static void cheevos_free_cheevo_set(const cheevoset_t *set)
|
||||
while (cheevo < end)
|
||||
cheevos_free_cheevo(cheevo++);
|
||||
|
||||
free((void*)set->cheevos);
|
||||
if (set->cheevos)
|
||||
free((void*)set->cheevos);
|
||||
}
|
||||
|
||||
#ifndef CHEEVOS_DONT_DEACTIVATE
|
||||
@ -2088,7 +2148,7 @@ void cheevos_reset_game(void)
|
||||
cheevo->last = 1;
|
||||
}
|
||||
|
||||
void cheevos_populate_menu(void *data, bool hardcore)
|
||||
void cheevos_populate_menu(void *data)
|
||||
{
|
||||
#ifdef HAVE_MENU
|
||||
unsigned i;
|
||||
@ -2101,39 +2161,30 @@ void cheevos_populate_menu(void *data, bool hardcore)
|
||||
|
||||
for (i = 0; cheevo < end; i++, cheevo++)
|
||||
{
|
||||
if (!hardcore)
|
||||
|
||||
if (!(cheevo->active & CHEEVOS_ACTIVE_HARDCORE))
|
||||
{
|
||||
if (!(cheevo->active & CHEEVOS_ACTIVE_SOFTCORE))
|
||||
{
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
}
|
||||
else
|
||||
{
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
}
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY_HARDCORE,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
set_badge_info(&badges_ctx, i, cheevo->badge, (cheevo->active & CHEEVOS_ACTIVE_HARDCORE));
|
||||
}
|
||||
else if (!(cheevo->active & CHEEVOS_ACTIVE_SOFTCORE))
|
||||
{
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
set_badge_info(&badges_ctx, i, cheevo->badge, (cheevo->active & CHEEVOS_ACTIVE_SOFTCORE));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(cheevo->active & CHEEVOS_ACTIVE_HARDCORE))
|
||||
{
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
}
|
||||
else
|
||||
{
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
}
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
set_badge_info(&badges_ctx, i, cheevo->badge, (cheevo->active & CHEEVOS_ACTIVE_SOFTCORE));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2145,39 +2196,29 @@ void cheevos_populate_menu(void *data, bool hardcore)
|
||||
|
||||
for (i = cheevos_locals.core.count; cheevo < end; i++, cheevo++)
|
||||
{
|
||||
if (!hardcore)
|
||||
if (!(cheevo->active & CHEEVOS_ACTIVE_HARDCORE))
|
||||
{
|
||||
if (!(cheevo->active & CHEEVOS_ACTIVE_SOFTCORE))
|
||||
{
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
}
|
||||
else
|
||||
{
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
}
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY_HARDCORE,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
set_badge_info(&badges_ctx, i, cheevo->badge, (cheevo->active & CHEEVOS_ACTIVE_HARDCORE));
|
||||
}
|
||||
else if (!(cheevo->active & CHEEVOS_ACTIVE_SOFTCORE))
|
||||
{
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
set_badge_info(&badges_ctx, i, cheevo->badge, (cheevo->active & CHEEVOS_ACTIVE_SOFTCORE));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(cheevo->active & CHEEVOS_ACTIVE_HARDCORE))
|
||||
{
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
}
|
||||
else
|
||||
{
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
}
|
||||
menu_entries_append_enum(info->list, cheevo->title,
|
||||
cheevo->description, MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
||||
MENU_SETTINGS_CHEEVOS_START + i, 0, 0);
|
||||
items_found++;
|
||||
set_badge_info(&badges_ctx, i, cheevo->badge, (cheevo->active & CHEEVOS_ACTIVE_SOFTCORE));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2469,37 +2510,47 @@ typedef struct
|
||||
char url[256]; \
|
||||
struct http_connection_t *conn; \
|
||||
struct http_t *http; \
|
||||
retro_time_t t0;
|
||||
retro_time_t t0; \
|
||||
char badge_basepath[PATH_MAX_LENGTH]; \
|
||||
char badge_fullpath[PATH_MAX_LENGTH]; \
|
||||
char badge_name[16]; \
|
||||
cheevo_t *cheevo; \
|
||||
const cheevo_t *cheevo_end;
|
||||
|
||||
#include "coro.h"
|
||||
|
||||
#define CHEEVOS_VAR_INFO CORO_VAR(info)
|
||||
#define CHEEVOS_VAR_DATA CORO_VAR(data)
|
||||
#define CHEEVOS_VAR_LEN CORO_VAR(len)
|
||||
#define CHEEVOS_VAR_PATH CORO_VAR(path)
|
||||
#define CHEEVOS_VAR_SETTINGS CORO_VAR(settings)
|
||||
#define CHEEVOS_VAR_SYSINFO CORO_VAR(sysinfo)
|
||||
#define CHEEVOS_VAR_I CORO_VAR(i)
|
||||
#define CHEEVOS_VAR_J CORO_VAR(j)
|
||||
#define CHEEVOS_VAR_K CORO_VAR(k)
|
||||
#define CHEEVOS_VAR_EXT CORO_VAR(ext)
|
||||
#define CHEEVOS_VAR_MD5 CORO_VAR(md5)
|
||||
#define CHEEVOS_VAR_HASH CORO_VAR(hash)
|
||||
#define CHEEVOS_VAR_GAMEID CORO_VAR(gameid)
|
||||
#define CHEEVOS_VAR_JSON CORO_VAR(json)
|
||||
#define CHEEVOS_VAR_COUNT CORO_VAR(count)
|
||||
#define CHEEVOS_VAR_OFFSET CORO_VAR(offset)
|
||||
#define CHEEVOS_VAR_HEADER CORO_VAR(header)
|
||||
#define CHEEVOS_VAR_ROMSIZE CORO_VAR(romsize)
|
||||
#define CHEEVOS_VAR_BYTES CORO_VAR(bytes)
|
||||
#define CHEEVOS_VAR_MAPPER CORO_VAR(mapper)
|
||||
#define CHEEVOS_VAR_ROUND CORO_VAR(round)
|
||||
#define CHEEVOS_VAR_STREAM CORO_VAR(stream)
|
||||
#define CHEEVOS_VAR_SIZE CORO_VAR(size)
|
||||
#define CHEEVOS_VAR_URL CORO_VAR(url)
|
||||
#define CHEEVOS_VAR_CONN CORO_VAR(conn)
|
||||
#define CHEEVOS_VAR_HTTP CORO_VAR(http)
|
||||
#define CHEEVOS_VAR_T0 CORO_VAR(t0)
|
||||
#define CHEEVOS_VAR_INFO CORO_VAR(info)
|
||||
#define CHEEVOS_VAR_DATA CORO_VAR(data)
|
||||
#define CHEEVOS_VAR_LEN CORO_VAR(len)
|
||||
#define CHEEVOS_VAR_PATH CORO_VAR(path)
|
||||
#define CHEEVOS_VAR_SETTINGS CORO_VAR(settings)
|
||||
#define CHEEVOS_VAR_SYSINFO CORO_VAR(sysinfo)
|
||||
#define CHEEVOS_VAR_I CORO_VAR(i)
|
||||
#define CHEEVOS_VAR_J CORO_VAR(j)
|
||||
#define CHEEVOS_VAR_K CORO_VAR(k)
|
||||
#define CHEEVOS_VAR_EXT CORO_VAR(ext)
|
||||
#define CHEEVOS_VAR_MD5 CORO_VAR(md5)
|
||||
#define CHEEVOS_VAR_HASH CORO_VAR(hash)
|
||||
#define CHEEVOS_VAR_GAMEID CORO_VAR(gameid)
|
||||
#define CHEEVOS_VAR_JSON CORO_VAR(json)
|
||||
#define CHEEVOS_VAR_COUNT CORO_VAR(count)
|
||||
#define CHEEVOS_VAR_OFFSET CORO_VAR(offset)
|
||||
#define CHEEVOS_VAR_HEADER CORO_VAR(header)
|
||||
#define CHEEVOS_VAR_ROMSIZE CORO_VAR(romsize)
|
||||
#define CHEEVOS_VAR_BYTES CORO_VAR(bytes)
|
||||
#define CHEEVOS_VAR_MAPPER CORO_VAR(mapper)
|
||||
#define CHEEVOS_VAR_ROUND CORO_VAR(round)
|
||||
#define CHEEVOS_VAR_STREAM CORO_VAR(stream)
|
||||
#define CHEEVOS_VAR_SIZE CORO_VAR(size)
|
||||
#define CHEEVOS_VAR_URL CORO_VAR(url)
|
||||
#define CHEEVOS_VAR_CONN CORO_VAR(conn)
|
||||
#define CHEEVOS_VAR_HTTP CORO_VAR(http)
|
||||
#define CHEEVOS_VAR_T0 CORO_VAR(t0)
|
||||
#define CHEEVOS_VAR_BADGE_PATH CORO_VAR(badge_fullpath)
|
||||
#define CHEEVOS_VAR_BADGE_BASE_PATH CORO_VAR(badge_fullpath)
|
||||
#define CHEEVOS_VAR_BADGE_NAME CORO_VAR(badge_name)
|
||||
#define CHEEVOS_VAR_CHEEVO_CURR CORO_VAR(cheevo)
|
||||
#define CHEEVOS_VAR_CHEEVO_END CORO_VAR(cheevo_end)
|
||||
|
||||
static int cheevos_iterate(coro_t* coro)
|
||||
{
|
||||
@ -2520,11 +2571,12 @@ static int cheevos_iterate(coro_t* coro)
|
||||
FILL_MD5 = -7,
|
||||
GET_GAMEID = -8,
|
||||
GET_CHEEVOS = -9,
|
||||
LOGIN = -10,
|
||||
HTTP_GET = -11,
|
||||
DEACTIVATE = -12,
|
||||
PLAYING = -13,
|
||||
DELAY = -14
|
||||
GET_BADGES = -10,
|
||||
LOGIN = -11,
|
||||
HTTP_GET = -12,
|
||||
DEACTIVATE = -13,
|
||||
PLAYING = -14,
|
||||
DELAY = -15
|
||||
};
|
||||
|
||||
static const uint32_t genesis_exts[] =
|
||||
@ -2605,7 +2657,7 @@ static int cheevos_iterate(coro_t* coro)
|
||||
/* Load the content into memory, or copy it over to our own buffer */
|
||||
if (!CHEEVOS_VAR_DATA)
|
||||
{
|
||||
CHEEVOS_VAR_STREAM = filestream_open(CHEEVOS_VAR_PATH, RFILE_MODE_READ, 0);
|
||||
CHEEVOS_VAR_STREAM = filestream_open(CHEEVOS_VAR_PATH, RFILE_MODE_READ, -1);
|
||||
|
||||
if (!CHEEVOS_VAR_STREAM)
|
||||
CORO_STOP();
|
||||
@ -2757,11 +2809,14 @@ static int cheevos_iterate(coro_t* coro)
|
||||
#endif
|
||||
if (cheevos_parse(CHEEVOS_VAR_JSON))
|
||||
{
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
if ((void*)CHEEVOS_VAR_JSON)
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
CORO_STOP();
|
||||
}
|
||||
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
if ((void*)CHEEVOS_VAR_JSON)
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
|
||||
cheevos_loaded = true;
|
||||
|
||||
/*
|
||||
@ -2778,27 +2833,35 @@ static int cheevos_iterate(coro_t* coro)
|
||||
|
||||
if(CHEEVOS_VAR_SETTINGS->bools.cheevos_verbose_enable)
|
||||
{
|
||||
const cheevo_t* cheevo = cheevos_locals.core.cheevos;
|
||||
const cheevo_t* end = cheevo + cheevos_locals.core.count;
|
||||
int number_of_unlocked = cheevos_locals.core.count;
|
||||
int mode;
|
||||
char msg[256];
|
||||
if(cheevos_locals.core.count > 0)
|
||||
{
|
||||
const cheevo_t* cheevo = cheevos_locals.core.cheevos;
|
||||
const cheevo_t* end = cheevo + cheevos_locals.core.count;
|
||||
int number_of_unlocked = cheevos_locals.core.count;
|
||||
int mode;
|
||||
char msg[256];
|
||||
|
||||
if(CHEEVOS_VAR_SETTINGS->bools.cheevos_hardcore_mode_enable)
|
||||
mode = CHEEVOS_ACTIVE_HARDCORE;
|
||||
if(CHEEVOS_VAR_SETTINGS->bools.cheevos_hardcore_mode_enable)
|
||||
mode = CHEEVOS_ACTIVE_HARDCORE;
|
||||
else
|
||||
mode = CHEEVOS_ACTIVE_SOFTCORE;
|
||||
|
||||
for(; cheevo < end; cheevo++)
|
||||
if(cheevo->active & mode)
|
||||
number_of_unlocked--;
|
||||
|
||||
snprintf(msg, sizeof(msg), "You have %d of %d achievements unlocked.",
|
||||
number_of_unlocked, cheevos_locals.core.count);
|
||||
msg[sizeof(msg) - 1] = 0;
|
||||
runloop_msg_queue_push(msg, 0, 6 * 60, false);
|
||||
}
|
||||
else
|
||||
mode = CHEEVOS_ACTIVE_SOFTCORE;
|
||||
runloop_msg_queue_push("This game has no achievements.", 0, 5 * 60, false);
|
||||
|
||||
for(; cheevo < end; cheevo++)
|
||||
if(cheevo->active & mode)
|
||||
number_of_unlocked--;
|
||||
|
||||
snprintf(msg, sizeof(msg), "You have %d of %d achievements unlocked.",
|
||||
number_of_unlocked, cheevos_locals.core.count);
|
||||
msg[sizeof(msg) - 1] = 0;
|
||||
runloop_msg_queue_push(msg, 0, 6 * 60, false);
|
||||
}
|
||||
|
||||
CORO_GOSUB(GET_BADGES);
|
||||
|
||||
CORO_STOP();
|
||||
|
||||
/**************************************************************************
|
||||
@ -2869,7 +2932,7 @@ static int cheevos_iterate(coro_t* coro)
|
||||
* Output CHEEVOS_VAR_GAMEID the Retro Achievements game ID, or 0 if not found
|
||||
*************************************************************************/
|
||||
CORO_SUB(LYNX_MD5)
|
||||
|
||||
|
||||
if (CHEEVOS_VAR_LEN < 0x0240)
|
||||
{
|
||||
CHEEVOS_VAR_GAMEID = 0;
|
||||
@ -3052,12 +3115,14 @@ static int cheevos_iterate(coro_t* coro)
|
||||
|
||||
if (cheevos_get_value(CHEEVOS_VAR_JSON, CHEEVOS_JSON_KEY_GAMEID, gameid, sizeof(gameid)))
|
||||
{
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
if ((void*)CHEEVOS_VAR_JSON)
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
RARCH_ERR("[CHEEVOS]: error getting game_id.\n");
|
||||
CORO_RET();
|
||||
}
|
||||
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
if ((void*)CHEEVOS_VAR_JSON)
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
RARCH_LOG("[CHEEVOS]: got game id %s.\n", gameid);
|
||||
CHEEVOS_VAR_GAMEID = strtol(gameid, NULL, 10);
|
||||
CORO_RET();
|
||||
@ -3070,14 +3135,12 @@ static int cheevos_iterate(coro_t* coro)
|
||||
*************************************************************************/
|
||||
CORO_SUB(GET_CHEEVOS)
|
||||
|
||||
CORO_GOSUB(LOGIN);
|
||||
CORO_GOSUB(LOGIN);
|
||||
|
||||
snprintf(
|
||||
CHEEVOS_VAR_URL, sizeof(CHEEVOS_VAR_URL),
|
||||
"http://retroachievements.org/dorequest.php?r=patch&u=%s&g=%u&f=3&l=1&t=%s",
|
||||
CHEEVOS_VAR_SETTINGS->arrays.cheevos_username,
|
||||
CHEEVOS_VAR_GAMEID, cheevos_locals.token
|
||||
);
|
||||
snprintf(CHEEVOS_VAR_URL, sizeof(CHEEVOS_VAR_URL),
|
||||
"http://retroachievements.org/dorequest.php?r=patch&u=%s&g=%u&f=3&l=1&t=%s",
|
||||
CHEEVOS_VAR_SETTINGS->arrays.cheevos_username,
|
||||
CHEEVOS_VAR_GAMEID, cheevos_locals.token);
|
||||
|
||||
CHEEVOS_VAR_URL[sizeof(CHEEVOS_VAR_URL) - 1] = 0;
|
||||
|
||||
@ -3096,6 +3159,62 @@ static int cheevos_iterate(coro_t* coro)
|
||||
RARCH_LOG("[CHEEVOS]: got achievements for game id %u.\n", CHEEVOS_VAR_GAMEID);
|
||||
CORO_RET();
|
||||
|
||||
/**************************************************************************
|
||||
* Info Gets the achievements from Retro Achievements
|
||||
* Inputs CHEEVOS_VAR_GAMEID
|
||||
* Outputs CHEEVOS_VAR_JSON
|
||||
*************************************************************************/
|
||||
CORO_SUB(GET_BADGES)
|
||||
|
||||
badges_ctx = new_badges_ctx;
|
||||
|
||||
settings_t *settings = config_get_ptr();
|
||||
if (!string_is_equal(settings->arrays.menu_driver, "xmb") ||
|
||||
!settings->bools.cheevos_badges_enable)
|
||||
CORO_RET();
|
||||
|
||||
CHEEVOS_VAR_CHEEVO_CURR = cheevos_locals.core.cheevos;
|
||||
CHEEVOS_VAR_CHEEVO_END = cheevos_locals.core.cheevos + cheevos_locals.core.count;
|
||||
|
||||
for (; CHEEVOS_VAR_CHEEVO_CURR < CHEEVOS_VAR_CHEEVO_END ; CHEEVOS_VAR_CHEEVO_CURR++)
|
||||
{
|
||||
for (CHEEVOS_VAR_J = 0 ; CHEEVOS_VAR_J < 2; CHEEVOS_VAR_J++)
|
||||
{
|
||||
CHEEVOS_VAR_BADGE_PATH[0] = '\0';
|
||||
fill_pathname_application_special(CHEEVOS_VAR_BADGE_BASE_PATH, sizeof(CHEEVOS_VAR_BADGE_BASE_PATH),
|
||||
APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES);
|
||||
|
||||
if (!path_is_directory(CHEEVOS_VAR_BADGE_BASE_PATH))
|
||||
path_mkdir(CHEEVOS_VAR_BADGE_BASE_PATH);
|
||||
CORO_YIELD();
|
||||
if (CHEEVOS_VAR_J == 0)
|
||||
snprintf(CHEEVOS_VAR_BADGE_NAME, sizeof(CHEEVOS_VAR_BADGE_NAME), "%s.png", CHEEVOS_VAR_CHEEVO_CURR->badge);
|
||||
else
|
||||
snprintf(CHEEVOS_VAR_BADGE_NAME, sizeof(CHEEVOS_VAR_BADGE_NAME), "%s_lock.png", CHEEVOS_VAR_CHEEVO_CURR->badge);
|
||||
|
||||
fill_pathname_join(CHEEVOS_VAR_BADGE_PATH, CHEEVOS_VAR_BADGE_BASE_PATH, CHEEVOS_VAR_BADGE_NAME, sizeof(CHEEVOS_VAR_BADGE_PATH));
|
||||
|
||||
if (!badge_exists(CHEEVOS_VAR_BADGE_PATH))
|
||||
{
|
||||
#ifdef CHEEVOS_LOG_BADGES
|
||||
RARCH_LOG("[CHEEVOS]: downloading badge %s\n", CHEEVOS_VAR_BADGE_PATH);
|
||||
#endif
|
||||
snprintf(CHEEVOS_VAR_URL, sizeof(CHEEVOS_VAR_URL), "http://i.retroachievements.org/Badge/%s", CHEEVOS_VAR_BADGE_NAME);
|
||||
|
||||
CORO_GOSUB(HTTP_GET);
|
||||
if (CHEEVOS_VAR_JSON != NULL)
|
||||
{
|
||||
if (!filestream_write_file(CHEEVOS_VAR_BADGE_PATH, CHEEVOS_VAR_JSON, CHEEVOS_VAR_K))
|
||||
RARCH_ERR("[CHEEVOS]: error writing badge %s\n", CHEEVOS_VAR_BADGE_PATH);
|
||||
else
|
||||
free(CHEEVOS_VAR_JSON);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CORO_RET();
|
||||
|
||||
/**************************************************************************
|
||||
* Info Logs in the user at Retro Achievements
|
||||
*************************************************************************/
|
||||
@ -3139,7 +3258,8 @@ static int cheevos_iterate(coro_t* coro)
|
||||
if (CHEEVOS_VAR_JSON)
|
||||
{
|
||||
int res = cheevos_get_value(CHEEVOS_VAR_JSON, CHEEVOS_JSON_KEY_TOKEN, cheevos_locals.token, sizeof(cheevos_locals.token));
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
if ((void*)CHEEVOS_VAR_JSON)
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
@ -3188,7 +3308,7 @@ static int cheevos_iterate(coro_t* coro)
|
||||
{
|
||||
if (CHEEVOS_VAR_K != 0)
|
||||
RARCH_LOG("[CHEEVOS]: Retrying HTTP request: %u of 5\n", CHEEVOS_VAR_K + 1);
|
||||
|
||||
|
||||
CHEEVOS_VAR_JSON = NULL;
|
||||
CHEEVOS_VAR_CONN = net_http_connection_new(CHEEVOS_VAR_URL, "GET", NULL);
|
||||
|
||||
@ -3236,6 +3356,7 @@ static int cheevos_iterate(coro_t* coro)
|
||||
CHEEVOS_VAR_JSON[length] = 0;
|
||||
}
|
||||
|
||||
CHEEVOS_VAR_K = length;
|
||||
net_http_delete(CHEEVOS_VAR_HTTP);
|
||||
net_http_connection_free(CHEEVOS_VAR_CONN);
|
||||
CORO_RET();
|
||||
@ -3281,8 +3402,9 @@ static int cheevos_iterate(coro_t* coro)
|
||||
RARCH_LOG("[CHEEVOS]: deactivated unlocked achievements in softcore mode.\n");
|
||||
else
|
||||
RARCH_ERR("[CHEEVOS]: error deactivating unlocked achievements in softcore mode.\n");
|
||||
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
|
||||
if ((void*)CHEEVOS_VAR_JSON)
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
}
|
||||
else
|
||||
RARCH_ERR("[CHEEVOS]: error retrieving list of unlocked achievements in softcore mode.\n");
|
||||
@ -3309,8 +3431,9 @@ static int cheevos_iterate(coro_t* coro)
|
||||
RARCH_LOG("[CHEEVOS]: deactivated unlocked achievements in hardcore mode.\n");
|
||||
else
|
||||
RARCH_ERR("[CHEEVOS]: error deactivating unlocked achievements in hardcore mode.\n");
|
||||
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
|
||||
if ((void*)CHEEVOS_VAR_JSON)
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
}
|
||||
else
|
||||
RARCH_ERR("[CHEEVOS]: error retrieving list of unlocked achievements in hardcore mode.\n");
|
||||
@ -3343,7 +3466,8 @@ static int cheevos_iterate(coro_t* coro)
|
||||
if (CHEEVOS_VAR_JSON)
|
||||
{
|
||||
RARCH_LOG("[CHEEVOS]: posted playing activity.\n");
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
if ((void*)CHEEVOS_VAR_JSON)
|
||||
free((void*)CHEEVOS_VAR_JSON);
|
||||
}
|
||||
else
|
||||
RARCH_ERR("[CHEEVOS]: error posting playing activity.\n");
|
||||
@ -3358,11 +3482,16 @@ static void cheevos_task_handler(retro_task_t *task)
|
||||
{
|
||||
coro_t *coro = (coro_t*)task->state;
|
||||
|
||||
if (!coro)
|
||||
return;
|
||||
|
||||
if (!cheevos_iterate(coro))
|
||||
{
|
||||
task_set_finished(task, true);
|
||||
free(CHEEVOS_VAR_DATA);
|
||||
free((void*)CHEEVOS_VAR_PATH);
|
||||
if (CHEEVOS_VAR_DATA)
|
||||
free(CHEEVOS_VAR_DATA);
|
||||
if ((void*)CHEEVOS_VAR_PATH)
|
||||
free((void*)CHEEVOS_VAR_PATH);
|
||||
free((void*)coro);
|
||||
}
|
||||
}
|
||||
@ -3370,8 +3499,8 @@ static void cheevos_task_handler(retro_task_t *task)
|
||||
bool cheevos_load(const void *data)
|
||||
{
|
||||
retro_task_t *task;
|
||||
coro_t *coro;
|
||||
const struct retro_game_info *info;
|
||||
const struct retro_game_info *info = NULL;
|
||||
coro_t *coro = NULL;
|
||||
|
||||
cheevos_loaded = 0;
|
||||
|
||||
@ -3387,7 +3516,8 @@ bool cheevos_load(const void *data)
|
||||
|
||||
if (!task)
|
||||
{
|
||||
free((void*)coro);
|
||||
if ((void*)coro)
|
||||
free((void*)coro);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3406,8 +3536,10 @@ bool cheevos_load(const void *data)
|
||||
|
||||
if (!CHEEVOS_VAR_DATA)
|
||||
{
|
||||
free((void*)task);
|
||||
free((void*)coro);
|
||||
if ((void*)task)
|
||||
free((void*)task);
|
||||
if ((void*)coro)
|
||||
free((void*)coro);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ bool cheevos_load(const void *data);
|
||||
|
||||
void cheevos_reset_game(void);
|
||||
|
||||
void cheevos_populate_menu(void *data, bool hardcore);
|
||||
void cheevos_populate_menu(void *data);
|
||||
|
||||
bool cheevos_get_description(cheevos_ctx_desc_t *desc);
|
||||
|
||||
|
@ -119,12 +119,21 @@ void cheevos_var_parse(cheevos_var_t* var, const char** memaddr)
|
||||
const char *str = *memaddr;
|
||||
unsigned base = 16;
|
||||
|
||||
var->is_bcd = false;
|
||||
|
||||
if (toupper((unsigned char)*str) == 'D' && str[1] == '0' && toupper((unsigned char)str[2]) == 'X')
|
||||
{
|
||||
/* d0x + 4 hex digits */
|
||||
str += 3;
|
||||
var->type = CHEEVOS_VAR_TYPE_DELTA_MEM;
|
||||
}
|
||||
else if (toupper((unsigned char)*str) == 'B' && str[1] == '0' && toupper((unsigned char)str[2]) == 'X')
|
||||
{
|
||||
/* b0x (binary-coded decimal) */
|
||||
str += 3;
|
||||
var->is_bcd = true;
|
||||
var->type = CHEEVOS_VAR_TYPE_ADDRESS;
|
||||
}
|
||||
else if (*str == '0' && toupper((unsigned char)str[1]) == 'X')
|
||||
{
|
||||
/* 0x + 4 hex digits */
|
||||
@ -406,5 +415,8 @@ unsigned cheevos_var_get_value(cheevos_var_t* var)
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
if(var->is_bcd)
|
||||
return (((value >> 4) & 0xf) * 10) + (value & 0xf);
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ typedef struct
|
||||
cheevos_var_size_t size;
|
||||
cheevos_var_type_t type;
|
||||
int bank_id;
|
||||
bool is_bcd;
|
||||
unsigned value;
|
||||
unsigned previous;
|
||||
} cheevos_var_t;
|
||||
|
151
command.c
151
command.c
@ -641,6 +641,7 @@ static void command_stdin_poll(command_t *handle)
|
||||
|
||||
bool command_poll(command_t *handle)
|
||||
{
|
||||
memset(handle->state, 0, sizeof(handle->state));
|
||||
#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORK_CMD) && defined(HAVE_COMMAND)
|
||||
command_network_poll(handle);
|
||||
#endif
|
||||
@ -1307,14 +1308,18 @@ static void command_event_restore_default_shader_preset(void)
|
||||
if (!path_is_empty(RARCH_PATH_DEFAULT_SHADER_PRESET))
|
||||
{
|
||||
/* auto shader preset: reload the original shader */
|
||||
settings_t *settings = config_get_ptr();
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *shader_preset = path_get(RARCH_PATH_DEFAULT_SHADER_PRESET);
|
||||
|
||||
RARCH_LOG("%s %s\n",
|
||||
msg_hash_to_str(MSG_RESTORING_DEFAULT_SHADER_PRESET_TO),
|
||||
path_get(RARCH_PATH_DEFAULT_SHADER_PRESET));
|
||||
strlcpy(settings->paths.path_shader,
|
||||
path_get(RARCH_PATH_DEFAULT_SHADER_PRESET),
|
||||
sizeof(settings->paths.path_shader));
|
||||
if (!string_is_empty(shader_preset))
|
||||
{
|
||||
RARCH_LOG("%s %s\n",
|
||||
msg_hash_to_str(MSG_RESTORING_DEFAULT_SHADER_PRESET_TO),
|
||||
shader_preset);
|
||||
strlcpy(settings->paths.path_shader,
|
||||
shader_preset,
|
||||
sizeof(settings->paths.path_shader));
|
||||
}
|
||||
}
|
||||
|
||||
path_clear(RARCH_PATH_DEFAULT_SHADER_PRESET);
|
||||
@ -1373,24 +1378,32 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool command_event_save_config(const char *config_path,
|
||||
static bool command_event_save_config(
|
||||
const char *config_path,
|
||||
char *s, size_t len)
|
||||
{
|
||||
if (string_is_empty(config_path) || !config_save_file(config_path))
|
||||
bool path_exists = !string_is_empty(config_path);
|
||||
const char *str = path_exists ? config_path :
|
||||
path_get(RARCH_PATH_CONFIG);
|
||||
|
||||
if (path_exists && config_save_file(config_path))
|
||||
{
|
||||
snprintf(s, len, "[Config]: %s \"%s\".",
|
||||
msg_hash_to_str(MSG_SAVED_NEW_CONFIG_TO),
|
||||
config_path);
|
||||
RARCH_LOG("%s\n", s);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string_is_empty(str))
|
||||
{
|
||||
snprintf(s, len, "%s \"%s\".",
|
||||
msg_hash_to_str(MSG_FAILED_SAVING_CONFIG_TO),
|
||||
path_get(RARCH_PATH_CONFIG));
|
||||
str);
|
||||
RARCH_ERR("%s\n", s);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
snprintf(s, len, "[Config]: %s \"%s\".",
|
||||
msg_hash_to_str(MSG_SAVED_NEW_CONFIG_TO),
|
||||
path_get(RARCH_PATH_CONFIG));
|
||||
RARCH_LOG("%s\n", s);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1407,6 +1420,7 @@ static bool command_event_save_core_config(void)
|
||||
bool ret = false;
|
||||
bool found_path = false;
|
||||
bool overrides_active = false;
|
||||
const char *core_path = NULL;
|
||||
char *config_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
char *config_name = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
char *config_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
@ -1429,8 +1443,10 @@ static bool command_event_save_core_config(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
core_path = path_get(RARCH_PATH_CORE);
|
||||
|
||||
/* Infer file name based on libretro core. */
|
||||
if (!string_is_empty(path_get(RARCH_PATH_CORE)) && path_file_exists(path_get(RARCH_PATH_CORE)))
|
||||
if (!string_is_empty(core_path) && path_file_exists(core_path))
|
||||
{
|
||||
unsigned i;
|
||||
RARCH_LOG("%s\n", msg_hash_to_str(MSG_USING_CORE_NAME_FOR_NEW_CONFIG));
|
||||
@ -1442,7 +1458,7 @@ static bool command_event_save_core_config(void)
|
||||
|
||||
fill_pathname_base_noext(
|
||||
config_name,
|
||||
path_get(RARCH_PATH_CORE),
|
||||
core_path,
|
||||
config_size);
|
||||
|
||||
fill_pathname_join(config_path, config_dir, config_name,
|
||||
@ -1489,7 +1505,8 @@ static bool command_event_save_core_config(void)
|
||||
|
||||
command_event_save_config(config_path, msg, sizeof(msg));
|
||||
|
||||
runloop_msg_queue_push(msg, 1, 180, true);
|
||||
if (!string_is_empty(msg))
|
||||
runloop_msg_queue_push(msg, 1, 180, true);
|
||||
|
||||
if (overrides_active)
|
||||
rarch_ctl(RARCH_CTL_SET_OVERRIDES_ACTIVE, NULL);
|
||||
@ -1685,6 +1702,62 @@ static bool command_event_resize_windowed_scale(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
void command_playlist_push_write(
|
||||
void *data,
|
||||
const char *path,
|
||||
const char *label,
|
||||
const char *core_path,
|
||||
const char *core_name)
|
||||
{
|
||||
playlist_t *playlist = (playlist_t*)data;
|
||||
|
||||
if (!playlist)
|
||||
return;
|
||||
|
||||
if (playlist_push(
|
||||
playlist,
|
||||
path,
|
||||
label,
|
||||
core_path,
|
||||
core_name,
|
||||
NULL,
|
||||
NULL
|
||||
))
|
||||
playlist_write_file(playlist);
|
||||
}
|
||||
|
||||
void command_playlist_update_write(
|
||||
void *data,
|
||||
size_t idx,
|
||||
const char *core_display_name,
|
||||
const char *label,
|
||||
const char *path)
|
||||
{
|
||||
playlist_t *plist = (playlist_t*)data;
|
||||
playlist_t *playlist = NULL;
|
||||
|
||||
if (plist)
|
||||
playlist = plist;
|
||||
#ifdef HAVE_MENU
|
||||
else
|
||||
menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist);
|
||||
#endif
|
||||
if (!playlist)
|
||||
return;
|
||||
|
||||
playlist_update(
|
||||
playlist,
|
||||
idx,
|
||||
label,
|
||||
NULL,
|
||||
path,
|
||||
core_display_name,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
playlist_write_file(playlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* command_event:
|
||||
* @cmd : Event command index.
|
||||
@ -1735,16 +1808,18 @@ bool command_event(enum event_command cmd, void *data)
|
||||
core_info_ctx_find_t info_find;
|
||||
rarch_system_info_t *system_info = runloop_get_system_info();
|
||||
struct retro_system_info *system = &system_info->info;
|
||||
const char *core_path = path_get(RARCH_PATH_CORE);
|
||||
|
||||
#if defined(HAVE_DYNAMIC)
|
||||
if (string_is_empty(path_get(RARCH_PATH_CORE)))
|
||||
if (string_is_empty(core_path))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
libretro_get_system_info(
|
||||
path_get(RARCH_PATH_CORE),
|
||||
core_path,
|
||||
system,
|
||||
&system_info->load_no_content);
|
||||
info_find.path = path_get(RARCH_PATH_CORE);
|
||||
info_find.path = core_path;
|
||||
|
||||
if (!core_info_load(&info_find))
|
||||
{
|
||||
@ -2237,18 +2312,32 @@ TODO: Add a setting for these tweaks */
|
||||
ui_companion_driver_toggle();
|
||||
break;
|
||||
case CMD_EVENT_ADD_TO_FAVORITES:
|
||||
playlist_push(
|
||||
{
|
||||
global_t *global = global_get_ptr();
|
||||
rarch_system_info_t *sys_info = runloop_get_system_info();
|
||||
const char *core_name = NULL;
|
||||
const char *core_path = NULL;
|
||||
const char *label = NULL;
|
||||
|
||||
if (sys_info)
|
||||
{
|
||||
core_name = sys_info->info.library_name;
|
||||
core_path = path_get(RARCH_PATH_CORE);
|
||||
}
|
||||
|
||||
if (!string_is_empty(global->name.label))
|
||||
label = global->name.label;
|
||||
|
||||
command_playlist_push_write(
|
||||
g_defaults.content_favorites,
|
||||
path_get(RARCH_PATH_CONTENT),
|
||||
NULL,
|
||||
file_path_str(FILE_PATH_DETECT),
|
||||
file_path_str(FILE_PATH_DETECT),
|
||||
NULL,
|
||||
NULL
|
||||
(const char*)data,
|
||||
label,
|
||||
core_path,
|
||||
core_name
|
||||
);
|
||||
playlist_write_file(g_defaults.content_favorites);
|
||||
runloop_msg_queue_push(msg_hash_to_str(MSG_ADDED_TO_FAVORITES), 1, 180, true);
|
||||
break;
|
||||
}
|
||||
case CMD_EVENT_RESTART_RETROARCH:
|
||||
if (!frontend_driver_set_fork(FRONTEND_FORK_RESTART))
|
||||
return false;
|
||||
|
14
command.h
14
command.h
@ -259,6 +259,20 @@ bool command_free(command_t *handle);
|
||||
**/
|
||||
bool command_event(enum event_command action, void *data);
|
||||
|
||||
void command_playlist_push_write(
|
||||
void *data,
|
||||
const char *path,
|
||||
const char *label,
|
||||
const char *core_path,
|
||||
const char *core_name);
|
||||
|
||||
void command_playlist_update_write(
|
||||
void *data,
|
||||
size_t idx,
|
||||
const char *core_display_name,
|
||||
const char *label,
|
||||
const char *path);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
@ -528,7 +528,7 @@ static const bool netplay_nat_traversal = false;
|
||||
|
||||
static const unsigned netplay_delay_frames = 16;
|
||||
|
||||
static const int netplay_check_frames = 30;
|
||||
static const int netplay_check_frames = 600;
|
||||
|
||||
static const bool netplay_use_mitm_server = false;
|
||||
|
||||
|
@ -1255,6 +1255,9 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
SETTING_BOOL("cheevos_test_unofficial", &settings->bools.cheevos_test_unofficial, true, false, false);
|
||||
SETTING_BOOL("cheevos_hardcore_mode_enable", &settings->bools.cheevos_hardcore_mode_enable, true, false, false);
|
||||
SETTING_BOOL("cheevos_leaderboards_enable", &settings->bools.cheevos_leaderboards_enable, true, false, false);
|
||||
#ifdef HAVE_XMB
|
||||
SETTING_BOOL("cheevos_badges_enable", &settings->bools.cheevos_badges_enable, true, false, false);
|
||||
#endif
|
||||
SETTING_BOOL("cheevos_verbose_enable", &settings->bools.cheevos_verbose_enable, true, false, false);
|
||||
#endif
|
||||
#ifdef HAVE_OVERLAY
|
||||
@ -1864,7 +1867,7 @@ static void config_set_defaults(void)
|
||||
temp_str[0] = '\0';
|
||||
|
||||
fill_pathname_expand_special(temp_str,
|
||||
g_defaults.path.config,
|
||||
g_defaults.path.config,
|
||||
PATH_MAX_LENGTH * sizeof(char));
|
||||
path_set(RARCH_PATH_CONFIG, temp_str);
|
||||
free(temp_str);
|
||||
@ -2262,6 +2265,8 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
#ifdef HAVE_NETWORKING
|
||||
char *override_netplay_ip_address = NULL;
|
||||
#endif
|
||||
const char *path_core = NULL;
|
||||
const char *path_config = NULL;
|
||||
int bool_settings_size = sizeof(settings->bools) / sizeof(settings->bools.placeholder);
|
||||
int float_settings_size = sizeof(settings->floats) / sizeof(settings->floats.placeholder);
|
||||
int int_settings_size = sizeof(settings->ints) / sizeof(settings->ints.placeholder);
|
||||
@ -2534,13 +2539,16 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
audio_set_float(AUDIO_ACTION_VOLUME_GAIN, settings->floats.audio_volume);
|
||||
audio_set_float(AUDIO_ACTION_MIXER_VOLUME_GAIN, settings->floats.audio_mixer_volume);
|
||||
|
||||
path_config = path_get(RARCH_PATH_CONFIG);
|
||||
path_core = path_get(RARCH_PATH_CORE);
|
||||
|
||||
if (string_is_empty(settings->paths.path_content_history))
|
||||
{
|
||||
if (string_is_empty(settings->paths.directory_content_history))
|
||||
{
|
||||
fill_pathname_resolve_relative(
|
||||
settings->paths.path_content_history,
|
||||
path_get(RARCH_PATH_CONFIG),
|
||||
path_config,
|
||||
file_path_str(FILE_PATH_CONTENT_HISTORY),
|
||||
sizeof(settings->paths.path_content_history));
|
||||
}
|
||||
@ -2559,7 +2567,7 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
{
|
||||
fill_pathname_resolve_relative(
|
||||
settings->paths.path_content_favorites,
|
||||
path_get(RARCH_PATH_CONFIG),
|
||||
path_config,
|
||||
file_path_str(FILE_PATH_CONTENT_FAVORITES),
|
||||
sizeof(settings->paths.path_content_favorites));
|
||||
}
|
||||
@ -2578,7 +2586,7 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
{
|
||||
fill_pathname_resolve_relative(
|
||||
settings->paths.path_content_music_history,
|
||||
path_get(RARCH_PATH_CONFIG),
|
||||
path_config,
|
||||
file_path_str(FILE_PATH_CONTENT_MUSIC_HISTORY),
|
||||
sizeof(settings->paths.path_content_music_history));
|
||||
}
|
||||
@ -2597,7 +2605,7 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
{
|
||||
fill_pathname_resolve_relative(
|
||||
settings->paths.path_content_video_history,
|
||||
path_get(RARCH_PATH_CONFIG),
|
||||
path_config,
|
||||
file_path_str(FILE_PATH_CONTENT_VIDEO_HISTORY),
|
||||
sizeof(settings->paths.path_content_video_history));
|
||||
}
|
||||
@ -2616,7 +2624,7 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
{
|
||||
fill_pathname_resolve_relative(
|
||||
settings->paths.path_content_image_history,
|
||||
path_get(RARCH_PATH_CONFIG),
|
||||
path_config,
|
||||
file_path_str(FILE_PATH_CONTENT_IMAGE_HISTORY),
|
||||
sizeof(settings->paths.path_content_image_history));
|
||||
}
|
||||
@ -2642,14 +2650,14 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
}
|
||||
|
||||
#ifdef RARCH_CONSOLE
|
||||
if (!string_is_empty(path_get(RARCH_PATH_CORE)))
|
||||
if (!string_is_empty(path_core))
|
||||
{
|
||||
#endif
|
||||
/* Safe-guard against older behavior. */
|
||||
if (path_is_directory(path_get(RARCH_PATH_CORE)))
|
||||
if (path_is_directory(path_core))
|
||||
{
|
||||
RARCH_WARN("\"libretro_path\" is a directory, using this for \"libretro_directory\" instead.\n");
|
||||
strlcpy(settings->paths.directory_libretro, path_get(RARCH_PATH_CORE),
|
||||
strlcpy(settings->paths.directory_libretro, path_core,
|
||||
sizeof(settings->paths.directory_libretro));
|
||||
path_clear(RARCH_PATH_CORE);
|
||||
}
|
||||
@ -2690,9 +2698,7 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
*settings->paths.directory_system = '\0';
|
||||
|
||||
if (settings->floats.slowmotion_ratio < 1.0f)
|
||||
{
|
||||
configuration_set_float(settings, settings->floats.slowmotion_ratio, 1.0f);
|
||||
}
|
||||
|
||||
/* Sanitize fastforward_ratio value - previously range was -1
|
||||
* and up (with 0 being skipped) */
|
||||
@ -3543,8 +3549,7 @@ bool config_save_autoconf_profile(const char *path, unsigned user)
|
||||
config_file_free(conf);
|
||||
free(buf);
|
||||
free(autoconf_file);
|
||||
if (path_new)
|
||||
free(path_new);
|
||||
free(path_new);
|
||||
return ret;
|
||||
|
||||
error:
|
||||
|
@ -184,6 +184,7 @@ typedef struct settings
|
||||
bool cheevos_test_unofficial;
|
||||
bool cheevos_hardcore_mode_enable;
|
||||
bool cheevos_leaderboards_enable;
|
||||
bool cheevos_badges_enable;
|
||||
bool cheevos_verbose_enable;
|
||||
|
||||
/* Camera */
|
||||
|
44
core_info.c
44
core_info.c
@ -389,6 +389,10 @@ static core_info_list_t *core_info_list_new(const char *path)
|
||||
&tmp_bool))
|
||||
core_info[i].supports_no_game = tmp_bool;
|
||||
|
||||
if (config_get_bool(conf, "database_match_archive_member",
|
||||
&tmp_bool))
|
||||
core_info[i].database_match_archive_member = tmp_bool;
|
||||
|
||||
core_info[i].config_data = conf;
|
||||
}
|
||||
else
|
||||
@ -823,6 +827,46 @@ size_t core_info_list_num_info_files(core_info_list_t *core_info_list)
|
||||
return num;
|
||||
}
|
||||
|
||||
bool core_info_database_match_archive_member(const char *database_path)
|
||||
{
|
||||
char *database = NULL;
|
||||
const char *new_path = path_basename(database_path);
|
||||
|
||||
if (string_is_empty(new_path))
|
||||
return false;
|
||||
|
||||
database = strdup(new_path);
|
||||
|
||||
if (string_is_empty(database))
|
||||
goto error;
|
||||
|
||||
path_remove_extension(database);
|
||||
|
||||
if (core_info_curr_list)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < core_info_curr_list->count; i++)
|
||||
{
|
||||
const core_info_t *info = &core_info_curr_list->list[i];
|
||||
|
||||
if (!info->database_match_archive_member)
|
||||
continue;
|
||||
|
||||
if (!string_list_find_elem(info->databases_list, database))
|
||||
continue;
|
||||
|
||||
free(database);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
if (database)
|
||||
free(database);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool core_info_database_supports_content_path(const char *database_path, const char *path)
|
||||
{
|
||||
char *database = NULL;
|
||||
|
@ -38,6 +38,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
bool supports_no_game;
|
||||
bool database_match_archive_member;
|
||||
size_t firmware_count;
|
||||
char *path;
|
||||
void *config_data;
|
||||
@ -120,6 +121,8 @@ bool core_info_load(core_info_ctx_find_t *info);
|
||||
|
||||
bool core_info_database_supports_content_path(const char *database_path, const char *path);
|
||||
|
||||
bool core_info_database_match_archive_member(const char *database_path);
|
||||
|
||||
bool core_info_unsupported_content_path(const char *path);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - 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.
|
||||
@ -28,6 +28,10 @@
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#include <kernel/image.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <boolean.h>
|
||||
#include <string.h>
|
||||
@ -119,7 +123,7 @@ void fill_pathname_abbreviate_special(char *out_path,
|
||||
* Keep application dir in front of home, moving app dir to a
|
||||
* new location inside home would break otherwise. */
|
||||
|
||||
/* ugly hack - use application_dir pointer
|
||||
/* ugly hack - use application_dir pointer
|
||||
* before filling it in. C89 reasons */
|
||||
candidates[0] = application_dir;
|
||||
candidates[1] = home;
|
||||
@ -129,23 +133,23 @@ void fill_pathname_abbreviate_special(char *out_path,
|
||||
notations [1] = "~";
|
||||
notations [2] = NULL;
|
||||
|
||||
fill_pathname_application_path(application_dir,
|
||||
fill_pathname_application_path(application_dir,
|
||||
PATH_MAX_LENGTH * sizeof(char));
|
||||
path_basedir_wrapper(application_dir);
|
||||
|
||||
|
||||
for (i = 0; candidates[i]; i++)
|
||||
{
|
||||
if (!string_is_empty(candidates[i]) &&
|
||||
if (!string_is_empty(candidates[i]) &&
|
||||
strstr(in_path, candidates[i]) == in_path)
|
||||
{
|
||||
size_t src_size = strlcpy(out_path, notations[i], size);
|
||||
|
||||
retro_assert(src_size < size);
|
||||
|
||||
|
||||
out_path += src_size;
|
||||
size -= src_size;
|
||||
in_path += strlen(candidates[i]);
|
||||
|
||||
|
||||
if (!path_char_is_slash(*in_path))
|
||||
{
|
||||
retro_assert(strlcpy(out_path,
|
||||
@ -242,7 +246,7 @@ void fill_pathname_application_path(char *s, size_t len)
|
||||
CFStringGetCString(bundle_path, s, len, kCFStringEncodingUTF8);
|
||||
CFRelease(bundle_path);
|
||||
CFRelease(bundle_url);
|
||||
|
||||
|
||||
retro_assert(strlcat(s, "nobin", len) < len);
|
||||
return;
|
||||
}
|
||||
@ -269,7 +273,7 @@ void fill_pathname_application_path(char *s, size_t len)
|
||||
char link_path[255];
|
||||
|
||||
link_path[0] = *s = '\0';
|
||||
pid = getpid();
|
||||
pid = getpid();
|
||||
|
||||
/* Linux, BSD and Solaris paths. Not standardized. */
|
||||
for (i = 0; i < ARRAY_SIZE(exts); i++)
|
||||
@ -287,7 +291,7 @@ void fill_pathname_application_path(char *s, size_t len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RARCH_ERR("Cannot resolve application path! This should not happen.\n");
|
||||
#endif
|
||||
}
|
||||
@ -335,7 +339,7 @@ void fill_pathname_application_special(char *s,
|
||||
char *s1 = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
s1[0] = '\0';
|
||||
|
||||
fill_pathname_application_special(s1,
|
||||
fill_pathname_application_special(s1,
|
||||
PATH_MAX_LENGTH * sizeof(char),
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH);
|
||||
fill_pathname_join(s,
|
||||
@ -349,7 +353,7 @@ void fill_pathname_application_special(char *s,
|
||||
#ifdef HAVE_ZARCH
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
fill_pathname_join(s,
|
||||
fill_pathname_join(s,
|
||||
settings->paths.directory_assets,
|
||||
"zarch",
|
||||
len);
|
||||
@ -501,6 +505,31 @@ void fill_pathname_application_special(char *s,
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES:
|
||||
{
|
||||
char *s1 = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
char *s2 = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
s1[0] = s2[0] = '\0';
|
||||
|
||||
fill_pathname_join(s1,
|
||||
settings->paths.directory_thumbnails,
|
||||
"cheevos",
|
||||
len);
|
||||
fill_pathname_join(s2,
|
||||
s1, "badges",
|
||||
PATH_MAX_LENGTH * sizeof(char)
|
||||
);
|
||||
fill_pathname_slash(s2,
|
||||
PATH_MAX_LENGTH * sizeof(char)
|
||||
);
|
||||
strlcpy(s, s2, len);
|
||||
free(s1);
|
||||
free(s2);
|
||||
}
|
||||
break;
|
||||
|
||||
case APPLICATION_SPECIAL_NONE:
|
||||
default:
|
||||
break;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2016 - 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.
|
||||
@ -104,7 +104,8 @@ enum application_special_type
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_FONT,
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH,
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_FONT,
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_ICONS
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_ICONS,
|
||||
APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -48,6 +48,7 @@
|
||||
|
||||
#include <boolean.h>
|
||||
#include <compat/apple_compat.h>
|
||||
#include <retro_assert.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <file/file_path.h>
|
||||
#include <rhash.h>
|
||||
@ -335,6 +336,15 @@ static void frontend_darwin_get_environment_settings(int *argc, char *argv[],
|
||||
CFSearchPathForDirectoriesInDomains(CFDocumentDirectory,
|
||||
CFUserDomainMask, 1, home_dir_buf, sizeof(home_dir_buf));
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
char resolved_home_dir_buf[PATH_MAX_LENGTH] = {0};
|
||||
if (realpath(home_dir_buf, resolved_home_dir_buf)) {
|
||||
retro_assert(strlcpy(home_dir_buf,
|
||||
resolved_home_dir_buf,
|
||||
sizeof(home_dir_buf)) < sizeof(home_dir_buf));
|
||||
}
|
||||
#endif
|
||||
|
||||
strlcat(home_dir_buf, "/RetroArch", sizeof(home_dir_buf));
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SHADER],
|
||||
home_dir_buf, "shaders_glsl",
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -155,9 +157,27 @@ static void x11_set_window_class(Display *dpy, Window win)
|
||||
XSetClassHint(dpy, win, &hint);
|
||||
}
|
||||
|
||||
static void x11_set_window_pid(Display *dpy, Window win)
|
||||
{
|
||||
pid_t pid = getpid();
|
||||
char hostname[HOST_NAME_MAX + 1];
|
||||
|
||||
XChangeProperty(dpy, win, XInternAtom(dpy, "_NET_WM_PID", False),
|
||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&pid, 1);
|
||||
|
||||
if(gethostname(hostname, HOST_NAME_MAX + 1) == -1)
|
||||
RARCH_WARN("Failed to get hostname.\n");
|
||||
else
|
||||
{
|
||||
XChangeProperty(dpy, win, XA_WM_CLIENT_MACHINE, XA_STRING, 8,
|
||||
PropModeReplace, (unsigned char *)hostname, strlen(hostname));
|
||||
}
|
||||
}
|
||||
|
||||
void x11_set_window_attr(Display *dpy, Window win)
|
||||
{
|
||||
x11_set_window_class(dpy, win);
|
||||
x11_set_window_pid(dpy, win);
|
||||
}
|
||||
|
||||
static void xdg_screensaver_inhibit(Window wnd)
|
||||
|
@ -222,7 +222,7 @@ static void gl_render_overlay(gl_t *gl, video_frame_info_t *video_info)
|
||||
|
||||
video_driver_set_coords(&coords);
|
||||
|
||||
video_info->cb_shader_set_mvp(gl,
|
||||
video_info->cb_set_mvp(gl,
|
||||
video_info->shader_data, &gl->mvp_no_rot);
|
||||
|
||||
for (i = 0; i < gl->overlays; i++)
|
||||
@ -377,18 +377,10 @@ static bool gl_shader_init(gl_t *gl, const gfx_ctx_driver_t *ctx_driver,
|
||||
)
|
||||
{
|
||||
video_shader_ctx_init_t init_data;
|
||||
enum rarch_shader_type type;
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *shader_path = (settings->bools.video_shader_enable
|
||||
&& *settings->paths.path_shader) ? settings->paths.path_shader : NULL;
|
||||
|
||||
if (!gl)
|
||||
{
|
||||
RARCH_ERR("[GL]: Invalid GL instance passed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
type = video_shader_parse_type(shader_path,
|
||||
enum rarch_shader_type type = video_shader_parse_type(shader_path,
|
||||
gl->core_context_in_use
|
||||
? RARCH_SHADER_GLSL : DEFAULT_SHADER_TYPE);
|
||||
|
||||
@ -621,6 +613,7 @@ static INLINE void gl_set_shader_viewports(gl_t *gl)
|
||||
shader_info.set_active = true;
|
||||
|
||||
video_shader_driver_use(shader_info);
|
||||
|
||||
gl_set_viewport_wrapper(gl, width, height, false, true);
|
||||
|
||||
shader_info.data = gl;
|
||||
@ -821,7 +814,7 @@ static void gl_render_osd_background(
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
video_info->cb_shader_set_mvp(gl,
|
||||
video_info->cb_set_mvp(gl,
|
||||
video_info->shader_data, &gl->mvp_no_rot);
|
||||
|
||||
uniform_param.type = UNIFORM_4F;
|
||||
@ -931,25 +924,23 @@ static INLINE void gl_draw_texture(gl_t *gl, video_frame_info_t *video_info)
|
||||
color[14] = 1.0f;
|
||||
color[15] = gl->menu_texture_alpha;
|
||||
|
||||
if (!gl->menu_texture)
|
||||
return;
|
||||
|
||||
gl->coords.vertex = vertexes_flipped;
|
||||
gl->coords.tex_coord = tex_coords;
|
||||
gl->coords.color = color;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl->menu_texture);
|
||||
|
||||
video_info->cb_shader_use(gl,
|
||||
video_info->shader_data, VIDEO_SHADER_STOCK_BLEND, true);
|
||||
|
||||
gl->coords.vertices = 4;
|
||||
gl->coords.vertices = 4;
|
||||
|
||||
coords.handle_data = NULL;
|
||||
coords.data = &gl->coords;
|
||||
coords.handle_data = NULL;
|
||||
coords.data = &gl->coords;
|
||||
|
||||
video_driver_set_coords(&coords);
|
||||
|
||||
video_info->cb_shader_set_mvp(gl,
|
||||
video_info->cb_set_mvp(gl,
|
||||
video_info->shader_data, &gl->mvp_no_rot);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
@ -965,9 +956,9 @@ static INLINE void gl_draw_texture(gl_t *gl, video_frame_info_t *video_info)
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
gl->coords.vertex = gl->vertex_ptr;
|
||||
gl->coords.tex_coord = gl->tex_info.coord;
|
||||
gl->coords.color = gl->white_color_ptr;
|
||||
gl->coords.vertex = gl->vertex_ptr;
|
||||
gl->coords.tex_coord = gl->tex_info.coord;
|
||||
gl->coords.color = gl->white_color_ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1131,7 +1122,7 @@ static bool gl_frame(void *data, const void *frame,
|
||||
|
||||
video_driver_set_coords(&coords);
|
||||
|
||||
video_info->cb_shader_set_mvp(gl, video_info->shader_data, &gl->mvp);
|
||||
video_info->cb_set_mvp(gl, video_info->shader_data, &gl->mvp);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
@ -1148,7 +1139,7 @@ static bool gl_frame(void *data, const void *frame,
|
||||
{
|
||||
menu_driver_frame(video_info);
|
||||
|
||||
if (gl->menu_texture_enable)
|
||||
if (gl->menu_texture)
|
||||
gl_draw_texture(gl, video_info);
|
||||
}
|
||||
#endif
|
||||
@ -1340,7 +1331,7 @@ static void gl_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static bool resolve_extensions(gl_t *gl, const char *context_ident)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
/* have_es2_compat - GL_RGB565 internal format support.
|
||||
* Even though ES2 support is claimed, the format
|
||||
@ -1510,20 +1501,20 @@ static const gfx_ctx_driver_t *gl_get_context(gl_t *gl)
|
||||
unsigned minor = hwr->version_minor;
|
||||
|
||||
#ifdef HAVE_OPENGLES
|
||||
api = GFX_CTX_OPENGL_ES_API;
|
||||
api_name = "OpenGL ES 2.0";
|
||||
api = GFX_CTX_OPENGL_ES_API;
|
||||
api_name = "OpenGL ES 2.0";
|
||||
|
||||
if (hwr->context_type == RETRO_HW_CONTEXT_OPENGLES3)
|
||||
{
|
||||
major = 3;
|
||||
minor = 0;
|
||||
api_name = "OpenGL ES 3.0";
|
||||
major = 3;
|
||||
minor = 0;
|
||||
api_name = "OpenGL ES 3.0";
|
||||
}
|
||||
else if (hwr->context_type == RETRO_HW_CONTEXT_OPENGLES_VERSION)
|
||||
api_name = "OpenGL ES 3.1+";
|
||||
api_name = "OpenGL ES 3.1+";
|
||||
#else
|
||||
api = GFX_CTX_OPENGL_API;
|
||||
api_name = "OpenGL";
|
||||
api = GFX_CTX_OPENGL_API;
|
||||
api_name = "OpenGL";
|
||||
#endif
|
||||
|
||||
(void)api_name;
|
||||
|
@ -113,6 +113,53 @@ static enum gfx_ctx_api x_api = GFX_CTX_NONE;
|
||||
|
||||
static gfx_ctx_x_data_t *current_context_data = NULL;
|
||||
|
||||
const unsigned long retroarch_icon_data[] = {
|
||||
16, 16,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, 0xffffffff, 0x00000000,
|
||||
0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x000000ff, 0xffffffff,
|
||||
0xffffffff, 0x000000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff,
|
||||
0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, 0x00000000, 0x00000000,
|
||||
0x00000000, 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
|
||||
0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0xffffffff,
|
||||
0x000000ff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff,
|
||||
0x000000ff, 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff,
|
||||
0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, 0x000000ff, 0xffffffff,
|
||||
0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x000000ff, 0x000000ff,
|
||||
0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
|
||||
0x000000ff, 0x000000ff, 0x000000ff, 0xffffffff, 0x00000000, 0x00000000,
|
||||
0x00000000, 0xffffffff, 0xffffffff, 0x000000ff, 0x000000ff, 0x000000ff,
|
||||
0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
|
||||
0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, 0xffffffff, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x000000ff,
|
||||
0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff,
|
||||
0xffffffff, 0x000000ff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
};
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
static PFNGLXCREATECONTEXTATTRIBSARBPROC glx_create_context_attribs;
|
||||
|
||||
@ -574,6 +621,8 @@ static bool gfx_ctx_x_set_video_mode(void *data,
|
||||
XSetWindowAttributes swa = {0};
|
||||
int (*old_handler)(Display*, XErrorEvent*) = NULL;
|
||||
gfx_ctx_x_data_t *x = (gfx_ctx_x_data_t*)data;
|
||||
Atom net_wm_icon = XInternAtom(g_x11_dpy, "_NET_WM_ICON", False);
|
||||
Atom cardinal = XInternAtom(g_x11_dpy, "CARDINAL", False);
|
||||
|
||||
frontend_driver_install_signal_handler();
|
||||
|
||||
@ -661,6 +710,8 @@ static bool gfx_ctx_x_set_video_mode(void *data,
|
||||
(true_full ? CWOverrideRedirect : 0), &swa);
|
||||
XSetWindowBackground(g_x11_dpy, g_x11_win, 0);
|
||||
|
||||
XChangeProperty(g_x11_dpy, g_x11_win, net_wm_icon, cardinal, 32, PropModeReplace, (const unsigned char*)retroarch_icon_data, sizeof(retroarch_icon_data) / sizeof(*retroarch_icon_data));
|
||||
|
||||
switch (x_api)
|
||||
{
|
||||
case GFX_CTX_OPENGL_API:
|
||||
@ -1137,4 +1188,3 @@ const gfx_ctx_driver_t gfx_ctx_x = {
|
||||
#endif
|
||||
gfx_ctx_x_make_current
|
||||
};
|
||||
|
||||
|
@ -260,7 +260,7 @@ static void gl_raster_font_draw_vertices(gl_raster_t *font, const video_coords_t
|
||||
|
||||
video_driver_set_coords(&coords_data);
|
||||
|
||||
video_info->cb_shader_set_mvp(font->gl,
|
||||
video_info->cb_set_mvp(font->gl,
|
||||
video_info->shader_data, &font->gl->mvp_no_rot);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, coords->vertices);
|
||||
|
@ -333,7 +333,7 @@ static void gl2_renderchain_render(
|
||||
|
||||
video_driver_set_coords(&coords);
|
||||
|
||||
video_info->cb_shader_set_mvp(gl,
|
||||
video_info->cb_set_mvp(gl,
|
||||
video_info->shader_data, &gl->mvp);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
@ -408,7 +408,7 @@ static void gl2_renderchain_render(
|
||||
|
||||
video_driver_set_coords(&coords);
|
||||
|
||||
video_info->cb_shader_set_mvp(gl,
|
||||
video_info->cb_set_mvp(gl,
|
||||
video_info->shader_data, &gl->mvp);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
@ -497,10 +497,12 @@ const char* config_get_video_driver_options(void)
|
||||
return char_list_new_special(STRING_LIST_VIDEO_DRIVERS, NULL);
|
||||
}
|
||||
|
||||
#ifdef HAVE_VULKAN
|
||||
static bool hw_render_context_is_vulkan(enum retro_hw_context_type type)
|
||||
{
|
||||
return type == RETRO_HW_CONTEXT_VULKAN;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool hw_render_context_is_gl(enum retro_hw_context_type type)
|
||||
{
|
||||
@ -2407,8 +2409,9 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
|
||||
video_driver_frame_count++;
|
||||
|
||||
// Display the FPS, with a higher priority.
|
||||
if (video_info.fps_show)
|
||||
runloop_msg_queue_push(video_info.fps_text, 1, 1, false);
|
||||
runloop_msg_queue_push(video_info.fps_text, 2, 1, true);
|
||||
}
|
||||
|
||||
void video_driver_display_type_set(enum rarch_display_type type)
|
||||
@ -2590,7 +2593,7 @@ void video_driver_build_info(video_frame_info_t *video_info)
|
||||
video_info->cb_set_resize = current_video_context.set_resize;
|
||||
|
||||
video_info->cb_shader_use = video_driver_cb_shader_use;
|
||||
video_info->cb_shader_set_mvp = video_driver_cb_shader_set_mvp;
|
||||
video_info->cb_set_mvp = video_driver_cb_shader_set_mvp;
|
||||
|
||||
#if 0
|
||||
video_info->cb_set_coords = video_driver_cb_set_coords;
|
||||
|
@ -470,7 +470,7 @@ typedef struct video_frame_info
|
||||
bool (*cb_set_coords)(void *handle_data,
|
||||
void *shader_data, const struct video_coords *coords);
|
||||
#endif
|
||||
bool (*cb_shader_set_mvp)(void *data, void *shader_data,
|
||||
bool (*cb_set_mvp)(void *data, void *shader_data,
|
||||
const void *mat_data);
|
||||
|
||||
void *context_data;
|
||||
|
@ -151,6 +151,7 @@ ACHIEVEMENTS
|
||||
#include "../libretro-common/formats/json/jsonsax.c"
|
||||
#include "../network/net_http_special.c"
|
||||
#include "../cheevos/cheevos.c"
|
||||
#include "../cheevos/badges.c"
|
||||
#include "../cheevos/var.c"
|
||||
#include "../cheevos/cond.c"
|
||||
#endif
|
||||
@ -821,6 +822,10 @@ FILE
|
||||
#include "../list_special.c"
|
||||
#include "../libretro-common/string/stdstring.c"
|
||||
#include "../libretro-common/file/nbio/nbio_stdio.c"
|
||||
#include "../libretro-common/file/nbio/nbio_linux.c"
|
||||
#include "../libretro-common/file/nbio/nbio_unixmmap.c"
|
||||
#include "../libretro-common/file/nbio/nbio_windowsmmap.c"
|
||||
#include "../libretro-common/file/nbio/nbio_intf.c"
|
||||
|
||||
/*============================================================
|
||||
MESSAGE
|
||||
|
@ -85,7 +85,7 @@ struct dinput_input
|
||||
int mouse_rel_y;
|
||||
int mouse_x;
|
||||
int mouse_y;
|
||||
bool mouse_l, mouse_r, mouse_m, mouse_wu, mouse_wd, mouse_hwu, mouse_hwd;
|
||||
bool mouse_l, mouse_r, mouse_m, mouse_b4, mouse_b5, mouse_wu, mouse_wd, mouse_hwu, mouse_hwd;
|
||||
struct pointer_status pointer_head; /* dummy head for easier iteration */
|
||||
};
|
||||
|
||||
@ -246,6 +246,8 @@ static void dinput_poll(void *data)
|
||||
di->mouse_l = mouse_state.rgbButtons[0];
|
||||
di->mouse_r = mouse_state.rgbButtons[1];
|
||||
di->mouse_m = mouse_state.rgbButtons[2];
|
||||
di->mouse_b4 = mouse_state.rgbButtons[3];
|
||||
di->mouse_b5 = mouse_state.rgbButtons[4];
|
||||
|
||||
/* No simple way to get absolute coordinates
|
||||
* for RETRO_DEVICE_POINTER. Just use Win32 APIs. */
|
||||
@ -368,6 +370,10 @@ static int16_t dinput_mouse_state(struct dinput_input *di, unsigned id)
|
||||
return state;
|
||||
case RETRO_DEVICE_ID_MOUSE_MIDDLE:
|
||||
return di->mouse_m;
|
||||
case RETRO_DEVICE_ID_MOUSE_BUTTON_4:
|
||||
return di->mouse_b4;
|
||||
case RETRO_DEVICE_ID_MOUSE_BUTTON_5:
|
||||
return di->mouse_b5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -38,7 +38,7 @@ typedef struct sdl_input
|
||||
|
||||
int mouse_x, mouse_y;
|
||||
int mouse_abs_x, mouse_abs_y;
|
||||
int mouse_l, mouse_r, mouse_m, mouse_wu, mouse_wd, mouse_wl, mouse_wr;
|
||||
int mouse_l, mouse_r, mouse_m, mouse_b4, mouse_b5, mouse_wu, mouse_wd, mouse_wl, mouse_wr;
|
||||
} sdl_input_t;
|
||||
|
||||
static void *sdl_input_init(const char *joypad_driver)
|
||||
@ -131,6 +131,10 @@ static int16_t sdl_mouse_device_state(sdl_input_t *sdl, unsigned id)
|
||||
return sdl->mouse_y;
|
||||
case RETRO_DEVICE_ID_MOUSE_MIDDLE:
|
||||
return sdl->mouse_m;
|
||||
case RETRO_DEVICE_ID_MOUSE_BUTTON_4:
|
||||
return sdl->mouse_b4;
|
||||
case RETRO_DEVICE_ID_MOUSE_BUTTON_5:
|
||||
return sdl->mouse_b5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -310,6 +314,8 @@ static void sdl_poll_mouse(sdl_input_t *sdl)
|
||||
sdl->mouse_l = (SDL_BUTTON(SDL_BUTTON_LEFT) & btn) ? 1 : 0;
|
||||
sdl->mouse_r = (SDL_BUTTON(SDL_BUTTON_RIGHT) & btn) ? 1 : 0;
|
||||
sdl->mouse_m = (SDL_BUTTON(SDL_BUTTON_MIDDLE) & btn) ? 1 : 0;
|
||||
sdl->mouse_b4 = (SDL_BUTTON(SDL_BUTTON_X1) & btn) ? 1 : 0;
|
||||
sdl->mouse_b5 = (SDL_BUTTON(SDL_BUTTON_X2) & btn) ? 1 : 0;
|
||||
#ifndef HAVE_SDL2
|
||||
sdl->mouse_wu = (SDL_BUTTON(SDL_BUTTON_WHEELUP) & btn) ? 1 : 0;
|
||||
sdl->mouse_wd = (SDL_BUTTON(SDL_BUTTON_WHEELDOWN) & btn) ? 1 : 0;
|
||||
|
@ -32,7 +32,7 @@ typedef struct
|
||||
HANDLE hnd;
|
||||
LONG x, y, dlt_x, dlt_y;
|
||||
LONG whl_u, whl_d;
|
||||
bool btn_l, btn_m, btn_r;
|
||||
bool btn_l, btn_m, btn_r, btn_b4, btn_b5;
|
||||
} winraw_mouse_t;
|
||||
|
||||
typedef struct
|
||||
@ -279,6 +279,10 @@ static int16_t winraw_mouse_state(winraw_input_t *wr,
|
||||
return mouse->whl_d ? 1 : 0;
|
||||
case RETRO_DEVICE_ID_MOUSE_MIDDLE:
|
||||
return mouse->btn_m ? 1 : 0;
|
||||
case RETRO_DEVICE_ID_MOUSE_BUTTON_4:
|
||||
return mouse->btn_b4 ? 1 : 0;
|
||||
case RETRO_DEVICE_ID_MOUSE_BUTTON_5:
|
||||
return mouse->btn_b5 ? 1 : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -419,6 +423,16 @@ static void winraw_update_mouse_state(winraw_mouse_t *mouse, RAWMOUSE *state)
|
||||
else if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
|
||||
mouse->btn_r = false;
|
||||
|
||||
if (state->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN)
|
||||
mouse->btn_b4 = true;
|
||||
else if (state->usButtonFlags & RI_MOUSE_BUTTON_4_UP)
|
||||
mouse->btn_b4 = false;
|
||||
|
||||
if (state->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN)
|
||||
mouse->btn_b5 = true;
|
||||
else if (state->usButtonFlags & RI_MOUSE_BUTTON_5_UP)
|
||||
mouse->btn_b5 = false;
|
||||
|
||||
if (state->usButtonFlags & RI_MOUSE_WHEEL)
|
||||
{
|
||||
if ((SHORT)state->usButtonData > 0)
|
||||
@ -566,6 +580,8 @@ static void winraw_poll(void *d)
|
||||
wr->mice[i].btn_l = g_mice[i].btn_l;
|
||||
wr->mice[i].btn_m = g_mice[i].btn_m;
|
||||
wr->mice[i].btn_r = g_mice[i].btn_r;
|
||||
wr->mice[i].btn_b4 = g_mice[i].btn_b4;
|
||||
wr->mice[i].btn_b5 = g_mice[i].btn_b5;
|
||||
}
|
||||
|
||||
if (wr->joypad)
|
||||
|
@ -212,33 +212,33 @@ static void wiiu_joypad_poll(void)
|
||||
if (vpad.tpNormal.touched && vpad.tpNormal.validity == VPAD_VALID) {
|
||||
struct video_viewport vp = {0};
|
||||
video_driver_get_viewport_info(&vp);
|
||||
VPADTouchData cal = {0};
|
||||
VPADTouchData cal720p = {0};
|
||||
/* Calibrates data to a 720p screen, seems to clamp outer 12px */
|
||||
VPADGetTPCalibratedPoint(0, &cal, &(vpad.tpNormal));
|
||||
VPADGetTPCalibratedPoint(0, &cal720p, &(vpad.tpNormal));
|
||||
/* Recalibrate to match video driver's coordinate system */
|
||||
VPADTouchData calNative = {0};
|
||||
calNative.x = scaleTP(12, 1268, 0, vp.full_width, cal720p.x);
|
||||
calNative.y = scaleTP(12, 708, 0, vp.full_height, cal720p.y);
|
||||
/* Clamp to actual game image */
|
||||
VPADTouchData calClamped = calNative;
|
||||
bool touchClamped = false;
|
||||
if (cal.x < vp.x) {
|
||||
cal.x = vp.x;
|
||||
if (calClamped.x < vp.x) {
|
||||
calClamped.x = vp.x;
|
||||
touchClamped = true;
|
||||
} else if (cal.x > vp.x + vp.width) {
|
||||
cal.x = vp.x + vp.width;
|
||||
} else if (calClamped.x > vp.x + vp.width) {
|
||||
calClamped.x = vp.x + vp.width;
|
||||
touchClamped = true;
|
||||
}
|
||||
if (cal.y < vp.y) {
|
||||
cal.y = vp.y;
|
||||
if (calClamped.y < vp.y) {
|
||||
calClamped.y = vp.y;
|
||||
touchClamped = true;
|
||||
} else if (cal.y > vp.y + vp.height) {
|
||||
cal.y = vp.y + vp.height;
|
||||
} else if (calClamped.y > vp.y + vp.height) {
|
||||
calClamped.y = vp.y + vp.height;
|
||||
touchClamped = true;
|
||||
}
|
||||
/* Account for 12px clamp on VPADGetTPCalibratedPoint */
|
||||
if (vp.x < 12) vp.x = 12;
|
||||
if (vp.y < 12) vp.y = 12;
|
||||
if (vp.x + vp.width > 1268) vp.width = 1268 - vp.x;
|
||||
if (vp.y + vp.height > 708) vp.height = 708 - vp.y;
|
||||
/* Calibrate to libretro spec and save as axis 2 (idx 4,5) */
|
||||
analog_state[0][2][0] = scaleTP(vp.x, vp.x + vp.width, -0x7fff, 0x7fff, cal.x);
|
||||
analog_state[0][2][1] = scaleTP(vp.y, vp.y + vp.height, -0x7fff, 0x7fff, cal.y);
|
||||
analog_state[0][2][0] = scaleTP(vp.x, vp.x + vp.width, -0x7fff, 0x7fff, calClamped.x);
|
||||
analog_state[0][2][1] = scaleTP(vp.y, vp.y + vp.height, -0x7fff, 0x7fff, calClamped.y);
|
||||
|
||||
/* Emulating a button (#19) for touch; lets people assign it to menu
|
||||
for that traditional RetroArch Wii U feel */
|
||||
|
@ -669,7 +669,8 @@ int16_t input_state(unsigned port, unsigned device,
|
||||
|
||||
#ifdef HAVE_KEYMAPPER
|
||||
if (input_driver_mapper)
|
||||
input_mapper_state(&res, port, device, idx, id);
|
||||
input_mapper_state(input_driver_mapper,
|
||||
&res, port, device, idx, id);
|
||||
#endif
|
||||
|
||||
/* Don't allow turbo for D-pad. */
|
||||
@ -778,17 +779,12 @@ void state_tracker_update_input(uint16_t *input1, uint16_t *input2)
|
||||
* Grab an input sample for this frame. We exclude
|
||||
* keyboard input here.
|
||||
*
|
||||
* TODO: In case RARCH_BIND_LIST_END starts exceeding 64,
|
||||
* and you need a bitmask of more than 64 entries, reimplement
|
||||
* it to use something like rarch_bits_t.
|
||||
*
|
||||
* Returns: Input sample containing a mask of all pressed keys.
|
||||
*/
|
||||
uint64_t input_menu_keys_pressed(void *data, uint64_t last_input)
|
||||
void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state)
|
||||
{
|
||||
unsigned i, port;
|
||||
rarch_joypad_info_t joypad_info;
|
||||
uint64_t ret = 0;
|
||||
const struct retro_keybind *binds[MAX_USERS] = {NULL};
|
||||
settings_t *settings = (settings_t*)data;
|
||||
const struct retro_keybind *binds_norm = NULL;
|
||||
@ -798,6 +794,8 @@ uint64_t input_menu_keys_pressed(void *data, uint64_t last_input)
|
||||
settings->bools.input_all_users_control_menu
|
||||
? max_users : 1;
|
||||
|
||||
RARCH_INPUT_STATE_CLEAR_PTR( p_new_state );
|
||||
|
||||
input_driver_block_libretro_input = false;
|
||||
input_driver_block_hotkey = false;
|
||||
|
||||
@ -898,7 +896,7 @@ uint64_t input_menu_keys_pressed(void *data, uint64_t last_input)
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
BIT64_SET(ret, i);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -908,7 +906,7 @@ uint64_t input_menu_keys_pressed(void *data, uint64_t last_input)
|
||||
{
|
||||
if (current_input->meta_key_pressed(current_input_data, i))
|
||||
{
|
||||
BIT64_SET(ret, i);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -916,7 +914,7 @@ uint64_t input_menu_keys_pressed(void *data, uint64_t last_input)
|
||||
#ifdef HAVE_OVERLAY
|
||||
if (overlay_ptr && input_overlay_key_pressed(overlay_ptr, i))
|
||||
{
|
||||
BIT64_SET(ret, i);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@ -931,7 +929,7 @@ uint64_t input_menu_keys_pressed(void *data, uint64_t last_input)
|
||||
|
||||
if (command_get(&handle))
|
||||
{
|
||||
BIT64_SET(ret, i);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -940,7 +938,7 @@ uint64_t input_menu_keys_pressed(void *data, uint64_t last_input)
|
||||
#ifdef HAVE_NETWORKGAMEPAD
|
||||
if (input_driver_remote && input_remote_key_pressed(i, 0))
|
||||
{
|
||||
BIT64_SET(ret, i);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@ -995,11 +993,9 @@ uint64_t input_menu_keys_pressed(void *data, uint64_t last_input)
|
||||
{
|
||||
if (current_input->input_state(current_input_data, joypad_info, binds, 0,
|
||||
RETRO_DEVICE_KEYBOARD, 0, ids[i][0]))
|
||||
BIT64_SET(ret, ids[i][1]);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, ids[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1008,17 +1004,12 @@ uint64_t input_menu_keys_pressed(void *data, uint64_t last_input)
|
||||
*
|
||||
* Grab an input sample for this frame.
|
||||
*
|
||||
* TODO: In case RARCH_BIND_LIST_END starts exceeding 64,
|
||||
* and you need a bitmask of more than 64 entries, reimplement
|
||||
* it to use something like rarch_bits_t.
|
||||
*
|
||||
* Returns: Input sample containing a mask of all pressed keys.
|
||||
*/
|
||||
uint64_t input_keys_pressed(void *data, uint64_t last_input)
|
||||
void input_keys_pressed(void *data, retro_bits_t* p_new_state)
|
||||
{
|
||||
unsigned i;
|
||||
rarch_joypad_info_t joypad_info;
|
||||
uint64_t ret = 0;
|
||||
settings_t *settings = (settings_t*)data;
|
||||
const struct retro_keybind *binds = input_config_binds[0];
|
||||
const struct retro_keybind *binds_auto = &input_autoconf_binds[0][RARCH_ENABLE_HOTKEY];
|
||||
@ -1029,6 +1020,8 @@ uint64_t input_keys_pressed(void *data, uint64_t last_input)
|
||||
const struct retro_keybind *enable_hotkey = &input_config_binds[0][RARCH_ENABLE_HOTKEY];
|
||||
bool game_focus_toggle_valid = false;
|
||||
|
||||
RARCH_INPUT_STATE_CLEAR_PTR( p_new_state );
|
||||
|
||||
joypad_info.joy_idx = settings->uints.input_joypad_map[0];
|
||||
joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx];
|
||||
joypad_info.axis_threshold = input_driver_axis_threshold;
|
||||
@ -1073,7 +1066,7 @@ uint64_t input_keys_pressed(void *data, uint64_t last_input)
|
||||
0, RETRO_DEVICE_JOYPAD, 0, i)
|
||||
)
|
||||
{
|
||||
BIT64_SET(ret, i);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1081,7 +1074,7 @@ uint64_t input_keys_pressed(void *data, uint64_t last_input)
|
||||
current_input->meta_key_pressed(current_input_data, i)
|
||||
)
|
||||
{
|
||||
BIT64_SET(ret, i);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1089,7 +1082,7 @@ uint64_t input_keys_pressed(void *data, uint64_t last_input)
|
||||
if (overlay_ptr &&
|
||||
input_overlay_key_pressed(overlay_ptr, i))
|
||||
{
|
||||
BIT64_SET(ret, i);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@ -1104,7 +1097,7 @@ uint64_t input_keys_pressed(void *data, uint64_t last_input)
|
||||
|
||||
if (command_get(&handle))
|
||||
{
|
||||
BIT64_SET(ret, i);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -1114,13 +1107,11 @@ uint64_t input_keys_pressed(void *data, uint64_t last_input)
|
||||
if (input_driver_remote &&
|
||||
input_remote_key_pressed(i, 0))
|
||||
{
|
||||
BIT64_SET(ret, i);
|
||||
RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -1609,53 +1600,99 @@ int16_t input_joypad_analog(const input_device_driver_t *drv,
|
||||
unsigned port, unsigned idx, unsigned ident,
|
||||
const struct retro_keybind *binds)
|
||||
{
|
||||
uint32_t axis_minus, axis_plus;
|
||||
int16_t pressed_minus, pressed_plus, res;
|
||||
unsigned ident_minus = 0;
|
||||
unsigned ident_plus = 0;
|
||||
const struct retro_keybind *bind_minus = NULL;
|
||||
const struct retro_keybind *bind_plus = NULL;
|
||||
int16_t res;
|
||||
|
||||
input_conv_analog_id_to_bind_id(idx, ident, &ident_minus, &ident_plus);
|
||||
if ( idx == RETRO_DEVICE_INDEX_ANALOG_BUTTON )
|
||||
{
|
||||
/* A RETRO_DEVICE_JOYPAD button? */
|
||||
if ( ident < RARCH_FIRST_CUSTOM_BIND )
|
||||
{
|
||||
uint32_t axis = 0;
|
||||
const struct retro_keybind *bind = NULL;
|
||||
|
||||
bind_minus = &binds[ident_minus];
|
||||
bind_plus = &binds[ident_plus];
|
||||
bind = &binds[ ident ];
|
||||
if (!bind->valid)
|
||||
return 0;
|
||||
|
||||
if (!bind_minus->valid || !bind_plus->valid)
|
||||
return 0;
|
||||
axis = bind->joyaxis;
|
||||
if ( axis == AXIS_NONE )
|
||||
axis = joypad_info.auto_binds[ ident ].joyaxis;
|
||||
|
||||
axis_minus = bind_minus->joyaxis;
|
||||
axis_plus = bind_plus->joyaxis;
|
||||
/* Analog button. */
|
||||
res = abs( drv->axis( joypad_info.joy_idx, axis ) );
|
||||
|
||||
if (axis_minus == AXIS_NONE)
|
||||
axis_minus = joypad_info.auto_binds[ident_minus].joyaxis;
|
||||
if (axis_plus == AXIS_NONE)
|
||||
axis_plus = joypad_info.auto_binds[ident_plus].joyaxis;
|
||||
/* If the result is zero, it's got a digital button attached to it */
|
||||
if ( res == 0 )
|
||||
{
|
||||
uint64_t key = bind->joykey;
|
||||
|
||||
pressed_minus = abs(drv->axis(joypad_info.joy_idx, axis_minus));
|
||||
pressed_plus = abs(drv->axis(joypad_info.joy_idx, axis_plus));
|
||||
res = pressed_plus - pressed_minus;
|
||||
if ( key == NO_BTN )
|
||||
key = joypad_info.auto_binds[ ident ].joykey;
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
int16_t digital_left = 0;
|
||||
int16_t digital_right = 0;
|
||||
uint64_t key_minus = bind_minus->joykey;
|
||||
uint64_t key_plus = bind_plus->joykey;
|
||||
if ( drv->button(joypad_info.joy_idx, (uint16_t)key))
|
||||
res = 0x7fff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* not a suitable button */
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Analog sticks. Either RETRO_DEVICE_INDEX_ANALOG_LEFT
|
||||
* or RETRO_DEVICE_INDEX_ANALOG_RIGHT */
|
||||
|
||||
if (key_minus == NO_BTN)
|
||||
key_minus = joypad_info.auto_binds[ident_minus].joykey;
|
||||
if (key_plus == NO_BTN)
|
||||
key_plus = joypad_info.auto_binds[ident_plus].joykey;
|
||||
uint32_t axis_minus, axis_plus;
|
||||
int16_t pressed_minus, pressed_plus;
|
||||
unsigned ident_minus = 0;
|
||||
unsigned ident_plus = 0;
|
||||
const struct retro_keybind *bind_minus = NULL;
|
||||
const struct retro_keybind *bind_plus = NULL;
|
||||
|
||||
if (drv->button(joypad_info.joy_idx, (uint16_t)key_minus))
|
||||
digital_left = -0x7fff;
|
||||
if (drv->button(joypad_info.joy_idx, (uint16_t)key_plus))
|
||||
digital_right = 0x7fff;
|
||||
return digital_right + digital_left;
|
||||
}
|
||||
input_conv_analog_id_to_bind_id(idx, ident, &ident_minus, &ident_plus);
|
||||
|
||||
return res;
|
||||
bind_minus = &binds[ident_minus];
|
||||
bind_plus = &binds[ident_plus];
|
||||
|
||||
if (!bind_minus->valid || !bind_plus->valid)
|
||||
return 0;
|
||||
|
||||
axis_minus = bind_minus->joyaxis;
|
||||
axis_plus = bind_plus->joyaxis;
|
||||
|
||||
if (axis_minus == AXIS_NONE)
|
||||
axis_minus = joypad_info.auto_binds[ident_minus].joyaxis;
|
||||
if (axis_plus == AXIS_NONE)
|
||||
axis_plus = joypad_info.auto_binds[ident_plus].joyaxis;
|
||||
|
||||
pressed_minus = abs(drv->axis(joypad_info.joy_idx, axis_minus));
|
||||
pressed_plus = abs(drv->axis(joypad_info.joy_idx, axis_plus));
|
||||
res = pressed_plus - pressed_minus;
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
int16_t digital_left = 0;
|
||||
int16_t digital_right = 0;
|
||||
uint64_t key_minus = bind_minus->joykey;
|
||||
uint64_t key_plus = bind_plus->joykey;
|
||||
|
||||
if (key_minus == NO_BTN)
|
||||
key_minus = joypad_info.auto_binds[ident_minus].joykey;
|
||||
if (key_plus == NO_BTN)
|
||||
key_plus = joypad_info.auto_binds[ident_plus].joykey;
|
||||
|
||||
if (drv->button(joypad_info.joy_idx, (uint16_t)key_minus))
|
||||
digital_left = -0x7fff;
|
||||
if (drv->button(joypad_info.joy_idx, (uint16_t)key_plus))
|
||||
digital_right = 0x7fff;
|
||||
|
||||
return digital_right + digital_left;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2474,10 +2511,17 @@ void input_config_get_bind_string(char *buf, const struct retro_keybind *bind,
|
||||
input_keymaps_translate_rk_to_str(bind->key, key, sizeof(key));
|
||||
if (string_is_equal(key, file_path_str(FILE_PATH_NUL)))
|
||||
*key = '\0';
|
||||
|
||||
snprintf(keybuf, sizeof(keybuf), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_KEY), key);
|
||||
strlcat(buf, keybuf, size);
|
||||
/*empty?*/
|
||||
if ( *key != '\0' ) {
|
||||
snprintf(keybuf, sizeof(keybuf), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_KEY), key);
|
||||
strlcat(buf, keybuf, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*completely empty?*/
|
||||
if ( *buf == '\0' ) {
|
||||
strlcat(buf, "---", size);
|
||||
}
|
||||
}
|
||||
|
||||
const char *input_config_get_device_name(unsigned port)
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <retro_common_api.h>
|
||||
#include <retro_inline.h>
|
||||
#include <libretro.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include "input_defines.h"
|
||||
|
||||
@ -333,10 +334,30 @@ void input_poll(void);
|
||||
int16_t input_state(unsigned port, unsigned device,
|
||||
unsigned idx, unsigned id);
|
||||
|
||||
uint64_t input_keys_pressed(void *data, uint64_t last_input);
|
||||
#define RARCH_INPUT_STATE_BIT_SET(a,bit) ((a).data [((bit) >> 5)] |= (1 << ((bit) & 31)))
|
||||
#define RARCH_INPUT_STATE_BIT_SET_PTR(a,bit) ((a)->data[((bit) >> 5)] |= (1 << ((bit) & 31)))
|
||||
#define RARCH_INPUT_STATE_BIT_GET(a,bit) ((a).data [((bit) >> 5)] & (1 << ((bit) & 31)))
|
||||
#define RARCH_INPUT_STATE_BIT_GET_PTR(a,bit) ((a)->data[((bit) >> 5)] & (1 << ((bit) & 31)))
|
||||
#define RARCH_INPUT_STATE_CLEAR(a) memset(&a, 0, sizeof(a));
|
||||
#define RARCH_INPUT_STATE_CLEAR_PTR(a) memset(a, 0, sizeof(retro_bits_t));
|
||||
#define RARCH_INPUT_STATE_ANY_SET(a) ( ((a).data[0])||((a).data[1])||((a).data[2])||((a).data[3])|| \
|
||||
((a).data[4])||((a).data[5])||((a).data[6])||((a).data[7]) )
|
||||
#define RARCH_INPUT_STATE_ANY_SET_PTR(a) ( ((a)->data[0])||((a)->data[1])||((a)->data[2])||((a)->data[3])|| \
|
||||
((a)->data[4])||((a)->data[5])||((a)->data[6])||((a)->data[7]) )
|
||||
#define RARCH_INPUT_STATE_CLEAR_BITS(a,b) \
|
||||
((a).data[0])&=(~((b).data[0])); \
|
||||
((a).data[1])&=(~((b).data[1])); \
|
||||
((a).data[2])&=(~((b).data[2])); \
|
||||
((a).data[3])&=(~((b).data[3])); \
|
||||
((a).data[4])&=(~((b).data[4])); \
|
||||
((a).data[5])&=(~((b).data[5])); \
|
||||
((a).data[6])&=(~((b).data[6])); \
|
||||
((a).data[7])&=(~((b).data[7]));
|
||||
|
||||
void input_keys_pressed(void *data, retro_bits_t* new_state);
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
uint64_t input_menu_keys_pressed(void *data, uint64_t last_input);
|
||||
void input_menu_keys_pressed(void *data, retro_bits_t* new_state);
|
||||
#endif
|
||||
|
||||
void *input_driver_get_data(void);
|
||||
@ -520,6 +541,7 @@ static INLINE bool input_joypad_pressed(
|
||||
* E.g.:
|
||||
* - RETRO_DEVICE_INDEX_ANALOG_LEFT
|
||||
* - RETRO_DEVICE_INDEX_ANALOG_RIGHT
|
||||
* - RETRO_DEVICE_INDEX_ANALOG_BUTTON
|
||||
* @ident : Analog key identifier.
|
||||
* E.g.:
|
||||
* - RETRO_DEVICE_ID_ANALOG_X
|
||||
|
@ -56,82 +56,89 @@ struct input_mapper
|
||||
uint64_t buttons;
|
||||
};
|
||||
|
||||
static input_mapper_t *mapper_ptr;
|
||||
|
||||
input_mapper_t *input_mapper_new(uint16_t port)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
input_mapper_t* handle = (input_mapper_t*)
|
||||
calloc(1, sizeof(*handle));
|
||||
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
handle->port = port;
|
||||
mapper_ptr = handle;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void input_mapper_free(input_mapper_t *handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
free (handle);
|
||||
}
|
||||
|
||||
void input_mapper_poll(input_mapper_t *handle)
|
||||
{
|
||||
int i;
|
||||
settings_t *settings = config_get_ptr();
|
||||
unsigned device = settings->uints.input_libretro_device[handle->port];
|
||||
device &= RETRO_DEVICE_MASK;
|
||||
unsigned device = settings->uints.input_libretro_device[handle->port];
|
||||
|
||||
device &= RETRO_DEVICE_MASK;
|
||||
|
||||
/* for now we only handle keyboard inputs */
|
||||
if (device == RETRO_DEVICE_KEYBOARD)
|
||||
{
|
||||
int i;
|
||||
memset(handle->keys, 0, sizeof(handle->keys));
|
||||
if (device != RETRO_DEVICE_KEYBOARD)
|
||||
return;
|
||||
|
||||
for (i = 0; i < RARCH_CUSTOM_BIND_LIST_END; i++)
|
||||
memset(handle->keys, 0, sizeof(handle->keys));
|
||||
|
||||
for (i = 0; i < RARCH_CUSTOM_BIND_LIST_END; i++)
|
||||
{
|
||||
if (i < RETROK_LAST)
|
||||
{
|
||||
if (i < RETROK_LAST)
|
||||
if (input_state(handle->port, RETRO_DEVICE_JOYPAD, 0, i))
|
||||
{
|
||||
if (input_state(handle->port, RETRO_DEVICE_JOYPAD, 0, i))
|
||||
{
|
||||
MAPPER_SET_KEY (handle, settings->uints.input_keymapper_ids[i]);
|
||||
input_keyboard_event(true, settings->uints.input_keymapper_ids[i], 0, 0, RETRO_DEVICE_KEYBOARD);
|
||||
}
|
||||
else
|
||||
input_keyboard_event(false, settings->uints.input_keymapper_ids[i], 0, 0, RETRO_DEVICE_KEYBOARD);
|
||||
MAPPER_SET_KEY (handle,
|
||||
settings->uints.input_keymapper_ids[i]);
|
||||
input_keyboard_event(true,
|
||||
settings->uints.input_keymapper_ids[i],
|
||||
0, 0, RETRO_DEVICE_KEYBOARD);
|
||||
}
|
||||
else
|
||||
input_keyboard_event(false,
|
||||
settings->uints.input_keymapper_ids[i],
|
||||
0, 0, RETRO_DEVICE_KEYBOARD);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void input_mapper_state(
|
||||
input_mapper_t *handle,
|
||||
int16_t *ret,
|
||||
unsigned port,
|
||||
unsigned device,
|
||||
unsigned idx,
|
||||
unsigned id)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
settings_t *settings = config_get_ptr();
|
||||
switch (device)
|
||||
{
|
||||
case RETRO_DEVICE_KEYBOARD:
|
||||
if (id < RETROK_LAST)
|
||||
{
|
||||
/*
|
||||
RARCH_LOG("State: UDLR %u %u %u %u\n",
|
||||
MAPPER_GET_KEY(mapper_ptr, RETROK_UP),
|
||||
MAPPER_GET_KEY(mapper_ptr, RETROK_DOWN),
|
||||
MAPPER_GET_KEY(mapper_ptr, RETROK_LEFT),
|
||||
MAPPER_GET_KEY(mapper_ptr, RETROK_RIGHT)
|
||||
);*/
|
||||
RARCH_LOG("State: UDLR %u %u %u %u\n",
|
||||
MAPPER_GET_KEY(handle, RETROK_UP),
|
||||
MAPPER_GET_KEY(handle, RETROK_DOWN),
|
||||
MAPPER_GET_KEY(handle, RETROK_LEFT),
|
||||
MAPPER_GET_KEY(handle, RETROK_RIGHT)
|
||||
);*/
|
||||
|
||||
if (MAPPER_GET_KEY(mapper_ptr, id))
|
||||
if (MAPPER_GET_KEY(handle, id))
|
||||
*ret |= 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ void input_mapper_poll(input_mapper_t *handle);
|
||||
bool input_mapper_key_pressed(int key);
|
||||
|
||||
void input_mapper_state(
|
||||
input_mapper_t *handle,
|
||||
int16_t *ret,
|
||||
unsigned port,
|
||||
unsigned device,
|
||||
|
@ -1674,6 +1674,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2163,6 +2165,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"跳过 SRAM 加载。")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"慢动作。")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"快进。")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"慢动作回溯。")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
|
@ -1674,6 +1674,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2163,6 +2165,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"跳過 SRAM 戴入。")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"慢動作。")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"快進。")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"慢動作回溯。")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
|
@ -1263,6 +1263,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG,
|
||||
"Rechter Analogstick")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES,
|
||||
"Zu Favoriten hinzufügen")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST,
|
||||
"Zu Favoriten hinzufügen")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN,
|
||||
"Starten")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_MUSIC,
|
||||
@ -1723,6 +1725,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2225,6 +2229,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"Überspringe Laden des SRAM.")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"Zeitlupe.")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"Snel vooruit.")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"In Zeitlupe zurückspulen.")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
@ -2818,6 +2824,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION,
|
||||
"Zeige weiterführende Informationen über diesen Inhalt an.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES,
|
||||
"Füge diesen Eintrag zu deinen Favoriten hinzu.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST,
|
||||
"Füge diesen Eintrag zu deinen Favoriten hinzu.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_RUN,
|
||||
"Starte den Inhalt.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS,
|
||||
|
@ -1570,6 +1570,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2052,6 +2054,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"Skipping SRAM load.")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"Slow motion.")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"Fast forward.")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"Slow motion rewind.")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
|
@ -1469,6 +1469,8 @@ const char *msg_hash_to_str_es(enum msg_hash_enums msg)
|
||||
return "Omitiendo carga de SRAM.";
|
||||
case MSG_SLOW_MOTION:
|
||||
return "Cámara lenta.";
|
||||
case MSG_FAST_FORWARD:
|
||||
return "Avance rápido.";
|
||||
case MSG_SLOW_MOTION_REWIND:
|
||||
return "Rebobinar cámara lenta.";
|
||||
case MSG_SRAM_WILL_NOT_BE_SAVED:
|
||||
|
@ -1695,6 +1695,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2183,6 +2185,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"Ignore le chargement de la SRAM.")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"Ralenti.")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"Avance rapide.")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"Rembobinage ralenti.")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
|
@ -1263,6 +1263,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG,
|
||||
"Analogico Destro")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES,
|
||||
"Aggiungi a Preferiti")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST,
|
||||
"Aggiungi a Preferiti")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN,
|
||||
"Avvia")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_MUSIC,
|
||||
@ -1721,6 +1723,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroAttivo")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2223,6 +2227,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"Skipping SRAM load.")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"Slow motion.")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"Avanzamento rapido.")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"Riavvolgimento lento.")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
@ -2816,6 +2822,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION,
|
||||
"Visualizza ulteriori informazioni sul contenuto.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES,
|
||||
"Aggiunge il titolo ai tuoi preferiti.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST,
|
||||
"Aggiunge il titolo ai tuoi preferiti.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_RUN,
|
||||
"Avvia il contenuto.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS,
|
||||
|
@ -1737,6 +1737,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"ピクセル")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"レトロアクティブ")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"ドット絵")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2237,6 +2239,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"Skipping SRAM load.")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"スローモーション。")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"早送り。")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"スローモーション巻き戻し。")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
@ -3165,6 +3169,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_OPACITY,
|
||||
"OSDメッセージ背景の不透明性")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES,
|
||||
"お気に入りに追加")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST,
|
||||
"お気に入りに追加")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE,
|
||||
"キオスクモードを無効")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE,
|
||||
|
@ -1671,6 +1671,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2163,6 +2165,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"SRAM 불러오기 건너뛰는 중.")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"슬로우 모션.")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"빨리 감기.")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"슬로우 모션 되감기.")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
|
@ -136,6 +136,8 @@ MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE,
|
||||
"cheevos_hardcore_mode_enable")
|
||||
MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE,
|
||||
"cheevos_leaderboards_enable")
|
||||
MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE,
|
||||
"cheevos_badges_enable")
|
||||
MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_LOCKED_ACHIEVEMENTS,
|
||||
"cheevos_locked_achievements")
|
||||
MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
||||
@ -148,6 +150,8 @@ MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ACHIEVEMENTS,
|
||||
"cheevos_unlocked_achievements")
|
||||
MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY,
|
||||
"cheevos_unlocked_entry")
|
||||
MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY_HARDCORE,
|
||||
"cheevos_unlocked_entry_hardcore")
|
||||
MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_USERNAME,
|
||||
"cheevos_username")
|
||||
MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_VERBOSE_ENABLE,
|
||||
@ -873,6 +877,8 @@ MSG_HASH(MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN,
|
||||
"rgui_show_start_screen")
|
||||
MSG_HASH(MENU_ENUM_LABEL_ADD_TO_FAVORITES,
|
||||
"favorites_add")
|
||||
MSG_HASH(MENU_ENUM_LABEL_ADD_TO_FAVORITES_PLAYLIST,
|
||||
"favorites_add_playlist")
|
||||
MSG_HASH(MENU_ENUM_LABEL_RUN,
|
||||
"collection")
|
||||
MSG_HASH(MENU_ENUM_LABEL_RUN_MUSIC,
|
||||
|
@ -1568,6 +1568,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2050,6 +2052,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"Skipping SRAM load.")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"Slow motion.")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"Snel vooruit.")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"Slow motion rewind.")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
@ -982,6 +982,8 @@ const char *msg_hash_to_str_pl(enum msg_hash_enums msg)
|
||||
return "Pomijanie wczytywania SRAM.";
|
||||
case MSG_SLOW_MOTION:
|
||||
return "Spowolnione tempo.";
|
||||
case MSG_FAST_FORWARD:
|
||||
return "Szybko do przodu.";
|
||||
case MSG_SLOW_MOTION_REWIND:
|
||||
return "Przewijanie w spowolnionym tempie.";
|
||||
case MSG_SRAM_WILL_NOT_BE_SAVED:
|
||||
|
@ -1525,6 +1525,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG,
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES,
|
||||
"Adicionar aos Favoritos"
|
||||
)
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST,
|
||||
"Adicionar aos Favoritos"
|
||||
)
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN,
|
||||
"Executar"
|
||||
)
|
||||
@ -2212,6 +2215,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive"
|
||||
)
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem"
|
||||
)
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art"
|
||||
)
|
||||
@ -2965,6 +2971,9 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"Câmera Lenta."
|
||||
)
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"Avanço rápido."
|
||||
)
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"Voltar Atrás em Câmera Lenta."
|
||||
)
|
||||
@ -3553,6 +3562,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION,
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES,
|
||||
"Adicionar o item aos seus favoritos."
|
||||
)
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST,
|
||||
"Adicionar o item aos seus favoritos."
|
||||
)
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_RUN,
|
||||
"Iniciar o conteúdo."
|
||||
)
|
||||
|
@ -1663,6 +1663,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2153,6 +2155,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"Ignorando carregamento de SRAM.")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"Câmera lenta.")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"Avanço rápido.")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"Função rewind em câmera lenta.")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -434,6 +434,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE,
|
||||
"Leaderboards"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE,
|
||||
"Achievement Badges"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS,
|
||||
"Locked Achievements:"
|
||||
@ -458,6 +462,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY,
|
||||
"Unlocked"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY_HARDCORE,
|
||||
"Hardcore"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE,
|
||||
"Achievements Verbose Mode"
|
||||
@ -1267,6 +1275,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG,
|
||||
"Right Analog")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES,
|
||||
"Add to Favorites")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST,
|
||||
"Add to Favorites")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN,
|
||||
"Run")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN_MUSIC,
|
||||
@ -1610,9 +1620,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER,
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE,
|
||||
"Enable Onscreen Notifications")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH,
|
||||
"Onscreen Notification Font")
|
||||
"Notification Font")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE,
|
||||
"Onscreen Notification Size")
|
||||
"Notification Size")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT,
|
||||
"Force aspect ratio")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE,
|
||||
@ -1634,9 +1644,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES,
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES,
|
||||
"Max swapchain images")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_X,
|
||||
"Onscreen Notification X Position")
|
||||
"Notification X Position")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_Y,
|
||||
"Onscreen Notification Y Position")
|
||||
"Notification Y Position")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX,
|
||||
"Monitor Index")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD,
|
||||
@ -1727,6 +1737,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -1787,6 +1799,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE,
|
||||
"Enable or disable savestates, cheats, rewind, fast-forward, pause, and slow-motion for all games.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_LEADERBOARDS_ENABLE,
|
||||
"Enable or disable in-game leaderboards. Has no effect if Hardcore Mode is disabled.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_BADGES_ENABLE,
|
||||
"Enable or disable badge display in Achievement List.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_VERBOSE_ENABLE,
|
||||
"Enable or disable OSD verbosity for achievements.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS,
|
||||
@ -2231,6 +2245,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"Skipping SRAM load.")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"Slow motion.")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"Fast forward.")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"Slow motion rewind.")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
@ -2824,6 +2840,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION,
|
||||
"View more information about the content.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES,
|
||||
"Add the entry to your favorites.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_ADD_TO_FAVORITES_PLAYLIST,
|
||||
"Add the entry to your favorites.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_RUN,
|
||||
"Start the content.")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS,
|
||||
@ -3234,15 +3252,15 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QUICK_MENU_SHOW_INFORMATION,
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION,
|
||||
"Show/hide the 'Information' option.")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_ENABLE,
|
||||
"Onscreen Notification Background Enable")
|
||||
"Notification Background Enable")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_RED,
|
||||
"Onscreen Notification Background Red Color")
|
||||
"Notification Background Red Color")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_GREEN,
|
||||
"Onscreen Notification Background Green Color")
|
||||
"Notification Background Green Color")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_BLUE,
|
||||
"Onscreen Notification Background Blue Color")
|
||||
"Notification Background Blue Color")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_BGCOLOR_OPACITY,
|
||||
"Onscreen Notification Background Opacity")
|
||||
"Notification Background Opacity")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DISABLE_KIOSK_MODE,
|
||||
"Disable Kiosk Mode")
|
||||
MSG_HASH(MENU_ENUM_SUBLABEL_MENU_DISABLE_KIOSK_MODE,
|
||||
@ -3262,11 +3280,11 @@ MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_OK,
|
||||
MSG_HASH(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK,
|
||||
"Password incorrect.")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_RED,
|
||||
"Onscreen Notification Red Color")
|
||||
"Notification Red Color")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_GREEN,
|
||||
"Onscreen Notification Green Color")
|
||||
"Notification Green Color")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_COLOR_BLUE,
|
||||
"Onscreen Notification Blue Color")
|
||||
"Notification Blue Color")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAMECOUNT_SHOW,
|
||||
"Show frame count on FPS display")
|
||||
MSG_HASH(MSG_CONFIG_OVERRIDE_LOADED,
|
||||
|
@ -1689,6 +1689,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
"Pixel")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
"RetroActive")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
"Retrosystem")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART,
|
||||
"Dot-Art")
|
||||
MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME,
|
||||
@ -2181,6 +2183,8 @@ MSG_HASH(MSG_SKIPPING_SRAM_LOAD,
|
||||
"Skipping SRAM load.")
|
||||
MSG_HASH(MSG_SLOW_MOTION,
|
||||
"Slow motion.")
|
||||
MSG_HASH(MSG_FAST_FORWARD,
|
||||
"Nhanh về phía trước.")
|
||||
MSG_HASH(MSG_SLOW_MOTION_REWIND,
|
||||
"Slow motion rewind.")
|
||||
MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED,
|
||||
|
@ -20,6 +20,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
@ -60,3 +61,10 @@ size_t strlcat(char *dest, const char *source, size_t size)
|
||||
return len + strlcpy(dest, source, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
char *strldup(const char *s, size_t n)
|
||||
{
|
||||
char *dst = malloc(sizeof(char) * (n + 1));
|
||||
strlcpy(dst, s, n);
|
||||
return dst;
|
||||
}
|
||||
|
@ -389,14 +389,13 @@ static config_file_t *config_file_new_internal(
|
||||
goto error;
|
||||
|
||||
conf->include_depth = depth;
|
||||
file = filestream_open(path, RFILE_MODE_READ_TEXT, -1);
|
||||
file = filestream_open(path, RFILE_MODE_READ_TEXT, 0x4000);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
free(conf->path);
|
||||
goto error;
|
||||
}
|
||||
setvbuf(filestream_get_fp(file), NULL, _IOFBF, 0x4000);
|
||||
|
||||
while (!filestream_eof(file))
|
||||
{
|
||||
@ -917,15 +916,9 @@ bool config_file_write(config_file_t *conf, const char *path)
|
||||
|
||||
if (!string_is_empty(path))
|
||||
{
|
||||
file = filestream_open(path, RFILE_MODE_WRITE, -1);
|
||||
file = filestream_open(path, RFILE_MODE_WRITE, 0x4000);
|
||||
if (!file)
|
||||
return false;
|
||||
#ifdef WIIU
|
||||
/* TODO: use FBF everywhere once https://i.imgur.com/muVhNeF.jpg is fixed */
|
||||
setvbuf(filestream_get_fp(file), NULL, _IONBF, 0x4000);
|
||||
#else
|
||||
setvbuf(filestream_get_fp(file), NULL, _IOFBF, 0x4000);
|
||||
#endif
|
||||
config_file_dump(conf, filestream_get_fp(file));
|
||||
}
|
||||
else
|
||||
|
@ -72,10 +72,6 @@
|
||||
#include <pspkernel.h>
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#include <kernel/image.h>
|
||||
#endif
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include <cell/cell_fs.h>
|
||||
#endif
|
||||
|
85
libretro-common/file/nbio/nbio_intf.c
Normal file
85
libretro-common/file/nbio/nbio_intf.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* Copyright (C) 2010-2017 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (nbio_intf.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <file/nbio.h>
|
||||
|
||||
extern nbio_intf_t nbio_linux;
|
||||
extern nbio_intf_t nbio_mmap_unix;
|
||||
extern nbio_intf_t nbio_mmap_win32;
|
||||
extern nbio_intf_t nbio_stdio;
|
||||
|
||||
#if defined(_linux__)
|
||||
static nbio_intf_t *internal_nbio = &nbio_linux;
|
||||
#elif defined(HAVE_MMAP) && defined(BSD)
|
||||
static nbio_intf_t *internal_nbio = &nbio_mmap_unix;
|
||||
#elif defined(_WIN32) && !defined(_XBOX)
|
||||
static nbio_intf_t *internal_nbio = &nbio_mmap_win32;
|
||||
#else
|
||||
static nbio_intf_t *internal_nbio = &nbio_stdio;
|
||||
#endif
|
||||
|
||||
void *nbio_open(const char * filename, unsigned mode)
|
||||
{
|
||||
return internal_nbio->open(filename, mode);
|
||||
}
|
||||
|
||||
void nbio_begin_read(void *data)
|
||||
{
|
||||
internal_nbio->begin_read(data);
|
||||
}
|
||||
|
||||
void nbio_begin_write(void *data)
|
||||
{
|
||||
internal_nbio->begin_write(data);
|
||||
}
|
||||
|
||||
bool nbio_iterate(void *data)
|
||||
{
|
||||
return internal_nbio->iterate(data);
|
||||
}
|
||||
|
||||
void nbio_resize(void *data, size_t len)
|
||||
{
|
||||
internal_nbio->resize(data, len);
|
||||
}
|
||||
|
||||
void *nbio_get_ptr(void *data, size_t* len)
|
||||
{
|
||||
return internal_nbio->get_ptr(data, len);
|
||||
}
|
||||
|
||||
void nbio_cancel(void *data)
|
||||
{
|
||||
internal_nbio->cancel(data);
|
||||
}
|
||||
|
||||
void nbio_free(void *data)
|
||||
{
|
||||
internal_nbio->free(data);
|
||||
}
|
230
libretro-common/file/nbio/nbio_linux.c
Normal file
230
libretro-common/file/nbio/nbio_linux.c
Normal file
@ -0,0 +1,230 @@
|
||||
/* Copyright (C) 2010-2017 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (nbio_linux.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <file/nbio.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <linux/aio_abi.h>
|
||||
|
||||
struct nbio_linux_t
|
||||
{
|
||||
int fd;
|
||||
bool busy;
|
||||
|
||||
aio_context_t ctx;
|
||||
struct iocb cb;
|
||||
|
||||
void* ptr;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/* there's also a Unix AIO thingy, but it's not in glibc
|
||||
* and we don't want more dependencies */
|
||||
|
||||
static int io_setup(unsigned nr, aio_context_t * ctxp)
|
||||
{
|
||||
return syscall(__NR_io_setup, nr, ctxp);
|
||||
}
|
||||
|
||||
static int io_destroy(aio_context_t ctx)
|
||||
{
|
||||
return syscall(__NR_io_destroy, ctx);
|
||||
}
|
||||
|
||||
static int io_submit(aio_context_t ctx, long nr, struct iocb ** cbp)
|
||||
{
|
||||
return syscall(__NR_io_submit, ctx, nr, cbp);
|
||||
}
|
||||
|
||||
static int io_cancel(aio_context_t ctx, struct iocb * iocb, struct io_event * result)
|
||||
{
|
||||
return syscall(__NR_io_cancel, ctx, iocb, result);
|
||||
}
|
||||
|
||||
static int io_getevents(aio_context_t ctx, long min_nr, long nr,
|
||||
struct io_event * events, struct timespec * timeout)
|
||||
{
|
||||
return syscall(__NR_io_getevents, ctx, min_nr, nr, events, timeout);
|
||||
}
|
||||
|
||||
static void nbio_begin_op(struct nbio_linux_t* handle, uint16_t op)
|
||||
{
|
||||
struct iocb * cbp = &handle->cb;
|
||||
|
||||
memset(&handle->cb, 0, sizeof(handle->cb));
|
||||
|
||||
handle->cb.aio_fildes = handle->fd;
|
||||
handle->cb.aio_lio_opcode = op;
|
||||
|
||||
handle->cb.aio_buf = (uint64_t)(uintptr_t)handle->ptr;
|
||||
handle->cb.aio_offset = 0;
|
||||
handle->cb.aio_nbytes = handle->len;
|
||||
|
||||
if (io_submit(handle->ctx, 1, &cbp) != 1)
|
||||
{
|
||||
puts("ERROR - io_submit() failed");
|
||||
abort();
|
||||
}
|
||||
|
||||
handle->busy = true;
|
||||
}
|
||||
|
||||
static void *nbio_linux_open(const char * filename, unsigned mode)
|
||||
{
|
||||
static const int o_flags[] = { O_RDONLY, O_RDWR|O_CREAT|O_TRUNC, O_RDWR, O_RDONLY, O_RDWR|O_CREAT|O_TRUNC };
|
||||
|
||||
aio_context_t ctx = 0;
|
||||
struct nbio_linux_t* handle = NULL;
|
||||
int fd = open(filename, o_flags[mode]|O_CLOEXEC, 0644);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
if (io_setup(128, &ctx) < 0)
|
||||
{
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle = malloc(sizeof(struct nbio_linux_t));
|
||||
handle->fd = fd;
|
||||
handle->ctx = ctx;
|
||||
handle->len = lseek(fd, 0, SEEK_END);
|
||||
handle->ptr = malloc(handle->len);
|
||||
handle->busy = false;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void nbio_linux_begin_read(void *data)
|
||||
{
|
||||
struct nbio_linux_t* handle = (struct nbio_linux_t*)data;
|
||||
if (handle)
|
||||
nbio_begin_op(handle, IOCB_CMD_PREAD);
|
||||
}
|
||||
|
||||
static void nbio_linux_begin_write(void *data)
|
||||
{
|
||||
struct nbio_linux_t* handle = (struct nbio_linux_t*)data;
|
||||
if (handle)
|
||||
nbio_begin_op(handle, IOCB_CMD_PWRITE);
|
||||
}
|
||||
|
||||
static bool nbio_linux_iterate(void *data)
|
||||
{
|
||||
struct nbio_linux_t* handle = (struct nbio_linux_t*)data;
|
||||
if (!handle)
|
||||
return false;
|
||||
if (handle->busy)
|
||||
{
|
||||
struct io_event ev;
|
||||
if (io_getevents(handle->ctx, 0, 1, &ev, NULL) == 1)
|
||||
handle->busy = false;
|
||||
}
|
||||
return !handle->busy;
|
||||
}
|
||||
|
||||
static void nbio_linux_resize(void *data, size_t len)
|
||||
{
|
||||
struct nbio_linux_t* handle = (struct nbio_linux_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (len < handle->len)
|
||||
{
|
||||
/* this works perfectly fine if this check is removed, but it
|
||||
* won't work on other nbio implementations */
|
||||
/* therefore, it's blocked so nobody accidentally relies on it */
|
||||
puts("ERROR - attempted file shrink operation, not implemented");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (ftruncate(handle->fd, len) != 0)
|
||||
{
|
||||
puts("ERROR - couldn't resize file (ftruncate)");
|
||||
abort(); /* this one returns void and I can't find any other way
|
||||
for it to report failure */
|
||||
}
|
||||
handle->ptr = realloc(handle->ptr, len);
|
||||
handle->len = len;
|
||||
}
|
||||
|
||||
static void *nbio_linux_get_ptr(void *data, size_t* len)
|
||||
{
|
||||
struct nbio_linux_t* handle = (struct nbio_linux_t*)data;
|
||||
if (!handle)
|
||||
return NULL;
|
||||
if (len)
|
||||
*len = handle->len;
|
||||
if (!handle->busy)
|
||||
return handle->ptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void nbio_linux_cancel(void *data)
|
||||
{
|
||||
struct nbio_linux_t* handle = (struct nbio_linux_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->busy)
|
||||
{
|
||||
struct io_event ev;
|
||||
io_cancel(handle->ctx, &handle->cb, &ev);
|
||||
handle->busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void nbio_linux_free(void *data)
|
||||
{
|
||||
struct nbio_linux_t* handle = (struct nbio_linux_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
io_destroy(handle->ctx);
|
||||
close(handle->fd);
|
||||
free(handle->ptr);
|
||||
free(handle);
|
||||
}
|
||||
|
||||
nbio_intf_t nbio_linux = {
|
||||
nbio_linux_open,
|
||||
nbio_linux_begin_read,
|
||||
nbio_linux_begin_write,
|
||||
nbio_linux_iterate,
|
||||
nbio_linux_resize,
|
||||
nbio_linux_get_ptr,
|
||||
nbio_linux_cancel,
|
||||
nbio_linux_free,
|
||||
"nbio_linux",
|
||||
};
|
||||
|
||||
#endif
|
@ -1,227 +1,268 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <file/nbio.h>
|
||||
#include <encodings/utf.h>
|
||||
|
||||
/* Assume W-functions do not work below VC2005 and Xbox platforms */
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX)
|
||||
|
||||
#ifndef LEGACY_WIN32
|
||||
#define LEGACY_WIN32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
struct nbio_t
|
||||
{
|
||||
FILE* f;
|
||||
void* data;
|
||||
size_t progress;
|
||||
size_t len;
|
||||
/*
|
||||
* possible values:
|
||||
* NBIO_READ, NBIO_WRITE - obvious
|
||||
* -1 - currently doing nothing
|
||||
* -2 - the pointer was reallocated since the last operation
|
||||
*/
|
||||
signed char op;
|
||||
signed char mode;
|
||||
};
|
||||
|
||||
#if !defined(_WIN32) || defined(LEGACY_WIN32)
|
||||
static const char * modes[]={ "rb", "wb", "r+b", "rb", "wb", "r+b" };
|
||||
#else
|
||||
static const wchar_t * modes[]={ L"rb", L"wb", L"r+b", L"rb", L"wb", L"r+b" };
|
||||
#endif
|
||||
|
||||
struct nbio_t* nbio_open(const char * filename, unsigned mode)
|
||||
{
|
||||
void *buf = NULL;
|
||||
struct nbio_t* handle = NULL;
|
||||
size_t len = 0;
|
||||
#if !defined(_WIN32) || defined(LEGACY_WIN32)
|
||||
FILE* f = fopen(filename, modes[mode]);
|
||||
#else
|
||||
wchar_t *filename_wide = utf8_to_utf16_string_alloc(filename);
|
||||
FILE* f = _wfopen(filename_wide, modes[mode]);
|
||||
|
||||
if (filename_wide)
|
||||
free(filename_wide);
|
||||
#endif
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
handle = (struct nbio_t*)malloc(sizeof(struct nbio_t));
|
||||
|
||||
if (!handle)
|
||||
goto error;
|
||||
|
||||
handle->f = f;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case NBIO_WRITE:
|
||||
case BIO_WRITE:
|
||||
break;
|
||||
default:
|
||||
fseek(handle->f, 0, SEEK_END);
|
||||
len = ftell(handle->f);
|
||||
break;
|
||||
}
|
||||
|
||||
handle->mode = mode;
|
||||
|
||||
if (len)
|
||||
buf = malloc(len);
|
||||
|
||||
if (!buf)
|
||||
goto error;
|
||||
|
||||
handle->data = buf;
|
||||
handle->len = len;
|
||||
handle->progress = handle->len;
|
||||
handle->op = -2;
|
||||
|
||||
return handle;
|
||||
|
||||
error:
|
||||
if (handle)
|
||||
free(handle);
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nbio_begin_read(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file read operation while busy");
|
||||
abort();
|
||||
}
|
||||
|
||||
fseek(handle->f, 0, SEEK_SET);
|
||||
|
||||
handle->op = NBIO_READ;
|
||||
handle->progress = 0;
|
||||
}
|
||||
|
||||
void nbio_begin_write(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file write operation while busy");
|
||||
abort();
|
||||
}
|
||||
|
||||
fseek(handle->f, 0, SEEK_SET);
|
||||
handle->op = NBIO_WRITE;
|
||||
handle->progress = 0;
|
||||
}
|
||||
|
||||
bool nbio_iterate(struct nbio_t* handle)
|
||||
{
|
||||
size_t amount = 65536;
|
||||
|
||||
if (!handle)
|
||||
return false;
|
||||
|
||||
if (amount > handle->len - handle->progress)
|
||||
amount = handle->len - handle->progress;
|
||||
|
||||
switch (handle->op)
|
||||
{
|
||||
case NBIO_READ:
|
||||
if (handle->mode == BIO_READ)
|
||||
{
|
||||
amount = handle->len;
|
||||
fread((char*)handle->data, 1, amount, handle->f);
|
||||
}
|
||||
else
|
||||
fread((char*)handle->data + handle->progress, 1, amount, handle->f);
|
||||
break;
|
||||
case NBIO_WRITE:
|
||||
if (handle->mode == BIO_WRITE)
|
||||
{
|
||||
size_t written = 0;
|
||||
amount = handle->len;
|
||||
written = fwrite((char*)handle->data, 1, amount, handle->f);
|
||||
if (written != amount)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
fwrite((char*)handle->data + handle->progress, 1, amount, handle->f);
|
||||
break;
|
||||
}
|
||||
|
||||
handle->progress += amount;
|
||||
|
||||
if (handle->progress == handle->len)
|
||||
handle->op = -1;
|
||||
return (handle->op < 0);
|
||||
}
|
||||
|
||||
void nbio_resize(struct nbio_t* handle, size_t len)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file resize operation while busy");
|
||||
abort();
|
||||
}
|
||||
if (len < handle->len)
|
||||
{
|
||||
puts("ERROR - attempted file shrink operation, not implemented");
|
||||
abort();
|
||||
}
|
||||
|
||||
handle->len = len;
|
||||
handle->data = realloc(handle->data, handle->len);
|
||||
handle->op = -1;
|
||||
handle->progress = handle->len;
|
||||
}
|
||||
|
||||
void* nbio_get_ptr(struct nbio_t* handle, size_t* len)
|
||||
{
|
||||
if (!handle)
|
||||
return NULL;
|
||||
if (len)
|
||||
*len = handle->len;
|
||||
if (handle->op == -1)
|
||||
return handle->data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nbio_cancel(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
handle->op = -1;
|
||||
handle->progress = handle->len;
|
||||
}
|
||||
|
||||
void nbio_free(struct nbio_t* handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted free() while busy");
|
||||
abort();
|
||||
}
|
||||
fclose(handle->f);
|
||||
free(handle->data);
|
||||
|
||||
handle->f = NULL;
|
||||
handle->data = NULL;
|
||||
free(handle);
|
||||
}
|
||||
/* Copyright (C) 2010-2017 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (nbio_stdio.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <file/nbio.h>
|
||||
#include <encodings/utf.h>
|
||||
|
||||
/* Assume W-functions do not work below VC2005 and Xbox platforms */
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX)
|
||||
|
||||
#ifndef LEGACY_WIN32
|
||||
#define LEGACY_WIN32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
struct nbio_stdio_t
|
||||
{
|
||||
FILE* f;
|
||||
void* data;
|
||||
size_t progress;
|
||||
size_t len;
|
||||
/*
|
||||
* possible values:
|
||||
* NBIO_READ, NBIO_WRITE - obvious
|
||||
* -1 - currently doing nothing
|
||||
* -2 - the pointer was reallocated since the last operation
|
||||
*/
|
||||
signed char op;
|
||||
signed char mode;
|
||||
};
|
||||
|
||||
#if !defined(_WIN32) || defined(LEGACY_WIN32)
|
||||
static const char *stdio_modes[] = { "rb", "wb", "r+b", "rb", "wb", "r+b" };
|
||||
#else
|
||||
static const wchar_t *stdio_modes[] = { L"rb", L"wb", L"r+b", L"rb", L"wb", L"r+b" };
|
||||
#endif
|
||||
|
||||
static void *nbio_stdio_open(const char * filename, unsigned mode)
|
||||
{
|
||||
void *buf = NULL;
|
||||
struct nbio_stdio_t* handle = NULL;
|
||||
size_t len = 0;
|
||||
#if !defined(_WIN32) || defined(LEGACY_WIN32)
|
||||
FILE* f = fopen(filename, stdio_modes[mode]);
|
||||
#else
|
||||
wchar_t *filename_wide = utf8_to_utf16_string_alloc(filename);
|
||||
FILE* f = _wfopen(filename_wide, stdio_modes[mode]);
|
||||
|
||||
if (filename_wide)
|
||||
free(filename_wide);
|
||||
#endif
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
handle = (struct nbio_stdio_t*)malloc(sizeof(struct nbio_stdio_t));
|
||||
|
||||
if (!handle)
|
||||
goto error;
|
||||
|
||||
handle->f = f;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case NBIO_WRITE:
|
||||
case BIO_WRITE:
|
||||
break;
|
||||
default:
|
||||
fseek(handle->f, 0, SEEK_END);
|
||||
len = ftell(handle->f);
|
||||
break;
|
||||
}
|
||||
|
||||
handle->mode = mode;
|
||||
|
||||
if (len)
|
||||
buf = malloc(len);
|
||||
|
||||
if (len && !buf)
|
||||
goto error;
|
||||
|
||||
handle->data = buf;
|
||||
handle->len = len;
|
||||
handle->progress = handle->len;
|
||||
handle->op = -2;
|
||||
|
||||
return handle;
|
||||
|
||||
error:
|
||||
if (handle)
|
||||
free(handle);
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void nbio_stdio_begin_read(void *data)
|
||||
{
|
||||
struct nbio_stdio_t *handle = (struct nbio_stdio_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file read operation while busy");
|
||||
abort();
|
||||
}
|
||||
|
||||
fseek(handle->f, 0, SEEK_SET);
|
||||
|
||||
handle->op = NBIO_READ;
|
||||
handle->progress = 0;
|
||||
}
|
||||
|
||||
static void nbio_stdio_begin_write(void *data)
|
||||
{
|
||||
struct nbio_stdio_t *handle = (struct nbio_stdio_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file write operation while busy");
|
||||
abort();
|
||||
}
|
||||
|
||||
fseek(handle->f, 0, SEEK_SET);
|
||||
handle->op = NBIO_WRITE;
|
||||
handle->progress = 0;
|
||||
}
|
||||
|
||||
static bool nbio_stdio_iterate(void *data)
|
||||
{
|
||||
size_t amount = 65536;
|
||||
struct nbio_stdio_t *handle = (struct nbio_stdio_t*)data;
|
||||
|
||||
if (!handle)
|
||||
return false;
|
||||
|
||||
if (amount > handle->len - handle->progress)
|
||||
amount = handle->len - handle->progress;
|
||||
|
||||
switch (handle->op)
|
||||
{
|
||||
case NBIO_READ:
|
||||
if (handle->mode == BIO_READ)
|
||||
{
|
||||
amount = handle->len;
|
||||
fread((char*)handle->data, 1, amount, handle->f);
|
||||
}
|
||||
else
|
||||
fread((char*)handle->data + handle->progress, 1, amount, handle->f);
|
||||
break;
|
||||
case NBIO_WRITE:
|
||||
if (handle->mode == BIO_WRITE)
|
||||
{
|
||||
size_t written = 0;
|
||||
amount = handle->len;
|
||||
written = fwrite((char*)handle->data, 1, amount, handle->f);
|
||||
if (written != amount)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
fwrite((char*)handle->data + handle->progress, 1, amount, handle->f);
|
||||
break;
|
||||
}
|
||||
|
||||
handle->progress += amount;
|
||||
|
||||
if (handle->progress == handle->len)
|
||||
handle->op = -1;
|
||||
return (handle->op < 0);
|
||||
}
|
||||
|
||||
static void nbio_stdio_resize(void *data, size_t len)
|
||||
{
|
||||
struct nbio_stdio_t *handle = (struct nbio_stdio_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted file resize operation while busy");
|
||||
abort();
|
||||
}
|
||||
if (len < handle->len)
|
||||
{
|
||||
puts("ERROR - attempted file shrink operation, not implemented");
|
||||
abort();
|
||||
}
|
||||
|
||||
handle->len = len;
|
||||
handle->data = realloc(handle->data, handle->len);
|
||||
handle->op = -1;
|
||||
handle->progress = handle->len;
|
||||
}
|
||||
|
||||
static void *nbio_stdio_get_ptr(void *data, size_t* len)
|
||||
{
|
||||
struct nbio_stdio_t *handle = (struct nbio_stdio_t*)data;
|
||||
if (!handle)
|
||||
return NULL;
|
||||
if (len)
|
||||
*len = handle->len;
|
||||
if (handle->op == -1)
|
||||
return handle->data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void nbio_stdio_cancel(void *data)
|
||||
{
|
||||
struct nbio_stdio_t *handle = (struct nbio_stdio_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
handle->op = -1;
|
||||
handle->progress = handle->len;
|
||||
}
|
||||
|
||||
static void nbio_stdio_free(void *data)
|
||||
{
|
||||
struct nbio_stdio_t *handle = (struct nbio_stdio_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
if (handle->op >= 0)
|
||||
{
|
||||
puts("ERROR - attempted free() while busy");
|
||||
abort();
|
||||
}
|
||||
fclose(handle->f);
|
||||
free(handle->data);
|
||||
|
||||
handle->f = NULL;
|
||||
handle->data = NULL;
|
||||
free(handle);
|
||||
}
|
||||
|
||||
nbio_intf_t nbio_stdio = {
|
||||
nbio_stdio_open,
|
||||
nbio_stdio_begin_read,
|
||||
nbio_stdio_begin_write,
|
||||
nbio_stdio_iterate,
|
||||
nbio_stdio_resize,
|
||||
nbio_stdio_get_ptr,
|
||||
nbio_stdio_cancel,
|
||||
nbio_stdio_free,
|
||||
"nbio_stdio",
|
||||
};
|
||||
|
161
libretro-common/file/nbio/nbio_unixmmap.c
Normal file
161
libretro-common/file/nbio/nbio_unixmmap.c
Normal file
@ -0,0 +1,161 @@
|
||||
/* Copyright (C) 2010-2017 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (nbio_unixmmap.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_MMAP) && defined(BSD)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <file/nbio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
struct nbio_mmap_unix_t
|
||||
{
|
||||
int fd;
|
||||
int map_flags;
|
||||
size_t len;
|
||||
void* ptr;
|
||||
};
|
||||
|
||||
static void *nbio_mmap_unix_open(const char * filename, unsigned mode)
|
||||
{
|
||||
static const int o_flags[] = { O_RDONLY, O_RDWR|O_CREAT|O_TRUNC, O_RDWR, O_RDONLY, O_RDWR|O_CREAT|O_TRUNC };
|
||||
static const int map_flags[] = { PROT_READ, PROT_WRITE|PROT_READ, PROT_WRITE|PROT_READ, PROT_READ, PROT_WRITE|PROT_READ };
|
||||
|
||||
size_t len;
|
||||
void* ptr = NULL;
|
||||
struct nbio_mmap_unix_t* handle = NULL;
|
||||
int fd = open(filename, o_flags[mode]|O_CLOEXEC, 0644);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
len = lseek(fd, 0, SEEK_END);
|
||||
if (len != 0)
|
||||
ptr = mmap(NULL, len, map_flags[mode], MAP_SHARED, fd, 0);
|
||||
|
||||
if (ptr == MAP_FAILED)
|
||||
{
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle = malloc(sizeof(struct nbio_mmap_unix_t));
|
||||
handle->fd = fd;
|
||||
handle->map_flags = map_flags[mode];
|
||||
handle->len = len;
|
||||
handle->ptr = ptr;
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void nbio_mmap_unix_begin_read(void *data)
|
||||
{
|
||||
/* not needed */
|
||||
}
|
||||
|
||||
static void nbio_mmap_unix_begin_write(void *data)
|
||||
{
|
||||
/* not needed */
|
||||
}
|
||||
|
||||
static bool nbio_mmap_unix_iterate(void *data)
|
||||
{
|
||||
return true; /* not needed */
|
||||
}
|
||||
|
||||
static void nbio_mmap_unix_resize(void *data, size_t len)
|
||||
{
|
||||
struct nbio_mmap_unix_t* handle = (struct nbio_mmap_unix_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
if (len < handle->len)
|
||||
{
|
||||
/* this works perfectly fine if this check is removed, but it
|
||||
* won't work on other nbio implementations */
|
||||
/* therefore, it's blocked so nobody accidentally relies on it */
|
||||
puts("ERROR - attempted file shrink operation, not implemented");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (ftruncate(handle->fd, len) != 0)
|
||||
{
|
||||
puts("ERROR - couldn't resize file (ftruncate)");
|
||||
abort(); /* this one returns void and I can't find any other
|
||||
way for it to report failure */
|
||||
}
|
||||
|
||||
munmap(handle->ptr, handle->len);
|
||||
|
||||
handle->ptr = mmap(NULL, len, handle->map_flags, MAP_SHARED, handle->fd, 0);
|
||||
handle->len = len;
|
||||
|
||||
if (handle->ptr == MAP_FAILED)
|
||||
{
|
||||
puts("ERROR - couldn't resize file (mmap)");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void *nbio_mmap_unix_get_ptr(void *data, size_t* len)
|
||||
{
|
||||
struct nbio_mmap_unix_t* handle = (struct nbio_mmap_unix_t*)data;
|
||||
if (!handle)
|
||||
return NULL;
|
||||
if (len)
|
||||
*len = handle->len;
|
||||
return handle->ptr;
|
||||
}
|
||||
|
||||
static void nbio_mmap_unix_cancel(void *data)
|
||||
{
|
||||
/* not needed */
|
||||
}
|
||||
|
||||
static void nbio_mmap_unix_free(void *data)
|
||||
{
|
||||
struct nbio_mmap_unix_t* handle = (struct nbio_mmap_unix_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
close(handle->fd);
|
||||
munmap(handle->ptr, handle->len);
|
||||
free(handle);
|
||||
}
|
||||
|
||||
nbio_intf_t nbio_mmap_unix = {
|
||||
nbio_mmap_unix_open,
|
||||
nbio_mmap_unix_begin_read,
|
||||
nbio_mmap_unix_begin_write,
|
||||
nbio_mmap_unix_iterate,
|
||||
nbio_mmap_unix_resize,
|
||||
nbio_mmap_unix_get_ptr,
|
||||
nbio_mmap_unix_cancel,
|
||||
nbio_mmap_unix_free,
|
||||
"nbio_mmap_unix",
|
||||
};
|
||||
|
||||
#endif
|
186
libretro-common/file/nbio/nbio_windowsmmap.c
Normal file
186
libretro-common/file/nbio/nbio_windowsmmap.c
Normal file
@ -0,0 +1,186 @@
|
||||
/* Copyright (C) 2010-2017 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (nbio_windowsmmap.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <file/nbio.h>
|
||||
#include <encodings/utf.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* Assume W-functions do not work below VC2005 and Xbox platforms */
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX)
|
||||
|
||||
#ifndef LEGACY_WIN32
|
||||
#define LEGACY_WIN32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef FILE_SHARE_ALL
|
||||
#define FILE_SHARE_ALL (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE)
|
||||
#endif
|
||||
|
||||
struct nbio_mmap_win32_t
|
||||
{
|
||||
HANDLE file;
|
||||
bool is_write;
|
||||
size_t len;
|
||||
void* ptr;
|
||||
};
|
||||
|
||||
static void *nbio_mmap_win32_open(const char * filename, unsigned mode)
|
||||
{
|
||||
static const DWORD dispositions[] = { OPEN_EXISTING, CREATE_ALWAYS, OPEN_ALWAYS, OPEN_EXISTING, CREATE_ALWAYS };
|
||||
HANDLE mem;
|
||||
LARGE_INTEGER len;
|
||||
struct nbio_mmap_win32_t* handle = NULL;
|
||||
void* ptr = NULL;
|
||||
bool is_write = (mode == NBIO_WRITE || mode == NBIO_UPDATE || mode == BIO_WRITE);
|
||||
DWORD access = (is_write ? GENERIC_READ|GENERIC_WRITE : GENERIC_READ);
|
||||
#if !defined(_WIN32) || defined(LEGACY_WIN32)
|
||||
HANDLE file = CreateFile(filename, access, FILE_SHARE_ALL, NULL, dispositions[mode], FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#else
|
||||
wchar_t *filename_wide = utf8_to_utf16_string_alloc(filename);
|
||||
HANDLE file = CreateFileW(filename_wide, access, FILE_SHARE_ALL, NULL, dispositions[mode], FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (filename_wide)
|
||||
free(filename_wide);
|
||||
#endif
|
||||
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
return NULL;
|
||||
|
||||
GetFileSizeEx(file, &len);
|
||||
|
||||
mem = CreateFileMapping(file, NULL, is_write ? PAGE_READWRITE : PAGE_READONLY, 0, 0, NULL);
|
||||
ptr = MapViewOfFile(mem, is_write ? (FILE_MAP_READ|FILE_MAP_WRITE) : FILE_MAP_READ, 0, 0, len.QuadPart);
|
||||
CloseHandle(mem);
|
||||
|
||||
handle = malloc(sizeof(struct nbio_mmap_win32_t));
|
||||
|
||||
handle->file = file;
|
||||
handle->is_write = is_write;
|
||||
handle->len = len.QuadPart;
|
||||
handle->ptr = ptr;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void nbio_mmap_win32_begin_read(void *data)
|
||||
{
|
||||
/* not needed */
|
||||
}
|
||||
|
||||
static void nbio_mmap_win32_begin_write(void *data)
|
||||
{
|
||||
/* not needed */
|
||||
}
|
||||
|
||||
static bool nbio_mmap_win32_iterate(void *data)
|
||||
{
|
||||
/* not needed */
|
||||
return true;
|
||||
}
|
||||
|
||||
static void nbio_mmap_win32_resize(void *data, size_t len)
|
||||
{
|
||||
LARGE_INTEGER len_li;
|
||||
HANDLE mem;
|
||||
struct nbio_mmap_win32_t* handle = (struct nbio_mmap_win32_t*)data;
|
||||
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (len < handle->len)
|
||||
{
|
||||
/* this works perfectly fine if this check is removed,
|
||||
* but it won't work on other nbio implementations */
|
||||
/* therefore, it's blocked so nobody accidentally
|
||||
* relies on it. */
|
||||
puts("ERROR - attempted file shrink operation, not implemented");
|
||||
abort();
|
||||
}
|
||||
|
||||
len_li.QuadPart = len;
|
||||
SetFilePointerEx(handle->file, len_li, NULL, FILE_BEGIN);
|
||||
|
||||
if (!SetEndOfFile(handle->file))
|
||||
{
|
||||
puts("ERROR - couldn't resize file (SetEndOfFile)");
|
||||
abort(); /* this one returns void and I can't find any other way for it to report failure */
|
||||
}
|
||||
handle->len = len;
|
||||
|
||||
UnmapViewOfFile(handle->ptr);
|
||||
mem = CreateFileMapping(handle->file, NULL, handle->is_write ? PAGE_READWRITE : PAGE_READONLY, 0, 0, NULL);
|
||||
handle->ptr = MapViewOfFile(mem, handle->is_write ? (FILE_MAP_READ|FILE_MAP_WRITE) : FILE_MAP_READ, 0, 0, len);
|
||||
CloseHandle(mem);
|
||||
|
||||
if (!handle->ptr)
|
||||
{
|
||||
puts("ERROR - couldn't resize file (MapViewOfFile)");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void *nbio_mmap_win32_get_ptr(void *data, size_t* len)
|
||||
{
|
||||
struct nbio_mmap_win32_t* handle = (struct nbio_mmap_win32_t*)data;
|
||||
if (!handle)
|
||||
return NULL;
|
||||
if (len)
|
||||
*len = handle->len;
|
||||
return handle->ptr;
|
||||
}
|
||||
|
||||
static void nbio_mmap_win32_cancel(void *data)
|
||||
{
|
||||
/* not needed */
|
||||
}
|
||||
|
||||
static void nbio_mmap_win32_free(void *data)
|
||||
{
|
||||
struct nbio_mmap_win32_t* handle = (struct nbio_mmap_win32_t*)data;
|
||||
if (!handle)
|
||||
return;
|
||||
CloseHandle(handle->file);
|
||||
UnmapViewOfFile(handle->ptr);
|
||||
free(handle);
|
||||
}
|
||||
|
||||
nbio_intf_t nbio_mmap_win32 = {
|
||||
nbio_mmap_win32_open,
|
||||
nbio_mmap_win32_begin_read,
|
||||
nbio_mmap_win32_begin_write,
|
||||
nbio_mmap_win32_iterate,
|
||||
nbio_mmap_win32_resize,
|
||||
nbio_mmap_win32_get_ptr,
|
||||
nbio_mmap_win32_cancel,
|
||||
nbio_mmap_win32_free,
|
||||
"nbio_mmap_win32",
|
||||
};
|
||||
|
||||
#endif
|
@ -999,8 +999,6 @@ bool rpng_iterate_image(rpng_t *rpng)
|
||||
if (!read_chunk_header(buf, &chunk))
|
||||
return false;
|
||||
|
||||
*buf += 8;
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
|
@ -52,6 +52,8 @@ size_t strlcat(char *dest, const char *source, size_t size);
|
||||
|
||||
#endif
|
||||
|
||||
char *strldup(const char *s, size_t n);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
@ -42,6 +42,7 @@ RETRO_BEGIN_DECLS
|
||||
#define NBIO_UPDATE 2
|
||||
#endif
|
||||
|
||||
/* these two are blocking; nbio_iterate always returns true, but that operation (or something earlier) may take arbitrarily long */
|
||||
#ifndef BIO_READ
|
||||
#define BIO_READ 3
|
||||
#endif
|
||||
@ -50,52 +51,73 @@ RETRO_BEGIN_DECLS
|
||||
#define BIO_WRITE 4
|
||||
#endif
|
||||
|
||||
struct nbio_t;
|
||||
typedef struct nbio_intf
|
||||
{
|
||||
void *(*open)(const char * filename, unsigned mode);
|
||||
|
||||
void (*begin_read)(void *data);
|
||||
|
||||
void (*begin_write)(void *data);
|
||||
|
||||
bool (*iterate)(void *data);
|
||||
|
||||
void (*resize)(void *data, size_t len);
|
||||
|
||||
void *(*get_ptr)(void *data, size_t* len);
|
||||
|
||||
void (*cancel)(void *data);
|
||||
|
||||
void (*free)(void *data);
|
||||
|
||||
/* Human readable string. */
|
||||
const char *ident;
|
||||
} nbio_intf_t;
|
||||
|
||||
/*
|
||||
* Creates an nbio structure for performing the given operation on the given file.
|
||||
* Creates an nbio structure for performing the
|
||||
* given operation on the given file.
|
||||
*/
|
||||
struct nbio_t* nbio_open(const char * filename, unsigned mode);
|
||||
void *nbio_open(const char * filename, unsigned mode);
|
||||
|
||||
/*
|
||||
* Starts reading the given file. When done, it will be available in nbio_get_ptr.
|
||||
* Can not be done if the structure was created with nbio_write.
|
||||
* Can not be done if the structure was created with {N,}BIO_WRITE.
|
||||
*/
|
||||
void nbio_begin_read(struct nbio_t* handle);
|
||||
void nbio_begin_read(void *data);
|
||||
|
||||
/*
|
||||
* Starts writing to the given file. Before this, you should've copied the data to nbio_get_ptr.
|
||||
* Can not be done if the structure was created with nbio_read.
|
||||
* Can not be done if the structure was created with {N,}BIO_READ.
|
||||
*/
|
||||
void nbio_begin_write(struct nbio_t* handle);
|
||||
void nbio_begin_write(void *data);
|
||||
|
||||
/*
|
||||
* Performs part of the requested operation, or checks how it's going.
|
||||
* When it returns true, it's done.
|
||||
*/
|
||||
bool nbio_iterate(struct nbio_t* handle);
|
||||
bool nbio_iterate(void *data);
|
||||
|
||||
/*
|
||||
* Resizes the file up to the given size; cannot shrink.
|
||||
* Can not be done if the structure was created with nbio_read.
|
||||
* Can not be done if the structure was created with {N,}BIO_READ.
|
||||
*/
|
||||
void nbio_resize(struct nbio_t* handle, size_t len);
|
||||
void nbio_resize(void *data, size_t len);
|
||||
|
||||
/*
|
||||
* Returns a pointer to the file data. Writable only if structure was not created with nbio_read.
|
||||
* Returns a pointer to the file data. Writable only if structure was not created with {N,}BIO_READ.
|
||||
* If any operation is in progress, the pointer will be NULL, but len will still be correct.
|
||||
*/
|
||||
void* nbio_get_ptr(struct nbio_t* handle, size_t* len);
|
||||
void* nbio_get_ptr(void *data, size_t* len);
|
||||
|
||||
/*
|
||||
* Stops any pending operation, allowing the object to be freed.
|
||||
*/
|
||||
void nbio_cancel(struct nbio_t* handle);
|
||||
void nbio_cancel(void *data);
|
||||
|
||||
/*
|
||||
* Deletes the nbio structure and its associated pointer.
|
||||
*/
|
||||
void nbio_free(struct nbio_t* handle);
|
||||
void nbio_free(void *data);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
|
@ -131,11 +131,12 @@ extern "C" {
|
||||
#define RETRO_DEVICE_LIGHTGUN 4
|
||||
|
||||
/* The ANALOG device is an extension to JOYPAD (RetroPad).
|
||||
* Similar to DualShock it adds two analog sticks.
|
||||
* This is treated as a separate device type as it returns values in the
|
||||
* full analog range of [-0x8000, 0x7fff]. Positive X axis is right.
|
||||
* Positive Y axis is down.
|
||||
* Only use ANALOG type when polling for analog values of the axes.
|
||||
* Similar to DualShock2 it adds two analog sticks and all buttons can
|
||||
* be analog. This is treated as a separate device type as it returns
|
||||
* axis values in the full analog range of [-0x8000, 0x7fff].
|
||||
* Positive X axis is right. Positive Y axis is down.
|
||||
* Buttons are returned in the range [0, 0x7fff].
|
||||
* Only use ANALOG type when polling for analog values.
|
||||
*/
|
||||
#define RETRO_DEVICE_ANALOG 5
|
||||
|
||||
@ -174,7 +175,8 @@ extern "C" {
|
||||
/* Buttons for the RetroPad (JOYPAD).
|
||||
* The placement of these is equivalent to placements on the
|
||||
* Super Nintendo controller.
|
||||
* L2/R2/L3/R3 buttons correspond to the PS1 DualShock. */
|
||||
* L2/R2/L3/R3 buttons correspond to the PS1 DualShock.
|
||||
* Also used as id values for RETRO_DEVICE_INDEX_ANALOG_BUTTON */
|
||||
#define RETRO_DEVICE_ID_JOYPAD_B 0
|
||||
#define RETRO_DEVICE_ID_JOYPAD_Y 1
|
||||
#define RETRO_DEVICE_ID_JOYPAD_SELECT 2
|
||||
@ -193,10 +195,11 @@ extern "C" {
|
||||
#define RETRO_DEVICE_ID_JOYPAD_R3 15
|
||||
|
||||
/* Index / Id values for ANALOG device. */
|
||||
#define RETRO_DEVICE_INDEX_ANALOG_LEFT 0
|
||||
#define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1
|
||||
#define RETRO_DEVICE_ID_ANALOG_X 0
|
||||
#define RETRO_DEVICE_ID_ANALOG_Y 1
|
||||
#define RETRO_DEVICE_INDEX_ANALOG_LEFT 0
|
||||
#define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1
|
||||
#define RETRO_DEVICE_INDEX_ANALOG_BUTTON 2
|
||||
#define RETRO_DEVICE_ID_ANALOG_X 0
|
||||
#define RETRO_DEVICE_ID_ANALOG_Y 1
|
||||
|
||||
/* Id values for MOUSE. */
|
||||
#define RETRO_DEVICE_ID_MOUSE_X 0
|
||||
@ -208,6 +211,8 @@ extern "C" {
|
||||
#define RETRO_DEVICE_ID_MOUSE_MIDDLE 6
|
||||
#define RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP 7
|
||||
#define RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN 8
|
||||
#define RETRO_DEVICE_ID_MOUSE_BUTTON_4 9
|
||||
#define RETRO_DEVICE_ID_MOUSE_BUTTON_5 10
|
||||
|
||||
/* Id values for LIGHTGUN types. */
|
||||
#define RETRO_DEVICE_ID_LIGHTGUN_X 0
|
||||
|
@ -56,7 +56,17 @@ void filestream_set_size(RFILE *stream);
|
||||
|
||||
const char *filestream_get_ext(RFILE *stream);
|
||||
|
||||
RFILE *filestream_open(const char *path, unsigned mode, ssize_t len);
|
||||
/**
|
||||
* filestream_open:
|
||||
* @path : path to file
|
||||
* @mode : file mode to use when opening (read/write)
|
||||
* @bufsize : optional buffer size (-1 or 0 to use default)
|
||||
*
|
||||
* Opens a file for reading or writing, depending on the requested mode.
|
||||
* If bufsize is > 0 for unbuffered modes (like RFILE_MODE_WRITE), file will instead be fully buffered.
|
||||
* Returns a pointer to an RFILE if opened successfully, otherwise NULL.
|
||||
**/
|
||||
RFILE *filestream_open(const char *path, unsigned mode, ssize_t bufsize);
|
||||
|
||||
ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence);
|
||||
|
||||
|
@ -48,7 +48,8 @@
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
void* mmap(void *addr, size_t len, int prot, int flags, int fildes, size_t offset)
|
||||
void* mmap(void *addr, size_t len, int prot, int flags,
|
||||
int fildes, size_t offset)
|
||||
{
|
||||
void *map = (void*)NULL;
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
@ -57,36 +58,34 @@ void* mmap(void *addr, size_t len, int prot, int flags, int fildes, size_t offse
|
||||
{
|
||||
case PROT_READ:
|
||||
default:
|
||||
{
|
||||
handle = CreateFileMapping((HANDLE) _get_osfhandle(fildes), 0, PAGE_READONLY, 0,
|
||||
len, 0);
|
||||
if (!handle)
|
||||
break;
|
||||
map = (void*)MapViewOfFile(handle, FILE_MAP_READ, 0, 0, len);
|
||||
CloseHandle(handle);
|
||||
handle = CreateFileMapping((HANDLE)
|
||||
_get_osfhandle(fildes), 0, PAGE_READONLY, 0,
|
||||
len, 0);
|
||||
if (!handle)
|
||||
break;
|
||||
}
|
||||
map = (void*)MapViewOfFile(handle, FILE_MAP_READ, 0, 0, len);
|
||||
CloseHandle(handle);
|
||||
break;
|
||||
case PROT_WRITE:
|
||||
{
|
||||
handle = CreateFileMapping((HANDLE) _get_osfhandle(fildes),0,PAGE_READWRITE,0,
|
||||
len, 0);
|
||||
if (!handle)
|
||||
break;
|
||||
map = (void*)MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, len);
|
||||
CloseHandle(handle);
|
||||
handle = CreateFileMapping((HANDLE)
|
||||
_get_osfhandle(fildes),0,PAGE_READWRITE,0,
|
||||
len, 0);
|
||||
if (!handle)
|
||||
break;
|
||||
}
|
||||
map = (void*)MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, len);
|
||||
CloseHandle(handle);
|
||||
break;
|
||||
case PROT_READWRITE:
|
||||
{
|
||||
handle = CreateFileMapping((HANDLE) _get_osfhandle(fildes),0,PAGE_READWRITE,0,
|
||||
len, 0);
|
||||
if (!handle)
|
||||
break;
|
||||
map = (void*)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, len);
|
||||
CloseHandle(handle);
|
||||
handle = CreateFileMapping((HANDLE)
|
||||
_get_osfhandle(fildes),0,PAGE_READWRITE,0,
|
||||
len, 0);
|
||||
if (!handle)
|
||||
break;
|
||||
}
|
||||
map = (void*)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, len);
|
||||
CloseHandle(handle);
|
||||
break;
|
||||
}
|
||||
|
||||
if (map == (void*)NULL)
|
||||
return((void*)MAP_FAILED);
|
||||
return((void*) ((int8_t*)map + offset));
|
||||
@ -110,7 +109,8 @@ int mprotect(void *addr, size_t len, int prot)
|
||||
}
|
||||
|
||||
#elif !defined(HAVE_MMAN)
|
||||
void* mmap(void *addr, size_t len, int prot, int flags, int fildes, size_t offset)
|
||||
void* mmap(void *addr, size_t len, int prot, int flags,
|
||||
int fildes, size_t offset)
|
||||
{
|
||||
return malloc(len);
|
||||
}
|
||||
@ -123,7 +123,8 @@ int munmap(void *addr, size_t len)
|
||||
|
||||
int mprotect(void *addr, size_t len, int prot)
|
||||
{
|
||||
/* stub - not really needed at this point since this codepath has no dynarecs */
|
||||
/* stub - not really needed at this point
|
||||
* since this codepath has no dynarecs. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@ static void nbio_write_test(void)
|
||||
bool looped = false;
|
||||
void* ptr = NULL;
|
||||
struct nbio_t* write = nbio_open("test.bin", NBIO_WRITE);
|
||||
if (!write)
|
||||
puts("ERROR: nbio_open failed (1)");
|
||||
|
||||
nbio_resize(write, 1024*1024);
|
||||
|
||||
@ -33,6 +35,8 @@ static void nbio_read_test(void)
|
||||
bool looped = false;
|
||||
struct nbio_t* read = nbio_open("test.bin", NBIO_READ);
|
||||
void* ptr = nbio_get_ptr(read, &size);
|
||||
if (!read)
|
||||
puts("ERROR: nbio_open failed (2)");
|
||||
|
||||
if (size != 1024*1024)
|
||||
puts("ERROR: wrong size (2)");
|
||||
|
@ -18,14 +18,18 @@ SOURCES_C := \
|
||||
$(LIBRETRO_PNG_DIR)/rpng.c \
|
||||
$(LIBRETRO_PNG_DIR)/rpng_encode.c \
|
||||
$(LIBRETRO_COMM_DIR)/encodings/encoding_crc32.c \
|
||||
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.c \
|
||||
$(LIBRETRO_COMM_DIR)/string/stdstring.c \
|
||||
$(LIBRETRO_COMM_DIR)/compat/compat_strl.c \
|
||||
$(LIBRETRO_COMM_DIR)/compat/compat_strcasestr.c \
|
||||
$(LIBRETRO_COMM_DIR)/file/nbio/nbio_stdio.c \
|
||||
$(LIBRETRO_COMM_DIR)/file/archive_file.c \
|
||||
$(LIBRETRO_COMM_DIR)/file/archive_file_zlib.c \
|
||||
$(LIBRETRO_COMM_DIR)//file/file_path.c \
|
||||
$(LIBRETRO_COMM_DIR)//file/retro_stat.c \
|
||||
$(LIBRETRO_COMM_DIR)/file/file_path.c \
|
||||
$(LIBRETRO_COMM_DIR)/streams/file_stream.c \
|
||||
$(LIBRETRO_COMM_DIR)/streams/trans_stream.c \
|
||||
$(LIBRETRO_COMM_DIR)/streams/trans_stream_zlib.c \
|
||||
$(LIBRETRO_COMM_DIR)/streams/trans_stream_pipe.c \
|
||||
$(LIBRETRO_COMM_DIR)/lists/string_list.c
|
||||
|
||||
OBJS := $(SOURCES_C:.c=.o)
|
||||
|
@ -25,6 +25,10 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
# ifdef _MSC_VER
|
||||
# define setmode _setmode
|
||||
@ -107,6 +111,7 @@ struct RFILE
|
||||
#endif
|
||||
int fd;
|
||||
#endif
|
||||
char *buf;
|
||||
};
|
||||
|
||||
FILE* filestream_get_fp(RFILE *stream)
|
||||
@ -154,7 +159,17 @@ void filestream_set_size(RFILE *stream)
|
||||
filestream_seek(stream, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
|
||||
/**
|
||||
* filestream_open:
|
||||
* @path : path to file
|
||||
* @mode : file mode to use when opening (read/write)
|
||||
* @bufsize : optional buffer size (-1 or 0 to use default)
|
||||
*
|
||||
* Opens a file for reading or writing, depending on the requested mode.
|
||||
* If bufsize is > 0 for unbuffered modes (like RFILE_MODE_WRITE), file will instead be fully buffered.
|
||||
* Returns a pointer to an RFILE if opened successfully, otherwise NULL.
|
||||
**/
|
||||
RFILE *filestream_open(const char *path, unsigned mode, ssize_t bufsize)
|
||||
{
|
||||
int flags = 0;
|
||||
int mode_int = 0;
|
||||
@ -254,6 +269,9 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
|
||||
|
||||
#if defined(PSP)
|
||||
stream->fd = sceIoOpen(path, flags, mode_int);
|
||||
|
||||
if (stream->fd == -1)
|
||||
goto error;
|
||||
#else
|
||||
#if defined(HAVE_BUFFERED_IO)
|
||||
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0 && mode_str)
|
||||
@ -275,13 +293,28 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
|
||||
#else
|
||||
stream->fp = fopen(path, mode_str);
|
||||
#endif
|
||||
|
||||
if (!stream->fp)
|
||||
goto error;
|
||||
|
||||
if (bufsize > 0)
|
||||
{
|
||||
/* Regarding setvbuf:
|
||||
*
|
||||
* https://www.freebsd.org/cgi/man.cgi?query=setvbuf&apropos=0&sektion=0&manpath=FreeBSD+11.1-RELEASE&arch=default&format=html
|
||||
*
|
||||
* If the size argument is not zero but buf is NULL, a buffer of the given size will be allocated immediately, and
|
||||
* released on close. This is an extension to ANSI C.
|
||||
*
|
||||
* Since C89 does not support specifying a null buffer with a non-zero size, we create and track our own buffer for it.
|
||||
*/
|
||||
stream->buf = (char*)calloc(1, bufsize);
|
||||
setvbuf(stream->fp, stream->buf, _IOFBF, bufsize);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* FIXME: HAVE_BUFFERED_IO is always 1, but if it is ever changed, open() needs to be changed to _wopen() for WIndows. */
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#if defined(LEGACY_WIN32)
|
||||
(void)path_wide;
|
||||
@ -297,8 +330,10 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
|
||||
free(path_wide);
|
||||
#endif
|
||||
#else
|
||||
/* FIXME: HAVE_BUFFERED_IO is always 1, but if it is ever changed, this open() needs to have an alternate _wopen() for Windows. */
|
||||
stream->fd = open(path, flags, mode_int);
|
||||
#endif
|
||||
|
||||
if (stream->fd == -1)
|
||||
goto error;
|
||||
#ifdef HAVE_MMAP
|
||||
@ -323,11 +358,6 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PSP)
|
||||
if (stream->fd == -1)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
{
|
||||
const char *ld = (const char*)strrchr(path, '.');
|
||||
if (ld)
|
||||
@ -666,6 +696,8 @@ int filestream_close(RFILE *stream)
|
||||
if (stream->fd > 0)
|
||||
close(stream->fd);
|
||||
#endif
|
||||
if (stream->buf)
|
||||
free(stream->buf);
|
||||
free(stream);
|
||||
|
||||
return 0;
|
||||
|
@ -186,7 +186,7 @@ static struct rmsgpack_read_callbacks stub_callbacks = {
|
||||
int main(void)
|
||||
{
|
||||
struct stub_state state;
|
||||
RFILE *fd = filestream_open("test.msgpack", RFILE_MODE_READ, 0);
|
||||
RFILE *fd = filestream_open("test.msgpack", RFILE_MODE_READ, -1);
|
||||
|
||||
state.i = 0;
|
||||
state.stack[0] = 0;
|
||||
|
@ -78,11 +78,6 @@ static int deferred_push_achievement_list(menu_displaylist_info_t *info)
|
||||
return deferred_push_dlist(info, DISPLAYLIST_ACHIEVEMENT_LIST);
|
||||
}
|
||||
|
||||
static int deferred_push_achievement_list_hardcore(menu_displaylist_info_t *info)
|
||||
{
|
||||
return deferred_push_dlist(info, DISPLAYLIST_ACHIEVEMENT_LIST_HARDCORE);
|
||||
}
|
||||
|
||||
static int deferred_push_rdb_collection(menu_displaylist_info_t *info)
|
||||
{
|
||||
return deferred_push_dlist(info, DISPLAYLIST_PLAYLIST_COLLECTION);
|
||||
@ -1533,9 +1528,6 @@ static int menu_cbs_init_bind_deferred_push_compare_label(
|
||||
case MENU_ENUM_LABEL_ACHIEVEMENT_LIST:
|
||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_achievement_list);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_ACHIEVEMENT_LIST_HARDCORE:
|
||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_achievement_list_hardcore);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_CORE_COUNTERS:
|
||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_core_counters);
|
||||
break;
|
||||
@ -1768,9 +1760,6 @@ static int menu_cbs_init_bind_deferred_push_compare_label(
|
||||
case MENU_LABEL_ACHIEVEMENT_LIST:
|
||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_achievement_list);
|
||||
break;
|
||||
case MENU_LABEL_ACHIEVEMENT_LIST_HARDCORE:
|
||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_achievement_list_hardcore);
|
||||
break;
|
||||
case MENU_LABEL_CORE_COUNTERS:
|
||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_core_counters);
|
||||
break;
|
||||
|
@ -94,6 +94,21 @@ static void menu_action_setting_disp_set_label_cheevos_unlocked_entry(
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY), len);
|
||||
}
|
||||
|
||||
static void menu_action_setting_disp_set_label_cheevos_unlocked_entry_hardcore(
|
||||
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)
|
||||
{
|
||||
*w = 19;
|
||||
strlcpy(s2, path, len2);
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY_HARDCORE), len);
|
||||
}
|
||||
|
||||
static void menu_action_setting_disp_set_label_remap_file_load(
|
||||
file_list_t* list,
|
||||
unsigned *w, unsigned type, unsigned i,
|
||||
@ -741,6 +756,10 @@ static void menu_action_setting_disp_set_label_xmb_theme(
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE), len);
|
||||
break;
|
||||
case XMB_ICON_THEME_RETROSYSTEM:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM), len);
|
||||
break;
|
||||
case XMB_ICON_THEME_PIXEL:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL), len);
|
||||
@ -1972,6 +1991,10 @@ int menu_cbs_init_bind_get_string_representation(menu_file_list_cbs_t *cbs,
|
||||
BIND_ACTION_GET_VALUE(cbs,
|
||||
menu_action_setting_disp_set_label_cheevos_unlocked_entry);
|
||||
return 0;
|
||||
case MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY_HARDCORE:
|
||||
BIND_ACTION_GET_VALUE(cbs,
|
||||
menu_action_setting_disp_set_label_cheevos_unlocked_entry_hardcore);
|
||||
return 0;
|
||||
case MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY:
|
||||
BIND_ACTION_GET_VALUE(cbs,
|
||||
menu_action_setting_disp_set_label_cheevos_locked_entry);
|
||||
|
@ -1443,6 +1443,7 @@ static int action_ok_file_load(const char *path,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int action_ok_playlist_entry_collection(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
@ -1506,7 +1507,6 @@ static int action_ok_playlist_entry_collection(const char *path,
|
||||
&& string_is_equal(core_name, file_path_str(FILE_PATH_DETECT)))
|
||||
{
|
||||
core_info_ctx_find_t core_info;
|
||||
char new_display_name[PATH_MAX_LENGTH];
|
||||
const char *entry_path = NULL;
|
||||
const char *path_base =
|
||||
path_basename(menu->db_playlist_file);
|
||||
@ -1514,8 +1514,6 @@ static int action_ok_playlist_entry_collection(const char *path,
|
||||
menu_content_playlist_find_associated_core(
|
||||
path_base, new_core_path, sizeof(new_core_path));
|
||||
|
||||
new_display_name[0] = '\0';
|
||||
|
||||
core_info.inf = NULL;
|
||||
core_info.path = new_core_path;
|
||||
|
||||
@ -1535,29 +1533,23 @@ static int action_ok_playlist_entry_collection(const char *path,
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist);
|
||||
|
||||
strlcpy(new_display_name,
|
||||
core_info.inf->display_name, sizeof(new_display_name));
|
||||
playlist_update(tmp_playlist,
|
||||
command_playlist_update_write(tmp_playlist,
|
||||
selection_ptr,
|
||||
core_info.inf->display_name,
|
||||
NULL,
|
||||
NULL,
|
||||
new_core_path,
|
||||
new_display_name,
|
||||
NULL,
|
||||
NULL);
|
||||
playlist_write_file(tmp_playlist);
|
||||
new_core_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
strlcpy(new_core_path, core_path, sizeof(new_core_path));
|
||||
}
|
||||
|
||||
playlist_info.data = playlist;
|
||||
playlist_info.idx = (unsigned)selection_ptr;
|
||||
|
||||
if (!menu_content_playlist_load(&playlist_info))
|
||||
{
|
||||
runloop_msg_queue_push("File could not be loaded from playlist.\n", 1, 100, true);
|
||||
runloop_msg_queue_push(
|
||||
"File could not be loaded from playlist.\n",
|
||||
1, 100, true);
|
||||
return menu_cbs_exit();
|
||||
}
|
||||
|
||||
@ -1566,7 +1558,7 @@ static int action_ok_playlist_entry_collection(const char *path,
|
||||
|
||||
|
||||
if (!task_push_load_content_from_playlist_from_menu(
|
||||
new_core_path, path,
|
||||
new_core_path, path, entry_label,
|
||||
&content_info,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
@ -1582,9 +1574,9 @@ static int action_ok_playlist_entry(const char *path,
|
||||
size_t selection_ptr = 0;
|
||||
playlist_t *playlist = g_defaults.content_history;
|
||||
const char *entry_path = NULL;
|
||||
const char *entry_label = NULL;
|
||||
const char *core_path = NULL;
|
||||
const char *core_name = NULL;
|
||||
playlist_t *tmp_playlist = NULL;
|
||||
menu_handle_t *menu = NULL;
|
||||
|
||||
content_info.argc = 0;
|
||||
@ -1598,14 +1590,13 @@ static int action_ok_playlist_entry(const char *path,
|
||||
selection_ptr = entry_idx;
|
||||
|
||||
playlist_get_index(playlist, selection_ptr,
|
||||
&entry_path, NULL, &core_path, &core_name, NULL, NULL);
|
||||
&entry_path, &entry_label, &core_path, &core_name, NULL, NULL);
|
||||
|
||||
if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT))
|
||||
&& string_is_equal(core_name, file_path_str(FILE_PATH_DETECT)))
|
||||
{
|
||||
core_info_ctx_find_t core_info;
|
||||
char new_core_path[PATH_MAX_LENGTH];
|
||||
char *new_display_name = NULL;
|
||||
const char *entry_path = NULL;
|
||||
const char *path_base =
|
||||
path_basename(menu->db_playlist_file);
|
||||
@ -1629,21 +1620,11 @@ static int action_ok_playlist_entry(const char *path,
|
||||
return action_ok_file_load_with_detect_core(entry_path,
|
||||
label, type, selection_ptr, entry_idx);
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist);
|
||||
|
||||
new_display_name = strdup(core_info.inf->display_name);
|
||||
|
||||
playlist_update(tmp_playlist,
|
||||
command_playlist_update_write(NULL,
|
||||
selection_ptr,
|
||||
core_info.inf->display_name,
|
||||
NULL,
|
||||
NULL,
|
||||
new_core_path,
|
||||
new_display_name,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
free(new_display_name);
|
||||
playlist_write_file(tmp_playlist);
|
||||
new_core_path);
|
||||
}
|
||||
|
||||
playlist_info.data = playlist;
|
||||
@ -1662,7 +1643,7 @@ static int action_ok_playlist_entry(const char *path,
|
||||
NULL, NULL);
|
||||
|
||||
if (!task_push_load_content_from_playlist_from_menu(
|
||||
core_path, path,
|
||||
core_path, path, entry_label,
|
||||
&content_info,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
@ -1679,6 +1660,7 @@ static int action_ok_playlist_entry_start_content(const char *path,
|
||||
bool playlist_initialized = false;
|
||||
playlist_t *playlist = NULL;
|
||||
const char *entry_path = NULL;
|
||||
const char *entry_label = NULL;
|
||||
const char *core_path = NULL;
|
||||
const char *core_name = NULL;
|
||||
playlist_t *tmp_playlist = NULL;
|
||||
@ -1708,20 +1690,19 @@ static int action_ok_playlist_entry_start_content(const char *path,
|
||||
selection_ptr = rdb_entry_start_game_selection_ptr;
|
||||
|
||||
playlist_get_index(playlist, selection_ptr,
|
||||
&entry_path, NULL, &core_path, &core_name, NULL, NULL);
|
||||
&entry_path, &entry_label, &core_path, &core_name, NULL, NULL);
|
||||
|
||||
if ( string_is_equal(core_path, file_path_str(FILE_PATH_DETECT))
|
||||
&& string_is_equal(core_name, file_path_str(FILE_PATH_DETECT)))
|
||||
{
|
||||
core_info_ctx_find_t core_info;
|
||||
char new_core_path[PATH_MAX_LENGTH];
|
||||
char new_display_name[PATH_MAX_LENGTH];
|
||||
const char *entry_path = NULL;
|
||||
const char *path_base =
|
||||
path_basename(menu->db_playlist_file);
|
||||
bool found_associated_core = false;
|
||||
|
||||
new_core_path[0] = new_display_name[0] = '\0';
|
||||
new_core_path[0] = '\0';
|
||||
|
||||
found_associated_core =
|
||||
menu_content_playlist_find_associated_core(
|
||||
@ -1746,17 +1727,12 @@ static int action_ok_playlist_entry_start_content(const char *path,
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist);
|
||||
|
||||
strlcpy(new_display_name,
|
||||
core_info.inf->display_name, sizeof(new_display_name));
|
||||
playlist_update(tmp_playlist,
|
||||
command_playlist_update_write(
|
||||
tmp_playlist,
|
||||
selection_ptr,
|
||||
core_info.inf->display_name,
|
||||
NULL,
|
||||
NULL,
|
||||
new_core_path,
|
||||
new_display_name,
|
||||
NULL,
|
||||
NULL);
|
||||
playlist_write_file(tmp_playlist);
|
||||
new_core_path);
|
||||
}
|
||||
|
||||
playlist_info.data = playlist;
|
||||
@ -1772,7 +1748,7 @@ static int action_ok_playlist_entry_start_content(const char *path,
|
||||
playlist_info.idx, &path, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!task_push_load_content_from_playlist_from_menu(
|
||||
core_path, path,
|
||||
core_path, path, entry_label,
|
||||
&content_info,
|
||||
NULL, NULL))
|
||||
return -1;
|
||||
@ -1828,15 +1804,12 @@ static int action_ok_audio_add_to_mixer_and_collection(const char *path,
|
||||
fill_pathname_join(combined_path, menu->scratch2_buf,
|
||||
menu->scratch_buf, sizeof(combined_path));
|
||||
|
||||
playlist_push(g_defaults.music_history,
|
||||
command_playlist_push_write(
|
||||
g_defaults.music_history,
|
||||
combined_path,
|
||||
NULL,
|
||||
"builtin",
|
||||
"musicplayer",
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
playlist_write_file(g_defaults.music_history);
|
||||
"musicplayer");
|
||||
|
||||
if(path_file_exists(combined_path))
|
||||
task_push_audio_mixer_load(combined_path,
|
||||
@ -1929,25 +1902,11 @@ static void menu_input_st_string_cb_rename_entry(void *userdata,
|
||||
const char *label = menu_input_dialog_get_buffer();
|
||||
|
||||
if (!string_is_empty(label))
|
||||
{
|
||||
playlist_t *tmp_playlist = NULL;
|
||||
size_t new_selection_ptr = menu_input_dialog_get_kb_idx();
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist);
|
||||
|
||||
if (tmp_playlist)
|
||||
{
|
||||
playlist_update(tmp_playlist,
|
||||
new_selection_ptr,
|
||||
NULL,
|
||||
label,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
playlist_write_file(tmp_playlist);
|
||||
}
|
||||
}
|
||||
command_playlist_update_write(NULL,
|
||||
menu_input_dialog_get_kb_idx(),
|
||||
NULL,
|
||||
label,
|
||||
NULL);
|
||||
}
|
||||
|
||||
menu_input_dialog_end();
|
||||
@ -2316,26 +2275,14 @@ static int action_ok_core_deferred_set(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
char core_display_name[PATH_MAX_LENGTH];
|
||||
playlist_t *playlist = NULL;
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
|
||||
core_display_name[0] = '\0';
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist);
|
||||
|
||||
retro_assert(playlist != NULL);
|
||||
|
||||
core_info_get_name(path, core_display_name, sizeof(core_display_name));
|
||||
|
||||
idx = rdb_entry_start_game_selection_ptr;
|
||||
|
||||
playlist_update(playlist, idx,
|
||||
NULL, NULL,
|
||||
path, core_display_name,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
playlist_write_file(playlist);
|
||||
command_playlist_update_write(NULL,
|
||||
rdb_entry_start_game_selection_ptr,
|
||||
core_display_name, NULL, path);
|
||||
|
||||
menu_entries_pop_stack(&selection, 0, 1);
|
||||
menu_navigation_set_selection(selection);
|
||||
@ -2347,26 +2294,14 @@ static int action_ok_core_deferred_set_current_core(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
char core_display_name[PATH_MAX_LENGTH];
|
||||
playlist_t *playlist = NULL;
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
|
||||
core_display_name[0] = '\0';
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist);
|
||||
|
||||
retro_assert(playlist != NULL);
|
||||
|
||||
core_info_get_name(path, core_display_name, sizeof(core_display_name));
|
||||
|
||||
idx = rdb_entry_start_game_selection_ptr;
|
||||
|
||||
playlist_update(playlist, idx,
|
||||
NULL, NULL,
|
||||
path, core_display_name,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
playlist_write_file(playlist);
|
||||
command_playlist_update_write(NULL,
|
||||
rdb_entry_start_game_selection_ptr,
|
||||
core_display_name, NULL, path);
|
||||
|
||||
menu_entries_pop_stack(&selection, 0, 1);
|
||||
menu_navigation_set_selection(selection);
|
||||
@ -3209,7 +3144,34 @@ default_action_ok_cmd_func(action_ok_restart_content, CMD_EVENT_RESET)
|
||||
default_action_ok_cmd_func(action_ok_screenshot, CMD_EVENT_TAKE_SCREENSHOT)
|
||||
default_action_ok_cmd_func(action_ok_disk_cycle_tray_status, CMD_EVENT_DISK_EJECT_TOGGLE )
|
||||
default_action_ok_cmd_func(action_ok_shader_apply_changes, CMD_EVENT_SHADERS_APPLY_CHANGES )
|
||||
default_action_ok_cmd_func(action_ok_add_to_favorites, CMD_EVENT_ADD_TO_FAVORITES)
|
||||
|
||||
static int action_ok_add_to_favorites(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
void *new_path = (void*)path_get(RARCH_PATH_CONTENT);
|
||||
if (!command_event(CMD_EVENT_ADD_TO_FAVORITES, new_path))
|
||||
return menu_cbs_exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_ok_add_to_favorites_playlist(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
const char *tmp_path = NULL;
|
||||
playlist_t *tmp_playlist = NULL;
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &tmp_playlist);
|
||||
|
||||
if (!tmp_playlist)
|
||||
return 0;
|
||||
|
||||
playlist_get_index(tmp_playlist,
|
||||
rpl_entry_selection_ptr, &tmp_path, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!command_event(CMD_EVENT_ADD_TO_FAVORITES, (void*)tmp_path))
|
||||
return menu_cbs_exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_ok_rename_entry(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
@ -3267,7 +3229,11 @@ static int action_ok_delete_entry(const char *path,
|
||||
playlist = g_defaults.image_history;
|
||||
#endif
|
||||
|
||||
playlist_delete_index(playlist, rpl_entry_selection_ptr);
|
||||
if (playlist)
|
||||
{
|
||||
playlist_delete_index(playlist, rpl_entry_selection_ptr);
|
||||
playlist_write_file(playlist);
|
||||
}
|
||||
|
||||
new_selection_ptr = menu_navigation_get_selection();
|
||||
menu_entries_pop_stack(&new_selection_ptr, 0, 1);
|
||||
@ -3708,13 +3674,17 @@ static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const cha
|
||||
else
|
||||
{
|
||||
char s[PATH_MAX_LENGTH];
|
||||
int i = 0;
|
||||
int k = 0;
|
||||
file_list_t *file_list = menu_entries_get_selection_buf_ptr(0);
|
||||
unsigned i = 0;
|
||||
unsigned j = 0;
|
||||
file_list_t *list = menu_entries_get_selection_buf_ptr(0);
|
||||
|
||||
lan_room_count = 0;
|
||||
|
||||
#ifndef RARCH_CONSOLE
|
||||
netplay_discovery_driver_ctl(RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &lan_hosts);
|
||||
if (lan_hosts)
|
||||
lan_room_count = (int)lan_hosts->size;
|
||||
lan_room_count = (int)lan_hosts->size;
|
||||
#endif
|
||||
|
||||
netplay_rooms_parse(data->data);
|
||||
|
||||
@ -3735,32 +3705,15 @@ static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const cha
|
||||
|
||||
if (lan_room_count != 0)
|
||||
{
|
||||
struct netplay_host *host = NULL;
|
||||
|
||||
for (host = &lan_hosts->hosts[k]; i < netplay_room_count + lan_room_count; i++)
|
||||
for (i = netplay_room_count; i < netplay_room_count + lan_room_count; i++)
|
||||
{
|
||||
struct sockaddr *address = NULL;
|
||||
struct netplay_host *host = &lan_hosts->hosts[j++];
|
||||
|
||||
strlcpy(netplay_room_list[i].nickname,
|
||||
host->nick,
|
||||
sizeof(netplay_room_list[i].nickname));
|
||||
|
||||
address = &host->addr;
|
||||
|
||||
if (address->sa_family == AF_INET)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) address;
|
||||
inet_ntop_compat(AF_INET, &sin->sin_addr,
|
||||
netplay_room_list[i].address, INET6_ADDRSTRLEN);
|
||||
}
|
||||
#if defined(AF_INET6) && !defined(HAVE_SOCKET_LEGACY)
|
||||
else if (address->sa_family == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6 *sin = (struct sockaddr_in6 *) address;
|
||||
inet_ntop_compat(AF_INET6, &sin->sin6_addr,
|
||||
netplay_room_list[i].address, INET6_ADDRSTRLEN);
|
||||
}
|
||||
#endif
|
||||
strlcpy(netplay_room_list[i].address, host->address, INET6_ADDRSTRLEN);
|
||||
|
||||
strlcpy(netplay_room_list[i].corename,
|
||||
host->core,
|
||||
@ -3775,7 +3728,7 @@ static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const cha
|
||||
host->content,
|
||||
sizeof(netplay_room_list[i].gamename));
|
||||
|
||||
netplay_room_list[i].port = 55435;
|
||||
netplay_room_list[i].port = host->port;
|
||||
netplay_room_list[i].gamecrc = host->content_crc;
|
||||
netplay_room_list[i].timestamp = 0;
|
||||
netplay_room_list[i].lan = true;
|
||||
@ -3786,7 +3739,7 @@ static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const cha
|
||||
}
|
||||
netplay_room_count += lan_room_count;
|
||||
}
|
||||
netplay_refresh_rooms_menu(file_list);
|
||||
netplay_refresh_rooms_menu(list);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3852,7 +3805,9 @@ static int action_ok_push_netplay_refresh_rooms(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
char url [2048] = "http://newlobby.libretro.com/list/";
|
||||
#ifndef RARCH_CONSOLE
|
||||
task_push_netplay_lan_scan(netplay_lan_scan_callback);
|
||||
#endif
|
||||
task_push_http_transfer(url, true, NULL, netplay_refresh_rooms_cb, NULL);
|
||||
return 0;
|
||||
}
|
||||
@ -4401,6 +4356,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_RESUME_CONTENT:
|
||||
BIND_ACTION_OK(cbs, action_ok_resume_content);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_ADD_TO_FAVORITES_PLAYLIST:
|
||||
BIND_ACTION_OK(cbs, action_ok_add_to_favorites_playlist);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_ADD_TO_FAVORITES:
|
||||
BIND_ACTION_OK(cbs, action_ok_add_to_favorites);
|
||||
break;
|
||||
|
@ -23,6 +23,12 @@
|
||||
#include "../widgets/menu_entry.h"
|
||||
#include "../menu_cbs.h"
|
||||
#include "../menu_setting.h"
|
||||
#include "../../tasks/tasks_internal.h"
|
||||
|
||||
#ifdef HAVE_NETWORKING
|
||||
#include "../../network/netplay/netplay.h"
|
||||
#include "../../network/netplay/netplay_discovery.h"
|
||||
#endif
|
||||
|
||||
#ifndef BIND_ACTION_SELECT
|
||||
#define BIND_ACTION_SELECT(cbs, name) \
|
||||
@ -42,7 +48,9 @@ static int action_select_default(const char *path, const char *label, unsigned t
|
||||
menu_entry_init(&entry);
|
||||
menu_entry_get(&entry, 0, idx, NULL, false);
|
||||
|
||||
cbs = selection_buf ? (menu_file_list_cbs_t*)file_list_get_actiondata_at_offset(selection_buf, idx) : NULL;
|
||||
if (selection_buf)
|
||||
cbs = (menu_file_list_cbs_t*)
|
||||
file_list_get_actiondata_at_offset(selection_buf, idx);
|
||||
|
||||
if (!cbs)
|
||||
{
|
||||
@ -76,7 +84,7 @@ static int action_select_default(const char *path, const char *label, unsigned t
|
||||
if (action == MENU_ACTION_NOOP)
|
||||
{
|
||||
if (cbs->action_ok)
|
||||
action = MENU_ACTION_OK;
|
||||
action = MENU_ACTION_OK;
|
||||
else
|
||||
{
|
||||
if (cbs->action_start)
|
||||
@ -146,6 +154,53 @@ static int action_select_input_desc_kbd(const char *path, const char *label, uns
|
||||
return action_right_input_desc_kbd(type, label, true);
|
||||
}
|
||||
|
||||
static int action_select_netplay_connect_room(const char *path, const char *label, unsigned type,
|
||||
size_t idx)
|
||||
{
|
||||
#ifdef HAVE_NETWORKING
|
||||
char tmp_hostname[4115];
|
||||
|
||||
tmp_hostname[0] = '\0';
|
||||
|
||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
|
||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||
|
||||
if (netplay_room_list[idx - 3].host_method == NETPLAY_HOST_METHOD_MITM)
|
||||
{
|
||||
snprintf(tmp_hostname,
|
||||
sizeof(tmp_hostname),
|
||||
"%s|%d",
|
||||
netplay_room_list[idx - 3].mitm_address,
|
||||
netplay_room_list[idx - 3].mitm_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(tmp_hostname,
|
||||
sizeof(tmp_hostname),
|
||||
"%s|%d",
|
||||
netplay_room_list[idx - 3].address,
|
||||
netplay_room_list[idx - 3].port);
|
||||
}
|
||||
|
||||
#if 0
|
||||
RARCH_LOG("[lobby] connecting to: %s with game: %s/%08x\n",
|
||||
tmp_hostname,
|
||||
netplay_room_list[idx - 3].gamename,
|
||||
netplay_room_list[idx - 3].gamecrc);
|
||||
#endif
|
||||
|
||||
task_push_netplay_crc_scan(netplay_room_list[idx - 3].gamecrc,
|
||||
netplay_room_list[idx - 3].gamename,
|
||||
tmp_hostname, netplay_room_list[idx - 3].corename);
|
||||
|
||||
#else
|
||||
return -1;
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int menu_cbs_init_bind_select_compare_type(
|
||||
menu_file_list_cbs_t *cbs, unsigned type)
|
||||
{
|
||||
@ -180,6 +235,7 @@ static int menu_cbs_init_bind_select_compare_type(
|
||||
#endif
|
||||
else
|
||||
{
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case FILE_TYPE_USE_DIRECTORY:
|
||||
@ -207,6 +263,14 @@ int menu_cbs_init_bind_select(menu_file_list_cbs_t *cbs,
|
||||
|
||||
BIND_ACTION_SELECT(cbs, action_select_default);
|
||||
|
||||
#ifdef HAVE_NETWORKING
|
||||
if (cbs->enum_idx == MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM)
|
||||
{
|
||||
BIND_ACTION_SELECT(cbs, action_select_netplay_connect_room);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cbs->setting)
|
||||
{
|
||||
uint64_t flags = cbs->setting->flags;
|
||||
|
@ -63,6 +63,7 @@ default_sublabel_macro(action_bind_sublabel_cheevos_enable, MENU_
|
||||
default_sublabel_macro(action_bind_sublabel_cheevos_test_unofficial, MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL)
|
||||
default_sublabel_macro(action_bind_sublabel_cheevos_hardcore_mode_enable, MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE)
|
||||
default_sublabel_macro(action_bind_sublabel_cheevos_leaderboards_enable, MENU_ENUM_SUBLABEL_CHEEVOS_LEADERBOARDS_ENABLE)
|
||||
default_sublabel_macro(action_bind_sublabel_cheevos_badges_enable, MENU_ENUM_SUBLABEL_CHEEVOS_BADGES_ENABLE)
|
||||
default_sublabel_macro(action_bind_sublabel_cheevos_verbose_enable, MENU_ENUM_SUBLABEL_CHEEVOS_VERBOSE_ENABLE)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_views_settings_list, MENU_ENUM_SUBLABEL_MENU_VIEWS_SETTINGS)
|
||||
default_sublabel_macro(action_bind_sublabel_quick_menu_views_settings_list, MENU_ENUM_SUBLABEL_QUICK_MENU_VIEWS_SETTINGS)
|
||||
@ -1246,6 +1247,7 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_shared_context);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY:
|
||||
case MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY_HARDCORE:
|
||||
case MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_entry);
|
||||
break;
|
||||
@ -1266,6 +1268,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_leaderboards_enable);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_badges_enable);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_CHEEVOS_VERBOSE_ENABLE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_verbose_enable);
|
||||
break;
|
||||
|
@ -189,7 +189,6 @@ default_fill_title_macro(action_get_title_collection, MENU_ENUM_LABE
|
||||
default_title_copy_macro(action_get_title_help, MENU_ENUM_LABEL_VALUE_HELP_LIST)
|
||||
default_title_copy_macro(action_get_title_input_settings, MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS)
|
||||
default_title_copy_macro(action_get_title_cheevos_list, MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST)
|
||||
default_title_copy_macro(action_get_title_cheevos_list_hardcore, MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE)
|
||||
default_title_copy_macro(action_get_title_video_shader_parameters,MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS)
|
||||
default_title_copy_macro(action_get_title_video_shader_preset_parameters,MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_PARAMETERS)
|
||||
|
||||
@ -1018,9 +1017,6 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs,
|
||||
case MENU_LABEL_ACHIEVEMENT_LIST:
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_cheevos_list);
|
||||
break;
|
||||
case MENU_LABEL_ACHIEVEMENT_LIST_HARDCORE:
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_cheevos_list_hardcore);
|
||||
break;
|
||||
case MENU_LABEL_VIDEO_SHADER_PARAMETERS:
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_video_shader_parameters);
|
||||
break;
|
||||
|
@ -61,6 +61,8 @@
|
||||
|
||||
#include "../../tasks/tasks_internal.h"
|
||||
|
||||
#include "../../cheevos/badges.h"
|
||||
|
||||
#define XMB_RIBBON_ROWS 64
|
||||
#define XMB_RIBBON_COLS 64
|
||||
#define XMB_RIBBON_VERTICES 2*XMB_RIBBON_COLS*XMB_RIBBON_ROWS-2*XMB_RIBBON_COLS
|
||||
@ -382,6 +384,8 @@ const char* xmb_theme_ident(void)
|
||||
return "flatui";
|
||||
case XMB_ICON_THEME_RETROACTIVE:
|
||||
return "retroactive";
|
||||
case XMB_ICON_THEME_RETROSYSTEM:
|
||||
return "retrosystem";
|
||||
case XMB_ICON_THEME_PIXEL:
|
||||
return "pixel";
|
||||
case XMB_ICON_THEME_NEOACTIVE:
|
||||
@ -2100,6 +2104,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
|
||||
case MENU_ENUM_LABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE:
|
||||
return xmb->textures.list[XMB_TEXTURE_CORE_OPTIONS];
|
||||
case MENU_ENUM_LABEL_ADD_TO_FAVORITES:
|
||||
case MENU_ENUM_LABEL_ADD_TO_FAVORITES_PLAYLIST:
|
||||
return xmb->textures.list[XMB_TEXTURE_ADD_FAVORITE];
|
||||
case MENU_ENUM_LABEL_CORE_INPUT_REMAPPING_OPTIONS:
|
||||
return xmb->textures.list[XMB_TEXTURE_INPUT_REMAPPING_OPTIONS];
|
||||
@ -2237,6 +2242,18 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_CHEEVOS
|
||||
if ((type >= MENU_SETTINGS_CHEEVOS_START) &&
|
||||
(type < MENU_SETTINGS_NETPLAY_ROOMS_START))
|
||||
{
|
||||
int new_id = type - MENU_SETTINGS_CHEEVOS_START;
|
||||
if ( get_badge_texture(new_id) != 0 )
|
||||
return get_badge_texture( new_id );
|
||||
else
|
||||
return xmb->textures.list[XMB_TEXTURE_SUBSETTING]; // Should be replaced with placeholder badge icon.
|
||||
}
|
||||
#endif
|
||||
|
||||
return xmb->textures.list[XMB_TEXTURE_SUBSETTING];
|
||||
}
|
||||
|
||||
|
@ -1572,7 +1572,7 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info,
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free(path_short);
|
||||
}
|
||||
|
||||
@ -2954,11 +2954,6 @@ static int menu_displaylist_parse_load_content_settings(
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_ACHIEVEMENT_LIST),
|
||||
MENU_ENUM_LABEL_ACHIEVEMENT_LIST,
|
||||
MENU_SETTING_ACTION, 0, 0);
|
||||
menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_ACHIEVEMENT_LIST_HARDCORE),
|
||||
MENU_ENUM_LABEL_ACHIEVEMENT_LIST_HARDCORE,
|
||||
MENU_SETTING_ACTION, 0, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -3035,6 +3030,14 @@ static int menu_displaylist_parse_horizontal_content_actions(
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_DELETE_ENTRY),
|
||||
MENU_ENUM_LABEL_DELETE_ENTRY,
|
||||
MENU_SETTING_ACTION_DELETE_ENTRY, 0, 0);
|
||||
|
||||
if (settings->bools.quick_menu_show_add_to_favorites)
|
||||
{
|
||||
menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_TO_FAVORITES_PLAYLIST),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_ADD_TO_FAVORITES_PLAYLIST),
|
||||
MENU_ENUM_LABEL_ADD_TO_FAVORITES_PLAYLIST, FILE_TYPE_PLAYLIST_ENTRY, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string_is_empty(db_name) && (!content_loaded ||
|
||||
@ -3487,7 +3490,7 @@ static int menu_displaylist_parse_options_remappings(
|
||||
}
|
||||
#ifdef HAVE_KEYMAPPER
|
||||
if (system)
|
||||
{
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
unsigned device = settings->uints.input_libretro_device[settings->uints.keymapper_port];
|
||||
@ -3506,13 +3509,13 @@ static int menu_displaylist_parse_options_remappings(
|
||||
keybind = &input_config_binds[settings->uints.keymapper_port][retro_id];
|
||||
auto_bind = (const struct retro_keybind*)
|
||||
input_config_get_bind_auto(settings->uints.keymapper_port, retro_id);
|
||||
|
||||
|
||||
input_config_get_bind_string(descriptor,
|
||||
keybind, auto_bind, sizeof(descriptor));
|
||||
|
||||
if(!strstr(descriptor, "Auto"))
|
||||
{
|
||||
const struct retro_keybind *keyptr =
|
||||
const struct retro_keybind *keyptr =
|
||||
&input_config_binds[settings->uints.keymapper_port][retro_id];
|
||||
|
||||
strlcpy(descriptor, msg_hash_to_str(keyptr->enum_idx), sizeof(descriptor));
|
||||
@ -3852,7 +3855,7 @@ static int menu_displaylist_parse_cores(
|
||||
malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
char *display_name = (char*)
|
||||
malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
core_path[0] =
|
||||
core_path[0] =
|
||||
display_name[0] = '\0';
|
||||
|
||||
fill_pathname_join(core_path, dir, path,
|
||||
@ -4172,7 +4175,7 @@ static void menu_displaylist_parse_playlist_generic(
|
||||
{
|
||||
playlist_t *playlist = NULL;
|
||||
char *path_playlist = NULL;
|
||||
|
||||
|
||||
menu_displaylist_set_new_playlist(menu, playlist_path);
|
||||
|
||||
menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist);
|
||||
@ -4732,15 +4735,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
|
||||
case DISPLAYLIST_ACHIEVEMENT_LIST:
|
||||
#ifdef HAVE_CHEEVOS
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
||||
cheevos_populate_menu(info, false);
|
||||
info->need_push = true;
|
||||
info->need_refresh = true;
|
||||
#endif
|
||||
break;
|
||||
case DISPLAYLIST_ACHIEVEMENT_LIST_HARDCORE:
|
||||
#ifdef HAVE_CHEEVOS
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
||||
cheevos_populate_menu(info, true);
|
||||
cheevos_populate_menu(info);
|
||||
info->need_push = true;
|
||||
info->need_refresh = true;
|
||||
#endif
|
||||
@ -5607,6 +5602,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
|
||||
menu_displaylist_parse_settings_enum(menu, info,
|
||||
MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE,
|
||||
PARSE_ONLY_BOOL, false);
|
||||
if (string_is_equal_fast(settings->arrays.menu_driver, "xmb", 3))
|
||||
{
|
||||
menu_displaylist_parse_settings_enum(menu, info,
|
||||
MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE,
|
||||
PARSE_ONLY_BOOL, false);
|
||||
}
|
||||
menu_displaylist_parse_settings_enum(menu, info,
|
||||
MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL,
|
||||
PARSE_ONLY_BOOL, false);
|
||||
|
@ -108,8 +108,7 @@ enum menu_displaylist_ctl_state
|
||||
DISPLAYLIST_NETWORK_INFO,
|
||||
DISPLAYLIST_SYSTEM_INFO,
|
||||
DISPLAYLIST_ACHIEVEMENT_LIST,
|
||||
DISPLAYLIST_ACHIEVEMENT_LIST_HARDCORE,
|
||||
DISPLAYLIST_USER_BINDS_LIST,
|
||||
DISPLAYLIST_USER_BINDS_LIST,
|
||||
DISPLAYLIST_ACCOUNTS_LIST,
|
||||
DISPLAYLIST_DRIVER_SETTINGS_LIST,
|
||||
DISPLAYLIST_VIDEO_SETTINGS_LIST,
|
||||
|
@ -248,6 +248,7 @@ enum xmb_icon_theme
|
||||
XMB_ICON_THEME_SYSTEMATIC,
|
||||
XMB_ICON_THEME_DOTART,
|
||||
XMB_ICON_THEME_CUSTOM,
|
||||
XMB_ICON_THEME_RETROSYSTEM,
|
||||
XMB_ICON_THEME_LAST
|
||||
};
|
||||
|
||||
|
@ -137,7 +137,7 @@ void menu_event_kb_set(bool down, enum retro_key key)
|
||||
* entire button state either but do a separate event per button
|
||||
* state.
|
||||
*/
|
||||
unsigned menu_event(uint64_t input, uint64_t trigger_input)
|
||||
unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input)
|
||||
{
|
||||
menu_animation_ctx_delta_t delta;
|
||||
float delta_time;
|
||||
@ -160,12 +160,12 @@ unsigned menu_event(uint64_t input, uint64_t trigger_input)
|
||||
unsigned menu_cancel_btn = (!input_swap_override &&
|
||||
settings->bools.input_menu_swap_ok_cancel_buttons) ?
|
||||
RETRO_DEVICE_ID_JOYPAD_A : RETRO_DEVICE_ID_JOYPAD_B;
|
||||
unsigned ok_current = (unsigned)(input & UINT64_C(1) << menu_ok_btn);
|
||||
unsigned ok_current = RARCH_INPUT_STATE_BIT_GET_PTR(p_input, menu_ok_btn );
|
||||
unsigned ok_trigger = ok_current & ~ok_old;
|
||||
|
||||
ok_old = ok_current;
|
||||
|
||||
if (input)
|
||||
if (RARCH_INPUT_STATE_ANY_SET_PTR(p_input))
|
||||
{
|
||||
if (!first_held)
|
||||
{
|
||||
@ -179,7 +179,7 @@ unsigned menu_event(uint64_t input, uint64_t trigger_input)
|
||||
|
||||
if (delay_count >= delay_timer)
|
||||
{
|
||||
uint64_t input_repeat = 0;
|
||||
uint32_t input_repeat = 0;
|
||||
BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_UP);
|
||||
BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_DOWN);
|
||||
BIT32_SET(input_repeat, RETRO_DEVICE_ID_JOYPAD_LEFT);
|
||||
@ -189,7 +189,7 @@ unsigned menu_event(uint64_t input, uint64_t trigger_input)
|
||||
|
||||
set_scroll = true;
|
||||
first_held = false;
|
||||
trigger_input |= input & input_repeat;
|
||||
p_trigger_input->data[0] |= p_input->data[0] & input_repeat;
|
||||
|
||||
menu_driver_ctl(MENU_NAVIGATION_CTL_GET_SCROLL_ACCEL,
|
||||
&new_scroll_accel);
|
||||
@ -221,31 +221,31 @@ unsigned menu_event(uint64_t input, uint64_t trigger_input)
|
||||
{
|
||||
menu_event_osk_iterate();
|
||||
|
||||
if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN))
|
||||
{
|
||||
if (menu_event_get_osk_ptr() < 33)
|
||||
menu_event_set_osk_ptr(menu_event_get_osk_ptr() + OSK_CHARS_PER_LINE);
|
||||
}
|
||||
|
||||
if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP))
|
||||
{
|
||||
if (menu_event_get_osk_ptr() >= OSK_CHARS_PER_LINE)
|
||||
menu_event_set_osk_ptr(menu_event_get_osk_ptr() - OSK_CHARS_PER_LINE);
|
||||
}
|
||||
|
||||
if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT))
|
||||
{
|
||||
if (menu_event_get_osk_ptr() < 43)
|
||||
menu_event_set_osk_ptr(menu_event_get_osk_ptr() + 1);
|
||||
}
|
||||
|
||||
if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT))
|
||||
{
|
||||
if (menu_event_get_osk_ptr() >= 1)
|
||||
menu_event_set_osk_ptr(menu_event_get_osk_ptr() - 1);
|
||||
}
|
||||
|
||||
if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L))
|
||||
{
|
||||
if (menu_event_get_osk_idx() > OSK_TYPE_UNKNOWN + 1)
|
||||
menu_event_set_osk_idx((enum osk_type)(menu_event_get_osk_idx() - 1));
|
||||
@ -253,7 +253,7 @@ unsigned menu_event(uint64_t input, uint64_t trigger_input)
|
||||
menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_LAST - 1));
|
||||
}
|
||||
|
||||
if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R))
|
||||
{
|
||||
if (menu_event_get_osk_idx() < OSK_TYPE_LAST - 1)
|
||||
menu_event_set_osk_idx((enum osk_type)(menu_event_get_osk_idx() + 1));
|
||||
@ -261,50 +261,50 @@ unsigned menu_event(uint64_t input, uint64_t trigger_input)
|
||||
menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_UNKNOWN + 1));
|
||||
}
|
||||
|
||||
if (trigger_input & (UINT64_C(1) << menu_ok_btn))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, menu_ok_btn))
|
||||
{
|
||||
if (menu_event_get_osk_ptr() >= 0)
|
||||
menu_event_osk_append(menu_event_get_osk_ptr());
|
||||
}
|
||||
|
||||
if (trigger_input & (UINT64_C(1) << menu_cancel_btn))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, menu_cancel_btn))
|
||||
{
|
||||
input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD);
|
||||
}
|
||||
|
||||
/* send return key to close keyboard input window */
|
||||
if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START))
|
||||
input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD);
|
||||
|
||||
trigger_input = 0;
|
||||
RARCH_INPUT_STATE_CLEAR_PTR(p_trigger_input);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP))
|
||||
ret = MENU_ACTION_UP;
|
||||
else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN))
|
||||
ret = MENU_ACTION_DOWN;
|
||||
else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT))
|
||||
ret = MENU_ACTION_LEFT;
|
||||
else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT))
|
||||
ret = MENU_ACTION_RIGHT;
|
||||
else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L))
|
||||
ret = MENU_ACTION_SCROLL_UP;
|
||||
else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R))
|
||||
ret = MENU_ACTION_SCROLL_DOWN;
|
||||
else if (ok_trigger)
|
||||
ret = MENU_ACTION_OK;
|
||||
else if (trigger_input & (UINT64_C(1) << menu_cancel_btn))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, menu_cancel_btn))
|
||||
ret = MENU_ACTION_CANCEL;
|
||||
else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_X))
|
||||
ret = MENU_ACTION_SEARCH;
|
||||
else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_Y))
|
||||
ret = MENU_ACTION_SCAN;
|
||||
else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START))
|
||||
ret = MENU_ACTION_START;
|
||||
else if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_SELECT))
|
||||
ret = MENU_ACTION_INFO;
|
||||
else if (trigger_input & (UINT64_C(1) << RARCH_MENU_TOGGLE))
|
||||
else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RARCH_MENU_TOGGLE))
|
||||
ret = MENU_ACTION_TOGGLE;
|
||||
}
|
||||
|
||||
@ -314,7 +314,7 @@ unsigned menu_event(uint64_t input, uint64_t trigger_input)
|
||||
menu_event_kb_set_internal(RETROK_F11, 0);
|
||||
}
|
||||
|
||||
if (runloop_cmd_press(trigger_input, RARCH_QUIT_KEY))
|
||||
if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RARCH_QUIT_KEY))
|
||||
return MENU_ACTION_QUIT;
|
||||
|
||||
mouse_enabled = settings->bools.menu_mouse_enable;
|
||||
|
@ -44,7 +44,7 @@ RETRO_BEGIN_DECLS
|
||||
* entire button state either but do a separate event per button
|
||||
* state.
|
||||
*/
|
||||
unsigned menu_event(uint64_t input, uint64_t trigger_state);
|
||||
unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_state);
|
||||
|
||||
/* Set a specific keyboard key.
|
||||
*
|
||||
|
@ -917,7 +917,7 @@ int menu_setting_set(unsigned type, const char *label,
|
||||
int ret = 0;
|
||||
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
menu_file_list_cbs_t *cbs = selection_buf ?
|
||||
menu_file_list_cbs_t *cbs = selection_buf ?
|
||||
(menu_file_list_cbs_t*)file_list_get_actiondata_at_offset(selection_buf, selection) : NULL;
|
||||
|
||||
if (!cbs)
|
||||
@ -1446,7 +1446,7 @@ static int setting_action_ok_bind_defaults(void *data, bool wraparound)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
setting_get_string_representation_st_float_video_refresh_rate_auto(
|
||||
void *data, char *s, size_t len)
|
||||
{
|
||||
@ -6461,6 +6461,22 @@ static bool setting_append_list(
|
||||
SD_FLAG_NONE
|
||||
);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.cheevos_badges_enable,
|
||||
MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE,
|
||||
MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE,
|
||||
false,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE
|
||||
);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.cheevos_verbose_enable,
|
||||
|
@ -255,6 +255,7 @@ void menu_dialog_push_pending(bool push, enum menu_dialog_type type)
|
||||
void menu_dialog_push(void)
|
||||
{
|
||||
menu_displaylist_info_t info;
|
||||
const char *label;
|
||||
|
||||
if (!menu_dialog_is_push_pending())
|
||||
return;
|
||||
@ -263,8 +264,11 @@ void menu_dialog_push(void)
|
||||
|
||||
info.list = menu_entries_get_menu_stack_ptr(0);
|
||||
info.enum_idx = MENU_ENUM_LABEL_HELP;
|
||||
info.label = strdup(
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_HELP));
|
||||
|
||||
/* Set the label string, if it exists. */
|
||||
label = msg_hash_to_str(MENU_ENUM_LABEL_HELP);
|
||||
if (label)
|
||||
info.label = strdup(label);
|
||||
|
||||
menu_displaylist_ctl(DISPLAYLIST_HELP, &info);
|
||||
}
|
||||
|
@ -274,9 +274,10 @@ void filebrowser_parse(void *data, unsigned type_data)
|
||||
}
|
||||
|
||||
end:
|
||||
menu_entries_prepend(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY),
|
||||
path,
|
||||
MENU_ENUM_LABEL_PARENT_DIRECTORY,
|
||||
FILE_TYPE_PARENT_DIRECTORY, 0, 0);
|
||||
if (info)
|
||||
menu_entries_prepend(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY),
|
||||
path,
|
||||
MENU_ENUM_LABEL_PARENT_DIRECTORY,
|
||||
FILE_TYPE_PARENT_DIRECTORY, 0, 0);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ void menu_input_dialog_end(void)
|
||||
{
|
||||
menu_input_dialog_keyboard_type = 0;
|
||||
menu_input_dialog_keyboard_idx = 0;
|
||||
menu_input_dialog_keyboard_display = false;
|
||||
menu_input_dialog_keyboard_display = false;
|
||||
menu_input_dialog_keyboard_label[0] = '\0';
|
||||
menu_input_dialog_keyboard_label_setting[0] = '\0';
|
||||
|
||||
@ -86,17 +86,17 @@ unsigned menu_input_dialog_get_kb_idx(void)
|
||||
|
||||
bool menu_input_dialog_get_display_kb(void)
|
||||
{
|
||||
return menu_input_dialog_keyboard_display;
|
||||
return menu_input_dialog_keyboard_display;
|
||||
}
|
||||
|
||||
void menu_input_dialog_display_kb(void)
|
||||
{
|
||||
menu_input_dialog_keyboard_display = true;
|
||||
menu_input_dialog_keyboard_display = true;
|
||||
}
|
||||
|
||||
void menu_input_dialog_hide_kb(void)
|
||||
{
|
||||
menu_input_dialog_keyboard_display = false;
|
||||
menu_input_dialog_keyboard_display = false;
|
||||
}
|
||||
|
||||
bool menu_input_dialog_start_search(void)
|
||||
@ -128,10 +128,14 @@ bool menu_input_dialog_start(menu_input_ctx_line_t *line)
|
||||
return false;
|
||||
|
||||
menu_input_dialog_display_kb();
|
||||
strlcpy(menu_input_dialog_keyboard_label, line->label,
|
||||
sizeof(menu_input_dialog_keyboard_label));
|
||||
strlcpy(menu_input_dialog_keyboard_label_setting,
|
||||
line->label_setting, sizeof(menu_input_dialog_keyboard_label_setting));
|
||||
|
||||
// Only copy over the menu label and setting if they exist.
|
||||
if (line->label)
|
||||
strlcpy(menu_input_dialog_keyboard_label, line->label,
|
||||
sizeof(menu_input_dialog_keyboard_label));
|
||||
if (line->label_setting)
|
||||
strlcpy(menu_input_dialog_keyboard_label_setting,
|
||||
line->label_setting, sizeof(menu_input_dialog_keyboard_label_setting));
|
||||
|
||||
menu_input_dialog_keyboard_type = line->type;
|
||||
menu_input_dialog_keyboard_idx = line->idx;
|
||||
|
@ -342,6 +342,7 @@ enum msg_hash_enums
|
||||
MSG_REWINDING,
|
||||
MSG_SLOW_MOTION_REWIND,
|
||||
MSG_SLOW_MOTION,
|
||||
MSG_FAST_FORWARD,
|
||||
MSG_REWIND_REACHED_END,
|
||||
MSG_FAILED_TO_START_MOVIE_RECORD,
|
||||
MSG_CHEEVOS_HARDCORE_MODE_ENABLE,
|
||||
@ -422,6 +423,7 @@ enum msg_hash_enums
|
||||
MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME,
|
||||
MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI,
|
||||
MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE,
|
||||
MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROSYSTEM,
|
||||
MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL,
|
||||
MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE,
|
||||
MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC,
|
||||
@ -461,6 +463,7 @@ enum msg_hash_enums
|
||||
MENU_ENUM_LABEL_PLAYLIST_COLLECTION_ENTRY,
|
||||
|
||||
MENU_LABEL(CHEEVOS_UNLOCKED_ENTRY),
|
||||
MENU_LABEL(CHEEVOS_UNLOCKED_ENTRY_HARDCORE),
|
||||
MENU_LABEL(CHEEVOS_LOCKED_ENTRY),
|
||||
|
||||
MENU_ENUM_LABEL_SHADER_PARAMETERS_ENTRY,
|
||||
@ -787,6 +790,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(GOTO_IMAGES),
|
||||
MENU_LABEL(GOTO_VIDEO),
|
||||
MENU_LABEL(ADD_TO_FAVORITES),
|
||||
MENU_LABEL(ADD_TO_FAVORITES_PLAYLIST),
|
||||
MENU_LABEL(MENU_THROTTLE_FRAMERATE),
|
||||
MENU_LABEL(NO_ACHIEVEMENTS_TO_DISPLAY),
|
||||
MENU_LABEL(NO_ENTRIES_TO_DISPLAY),
|
||||
@ -850,6 +854,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(ACCOUNTS_CHEEVOS_USERNAME),
|
||||
MENU_LABEL(CHEEVOS_HARDCORE_MODE_ENABLE),
|
||||
MENU_LABEL(CHEEVOS_LEADERBOARDS_ENABLE),
|
||||
MENU_LABEL(CHEEVOS_BADGES_ENABLE),
|
||||
MENU_LABEL(CHEEVOS_TEST_UNOFFICIAL),
|
||||
MENU_LABEL(CHEEVOS_VERBOSE_ENABLE),
|
||||
MENU_LABEL(CHEEVOS_ENABLE),
|
||||
@ -1852,7 +1857,6 @@ enum msg_hash_enums
|
||||
#define MENU_LABEL_FRONTEND_COUNTERS 0xe5696877U
|
||||
#define MENU_LABEL_CORE_COUNTERS 0x64cc83e0U
|
||||
#define MENU_LABEL_ACHIEVEMENT_LIST 0x7b90fc49U
|
||||
#define MENU_LABEL_ACHIEVEMENT_LIST_HARDCORE 0x7c632930U
|
||||
#define MENU_LABEL_CORE_INFORMATION 0xb638e0d3U
|
||||
#define MENU_LABEL_CORE_OPTIONS 0xf65e60f9U
|
||||
#define MENU_LABEL_SHADER_OPTIONS 0x1f7d2fc7U
|
||||
|
@ -60,6 +60,7 @@ struct ad_packet
|
||||
uint32_t header;
|
||||
uint32_t protocol_version;
|
||||
uint32_t port;
|
||||
char address[NETPLAY_HOST_STR_LEN];
|
||||
char retroarch_version[NETPLAY_HOST_STR_LEN];
|
||||
char nick[NETPLAY_HOST_STR_LEN];
|
||||
char core[NETPLAY_HOST_STR_LEN];
|
||||
@ -107,7 +108,7 @@ bool init_netplay_discovery(void)
|
||||
error:
|
||||
if (addr)
|
||||
freeaddrinfo_retro(addr);
|
||||
RARCH_ERR("Failed to initialize netplay advertisement client socket.\n");
|
||||
RARCH_ERR("[discovery] Failed to initialize netplay advertisement client socket.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -122,9 +123,13 @@ void deinit_netplay_discovery(void)
|
||||
}
|
||||
|
||||
/** Discovery control */
|
||||
/* Todo: implement net_ifinfo and ntohs for consoles */
|
||||
bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state, void *data)
|
||||
{
|
||||
#ifndef RARCH_CONSOLE
|
||||
char port_str[6];
|
||||
int k = 0;
|
||||
int ret;
|
||||
|
||||
if (lan_ad_client_fd < 0)
|
||||
return false;
|
||||
@ -136,6 +141,11 @@ bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state,
|
||||
struct addrinfo hints = {0}, *addr;
|
||||
int canBroadcast = 1;
|
||||
|
||||
net_ifinfo_t interfaces;
|
||||
|
||||
if (!net_ifinfo_new(&interfaces))
|
||||
return false;
|
||||
|
||||
/* Get the broadcast address (IPv4 only for now) */
|
||||
snprintf(port_str, 6, "%hu", (unsigned short) RARCH_DEFAULT_PORT);
|
||||
if (getaddrinfo_retro("255.255.255.255", port_str, &hints, &addr) < 0)
|
||||
@ -145,20 +155,28 @@ bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state,
|
||||
#if defined(SOL_SOCKET) && defined(SO_BROADCAST)
|
||||
if (setsockopt(lan_ad_client_fd, SOL_SOCKET, SO_BROADCAST,
|
||||
(const char *)&canBroadcast, sizeof(canBroadcast)) < 0)
|
||||
RARCH_WARN("Failed to set netplay discovery port to broadcast.\n");
|
||||
RARCH_WARN("[discovery] Failed to set netplay discovery port to broadcast\n");
|
||||
#endif
|
||||
|
||||
/* Put together the request */
|
||||
memcpy((void *) &ad_packet_buffer, "RANQ", 4);
|
||||
ad_packet_buffer.protocol_version = htonl(NETPLAY_PROTOCOL_VERSION);
|
||||
|
||||
/* And send it off */
|
||||
if (sendto(lan_ad_client_fd, (const char *) &ad_packet_buffer,
|
||||
2*sizeof(uint32_t), 0, addr->ai_addr, addr->ai_addrlen) <
|
||||
(ssize_t) (2*sizeof(uint32_t)))
|
||||
RARCH_WARN("Failed to send netplay discovery response.\n");
|
||||
for (k=0; k < interfaces.size; k++)
|
||||
{
|
||||
strlcpy(ad_packet_buffer.address, interfaces.entries[k].host,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
|
||||
/* And send it off */
|
||||
ret = sendto(lan_ad_client_fd, (const char *) &ad_packet_buffer,
|
||||
sizeof(struct ad_packet), 0, addr->ai_addr, addr->ai_addrlen);
|
||||
if (ret < (ssize_t) (2*sizeof(uint32_t)))
|
||||
RARCH_WARN("[discovery] Failed to send netplay discovery query (error: %d)\n", errno);
|
||||
}
|
||||
|
||||
freeaddrinfo_retro(addr);
|
||||
net_ifinfo_free(&interfaces);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -175,7 +193,7 @@ bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state,
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -201,7 +219,7 @@ static bool init_lan_ad_server_socket(netplay_t *netplay, uint16_t port)
|
||||
error:
|
||||
if (addr)
|
||||
freeaddrinfo_retro(addr);
|
||||
RARCH_ERR("Failed to initialize netplay advertisement socket.\n");
|
||||
RARCH_ERR("[discovery] Failed to initialize netplay advertisement socket\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -212,15 +230,25 @@ error:
|
||||
*/
|
||||
bool netplay_lan_ad_server(netplay_t *netplay)
|
||||
{
|
||||
/* Todo: implement net_ifinfo and ntohs for consoles */
|
||||
#ifndef RARCH_CONSOLE
|
||||
fd_set fds;
|
||||
struct timeval tmp_tv = {0};
|
||||
struct sockaddr their_addr;
|
||||
socklen_t addr_size;
|
||||
rarch_system_info_t *info = NULL;
|
||||
int ret, k = 0;
|
||||
char reply_addr[NETPLAY_HOST_STR_LEN], port_str[6];
|
||||
struct addrinfo *our_addr, hints = {0};
|
||||
|
||||
net_ifinfo_t interfaces;
|
||||
|
||||
if (!net_ifinfo_new(&interfaces))
|
||||
return false;
|
||||
|
||||
if (lan_ad_server_fd < 0 && !init_lan_ad_server_socket(netplay, RARCH_DEFAULT_PORT))
|
||||
return false;
|
||||
|
||||
|
||||
/* Check for any ad queries */
|
||||
while (1)
|
||||
{
|
||||
@ -234,59 +262,100 @@ bool netplay_lan_ad_server(netplay_t *netplay)
|
||||
/* Somebody queried, so check that it's valid */
|
||||
addr_size = sizeof(their_addr);
|
||||
|
||||
if (recvfrom(lan_ad_server_fd, (char*)&ad_packet_buffer,
|
||||
sizeof(struct ad_packet), 0, &their_addr, &addr_size) >=
|
||||
(ssize_t) (2*sizeof(uint32_t)))
|
||||
ret = recvfrom(lan_ad_server_fd, (char*)&ad_packet_buffer,
|
||||
sizeof(struct ad_packet), 0, &their_addr, &addr_size);
|
||||
if (ret >= (ssize_t) (2 * sizeof(uint32_t)))
|
||||
{
|
||||
char s[NETPLAY_HOST_STR_LEN];
|
||||
uint32_t content_crc = 0;
|
||||
|
||||
/* Make sure it's a valid query */
|
||||
if (memcmp((void *) &ad_packet_buffer, "RANQ", 4))
|
||||
{
|
||||
RARCH_LOG("[discovery] invalid query\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* For this version */
|
||||
if (ntohl(ad_packet_buffer.protocol_version) !=
|
||||
NETPLAY_PROTOCOL_VERSION)
|
||||
continue;
|
||||
|
||||
info = runloop_get_system_info();
|
||||
|
||||
/* Now build our response */
|
||||
content_crc = content_get_crc();
|
||||
|
||||
memset(&ad_packet_buffer, 0, sizeof(struct ad_packet));
|
||||
memcpy(&ad_packet_buffer, "RANS", 4);
|
||||
|
||||
ad_packet_buffer.protocol_version =
|
||||
htonl(NETPLAY_PROTOCOL_VERSION);
|
||||
ad_packet_buffer.port = htonl(netplay->tcp_port);
|
||||
strlcpy(ad_packet_buffer.retroarch_version, PACKAGE_VERSION,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
strlcpy(ad_packet_buffer.content, !string_is_empty(
|
||||
path_basename(path_get(RARCH_PATH_BASENAME)))
|
||||
? path_basename(path_get(RARCH_PATH_BASENAME)) : "N/A",
|
||||
NETPLAY_HOST_LONGSTR_LEN);
|
||||
strlcpy(ad_packet_buffer.nick, netplay->nick, NETPLAY_HOST_STR_LEN);
|
||||
|
||||
if (info)
|
||||
{
|
||||
strlcpy(ad_packet_buffer.core, info->info.library_name,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
strlcpy(ad_packet_buffer.core_version, info->info.library_version,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
RARCH_LOG("[discovery] invalid protocol version\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(s, sizeof(s), "%d", content_crc);
|
||||
strlcpy(ad_packet_buffer.content_crc, s,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
strlcpy(reply_addr, ad_packet_buffer.address, NETPLAY_HOST_STR_LEN);
|
||||
|
||||
/* And send it */
|
||||
sendto(lan_ad_server_fd, (const char*)&ad_packet_buffer,
|
||||
sizeof(struct ad_packet), 0, &their_addr, addr_size);
|
||||
for (k = 0; k < interfaces.size; k++)
|
||||
{
|
||||
char *p;
|
||||
char sub[NETPLAY_HOST_STR_LEN];
|
||||
|
||||
p=strrchr(reply_addr,'.');
|
||||
if (p)
|
||||
{
|
||||
strlcpy(sub, reply_addr, p - reply_addr + 1);
|
||||
if (strstr(interfaces.entries[k].host, sub) &&
|
||||
!strstr(interfaces.entries[k].host, "127.0.0.1"))
|
||||
{
|
||||
RARCH_LOG ("[discovery] query received on common interface: %s/%s (theirs / ours) \n",
|
||||
reply_addr, interfaces.entries[k].host);
|
||||
|
||||
info = runloop_get_system_info();
|
||||
|
||||
/* Now build our response */
|
||||
content_crc = content_get_crc();
|
||||
|
||||
memset(&ad_packet_buffer, 0, sizeof(struct ad_packet));
|
||||
memcpy(&ad_packet_buffer, "RANS", 4);
|
||||
|
||||
strlcpy(ad_packet_buffer.address, interfaces.entries[k].host,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
ad_packet_buffer.protocol_version =
|
||||
htonl(NETPLAY_PROTOCOL_VERSION);
|
||||
ad_packet_buffer.port = htonl(netplay->tcp_port);
|
||||
strlcpy(ad_packet_buffer.retroarch_version, PACKAGE_VERSION,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
strlcpy(ad_packet_buffer.content, !string_is_empty(
|
||||
path_basename(path_get(RARCH_PATH_BASENAME)))
|
||||
? path_basename(path_get(RARCH_PATH_BASENAME)) : "N/A",
|
||||
NETPLAY_HOST_LONGSTR_LEN);
|
||||
strlcpy(ad_packet_buffer.nick, netplay->nick, NETPLAY_HOST_STR_LEN);
|
||||
|
||||
if (info)
|
||||
{
|
||||
strlcpy(ad_packet_buffer.core, info->info.library_name,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
strlcpy(ad_packet_buffer.core_version, info->info.library_version,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
}
|
||||
|
||||
snprintf(s, sizeof(s), "%d", content_crc);
|
||||
strlcpy(ad_packet_buffer.content_crc, s,
|
||||
NETPLAY_HOST_STR_LEN);
|
||||
|
||||
/* Build up the destination address*/
|
||||
snprintf(port_str, 6, "%hu", ntohs(((struct sockaddr_in*)(&their_addr))->sin_port));
|
||||
if (getaddrinfo_retro(reply_addr, port_str, &hints, &our_addr) < 0)
|
||||
continue;
|
||||
|
||||
RARCH_LOG ("[discovery] sending reply to %s \n", reply_addr);
|
||||
|
||||
/* And send it */
|
||||
sendto(lan_ad_server_fd, (const char*)&ad_packet_buffer,
|
||||
sizeof(struct ad_packet), 0, our_addr->ai_addr, our_addr->ai_addrlen);
|
||||
freeaddrinfo_retro(our_addr);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
net_ifinfo_free(&interfaces);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -350,7 +419,7 @@ static bool netplay_lan_ad_client(void)
|
||||
{
|
||||
struct sockaddr_in *sin = NULL;
|
||||
|
||||
RARCH_WARN ("[lobby] using IPv4 for discovery\n");
|
||||
RARCH_WARN ("[discovery] using IPv4 for discovery\n");
|
||||
sin = (struct sockaddr_in *) &their_addr;
|
||||
sin->sin_port = htons(ntohl(ad_packet_buffer.port));
|
||||
|
||||
@ -359,7 +428,7 @@ static bool netplay_lan_ad_client(void)
|
||||
else if (their_addr.sa_family == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6 *sin6 = NULL;
|
||||
RARCH_WARN ("[lobby] using IPv6 for discovery\n");
|
||||
RARCH_WARN ("[discovery] using IPv6 for discovery\n");
|
||||
sin6 = (struct sockaddr_in6 *) &their_addr;
|
||||
sin6->sin6_port = htons(ad_packet_buffer.port);
|
||||
|
||||
@ -402,6 +471,9 @@ static bool netplay_lan_ad_client(void)
|
||||
host->addr = their_addr;
|
||||
host->addrlen = addr_size;
|
||||
|
||||
host->port = ntohl(ad_packet_buffer.port);
|
||||
|
||||
strlcpy(host->address, ad_packet_buffer.address, NETPLAY_HOST_STR_LEN);
|
||||
strlcpy(host->nick, ad_packet_buffer.nick, NETPLAY_HOST_STR_LEN);
|
||||
strlcpy(host->core, ad_packet_buffer.core, NETPLAY_HOST_STR_LEN);
|
||||
strlcpy(host->retroarch_version, ad_packet_buffer.retroarch_version,
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define __RARCH_NETPLAY_DISCOVERY_H
|
||||
|
||||
#include <net/net_compat.h>
|
||||
#include <net/net_ifinfo.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#define NETPLAY_HOST_STR_LEN 32
|
||||
@ -36,12 +37,14 @@ struct netplay_host
|
||||
struct sockaddr addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
char address[NETPLAY_HOST_STR_LEN];
|
||||
char nick[NETPLAY_HOST_STR_LEN];
|
||||
char core[NETPLAY_HOST_STR_LEN];
|
||||
char core_version[NETPLAY_HOST_STR_LEN];
|
||||
char retroarch_version[NETPLAY_HOST_STR_LEN];
|
||||
char content[NETPLAY_HOST_LONGSTR_LEN];
|
||||
int content_crc;
|
||||
int port;
|
||||
};
|
||||
|
||||
struct netplay_host_list
|
||||
|
@ -1,8 +1,8 @@
|
||||
<!-- <!DOCTYPE manifest [ <!ENTITY % versionDTD SYSTEM "../../../version.dtd"> %versionDTD; ]> !-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.retroarch"
|
||||
android:versionCode="62"
|
||||
android:versionName="1.6.7"
|
||||
android:versionCode="63"
|
||||
android:versionName="1.6.9"
|
||||
android:installLocation="internalOnly">
|
||||
<uses-feature android:glEsVersion="0x00020000" />
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
|
||||
|
20
playlist.c
20
playlist.c
@ -121,8 +121,6 @@ void playlist_delete_index(playlist_t *playlist,
|
||||
|
||||
playlist->size = playlist->size - 1;
|
||||
playlist->modified = true;
|
||||
|
||||
playlist_write_file(playlist);
|
||||
}
|
||||
|
||||
void playlist_get_index_by_path(playlist_t *playlist,
|
||||
@ -283,17 +281,19 @@ bool playlist_push(playlist_t *playlist,
|
||||
const char *db_name)
|
||||
{
|
||||
size_t i;
|
||||
bool core_path_empty = string_is_empty(core_path);
|
||||
bool core_name_empty = string_is_empty(core_name);
|
||||
|
||||
if (string_is_empty(core_path) || string_is_empty(core_name))
|
||||
if (core_path_empty || core_name_empty)
|
||||
{
|
||||
if (string_is_empty(core_name) && !string_is_empty(core_path))
|
||||
if (core_name_empty && !core_path_empty)
|
||||
{
|
||||
static char base_path[255] = {0};
|
||||
fill_pathname_base_noext(base_path, core_path, sizeof(base_path));
|
||||
core_name = base_path;
|
||||
}
|
||||
|
||||
if (string_is_empty(core_path) || string_is_empty(core_name))
|
||||
if (core_path_empty || core_name_empty)
|
||||
{
|
||||
RARCH_ERR("cannot push NULL or empty core name into the playlist.\n");
|
||||
return false;
|
||||
@ -381,22 +381,23 @@ void playlist_write_file(playlist_t *playlist)
|
||||
{
|
||||
size_t i;
|
||||
RFILE *file = NULL;
|
||||
FILE *fp = NULL;
|
||||
|
||||
if (!playlist || !playlist->modified)
|
||||
return;
|
||||
|
||||
file = filestream_open(playlist->conf_path, RFILE_MODE_WRITE, -1);
|
||||
|
||||
RARCH_LOG("Trying to write to playlist file: %s\n", playlist->conf_path);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
RARCH_ERR("Failed to write to playlist file: %s\n", playlist->conf_path);
|
||||
return;
|
||||
}
|
||||
|
||||
fp = filestream_get_fp(file);
|
||||
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
fprintf(filestream_get_fp(file), "%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
fprintf(fp, "%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
playlist->entries[i].path ? playlist->entries[i].path : "",
|
||||
playlist->entries[i].label ? playlist->entries[i].label : "",
|
||||
playlist->entries[i].core_path,
|
||||
@ -406,6 +407,9 @@ void playlist_write_file(playlist_t *playlist)
|
||||
);
|
||||
|
||||
playlist->modified = false;
|
||||
|
||||
RARCH_LOG("Written to playlist file: %s\n", playlist->conf_path);
|
||||
|
||||
filestream_close(file);
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,13 @@
|
||||
check_switch_c C99 -std=gnu99 "Cannot find C99 compatible compiler."
|
||||
|
||||
check_switch_c NOUNUSED -Wno-unused-result
|
||||
add_define_make NOUNUSED "$HAVE_NOUNUSED"
|
||||
check_switch_c NOUNUSED_VARIABLE -Wno-unused-variable
|
||||
add_define_make NOUNUSED_VARIABLE "$HAVE_NOUNUSED_VARIABLE"
|
||||
check_switch '' C99 -std=gnu99 "Cannot find C99 compatible compiler."
|
||||
check_switch '' NOUNUSED -Wno-unused-result
|
||||
add_define MAKEFILE NOUNUSED "$HAVE_NOUNUSED"
|
||||
check_switch '' NOUNUSED_VARIABLE -Wno-unused-variable
|
||||
add_define MAKEFILE NOUNUSED_VARIABLE "$HAVE_NOUNUSED_VARIABLE"
|
||||
|
||||
# There are still broken 64-bit Linux distros out there. :)
|
||||
[ -z "$CROSS_COMPILE" ] && [ -d /usr/lib64 ] && add_library_dirs /usr/lib64
|
||||
[ -z "$CROSS_COMPILE" ] && [ -d /usr/lib64 ] && add_dirs LIBRARY /usr/lib64
|
||||
|
||||
[ -z "$CROSS_COMPILE" ] && [ -d /opt/local/lib ] && add_library_dirs /opt/local/lib
|
||||
[ -z "$CROSS_COMPILE" ] && [ -d /opt/local/lib ] && add_dirs LIBRARY /opt/local/lib
|
||||
|
||||
[ "$GLOBAL_CONFIG_DIR" ] || \
|
||||
{ case "$PREFIX" in
|
||||
@ -35,11 +34,10 @@ elif [ "$OS" = 'Win32' ]; then
|
||||
SOCKETHEADER="#include <winsock2.h>"
|
||||
DYLIB=
|
||||
elif [ "$OS" = 'Cygwin' ]; then
|
||||
echo "Error: Cygwin is not a supported platform. See https://bot.libretro.com/docs/compilation/windows/"
|
||||
exit 1
|
||||
die 1 'Error: Cygwin is not a supported platform. See https://bot.libretro.com/docs/compilation/windows/'
|
||||
fi
|
||||
|
||||
add_define_make DYLIB_LIB "$DYLIB"
|
||||
add_define MAKEFILE DYLIB_LIB "$DYLIB"
|
||||
|
||||
check_lib '' SYSTEMD -lsystemd sd_get_machine_names
|
||||
|
||||
@ -48,7 +46,7 @@ if [ "$HAVE_VIDEOCORE" != "no" ]; then
|
||||
|
||||
# use fallback if pkgconfig is not available
|
||||
if [ ! "$VC_TEST_LIBS" ]; then
|
||||
[ -d /opt/vc/lib ] && add_library_dirs /opt/vc/lib && add_library_dirs /opt/vc/lib/GL
|
||||
[ -d /opt/vc/lib ] && add_dirs LIBRARY /opt/vc/lib /opt/vc/lib/GL
|
||||
check_lib '' VIDEOCORE -lbcm_host bcm_host_init "-lvcos -lvchiq_arm"
|
||||
else
|
||||
HAVE_VIDEOCORE="$HAVE_VC_TEST"
|
||||
@ -61,9 +59,9 @@ if [ "$HAVE_VIDEOCORE" = 'yes' ]; then
|
||||
|
||||
# use fallback if pkgconfig is not available
|
||||
if [ ! "$VC_TEST_LIBS" ]; then
|
||||
[ -d /opt/vc/include ] && add_include_dirs /opt/vc/include
|
||||
[ -d /opt/vc/include/interface/vcos/pthreads ] && add_include_dirs /opt/vc/include/interface/vcos/pthreads
|
||||
[ -d /opt/vc/include/interface/vmcs_host/linux ] && add_include_dirs /opt/vc/include/interface/vmcs_host/linux
|
||||
[ -d /opt/vc/include ] && add_dirs INCLUDE /opt/vc/include
|
||||
[ -d /opt/vc/include/interface/vcos/pthreads ] && add_dirs INCLUDE /opt/vc/include/interface/vcos/pthreads
|
||||
[ -d /opt/vc/include/interface/vmcs_host/linux ] && add_dirs INCLUDE /opt/vc/include/interface/vmcs_host/linux
|
||||
EXTRA_GL_LIBS="-lbrcmEGL -lbrcmGLESv2 -lbcm_host -lvcos -lvchiq_arm"
|
||||
fi
|
||||
fi
|
||||
@ -75,12 +73,12 @@ if [ "$HAVE_NEON" = "yes" ]; then
|
||||
fi
|
||||
|
||||
if [ "$HAVE_7ZIP" = "yes" ]; then
|
||||
add_include_dirs ./deps/7zip/
|
||||
add_dirs INCLUDE ./deps/7zip
|
||||
fi
|
||||
|
||||
if [ "$HAVE_PRESERVE_DYLIB" = "yes" ]; then
|
||||
echo "Notice: Disabling dlclose() of shared objects for Valgrind support."
|
||||
add_define_make HAVE_PRESERVE_DYLIB "1"
|
||||
die : 'Notice: Disabling dlclose() of shared objects for Valgrind support.'
|
||||
add_define MAKEFILE HAVE_PRESERVE_DYLIB "1"
|
||||
fi
|
||||
|
||||
if [ "$HAVE_FLOATHARD" = "yes" ]; then
|
||||
@ -122,8 +120,8 @@ if [ "$HAVE_EGL" != "no" ] && [ "$OS" != 'Win32' ]; then
|
||||
check_pkgconf EGL "$VC_PREFIX"egl
|
||||
# some systems have EGL libs, but no pkgconfig
|
||||
if [ "$HAVE_EGL" = "no" ]; then
|
||||
HAVE_EGL=auto; check_lib '' EGL "-l${VC_PREFIX}EGL $EXTRA_GL_LIBS"
|
||||
[ "$HAVE_EGL" = "yes" ] && EGL_LIBS=-l"$VC_PREFIX"EGL
|
||||
HAVE_EGL=auto
|
||||
check_lib '' EGL "-l${VC_PREFIX}EGL $EXTRA_GL_LIBS"
|
||||
else
|
||||
EGL_LIBS="$EGL_LIBS $EXTRA_GL_LIBS"
|
||||
fi
|
||||
@ -143,7 +141,7 @@ if [ "$HAVE_DISPMANX" != "no" ]; then
|
||||
fi
|
||||
|
||||
if [ "$LIBRETRO" ]; then
|
||||
echo "Notice: Explicit libretro used, disabling dynamic libretro loading ..."
|
||||
die : 'Notice: Explicit libretro used, disabling dynamic libretro loading ...'
|
||||
HAVE_DYNAMIC='no'
|
||||
else LIBRETRO="-lretro"
|
||||
fi
|
||||
@ -151,17 +149,17 @@ fi
|
||||
[ "$HAVE_DYNAMIC" = 'yes' ] || {
|
||||
#check_lib '' RETRO "$LIBRETRO" retro_init "$DYLIB" "Cannot find libretro, did you forget --with-libretro=\"-lretro\"?"
|
||||
check_lib '' RETRO "$LIBRETRO" "$DYLIB" "Cannot find libretro, did you forget --with-libretro=\"-lretro\"?"
|
||||
add_define_make libretro "$LIBRETRO"
|
||||
add_define MAKEFILE libretro "$LIBRETRO"
|
||||
}
|
||||
|
||||
[ -z "$ASSETS_DIR" ] && ASSETS_DIR="${PREFIX}/share"
|
||||
add_define_make ASSETS_DIR "$ASSETS_DIR"
|
||||
add_define MAKEFILE ASSETS_DIR "$ASSETS_DIR"
|
||||
|
||||
[ -z "$BIN_DIR" ] && BIN_DIR="${PREFIX}/bin"
|
||||
add_define_make BIN_DIR "$BIN_DIR"
|
||||
add_define MAKEFILE BIN_DIR "$BIN_DIR"
|
||||
|
||||
[ -z "$MAN_DIR" ] && MAN_DIR="${PREFIX}/share/man"
|
||||
add_define_make MAN_DIR "$MAN_DIR"
|
||||
add_define MAKEFILE MAN_DIR "$MAN_DIR"
|
||||
|
||||
if [ "$OS" = 'DOS' ]; then
|
||||
HAVE_SHADERPIPELINE=no
|
||||
@ -197,7 +195,7 @@ if [ "$HAVE_NETWORKING" = 'yes' ]; then
|
||||
check_lib '' GETADDRINFO "$SOCKETLIB" getaddrinfo
|
||||
if [ "$HAVE_GETADDRINFO" != 'yes' ]; then
|
||||
HAVE_SOCKET_LEGACY=yes
|
||||
echo "Notice: RetroArch will use legacy socket support"
|
||||
die : 'Notice: RetroArch will use legacy socket support'
|
||||
fi
|
||||
fi
|
||||
HAVE_NETWORK_CMD=yes
|
||||
@ -211,7 +209,7 @@ if [ "$HAVE_NETWORKING" = 'yes' ]; then
|
||||
HAVE_MINIUPNPC='yes'
|
||||
fi
|
||||
else
|
||||
echo "Warning: All networking features have been disabled."
|
||||
die : 'Warning: All networking features have been disabled.'
|
||||
HAVE_KEYMAPPER='no'
|
||||
HAVE_NETWORK_CMD='no'
|
||||
HAVE_NETWORKGAMEPAD='no'
|
||||
@ -229,8 +227,7 @@ fi
|
||||
check_lib '' GETOPT_LONG "$CLIB" getopt_long
|
||||
|
||||
if [ "$HAVE_DYLIB" = 'no' ] && [ "$HAVE_DYNAMIC" = 'yes' ]; then
|
||||
echo "Error: Dynamic loading of libretro is enabled, but your platform does not appear to have dlopen(), use --disable-dynamic or --with-libretro=\"-lretro\"".
|
||||
exit 1
|
||||
die 1 'Error: Dynamic loading of libretro is enabled, but your platform does not appear to have dlopen(), use --disable-dynamic or --with-libretro="-lretro".'
|
||||
fi
|
||||
|
||||
check_pkgconf ALSA alsa
|
||||
@ -240,7 +237,7 @@ check_header OSS_BSD soundcard.h
|
||||
check_lib '' OSS_LIB -lossaudio
|
||||
|
||||
if [ "$OS" = 'Linux' ]; then
|
||||
HAVE_TINYALSA=yes
|
||||
HAVE_TINYALSA=yes
|
||||
fi
|
||||
|
||||
if [ "$OS" = 'Darwin' ]; then
|
||||
@ -266,10 +263,10 @@ check_pkgconf SDL2 sdl2 2.0.0
|
||||
|
||||
if [ "$HAVE_SDL2" = 'yes' ]; then
|
||||
if [ "$HAVE_SDL2" = 'yes' ] && [ "$HAVE_SDL" = 'yes' ]; then
|
||||
echo "Notice: SDL drivers will be replaced by SDL2 ones."
|
||||
die : 'Notice: SDL drivers will be replaced by SDL2 ones.'
|
||||
HAVE_SDL=no
|
||||
elif [ "$HAVE_SDL2" = 'no' ]; then
|
||||
echo "Warning: SDL2 not found, skipping."
|
||||
die : 'Warning: SDL2 not found, skipping.'
|
||||
HAVE_SDL2=no
|
||||
fi
|
||||
fi
|
||||
@ -305,23 +302,17 @@ if [ "$HAVE_OPENGL" != 'no' ] && [ "$HAVE_OPENGLES" != 'yes' ]; then
|
||||
|
||||
if [ "$HAVE_OPENGL" = 'yes' ]; then
|
||||
if [ "$OS" = 'Darwin' ]; then
|
||||
check_lib '' CG "-framework Cg" cgCreateContext
|
||||
[ "$HAVE_CG" = 'yes' ] && CG_LIBS='-framework Cg'
|
||||
check_lib '' CG '-framework Cg' cgCreateContext
|
||||
elif [ "$OS" = 'Win32' ]; then
|
||||
check_lib cxx CG -lcg cgCreateContext
|
||||
[ "$HAVE_CG" = 'yes' ] && CG_LIBS='-lcg -lcgGL'
|
||||
check_lib cxx CG '-lcg -lcgGL' cgCreateContext
|
||||
else
|
||||
# On some distros, -lCg doesn't link against -lstdc++ it seems ...
|
||||
check_lib cxx CG -lCg cgCreateContext
|
||||
[ "$HAVE_CG" = 'yes' ] && CG_LIBS='-lCg -lCgGL'
|
||||
check_lib cxx CG '-lCg -lCgGL' cgCreateContext
|
||||
fi
|
||||
|
||||
# fix undefined variables
|
||||
PKG_CONF_USED="$PKG_CONF_USED CG"
|
||||
|
||||
check_pkgconf OSMESA osmesa
|
||||
else
|
||||
echo "Notice: Ignoring Cg. Desktop OpenGL is not enabled."
|
||||
die : 'Notice: Ignoring Cg. Desktop OpenGL is not enabled.'
|
||||
HAVE_CG='no'
|
||||
fi
|
||||
fi
|
||||
@ -349,11 +340,11 @@ if [ "$HAVE_THREADS" != 'no' ]; then
|
||||
HAVE_FFMPEG='yes'
|
||||
if [ "$HAVE_AVCODEC" = 'no' ] || [ "$HAVE_SWRESAMPLE" = 'no' ] || [ "$HAVE_AVFORMAT" = 'no' ] || [ "$HAVE_AVUTIL" = 'no' ] || [ "$HAVE_SWSCALE" = 'no' ]; then
|
||||
HAVE_FFMPEG='no'
|
||||
echo "Notice: FFmpeg built-in support disabled due to missing or unsuitable packages."
|
||||
die : 'Notice: FFmpeg built-in support disabled due to missing or unsuitable packages.'
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "Notice: Not building with threading support. Will skip FFmpeg."
|
||||
die : 'Notice: Not building with threading support. Will skip FFmpeg.'
|
||||
HAVE_FFMPEG='no'
|
||||
fi
|
||||
|
||||
@ -367,8 +358,7 @@ if [ "$HAVE_KMS" != "no" ]; then
|
||||
if [ "$HAVE_GBM" = "yes" ] && [ "$HAVE_DRM" = "yes" ] && [ "$HAVE_EGL" = "yes" ]; then
|
||||
HAVE_KMS=yes
|
||||
elif [ "$HAVE_KMS" = "yes" ]; then
|
||||
echo "Error: Cannot find libgbm, libdrm and EGL libraries required for KMS. Compile without --enable-kms."
|
||||
exit 1
|
||||
die 1 'Error: Cannot find libgbm, libdrm and EGL libraries required for KMS. Compile without --enable-kms.'
|
||||
else
|
||||
HAVE_KMS=no
|
||||
fi
|
||||
@ -379,14 +369,14 @@ check_pkgconf LIBXML2 libxml-2.0
|
||||
if [ "$HAVE_EGL" = "yes" ]; then
|
||||
if [ "$HAVE_OPENGLES" != "no" ]; then
|
||||
if [ "$OPENGLES_LIBS" ] || [ "$OPENGLES_CFLAGS" ]; then
|
||||
echo "Notice: Using custom OpenGLES CFLAGS ($OPENGLES_CFLAGS) and LDFLAGS ($OPENGLES_LIBS)."
|
||||
add_define_make OPENGLES_LIBS "$OPENGLES_LIBS"
|
||||
add_define_make OPENGLES_CFLAGS "$OPENGLES_CFLAGS"
|
||||
die : "Notice: Using custom OpenGLES CFLAGS ($OPENGLES_CFLAGS) and LDFLAGS ($OPENGLES_LIBS)."
|
||||
add_define MAKEFILE OPENGLES_LIBS "$OPENGLES_LIBS"
|
||||
add_define MAKEFILE OPENGLES_CFLAGS "$OPENGLES_CFLAGS"
|
||||
else
|
||||
HAVE_OPENGLES=auto; check_pkgconf OPENGLES "$VC_PREFIX"glesv2
|
||||
if [ "$HAVE_OPENGLES" = "no" ]; then
|
||||
HAVE_OPENGLES=auto; check_lib '' OPENGLES "-l${VC_PREFIX}GLESv2 $EXTRA_GL_LIBS"
|
||||
add_define_make OPENGLES_LIBS "-l${VC_PREFIX}GLESv2 $EXTRA_GL_LIBS"
|
||||
add_define MAKEFILE OPENGLES_LIBS "-l${VC_PREFIX}GLESv2 $EXTRA_GL_LIBS"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -406,7 +396,11 @@ check_pkgconf V4L2 libv4l2
|
||||
check_pkgconf FREETYPE freetype2
|
||||
check_pkgconf X11 x11
|
||||
check_pkgconf XCB xcb
|
||||
[ "$HAVE_X11" = "no" ] && HAVE_XEXT=no && HAVE_XF86VM=no && HAVE_XINERAMA=no && HAVE_XSHM=no
|
||||
|
||||
if [ "$HAVE_X11" = "no" ] && [ "$OS" != 'Darwin' ]; then
|
||||
HAVE_X11=auto
|
||||
check_lib '' X11 -lX11
|
||||
fi
|
||||
|
||||
check_pkgconf WAYLAND wayland-egl
|
||||
check_pkgconf WAYLAND_CURSOR wayland-cursor
|
||||
@ -415,11 +409,26 @@ check_pkgconf XKBCOMMON xkbcommon 0.3.2
|
||||
check_pkgconf DBUS dbus-1
|
||||
check_pkgconf XEXT xext
|
||||
check_pkgconf XF86VM xxf86vm
|
||||
|
||||
if [ "$HAVE_X11" != "no" ]; then
|
||||
if [ "$HAVE_XEXT" = "no" ]; then
|
||||
HAVE_XEXT=auto
|
||||
check_lib '' XEXT -lXext
|
||||
fi
|
||||
|
||||
if [ "$HAVE_XF86VM" = "no" ]; then
|
||||
HAVE_XF86VM=auto
|
||||
check_lib '' XF86VM -lXxf86vm
|
||||
fi
|
||||
else
|
||||
HAVE_XEXT=no; HAVE_XF86VM=no; HAVE_XINERAMA=no; HAVE_XSHM=no
|
||||
fi
|
||||
|
||||
check_pkgconf XINERAMA xinerama
|
||||
if [ "$HAVE_X11" = 'yes' ] && [ "$HAVE_XEXT" = 'yes' ] && [ "$HAVE_XF86VM" = 'yes' ]; then
|
||||
check_pkgconf XVIDEO xv
|
||||
else
|
||||
echo "Notice: X11, Xext or xf86vm not present. Skipping X11 code paths."
|
||||
die : 'Notice: X11, Xext or xf86vm not present. Skipping X11 code paths.'
|
||||
HAVE_X11='no'
|
||||
HAVE_XVIDEO='no'
|
||||
fi
|
||||
@ -427,8 +436,8 @@ fi
|
||||
if [ "$HAVE_UDEV" != "no" ]; then
|
||||
check_pkgconf UDEV libudev
|
||||
if [ "$HAVE_UDEV" = "no" ]; then
|
||||
HAVE_UDEV=auto; check_lib '' UDEV "-ludev"
|
||||
[ "$HAVE_UDEV" = "yes" ] && UDEV_LIBS=-ludev
|
||||
HAVE_UDEV=auto
|
||||
check_lib '' UDEV "-ludev"
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -444,18 +453,6 @@ check_lib '' STRCASESTR "$CLIB" strcasestr
|
||||
check_lib '' MMAP "$CLIB" mmap
|
||||
check_lib '' VULKAN -lvulkan vkCreateInstance
|
||||
|
||||
if [ "$HAVE_VULKAN" != 'no' ] && [ ! -e deps/glslang/glslang/README.md ]; then
|
||||
echo "Warning: glslang submodule not loaded, can't use Vulkan."
|
||||
echo "To fix, use: git submodule init && git submodule update"
|
||||
HAVE_VULKAN=no
|
||||
fi
|
||||
|
||||
if [ "$HAVE_VULKAN" != 'no' ] && [ ! -e deps/SPIRV-Cross/README.md ]; then
|
||||
echo "Warning: SPIRV-Cross submodule not loaded, can't use Vulkan."
|
||||
echo "To fix, use: git submodule init && git submodule update"
|
||||
HAVE_VULKAN=no
|
||||
fi
|
||||
|
||||
check_pkgconf PYTHON python3
|
||||
|
||||
if [ "$HAVE_MATERIALUI" != 'no' ] || [ "$HAVE_XMB" != 'no' ] || [ "$HAVE_ZARCH" != 'no' ]; then
|
||||
@ -463,35 +460,35 @@ if [ "$HAVE_MATERIALUI" != 'no' ] || [ "$HAVE_XMB" != 'no' ] || [ "$HAVE_ZARCH"
|
||||
HAVE_MATERIALUI=no
|
||||
HAVE_XMB=no
|
||||
HAVE_ZARCH=no
|
||||
echo "Notice: RGUI not available, MaterialUI, XMB and ZARCH will also be disabled."
|
||||
die : 'Notice: RGUI not available, MaterialUI, XMB and ZARCH will also be disabled.'
|
||||
elif [ "$HAVE_OPENGL" = 'no' ] && [ "$HAVE_OPENGLES" = 'no' ] && [ "$HAVE_VULKAN" = 'no' ]; then
|
||||
if [ "$OS" = 'Win32' ]; then
|
||||
HAVE_SHADERPIPELINE=no
|
||||
HAVE_VULKAN=no
|
||||
echo "Notice: Hardware rendering context not available."
|
||||
die : 'Notice: Hardware rendering context not available.'
|
||||
elif [ "$HAVE_CACA" = 'yes' ]; then
|
||||
echo "Notice: Hardware rendering context not available."
|
||||
die : 'Notice: Hardware rendering context not available.'
|
||||
else
|
||||
HAVE_MATERIALUI=no
|
||||
HAVE_XMB=no
|
||||
HAVE_ZARCH=no
|
||||
echo "Notice: Hardware rendering context not available, XMB, MaterialUI and ZARCH will also be disabled."
|
||||
die : 'Notice: Hardware rendering context not available, XMB, MaterialUI and ZARCH will also be disabled.'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
check_macro NEON __ARM_NEON__
|
||||
|
||||
add_define_make OS "$OS"
|
||||
add_define MAKEFILE OS "$OS"
|
||||
|
||||
if [ "$HAVE_ZLIB" = 'no' ] && [ "$HAVE_RPNG" != 'no' ]; then
|
||||
HAVE_RPNG=no
|
||||
echo "Notice: zlib is not available, RPNG will also be disabled."
|
||||
die : 'Notice: zlib is not available, RPNG will also be disabled.'
|
||||
fi
|
||||
|
||||
if [ "$HAVE_THREADS" = 'no' ] && [ "$HAVE_LIBUSB" != 'no' ]; then
|
||||
HAVE_LIBUSB=no
|
||||
echo "Notice: Threads are not available, libusb will also be disabled."
|
||||
die : 'Notice: Threads are not available, libusb will also be disabled.'
|
||||
fi
|
||||
|
||||
if [ "$HAVE_V4L2" != 'no' ] && [ "$HAVE_VIDEOPROCESSOR" != 'no' ]; then
|
||||
@ -499,7 +496,7 @@ if [ "$HAVE_V4L2" != 'no' ] && [ "$HAVE_VIDEOPROCESSOR" != 'no' ]; then
|
||||
fi
|
||||
|
||||
# Creates config.mk and config.h.
|
||||
add_define_make GLOBAL_CONFIG_DIR "$GLOBAL_CONFIG_DIR"
|
||||
add_define MAKEFILE GLOBAL_CONFIG_DIR "$GLOBAL_CONFIG_DIR"
|
||||
set -- $(set | grep ^HAVE_)
|
||||
while [ $# -gt 0 ]; do
|
||||
tmpvar="${1%=*}"
|
||||
|
@ -14,12 +14,17 @@ cc_works=0
|
||||
if [ "$CC" ]; then
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" >/dev/null 2>&1 && cc_works=1
|
||||
else
|
||||
for CC in $(printf %s "$(which ${CROSS_COMPILE}gcc ${CROSS_COMPILE}cc ${CROSS_COMPILE}clang 2>/dev/null)") ''; do
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" >/dev/null 2>&1 && cc_works=1 && break
|
||||
for cc in gcc cc clang; do
|
||||
CC="$(exists "${CROSS_COMPILE}${cc}")" || CC=""
|
||||
if [ "$CC" ]; then
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" >/dev/null 2>&1 && {
|
||||
cc_works=1; break
|
||||
}
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
rm -f "$TEMP_C" "$TEMP_EXE"
|
||||
rm -f -- "$TEMP_C" "$TEMP_EXE"
|
||||
|
||||
cc_status='does not work'
|
||||
if [ "$cc_works" = '1' ]; then
|
||||
@ -31,8 +36,7 @@ fi
|
||||
echo "Checking for suitable working C compiler ... $CC $cc_status"
|
||||
|
||||
if [ "$cc_works" = '0' ] && [ "$USE_LANG_C" = 'yes' ]; then
|
||||
echo "Error: Cannot proceed without a working C compiler."
|
||||
exit 1
|
||||
die 1 'Error: Cannot proceed without a working C compiler.'
|
||||
fi
|
||||
|
||||
# Checking for working C++
|
||||
@ -45,12 +49,17 @@ cxx_works=0
|
||||
if [ "$CXX" ]; then
|
||||
"$CXX" -o "$TEMP_EXE" "$TEMP_CXX" >/dev/null 2>&1 && cxx_works=1
|
||||
else
|
||||
for CXX in $(printf %s "$(which ${CROSS_COMPILE}g++ ${CROSS_COMPILE}c++ ${CROSS_COMPILE}clang++ 2>/dev/null)") ''; do
|
||||
"$CXX" -o "$TEMP_EXE" "$TEMP_CXX" >/dev/null 2>&1 && cxx_works=1 && break
|
||||
for cxx in g++ c++ clang++; do
|
||||
CXX="$(exists "${CROSS_COMPILE}${cxx}")" || CXX=""
|
||||
if [ "$CXX" ]; then
|
||||
"$CXX" -o "$TEMP_EXE" "$TEMP_CXX" >/dev/null 2>&1 && {
|
||||
cxx_works=1; break
|
||||
}
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
rm -f "$TEMP_CXX" "$TEMP_EXE"
|
||||
rm -f -- "$TEMP_CXX" "$TEMP_EXE"
|
||||
|
||||
cxx_status='does not work'
|
||||
if [ "$cxx_works" = '1' ]; then
|
||||
@ -62,33 +71,31 @@ fi
|
||||
echo "Checking for suitable working C++ compiler ... $CXX $cxx_status"
|
||||
|
||||
if [ "$cxx_works" = '0' ] && [ "$USE_LANG_CXX" = 'yes' ]; then
|
||||
echo "Error: Cannot proceed without a working C++ compiler."
|
||||
exit 1
|
||||
die 1 'Error: Cannot proceed without a working C++ compiler.'
|
||||
fi
|
||||
|
||||
if [ "$OS" = "Win32" ]; then
|
||||
echobuf="Checking for windres"
|
||||
if [ -z "$WINDRES" ]; then
|
||||
WINDRES=$(which ${CROSS_COMPILE}windres)
|
||||
[ "$WINDRES" ] || { echo "$echobuf ... Not found. Exiting."; exit 1; }
|
||||
WINDRES="$(exists "${CROSS_COMPILE}windres")" || WINDRES=""
|
||||
[ -z "$WINDRES" ] && die 1 "$echobuf ... Not found. Exiting."
|
||||
fi
|
||||
echo "$echobuf ... $WINDRES"
|
||||
fi
|
||||
|
||||
[ -n "$PKG_CONF_PATH" ] || {
|
||||
if [ -z "$PKG_CONF_PATH" ]; then
|
||||
PKG_CONF_PATH="none"
|
||||
|
||||
for p in $(which "${CROSS_COMPILE}pkg-config" 2>/dev/null) ''; do
|
||||
[ -n "$p" ] && {
|
||||
PKG_CONF_PATH=$p;
|
||||
break;
|
||||
for pkgconf in pkgconf pkg-config; do
|
||||
PKGCONF="$(exists "${CROSS_COMPILE}${pkgconf}")" || PKGCONF=""
|
||||
[ "$PKGCONF" ] && {
|
||||
PKG_CONF_PATH="$PKGCONF"
|
||||
break
|
||||
}
|
||||
done
|
||||
|
||||
}
|
||||
fi
|
||||
|
||||
echo "Checking for pkg-config ... $PKG_CONF_PATH"
|
||||
|
||||
if [ "$PKG_CONF_PATH" = "none" ]; then
|
||||
echo "Warning: pkg-config not found, package checks will fail."
|
||||
die : 'Warning: pkg-config not found, package checks will fail.'
|
||||
fi
|
||||
|
233
qb/qb.libs.sh
233
qb/qb.libs.sh
@ -1,50 +1,48 @@
|
||||
MAKEFILE_DEFINES='.MAKEFILE_DEFINES'
|
||||
CONFIG_DEFINES='.CONFIG_DEFINES'
|
||||
cat /dev/null > "$MAKEFILE_DEFINES" > "$CONFIG_DEFINES"
|
||||
#cat /dev/null > "${MAKEFILE_DEFINES:=.MAKEFILE_DEFINES}" > "${CONFIG_DEFINES=.CONFIG_DEFINES}"
|
||||
MAKEFILE_DEFINES=''
|
||||
CONFIG_DEFINES=''
|
||||
|
||||
[ "$PREFIX" ] || PREFIX="/usr/local"
|
||||
|
||||
add_define_header()
|
||||
{ echo "$1=$2" >> "$CONFIG_DEFINES";}
|
||||
add_define() # $1 = MAKEFILE or CONFIG $2 = define $3 = value
|
||||
{ eval "${1}_DEFINES=\"\${${1}_DEFINES} $2=$3\""; }
|
||||
|
||||
add_define_make()
|
||||
{ echo "$1=$2" >> "$MAKEFILE_DEFINES";}
|
||||
|
||||
add_include_dirs()
|
||||
{ while [ "$1" ]; do INCLUDE_DIRS="$INCLUDE_DIRS -I$1"; shift; done
|
||||
INCLUDE_DIRS="${INCLUDE_DIRS# }"
|
||||
add_dirs() # $1 = INCLUDE or LIBRARY $@ = include or library paths
|
||||
{ ADD="$1"; LINK="${1%"${1#?}"}"; shift
|
||||
while [ "$1" ]; do
|
||||
eval "${ADD}_DIRS=\"\${${ADD}_DIRS} -${LINK}${1}\""
|
||||
shift
|
||||
done
|
||||
eval "${ADD}_DIRS=\"\${${ADD}_DIRS# }\""
|
||||
}
|
||||
|
||||
add_library_dirs()
|
||||
{ while [ "$1" ]; do LIBRARY_DIRS="$LIBRARY_DIRS -L$1"; shift; done
|
||||
LIBRARY_DIRS="${LIBRARY_DIRS# }"
|
||||
}
|
||||
|
||||
check_lib() # $1 = language $2 = HAVE_$2 $3 = lib $4 = function in lib $5 = extralibs $6 = headers $7 = critical error message [checked only if non-empty]
|
||||
{ tmpval="$(eval echo \$HAVE_$2)"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
|
||||
if [ "$1" = cxx ]; then
|
||||
check_compiler() # $1 = language $2 = function in lib
|
||||
{ if [ "$1" = cxx ]; then
|
||||
COMPILER="$CXX"
|
||||
TEMP_CODE="$TEMP_CXX"
|
||||
TEST_C="extern \"C\" { void $4(void); } int main() { $4(); }"
|
||||
TEST_C="extern \"C\" { void $2(void); } int main() { $2(); }"
|
||||
else
|
||||
COMPILER="$CC"
|
||||
TEMP_CODE="$TEMP_C"
|
||||
TEST_C="void $4(void); int main(void) { $4(); return 0; }"
|
||||
TEST_C="void $2(void); int main(void) { $2(); return 0; }"
|
||||
fi
|
||||
}
|
||||
|
||||
check_lib() # $1 = language $2 = HAVE_$2 $3 = lib $4 = function in lib $5 = extralibs $6 = headers $7 = critical error message [checked only if non-empty]
|
||||
{ tmpval="$(eval "printf %s \"\$HAVE_$2\"")"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
|
||||
check_compiler "$1" "$4"
|
||||
|
||||
if [ "$4" ]; then
|
||||
ECHOBUF="Checking function $4 in ${3% }"
|
||||
if [ "$6" ]; then
|
||||
printf %s\\n "$6" "int main(void) { void *p = (void*)$4; return 0; }" > "$TEMP_CODE"
|
||||
else
|
||||
echo "$TEST_C" > "$TEMP_CODE"
|
||||
printf %s\\n "$TEST_C" > "$TEMP_CODE"
|
||||
fi
|
||||
else
|
||||
ECHOBUF="Checking existence of ${3% }"
|
||||
echo "int main(void) { return 0; }" > "$TEMP_CODE"
|
||||
printf %s\\n 'int main(void) { return 0; }' > "$TEMP_CODE"
|
||||
fi
|
||||
answer='no'
|
||||
"$COMPILER" -o \
|
||||
@ -56,43 +54,23 @@ check_lib() # $1 = language $2 = HAVE_$2 $3 = lib $4 = function in lib $5 =
|
||||
$CFLAGS \
|
||||
$LDFLAGS \
|
||||
$(printf %s "$3") >>config.log 2>&1 && answer='yes'
|
||||
eval HAVE_$2="$answer"; echo "$ECHOBUF ... $answer"
|
||||
eval "HAVE_$2=\"$answer\""
|
||||
printf %s\\n "$ECHOBUF ... $answer"
|
||||
rm -f -- "$TEMP_CODE" "$TEMP_EXE"
|
||||
|
||||
[ "$answer" = 'no' ] && {
|
||||
[ "$7" ] && { echo "$7"; exit 1;}
|
||||
if [ "$answer" = 'no' ]; then
|
||||
[ "$7" ] && die 1 "$7"
|
||||
[ "$tmpval" = 'yes' ] && {
|
||||
echo "Forced to build with library $3, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
die 1 "Forced to build with library $3, but cannot locate. Exiting ..."
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
eval "${2}_LIBS=\"$3\""
|
||||
PKG_CONF_USED="$PKG_CONF_USED $2"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
check_code_c()
|
||||
{ tmpval="$(eval echo \$HAVE_$1)"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
|
||||
ECHOBUF="Checking C code snippet \"$3\""
|
||||
answer='no'
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" $INCLUDE_DIRS $LIBRARY_DIRS $2 $CFLAGS $LDFLAGS >>config.log 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm -f -- "$TEMP_C" "$TEMP_EXE"
|
||||
}
|
||||
|
||||
check_code_cxx()
|
||||
{ tmpval="$(eval echo \$HAVE_$1)"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
|
||||
ECHOBUF="Checking C++ code snippet \"$3\""
|
||||
answer='no'
|
||||
"$CXX" -o "$TEMP_EXE" "$TEMP_CXX" $INCLUDE_DIRS $LIBRARY_DIRS $2 $CXXFLAGS $LDFLAGS >>config.log 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm -f -- "$TEMP_CXX" "$TEMP_EXE"
|
||||
}
|
||||
|
||||
check_pkgconf() #$1 = HAVE_$1 $2 = package $3 = version $4 = critical error message [checked only if non-empty]
|
||||
{ tmpval="$(eval echo \$HAVE_$1)"
|
||||
[ "$tmpval" = 'no' ] && return 0
|
||||
@ -117,14 +95,13 @@ check_pkgconf() #$1 = HAVE_$1 $2 = package $3 = version $4 = critical error mess
|
||||
|
||||
eval HAVE_$1="$answer";
|
||||
echo "$ECHOBUF ... $version"
|
||||
PKG_CONF_USED="$PKG_CONF_USED $1"
|
||||
[ "$answer" = 'no' ] && {
|
||||
[ "$4" ] && { echo "$4"; exit 1;}
|
||||
[ "$tmpval" = 'yes' ] && {
|
||||
echo "Forced to build with package $2, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
if [ "$answer" = 'no' ]; then
|
||||
[ "$4" ] && die 1 "$4"
|
||||
[ "$tmpval" = 'yes' ] && \
|
||||
die 1 "Forced to build with package $2, but cannot locate. Exiting ..."
|
||||
else
|
||||
PKG_CONF_USED="$PKG_CONF_USED $1"
|
||||
fi
|
||||
}
|
||||
|
||||
check_header() #$1 = HAVE_$1 $2..$5 = header files
|
||||
@ -140,10 +117,8 @@ check_header() #$1 = HAVE_$1 $2..$5 = header files
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" $INCLUDE_DIRS >>config.log 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "Checking presence of header file $CHECKHEADER ... $answer"
|
||||
rm -f -- "$TEMP_C" "$TEMP_EXE"
|
||||
[ "$tmpval" = 'yes' ] && [ "$answer" = 'no' ] && {
|
||||
echo "Build assumed that $2 exists, but cannot locate. Exiting ..."
|
||||
exit 1
|
||||
}
|
||||
[ "$tmpval" = 'yes' ] && [ "$answer" = 'no' ] && \
|
||||
die 1 "Build assumed that $2 exists, but cannot locate. Exiting ..."
|
||||
}
|
||||
|
||||
check_macro() #$1 = HAVE_$1 $2 = macro name
|
||||
@ -160,110 +135,104 @@ EOF
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" $CFLAGS $INCLUDE_DIRS >>config.log 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm -f -- "$TEMP_C" "$TEMP_EXE"
|
||||
[ "$tmpval" = 'yes' ] && [ "$answer" = 'no' ] && {
|
||||
echo "Build assumed that $2 is defined, but it's not. Exiting ..."
|
||||
exit 1
|
||||
}
|
||||
[ "$tmpval" = 'yes' ] && [ "$answer" = 'no' ] && \
|
||||
die 1 "Build assumed that $2 is defined, but it's not. Exiting ..."
|
||||
}
|
||||
|
||||
check_switch_c() #$1 = HAVE_$1 $2 = switch $3 = critical error message [checked only if non-empty]
|
||||
{ ECHOBUF="Checking for availability of switch $2 in $CC"
|
||||
echo "int main(void) { return 0; }" > $TEMP_C
|
||||
answer='no'
|
||||
"$CC" -o "$TEMP_EXE" "$TEMP_C" $2 >>config.log 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm -f -- "$TEMP_C" "$TEMP_EXE"
|
||||
[ "$answer" = 'no' ] && {
|
||||
[ "$3" ] && { echo "$3"; exit 1;}
|
||||
}
|
||||
}
|
||||
check_switch() # $1 = language $2 = HAVE_$2 $3 = switch $4 = critical error message [checked only if non-empty]
|
||||
{ check_compiler "$1" ''
|
||||
|
||||
check_switch_cxx() #$1 = HAVE_$1 $2 = switch $3 = critical error message [checked only if non-empty]
|
||||
{ ECHOBUF="Checking for availability of switch $2 in $CXX"
|
||||
echo "int main() { return 0; }" > $TEMP_CXX
|
||||
ECHOBUF="Checking for availability of switch $3 in $COMPILER"
|
||||
printf %s\\n 'int main(void) { return 0; }' > "$TEMP_CODE"
|
||||
answer='no'
|
||||
"$CXX" -o "$TEMP_EXE" "$TEMP_CXX" "$2" >>config.log 2>&1 && answer='yes'
|
||||
eval HAVE_$1="$answer"; echo "$ECHOBUF ... $answer"
|
||||
rm -f -- "$TEMP_CXX" "$TEMP_EXE"
|
||||
"$COMPILER" -o "$TEMP_EXE" "$TEMP_CODE" "$3" >>config.log 2>&1 && answer='yes'
|
||||
eval "HAVE_$2=\"$answer\""
|
||||
printf %s\\n "$ECHOBUF ... $answer"
|
||||
rm -f -- "$TEMP_CODE" "$TEMP_EXE"
|
||||
[ "$answer" = 'no' ] && {
|
||||
[ "$3" ] && { echo "$3"; exit 1;}
|
||||
[ "$4" ] && die 1 "$4"
|
||||
}
|
||||
}
|
||||
|
||||
create_config_header()
|
||||
{ outfile="$1"; shift
|
||||
|
||||
echo "Creating config header: $outfile"
|
||||
name=$(echo "QB_${outfile}__" | tr '.[a-z]' '_[A-Z]')
|
||||
{ echo "#ifndef $name"
|
||||
echo "#define $name"
|
||||
echo ""
|
||||
echo "#define PACKAGE_NAME \"$PACKAGE_NAME\""
|
||||
printf %s\\n "Creating config header: $outfile"
|
||||
name="$(printf %s "QB_${outfile}__" | tr '.[a-z]' '_[A-Z]')"
|
||||
|
||||
{ printf %s\\n "#ifndef $name" "#define $name" '' \
|
||||
"#define PACKAGE_NAME \"$PACKAGE_NAME\""
|
||||
|
||||
while [ "$1" ]; do
|
||||
case $(eval echo \$HAVE_$1) in
|
||||
case "$(eval "printf %s \"\$HAVE_$1\"")" in
|
||||
'yes')
|
||||
if [ "$(eval echo \$C89_$1)" = "no" ]; then echo "#if __cplusplus || __STDC_VERSION__ >= 199901L"; fi
|
||||
echo "#define HAVE_$1 1"
|
||||
if [ "$(eval echo \$C89_$1)" = "no" ]; then echo "#endif"; fi
|
||||
;;
|
||||
'no') echo "/* #undef HAVE_$1 */";;
|
||||
if [ "$(eval "printf %s \"\$C89_$1\"")" = 'no' ]; then
|
||||
printf %s\\n '#if __cplusplus || __STDC_VERSION__ >= 199901L' \
|
||||
"#define HAVE_$1 1" '#endif'
|
||||
else
|
||||
printf %s\\n "#define HAVE_$1 1"
|
||||
fi
|
||||
;;
|
||||
'no') printf %s\\n "/* #undef HAVE_$1 */";;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
while IFS='=' read VAR VAL; do echo "#define $VAR $VAL"; done < "$CONFIG_DEFINES"
|
||||
eval "set -- $CONFIG_DEFINES"
|
||||
for VAR do
|
||||
printf %s\\n "#define ${VAR%%=*} ${VAR#*=}"
|
||||
done
|
||||
|
||||
echo "#endif"
|
||||
printf %s\\n '#endif'
|
||||
} > "$outfile"
|
||||
}
|
||||
|
||||
create_config_make()
|
||||
{ outfile="$1"; shift
|
||||
|
||||
echo "Creating make config: $outfile"
|
||||
printf %s\\n "Creating make config: $outfile"
|
||||
|
||||
{ if [ "$USE_LANG_C" = 'yes' ]; then
|
||||
echo "CC = $CC"
|
||||
echo "CFLAGS = $CFLAGS"
|
||||
fi
|
||||
if [ "$USE_LANG_CXX" = 'yes' ]; then
|
||||
echo "CXX = $CXX"
|
||||
echo "CXXFLAGS = $CXXFLAGS"
|
||||
fi
|
||||
echo "WINDRES = $WINDRES"
|
||||
echo "ASFLAGS = $ASFLAGS"
|
||||
echo "LDFLAGS = $LDFLAGS"
|
||||
echo "INCLUDE_DIRS = $INCLUDE_DIRS"
|
||||
echo "LIBRARY_DIRS = $LIBRARY_DIRS"
|
||||
echo "PACKAGE_NAME = $PACKAGE_NAME"
|
||||
echo "PREFIX = $PREFIX"
|
||||
{ [ "$USE_LANG_C" = 'yes' ] && printf %s\\n "CC = $CC" "CFLAGS = $CFLAGS"
|
||||
[ "$USE_LANG_CXX" = 'yes' ] && printf %s\\n "CXX = $CXX" "CXXFLAGS = $CXXFLAGS"
|
||||
|
||||
printf %s\\n "WINDRES = $WINDRES" \
|
||||
"ASFLAGS = $ASFLAGS" \
|
||||
"LDFLAGS = $LDFLAGS" \
|
||||
"INCLUDE_DIRS = $INCLUDE_DIRS" \
|
||||
"LIBRARY_DIRS = $LIBRARY_DIRS" \
|
||||
"PACKAGE_NAME = $PACKAGE_NAME" \
|
||||
"BUILD = $BUILD" \
|
||||
"PREFIX = $PREFIX"
|
||||
|
||||
while [ "$1" ]; do
|
||||
case $(eval echo \$HAVE_$1) in
|
||||
case "$(eval "printf %s \"\$HAVE_$1\"")" in
|
||||
'yes')
|
||||
if [ "$(eval echo \$C89_$1)" = "no" ]; then echo "ifneq (\$(C89_BUILD),1)"; fi
|
||||
echo "HAVE_$1 = 1"
|
||||
if [ "$(eval echo \$C89_$1)" = "no" ]; then echo "endif"; fi
|
||||
;;
|
||||
'no') echo "HAVE_$1 = 0";;
|
||||
if [ "$(eval "printf %s \"\$C89_$1\"")" = 'no' ]; then
|
||||
printf %s\\n "ifneq (\$(C89_BUILD),1)" \
|
||||
"HAVE_$1 = 1" 'endif'
|
||||
else
|
||||
printf %s\\n "HAVE_$1 = 1"
|
||||
fi
|
||||
;;
|
||||
'no') printf %s\\n "HAVE_$1 = 0";;
|
||||
esac
|
||||
|
||||
case "$PKG_CONF_USED" in
|
||||
*$1*)
|
||||
FLAGS="$(eval echo \$$1_CFLAGS)"
|
||||
LIBS="$(eval echo \$$1_LIBS)"
|
||||
echo "$1_CFLAGS = ${FLAGS%"${FLAGS##*[! ]}"}"
|
||||
echo "$1_LIBS = ${LIBS%"${LIBS##*[! ]}"}"
|
||||
FLAGS="$(eval "printf %s \"\$$1_CFLAGS\"")"
|
||||
LIBS="$(eval "printf %s \"\$$1_LIBS\"")"
|
||||
[ "${FLAGS}" ] && printf %s\\n "$1_CFLAGS = ${FLAGS%"${FLAGS##*[! ]}"}"
|
||||
[ "${LIBS}" ] && printf %s\\n "$1_LIBS = ${LIBS%"${LIBS##*[! ]}"}"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
while IFS='=' read VAR VAL; do echo "$VAR = $VAL"; done < "$MAKEFILE_DEFINES"
|
||||
eval "set -- $MAKEFILE_DEFINES"
|
||||
for VAR do
|
||||
printf %s\\n "${VAR%%=*} = ${VAR#*=}"
|
||||
done
|
||||
|
||||
} > "$outfile"
|
||||
}
|
||||
|
||||
. qb/config.libs.sh
|
||||
|
||||
rm -f -- "$MAKEFILE_DEFINES" "$CONFIG_DEFINES"
|
||||
|
@ -1,3 +1,14 @@
|
||||
die() # $1 = exit code, use : to not exit when printing warnings $@ = exit or warning messages
|
||||
{
|
||||
ret="$1"
|
||||
shift 1
|
||||
printf %s\\n "$@" >&2
|
||||
case "$ret" in
|
||||
: ) return 0 ;;
|
||||
* ) exit "$ret" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
print_help_option() # $1 = option $@ = description
|
||||
{
|
||||
_opt="$1"
|
||||
@ -23,14 +34,18 @@ General options:
|
||||
EOF
|
||||
print_help_option "--prefix=PATH" "Install path prefix"
|
||||
print_help_option "--global-config-dir=PATH" "System wide config file prefix"
|
||||
print_help_option "--host=HOST" "cross-compile to build programs to run on HOST"
|
||||
print_help_option "--build=BUILD" "The build system (no-op)"
|
||||
print_help_option "--host=HOST" "Cross-compile with HOST-gcc instead of gcc"
|
||||
print_help_option "--help" "Show this help"
|
||||
|
||||
echo ""
|
||||
echo "Custom options:"
|
||||
|
||||
while IFS='=#' read VAR VAL COMMENT; do
|
||||
VAR=$(echo "${VAR##HAVE_}" | tr '[:upper:]' '[:lower:]')
|
||||
while read -r VAR COMMENT; do
|
||||
TMPVAR="${VAR%=*}"
|
||||
COMMENT="${COMMENT#*#}"
|
||||
VAL="${VAR#*=}"
|
||||
VAR="$(echo "${TMPVAR#HAVE_}" | tr '[:upper:]' '[:lower:]')"
|
||||
case "$VAR" in
|
||||
'c89_'*) continue;;
|
||||
*)
|
||||
@ -50,20 +65,26 @@ EOF
|
||||
}
|
||||
|
||||
opt_exists() # $opt is returned if exists in OPTS
|
||||
{ opt=$(echo "$1" | tr '[:lower:]' '[:upper:]')
|
||||
for OPT in $OPTS; do [ "$opt" = "$OPT" ] && return; done
|
||||
echo "Unknown option $2"; exit 1
|
||||
{ opt="$(echo "$1" | tr '[:lower:]' '[:upper:]')"
|
||||
err="$2"
|
||||
eval "set -- $OPTS"
|
||||
for OPT do [ "$opt" = "$OPT" ] && return; done
|
||||
die 1 "Unknown option $err"
|
||||
}
|
||||
|
||||
parse_input() # Parse stuff :V
|
||||
{ OPTS=; while IFS='=' read VAR dummy; do OPTS="$OPTS ${VAR##HAVE_}"; done < 'qb/config.params.sh'
|
||||
#OPTS contains all available options in config.params.sh - used to speedup
|
||||
#things in opt_exists()
|
||||
{ OPTS=; while read -r VAR _; do
|
||||
TMPVAR="${VAR%=*}"
|
||||
OPTS="$OPTS ${TMPVAR##HAVE_}"
|
||||
done < 'qb/config.params.sh'
|
||||
#OPTS contains all available options in config.params.sh - used to speedup
|
||||
#things in opt_exists()
|
||||
|
||||
while [ "$1" ]; do
|
||||
case "$1" in
|
||||
--prefix=*) PREFIX=${1##--prefix=};;
|
||||
--global-config-dir=*) GLOBAL_CONFIG_DIR=${1##--global-config-dir=};;
|
||||
--build=*) BUILD="${1#*=}";;
|
||||
--host=*) CROSS_COMPILE=${1##--host=}-;;
|
||||
--enable-*)
|
||||
opt_exists "${1##--enable-}" "$1"
|
||||
@ -81,7 +102,7 @@ parse_input() # Parse stuff :V
|
||||
eval "$opt=\"$val\""
|
||||
;;
|
||||
-h|--help) print_help; exit 0;;
|
||||
*) echo "Unknown option $1"; exit 1;;
|
||||
*) die 1 "Unknown option $1";;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
@ -89,4 +110,4 @@ parse_input() # Parse stuff :V
|
||||
|
||||
. qb/config.params.sh
|
||||
|
||||
parse_input "$@"
|
||||
parse_input "$@"
|
||||
|
@ -1,3 +1,24 @@
|
||||
exists() # checks executables listed in $@ against the $PATH
|
||||
{
|
||||
v=1
|
||||
while [ "$#" -gt 0 ]; do
|
||||
arg="$1"
|
||||
shift 1
|
||||
case "$arg" in ''|*/) continue ;; esac
|
||||
x="${arg##*/}"
|
||||
z="${arg%/*}"
|
||||
[ ! -f "$z/$x" ] || [ ! -x "$z/$x" ] && [ "$z/$x" = "$arg" ] && continue
|
||||
[ "$x" = "$z" ] && [ -x "$z/$x" ] && [ ! -f "$arg" ] && z=
|
||||
p=":$z:$PATH"
|
||||
while [ "$p" != "${p#*:}" ]; do
|
||||
p="${p#*:}"
|
||||
d="${p%%:*}"
|
||||
{ [ -f "$d/$x" ] && [ -x "$d/$x" ] && \
|
||||
{ printf %s\\n "$d/$x"; v=0; break; }; } || :
|
||||
done
|
||||
done
|
||||
return "$v"
|
||||
}
|
||||
|
||||
if [ -n "$CROSS_COMPILE" ]; then
|
||||
case "$CROSS_COMPILE" in
|
||||
@ -26,4 +47,3 @@ if [ -e /etc/lsb-release ]; then
|
||||
fi
|
||||
|
||||
echo "Checking operating system ... $OS ${DISTRO}"
|
||||
|
||||
|
@ -68,6 +68,17 @@ extern "C" {
|
||||
#include "../../gfx/video_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#ifndef AV_CODEC_FLAG_QSCALE
|
||||
#define AV_CODEC_FLAG_QSCALE CODEC_FLAG_QSCALE
|
||||
#endif
|
||||
|
||||
#ifndef AV_CODEC_FLAG_GLOBAL_HEADER
|
||||
#define AV_CODEC_FLAG_GLOBAL_HEADER CODEC_FLAG_GLOBAL_HEADER
|
||||
#endif
|
||||
|
||||
#ifndef AV_INPUT_BUFFER_MIN_SIZE
|
||||
#define AV_INPUT_BUFFER_MIN_SIZE FF_MIN_BUFFER_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef PIX_FMT_RGB32
|
||||
#define PIX_FMT_RGB32 AV_PIX_FMT_RGB32
|
||||
@ -348,7 +359,7 @@ static bool ffmpeg_init_audio(ffmpeg_t *handle)
|
||||
|
||||
if (params->audio_qscale)
|
||||
{
|
||||
audio->codec->flags |= CODEC_FLAG_QSCALE;
|
||||
audio->codec->flags |= AV_CODEC_FLAG_QSCALE;
|
||||
audio->codec->global_quality = params->audio_global_quality;
|
||||
}
|
||||
else if (params->audio_bit_rate)
|
||||
@ -358,7 +369,7 @@ static bool ffmpeg_init_audio(ffmpeg_t *handle)
|
||||
audio->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
||||
|
||||
if (handle->muxer.ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
audio->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
audio->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
if (avcodec_open2(audio->codec, codec, params->audio_opts ? ¶ms->audio_opts : NULL) != 0)
|
||||
return false;
|
||||
@ -378,7 +389,7 @@ static bool ffmpeg_init_audio(ffmpeg_t *handle)
|
||||
if (!audio->buffer)
|
||||
return false;
|
||||
|
||||
audio->outbuf_size = FF_MIN_BUFFER_SIZE;
|
||||
audio->outbuf_size = AV_INPUT_BUFFER_MIN_SIZE;
|
||||
audio->outbuf = (uint8_t*)av_malloc(audio->outbuf_size);
|
||||
if (!audio->outbuf)
|
||||
return false;
|
||||
@ -490,14 +501,14 @@ static bool ffmpeg_init_video(ffmpeg_t *handle)
|
||||
|
||||
if (params->video_qscale)
|
||||
{
|
||||
video->codec->flags |= CODEC_FLAG_QSCALE;
|
||||
video->codec->flags |= AV_CODEC_FLAG_QSCALE;
|
||||
video->codec->global_quality = params->video_global_quality;
|
||||
}
|
||||
else if (params->video_bit_rate)
|
||||
video->codec->bit_rate = params->video_bit_rate;
|
||||
|
||||
if (handle->muxer.ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
video->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
video->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
if (avcodec_open2(video->codec, codec, params->video_opts ?
|
||||
¶ms->video_opts : NULL) != 0)
|
||||
|
102
retroarch.c
102
retroarch.c
@ -219,6 +219,7 @@ static bool runloop_paused = false;
|
||||
static bool runloop_idle = false;
|
||||
static bool runloop_exec = false;
|
||||
static bool runloop_slowmotion = false;
|
||||
static bool runloop_fastmotion = false;
|
||||
static bool runloop_shutdown_initiated = false;
|
||||
static bool runloop_core_shutdown_initiated = false;
|
||||
static bool runloop_perfcnt_enable = false;
|
||||
@ -1380,10 +1381,10 @@ static bool rarch_game_specific_options(char **output)
|
||||
|
||||
if (!retroarch_validate_game_options(game_path,
|
||||
game_path_size, false))
|
||||
goto error;
|
||||
goto error;
|
||||
|
||||
if (!config_file_exists(game_path))
|
||||
goto error;
|
||||
goto error;
|
||||
|
||||
RARCH_LOG("%s %s\n",
|
||||
msg_hash_to_str(MSG_GAME_SPECIFIC_CORE_OPTIONS_FOUND_AT),
|
||||
@ -2309,40 +2310,40 @@ bool runloop_msg_queue_pull(const char **ret)
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
static bool input_driver_toggle_button_combo(
|
||||
unsigned mode, uint64_t input)
|
||||
unsigned mode, retro_bits_t* p_input)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case INPUT_TOGGLE_DOWN_Y_L_R:
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_DOWN))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_DOWN))
|
||||
return false;
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_Y))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_Y))
|
||||
return false;
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_L))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L))
|
||||
return false;
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_R))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R))
|
||||
return false;
|
||||
break;
|
||||
case INPUT_TOGGLE_L3_R3:
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_L3))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L3))
|
||||
return false;
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_R3))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R3))
|
||||
return false;
|
||||
break;
|
||||
case INPUT_TOGGLE_L1_R1_START_SELECT:
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_START))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_START))
|
||||
return false;
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_SELECT))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_SELECT))
|
||||
return false;
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_L))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L))
|
||||
return false;
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_R))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R))
|
||||
return false;
|
||||
break;
|
||||
case INPUT_TOGGLE_START_SELECT:
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_START))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_START))
|
||||
return false;
|
||||
if (!BIT64_GET(input, RETRO_DEVICE_ID_JOYPAD_SELECT))
|
||||
if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_SELECT))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
@ -2359,7 +2360,7 @@ static enum runloop_state runloop_check_state(
|
||||
bool input_nonblock_state,
|
||||
unsigned *sleep_ms)
|
||||
{
|
||||
static uint64_t last_input = 0;
|
||||
static retro_bits_t last_input = {{0}};
|
||||
static bool old_fs_toggle_pressed= false;
|
||||
static bool old_focus = true;
|
||||
bool is_focused = false;
|
||||
@ -2371,13 +2372,17 @@ static enum runloop_state runloop_check_state(
|
||||
#ifdef HAVE_MENU
|
||||
bool menu_driver_binding_state = menu_driver_is_binding_state();
|
||||
bool menu_is_alive = menu_driver_is_alive();
|
||||
uint64_t current_input =
|
||||
menu_is_alive && !(settings->bools.menu_unified_controls && !menu_input_dialog_get_display_kb())?
|
||||
input_menu_keys_pressed(settings, last_input) :
|
||||
input_keys_pressed(settings, last_input);
|
||||
|
||||
retro_bits_t current_input;
|
||||
|
||||
if ( menu_is_alive && !(settings->bools.menu_unified_controls && !menu_input_dialog_get_display_kb()) )
|
||||
input_menu_keys_pressed(settings, ¤t_input);
|
||||
else
|
||||
input_keys_pressed(settings, ¤t_input);
|
||||
|
||||
#else
|
||||
uint64_t current_input =
|
||||
input_keys_pressed(settings, last_input);
|
||||
retro_bits_t current_input;
|
||||
input_keys_pressed(settings, ¤t_input);
|
||||
#endif
|
||||
last_input = current_input;
|
||||
|
||||
@ -2385,20 +2390,20 @@ static enum runloop_state runloop_check_state(
|
||||
if (
|
||||
((settings->uints.input_menu_toggle_gamepad_combo != INPUT_TOGGLE_NONE) &&
|
||||
input_driver_toggle_button_combo(
|
||||
settings->uints.input_menu_toggle_gamepad_combo, last_input)))
|
||||
settings->uints.input_menu_toggle_gamepad_combo, &last_input)))
|
||||
{
|
||||
BIT64_SET(current_input, RARCH_MENU_TOGGLE);
|
||||
RARCH_INPUT_STATE_BIT_SET(current_input, RARCH_MENU_TOGGLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (input_driver_flushing_input)
|
||||
{
|
||||
input_driver_flushing_input = false;
|
||||
if (current_input)
|
||||
if (RARCH_INPUT_STATE_ANY_SET(current_input))
|
||||
{
|
||||
current_input = 0;
|
||||
RARCH_INPUT_STATE_CLEAR( current_input );
|
||||
if (runloop_paused)
|
||||
BIT64_SET(current_input, RARCH_PAUSE_TOGGLE);
|
||||
RARCH_INPUT_STATE_BIT_SET(current_input, RARCH_PAUSE_TOGGLE);
|
||||
input_driver_flushing_input = true;
|
||||
}
|
||||
}
|
||||
@ -2407,7 +2412,7 @@ static enum runloop_state runloop_check_state(
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
if (menu_driver_binding_state)
|
||||
current_input = 0;
|
||||
RARCH_INPUT_STATE_CLEAR( current_input );
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
@ -2528,15 +2533,21 @@ static enum runloop_state runloop_check_state(
|
||||
#ifdef HAVE_MENU
|
||||
if (menu_is_alive)
|
||||
{
|
||||
static uint64_t old_input = 0;
|
||||
static retro_bits_t old_input = {{0}};
|
||||
menu_ctx_iterate_t iter;
|
||||
|
||||
retro_ctx.poll_cb();
|
||||
|
||||
{
|
||||
uint64_t trigger_input = current_input & ~old_input;
|
||||
enum menu_action action = (enum menu_action)menu_event(current_input, trigger_input);
|
||||
bool focused = pause_nonactive ? is_focused : true;
|
||||
retro_bits_t trigger_input;
|
||||
enum menu_action action;
|
||||
bool focused;
|
||||
|
||||
trigger_input = current_input;
|
||||
RARCH_INPUT_STATE_CLEAR_BITS( trigger_input, old_input );
|
||||
|
||||
action = (enum menu_action)menu_event(¤t_input, &trigger_input);
|
||||
focused = pause_nonactive ? is_focused : true;
|
||||
|
||||
focused = focused && !ui_companion_is_on_foreground();
|
||||
|
||||
@ -2765,21 +2776,35 @@ static enum runloop_state runloop_check_state(
|
||||
|
||||
if (new_button_state && !old_button_state)
|
||||
{
|
||||
if (input_nonblock_state)
|
||||
if (input_nonblock_state) {
|
||||
input_driver_unset_nonblock_state();
|
||||
else
|
||||
runloop_fastmotion = false;
|
||||
}
|
||||
else {
|
||||
input_driver_set_nonblock_state();
|
||||
runloop_fastmotion = true;
|
||||
}
|
||||
driver_set_nonblock_state();
|
||||
}
|
||||
else if (old_hold_button_state != new_hold_button_state)
|
||||
{
|
||||
if (new_hold_button_state)
|
||||
if (new_hold_button_state) {
|
||||
input_driver_set_nonblock_state();
|
||||
else
|
||||
runloop_fastmotion = true;
|
||||
}
|
||||
else {
|
||||
input_driver_unset_nonblock_state();
|
||||
runloop_fastmotion = false;
|
||||
}
|
||||
driver_set_nonblock_state();
|
||||
}
|
||||
|
||||
// Display the fast forward state to the user, if needed.
|
||||
if (runloop_fastmotion) {
|
||||
runloop_msg_queue_push(
|
||||
msg_hash_to_str(MSG_FAST_FORWARD), 1, 1, false);
|
||||
}
|
||||
|
||||
old_button_state = new_button_state;
|
||||
old_hold_button_state = new_hold_button_state;
|
||||
}
|
||||
@ -2883,10 +2908,10 @@ static enum runloop_state runloop_check_state(
|
||||
|
||||
if (state_manager_frame_is_reversed())
|
||||
runloop_msg_queue_push(
|
||||
msg_hash_to_str(MSG_SLOW_MOTION_REWIND), 2, 30, true);
|
||||
msg_hash_to_str(MSG_SLOW_MOTION_REWIND), 1, 1, false);
|
||||
else
|
||||
runloop_msg_queue_push(
|
||||
msg_hash_to_str(MSG_SLOW_MOTION), 2, 30, true);
|
||||
msg_hash_to_str(MSG_SLOW_MOTION), 1, 1, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3130,7 +3155,6 @@ int runloop_iterate(unsigned *sleep_ms)
|
||||
if (settings->floats.fastforward_ratio)
|
||||
end:
|
||||
{
|
||||
|
||||
retro_time_t to_sleep_ms = (
|
||||
(frame_limit_last_time + frame_limit_minimum_time)
|
||||
- cpu_features_get_time_usec()) / 1000;
|
||||
|
@ -1,9 +1,10 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=RetroArch
|
||||
GenericName=Libretro Frontend
|
||||
GenericName=RetroArch
|
||||
Type=Application
|
||||
Comment=Multi-Engine Platform
|
||||
Comment=Frontend for emulators, game engines and media players
|
||||
Comment[ru]=Графический интерфейс для эмуляторов, игровых движков и медиаплееров
|
||||
Icon=retroarch
|
||||
Exec=retroarch
|
||||
Terminal=false
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user