diff --git a/libretro/Makefile.common b/libretro/Makefile.common
index fe11bda5..76546c4a 100644
--- a/libretro/Makefile.common
+++ b/libretro/Makefile.common
@@ -5,7 +5,7 @@ ifneq (,$(findstring msvc2003,$(platform)))
INCFLAGS += -I$(LIBRETRO_COMM_DIR)/include/compat/msvc
endif
-SOURCES_C :=
+SOURCES_C := $(CORE_DIR)/filter/snes_ntsc.c
SOURCES_CXX := $(CORE_DIR)/apu/apu.cpp \
$(CORE_DIR)/apu/bapu/dsp/sdsp.cpp \
$(CORE_DIR)/apu/bapu/smp/smp.cpp \
diff --git a/libretro/libretro-win32.vcxproj b/libretro/libretro-win32.vcxproj
index 107d53bc..41ea59b2 100644
--- a/libretro/libretro-win32.vcxproj
+++ b/libretro/libretro-win32.vcxproj
@@ -199,6 +199,7 @@
+
@@ -257,6 +258,7 @@
+
@@ -311,4 +313,4 @@
-
\ No newline at end of file
+
diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp
index fffcf002..855fb40d 100644
--- a/libretro/libretro.cpp
+++ b/libretro/libretro.cpp
@@ -23,6 +23,7 @@
#include
#include
#include
+#include "filter/snes_ntsc.h"
#define RETRO_DEVICE_JOYPAD_MULTITAP ((1 << 8) | RETRO_DEVICE_JOYPAD)
#define RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE ((1 << 8) | RETRO_DEVICE_LIGHTGUN)
@@ -69,6 +70,12 @@ 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 snes_ntsc_t *snes_ntsc = NULL;
+static int blargg_filter = 0;
+static uint16 *ntsc_screen_buffer, *snes_ntsc_buffer;
+
+#define MAX_SNES_WIDTH_NTSC SNES_NTSC_OUT_WIDTH(256)
+
static void extract_basename(char *buf, const char *path, size_t size)
{
const char *base = strrchr(path, '/');
@@ -181,6 +188,7 @@ void retro_set_environment(retro_environment_t cb)
{ "snes9x_randomize_memory", "Randomize Memory (Unsafe); disabled|enabled" },
{ "snes9x_hires_blend", "Hires Blending; disabled|merge|blur" },
{ "snes9x_audio_interpolation", "Audio Interpolation; gaussian|cubic|sinc|none|linear" },
+ { "snes9x_blargg", "Blargg NTSC filter; disabled|monochrome|rf|composite|s-video|rgb" },
{ "snes9x_layer_1", "Show layer 1; enabled|disabled" },
{ "snes9x_layer_2", "Show layer 2; enabled|disabled" },
{ "snes9x_layer_3", "Show layer 3; enabled|disabled" },
@@ -604,6 +612,57 @@ static void update_variables(void)
Settings.BlockInvalidVRAMAccessMaster = !strcmp(var.value, "disabled") ? false : true;
else
Settings.BlockInvalidVRAMAccessMaster = true;
+
+ var.key = "snes9x_blargg";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ blargg_filter = 0;
+ else
+ {
+ int old_filter = blargg_filter;
+
+ if(!snes_ntsc) snes_ntsc = new snes_ntsc_t;
+ snes_ntsc_setup_t setup = snes_ntsc_composite;
+
+ if (strcmp(var.value, "monochrome") == 0)
+ {
+ blargg_filter = 1;
+
+ setup = snes_ntsc_monochrome;
+ }
+ else if (strcmp(var.value, "rf") == 0)
+ {
+ blargg_filter = 2;
+
+ setup = snes_ntsc_composite;
+ setup.merge_fields = 0;
+ }
+ else if (strcmp(var.value, "composite") == 0)
+ {
+ blargg_filter = 3;
+
+ setup = snes_ntsc_composite;
+ }
+ else if (strcmp(var.value, "s-video") == 0)
+ {
+ blargg_filter = 4;
+
+ setup = snes_ntsc_svideo;
+ }
+ else if (strcmp(var.value, "rgb") == 0)
+ {
+ blargg_filter = 5;
+
+ setup = snes_ntsc_rgb;
+ }
+
+ if (old_filter != blargg_filter)
+ snes_ntsc_init( snes_ntsc, &setup );
+ }
+ }
}
static void S9xAudioCallback(void*)
@@ -687,7 +746,7 @@ void retro_get_system_av_info(struct retro_system_av_info *info)
info->geometry.base_width = width;
info->geometry.base_height = height;
- info->geometry.max_width = MAX_SNES_WIDTH;
+ info->geometry.max_width = MAX_SNES_WIDTH_NTSC;
info->geometry.max_height = MAX_SNES_HEIGHT;
info->geometry.aspect_ratio = get_aspect_ratio(width, height);
info->timing.sample_rate = 32000;
@@ -1225,9 +1284,11 @@ void retro_init(void)
S9xSetSoundMute(FALSE);
S9xSetSamplesAvailableCallback(S9xAudioCallback, NULL);
- GFX.Pitch = MAX_SNES_WIDTH * sizeof(uint16);
+ GFX.Pitch = MAX_SNES_WIDTH_NTSC * sizeof(uint16);
screen_buffer = (uint16*) calloc(1, GFX.Pitch * (MAX_SNES_HEIGHT + 16));
GFX.Screen = screen_buffer + (GFX.Pitch >> 1) * 16;
+ ntsc_screen_buffer = (uint16*) calloc(1, GFX.Pitch * (MAX_SNES_HEIGHT + 16));
+ snes_ntsc_buffer = ntsc_screen_buffer + (GFX.Pitch >> 1) * 16;
S9xGraphicsInit();
S9xInitInputDevices();
@@ -1552,6 +1613,7 @@ void retro_deinit()
S9xUnmapAllControls();
free(screen_buffer);
+ free(ntsc_screen_buffer);
}
@@ -1702,7 +1764,16 @@ bool8 S9xDeinitUpdate(int width, int height)
}
- if (width == MAX_SNES_WIDTH && hires_blend)
+ if(blargg_filter)
+ {
+ if(width == 512)
+ snes_ntsc_blit_hires(snes_ntsc, GFX.Screen, GFX.Pitch/2, 0, width, height, snes_ntsc_buffer, GFX.Pitch);
+ else
+ snes_ntsc_blit(snes_ntsc, GFX.Screen, GFX.Pitch/2, 0, width, height, snes_ntsc_buffer, GFX.Pitch);
+
+ video_cb(snes_ntsc_buffer + ((int)(GFX.Pitch >> 1) * overscan_offset), MAX_SNES_WIDTH_NTSC, height, GFX.Pitch);
+ }
+ else if (width == MAX_SNES_WIDTH && hires_blend)
{
#define AVERAGE_565(el0, el1) (((el0) & (el1)) + ((((el0) ^ (el1)) & 0xF7DE) >> 1))