diff --git a/src/cartridge.cpp b/src/cartridge.cpp index 9494b8d..7834fb4 100644 --- a/src/cartridge.cpp +++ b/src/cartridge.cpp @@ -44,9 +44,9 @@ bool Cartridge::loadRom(std::string path) romSize = ftell(romFile); fseek(romFile, 0, SEEK_SET); - // Choose the save extension based on the instance number + // Choose the save extension based on the instance ID // This ensures multiple instances don't write over the same file - std::string ext = number ? (".sv" + std::to_string(number + 1)) : ".sav"; + std::string ext = core->getId() ? (".sv" + std::to_string(core->getId() + 1)) : ".sav"; // Attempt to load the ROM's save into memory saveName = path.substr(0, path.rfind(".")) + ext; diff --git a/src/cartridge.h b/src/cartridge.h index eaff965..cbe03fc 100644 --- a/src/cartridge.h +++ b/src/cartridge.h @@ -38,7 +38,7 @@ enum NdsCmdMode class Cartridge { public: - Cartridge(Core *core, int number): core(core), number(number) {} + Cartridge(Core *core): core(core) {} ~Cartridge(); virtual bool loadRom(std::string path); @@ -52,7 +52,6 @@ class Cartridge protected: Core *core; - int number; FILE *romFile = nullptr; uint8_t *rom = nullptr, *save = nullptr; @@ -69,7 +68,7 @@ class Cartridge class CartridgeNds: public Cartridge { public: - CartridgeNds(Core *core, int number): Cartridge(core, number) {} + CartridgeNds(Core *core): Cartridge(core) {} bool loadRom(std::string path); void directBoot(); @@ -115,7 +114,7 @@ class CartridgeNds: public Cartridge class CartridgeGba: public Cartridge { public: - CartridgeGba(Core *core, int number): Cartridge(core, number) {} + CartridgeGba(Core *core): Cartridge(core) {} bool loadRom(std::string path); diff --git a/src/core.cpp b/src/core.cpp index 36d5c54..d21b756 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -24,9 +24,10 @@ #include "core.h" #include "settings.h" -Core::Core(std::string ndsPath, std::string gbaPath, int number): - cartridgeNds(this, number), - cartridgeGba(this, number), +Core::Core(std::string ndsPath, std::string gbaPath, int id): + id(id), + cartridgeNds(this), + cartridgeGba(this), cp15(this), divSqrt(this), dldi(this), @@ -40,7 +41,7 @@ Core::Core(std::string ndsPath, std::string gbaPath, int number): ipc(this), memory(this), rtc(this), - spi(this, number), + spi(this), spu(this), timers { Timers(this, 0), Timers(this, 1) }, wifi(this) diff --git a/src/core.h b/src/core.h index 0f195b3..c4c2405 100644 --- a/src/core.h +++ b/src/core.h @@ -66,11 +66,12 @@ struct Task class Core { public: - Core(std::string ndsPath = "", std::string gbaPath = "", int number = 0); + Core(std::string ndsPath = "", std::string gbaPath = "", int id = 0); void runFrame() { (this->*runFunc)(); } bool isGbaMode() { return gbaMode; } + int getId() { return id; } int getFps() { return fps; } uint32_t getGlobalCycles() { return globalCycles; } @@ -100,8 +101,9 @@ class Core Wifi wifi; private: - bool gbaMode = false; void (Core::*runFunc)() = &Core::runNdsFrame; + bool gbaMode = false; + int id = 0; std::vector tasks; uint32_t globalCycles = 0; diff --git a/src/desktop/layout_dialog.cpp b/src/desktop/layout_dialog.cpp index 1c771a8..5faf4d8 100644 --- a/src/desktop/layout_dialog.cpp +++ b/src/desktop/layout_dialog.cpp @@ -63,7 +63,7 @@ EVT_BUTTON(wxID_CANCEL, LayoutDialog::cancel) EVT_BUTTON(wxID_OK, LayoutDialog::confirm) wxEND_EVENT_TABLE() -LayoutDialog::LayoutDialog(NooFrame *frame): wxDialog(nullptr, wxID_ANY, "Screen Layout"), frame(frame) +LayoutDialog::LayoutDialog(NooApp *app): wxDialog(nullptr, wxID_ANY, "Screen Layout"), app(app) { // Remember the previous settings in case the changes are discarded prevSettings[0] = ScreenLayout::getScreenRotation(); @@ -173,144 +173,112 @@ void LayoutDialog::rotateNone(wxCommandEvent &event) { // Set the screen rotation setting to none ScreenLayout::setScreenRotation(0); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::rotateCw(wxCommandEvent &event) { // Set the screen rotation setting to clockwise ScreenLayout::setScreenRotation(1); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::rotateCcw(wxCommandEvent &event) { // Set the screen rotation setting to counter-clockwise ScreenLayout::setScreenRotation(2); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::arrangeAuto(wxCommandEvent &event) { // Set the screen arrangement setting to automatic ScreenLayout::setScreenArrangement(0); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::arrangeVert(wxCommandEvent &event) { // Set the screen arrangement setting to vertical ScreenLayout::setScreenArrangement(1); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::arrangeHori(wxCommandEvent &event) { // Set the screen arrangement setting to horizontal ScreenLayout::setScreenArrangement(2); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::sizeEven(wxCommandEvent &event) { // Set the screen sizing setting to even ScreenLayout::setScreenSizing(0); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::sizeTop(wxCommandEvent &event) { // Set the screen sizing setting to enlarge top ScreenLayout::setScreenSizing(1); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::sizeBot(wxCommandEvent &event) { // Set the screen sizing setting to enlarge bottom ScreenLayout::setScreenSizing(2); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::gapNone(wxCommandEvent &event) { // Set the screen gap setting to none ScreenLayout::setScreenGap(0); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::gapQuart(wxCommandEvent &event) { // Set the screen gap setting to quarter ScreenLayout::setScreenGap(1); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::gapHalf(wxCommandEvent &event) { // Set the screen gap setting to half ScreenLayout::setScreenGap(2); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::gapFull(wxCommandEvent &event) { // Set the screen gap setting to full ScreenLayout::setScreenGap(3); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::intScale(wxCommandEvent &event) { // Toggle the integer scale setting ScreenLayout::setIntegerScale(!ScreenLayout::getIntegerScale()); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::gbaCrop(wxCommandEvent &event) { // Toggle the GBA crop setting ScreenLayout::setGbaCrop(!ScreenLayout::getGbaCrop()); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::filter(wxCommandEvent &event) { // Toggle the screen filter setting NooApp::setScreenFilter(!NooApp::getScreenFilter()); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); } void LayoutDialog::cancel(wxCommandEvent &event) @@ -323,9 +291,7 @@ void LayoutDialog::cancel(wxCommandEvent &event) ScreenLayout::setIntegerScale(prevSettings[4]); ScreenLayout::setGbaCrop(prevSettings[5]); NooApp::setScreenFilter(prevSettings[6]); - - // Trigger a resize to update the screen layout - frame->SendSizeEvent(); + app->updateLayouts(); event.Skip(true); } diff --git a/src/desktop/layout_dialog.h b/src/desktop/layout_dialog.h index 1ce9b56..c5c7c1c 100644 --- a/src/desktop/layout_dialog.h +++ b/src/desktop/layout_dialog.h @@ -22,15 +22,15 @@ #include -#include "noo_frame.h" +class NooApp; class LayoutDialog: public wxDialog { public: - LayoutDialog(NooFrame *frame); + LayoutDialog(NooApp *app); private: - NooFrame *frame; + NooApp *app; int prevSettings[7]; diff --git a/src/desktop/noo_app.cpp b/src/desktop/noo_app.cpp index 12b35cd..0b4c52f 100644 --- a/src/desktop/noo_app.cpp +++ b/src/desktop/noo_app.cpp @@ -106,7 +106,7 @@ bool NooApp::OnInit() void NooApp::createFrame() { - // Create a new frame using the lowest free instance number + // Create a new frame using the lowest free instance ID for (int i = 0; i < MAX_FRAMES; i++) { if (!frames[i]) @@ -117,31 +117,41 @@ void NooApp::createFrame() } } -void NooApp::removeFrame(int number) +void NooApp::removeFrame(int id) { - // Free an instance number; this should be done on frame destruction - frames[number] = nullptr; + // Free an instance ID; this should be done on frame destruction + frames[id] = nullptr; } -void NooApp::connectCore(int number) +void NooApp::connectCore(int id) { // Connect a frame's core to all other active cores for (int i = 0; i < MAX_FRAMES; i++) { - if (!frames[i] || i == number) continue; + if (!frames[i] || i == id) continue; if (Core *core = frames[i]->getCore()) - core->wifi.addConnection(frames[number]->getCore()); + core->wifi.addConnection(frames[id]->getCore()); } } -void NooApp::disconnCore(int number) +void NooApp::disconnCore(int id) { // Disconnect a frame's core from all other active cores for (int i = 0; i < MAX_FRAMES; i++) { - if (!frames[i] || i == number) continue; + if (!frames[i] || i == id) continue; if (Core *core = frames[i]->getCore()) - core->wifi.remConnection(frames[number]->getCore()); + core->wifi.remConnection(frames[id]->getCore()); + } +} + +void NooApp::updateLayouts() +{ + // Trigger resize events for frames to update screen layouts + for (size_t i = 0; i < MAX_FRAMES; i++) + { + if (frames[i]) + frames[i]->SendSizeEvent(); } } @@ -163,7 +173,7 @@ int NooApp::audioCallback(const void *in, void *out, unsigned long count, uint32_t *original = nullptr; // Get samples from each instance so frame limiting is enforced - // Only the lowest instance number's samples are played; the rest are discarded + // Only the lowest instance ID's samples are played; the rest are discarded for (size_t i = 0; i < MAX_FRAMES; i++) { if (!frames[i]) continue; diff --git a/src/desktop/noo_app.h b/src/desktop/noo_app.h index 0f85402..5a274d6 100644 --- a/src/desktop/noo_app.h +++ b/src/desktop/noo_app.h @@ -31,10 +31,12 @@ class NooApp: public wxApp { public: void createFrame(); - void removeFrame(int number); + void removeFrame(int id); - void connectCore(int number); - void disconnCore(int number); + void connectCore(int id); + void disconnCore(int id); + + void updateLayouts(); static int getScreenFilter() { return screenFilter; } static int getKeyBind(int index) { return keyBinds[index]; } diff --git a/src/desktop/noo_frame.cpp b/src/desktop/noo_frame.cpp index 263e53d..a1ca4b9 100644 --- a/src/desktop/noo_frame.cpp +++ b/src/desktop/noo_frame.cpp @@ -81,8 +81,8 @@ EVT_DROP_FILES(NooFrame::dropFiles) EVT_CLOSE(NooFrame::close) wxEND_EVENT_TABLE() -NooFrame::NooFrame(NooApp *app, int number, std::string path): - wxFrame(nullptr, wxID_ANY, "NooDS"), app(app), number(number) +NooFrame::NooFrame(NooApp *app, int id, std::string path): + wxFrame(nullptr, wxID_ANY, "NooDS"), app(app), id(id) { // Set the icon wxIcon icon(icon_xpm); @@ -163,7 +163,7 @@ NooFrame::NooFrame(NooApp *app, int number, std::string path): wxMenuBar *menuBar = new wxMenuBar(); menuBar->Append(fileMenu, "&File"); menuBar->Append(systemMenu, "&System"); - if (number == 0) // Only show settings in the main instance + if (id == 0) // Only show settings in the main instance menuBar->Append(settingsMenu, "&Settings"); SetMenuBar(menuBar); @@ -216,7 +216,7 @@ void NooFrame::Refresh() // Override the refresh function to also update the FPS counter wxString label = "NooDS"; - if (number) label += wxString::Format(" (%d)", number + 1); + if (id > 0) label += wxString::Format(" (%d)", id + 1); if (running) label += wxString::Format(" - %d FPS", core->getFps()); SetLabel(label); } @@ -250,8 +250,8 @@ void NooFrame::startCore(bool full) try { // Attempt to boot the core - core = new Core(ndsPath, gbaPath, number); - app->connectCore(number); + core = new Core(ndsPath, gbaPath, id); + app->connectCore(id); } catch (CoreError e) { @@ -336,7 +336,7 @@ void NooFrame::stopCore(bool full) // Shut down the core if (core) { - app->disconnCore(number); + app->disconnCore(id); delete core; core = nullptr; } @@ -537,7 +537,7 @@ void NooFrame::inputSettings(wxCommandEvent &event) void NooFrame::layoutSettings(wxCommandEvent &event) { // Show the layout settings dialog - LayoutDialog layoutDialog(this); + LayoutDialog layoutDialog(app); layoutDialog.ShowModal(); } @@ -646,6 +646,6 @@ void NooFrame::close(wxCloseEvent &event) { // Properly shut down the emulator stopCore(true); - app->removeFrame(number); + app->removeFrame(id); event.Skip(true); } diff --git a/src/desktop/noo_frame.h b/src/desktop/noo_frame.h index e749426..7ff891b 100644 --- a/src/desktop/noo_frame.h +++ b/src/desktop/noo_frame.h @@ -31,7 +31,7 @@ class NooCanvas; class NooFrame: public wxFrame { public: - NooFrame(NooApp *app, int number = 0, std::string path = ""); + NooFrame(NooApp *app, int id = 0, std::string path = ""); void Refresh(); @@ -51,7 +51,7 @@ class NooFrame: public wxFrame wxJoystick *joystick; wxTimer *timer; - int number = 0; + int id = 0; Core *core = nullptr; bool running = false; diff --git a/src/spi.cpp b/src/spi.cpp index 0a0c318..e9b9eaf 100644 --- a/src/spi.cpp +++ b/src/spi.cpp @@ -61,11 +61,11 @@ bool Spi::loadFirmware() fread(firmware, sizeof(uint8_t), firmSize, file); fclose(file); - if (number > 0) + if (core->getId() > 0) { - // Increment the MAC address based on the instance number + // Increment the MAC address based on the instance ID // This allows instances to be detected as separate systems - firmware[0x36] += number; + firmware[0x36] += core->getId(); // Recalculate the WiFi config CRC uint16_t crc = crc16(0, &firmware[0x2C], 0x138); @@ -86,16 +86,16 @@ bool Spi::loadFirmware() firmware[0x21] = 0x3F; // User settings offset / 8, byte 2 // Set some WiFi config data - firmware[0x2C] = 0x38; // Config length, byte 1 - firmware[0x2D] = 0x01; // Config length, byte 2 - firmware[0x36] = number; // MAC address, byte 1 - firmware[0x37] = 0x09; // MAC address, byte 2 - firmware[0x38] = 0xBF; // MAC address, byte 3 - firmware[0x39] = 0x12; // MAC address, byte 4 - firmware[0x3A] = 0x34; // MAC address, byte 5 - firmware[0x3B] = 0x56; // MAC address, byte 6 - firmware[0x3C] = 0xFE; // Enabled channels, byte 1 - firmware[0x3D] = 0x3F; // Enabled channels, byte 2 + firmware[0x2C] = 0x38; // Config length, byte 1 + firmware[0x2D] = 0x01; // Config length, byte 2 + firmware[0x36] = core->getId(); // MAC address, byte 1 + firmware[0x37] = 0x09; // MAC address, byte 2 + firmware[0x38] = 0xBF; // MAC address, byte 3 + firmware[0x39] = 0x12; // MAC address, byte 4 + firmware[0x3A] = 0x34; // MAC address, byte 5 + firmware[0x3B] = 0x56; // MAC address, byte 6 + firmware[0x3C] = 0xFE; // Enabled channels, byte 1 + firmware[0x3D] = 0x3F; // Enabled channels, byte 2 // Calculate the WiFi config CRC uint16_t crc = crc16(0, &firmware[0x2C], 0x138); diff --git a/src/spi.h b/src/spi.h index 54132bb..eb2524f 100644 --- a/src/spi.h +++ b/src/spi.h @@ -27,7 +27,7 @@ class Core; class Spi { public: - Spi(Core *core, int number): core(core), number(number) {} + Spi(Core *core): core(core) {} ~Spi(); bool loadFirmware(); @@ -44,7 +44,6 @@ class Spi private: Core *core; - int number; uint8_t *firmware = nullptr; size_t firmSize = 0; diff --git a/src/wifi.cpp b/src/wifi.cpp index b94ed94..83d0336 100644 --- a/src/wifi.cpp +++ b/src/wifi.cpp @@ -143,7 +143,7 @@ void Wifi::processPackets() { wRxbufWrcsr++; wRxbufWrcsr = (wRxbufBegin & 0x1FFE) + (wRxbufWrcsr - (wRxbufBegin & 0x1FFE)) % ((wRxbufEnd & 0x1FFE) - (wRxbufBegin & 0x1FFE)); - wRxbufWrcsr &= 0x1FFF; + wRxbufWrcsr &= 0xFFF; } } @@ -344,7 +344,7 @@ void Wifi::writeWTxbufWrData(uint16_t mask, uint16_t value) wTxbufWrAddr += 2; if (wTxbufWrAddr == wTxbufGap) wTxbufWrAddr += wTxbufGapdisp << 1; - wTxbufWrAddr %= 0x2000; + wTxbufWrAddr &= 0x1FFF; // Decrement the write counter and trigger an interrupt at the end if (wTxbufCount > 0 && --wTxbufCount == 0) @@ -503,12 +503,14 @@ uint16_t Wifi::readWRxbufRdData() uint16_t value = core->memory.read(1, 0x4804000 + wRxbufRdAddr); // Increment the read address - wRxbufRdAddr += 2; - if (wRxbufRdAddr == wRxbufGap) - wRxbufRdAddr += wRxbufGapdisp << 1; if ((wRxbufBegin & 0x1FFE) != (wRxbufEnd & 0x1FFE)) + { + wRxbufRdAddr += 2; + if (wRxbufRdAddr == wRxbufGap) + wRxbufRdAddr += wRxbufGapdisp << 1; wRxbufRdAddr = (wRxbufBegin & 0x1FFE) + (wRxbufRdAddr - (wRxbufBegin & 0x1FFE)) % ((wRxbufEnd & 0x1FFE) - (wRxbufBegin & 0x1FFE)); - wRxbufRdAddr %= 0x2000; + wRxbufRdAddr &= 0x1FFF; + } // Decrement the read counter and trigger an interrupt at the end if (wRxbufCount > 0 && --wRxbufCount == 0)