Merge remote-tracking branch 'upstream/master' into jump-after-writeback

This commit is contained in:
Jaklyy 2024-07-03 15:26:58 -04:00
commit 0060958fed
231 changed files with 17051 additions and 5250 deletions

View File

@ -5,6 +5,7 @@
<a href="http://melonds.kuribo64.net/downloads.php" alt="Release: 0.9.5"><img src="https://img.shields.io/badge/release-0.9.5-%235c913b.svg"></a> <a href="http://melonds.kuribo64.net/downloads.php" alt="Release: 0.9.5"><img src="https://img.shields.io/badge/release-0.9.5-%235c913b.svg"></a>
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-%23ff554d.svg"></a> <a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-%23ff554d.svg"></a>
<a href="https://kiwiirc.com/client/irc.badnik.net/?nick=IRC-Source_?#melonds" alt="IRC channel: #melonds"><img src="https://img.shields.io/badge/IRC%20chat-%23melonds-%23dd2e44.svg"></a> <a href="https://kiwiirc.com/client/irc.badnik.net/?nick=IRC-Source_?#melonds" alt="IRC channel: #melonds"><img src="https://img.shields.io/badge/IRC%20chat-%23melonds-%23dd2e44.svg"></a>
<a href="https://discord.gg/pAMAtExcqV" alt="Discord"><img src="https://img.shields.io/badge/Discord-Kuribo64-7289da?logo=discord&logoColor=white"></a>
<br> <br>
<a href="https://github.com/melonDS-emu/melonDS/actions/workflows/build-windows.yml?query=event%3Apush"><img src="https://github.com/melonDS-emu/melonDS/actions/workflows/build-windows.yml/badge.svg" /></a> <a href="https://github.com/melonDS-emu/melonDS/actions/workflows/build-windows.yml?query=event%3Apush"><img src="https://github.com/melonDS-emu/melonDS/actions/workflows/build-windows.yml/badge.svg" /></a>
<a href="https://github.com/melonDS-emu/melonDS/actions/workflows/build-ubuntu.yml?query=event%3Apush"><img src="https://github.com/melonDS-emu/melonDS/actions/workflows/build-ubuntu.yml/badge.svg" /></a> <a href="https://github.com/melonDS-emu/melonDS/actions/workflows/build-ubuntu.yml?query=event%3Apush"><img src="https://github.com/melonDS-emu/melonDS/actions/workflows/build-ubuntu.yml/badge.svg" /></a>

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team, RSDuck Copyright 2016-2024 melonDS team, RSDuck
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -133,6 +133,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.h.in" "${CMAKE_CURRENT_BINAR
target_sources(core PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/version.h") target_sources(core PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/version.h")
target_include_directories(core PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") target_include_directories(core PUBLIC "${CMAKE_CURRENT_BINARY_DIR}")
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(teakra EXCLUDE_FROM_ALL) add_subdirectory(teakra EXCLUDE_FROM_ALL)
# Workaround for building teakra with -O0 on Windows either failing or hanging forever # Workaround for building teakra with -O0 on Windows either failing or hanging forever
target_compile_options(teakra PRIVATE "$<$<CONFIG:DEBUG>:-Og>") target_compile_options(teakra PRIVATE "$<$<CONFIG:DEBUG>:-Og>")
@ -140,7 +141,9 @@ target_link_libraries(core PRIVATE teakra)
if (NOT MSVC) if (NOT MSVC)
# MSVC has its own compiler flag syntax; if we ever support it, # MSVC has its own compiler flag syntax; if we ever support it,
# be sure to silence any equivalent warnings there. # be sure to add equivalent flags here.
target_compile_options(core PUBLIC -fwrapv)
target_compile_options(core PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>") target_compile_options(core PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>")
# These warnings are excessive, and are only triggered in the ARMJIT code # These warnings are excessive, and are only triggered in the ARMJIT code

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -70,8 +70,28 @@ const u32 NDMAModes[] =
0xFF, // wifi / GBA cart slot (TODO) 0xFF, // wifi / GBA cart slot (TODO)
}; };
DSi::DSi(DSiArgs&& args) noexcept : /*DSi::DSi() noexcept :
NDS(std::move(args), 1), DSi(
DSiArgs {
NDSArgs {
nullptr,
nullptr,
bios_arm9_bin,
bios_arm7_bin,
Firmware(0),
},
nullptr,
nullptr,
nullptr,
nullptr,
false
}
)
{
}*/
DSi::DSi(DSiArgs&& args, void* userdata) noexcept :
NDS(std::move(args), 1, userdata),
NDMAs { NDMAs {
DSi_NDMA(0, 0, *this), DSi_NDMA(0, 0, *this),
DSi_NDMA(0, 1, *this), DSi_NDMA(0, 1, *this),

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -131,7 +131,8 @@ public:
void ARM7IOWrite32(u32 addr, u32 val) override; void ARM7IOWrite32(u32 addr, u32 val) override;
public: public:
DSi(DSiArgs&& args) noexcept; DSi(DSiArgs&& args, void* userdata = nullptr) noexcept;
//DSi() noexcept;
~DSi() noexcept override; ~DSi() noexcept override;
DSi(const DSi&) = delete; DSi(const DSi&) = delete;
DSi& operator=(const DSi&) = delete; DSi& operator=(const DSi&) = delete;

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -410,7 +410,7 @@ void DSi_Camera::DoSavestate(Savestate* file)
void DSi_Camera::Reset() void DSi_Camera::Reset()
{ {
Platform::Camera_Stop(Num); Platform::Camera_Stop(Num, DSi.UserData);
DataPos = 0; DataPos = 0;
RegAddr = 0; RegAddr = 0;
@ -435,7 +435,7 @@ void DSi_Camera::Reset()
void DSi_Camera::Stop() void DSi_Camera::Stop()
{ {
Platform::Camera_Stop(Num); Platform::Camera_Stop(Num, DSi.UserData);
} }
bool DSi_Camera::IsActivated() const bool DSi_Camera::IsActivated() const
@ -474,7 +474,7 @@ void DSi_Camera::StartTransfer()
FrameFormat = 0; FrameFormat = 0;
} }
Platform::Camera_CaptureFrame(Num, FrameBuffer, 640, 480, true); Platform::Camera_CaptureFrame(Num, FrameBuffer, 640, 480, true, DSi.UserData);
} }
bool DSi_Camera::TransferDone() const bool DSi_Camera::TransferDone() const
@ -655,8 +655,8 @@ void DSi_Camera::I2C_WriteReg(u16 addr, u16 val)
StandbyCnt = val; StandbyCnt = val;
//printf("CAM%d STBCNT=%04X (%04X)\n", Num, StandbyCnt, val); //printf("CAM%d STBCNT=%04X (%04X)\n", Num, StandbyCnt, val);
bool isactive = IsActivated(); bool isactive = IsActivated();
if (isactive && !wasactive) Platform::Camera_Start(Num); if (isactive && !wasactive) Platform::Camera_Start(Num, DSi.UserData);
else if (wasactive && !isactive) Platform::Camera_Stop(Num); else if (wasactive && !isactive) Platform::Camera_Stop(Num, DSi.UserData);
} }
return; return;
case 0x001A: case 0x001A:
@ -665,8 +665,8 @@ void DSi_Camera::I2C_WriteReg(u16 addr, u16 val)
MiscCnt = val & 0x0B7B; MiscCnt = val & 0x0B7B;
//printf("CAM%d MISCCNT=%04X (%04X)\n", Num, MiscCnt, val); //printf("CAM%d MISCCNT=%04X (%04X)\n", Num, MiscCnt, val);
bool isactive = IsActivated(); bool isactive = IsActivated();
if (isactive && !wasactive) Platform::Camera_Start(Num); if (isactive && !wasactive) Platform::Camera_Start(Num, DSi.UserData);
else if (wasactive && !isactive) Platform::Camera_Stop(Num); else if (wasactive && !isactive) Platform::Camera_Stop(Num, DSi.UserData);
} }
return; return;

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -1334,7 +1334,7 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
} }
printf("\n");*/ printf("\n");*/
Platform::LAN_SendPacket(LANBuffer, lan_len); Platform::Net_SendPacket(LANBuffer, lan_len, DSi.UserData);
} }
void DSi_NWifi::SendWMIEvent(u8 ep, u16 id, u8* data, u32 len) void DSi_NWifi::SendWMIEvent(u8 ep, u16 id, u8* data, u32 len)
@ -1442,20 +1442,26 @@ void DSi_NWifi::CheckRX()
if (!Mailbox[8].CanFit(2048)) if (!Mailbox[8].CanFit(2048))
return; return;
int rxlen = Platform::LAN_RecvPacket(LANBuffer); int rxlen = Platform::Net_RecvPacket(LANBuffer, DSi.UserData);
if (rxlen > 0) while (rxlen > 0)
{ {
//printf("WMI packet recv %04X %04X %04X\n", *(u16*)&LANBuffer[0], *(u16*)&LANBuffer[2], *(u16*)&LANBuffer[4]); //printf("WMI packet recv %04X %04X %04X\n", *(u16*)&LANBuffer[0], *(u16*)&LANBuffer[2], *(u16*)&LANBuffer[4]);
// check destination MAC // check destination MAC
if (*(u32*)&LANBuffer[0] != 0xFFFFFFFF || *(u16*)&LANBuffer[4] != 0xFFFF) if (*(u32*)&LANBuffer[0] != 0xFFFFFFFF || *(u16*)&LANBuffer[4] != 0xFFFF)
{ {
if (memcmp(&LANBuffer[0], &EEPROM[0x00A], 6)) if (memcmp(&LANBuffer[0], &EEPROM[0x00A], 6))
return; {
rxlen = Platform::Net_RecvPacket(LANBuffer, DSi.UserData);
continue;
}
} }
// check source MAC, in case we get a packet we just sent out // check source MAC, in case we get a packet we just sent out
if (!memcmp(&LANBuffer[6], &EEPROM[0x00A], 6)) if (!memcmp(&LANBuffer[6], &EEPROM[0x00A], 6))
return; {
rxlen = Platform::Net_RecvPacket(LANBuffer, DSi.UserData);
continue;
}
// packet is good // packet is good

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -24,6 +24,7 @@
namespace melonDS namespace melonDS
{ {
template<typename T, u32 NumEntries> template<typename T, u32 NumEntries>
class FIFO class FIFO
{ {
@ -191,5 +192,121 @@ private:
u32 ReadPos, WritePos; u32 ReadPos, WritePos;
}; };
template<u32 Size>
class RingBuffer
{
public:
void Clear()
{
NumOccupied = 0;
ReadPos = 0;
WritePos = 0;
memset(Buffer, 0, Size);
}
void DoSavestate(Savestate* file)
{
file->Var32(&NumOccupied);
file->Var32(&ReadPos);
file->Var32(&WritePos);
file->VarArray(Buffer, Size);
}
bool Write(const void* data, u32 len)
{
if (!CanFit(len)) return false;
if ((WritePos + len) >= Size)
{
u32 part1 = Size - WritePos;
memcpy(&Buffer[WritePos], data, part1);
if (len > part1)
memcpy(Buffer, &((u8*)data)[part1], len - part1);
WritePos = len - part1;
}
else
{
memcpy(&Buffer[WritePos], data, len);
WritePos += len;
}
NumOccupied += len;
return true;
}
bool Read(void* data, u32 len)
{
if (NumOccupied < len) return false;
u32 readpos = ReadPos;
if ((readpos + len) >= Size)
{
u32 part1 = Size - readpos;
memcpy(data, &Buffer[readpos], part1);
if (len > part1)
memcpy(&((u8*)data)[part1], Buffer, len - part1);
ReadPos = len - part1;
}
else
{
memcpy(data, &Buffer[readpos], len);
ReadPos += len;
}
NumOccupied -= len;
return true;
}
bool Peek(void* data, u32 offset, u32 len)
{
if (NumOccupied < len) return false;
u32 readpos = ReadPos + offset;
if (readpos >= Size) readpos -= Size;
if ((readpos + len) >= Size)
{
u32 part1 = Size - readpos;
memcpy(data, &Buffer[readpos], part1);
if (len > part1)
memcpy(&((u8*)data)[part1], Buffer, len - part1);
}
else
{
memcpy(data, &Buffer[readpos], len);
}
return true;
}
bool Skip(u32 len)
{
if (NumOccupied < len) return false;
ReadPos += len;
if (ReadPos >= Size)
ReadPos -= Size;
NumOccupied -= len;
return true;
}
u32 Level() const { return NumOccupied; }
bool IsEmpty() const { return NumOccupied == 0; }
bool IsFull() const { return NumOccupied >= Size; }
bool CanFit(u32 num) const { return ((NumOccupied + num) <= Size); }
private:
u8 Buffer[Size] = {0};
u32 NumOccupied = 0;
u32 ReadPos = 0, WritePos = 0;
};
} }
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -95,17 +95,18 @@ u32 CartCommon::GetSaveMemoryLength() const
return 0; return 0;
} }
CartGame::CartGame(const u8* rom, u32 len, const u8* sram, u32 sramlen, GBACart::CartType type) : CartGame::CartGame(const u8* rom, u32 len, const u8* sram, u32 sramlen, void* userdata, GBACart::CartType type) :
CartGame(CopyToUnique(rom, len), len, CopyToUnique(sram, sramlen), sramlen, type) CartGame(CopyToUnique(rom, len), len, CopyToUnique(sram, sramlen), sramlen, userdata, type)
{ {
} }
CartGame::CartGame(std::unique_ptr<u8[]>&& rom, u32 len, std::unique_ptr<u8[]>&& sram, u32 sramlen, GBACart::CartType type) : CartGame::CartGame(std::unique_ptr<u8[]>&& rom, u32 len, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata, GBACart::CartType type) :
CartCommon(type), CartCommon(type),
ROM(std::move(rom)), ROM(std::move(rom)),
ROMLength(len), ROMLength(len),
SRAM(std::move(sram)), SRAM(std::move(sram)),
SRAMLength(sramlen) SRAMLength(sramlen),
UserData(userdata)
{ {
if (SRAM && SRAMLength) if (SRAM && SRAMLength)
{ {
@ -170,7 +171,7 @@ void CartGame::DoSavestate(Savestate* file)
file->Var8((u8*)&SRAMType); file->Var8((u8*)&SRAMType);
if ((!file->Saving) && SRAM) if ((!file->Saving) && SRAM)
Platform::WriteGBASave(SRAM.get(), SRAMLength, 0, SRAMLength); Platform::WriteGBASave(SRAM.get(), SRAMLength, 0, SRAMLength, UserData);
} }
void CartGame::SetupSave(u32 type) void CartGame::SetupSave(u32 type)
@ -223,7 +224,7 @@ void CartGame::SetSaveMemory(const u8* savedata, u32 savelen)
u32 len = std::min(savelen, SRAMLength); u32 len = std::min(savelen, SRAMLength);
memcpy(SRAM.get(), savedata, len); memcpy(SRAM.get(), savedata, len);
Platform::WriteGBASave(savedata, len, 0, len); Platform::WriteGBASave(savedata, len, 0, len, UserData);
} }
u16 CartGame::ROMRead(u32 addr) const u16 CartGame::ROMRead(u32 addr) const
@ -464,7 +465,7 @@ void CartGame::SRAMWrite_FLASH(u32 addr, u8 val)
u32 start_addr = addr + 0x10000 * SRAMFlashState.bank; u32 start_addr = addr + 0x10000 * SRAMFlashState.bank;
memset((u8*)&SRAM[start_addr], 0xFF, 0x1000); memset((u8*)&SRAM[start_addr], 0xFF, 0x1000);
Platform::WriteGBASave(SRAM.get(), SRAMLength, start_addr, 0x1000); Platform::WriteGBASave(SRAM.get(), SRAMLength, start_addr, 0x1000, UserData);
} }
SRAMFlashState.state = 0; SRAMFlashState.state = 0;
SRAMFlashState.cmd = 0; SRAMFlashState.cmd = 0;
@ -523,18 +524,18 @@ void CartGame::SRAMWrite_SRAM(u32 addr, u8 val)
*(u8*)&SRAM[addr] = val; *(u8*)&SRAM[addr] = val;
// TODO: optimize this!! // TODO: optimize this!!
Platform::WriteGBASave(SRAM.get(), SRAMLength, addr, 1); Platform::WriteGBASave(SRAM.get(), SRAMLength, addr, 1, UserData);
} }
} }
CartGameSolarSensor::CartGameSolarSensor(const u8* rom, u32 len, const u8* sram, u32 sramlen) : CartGameSolarSensor::CartGameSolarSensor(const u8* rom, u32 len, const u8* sram, u32 sramlen, void* userdata) :
CartGameSolarSensor(CopyToUnique(rom, len), len, CopyToUnique(sram, sramlen), sramlen) CartGameSolarSensor(CopyToUnique(rom, len), len, CopyToUnique(sram, sramlen), sramlen, userdata)
{ {
} }
CartGameSolarSensor::CartGameSolarSensor(std::unique_ptr<u8[]>&& rom, u32 len, std::unique_ptr<u8[]>&& sram, u32 sramlen) : CartGameSolarSensor::CartGameSolarSensor(std::unique_ptr<u8[]>&& rom, u32 len, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata) :
CartGame(std::move(rom), len, std::move(sram), sramlen, CartType::GameSolarSensor) CartGame(std::move(rom), len, std::move(sram), sramlen, userdata, CartType::GameSolarSensor)
{ {
} }
@ -680,7 +681,7 @@ void CartRAMExpansion::ROMWrite(u32 addr, u16 val)
} }
} }
GBACartSlot::GBACartSlot(std::unique_ptr<CartCommon>&& cart) noexcept : Cart(std::move(cart)) GBACartSlot::GBACartSlot(melonDS::NDS& nds, std::unique_ptr<CartCommon>&& cart) noexcept : NDS(nds), Cart(std::move(cart))
{ {
} }
@ -723,24 +724,24 @@ void GBACartSlot::DoSavestate(Savestate* file) noexcept
if (Cart) Cart->DoSavestate(file); if (Cart) Cart->DoSavestate(file);
} }
std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen) std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, void* userdata)
{ {
return ParseROM(std::move(romdata), romlen, nullptr, 0); return ParseROM(std::move(romdata), romlen, nullptr, 0, userdata);
} }
std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, const u8* sramdata, u32 sramlen) std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, const u8* sramdata, u32 sramlen, void* userdata)
{ {
auto [romcopy, romcopylen] = PadToPowerOf2(romdata, romlen); auto [romcopy, romcopylen] = PadToPowerOf2(romdata, romlen);
return ParseROM(std::move(romcopy), romcopylen, CopyToUnique(sramdata, sramlen), sramlen); return ParseROM(std::move(romcopy), romcopylen, CopyToUnique(sramdata, sramlen), sramlen, userdata);
} }
std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen) std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, void* userdata)
{ {
return ParseROM(romdata, romlen, nullptr, 0); return ParseROM(romdata, romlen, nullptr, 0, userdata);
} }
std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, std::unique_ptr<u8[]>&& sramdata, u32 sramlen) std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, std::unique_ptr<u8[]>&& sramdata, u32 sramlen, void* userdata)
{ {
if (romdata == nullptr) if (romdata == nullptr)
{ {
@ -773,9 +774,9 @@ std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen
std::unique_ptr<CartCommon> cart; std::unique_ptr<CartCommon> cart;
if (solarsensor) if (solarsensor)
cart = std::make_unique<CartGameSolarSensor>(std::move(cartrom), cartromsize, std::move(sramdata), sramlen); cart = std::make_unique<CartGameSolarSensor>(std::move(cartrom), cartromsize, std::move(sramdata), sramlen, userdata);
else else
cart = std::make_unique<CartGame>(std::move(cartrom), cartromsize, std::move(sramdata), sramlen); cart = std::make_unique<CartGame>(std::move(cartrom), cartromsize, std::move(sramdata), sramlen, userdata);
cart->Reset(); cart->Reset();

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -72,8 +72,8 @@ private:
class CartGame : public CartCommon class CartGame : public CartCommon
{ {
public: public:
CartGame(const u8* rom, u32 len, const u8* sram, u32 sramlen, GBACart::CartType type = GBACart::CartType::Game); CartGame(const u8* rom, u32 len, const u8* sram, u32 sramlen, void* userdata, GBACart::CartType type = GBACart::CartType::Game);
CartGame(std::unique_ptr<u8[]>&& rom, u32 len, std::unique_ptr<u8[]>&& sram, u32 sramlen, GBACart::CartType type = GBACart::CartType::Game); CartGame(std::unique_ptr<u8[]>&& rom, u32 len, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata, GBACart::CartType type = GBACart::CartType::Game);
~CartGame() override; ~CartGame() override;
u32 Checksum() const override; u32 Checksum() const override;
@ -104,6 +104,8 @@ protected:
u8 SRAMRead_SRAM(u32 addr); u8 SRAMRead_SRAM(u32 addr);
void SRAMWrite_SRAM(u32 addr, u8 val); void SRAMWrite_SRAM(u32 addr, u8 val);
void* UserData;
std::unique_ptr<u8[]> ROM; std::unique_ptr<u8[]> ROM;
u32 ROMLength; u32 ROMLength;
@ -147,8 +149,8 @@ private:
class CartGameSolarSensor : public CartGame class CartGameSolarSensor : public CartGame
{ {
public: public:
CartGameSolarSensor(const u8* rom, u32 len, const u8* sram, u32 sramlen); CartGameSolarSensor(const u8* rom, u32 len, const u8* sram, u32 sramlen, void* userdata);
CartGameSolarSensor(std::unique_ptr<u8[]>&& rom, u32 len, std::unique_ptr<u8[]>&& sram, u32 sramlen); CartGameSolarSensor(std::unique_ptr<u8[]>&& rom, u32 len, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata);
void Reset() override; void Reset() override;
@ -197,7 +199,7 @@ enum
class GBACartSlot class GBACartSlot
{ {
public: public:
GBACartSlot(std::unique_ptr<CartCommon>&& cart = nullptr) noexcept; GBACartSlot(melonDS::NDS& nds, std::unique_ptr<CartCommon>&& cart = nullptr) noexcept;
~GBACartSlot() noexcept = default; ~GBACartSlot() noexcept = default;
void Reset() noexcept; void Reset() noexcept;
void DoSavestate(Savestate* file) noexcept; void DoSavestate(Savestate* file) noexcept;
@ -258,6 +260,7 @@ public:
/// if a cart is loaded and supports SRAM, otherwise zero. /// if a cart is loaded and supports SRAM, otherwise zero.
[[nodiscard]] u32 GetSaveMemoryLength() const noexcept { return Cart ? Cart->GetSaveMemoryLength() : 0; } [[nodiscard]] u32 GetSaveMemoryLength() const noexcept { return Cart ? Cart->GetSaveMemoryLength() : 0; }
private: private:
melonDS::NDS& NDS;
std::unique_ptr<CartCommon> Cart = nullptr; std::unique_ptr<CartCommon> Cart = nullptr;
u16 OpenBusDecay = 0; u16 OpenBusDecay = 0;
}; };
@ -270,9 +273,9 @@ private:
/// @param romlen The length of the ROM data in bytes. /// @param romlen The length of the ROM data in bytes.
/// @returns A \c GBACart::CartCommon object representing the parsed ROM, /// @returns A \c GBACart::CartCommon object representing the parsed ROM,
/// or \c nullptr if the ROM data couldn't be parsed. /// or \c nullptr if the ROM data couldn't be parsed.
std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen); std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, void* userdata = nullptr);
std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen); std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, void* userdata = nullptr);
std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, const u8* sramdata, u32 sramlen); std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, const u8* sramdata, u32 sramlen, void* userdata = nullptr);
/// @param romdata The ROM data to parse. Will be moved-from. /// @param romdata The ROM data to parse. Will be moved-from.
/// @param romlen Length of romdata in bytes. /// @param romlen Length of romdata in bytes.
@ -282,7 +285,7 @@ std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, const u8* sr
/// May be zero, in which case the cart will have no save data. /// May be zero, in which case the cart will have no save data.
/// @return Unique pointer to the parsed GBA cart, /// @return Unique pointer to the parsed GBA cart,
/// or \c nullptr if there was an error. /// or \c nullptr if there was an error.
std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, std::unique_ptr<u8[]>&& sramdata, u32 sramlen); std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, std::unique_ptr<u8[]>&& sramdata, u32 sramlen, void* userdata = nullptr);
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -254,7 +254,11 @@ void SoftRenderer::DrawScanline(u32 line, Unit* unit)
if (GPU.GPU3D.IsRendererAccelerated()) if (GPU.GPU3D.IsRendererAccelerated())
{ {
dst[256*3] = masterBrightness | (CurUnit->DispCnt & 0x30000); u32 xpos = GPU.GPU3D.GetRenderXPos();
dst[256*3] = masterBrightness |
(CurUnit->DispCnt & 0x30000) |
(xpos << 24) | ((xpos & 0x100) << 15);
return; return;
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2022 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -233,6 +233,7 @@ std::unique_ptr<GLRenderer> GLRenderer::New() noexcept
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(IndexBuffer), nullptr, GL_DYNAMIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(IndexBuffer), nullptr, GL_DYNAMIC_DRAW);
glGenFramebuffers(1, &result->MainFramebuffer); glGenFramebuffers(1, &result->MainFramebuffer);
glGenFramebuffers(1, &result->DownscaleFramebuffer);
// color buffers // color buffers
glGenTextures(1, &result->ColorBufferTex); glGenTextures(1, &result->ColorBufferTex);

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -51,7 +51,6 @@ std::optional<GLCompositor> GLCompositor::New() noexcept
GLCompositor::GLCompositor(GLuint compShader) noexcept : CompShader(compShader) GLCompositor::GLCompositor(GLuint compShader) noexcept : CompShader(compShader)
{ {
CompScaleLoc = glGetUniformLocation(CompShader, "u3DScale"); CompScaleLoc = glGetUniformLocation(CompShader, "u3DScale");
Comp3DXPosLoc = glGetUniformLocation(CompShader, "u3DXPos");
glUseProgram(CompShader); glUseProgram(CompShader);
GLuint screenTextureUniform = glGetUniformLocation(CompShader, "ScreenTex"); GLuint screenTextureUniform = glGetUniformLocation(CompShader, "ScreenTex");
@ -140,7 +139,6 @@ GLCompositor::GLCompositor(GLCompositor&& other) noexcept :
ScreenH(other.ScreenH), ScreenH(other.ScreenH),
ScreenW(other.ScreenW), ScreenW(other.ScreenW),
CompScaleLoc(other.CompScaleLoc), CompScaleLoc(other.CompScaleLoc),
Comp3DXPosLoc(other.Comp3DXPosLoc),
CompVertices(other.CompVertices), CompVertices(other.CompVertices),
CompShader(other.CompShader), CompShader(other.CompShader),
CompVertexBufferID(other.CompVertexBufferID), CompVertexBufferID(other.CompVertexBufferID),
@ -165,7 +163,6 @@ GLCompositor& GLCompositor::operator=(GLCompositor&& other) noexcept
ScreenH = other.ScreenH; ScreenH = other.ScreenH;
ScreenW = other.ScreenW; ScreenW = other.ScreenW;
CompScaleLoc = other.CompScaleLoc; CompScaleLoc = other.CompScaleLoc;
Comp3DXPosLoc = other.Comp3DXPosLoc;
CompVertices = other.CompVertices; CompVertices = other.CompVertices;
// Clean up these resources before overwriting them // Clean up these resources before overwriting them
@ -258,9 +255,6 @@ void GLCompositor::RenderFrame(const GPU& gpu, Renderer3D& renderer) noexcept
glUseProgram(CompShader); glUseProgram(CompShader);
glUniform1ui(CompScaleLoc, Scale); glUniform1ui(CompScaleLoc, Scale);
// TODO: support setting this midframe, if ever needed
glUniform1i(Comp3DXPosLoc, ((int)gpu.GPU3D.GetRenderXPos() << 23) >> 23);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, CompScreenInputTex); glBindTexture(GL_TEXTURE_2D, CompScreenInputTex);

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -52,7 +52,6 @@ private:
GLuint CompShader {}; GLuint CompShader {};
GLuint CompScaleLoc = 0; GLuint CompScaleLoc = 0;
GLuint Comp3DXPosLoc = 0;
GLuint CompVertexBufferID = 0; GLuint CompVertexBufferID = 0;
GLuint CompVertexArrayID = 0; GLuint CompVertexArrayID = 0;

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -43,7 +43,6 @@ void main()
const char* kCompositorFS_Nearest = R"(#version 140 const char* kCompositorFS_Nearest = R"(#version 140
uniform uint u3DScale; uniform uint u3DScale;
uniform int u3DXPos;
uniform usampler2D ScreenTex; uniform usampler2D ScreenTex;
uniform sampler2D _3DTex; uniform sampler2D _3DTex;
@ -56,11 +55,13 @@ void main()
{ {
ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0));
float _3dxpos = float(u3DXPos);
ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0));
int dispmode = mbright.b & 0x3; int dispmode = mbright.b & 0x3;
// mbright.a == HOFS bit0..7
// mbright.b bit7 == HOFS bit8 (sign)
float _3dxpos = float(mbright.a - ((mbright.b & 0x80) * 2));
if (dispmode == 1) if (dispmode == 1)
{ {
ivec4 val1 = pixel; ivec4 val1 = pixel;

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -89,8 +89,9 @@ NDS::NDS() noexcept :
{ {
} }
NDS::NDS(NDSArgs&& args, int type) noexcept : NDS::NDS(NDSArgs&& args, int type, void* userdata) noexcept :
ConsoleType(type), ConsoleType(type),
UserData(userdata),
ARM7BIOS(*args.ARM7BIOS), ARM7BIOS(*args.ARM7BIOS),
ARM9BIOS(*args.ARM9BIOS), ARM9BIOS(*args.ARM9BIOS),
ARM7BIOSNative(CRC32(ARM7BIOS.data(), ARM7BIOS.size()) == ARM7BIOSCRC32), ARM7BIOSNative(CRC32(ARM7BIOS.data(), ARM7BIOS.size()) == ARM7BIOSCRC32),
@ -102,7 +103,7 @@ NDS::NDS(NDSArgs&& args, int type) noexcept :
RTC(*this), RTC(*this),
Wifi(*this), Wifi(*this),
NDSCartSlot(*this, std::move(args.NDSROM)), NDSCartSlot(*this, std::move(args.NDSROM)),
GBACartSlot(type == 1 ? nullptr : std::move(args.GBAROM)), GBACartSlot(*this, type == 1 ? nullptr : std::move(args.GBAROM)),
AREngine(*this), AREngine(*this),
ARM9(*this, args.GDB, args.JIT.has_value()), ARM9(*this, args.GDB, args.JIT.has_value()),
ARM7(*this, args.GDB, args.JIT.has_value()), ARM7(*this, args.GDB, args.JIT.has_value()),
@ -574,7 +575,7 @@ void NDS::Stop(Platform::StopReason reason)
Log(level, "Stopping emulated console (Reason: %s)\n", StopReasonName(reason)); Log(level, "Stopping emulated console (Reason: %s)\n", StopReasonName(reason));
Running = false; Running = false;
Platform::SignalStop(reason); Platform::SignalStop(reason, UserData);
GPU.Stop(); GPU.Stop();
SPU.Stop(); SPU.Stop();
} }
@ -1540,7 +1541,7 @@ void NDS::NocashPrint(u32 ncpu, u32 addr)
} }
output[ptr] = '\0'; output[ptr] = '\0';
Log(LogLevel::Debug, "%s", output); Log(LogLevel::Debug, "%s\n", output);
} }
void NDS::MonitorARM9Jump(u32 addr) void NDS::MonitorARM9Jump(u32 addr)

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -229,6 +229,8 @@ private:
#endif #endif
public: // TODO: Encapsulate the rest of these members public: // TODO: Encapsulate the rest of these members
void* UserData;
int ConsoleType; int ConsoleType;
int CurCPU; int CurCPU;
@ -522,7 +524,7 @@ private:
template <bool EnableJIT> template <bool EnableJIT>
u32 RunFrame(); u32 RunFrame();
public: public:
NDS(NDSArgs&& args) noexcept : NDS(std::move(args), 0) {} NDS(NDSArgs&& args, void* userdata = nullptr) noexcept : NDS(std::move(args), 0, userdata) {}
NDS() noexcept; NDS() noexcept;
virtual ~NDS() noexcept; virtual ~NDS() noexcept;
NDS(const NDS&) = delete; NDS(const NDS&) = delete;
@ -532,7 +534,7 @@ public:
// The frontend should set and unset this manually after creating and destroying the NDS object. // The frontend should set and unset this manually after creating and destroying the NDS object.
[[deprecated("Temporary workaround until JIT code generation is revised to accommodate multiple NDS objects.")]] static NDS* Current; [[deprecated("Temporary workaround until JIT code generation is revised to accommodate multiple NDS objects.")]] static NDS* Current;
protected: protected:
explicit NDS(NDSArgs&& args, int type) noexcept; explicit NDS(NDSArgs&& args, int type, void* userdata) noexcept;
virtual void DoSavestateExtra(Savestate* file) {} virtual void DoSavestateExtra(Savestate* file) {}
}; };

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -173,17 +173,18 @@ void NDSCartSlot::Key2_Encrypt(const u8* data, u32 len) noexcept
} }
CartCommon::CartCommon(const u8* rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, melonDS::NDSCart::CartType type) : CartCommon::CartCommon(const u8* rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, melonDS::NDSCart::CartType type, void* userdata) :
CartCommon(CopyToUnique(rom, len), len, chipid, badDSiDump, romparams, type) CartCommon(CopyToUnique(rom, len), len, chipid, badDSiDump, romparams, type, userdata)
{ {
} }
CartCommon::CartCommon(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, melonDS::NDSCart::CartType type) : CartCommon::CartCommon(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, melonDS::NDSCart::CartType type, void* userdata) :
ROM(std::move(rom)), ROM(std::move(rom)),
ROMLength(len), ROMLength(len),
ChipID(chipid), ChipID(chipid),
ROMParams(romparams), ROMParams(romparams),
CartType(type) CartType(type),
UserData(userdata)
{ {
memcpy(&Header, ROM.get(), sizeof(Header)); memcpy(&Header, ROM.get(), sizeof(Header));
IsDSi = Header.IsDSi() && !badDSiDump; IsDSi = Header.IsDSi() && !badDSiDump;
@ -375,13 +376,13 @@ const NDSBanner* CartCommon::Banner() const
return nullptr; return nullptr;
} }
CartRetail::CartRetail(const u8* rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, melonDS::NDSCart::CartType type) : CartRetail::CartRetail(const u8* rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata, melonDS::NDSCart::CartType type) :
CartRetail(CopyToUnique(rom, len), len, chipid, badDSiDump, romparams, std::move(sram), sramlen, type) CartRetail(CopyToUnique(rom, len), len, chipid, badDSiDump, romparams, std::move(sram), sramlen, userdata, type)
{ {
} }
CartRetail::CartRetail(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, melonDS::NDSCart::CartType type) : CartRetail::CartRetail(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata, melonDS::NDSCart::CartType type) :
CartCommon(std::move(rom), len, chipid, badDSiDump, romparams, type) CartCommon(std::move(rom), len, chipid, badDSiDump, romparams, type, userdata)
{ {
u32 savememtype = ROMParams.SaveMemType <= 10 ? ROMParams.SaveMemType : 0; u32 savememtype = ROMParams.SaveMemType <= 10 ? ROMParams.SaveMemType : 0;
constexpr int sramlengths[] = constexpr int sramlengths[] =
@ -469,7 +470,7 @@ void CartRetail::DoSavestate(Savestate* file)
file->Var8(&SRAMStatus); file->Var8(&SRAMStatus);
if ((!file->Saving) && SRAM) if ((!file->Saving) && SRAM)
Platform::WriteNDSSave(SRAM.get(), SRAMLength, 0, SRAMLength); Platform::WriteNDSSave(SRAM.get(), SRAMLength, 0, SRAMLength, UserData);
} }
void CartRetail::SetSaveMemory(const u8* savedata, u32 savelen) void CartRetail::SetSaveMemory(const u8* savedata, u32 savelen)
@ -478,7 +479,7 @@ void CartRetail::SetSaveMemory(const u8* savedata, u32 savelen)
u32 len = std::min(savelen, SRAMLength); u32 len = std::min(savelen, SRAMLength);
memcpy(SRAM.get(), savedata, len); memcpy(SRAM.get(), savedata, len);
Platform::WriteNDSSave(savedata, len, 0, len); Platform::WriteNDSSave(savedata, len, 0, len, UserData);
} }
int CartRetail::ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, const u8* cmd, u8* data, u32 len) int CartRetail::ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, const u8* cmd, u8* data, u32 len)
@ -594,7 +595,8 @@ u8 CartRetail::SRAMWrite_EEPROMTiny(u8 val, u32 pos, bool last)
{ {
SRAMStatus &= ~(1<<1); SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM.get(), SRAMLength, Platform::WriteNDSSave(SRAM.get(), SRAMLength,
(SRAMFirstAddr + ((SRAMCmd==0x0A)?0x100:0)) & 0x1FF, SRAMAddr-SRAMFirstAddr); (SRAMFirstAddr + ((SRAMCmd==0x0A)?0x100:0)) & 0x1FF, SRAMAddr-SRAMFirstAddr,
UserData);
} }
return 0; return 0;
@ -658,7 +660,8 @@ u8 CartRetail::SRAMWrite_EEPROM(u8 val, u32 pos, bool last)
{ {
SRAMStatus &= ~(1<<1); SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM.get(), SRAMLength, Platform::WriteNDSSave(SRAM.get(), SRAMLength,
SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr); SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr,
UserData);
} }
return 0; return 0;
@ -715,7 +718,8 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
{ {
SRAMStatus &= ~(1<<1); SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM.get(), SRAMLength, Platform::WriteNDSSave(SRAM.get(), SRAMLength,
SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr); SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr,
UserData);
} }
return 0; return 0;
@ -752,7 +756,8 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
{ {
SRAMStatus &= ~(1<<1); SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM.get(), SRAMLength, Platform::WriteNDSSave(SRAM.get(), SRAMLength,
SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr); SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr,
UserData);
} }
return 0; return 0;
@ -798,7 +803,8 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
{ {
SRAMStatus &= ~(1<<1); SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM.get(), SRAMLength, Platform::WriteNDSSave(SRAM.get(), SRAMLength,
SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr); SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr,
UserData);
} }
return 0; return 0;
@ -821,7 +827,8 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
{ {
SRAMStatus &= ~(1<<1); SRAMStatus &= ~(1<<1);
Platform::WriteNDSSave(SRAM.get(), SRAMLength, Platform::WriteNDSSave(SRAM.get(), SRAMLength,
SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr); SRAMFirstAddr & (SRAMLength-1), SRAMAddr-SRAMFirstAddr,
UserData);
} }
return 0; return 0;
@ -832,13 +839,13 @@ u8 CartRetail::SRAMWrite_FLASH(u8 val, u32 pos, bool last)
} }
} }
CartRetailNAND::CartRetailNAND(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen) : CartRetailNAND::CartRetailNAND(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata) :
CartRetailNAND(CopyToUnique(rom, len), len, chipid, romparams, std::move(sram), sramlen) CartRetailNAND(CopyToUnique(rom, len), len, chipid, romparams, std::move(sram), sramlen, userdata)
{ {
} }
CartRetailNAND::CartRetailNAND(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen) : CartRetailNAND::CartRetailNAND(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata) :
CartRetail(std::move(rom), len, chipid, false, romparams, std::move(sram), sramlen, CartType::RetailNAND) CartRetail(std::move(rom), len, chipid, false, romparams, std::move(sram), sramlen, userdata, CartType::RetailNAND)
{ {
BuildSRAMID(); BuildSRAMID();
} }
@ -908,7 +915,7 @@ int CartRetailNAND::ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, co
if (SRAMLength && SRAMAddr < (SRAMBase+SRAMLength-0x20000)) if (SRAMLength && SRAMAddr < (SRAMBase+SRAMLength-0x20000))
{ {
memcpy(&SRAM[SRAMAddr - SRAMBase], SRAMWriteBuffer, 0x800); memcpy(&SRAM[SRAMAddr - SRAMBase], SRAMWriteBuffer, 0x800);
Platform::WriteNDSSave(SRAM.get(), SRAMLength, SRAMAddr - SRAMBase, 0x800); Platform::WriteNDSSave(SRAM.get(), SRAMLength, SRAMAddr - SRAMBase, 0x800, UserData);
} }
SRAMAddr = 0; SRAMAddr = 0;
@ -1064,8 +1071,8 @@ void CartRetailNAND::BuildSRAMID()
} }
CartRetailIR::CartRetailIR(const u8* rom, u32 len, u32 chipid, u32 irversion, bool badDSiDump, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen) : CartRetailIR::CartRetailIR(const u8* rom, u32 len, u32 chipid, u32 irversion, bool badDSiDump, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata) :
CartRetailIR(CopyToUnique(rom, len), len, chipid, irversion, badDSiDump, romparams, std::move(sram), sramlen) CartRetailIR(CopyToUnique(rom, len), len, chipid, irversion, badDSiDump, romparams, std::move(sram), sramlen, userdata)
{ {
} }
@ -1077,9 +1084,10 @@ CartRetailIR::CartRetailIR(
bool badDSiDump, bool badDSiDump,
ROMListEntry romparams, ROMListEntry romparams,
std::unique_ptr<u8[]>&& sram, std::unique_ptr<u8[]>&& sram,
u32 sramlen u32 sramlen,
void* userdata
) : ) :
CartRetail(std::move(rom), len, chipid, badDSiDump, romparams, std::move(sram), sramlen, CartType::RetailIR), CartRetail(std::move(rom), len, chipid, badDSiDump, romparams, std::move(sram), sramlen, userdata, CartType::RetailIR),
IRVersion(irversion) IRVersion(irversion)
{ {
} }
@ -1122,13 +1130,13 @@ u8 CartRetailIR::SPIWrite(u8 val, u32 pos, bool last)
return 0; return 0;
} }
CartRetailBT::CartRetailBT(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen) : CartRetailBT::CartRetailBT(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata) :
CartRetailBT(CopyToUnique(rom, len), len, chipid, romparams, std::move(sram), sramlen) CartRetailBT(CopyToUnique(rom, len), len, chipid, romparams, std::move(sram), sramlen, userdata)
{ {
} }
CartRetailBT::CartRetailBT(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen) : CartRetailBT::CartRetailBT(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata) :
CartRetail(std::move(rom), len, chipid, false, romparams, std::move(sram), sramlen, CartType::RetailBT) CartRetail(std::move(rom), len, chipid, false, romparams, std::move(sram), sramlen, userdata, CartType::RetailBT)
{ {
Log(LogLevel::Info,"POKETYPE CART\n"); Log(LogLevel::Info,"POKETYPE CART\n");
} }
@ -1150,12 +1158,12 @@ u8 CartRetailBT::SPIWrite(u8 val, u32 pos, bool last)
} }
CartSD::CartSD(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard) : CartSD::CartSD(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, void* userdata, std::optional<FATStorage>&& sdcard) :
CartSD(CopyToUnique(rom, len), len, chipid, romparams, std::move(sdcard)) CartSD(CopyToUnique(rom, len), len, chipid, romparams, userdata, std::move(sdcard))
{} {}
CartSD::CartSD(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard) : CartSD::CartSD(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, void* userdata, std::optional<FATStorage>&& sdcard) :
CartCommon(std::move(rom), len, chipid, false, romparams, CartType::Homebrew), CartCommon(std::move(rom), len, chipid, false, romparams, CartType::Homebrew, userdata),
SD(std::move(sdcard)) SD(std::move(sdcard))
{ {
sdcard = std::nullopt; sdcard = std::nullopt;
@ -1306,12 +1314,12 @@ void CartSD::ReadROM_B7(u32 addr, u32 len, u8* data, u32 offset) const
memcpy(data+offset, ROM.get()+addr, len); memcpy(data+offset, ROM.get()+addr, len);
} }
CartHomebrew::CartHomebrew(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard) : CartHomebrew::CartHomebrew(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, void* userdata, std::optional<FATStorage>&& sdcard) :
CartSD(rom, len, chipid, romparams, std::move(sdcard)) CartSD(rom, len, chipid, romparams, userdata, std::move(sdcard))
{} {}
CartHomebrew::CartHomebrew(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard) : CartHomebrew::CartHomebrew(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, void* userdata, std::optional<FATStorage>&& sdcard) :
CartSD(std::move(rom), len, chipid, romparams, std::move(sdcard)) CartSD(std::move(rom), len, chipid, romparams, userdata, std::move(sdcard))
{} {}
CartHomebrew::~CartHomebrew() = default; CartHomebrew::~CartHomebrew() = default;
@ -1565,12 +1573,12 @@ void NDSCartSlot::DecryptSecureArea(u8* out) noexcept
} }
} }
std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, std::optional<NDSCartArgs>&& args) std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, void* userdata, std::optional<NDSCartArgs>&& args)
{ {
return ParseROM(CopyToUnique(romdata, romlen), romlen, std::move(args)); return ParseROM(CopyToUnique(romdata, romlen), romlen, userdata, std::move(args));
} }
std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, std::optional<NDSCartArgs>&& args) std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, void* userdata, std::optional<NDSCartArgs>&& args)
{ {
if (romdata == nullptr) if (romdata == nullptr)
{ {
@ -1659,21 +1667,21 @@ std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen
if (homebrew) if (homebrew)
{ {
std::optional<FATStorage> sdcard = args && args->SDCard ? std::make_optional<FATStorage>(std::move(*args->SDCard)) : std::nullopt; std::optional<FATStorage> sdcard = args && args->SDCard ? std::make_optional<FATStorage>(std::move(*args->SDCard)) : std::nullopt;
cart = std::make_unique<CartHomebrew>(std::move(cartrom), cartromsize, cartid, romparams, std::move(sdcard)); cart = std::make_unique<CartHomebrew>(std::move(cartrom), cartromsize, cartid, romparams, userdata, std::move(sdcard));
} }
else if (gametitle[0] == 0 && !strncmp("SD/TF-NDS", gametitle + 1, 9) && gamecode == 0x414D5341) else if (gametitle[0] == 0 && !strncmp("SD/TF-NDS", gametitle + 1, 9) && gamecode == 0x414D5341)
{ {
std::optional<FATStorage> sdcard = args && args->SDCard ? std::make_optional<FATStorage>(std::move(*args->SDCard)) : std::nullopt; std::optional<FATStorage> sdcard = args && args->SDCard ? std::make_optional<FATStorage>(std::move(*args->SDCard)) : std::nullopt;
cart = std::make_unique<CartR4>(std::move(cartrom), cartromsize, cartid, romparams, CartR4TypeR4, CartR4LanguageEnglish, std::move(sdcard)); cart = std::make_unique<CartR4>(std::move(cartrom), cartromsize, cartid, romparams, CartR4TypeR4, CartR4LanguageEnglish, userdata, std::move(sdcard));
} }
else if (cartid & 0x08000000) else if (cartid & 0x08000000)
cart = std::make_unique<CartRetailNAND>(std::move(cartrom), cartromsize, cartid, romparams, std::move(sram), sramlen); cart = std::make_unique<CartRetailNAND>(std::move(cartrom), cartromsize, cartid, romparams, std::move(sram), sramlen, userdata);
else if (irversion != 0) else if (irversion != 0)
cart = std::make_unique<CartRetailIR>(std::move(cartrom), cartromsize, cartid, irversion, badDSiDump, romparams, std::move(sram), sramlen); cart = std::make_unique<CartRetailIR>(std::move(cartrom), cartromsize, cartid, irversion, badDSiDump, romparams, std::move(sram), sramlen, userdata);
else if ((gamecode & 0xFFFFFF) == 0x505A55) // UZPx else if ((gamecode & 0xFFFFFF) == 0x505A55) // UZPx
cart = std::make_unique<CartRetailBT>(std::move(cartrom), cartromsize, cartid, romparams, std::move(sram), sramlen); cart = std::make_unique<CartRetailBT>(std::move(cartrom), cartromsize, cartid, romparams, std::move(sram), sramlen, userdata);
else else
cart = std::make_unique<CartRetail>(std::move(cartrom), cartromsize, cartid, badDSiDump, romparams, std::move(sram), sramlen); cart = std::make_unique<CartRetail>(std::move(cartrom), cartromsize, cartid, badDSiDump, romparams, std::move(sram), sramlen, userdata);
args = std::nullopt; args = std::nullopt;
return cart; return cart;

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2016-2023 melonDS team Copyright 2016-2024 melonDS team
This file is part of melonDS. This file is part of melonDS.
@ -76,8 +76,8 @@ struct NDSCartArgs
class CartCommon class CartCommon
{ {
public: public:
CartCommon(const u8* rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, CartType type); CartCommon(const u8* rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, CartType type, void* userdata);
CartCommon(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, CartType type); CartCommon(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, bool badDSiDump, ROMListEntry romparams, CartType type, void* userdata);
virtual ~CartCommon(); virtual ~CartCommon();
[[nodiscard]] u32 Type() const { return CartType; }; [[nodiscard]] u32 Type() const { return CartType; };
@ -111,6 +111,8 @@ public:
protected: protected:
void ReadROM(u32 addr, u32 len, u8* data, u32 offset) const; void ReadROM(u32 addr, u32 len, u8* data, u32 offset) const;
void* UserData;
std::unique_ptr<u8[]> ROM = nullptr; std::unique_ptr<u8[]> ROM = nullptr;
u32 ROMLength = 0; u32 ROMLength = 0;
u32 ChipID = 0; u32 ChipID = 0;
@ -139,6 +141,7 @@ public:
ROMListEntry romparams, ROMListEntry romparams,
std::unique_ptr<u8[]>&& sram, std::unique_ptr<u8[]>&& sram,
u32 sramlen, u32 sramlen,
void* userdata,
melonDS::NDSCart::CartType type = CartType::Retail melonDS::NDSCart::CartType type = CartType::Retail
); );
CartRetail( CartRetail(
@ -148,6 +151,7 @@ public:
ROMListEntry romparams, ROMListEntry romparams,
std::unique_ptr<u8[]>&& sram, std::unique_ptr<u8[]>&& sram,
u32 sramlen, u32 sramlen,
void* userdata,
melonDS::NDSCart::CartType type = CartType::Retail melonDS::NDSCart::CartType type = CartType::Retail
); );
~CartRetail() override; ~CartRetail() override;
@ -187,8 +191,8 @@ protected:
class CartRetailNAND : public CartRetail class CartRetailNAND : public CartRetail
{ {
public: public:
CartRetailNAND(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen); CartRetailNAND(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata);
CartRetailNAND(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen); CartRetailNAND(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata);
~CartRetailNAND() override; ~CartRetailNAND() override;
void Reset() override; void Reset() override;
@ -216,8 +220,8 @@ private:
class CartRetailIR : public CartRetail class CartRetailIR : public CartRetail
{ {
public: public:
CartRetailIR(const u8* rom, u32 len, u32 chipid, u32 irversion, bool badDSiDump, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen); CartRetailIR(const u8* rom, u32 len, u32 chipid, u32 irversion, bool badDSiDump, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata);
CartRetailIR(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, u32 irversion, bool badDSiDump, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen); CartRetailIR(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, u32 irversion, bool badDSiDump, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata);
~CartRetailIR() override; ~CartRetailIR() override;
void Reset() override; void Reset() override;
@ -235,8 +239,8 @@ private:
class CartRetailBT : public CartRetail class CartRetailBT : public CartRetail
{ {
public: public:
CartRetailBT(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen); CartRetailBT(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata);
CartRetailBT(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen); CartRetailBT(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata);
~CartRetailBT() override; ~CartRetailBT() override;
u8 SPIWrite(u8 val, u32 pos, bool last) override; u8 SPIWrite(u8 val, u32 pos, bool last) override;
@ -246,8 +250,8 @@ public:
class CartSD : public CartCommon class CartSD : public CartCommon
{ {
public: public:
CartSD(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard = std::nullopt); CartSD(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, void* userdata, std::optional<FATStorage>&& sdcard = std::nullopt);
CartSD(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard = std::nullopt); CartSD(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, void* userdata, std::optional<FATStorage>&& sdcard = std::nullopt);
~CartSD() override; ~CartSD() override;
[[nodiscard]] const std::optional<FATStorage>& GetSDCard() const noexcept { return SD; } [[nodiscard]] const std::optional<FATStorage>& GetSDCard() const noexcept { return SD; }
@ -288,8 +292,8 @@ protected:
class CartHomebrew : public CartSD class CartHomebrew : public CartSD
{ {
public: public:
CartHomebrew(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard = std::nullopt); CartHomebrew(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, void* userdata, std::optional<FATStorage>&& sdcard = std::nullopt);
CartHomebrew(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard = std::nullopt); CartHomebrew(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, void* userdata, std::optional<FATStorage>&& sdcard = std::nullopt);
~CartHomebrew() override; ~CartHomebrew() override;
void Reset() override; void Reset() override;
@ -322,7 +326,7 @@ enum CartR4Language
class CartR4 : public CartSD class CartR4 : public CartSD
{ {
public: public:
CartR4(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, CartR4Type ctype, CartR4Language clanguage, CartR4(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, CartR4Type ctype, CartR4Language clanguage, void* userdata,
std::optional<FATStorage>&& sdcard = std::nullopt); std::optional<FATStorage>&& sdcard = std::nullopt);
~CartR4() override; ~CartR4() override;
@ -461,8 +465,8 @@ private:
/// If not given, the cart will not have an SD card. /// If not given, the cart will not have an SD card.
/// @returns A \c NDSCart::CartCommon object representing the parsed ROM, /// @returns A \c NDSCart::CartCommon object representing the parsed ROM,
/// or \c nullptr if the ROM data couldn't be parsed. /// or \c nullptr if the ROM data couldn't be parsed.
std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, std::optional<NDSCartArgs>&& args = std::nullopt); std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, void* userdata = nullptr, std::optional<NDSCartArgs>&& args = std::nullopt);
std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, std::optional<NDSCartArgs>&& args = std::nullopt); std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, void* userdata = nullptr, std::optional<NDSCartArgs>&& args = std::nullopt);
} }
#endif #endif

Some files were not shown because too many files have changed in this diff Show More