Unverified Commit b14f83a8 authored by kps501's avatar kps501 Committed by GitHub
Browse files

backport hires blending, add libretro features

runahead polling - lightgun, mouse (no secondary)
lufia 2 credits - slow interlace
parent fe29564d
......@@ -47,9 +47,10 @@ char g_basename[1024];
bool overclock_cycles = false;
bool reduce_sprite_flicker = false;
bool randomize_memory = false;
int interlace_speed;
int one_c, slow_one_c, two_c;
int freq = 10;
int macsrifle_adjust_x, macsrifle_adjust_y;
bool hires_blend = false;
retro_log_printf_t log_cb = NULL;
static retro_video_refresh_t video_cb = NULL;
......@@ -58,6 +59,8 @@ static retro_audio_sample_batch_t audio_batch_cb = NULL;
static retro_input_poll_t poll_cb = NULL;
static retro_input_state_t input_state_cb = NULL;
static bool lufia2_credits_hack = false;
static void extract_basename(char *buf, const char *path, size_t size)
{
const char *base = strrchr(path, '/');
......@@ -130,7 +133,8 @@ void retro_set_environment(retro_environment_t cb)
// 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; 10MHz|20MHz|40MHz|60MHz|80MHz|100MHz" },
{ "snes9x_hires_blend", "Hires Blending; disabled|enabled" },
{ "snes9x_overclock_superfx", "SuperFX Overclocking; 100%|150%|200%|250%|300%|350%|400%|450%|500%|50%" },
{ "snes9x_overclock_cycles", "Reduce Slowdown (Hack, Unsafe); disabled|compatible|max" },
{ "snes9x_reduce_sprite_flicker", "Reduce Flickering (Hack, Unsafe); disabled|enabled" },
{ "snes9x_randomize_memory", "Randomize Memory (Unsafe); disabled|enabled" },
......@@ -141,7 +145,7 @@ void retro_set_environment(retro_environment_t cb)
{ "snes9x_layer_5", "Show sprite layer; enabled|disabled" },
{ "snes9x_gfx_clip", "Enable graphic clip windows; enabled|disabled" },
{ "snes9x_gfx_transp", "Enable transparency effects; enabled|disabled" },
{ "snes9x_gfx_hires", "Enable hires mode; enabled|disabled" },
{ "snes9x_gfx_hires", "Enable hires mode; enabled|disabled" },
{ "snes9x_sndchan_1", "Enable sound channel 1; enabled|disabled" },
{ "snes9x_sndchan_2", "Enable sound channel 2; enabled|disabled" },
{ "snes9x_sndchan_3", "Enable sound channel 3; enabled|disabled" },
......@@ -200,18 +204,23 @@ 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))
{
int newval = atoi(var.value);
if (freq != newval)
{
freq = newval;
Settings.SuperFXSpeedPerLine = 0.417f * ((freq + 0.5f) * 1e6);
reset_sfx = true;
}
int newval;
if(sscanf(var.value,"%d%",&newval))
Settings.SuperFXClockMultiplier = newval;
}
var.key = "snes9x_up_down_allowed";
......@@ -352,9 +361,6 @@ static void update_variables(void)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
macsrifle_adjust_y = atoi(var.value);
if (reset_sfx)
S9xResetSuperFX();
if (geometry_update)
update_geometry();
}
......@@ -727,7 +733,17 @@ bool retro_load_game(const struct retro_game_info *game)
)
ChronoTriggerFrameHack = true;
struct retro_memory_map map={ memorydesc+MAX_MAPS-memorydesc_c, memorydesc_c };
lufia2_credits_hack = false;
if (Memory.match_id("E9ANIE") ||
Memory.match_id("01ANIP") ||
Memory.match_id("C0ANIJ") ||
Memory.match_id("01ANIS") ||
Memory.match_id("01ANIH") ||
Memory.match_id("01ANID")
)
lufia2_credits_hack = true;
struct retro_memory_map map={ memorydesc+MAX_MAPS-memorydesc_c, memorydesc_c };
if (rom_loaded) environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &map);
update_geometry();
......@@ -817,7 +833,7 @@ void retro_init(void)
environ_cb(RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS, &achievements);
memset(&Settings, 0, sizeof(Settings));
Settings.SuperFXSpeedPerLine = 0.417 * 10.5e6;
Settings.SuperFXClockMultiplier = 100;
Settings.MouseMaster = TRUE;
Settings.SuperScopeMaster = TRUE;
Settings.JustifierMaster = TRUE;
......@@ -1012,20 +1028,33 @@ 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 int16_t snes_macsrifle_state[2] = {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])
{
case RETRO_DEVICE_NONE:
break;
break;
case RETRO_DEVICE_JOYPAD:
for (int i = BTN_FIRST; i <= BTN_LAST; i++)
......@@ -1039,18 +1068,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:
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(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;
......@@ -1062,8 +1095,11 @@ static void report_buttons()
case RETRO_DEVICE_LIGHTGUN_JUSTIFIER:
case RETRO_DEVICE_LIGHTGUN_JUSTIFIERS:
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(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;
......@@ -1074,8 +1110,11 @@ static void report_buttons()
break;
case RETRO_DEVICE_LIGHTGUN_MACSRIFLE:
snes_macsrifle_state[0] += input_state_cb(port, RETRO_DEVICE_LIGHTGUN_MACSRIFLE, 0, RETRO_DEVICE_ID_LIGHTGUN_X);
snes_macsrifle_state[1] += input_state_cb(port, RETRO_DEVICE_LIGHTGUN_MACSRIFLE, 0, RETRO_DEVICE_ID_LIGHTGUN_Y);
if(runahead_poll)
{
snes_macsrifle_state[0] += input_state_cb(port, RETRO_DEVICE_LIGHTGUN_MACSRIFLE, 0, RETRO_DEVICE_ID_LIGHTGUN_X);
snes_macsrifle_state[1] += input_state_cb(port, RETRO_DEVICE_LIGHTGUN_MACSRIFLE, 0, RETRO_DEVICE_ID_LIGHTGUN_Y);
}
if (snes_macsrifle_state[0] < 0) snes_macsrifle_state[0] = 0;
else if (snes_macsrifle_state[0] > (SNES_WIDTH-1)) snes_macsrifle_state[0] = SNES_WIDTH-1;
if (snes_macsrifle_state[1] < 0) snes_macsrifle_state[1] = 0;
......@@ -1088,7 +1127,6 @@ static void report_buttons()
default:
if (log_cb)
log_cb(RETRO_LOG_ERROR, "[libretro]: Unknown device...\n");
}
}
}
......@@ -1282,12 +1320,41 @@ 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.Screen + 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.Screen, width, height, GFX.Pitch);
return TRUE;
}
bool8 S9xContinueUpdate(int width, int height)
{
// scrolling credits interlace -- show whole frame
if(lufia2_credits_hack && PPU.BGMode==6)
return TRUE;
return S9xDeinitUpdate(width, height);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment