Add fallback to Drastic BIOS and fake firmware when not provided (#105)

* Generate a simple non-bootable firmware when not provided.

* Expose Username and Language into settings dialog.

* Add firmware overrides for more settings. Also make override optionals when a firmware is provided.

* Refactor firmware settings into separate dialog.

* use usernameLength instead of u16Username.length() (#3)

* Fix curly braces code-style.

* Fallback to FreeBIOS when BIOS files are not found.

* Add sources of drastic bios files.

* Handle frontend language and set default username.

* Add missing configuration variables.

* Allow load to progress when firmware/bios is missing.

* Use new arm toolchain to build drastic bios.

Co-authored-by: kyandora <71771686+kyandora@users.noreply.github.com>
Co-authored-by: Filippo Scognamiglio <filippo.scognamiglio@felgo.com>
This commit is contained in:
Filippo Scognamiglio 2021-04-11 15:28:15 +02:00 committed by Mats
parent f091fb486a
commit 53d14f403c
21 changed files with 3451 additions and 52 deletions

17
freebios/Makefile Executable file
View File

@ -0,0 +1,17 @@
TC_PREFIX = /home/swordfish/Downloads/gcc-arm-10.2-2020.11-x86_64-arm-none-eabi
PREFIX = $(TC_PREFIX)
AS = $(PREFIX)/bin/arm-none-eabi-gcc
OBJCOPY = $(PREFIX)/bin/arm-none-eabi-objcopy
BIN_ARM7 = drastic_bios_arm7
BIN_ARM9 = drastic_bios_arm9
all:
$(AS) bios_common.S -DBIOS_ARM7 -march=armv4t -c -Wa,-asl=$(BIN_ARM7).list -o $(BIN_ARM7).o
$(AS) bios_common.S -DBIOS_ARM9 -march=armv5t -c -Wa,-asl=$(BIN_ARM9).list -o $(BIN_ARM9).o
$(OBJCOPY) -O binary $(BIN_ARM7).o $(BIN_ARM7).bin
$(OBJCOPY) -O binary $(BIN_ARM9).o $(BIN_ARM9).bin
clean:
rm -f $(BIN_ARM7).bin $(BIN_ARM7).o $(BIN_ARM9).bin $(BIN_ARM9).o

1135
freebios/bios_common.S Executable file

File diff suppressed because it is too large Load Diff

BIN
freebios/drastic_bios_arm7.bin Executable file

Binary file not shown.

BIN
freebios/drastic_bios_arm9.bin Executable file

Binary file not shown.

View File

@ -0,0 +1,36 @@
Custom NDS ARM7/ARM9 BIOS replacement
Copyright (c) 2013, Gilead Kutnick
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1) Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2) Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-- Info --
This archive contains source code and assembly for a custom BIOS replacement
for the Nintendo DS system. This code is in no way affiliated with Nintendo
and is not derived from Nintendo's BIOS implementation but has been implemented
using publically available documentation.
It can be assembled using the included Makefile along with a proper ARM gcc
toolchain. Change the first four lines to point to the proper toolchain of your
choice.

View File

@ -39,6 +39,7 @@ add_library(core STATIC
NDSCart_SRAMManager.cpp
Platform.h
ROMList.h
FreeBIOS.h
RTC.cpp
Savestate.cpp
SPI.cpp

View File

@ -34,6 +34,14 @@ char FirmwarePath[1024];
int DLDIEnable;
char DLDISDPath[1024];
char FirmwareUsername[64];
int FirmwareLanguage;
bool FirmwareOverrideSettings;
int FirmwareBirthdayMonth;
int FirmwareBirthdayDay;
int FirmwareFavouriteColour;
char FirmwareMessage[1024];
char DSiBIOS9Path[1024];
char DSiBIOS7Path[1024];
char DSiFirmwarePath[1024];
@ -60,6 +68,14 @@ ConfigEntry ConfigFile[] =
{"DLDIEnable", 0, &DLDIEnable, 0, NULL, 0},
{"DLDISDPath", 1, DLDISDPath, 0, "", 1023},
{"FirmwareUsername", 1, FirmwareUsername, 0, "MelonDS", 63},
{"FirmwareLanguage", 0, &FirmwareLanguage, 1, NULL, 0},
{"FirmwareOverrideSettings", 0, &FirmwareOverrideSettings, false, NULL, 0},
{"FirmwareBirthdayMonth", 0, &FirmwareBirthdayMonth, 0, NULL, 0},
{"FirmwareBirthdayDay", 0, &FirmwareBirthdayDay, 0, NULL, 0},
{"FirmwareFavouriteColour", 0, &FirmwareFavouriteColour, 0, NULL, 0},
{"FirmwareMessage", 1, FirmwareMessage, 0, "", 1023},
{"DSiBIOS9Path", 1, DSiBIOS9Path, 0, "", 1023},
{"DSiBIOS7Path", 1, DSiBIOS7Path, 0, "", 1023},
{"DSiFirmwarePath", 1, DSiFirmwarePath, 0, "", 1023},

View File

@ -47,6 +47,14 @@ extern char FirmwarePath[1024];
extern int DLDIEnable;
extern char DLDISDPath[1024];
extern char FirmwareUsername[64];
extern int FirmwareLanguage;
extern bool FirmwareOverrideSettings;
extern int FirmwareBirthdayMonth;
extern int FirmwareBirthdayDay;
extern int FirmwareFavouriteColour;
extern char FirmwareMessage[1024];
extern char DSiBIOS9Path[1024];
extern char DSiBIOS7Path[1024];
extern char DSiFirmwarePath[1024];

1747
src/FreeBIOS.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -34,6 +34,7 @@
#include "AREngine.h"
#include "Platform.h"
#include "NDSCart_SRAMManager.h"
#include "FreeBIOS.h"
#ifdef JIT_ENABLED
#include "ARMJIT.h"
@ -466,10 +467,8 @@ void Reset()
f = Platform::OpenLocalFile(Config::BIOS9Path, "rb");
if (!f)
{
printf("ARM9 BIOS not found\n");
for (i = 0; i < 16; i++)
((u32*)ARM9BIOS)[i] = 0xE7FFDEFF;
printf("ARM9 BIOS not found. Loading FreeBIOS.\n");
memcpy(ARM9BIOS, bios_arm9_bin, bios_arm9_bin_len);
}
else
{
@ -483,10 +482,8 @@ void Reset()
f = Platform::OpenLocalFile(Config::BIOS7Path, "rb");
if (!f)
{
printf("ARM7 BIOS not found\n");
for (i = 0; i < 16; i++)
((u32*)ARM7BIOS)[i] = 0xE7FFDEFF;
printf("ARM7 BIOS not found. Loading FreeBIOS.\n");
memcpy(ARM7BIOS, bios_arm7_bin, bios_arm7_bin_len);
}
else
{

View File

@ -19,6 +19,8 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <algorithm>
#include "Config.h"
#include "NDS.h"
#include "DSi.h"
@ -112,25 +114,25 @@ u32 FixFirmwareLength(u32 originalLength)
return originalLength;
}
void Reset()
void LoadDefaultFirmware()
{
if (Firmware) delete[] Firmware;
Firmware = NULL;
FirmwareLength = 0x20000;
Firmware = new u8[FirmwareLength];
memset(Firmware, 0xFF, FirmwareLength);
FirmwareMask = FirmwareLength - 1;
if (NDS::ConsoleType == 1)
strncpy(FirmwarePath, Config::DSiFirmwarePath, 1023);
else
strncpy(FirmwarePath, Config::FirmwarePath, 1023);
u32 userdata = 0x7FE00 & FirmwareMask;
FILE* f = Platform::OpenLocalFile(FirmwarePath, "rb");
if (!f)
{
printf("Firmware not found\n");
memset(Firmware + userdata, 0, 0x74);
// TODO: generate default firmware
return;
// user settings offset
*(u16*)&Firmware[0x20] = (FirmwareLength - 0x200) >> 3;
Firmware[userdata+0x00] = 5; // version
}
void LoadFirmwareFromFile(FILE* f)
{
fseek(f, 0, SEEK_END);
FirmwareLength = FixFirmwareLength((u32)ftell(f));
@ -159,6 +161,54 @@ void Reset()
fclose(f);
}
}
}
void LoadUserSettingsFromConfig() {
// setting up username
std::string username(Config::FirmwareUsername);
std::u16string u16Username(username.begin(), username.end());
size_t usernameLength = std::min(u16Username.length(), (size_t) 10);
memcpy(Firmware + UserSettings + 0x06, u16Username.data(), usernameLength * sizeof(char16_t));
Firmware[UserSettings+0x1A] = usernameLength;
// setting language
Firmware[UserSettings+0x64] = Config::FirmwareLanguage;
// setting up color
Firmware[UserSettings+0x02] = Config::FirmwareFavouriteColour;
// setting up birthday
Firmware[UserSettings+0x03] = Config::FirmwareBirthdayMonth;
Firmware[UserSettings+0x04] = Config::FirmwareBirthdayDay;
// setup message
std::string message(Config::FirmwareMessage);
std::u16string u16message(message.begin(), message.end());
size_t messageLength = std::min(u16message.length(), (size_t) 26);
memcpy(Firmware + UserSettings + 0x1C, u16message.data(), messageLength * sizeof(char16_t));
Firmware[UserSettings+0x50] = messageLength;
}
void Reset()
{
if (Firmware) delete[] Firmware;
Firmware = NULL;
if (NDS::ConsoleType == 1)
strncpy(FirmwarePath, Config::DSiFirmwarePath, 1023);
else
strncpy(FirmwarePath, Config::FirmwarePath, 1023);
FILE* f = Platform::OpenLocalFile(FirmwarePath, "rb");
if (!f)
{
printf("Firmware not found generating default one.\n");
LoadDefaultFirmware();
}
else
{
LoadFirmwareFromFile(f);
}
FirmwareMask = FirmwareLength - 1;
@ -186,6 +236,26 @@ void Reset()
*(u16*)&Firmware[userdata+0x72] = CRC16(&Firmware[userdata], 0x70, 0xFFFF);
if (Config::RandomizeMAC)
{
if (!f || Config::FirmwareOverrideSettings)
LoadUserSettingsFromConfig();
// fix touchscreen coords
*(u16*)&Firmware[userdata+0x58] = 0;
*(u16*)&Firmware[userdata+0x5A] = 0;
Firmware[userdata+0x5C] = 0;
Firmware[userdata+0x5D] = 0;
*(u16*)&Firmware[userdata+0x5E] = 255<<4;
*(u16*)&Firmware[userdata+0x60] = 191<<4;
Firmware[userdata+0x62] = 255;
Firmware[userdata+0x63] = 191;
// disable autoboot
//Firmware[userdata+0x64] &= 0xBF;
*(u16*)&Firmware[userdata+0x72] = CRC16(&Firmware[userdata], 0x70, 0xFFFF);
if (Config::RandomizeMAC)
{
// replace MAC address with random address
@ -198,6 +268,7 @@ void Reset()
*(u16*)&Firmware[0x2A] = CRC16(&Firmware[0x2C], *(u16*)&Firmware[0x2C], 0x0000);
}
}
printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
Firmware[0x36], Firmware[0x37], Firmware[0x38],

View File

@ -93,8 +93,8 @@ int VerifyDSBIOS()
long len;
f = Platform::OpenLocalFile(Config::BIOS9Path, "rb");
if (!f) return Load_BIOS9Missing;
if (f)
{
fseek(f, 0, SEEK_END);
len = ftell(f);
if (len != 0x1000)
@ -104,10 +104,15 @@ int VerifyDSBIOS()
}
fclose(f);
}
else
{
printf("Bios ARM9 not found. Proceeding with FreeBIOS.");
}
f = Platform::OpenLocalFile(Config::BIOS7Path, "rb");
if (!f) return Load_BIOS7Missing;
if (f)
{
fseek(f, 0, SEEK_END);
len = ftell(f);
if (len != 0x4000)
@ -117,6 +122,11 @@ int VerifyDSBIOS()
}
fclose(f);
}
else
{
printf("Bios ARM7 not found. Proceeding with FreeBIOS.");
}
return Load_OK;
}
@ -163,7 +173,7 @@ int VerifyDSFirmware()
long len;
f = Platform::OpenLocalFile(Config::FirmwarePath, "rb");
if (!f) return Load_FirmwareMissing;
if (!f) return Load_FirmwareNotBootable;
fseek(f, 0, SEEK_END);
len = ftell(f);

View File

@ -8,6 +8,7 @@ SET(SOURCES_QT_SDL
InputConfigDialog.cpp
VideoSettingsDialog.cpp
AudioSettingsDialog.cpp
FirmwareSettingsDialog.cpp
WifiSettingsDialog.cpp
InterfaceSettingsDialog.cpp
ROMInfoDialog.cpp

View File

@ -19,6 +19,8 @@
#include <stdio.h>
#include <QFileDialog>
#include <QMessageBox>
#include <QList>
#include <QDateEdit>
#include "types.h"
#include "Platform.h"

View File

@ -0,0 +1,72 @@
/*
Copyright 2016-2020 Arisotura
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#include "Config.h"
#include "FirmwareSettingsDialog.h"
#include "ui_FirmwareSettingsDialog.h"
FirmwareSettingsDialog* FirmwareSettingsDialog::currentDlg = nullptr;
FirmwareSettingsDialog::FirmwareSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::FirmwareSettingsDialog)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
ui->usernameEdit->setText(Config::FirmwareUsername);
ui->languageBox->addItems(languages);
ui->languageBox->setCurrentIndex(Config::FirmwareLanguage);
QDate birthDate = QDate(QDate::currentDate().year(), Config::FirmwareBirthdayMonth, Config::FirmwareBirthdayDay);
ui->birthdayEdit->setDate(birthDate);
ui->colorsEdit->addItems(colours);
ui->colorsEdit->setCurrentIndex(Config::FirmwareFavouriteColour);
ui->messageEdit->setText(Config::FirmwareMessage);
ui->overrideFirmwareBox->setChecked(Config::FirmwareOverrideSettings);
}
FirmwareSettingsDialog::~FirmwareSettingsDialog()
{
delete ui;
}
void FirmwareSettingsDialog::on_dialogButtons_accepted()
{
std::string newName = ui->usernameEdit->text().toStdString();
strncpy(Config::FirmwareUsername, newName.c_str(), 63); Config::FirmwareUsername[63] = '\0';
Config::FirmwareLanguage = ui->languageBox->currentIndex();
Config::FirmwareFavouriteColour = ui->colorsEdit->currentIndex();
Config::FirmwareBirthdayDay = ui->birthdayEdit->date().day();
Config::FirmwareBirthdayMonth = ui->birthdayEdit->date().month();
Config::FirmwareOverrideSettings = ui->overrideFirmwareBox->isChecked();
std::string newMessage = ui->messageEdit->text().toStdString();
strncpy(Config::FirmwareMessage, newMessage.c_str(), 1023); Config::FirmwareMessage[1023] = '\0';
Config::Save();
closeDlg();
}
void FirmwareSettingsDialog::on_dialogButtons_rejected()
{
closeDlg();
}

View File

@ -0,0 +1,92 @@
/*
Copyright 2016-2020 Arisotura
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#ifndef FIRMWARESETTINGSDIALOG_H
#define FIRMWARESETTINGSDIALOG_H
#include <QDialog>
#include <QWidget>
namespace Ui { class FirmwareSettingsDialog; }
class FirmwareSettingsDialog;
class FirmwareSettingsDialog : public QDialog
{
Q_OBJECT
public:
const QStringList colours
{
"Greyish Blue",
"Brown",
"Red",
"Light Pink",
"Orange",
"Yellow",
"Lime",
"Light Green",
"Dark Green",
"Turqoise",
"Light Blue",
"Blue",
"Dark Blue",
"Dark Purple",
"Light Purple",
"Dark Pink"
};
const QStringList languages
{
"Japanese",
"English",
"French",
"German",
"Italian",
"Spanish"
};
explicit FirmwareSettingsDialog(QWidget* parent);
~FirmwareSettingsDialog();
static FirmwareSettingsDialog* currentDlg;
static FirmwareSettingsDialog* openDlg(QWidget* parent)
{
if (currentDlg)
{
currentDlg->activateWindow();
return currentDlg;
}
currentDlg = new FirmwareSettingsDialog(parent);
currentDlg->show();
return currentDlg;
}
static void closeDlg()
{
currentDlg = nullptr;
}
private slots:
void on_dialogButtons_accepted();
void on_dialogButtons_rejected();
private:
Ui::FirmwareSettingsDialog* ui;
};
#endif // FIRMWARESETTINGSDIALOG_H

View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FirmwareSettingsDialog</class>
<widget class="QDialog" name="FirmwareSettingsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>511</width>
<height>272</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Firmware settings - melonDS</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="usernameLabel">
<property name="text">
<string>Username</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="usernameEdit">
<property name="text">
<string>MelonDS</string>
</property>
<property name="maxLength">
<number>10</number>
</property>
<property name="clearButtonEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="languageBox"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Birthday</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDateEdit" name="birthdayEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="colorsEdit"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Message</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="messageEdit"/>
</item>
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="overrideFirmwareBox">
<property name="text">
<string>Override firmware settings</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="dialogButtons">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>dialogButtons</sender>
<signal>accepted()</signal>
<receiver>FirmwareSettingsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>255</x>
<y>250</y>
</hint>
<hint type="destinationlabel">
<x>255</x>
<y>135</y>
</hint>
</hints>
</connection>
<connection>
<sender>dialogButtons</sender>
<signal>rejected()</signal>
<receiver>FirmwareSettingsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>255</x>
<y>250</y>
</hint>
<hint type="destinationlabel">
<x>255</x>
<y>135</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -55,6 +55,7 @@
#include "InputConfigDialog.h"
#include "VideoSettingsDialog.h"
#include "AudioSettingsDialog.h"
#include "FirmwareSettingsDialog.h"
#include "WifiSettingsDialog.h"
#include "InterfaceSettingsDialog.h"
#include "ROMInfoDialog.h"
@ -1411,6 +1412,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actInterfaceSettings = menu->addAction("Interface settings");
connect(actInterfaceSettings, &QAction::triggered, this, &MainWindow::onOpenInterfaceSettings);
actFirmwareSettings = menu->addAction("Firmware settings");
connect(actFirmwareSettings, &QAction::triggered, this, &MainWindow::onOpenFirmwareSettings);
{
QMenu* submenu = menu->addMenu("Savestate settings");
@ -2456,6 +2460,14 @@ void MainWindow::onUpdateAudioSettings()
SPU::SetDegrade10Bit(Config::AudioBitrate == 1);
}
void MainWindow::onOpenFirmwareSettings()
{
FirmwareSettingsDialog* dlg = FirmwareSettingsDialog::openDlg(this);
connect(dlg, &FirmwareSettingsDialog::finished, this, &MainWindow::onFirmwareSettingsFinished);
}
void MainWindow::onFirmwareSettingsFinished(int res) {}
void MainWindow::onAudioSettingsFinished(int res)
{
micClose();

View File

@ -257,9 +257,11 @@ private slots:
void onOpenVideoSettings();
void onOpenAudioSettings();
void onUpdateAudioSettings();
void onOpenFirmwareSettings();
void onAudioSettingsFinished(int res);
void onOpenWifiSettings();
void onWifiSettingsFinished(int res);
void onFirmwareSettingsFinished(int res);
void onOpenInterfaceSettings();
void onInterfaceSettingsFinished(int res);
void onUpdateMouseTimer();
@ -331,6 +333,7 @@ public:
QAction* actVideoSettings;
QAction* actAudioSettings;
QAction* actWifiSettings;
QAction* actFirmwareSettings;
QAction* actInterfaceSettings;
QAction* actSavestateSRAMReloc;
QAction* actScreenSize[4];

View File

@ -31,6 +31,14 @@ namespace Config
int DLDIEnable;
char DLDISDPath[1024];
char FirmwareUsername[64];
int FirmwareLanguage;
int FirmwareFavouriteColour;
int FirmwareBirthdayMonth;
int FirmwareBirthdayDay;
char FirmwareMessage[1024];
bool FirmwareOverrideSettings;
char DSiBIOS9Path[1024];
char DSiBIOS7Path[1024];
char DSiFirmwarePath[1024];

View File

@ -568,7 +568,7 @@ bool retro_load_game(const struct retro_game_info *info)
// Abort if there are any of the required roms are missing
if(!missing_roms.empty())
{
std::string msg = "Missing required bios/firmware in system directory: ";
std::string msg = "Missing bios/firmware in system directory. Using FreeBIOS.";
int i = 0;
int len = missing_roms.size();
@ -582,13 +582,12 @@ bool retro_load_game(const struct retro_game_info *info)
msg.append("\n");
log_cb(RETRO_LOG_ERROR, msg.c_str());
return false;
}
strcpy(Config::BIOS7Path, "bios7.bin");
strcpy(Config::BIOS9Path, "bios9.bin");
strcpy(Config::FirmwarePath, "firmware.bin");
strcpy(Config::FirmwareUsername, "MelonDS");
struct retro_input_descriptor desc[] = {
{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left" },
@ -621,6 +620,34 @@ bool retro_load_game(const struct retro_game_info *info)
return false;
}
unsigned language = RETRO_LANGUAGE_ENGLISH;
environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language);
switch(language)
{
case RETRO_LANGUAGE_JAPANESE:
Config::FirmwareLanguage = 0;
break;
case RETRO_LANGUAGE_FRENCH:
Config::FirmwareLanguage = 2;
break;
case RETRO_LANGUAGE_GERMAN:
Config::FirmwareLanguage = 3;
break;
case RETRO_LANGUAGE_ITALIAN:
Config::FirmwareLanguage = 4;
break;
case RETRO_LANGUAGE_SPANISH:
Config::FirmwareLanguage = 5;
break;
default:
Config::FirmwareLanguage = 1; // English
}
check_variables(true);
// Initialize the opengl state if needed