Merge branch 'master' into archive-polishing
This commit is contained in:
commit
29c290f45a
|
@ -21,7 +21,9 @@ jobs:
|
|||
- name: Install dependencies
|
||||
working-directory: ${{runner.workspace}}
|
||||
run: |
|
||||
brew install cmake sdl2 qt5 libslirp libarchive
|
||||
rm -rf /usr/local/bin/2to3 # Temporary workaround suggested here - https://github.com/actions/virtual-environments/issues/2322#issuecomment-749211076
|
||||
brew update
|
||||
brew install sdl2 qt@5 libslirp libarchive
|
||||
- name: Create build environment
|
||||
run: mkdir ${{runner.workspace}}/build
|
||||
- name: Configure
|
||||
|
|
|
@ -86,7 +86,7 @@ If everything went well, melonDS should now be in the `dist` folder.
|
|||
|
||||
### macOS:
|
||||
1. Install the [Homebrew Package Manager](https://brew.sh)
|
||||
2. Install dependencies: `brew install git pkg-config cmake sdl2 qt5 libslirp libarchive`
|
||||
2. Install dependencies: `brew install git pkg-config cmake sdl2 qt@5 libslirp libarchive`
|
||||
3. Compile:
|
||||
```zsh
|
||||
git clone https://github.com/Arisotura/melonDS.git
|
||||
|
|
|
@ -101,8 +101,8 @@ if (ENABLE_JIT)
|
|||
endif()
|
||||
|
||||
if (APPLE)
|
||||
target_include_directories(core PUBLIC /usr/local/include)
|
||||
target_link_directories(core PUBLIC /usr/local/lib)
|
||||
target_include_directories(core PUBLIC /usr/local/include /opt/homebrew/include)
|
||||
target_link_directories(core PUBLIC /usr/local/lib /opt/homebrew/lib)
|
||||
endif()
|
||||
|
||||
if (ENABLE_OGLRENDERER)
|
||||
|
@ -119,4 +119,4 @@ else()
|
|||
else()
|
||||
target_link_libraries(core)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
|
42
src/DSi.cpp
42
src/DSi.cpp
|
@ -74,6 +74,9 @@ DSi_NDMA* NDMAs[8];
|
|||
DSi_SDHost* SDMMC;
|
||||
DSi_SDHost* SDIO;
|
||||
|
||||
FILE* SDMMCFile;
|
||||
FILE* SDIOFile;
|
||||
|
||||
u64 ConsoleID;
|
||||
u8 eMMC_CID[16];
|
||||
|
||||
|
@ -122,6 +125,8 @@ void DeInit()
|
|||
|
||||
delete SDMMC;
|
||||
delete SDIO;
|
||||
|
||||
CloseDSiNAND();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
|
@ -302,12 +307,11 @@ bool LoadNAND()
|
|||
memset(NWRAMEnd, 0, sizeof(NWRAMEnd));
|
||||
memset(NWRAMMask, 0, sizeof(NWRAMMask));
|
||||
|
||||
FILE* f = Platform::OpenLocalFile(Config::DSiNANDPath, "rb");
|
||||
if (f)
|
||||
if (SDMMCFile)
|
||||
{
|
||||
u32 bootparams[8];
|
||||
fseek(f, 0x220, SEEK_SET);
|
||||
fread(bootparams, 4, 8, f);
|
||||
fseek(SDMMCFile, 0x220, SEEK_SET);
|
||||
fread(bootparams, 4, 8, SDMMCFile);
|
||||
|
||||
printf("ARM9: offset=%08X size=%08X RAM=%08X size_aligned=%08X\n",
|
||||
bootparams[0], bootparams[1], bootparams[2], bootparams[3]);
|
||||
|
@ -320,8 +324,8 @@ bool LoadNAND()
|
|||
MBK[1][8] = 0;
|
||||
|
||||
u32 mbk[12];
|
||||
fseek(f, 0x380, SEEK_SET);
|
||||
fread(mbk, 4, 12, f);
|
||||
fseek(SDMMCFile, 0x380, SEEK_SET);
|
||||
fread(mbk, 4, 12, SDMMCFile);
|
||||
|
||||
MapNWRAM_A(0, mbk[0] & 0xFF);
|
||||
MapNWRAM_A(1, (mbk[0] >> 8) & 0xFF);
|
||||
|
@ -375,12 +379,12 @@ bool LoadNAND()
|
|||
|
||||
AES_init_ctx_iv(&ctx, boot2key, boot2iv);
|
||||
|
||||
fseek(f, bootparams[0], SEEK_SET);
|
||||
fseek(SDMMCFile, bootparams[0], SEEK_SET);
|
||||
dstaddr = bootparams[2];
|
||||
for (u32 i = 0; i < bootparams[3]; i += 16)
|
||||
{
|
||||
u8 data[16];
|
||||
fread(data, 16, 1, f);
|
||||
fread(data, 16, 1, SDMMCFile);
|
||||
|
||||
for (int j = 0; j < 16; j++) tmp[j] = data[15-j];
|
||||
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
|
||||
|
@ -400,12 +404,12 @@ bool LoadNAND()
|
|||
|
||||
AES_init_ctx_iv(&ctx, boot2key, boot2iv);
|
||||
|
||||
fseek(f, bootparams[4], SEEK_SET);
|
||||
fseek(SDMMCFile, bootparams[4], SEEK_SET);
|
||||
dstaddr = bootparams[6];
|
||||
for (u32 i = 0; i < bootparams[7]; i += 16)
|
||||
{
|
||||
u8 data[16];
|
||||
fread(data, 16, 1, f);
|
||||
fread(data, 16, 1, SDMMCFile);
|
||||
|
||||
for (int j = 0; j < 16; j++) tmp[j] = data[15-j];
|
||||
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
|
||||
|
@ -427,25 +431,22 @@ bool LoadNAND()
|
|||
|
||||
// read the nocash footer
|
||||
|
||||
fseek(f, -0x40, SEEK_END);
|
||||
fseek(SDMMCFile, -0x40, SEEK_END);
|
||||
|
||||
char nand_footer[16];
|
||||
const char* nand_footer_ref = "DSi eMMC CID/CPU";
|
||||
fread(nand_footer, 1, 16, f);
|
||||
fread(nand_footer, 1, 16, SDMMCFile);
|
||||
if (memcmp(nand_footer, nand_footer_ref, 16))
|
||||
{
|
||||
printf("ERROR: NAND missing nocash footer\n");
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
fread(eMMC_CID, 1, 16, f);
|
||||
fread(&ConsoleID, 1, 8, f);
|
||||
fread(eMMC_CID, 1, 16, SDMMCFile);
|
||||
fread(&ConsoleID, 1, 8, SDMMCFile);
|
||||
|
||||
printf("eMMC CID: "); printhex(eMMC_CID, 16);
|
||||
printf("Console ID: %016llX\n", ConsoleID);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
memset(ITCMInit, 0, 0x8000);
|
||||
|
@ -463,6 +464,13 @@ bool LoadNAND()
|
|||
return true;
|
||||
}
|
||||
|
||||
void CloseDSiNAND()
|
||||
{
|
||||
if (DSi::SDMMCFile)
|
||||
fclose(DSi::SDMMCFile);
|
||||
if (DSi::SDIOFile)
|
||||
fclose(DSi::SDIOFile);
|
||||
}
|
||||
|
||||
void RunNDMAs(u32 cpu)
|
||||
{
|
||||
|
|
|
@ -36,6 +36,9 @@ extern u64 ConsoleID;
|
|||
extern DSi_SDHost* SDMMC;
|
||||
extern DSi_SDHost* SDIO;
|
||||
|
||||
extern FILE* SDMMCFile;
|
||||
extern FILE* SDIOFile;
|
||||
|
||||
const u32 NWRAMSize = 0x40000;
|
||||
|
||||
extern u8* NWRAM_A;
|
||||
|
@ -59,6 +62,8 @@ void SoftReset();
|
|||
bool LoadBIOS();
|
||||
bool LoadNAND();
|
||||
|
||||
void CloseDSiNAND();
|
||||
|
||||
void RunNDMAs(u32 cpu);
|
||||
void StallNDMAs();
|
||||
bool NDMAsInMode(u32 cpu, u32 mode);
|
||||
|
|
|
@ -114,14 +114,14 @@ void DSi_SDHost::Reset()
|
|||
|
||||
if (Config::DSiSDEnable)
|
||||
{
|
||||
sd = new DSi_MMCStorage(this, false, Config::DSiSDPath);
|
||||
sd = new DSi_MMCStorage(this, false, DSi::SDIOFile);
|
||||
u8 sd_cid[16] = {0xBD, 0x12, 0x34, 0x56, 0x78, 0x03, 0x4D, 0x30, 0x30, 0x46, 0x50, 0x41, 0x00, 0x00, 0x15, 0x00};
|
||||
sd->SetCID(sd_cid);
|
||||
}
|
||||
else
|
||||
sd = nullptr;
|
||||
|
||||
mmc = new DSi_MMCStorage(this, true, Config::DSiNANDPath);
|
||||
mmc = new DSi_MMCStorage(this, true, DSi::SDMMCFile);
|
||||
mmc->SetCID(DSi::eMMC_CID);
|
||||
|
||||
Ports[0] = sd;
|
||||
|
@ -706,30 +706,14 @@ void DSi_SDHost::CheckSwapFIFO()
|
|||
|
||||
#define MMC_DESC (Internal?"NAND":"SDcard")
|
||||
|
||||
DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path) : DSi_SDDevice(host)
|
||||
DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, FILE* file) : DSi_SDDevice(host)
|
||||
{
|
||||
Internal = internal;
|
||||
strncpy(FilePath, path, 1023); FilePath[1023] = '\0';
|
||||
|
||||
File = Platform::OpenLocalFile(path, "r+b");
|
||||
if (!File)
|
||||
{
|
||||
if (internal)
|
||||
{
|
||||
// TODO: proper failure
|
||||
printf("!! MMC file %s does not exist\n", path);
|
||||
}
|
||||
else
|
||||
{
|
||||
File = Platform::OpenLocalFile(path, "w+b");
|
||||
}
|
||||
}
|
||||
File = file;
|
||||
}
|
||||
|
||||
DSi_MMCStorage::~DSi_MMCStorage()
|
||||
{
|
||||
if (File) fclose(File);
|
||||
}
|
||||
{}
|
||||
|
||||
void DSi_MMCStorage::Reset()
|
||||
{
|
||||
|
|
|
@ -120,7 +120,7 @@ protected:
|
|||
class DSi_MMCStorage : public DSi_SDDevice
|
||||
{
|
||||
public:
|
||||
DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path);
|
||||
DSi_MMCStorage(DSi_SDHost* host, bool internal, FILE* file);
|
||||
~DSi_MMCStorage();
|
||||
|
||||
void Reset();
|
||||
|
@ -134,7 +134,6 @@ public:
|
|||
|
||||
private:
|
||||
bool Internal;
|
||||
char FilePath[1024];
|
||||
FILE* File;
|
||||
|
||||
u8 CID[16];
|
||||
|
|
|
@ -65,7 +65,7 @@ struct
|
|||
float uFogDensity[34][4]; // float[34] 168 / 136
|
||||
u32 uFogOffset; // int 304 / 1
|
||||
u32 uFogShift; // int 305 / 1
|
||||
|
||||
u32 _pad1[2]; // int 306 / 2
|
||||
} ShaderConfig;
|
||||
|
||||
GLuint ShaderConfigUBO;
|
||||
|
@ -284,7 +284,8 @@ bool Init()
|
|||
|
||||
glGenBuffers(1, &ShaderConfigUBO);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, ShaderConfigUBO);
|
||||
glBufferData(GL_UNIFORM_BUFFER, (sizeof(ShaderConfig) + 15) & ~15, &ShaderConfig, GL_STATIC_DRAW);
|
||||
static_assert((sizeof(ShaderConfig) & 15) == 0);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(ShaderConfig), &ShaderConfig, GL_STATIC_DRAW);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, ShaderConfigUBO);
|
||||
|
||||
|
||||
|
|
|
@ -123,7 +123,8 @@ void EnableCheats(bool enable);
|
|||
// 2 = emphasize bottom screen
|
||||
// * screenGap: size of the gap between the two screens
|
||||
// * integerScale: force screens to be scaled up at integer scaling factors
|
||||
void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int rotation, int sizing, int screenGap, bool integerScale);
|
||||
// * screenSwap: whether to swap the position of both screens
|
||||
void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int rotation, int sizing, int screenGap, bool integerScale, int swapScreens);
|
||||
|
||||
// get a 2x3 transform matrix for each screen
|
||||
// note: the transform assumes an origin point at the top left of the display,
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "Platform.h"
|
||||
|
||||
#include "NDS.h"
|
||||
#include "DSi.h"
|
||||
#include "GBACart.h"
|
||||
|
||||
#include "AREngine.h"
|
||||
|
@ -202,18 +203,27 @@ int VerifyDSiFirmware()
|
|||
return Load_OK;
|
||||
}
|
||||
|
||||
int VerifyDSiNAND()
|
||||
int SetupDSiNAND()
|
||||
{
|
||||
FILE* f;
|
||||
long len;
|
||||
|
||||
f = Platform::OpenLocalFile(Config::DSiNANDPath, "rb");
|
||||
f = Platform::OpenLocalFile(Config::DSiNANDPath, "r+b");
|
||||
if (!f) return Load_DSiNANDMissing;
|
||||
|
||||
// TODO: some basic checks
|
||||
// check that it has the nocash footer, and all
|
||||
|
||||
fclose(f);
|
||||
DSi::SDMMCFile = f;
|
||||
|
||||
if (Config::DSiSDEnable)
|
||||
{
|
||||
f = Platform::OpenLocalFile(Config::DSiSDPath, "r+b");
|
||||
if (f)
|
||||
DSi::SDIOFile = f;
|
||||
else
|
||||
DSi::SDIOFile = Platform::OpenLocalFile(Config::DSiSDPath, "w+b");
|
||||
}
|
||||
|
||||
return Load_OK;
|
||||
}
|
||||
|
@ -246,6 +256,8 @@ void LoadCheats()
|
|||
|
||||
int LoadBIOS()
|
||||
{
|
||||
DSi::CloseDSiNAND();
|
||||
|
||||
int res;
|
||||
|
||||
res = VerifyDSBIOS();
|
||||
|
@ -259,7 +271,7 @@ int LoadBIOS()
|
|||
res = VerifyDSiFirmware();
|
||||
if (res != Load_OK) return res;
|
||||
|
||||
res = VerifyDSiNAND();
|
||||
res = SetupDSiNAND();
|
||||
if (res != Load_OK) return res;
|
||||
}
|
||||
else
|
||||
|
@ -366,6 +378,8 @@ int LoadROM(const u8 *romdata, u32 romlength, const char *archivefilename, const
|
|||
|
||||
int LoadROM(const char* file, int slot)
|
||||
{
|
||||
DSi::CloseDSiNAND();
|
||||
|
||||
int res;
|
||||
bool directboot = Config::DirectBoot != 0;
|
||||
|
||||
|
@ -386,7 +400,7 @@ int LoadROM(const char* file, int slot)
|
|||
res = VerifyDSiFirmware();
|
||||
if (res != Load_OK) return res;
|
||||
|
||||
res = VerifyDSiNAND();
|
||||
res = SetupDSiNAND();
|
||||
if (res != Load_OK) return res;
|
||||
|
||||
GBACart::Eject();
|
||||
|
@ -457,10 +471,14 @@ void UnloadROM(int slot)
|
|||
}
|
||||
|
||||
ROMPath[slot][0] = '\0';
|
||||
|
||||
DSi::CloseDSiNAND();
|
||||
}
|
||||
|
||||
int Reset()
|
||||
{
|
||||
DSi::CloseDSiNAND();
|
||||
|
||||
int res;
|
||||
bool directboot = Config::DirectBoot != 0;
|
||||
|
||||
|
@ -475,7 +493,7 @@ int Reset()
|
|||
res = VerifyDSiFirmware();
|
||||
if (res != Load_OK) return res;
|
||||
|
||||
res = VerifyDSiNAND();
|
||||
res = SetupDSiNAND();
|
||||
if (res != Load_OK) return res;
|
||||
|
||||
GBACart::Eject();
|
||||
|
|
|
@ -109,7 +109,7 @@ void M23_Transform(float* m, float& x, float& y)
|
|||
}
|
||||
|
||||
|
||||
void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int rotation, int sizing, int screenGap, bool integerScale)
|
||||
void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int rotation, int sizing, int screenGap, bool integerScale, int swapScreens)
|
||||
{
|
||||
float refpoints[4][2] =
|
||||
{
|
||||
|
@ -152,7 +152,7 @@ void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int
|
|||
(((layout == 0 && (rotation % 2 == 0)) || (layout == 1 && (rotation % 2 == 1))
|
||||
? 192.f : 256.f)
|
||||
+ screenGap) / 2.f;
|
||||
if (rotation == 1 || rotation == 2)
|
||||
if ((rotation == 1 || rotation == 2) ^ swapScreens)
|
||||
offset *= -1.f;
|
||||
|
||||
M23_Translate(TopScreenMtx, (idx==0)?-offset:0, (idx==1)?-offset:0);
|
||||
|
|
|
@ -39,6 +39,7 @@ int WindowMaximized;
|
|||
int ScreenRotation;
|
||||
int ScreenGap;
|
||||
int ScreenLayout;
|
||||
int ScreenSwap;
|
||||
int ScreenSizing;
|
||||
int IntegerScaling;
|
||||
int ScreenFilter;
|
||||
|
@ -135,6 +136,7 @@ ConfigEntry PlatformConfigFile[] =
|
|||
{"ScreenRotation", 0, &ScreenRotation, 0, NULL, 0},
|
||||
{"ScreenGap", 0, &ScreenGap, 0, NULL, 0},
|
||||
{"ScreenLayout", 0, &ScreenLayout, 0, NULL, 0},
|
||||
{"ScreenSwap", 0, &ScreenSwap, 0, NULL, 0},
|
||||
{"ScreenSizing", 0, &ScreenSizing, 0, NULL, 0},
|
||||
{"IntegerScaling", 0, &IntegerScaling, 0, NULL, 0},
|
||||
{"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0},
|
||||
|
|
|
@ -53,6 +53,7 @@ extern int WindowMaximized;
|
|||
extern int ScreenRotation;
|
||||
extern int ScreenGap;
|
||||
extern int ScreenLayout;
|
||||
extern int ScreenSwap;
|
||||
extern int ScreenSizing;
|
||||
extern int IntegerScaling;
|
||||
extern int ScreenFilter;
|
||||
|
|
|
@ -647,7 +647,8 @@ void ScreenHandler::screenSetupLayout(int w, int h)
|
|||
Config::ScreenRotation,
|
||||
sizing,
|
||||
Config::ScreenGap,
|
||||
Config::IntegerScaling != 0);
|
||||
Config::IntegerScaling != 0,
|
||||
Config::ScreenSwap != 0);
|
||||
|
||||
Frontend::GetScreenTransforms(screenMatrix[0], screenMatrix[1]);
|
||||
}
|
||||
|
@ -1232,6 +1233,12 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
|
|||
}
|
||||
|
||||
connect(grpScreenLayout, &QActionGroup::triggered, this, &MainWindow::onChangeScreenLayout);
|
||||
|
||||
submenu->addSeparator();
|
||||
|
||||
actScreenSwap = submenu->addAction("Swap screens");
|
||||
actScreenSwap->setCheckable(true);
|
||||
connect(actScreenSwap, &QAction::triggered, this, &MainWindow::onChangeScreenSwap);
|
||||
}
|
||||
{
|
||||
QMenu* submenu = menu->addMenu("Screen sizing");
|
||||
|
@ -1315,6 +1322,8 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
|
|||
actScreenSizing[Config::ScreenSizing]->setChecked(true);
|
||||
actIntegerScaling->setChecked(Config::IntegerScaling != 0);
|
||||
|
||||
actScreenSwap->setChecked(Config::ScreenSwap != 0);
|
||||
|
||||
actScreenFiltering->setChecked(Config::ScreenFilter != 0);
|
||||
actShowOSD->setChecked(Config::ShowOSD != 0);
|
||||
|
||||
|
@ -2163,6 +2172,13 @@ void MainWindow::onChangeScreenLayout(QAction* act)
|
|||
emit screenLayoutChange();
|
||||
}
|
||||
|
||||
void MainWindow::onChangeScreenSwap(bool checked)
|
||||
{
|
||||
Config::ScreenSwap = checked?1:0;
|
||||
|
||||
emit screenLayoutChange();
|
||||
}
|
||||
|
||||
void MainWindow::onChangeScreenSizing(QAction* act)
|
||||
{
|
||||
int sizing = act->data().toInt();
|
||||
|
|
|
@ -222,6 +222,7 @@ private slots:
|
|||
void onChangeScreenRotation(QAction* act);
|
||||
void onChangeScreenGap(QAction* act);
|
||||
void onChangeScreenLayout(QAction* act);
|
||||
void onChangeScreenSwap(bool checked);
|
||||
void onChangeScreenSizing(QAction* act);
|
||||
void onChangeIntegerScaling(bool checked);
|
||||
void onChangeScreenFiltering(bool checked);
|
||||
|
@ -282,6 +283,7 @@ public:
|
|||
QAction* actScreenGap[6];
|
||||
QActionGroup* grpScreenLayout;
|
||||
QAction* actScreenLayout[3];
|
||||
QAction* actScreenSwap;
|
||||
QActionGroup* grpScreenSizing;
|
||||
QAction* actScreenSizing[4];
|
||||
QAction* actIntegerScaling;
|
||||
|
|
Loading…
Reference in New Issue