mirror of
https://github.com/libretro/RetroArch
synced 2025-03-06 04:13:52 +00:00
Move Retrolaunch to separate repo
This commit is contained in:
parent
7c842f9342
commit
b61b6fa84b
14
Makefile
14
Makefile
@ -11,7 +11,6 @@ endif
|
|||||||
|
|
||||||
OBJ :=
|
OBJ :=
|
||||||
JOYCONFIG_OBJ :=
|
JOYCONFIG_OBJ :=
|
||||||
RETROLAUNCH_OBJ :=
|
|
||||||
LIBS :=
|
LIBS :=
|
||||||
DEFINES := -DHAVE_CONFIG_H -DRARCH_INTERNAL -DHAVE_OVERLAY
|
DEFINES := -DHAVE_CONFIG_H -DRARCH_INTERNAL -DHAVE_OVERLAY
|
||||||
DEFINES += -DGLOBAL_CONFIG_DIR='"$(GLOBAL_CONFIG_DIR)"'
|
DEFINES += -DGLOBAL_CONFIG_DIR='"$(GLOBAL_CONFIG_DIR)"'
|
||||||
@ -77,12 +76,10 @@ endif
|
|||||||
|
|
||||||
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
|
||||||
RARCH_JOYCONFIG_OBJ := $(addprefix $(OBJDIR)/,$(JOYCONFIG_OBJ))
|
RARCH_JOYCONFIG_OBJ := $(addprefix $(OBJDIR)/,$(JOYCONFIG_OBJ))
|
||||||
RARCH_RETROLAUNCH_OBJ := $(addprefix $(OBJDIR)/,$(RETROLAUNCH_OBJ))
|
|
||||||
|
|
||||||
all: $(TARGET) $(JTARGET) config.mk
|
all: $(TARGET) $(JTARGET) config.mk
|
||||||
|
|
||||||
-include $(RARCH_OBJ:.o=.d) $(RARCH_JOYCONFIG_OBJ:.o=.d) $(RARCH_RETROLAUNCH_OBJ:.o=.d)
|
-include $(RARCH_OBJ:.o=.d) $(RARCH_JOYCONFIG_OBJ:.o=.d)
|
||||||
|
|
||||||
config.mk: configure qb/*
|
config.mk: configure qb/*
|
||||||
@echo "config.mk is outdated or non-existing. Run ./configure again."
|
@echo "config.mk is outdated or non-existing. Run ./configure again."
|
||||||
@exit 1
|
@exit 1
|
||||||
@ -95,10 +92,6 @@ $(JTARGET): $(RARCH_JOYCONFIG_OBJ)
|
|||||||
@$(if $(Q), $(shell echo echo LD $@),)
|
@$(if $(Q), $(shell echo echo LD $@),)
|
||||||
$(Q)$(LINK) -o $@ $(RARCH_JOYCONFIG_OBJ) $(JOYCONFIG_LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
$(Q)$(LINK) -o $@ $(RARCH_JOYCONFIG_OBJ) $(JOYCONFIG_LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
||||||
|
|
||||||
tools/retrolaunch/retrolaunch: $(RARCH_RETROLAUNCH_OBJ)
|
|
||||||
@$(if $(Q), $(shell echo echo LD $@),)
|
|
||||||
$(Q)$(LINK) -o $@ $(RARCH_RETROLAUNCH_OBJ) $(LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c config.h config.mk
|
$(OBJDIR)/%.o: %.c config.h config.mk
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
@$(if $(Q), $(shell echo echo CC $<),)
|
@$(if $(Q), $(shell echo echo CC $<),)
|
||||||
@ -131,11 +124,6 @@ $(OBJDIR)/tools/udev_joypad.o: input/udev_joypad.c
|
|||||||
@$(if $(Q), $(shell echo echo CC $<),)
|
@$(if $(Q), $(shell echo echo CC $<),)
|
||||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -DIS_JOYCONFIG -c -o $@ $<
|
$(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -DIS_JOYCONFIG -c -o $@ $<
|
||||||
|
|
||||||
$(OBJDIR)/tools/input_common_launch.o: input/input_common.c
|
|
||||||
@mkdir -p $(dir $@)
|
|
||||||
@$(if $(Q), $(shell echo echo CC $<),)
|
|
||||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) -MMD -DIS_RETROLAUNCH -c -o $@ $<
|
|
||||||
|
|
||||||
$(OBJDIR)/tools/input_common_joyconfig.o: input/input_common.c
|
$(OBJDIR)/tools/input_common_joyconfig.o: input/input_common.c
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
@$(if $(Q), $(shell echo echo CC $<),)
|
@$(if $(Q), $(shell echo echo CC $<),)
|
||||||
|
@ -536,7 +536,6 @@ ifeq ($(HAVE_7ZIP),1)
|
|||||||
deps/7zip/7zBuf.o \
|
deps/7zip/7zBuf.o \
|
||||||
decompress/7zip_support.o
|
decompress/7zip_support.o
|
||||||
OBJ += $(7ZOBJ)
|
OBJ += $(7ZOBJ)
|
||||||
RETROLAUNCH_OBJ += $(7ZOBJ)
|
|
||||||
JOYCONFIG_OBJ += $(7ZOBJ)
|
JOYCONFIG_OBJ += $(7ZOBJ)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -544,7 +543,6 @@ ifeq ($(HAVE_ZLIB), 1)
|
|||||||
ZLIB_OBJS = decompress/zip_support.o
|
ZLIB_OBJS = decompress/zip_support.o
|
||||||
OBJ += gfx/rpng/rpng.o file_extract.o
|
OBJ += gfx/rpng/rpng.o file_extract.o
|
||||||
OBJ += $(ZLIB_OBJS)
|
OBJ += $(ZLIB_OBJS)
|
||||||
RETROLAUNCH_OBJ += $(ZLIB_OBJS)
|
|
||||||
JOYCONFIG_OBJ += $(ZLIB_OBJS)
|
JOYCONFIG_OBJ += $(ZLIB_OBJS)
|
||||||
DEFINES += -DHAVE_ZLIB
|
DEFINES += -DHAVE_ZLIB
|
||||||
HAVE_COMPRESSION = 1
|
HAVE_COMPRESSION = 1
|
||||||
@ -582,7 +580,6 @@ else
|
|||||||
ifeq ($(HAVE_ZLIB),1)
|
ifeq ($(HAVE_ZLIB),1)
|
||||||
ZLIB_OBJS = deps/rzlib/unzip.o deps/rzlib/ioapi.o
|
ZLIB_OBJS = deps/rzlib/unzip.o deps/rzlib/ioapi.o
|
||||||
OBJ += $(ZLIB_OBJS)
|
OBJ += $(ZLIB_OBJS)
|
||||||
RETROLAUNCH_OBJ += $(ZLIB_OBJS)
|
|
||||||
JOYCONFIG_OBJ += $(ZLIB_OBJS)
|
JOYCONFIG_OBJ += $(ZLIB_OBJS)
|
||||||
HAVE_ZLIB_DEFLATE = 1
|
HAVE_ZLIB_DEFLATE = 1
|
||||||
endif
|
endif
|
||||||
@ -627,7 +624,7 @@ ifeq ($(HAVE_COMPRESSION), 1)
|
|||||||
DEFINES += -DHAVE_COMPRESSION
|
DEFINES += -DHAVE_COMPRESSION
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Joyconfig / RetroLaunch binaries
|
# Joyconfig binary
|
||||||
|
|
||||||
JOYCONFIG_OBJ += tools/retroarch-joyconfig.o \
|
JOYCONFIG_OBJ += tools/retroarch-joyconfig.o \
|
||||||
conf/config_file.o \
|
conf/config_file.o \
|
||||||
@ -635,16 +632,3 @@ JOYCONFIG_OBJ += tools/retroarch-joyconfig.o \
|
|||||||
string_list.o \
|
string_list.o \
|
||||||
compat/compat.o \
|
compat/compat.o \
|
||||||
tools/input_common_joyconfig.o
|
tools/input_common_joyconfig.o
|
||||||
|
|
||||||
RETROLAUNCH_OBJ += tools/retrolaunch/main.o \
|
|
||||||
hash.o \
|
|
||||||
tools/retrolaunch/parser.o \
|
|
||||||
tools/retrolaunch/cd_detect.o \
|
|
||||||
compat/fnmatch_rarch.o \
|
|
||||||
tools/input_common_launch.o \
|
|
||||||
file_path.o \
|
|
||||||
dir_list.o \
|
|
||||||
string_list.o \
|
|
||||||
compat/compat.o \
|
|
||||||
conf/config_file.o \
|
|
||||||
settings.o
|
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
.\" retrolaunch.1:
|
|
||||||
|
|
||||||
.TH "RETROLAUNCH" "1" "July 10, 2014" "RETROLAUNCH" "System Manager's Manual: retrolaunch"
|
|
||||||
|
|
||||||
.SH "NAME"
|
|
||||||
|
|
||||||
retrolauch \- Deprecated content Launcher.
|
|
||||||
|
|
||||||
.SH "SYNOPSIS"
|
|
||||||
|
|
||||||
\fBretrolaunch\fR <content>
|
|
||||||
|
|
||||||
.SH "DESCRIPTION"
|
|
||||||
|
|
||||||
\fBretrolaunch\fR is a deprecated content launcher.
|
|
||||||
|
|
@ -51,7 +51,6 @@
|
|||||||
#include "../file.h"
|
#include "../file.h"
|
||||||
|
|
||||||
rarch_joypad_driver_t *joypad_drivers[] = {
|
rarch_joypad_driver_t *joypad_drivers[] = {
|
||||||
#ifndef IS_RETROLAUNCH
|
|
||||||
#ifdef __CELLOS_LV2__
|
#ifdef __CELLOS_LV2__
|
||||||
&ps3_joypad,
|
&ps3_joypad,
|
||||||
#endif
|
#endif
|
||||||
@ -95,7 +94,6 @@ rarch_joypad_driver_t *joypad_drivers[] = {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef __QNX__
|
#ifdef __QNX__
|
||||||
&qnx_joypad,
|
&qnx_joypad,
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
@ -268,7 +266,6 @@ bool input_joypad_hat_raw(const rarch_joypad_driver_t *drv,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef IS_RETROLAUNCH
|
|
||||||
bool input_translate_coord_viewport(int mouse_x, int mouse_y,
|
bool input_translate_coord_viewport(int mouse_x, int mouse_y,
|
||||||
int16_t *res_x, int16_t *res_y, int16_t *res_screen_x,
|
int16_t *res_x, int16_t *res_y, int16_t *res_screen_x,
|
||||||
int16_t *res_screen_y)
|
int16_t *res_screen_y)
|
||||||
@ -305,7 +302,6 @@ bool input_translate_coord_viewport(int mouse_x, int mouse_y,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
const struct rarch_key_map rarch_key_map_x11[] = {
|
const struct rarch_key_map rarch_key_map_x11[] = {
|
||||||
@ -1521,7 +1517,7 @@ void input_config_parse_joy_axis(config_file_t *conf, const char *prefix,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(IS_JOYCONFIG) && !defined(IS_RETROLAUNCH)
|
#if !defined(IS_JOYCONFIG)
|
||||||
static void input_get_bind_string_joykey(char *buf, const char *prefix,
|
static void input_get_bind_string_joykey(char *buf, const char *prefix,
|
||||||
const struct retro_keybind *bind, size_t size)
|
const struct retro_keybind *bind, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -1,350 +0,0 @@
|
|||||||
#include "parser.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "log.h"
|
|
||||||
#include "../../file.h"
|
|
||||||
#include "../../compat/strl.h"
|
|
||||||
|
|
||||||
#define MAGIC_LEN 16
|
|
||||||
|
|
||||||
struct MagicEntry
|
|
||||||
{
|
|
||||||
const char* system_name;
|
|
||||||
const char* magic;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct MagicEntry MAGIC_NUMBERS[] = {
|
|
||||||
{"ps1", "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x02\x00\x02\x00"},
|
|
||||||
{"pcecd", "\x82\xb1\x82\xcc\x83\x76\x83\x8d\x83\x4f\x83\x89\x83\x80\x82\xcc\x92"},
|
|
||||||
{"scd", "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x02\x00\x01\x53"},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static int find_first_data_track(const char* cue_path, int32_t* offset,
|
|
||||||
char* track_path, size_t max_len)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
int fd = -1;
|
|
||||||
char tmp_token[MAX_TOKEN_LEN];
|
|
||||||
int m, s, f;
|
|
||||||
char cue_dir[PATH_MAX];
|
|
||||||
strlcpy(cue_dir, cue_path, PATH_MAX);
|
|
||||||
path_basedir(cue_dir);
|
|
||||||
|
|
||||||
fd = open(cue_path, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
LOG_WARN("Could not open CUE file '%s': %s", cue_path,
|
|
||||||
strerror(errno));
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DEBUG("Parsing CUE file '%s'...", cue_path);
|
|
||||||
|
|
||||||
while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0)
|
|
||||||
{
|
|
||||||
if (strcmp(tmp_token, "FILE") == 0)
|
|
||||||
{
|
|
||||||
get_token(fd, tmp_token, MAX_TOKEN_LEN);
|
|
||||||
fill_pathname_join(track_path, cue_dir, tmp_token, max_len);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (strcasecmp(tmp_token, "TRACK") == 0)
|
|
||||||
{
|
|
||||||
get_token(fd, tmp_token, MAX_TOKEN_LEN);
|
|
||||||
get_token(fd, tmp_token, MAX_TOKEN_LEN);
|
|
||||||
if (strcasecmp(tmp_token, "AUDIO") == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
find_token(fd, "INDEX");
|
|
||||||
get_token(fd, tmp_token, MAX_TOKEN_LEN);
|
|
||||||
get_token(fd, tmp_token, MAX_TOKEN_LEN);
|
|
||||||
if (sscanf(tmp_token, "%02d:%02d:%02d", &m, &s, &f) < 3)
|
|
||||||
{
|
|
||||||
LOG_WARN("Error parsing time stamp '%s'", tmp_token);
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
*offset = ((m * 60) * (s * 75) * f) * 25;
|
|
||||||
|
|
||||||
LOG_DEBUG("Found 1st data track on file '%s+%d'",
|
|
||||||
track_path, *offset);
|
|
||||||
|
|
||||||
rv = 0;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = -EINVAL;
|
|
||||||
|
|
||||||
clean:
|
|
||||||
close(fd);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int find_ps1_canonical_name(const char* game_id, char* game_name,
|
|
||||||
size_t max_len)
|
|
||||||
{
|
|
||||||
char tmp_token[MAX_TOKEN_LEN];
|
|
||||||
int rv = 0;
|
|
||||||
int fd = open("cddb/ps1.idlst", O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
LOG_WARN("Could not open id list: %s", strerror(errno));
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (get_token(fd, tmp_token, MAX_TOKEN_LEN) > 0)
|
|
||||||
{
|
|
||||||
if(strcasecmp(tmp_token, game_id) != 0)
|
|
||||||
{
|
|
||||||
get_token(fd, tmp_token, max_len);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rv = get_token(fd, game_name, max_len)) < 0)
|
|
||||||
goto clean;
|
|
||||||
|
|
||||||
rv = 0;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = -ENOENT;
|
|
||||||
clean:
|
|
||||||
close(fd);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int detect_ps1_game(const char* track_path, int32_t offset,
|
|
||||||
char* game_name, size_t max_len)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
char buff[4096];
|
|
||||||
const char* pattern = "cdrom:";
|
|
||||||
const char* pat_c;
|
|
||||||
char* c;
|
|
||||||
char* id_start;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
int fd = open(track_path, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Could not open data track: %s", strerror(errno));
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
lseek(fd, 0x9340, SEEK_SET);
|
|
||||||
if (read(fd, buff, 10) > 0)
|
|
||||||
{
|
|
||||||
buff[10] = '\0';
|
|
||||||
buff[4] = '-';
|
|
||||||
LOG_DEBUG("Found disk label '%s'", buff);
|
|
||||||
rv = find_ps1_canonical_name(buff, game_name, max_len);
|
|
||||||
if (rv == 0)
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buff, 0, sizeof(buff));
|
|
||||||
pat_c = pattern;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
rv = read(fd, buff, 4096);
|
|
||||||
if (rv < 0)
|
|
||||||
{
|
|
||||||
rv = -errno;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < rv; i++)
|
|
||||||
{
|
|
||||||
if (*pat_c == buff[i])
|
|
||||||
pat_c++;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pat_c = pattern;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*pat_c == '\0')
|
|
||||||
{
|
|
||||||
id_start = &buff[i] + 1;
|
|
||||||
c = strchr(id_start, ';');
|
|
||||||
if (!c)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Invalid pattern in buffer.");
|
|
||||||
rv = -EINVAL;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
*c = '\0';
|
|
||||||
c = strrchr(id_start, '\\');
|
|
||||||
if (c != NULL)
|
|
||||||
id_start = c + 1;
|
|
||||||
id_start[4] = '-';
|
|
||||||
id_start[8] = id_start[9];
|
|
||||||
id_start[9] = id_start[10];
|
|
||||||
id_start[10] = '\0';
|
|
||||||
LOG_DEBUG("Found ps1 id %s", id_start);
|
|
||||||
rv = find_ps1_canonical_name(id_start, game_name, max_len);
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rv = -EINVAL;
|
|
||||||
clean:
|
|
||||||
close(fd);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int detect_system(const char* track_path, int32_t offset,
|
|
||||||
const char** system_name)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
char magic[MAGIC_LEN];
|
|
||||||
int fd;
|
|
||||||
//struct MagicEntry entry;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
fd = open(track_path, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
LOG_WARN("Could not open data track of file '%s': %s",
|
|
||||||
track_path, strerror(errno));
|
|
||||||
rv = -errno;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
lseek(fd, offset, SEEK_SET);
|
|
||||||
if (read(fd, magic, MAGIC_LEN) < MAGIC_LEN)
|
|
||||||
{
|
|
||||||
LOG_WARN("Could not read data from file '%s' at offset %d: %s",
|
|
||||||
track_path, offset, strerror(errno));
|
|
||||||
rv = -errno;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DEBUG("Comparing with known magic numbers...");
|
|
||||||
for (i = 0; MAGIC_NUMBERS[i].system_name != NULL; i++)
|
|
||||||
{
|
|
||||||
if (memcmp(MAGIC_NUMBERS[i].magic, magic, MAGIC_LEN) == 0)
|
|
||||||
{
|
|
||||||
*system_name = MAGIC_NUMBERS[i].system_name;
|
|
||||||
rv = 0;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_WARN("Could not find compatible system");
|
|
||||||
rv = -EINVAL;
|
|
||||||
clean:
|
|
||||||
close(fd);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int find_first_cue(const char* m3u_path, char* cue_path, size_t max_len)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
int skip = 0;
|
|
||||||
int midstream = 0;
|
|
||||||
|
|
||||||
int fd = open(m3u_path, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
LOG_WARN("Could not open m3u '%s': %s", m3u_path, strerror(errno));
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(cue_path, m3u_path, PATH_MAX);
|
|
||||||
path_basedir(cue_path);
|
|
||||||
cue_path += strlen(cue_path);
|
|
||||||
cue_path[0] = '/';
|
|
||||||
cue_path++;
|
|
||||||
|
|
||||||
while ((read(fd, &c, 1) > 0))
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '#':
|
|
||||||
if (!midstream)
|
|
||||||
skip = 1;
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
if (skip)
|
|
||||||
skip = 0;
|
|
||||||
else if(midstream)
|
|
||||||
{
|
|
||||||
cue_path[0] = '\0';
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ' ':
|
|
||||||
if (!midstream)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (!skip)
|
|
||||||
{
|
|
||||||
midstream = 1;
|
|
||||||
cue_path[0] = c;
|
|
||||||
cue_path++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int detect_cd_game(const char* target_path, char* game_name, size_t max_len)
|
|
||||||
{
|
|
||||||
char cue_path[PATH_MAX];
|
|
||||||
char track_path[PATH_MAX];
|
|
||||||
int32_t offset = 0;
|
|
||||||
const char* system_name = NULL;
|
|
||||||
int rv;
|
|
||||||
if (strcasecmp(target_path + strlen(target_path) - 4, ".m3u") == 0)
|
|
||||||
{
|
|
||||||
rv = find_first_cue(target_path, cue_path, PATH_MAX);
|
|
||||||
if (rv < 0)
|
|
||||||
{
|
|
||||||
LOG_WARN("Could not parse m3u: %s", strerror(-rv));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
strncpy(cue_path, target_path, max_len);
|
|
||||||
|
|
||||||
rv = find_first_data_track(cue_path, &offset, track_path, PATH_MAX);
|
|
||||||
if (rv < 0)
|
|
||||||
{
|
|
||||||
LOG_WARN("Could not find valid data track: %s", strerror(-rv));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DEBUG("Reading 1st data track...");
|
|
||||||
|
|
||||||
if ((rv = detect_system(track_path, offset, &system_name)) < 0)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
LOG_DEBUG("Detected %s media", system_name);
|
|
||||||
|
|
||||||
snprintf(game_name, max_len, "%s.", system_name);
|
|
||||||
game_name += strlen(system_name) + 1;
|
|
||||||
max_len -= strlen(system_name) + 1;
|
|
||||||
if (strcmp(system_name, "ps1") == 0)
|
|
||||||
{
|
|
||||||
if (detect_ps1_game(track_path, offset, game_name, max_len) == 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(game_name, max_len, "<unknown>");
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
#ifdef _WIN32
|
|
||||||
#include <io.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int detect_cd_game(const char* cue_path, char* game_name, size_t max_len);
|
|
@ -1,19 +0,0 @@
|
|||||||
# Core preferences, cores are ordered by preference. If a core doesn't exist ;
|
|
||||||
# or is marked as broken in launch.conf the next in line will be used. ;
|
|
||||||
"ps1" mednafen_psx_libretro pcsx_rearmed_libretro ;
|
|
||||||
"smd" genesis_plus_gx_libretro ;
|
|
||||||
"nes" bnes_libretro fceumm_libretro nestopia_libretro quicknes_libretro ;
|
|
||||||
"gba" vba_next_libretro mednafen_gba_libretro ;
|
|
||||||
"npg" mednafen_ngp_libretro ;
|
|
||||||
"a26" stella_libretro ;
|
|
||||||
"snes" snes9x_libretro snes9x_next_libretro mednafen_snes_libretro bsnes_libretro_performance bsnes_libretro_balanced bsnes_libretro_accuracy;
|
|
||||||
"gbc" gambatte_libretro ;
|
|
||||||
"gb" gambatte_libretro ;
|
|
||||||
"gg" genesis_plus_gx_libretro ;
|
|
||||||
"nds" desmume_libretro ;
|
|
||||||
"pce" mednafen_pce_fast_libretro ;
|
|
||||||
"pcecd" mednafen_pce_fast_libretro ;
|
|
||||||
"sms" genesis_plus_gx_libretro ;
|
|
||||||
"scd" genesis_plus_gx_libretro ;
|
|
||||||
"wswan" mednafen_wswan_libretro ;
|
|
||||||
"n64" mupen64plus_libretro ;
|
|
@ -1,491 +0,0 @@
|
|||||||
# PS1 Dualanalog Games ;
|
|
||||||
|
|
||||||
"ps1.007 - Demain ne Meurt Jamais" dualanalog ;
|
|
||||||
"ps1.007 - Le Monde Ne Suffit Pas" dualanalog ;
|
|
||||||
"ps1.007 Racing*" dualanalog ;
|
|
||||||
"ps1.007 - The World Is Not Enough*" dualanalog ;
|
|
||||||
"ps1.007 - Tomorrow Never Dies*" dualanalog ;
|
|
||||||
"ps1.102 Dalmations - Puppies To The Rescue" dualanalog ;
|
|
||||||
"ps1.40 Winks*" dualanalog ;
|
|
||||||
"ps1.Ace Combat*" dualanalog ;
|
|
||||||
"ps1.Aces of the Air*" dualanalog ;
|
|
||||||
"ps1.Action Bass*" dualanalog ;
|
|
||||||
"ps1.Action Man - Operation Extreme*" dualanalog ;
|
|
||||||
"ps1.Advanced V.G. 2*" dualanalog ;
|
|
||||||
"ps1.Adventure of Phix" dualanalog ;
|
|
||||||
"ps1.Aironauts*" dualanalog ;
|
|
||||||
"ps1.Air Race Championship*" dualanalog ;
|
|
||||||
"ps1.Akuji - The Heartless*" dualanalog ;
|
|
||||||
"ps1.Alfred Chicken*" dualanalog ;
|
|
||||||
"ps1.Alien la Resurrection*" dualanalog ;
|
|
||||||
"ps1.Alien Resurrection*" dualanalog ;
|
|
||||||
"ps1.Alone In The Dark - The New Nightmare*" dualanalog ;
|
|
||||||
"ps1.Alundra 2*" dualanalog ;
|
|
||||||
"ps1.Amazing Virtual Sea Monkeys*" dualanalog ;
|
|
||||||
"ps1.Animorphs - Shattered Reality*" dualanalog ;
|
|
||||||
"ps1.Ape Escape*" dualanalog ;
|
|
||||||
"ps1.Apocalypse*" dualanalog ;
|
|
||||||
"ps1.Aqua GT*" dualanalog ;
|
|
||||||
"ps1.Arcade Party Pack" dualanalog ;
|
|
||||||
"ps1.Armored Core - Master of Arena*" dualanalog ;
|
|
||||||
"ps1.Armorines - Project Swarm*" dualanalog ;
|
|
||||||
"ps1.Army Men 3D*" dualanalog ;
|
|
||||||
"ps1.Army Men - Air Attack 2*" dualanalog ;
|
|
||||||
"ps1.Army Men - Air Attack*" dualanalog ;
|
|
||||||
"ps1.Army Men - Green Rouge*" dualanalog ;
|
|
||||||
"ps1.Army Men - Sarge's Heroes 2*" dualanalog ;
|
|
||||||
"ps1.Army Men - Sarge's Heroes*" dualanalog ;
|
|
||||||
"ps1.Army Men - World War*" dualanalog ;
|
|
||||||
"ps1.Assault Retribution*" dualanalog ;
|
|
||||||
"ps1.Asterix - Mega Madness*" dualanalog ;
|
|
||||||
"ps1.Asteroids*" dualanalog ;
|
|
||||||
"ps1.Barbie Explorer" dualanalog ;
|
|
||||||
"ps1.Barbie - Gotta Have Games" dualanalog ;
|
|
||||||
"ps1.Batman Beyond - Return of the Joker" dualanalog ;
|
|
||||||
"ps1.Batman & Robin" dualanalog ;
|
|
||||||
"ps1.Battle Arena Toshinden 4" dualanalog ;
|
|
||||||
"ps1.Bear in the Big Blue House" dualanalog ;
|
|
||||||
"ps1.Beatmania" dualanalog ;
|
|
||||||
"ps1.Beat Planet Music" dualanalog ;
|
|
||||||
"ps1.Beyblade" dualanalog ;
|
|
||||||
"ps1.Big Bass Fishing" dualanalog ;
|
|
||||||
"ps1.BioHazard - Director's Cut - Dual Shock*" dualanalog ;
|
|
||||||
"ps1.Bishi Bashi Special" dualanalog ;
|
|
||||||
"ps1.Blade" dualanalog ;
|
|
||||||
"ps1.Blasto!" dualanalog ;
|
|
||||||
"ps1.Blast Radius" dualanalog ;
|
|
||||||
"ps1.Block Kuzushi" dualanalog ;
|
|
||||||
"ps1.Block Wars" dualanalog ;
|
|
||||||
"ps1.Bloody Roar 2*" dualanalog ;
|
|
||||||
"ps1.Bob the Builder - Can We Fix It" dualanalog ;
|
|
||||||
"ps1.Boombots" dualanalog ;
|
|
||||||
"ps1.Bratz" dualanalog ;
|
|
||||||
"ps1.Brave Fencer Musashi*" dualanalog ;
|
|
||||||
"ps1.Breakout" dualanalog ;
|
|
||||||
"ps1.Buggy" dualanalog ;
|
|
||||||
"ps1.Bugs Bunny - Lost in Time*" dualanalog ;
|
|
||||||
"ps1.Bugs Bunny & Taz - Time Busters" dualanalog ;
|
|
||||||
"ps1.C-12 - The Final Resistance" dualanalog ;
|
|
||||||
"ps1.Captain Commando" dualanalog ;
|
|
||||||
"ps1.Cardinal Syn*" dualanalog ;
|
|
||||||
"ps1.Carmageddon*" dualanalog ;
|
|
||||||
"ps1.Casper - Friends Around The World" dualanalog ;
|
|
||||||
"ps1.Chaos Break" dualanalog ;
|
|
||||||
"ps1.Chicken Run" dualanalog ;
|
|
||||||
"ps1.Chippoke Ralph no Daibouken (Adventure of Little Ralph)" dualanalog ;
|
|
||||||
"ps1.Chocobo Racing" dualanalog ;
|
|
||||||
"ps1.Chrono Cross*" dualanalog ;
|
|
||||||
"ps1.Colin Mc[rR]ae*" dualanalog ;
|
|
||||||
"ps1.Colony Wars*" dualanalog ;
|
|
||||||
"ps1.Cosmowarrior Rei" dualanalog ;
|
|
||||||
"ps1.Cowboy Bebop" dualanalog ;
|
|
||||||
"ps1.Crash Bandicoot 2*" dualanalog ;
|
|
||||||
"ps1.Crash Bandicoot 3*" dualanalog ;
|
|
||||||
"ps1.Crash Bandicoot Carnival - Crash Bash*" dualanalog ;
|
|
||||||
"ps1.Crash Bash Demo" dualanalog ;
|
|
||||||
"ps1.Crash Bash" dualanalog ;
|
|
||||||
"ps1.Crash Bash" dualanalog ;
|
|
||||||
"ps1.Crash Bash & Spyro - Year of the Dragon Demo" dualanalog ;
|
|
||||||
"ps1.Crash Team Racing*" dualanalog multitap ;
|
|
||||||
"ps1.Crisis Beat" dualanalog ;
|
|
||||||
"ps1.Croc 2*" dualanalog ;
|
|
||||||
"ps1.Croc - Legend of the Gobbos" dualanalog ;
|
|
||||||
"ps1.C - The Contra Adventure" dualanalog ;
|
|
||||||
"ps1.CT Special Forces" dualanalog ;
|
|
||||||
"ps1.CyberTiger Golf" dualanalog ;
|
|
||||||
"ps1.Danger Girl" dualanalog ;
|
|
||||||
"ps1.Darkstalkers 3*" dualanalog ;
|
|
||||||
"ps1.Darkstone - Evil Reigns" dualanalog ;
|
|
||||||
"ps1.Deep Freeze*" dualanalog ;
|
|
||||||
"ps1.Delta Force - Urban Warfar" dualanalog ;
|
|
||||||
"ps1.Demolition Racer" dualanalog ;
|
|
||||||
"ps1.Dexter's Laboratory - Mandark's Lab" dualanalog ;
|
|
||||||
"ps1.Dezaemon Kids!*" dualanalog ;
|
|
||||||
"ps1.Die Hard Trilogy 2*" dualanalog ;
|
|
||||||
"ps1.Digimon Rumble Arena" dualanalog ;
|
|
||||||
"ps1.Disney's 101 Dalmations*" dualanalog ;
|
|
||||||
"ps1.Disney's A Bug's Life*" dualanalog ;
|
|
||||||
"ps1.Disney's Aladdin la revanche de Nasira" dualanalog ;
|
|
||||||
"ps1.Disney's Aladdin - La Vendetta di Nasira" dualanalog ;
|
|
||||||
"ps1.Disney's Aladdin - Nasira's Revenge" dualanalog ;
|
|
||||||
"ps1.Disney's Buzz Lightyear of Star Command" dualanalog ;
|
|
||||||
"ps1.Disney's Peter Pan in Return to Neverland" dualanalog ;
|
|
||||||
"ps1.Disney's Tarzan*" dualanalog ;
|
|
||||||
"ps1.Disney's The Emperor's New Groove" dualanalog ;
|
|
||||||
"ps1.Disney's The Lion King II - Simba's Mighty Adventure" dualanalog ;
|
|
||||||
"ps1.Disney's Toy Story 2 - Buzz Lightyear to the Rescue*" dualanalog ;
|
|
||||||
"ps1.Dragon Valor*" dualanalog ;
|
|
||||||
"ps1.Dreams" dualanalog ;
|
|
||||||
"ps1.Driver 2*" dualanalog ;
|
|
||||||
"ps1.Duke Nukem - Land of the Babes" dualanalog ;
|
|
||||||
"ps1.Duke Nukem - Time to Kill" dualanalog ;
|
|
||||||
"ps1.Dukes of Hazzard*" dualanalog ;
|
|
||||||
"ps1.Eagle One - Harrier Attack" dualanalog ;
|
|
||||||
"ps1.Ehrgeiz" dualanalog ;
|
|
||||||
"ps1.Elemental Gearbolt" dualanalog ;
|
|
||||||
"ps1.ET - The Extra-Terrestrial - Interplanetary Mission" dualanalog ;
|
|
||||||
"ps1.Evil Dead - Hail to the King*" dualanalog ;
|
|
||||||
"ps1.Fatal Fury*" dualanalog ;
|
|
||||||
"ps1.Fear Effect*" dualanalog ;
|
|
||||||
"ps1.Fighting Force*" dualanalog ;
|
|
||||||
"ps1.Firebugs" dualanalog ;
|
|
||||||
"ps1.Fist of the North Star - Hokuto no Ken" dualanalog ;
|
|
||||||
"ps1.Flintstones Bedrock Bowling" dualanalog ;
|
|
||||||
"ps1.Forsaken*" dualanalog ;
|
|
||||||
"ps1.From TV Animation - One Piece - Oceans of Dreams" dualanalog ;
|
|
||||||
"ps1.From TV Animation - One Piece - Tobidase Kaizokudan!*" dualanalog ;
|
|
||||||
"ps1.Future Cop*" dualanalog ;
|
|
||||||
"ps1.Galaga - Destination Earth" dualanalog ;
|
|
||||||
"ps1.Galerians*" dualanalog ;
|
|
||||||
"ps1.Gauntlet Legends" dualanalog ;
|
|
||||||
"ps1.G Darius*" dualanalog ;
|
|
||||||
"ps1.Gex 3 - Deep Cover Gecko*" dualanalog ;
|
|
||||||
"ps1.Ghoul Panic" dualanalog ;
|
|
||||||
"ps1.Global Domination*" dualanalog ;
|
|
||||||
"ps1.G-Police*" dualanalog ;
|
|
||||||
"ps1.Gran Turismo*" dualanalog ;
|
|
||||||
"ps1.Grinch, The" dualanalog ;
|
|
||||||
"ps1.Groove Adventure Rave*" dualanalog ;
|
|
||||||
"ps1.Grudge Warriors" dualanalog ;
|
|
||||||
"ps1.Guardian of Darkness, The" dualanalog ;
|
|
||||||
"ps1.Guilty Gear*" dualanalog ;
|
|
||||||
"ps1.Guitar Freaks*" dualanalog ;
|
|
||||||
"ps1.Gunbare! The Game Paradise 2" dualanalog ;
|
|
||||||
"ps1.Gunfighter - The Legend of Jesse James" dualanalog ;
|
|
||||||
"ps1.Hakaioh - King of Crusher" dualanalog ;
|
|
||||||
"ps1.Harry Potter and The Chamber of Secrets" dualanalog ;
|
|
||||||
"ps1.Harry Potter and The Philosopher's Stone" dualanalog ;
|
|
||||||
"ps1.Harry Potter and The Sorcerer's Stone" dualanalog ;
|
|
||||||
"ps1.Hellboy - Asylum Seeker" dualanalog ;
|
|
||||||
"ps1.Hidden & Dangerous" dualanalog ;
|
|
||||||
"ps1.Hokuto no Ken - Seiki Matsukyu Seishi Densets" dualanalog ;u (Fist of the North Star)
|
|
||||||
"ps1.Hot Wheels - Extreme Racing" dualanalog ;
|
|
||||||
"ps1.Hugo*" dualanalog ;
|
|
||||||
"ps1.Hydro Thunder" dualanalog ;
|
|
||||||
"ps1.Infestation" dualanalog ;
|
|
||||||
"ps1.Inspector Gadget - Gadget's Crazy Maze" dualanalog ;
|
|
||||||
"ps1.Invasion From Beyond - B-Movie" dualanalog ;
|
|
||||||
"ps1.Iron Soldier 3" dualanalog ;
|
|
||||||
"ps1.Irritating Stick*" dualanalog ;
|
|
||||||
"ps1.IS - Internal Section" dualanalog ;
|
|
||||||
"ps1.Jackie Chan Stuntmaster" dualanalog ;
|
|
||||||
"ps1.Jersey Devil*" dualanalog ;
|
|
||||||
"ps1.Jet Moto 2" dualanalog ;
|
|
||||||
"ps1.Jet Moto 3*" dualanalog ;
|
|
||||||
"ps1.Jinx" dualanalog ;
|
|
||||||
"ps1.Kakuge-Yaro - Fighting Game Cre" dualanalog ;ator
|
|
||||||
"ps1.Kamen Rider*" dualanalog ;
|
|
||||||
"ps1.Kidou Keisatsu Patlabor - Game Edition (Mobile Police)" dualanalog ;
|
|
||||||
"ps1.Kitchen Panic" dualanalog ;
|
|
||||||
"ps1.KKND - Krossfire*" dualanalog ;
|
|
||||||
"ps1.Klaymen Gun-Hockey" dualanalog ;
|
|
||||||
"ps1.Korokoro Postnin" dualanalog ;
|
|
||||||
"ps1.Largo Winch - Commando Sar" dualanalog ;
|
|
||||||
"ps1.Lattice - 200 Ec7" dualanalog ;
|
|
||||||
"ps1.Legacy of Kain - Soul Reaver*" pcsxr dualanalog ;
|
|
||||||
"ps1.Legend of Mana" dualanalog ;
|
|
||||||
"ps1.Lego Island 2*" dualanalog ;
|
|
||||||
"ps1.Looney Toons Sheep Raider" dualanalog ;
|
|
||||||
"ps1.Lucifer Ring" dualanalog ;
|
|
||||||
"ps1.Lucky Luke*" dualanalog ;
|
|
||||||
"ps1.Marble Master" dualanalog ;
|
|
||||||
"ps1.Marvel Super Heroes" dualanalog ;
|
|
||||||
"ps1.Mary-Kate & Ashley - Magical Mystery Mall" dualanalog ;
|
|
||||||
"ps1.Mass Destruction" dualanalog ;
|
|
||||||
"ps1.MDK" dualanalog ;
|
|
||||||
"ps1.Medal of Honor*" dualanalog ;
|
|
||||||
"ps1.Medievil" dualanalog ;
|
|
||||||
"ps1.MegaMan Legends 2" dualanalog ;
|
|
||||||
"ps1.Men In Black*" dualanalog ;
|
|
||||||
"ps1.Metal Gear Solid*" dualanalog ;
|
|
||||||
"ps1.Micro Maniacs*" dualanalog ;
|
|
||||||
"ps1.Millennium Soldier - Expendable" dualanalog ;
|
|
||||||
"ps1.Miracle Space Race" dualanalog ;
|
|
||||||
"ps1.Misadventures of Tron Bonne, The" dualanalog ;
|
|
||||||
"ps1.Missile Command*" dualanalog ;
|
|
||||||
"ps1.Mission - Impossible" dualanalog ;
|
|
||||||
"ps1.Mission Impossible" dualanalog ;
|
|
||||||
"ps1.Monkey Hero*" dualanalog ;
|
|
||||||
"ps1.Moorhen 3 - Chicken Chase" dualanalog ;
|
|
||||||
"ps1.Mortal Kombat - Special Forces" dualanalog ;
|
|
||||||
"ps1.Mortal Kombat Special Forces" dualanalog ;
|
|
||||||
"ps1.Ms. Pac-Man Maze Madness Demo" dualanalog ;
|
|
||||||
"ps1.Ms. Pacman - Maze Madness" dualanalog ;
|
|
||||||
"ps1.MTV Celebrity Deathmatch" dualanalog ;
|
|
||||||
"ps1.Mummy, The" dualanalog ;
|
|
||||||
"ps1.Muppet Monster Adventure*" dualanalog ;
|
|
||||||
"ps1.N2O Nitrous Oxide" dualanalog ;
|
|
||||||
"ps1.NBA Hoopz" dualanalog ;
|
|
||||||
"ps1.NFL Blitz 2001" dualanalog ;
|
|
||||||
"ps1.NFL Blitz" dualanalog ;
|
|
||||||
"ps1.N-Gen - Next Generation Racing" dualanalog ;
|
|
||||||
"ps1.N-Gen Racing" dualanalog ;
|
|
||||||
"ps1.Night Raid" dualanalog ;
|
|
||||||
"ps1.Nijiiro Dodgeball" dualanalog ;
|
|
||||||
"ps1.Nijiiro Twinkle - Guruguru Daisakusen*" dualanalog ;
|
|
||||||
"ps1.O.D.T. Demo" dualanalog ;
|
|
||||||
"ps1.ODT - Escape or Die Trying*" dualanalog ;
|
|
||||||
"ps1.Omega Boost" dualanalog ;
|
|
||||||
"ps1.One" dualanalog ;
|
|
||||||
"ps1.Overblood 2*" dualanalog ;
|
|
||||||
"ps1.Over Blood" dualanalog ;
|
|
||||||
"ps1.Pac-Man World*" dualanalog ;
|
|
||||||
"ps1.Panzer Front*" dualanalog ;
|
|
||||||
"ps1.Parasite Eve*" dualanalog ;
|
|
||||||
"ps1.Pepsi-Man" dualanalog ;
|
|
||||||
"ps1.Peter Pan - Return to Neverland" dualanalog ;
|
|
||||||
"ps1.Phix no Daibouken - In The Magnetic World" dualanalog ;
|
|
||||||
"ps1.Planet of the Apes" dualanalog ;
|
|
||||||
"ps1.Point Blank 3*" dualanalog ;
|
|
||||||
"ps1.Powerpuff Girls - Chemical X-Traction" dualanalog ;
|
|
||||||
"ps1.Pro Pinball*" dualanalog ;
|
|
||||||
"ps1.Puchi Carat*" dualanalog ;
|
|
||||||
"ps1.Q-Bert" dualanalog ;
|
|
||||||
"ps1.Radikal Bikers" dualanalog ;
|
|
||||||
"ps1.Rageball" dualanalog ;
|
|
||||||
"ps1.Rampage Through Time" dualanalog ;
|
|
||||||
"ps1.Rascal Demo" dualanalog ;
|
|
||||||
"ps1.Rascal" dualanalog ;
|
|
||||||
"ps1.Raycrisis - Series Termination" dualanalog ;
|
|
||||||
"ps1.Rayman 2 - The Great Escape*" dualanalog ;
|
|
||||||
"ps1.Rayman Rush" dualanalog ;
|
|
||||||
"ps1.Razor Freestyle Scooter" dualanalog ;
|
|
||||||
"ps1.RC de Go*" dualanalog ;
|
|
||||||
"ps1.RC Helicopter*" dualanalog ;
|
|
||||||
"ps1.RC Revenge*" dualanalog ;
|
|
||||||
"ps1.Reboot*" dualanalog ;
|
|
||||||
"ps1.Rescue Shot*" dualanalog ;
|
|
||||||
"ps1.Resident Evil 2*" dualanalog ;
|
|
||||||
"ps1.Resident Evil 3*" dualanalog ;
|
|
||||||
"ps1.Resident Evil Survivor" dualanalog ;
|
|
||||||
"ps1.Re-Volt*" dualanalog ;
|
|
||||||
"ps1.Rising Zan*" dualanalog ;
|
|
||||||
"ps1.Road Rash 3D*" dualanalog ;
|
|
||||||
"ps1.Road Rash - Jailbreak" dualanalog ;
|
|
||||||
"ps1.Rogue Trip*" dualanalog ;
|
|
||||||
"ps1.Rollcage*" dualanalog ;
|
|
||||||
"ps1.Rosco McQueen*" dualanalog ;
|
|
||||||
"ps1.Rugrats*" dualanalog ;
|
|
||||||
"ps1.Runabout 2*" dualanalog ;
|
|
||||||
"ps1.Sabrina the Teenage Witch - A Twitch i" dualanalog ;n Time
|
|
||||||
"ps1.Saltwater Sportfishing" dualanalog ;
|
|
||||||
"ps1.Saru! Get You!*" dualanalog ;
|
|
||||||
"ps1.S.C.A.R.S." dualanalog ;
|
|
||||||
"ps1.Scooby-Doo and The Cyber Chase*" dualanalog ;
|
|
||||||
"ps1.SCUS-94647 "Disney's Treasure Planet" dualanalog ;
|
|
||||||
"ps1.Shadow Man*" dualanalog ;
|
|
||||||
"ps1.Shadow Master" dualanalog ;
|
|
||||||
"ps1.Shiritsu*" dualanalog ;
|
|
||||||
"ps1.Silent Bomber" dualanalog ;
|
|
||||||
"ps1.Silent Hill*" dualanalog ;
|
|
||||||
"ps1.Silhouette Mirage*" dualanalog ;
|
|
||||||
"ps1.Simple 1500 Series Vol.099 - The Kendo" dualanalog ;
|
|
||||||
"ps1.Simple Characters 2000 Series #02 - Afro Inu - The Puzzle*" dualanalog ;
|
|
||||||
"ps1.Simple Characters 2000 Series #08 - Gatchaman Shoot" dualanalog ;
|
|
||||||
"ps1.Simpsons Wrestling" dualanalog ;
|
|
||||||
"ps1.SLUS-01286 "Disney's The Little Mermaid II*" dualanalog ;
|
|
||||||
"ps1.Small Soldiers*" dualanalog ;
|
|
||||||
"ps1.Smurf Racer" dualanalog ;
|
|
||||||
"ps1.Snowboarding" dualanalog ;
|
|
||||||
"ps1.Sorcerer's Maze" dualanalog ;
|
|
||||||
"ps1.Soul of the Samurai" dualanalog ;
|
|
||||||
"ps1.Soul Reaver - Legacy of Kain*" dualanalog ;
|
|
||||||
"ps1.Space Battleship - Uchuu Senkan Yamato" dualanalog ;
|
|
||||||
"ps1.Space Debris*" dualanalog ;
|
|
||||||
"ps1.Spec Ops*" dualanalog ;
|
|
||||||
"ps1.Speedball 2100*" dualanalog ;
|
|
||||||
"ps1.Spiderman*" dualanalog ;
|
|
||||||
"ps1.Spin Jam" dualanalog ;
|
|
||||||
"ps1.Spyro the Dragon*"" dualanalog ;
|
|
||||||
"ps1.Spyro - Year of the Dragon*" dualanalog ;
|
|
||||||
"ps1.Starfighter Sanvein" dualanalog ;
|
|
||||||
"ps1.Star Ixiom" dualanalog ;
|
|
||||||
"ps1.Star Ocean - The Second Story*" dualanalog ;
|
|
||||||
"ps1.Star Trek - Invasion" dualanalog ;
|
|
||||||
"ps1.Star Wars*" dualanalog ;
|
|
||||||
"ps1.Steel Reign" dualanalog ;
|
|
||||||
"ps1.Street Sk8er*" dualanalog ;
|
|
||||||
"ps1.Syphon Filter*" dualanalog ;
|
|
||||||
"ps1.T'ai Fu*" dualanalog ;
|
|
||||||
"ps1.Tail Concerto*" dualanalog ;
|
|
||||||
"ps1.Tales of Destiny*" dualanalog ;
|
|
||||||
"ps1.Tales of Eternia*" dualanalog ;
|
|
||||||
"ps1.Tales of Phantasia*" dualanalog ;
|
|
||||||
"ps1.Team Buddies" dualanalog ;
|
|
||||||
"ps1.Technomage" dualanalog ;
|
|
||||||
"ps1.Tenchu 2*" dualanalog ;
|
|
||||||
"ps1.Terracon" dualanalog ;
|
|
||||||
"ps1.Test Drive 5" dualanalog ;
|
|
||||||
"ps1.Test Drive 6" dualanalog ;
|
|
||||||
"ps1.Threads of Fate" dualanalog ;
|
|
||||||
"ps1.Thunder Force V - Perfect System" dualanalog ;
|
|
||||||
"ps1.Time Crisis II - Project Titan*" dualanalog ;
|
|
||||||
"ps1.Time Crisis - Project Titan" dualanalog ;
|
|
||||||
"ps1.Tintin - Destination Adventure" dualanalog ;
|
|
||||||
"ps1.Tiny Bullets" dualanalog ;
|
|
||||||
"ps1.Tiny Toons Adventures*" dualanalog ;
|
|
||||||
"ps1.Tobal 2" dualanalog ;
|
|
||||||
"ps1.Tomba!*" dualanalog ;
|
|
||||||
"ps1.Tombi!*" dualanalog ;
|
|
||||||
"ps1.Tomb Raider*" dualanalog ;
|
|
||||||
"ps1.Tom Clancy's Rainbow Six*" dualanalog ;
|
|
||||||
"ps1.Treasures of the Deep*" dualanalog ;
|
|
||||||
"ps1.Twinbee RPG*" dualanalog ;
|
|
||||||
"ps1.Twisted Metal 3*" dualanalog ;
|
|
||||||
"ps1.Twisted Metal 4*" dualanalog ;
|
|
||||||
"ps1.Twisted Metal III Demo" dualanalog ;
|
|
||||||
"ps1.Twisted Metal - Small Brawl" dualanalog ;
|
|
||||||
"ps1.Tyco RC*" dualanalog ;
|
|
||||||
"ps1.Um Jammer Lammy*" dualanalog ;
|
|
||||||
"ps1.U.P.P." dualanalog ;
|
|
||||||
"ps1.Uprising X" dualanalog ;
|
|
||||||
"ps1.Urban Chaos*" dualanalog ;
|
|
||||||
"ps1.V2000" dualanalog ;
|
|
||||||
"ps1.Vagrant Story*" dualanalog ;
|
|
||||||
"ps1.Vampire Hunter D*" dualanalog ;
|
|
||||||
"ps1.Vanark - Astro Trooper" dualanalog ;
|
|
||||||
"ps1.VDisney's Atlantis*" dualanalog ;
|
|
||||||
"ps1.VDisney's Lilo & Stitch" dualanalog ;
|
|
||||||
"ps1.VDisney's Pooh's Party Game - In Search of the Treasure" dualanalog ;
|
|
||||||
"ps1.Vigilante 8*" dualanalog ;
|
|
||||||
"ps1.Viper" dualanalog ;
|
|
||||||
"ps1.War Games - Defcon 1" dualanalog ;
|
|
||||||
"ps1.Warriors of Might & Magic" dualanalog ;
|
|
||||||
"ps1.Wild 9" dualanalog ;
|
|
||||||
"ps1.Wing Over 2" dualanalog ;
|
|
||||||
"ps1.Winnie the Pooh - Tigger's Honey Hunt" dualanalog ;
|
|
||||||
"ps1.Wipeout 3*" dualanalog ;
|
|
||||||
"ps1.World's Scariest Police Chases" dualanalog ;
|
|
||||||
"ps1.Worms World Party" dualanalog ;
|
|
||||||
"ps1.Xena - Warrior Princess*" dualanalog ;
|
|
||||||
"ps1.X-Men - Mutant Academy*" dualanalog ;
|
|
||||||
"ps1.Zanac X Zanac" dualanalog ;
|
|
||||||
"ps1.Zoboomafoo" dualanalog ;
|
|
||||||
|
|
||||||
# Genesis\MD Multitap Games ;
|
|
||||||
|
|
||||||
"smd.Gauntlet IV*" multitap ;
|
|
||||||
"smd.NBA Jam Tournament Edition*" multitap ;
|
|
||||||
"smd.General Chaos*" multitap ;
|
|
||||||
"smd.Mega Bomberman*" multitap ;
|
|
||||||
"smd.World Cup USA 94*" multitap ;
|
|
||||||
"smd.Lost Vikings, The*" multitap ;
|
|
||||||
"smd.Mutant League Hockey*" multitap ;
|
|
||||||
|
|
||||||
# SNES BSNES Performance ;
|
|
||||||
"snes.Psycho Dream*" !snes9x-next ;
|
|
||||||
|
|
||||||
# SNES Multitap Games ;
|
|
||||||
|
|
||||||
"snes.Bakukyuu Renpatsu!! Super B-Daman*" multitap ;
|
|
||||||
"snes.Bakutou Dochers - Bumps-jima wa Oosawagi*" multitap ;
|
|
||||||
"snes.Barkley Shut Up and Jam!*" multitap ;
|
|
||||||
"snes.Barkley Shut Up and Jam!*" multitap ;
|
|
||||||
"snes.Battle Cross*" multitap ;
|
|
||||||
"snes.Battle Jockey*" multitap ;
|
|
||||||
"snes.Bill Walsh College Football*" multitap ;
|
|
||||||
"snes.Capcom's Soccer Shootout*" multitap ;
|
|
||||||
"snes.College Slam*" multitap ;
|
|
||||||
"snes.Crystal Beans From Dungeon Explorer*" multitap ;
|
|
||||||
"snes.Dragon - The Bruce Lee Story*" multitap ;
|
|
||||||
"snes.Dream Basketball - Dunk and Hoop*" multitap ;
|
|
||||||
"snes.Dynamic Stadium*" multitap ;
|
|
||||||
"snes.ESPN National Hockey Night*" multitap ;
|
|
||||||
"snes.FIFA 98*" multitap ;
|
|
||||||
"snes.FIFA International Soccer*" multitap ;
|
|
||||||
"snes.FIFA Soccer 96*" multitap ;
|
|
||||||
"snes.FIFA Soccer 97*" multitap ;
|
|
||||||
"snes.Final Set*" multitap ;
|
|
||||||
"snes.Fire Striker*" multitap ;
|
|
||||||
"snes.From TV Animation Slam Dunk - SD Heat Up!!*" multitap ;
|
|
||||||
"snes.Go! Go! Dodge League*" multitap ;
|
|
||||||
"snes.Hammerlock Wrestling*" multitap ;
|
|
||||||
"snes.Hat Trick Hero 2*" multitap ;
|
|
||||||
"snes.Head-On Soccer*" multitap ;
|
|
||||||
"snes.Hebereke no Oishii Puzzle ha Irimasenka*" multitap ;
|
|
||||||
"snes.Human Grand Prix III - F1 Triple Battle*" multitap ;
|
|
||||||
"snes.Human Grand Prix IV - F1 Dream Battle*" multitap ;
|
|
||||||
"snes.Hungry Dinosaurs*" multitap ;
|
|
||||||
"snes.International Superstar Soccer Deluxe*" multitap ;
|
|
||||||
"snes.J.League Excite Stage '94*" multitap ;
|
|
||||||
"snes.J.League Excite Stage '95*" multitap ;
|
|
||||||
"snes.J.League Excite Stage '96*" multitap ;
|
|
||||||
"snes.J.League Super Soccer '95*" multitap ;
|
|
||||||
"snes.J.League Super Soccer*" multitap ;
|
|
||||||
"snes.JWP Joshi Pro Wrestling - Pure Wrestle Queens*" multitap ;
|
|
||||||
"snes.Jikkyou Power Pro Wrestling '96*" multitap ;
|
|
||||||
"snes.Jimmy Connors Pro Tennis Tour*" multitap ;
|
|
||||||
"snes.Kunio-kun no Dodge Ball dayo Zenin Shuugou!*" multitap ;
|
|
||||||
"snes.Looney Tunes Basketball*" multitap ;
|
|
||||||
"snes.Madden NFL '94*" multitap ;
|
|
||||||
"snes.Madden NFL '95*" multitap ;
|
|
||||||
"snes.Madden NFL '96*" multitap ;
|
|
||||||
"snes.Madden NFL '97*" multitap ;
|
|
||||||
"snes.Madden NFL '98*" multitap ;
|
|
||||||
"snes.Micro Machines 2 - Turbo Tournament*" multitap ;
|
|
||||||
"snes.Micro Machines*" multitap ;
|
|
||||||
"snes.Mizuki Shigeru no Youkai Hyakkiyakou*" multitap ;
|
|
||||||
"snes.Multi Play Volleyball*" multitap ;
|
|
||||||
"snes.NBA Give 'N Go*" multitap ;
|
|
||||||
"snes.NBA Hang Time*" multitap ;
|
|
||||||
"snes.NBA Jam - Tournament Edition*" multitap ;
|
|
||||||
"snes.NBA Jam*" multitap ;
|
|
||||||
"snes.NBA Live 95*" multitap ;
|
|
||||||
"snes.NBA Live 96*" multitap ;
|
|
||||||
"snes.NBA Live 97*" multitap ;
|
|
||||||
"snes.NBA Live 98*" multitap ;
|
|
||||||
"snes.NCAA Final Four Basketball*" multitap ;
|
|
||||||
"snes.NCAA Football*" multitap ;
|
|
||||||
"snes.NFL Quarterback Club 96*" multitap ;
|
|
||||||
"snes.NFL Quarterback Club*" multitap ;
|
|
||||||
"snes.NHL '94*" multitap ;
|
|
||||||
"snes.NHL '98*" multitap ;
|
|
||||||
"snes.NHL Pro Hockey '94*" multitap ;
|
|
||||||
"snes.Natsume Championship Wrestling*" multitap ;
|
|
||||||
"snes.Peace Keepers, The*" multitap ;
|
|
||||||
"snes.Pieces*" multitap ;
|
|
||||||
"snes.Rap Jam - Volume One*" multitap ;
|
|
||||||
"snes.Saturday Night Slam Masters*" multitap ;
|
|
||||||
"snes.Secret of Mana*" multitap ;
|
|
||||||
"snes.Shin Nippon Pro Wrestling '94 - Battlefield in Tokyo Dome*" multitap ;
|
|
||||||
"snes.Shin Nippon Pro Wrestling - Chou Senshi in Tokyo Dome*" multitap ;
|
|
||||||
"snes.Shin Nippon Pro Wrestling Kounin '95 - Tokyo Dome Battle 7*" multitap ;
|
|
||||||
"snes.Smash Tennis*" multitap ;
|
|
||||||
"snes.Sporting News, The - Power Baseball*" multitap ;
|
|
||||||
"snes.Sterling Sharpe End 2 End*" multitap ;
|
|
||||||
"snes.Street Hockey '95*" multitap ;
|
|
||||||
"snes.Street Racer*" multitap ;
|
|
||||||
"snes.Sugoi Hebereke*" multitap ;
|
|
||||||
"snes.Sugoro Quest++ Dicenics*" multitap ;
|
|
||||||
"snes.Super Bomberman - Panic Bomber W*" multitap ;
|
|
||||||
"snes.Super Bomberman 2*" multitap ;
|
|
||||||
"snes.Super Bomberman 3*" multitap ;
|
|
||||||
"snes.Super Bomberman 4*" multitap ;
|
|
||||||
"snes.Super Bomberman 5*" multitap ;
|
|
||||||
"snes.Super Bomberman*" multitap ;
|
|
||||||
"snes.Super Fire Pro Wrestling - Queen's Special*" multitap ;
|
|
||||||
"snes.Super Fire Pro Wrestling Special*" multitap ;
|
|
||||||
"snes.Super Fire Pro Wrestling X Premium*" multitap ;
|
|
||||||
"snes.Super Fire Pro Wrestling X*" multitap ;
|
|
||||||
"snes.Super Formation Soccer 94 - World Cup Final Data*" multitap ;
|
|
||||||
"snes.Super Formation Soccer 94*" multitap ;
|
|
||||||
"snes.Super Formation Soccer 95 della Serie A - UCC Xaqua*" multitap ;
|
|
||||||
"snes.Super Formation Soccer 95 della Serie A*" multitap ;
|
|
||||||
"snes.Super Formation Soccer 96*" multitap ;
|
|
||||||
"snes.Super Formation Soccer II*" multitap ;
|
|
||||||
"snes.Super Ice Hockey*" multitap ;
|
|
||||||
"snes.Super Kyousouba - Kaze no Sylphid*" multitap ;
|
|
||||||
"snes.Super Power League*" multitap ;
|
|
||||||
"snes.Super Tekkyuu Fight!*" multitap ;
|
|
||||||
"snes.Super Tetris 3*" multitap ;
|
|
||||||
"snes.Syndicate*" multitap ;
|
|
||||||
"snes.Tenryu Genichiro no Pro Wrestling Revolution*" multitap ;
|
|
||||||
"snes.Tiny Toon Adventures - Wild & Wacky Sports*" multitap ;
|
|
||||||
"snes.Top Gear 3000*" multitap ;
|
|
||||||
"snes.Turbo Toons*" multitap ;
|
|
||||||
"snes.Virtual Soccer*" multitap ;
|
|
||||||
"snes.Vs. Collection*" multitap ;
|
|
||||||
"snes.WWF Raw*" multitap ;
|
|
||||||
"snes.Yuujin no Furi Furi Girls*" multitap ;
|
|
||||||
"snes.Zero 4 Champ RR-Z*" multitap ;
|
|
||||||
"snes.Zero 4 Champ RR*" multitap ;
|
|
@ -1,6 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define LOG(stream, level, msg, ...) fprintf(stream, "%s::%s+%d::", level, __FILE__, __LINE__); fprintf(stream, msg, ##__VA_ARGS__); fprintf(stream, "\n")
|
|
||||||
#define LOG_DEBUG(msg, ...) LOG(stderr, "DEBUG", msg, ##__VA_ARGS__)
|
|
||||||
#define LOG_WARN(msg, ...) LOG(stderr, "WARNING", msg, ##__VA_ARGS__)
|
|
||||||
#define LOG_INFO(msg, ...) LOG(stdout, "INFO", msg, ##__VA_ARGS__)
|
|
@ -1,322 +0,0 @@
|
|||||||
#ifdef _WIN32
|
|
||||||
#include <io.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "../../hash.h"
|
|
||||||
#include "parser.h"
|
|
||||||
#include "cd_detect.h"
|
|
||||||
#include "../../compat/fnmatch_rarch.h"
|
|
||||||
#include "../../file.h"
|
|
||||||
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#define SHA1_LEN 40
|
|
||||||
#define HASH_LEN SHA1_LEN
|
|
||||||
|
|
||||||
struct core_file
|
|
||||||
{
|
|
||||||
char name[PATH_MAX];
|
|
||||||
char desc[PATH_MAX];
|
|
||||||
char serial[PATH_MAX];
|
|
||||||
char size[PATH_MAX];
|
|
||||||
char sha1[PATH_MAX];
|
|
||||||
};
|
|
||||||
|
|
||||||
static int find_hash(int fd, const char *hash, char *game_name, size_t max_len,
|
|
||||||
struct core_file *info_content)
|
|
||||||
{
|
|
||||||
if (!info_content)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (find_token(fd, "game") < 0) return -1;
|
|
||||||
if (find_token(fd, "name") < 0) return -1;
|
|
||||||
|
|
||||||
if (get_token(fd, game_name, max_len) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (find_token(fd, "description") < 0) return -1;
|
|
||||||
|
|
||||||
if (get_token(fd, info_content->desc, sizeof(info_content->desc)) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (find_token(fd, "size") < 0) return -1;
|
|
||||||
|
|
||||||
if (get_token(fd, info_content->size, sizeof(info_content->size)) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (find_token(fd, "serial") == 0)
|
|
||||||
get_token(fd, info_content->serial, sizeof(info_content->serial));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (find_token(fd, "sha1") < 0) return -1;
|
|
||||||
|
|
||||||
if (get_token(fd, info_content->sha1, MAX_TOKEN_LEN) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!strcasecmp(hash, info_content->sha1))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
find_content_canonical_name(const char *hash, char *game_name, size_t max_len,
|
|
||||||
struct core_file *info_content)
|
|
||||||
{
|
|
||||||
// TODO: Error handling
|
|
||||||
size_t i;
|
|
||||||
int rv, fd, offs;
|
|
||||||
const char *dat_name, *dat_name_dot;
|
|
||||||
struct string_list *files = dir_list_new("db", "dat", false);
|
|
||||||
|
|
||||||
if (!files)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (i = 0; i < files->size; i++)
|
|
||||||
{
|
|
||||||
dat_name = path_basename(files->elems[i].data);
|
|
||||||
|
|
||||||
dat_name_dot = strchr(dat_name, '.');
|
|
||||||
if (!dat_name_dot)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
offs = dat_name_dot - dat_name + 1;
|
|
||||||
memcpy(game_name, dat_name, offs);
|
|
||||||
|
|
||||||
fd = open(files->elems[i].data, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (find_hash(fd, hash,game_name + offs,
|
|
||||||
max_len - offs, info_content) == 0)
|
|
||||||
{
|
|
||||||
rv = 0;
|
|
||||||
close(fd);
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
rv = -1;
|
|
||||||
clean:
|
|
||||||
dir_list_free(files);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_sha1(const char *path, char *result)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
unsigned char buff[4096];
|
|
||||||
SHA1Context sha;
|
|
||||||
int fd = open(path, O_RDONLY);
|
|
||||||
|
|
||||||
if (fd < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
SHA1Reset(&sha);
|
|
||||||
rv = 1;
|
|
||||||
while (rv > 0)
|
|
||||||
{
|
|
||||||
rv = read(fd, buff, 4096);
|
|
||||||
if (rv < 0)
|
|
||||||
{
|
|
||||||
close(fd);
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHA1Input(&sha, buff, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SHA1Result(&sha))
|
|
||||||
{
|
|
||||||
close(fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(result, "%08X%08X%08X%08X%08X",
|
|
||||||
sha.Message_Digest[0],
|
|
||||||
sha.Message_Digest[1],
|
|
||||||
sha.Message_Digest[2],
|
|
||||||
sha.Message_Digest[3], sha.Message_Digest[4]);
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RunInfo
|
|
||||||
{
|
|
||||||
char broken_cores[PATH_MAX];
|
|
||||||
int multitap;
|
|
||||||
int dualanalog;
|
|
||||||
char system[10];
|
|
||||||
};
|
|
||||||
|
|
||||||
static int read_launch_conf(struct RunInfo *info, const char *game_name)
|
|
||||||
{
|
|
||||||
int fd = open("./launch.conf", O_RDONLY);
|
|
||||||
int rv;
|
|
||||||
int bci = 0;
|
|
||||||
char token[MAX_TOKEN_LEN];
|
|
||||||
if (fd < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0)
|
|
||||||
goto clean;
|
|
||||||
|
|
||||||
if (rl_fnmatch(token, game_name, 0) != 0)
|
|
||||||
{
|
|
||||||
if ((rv = find_token(fd, ";")) < 0)
|
|
||||||
goto clean;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DEBUG("Matched rule '%s'", token);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0)
|
|
||||||
goto clean;
|
|
||||||
|
|
||||||
while (strcmp(token, ";") != 0)
|
|
||||||
{
|
|
||||||
if (!strcmp(token, "multitap"))
|
|
||||||
info->multitap = 1;
|
|
||||||
else if (!strcmp(token, "dualanalog"))
|
|
||||||
info->dualanalog = 1;
|
|
||||||
else if (token[0] == '!')
|
|
||||||
{
|
|
||||||
strncpy(&info->broken_cores[bci], &token[1], PATH_MAX - bci);
|
|
||||||
bci += strnlen(&token[1], PATH_MAX) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rv = get_token(fd, token, MAX_TOKEN_LEN)) < 0)
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
rv = 0;
|
|
||||||
clean:
|
|
||||||
close(fd);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_run_info(struct RunInfo *info, const char *game_name)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(info, 0, sizeof(struct RunInfo));
|
|
||||||
|
|
||||||
for (i = 0; i < 9; i++)
|
|
||||||
{
|
|
||||||
if (game_name[i] == '.')
|
|
||||||
break;
|
|
||||||
info->system[i] = game_name[i];
|
|
||||||
}
|
|
||||||
info->system[i] = '\0';
|
|
||||||
info->multitap = 0;
|
|
||||||
info->dualanalog = 0;
|
|
||||||
|
|
||||||
read_launch_conf(info, game_name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int detect_content_game(const char *path, char *game_name,
|
|
||||||
size_t max_len, struct core_file *info_content)
|
|
||||||
{
|
|
||||||
char hash[HASH_LEN + 1], *substr;
|
|
||||||
const char *suffix = strrchr(path, '.');
|
|
||||||
|
|
||||||
if (!suffix)
|
|
||||||
{
|
|
||||||
LOG_WARN("Could not find extension for: %s", path);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(hash, 0, sizeof(hash));
|
|
||||||
|
|
||||||
get_sha1(path, hash);
|
|
||||||
#if 0
|
|
||||||
if (rv < 0)
|
|
||||||
LOG_WARN("Could not calculate hash: %s", strerror(-rv));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (find_content_canonical_name(hash, game_name, max_len, info_content) < 0)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Could not detect content with hash `%s`.", hash);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
substr = strrchr(game_name, '.');
|
|
||||||
if (substr)
|
|
||||||
strcpy(info_content->name, substr + 1);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int detect_file(const char *path, char *game_name, size_t max_len,
|
|
||||||
struct core_file *info_content)
|
|
||||||
{
|
|
||||||
if ((!strcasecmp(path + strlen(path) - 4, ".cue")) ||
|
|
||||||
(!strcasecmp(path + strlen(path) - 4, ".m3u")))
|
|
||||||
{
|
|
||||||
LOG_INFO("Starting CD game content detection...");
|
|
||||||
return detect_cd_game(path, game_name, max_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return detect_content_game(path, game_name, max_len, info_content);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef RARCH_CONSOLE
|
|
||||||
#ifndef __APPLE__
|
|
||||||
#undef main
|
|
||||||
#endif
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
struct RunInfo info;
|
|
||||||
struct core_file info_content;
|
|
||||||
int rv;
|
|
||||||
char game_name[MAX_TOKEN_LEN];
|
|
||||||
char *path = argv[1];
|
|
||||||
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
printf("usage: retrolaunch <ROM>\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INFO("Analyzing '%s'", path);
|
|
||||||
if ((rv = detect_file(path, game_name, MAX_TOKEN_LEN, &info_content)) < 0)
|
|
||||||
{
|
|
||||||
LOG_WARN("Could not detect game: %s", strerror(-rv));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INFO("Content Name : `%s`", info_content.name);
|
|
||||||
LOG_INFO("Content Description : `%s`", info_content.desc);
|
|
||||||
LOG_INFO("Content Serial : `%s`", info_content.serial);
|
|
||||||
LOG_INFO("Content Size : `%s`", info_content.size);
|
|
||||||
LOG_INFO("Content SHA-1 : `%s`", info_content.sha1);
|
|
||||||
|
|
||||||
if ((rv = get_run_info(&info, game_name)) < 0)
|
|
||||||
{
|
|
||||||
LOG_WARN("Could not detect run info: %s", strerror(-rv));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,80 +0,0 @@
|
|||||||
#include "parser.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
ssize_t get_token(int fd, char *token, size_t max_len)
|
|
||||||
{
|
|
||||||
char *c = token;
|
|
||||||
int rv;
|
|
||||||
ssize_t len = 0;
|
|
||||||
int in_string = 0;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
rv = read(fd, c, 1);
|
|
||||||
if (rv == 0)
|
|
||||||
return 0;
|
|
||||||
else if (rv < 1)
|
|
||||||
{
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
case EINTR:
|
|
||||||
case EAGAIN:
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (*c)
|
|
||||||
{
|
|
||||||
case ' ':
|
|
||||||
case '\t':
|
|
||||||
case '\r':
|
|
||||||
case '\n':
|
|
||||||
if (c == token)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!in_string)
|
|
||||||
{
|
|
||||||
*c = '\0';
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '\"':
|
|
||||||
if (c == token)
|
|
||||||
{
|
|
||||||
in_string = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*c = '\0';
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
len++;
|
|
||||||
c++;
|
|
||||||
if (len == (ssize_t)max_len)
|
|
||||||
{
|
|
||||||
*c = '\0';
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int find_token(int fd, const char *token)
|
|
||||||
{
|
|
||||||
int tmp_len = strlen(token);
|
|
||||||
char *tmp_token = (char*)calloc(tmp_len, 1);
|
|
||||||
if (!tmp_token)
|
|
||||||
return -1;
|
|
||||||
while (strncmp(tmp_token, token, tmp_len) != 0)
|
|
||||||
{
|
|
||||||
if (get_token(fd, tmp_token, tmp_len) <= 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
#ifdef _WIN32
|
|
||||||
#include <io.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_TOKEN_LEN 255
|
|
||||||
|
|
||||||
ssize_t get_token(int fd, char* token, size_t max_len);
|
|
||||||
int find_token(int fd, const char* token);
|
|
Loading…
x
Reference in New Issue
Block a user