mirror of
https://github.com/Rosalie241/RMG.git
synced 2025-06-25 14:07:02 -04:00
215 lines
5.3 KiB
C++
215 lines
5.3 KiB
C++
/*
|
|
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
|
* Copyright (C) 2020-2025 Rosalie Wanders <rosalie@mailbox.org>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
#define CORE_INTERNAL
|
|
#include "Directories.hpp"
|
|
#include "MediaLoader.hpp"
|
|
#include "Settings.hpp"
|
|
#include "Archive.hpp"
|
|
#include "Library.hpp"
|
|
#include "String.hpp"
|
|
#include "Error.hpp"
|
|
#include "File.hpp"
|
|
|
|
#include "m64p/Api.hpp"
|
|
|
|
#include <string.h>
|
|
#include <cstdint>
|
|
|
|
//
|
|
// Local Variables
|
|
//
|
|
|
|
static bool l_HasExtractedDisk = false;
|
|
static std::filesystem::path l_DdDiskFile;
|
|
static std::filesystem::path l_DdRomFile;
|
|
|
|
//
|
|
// Local Functions
|
|
//
|
|
|
|
static char* medialoader_get_dd_disk(void*)
|
|
{
|
|
if (l_DdDiskFile.empty())
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
return strdup(l_DdDiskFile.string().c_str());
|
|
}
|
|
|
|
static void medialoader_set_dd_rom_region(void*, uint8_t region)
|
|
{
|
|
switch (region)
|
|
{
|
|
case DDREGION_JAPAN:
|
|
l_DdRomFile = CoreSettingsGetStringValue(SettingsID::Core_64DD_JapaneseIPL);
|
|
break;
|
|
case DDREGION_US:
|
|
l_DdRomFile = CoreSettingsGetStringValue(SettingsID::Core_64DD_AmericanIPL);
|
|
break;
|
|
case DDREGION_DEV:
|
|
l_DdRomFile = CoreSettingsGetStringValue(SettingsID::Core_64DD_DevelopmentIPL);
|
|
break;
|
|
case DDREGION_UNKNOWN:
|
|
l_DdRomFile.clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
static char* medialoader_get_dd_rom(void*)
|
|
{
|
|
if (l_DdRomFile.empty())
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
return strdup(l_DdRomFile.string().c_str());
|
|
}
|
|
|
|
static char* medialoader_get_gb_cart_ram(void*, int index)
|
|
{
|
|
std::filesystem::path gameBoySave;
|
|
const SettingsID settingIds[] =
|
|
{
|
|
SettingsID::Core_Gameboy_P1_Save,
|
|
SettingsID::Core_Gameboy_P2_Save,
|
|
SettingsID::Core_Gameboy_P3_Save,
|
|
SettingsID::Core_Gameboy_P4_Save,
|
|
};
|
|
|
|
gameBoySave = CoreSettingsGetStringValue(settingIds[index]);
|
|
if (gameBoySave.empty())
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
return strdup(gameBoySave.string().c_str());
|
|
}
|
|
|
|
static char* mediaLoader_get_gb_cart_rom(void*, int index)
|
|
{
|
|
std::filesystem::path gameBoyRom;
|
|
const SettingsID settingIds[] =
|
|
{
|
|
SettingsID::Core_Gameboy_P1_Rom,
|
|
SettingsID::Core_Gameboy_P2_Rom,
|
|
SettingsID::Core_Gameboy_P3_Rom,
|
|
SettingsID::Core_Gameboy_P4_Rom,
|
|
};
|
|
|
|
gameBoyRom = CoreSettingsGetStringValue(settingIds[index]);
|
|
if (gameBoyRom.empty())
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
return strdup(gameBoyRom.string().c_str());
|
|
}
|
|
|
|
//
|
|
// Exported Functions
|
|
//
|
|
|
|
CORE_EXPORT bool CoreSetupMediaLoader(void)
|
|
{
|
|
std::string error;
|
|
m64p_error ret;
|
|
|
|
m64p_media_loader mediaLoader;
|
|
mediaLoader.cb_data = nullptr;
|
|
mediaLoader.get_dd_disk = medialoader_get_dd_disk;
|
|
mediaLoader.set_dd_rom_region = medialoader_set_dd_rom_region;
|
|
mediaLoader.get_dd_rom = medialoader_get_dd_rom;
|
|
mediaLoader.get_gb_cart_ram = medialoader_get_gb_cart_ram;
|
|
mediaLoader.get_gb_cart_rom = mediaLoader_get_gb_cart_rom;
|
|
|
|
if (!m64p::Core.IsHooked())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
ret = m64p::Core.DoCommand(M64CMD_SET_MEDIA_LOADER, sizeof(mediaLoader), &mediaLoader);
|
|
if (ret != M64ERR_SUCCESS)
|
|
{
|
|
error = "CoreSetupMediaLoader m64p::Core.DoCommand(M64CMD_SET_MEDIA_LOADER) Failed: ";
|
|
error += m64p::Core.ErrorMessage(ret);
|
|
CoreSetError(error);
|
|
}
|
|
|
|
return ret == M64ERR_SUCCESS;
|
|
}
|
|
|
|
CORE_EXPORT void CoreResetMediaLoader(void)
|
|
{
|
|
std::error_code errorCode;
|
|
|
|
// attempt to remove extracted disk file
|
|
if (l_HasExtractedDisk && !l_DdRomFile.empty())
|
|
{
|
|
std::filesystem::remove(l_DdDiskFile, errorCode);
|
|
}
|
|
|
|
l_HasExtractedDisk = false;
|
|
l_DdRomFile = "";
|
|
l_DdDiskFile = "";
|
|
}
|
|
|
|
CORE_EXPORT void CoreMediaLoaderSetDiskFile(std::filesystem::path disk)
|
|
{
|
|
std::error_code error_code;
|
|
std::vector<char> buf;
|
|
std::string file_extension;
|
|
|
|
file_extension = disk.has_extension() ? disk.extension().string() : "";
|
|
file_extension = CoreLowerString(file_extension);
|
|
|
|
// extract disk when it's in an archive
|
|
if (file_extension == ".zip" ||
|
|
file_extension == ".7z")
|
|
{
|
|
std::filesystem::path extracted_file;
|
|
bool is_disk = false;
|
|
|
|
if (!CoreReadArchiveFile(disk, extracted_file, is_disk, buf))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// do nothing if archive doesn't contain a disk
|
|
if (!is_disk)
|
|
{
|
|
return;
|
|
}
|
|
|
|
disk = CoreGetUserCacheDirectory();
|
|
disk += CORE_DIR_SEPERATOR_STR;
|
|
disk += "extracted_disks";
|
|
disk += CORE_DIR_SEPERATOR_STR;
|
|
disk += extracted_file.filename();
|
|
|
|
// attempt to create extraction directory
|
|
if (!std::filesystem::is_directory(disk.parent_path(), error_code) &&
|
|
!std::filesystem::create_directory(disk.parent_path(), error_code))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// attempt to write temporary file
|
|
if (!CoreWriteFile(disk, buf))
|
|
{
|
|
return;
|
|
}
|
|
|
|
l_HasExtractedDisk = true;
|
|
}
|
|
|
|
|
|
l_DdDiskFile = disk;
|
|
}
|