Skip to content

Commit 0095bf8

Browse files
authored
Merge pull request #160 from asmblur/master
Simple BIOS overlay support.
2 parents daf18f2 + 486f08a commit 0095bf8

File tree

9 files changed

+274
-24
lines changed

9 files changed

+274
-24
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ vsprojects/packages
2929
*.o
3030
*.dep
3131
/pcsx-redux
32+
/pcsx.json
33+
/memcard1.mcd
34+
/memcard2.mcd
35+

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ CPPFLAGS += -Ithird_party
1313
CPPFLAGS += -Ithird_party/imgui
1414
CPPFLAGS += -Ithird_party/imgui/examples/libs/gl3w
1515
CPPFLAGS += -Ithird_party/imgui/examples
16+
CPPFLAGS += -Ithird_party/imgui/misc/cpp
1617
CPPFLAGS += -Ithird_party/imgui_club
1718
CPPFLAGS += -Ithird_party/zstr/src
1819
CPPFLAGS += -O3

src/core/misc.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ int RecvPcsxInfo() {
681681
else
682682
PCSX::g_emulator.m_psxCpu = &g_psxRec;
683683
#endif
684-
if (PCSX::g_emulator.m_psxCpu->Init() == -1) {
684+
if (!PCSX::g_emulator.m_psxCpu->Init()) {
685685
PCSX::g_system->close();
686686
return -1;
687687
}

src/core/psxemulator.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ class Emulator {
107107
enum VideoType { PSX_TYPE_NTSC = 0, PSX_TYPE_PAL }; // PSX Types
108108
enum CPUType { CPU_DYNAREC = 0, CPU_INTERPRETER }; // CPU Types
109109
enum CDDAType { CDDA_DISABLED = 0, CDDA_ENABLED_LE, CDDA_ENABLED_BE }; // CDDA Types
110+
struct OverlaySetting {
111+
typedef SettingPath<TYPESTRING("Filename")> Filename;
112+
typedef Setting<uint32_t, TYPESTRING("FileOffset")> FileOffset;
113+
typedef Setting<uint32_t, TYPESTRING("LoadOffset")> LoadOffset;
114+
typedef Setting<uint32_t, TYPESTRING("LoadSize")> LoadSize;
115+
typedef Setting<bool, TYPESTRING("Enabled")> Enabled;
116+
typedef Settings<Filename, FileOffset, LoadOffset, LoadSize, Enabled> type;
117+
};
118+
typedef SettingArray<TYPESTRING("Overlay"), OverlaySetting::type> SettingBiosOverlay;
110119
typedef Setting<bool, TYPESTRING("Stdout")> SettingStdout;
111120
typedef SettingPath<TYPESTRING("Logfile")> SettingLogfile;
112121
typedef SettingPath<TYPESTRING("Mcd1")> SettingMcd1;
@@ -133,7 +142,7 @@ class Emulator {
133142
Settings<SettingStdout, SettingLogfile, SettingMcd1, SettingMcd2, SettingBios, SettingPpfDir, SettingPsxExe,
134143
SettingXa, SettingSioIrq, SettingSpuIrq, SettingBnWMdec, SettingAutoVideo, SettingVideo, SettingCDDA,
135144
SettingHLE, SettingFastBoot, SettingDebug, SettingVerbose, SettingRCntFix, SettingIsoPath, SettingLocale,
136-
SettingMcd1Inserted, SettingMcd2Inserted>
145+
SettingMcd1Inserted, SettingMcd2Inserted, SettingBiosOverlay>
137146
settings;
138147
class PcsxConfig {
139148
public:

src/core/psxmem.cc

Lines changed: 93 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
* PSX memory functions.
2222
*/
2323

24+
#include "core/psxmem.h"
2425
#include "core/debug.h"
2526
#include "core/file.h"
26-
#include "core/psxmem.h"
2727
#include "core/psxhw.h"
2828
#include "core/r3000a.h"
2929

@@ -70,27 +70,114 @@ int PCSX::Memory::psxMemInit() {
7070
}
7171

7272
void PCSX::Memory::psxMemReset() {
73-
File *f;
74-
73+
const uint32_t bios_size = 0x00080000;
7574
memset(g_psxM, 0, 0x00200000);
7675
memset(g_psxP, 0, 0x00010000);
77-
memset(g_psxR, 0, 0x80000);
76+
memset(g_psxR, 0, bios_size);
7877
g_emulator.m_psxBios->m_realBiosLoaded = false;
7978

8079
// Load BIOS
8180
PCSX::u8string biosPath = PCSX::g_emulator.settings.get<PCSX::Emulator::SettingBios>().string();
8281
if (!PCSX::g_emulator.settings.get<PCSX::Emulator::SettingHLE>()) {
83-
f = new File(biosPath);
82+
File *f = new File(biosPath);
8483
if (f->failed()) {
8584
PCSX::g_system->message(_("Could not open BIOS:\"%s\". Enabling HLE Bios!\n"), biosPath.c_str());
8685
PCSX::g_emulator.settings.get<PCSX::Emulator::SettingHLE>() = true;
8786
} else {
88-
f->read(g_psxR, 0x80000);
87+
f->read(g_psxR, bios_size);
8988
f->close();
9089
PCSX::g_system->printf(_("Loaded BIOS: %s\n"), biosPath.c_str());
9190
g_emulator.m_psxBios->m_realBiosLoaded = true;
9291
}
9392
delete f;
93+
94+
if (g_emulator.m_psxBios->m_realBiosLoaded) {
95+
for (auto &overlay : g_emulator.settings.get<Emulator::SettingBiosOverlay>()) {
96+
if (!overlay.get<Emulator::OverlaySetting::Enabled>()) continue;
97+
const auto &filename = overlay.get<Emulator::OverlaySetting::Filename>();
98+
auto foffset = overlay.get<Emulator::OverlaySetting::FileOffset>();
99+
auto loffset = overlay.get<Emulator::OverlaySetting::LoadOffset>();
100+
auto lsize = overlay.get<Emulator::OverlaySetting::LoadSize>();
101+
bool failed = false;
102+
File *f = new File(filename);
103+
104+
if (f->failed()) {
105+
PCSX::g_system->message(_("Could not open BIOS Overlay:\"%s\"!\n"), filename.string().c_str());
106+
failed = true;
107+
}
108+
109+
ssize_t fsize;
110+
if (!failed) {
111+
f->seek(0, SEEK_END);
112+
fsize = f->tell();
113+
114+
if (foffset < 0) {
115+
// negative offset means from end of file
116+
foffset = foffset + fsize;
117+
118+
if (foffset < 0) {
119+
// fail if the negative offset is more than the total file size
120+
PCSX::g_system->message(_("Invalid file offset for BIOS Overlay:\"%s\"!\n"),
121+
filename.string().c_str());
122+
failed = true;
123+
}
124+
} else if (foffset > fsize) {
125+
PCSX::g_system->message(_("Invalid file offset for BIOS Overlay:\"%s\"!\n"),
126+
filename.string().c_str());
127+
failed = true;
128+
}
129+
}
130+
if (!failed) {
131+
f->seek(foffset, SEEK_SET);
132+
133+
fsize = fsize - foffset;
134+
135+
if (lsize <= 0) {
136+
// lsize <= 0 means "from file size"
137+
138+
lsize = fsize + lsize;
139+
140+
if (lsize < 0) {
141+
PCSX::g_system->message(_("Invalid load size specified BIOS Overlay:\"%s\"!\n"),
142+
filename.string().c_str());
143+
failed = true;
144+
}
145+
}
146+
}
147+
if (!failed) {
148+
if (lsize > fsize) {
149+
PCSX::g_system->message(_("Invalid load size specified BIOS Overlay:\"%s\"!\n"),
150+
filename.string().c_str());
151+
failed = true;
152+
}
153+
}
154+
if (!failed) {
155+
if (loffset < 0) {
156+
// negative offset means from end of device memory region
157+
158+
loffset = loffset + bios_size;
159+
160+
if (loffset < 0) {
161+
// fail if the negative offset is more than the BIOS size
162+
PCSX::g_system->message(_("Invalid load offset for BIOS Overlay:\"%s\"!\n"),
163+
filename.string().c_str());
164+
failed = true;
165+
}
166+
} else if (loffset > bios_size) {
167+
PCSX::g_system->message(_("Invalid load offset for BIOS Overlay:\"%s\"!\n"),
168+
filename.string().c_str());
169+
failed = true;
170+
}
171+
}
172+
if (!failed) {
173+
f->read(g_psxR + loffset, lsize);
174+
PCSX::g_system->printf(_("Loaded BIOS overlay: %s\n"), filename.string().c_str());
175+
}
176+
177+
f->close();
178+
delete f;
179+
}
180+
}
94181
}
95182
}
96183

src/gui/gui.cc

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "imgui.h"
3636
#include "imgui_impl_glfw.h"
3737
#include "imgui_impl_opengl3.h"
38+
#include "imgui_stdlib.h"
3839

3940
#include "core/cdrom.h"
4041
#include "core/gpu.h"
@@ -403,7 +404,23 @@ void PCSX::GUI::endFrame() {
403404
}
404405
ImGui::Separator();
405406
if (ImGui::BeginMenu(_("Configuration"))) {
406-
ImGui::MenuItem(_("Emulation"), nullptr, &m_showCfg);
407+
if (ImGui::MenuItem(_("Emulation"), nullptr, &m_showCfg)) {
408+
auto& overlays = g_emulator.settings.get<Emulator::SettingBiosOverlay>();
409+
m_overlayFileOffsets.resize(overlays.size());
410+
m_overlayLoadOffsets.resize(overlays.size());
411+
m_overlayLoadSizes.resize(overlays.size());
412+
unsigned counter = 0;
413+
for (auto& overlay : overlays) {
414+
char str[32];
415+
std::snprintf(str, 32, "0x%08x", overlay.get<Emulator::OverlaySetting::FileOffset>().value);
416+
m_overlayFileOffsets[counter] = str;
417+
std::snprintf(str, 32, "0x%08x", overlay.get<Emulator::OverlaySetting::LoadOffset>().value);
418+
m_overlayLoadOffsets[counter] = str;
419+
std::snprintf(str, 32, "0x%08x", overlay.get<Emulator::OverlaySetting::LoadSize>().value);
420+
m_overlayLoadSizes[counter] = str;
421+
counter++;
422+
}
423+
}
407424
ImGui::MenuItem(_("GPU"), nullptr, &PCSX::g_emulator.m_gpu->m_showCfg);
408425
ImGui::MenuItem(_("SPU"), nullptr, &PCSX::g_emulator.m_spu->m_showCfg);
409426
ImGui::EndMenu();
@@ -612,6 +629,7 @@ static void ShowHelpMarker(const char* desc) {
612629
bool PCSX::GUI::configure() {
613630
bool changed = false;
614631
bool selectBiosDialog = false;
632+
bool selectBiosOverlayDialog = false;
615633
auto& settings = PCSX::g_emulator.settings;
616634
if (!m_showCfg) return false;
617635

@@ -689,16 +707,105 @@ bool PCSX::GUI::configure() {
689707
changed |= ImGui::Checkbox(_("BIOS HLE"), &settings.get<Emulator::SettingHLE>().value);
690708
changed |= ImGui::Checkbox(_("Fast boot"), &settings.get<Emulator::SettingFastBoot>().value);
691709
auto bios = settings.get<Emulator::SettingBios>().string();
692-
ImGui::InputText(_("BIOS file"), const_cast<char*>(reinterpret_cast<const char*>(bios.c_str())), bios.length(), ImGuiInputTextFlags_ReadOnly);
710+
ImGui::InputText(_("BIOS file"), const_cast<char*>(reinterpret_cast<const char*>(bios.c_str())), bios.length(),
711+
ImGuiInputTextFlags_ReadOnly);
693712
ImGui::SameLine();
694713
selectBiosDialog = ImGui::Button("...");
714+
if (ImGui::CollapsingHeader(_("Advanced BIOS patching"))) {
715+
auto& overlays = settings.get<Emulator::SettingBiosOverlay>();
716+
if (ImGui::Button(_("Add one entry"))) overlays.push_back({});
717+
m_overlayFileOffsets.resize(overlays.size());
718+
m_overlayLoadOffsets.resize(overlays.size());
719+
m_overlayLoadSizes.resize(overlays.size());
720+
int counter = 0;
721+
int overlayToRemove = -1;
722+
int swapMe = -1;
723+
for (auto& overlay : overlays) {
724+
std::string id = "overlay" + std::to_string(counter);
725+
ImGui::BeginChild(id.c_str(), ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 7.0f), true);
726+
auto overlayFilename = overlay.get<Emulator::OverlaySetting::Filename>().string();
727+
ImGui::InputText(_("Filename"),
728+
const_cast<char*>(reinterpret_cast<const char*>(overlayFilename.c_str())),
729+
overlayFilename.length(), ImGuiInputTextFlags_ReadOnly);
730+
ImGui::SameLine();
731+
if (ImGui::Button("...")) {
732+
selectBiosOverlayDialog = true;
733+
m_selectedBiosOverlayId = counter;
734+
}
735+
if (ImGui::InputText(_("File Offset"), &m_overlayFileOffsets[counter])) {
736+
char* endPtr;
737+
uint32_t offset = strtoul(m_overlayFileOffsets[counter].c_str(), &endPtr, 0);
738+
if (!m_overlayFileOffsets[counter].empty() && !*endPtr) {
739+
overlay.get<Emulator::OverlaySetting::FileOffset>().value = offset;
740+
changed = true;
741+
}
742+
}
743+
if (ImGui::InputText(_("Load Offset"), &m_overlayLoadOffsets[counter])) {
744+
char* endPtr;
745+
uint32_t offset = strtoul(m_overlayLoadOffsets[counter].c_str(), &endPtr, 0);
746+
if (!m_overlayLoadOffsets[counter].empty() && !*endPtr) {
747+
overlay.get<Emulator::OverlaySetting::LoadOffset>().value = offset;
748+
changed = true;
749+
}
750+
}
751+
if (ImGui::InputText(_("Load Size"), &m_overlayLoadSizes[counter])) {
752+
char* endPtr;
753+
uint32_t size = strtoul(m_overlayLoadSizes[counter].c_str(), &endPtr, 0);
754+
if (!m_overlayLoadSizes[counter].empty() && !*endPtr) {
755+
overlay.get<Emulator::OverlaySetting::LoadSize>().value = size;
756+
changed = true;
757+
}
758+
}
759+
if (ImGui::Checkbox(_("Enabled"), &overlay.get<Emulator::OverlaySetting::Enabled>().value))
760+
changed = true;
761+
ImGui::SameLine();
762+
if (ImGui::Button(_("Remove"))) {
763+
overlayToRemove = counter;
764+
}
765+
ImGui::SameLine();
766+
if (ImGui::Button(_("Move up"))) {
767+
swapMe = counter - 1;
768+
}
769+
ImGui::SameLine();
770+
if (ImGui::Button(_("Move down"))) {
771+
swapMe = counter;
772+
}
773+
ImGui::EndChild();
774+
counter++;
775+
}
776+
if (overlayToRemove >= 0) {
777+
overlays.erase(overlays.begin() + overlayToRemove);
778+
changed = true;
779+
}
780+
if ((swapMe >= 0) && (swapMe != (overlays.size() - 1))) {
781+
std::iter_swap(overlays.begin() + swapMe, overlays.begin() + swapMe + 1);
782+
std::iter_swap(m_overlayFileOffsets.begin() + swapMe, m_overlayFileOffsets.begin() + swapMe + 1);
783+
std::iter_swap(m_overlayLoadOffsets.begin() + swapMe, m_overlayLoadOffsets.begin() + swapMe + 1);
784+
std::iter_swap(m_overlayLoadSizes.begin() + swapMe, m_overlayLoadSizes.begin() + swapMe + 1);
785+
changed = true;
786+
}
787+
}
695788
}
696789
ImGui::End();
697790

698791
if (selectBiosDialog) m_selectBiosDialog.openDialog();
699792
if (m_selectBiosDialog.draw()) {
700793
std::vector<PCSX::u8string> fileToOpen = m_selectBiosDialog.selected();
701-
if (!fileToOpen.empty()) settings.get<Emulator::SettingBios>().value = fileToOpen[0];
794+
if (!fileToOpen.empty()) {
795+
settings.get<Emulator::SettingBios>().value = fileToOpen[0];
796+
changed = true;
797+
}
798+
}
799+
800+
if (selectBiosOverlayDialog) m_selectBiosOverlayDialog.openDialog();
801+
if (m_selectBiosOverlayDialog.draw()) {
802+
std::vector<PCSX::u8string> fileToOpen = m_selectBiosOverlayDialog.selected();
803+
if (!fileToOpen.empty()) {
804+
settings.get<Emulator::SettingBiosOverlay>()[m_selectedBiosOverlayId]
805+
.get<Emulator::OverlaySetting::Filename>()
806+
.value = fileToOpen[0];
807+
changed = true;
808+
}
702809
}
703810
return changed;
704811
}

src/gui/gui.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,12 @@ class GUI final {
154154
Widgets::Assembly m_assembly = {&m_mainMemEditors[0].editor, &m_hwrEditor.editor};
155155
Widgets::FileDialog m_openIsoFileDialog = {[]() { return _("Open Image"); }};
156156
Widgets::FileDialog m_selectBiosDialog = {[]() { return _("Select BIOS"); }};
157+
Widgets::FileDialog m_selectBiosOverlayDialog = {[]() { return _("Select BIOS Overlay"); }};
158+
int m_selectedBiosOverlayId;
157159
Widgets::Breakpoints m_breakpoints;
160+
std::vector<std::string> m_overlayFileOffsets;
161+
std::vector<std::string> m_overlayLoadOffsets;
162+
std::vector<std::string> m_overlayLoadSizes;
158163

159164
bool m_showCfg = false;
160165
bool &m_showBiosCounters = {settings.get<ShowBiosCounters>().value};

0 commit comments

Comments
 (0)