mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-23 14:25:37 +00:00
BIOS: Automatically detect images, improve selection UI
This commit is contained in:
parent
3385346b7f
commit
7d01bedf07
|
@ -4,6 +4,7 @@
|
|||
#include "common/log.h"
|
||||
#include "common/md5_digest.h"
|
||||
#include "cpu_disasm.h"
|
||||
#include <array>
|
||||
#include <cerrno>
|
||||
Log_SetChannel(BIOS);
|
||||
|
||||
|
@ -36,16 +37,28 @@ std::string Hash::ToString() const
|
|||
return str;
|
||||
}
|
||||
|
||||
static constexpr Hash SCPH_1000_HASH = MakeHashFromString("239665b1a3dade1b5a52c06338011044");
|
||||
static constexpr Hash SCPH_1001_HASH = MakeHashFromString("924e392ed05558ffdb115408c263dccf");
|
||||
static constexpr Hash SCPH_1002_HASH = MakeHashFromString("54847e693405ffeb0359c6287434cbef");
|
||||
static constexpr Hash SCPH_3000_HASH = MakeHashFromString("849515939161e62f6b866f6853006780");
|
||||
static constexpr Hash SCPH_5500_HASH = MakeHashFromString("8dd7d5296a650fac7319bce665a6a53c");
|
||||
static constexpr Hash SCPH_5501_HASH = MakeHashFromString("490f666e1afb15b7362b406ed1cea246");
|
||||
static constexpr Hash SCPH_5502_HASH = MakeHashFromString("32736f17079d0b2b7024407c39bd3050");
|
||||
static constexpr Hash SCPH_7001_HASH = MakeHashFromString("1e68c231d0896b7eadcad1d7d8e76129");
|
||||
static constexpr Hash SCPH_7002_HASH = MakeHashFromString("b9d9a0286c33dc6b7237bb13cd46fdee");
|
||||
static constexpr Hash SCPH_POPS660_HASH = MakeHashFromString("c53ca5908936d412331790f4426c6c33");
|
||||
static constexpr std::array<ImageInfo, 12> s_image_infos = {{
|
||||
{"SCPH-1000, DTL-H1000 (v1.0 J)", ConsoleRegion::NTSC_J, MakeHashFromString("239665b1a3dade1b5a52c06338011044")},
|
||||
{"SCPH-1001, 5003, DTL-H1201, H3001 (v2.2 12-04-95 A)", ConsoleRegion::NTSC_U,
|
||||
MakeHashFromString("924e392ed05558ffdb115408c263dccf")},
|
||||
{"SCPH-1002, DTL-H1002 (v2.0 05-10-95 E)", ConsoleRegion::PAL,
|
||||
MakeHashFromString("54847e693405ffeb0359c6287434cbef")},
|
||||
{"SCPH-3000, DTL-H1000H (v1.1 01-22-95)", ConsoleRegion::NTSC_J,
|
||||
MakeHashFromString("849515939161e62f6b866f6853006780")},
|
||||
{"SCPH-5000, DTL-H1200, H3000 (v2.2 12-04-95 J)", ConsoleRegion::NTSC_J,
|
||||
MakeHashFromString("8dd7d5296a650fac7319bce665a6a53c")},
|
||||
{"SCPH-5501, 5503, 7003 (v3.0 11-18-96 A)", ConsoleRegion::NTSC_U,
|
||||
MakeHashFromString("490f666e1afb15b7362b406ed1cea246")},
|
||||
{"SCPH-5502, 5552 (v3.0 01-06-97 E)", ConsoleRegion::PAL, MakeHashFromString("32736f17079d0b2b7024407c39bd3050")},
|
||||
{"SCPH-7000, 7500, 9000 (v4.0 08-18-97 J)", ConsoleRegion::NTSC_J,
|
||||
MakeHashFromString("8e4c14f567745eff2f0408c8129f72a6")},
|
||||
{"SCPH-7000W (v4.1 11-14-97 A)", ConsoleRegion::NTSC_J, MakeHashFromString("b84be139db3ee6cbd075630aa20a6553")},
|
||||
{"SCPH-7001, 7501, 7503, 9001, 9003, 9903 (v4.1 12-16-97 A)", ConsoleRegion::NTSC_U,
|
||||
MakeHashFromString("1e68c231d0896b7eadcad1d7d8e76129")},
|
||||
{"SCPH-7002, 7502, 9002 (v4.1 12-16-97 E)", ConsoleRegion::PAL,
|
||||
MakeHashFromString("b9d9a0286c33dc6b7237bb13cd46fdee")},
|
||||
{"POPS-660 (PSP)", ConsoleRegion::Auto, MakeHashFromString("c53ca5908936d412331790f4426c6c33")},
|
||||
}};
|
||||
|
||||
Hash GetHash(const Image& image)
|
||||
{
|
||||
|
@ -56,14 +69,13 @@ Hash GetHash(const Image& image)
|
|||
return hash;
|
||||
}
|
||||
|
||||
std::optional<Image> LoadImageFromFile(std::string_view filename)
|
||||
std::optional<Image> LoadImageFromFile(const char* filename)
|
||||
{
|
||||
Image ret(BIOS_SIZE);
|
||||
std::string filename_str(filename);
|
||||
auto fp = FileSystem::OpenManagedCFile(filename_str.c_str(), "rb");
|
||||
auto fp = FileSystem::OpenManagedCFile(filename, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
Log_ErrorPrintf("Failed to open BIOS image '%s', errno=%d", filename_str.c_str(), errno);
|
||||
Log_ErrorPrintf("Failed to open BIOS image '%s', errno=%d", filename, errno);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
@ -73,21 +85,20 @@ std::optional<Image> LoadImageFromFile(std::string_view filename)
|
|||
|
||||
if (size != BIOS_SIZE)
|
||||
{
|
||||
Log_ErrorPrintf("BIOS image '%s' mismatch, expecting %u bytes, got %u bytes", filename_str.c_str(), BIOS_SIZE,
|
||||
size);
|
||||
Log_ErrorPrintf("BIOS image '%s' mismatch, expecting %u bytes, got %u bytes", filename, BIOS_SIZE, size);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (std::fread(ret.data(), 1, ret.size(), fp.get()) != ret.size())
|
||||
{
|
||||
Log_ErrorPrintf("Failed to read BIOS image '%s'", filename_str.c_str());
|
||||
Log_ErrorPrintf("Failed to read BIOS image '%s'", filename);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::optional<Hash> GetHashForFile(const std::string_view filename)
|
||||
std::optional<Hash> GetHashForFile(const char* filename)
|
||||
{
|
||||
auto image = LoadImageFromFile(filename);
|
||||
if (!image)
|
||||
|
@ -96,23 +107,24 @@ std::optional<Hash> GetHashForFile(const std::string_view filename)
|
|||
return GetHash(*image);
|
||||
}
|
||||
|
||||
const ImageInfo* GetImageInfoForHash(const Hash& hash)
|
||||
{
|
||||
for (const ImageInfo& ii : s_image_infos)
|
||||
{
|
||||
if (ii.hash == hash)
|
||||
return ⅈ
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool IsValidHashForRegion(ConsoleRegion region, const Hash& hash)
|
||||
{
|
||||
switch (region)
|
||||
{
|
||||
case ConsoleRegion::NTSC_J:
|
||||
return (hash == SCPH_1000_HASH || hash == SCPH_3000_HASH || hash == SCPH_5500_HASH || hash == SCPH_POPS660_HASH);
|
||||
const ImageInfo* ii = GetImageInfoForHash(hash);
|
||||
if (!ii)
|
||||
return false;
|
||||
|
||||
case ConsoleRegion::NTSC_U:
|
||||
return (hash == SCPH_1001_HASH || hash == SCPH_5501_HASH || hash == SCPH_7001_HASH || hash == SCPH_POPS660_HASH);
|
||||
|
||||
case ConsoleRegion::PAL:
|
||||
return (hash == SCPH_1002_HASH || hash == SCPH_5502_HASH || hash == SCPH_7002_HASH || hash == SCPH_POPS660_HASH);
|
||||
|
||||
case ConsoleRegion::Auto:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return (ii->region == ConsoleRegion::Auto || ii->region == region);
|
||||
}
|
||||
|
||||
void PatchBIOS(Image& bios, u32 address, u32 value, u32 mask /*= UINT32_C(0xFFFFFFFF)*/)
|
||||
|
@ -135,9 +147,8 @@ void PatchBIOS(Image& bios, u32 address, u32 value, u32 mask /*= UINT32_C(0xFFFF
|
|||
|
||||
bool PatchBIOSEnableTTY(Image& image, const Hash& hash)
|
||||
{
|
||||
if (hash != SCPH_1000_HASH && hash != SCPH_1001_HASH && hash != SCPH_1002_HASH && hash != SCPH_3000_HASH &&
|
||||
hash != SCPH_5500_HASH && hash != SCPH_5501_HASH && hash != SCPH_5502_HASH && hash != SCPH_7001_HASH &&
|
||||
hash != SCPH_7002_HASH && hash != SCPH_POPS660_HASH)
|
||||
const ImageInfo* ii = GetImageInfoForHash(hash);
|
||||
if (!ii)
|
||||
{
|
||||
Log_WarningPrintf("Incompatible version for TTY patch: %s", hash.ToString().c_str());
|
||||
return false;
|
||||
|
@ -151,9 +162,8 @@ bool PatchBIOSEnableTTY(Image& image, const Hash& hash)
|
|||
|
||||
bool PatchBIOSFastBoot(Image& image, const Hash& hash)
|
||||
{
|
||||
if (hash != SCPH_1000_HASH && hash != SCPH_1001_HASH && hash != SCPH_1002_HASH && hash != SCPH_3000_HASH &&
|
||||
hash != SCPH_5500_HASH && hash != SCPH_5501_HASH && hash != SCPH_5502_HASH && hash != SCPH_7001_HASH &&
|
||||
hash != SCPH_7002_HASH && hash != SCPH_POPS660_HASH)
|
||||
const ImageInfo* ii = GetImageInfoForHash(hash);
|
||||
if (!ii)
|
||||
{
|
||||
Log_WarningPrintf("Incompatible version for fast-boot patch: %s", hash.ToString().c_str());
|
||||
return false;
|
||||
|
|
|
@ -24,6 +24,13 @@ struct Hash
|
|||
std::string ToString() const;
|
||||
};
|
||||
|
||||
struct ImageInfo
|
||||
{
|
||||
const char* description;
|
||||
ConsoleRegion region;
|
||||
Hash hash;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct PSEXEHeader
|
||||
{
|
||||
|
@ -46,9 +53,10 @@ static_assert(sizeof(PSEXEHeader) == 0x800);
|
|||
#pragma pack(pop)
|
||||
|
||||
Hash GetHash(const Image& image);
|
||||
std::optional<Image> LoadImageFromFile(std::string_view filename);
|
||||
std::optional<Hash> GetHashForFile(std::string_view filename);
|
||||
std::optional<Image> LoadImageFromFile(const char* filename);
|
||||
std::optional<Hash> GetHashForFile(const char* filename);
|
||||
|
||||
const ImageInfo* GetImageInfoForHash(const Hash& hash);
|
||||
bool IsValidHashForRegion(ConsoleRegion region, const Hash& hash);
|
||||
|
||||
void PatchBIOS(Image& image, u32 address, u32 value, u32 mask = UINT32_C(0xFFFFFFFF));
|
||||
|
|
|
@ -201,84 +201,132 @@ void HostInterface::AddFormattedOSDMessage(float duration, const char* format, .
|
|||
|
||||
std::optional<std::vector<u8>> HostInterface::GetBIOSImage(ConsoleRegion region)
|
||||
{
|
||||
// Try the other default filenames in the directory of the configured BIOS.
|
||||
#define TRY_FILENAME(filename) \
|
||||
do \
|
||||
{ \
|
||||
String try_filename = filename; \
|
||||
std::optional<BIOS::Image> found_image = BIOS::LoadImageFromFile(try_filename.GetCharArray()); \
|
||||
if (found_image) \
|
||||
{ \
|
||||
BIOS::Hash found_hash = BIOS::GetHash(*found_image); \
|
||||
Log_DevPrintf("Hash for BIOS '%s': %s", try_filename.GetCharArray(), found_hash.ToString().c_str()); \
|
||||
if (BIOS::IsValidHashForRegion(region, found_hash)) \
|
||||
{ \
|
||||
Log_InfoPrintf("Using BIOS from '%s' for region '%s'", try_filename.GetCharArray(), \
|
||||
Settings::GetConsoleRegionName(region)); \
|
||||
return found_image; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Try the configured image.
|
||||
TRY_FILENAME(g_settings.bios_path.c_str());
|
||||
|
||||
// Try searching in the same folder for other region's images.
|
||||
const std::string* bios_path;
|
||||
switch (region)
|
||||
{
|
||||
case ConsoleRegion::NTSC_J:
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph3000.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "ps-11j.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph1000.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "ps-10j.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph5500.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "ps-30j.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph7000.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph7500.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph9000.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "ps-40j.bin", false, false));
|
||||
break;
|
||||
|
||||
case ConsoleRegion::NTSC_U:
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph1001.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "ps-22a.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph5501.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph5503.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph7003.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "ps-30a.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph7001.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph7501.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph7503.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph9001.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph9003.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph9903.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "ps-41a.bin", false, false));
|
||||
bios_path = &g_settings.bios_path_ntsc_j;
|
||||
break;
|
||||
|
||||
case ConsoleRegion::PAL:
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph1002.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "ps-21e.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph5502.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph5552.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "ps-30e.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph7002.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph7502.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "scph9002.bin", false, false));
|
||||
TRY_FILENAME(FileSystem::BuildPathRelativeToFile(g_settings.bios_path.c_str(), "ps-41e.bin", false, false));
|
||||
bios_path = &g_settings.bios_path_pal;
|
||||
break;
|
||||
|
||||
case ConsoleRegion::NTSC_U:
|
||||
default:
|
||||
bios_path = &g_settings.bios_path_ntsc_u;
|
||||
break;
|
||||
}
|
||||
|
||||
#undef RELATIVE_PATH
|
||||
#undef TRY_FILENAME
|
||||
if (bios_path->empty())
|
||||
{
|
||||
// auto-detect
|
||||
return FindBIOSImageInDirectory(region, GetUserDirectoryRelativePath("bios").c_str());
|
||||
}
|
||||
|
||||
// Fall back to the default image.
|
||||
Log_WarningPrintf("No suitable BIOS image for region %s could be located, using configured image '%s'. This may "
|
||||
"result in instability.",
|
||||
Settings::GetConsoleRegionName(region), g_settings.bios_path.c_str());
|
||||
return BIOS::LoadImageFromFile(g_settings.bios_path);
|
||||
// try the configured path
|
||||
std::optional<BIOS::Image> image = BIOS::LoadImageFromFile(
|
||||
GetUserDirectoryRelativePath("bios" FS_OSPATH_SEPARATOR_STR "%s", bios_path->c_str()).c_str());
|
||||
if (!image.has_value())
|
||||
{
|
||||
g_host_interface->ReportFormattedError(
|
||||
g_host_interface->TranslateString("HostInterface", "Failed to load configured BIOS file '%s'"),
|
||||
bios_path->c_str());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
BIOS::Hash found_hash = BIOS::GetHash(*image);
|
||||
Log_DevPrintf("Hash for BIOS '%s': %s", bios_path->c_str(), found_hash.ToString().c_str());
|
||||
|
||||
if (!BIOS::IsValidHashForRegion(region, found_hash))
|
||||
Log_WarningPrintf("Hash for BIOS '%s' does not match region. This may cause issues.", bios_path->c_str());
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
std::optional<std::vector<u8>> HostInterface::FindBIOSImageInDirectory(ConsoleRegion region, const char* directory)
|
||||
{
|
||||
Log_InfoPrintf("Searching for a %s BIOS in '%s'...", Settings::GetConsoleRegionDisplayName(region), directory);
|
||||
|
||||
FileSystem::FindResultsArray results;
|
||||
FileSystem::FindFiles(
|
||||
directory, "*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RELATIVE_PATHS, &results);
|
||||
|
||||
std::string fallback_path;
|
||||
std::optional<BIOS::Image> fallback_image;
|
||||
|
||||
for (const FILESYSTEM_FIND_DATA& fd : results)
|
||||
{
|
||||
if (fd.Size != BIOS::BIOS_SIZE)
|
||||
{
|
||||
Log_WarningPrintf("Skipping '%s': incorrect size", fd.FileName.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string full_path(
|
||||
StringUtil::StdStringFromFormat("%s" FS_OSPATH_SEPARATOR_STR "%s", directory, fd.FileName.c_str()));
|
||||
|
||||
std::optional<BIOS::Image> found_image = BIOS::LoadImageFromFile(full_path.c_str());
|
||||
if (!found_image)
|
||||
continue;
|
||||
|
||||
BIOS::Hash found_hash = BIOS::GetHash(*found_image);
|
||||
Log_DevPrintf("Hash for BIOS '%s': %s", fd.FileName.c_str(), found_hash.ToString().c_str());
|
||||
|
||||
if (BIOS::IsValidHashForRegion(region, found_hash))
|
||||
{
|
||||
Log_InfoPrintf("Using BIOS '%s'", fd.FileName.c_str());
|
||||
return found_image;
|
||||
}
|
||||
|
||||
fallback_path = std::move(full_path);
|
||||
fallback_image = std::move(found_image);
|
||||
}
|
||||
|
||||
if (!fallback_image.has_value())
|
||||
{
|
||||
g_host_interface->ReportFormattedError(
|
||||
g_host_interface->TranslateString("HostInterface", "No BIOS image found for %s region"),
|
||||
Settings::GetConsoleRegionDisplayName(region));
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Log_WarningPrintf("Falling back to possibly-incompatible image '%s'", fallback_path.c_str());
|
||||
return fallback_image;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, const BIOS::ImageInfo*>>
|
||||
HostInterface::FindBIOSImagesInDirectory(const char* directory)
|
||||
{
|
||||
std::vector<std::pair<std::string, const BIOS::ImageInfo*>> results;
|
||||
|
||||
FileSystem::FindResultsArray files;
|
||||
FileSystem::FindFiles(directory, "*",
|
||||
FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RELATIVE_PATHS, &files);
|
||||
|
||||
for (FILESYSTEM_FIND_DATA& fd : files)
|
||||
{
|
||||
if (fd.Size != BIOS::BIOS_SIZE)
|
||||
continue;
|
||||
|
||||
std::string full_path(
|
||||
StringUtil::StdStringFromFormat("%s" FS_OSPATH_SEPARATOR_STR "%s", directory, fd.FileName.c_str()));
|
||||
|
||||
std::optional<BIOS::Image> found_image = BIOS::LoadImageFromFile(full_path.c_str());
|
||||
if (!found_image)
|
||||
continue;
|
||||
|
||||
BIOS::Hash found_hash = BIOS::GetHash(*found_image);
|
||||
const BIOS::ImageInfo* ii = BIOS::GetImageInfoForHash(found_hash);
|
||||
results.emplace_back(std::move(fd.FileName), ii);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, const BIOS::ImageInfo*>> HostInterface::FindBIOSImagesInUserDirectory()
|
||||
{
|
||||
return FindBIOSImagesInDirectory(GetUserDirectoryRelativePath("bios").c_str());
|
||||
}
|
||||
|
||||
bool HostInterface::LoadState(const char* filename)
|
||||
|
@ -410,7 +458,9 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si)
|
|||
si.SetBoolValue("Audio", "Sync", true);
|
||||
si.SetBoolValue("Audio", "DumpOnBoot", false);
|
||||
|
||||
si.SetStringValue("BIOS", "Path", "bios" FS_OSPATH_SEPARATOR_STR "scph1001.bin");
|
||||
si.SetStringValue("BIOS", "PathNTSCU", "");
|
||||
si.SetStringValue("BIOS", "PathNTSCJ", "");
|
||||
si.SetStringValue("BIOS", "PathPAL", "");
|
||||
si.SetBoolValue("BIOS", "PatchTTYEnable", false);
|
||||
si.SetBoolValue("BIOS", "PatchFastBoot", false);
|
||||
|
||||
|
|
|
@ -22,6 +22,11 @@ class GameList;
|
|||
|
||||
struct SystemBootParameters;
|
||||
|
||||
namespace BIOS
|
||||
{
|
||||
struct ImageInfo;
|
||||
}
|
||||
|
||||
class HostInterface
|
||||
{
|
||||
public:
|
||||
|
@ -116,6 +121,14 @@ public:
|
|||
/// Loads the BIOS image for the specified region.
|
||||
std::optional<std::vector<u8>> GetBIOSImage(ConsoleRegion region);
|
||||
|
||||
/// Searches for a BIOS image for the specified region in the specified directory. If no match is found, the first
|
||||
/// 512KB BIOS image will be used.
|
||||
std::optional<std::vector<u8>> FindBIOSImageInDirectory(ConsoleRegion region, const char* directory);
|
||||
|
||||
/// Returns a list of filenames and descriptions for BIOS images in a directory.
|
||||
std::vector<std::pair<std::string, const BIOS::ImageInfo*>> FindBIOSImagesInDirectory(const char* directory);
|
||||
std::vector<std::pair<std::string, const BIOS::ImageInfo*>> FindBIOSImagesInUserDirectory();
|
||||
|
||||
virtual void OnRunningGameChanged();
|
||||
virtual void OnSystemPerformanceCountersUpdated();
|
||||
|
||||
|
|
|
@ -157,7 +157,9 @@ void Settings::Load(SettingsInterface& si)
|
|||
gpu_fifo_size = static_cast<u32>(si.GetIntValue("Hacks", "GPUFIFOSize", DEFAULT_GPU_FIFO_SIZE));
|
||||
gpu_max_run_ahead = si.GetIntValue("Hacks", "GPUMaxRunAhead", DEFAULT_GPU_MAX_RUN_AHEAD);
|
||||
|
||||
bios_path = si.GetStringValue("BIOS", "Path", "bios" FS_OSPATH_SEPARATOR_STR "scph1001.bin");
|
||||
bios_path_ntsc_u = si.GetStringValue("BIOS", "PathNTSCU", "");
|
||||
bios_path_ntsc_j = si.GetStringValue("BIOS", "PathNTSCJ", "");
|
||||
bios_path_pal = si.GetStringValue("BIOS", "PathPAL", "");
|
||||
bios_patch_tty_enable = si.GetBoolValue("BIOS", "PatchTTYEnable", false);
|
||||
bios_patch_fast_boot = si.GetBoolValue("BIOS", "PatchFastBoot", false);
|
||||
|
||||
|
@ -271,7 +273,9 @@ void Settings::Save(SettingsInterface& si) const
|
|||
si.SetIntValue("Hacks", "GPUFIFOSize", gpu_fifo_size);
|
||||
si.SetIntValue("Hacks", "GPUMaxRunAhead", gpu_max_run_ahead);
|
||||
|
||||
si.SetStringValue("BIOS", "Path", bios_path.c_str());
|
||||
si.SetStringValue("BIOS", "PathNTSCJ", bios_path_ntsc_j.c_str());
|
||||
si.SetStringValue("BIOS", "PathNTSCU", bios_path_ntsc_u.c_str());
|
||||
si.SetStringValue("BIOS", "PathPAL", bios_path_pal.c_str());
|
||||
si.SetBoolValue("BIOS", "PatchTTYEnable", bios_patch_tty_enable);
|
||||
si.SetBoolValue("BIOS", "PatchFastBoot", bios_patch_fast_boot);
|
||||
|
||||
|
|
|
@ -147,7 +147,9 @@ struct Settings
|
|||
|
||||
// TODO: Controllers, memory cards, etc.
|
||||
|
||||
std::string bios_path;
|
||||
std::string bios_path_ntsc_j;
|
||||
std::string bios_path_ntsc_u;
|
||||
std::string bios_path_pal;
|
||||
bool bios_patch_tty_enable = false;
|
||||
bool bios_patch_fast_boot = false;
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ set(SRCS
|
|||
autoupdaterdialog.cpp
|
||||
autoupdaterdialog.h
|
||||
autoupdaterdialog.ui
|
||||
biossettingswidget.cpp
|
||||
biossettingswidget.h
|
||||
biossettingswidget.ui
|
||||
consolesettingswidget.cpp
|
||||
consolesettingswidget.h
|
||||
consolesettingswidget.ui
|
||||
|
|
123
src/duckstation-qt/biossettingswidget.cpp
Normal file
123
src/duckstation-qt/biossettingswidget.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
#include "biossettingswidget.h"
|
||||
#include "core/bios.h"
|
||||
#include "qthostinterface.h"
|
||||
#include "settingsdialog.h"
|
||||
#include "settingwidgetbinder.h"
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <algorithm>
|
||||
|
||||
static void populateDropDownForRegion(ConsoleRegion region, QComboBox* cb,
|
||||
std::vector<std::pair<std::string, const BIOS::ImageInfo*>>& images)
|
||||
{
|
||||
cb->addItem(QIcon(QStringLiteral(":/icons/system-search.png")),
|
||||
QT_TRANSLATE_NOOP("BIOSSettingsWidget", "Auto-Detect"));
|
||||
|
||||
std::sort(images.begin(), images.end(), [region](const auto& left, const auto& right) {
|
||||
const bool left_region_match = (left.second && left.second->region == region);
|
||||
const bool right_region_match = (right.second && right.second->region == region);
|
||||
if (left_region_match && !right_region_match)
|
||||
return true;
|
||||
else if (right_region_match && left_region_match)
|
||||
return false;
|
||||
|
||||
return left.first < right.first;
|
||||
});
|
||||
|
||||
for (const auto& [name, info] : images)
|
||||
{
|
||||
QIcon icon;
|
||||
if (info)
|
||||
{
|
||||
switch (info->region)
|
||||
{
|
||||
case ConsoleRegion::NTSC_J:
|
||||
icon = QIcon(QStringLiteral(":/icons/flag-jp.png"));
|
||||
break;
|
||||
case ConsoleRegion::PAL:
|
||||
icon = QIcon(QStringLiteral(":/icons/flag-eu.png"));
|
||||
break;
|
||||
case ConsoleRegion::NTSC_U:
|
||||
icon = QIcon(QStringLiteral(":/icons/flag-uc.png"));
|
||||
break;
|
||||
default:
|
||||
icon = QIcon(QStringLiteral(":/icons/applications-other.png"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
icon = QIcon(QStringLiteral(":/icons/applications-other.png"));
|
||||
}
|
||||
|
||||
QString name_str(QString::fromStdString(name));
|
||||
cb->addItem(icon,
|
||||
QStringLiteral("%1 (%2)")
|
||||
.arg(info ? QString(info->description) : qApp->translate("BIOSSettingsWidget", "Unknown"))
|
||||
.arg(name_str),
|
||||
QVariant(name_str));
|
||||
}
|
||||
}
|
||||
|
||||
static void setDropDownValue(QComboBox* cb, const std::string& name)
|
||||
{
|
||||
QSignalBlocker sb(cb);
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
cb->setCurrentIndex(0);
|
||||
return;
|
||||
}
|
||||
|
||||
QString qname(QString::fromStdString(name));
|
||||
for (int i = 1; i < cb->count(); i++)
|
||||
{
|
||||
if (cb->itemData(i) == qname)
|
||||
{
|
||||
cb->setCurrentIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cb->addItem(qname, QVariant(qname));
|
||||
cb->setCurrentIndex(cb->count() - 1);
|
||||
}
|
||||
|
||||
BIOSSettingsWidget::BIOSSettingsWidget(QtHostInterface* host_interface, QWidget* parent, SettingsDialog* dialog)
|
||||
: QWidget(parent), m_host_interface(host_interface)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.enableTTYOutput, "BIOS", "PatchTTYEnable");
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.fastBoot, "BIOS", "PatchFastBoot");
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.fastBoot, tr("Fast Boot"), tr("Unchecked"),
|
||||
tr("Patches the BIOS to skip the console's boot animation. Does not work with all games, "
|
||||
"but usually safe to enabled."));
|
||||
|
||||
auto images = m_host_interface->FindBIOSImagesInUserDirectory();
|
||||
populateDropDownForRegion(ConsoleRegion::NTSC_J, m_ui.imageNTSCJ, images);
|
||||
populateDropDownForRegion(ConsoleRegion::NTSC_U, m_ui.imageNTSCU, images);
|
||||
populateDropDownForRegion(ConsoleRegion::PAL, m_ui.imagePAL, images);
|
||||
|
||||
setDropDownValue(m_ui.imageNTSCJ, m_host_interface->GetStringSettingValue("BIOS", "PathNTSCJ", ""));
|
||||
setDropDownValue(m_ui.imageNTSCU, m_host_interface->GetStringSettingValue("BIOS", "PathNTSCU", ""));
|
||||
setDropDownValue(m_ui.imagePAL, m_host_interface->GetStringSettingValue("BIOS", "PathPAL", ""));
|
||||
|
||||
connect(m_ui.imageNTSCJ, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
m_host_interface->SetStringSettingValue("BIOS", "PathNTSCJ",
|
||||
m_ui.imageNTSCJ->itemData(index).toString().toStdString().c_str());
|
||||
m_host_interface->applySettings();
|
||||
});
|
||||
connect(m_ui.imageNTSCU, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
m_host_interface->SetStringSettingValue("BIOS", "PathNTSCU",
|
||||
m_ui.imageNTSCU->itemData(index).toString().toStdString().c_str());
|
||||
m_host_interface->applySettings();
|
||||
});
|
||||
connect(m_ui.imagePAL, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
m_host_interface->SetStringSettingValue("BIOS", "PathPAL",
|
||||
m_ui.imagePAL->itemData(index).toString().toStdString().c_str());
|
||||
m_host_interface->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
BIOSSettingsWidget::~BIOSSettingsWidget() = default;
|
22
src/duckstation-qt/biossettingswidget.h
Normal file
22
src/duckstation-qt/biossettingswidget.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
#include "core/types.h"
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#include "ui_biossettingswidget.h"
|
||||
|
||||
class QtHostInterface;
|
||||
class SettingsDialog;
|
||||
|
||||
class BIOSSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BIOSSettingsWidget(QtHostInterface* host_interface, QWidget* parent, SettingsDialog* dialog);
|
||||
~BIOSSettingsWidget();
|
||||
|
||||
private:
|
||||
Ui::BIOSSettingsWidget m_ui;
|
||||
|
||||
QtHostInterface* m_host_interface;
|
||||
};
|
129
src/duckstation-qt/biossettingswidget.ui
Normal file
129
src/duckstation-qt/biossettingswidget.ui
Normal file
|
@ -0,0 +1,129 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BIOSSettingsWidget</class>
|
||||
<widget class="QWidget" name="BIOSSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>472</width>
|
||||
<height>259</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>BIOS Selection</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>NTSC-J (Japan):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="imageNTSCJ">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>NTSC-U/C (US/Canada):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="imageNTSCU">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>PAL (Europe, Australia):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="imagePAL">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Options and Patches</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fastBoot">
|
||||
<property name="text">
|
||||
<string>Fast Boot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableTTYOutput">
|
||||
<property name="text">
|
||||
<string>Enable TTY Output</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,9 +1,6 @@
|
|||
#include "consolesettingswidget.h"
|
||||
#include "settingsdialog.h"
|
||||
#include "settingwidgetbinder.h"
|
||||
#include <QtWidgets/QFileDialog>
|
||||
|
||||
static constexpr char BIOS_IMAGE_FILTER[] = "Binary Images (*.bin);;All Files (*.*)";
|
||||
|
||||
ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QWidget* parent, SettingsDialog* dialog)
|
||||
: QWidget(parent), m_host_interface(host_interface)
|
||||
|
@ -25,9 +22,6 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW
|
|||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.region, "Console", "Region",
|
||||
&Settings::ParseConsoleRegionName, &Settings::GetConsoleRegionName,
|
||||
Settings::DEFAULT_CONSOLE_REGION);
|
||||
SettingWidgetBinder::BindWidgetToStringSetting(m_host_interface, m_ui.biosPath, "BIOS", "Path");
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.enableTTYOutput, "BIOS", "PatchTTYEnable");
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.fastBoot, "BIOS", "PatchFastBoot");
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.cpuExecutionMode, "CPU", "ExecutionMode",
|
||||
&Settings::ParseCPUExecutionMode, &Settings::GetCPUExecutionModeName,
|
||||
Settings::DEFAULT_CPU_EXECUTION_MODE);
|
||||
|
@ -36,12 +30,6 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW
|
|||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cdromLoadImageToRAM, "CDROM", "LoadImageToRAM",
|
||||
false);
|
||||
|
||||
connect(m_ui.biosPathBrowse, &QPushButton::pressed, this, &ConsoleSettingsWidget::onBrowseBIOSPathButtonClicked);
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.fastBoot, tr("Fast Boot"), tr("Unchecked"),
|
||||
tr("Patches the BIOS to skip the console's boot animation. Does not work with all games, "
|
||||
"but usually safe to enabled."));
|
||||
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.cdromLoadImageToRAM, tr("Preload Image to RAM"), tr("Unchecked"),
|
||||
tr("Loads the game image into RAM. Useful for network paths that may become unreliable during gameplay. In some "
|
||||
|
@ -49,16 +37,3 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW
|
|||
}
|
||||
|
||||
ConsoleSettingsWidget::~ConsoleSettingsWidget() = default;
|
||||
|
||||
void ConsoleSettingsWidget::onBrowseBIOSPathButtonClicked()
|
||||
{
|
||||
QString path = QDir::toNativeSeparators(
|
||||
QFileDialog::getOpenFileName(this, tr("Select BIOS Image"), QString(), tr(BIOS_IMAGE_FILTER)));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
m_ui.biosPath->setText(path);
|
||||
|
||||
m_host_interface->SetStringSettingValue("BIOS", "Path", path.toUtf8().constData());
|
||||
m_host_interface->applySettings();
|
||||
}
|
||||
|
|
|
@ -15,9 +15,6 @@ public:
|
|||
explicit ConsoleSettingsWidget(QtHostInterface* host_interface, QWidget* parent, SettingsDialog* dialog);
|
||||
~ConsoleSettingsWidget();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onBrowseBIOSPathButtonClicked();
|
||||
|
||||
private:
|
||||
Ui::ConsoleSettingsWidget m_ui;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>502</width>
|
||||
<height>358</height>
|
||||
<height>255</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -42,41 +42,6 @@
|
|||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="region"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>BIOS Image Path:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="fastBoot">
|
||||
<property name="text">
|
||||
<string>Fast Boot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="enableTTYOutput">
|
||||
<property name="text">
|
||||
<string>Enable TTY Output</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="biosPath"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="biosPathBrowse">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -145,7 +110,7 @@
|
|||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/icons.qrc"/>
|
||||
<include location="resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
<ClCompile Include="advancedsettingswidget.cpp" />
|
||||
<ClCompile Include="audiosettingswidget.cpp" />
|
||||
<ClCompile Include="autoupdaterdialog.cpp" />
|
||||
<ClCompile Include="biossettingswidget.cpp" />
|
||||
<ClCompile Include="consolesettingswidget.cpp" />
|
||||
<ClCompile Include="enhancementsettingswidget.cpp" />
|
||||
<ClCompile Include="gamelistmodel.cpp" />
|
||||
|
@ -68,6 +69,7 @@
|
|||
<ItemGroup>
|
||||
<QtMoc Include="aboutdialog.h" />
|
||||
<QtMoc Include="audiosettingswidget.h" />
|
||||
<QtMoc Include="biossettingswidget.h" />
|
||||
<QtMoc Include="controllersettingswidget.h" />
|
||||
<QtMoc Include="enhancementsettingswidget.h" />
|
||||
<QtMoc Include="memorycardsettingswidget.h" />
|
||||
|
@ -124,6 +126,9 @@
|
|||
<QtUi Include="audiosettingswidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="biossettingswidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="consolesettingswidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
|
@ -171,6 +176,7 @@
|
|||
<ClCompile Include="$(IntDir)moc_audiosettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_autoupdaterdialog.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_advancedsettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_biossettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_consolesettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_controllersettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_enhancementsettingswidget.cpp" />
|
||||
|
|
|
@ -646,6 +646,8 @@ void MainWindow::connectSignals()
|
|||
connect(m_ui.actionSettings, &QAction::triggered, [this]() { doSettings(SettingsDialog::Category::Count); });
|
||||
connect(m_ui.actionGeneralSettings, &QAction::triggered,
|
||||
[this]() { doSettings(SettingsDialog::Category::GeneralSettings); });
|
||||
connect(m_ui.actionBIOSSettings, &QAction::triggered,
|
||||
[this]() { doSettings(SettingsDialog::Category::BIOSSettings); });
|
||||
connect(m_ui.actionConsoleSettings, &QAction::triggered,
|
||||
[this]() { doSettings(SettingsDialog::Category::ConsoleSettings); });
|
||||
connect(m_ui.actionGameListSettings, &QAction::triggered,
|
||||
|
|
|
@ -115,6 +115,7 @@
|
|||
<addaction name="actionFullscreen"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionGeneralSettings"/>
|
||||
<addaction name="actionBIOSSettings"/>
|
||||
<addaction name="actionConsoleSettings"/>
|
||||
<addaction name="actionGameListSettings"/>
|
||||
<addaction name="actionHotkeySettings"/>
|
||||
|
@ -322,6 +323,15 @@
|
|||
<string>E&xit</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionBIOSSettings">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/icons/media-flash-2.png</normaloff>:/icons/media-flash-2.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>B&IOS Settings...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionConsoleSettings">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
|
|
BIN
src/duckstation-qt/resources/icons/media-flash-2.png
Normal file
BIN
src/duckstation-qt/resources/icons/media-flash-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
src/duckstation-qt/resources/icons/media-flash-2@2x.png
Normal file
BIN
src/duckstation-qt/resources/icons/media-flash-2@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4 KiB |
|
@ -59,6 +59,8 @@
|
|||
<file>icons/list-remove@2x.png</file>
|
||||
<file>icons/media-flash.png</file>
|
||||
<file>icons/media-flash@2x.png</file>
|
||||
<file>icons/media-flash-2.png</file>
|
||||
<file>icons/media-flash-2@2x.png</file>
|
||||
<file>icons/media-flash-24.png</file>
|
||||
<file>icons/media-flash-24@2x.png</file>
|
||||
<file>icons/media-optical.png</file>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "settingsdialog.h"
|
||||
#include "advancedsettingswidget.h"
|
||||
#include "audiosettingswidget.h"
|
||||
#include "biossettingswidget.h"
|
||||
#include "consolesettingswidget.h"
|
||||
#include "controllersettingswidget.h"
|
||||
#include "displaysettingswidget.h"
|
||||
|
@ -24,6 +25,7 @@ SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent
|
|||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
m_general_settings = new GeneralSettingsWidget(host_interface, m_ui.settingsContainer, this);
|
||||
m_bios_settings = new BIOSSettingsWidget(host_interface, m_ui.settingsContainer, this);
|
||||
m_console_settings = new ConsoleSettingsWidget(host_interface, m_ui.settingsContainer, this);
|
||||
m_game_list_settings = new GameListSettingsWidget(host_interface, m_ui.settingsContainer);
|
||||
m_hotkey_settings = new HotkeySettingsWidget(host_interface, m_ui.settingsContainer);
|
||||
|
@ -36,6 +38,7 @@ SettingsDialog::SettingsDialog(QtHostInterface* host_interface, QWidget* parent
|
|||
m_advanced_settings = new AdvancedSettingsWidget(host_interface, m_ui.settingsContainer, this);
|
||||
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::GeneralSettings), m_general_settings);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::BIOSSettings), m_bios_settings);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::ConsoleSettings), m_console_settings);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::GameListSettings), m_game_list_settings);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::HotkeySettings), m_hotkey_settings);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
class QtHostInterface;
|
||||
|
||||
class GeneralSettingsWidget;
|
||||
class BIOSSettingsWidget;
|
||||
class GameListSettingsWidget;
|
||||
class HotkeySettingsWidget;
|
||||
class ConsoleSettingsWidget;
|
||||
|
@ -27,6 +28,7 @@ public:
|
|||
enum class Category
|
||||
{
|
||||
GeneralSettings,
|
||||
BIOSSettings,
|
||||
ConsoleSettings,
|
||||
GameListSettings,
|
||||
HotkeySettings,
|
||||
|
@ -44,6 +46,7 @@ public:
|
|||
~SettingsDialog();
|
||||
|
||||
GeneralSettingsWidget* getGeneralSettingsWidget() const { return m_general_settings; }
|
||||
BIOSSettingsWidget* getBIOSSettingsWidget() const { return m_bios_settings; }
|
||||
ConsoleSettingsWidget* getConsoleSettingsWidget() const { return m_console_settings; }
|
||||
GameListSettingsWidget* getGameListSettingsWidget() const { return m_game_list_settings; }
|
||||
HotkeySettingsWidget* getHotkeySettingsWidget() const { return m_hotkey_settings; }
|
||||
|
@ -72,6 +75,7 @@ private:
|
|||
QtHostInterface* m_host_interface;
|
||||
|
||||
GeneralSettingsWidget* m_general_settings = nullptr;
|
||||
BIOSSettingsWidget* m_bios_settings = nullptr;
|
||||
ConsoleSettingsWidget* m_console_settings = nullptr;
|
||||
GameListSettingsWidget* m_game_list_settings = nullptr;
|
||||
HotkeySettingsWidget* m_hotkey_settings = nullptr;
|
||||
|
@ -79,7 +83,7 @@ private:
|
|||
MemoryCardSettingsWidget* m_memory_card_settings = nullptr;
|
||||
DisplaySettingsWidget* m_display_settings = nullptr;
|
||||
EnhancementSettingsWidget* m_enhancement_settings = nullptr;
|
||||
PostProcessingSettingsWidget *m_post_processing_settings = nullptr;
|
||||
PostProcessingSettingsWidget* m_post_processing_settings = nullptr;
|
||||
AudioSettingsWidget* m_audio_settings = nullptr;
|
||||
AdvancedSettingsWidget* m_advanced_settings = nullptr;
|
||||
|
||||
|
|
|
@ -67,6 +67,15 @@
|
|||
<normaloff>:/icons/applications-system.png</normaloff>:/icons/applications-system.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>BIOS Settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="resources/resources.qrc">
|
||||
<normaloff>:/icons/media-flash-2.png</normaloff>:/icons/media-flash-2.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Console Settings</string>
|
||||
|
|
|
@ -1182,10 +1182,6 @@ void SDLHostInterface::DrawSettingsWindow()
|
|||
settings_changed = true;
|
||||
}
|
||||
|
||||
ImGui::Text("BIOS Path:");
|
||||
ImGui::SameLine(indent);
|
||||
settings_changed |= DrawFileChooser("##bios_path", &m_settings_copy.bios_path);
|
||||
|
||||
settings_changed |= ImGui::Checkbox("Enable TTY Output", &m_settings_copy.bios_patch_tty_enable);
|
||||
settings_changed |= ImGui::Checkbox("Fast Boot", &m_settings_copy.bios_patch_fast_boot);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue