mirror of https://github.com/snes9xgit/snes9x.git
commit
cb27f5bf24
|
@ -56,7 +56,7 @@ ifneq (,$(findstring unix,$(platform)))
|
|||
CC = gcc
|
||||
SHARED := -shared -z defs
|
||||
else
|
||||
SHARED := -shared -Wl,--version-script=link.T -Wl,-z,defs
|
||||
SHARED := -shared -Wl,--version-script=link.T
|
||||
endif
|
||||
ifneq ($(findstring Haiku,$(shell uname -a)),)
|
||||
LIBS :=
|
||||
|
@ -252,11 +252,14 @@ else ifneq (,$(findstring windows_msvc2017,$(platform)))
|
|||
LIBS += kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
|
||||
else ifneq (,$(findstring uwp,$(PlatformSuffix)))
|
||||
WinPartition = uwp
|
||||
MSVC2017CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_APP -DWINDLL -D_UNICODE -DUNICODE -DWRL_NO_DEFAULT_LIB
|
||||
MSVC2017CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_APP -D_WINDLL -D_UNICODE -DUNICODE -D__WRL_NO_DEFAULT_LIB__ -ZW:nostdlib -EHsc
|
||||
LDFLAGS += -APPCONTAINER -NXCOMPAT -DYNAMICBASE -MANIFEST:NO -LTCG -OPT:REF -SUBSYSTEM:CONSOLE -MANIFESTUAC:NO -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1 -DEBUG:FULL -WINMD:NO
|
||||
LIBS += WindowsApp.lib
|
||||
endif
|
||||
|
||||
# Specific to this core
|
||||
MSVC2017CompileFlags += -D__WIN32__
|
||||
|
||||
CFLAGS += $(MSVC2017CompileFlags)
|
||||
CXXFLAGS += $(MSVC2017CompileFlags)
|
||||
|
||||
|
@ -320,6 +323,9 @@ else ifneq (,$(findstring windows_msvc2017,$(platform)))
|
|||
PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VsInstallRoot)/Common7/IDE")
|
||||
INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/include")
|
||||
LIB := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/lib/$(TargetArchMoniker)")
|
||||
ifneq (,$(findstring uwp,$(PlatformSuffix)))
|
||||
LIB := $(shell IFS=$$'\n'; cygpath -w "$(LIB)/store")
|
||||
endif
|
||||
|
||||
export INCLUDE := $(INCLUDE);$(WindowsSDKSharedIncludeDir);$(WindowsSDKUCRTIncludeDir);$(WindowsSDKUMIncludeDir)
|
||||
export LIB := $(LIB);$(WindowsSDKUCRTLibDir);$(WindowsSDKUMLibDir)
|
||||
|
|
|
@ -35,10 +35,12 @@
|
|||
#define RETRO_MEMORY_SNES_GAME_BOY_RAM ((5 << 8) | RETRO_MEMORY_SAVE_RAM)
|
||||
#define RETRO_MEMORY_SNES_GAME_BOY_RTC ((6 << 8) | RETRO_MEMORY_RTC)
|
||||
|
||||
#define RETRO_GAME_TYPE_BSX 0x101
|
||||
#define RETRO_GAME_TYPE_BSX_SLOTTED 0x102
|
||||
#define RETRO_GAME_TYPE_SUFAMI_TURBO 0x103
|
||||
#define RETRO_GAME_TYPE_SUPER_GAME_BOY 0x104
|
||||
#define RETRO_GAME_TYPE_BSX 0x101 | 0x1000
|
||||
#define RETRO_GAME_TYPE_BSX_SLOTTED 0x102 | 0x1000
|
||||
#define RETRO_GAME_TYPE_SUFAMI_TURBO 0x103 | 0x1000
|
||||
#define RETRO_GAME_TYPE_SUPER_GAME_BOY 0x104 | 0x1000
|
||||
#define RETRO_GAME_TYPE_MULTI_CART 0x105 | 0x1000
|
||||
|
||||
|
||||
#define SNES_4_3 4.0f / 3.0f
|
||||
#define SNES_8_7 8.0f / 7.0f
|
||||
|
@ -46,6 +48,12 @@
|
|||
char g_rom_dir[1024];
|
||||
char g_basename[1024];
|
||||
|
||||
bool hires_blend = false;
|
||||
static uint16 *gfx_blend;
|
||||
|
||||
char retro_system_directory[4096];
|
||||
char retro_save_directory[4096];
|
||||
|
||||
retro_log_printf_t log_cb = NULL;
|
||||
static retro_video_refresh_t video_cb = NULL;
|
||||
static retro_audio_sample_t audio_cb = NULL;
|
||||
|
@ -128,18 +136,39 @@ static retro_environment_t environ_cb;
|
|||
static overscan_mode crop_overscan_mode = OVERSCAN_CROP_ON; // default to crop
|
||||
static aspect_mode aspect_ratio_mode = ASPECT_RATIO_4_3; // default to 4:3
|
||||
static bool rom_loaded = false;
|
||||
|
||||
void retro_set_environment(retro_environment_t cb)
|
||||
{
|
||||
environ_cb = cb;
|
||||
|
||||
static const struct retro_subsystem_memory_info multi_a_memory[] = {
|
||||
{ "srm", RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM },
|
||||
};
|
||||
|
||||
static const struct retro_subsystem_memory_info multi_b_memory[] = {
|
||||
{ "srm", RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM },
|
||||
};
|
||||
|
||||
static const struct retro_subsystem_rom_info multicart_roms[] = {
|
||||
{ "Cart A", "smc|sfc|swc|fig|bs", false, false, false, multi_a_memory, 1 },
|
||||
{ "Add-On B", "smc|sfc|swc|fig|bs", false, false, false, multi_b_memory, 1 },
|
||||
};
|
||||
|
||||
static const struct retro_subsystem_info subsystems[] = {
|
||||
{ "Multi-Cart Link", "multicart_addon", multicart_roms, 2, RETRO_GAME_TYPE_MULTI_CART },
|
||||
{}
|
||||
};
|
||||
|
||||
cb(RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO, (void*)subsystems);
|
||||
|
||||
|
||||
struct retro_variable variables[] = {
|
||||
// These variable names and possible values constitute an ABI with ZMZ (ZSNES Libretro player).
|
||||
// Changing "Show layer 1" is fine, but don't change "layer_1"/etc or the possible values ("Yes|No").
|
||||
// Adding more variables and rearranging them is safe.
|
||||
{ "snes9x_up_down_allowed", "Allow Opposing Directions; disabled|enabled" },
|
||||
{ "snes9x_overclock", "SuperFX Frequency; 100%|200%|400%|600%|800%|1000%" },
|
||||
//{ "snes9x_overclock_cycles", "Reduce Slowdown (Hack, Unsafe); disabled|compatible|max" },
|
||||
//{ "snes9x_reduce_sprite_flicker", "Reduce Flickering (Hack, Unsafe); disabled|enabled" },
|
||||
{ "snes9x_overclock_superfx", "SuperFX Overclocking; 100%|150%|200%|250%|300%|350%|400%|450%|500%|50%" },
|
||||
{ "snes9x_hires_blend", "Hires Blending; disabled|enabled" },
|
||||
{ "snes9x_layer_1", "Show layer 1; enabled|disabled" },
|
||||
{ "snes9x_layer_2", "Show layer 2; enabled|disabled" },
|
||||
{ "snes9x_layer_3", "Show layer 3; enabled|disabled" },
|
||||
|
@ -163,13 +192,15 @@ void retro_set_environment(retro_environment_t cb)
|
|||
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
|
||||
|
||||
const struct retro_controller_description port_1[] = {
|
||||
static const struct retro_controller_description port_1[] = {
|
||||
{ "None", RETRO_DEVICE_NONE },
|
||||
{ "SNES Joypad", RETRO_DEVICE_JOYPAD },
|
||||
{ "SNES Mouse", RETRO_DEVICE_MOUSE },
|
||||
{ "Multitap", RETRO_DEVICE_JOYPAD_MULTITAP },
|
||||
};
|
||||
|
||||
const struct retro_controller_description port_2[] = {
|
||||
static const struct retro_controller_description port_2[] = {
|
||||
{ "None", RETRO_DEVICE_NONE },
|
||||
{ "SNES Joypad", RETRO_DEVICE_JOYPAD },
|
||||
{ "SNES Mouse", RETRO_DEVICE_MOUSE },
|
||||
{ "Multitap", RETRO_DEVICE_JOYPAD_MULTITAP },
|
||||
|
@ -177,16 +208,27 @@ void retro_set_environment(retro_environment_t cb)
|
|||
{ "Justifier", RETRO_DEVICE_LIGHTGUN_JUSTIFIER },
|
||||
};
|
||||
|
||||
const struct retro_controller_info ports[] = {
|
||||
{ port_1, 3 },
|
||||
{ port_2, 5 },
|
||||
{ 0, 0 },
|
||||
static const struct retro_controller_description port_3[] = {
|
||||
{ "None", RETRO_DEVICE_NONE },
|
||||
{ "SNES Joypad", RETRO_DEVICE_JOYPAD },
|
||||
};
|
||||
|
||||
static const struct retro_controller_info ports[] = {
|
||||
{ port_1, 4 },
|
||||
{ port_2, 6 },
|
||||
{ port_3, 2 },
|
||||
{ port_3, 2 },
|
||||
{ port_3, 2 },
|
||||
{ port_3, 2 },
|
||||
{ port_3, 2 },
|
||||
{ port_3, 2 },
|
||||
{},
|
||||
};
|
||||
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
|
||||
}
|
||||
|
||||
void update_geometry()
|
||||
void update_geometry(void)
|
||||
{
|
||||
struct retro_system_av_info av_info;
|
||||
retro_get_system_av_info(&av_info);
|
||||
|
@ -198,7 +240,16 @@ static void update_variables(void)
|
|||
bool geometry_update = false;
|
||||
char key[256];
|
||||
struct retro_variable var;
|
||||
var.key = "snes9x_overclock";
|
||||
|
||||
var.key = "snes9x_hires_blend";
|
||||
var.value = NULL;
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
hires_blend = !strcmp(var.value, "disabled") ? false : true;
|
||||
else
|
||||
hires_blend = false;
|
||||
|
||||
var.key = "snes9x_overclock_superfx";
|
||||
var.value = NULL;
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
|
@ -207,6 +258,14 @@ static void update_variables(void)
|
|||
Settings.SuperFXClockMultiplier = freq;
|
||||
}
|
||||
|
||||
var.key = "snes9x_hires_blend";
|
||||
var.value = NULL;
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
hires_blend = !strcmp(var.value, "disabled") ? false : true;
|
||||
else
|
||||
hires_blend = false;
|
||||
|
||||
var.key = "snes9x_up_down_allowed";
|
||||
var.value = NULL;
|
||||
|
||||
|
@ -328,7 +387,7 @@ void retro_get_system_info(struct retro_system_info *info)
|
|||
#define GIT_VERSION ""
|
||||
#endif
|
||||
info->library_version = VERSION GIT_VERSION;
|
||||
info->valid_extensions = "smc|sfc|swc|fig";
|
||||
info->valid_extensions = "smc|sfc|swc|fig|bs";
|
||||
info->need_fullpath = false;
|
||||
info->block_extract = false;
|
||||
}
|
||||
|
@ -396,10 +455,10 @@ void retro_reset()
|
|||
S9xSoftReset();
|
||||
}
|
||||
|
||||
static unsigned snes_devices[2];
|
||||
static unsigned snes_devices[8];
|
||||
void retro_set_controller_port_device(unsigned port, unsigned device)
|
||||
{
|
||||
if (port < 2)
|
||||
if (port < 8)
|
||||
{
|
||||
int offset = snes_devices[0] == RETRO_DEVICE_JOYPAD_MULTITAP ? 4 : 1;
|
||||
switch (device)
|
||||
|
@ -424,15 +483,18 @@ void retro_set_controller_port_device(unsigned port, unsigned device)
|
|||
S9xSetController(port, CTL_JUSTIFIER, 0, 0, 0, 0);
|
||||
snes_devices[port] = RETRO_DEVICE_LIGHTGUN_JUSTIFIER;
|
||||
break;
|
||||
case RETRO_DEVICE_NONE:
|
||||
S9xSetController(port, CTL_NONE, 0, 0, 0, 0);
|
||||
snes_devices[port] = RETRO_DEVICE_NONE;
|
||||
break;
|
||||
default:
|
||||
if (log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "[libretro]: Invalid device (%d).\n", device);
|
||||
log_cb(RETRO_LOG_ERROR, "Invalid device (%d).\n", device);
|
||||
break;
|
||||
}
|
||||
if (!port)
|
||||
retro_set_controller_port_device(1, snes_devices[1]);
|
||||
}
|
||||
else if(device != RETRO_DEVICE_NONE)
|
||||
log_cb(RETRO_LOG_INFO, "[libretro]: Nonexistent Port (%d).\n", port);
|
||||
log_cb(RETRO_LOG_INFO, "Nonexistent Port (%d).\n", port);
|
||||
}
|
||||
|
||||
void retro_cheat_reset()
|
||||
|
@ -549,6 +611,75 @@ static void init_descriptors(void)
|
|||
environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);
|
||||
}
|
||||
|
||||
static bool valid_normal_bank (uint8 bankbyte)
|
||||
{
|
||||
switch (bankbyte)
|
||||
{
|
||||
case 32: case 33: case 48: case 49:
|
||||
return (true);
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
static int is_bsx (uint8 *p)
|
||||
{
|
||||
if ((p[26] == 0x33 || p[26] == 0xFF) && (!p[21] || (p[21] & 131) == 128) && valid_normal_bank(p[24]))
|
||||
{
|
||||
unsigned char m = p[22];
|
||||
|
||||
if (!m && !p[23])
|
||||
return (2);
|
||||
|
||||
if ((m == 0xFF && p[23] == 0xFF) || (!(m & 0xF) && ((m >> 4) - 1 < 12)))
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool8 LoadBIOS(uint8 *biosrom, char *biosname, int biossize)
|
||||
{
|
||||
FILE *fp;
|
||||
char name[PATH_MAX + 1];
|
||||
bool8 r = FALSE;
|
||||
|
||||
strcpy(name, S9xGetDirectory(ROMFILENAME_DIR));
|
||||
strcat(name, SLASH_STR);
|
||||
strcat(name, biosname);
|
||||
|
||||
fp = fopen(name, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
strcpy(name, S9xGetDirectory(BIOS_DIR));
|
||||
strcat(name, SLASH_STR);
|
||||
strcat(name, biosname);
|
||||
|
||||
fp = fopen(name, "rb");
|
||||
}
|
||||
|
||||
if (fp)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
size = fread((void *) biosrom, 1, biossize, fp);
|
||||
fclose(fp);
|
||||
if (size == biossize)
|
||||
r = TRUE;
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
static bool8 is_SufamiTurbo_Cart (const uint8 *data, uint32 size)
|
||||
{
|
||||
if (size >= 0x80000 && size <= 0x100000 &&
|
||||
strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) != 0)
|
||||
return (TRUE);
|
||||
else
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
bool retro_load_game(const struct retro_game_info *game)
|
||||
{
|
||||
init_descriptors();
|
||||
|
@ -559,17 +690,34 @@ bool retro_load_game(const struct retro_game_info *game)
|
|||
rom_loaded = Memory.LoadROM(game->path);
|
||||
else
|
||||
{
|
||||
uint8 *biosrom = new uint8[0x100000];
|
||||
|
||||
if (game->path != NULL)
|
||||
{
|
||||
extract_basename(g_basename, game->path, sizeof(g_basename));
|
||||
extract_directory(g_rom_dir, game->path, sizeof(g_rom_dir));
|
||||
}
|
||||
|
||||
if (is_SufamiTurbo_Cart((uint8 *) game->data, game->size)) {
|
||||
if (rom_loaded = LoadBIOS(biosrom,"STBIOS.bin",0x40000))
|
||||
rom_loaded = Memory.LoadMultiCartMem((const uint8_t*)game->data, game->size, 0, 0, biosrom, 0x40000);
|
||||
}
|
||||
|
||||
else
|
||||
if ((is_bsx((uint8 *) game->data + 0x7fc0)==1) | (is_bsx((uint8 *) game->data + 0xffc0)==1)) {
|
||||
if (rom_loaded = LoadBIOS(biosrom,"BS-X.bin",0x100000))
|
||||
rom_loaded = Memory.LoadMultiCartMem(biosrom, 0x100000, (const uint8_t*)game->data, game->size, 0, 0);
|
||||
}
|
||||
|
||||
else
|
||||
rom_loaded = Memory.LoadROMMem((const uint8_t*)game->data ,game->size);
|
||||
|
||||
if(biosrom) delete[] biosrom;
|
||||
}
|
||||
|
||||
int pixel_format = RGB555;
|
||||
if(environ_cb) {
|
||||
if(environ_cb)
|
||||
{
|
||||
pixel_format = RGB565;
|
||||
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565;
|
||||
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
||||
|
@ -579,8 +727,148 @@ bool retro_load_game(const struct retro_game_info *game)
|
|||
S9xSetRenderPixelFormat(pixel_format);
|
||||
S9xGraphicsInit();
|
||||
|
||||
if (rom_loaded)
|
||||
update_geometry();
|
||||
|
||||
if (!rom_loaded && log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "[libretro]: Rom loading failed...\n");
|
||||
log_cb(RETRO_LOG_ERROR, "ROM loading failed...\n");
|
||||
|
||||
return rom_loaded;
|
||||
}
|
||||
|
||||
static void remove_header(uint8_t *&romptr, size_t &romsize, bool multicart_sufami)
|
||||
{
|
||||
if (romptr==0 || romsize==0) return;
|
||||
|
||||
uint32 calc_size = (romsize / 0x2000) * 0x2000;
|
||||
if ((romsize - calc_size == 512 && !Settings.ForceNoHeader) || Settings.ForceHeader)
|
||||
{
|
||||
romptr += 512;
|
||||
romsize -= 512;
|
||||
|
||||
if(log_cb) log_cb(RETRO_LOG_INFO,"ROM header removed\n");
|
||||
}
|
||||
|
||||
if (multicart_sufami && (romptr + romsize) >= (romptr + 0x100000))
|
||||
{
|
||||
if (strncmp((const char*)(romptr + 0x100000), "BANDAI SFC-ADX", 14) == 0 &&
|
||||
strncmp((const char*)(romptr + 0x000000), "BANDAI SFC-ADX", 14) == 0)
|
||||
{
|
||||
romptr += 0x100000;
|
||||
romsize -= 0x100000;
|
||||
|
||||
if(log_cb) log_cb(RETRO_LOG_INFO,"Sufami Turbo Multi-ROM bios removed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info)
|
||||
{
|
||||
uint8_t *romptr[3];
|
||||
size_t romsize[3];
|
||||
|
||||
for(size_t i=0; i < num_info; i++)
|
||||
{
|
||||
romptr[i] = (uint8_t *) info[i].data;
|
||||
romsize[i] = info[i].size;
|
||||
remove_header(romptr[i], romsize[i], true);
|
||||
}
|
||||
|
||||
init_descriptors();
|
||||
rom_loaded = false;
|
||||
|
||||
update_variables();
|
||||
switch (game_type)
|
||||
{
|
||||
case RETRO_GAME_TYPE_BSX:
|
||||
if(num_info == 1)
|
||||
{
|
||||
rom_loaded = Memory.LoadROMMem((const uint8_t*)romptr[0],romsize[0]);
|
||||
}
|
||||
else if(num_info == 2)
|
||||
{
|
||||
memcpy(Memory.BIOSROM,(const uint8_t*)romptr[0],info[0].size);
|
||||
rom_loaded = Memory.LoadROMMem((const uint8_t*)romptr[1],info[1].size);
|
||||
}
|
||||
|
||||
if (!rom_loaded && log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "BSX ROM loading failed...\n");
|
||||
break;
|
||||
case RETRO_GAME_TYPE_BSX_SLOTTED:
|
||||
case RETRO_GAME_TYPE_MULTI_CART:
|
||||
if(num_info == 2)
|
||||
{
|
||||
if (is_SufamiTurbo_Cart((const uint8_t*)romptr[0], romsize[0]))
|
||||
{
|
||||
log_cb(RETRO_LOG_ERROR, "Cart is Sufami Turbo...\n");
|
||||
uint8 *biosrom = new uint8[0x40000];
|
||||
uint8 *biosptr = biosrom;
|
||||
|
||||
if (LoadBIOS(biosptr,"STBIOS.bin",0x40000))
|
||||
{
|
||||
if (log_cb)
|
||||
log_cb(RETRO_LOG_INFO, "Loading Sufami Turbo link game\n");
|
||||
|
||||
rom_loaded = Memory.LoadMultiCartMem((const uint8_t*)romptr[0], romsize[0],
|
||||
(const uint8_t*)romptr[1], romsize[1], biosptr, 0x40000);
|
||||
}
|
||||
|
||||
if (biosrom)
|
||||
delete[] biosrom;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (log_cb)
|
||||
log_cb(RETRO_LOG_INFO, "Loading Multi-Cart link game\n");
|
||||
|
||||
rom_loaded = Memory.LoadMultiCartMem((const uint8_t*)romptr[0], romsize[0],
|
||||
(const uint8_t*)romptr[1], romsize[1], NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!rom_loaded && log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "Multirom loading failed...\n");
|
||||
break;
|
||||
|
||||
case RETRO_GAME_TYPE_SUFAMI_TURBO:
|
||||
if(num_info == 2)
|
||||
{
|
||||
uint8 *biosrom = new uint8[0x100000];
|
||||
|
||||
if ((rom_loaded = LoadBIOS(biosrom,"STBIOS.bin",0x100000)))
|
||||
rom_loaded = Memory.LoadMultiCartMem((const uint8_t*)romptr[0], romsize[0],
|
||||
(const uint8_t*)romptr[1], romsize[1], biosrom, 0x40000);
|
||||
|
||||
if (biosrom)
|
||||
delete[] biosrom;
|
||||
}
|
||||
|
||||
if (!rom_loaded && log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "Sufami Turbo ROM loading failed...\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
rom_loaded = false;
|
||||
log_cb(RETRO_LOG_ERROR, "Multi-cart ROM loading failed...\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (rom_loaded)
|
||||
{
|
||||
int pixel_format = RGB555;
|
||||
if(environ_cb)
|
||||
{
|
||||
pixel_format = RGB565;
|
||||
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565;
|
||||
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
||||
pixel_format = RGB555;
|
||||
}
|
||||
S9xGraphicsDeinit();
|
||||
S9xSetRenderPixelFormat(pixel_format);
|
||||
S9xGraphicsInit();
|
||||
|
||||
update_geometry();
|
||||
}
|
||||
|
||||
return rom_loaded;
|
||||
}
|
||||
|
@ -588,58 +876,6 @@ bool retro_load_game(const struct retro_game_info *game)
|
|||
void retro_unload_game(void)
|
||||
{}
|
||||
|
||||
bool retro_load_game_special(unsigned game_type,
|
||||
const struct retro_game_info *info, size_t num_info) {
|
||||
|
||||
init_descriptors();
|
||||
|
||||
update_variables();
|
||||
|
||||
switch (game_type) {
|
||||
case RETRO_GAME_TYPE_BSX:
|
||||
|
||||
if(num_info == 1) {
|
||||
rom_loaded = Memory.LoadROMMem((const uint8_t*)info[0].data,info[0].size);
|
||||
} else if(num_info == 2) {
|
||||
memcpy(Memory.BIOSROM,(const uint8_t*)info[0].data,info[0].size);
|
||||
rom_loaded = Memory.LoadROMMem((const uint8_t*)info[1].data,info[1].size);
|
||||
}
|
||||
|
||||
if (!rom_loaded && log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "[libretro]: BSX ROM loading failed...\n");
|
||||
|
||||
break;
|
||||
|
||||
case RETRO_GAME_TYPE_BSX_SLOTTED:
|
||||
|
||||
if(num_info == 2)
|
||||
rom_loaded = Memory.LoadMultiCartMem((const uint8_t*)info[0].data, info[0].size,
|
||||
(const uint8_t*)info[1].data, info[1].size, NULL, 0);
|
||||
|
||||
if (!rom_loaded && log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "[libretro]: Multirom loading failed...\n");
|
||||
|
||||
break;
|
||||
|
||||
case RETRO_GAME_TYPE_SUFAMI_TURBO:
|
||||
|
||||
if(num_info == 3)
|
||||
rom_loaded = Memory.LoadMultiCartMem((const uint8_t*)info[1].data, info[1].size,
|
||||
(const uint8_t*)info[2].data, info[2].size, (const uint8_t*)info[0].data, info[0].size);
|
||||
|
||||
if (!rom_loaded && log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "[libretro]: Sufami Turbo ROM loading failed...\n");
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
rom_loaded = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return rom_loaded;
|
||||
}
|
||||
|
||||
static void map_buttons();
|
||||
|
||||
static void check_system_specs(void)
|
||||
|
@ -658,6 +894,22 @@ void retro_init(void)
|
|||
else
|
||||
log_cb = NULL;
|
||||
|
||||
const char *dir = NULL;
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
|
||||
snprintf(retro_system_directory, sizeof(retro_system_directory), "%s", dir);
|
||||
else
|
||||
snprintf(retro_system_directory, sizeof(retro_system_directory), "%s", ".");
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir)
|
||||
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", dir);
|
||||
else
|
||||
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", ".");
|
||||
|
||||
// State that SNES9X supports achievements.
|
||||
bool achievements = true;
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS, &achievements);
|
||||
|
||||
memset(&Settings, 0, sizeof(Settings));
|
||||
Settings.MouseMaster = TRUE;
|
||||
Settings.SuperScopeMaster = TRUE;
|
||||
|
@ -688,7 +940,7 @@ void retro_init(void)
|
|||
S9xDeinitAPU();
|
||||
|
||||
if (log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "[libretro]: Failed to init Memory or APU.\n");
|
||||
log_cb(RETRO_LOG_ERROR, "Failed to init Memory or APU.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -706,6 +958,7 @@ void retro_init(void)
|
|||
|
||||
GFX.Pitch = MAX_SNES_WIDTH * sizeof(uint16);
|
||||
GFX.Screen = (uint16*) calloc(1, GFX.Pitch * MAX_SNES_HEIGHT);
|
||||
gfx_blend = (uint16*) calloc(1, GFX.Pitch * MAX_SNES_HEIGHT);
|
||||
S9xGraphicsInit();
|
||||
|
||||
S9xInitInputDevices();
|
||||
|
@ -846,13 +1099,25 @@ static void map_buttons()
|
|||
// libretro uses relative values for analogue devices.
|
||||
// S9x seems to use absolute values, but do convert these into relative values in the core. (Why?!)
|
||||
// Hack around it. :)
|
||||
|
||||
static int16_t snes_mouse_state[2][2] = {{0}, {0}};
|
||||
static int16_t snes_scope_state[2] = {0};
|
||||
static int16_t snes_justifier_state[2][2] = {{0}, {0}};
|
||||
static void report_buttons()
|
||||
{
|
||||
int _x, _y;
|
||||
int offset = snes_devices[0] == RETRO_DEVICE_JOYPAD_MULTITAP ? 4 : 1;
|
||||
|
||||
int runahead_poll = 0;
|
||||
int result = -1;
|
||||
if(environ_cb(RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE, &result))
|
||||
{
|
||||
// runahead off: 3
|
||||
// runahead secondary off: 0,0,0,0,0,3
|
||||
runahead_poll = (result & 0x0b)==3;
|
||||
|
||||
// runahead secondary on: 2,8,8,8,8,9 (messy sync problems)
|
||||
}
|
||||
|
||||
for (int port = 0; port <= 1; port++)
|
||||
{
|
||||
switch (snes_devices[port])
|
||||
|
@ -869,18 +1134,22 @@ static void report_buttons()
|
|||
break;
|
||||
|
||||
case RETRO_DEVICE_MOUSE:
|
||||
_x = input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
|
||||
_y = input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
|
||||
snes_mouse_state[port][0] += _x;
|
||||
snes_mouse_state[port][1] += _y;
|
||||
if(runahead_poll)
|
||||
{
|
||||
snes_mouse_state[port][0] = input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
|
||||
snes_mouse_state[port][1] = input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
|
||||
}
|
||||
S9xReportPointer(BTN_POINTER + port, snes_mouse_state[port][0], snes_mouse_state[port][1]);
|
||||
for (int i = MOUSE_LEFT; i <= MOUSE_LAST; i++)
|
||||
S9xReportButton(MAKE_BUTTON(port + 1, i), input_state_cb(port, RETRO_DEVICE_MOUSE, 0, i));
|
||||
break;
|
||||
|
||||
case RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE:
|
||||
if(runahead_poll)
|
||||
{
|
||||
snes_scope_state[0] += input_state_cb(port, RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE, 0, RETRO_DEVICE_ID_LIGHTGUN_X);
|
||||
snes_scope_state[1] += input_state_cb(port, RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE, 0, RETRO_DEVICE_ID_LIGHTGUN_Y);
|
||||
}
|
||||
if (snes_scope_state[0] < 0) snes_scope_state[0] = 0;
|
||||
else if (snes_scope_state[0] > (SNES_WIDTH-1)) snes_scope_state[0] = SNES_WIDTH-1;
|
||||
if (snes_scope_state[1] < 0) snes_scope_state[1] = 0;
|
||||
|
@ -892,8 +1161,11 @@ static void report_buttons()
|
|||
|
||||
case RETRO_DEVICE_LIGHTGUN_JUSTIFIER:
|
||||
case RETRO_DEVICE_LIGHTGUN_JUSTIFIERS:
|
||||
if(runahead_poll)
|
||||
{
|
||||
snes_justifier_state[port][0] += input_state_cb(port, RETRO_DEVICE_LIGHTGUN_JUSTIFIER, 0, RETRO_DEVICE_ID_LIGHTGUN_X);
|
||||
snes_justifier_state[port][1] += input_state_cb(port, RETRO_DEVICE_LIGHTGUN_JUSTIFIER, 0, RETRO_DEVICE_ID_LIGHTGUN_Y);
|
||||
}
|
||||
if (snes_justifier_state[port][0] < 0) snes_justifier_state[port][0] = 0;
|
||||
else if (snes_justifier_state[port][0] > (SNES_WIDTH-1)) snes_justifier_state[port][0] = SNES_WIDTH-1;
|
||||
if (snes_justifier_state[port][1] < 0) snes_justifier_state[port][1] = 0;
|
||||
|
@ -903,10 +1175,12 @@ static void report_buttons()
|
|||
S9xReportButton(MAKE_BUTTON(2, i), input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, i));
|
||||
break;
|
||||
|
||||
case RETRO_DEVICE_NONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "[libretro]: Unknown device...\n");
|
||||
|
||||
log_cb(RETRO_LOG_ERROR, "Unknown device...\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -952,6 +1226,7 @@ void retro_deinit()
|
|||
S9xUnmapAllControls();
|
||||
|
||||
free(GFX.Screen);
|
||||
free(gfx_blend);
|
||||
}
|
||||
|
||||
|
||||
|
@ -964,8 +1239,8 @@ void* retro_get_memory_data(unsigned type)
|
|||
{
|
||||
void* data;
|
||||
|
||||
switch(type) {
|
||||
case RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM:
|
||||
switch(type)
|
||||
{
|
||||
case RETRO_MEMORY_SAVE_RAM:
|
||||
data = Memory.SRAM;
|
||||
break;
|
||||
|
@ -1004,7 +1279,7 @@ size_t retro_get_memory_size(unsigned type)
|
|||
size = 0x20000;
|
||||
break;
|
||||
case RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM:
|
||||
size = (unsigned) (Multi.cartType && Multi.sramSizeB ? (1 << (Multi.sramSizeB + 3)) * 128 : 0);
|
||||
size = (unsigned) (Multi.cartType==4 && Multi.sramSizeB ? (1 << (Multi.sramSizeB + 3)) * 128 : 0);
|
||||
break;
|
||||
case RETRO_MEMORY_RTC:
|
||||
size = (Settings.SRTC || Settings.SPC7110RTC)?20:0;
|
||||
|
@ -1076,12 +1351,42 @@ bool8 S9xDeinitUpdate(int width, int height)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if(width==MAX_SNES_WIDTH && hires_blend)
|
||||
{
|
||||
#define AVERAGE_565(el0, el1) (((el0) & (el1)) + ((((el0) ^ (el1)) & 0xF7DE) >> 1))
|
||||
for (register int y = 0; y < height; y++)
|
||||
{
|
||||
register uint16 *input = (uint16 *) ((uint8 *) GFX.Screen + y * GFX.Pitch);
|
||||
register uint16 *output = (uint16 *) ((uint8 *) gfx_blend + y * GFX.Pitch);
|
||||
register uint16 l, r;
|
||||
|
||||
l = 0;
|
||||
for (register int x = 0; x < (width >> 1); x++)
|
||||
{
|
||||
r = *input++;
|
||||
*output++ = AVERAGE_565 (l, r);
|
||||
l = r;
|
||||
|
||||
r = *input++;
|
||||
*output++ = AVERAGE_565 (l, r);
|
||||
l = r;
|
||||
}
|
||||
}
|
||||
|
||||
video_cb(gfx_blend, width, height, GFX.Pitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
video_cb(GFX.Screen, width, height, GFX.Pitch);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool8 S9xContinueUpdate(int width, int height)
|
||||
{
|
||||
S9xDeinitUpdate(width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1105,8 +1410,7 @@ const char* S9xGetFilename(const char* in, s9x_getdirtype type)
|
|||
switch (type)
|
||||
{
|
||||
case ROMFILENAME_DIR:
|
||||
sprintf(newpath, "%s%c%s%s",
|
||||
g_rom_dir, SLASH, g_basename, in);
|
||||
sprintf(newpath, "%s%c%s%s", g_rom_dir, SLASH, g_basename, in);
|
||||
return newpath;
|
||||
default:
|
||||
break;
|
||||
|
@ -1121,6 +1425,8 @@ const char* S9xGetDirectory(s9x_getdirtype type)
|
|||
{
|
||||
case ROMFILENAME_DIR:
|
||||
return g_rom_dir;
|
||||
case BIOS_DIR:
|
||||
return retro_system_directory;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue