mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-26 15:50:00 -06:00
Add support for using the solar sensor without requiring a Boktai ROM (#2221)
* Add a `GBAHeader` struct * Add extra `GBAAddon` entries for the Boktai carts - Each game in the trilogy has a different effect on Lunar Knights (the only commercial DS game to support the solar sensor) * Copy the logo data from the NDS ROM's header to the Boktai stub's header
This commit is contained in:
@ -539,6 +539,57 @@ CartGameSolarSensor::CartGameSolarSensor(std::unique_ptr<u8[]>&& rom, u32 len, s
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<CartGameSolarSensor> CreateFakeSolarSensorROM(const char* gamecode, const NDSCart::CartCommon& cart, void* userdata) noexcept
|
||||
{
|
||||
return CreateFakeSolarSensorROM(gamecode, cart.GetHeader().NintendoLogo, userdata);
|
||||
}
|
||||
|
||||
std::unique_ptr<CartGameSolarSensor> CreateFakeSolarSensorROM(const char* gamecode, const GBACart::CartGame& cart, void* userdata) noexcept
|
||||
{
|
||||
return CreateFakeSolarSensorROM(gamecode, cart.GetHeader().NintendoLogo, userdata);
|
||||
}
|
||||
|
||||
std::unique_ptr<CartGameSolarSensor> CreateFakeSolarSensorROM(const char* gamecode, const u8* logo, void* userdata) noexcept
|
||||
{
|
||||
if (!gamecode)
|
||||
return nullptr;
|
||||
|
||||
if (strnlen(gamecode, sizeof(GBAHeader::GameCode)) > sizeof(GBAHeader::GameCode))
|
||||
return nullptr;
|
||||
|
||||
bool solarsensor = false;
|
||||
for (const char* i : SOLAR_SENSOR_GAMECODES)
|
||||
{
|
||||
if (strcmp(gamecode, i) == 0) {
|
||||
solarsensor = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!solarsensor)
|
||||
return nullptr;
|
||||
|
||||
// just 256 bytes; we don't need a whole ROM!
|
||||
constexpr size_t FAKE_BOKTAI_ROM_LENGTH = 0x100;
|
||||
std::unique_ptr<u8[]> rom = std::make_unique<u8[]>(FAKE_BOKTAI_ROM_LENGTH);
|
||||
|
||||
// create a fake ROM
|
||||
GBAHeader& header = *reinterpret_cast<GBAHeader*>(rom.get());
|
||||
memcpy(header.Title, BOKTAI_STUB_TITLE, strnlen(BOKTAI_STUB_TITLE, sizeof(header.Title)));
|
||||
memcpy(header.GameCode, gamecode, strnlen(gamecode, sizeof(header.GameCode)));
|
||||
header.FixedValue = 0x96;
|
||||
if (logo)
|
||||
{
|
||||
memcpy(header.NintendoLogo, logo, sizeof(header.NintendoLogo));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(header.NintendoLogo, 0xFF, sizeof(header.NintendoLogo));
|
||||
}
|
||||
|
||||
return std::make_unique<CartGameSolarSensor>(std::move(rom), FAKE_BOKTAI_ROM_LENGTH, nullptr, 0, userdata);
|
||||
}
|
||||
|
||||
const int CartGameSolarSensor::kLuxLevels[11] = {0, 5, 11, 18, 27, 42, 62, 84, 109, 139, 183};
|
||||
|
||||
void CartGameSolarSensor::Reset()
|
||||
@ -843,7 +894,18 @@ std::unique_ptr<CartCommon> LoadAddon(int type, void* userdata)
|
||||
case GBAAddon_RumblePak:
|
||||
cart = std::make_unique<CartRumblePak>(userdata);
|
||||
break;
|
||||
|
||||
case GBAAddon_SolarSensorBoktai1:
|
||||
// US Boktai 1
|
||||
cart = CreateFakeSolarSensorROM("U3IE", nullptr, userdata);
|
||||
break;
|
||||
case GBAAddon_SolarSensorBoktai2:
|
||||
// US Boktai 2
|
||||
cart = CreateFakeSolarSensorROM("U32E", nullptr, userdata);
|
||||
break;
|
||||
case GBAAddon_SolarSensorBoktai3:
|
||||
// JP Boktai 3
|
||||
cart = CreateFakeSolarSensorROM("U33J", nullptr, userdata);
|
||||
break;
|
||||
default:
|
||||
Log(LogLevel::Warn, "GBACart: !! invalid addon type %d\n", type);
|
||||
return nullptr;
|
||||
|
Reference in New Issue
Block a user