Skip to content

Commit

Permalink
Move GBACart-related global state into objects (melonDS-emu#1870)
Browse files Browse the repository at this point in the history
- RAII will now do the heavy lifting
- Mark some methods as const or noexcept
- Once the `NDS` object is finalized, most of these `assert`s can go away
  • Loading branch information
JesseTG authored Nov 8, 2023
1 parent b4ff911 commit 8b47178
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 155 deletions.
64 changes: 15 additions & 49 deletions src/GBACart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ const char SOLAR_SENSOR_GAMECODES[10][5] =
"A3IJ" // Boktai - The Sun Is in Your Hand (USA) (Sample)
};

std::unique_ptr<CartCommon> Cart;

u16 OpenBusDecay;


CartCommon::CartCommon()
{
}
Expand Down Expand Up @@ -77,7 +72,7 @@ int CartCommon::SetInput(int num, bool pressed)
return -1;
}

u16 CartCommon::ROMRead(u32 addr)
u16 CartCommon::ROMRead(u32 addr) const
{
return 0;
}
Expand Down Expand Up @@ -243,7 +238,7 @@ void CartGame::LoadSave(const u8* savedata, u32 savelen)
Platform::WriteGBASave(savedata, len, 0, len);
}

u16 CartGame::ROMRead(u32 addr)
u16 CartGame::ROMRead(u32 addr) const
{
addr &= 0x01FFFFFF;

Expand Down Expand Up @@ -639,7 +634,7 @@ void CartRAMExpansion::DoSavestate(Savestate* file)
file->Var16(&RAMEnable);
}

u16 CartRAMExpansion::ROMRead(u32 addr)
u16 CartRAMExpansion::ROMRead(u32 addr) const
{
addr &= 0x01FFFFFF;

Expand Down Expand Up @@ -696,25 +691,12 @@ void CartRAMExpansion::ROMWrite(u32 addr, u16 val)
}
}


bool Init()
{
Cart = nullptr;

return true;
}

void DeInit()
{
Cart = nullptr;
}

void Reset()
void GBACartSlot::Reset() noexcept
{
if (Cart) Cart->Reset();
}

void DoSavestate(Savestate* file)
void GBACartSlot::DoSavestate(Savestate* file) noexcept
{
file->Section("GBAC"); // Game Boy Advance Cartridge

Expand Down Expand Up @@ -816,7 +798,7 @@ std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen)
return cart;
}

bool InsertROM(std::unique_ptr<CartCommon>&& cart)
bool GBACartSlot::InsertROM(std::unique_ptr<CartCommon>&& cart) noexcept
{
if (!cart) {
Log(LogLevel::Error, "Failed to insert invalid GBA cart; existing cart (if any) was not ejected.\n");
Expand Down Expand Up @@ -844,14 +826,14 @@ bool InsertROM(std::unique_ptr<CartCommon>&& cart)
return true;
}

bool LoadROM(const u8* romdata, u32 romlen)
bool GBACartSlot::LoadROM(const u8* romdata, u32 romlen) noexcept
{
std::unique_ptr<CartCommon> data = ParseROM(romdata, romlen);

return InsertROM(std::move(data));
}

void LoadSave(const u8* savedata, u32 savelen)
void GBACartSlot::LoadSave(const u8* savedata, u32 savelen) noexcept
{
if (Cart)
{
Expand All @@ -862,7 +844,7 @@ void LoadSave(const u8* savedata, u32 savelen)
}
}

void LoadAddon(int type)
void GBACartSlot::LoadAddon(int type) noexcept
{
switch (type)
{
Expand All @@ -876,58 +858,42 @@ void LoadAddon(int type)
}
}

void EjectCart()
void GBACartSlot::EjectCart() noexcept
{
Cart = nullptr;
}


int SetInput(int num, bool pressed)
int GBACartSlot::SetInput(int num, bool pressed) noexcept
{
if (Cart) return Cart->SetInput(num, pressed);

return -1;
}


void SetOpenBusDecay(u16 val)
{
OpenBusDecay = val;
}


u16 ROMRead(u32 addr)
u16 GBACartSlot::ROMRead(u32 addr) const noexcept
{
if (Cart) return Cart->ROMRead(addr);

return ((addr >> 1) & 0xFFFF) | OpenBusDecay;
}

void ROMWrite(u32 addr, u16 val)
void GBACartSlot::ROMWrite(u32 addr, u16 val) noexcept
{
if (Cart) Cart->ROMWrite(addr, val);
}

u8 SRAMRead(u32 addr)
u8 GBACartSlot::SRAMRead(u32 addr) noexcept
{
if (Cart) return Cart->SRAMRead(addr);

return 0xFF;
}

void SRAMWrite(u32 addr, u8 val)
void GBACartSlot::SRAMWrite(u32 addr, u8 val) noexcept
{
if (Cart) Cart->SRAMWrite(addr, val);
}

u8* GetSaveMemory()
{
return Cart ? Cart->GetSaveMemory() : nullptr;
}

u32 GetSaveMemoryLength()
{
return Cart ? Cart->GetSaveMemoryLength() : 0;
}

}
98 changes: 49 additions & 49 deletions src/GBACart.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class CartCommon

virtual int SetInput(int num, bool pressed);

virtual u16 ROMRead(u32 addr);
virtual u16 ROMRead(u32 addr) const;
virtual void ROMWrite(u32 addr, u16 val);

virtual u8 SRAMRead(u32 addr);
Expand Down Expand Up @@ -83,7 +83,7 @@ class CartGame : public CartCommon
virtual void SetupSave(u32 type) override;
virtual void LoadSave(const u8* savedata, u32 savelen) override;

virtual u16 ROMRead(u32 addr) override;
virtual u16 ROMRead(u32 addr) const override;
virtual void ROMWrite(u32 addr, u16 val) override;

virtual u8 SRAMRead(u32 addr) override;
Expand Down Expand Up @@ -180,7 +180,7 @@ class CartRAMExpansion : public CartCommon

void DoSavestate(Savestate* file) override;

u16 ROMRead(u32 addr) override;
u16 ROMRead(u32 addr) const override;
void ROMWrite(u32 addr, u16 val) override;

private:
Expand All @@ -195,13 +195,52 @@ enum
Input_SolarSensorUp,
};

extern std::unique_ptr<CartCommon> Cart;

bool Init();
void DeInit();
void Reset();

void DoSavestate(Savestate* file);
class GBACartSlot
{
public:
GBACartSlot() noexcept = default;
~GBACartSlot() noexcept = default;
void Reset() noexcept;
void DoSavestate(Savestate* file) noexcept;
/// Applies the GBACartData to the emulator state and unloads an existing ROM if any.
/// Upon successful insertion, \c cart will be nullptr and the global GBACart state
/// (\c CartROM, CartInserted, etc.) will be updated.
bool InsertROM(std::unique_ptr<CartCommon>&& cart) noexcept;
bool LoadROM(const u8* romdata, u32 romlen) noexcept;
void LoadSave(const u8* savedata, u32 savelen) noexcept;

void LoadAddon(int type) noexcept;

void EjectCart() noexcept;

// TODO: make more flexible, support nonbinary inputs
int SetInput(int num, bool pressed) noexcept;

void SetOpenBusDecay(u16 val) noexcept { OpenBusDecay = val; }

u16 ROMRead(u32 addr) const noexcept;
void ROMWrite(u32 addr, u16 val) noexcept;

u8 SRAMRead(u32 addr) noexcept;
void SRAMWrite(u32 addr, u8 val) noexcept;

/// This function is intended to allow frontends to save and load SRAM
/// without using melonDS APIs.
/// Modifying the emulated SRAM for any other reason is strongly discouraged.
/// The returned pointer may be invalidated if the emulator is reset,
/// or when a new game is loaded.
/// Consequently, don't store the returned pointer for any longer than necessary.
/// @returns Pointer to this cart's SRAM if a cart is loaded and supports SRAM, otherwise \c nullptr.
[[nodiscard]] u8* GetSaveMemory() noexcept { return Cart ? Cart->GetSaveMemory() : nullptr; }
[[nodiscard]] const u8* GetSaveMemory() const noexcept { return Cart ? Cart->GetSaveMemory() : nullptr; }

/// @returns The length of the buffer returned by ::GetSaveMemory()
/// if a cart is loaded and supports SRAM, otherwise zero.
[[nodiscard]] u32 GetSaveMemoryLength() const noexcept { return Cart ? Cart->GetSaveMemoryLength() : 0; }
private:
std::unique_ptr<CartCommon> Cart = nullptr;
u16 OpenBusDecay = 0;
};

/// Parses the given ROM data and constructs a \c GBACart::CartCommon subclass
/// that can be inserted into the emulator or used to extract information about the cart beforehand.
Expand All @@ -213,45 +252,6 @@ void DoSavestate(Savestate* file);
/// or \c nullptr if the ROM data couldn't be parsed.
std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen);

/// Applies the GBACartData to the emulator state and unloads an existing ROM if any.
/// Upon successful insertion, \c cart will be nullptr and the global GBACart state
/// (\c CartROM, CartInserted, etc.) will be updated.
bool InsertROM(std::unique_ptr<CartCommon>&& cart);
bool LoadROM(const u8* romdata, u32 romlen);
void LoadSave(const u8* savedata, u32 savelen);

void LoadAddon(int type);

void EjectCart();

//bool LoadROM(const char* path, const char* sram);
//bool LoadROM(const u8* romdata, u32 filelength, const char *sram);
//void RelocateSave(const char* path, bool write);

// TODO: make more flexible, support nonbinary inputs
int SetInput(int num, bool pressed);

void SetOpenBusDecay(u16 val);

u16 ROMRead(u32 addr);
void ROMWrite(u32 addr, u16 val);

u8 SRAMRead(u32 addr);
void SRAMWrite(u32 addr, u8 val);

/// This function is intended to allow frontends to save and load SRAM
/// without using melonDS APIs.
/// Modifying the emulated SRAM for any other reason is strongly discouraged.
/// The returned pointer may be invalidated if the emulator is reset,
/// or when a new game is loaded.
/// Consequently, don't store the returned pointer for any longer than necessary.
/// @returns Pointer to this cart's SRAM if a cart is loaded and supports SRAM, otherwise \c nullptr.
u8* GetSaveMemory();

/// @returns The length of the buffer returned by ::GetSaveMemory()
/// if a cart is loaded and supports SRAM, otherwise zero.
u32 GetSaveMemoryLength();

}

#endif // GBACART_H
Loading

0 comments on commit 8b47178

Please sign in to comment.