Add sufami... Now it should be pretty complete. :)

This commit is contained in:
Themaister 2011-01-12 21:57:55 +01:00
parent f9893b6c1b
commit 907c371a92
4 changed files with 270 additions and 46 deletions

166
file.c
View File

@ -168,11 +168,11 @@ void save_file(const char* path, int type)
static bool load_sgb_rom(void)
{
void *rom_buf;
void *rom_buf = NULL;
ssize_t rom_len = 0;
FILE *extra_rom;
void *extra_rom_buf;
FILE *extra_rom = NULL;
void *extra_rom_buf = NULL;
ssize_t extra_rom_len = 0;
if ((rom_len = read_file(g_extern.rom_file, &rom_buf)) == -1)
@ -220,9 +220,147 @@ error:
return false;
}
static bool load_bsx_rom(bool slotted)
{
void *rom_buf = NULL;
ssize_t rom_len = 0;
FILE *extra_rom = NULL;
void *extra_rom_buf = NULL;
ssize_t extra_rom_len = 0;
if ((rom_len = read_file(g_extern.rom_file, &rom_buf)) == -1)
{
SSNES_ERR("Could not read ROM file.\n");
goto error;
}
extra_rom = fopen(g_extern.bsx_rom_path, "rb");
if (!extra_rom)
{
SSNES_ERR("Couldn't open BSX game rom!\n");
goto error;
}
if ((extra_rom_len = read_file(extra_rom, &extra_rom_buf)) == -1)
{
SSNES_ERR("Cannot read BSX game rom.\n");
goto error;
}
if (slotted)
{
if (!psnes_load_cartridge_bsx_slotted(
NULL, rom_buf, rom_len,
NULL, extra_rom_buf, extra_rom_len))
{
SSNES_ERR("Cannot load BSX slotted rom.\n");
goto error;
}
}
else
{
if (!psnes_load_cartridge_bsx(
NULL, rom_buf, rom_len,
NULL, extra_rom_buf, extra_rom_len))
{
SSNES_ERR("Cannot load BSX rom.\n");
goto error;
}
}
if (g_extern.rom_file)
fclose(g_extern.rom_file);
if (extra_rom)
fclose(extra_rom);
free(rom_buf);
free(extra_rom_buf);
return true;
error:
if (g_extern.rom_file)
fclose(g_extern.rom_file);
if (extra_rom)
fclose(extra_rom);
free(rom_buf);
free(extra_rom_buf);
return false;
}
static bool load_sufami_rom(void)
{
void *rom_buf = NULL;
ssize_t rom_len = 0;
FILE *extra_rom[2] = {NULL};
void *extra_rom_buf[2] = {NULL};
ssize_t extra_rom_len[2] = {0};
if ((rom_len = read_file(g_extern.rom_file, &rom_buf)) == -1)
{
SSNES_ERR("Could not read ROM file.\n");
goto error;
}
const char *roms[2] = { g_extern.sufami_rom_path[0], g_extern.sufami_rom_path[1] };
for (int i = 0; i < 2; i++)
{
if (strlen(roms[i]) > 0)
{
extra_rom[i] = fopen(roms[i], "rb");
if (!extra_rom[i])
{
SSNES_ERR("Couldn't open BSX game rom!\n");
goto error;
}
if ((extra_rom_len[i] = read_file(extra_rom[i], &extra_rom_buf[i])) == -1)
{
SSNES_ERR("Cannot read BSX game rom.\n");
goto error;
}
}
}
if (!psnes_load_cartridge_sufami_turbo(
NULL, rom_buf, rom_len,
NULL, extra_rom_buf[0], extra_rom_len[0],
NULL, extra_rom_buf[1], extra_rom_len[1]))
{
SSNES_ERR("Cannot load Sufami Turbo rom.\n");
goto error;
}
if (g_extern.rom_file)
fclose(g_extern.rom_file);
for (int i = 0; i < 2; i++)
{
if (extra_rom[i])
fclose(extra_rom[i]);
free(extra_rom_buf[i]);
}
free(rom_buf);
return true;
error:
if (g_extern.rom_file)
fclose(g_extern.rom_file);
for (int i = 0; i < 2; i++)
{
if (extra_rom[i])
fclose(extra_rom[i]);
free(extra_rom_buf[i]);
}
free(rom_buf);
return false;
}
static bool load_normal_rom(void)
{
void *rom_buf;
void *rom_buf = NULL;
ssize_t rom_len = 0;
if ((rom_len = read_file(g_extern.rom_file, &rom_buf)) == -1)
@ -247,9 +385,10 @@ static bool load_normal_rom(void)
return true;
}
bool init_rom_file(void)
bool init_rom_file(enum ssnes_game_type type)
{
switch (g_extern.game_type)
switch (type)
{
case SSNES_CART_SGB:
if (!load_sgb_rom())
@ -260,6 +399,21 @@ bool init_rom_file(void)
if (!load_normal_rom())
return false;
break;
case SSNES_CART_BSX:
if (!load_bsx_rom(false))
return false;
break;
case SSNES_CART_BSX_SLOTTED:
if (!load_bsx_rom(true))
return false;
break;
case SSNES_CART_SUFAMI:
if (!load_sufami_rom())
return false;
break;
default:
SSNES_ERR("Invalid ROM type!\n");

3
file.h
View File

@ -24,6 +24,7 @@
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
#include "general.h"
ssize_t read_file(FILE *file, void **buf);
@ -32,6 +33,6 @@ void write_file(const char* path, uint8_t* data, size_t size);
void load_save_file(const char* path, int type);
void save_file(const char* path, int type);
bool init_rom_file(void);
bool init_rom_file(enum ssnes_game_type type);
#endif

View File

@ -81,7 +81,10 @@ struct settings
enum ssnes_game_type
{
SSNES_CART_NORMAL = 0,
SSNES_CART_SGB
SSNES_CART_SGB,
SSNES_CART_BSX,
SSNES_CART_BSX_SLOTTED,
SSNES_CART_SUFAMI,
};
struct global
@ -101,12 +104,17 @@ struct global
enum ssnes_game_type game_type;
char gb_rom_path[256];
char bsx_rom_path[256];
char sufami_rom_path[2][256];
char config_path[256];
char basename[256];
char savefile_name_srm[256];
char savefile_name_rtc[260]; // Make sure that fill_pathname has space.
char savefile_name_rtc[512]; // Make sure that fill_pathname has space.
char savefile_name_psrm[512];
char savefile_name_asrm[512];
char savefile_name_bsrm[512];
char savestate_name[256];
#ifdef HAVE_FFMPEG

135
ssnes.c
View File

@ -240,12 +240,16 @@ static void print_help(void)
puts("=================================================");
puts("ssnes: Simple Super Nintendo Emulator (libsnes)");
puts("=================================================");
puts("Usage: ssnes [rom file] [-h/--help | -c/--config | -v/--verbose | -4/--multitap | -j/--justifier | -J/--justifiers | -S/--savestate | -m/--mouse | -g/--gameboy | -p/--scope | -s/--save" FFMPEG_HELP_QUARK "]");
puts("Usage: ssnes [rom file] [-h/--help | -c/--config | -v/--verbose | -4/--multitap | -j/--justifier | -J/--justifiers | -S/--savestate | -m/--mouse | -g/--gameboy | -b/--bsx | -B/--bsxslot | --sufamiA | --sufamiB | -p/--scope | -s/--save" FFMPEG_HELP_QUARK "]");
puts("\t-h/--help: Show this help message");
puts("\t-s/--save: Path for save file (*.srm). Required when rom is input from stdin");
puts("\t-S/--savestate: Path to use for save states. If not selected, *.state will be assumed.");
puts("\t-c/--config: Path for config file." SSNES_DEFAULT_CONF_PATH_STR);
puts("\t-g/--gameboy: Path to Gameboy ROM. Load SuperGameBoy as the regular rom.");
puts("\t-b/--bsx: Path to BSX rom. Load BSX BIOS as the regular rom.");
puts("\t-B/--bsxslot: Path to BSX slotted rom. Load BSX BIOS as the regular rom.");
puts("\t--sufamiA: Path to A slot of Sufami Turbo. Load Sufami base cart as regular rom.");
puts("\t--sufamiB: Path to B slot of Sufami Turbo.");
puts("\t-m/--mouse: Connect a virtual mouse into designated port of the SNES (1 or 2).");
puts("\t\tThis argument can be specified several times to connect more mice.");
puts("\t-p/--scope: Connect a virtual SuperScope into port 2 of the SNES.");
@ -279,9 +283,13 @@ static void parse_input(int argc, char *argv[])
{ "mouse", 1, NULL, 'm' },
{ "scope", 0, NULL, 'p' },
{ "savestate", 1, NULL, 'S' },
{ "bsx", 1, NULL, 'b' },
{ "bsxslot", 1, NULL, 'B' },
{ "justifier", 0, NULL, 'j' },
{ "justifiers", 0, NULL, 'J' },
{ "multitap", 0, NULL, '4' },
{ "sufamiA", 1, NULL, 'Y' },
{ "sufamiB", 1, NULL, 'Z' },
{ NULL, 0, NULL, 0 }
};
@ -293,7 +301,7 @@ static void parse_input(int argc, char *argv[])
#define FFMPEG_RECORD_ARG
#endif
char optstring[] = "hs:vc:t:m:p4jkg:" FFMPEG_RECORD_ARG;
char optstring[] = "hs:vc:S:m:p4jJg:b:B:Y:Z:" FFMPEG_RECORD_ARG;
for(;;)
{
int c = getopt_long(argc, argv, optstring, opts, &option_index);
@ -329,6 +337,26 @@ static void parse_input(int argc, char *argv[])
g_extern.game_type = SSNES_CART_SGB;
break;
case 'b':
strncpy(g_extern.bsx_rom_path, optarg, sizeof(g_extern.bsx_rom_path) - 1);
g_extern.game_type = SSNES_CART_BSX;
break;
case 'B':
strncpy(g_extern.bsx_rom_path, optarg, sizeof(g_extern.bsx_rom_path) - 1);
g_extern.game_type = SSNES_CART_BSX_SLOTTED;
break;
case 'Y':
strncpy(g_extern.sufami_rom_path[0], optarg, sizeof(g_extern.sufami_rom_path[0]) - 1);
g_extern.game_type = SSNES_CART_SUFAMI;
break;
case 'Z':
strncpy(g_extern.sufami_rom_path[1], optarg, sizeof(g_extern.sufami_rom_path[1]) - 1);
g_extern.game_type = SSNES_CART_SUFAMI;
break;
case 'S':
strncpy(g_extern.savestate_name, optarg, sizeof(g_extern.savestate_name) - 1);
break;
@ -453,48 +481,59 @@ static void init_controllers(void)
}
}
static int get_sram_type(enum ssnes_game_type type)
{
switch (type)
{
case SSNES_CART_SGB:
return SNES_MEMORY_GAME_BOY_RAM;
case SSNES_CART_NORMAL:
return SNES_MEMORY_CARTRIDGE_RAM;
}
return 0;
}
static int get_rtc_type(enum ssnes_game_type type)
{
switch (type)
{
case SSNES_CART_SGB:
return SNES_MEMORY_GAME_BOY_RTC;
case SSNES_CART_NORMAL:
return SNES_MEMORY_CARTRIDGE_RTC;
}
return 0;
}
static inline void load_save_files(void)
{
int ram_type = get_sram_type(g_extern.game_type);
int rtc_type = get_rtc_type(g_extern.game_type);
switch (g_extern.game_type)
{
case SSNES_CART_NORMAL:
case SSNES_CART_SGB:
load_save_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
load_save_file(g_extern.savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
break;
load_save_file(g_extern.savefile_name_srm, ram_type);
load_save_file(g_extern.savefile_name_rtc, rtc_type);
case SSNES_CART_BSX:
case SSNES_CART_BSX_SLOTTED:
load_save_file(g_extern.savefile_name_srm, SNES_MEMORY_BSX_RAM);
load_save_file(g_extern.savefile_name_psrm, SNES_MEMORY_BSX_PRAM);
break;
case SSNES_CART_SUFAMI:
load_save_file(g_extern.savefile_name_asrm, SNES_MEMORY_SUFAMI_TURBO_A_RAM);
load_save_file(g_extern.savefile_name_bsrm, SNES_MEMORY_SUFAMI_TURBO_B_RAM);
break;
default:
break;
}
}
static inline void save_files(void)
{
int ram_type = get_sram_type(g_extern.game_type);
int rtc_type = get_rtc_type(g_extern.game_type);
switch (g_extern.game_type)
{
case SSNES_CART_NORMAL:
case SSNES_CART_SGB:
save_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
save_file(g_extern.savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
break;
save_file(g_extern.savefile_name_srm, ram_type);
save_file(g_extern.savefile_name_rtc, rtc_type);
case SSNES_CART_BSX:
case SSNES_CART_BSX_SLOTTED:
save_file(g_extern.savefile_name_srm, SNES_MEMORY_BSX_RAM);
save_file(g_extern.savefile_name_psrm, SNES_MEMORY_BSX_PRAM);
break;
case SSNES_CART_SUFAMI:
save_file(g_extern.savefile_name_asrm, SNES_MEMORY_SUFAMI_TURBO_A_RAM);
save_file(g_extern.savefile_name_bsrm, SNES_MEMORY_SUFAMI_TURBO_B_RAM);
break;
default:
break;
}
}
#ifdef HAVE_FFMPEG
static void init_recording(void)
{
@ -535,6 +574,29 @@ static void deinit_recording(void)
}
#endif
static void fill_pathnames(void)
{
switch (g_extern.game_type)
{
case SSNES_CART_BSX:
case SSNES_CART_BSX_SLOTTED:
// BSX PSRM
fill_pathname(g_extern.savefile_name_psrm, g_extern.savefile_name_srm, ".psrm");
break;
case SSNES_CART_SUFAMI:
// SUFAMI ARAM
fill_pathname(g_extern.savefile_name_asrm, g_extern.savefile_name_srm, ".asrm");
// SUFAMI BRAM
fill_pathname(g_extern.savefile_name_bsrm, g_extern.savefile_name_srm, ".bsrm");
break;
default:
// Infer .rtc save path from save ram path.
fill_pathname(g_extern.savefile_name_rtc, g_extern.savefile_name_srm, ".rtc");
}
}
int main(int argc, char *argv[])
{
@ -548,10 +610,9 @@ int main(int argc, char *argv[])
SSNES_LOG("Version of libsnes API: %u.%u\n", psnes_library_revision_major(), psnes_library_revision_minor());
// Infer .rtc save path from save ram path.
fill_pathname(g_extern.savefile_name_rtc, g_extern.savefile_name_srm, ".rtc");
fill_pathnames();
if (!init_rom_file())
if (!init_rom_file(g_extern.game_type))
goto error;
init_drivers();