i cannot figure it out istg
This commit is contained in:
@@ -116,6 +116,7 @@ void Core::Run(const float volumeL, const float volumeR) {
|
||||
}
|
||||
|
||||
for (int cycles = 0; cycles < mem->mmio.vi.cyclesPerHalfline;) {
|
||||
Scheduler::GetInstance().HandleEvents();
|
||||
const u32 taken = StepCPU();
|
||||
cycles += taken;
|
||||
frameCycles += taken;
|
||||
|
||||
@@ -96,51 +96,44 @@ u32 Interpreter::Step() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 DivideAddr(u32 addr, u32 &offset) {
|
||||
offset = (addr & (MAX_LINES_PER_BLOCK - 1)) / 4;
|
||||
return addr / MAX_LINES_PER_BLOCK;
|
||||
}
|
||||
|
||||
std::shared_ptr<CachedLine> CachedState::GetLine(u64 addr) {
|
||||
const CachedLine &CachedState::GetLine(u64 addr) {
|
||||
u32 offset;
|
||||
u32 page = DivideAddr(addr, offset);
|
||||
if (blocks[page])
|
||||
return blocks[page]->lines[offset];
|
||||
|
||||
return nullptr;
|
||||
return blocks[page].lines[offset];
|
||||
}
|
||||
|
||||
void CachedState::InsertLine(u64 addr, std::shared_ptr<CachedLine> line) {
|
||||
void CachedState::InsertLine(u64 addr, const CachedLine &line) {
|
||||
u32 offset;
|
||||
u32 page = DivideAddr(addr, offset);
|
||||
|
||||
if (!blocks[page])
|
||||
blocks[page] = std::make_unique<CachedBlock>();
|
||||
|
||||
blocks[page]->lines[offset] = line;
|
||||
blocks[page].lines[offset] = line;
|
||||
}
|
||||
|
||||
void CachedState::EvictLine(u64 addr) {
|
||||
u32 offset;
|
||||
u32 page = DivideAddr(addr, offset);
|
||||
|
||||
if (blocks[page]) {
|
||||
blocks[page]->lines[offset].reset();
|
||||
blocks[page].reset();
|
||||
}
|
||||
blocks[page].lines[offset] = CachedLine();
|
||||
}
|
||||
|
||||
u32 Interpreter::ExecuteCached() {
|
||||
auto addr = regs.pc;
|
||||
auto blockAddr = addr;
|
||||
auto line = cachedState.GetLine(addr);
|
||||
auto page = (addr >> 12) & 0xfffff;
|
||||
auto offset = addr & 0xfff;
|
||||
auto &blocks = cachedState.blocks;
|
||||
|
||||
if (line) {
|
||||
for (u32 i = 0; i < line->len; i++) {
|
||||
if (page >= blocks.size())
|
||||
blocks.push_back();
|
||||
|
||||
if (page < blocks.size()) {
|
||||
const auto &block = blocks[page];
|
||||
if (blocks[page].len > 0) {
|
||||
for (u32 i = 0; i < block.len; i++) {
|
||||
if (!MaybeAdvance())
|
||||
return i + 1;
|
||||
|
||||
Instruction instr = line->code[i];
|
||||
Instruction instr = block.code[i];
|
||||
DecodeExecute(instr);
|
||||
|
||||
// Branch likely with false condition, it wasn't taken so don't execute the delay slot
|
||||
@@ -148,13 +141,18 @@ u32 Interpreter::ExecuteCached() {
|
||||
break;
|
||||
}
|
||||
|
||||
if (line->cycles == 0)
|
||||
if (block.cycles == 0)
|
||||
Scheduler::GetInstance().SkipToNext();
|
||||
|
||||
return line->cycles;
|
||||
return block.cycles;
|
||||
}
|
||||
}
|
||||
|
||||
std::array<Instruction, MAX_INSTRUCTION_PER_LINE> code;
|
||||
if (line.code.size() > 0) {
|
||||
}
|
||||
|
||||
std::vector<Instruction> code;
|
||||
code.resize(MAX_INSTRUCTION_PER_LINE);
|
||||
|
||||
u32 i;
|
||||
bool fetchDelaySlot = false;
|
||||
@@ -180,7 +178,7 @@ u32 Interpreter::ExecuteCached() {
|
||||
}
|
||||
}
|
||||
|
||||
cachedState.InsertLine(blockAddr, std::make_shared<CachedLine>(code, i, i));
|
||||
cachedState.InsertLine(blockAddr, {code, i, i});
|
||||
|
||||
return ExecuteCached();
|
||||
}
|
||||
|
||||
@@ -5,36 +5,26 @@
|
||||
namespace n64 {
|
||||
struct Core;
|
||||
|
||||
static constexpr u32 MAX_LINES_PER_BLOCK = 1 << 12;
|
||||
static constexpr u32 MAX_INSTRUCTION_PER_LINE = MAX_LINES_PER_BLOCK >> 2;
|
||||
static constexpr u32 MAX_INSTRUCTION_PER_BLOCK = 1 << 12;
|
||||
|
||||
struct CachedLine {
|
||||
std::array<Instruction, MAX_INSTRUCTION_PER_LINE> code = {};
|
||||
struct CachedBlock {
|
||||
std::array<Instruction, MAX_INSTRUCTION_PER_BLOCK> code = {};
|
||||
u32 cycles = 0;
|
||||
u32 len = 0;
|
||||
};
|
||||
|
||||
struct CachedBlock {
|
||||
std::array<std::shared_ptr<CachedLine>, MAX_LINES_PER_BLOCK / 4> lines = {};
|
||||
};
|
||||
|
||||
using CachedBlocks = std::vector<std::unique_ptr<CachedBlock>>;
|
||||
|
||||
struct CachedState {
|
||||
CachedState() { blocks.resize((u64(std::numeric_limits<u32>::max()) + 1) / MAX_LINES_PER_BLOCK); }
|
||||
CachedBlocks blocks = {};
|
||||
CachedState() {}
|
||||
std::vector<CachedBlock> blocks = {};
|
||||
bool exception = false;
|
||||
|
||||
void Reset() {
|
||||
for (auto &block : blocks) {
|
||||
block.reset();
|
||||
}
|
||||
|
||||
blocks = {};
|
||||
exception = false;
|
||||
}
|
||||
|
||||
std::shared_ptr<CachedLine> GetLine(u64);
|
||||
void InsertLine(u64, std::shared_ptr<CachedLine>);
|
||||
const CachedLine &GetLine(u64);
|
||||
void InsertLine(u64, const CachedLine &);
|
||||
void EvictLine(u64);
|
||||
};
|
||||
|
||||
@@ -51,7 +41,6 @@ struct Interpreter final {
|
||||
cachedState.Reset();
|
||||
}
|
||||
|
||||
|
||||
CachedState cachedState;
|
||||
|
||||
private:
|
||||
|
||||
+64
-36
@@ -5,7 +5,9 @@
|
||||
#include <ImGuiImpl/StatusBar.hpp>
|
||||
#include <resources/gamecontrollerdb.h>
|
||||
|
||||
KaizenGui::KaizenGui() noexcept : window("Kaizen " KAIZEN_VERSION_STR, 1280, 720), settingsWindow(window), vulkanWidget(window.getHandle()), emuThread(fpsCounter, settingsWindow) {
|
||||
KaizenGui::KaizenGui() noexcept :
|
||||
window("Kaizen " KAIZEN_VERSION_STR, 1280, 720), settingsWindow(window), vulkanWidget(window.getHandle()),
|
||||
emuThread(fpsCounter, settingsWindow) {
|
||||
gui::Initialize(n64::Core::GetInstance().parallel.wsi, window.getHandle());
|
||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||
|
||||
@@ -33,7 +35,8 @@ void KaizenGui::QueryDevices(const SDL_Event &event) {
|
||||
if (gamepad)
|
||||
SDL_CloseGamepad(gamepad);
|
||||
break;
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,11 +48,16 @@ void KaizenGui::HandleInput(const SDL_Event &event) {
|
||||
if (!gamepad)
|
||||
break;
|
||||
{
|
||||
pif.UpdateButton(0, n64::Controller::Key::Z, SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) == SDL_JOYSTICK_AXIS_MAX);
|
||||
pif.UpdateButton(0, n64::Controller::Key::CUp, SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY) <= -127);
|
||||
pif.UpdateButton(0, n64::Controller::Key::CDown, SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY) >= 127);
|
||||
pif.UpdateButton(0, n64::Controller::Key::CLeft, SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX) <= -127);
|
||||
pif.UpdateButton(0, n64::Controller::Key::CRight, SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX) >= 127);
|
||||
pif.UpdateButton(0, n64::Controller::Key::Z,
|
||||
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) == SDL_JOYSTICK_AXIS_MAX);
|
||||
pif.UpdateButton(0, n64::Controller::Key::CUp,
|
||||
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY) <= -127);
|
||||
pif.UpdateButton(0, n64::Controller::Key::CDown,
|
||||
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY) >= 127);
|
||||
pif.UpdateButton(0, n64::Controller::Key::CLeft,
|
||||
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX) <= -127);
|
||||
pif.UpdateButton(0, n64::Controller::Key::CRight,
|
||||
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX) >= 127);
|
||||
|
||||
float xclamped = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTX);
|
||||
if (xclamped < 0) {
|
||||
@@ -134,16 +142,21 @@ void KaizenGui::HandleInput(const SDL_Event &event) {
|
||||
|
||||
float x = 0, y = 0;
|
||||
|
||||
if (keys[SDL_SCANCODE_UP]) y = 86;
|
||||
if (keys[SDL_SCANCODE_DOWN]) y = -86;
|
||||
if (keys[SDL_SCANCODE_LEFT]) x = -86;
|
||||
if (keys[SDL_SCANCODE_RIGHT]) x = 86;
|
||||
if (keys[SDL_SCANCODE_UP])
|
||||
y = 86;
|
||||
if (keys[SDL_SCANCODE_DOWN])
|
||||
y = -86;
|
||||
if (keys[SDL_SCANCODE_LEFT])
|
||||
x = -86;
|
||||
if (keys[SDL_SCANCODE_RIGHT])
|
||||
x = 86;
|
||||
|
||||
pif.UpdateAxis(0, n64::Controller::Axis::X, x);
|
||||
pif.UpdateAxis(0, n64::Controller::Axis::Y, y);
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,9 +169,9 @@ std::pair<std::optional<s64>, std::optional<Util::Error::MemoryAccess>> RenderEr
|
||||
auto memoryAccess = Util::Error::GetMemoryAccess();
|
||||
if (memoryAccess.has_value()) {
|
||||
const auto [is_write, size, address, written_val] = memoryAccess.value();
|
||||
ImGui::Text("%s", std::format("{} {}-bit value @ {:08X}{}", is_write ? "Writing" : "Reading",
|
||||
static_cast<u8>(size), address,
|
||||
is_write ? std::format(" (value = 0x{:X})", written_val) : "")
|
||||
ImGui::Text("%s",
|
||||
std::format("{} {}-bit value @ {:08X}{}", is_write ? "Writing" : "Reading", static_cast<u8>(size),
|
||||
address, is_write ? std::format(" (value = 0x{:X})", written_val) : "")
|
||||
.c_str());
|
||||
}
|
||||
|
||||
@@ -260,7 +273,8 @@ void KaizenGui::RenderUI() {
|
||||
if (ImGui::BeginPopupModal(Util::Error::GetSeverity().as_c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
emuThread.TogglePause();
|
||||
switch (Util::Error::GetSeverity().as_enum) {
|
||||
case Util::Error::Severity::WARN: {
|
||||
case Util::Error::Severity::WARN:
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_TitleBg, 0x8054eae5);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, 0xff7be4e1);
|
||||
ImGui::Text("Warning of type: %s", Util::Error::GetType().as_c_str());
|
||||
@@ -270,8 +284,10 @@ void KaizenGui::RenderUI() {
|
||||
RenderErrorMessageDetails();
|
||||
|
||||
if (n64::Core::GetInstance().romLoaded && !n64::Core::GetInstance().pause) {
|
||||
const bool ignore = ImGui::Button("Try continuing"); ImGui::SameLine();
|
||||
const bool stop = ImGui::Button("Stop emulation"); ImGui::SameLine();
|
||||
const bool ignore = ImGui::Button("Try continuing");
|
||||
ImGui::SameLine();
|
||||
const bool stop = ImGui::Button("Stop emulation");
|
||||
ImGui::SameLine();
|
||||
const bool chooseAnother = ImGui::Button("Choose another ROM");
|
||||
if (ignore || stop || chooseAnother) {
|
||||
Util::Error::SetHandled();
|
||||
@@ -294,8 +310,10 @@ void KaizenGui::RenderUI() {
|
||||
|
||||
if (ImGui::Button("OK"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
} break;
|
||||
case Util::Error::Severity::UNRECOVERABLE: {
|
||||
}
|
||||
break;
|
||||
case Util::Error::Severity::UNRECOVERABLE:
|
||||
{
|
||||
emuThread.Stop();
|
||||
ImGui::PushStyleColor(ImGuiCol_TitleBg, 0x800000ff);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, 0xff3b3bbf);
|
||||
@@ -307,8 +325,10 @@ void KaizenGui::RenderUI() {
|
||||
RenderErrorMessageDetails();
|
||||
if (ImGui::Button("OK"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
} break;
|
||||
case Util::Error::Severity::NON_FATAL: {
|
||||
}
|
||||
break;
|
||||
case Util::Error::Severity::NON_FATAL:
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_TitleBg, 0x800000ff);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, 0xff3b3bbf);
|
||||
ImGui::Text("An error has occurred!");
|
||||
@@ -318,10 +338,13 @@ void KaizenGui::RenderUI() {
|
||||
ImGui::Text(R"(Error message: "%s")", Util::Error::GetError().c_str());
|
||||
auto [lastPC, memoryAccess] = RenderErrorMessageDetails();
|
||||
|
||||
const bool ignore = ImGui::Button("Try continuing"); ImGui::SameLine();
|
||||
const bool stop = ImGui::Button("Stop emulation"); ImGui::SameLine();
|
||||
const bool ignore = ImGui::Button("Try continuing");
|
||||
ImGui::SameLine();
|
||||
const bool stop = ImGui::Button("Stop emulation");
|
||||
ImGui::SameLine();
|
||||
const bool chooseAnother = ImGui::Button("Choose another ROM");
|
||||
const bool openInDebugger = lastPC.has_value() ? ImGui::Button("Add breakpoint at this PC and open the debugger") : false;
|
||||
const bool openInDebugger =
|
||||
lastPC.has_value() ? ImGui::Button("Add breakpoint at this PC and open the debugger") : false;
|
||||
if (ignore || stop || chooseAnother || openInDebugger) {
|
||||
Util::Error::SetHandled();
|
||||
ImGui::CloseCurrentPopup();
|
||||
@@ -346,8 +369,10 @@ void KaizenGui::RenderUI() {
|
||||
debugger.Open();
|
||||
emuThread.Reset();
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
@@ -359,7 +384,8 @@ void KaizenGui::RenderUI() {
|
||||
}
|
||||
|
||||
if (shouldDisplaySpinner) {
|
||||
ImGui::SetNextWindowPos({static_cast<float>(width) * 0.5f, static_cast<float>(height) * 0.5f}, 0, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowPos({static_cast<float>(width) * 0.5f, static_cast<float>(height) * 0.5f}, 0,
|
||||
ImVec2(0.5f, 0.5f));
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, IM_COL32_BLACK_TRANS);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
|
||||
@@ -386,8 +412,11 @@ void KaizenGui::RenderUI() {
|
||||
|
||||
if (fileDialogOpen) {
|
||||
fileDialogOpen = false;
|
||||
constexpr SDL_DialogFileFilter filters[] = {{"All files", "*"}, {"Nintendo 64 executable", "n64;z64;v64"}, {"Nintendo 64 executable archive", "rar;tar;zip;7z"}};
|
||||
SDL_ShowOpenFileDialog([](void *userdata, const char * const *filelist, int) {
|
||||
constexpr SDL_DialogFileFilter filters[] = {{"All files", "*"},
|
||||
{"Nintendo 64 executable", "n64;z64;v64"},
|
||||
{"Nintendo 64 executable archive", "rar;tar;zip;7z"}};
|
||||
SDL_ShowOpenFileDialog(
|
||||
[](void *userdata, const char *const *filelist, int) {
|
||||
auto kaizen = static_cast<KaizenGui *>(userdata);
|
||||
|
||||
if (!filelist) {
|
||||
@@ -402,10 +431,10 @@ void KaizenGui::RenderUI() {
|
||||
|
||||
kaizen->fileToLoad = *filelist;
|
||||
kaizen->shouldDisplaySpinner = true;
|
||||
|
||||
std::thread fileWorker(&KaizenGui::FileWorker, kaizen);
|
||||
fileWorker.detach();
|
||||
}, this, window.getHandle(), filters, 3, nullptr, false);
|
||||
},
|
||||
this, window.getHandle(), filters, 3, nullptr, false);
|
||||
}
|
||||
|
||||
if (minimized)
|
||||
@@ -442,7 +471,8 @@ void KaizenGui::run() {
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
minimized = false;
|
||||
break;
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
QueryDevices(e);
|
||||
HandleInput(e);
|
||||
@@ -455,6 +485,4 @@ void KaizenGui::run() {
|
||||
}
|
||||
}
|
||||
|
||||
void KaizenGui::LoadTAS(const std::string &path) noexcept {
|
||||
n64::Core::GetInstance().LoadTAS(fs::path(path));
|
||||
}
|
||||
void KaizenGui::LoadTAS(const std::string &path) noexcept { n64::Core::GetInstance().LoadTAS(fs::path(path)); }
|
||||
|
||||
@@ -37,12 +37,13 @@ private:
|
||||
void HandleInput(const SDL_Event &event);
|
||||
void QueryDevices(const SDL_Event &event);
|
||||
|
||||
[[noreturn]] void FileWorker() {
|
||||
void FileWorker() {
|
||||
while (true) {
|
||||
if (!fileToLoad.empty()) {
|
||||
LoadROM(fileToLoad);
|
||||
shouldDisplaySpinner = false;
|
||||
fileToLoad = "";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user