Handle nand/firmware a bit bitter; add sound interpolation options; add hybrid screen option

This commit is contained in:
CasualPokePlayer 2024-06-06 13:49:44 -07:00
parent 5fc99f8a7d
commit 43a621a695
7 changed files with 101 additions and 13 deletions

Binary file not shown.

View File

@ -219,8 +219,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
Natural,
Vertical,
Horizontal,
// TODO? do we want this?
// Hybrid,
Hybrid,
}
public enum ScreenRotation : int
@ -251,6 +250,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
[BizImport(CC)]
public abstract void SetScreenSettings(IntPtr console, ref ScreenSettings screenSettings, out int width, out int height, out int vwidth, out int vheight);
[BizImport(CC)]
public abstract void SetSoundConfig(IntPtr console, NDS.NDSSettings.AudioBitDepthType bitDepth NDS.NDSSettings.AudioInterpolationType interpolation);
[BizImport(CC)]
public abstract void GetTouchCoords(ref int x, ref int y);

View File

@ -23,6 +23,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
Natural,
Vertical,
Horizontal,
Hybrid,
[Display(Name = "Top Only")]
Top,
[Display(Name = "Bottom Only")]
@ -91,8 +92,19 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
public enum AudioInterpolationType : int
{
None,
Linear,
Cosine,
Cubic,
[Display(Name = "Gaussian (SNES)")]
SNESGaussian,
}
[DisplayName("Audio Interpolation")]
[Description("Audio enhancement (original hardware has no audio interpolation).")]
[DefaultValue(AudioInterpolationType.None)]
[TypeConverter(typeof(DescribableEnumConverter))]
public AudioInterpolationType AudioInterpolation { get; set; }
[DisplayName("Alt Lag")]
[Description("If true, touch screen polling and ARM7 key polling will be considered for lag frames. Otherwise, only ARM9 key polling will be considered.")]
[DefaultValue(false)]
@ -441,6 +453,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
ScreenLayoutKind.Natural => LibMelonDS.ScreenLayout.Natural,
ScreenLayoutKind.Vertical => LibMelonDS.ScreenLayout.Vertical,
ScreenLayoutKind.Horizontal => LibMelonDS.ScreenLayout.Horizontal,
ScreenLayoutKind.Hybrid => LibMelonDS.ScreenLayout.Hybrid,
_ => LibMelonDS.ScreenLayout.Natural,
},
ScreenRotation = settings.ScreenRotation switch
@ -482,6 +495,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
RefreshScreenSettings(o);
}
_core.SetSoundConfig(_console, o.AudioBitDepth, o.AudioInterpolation);
_settings = o;
return ret ? PutSettingsDirtyBits.ScreenLayoutChanged : PutSettingsDirtyBits.None;
}

View File

@ -77,8 +77,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
{
DefaultWidth = 256,
DefaultHeight = 384,
MaxWidth = 256 * 16,
MaxHeight = (384 + 128) * 16,
MaxWidth = (256 * 16) * 3 + ((128 * 16) * 4 / 3) + 1,
MaxHeight = (384 / 2 * 16) * 2 + (128 * 16),
MaxSamples = 1024,
DefaultFpsNumerator = 33513982,
DefaultFpsDenominator = 560190,
@ -251,7 +251,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
consoleCreationArgs.SkipFW = _activeSyncSettings.SkipFirmware;
consoleCreationArgs.BitDepth = _settings.AudioBitDepth;
consoleCreationArgs.Interpolation = NDSSettings.AudioInterpolationType.None;
consoleCreationArgs.Interpolation = _settings.AudioInterpolation;
consoleCreationArgs.ThreeDeeRenderer = _activeSyncSettings.ThreeDeeRenderer;
consoleCreationArgs.Threaded3D = _activeSyncSettings.ThreadedRendering;
@ -560,6 +560,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
{
throw new InvalidOperationException("_frameThreadPtr mismatch");
}
_core.SetSoundConfig(_console, _settings.AudioBitDepth, _settings.AudioInterpolation);
}
// omega hack

View File

@ -138,9 +138,18 @@ static void SetFirmwareSettings(melonDS::Firmware::UserData& userData, FirmwareS
if (!((1 << static_cast<u8>(userData.ExtendedSettings.ExtendedLanguage)) & userData.ExtendedSettings.SupportedLanguageMask))
{
userData.ExtendedSettings.ExtendedLanguage = melonDS::Firmware::Language::English;
// Use the first supported language
for (int i = 0; i <= melonDS::Firmware::Language::Reserved; i++)
{
if ((1 << i) & userData.ExtendedSettings.SupportedLanguageMask)
{
userData.ExtendedSettings.ExtendedLanguage = static_cast<melonDS::Firmware::Language>(i);
break;
}
}
userData.Settings &= ~melonDS::Firmware::Language::Reserved;
userData.Settings |= melonDS::Firmware::Language::English;
userData.Settings |= userData.ExtendedSettings.ExtendedLanguage;
}
}
else
@ -267,6 +276,24 @@ static void SanitizeNandSettings(melonDS::DSi_NAND::DSiFirmwareSystemSettings& s
memset(settings.ParentalControlsSecretAnswer, 0, sizeof(settings.ParentalControlsSecretAnswer));
}
static void ClearNandSavs(melonDS::DSi_NAND::NANDMount& mount, u32 category)
{
std::vector<u32> titlelist;
mount.ListTitles(category, titlelist);
char fname[128];
for (auto& title : titlelist)
{
snprintf(fname, sizeof(fname), "0:/title/%08x/%08x/data/public.sav", category, title);
mount.RemoveFile(fname);
snprintf(fname, sizeof(fname), "0:/title/%08x/%08x/data/private.sav", category, title);
mount.RemoveFile(fname);
snprintf(fname, sizeof(fname), "0:/title/%08x/%08x/data/banner.sav", category, title);
mount.RemoveFile(fname);
}
}
static melonDS::DSi_NAND::NANDImage CreateNandImage(
u8* nandData, u32 nandLength, std::unique_ptr<melonDS::DSiBIOSImage>& arm7Bios,
FirmwareSettings& fwSettings, bool clearNand,
@ -312,8 +339,15 @@ static melonDS::DSi_NAND::NANDImage CreateNandImage(
if (!((1 << static_cast<u8>(settings.Language)) & serialData.SupportedLanguages))
{
// English is valid among all NANDs
settings.Language = melonDS::Firmware::Language::English;
// Use the first supported language
for (int i = 0; i <= melonDS::Firmware::Language::Reserved; i++)
{
if ((1 << i) & serialData.SupportedLanguages)
{
settings.Language = static_cast<melonDS::Firmware::Language>(i);
break;
}
}
}
}
@ -345,6 +379,21 @@ static melonDS::DSi_NAND::NANDImage CreateNandImage(
{
mount.DeleteTitle(DSIWARE_CATEGORY, title);
}
// clear out .sav files of builtin apps / title management / system menu
constexpr u32 BUILTIN_APP_CATEGORY = 0x00030005;
constexpr u32 TITLE_MANAGEMENT_CATEGORY = 0x00030015;
constexpr u32 SYSTEM_MENU_CATEGORY = 0x00030017;
ClearNandSavs(mount, BUILTIN_APP_CATEGORY);
ClearNandSavs(mount, TITLE_MANAGEMENT_CATEGORY);
ClearNandSavs(mount, SYSTEM_MENU_CATEGORY);
// clear out some other misc files
mount.RemoveFile("0:/shared2/launcher/wrap.bin");
mount.RemoveFile("0:/shared2/0000");
mount.RemoveFile("0:/sys/log/product.log");
mount.RemoveFile("0:/sys/log/sysmenu.log");
}
if (dsiWareData)

View File

@ -12,7 +12,10 @@
namespace Frontend
{
extern float TouchMtx[6];
extern float HybTouchMtx[6];
extern bool BotEnable;
extern bool HybEnable;
extern int HybScreen;
extern void M23_Transform(float* m, float& x, float& y);
}
@ -69,8 +72,8 @@ ECL_INVISIBLE static GLuint ScreenShaderTransformULoc, ScreenShaderSizeULoc;
ECL_INVISIBLE static GLuint VertexBuffer, VertexArray;
ECL_INVISIBLE static float ScreenMatrix[2 * 6];
ECL_INVISIBLE static int ScreenKinds[2];
ECL_INVISIBLE static float ScreenMatrix[3 * 6];
ECL_INVISIBLE static int ScreenKinds[3];
ECL_INVISIBLE static int NumScreens;
ECL_INVISIBLE static u32 Width, Height;
@ -254,6 +257,10 @@ static std::pair<u32, u32> GetScreenSize(const ScreenSettings* screenSettings, u
return isHori
? std::make_pair(h * 2 + gap, w)
: std::make_pair(w * 2 + gap, h);
case Frontend::screenLayout_Hybrid:
return isHori
? std::make_pair(h * 2 + gap, w * 3 + (int)ceil(gap * 4 / 3.0))
: std::make_pair(w * 3 + (int)ceil(gap * 4 / 3.0), h * 2 + gap);
default:
__builtin_unreachable();
}
@ -318,7 +325,14 @@ ECL_EXPORT void GetTouchCoords(int* x, int* y)
float vx = *x;
float vy = *y;
Frontend::M23_Transform(Frontend::TouchMtx, vx, vy);
if (Frontend::HybEnable && Frontend::HybScreen == 1)
{
Frontend::M23_Transform(Frontend::HybTouchMtx, vx, vy);
}
else
{
Frontend::M23_Transform(Frontend::TouchMtx, vx, vy);
}
*x = vx;
*y = vy;
@ -332,7 +346,7 @@ ECL_EXPORT void GetTouchCoords(int* x, int* y)
ECL_EXPORT void GetScreenCoords(float* x, float* y)
{
for (int i = 0; i < NumScreens; i++)
for (int i = NumScreens - 1; i >= 0; i--)
{
// bottom screen
if (ScreenKinds[i] == 1)

View File

@ -166,3 +166,9 @@ ECL_EXPORT u32 GetCallbackCycleOffset(melonDS::NDS* nds)
{
return RunningFrame ? nds->GetSysClockCycles(2) : 0;
}
ECL_EXPORT void SetSoundConfig(melonDS::NDS* nds, int bitDepth, int interpolation)
{
nds->SPU.SetDegrade10Bit(static_cast<melonDS::AudioBitDepth>(bitDepth));
nds->SPU.SetInterpolation(static_cast<melonDS::AudioInterpolation>(interpolation));
}