Skip to content

Commit

Permalink
merge doublemelon (melonDS-emu#2067)
Browse files Browse the repository at this point in the history
non-exhaustive (but exhausting) list of changes:

* base laid for multiple window support, but will likely require more work to work correctly
* encapsulation of frontend state for proper multi-instance support
* (JIT still needs a fix for the NDS::Current workaround but we can get there later)
* new, more flexible configuration system
  • Loading branch information
Arisotura authored Jun 15, 2024
1 parent 8e9b88d commit 25a7b1c
Show file tree
Hide file tree
Showing 111 changed files with 16,784 additions and 5,024 deletions.
24 changes: 22 additions & 2 deletions src/DSi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,28 @@ const u32 NDMAModes[] =
0xFF, // wifi / GBA cart slot (TODO)
};

DSi::DSi(DSiArgs&& args) noexcept :
NDS(std::move(args), 1),
/*DSi::DSi() noexcept :
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 {
DSi_NDMA(0, 0, *this),
DSi_NDMA(0, 1, *this),
Expand Down
3 changes: 2 additions & 1 deletion src/DSi.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ class DSi final : public NDS
void ARM7IOWrite32(u32 addr, u32 val) override;

public:
DSi(DSiArgs&& args) noexcept;
DSi(DSiArgs&& args, void* userdata = nullptr) noexcept;
//DSi() noexcept;
~DSi() noexcept override;
DSi(const DSi&) = delete;
DSi& operator=(const DSi&) = delete;
Expand Down
14 changes: 7 additions & 7 deletions src/DSi_Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ void DSi_Camera::DoSavestate(Savestate* file)

void DSi_Camera::Reset()
{
Platform::Camera_Stop(Num);
Platform::Camera_Stop(Num, DSi.UserData);

DataPos = 0;
RegAddr = 0;
Expand All @@ -435,7 +435,7 @@ void DSi_Camera::Reset()

void DSi_Camera::Stop()
{
Platform::Camera_Stop(Num);
Platform::Camera_Stop(Num, DSi.UserData);
}

bool DSi_Camera::IsActivated() const
Expand Down Expand Up @@ -474,7 +474,7 @@ void DSi_Camera::StartTransfer()
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
Expand Down Expand Up @@ -655,8 +655,8 @@ void DSi_Camera::I2C_WriteReg(u16 addr, u16 val)
StandbyCnt = val;
//printf("CAM%d STBCNT=%04X (%04X)\n", Num, StandbyCnt, val);
bool isactive = IsActivated();
if (isactive && !wasactive) Platform::Camera_Start(Num);
else if (wasactive && !isactive) Platform::Camera_Stop(Num);
if (isactive && !wasactive) Platform::Camera_Start(Num, DSi.UserData);
else if (wasactive && !isactive) Platform::Camera_Stop(Num, DSi.UserData);
}
return;
case 0x001A:
Expand All @@ -665,8 +665,8 @@ void DSi_Camera::I2C_WriteReg(u16 addr, u16 val)
MiscCnt = val & 0x0B7B;
//printf("CAM%d MISCCNT=%04X (%04X)\n", Num, MiscCnt, val);
bool isactive = IsActivated();
if (isactive && !wasactive) Platform::Camera_Start(Num);
else if (wasactive && !isactive) Platform::Camera_Stop(Num);
if (isactive && !wasactive) Platform::Camera_Start(Num, DSi.UserData);
else if (wasactive && !isactive) Platform::Camera_Stop(Num, DSi.UserData);
}
return;

Expand Down
16 changes: 11 additions & 5 deletions src/DSi_NWifi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1334,7 +1334,7 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
}
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)
Expand Down Expand Up @@ -1442,20 +1442,26 @@ void DSi_NWifi::CheckRX()
if (!Mailbox[8].CanFit(2048))
return;

int rxlen = Platform::LAN_RecvPacket(LANBuffer);
if (rxlen > 0)
int rxlen = Platform::Net_RecvPacket(LANBuffer, DSi.UserData);
while (rxlen > 0)
{
//printf("WMI packet recv %04X %04X %04X\n", *(u16*)&LANBuffer[0], *(u16*)&LANBuffer[2], *(u16*)&LANBuffer[4]);
// check destination MAC
if (*(u32*)&LANBuffer[0] != 0xFFFFFFFF || *(u16*)&LANBuffer[4] != 0xFFFF)
{
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
if (!memcmp(&LANBuffer[6], &EEPROM[0x00A], 6))
return;
{
rxlen = Platform::Net_RecvPacket(LANBuffer, DSi.UserData);
continue;
}

// packet is good

Expand Down
117 changes: 117 additions & 0 deletions src/FIFO.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

namespace melonDS
{

template<typename T, u32 NumEntries>
class FIFO
{
Expand Down Expand Up @@ -191,5 +192,121 @@ class DynamicFIFO
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
45 changes: 23 additions & 22 deletions src/GBACart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,18 @@ u32 CartCommon::GetSaveMemoryLength() const
return 0;
}

CartGame::CartGame(const u8* rom, u32 len, const u8* sram, u32 sramlen, GBACart::CartType type) :
CartGame(CopyToUnique(rom, len), len, CopyToUnique(sram, sramlen), sramlen, 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, 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),
ROM(std::move(rom)),
ROMLength(len),
SRAM(std::move(sram)),
SRAMLength(sramlen)
SRAMLength(sramlen),
UserData(userdata)
{
if (SRAM && SRAMLength)
{
Expand Down Expand Up @@ -170,7 +171,7 @@ void CartGame::DoSavestate(Savestate* file)
file->Var8((u8*)&SRAMType);

if ((!file->Saving) && SRAM)
Platform::WriteGBASave(SRAM.get(), SRAMLength, 0, SRAMLength);
Platform::WriteGBASave(SRAM.get(), SRAMLength, 0, SRAMLength, UserData);
}

void CartGame::SetupSave(u32 type)
Expand Down Expand Up @@ -223,7 +224,7 @@ void CartGame::SetSaveMemory(const u8* savedata, u32 savelen)

u32 len = std::min(savelen, SRAMLength);
memcpy(SRAM.get(), savedata, len);
Platform::WriteGBASave(savedata, len, 0, len);
Platform::WriteGBASave(savedata, len, 0, len, UserData);
}

u16 CartGame::ROMRead(u32 addr) const
Expand Down Expand Up @@ -464,7 +465,7 @@ void CartGame::SRAMWrite_FLASH(u32 addr, u8 val)
u32 start_addr = addr + 0x10000 * SRAMFlashState.bank;
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.cmd = 0;
Expand Down Expand Up @@ -523,18 +524,18 @@ void CartGame::SRAMWrite_SRAM(u32 addr, u8 val)
*(u8*)&SRAM[addr] = val;

// 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(CopyToUnique(rom, len), len, CopyToUnique(sram, sramlen), sramlen)
CartGameSolarSensor::CartGameSolarSensor(const u8* rom, u32 len, const u8* sram, u32 sramlen, void* userdata) :
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) :
CartGame(std::move(rom), len, std::move(sram), sramlen, CartType::GameSolarSensor)
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, userdata, CartType::GameSolarSensor)
{
}

Expand Down Expand Up @@ -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))
{
}

Expand Down Expand Up @@ -723,24 +724,24 @@ void GBACartSlot::DoSavestate(Savestate* file) noexcept
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);

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)
{
Expand Down Expand Up @@ -773,9 +774,9 @@ std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen

std::unique_ptr<CartCommon> cart;
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
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();

Expand Down
Loading

0 comments on commit 25a7b1c

Please sign in to comment.