mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-12-24 18:21:50 +01:00
Add Interpolation option and Add Gamemenu Audio
This adds the following: - A new gamemenu option called Audio - Under the new gamemenu option an option Interpolation with three options: Gaussian (Default), Linear, None
This commit is contained in:
parent
16c80360ce
commit
1479319bb5
@ -130,6 +130,8 @@ extern const u8 icon_settings_network_png[];
|
||||
extern const u32 icon_settings_network_png_size;
|
||||
extern const u8 icon_settings_video_png[];
|
||||
extern const u32 icon_settings_video_png_size;
|
||||
extern const u8 icon_settings_audio_png[];
|
||||
extern const u32 icon_settings_audio_png_size;
|
||||
extern const u8 icon_settings_screenshot_png[];
|
||||
extern const u32 icon_settings_screenshot_png_size;
|
||||
|
||||
|
BIN
source/images/icon_settings_audio.png
Normal file
BIN
source/images/icon_settings_audio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
128
source/menu.cpp
128
source/menu.cpp
@ -41,6 +41,7 @@
|
||||
#include "snes9x/snes9x.h"
|
||||
#include "snes9x/fxemu.h"
|
||||
#include "snes9x/memmap.h"
|
||||
#include "snes9x/apu/apu.h"
|
||||
#include "snes9x/cheats.h"
|
||||
|
||||
extern SCheatData Cheat;
|
||||
@ -1886,6 +1887,7 @@ static int MenuGameSettings()
|
||||
GuiImageData btnLargeOutlineOver(button_large_over_png);
|
||||
GuiImageData iconMappings(icon_settings_mappings_png);
|
||||
GuiImageData iconVideo(icon_settings_video_png);
|
||||
GuiImageData iconAudio(icon_settings_audio_png);
|
||||
GuiImageData iconController(icon_game_controllers_png);
|
||||
GuiImageData iconCheats(icon_game_cheats_png);
|
||||
GuiImageData iconScreenshot(icon_settings_screenshot_png);
|
||||
@ -1902,7 +1904,7 @@ static int MenuGameSettings()
|
||||
GuiImage mappingBtnIcon(&iconMappings);
|
||||
GuiButton mappingBtn(btnLargeOutline.GetWidth(), btnLargeOutline.GetHeight());
|
||||
mappingBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
mappingBtn.SetPosition(-125, 120);
|
||||
mappingBtn.SetPosition(-200, 120);
|
||||
mappingBtn.SetLabel(&mappingBtnTxt);
|
||||
mappingBtn.SetImage(&mappingBtnImg);
|
||||
mappingBtn.SetImageOver(&mappingBtnImgOver);
|
||||
@ -1913,6 +1915,24 @@ static int MenuGameSettings()
|
||||
mappingBtn.SetTrigger(trig2);
|
||||
mappingBtn.SetEffectGrow();
|
||||
|
||||
GuiText audioBtnTxt("Audio", 22, (GXColor){0, 0, 0, 255});
|
||||
audioBtnTxt.SetWrap(true, btnLargeOutline.GetWidth()-20);
|
||||
GuiImage audioBtnImg(&btnLargeOutline);
|
||||
GuiImage audioBtnImgOver(&btnLargeOutlineOver);
|
||||
GuiImage audioBtnIcon(&iconAudio);
|
||||
GuiButton audioBtn(btnLargeOutline.GetWidth(), btnLargeOutline.GetHeight());
|
||||
audioBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
audioBtn.SetPosition(0, 120);
|
||||
audioBtn.SetLabel(&audioBtnTxt);
|
||||
audioBtn.SetImage(&audioBtnImg);
|
||||
audioBtn.SetImageOver(&audioBtnImgOver);
|
||||
audioBtn.SetIcon(&audioBtnIcon);
|
||||
audioBtn.SetSoundOver(&btnSoundOver);
|
||||
audioBtn.SetSoundClick(&btnSoundClick);
|
||||
audioBtn.SetTrigger(trigA);
|
||||
audioBtn.SetTrigger(trig2);
|
||||
audioBtn.SetEffectGrow();
|
||||
|
||||
GuiText videoBtnTxt("Video", 22, (GXColor){0, 0, 0, 255});
|
||||
videoBtnTxt.SetWrap(true, btnLargeOutline.GetWidth()-20);
|
||||
GuiImage videoBtnImg(&btnLargeOutline);
|
||||
@ -1920,7 +1940,7 @@ static int MenuGameSettings()
|
||||
GuiImage videoBtnIcon(&iconVideo);
|
||||
GuiButton videoBtn(btnLargeOutline.GetWidth(), btnLargeOutline.GetHeight());
|
||||
videoBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
videoBtn.SetPosition(125, 120);
|
||||
videoBtn.SetPosition(200, 120);
|
||||
videoBtn.SetLabel(&videoBtnTxt);
|
||||
videoBtn.SetImage(&videoBtnImg);
|
||||
videoBtn.SetImageOver(&videoBtnImgOver);
|
||||
@ -2018,6 +2038,7 @@ static int MenuGameSettings()
|
||||
w.Append(&titleTxt);
|
||||
w.Append(&mappingBtn);
|
||||
w.Append(&videoBtn);
|
||||
w.Append(&audioBtn);
|
||||
w.Append(&controllerBtn);
|
||||
w.Append(&screenshotBtn);
|
||||
w.Append(&cheatsBtn);
|
||||
@ -2040,6 +2061,10 @@ static int MenuGameSettings()
|
||||
{
|
||||
menu = MENU_GAMESETTINGS_VIDEO;
|
||||
}
|
||||
else if(audioBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
menu = MENU_GAMESETTINGS_AUDIO;
|
||||
}
|
||||
else if(controllerBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
ControllerWindow();
|
||||
@ -3333,6 +3358,102 @@ static int MenuSettingsVideo()
|
||||
return menu;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* MenuSettingsAudio
|
||||
***************************************************************************/
|
||||
static int MenuSettingsAudio()
|
||||
{
|
||||
int menu = MENU_NONE;
|
||||
int ret;
|
||||
int i = 0;
|
||||
bool firstRun = true;
|
||||
OptionList options;
|
||||
sprintf(options.name[i++], "Interpolation");
|
||||
options.length = i;
|
||||
for(i=0; i < options.length; i++)
|
||||
options.value[i][0] = 0;
|
||||
GuiText titleTxt("Game Settings - Audio", 26, (GXColor){255, 255, 255, 255});
|
||||
titleTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
|
||||
titleTxt.SetPosition(50,50);
|
||||
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM);
|
||||
GuiSound btnSoundClick(button_click_pcm, button_click_pcm_size, SOUND_PCM);
|
||||
GuiImageData btnOutline(button_png);
|
||||
GuiImageData btnOutlineOver(button_over_png);
|
||||
GuiText backBtnTxt("Go Back", 22, (GXColor){0, 0, 0, 255});
|
||||
GuiImage backBtnImg(&btnOutline);
|
||||
GuiImage backBtnImgOver(&btnOutlineOver);
|
||||
GuiButton backBtn(btnOutline.GetWidth(), btnOutline.GetHeight());
|
||||
backBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
|
||||
backBtn.SetPosition(50, -35);
|
||||
backBtn.SetLabel(&backBtnTxt);
|
||||
backBtn.SetImage(&backBtnImg);
|
||||
backBtn.SetImageOver(&backBtnImgOver);
|
||||
backBtn.SetSoundOver(&btnSoundOver);
|
||||
backBtn.SetSoundClick(&btnSoundClick);
|
||||
backBtn.SetTrigger(trigA);
|
||||
backBtn.SetTrigger(trig2);
|
||||
backBtn.SetEffectGrow();
|
||||
GuiOptionBrowser optionBrowser(552, 248, &options);
|
||||
optionBrowser.SetPosition(0, 108);
|
||||
optionBrowser.SetCol2Position(200);
|
||||
optionBrowser.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
|
||||
HaltGui();
|
||||
GuiWindow w(screenwidth, screenheight);
|
||||
w.Append(&backBtn);
|
||||
mainWindow->Append(&optionBrowser);
|
||||
mainWindow->Append(&w);
|
||||
mainWindow->Append(&titleTxt);
|
||||
ResumeGui();
|
||||
|
||||
while(menu == MENU_NONE)
|
||||
{
|
||||
usleep(THREAD_SLEEP);
|
||||
ret = optionBrowser.GetClickedOption();
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
GCSettings.Interpolation++;
|
||||
if (GCSettings.Interpolation > 2) {
|
||||
GCSettings.Interpolation = 0;
|
||||
}
|
||||
switch(GCSettings.Interpolation)
|
||||
{
|
||||
case 0: Settings.InterpolationMethod = DSP_INTERPOLATION_GAUSSIAN; break;
|
||||
case 1: Settings.InterpolationMethod = DSP_INTERPOLATION_LINEAR; break;
|
||||
case 2: Settings.InterpolationMethod = DSP_INTERPOLATION_NONE; break;
|
||||
}
|
||||
break;
|
||||
S9xReset();
|
||||
}
|
||||
|
||||
if(ret >= 0 || firstRun)
|
||||
{
|
||||
firstRun = false;
|
||||
|
||||
switch(GCSettings.Interpolation)
|
||||
{
|
||||
case 0:
|
||||
sprintf (options.value[0], "Gaussian (Accurate)"); break;
|
||||
case 1:
|
||||
sprintf (options.value[0], "Linear"); break;
|
||||
case 2:
|
||||
sprintf (options.value[0], "None"); break;
|
||||
}
|
||||
optionBrowser.TriggerUpdate();
|
||||
}
|
||||
if(backBtn.GetState() == STATE_CLICKED)
|
||||
{
|
||||
menu = MENU_GAMESETTINGS;
|
||||
}
|
||||
}
|
||||
HaltGui();
|
||||
mainWindow->Remove(&optionBrowser);
|
||||
mainWindow->Remove(&w);
|
||||
mainWindow->Remove(&titleTxt);
|
||||
return menu;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* MenuSettings
|
||||
***************************************************************************/
|
||||
@ -4158,6 +4279,9 @@ MainMenu (int menu)
|
||||
case MENU_GAMESETTINGS_VIDEO:
|
||||
currentMenu = MenuSettingsVideo();
|
||||
break;
|
||||
case MENU_GAMESETTINGS_AUDIO:
|
||||
currentMenu = MenuSettingsAudio();
|
||||
break;
|
||||
case MENU_GAMESETTINGS_CHEATS:
|
||||
currentMenu = MenuGameCheats();
|
||||
break;
|
||||
|
@ -41,6 +41,7 @@ enum
|
||||
MENU_GAMESETTINGS_MAPPINGS_CTRL,
|
||||
MENU_GAMESETTINGS_MAPPINGS_MAP,
|
||||
MENU_GAMESETTINGS_VIDEO,
|
||||
MENU_GAMESETTINGS_AUDIO,
|
||||
MENU_GAMESETTINGS_CHEATS
|
||||
};
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "input.h"
|
||||
#include "button_mapping.h"
|
||||
|
||||
#include "snes9x/apu/apu.h"
|
||||
|
||||
struct SGCSettings GCSettings;
|
||||
|
||||
/****************************************************************************
|
||||
@ -151,6 +153,7 @@ preparePrefsData ()
|
||||
createXMLSetting("xshift", "Horizontal Video Shift", toStr(GCSettings.xshift));
|
||||
createXMLSetting("yshift", "Vertical Video Shift", toStr(GCSettings.yshift));
|
||||
createXMLSetting("sfxOverclock", "SuperFX Overclock", toStr(GCSettings.sfxOverclock));
|
||||
createXMLSetting("Interpolation", "Interpolation", toStr(GCSettings.Interpolation));
|
||||
|
||||
createXMLSection("Menu", "Menu Settings");
|
||||
|
||||
@ -335,6 +338,10 @@ decodePrefsData ()
|
||||
loadXMLSetting(&GCSettings.xshift, "xshift");
|
||||
loadXMLSetting(&GCSettings.yshift, "yshift");
|
||||
|
||||
// Audio Settings
|
||||
|
||||
loadXMLSetting(&GCSettings.Interpolation, "Interpolation");
|
||||
|
||||
// Emulation Settings
|
||||
|
||||
loadXMLSetting(&GCSettings.sfxOverclock, "sfxOverclock");
|
||||
@ -489,6 +496,10 @@ DefaultSettings ()
|
||||
Settings.SoundInputRate = 31950;
|
||||
Settings.DynamicRateControl = true;
|
||||
|
||||
// Interpolation Method
|
||||
GCSettings.Interpolation = 0;
|
||||
Settings.InterpolationMethod = DSP_INTERPOLATION_GAUSSIAN;
|
||||
|
||||
// Graphics
|
||||
Settings.Transparency = true;
|
||||
Settings.SupportHiRes = true;
|
||||
|
@ -1,5 +1,7 @@
|
||||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "snes9x.h"
|
||||
|
||||
#include "SPC_DSP.h"
|
||||
|
||||
#include "blargg_endian.h"
|
||||
@ -126,26 +128,45 @@ static short const gauss [512] =
|
||||
};
|
||||
|
||||
inline int SPC_DSP::interpolate( voice_t const* v )
|
||||
{
|
||||
int out;
|
||||
int const* in = &v->buf [(v->interp_pos >> 12) + v->buf_pos];
|
||||
switch (Settings.InterpolationMethod)
|
||||
{
|
||||
case 0: // raw
|
||||
{
|
||||
out = v->buf [(v->interp_pos >> 12) + v->buf_pos] & ~1;
|
||||
break;
|
||||
}
|
||||
case 1: // linear interpolation
|
||||
{
|
||||
int fract = v->interp_pos & 0xFFF;
|
||||
out = (0x1000 - fract) * in [0];
|
||||
out += fract * in [1];
|
||||
out >>= 12;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case 2: // Original gaussian filter
|
||||
{
|
||||
// Make pointers into gaussian based on fractional position between samples
|
||||
int offset = v->interp_pos >> 4 & 0xFF;
|
||||
short const* fwd = gauss + 255 - offset;
|
||||
short const* rev = gauss + offset; // mirror left half of gaussian
|
||||
|
||||
int const* in = &v->buf [(v->interp_pos >> 12) + v->buf_pos];
|
||||
int out;
|
||||
out = (fwd [ 0] * in [0]) >> 11;
|
||||
out += (fwd [256] * in [1]) >> 11;
|
||||
out += (rev [256] * in [2]) >> 11;
|
||||
out = (int16_t) out;
|
||||
out += (rev [ 0] * in [3]) >> 11;
|
||||
|
||||
CLAMP16( out );
|
||||
out &= ~1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
//// Counters
|
||||
|
||||
int const simple_counter_range = 2048 * 5 * 3; // 30720
|
||||
|
@ -47,4 +47,8 @@ void S9xUpdateDynamicRate (double rate);
|
||||
|
||||
extern SNES_SPC *spc_core;
|
||||
|
||||
#define DSP_INTERPOLATION_NONE 0
|
||||
#define DSP_INTERPOLATION_LINEAR 1
|
||||
#define DSP_INTERPOLATION_GAUSSIAN 2
|
||||
|
||||
#endif
|
||||
|
@ -242,6 +242,7 @@ struct SSettings
|
||||
bool8 ReverseStereo;
|
||||
bool8 Mute;
|
||||
bool8 DynamicRateControl;
|
||||
int32 InterpolationMethod;
|
||||
|
||||
bool8 SupportHiRes;
|
||||
bool8 Transparency;
|
||||
|
@ -486,6 +486,13 @@ int main(int argc, char *argv[])
|
||||
S9xResetSuperFX();
|
||||
}
|
||||
|
||||
switch (GCSettings.Interpolation)
|
||||
{
|
||||
case 0: Settings.InterpolationMethod = DSP_INTERPOLATION_GAUSSIAN; break;
|
||||
case 1: Settings.InterpolationMethod = DSP_INTERPOLATION_LINEAR; break;
|
||||
case 2: Settings.InterpolationMethod = DSP_INTERPOLATION_NONE; break;
|
||||
}
|
||||
|
||||
while (1) // main loop
|
||||
{
|
||||
if(!autoboot) {
|
||||
|
@ -119,6 +119,8 @@ struct SGCSettings{
|
||||
int PreviewImage;
|
||||
|
||||
int sfxOverclock;
|
||||
|
||||
int Interpolation;
|
||||
};
|
||||
|
||||
void ExitApp();
|
||||
|
Loading…
Reference in New Issue
Block a user