update melonDS
lots of changes needed here as core has done quite a bit of changes (which in any case has reduced needed changes in upstream for our fork, so easier merging in the future) gl crap is better done with fancy template classes to wrap around the msabi/sysvabi runtime check (so comparing with nullptr or using it as a bool works as expected) c# changes pending (API has changed)
This commit is contained in:
parent
e1fb97dee6
commit
659ff2e8de
Binary file not shown.
|
@ -72,12 +72,6 @@ void TraceTrampoline(TraceMask_t type, u32* regs, u32 opcode)
|
|||
TraceCallback(type, opcode, regs, disasm, NDS::GetSysClockCycles(2));
|
||||
}
|
||||
|
||||
namespace NDS
|
||||
{
|
||||
extern ARMv5* ARM9;
|
||||
extern ARMv4* ARM7;
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetRegs(u32* regs)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include "NDS.h"
|
||||
#include "DSi.h"
|
||||
#include "DSi_NAND.h"
|
||||
#include "DSi_TMD.h"
|
||||
#include "CRC32.h"
|
||||
#include "FreeBIOS.h"
|
||||
#include "SPI.h"
|
||||
|
||||
#include "BizFileManager.h"
|
||||
|
||||
|
@ -28,65 +31,366 @@ static std::optional<std::pair<std::unique_ptr<u8[]>, size_t>> GetFileData(std::
|
|||
return std::make_pair(std::move(data), size);
|
||||
}
|
||||
|
||||
const char* InitNAND(bool clearNand, bool dsiWare)
|
||||
// Inits NDS BIOS7 and BIOS9
|
||||
const char* InitNDSBIOS()
|
||||
{
|
||||
auto dsiBios7Path = Platform::GetConfigString(Platform::ConfigEntry::DSi_BIOS7Path);
|
||||
auto bios7i = Platform::OpenFile(dsiBios7Path, Platform::FileMode::Read);
|
||||
if (NDS::ConsoleType == 1 || Platform::GetConfigBool(Platform::ExternalBIOSEnable))
|
||||
{
|
||||
auto bios7 = Platform::OpenFile("bios7.bin", Platform::FileMode::Read);
|
||||
if (!bios7)
|
||||
{
|
||||
return "Failed to obtain BIOS7!";
|
||||
}
|
||||
|
||||
if (Platform::FileLength(bios7) != sizeof(NDS::ARM7BIOS))
|
||||
{
|
||||
Platform::CloseFile(bios7);
|
||||
return "Incorrectly sized BIOS7!";
|
||||
}
|
||||
|
||||
Platform::FileRewind(bios7);
|
||||
Platform::FileRead(NDS::ARM7BIOS, sizeof(bios7), 1, bios7);
|
||||
Platform::CloseFile(bios7);
|
||||
|
||||
auto bios9 = Platform::OpenFile("bios9.bin", Platform::FileMode::Read);
|
||||
if (!bios9)
|
||||
{
|
||||
return "Failed to obtain BIOS9!";
|
||||
}
|
||||
|
||||
if (Platform::FileLength(bios9) != sizeof(NDS::ARM9BIOS))
|
||||
{
|
||||
Platform::CloseFile(bios9);
|
||||
return "Incorrectly sized BIOS9!";
|
||||
}
|
||||
|
||||
Platform::FileRewind(bios9);
|
||||
Platform::FileRead(NDS::ARM9BIOS, sizeof(bios9), 1, bios9);
|
||||
Platform::CloseFile(bios9);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(NDS::ARM7BIOS, bios_arm7_bin, sizeof(bios_arm7_bin));
|
||||
memcpy(NDS::ARM9BIOS, bios_arm9_bin, sizeof(bios_arm9_bin));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void SanitizeExternalFirmware(SPI_Firmware::Firmware& firmware)
|
||||
{
|
||||
auto& header = firmware.Header();
|
||||
|
||||
const bool isDSiFw = header.ConsoleType == SPI_Firmware::FirmwareConsoleType::DSi;
|
||||
const auto defaultHeader = SPI_Firmware::FirmwareHeader(isDSiFw);
|
||||
|
||||
header.UserSettingsOffset = (0x7FE00 & firmware.Mask()) >> 3;
|
||||
|
||||
if (isDSiFw)
|
||||
{
|
||||
memset(&header.Unknown0[0], 0, (uintptr_t)&header.Unused2[0] - (uintptr_t)&header.Unknown0[0]);
|
||||
header.Unused2[0] = header.Unused2[1] = 0xFF;
|
||||
}
|
||||
|
||||
memcpy(&header.WifiConfigLength, &defaultHeader.WifiConfigLength, (uintptr_t)&header.Unknown4 - (uintptr_t)&header.WifiConfigLength);
|
||||
memset(&header.Unknown4, 0xFF, (uintptr_t)&header.Unused7 - (uintptr_t)&header.Unknown4 + 1);
|
||||
|
||||
if (isDSiFw)
|
||||
{
|
||||
header.WifiBoard = defaultHeader.WifiBoard;
|
||||
header.WifiFlash = defaultHeader.WifiFlash;
|
||||
}
|
||||
|
||||
header.UpdateChecksum();
|
||||
|
||||
auto& aps = firmware.AccessPoints();
|
||||
aps[0] = SPI_Firmware::WifiAccessPoint(NDS::ConsoleType);
|
||||
aps[1] = SPI_Firmware::WifiAccessPoint();
|
||||
aps[2] = SPI_Firmware::WifiAccessPoint();
|
||||
|
||||
if (isDSiFw)
|
||||
{
|
||||
auto& exAps = firmware.ExtendedAccessPoints();
|
||||
exAps[0] = SPI_Firmware::ExtendedWifiAccessPoint();
|
||||
exAps[1] = SPI_Firmware::ExtendedWifiAccessPoint();
|
||||
exAps[2] = SPI_Firmware::ExtendedWifiAccessPoint();
|
||||
}
|
||||
}
|
||||
|
||||
static void FixFirmwareTouchscreenCalibration(SPI_Firmware::UserData& userData)
|
||||
{
|
||||
userData.TouchCalibrationADC1[0] = 0;
|
||||
userData.TouchCalibrationADC1[1] = 0;
|
||||
userData.TouchCalibrationPixel1[0] = 0;
|
||||
userData.TouchCalibrationPixel1[1] = 0;
|
||||
userData.TouchCalibrationADC2[0] = 255 << 4;
|
||||
userData.TouchCalibrationADC2[1] = 191 << 4;
|
||||
userData.TouchCalibrationPixel2[0] = 255;
|
||||
userData.TouchCalibrationPixel2[1] = 191;
|
||||
}
|
||||
|
||||
static void SetFirmwareSettings(SPI_Firmware::UserData& userData, FirmwareSettings& fwSettings, bool dsiFw)
|
||||
{
|
||||
memset(userData.Bytes, 0, 0x74);
|
||||
userData.Version = 5;
|
||||
FixFirmwareTouchscreenCalibration(userData);
|
||||
|
||||
userData.NameLength = fwSettings.UsernameLength;
|
||||
memcpy(userData.Nickname, fwSettings.Username, sizeof(fwSettings.Username));
|
||||
userData.Settings = fwSettings.Language | SPI_Firmware::BacklightLevel::Max | 0xFC00;
|
||||
userData.BirthdayMonth = fwSettings.BirthdayMonth;
|
||||
userData.BirthdayDay = fwSettings.BirthdayDay;
|
||||
userData.FavoriteColor = fwSettings.Color;
|
||||
userData.MessageLength = fwSettings.MessageLength;
|
||||
memcpy(userData.Message, fwSettings.Message, sizeof(fwSettings.Message));
|
||||
|
||||
if (userData.ExtendedSettings.Unknown0 == 1)
|
||||
{
|
||||
userData.ExtendedSettings.ExtendedLanguage = static_cast<SPI_Firmware::Language>(fwSettings.Language & SPI_Firmware::Language::Reserved);
|
||||
memset(userData.ExtendedSettings.Unused0, dsiFw ? 0x00 : 0xFF, sizeof(userData.ExtendedSettings.Unused0));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(userData.Unused3, 0xFF, sizeof(userData.Unused3));
|
||||
}
|
||||
|
||||
// only extended settings should have Chinese
|
||||
if ((userData.Settings & SPI_Firmware::Language::Reserved) == SPI_Firmware::Language::Chinese)
|
||||
{
|
||||
userData.Settings &= SPI_Firmware::Language::Reserved;
|
||||
userData.Settings |= SPI_Firmware::Language::English;
|
||||
}
|
||||
}
|
||||
|
||||
// Inits NDS firmware
|
||||
const char* InitFirmware(FirmwareSettings& fwSettings)
|
||||
{
|
||||
auto firmware = SPI_Firmware::Firmware(NDS::ConsoleType);
|
||||
|
||||
if (Platform::GetConfigBool(Platform::ExternalBIOSEnable))
|
||||
{
|
||||
auto fw = Platform::OpenFile("firmware.bin", Platform::FileMode::Read);
|
||||
if (!fw)
|
||||
{
|
||||
return "Failed to obtain firmware!";
|
||||
}
|
||||
|
||||
firmware = SPI_Firmware::Firmware(fw);
|
||||
|
||||
if (firmware.Buffer())
|
||||
{
|
||||
// Fix header and AP points
|
||||
SanitizeExternalFirmware(firmware);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fwSettings.OverrideSettings = true;
|
||||
}
|
||||
|
||||
if (!firmware.Buffer())
|
||||
{
|
||||
return "Failed to load firmware!";
|
||||
}
|
||||
|
||||
for (SPI_Firmware::UserData& userData : firmware.UserData())
|
||||
{
|
||||
FixFirmwareTouchscreenCalibration(userData);
|
||||
userData.UpdateChecksum();
|
||||
}
|
||||
|
||||
if (fwSettings.OverrideSettings)
|
||||
{
|
||||
for (SPI_Firmware::UserData& userData : firmware.UserData())
|
||||
{
|
||||
SetFirmwareSettings(userData, fwSettings, firmware.Header().ConsoleType == SPI_Firmware::FirmwareConsoleType::DSi);
|
||||
userData.UpdateChecksum();
|
||||
}
|
||||
|
||||
SPI_Firmware::MacAddress mac;
|
||||
Platform::GetConfigArray(Platform::Firm_MAC, &mac);
|
||||
auto& header = firmware.Header();
|
||||
header.MacAddress = mac;
|
||||
header.UpdateChecksum();
|
||||
}
|
||||
|
||||
if (!SPI_Firmware::InstallFirmware(std::move(firmware)))
|
||||
{
|
||||
return "Failed to install firmware!";
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Inits DSi BIOS7i and BIOS9i
|
||||
const char* InitDSiBIOS()
|
||||
{
|
||||
if (NDS::ConsoleType == 0)
|
||||
{
|
||||
return "Tried to init DSi BIOSes in NDS mode";
|
||||
}
|
||||
|
||||
auto bios7i = Platform::OpenFile("bios7i.bin", Platform::FileMode::Read);
|
||||
if (!bios7i)
|
||||
{
|
||||
return "Failed to obtain BIOS7i!";
|
||||
}
|
||||
|
||||
u8 es_keyY[16]{};
|
||||
Platform::FileSeek(bios7i, 0x8308, Platform::FileSeekOrigin::Start);
|
||||
Platform::FileRead(es_keyY, 16, 1, bios7i);
|
||||
if (Platform::FileLength(bios7i) != sizeof(DSi::ARM7iBIOS))
|
||||
{
|
||||
Platform::CloseFile(bios7i);
|
||||
return "Incorrectly sized BIOS7i!";
|
||||
}
|
||||
|
||||
Platform::FileRewind(bios7i);
|
||||
Platform::FileRead(DSi::ARM7iBIOS, sizeof(bios7i), 1, bios7i);
|
||||
Platform::CloseFile(bios7i);
|
||||
|
||||
if (!DSi_NAND::Init(es_keyY))
|
||||
auto bios9i = Platform::OpenFile("bios9i.bin", Platform::FileMode::Read);
|
||||
if (!bios9i)
|
||||
{
|
||||
return "Failed to init DSi NAND!";
|
||||
return "Failed to obtain BIOS9i!";
|
||||
}
|
||||
|
||||
if (clearNand)
|
||||
if (Platform::FileLength(bios9i) != sizeof(DSi::ARM9iBIOS))
|
||||
{
|
||||
std::vector<u32> titlelist;
|
||||
DSi_NAND::ListTitles(DSIWARE_CATEGORY, titlelist);
|
||||
Platform::CloseFile(bios9i);
|
||||
return "Incorrectly sized BIOS9i!";
|
||||
}
|
||||
|
||||
for (auto& title : titlelist)
|
||||
Platform::FileRewind(bios9i);
|
||||
Platform::FileRead(DSi::ARM9iBIOS, sizeof(bios9i), 1, bios9i);
|
||||
Platform::CloseFile(bios9i);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void SanitizeNANDSettings(DSi_NAND::DSiFirmwareSystemSettings& settings)
|
||||
{
|
||||
memset(settings.Zero00, 0, sizeof(settings.Zero00));
|
||||
settings.Version = 1;
|
||||
settings.UpdateCounter = 0;
|
||||
memset(settings.Zero01, 0, sizeof(settings.Zero01));
|
||||
settings.BelowRAMAreaSize = 0x128;
|
||||
settings.ConfigFlags = 0x0100000F;
|
||||
settings.Zero02 = 0;
|
||||
settings.CountryCode = 49; // United States
|
||||
settings.RTCYear = 0;
|
||||
settings.RTCOffset = 0;
|
||||
memset(settings.Zero3, 0, sizeof(settings.Zero3));
|
||||
settings.EULAVersion = 1;
|
||||
memset(settings.Zero04, 0, sizeof(settings.Zero04));
|
||||
settings.AlarmHour = 0;
|
||||
settings.AlarmMinute = 0;
|
||||
memset(settings.Zero05, 0, sizeof(settings.Zero05));
|
||||
settings.AlarmEnable = false;
|
||||
memset(settings.Zero06, 0, sizeof(settings.Zero06));
|
||||
settings.Unknown0 = 0;
|
||||
settings.Unknown1 = 3; // apparently 2 or 3
|
||||
memset(settings.Zero07, 0, sizeof(settings.Zero07));
|
||||
settings.SystemMenuMostRecentTitleID.fill(0);
|
||||
settings.Unknown2[0] = 0x9C;
|
||||
settings.Unknown2[1] = 0x20;
|
||||
settings.Unknown2[2] = 0x01;
|
||||
settings.Unknown2[3] = 0x02;
|
||||
memset(settings.Zero08, 0, sizeof(settings.Zero08));
|
||||
settings.Zero09 = 0;
|
||||
settings.ParentalControlsFlags = 0;
|
||||
memset(settings.Zero10, 0, sizeof(settings.Zero10));
|
||||
settings.ParentalControlsRegion = 0;
|
||||
settings.ParentalControlsYearsOfAgeRating = 0;
|
||||
settings.ParentalControlsSecretQuestion = 0;
|
||||
settings.Unknown3 = 0; // apparently 0 or 6 or 7
|
||||
memset(settings.Zero11, 0, sizeof(settings.Zero11));
|
||||
memset(settings.ParentalControlsPIN, 0, sizeof(settings.ParentalControlsPIN));
|
||||
memset(settings.ParentalControlsSecretAnswer, 0, sizeof(settings.ParentalControlsSecretAnswer));
|
||||
}
|
||||
|
||||
const char* InitNAND(FirmwareSettings& fwSettings, bool clearNand, bool dsiWare)
|
||||
{
|
||||
auto nand = DSi_NAND::NANDImage(Platform::OpenFile("nand.bin", Platform::FileMode::Read), &DSi::ARM7iBIOS[0x8308]);
|
||||
if (!nand)
|
||||
{
|
||||
return "Failed to parse DSi NAND!";
|
||||
}
|
||||
|
||||
{
|
||||
auto mount = DSi_NAND::NANDMount(nand);
|
||||
if (!mount)
|
||||
{
|
||||
DSi_NAND::DeleteTitle(DSIWARE_CATEGORY, title);
|
||||
return "Failed to mount DSi NAND!";
|
||||
}
|
||||
|
||||
DSi_NAND::DSiFirmwareSystemSettings settings{};
|
||||
if (!mount.ReadUserData(settings))
|
||||
{
|
||||
return "Failed to read DSi NAND user data";
|
||||
}
|
||||
|
||||
if (fwSettings.OverrideSettings)
|
||||
{
|
||||
SanitizeNANDSettings(settings);
|
||||
memset(settings.Nickname, 0, sizeof(settings.Nickname));
|
||||
memcpy(settings.Nickname, fwSettings.Username, fwSettings.UsernameLength);
|
||||
settings.Language = static_cast<SPI_Firmware::Language>(fwSettings.Language & SPI_Firmware::Language::Reserved);
|
||||
settings.FavoriteColor = fwSettings.Color;
|
||||
settings.BirthdayMonth = fwSettings.BirthdayMonth;
|
||||
settings.BirthdayDay = fwSettings.BirthdayDay;
|
||||
memset(settings.Message, 0, sizeof(settings.Message));
|
||||
memcpy(settings.Message, fwSettings.Message, fwSettings.MessageLength);
|
||||
}
|
||||
|
||||
settings.TouchCalibrationADC1[0] = 0;
|
||||
settings.TouchCalibrationADC1[1] = 0;
|
||||
settings.TouchCalibrationPixel1[0] = 0;
|
||||
settings.TouchCalibrationPixel1[1] = 0;
|
||||
settings.TouchCalibrationADC2[0] = 255 << 4;
|
||||
settings.TouchCalibrationADC2[1] = 191 << 4;
|
||||
settings.TouchCalibrationPixel2[0] = 255;
|
||||
settings.TouchCalibrationPixel2[1] = 191;
|
||||
|
||||
settings.UpdateHash();
|
||||
|
||||
if (!mount.ApplyUserData(settings))
|
||||
{
|
||||
return "Failed to write DSi NAND user data";
|
||||
}
|
||||
|
||||
if (clearNand)
|
||||
{
|
||||
std::vector<u32> titlelist;
|
||||
mount.ListTitles(DSIWARE_CATEGORY, titlelist);
|
||||
|
||||
for (auto& title : titlelist)
|
||||
{
|
||||
mount.DeleteTitle(DSIWARE_CATEGORY, title);
|
||||
}
|
||||
}
|
||||
|
||||
if (dsiWare)
|
||||
{
|
||||
auto tmdData = GetFileData("tmd.rom");
|
||||
if (!tmdData)
|
||||
{
|
||||
return "Failed to obtain TMD!";
|
||||
}
|
||||
|
||||
if (tmdData->second < sizeof(DSi_TMD::TitleMetadata))
|
||||
{
|
||||
return "TMD is too small!";
|
||||
}
|
||||
|
||||
DSi_TMD::TitleMetadata tmd;
|
||||
memcpy(&tmd, tmdData->first.get(), sizeof(DSi_TMD::TitleMetadata));
|
||||
|
||||
if (!mount.ImportTitle("dsiware.rom", tmd, false))
|
||||
{
|
||||
return "Loading DSiWare failed!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dsiWare)
|
||||
{
|
||||
auto rom = GetFileData("dsiware.rom");
|
||||
if (!rom)
|
||||
{
|
||||
return "Failed to obtain DSiWare ROM!";
|
||||
}
|
||||
|
||||
auto tmdData = GetFileData("tmd.rom");
|
||||
if (!tmdData)
|
||||
{
|
||||
return "Failed to obtain TMD!";
|
||||
}
|
||||
|
||||
if (tmdData->second < sizeof(DSi_TMD::TitleMetadata))
|
||||
{
|
||||
return "TMD is too small!";
|
||||
}
|
||||
|
||||
DSi_TMD::TitleMetadata tmd;
|
||||
memcpy(&tmd, tmdData->first.get(), sizeof(DSi_TMD::TitleMetadata));
|
||||
if (!DSi_NAND::ImportTitle(rom->first.get(), rom->second, tmd, false))
|
||||
{
|
||||
DSi_NAND::DeInit();
|
||||
return "Loading DSiWare failed!";
|
||||
}
|
||||
}
|
||||
|
||||
DSi_NAND::DeInit();
|
||||
DSi::NANDImage = std::make_unique<DSi_NAND::NANDImage>(std::move(nand));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,23 @@
|
|||
namespace FileManager
|
||||
{
|
||||
|
||||
const char* InitNAND(bool clearNand, bool dsiWare);
|
||||
struct FirmwareSettings
|
||||
{
|
||||
bool OverrideSettings;
|
||||
int UsernameLength;
|
||||
char16_t Username[10];
|
||||
int Language;
|
||||
int BirthdayMonth;
|
||||
int BirthdayDay;
|
||||
int Color;
|
||||
int MessageLength;
|
||||
char16_t Message[26];
|
||||
};
|
||||
|
||||
const char* InitNDSBIOS();
|
||||
const char* InitFirmware(FirmwareSettings& fwSettings);
|
||||
const char* InitDSiBIOS();
|
||||
const char* InitNAND(FirmwareSettings& fwSettings, bool clearNand, bool dsiWare);
|
||||
const char* InitCarts(bool gba);
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,16 @@ static bool SkipFW;
|
|||
static time_t CurTime;
|
||||
static bool GLPresentation;
|
||||
|
||||
struct NDSTime
|
||||
{
|
||||
int Year; // 0-99
|
||||
int Month; // 1-12
|
||||
int Day; // 1-(28/29/30/31 depending on month/year)
|
||||
int Hour; // 0-23
|
||||
int Minute; // 0-59
|
||||
int Second; // 0-59
|
||||
};
|
||||
|
||||
struct InitConfig
|
||||
{
|
||||
bool SkipFW;
|
||||
|
@ -30,6 +40,8 @@ struct InitConfig
|
|||
bool IsWinApi;
|
||||
int ThreeDeeRenderer;
|
||||
GPU::RenderSettings RenderSettings;
|
||||
NDSTime StartTime;
|
||||
FileManager::FirmwareSettings FirmwareSettings;
|
||||
};
|
||||
|
||||
ECL_EXPORT const char* Init(InitConfig* initConfig,
|
||||
|
@ -45,12 +57,24 @@ ECL_EXPORT const char* Init(InitConfig* initConfig,
|
|||
SkipFW = initConfig->SkipFW;
|
||||
NDS::SetConsoleType(initConfig->DSi);
|
||||
|
||||
CurTime = 0;
|
||||
RTC::RtcCallback = []() { return CurTime; };
|
||||
if (const char* error = FileManager::InitNDSBIOS())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
if (const char* error = FileManager::InitFirmware(initConfig->FirmwareSettings))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
if (initConfig->DSi)
|
||||
{
|
||||
if (const char* error = FileManager::InitNAND(initConfig->ClearNAND, initConfig->LoadDSiWare))
|
||||
if (const char* error = FileManager::InitDSiBIOS())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
if (const char* error = FileManager::InitNAND(initConfig->FirmwareSettings, initConfig->ClearNAND, initConfig->LoadDSiWare))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
@ -61,6 +85,9 @@ ECL_EXPORT const char* Init(InitConfig* initConfig,
|
|||
return "Failed to init core!";
|
||||
}
|
||||
|
||||
RTC::SetDateTime(initConfig->StartTime.Year, initConfig->StartTime.Month, initConfig->StartTime.Day,
|
||||
initConfig->StartTime.Hour, initConfig->StartTime.Minute, initConfig->StartTime.Second);
|
||||
|
||||
if (loadGLProc)
|
||||
{
|
||||
switch (initConfig->ThreeDeeRenderer)
|
||||
|
@ -91,7 +118,7 @@ ECL_EXPORT const char* Init(InitConfig* initConfig,
|
|||
GPU::InitRenderer(initConfig->ThreeDeeRenderer);
|
||||
GPU::SetRenderSettings(initConfig->ThreeDeeRenderer, initConfig->RenderSettings);
|
||||
|
||||
NDS::LoadBIOS();
|
||||
NDS::Reset();
|
||||
|
||||
if (!initConfig->LoadDSiWare)
|
||||
{
|
||||
|
@ -126,14 +153,14 @@ static s16 biz_mic_input[735];
|
|||
|
||||
static bool ValidRange(s8 sensor)
|
||||
{
|
||||
return (sensor >= 0) && (sensor <= 10);
|
||||
return sensor >= 0 && sensor <= 10;
|
||||
}
|
||||
|
||||
static int sampPos = 0;
|
||||
|
||||
static void MicFeedNoise(s8 vol)
|
||||
{
|
||||
int sampLen = sizeof(mic_blow) / sizeof (*mic_blow);
|
||||
int sampLen = sizeof(mic_blow) / sizeof(*mic_blow);
|
||||
|
||||
for (int i = 0; i < 735; i++)
|
||||
{
|
||||
|
@ -150,7 +177,7 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo* f)
|
|||
|
||||
if (f->Keys & 0x8000)
|
||||
{
|
||||
NDS::LoadBIOS();
|
||||
NDS::Reset();
|
||||
if (SkipFW || NDS::NeedsDirectBoot())
|
||||
{
|
||||
NDS::SetupDirectBoot("nds.rom");
|
||||
|
|
|
@ -138,30 +138,6 @@ private:
|
|||
|
||||
static std::unordered_map<std::string, std::pair<std::shared_ptr<u8[]>, size_t>> FileBufferCache;
|
||||
|
||||
// TODO - I don't like this approach with NAND
|
||||
// Perhaps instead it would be better to use FileFlush to write to disk
|
||||
// (guarded by frontend determinism switch, of course)
|
||||
|
||||
ECL_EXPORT u32 GetNANDSize()
|
||||
{
|
||||
auto path = GetConfigString(ConfigEntry::DSi_NANDPath);
|
||||
if (auto cache = FileBufferCache.find(path); cache != FileBufferCache.end())
|
||||
{
|
||||
return cache->second.second;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetNANDData(u8* buf)
|
||||
{
|
||||
auto path = GetConfigString(ConfigEntry::DSi_NANDPath);
|
||||
if (auto cache = FileBufferCache.find(path); cache != FileBufferCache.end())
|
||||
{
|
||||
memcpy(buf, cache->second.first.get(), cache->second.second);
|
||||
}
|
||||
}
|
||||
|
||||
FileHandle* OpenFile(const std::string& path, FileMode mode)
|
||||
{
|
||||
if ((mode & FileMode::ReadWrite) == FileMode::None)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -64,39 +64,76 @@ ECL_EXPORT bool SaveRamIsDirty()
|
|||
|
||||
ECL_EXPORT void ImportDSiWareSavs(u32 titleId)
|
||||
{
|
||||
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
|
||||
auto& nand = DSi::NANDImage;
|
||||
if (nand && *nand)
|
||||
{
|
||||
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PublicSav, "public.sav");
|
||||
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PrivateSav, "private.sav");
|
||||
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_BannerSav, "banner.sav");
|
||||
DSi_NAND::DeInit();
|
||||
if (auto mount = DSi_NAND::NANDMount(*nand))
|
||||
{
|
||||
mount.ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PublicSav, "public.sav");
|
||||
mount.ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PrivateSav, "private.sav");
|
||||
mount.ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_BannerSav, "banner.sav");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT void ExportDSiWareSavs(u32 titleId)
|
||||
{
|
||||
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
|
||||
auto& nand = DSi::NANDImage;
|
||||
if (nand && *nand)
|
||||
{
|
||||
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PublicSav, "public.sav");
|
||||
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PrivateSav, "private.sav");
|
||||
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_BannerSav, "banner.sav");
|
||||
DSi_NAND::DeInit();
|
||||
if (auto mount = DSi_NAND::NANDMount(*nand))
|
||||
{
|
||||
mount.ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PublicSav, "public.sav");
|
||||
mount.ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PrivateSav, "private.sav");
|
||||
mount.ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_BannerSav, "banner.sav");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ECL_EXPORT void DSiWareSavsLength(u32 titleId, u32* publicSavSize, u32* privateSavSize, u32* bannerSavSize)
|
||||
{
|
||||
*publicSavSize = *privateSavSize = *bannerSavSize = 0;
|
||||
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
|
||||
{
|
||||
u32 version;
|
||||
NDSHeader header{};
|
||||
|
||||
DSi_NAND::GetTitleInfo(DSIWARE_CATEGORY, titleId, version, &header, nullptr);
|
||||
*publicSavSize = header.DSiPublicSavSize;
|
||||
*privateSavSize = header.DSiPrivateSavSize;
|
||||
*bannerSavSize = (header.AppFlags & 0x04) ? 0x4000 : 0;
|
||||
DSi_NAND::DeInit();
|
||||
auto& nand = DSi::NANDImage;
|
||||
if (nand && *nand)
|
||||
{
|
||||
if (auto mount = DSi_NAND::NANDMount(*nand))
|
||||
{
|
||||
u32 version;
|
||||
NDSHeader header{};
|
||||
|
||||
mount.GetTitleInfo(DSIWARE_CATEGORY, titleId, version, &header, nullptr);
|
||||
*publicSavSize = header.DSiPublicSavSize;
|
||||
*privateSavSize = header.DSiPrivateSavSize;
|
||||
*bannerSavSize = (header.AppFlags & 0x04) ? 0x4000 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - I don't like this approach with NAND
|
||||
// Perhaps instead it would be better to use FileFlush to write to disk
|
||||
// (guarded by frontend determinism switch, of course)
|
||||
|
||||
ECL_EXPORT u32 GetNANDSize()
|
||||
{
|
||||
auto& nand = DSi::NANDImage;
|
||||
if (nand && *nand)
|
||||
{
|
||||
return nand->GetLength();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ECL_EXPORT void GetNANDData(u8* buf)
|
||||
{
|
||||
auto& nand = DSi::NANDImage;
|
||||
if (nand && *nand)
|
||||
{
|
||||
auto len = nand->GetLength();
|
||||
auto file = nand->GetFile();
|
||||
Platform::FileRewind(file);
|
||||
Platform::FileRead(buf, 1, len, file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,4 +147,12 @@ void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen
|
|||
GbaSaveRamIsDirty = true;
|
||||
}
|
||||
|
||||
void WriteFirmware(const SPI_Firmware::Firmware& firmware, u32 writeoffset, u32 writelen)
|
||||
{
|
||||
}
|
||||
|
||||
void WriteDateTime(int year, int month, int day, int hour, int minute, int second)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ CORE_SRCS = \
|
|||
CP15.cpp \
|
||||
CRC32.cpp \
|
||||
DMA.cpp \
|
||||
DMA_Timings.cpp \
|
||||
DSi.cpp \
|
||||
DSi_AES.cpp \
|
||||
DSi_Camera.cpp \
|
||||
|
@ -32,7 +33,9 @@ CORE_SRCS = \
|
|||
DSi_NWifi.cpp \
|
||||
DSi_SD.cpp \
|
||||
DSi_SPI_TSC.cpp \
|
||||
FATIO.cpp \
|
||||
FATStorage.cpp \
|
||||
FreeBIOS.cpp \
|
||||
GBACart.cpp \
|
||||
GPU.cpp \
|
||||
GPU2D.cpp \
|
||||
|
@ -45,6 +48,7 @@ CORE_SRCS = \
|
|||
RTC.cpp \
|
||||
Savestate.cpp \
|
||||
SPI.cpp \
|
||||
SPI_Firmware.cpp \
|
||||
SPU.cpp \
|
||||
Wifi.cpp \
|
||||
WifiAP.cpp
|
||||
|
@ -67,7 +71,6 @@ TEAKRA_SRCS = \
|
|||
timer.cpp
|
||||
|
||||
FATFS_SRCS = \
|
||||
diskio.c \
|
||||
ff.c \
|
||||
ffsystem.c \
|
||||
ffunicode.c
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit ee581ad6461c78ab08e440bb1ca5afd05fa96f66
|
||||
Subproject commit 0506a84cdede08a4ebc7f71799265d91ac1d79dc
|
Loading…
Reference in New Issue