#pragma once #include "stdafx.h" #include "Console.h" #include "NotificationManager.h" #include "../Utilities/FolderUtilities.h" struct MissingFirmwareMessage { const char* Filename; FirmwareType Firmware; uint32_t Size; }; class FirmwareHelper { private: static bool AttemptLoadDspFirmware(string combinedFilename, string splitFilenameProgram, string splitFilenameData, vector& programRom, vector& dataRom, uint32_t programSize, uint32_t dataSize) { VirtualFile combinedFirmware( FolderUtilities::CombinePath(FolderUtilities::GetFirmwareFolder(), combinedFilename)); if (combinedFirmware.GetSize() == programSize + dataSize) { vector firmwareData; combinedFirmware.ReadFile(firmwareData); programRom.insert(programRom.end(), firmwareData.begin(), firmwareData.begin() + programSize); dataRom.insert(dataRom.end(), firmwareData.begin() + programSize, firmwareData.end()); return true; } else { VirtualFile splitFirmwareProg( FolderUtilities::CombinePath(FolderUtilities::GetFirmwareFolder(), splitFilenameProgram)); VirtualFile splitFirmwareData( FolderUtilities::CombinePath(FolderUtilities::GetFirmwareFolder(), splitFilenameData)); if (splitFirmwareProg.GetSize() == programSize && splitFirmwareData.GetSize() == dataSize) { splitFirmwareProg.ReadFile(programRom); splitFirmwareData.ReadFile(dataRom); return true; } } return false; } static bool AttemptLoadBsxFirmware(uint8_t** prgRom, uint32_t& prgSize) { VirtualFile firmware(FolderUtilities::CombinePath(FolderUtilities::GetFirmwareFolder(), "BS-X.bin")); if (firmware.IsValid() && firmware.GetSize() >= 0x8000) { *prgRom = new uint8_t[firmware.GetSize()]; prgSize = (uint32_t)firmware.GetSize(); firmware.ReadFile(*prgRom, (uint32_t)firmware.GetSize()); return true; } return false; } static bool AttemptLoadFirmware(uint8_t** out, string filename, uint32_t size, string altFilename = "") { string path = FolderUtilities::CombinePath(FolderUtilities::GetFirmwareFolder(), filename); VirtualFile firmware(path); if ((!firmware.IsValid() || firmware.GetSize() != size) && !altFilename.empty()) { string altPath = FolderUtilities::CombinePath(FolderUtilities::GetFirmwareFolder(), altFilename); firmware = VirtualFile(altPath); } if (firmware.IsValid() && firmware.GetSize() == size) { *out = new uint8_t[firmware.GetSize()]; firmware.ReadFile(*out, (uint32_t)firmware.GetSize()); return true; } return false; } public: static bool LoadDspFirmware(Console* console, FirmwareType type, string combinedFilename, string splitFilenameProgram, string splitFilenameData, vector& programRom, vector& dataRom, vector& embeddedFirware, uint32_t programSize = 0x1800, uint32_t dataSize = 0x800) { if (embeddedFirware.size() == programSize + dataSize) { programRom.insert(programRom.end(), embeddedFirware.begin(), embeddedFirware.begin() + programSize); dataRom.insert(dataRom.end(), embeddedFirware.begin() + programSize, embeddedFirware.end()); return true; } else if (AttemptLoadDspFirmware(combinedFilename, splitFilenameProgram, splitFilenameData, programRom, dataRom, programSize, dataSize)) { return true; } MissingFirmwareMessage msg; msg.Filename = combinedFilename.c_str(); msg.Firmware = type; msg.Size = programSize + dataSize; console->GetNotificationManager()->SendNotification(ConsoleNotificationType::MissingFirmware, &msg); //Try again in case the user selected a valid firmware file if (AttemptLoadDspFirmware(combinedFilename, splitFilenameProgram, splitFilenameData, programRom, dataRom, programSize, dataSize)) { return true; } MessageManager::DisplayMessage("Error", "Could not find firmware file for DSP: " + combinedFilename); return false; } static bool LoadBsxFirmware(Console* console, uint8_t** prgRom, uint32_t& prgSize) { if (AttemptLoadBsxFirmware(prgRom, prgSize)) { return true; } MissingFirmwareMessage msg; msg.Filename = "BS-X.bin"; msg.Firmware = FirmwareType::Satellaview; msg.Size = 1024 * 1024; console->GetNotificationManager()->SendNotification(ConsoleNotificationType::MissingFirmware, &msg); if (AttemptLoadBsxFirmware(prgRom, prgSize)) { return true; } MessageManager::DisplayMessage("Error", "Could not find firmware file for BS-X"); return false; } static bool LoadSgbFirmware(Console* console, uint8_t** prgRom, uint32_t& prgSize, bool useSgb2) { string filename = useSgb2 ? "SGB2.sfc" : "SGB1.sfc"; prgSize = useSgb2 ? 0x80000 : 0x40000; if (AttemptLoadFirmware(prgRom, filename, prgSize)) { return true; } MissingFirmwareMessage msg; msg.Filename = filename.c_str(); msg.Firmware = useSgb2 ? FirmwareType::SGB2 : FirmwareType::SGB1; msg.Size = prgSize; console->GetNotificationManager()->SendNotification(ConsoleNotificationType::MissingFirmware, &msg); if (AttemptLoadFirmware(prgRom, filename, prgSize)) { return true; } MessageManager::DisplayMessage("Error", "Could not find firmware file for Super Game Boy"); return false; } static bool LoadGbBootRom(Console* console, uint8_t** bootRom, FirmwareType type) { string filename; string altFilename; switch (type) { default: case FirmwareType::Gameboy: filename = "dmg_boot.bin"; altFilename = "gb_bios.bin"; break; case FirmwareType::GameboyColor: filename = "cgb_boot.bin"; altFilename = "gbc_bios.bin"; break; case FirmwareType::Sgb1GameboyCpu: filename = "sgb_boot.bin"; altFilename = "sgb_bios.bin"; break; case FirmwareType::Sgb2GameboyCpu: filename = "sgb2_boot.bin"; altFilename = "sgb_bios.bin"; break; } uint32_t size = type == FirmwareType::GameboyColor ? 2304 : 256; if (AttemptLoadFirmware(bootRom, filename, size, altFilename)) { return true; } /*MissingFirmwareMessage msg; msg.Filename = filename.c_str(); msg.Firmware = type; msg.Size = size; console->GetNotificationManager()->SendNotification(ConsoleNotificationType::MissingFirmware, &msg); if(AttemptLoadFirmware(bootRom, filename, size)) { return true; } MessageManager::DisplayMessage("Error", "Could not find boot rom: " + filename);*/ return false; } };