mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
SNES: Add support for Sufami Turbo games
This commit is contained in:
parent
8d6830a70a
commit
18269da46b
26 changed files with 333 additions and 37 deletions
|
@ -119,6 +119,7 @@
|
||||||
<ClInclude Include="SNES\Coprocessors\ST018\ArmV3Types.h" />
|
<ClInclude Include="SNES\Coprocessors\ST018\ArmV3Types.h" />
|
||||||
<ClInclude Include="SNES\Coprocessors\ST018\St018.h" />
|
<ClInclude Include="SNES\Coprocessors\ST018\St018.h" />
|
||||||
<ClInclude Include="SNES\Coprocessors\ST018\St018Types.h" />
|
<ClInclude Include="SNES\Coprocessors\ST018\St018Types.h" />
|
||||||
|
<ClInclude Include="SNES\Coprocessors\SufamiTurbo\SufamiTurbo.h" />
|
||||||
<ClInclude Include="SNES\Debugger\DummyArmV3Cpu.h" />
|
<ClInclude Include="SNES\Debugger\DummyArmV3Cpu.h" />
|
||||||
<ClInclude Include="SNES\Debugger\St018Debugger.h" />
|
<ClInclude Include="SNES\Debugger\St018Debugger.h" />
|
||||||
<ClInclude Include="SNES\Debugger\St018DisUtils.h" />
|
<ClInclude Include="SNES\Debugger\St018DisUtils.h" />
|
||||||
|
|
|
@ -2970,6 +2970,9 @@
|
||||||
<ClInclude Include="Shared\ArmEnums.h">
|
<ClInclude Include="Shared\ArmEnums.h">
|
||||||
<Filter>Shared</Filter>
|
<Filter>Shared</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="SNES\Coprocessors\SufamiTurbo\SufamiTurbo.h">
|
||||||
|
<Filter>SNES\Coprocessors\SufamiTurbo</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Shared\Video\RotateFilter.cpp">
|
<ClCompile Include="Shared\Video\RotateFilter.cpp">
|
||||||
|
@ -3457,5 +3460,8 @@
|
||||||
<Filter Include="SNES\Coprocessors\ST018">
|
<Filter Include="SNES\Coprocessors\ST018">
|
||||||
<UniqueIdentifier>{387c0b44-8063-45e8-a28a-b6d9e27b5a3f}</UniqueIdentifier>
|
<UniqueIdentifier>{387c0b44-8063-45e8-a28a-b6d9e27b5a3f}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="SNES\Coprocessors\SufamiTurbo">
|
||||||
|
<UniqueIdentifier>{bfdd4bb9-41c2-4255-a8c3-0176c990cbf3}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -61,6 +61,9 @@ public:
|
||||||
case MemoryType::SnesWorkRam:
|
case MemoryType::SnesWorkRam:
|
||||||
case MemoryType::BsxMemoryPack:
|
case MemoryType::BsxMemoryPack:
|
||||||
case MemoryType::BsxPsRam:
|
case MemoryType::BsxPsRam:
|
||||||
|
case MemoryType::SufamiTurboFirmware:
|
||||||
|
case MemoryType::SufamiTurboSecondCart:
|
||||||
|
case MemoryType::SufamiTurboSecondCartRam:
|
||||||
case MemoryType::SnesRegister:
|
case MemoryType::SnesRegister:
|
||||||
return CpuType::Snes;
|
return CpuType::Snes;
|
||||||
|
|
||||||
|
@ -232,6 +235,8 @@ public:
|
||||||
case MemoryType::DspProgramRom:
|
case MemoryType::DspProgramRom:
|
||||||
case MemoryType::St018PrgRom:
|
case MemoryType::St018PrgRom:
|
||||||
case MemoryType::St018DataRom:
|
case MemoryType::St018DataRom:
|
||||||
|
case MemoryType::SufamiTurboFirmware:
|
||||||
|
case MemoryType::SufamiTurboSecondCart:
|
||||||
case MemoryType::SpcRom:
|
case MemoryType::SpcRom:
|
||||||
case MemoryType::SmsPrgRom:
|
case MemoryType::SmsPrgRom:
|
||||||
case MemoryType::SmsBootRom:
|
case MemoryType::SmsBootRom:
|
||||||
|
@ -255,6 +260,7 @@ public:
|
||||||
case MemoryType::NesSaveRam:
|
case MemoryType::NesSaveRam:
|
||||||
case MemoryType::GbCartRam:
|
case MemoryType::GbCartRam:
|
||||||
case MemoryType::SnesSaveRam:
|
case MemoryType::SnesSaveRam:
|
||||||
|
case MemoryType::SufamiTurboSecondCartRam:
|
||||||
case MemoryType::PceSaveRam:
|
case MemoryType::PceSaveRam:
|
||||||
case MemoryType::SnesRegister:
|
case MemoryType::SnesRegister:
|
||||||
case MemoryType::SmsCartRam:
|
case MemoryType::SmsCartRam:
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "SNES/Coprocessors/BSX/BsxCart.h"
|
#include "SNES/Coprocessors/BSX/BsxCart.h"
|
||||||
#include "SNES/Coprocessors/BSX/BsxMemoryPack.h"
|
#include "SNES/Coprocessors/BSX/BsxMemoryPack.h"
|
||||||
#include "SNES/Coprocessors/SGB/SuperGameboy.h"
|
#include "SNES/Coprocessors/SGB/SuperGameboy.h"
|
||||||
|
#include "SNES/Coprocessors/SufamiTurbo/SufamiTurbo.h"
|
||||||
#include "Shared/EmuSettings.h"
|
#include "Shared/EmuSettings.h"
|
||||||
#include "Shared/SettingTypes.h"
|
#include "Shared/SettingTypes.h"
|
||||||
#include "Shared/BatteryManager.h"
|
#include "Shared/BatteryManager.h"
|
||||||
|
@ -64,12 +65,18 @@ unique_ptr<BaseCartridge> BaseCartridge::CreateCartridge(SnesConsole* console, V
|
||||||
}
|
}
|
||||||
cart->LoadRom();
|
cart->LoadRom();
|
||||||
cart->_emu->RegisterMemory(MemoryType::SnesPrgRom, cart->_prgRom, cart->_prgRomSize);
|
cart->_emu->RegisterMemory(MemoryType::SnesPrgRom, cart->_prgRom, cart->_prgRomSize);
|
||||||
|
} else if(fileExt == ".st") {
|
||||||
|
if(cart->LoadSufamiTurbo(romFile)) {
|
||||||
|
return cart;
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
} else if(fileExt == ".gb" || fileExt == ".gbc" || fileExt == ".gbx") {
|
} else if(fileExt == ".gb" || fileExt == ".gbc" || fileExt == ".gbx") {
|
||||||
if(cart->LoadGameboy(romFile)) {
|
if(cart->LoadGameboy(romFile)) {
|
||||||
return cart;
|
return cart;
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(romData.size() < 0x8000) {
|
if(romData.size() < 0x8000) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -88,7 +95,7 @@ unique_ptr<BaseCartridge> BaseCartridge::CreateCartridge(SnesConsole* console, V
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cart->LoadRom();
|
cart->LoadRom();
|
||||||
cart->EnsureValidPrgRomSize();
|
BaseCartridge::EnsureValidPrgRomSize(cart->_prgRomSize, cart->_prgRom);
|
||||||
}
|
}
|
||||||
|
|
||||||
cart->_emu->RegisterMemory(MemoryType::SnesPrgRom, cart->_prgRom, cart->_prgRomSize);
|
cart->_emu->RegisterMemory(MemoryType::SnesPrgRom, cart->_prgRom, cart->_prgRomSize);
|
||||||
|
@ -100,18 +107,18 @@ unique_ptr<BaseCartridge> BaseCartridge::CreateCartridge(SnesConsole* console, V
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseCartridge::EnsureValidPrgRomSize()
|
void BaseCartridge::EnsureValidPrgRomSize(uint32_t& size, uint8_t*& rom)
|
||||||
{
|
{
|
||||||
if((_prgRomSize & 0xFFF) != 0) {
|
if((size & 0xFFF) != 0) {
|
||||||
//Round up to the next 4kb size, to ensure we have access to all the rom's data
|
//Round up to the next 4kb size, to ensure we have access to all the rom's data
|
||||||
//Memory mappings expect a multiple of 4kb to work properly
|
//Memory mappings expect a multiple of 4kb to work properly
|
||||||
uint32_t orgPrgSize = _prgRomSize;
|
uint32_t orgPrgSize = size;
|
||||||
_prgRomSize = (_prgRomSize & ~0xFFF) + 0x1000;
|
size = (size & ~0xFFF) + 0x1000;
|
||||||
uint8_t* expandedPrgRom = new uint8_t[_prgRomSize];
|
uint8_t* expandedPrgRom = new uint8_t[size];
|
||||||
memset(expandedPrgRom, 0, _prgRomSize);
|
memset(expandedPrgRom, 0, size);
|
||||||
memcpy(expandedPrgRom, _prgRom, orgPrgSize);
|
memcpy(expandedPrgRom, rom, orgPrgSize);
|
||||||
delete[] _prgRom;
|
delete[] rom;
|
||||||
_prgRom = expandedPrgRom;
|
rom = expandedPrgRom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,6 +411,10 @@ void BaseCartridge::SaveBattery()
|
||||||
if(_gameboy) {
|
if(_gameboy) {
|
||||||
_gameboy->SaveBattery();
|
_gameboy->SaveBattery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_sufamiTurbo) {
|
||||||
|
_sufamiTurbo->SaveBattery();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseCartridge::Init(MemoryMappings &mm)
|
void BaseCartridge::Init(MemoryMappings &mm)
|
||||||
|
@ -555,7 +566,11 @@ bool BaseCartridge::MapSpecificCarts(MemoryMappings &mm)
|
||||||
{
|
{
|
||||||
string name = GetCartName();
|
string name = GetCartName();
|
||||||
string code = GetGameCode();
|
string code = GetGameCode();
|
||||||
if(GetCartName() == "DEZAEMON") {
|
|
||||||
|
if(_sufamiTurbo) {
|
||||||
|
_sufamiTurbo->InitializeMappings(mm, _prgRomHandlers, _saveRamHandlers);
|
||||||
|
return true;
|
||||||
|
} else if(GetCartName() == "DEZAEMON") {
|
||||||
//LOROM with mirrored SRAM?
|
//LOROM with mirrored SRAM?
|
||||||
mm.RegisterHandler(0x00, 0x7D, 0x8000, 0xFFFF, _prgRomHandlers);
|
mm.RegisterHandler(0x00, 0x7D, 0x8000, 0xFFFF, _prgRomHandlers);
|
||||||
mm.RegisterHandler(0x80, 0xFF, 0x8000, 0xFFFF, _prgRomHandlers);
|
mm.RegisterHandler(0x80, 0xFF, 0x8000, 0xFFFF, _prgRomHandlers);
|
||||||
|
@ -644,6 +659,30 @@ void BaseCartridge::LoadSpc()
|
||||||
SetupCpuHalt();
|
SetupCpuHalt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BaseCartridge::LoadSufamiTurbo(VirtualFile& romFile)
|
||||||
|
{
|
||||||
|
_sufamiTurbo.reset(SufamiTurbo::Init(_emu, romFile));
|
||||||
|
if(!_sufamiTurbo) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<uint8_t> romData;
|
||||||
|
romFile.ReadFile(romData);
|
||||||
|
|
||||||
|
_prgRomSize = (uint32_t)romData.size();
|
||||||
|
_prgRom = new uint8_t[_prgRomSize];
|
||||||
|
memcpy(_prgRom, romData.data(), romData.size());
|
||||||
|
BaseCartridge::EnsureValidPrgRomSize(_prgRomSize, _prgRom);
|
||||||
|
_emu->RegisterMemory(MemoryType::SnesPrgRom, _prgRom, _prgRomSize);
|
||||||
|
|
||||||
|
_saveRamSize = SufamiTurbo::GetSaveRamSize(romData);
|
||||||
|
_saveRam = new uint8_t[_saveRamSize];
|
||||||
|
_emu->RegisterMemory(MemoryType::SnesSaveRam, _saveRam, _saveRamSize);
|
||||||
|
_emu->GetSettings()->InitializeRam(GetRamPowerOnState(), _saveRam, _saveRamSize);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool BaseCartridge::LoadGameboy(VirtualFile& romFile)
|
bool BaseCartridge::LoadGameboy(VirtualFile& romFile)
|
||||||
{
|
{
|
||||||
_cartInfo = { };
|
_cartInfo = { };
|
||||||
|
|
|
@ -21,6 +21,7 @@ class Gameboy;
|
||||||
class SnesConsole;
|
class SnesConsole;
|
||||||
class Emulator;
|
class Emulator;
|
||||||
class SpcFileData;
|
class SpcFileData;
|
||||||
|
class SufamiTurbo;
|
||||||
enum class ConsoleRegion;
|
enum class ConsoleRegion;
|
||||||
enum class RamState;
|
enum class RamState;
|
||||||
|
|
||||||
|
@ -47,6 +48,7 @@ private:
|
||||||
BsxCart* _bsx = nullptr;
|
BsxCart* _bsx = nullptr;
|
||||||
unique_ptr<BsxMemoryPack> _bsxMemPack;
|
unique_ptr<BsxMemoryPack> _bsxMemPack;
|
||||||
unique_ptr<Gameboy> _gameboy;
|
unique_ptr<Gameboy> _gameboy;
|
||||||
|
unique_ptr<SufamiTurbo> _sufamiTurbo;
|
||||||
|
|
||||||
CartFlags::CartFlags _flags = CartFlags::CartFlags::None;
|
CartFlags::CartFlags _flags = CartFlags::CartFlags::None;
|
||||||
CoprocessorType _coprocessorType = CoprocessorType::None;
|
CoprocessorType _coprocessorType = CoprocessorType::None;
|
||||||
|
@ -83,10 +85,13 @@ private:
|
||||||
void InitRamPowerOnState();
|
void InitRamPowerOnState();
|
||||||
|
|
||||||
void LoadRom();
|
void LoadRom();
|
||||||
void EnsureValidPrgRomSize();
|
|
||||||
|
|
||||||
void LoadSpc();
|
void LoadSpc();
|
||||||
|
|
||||||
|
bool LoadSufamiTurbo(VirtualFile& romFile);
|
||||||
|
|
||||||
bool LoadGameboy(VirtualFile& romFile);
|
bool LoadGameboy(VirtualFile& romFile);
|
||||||
|
|
||||||
void SetupCpuHalt();
|
void SetupCpuHalt();
|
||||||
void InitCoprocessor();
|
void InitCoprocessor();
|
||||||
void LoadEmbeddedFirmware();
|
void LoadEmbeddedFirmware();
|
||||||
|
@ -99,6 +104,8 @@ public:
|
||||||
|
|
||||||
static unique_ptr<BaseCartridge> CreateCartridge(SnesConsole* console, VirtualFile &romFile);
|
static unique_ptr<BaseCartridge> CreateCartridge(SnesConsole* console, VirtualFile &romFile);
|
||||||
|
|
||||||
|
static void EnsureValidPrgRomSize(uint32_t& size, uint8_t*& rom);
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
void SaveBattery();
|
void SaveBattery();
|
||||||
|
|
148
Core/SNES/Coprocessors/SufamiTurbo/SufamiTurbo.h
Normal file
148
Core/SNES/Coprocessors/SufamiTurbo/SufamiTurbo.h
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
#pragma once
|
||||||
|
#include "pch.h"
|
||||||
|
#include "SNES/IMemoryHandler.h"
|
||||||
|
#include "SNES/RomHandler.h"
|
||||||
|
#include "SNES/MemoryMappings.h"
|
||||||
|
#include "Shared/Emulator.h"
|
||||||
|
#include "Shared/BatteryManager.h"
|
||||||
|
#include "Shared/FirmwareHelper.h"
|
||||||
|
#include "Utilities/VirtualFile.h"
|
||||||
|
|
||||||
|
struct SufamiTurboFilePromptMessage
|
||||||
|
{
|
||||||
|
char Filename[5000];
|
||||||
|
};
|
||||||
|
|
||||||
|
class SufamiTurbo
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Emulator* _emu = nullptr;
|
||||||
|
string _nameSlotA;
|
||||||
|
|
||||||
|
uint8_t* _firmware = nullptr;
|
||||||
|
uint32_t _firmwareSize = 0;
|
||||||
|
|
||||||
|
string _cartName;
|
||||||
|
uint8_t* _cartRom = nullptr;
|
||||||
|
uint32_t _cartRomSize = 0;
|
||||||
|
|
||||||
|
uint8_t* _cartRam = nullptr;
|
||||||
|
uint32_t _cartRamSize = 0;
|
||||||
|
|
||||||
|
vector<unique_ptr<IMemoryHandler>> _firmwareHandlers;
|
||||||
|
vector<unique_ptr<IMemoryHandler>> _cartRomHandlers;
|
||||||
|
vector<unique_ptr<IMemoryHandler>> _cartRamHandlers;
|
||||||
|
|
||||||
|
SufamiTurbo() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static SufamiTurbo* Init(Emulator* emu, VirtualFile& slotA)
|
||||||
|
{
|
||||||
|
vector<uint8_t> firmware;
|
||||||
|
if(!FirmwareHelper::LoadSufamiTurboFirmware(emu, firmware)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SufamiTurbo* st = new SufamiTurbo();
|
||||||
|
st->_emu = emu;
|
||||||
|
st->_nameSlotA = FolderUtilities::GetFilename(slotA.GetFileName(), false);
|
||||||
|
|
||||||
|
st->_firmwareSize = (uint32_t)firmware.size();
|
||||||
|
st->_firmware = new uint8_t[st->_firmwareSize];
|
||||||
|
memcpy(st->_firmware, firmware.data(), firmware.size());
|
||||||
|
BaseCartridge::EnsureValidPrgRomSize(st->_firmwareSize, st->_firmware);
|
||||||
|
emu->RegisterMemory(MemoryType::SufamiTurboFirmware, st->_firmware, st->_firmwareSize);
|
||||||
|
for(uint32_t i = 0; i < st->_firmwareSize; i += 0x1000) {
|
||||||
|
st->_firmwareHandlers.push_back(unique_ptr<RomHandler>(new RomHandler(st->_firmware, i, st->_firmwareSize, MemoryType::SufamiTurboFirmware)));
|
||||||
|
}
|
||||||
|
|
||||||
|
SufamiTurboFilePromptMessage msg = {};
|
||||||
|
emu->GetNotificationManager()->SendNotification(ConsoleNotificationType::SufamiTurboFilePrompt, &msg);
|
||||||
|
|
||||||
|
string slot2File = string(msg.Filename, strlen(msg.Filename));
|
||||||
|
if(slot2File.size()) {
|
||||||
|
VirtualFile file = slot2File;
|
||||||
|
if(file.IsValid()) {
|
||||||
|
vector<uint8_t> cart;
|
||||||
|
file.ReadFile(cart);
|
||||||
|
|
||||||
|
st->_cartName = FolderUtilities::GetFilename(file.GetFileName(), false);
|
||||||
|
if(st->_nameSlotA == st->_cartName) {
|
||||||
|
st->_cartName += "_SlotB";
|
||||||
|
}
|
||||||
|
|
||||||
|
st->_cartRomSize = (uint32_t)cart.size();
|
||||||
|
st->_cartRom = new uint8_t[st->_cartRomSize];
|
||||||
|
memcpy(st->_cartRom, cart.data(), cart.size());
|
||||||
|
BaseCartridge::EnsureValidPrgRomSize(st->_cartRomSize, st->_cartRom);
|
||||||
|
|
||||||
|
emu->RegisterMemory(MemoryType::SufamiTurboSecondCart, st->_cartRom, st->_cartRomSize);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < st->_cartRomSize; i += 0x1000) {
|
||||||
|
st->_cartRomHandlers.push_back(unique_ptr<RomHandler>(new RomHandler(st->_cartRom, i, st->_cartRomSize, MemoryType::SufamiTurboSecondCart)));
|
||||||
|
}
|
||||||
|
|
||||||
|
st->_cartRamSize = GetSaveRamSize(cart);
|
||||||
|
st->_cartRam = new uint8_t[st->_cartRamSize];
|
||||||
|
emu->RegisterMemory(MemoryType::SufamiTurboSecondCartRam, st->_cartRam, st->_cartRamSize);
|
||||||
|
memset(st->_cartRam, 0, st->_cartRamSize);
|
||||||
|
|
||||||
|
emu->GetBatteryManager()->LoadBattery(st->_cartName + ".srm", st->_cartRam, st->_cartRamSize);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < st->_cartRamSize; i += 0x1000) {
|
||||||
|
st->_cartRamHandlers.push_back(unique_ptr<RamHandler>(new RamHandler(st->_cartRam, i, st->_cartRamSize, MemoryType::SufamiTurboSecondCartRam)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t GetSaveRamSize(vector<uint8_t>& cart)
|
||||||
|
{
|
||||||
|
auto checkMarker = [&](string marker) {
|
||||||
|
return std::search((char*)cart.data(), (char*)cart.data()+cart.size(), marker.c_str(), marker.c_str()+marker.size()) != (char*)cart.data() + cart.size();
|
||||||
|
};
|
||||||
|
|
||||||
|
if(checkMarker("POIPOI.Ver") || checkMarker("SDBATTLE ")) {
|
||||||
|
return 0x800;
|
||||||
|
} else if(checkMarker("SD \xB6\xDE\xDD\xC0\xDE\xD1 GN")) {
|
||||||
|
//SD ガンダム GN
|
||||||
|
return 0x2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeMappings(MemoryMappings& mm, vector<unique_ptr<IMemoryHandler>>& prgRomHandlers, vector<unique_ptr<IMemoryHandler>>& saveRamHandlers)
|
||||||
|
{
|
||||||
|
mm.RegisterHandler(0x20, 0x3F, 0x8000, 0xFFFF, prgRomHandlers);
|
||||||
|
mm.RegisterHandler(0xA0, 0xBF, 0x8000, 0xFFFF, prgRomHandlers);
|
||||||
|
|
||||||
|
mm.RegisterHandler(0x60, 0x63, 0x8000, 0xFFFF, saveRamHandlers);
|
||||||
|
mm.RegisterHandler(0xE0, 0xE3, 0x8000, 0xFFFF, saveRamHandlers);
|
||||||
|
|
||||||
|
mm.RegisterHandler(0x00, 0x1F, 0x8000, 0xFFFF, _firmwareHandlers);
|
||||||
|
mm.RegisterHandler(0x80, 0x9F, 0x8000, 0xFFFF, _firmwareHandlers);
|
||||||
|
|
||||||
|
mm.RegisterHandler(0x40, 0x5F, 0x8000, 0xFFFF, _cartRomHandlers);
|
||||||
|
mm.RegisterHandler(0xC0, 0xDF, 0x8000, 0xFFFF, _cartRomHandlers);
|
||||||
|
|
||||||
|
mm.RegisterHandler(0x70, 0x73, 0x8000, 0xFFFF, _cartRamHandlers);
|
||||||
|
mm.RegisterHandler(0xF0, 0xF3, 0x8000, 0xFFFF, _cartRamHandlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveBattery()
|
||||||
|
{
|
||||||
|
if(_cartRam) {
|
||||||
|
_emu->GetBatteryManager()->SaveBattery(_cartName + ".srm", _cartRam, _cartRamSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~SufamiTurbo()
|
||||||
|
{
|
||||||
|
delete[] _firmware;
|
||||||
|
delete[] _cartRom;
|
||||||
|
delete[] _cartRam;
|
||||||
|
}
|
||||||
|
};
|
|
@ -472,6 +472,7 @@ AddressInfo SnesConsole::GetRelativeAddress(AddressInfo& absAddress, CpuType cpu
|
||||||
case MemoryType::SnesPrgRom:
|
case MemoryType::SnesPrgRom:
|
||||||
case MemoryType::SnesWorkRam:
|
case MemoryType::SnesWorkRam:
|
||||||
case MemoryType::SnesSaveRam:
|
case MemoryType::SnesSaveRam:
|
||||||
|
case MemoryType::SufamiTurboFirmware:
|
||||||
{
|
{
|
||||||
if(!mappings) {
|
if(!mappings) {
|
||||||
return unmapped;
|
return unmapped;
|
||||||
|
|
|
@ -72,7 +72,7 @@ public:
|
||||||
SnesConsole(Emulator* emu);
|
SnesConsole(Emulator* emu);
|
||||||
~SnesConsole();
|
~SnesConsole();
|
||||||
|
|
||||||
static vector<string> GetSupportedExtensions() { return { ".sfc", ".swc", ".fig", ".smc", ".bs", ".gb", ".gbc", ".gbx", ".spc" }; }
|
static vector<string> GetSupportedExtensions() { return { ".sfc", ".swc", ".fig", ".smc", ".bs", ".gb", ".gbc", ".gbx", ".spc", ".st" }; }
|
||||||
static vector<string> GetSupportedSignatures() { return { "SNES-SPC700 Sound File Data" }; }
|
static vector<string> GetSupportedSignatures() { return { "SNES-SPC700 Sound File Data" }; }
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "Shared/BatteryManager.h"
|
#include "Shared/BatteryManager.h"
|
||||||
#include "Utilities/VirtualFile.h"
|
#include "Utilities/VirtualFile.h"
|
||||||
#include "Utilities/FolderUtilities.h"
|
#include "Utilities/FolderUtilities.h"
|
||||||
|
#include "Utilities/StringUtilities.h"
|
||||||
|
|
||||||
void BatteryManager::Initialize(string romName, bool setBatteryFlag)
|
void BatteryManager::Initialize(string romName, bool setBatteryFlag)
|
||||||
{
|
{
|
||||||
|
@ -9,9 +10,13 @@ void BatteryManager::Initialize(string romName, bool setBatteryFlag)
|
||||||
_hasBattery = setBatteryFlag;
|
_hasBattery = setBatteryFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
string BatteryManager::GetBasePath()
|
string BatteryManager::GetBasePath(string& extension)
|
||||||
{
|
{
|
||||||
return FolderUtilities::CombinePath(FolderUtilities::GetSaveFolder(), _romName);
|
if(StringUtilities::StartsWith(extension, ".")) {
|
||||||
|
return FolderUtilities::CombinePath(FolderUtilities::GetSaveFolder(), _romName + extension);
|
||||||
|
} else {
|
||||||
|
return FolderUtilities::CombinePath(FolderUtilities::GetSaveFolder(), extension);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BatteryManager::SetBatteryProvider(shared_ptr<IBatteryProvider> provider)
|
void BatteryManager::SetBatteryProvider(shared_ptr<IBatteryProvider> provider)
|
||||||
|
@ -32,7 +37,7 @@ void BatteryManager::SaveBattery(string extension, uint8_t* data, uint32_t lengt
|
||||||
}
|
}
|
||||||
|
|
||||||
_hasBattery = true;
|
_hasBattery = true;
|
||||||
ofstream out(GetBasePath() + extension, ios::binary);
|
ofstream out(GetBasePath(extension), ios::binary);
|
||||||
if(out) {
|
if(out) {
|
||||||
out.write((char*)data, length);
|
out.write((char*)data, length);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +57,7 @@ vector<uint8_t> BatteryManager::LoadBattery(string extension)
|
||||||
//Used by movie player to provider initial state of ram at startup
|
//Used by movie player to provider initial state of ram at startup
|
||||||
batteryData = provider->LoadBattery(extension);
|
batteryData = provider->LoadBattery(extension);
|
||||||
} else {
|
} else {
|
||||||
VirtualFile file = GetBasePath() + extension;
|
VirtualFile file = GetBasePath(extension);
|
||||||
if(file.IsValid()) {
|
if(file.IsValid()) {
|
||||||
file.ReadFile(batteryData);
|
file.ReadFile(batteryData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ private:
|
||||||
std::weak_ptr<IBatteryProvider> _provider;
|
std::weak_ptr<IBatteryProvider> _provider;
|
||||||
std::weak_ptr<IBatteryRecorder> _recorder;
|
std::weak_ptr<IBatteryRecorder> _recorder;
|
||||||
|
|
||||||
string GetBasePath();
|
string GetBasePath(string& extension);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Initialize(string romName, bool setBatteryFlag = false);
|
void Initialize(string romName, bool setBatteryFlag = false);
|
||||||
|
|
|
@ -16,6 +16,7 @@ enum class FirmwareType
|
||||||
ST011,
|
ST011,
|
||||||
ST018,
|
ST018,
|
||||||
Satellaview,
|
Satellaview,
|
||||||
|
SufamiTurbo,
|
||||||
Gameboy,
|
Gameboy,
|
||||||
GameboyColor,
|
GameboyColor,
|
||||||
GameboyAdvance,
|
GameboyAdvance,
|
||||||
|
@ -185,6 +186,25 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool LoadSufamiTurboFirmware(Emulator* emu, vector<uint8_t>& data)
|
||||||
|
{
|
||||||
|
string filename = "SufamiTurbo.sfc";
|
||||||
|
|
||||||
|
if(AttemptLoadFirmware(data, filename, 0x40000)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MissingFirmwareMessage msg(filename.c_str(), FirmwareType::SufamiTurbo, 0x40000);
|
||||||
|
emu->GetNotificationManager()->SendNotification(ConsoleNotificationType::MissingFirmware, &msg);
|
||||||
|
|
||||||
|
if(AttemptLoadFirmware(data, filename, 0x40000)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageManager::DisplayMessage("Error", "Could not find firmware file for Sufami Turbo");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool LoadSgbFirmware(Emulator* emu, uint8_t** prgRom, uint32_t& prgSize, bool useSgb2, bool promptForFirmware)
|
static bool LoadSgbFirmware(Emulator* emu, uint8_t** prgRom, uint32_t& prgSize, bool useSgb2, bool promptForFirmware)
|
||||||
{
|
{
|
||||||
string filename = useSgb2 ? "SGB2.sfc" : "SGB1.sfc";
|
string filename = useSgb2 ? "SGB2.sfc" : "SGB1.sfc";
|
||||||
|
|
|
@ -22,6 +22,7 @@ enum class ConsoleNotificationType
|
||||||
ViewerRefresh,
|
ViewerRefresh,
|
||||||
EventViewerRefresh,
|
EventViewerRefresh,
|
||||||
MissingFirmware,
|
MissingFirmware,
|
||||||
|
SufamiTurboFilePrompt,
|
||||||
BeforeGameUnload,
|
BeforeGameUnload,
|
||||||
BeforeGameLoad,
|
BeforeGameLoad,
|
||||||
GameLoadFailed,
|
GameLoadFailed,
|
||||||
|
|
|
@ -38,6 +38,9 @@ enum class MemoryType
|
||||||
St018PrgRom,
|
St018PrgRom,
|
||||||
St018DataRom,
|
St018DataRom,
|
||||||
St018WorkRam,
|
St018WorkRam,
|
||||||
|
SufamiTurboFirmware,
|
||||||
|
SufamiTurboSecondCart,
|
||||||
|
SufamiTurboSecondCartRam,
|
||||||
|
|
||||||
GbPrgRom,
|
GbPrgRom,
|
||||||
GbWorkRam,
|
GbWorkRam,
|
||||||
|
|
|
@ -76,6 +76,8 @@ namespace Mesen.Config
|
||||||
case MemoryType.PcePrgRom:
|
case MemoryType.PcePrgRom:
|
||||||
case MemoryType.SmsPrgRom:
|
case MemoryType.SmsPrgRom:
|
||||||
case MemoryType.SpcRom:
|
case MemoryType.SpcRom:
|
||||||
|
case MemoryType.SufamiTurboFirmware:
|
||||||
|
case MemoryType.SufamiTurboSecondCart:
|
||||||
case MemoryType.DspProgramRom:
|
case MemoryType.DspProgramRom:
|
||||||
case MemoryType.DspDataRom:
|
case MemoryType.DspDataRom:
|
||||||
case MemoryType.GbBootRom:
|
case MemoryType.GbBootRom:
|
||||||
|
@ -107,11 +109,12 @@ namespace Mesen.Config
|
||||||
return ImportWorkRamLabels;
|
return ImportWorkRamLabels;
|
||||||
|
|
||||||
case MemoryType.SnesSaveRam:
|
case MemoryType.SnesSaveRam:
|
||||||
|
case MemoryType.BsxMemoryPack:
|
||||||
|
case MemoryType.SufamiTurboSecondCartRam:
|
||||||
case MemoryType.NesSaveRam:
|
case MemoryType.NesSaveRam:
|
||||||
case MemoryType.PceSaveRam:
|
case MemoryType.PceSaveRam:
|
||||||
case MemoryType.GbCartRam:
|
case MemoryType.GbCartRam:
|
||||||
case MemoryType.SmsCartRam:
|
case MemoryType.SmsCartRam:
|
||||||
case MemoryType.BsxMemoryPack:
|
|
||||||
case MemoryType.GbaSaveRam:
|
case MemoryType.GbaSaveRam:
|
||||||
case MemoryType.WsCartRam:
|
case MemoryType.WsCartRam:
|
||||||
return ImportSaveRamLabels;
|
return ImportSaveRamLabels;
|
||||||
|
|
|
@ -58,6 +58,7 @@ namespace Mesen.Debugger.Utilities
|
||||||
RomFormat.Sg => true,
|
RomFormat.Sg => true,
|
||||||
RomFormat.ColecoVision => true,
|
RomFormat.ColecoVision => true,
|
||||||
RomFormat.Gba => true,
|
RomFormat.Gba => true,
|
||||||
|
RomFormat.Ws => true,
|
||||||
_ => false
|
_ => false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -621,6 +621,9 @@ namespace Mesen.Interop
|
||||||
St018PrgRom,
|
St018PrgRom,
|
||||||
St018DataRom,
|
St018DataRom,
|
||||||
St018WorkRam,
|
St018WorkRam,
|
||||||
|
SufamiTurboFirmware,
|
||||||
|
SufamiTurboSecondCart,
|
||||||
|
SufamiTurboSecondCartRam,
|
||||||
|
|
||||||
GbPrgRom,
|
GbPrgRom,
|
||||||
GbWorkRam,
|
GbWorkRam,
|
||||||
|
|
|
@ -257,6 +257,7 @@ namespace Mesen.Interop
|
||||||
ST011,
|
ST011,
|
||||||
ST018,
|
ST018,
|
||||||
Satellaview,
|
Satellaview,
|
||||||
|
SufamiTurbo,
|
||||||
Gameboy,
|
Gameboy,
|
||||||
GameboyColor,
|
GameboyColor,
|
||||||
GameboyAdvance,
|
GameboyAdvance,
|
||||||
|
@ -285,6 +286,12 @@ namespace Mesen.Interop
|
||||||
public UInt32 AltSize;
|
public UInt32 AltSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct SufamiTurboFilePromptMessage
|
||||||
|
{
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5000)]
|
||||||
|
public byte[] Filename;
|
||||||
|
}
|
||||||
|
|
||||||
public struct ExecuteShortcutParams
|
public struct ExecuteShortcutParams
|
||||||
{
|
{
|
||||||
public EmulatorShortcut Shortcut;
|
public EmulatorShortcut Shortcut;
|
||||||
|
|
|
@ -18,6 +18,8 @@ public static class FirmwareTypeExtensions
|
||||||
case FirmwareType.ST011: return new("st011.rom") { new(0xD000, "8B2B3F3F3E6E29F4D21D8BC736B400BC988B7D2214EBEE15643F01C1FEE2F364") };
|
case FirmwareType.ST011: return new("st011.rom") { new(0xD000, "8B2B3F3F3E6E29F4D21D8BC736B400BC988B7D2214EBEE15643F01C1FEE2F364") };
|
||||||
case FirmwareType.ST018: return new("st018.rom") { new(0x28000, "6DF209AB5D2524D1839C038BE400AE5EB20DAFC14A3771A3239CD9E8ACD53806") };
|
case FirmwareType.ST018: return new("st018.rom") { new(0x28000, "6DF209AB5D2524D1839C038BE400AE5EB20DAFC14A3771A3239CD9E8ACD53806") };
|
||||||
|
|
||||||
|
case FirmwareType.SufamiTurbo: return new("SufamiTurbo.sfc") { new(0x40000, "EDACB453DA14F825F05D1134D6035F4BF034E55F7CFB97C70C4EE107EABC7342") };
|
||||||
|
|
||||||
case FirmwareType.Satellaview: return new("BS-X.bin") {
|
case FirmwareType.Satellaview: return new("BS-X.bin") {
|
||||||
new(1024 * 1024,
|
new(1024 * 1024,
|
||||||
"27CFDB99F7E4252BF3740D420147B63C4C88616883BC5E7FE43F2F30BF8C8CBB", //Japan, no DRM
|
"27CFDB99F7E4252BF3740D420147B63C4C88616883BC5E7FE43F2F30BF8C8CBB", //Japan, no DRM
|
||||||
|
|
|
@ -71,6 +71,9 @@ namespace Mesen.Interop
|
||||||
case MemoryType.SnesCgRam:
|
case MemoryType.SnesCgRam:
|
||||||
case MemoryType.BsxPsRam:
|
case MemoryType.BsxPsRam:
|
||||||
case MemoryType.BsxMemoryPack:
|
case MemoryType.BsxMemoryPack:
|
||||||
|
case MemoryType.SufamiTurboFirmware:
|
||||||
|
case MemoryType.SufamiTurboSecondCart:
|
||||||
|
case MemoryType.SufamiTurboSecondCartRam:
|
||||||
case MemoryType.SnesRegister:
|
case MemoryType.SnesRegister:
|
||||||
return CpuType.Snes;
|
return CpuType.Snes;
|
||||||
|
|
||||||
|
@ -246,6 +249,8 @@ namespace Mesen.Interop
|
||||||
case MemoryType.DspProgramRom:
|
case MemoryType.DspProgramRom:
|
||||||
case MemoryType.St018PrgRom:
|
case MemoryType.St018PrgRom:
|
||||||
case MemoryType.St018DataRom:
|
case MemoryType.St018DataRom:
|
||||||
|
case MemoryType.SufamiTurboFirmware:
|
||||||
|
case MemoryType.SufamiTurboSecondCart:
|
||||||
case MemoryType.SpcRom:
|
case MemoryType.SpcRom:
|
||||||
case MemoryType.SmsPrgRom:
|
case MemoryType.SmsPrgRom:
|
||||||
case MemoryType.SmsBootRom:
|
case MemoryType.SmsBootRom:
|
||||||
|
@ -272,6 +277,9 @@ namespace Mesen.Interop
|
||||||
case MemoryType.St018PrgRom:
|
case MemoryType.St018PrgRom:
|
||||||
case MemoryType.St018DataRom:
|
case MemoryType.St018DataRom:
|
||||||
case MemoryType.St018WorkRam:
|
case MemoryType.St018WorkRam:
|
||||||
|
case MemoryType.SufamiTurboFirmware:
|
||||||
|
case MemoryType.SufamiTurboSecondCart:
|
||||||
|
case MemoryType.SufamiTurboSecondCartRam:
|
||||||
|
|
||||||
//Gameboy
|
//Gameboy
|
||||||
case MemoryType.GbPrgRom:
|
case MemoryType.GbPrgRom:
|
||||||
|
@ -461,6 +469,10 @@ namespace Mesen.Interop
|
||||||
|
|
||||||
MemoryType.BsxPsRam => "PSRAM",
|
MemoryType.BsxPsRam => "PSRAM",
|
||||||
MemoryType.BsxMemoryPack => "MPACK",
|
MemoryType.BsxMemoryPack => "MPACK",
|
||||||
|
|
||||||
|
MemoryType.SufamiTurboFirmware => "BOOT",
|
||||||
|
MemoryType.SufamiTurboSecondCart => "BPRG",
|
||||||
|
MemoryType.SufamiTurboSecondCartRam => "BRAM",
|
||||||
|
|
||||||
MemoryType.GameboyMemory => "CPU",
|
MemoryType.GameboyMemory => "CPU",
|
||||||
MemoryType.GbPrgRom => "PRG",
|
MemoryType.GbPrgRom => "PRG",
|
||||||
|
|
|
@ -80,6 +80,7 @@ namespace Mesen.Interop
|
||||||
ViewerRefresh,
|
ViewerRefresh,
|
||||||
EventViewerRefresh,
|
EventViewerRefresh,
|
||||||
MissingFirmware,
|
MissingFirmware,
|
||||||
|
SufamiTurboFilePrompt,
|
||||||
BeforeGameUnload,
|
BeforeGameUnload,
|
||||||
BeforeGameLoad,
|
BeforeGameLoad,
|
||||||
GameLoadFailed,
|
GameLoadFailed,
|
||||||
|
|
|
@ -1725,6 +1725,8 @@
|
||||||
<Message ID="PromptSaveChanges">Save changes?</Message>
|
<Message ID="PromptSaveChanges">Save changes?</Message>
|
||||||
<Message ID="PromptKeepChanges">Keep changes?</Message>
|
<Message ID="PromptKeepChanges">Keep changes?</Message>
|
||||||
|
|
||||||
|
<Message ID="PromptLoadSufamiTurbo">Do you want to load a second Sufami Turbo ROM to insert into slot B?</Message>
|
||||||
|
|
||||||
<Message ID="UnknownFirmwareHash">This file does not match any of the known firmwares and may not work properly.

Expected (SHA256): {0}
Current (SHA256): {1}</Message>
|
<Message ID="UnknownFirmwareHash">This file does not match any of the known firmwares and may not work properly.

Expected (SHA256): {0}
Current (SHA256): {1}</Message>
|
||||||
<Message ID="InvalidFirmwareSize">This file does not have the required size.

Expected: {0} bytes
Current: {1} bytes</Message>
|
<Message ID="InvalidFirmwareSize">This file does not have the required size.

Expected: {0} bytes
Current: {1} bytes</Message>
|
||||||
<Message ID="PromptDeleteFirmware">The following file will be deleted permanently. Are you sure?

{0}</Message>
|
<Message ID="PromptDeleteFirmware">The following file will be deleted permanently. Are you sure?

{0}</Message>
|
||||||
|
@ -2683,6 +2685,7 @@ E
|
||||||
<Value ID="ST010">ST010</Value>
|
<Value ID="ST010">ST010</Value>
|
||||||
<Value ID="ST011">ST011</Value>
|
<Value ID="ST011">ST011</Value>
|
||||||
<Value ID="ST018">ST018</Value>
|
<Value ID="ST018">ST018</Value>
|
||||||
|
<Value ID="SufamiTurbo">Sufami Turbo</Value>
|
||||||
<Value ID="Satellaview">Satellaview (BS-X)</Value>
|
<Value ID="Satellaview">Satellaview (BS-X)</Value>
|
||||||
<Value ID="Gameboy">Game Boy CPU</Value>
|
<Value ID="Gameboy">Game Boy CPU</Value>
|
||||||
<Value ID="GameboyColor">Game Boy Color CPU</Value>
|
<Value ID="GameboyColor">Game Boy Color CPU</Value>
|
||||||
|
@ -2749,7 +2752,10 @@ E
|
||||||
<Value ID="St018PrgRom">ST018 PRG ROM</Value>
|
<Value ID="St018PrgRom">ST018 PRG ROM</Value>
|
||||||
<Value ID="St018DataRom">ST018 Data ROM</Value>
|
<Value ID="St018DataRom">ST018 Data ROM</Value>
|
||||||
<Value ID="St018WorkRam">ST018 Work RAM</Value>
|
<Value ID="St018WorkRam">ST018 Work RAM</Value>
|
||||||
|
<Value ID="SufamiTurboFirmware">Sufami Turbo Firmware</Value>
|
||||||
|
<Value ID="SufamiTurboSecondCart">Sufami Slot B ROM</Value>
|
||||||
|
<Value ID="SufamiTurboSecondCartRam">Sufami Slot B RAM</Value>
|
||||||
|
|
||||||
<Value ID="GameboyMemory">GB - CPU Memory</Value>
|
<Value ID="GameboyMemory">GB - CPU Memory</Value>
|
||||||
<Value ID="GbPrgRom">GB - PRG ROM</Value>
|
<Value ID="GbPrgRom">GB - PRG ROM</Value>
|
||||||
<Value ID="GbWorkRam">GB - Work RAM</Value>
|
<Value ID="GbWorkRam">GB - Work RAM</Value>
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace Mesen.Utilities
|
||||||
public const string NesAsmLabelExt = "fns";
|
public const string NesAsmLabelExt = "fns";
|
||||||
public const string BinExt = "bin";
|
public const string BinExt = "bin";
|
||||||
public const string NesExt = "nes";
|
public const string NesExt = "nes";
|
||||||
|
public const string SufamiTurboExt = "st";
|
||||||
|
|
||||||
public static async Task<string?> OpenFile(string? initialFolder, IRenderRoot? parent, params string[] extensions)
|
public static async Task<string?> OpenFile(string? initialFolder, IRenderRoot? parent, params string[] extensions)
|
||||||
{
|
{
|
||||||
|
@ -51,7 +52,7 @@ namespace Mesen.Utilities
|
||||||
foreach(string ext in extensions) {
|
foreach(string ext in extensions) {
|
||||||
if(ext == FileDialogHelper.RomExt) {
|
if(ext == FileDialogHelper.RomExt) {
|
||||||
filter.Add(new FilePickerFileType("All ROM files") { Patterns = new List<string>() {
|
filter.Add(new FilePickerFileType("All ROM files") { Patterns = new List<string>() {
|
||||||
"*.sfc", "*.fig", "*.smc", "*.bs", "*.spc",
|
"*.sfc", "*.fig", "*.smc", "*.bs", "*.st", "*.spc",
|
||||||
"*.nes", "*.fds", "*.unif", "*.unf", "*.studybox", "*.nsf", "*.nsfe",
|
"*.nes", "*.fds", "*.unif", "*.unf", "*.studybox", "*.nsf", "*.nsfe",
|
||||||
"*.gb", "*.gbc", "*.gbx", "*.gbs",
|
"*.gb", "*.gbc", "*.gbx", "*.gbs",
|
||||||
"*.pce", "*.sgx", "*.cue", "*.hes",
|
"*.pce", "*.sgx", "*.cue", "*.hes",
|
||||||
|
@ -60,7 +61,7 @@ namespace Mesen.Utilities
|
||||||
"*.ws", "*.wsc",
|
"*.ws", "*.wsc",
|
||||||
"*.zip", "*.7z"
|
"*.zip", "*.7z"
|
||||||
} });
|
} });
|
||||||
filter.Add(new FilePickerFileType("SNES ROM files") { Patterns = new List<string>() { "*.sfc", "*.fig", "*.smc", "*.bs", "*.spc" } });
|
filter.Add(new FilePickerFileType("SNES ROM files") { Patterns = new List<string>() { "*.sfc", "*.fig", "*.smc", "*.bs", "*.st", "*.spc" } });
|
||||||
filter.Add(new FilePickerFileType("NES ROM files") { Patterns = new List<string>() { "*.nes", "*.fds", "*.unif", "*.unf", "*.studybox", "*.nsf", "*.nsfe" } });
|
filter.Add(new FilePickerFileType("NES ROM files") { Patterns = new List<string>() { "*.nes", "*.fds", "*.unif", "*.unf", "*.studybox", "*.nsf", "*.nsfe" } });
|
||||||
filter.Add(new FilePickerFileType("GB ROM files") { Patterns = new List<string>() { "*.gb", "*.gbc", "*.gbx", "*.gbs" } });
|
filter.Add(new FilePickerFileType("GB ROM files") { Patterns = new List<string>() { "*.gb", "*.gbc", "*.gbx", "*.gbs" } });
|
||||||
filter.Add(new FilePickerFileType("GBA ROM files") { Patterns = new List<string>() { "*.gba" } });
|
filter.Add(new FilePickerFileType("GBA ROM files") { Patterns = new List<string>() { "*.gba" } });
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Mesen.Utilities
|
||||||
public static class FolderHelper
|
public static class FolderHelper
|
||||||
{
|
{
|
||||||
private static HashSet<string> _romExtensions = new HashSet<string>() {
|
private static HashSet<string> _romExtensions = new HashSet<string>() {
|
||||||
".sfc", ".smc", ".fig", ".swc", ".bs",
|
".sfc", ".smc", ".fig", ".swc", ".bs", ".st",
|
||||||
".gb", ".gbc", ".gbx",
|
".gb", ".gbc", ".gbx",
|
||||||
".nes", ".unif", ".unf", ".fds", ".studybox",
|
".nes", ".unif", ".unf", ".fds", ".studybox",
|
||||||
".pce", ".sgx", ".cue",
|
".pce", ".sgx", ".cue",
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
</c:OptionSection>
|
</c:OptionSection>
|
||||||
|
|
||||||
<c:OptionSection Header="{l:Translate lblSnes}" Icon="Assets/SnesIcon.png" >
|
<c:OptionSection Header="{l:Translate lblSnes}" Icon="Assets/SnesIcon.png" >
|
||||||
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,*">
|
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,*">
|
||||||
<TextBlock Text="DSP-1" Grid.Row="1" />
|
<TextBlock Text="DSP-1" Grid.Row="1" />
|
||||||
<c:FirmwareSelect FirmwareType="DSP1" Grid.Column="1" Grid.Row="1" />
|
<c:FirmwareSelect FirmwareType="DSP1" Grid.Column="1" Grid.Row="1" />
|
||||||
|
|
||||||
|
@ -111,20 +111,23 @@
|
||||||
<TextBlock Text="Satellaview / BS-X" Grid.Row="6" />
|
<TextBlock Text="Satellaview / BS-X" Grid.Row="6" />
|
||||||
<c:FirmwareSelect FirmwareType="Satellaview" Grid.Column="1" Grid.Row="6" />
|
<c:FirmwareSelect FirmwareType="Satellaview" Grid.Column="1" Grid.Row="6" />
|
||||||
|
|
||||||
<TextBlock Text="Super Game Boy (v1)" Grid.Row="7" />
|
<TextBlock Text="Sufami Turbo" Grid.Row="7" />
|
||||||
<c:FirmwareSelect FirmwareType="SGB1" Grid.Column="1" Grid.Row="7" />
|
<c:FirmwareSelect FirmwareType="SufamiTurbo" Grid.Column="1" Grid.Row="7" />
|
||||||
|
|
||||||
<TextBlock Text="Super Game Boy (v2)" Grid.Row="8" />
|
<TextBlock Text="Super Game Boy (v1)" Grid.Row="8" />
|
||||||
<c:FirmwareSelect FirmwareType="SGB2" Grid.Column="1" Grid.Row="8" />
|
<c:FirmwareSelect FirmwareType="SGB1" Grid.Column="1" Grid.Row="8" />
|
||||||
|
|
||||||
<TextBlock Text="ST010" Grid.Row="9" />
|
<TextBlock Text="Super Game Boy (v2)" Grid.Row="9" />
|
||||||
<c:FirmwareSelect FirmwareType="ST010" Grid.Column="1" Grid.Row="9" />
|
<c:FirmwareSelect FirmwareType="SGB2" Grid.Column="1" Grid.Row="9" />
|
||||||
|
|
||||||
<TextBlock Text="ST011" Grid.Row="10" />
|
<TextBlock Text="ST010" Grid.Row="10" />
|
||||||
<c:FirmwareSelect FirmwareType="ST011" Grid.Column="1" Grid.Row="10" />
|
<c:FirmwareSelect FirmwareType="ST010" Grid.Column="1" Grid.Row="10" />
|
||||||
|
|
||||||
<TextBlock Text="ST018" Grid.Row="11" />
|
<TextBlock Text="ST011" Grid.Row="11" />
|
||||||
<c:FirmwareSelect FirmwareType="ST018" Grid.Column="1" Grid.Row="11" />
|
<c:FirmwareSelect FirmwareType="ST011" Grid.Column="1" Grid.Row="11" />
|
||||||
|
|
||||||
|
<TextBlock Text="ST018" Grid.Row="12" />
|
||||||
|
<c:FirmwareSelect FirmwareType="ST018" Grid.Column="1" Grid.Row="12" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</c:OptionSection>
|
</c:OptionSection>
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ using Mesen.Controls;
|
||||||
using Mesen.Localization;
|
using Mesen.Localization;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Avalonia.VisualTree;
|
using Avalonia.VisualTree;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Mesen.Windows
|
namespace Mesen.Windows
|
||||||
{
|
{
|
||||||
|
@ -367,7 +368,7 @@ namespace Mesen.Windows
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ConsoleNotificationType.MissingFirmware:
|
case ConsoleNotificationType.MissingFirmware: {
|
||||||
MissingFirmwareMessage msg = Marshal.PtrToStructure<MissingFirmwareMessage>(e.Parameter);
|
MissingFirmwareMessage msg = Marshal.PtrToStructure<MissingFirmwareMessage>(e.Parameter);
|
||||||
TaskCompletionSource tcs = new TaskCompletionSource();
|
TaskCompletionSource tcs = new TaskCompletionSource();
|
||||||
Dispatcher.UIThread.Post(async () => {
|
Dispatcher.UIThread.Post(async () => {
|
||||||
|
@ -376,6 +377,25 @@ namespace Mesen.Windows
|
||||||
});
|
});
|
||||||
tcs.Task.Wait();
|
tcs.Task.Wait();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ConsoleNotificationType.SufamiTurboFilePrompt: {
|
||||||
|
SufamiTurboFilePromptMessage msg = Marshal.PtrToStructure<SufamiTurboFilePromptMessage>(e.Parameter);
|
||||||
|
TaskCompletionSource tcs = new TaskCompletionSource();
|
||||||
|
Dispatcher.UIThread.Post(async () => {
|
||||||
|
if(await MesenMsgBox.Show(this, "PromptLoadSufamiTurbo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) {
|
||||||
|
string? selectedFile = await FileDialogHelper.OpenFile(null, this, FileDialogHelper.SufamiTurboExt);
|
||||||
|
if(selectedFile != null) {
|
||||||
|
byte[] file = Encoding.UTF8.GetBytes(selectedFile);
|
||||||
|
Array.Copy(file, msg.Filename, file.Length);
|
||||||
|
Marshal.StructureToPtr<SufamiTurboFilePromptMessage>(msg, e.Parameter, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tcs.SetResult();
|
||||||
|
});
|
||||||
|
tcs.Task.Wait();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ConsoleNotificationType.BeforeGameLoad:
|
case ConsoleNotificationType.BeforeGameLoad:
|
||||||
Dispatcher.UIThread.Post(() => {
|
Dispatcher.UIThread.Post(() => {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
const std::initializer_list<string> VirtualFile::RomExtensions = {
|
const std::initializer_list<string> VirtualFile::RomExtensions = {
|
||||||
".nes", ".fds", ".unif", ".unf", ".nsf", ".nsfe", ".studybox",
|
".nes", ".fds", ".unif", ".unf", ".nsf", ".nsfe", ".studybox",
|
||||||
".sfc", ".swc", ".fig", ".smc", ".bs", ".spc",
|
".sfc", ".swc", ".fig", ".smc", ".bs", ".st", ".spc",
|
||||||
".gb", ".gbc", ".gbx", ".gbs",
|
".gb", ".gbc", ".gbx", ".gbs",
|
||||||
".pce", ".sgx", ".cue", ".hes",
|
".pce", ".sgx", ".cue", ".hes",
|
||||||
".sms", ".gg", ".sg", ".col",
|
".sms", ".gg", ".sg", ".col",
|
||||||
|
|
Loading…
Add table
Reference in a new issue