diff --git a/nxemu.sln b/nxemu.sln index 70b00af3..f0966191 100644 --- a/nxemu.sln +++ b/nxemu.sln @@ -4,6 +4,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 17.7.34018.315 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nxemu", "src\nxemu\nxemu.vcxproj", "{C8659F5A-3AFA-4BF0-9409-3B9819E17714}" + ProjectSection(ProjectDependencies) = postProject + {148184C3-456B-409C-8112-2FC35DE07D92} = {148184C3-456B-409C-8112-2FC35DE07D92} + {686302AD-7653-43FF-A120-44E8D45B7371} = {686302AD-7653-43FF-A120-44E8D45B7371} + {F119CF47-F0E6-4152-A9BD-07B20BD0B540} = {F119CF47-F0E6-4152-A9BD-07B20BD0B540} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rd Party", "3rd Party", "{F9F8A94D-341A-46BD-A4DA-13CC33489942}" EndProject diff --git a/src/nxemu-core/machine/switch_system.cpp b/src/nxemu-core/machine/switch_system.cpp index 8fe3ba31..acc2b463 100644 --- a/src/nxemu-core/machine/switch_system.cpp +++ b/src/nxemu-core/machine/switch_system.cpp @@ -2,6 +2,7 @@ #include "file_format/nacp.h" #include "file_format/nro.h" #include "settings/core_settings.h" +#include "settings/identifiers.h" #include "settings/settings.h" std::unique_ptr SwitchSystem::m_instance; @@ -30,17 +31,39 @@ SwitchSystem * SwitchSystem::GetInstance() return m_instance.get(); } -SwitchSystem::SwitchSystem() +SwitchSystem::SwitchSystem() : + m_emulationRunning(false) { } +SwitchSystem::~SwitchSystem() +{ + StopEmulation(); +} + bool SwitchSystem::Initialize() { + if (!m_modules.Initialize()) + { + return false; + } return true; } void SwitchSystem::StartEmulation(void) { + m_emulationRunning = true; + m_modules.StartEmulation(); +} + +void SwitchSystem::StopEmulation(void) +{ + if (!m_emulationRunning) + { + return; + } + m_emulationRunning = false; + m_modules.StopEmulation(); } bool SwitchSystem::LoadRom(const char * romFile) diff --git a/src/nxemu-core/machine/switch_system.h b/src/nxemu-core/machine/switch_system.h index c01e2fd0..a947cc52 100644 --- a/src/nxemu-core/machine/switch_system.h +++ b/src/nxemu-core/machine/switch_system.h @@ -1,12 +1,13 @@ #pragma once #include +#include "modules/modules.h" class Nro; class SwitchSystem { public: - ~SwitchSystem() = default; + ~SwitchSystem(); static bool Create(); static void ShutDown(); @@ -14,6 +15,7 @@ public: bool LoadRom(const char * romFile); void StartEmulation(void); + void StopEmulation(void); private: SwitchSystem(const SwitchSystem &) = delete; @@ -25,5 +27,7 @@ private: bool LoadNRO(const char * nroFile); static std::unique_ptr m_instance; + bool m_emulationRunning; + Modules m_modules; std::unique_ptr m_nro; }; diff --git a/src/nxemu-core/modules/cpu_module.cpp b/src/nxemu-core/modules/cpu_module.cpp new file mode 100644 index 00000000..6aee80a2 --- /dev/null +++ b/src/nxemu-core/modules/cpu_module.cpp @@ -0,0 +1,15 @@ +#include "cpu_module.h" + +void CpuModule::UnloadModule(void) +{ +} + +bool CpuModule::LoadFunctions(void) +{ + return true; +} + +MODULE_TYPE CpuModule::ModuleType() const +{ + return MODULE_TYPE_CPU; +} diff --git a/src/nxemu-core/modules/cpu_module.h b/src/nxemu-core/modules/cpu_module.h new file mode 100644 index 00000000..7b7ead74 --- /dev/null +++ b/src/nxemu-core/modules/cpu_module.h @@ -0,0 +1,20 @@ +#pragma once +#include "module_base.h" + +class CpuModule : + public ModuleBase +{ +public: + CpuModule() = default; + ~CpuModule() = default; + +protected: + void UnloadModule(void); + bool LoadFunctions(void); + + MODULE_TYPE ModuleType() const; + +private: + CpuModule(const CpuModule &) = delete; + CpuModule & operator=(const CpuModule &) = delete; +}; \ No newline at end of file diff --git a/src/nxemu-core/modules/module_base.h b/src/nxemu-core/modules/module_base.h index f75057a0..d4fd358a 100644 --- a/src/nxemu-core/modules/module_base.h +++ b/src/nxemu-core/modules/module_base.h @@ -13,14 +13,33 @@ class ModuleBase friend ModuleList; typedef void(CALL * tyGetModuleInfo)(MODULE_INFO * info); + typedef int(CALL * tyModuleInitialize)(ModuleInterfaces & interfaces); + typedef void(CALL * tyModuleCleanup)(); + typedef void(CALL * tyEmulationStarting)(); + typedef void(CALL * tyEmulationStopping)(); public: ModuleBase(); + ~ModuleBase(); + + bool Load(const char * fileName, IModuleNotification * notification, IModuleSettings * settings); + ModuleBase::tyEmulationStarting EmulationStarting; + ModuleBase::tyEmulationStopping EmulationStopping; + ModuleBase::tyModuleCleanup ModuleCleanup; protected: + virtual void UnloadModule(void) = 0; + virtual bool LoadFunctions(void) = 0; + virtual MODULE_TYPE ModuleType() const = 0; + static bool ValidVersion(MODULE_INFO & info); + DynLibHandle m_lib; + MODULE_INFO m_moduleInfo; + private: ModuleBase(const ModuleBase &) = delete; ModuleBase & operator=(const ModuleBase &) = delete; + + void ModuleDone(bool callUnloadModule = true); }; \ No newline at end of file diff --git a/src/nxemu-core/modules/module_notification.cpp b/src/nxemu-core/modules/module_notification.cpp new file mode 100644 index 00000000..fce316ec --- /dev/null +++ b/src/nxemu-core/modules/module_notification.cpp @@ -0,0 +1,12 @@ +#include "module_notification.h" +#include "notification.h" + +void ModuleNotification::DisplayError(const char * message) +{ + g_notify->DisplayError(message); +} + +void ModuleNotification::BreakPoint(const char * fileName, uint32_t lineNumber) +{ + g_notify->BreakPoint(fileName, lineNumber); +} diff --git a/src/nxemu-core/modules/module_notification.h b/src/nxemu-core/modules/module_notification.h new file mode 100644 index 00000000..6fdf27f3 --- /dev/null +++ b/src/nxemu-core/modules/module_notification.h @@ -0,0 +1,11 @@ +#pragma once + +#include "module_base.h" + +class ModuleNotification : + public IModuleNotification +{ +public: + void DisplayError(const char * message); + void BreakPoint(const char * fileName, uint32_t lineNumber); +}; \ No newline at end of file diff --git a/src/nxemu-core/modules/module_settings.cpp b/src/nxemu-core/modules/module_settings.cpp new file mode 100644 index 00000000..7c04922b --- /dev/null +++ b/src/nxemu-core/modules/module_settings.cpp @@ -0,0 +1,22 @@ +#include "module_settings.h" +#include "settings/settings.h" + +std::string ModuleSettings::GetString(const char * setting) const +{ + return Settings::GetInstance().GetString(setting); +} + +bool ModuleSettings::GetBool(const char * setting) const +{ + return Settings::GetInstance().GetBool(setting); +} + +void ModuleSettings::SetString(const char * setting, const char * value) +{ + Settings::GetInstance().SetString(setting, value); +} + +void ModuleSettings::SetBool(const char * setting, bool value) +{ + Settings::GetInstance().SetBool(setting, value); +} diff --git a/src/nxemu-core/modules/module_settings.h b/src/nxemu-core/modules/module_settings.h new file mode 100644 index 00000000..beaccfe4 --- /dev/null +++ b/src/nxemu-core/modules/module_settings.h @@ -0,0 +1,14 @@ +#pragma once + +#include "module_base.h" + +class ModuleSettings : + public IModuleSettings +{ +public: + //IModuleSettings + std::string GetString(const char * setting) const; + bool GetBool(const char * setting) const; + void SetString(const char * setting, const char * value); + void SetBool(const char * setting, bool value); +}; \ No newline at end of file diff --git a/src/nxemu-core/modules/modules.cpp b/src/nxemu-core/modules/modules.cpp new file mode 100644 index 00000000..792c732d --- /dev/null +++ b/src/nxemu-core/modules/modules.cpp @@ -0,0 +1,83 @@ +#include "modules.h" +#include "settings/core_settings.h" + +Modules::Modules() : + m_cpuModule(nullptr), + m_videoModule(nullptr), + m_operatingsystemModule(nullptr) +{ + CreateModules(); +} + +Modules::~Modules() +{ + for (BaseModules::iterator itr = m_baseModules.begin(); itr != m_baseModules.end(); itr++) + { + (*itr)->ModuleCleanup(); + } + m_baseModules.clear(); +} + +bool Modules::Initialize() +{ + if (m_cpuModule.get() == nullptr || m_videoModule.get() == nullptr || m_operatingsystemModule.get() == nullptr) + { + return false; + } + return true; +} + +void Modules::StartEmulation(void) +{ + for (BaseModules::iterator itr = m_baseModules.begin(); itr != m_baseModules.end(); itr++) + { + (*itr)->EmulationStarting(); + } +} + +void Modules::StopEmulation(void) +{ + for (BaseModules::iterator itr = m_baseModules.begin(); itr != m_baseModules.end(); itr++) + { + (*itr)->EmulationStopping(); + } +} + +void Modules::CreateModules(void) +{ + m_cpuFile = coreSettings.moduleCpuSelected; + m_videoFile = coreSettings.moduleVideoSelected; + m_operatingsystemFile = coreSettings.moduleOsSelected; + + LoadModule(m_cpuFile, m_cpuModule); + LoadModule(m_videoFile, m_videoModule); + LoadModule(m_operatingsystemFile, m_operatingsystemModule); + + if (m_cpuModule.get() != nullptr) + { + m_baseModules.push_back(m_cpuModule.get()); + } + if (m_videoModule.get() != nullptr) + { + m_baseModules.push_back(m_videoModule.get()); + } + if (m_operatingsystemModule.get() != nullptr) + { + m_baseModules.push_back(m_operatingsystemModule.get()); + } +} + +template +void Modules::LoadModule(const std::string & fileName, std::unique_ptr & plugin) +{ + Path fullPath((const char *)coreSettings.moduleDir, fileName.c_str()); + plugin = std::make_unique(); + if (plugin.get() == nullptr || !fullPath.FileExists() || !plugin->Load(fullPath, &m_moduleNotification, &m_moduleSettings)) + { + plugin = nullptr; + } +} + +template void Modules::LoadModule(const std::string & fileName, std::unique_ptr & plugin); +template void Modules::LoadModule(const std::string & fileName, std::unique_ptr & plugin); +template void Modules::LoadModule(const std::string & fileName, std::unique_ptr & plugin); diff --git a/src/nxemu-core/modules/modules.h b/src/nxemu-core/modules/modules.h new file mode 100644 index 00000000..938af588 --- /dev/null +++ b/src/nxemu-core/modules/modules.h @@ -0,0 +1,41 @@ +#pragma once +#include "cpu_module.h" +#include "module_notification.h" +#include "module_settings.h" +#include "operating_system_module.h" +#include "video_module.h" +#include +#include +#include + +class Modules +{ + typedef std::vector BaseModules; + +public: + Modules(); + ~Modules(); + + bool Initialize(); + void StartEmulation(void); + void StopEmulation(void); + +private: + Modules(const Modules &) = delete; + Modules & operator=(const Modules &) = delete; + + void CreateModules(void); + + template + void LoadModule(const std::string & fileName, std::unique_ptr & plugin); + + ModuleNotification m_moduleNotification; + ModuleSettings m_moduleSettings; + BaseModules m_baseModules; + std::unique_ptr m_cpuModule; + std::unique_ptr m_videoModule; + std::unique_ptr m_operatingsystemModule; + std::string m_cpuFile; + std::string m_videoFile; + std::string m_operatingsystemFile; +}; diff --git a/src/nxemu-core/modules/operating_system_module.cpp b/src/nxemu-core/modules/operating_system_module.cpp new file mode 100644 index 00000000..6a694901 --- /dev/null +++ b/src/nxemu-core/modules/operating_system_module.cpp @@ -0,0 +1,15 @@ +#include "operating_system_module.h" + +void OperatingSystemModule::UnloadModule() +{ +} + +bool OperatingSystemModule::LoadFunctions() +{ + return true; +} + +MODULE_TYPE OperatingSystemModule::ModuleType() const +{ + return MODULE_TYPE_OPERATING_SYSTEM; +} diff --git a/src/nxemu-core/modules/operating_system_module.h b/src/nxemu-core/modules/operating_system_module.h new file mode 100644 index 00000000..dde5eecc --- /dev/null +++ b/src/nxemu-core/modules/operating_system_module.h @@ -0,0 +1,19 @@ +#pragma once +#include "module_base.h" + +class OperatingSystemModule : + public ModuleBase +{ +public: + OperatingSystemModule() = default; + ~OperatingSystemModule() = default; + +protected: + void UnloadModule(); + bool LoadFunctions(); + MODULE_TYPE ModuleType() const; + +private: + OperatingSystemModule(const OperatingSystemModule &) = delete; + OperatingSystemModule & operator=(const OperatingSystemModule &) = delete; +}; \ No newline at end of file diff --git a/src/nxemu-core/modules/video_module.cpp b/src/nxemu-core/modules/video_module.cpp new file mode 100644 index 00000000..ce3a9a60 --- /dev/null +++ b/src/nxemu-core/modules/video_module.cpp @@ -0,0 +1,15 @@ +#include "video_module.h" + +void VideoModule::UnloadModule(void) +{ +} + +bool VideoModule::LoadFunctions(void) +{ + return true; +} + +MODULE_TYPE VideoModule::ModuleType() const +{ + return MODULE_TYPE_VIDEO; +} \ No newline at end of file diff --git a/src/nxemu-core/modules/video_module.h b/src/nxemu-core/modules/video_module.h new file mode 100644 index 00000000..1238cee3 --- /dev/null +++ b/src/nxemu-core/modules/video_module.h @@ -0,0 +1,19 @@ +#pragma once +#include "module_base.h" + +class VideoModule : + public ModuleBase +{ +public: + VideoModule() = default; + ~VideoModule() = default; + +protected: + void UnloadModule(void); + bool LoadFunctions(void); + MODULE_TYPE ModuleType() const; + +private: + VideoModule(const VideoModule &) = delete; + VideoModule & operator=(const VideoModule &) = delete; +}; \ No newline at end of file diff --git a/src/nxemu-core/notification.cpp b/src/nxemu-core/notification.cpp new file mode 100644 index 00000000..2945bc02 --- /dev/null +++ b/src/nxemu-core/notification.cpp @@ -0,0 +1,3 @@ +#include "notification.h" + +INotification * g_notify; diff --git a/src/nxemu-core/notification.h b/src/nxemu-core/notification.h index cba393cc..e906612f 100644 --- a/src/nxemu-core/notification.h +++ b/src/nxemu-core/notification.h @@ -1,6 +1,13 @@ #pragma once +#include __interface INotification { + //Error Messages + virtual void DisplayError(const char * message) const = 0; + virtual void BreakPoint(const char * fileName, uint32_t lineNumber) = 0; + virtual void AppInitDone(void) = 0; }; + +extern INotification * g_notify; diff --git a/src/nxemu-core/nxemu-core.vcxproj b/src/nxemu-core/nxemu-core.vcxproj index b453408f..eb707c5d 100644 --- a/src/nxemu-core/nxemu-core.vcxproj +++ b/src/nxemu-core/nxemu-core.vcxproj @@ -29,15 +29,24 @@ + + + + + + + + + @@ -46,8 +55,15 @@ + + + + + + + diff --git a/src/nxemu-core/nxemu-core.vcxproj.filters b/src/nxemu-core/nxemu-core.vcxproj.filters index a82dd540..1caa2b8f 100644 --- a/src/nxemu-core/nxemu-core.vcxproj.filters +++ b/src/nxemu-core/nxemu-core.vcxproj.filters @@ -78,6 +78,33 @@ Header Files\file_format + + Header Files\modules + + + Header Files\modules + + + Header Files\modules + + + Header Files\modules + + + Module Spec + + + Module Spec + + + Header Files\modules + + + Header Files\modules + + + Header Files\settings + @@ -107,5 +134,26 @@ Source Files\file_format + + Source Files\modules + + + Source Files\modules + + + Source Files\modules + + + Source Files\modules + + + Source Files\modules + + + Source Files\modules + + + Source Files + \ No newline at end of file diff --git a/src/nxemu-core/settings/core_settings.cpp b/src/nxemu-core/settings/core_settings.cpp index 64df0676..867cffd8 100644 --- a/src/nxemu-core/settings/core_settings.cpp +++ b/src/nxemu-core/settings/core_settings.cpp @@ -1,4 +1,5 @@ #include "core_settings.h" +#include "identifiers.h" #include "settings.h" #include #include diff --git a/src/nxemu-core/settings/core_settings.h b/src/nxemu-core/settings/core_settings.h index 408a57e3..91e50f22 100644 --- a/src/nxemu-core/settings/core_settings.h +++ b/src/nxemu-core/settings/core_settings.h @@ -2,15 +2,6 @@ #include "common/path.h" #include -namespace NXCoreSetting -{ -constexpr const char * GameFile = "nxcore:GameFile"; -constexpr const char * GameName = "nxcore:GameName"; -constexpr const char * ModuleCpuSelected = "nxcore:ModuleCpuSelected"; -constexpr const char * ModuleVideoSelected = "nxcore:ModuleVideoSelected"; -constexpr const char * ModuleOsSelected = "nxcore:ModuleOsSelected"; -} // namespace NXCoreSetting - struct CoreSettings { Path configDir; diff --git a/src/nxemu-core/settings/identifiers.h b/src/nxemu-core/settings/identifiers.h new file mode 100644 index 00000000..88c19d87 --- /dev/null +++ b/src/nxemu-core/settings/identifiers.h @@ -0,0 +1,10 @@ +#pragma once + +namespace NXCoreSetting +{ +constexpr const char * GameFile = "nxcore:GameFile"; +constexpr const char * GameName = "nxcore:GameName"; +constexpr const char * ModuleCpuSelected = "nxcore:ModuleCpuSelected"; +constexpr const char * ModuleVideoSelected = "nxcore:ModuleVideoSelected"; +constexpr const char * ModuleOsSelected = "nxcore:ModuleOsSelected"; +} // namespace NXCoreSetting \ No newline at end of file diff --git a/src/nxemu-core/settings/settings.cpp b/src/nxemu-core/settings/settings.cpp index 28cfaa9d..f73a8934 100644 --- a/src/nxemu-core/settings/settings.cpp +++ b/src/nxemu-core/settings/settings.cpp @@ -95,12 +95,32 @@ std::string Settings::GetDefaultString(const char * setting) const return itr->second; } +bool Settings::GetDefaultBool(const char * setting) const +{ + SettingsMapBool::const_iterator itr = m_settingsDefaultBool.find(setting); + if (itr == m_settingsDefaultBool.end()) + { + return false; + } + return itr->second; +} + std::string Settings::GetString(const char * setting) const { SettingsMapString::const_iterator itr = m_settingsString.find(setting); if (itr == m_settingsString.end()) { - return ""; + return GetDefaultString(setting); + } + return itr->second; +} + +bool Settings::GetBool(const char * setting) const +{ + SettingsMapBool::const_iterator itr = m_settingsBool.find(setting); + if (itr == m_settingsBool.end()) + { + return GetDefaultBool(setting); } return itr->second; } @@ -124,6 +144,11 @@ void Settings::SetDefaultString(const char * setting, const char * value) m_settingsDefaultString[setting] = value; } +void Settings::SetDefaultBool(const char * setting, bool value) +{ + m_settingsDefaultBool[setting] = value; +} + void Settings::SetString(const char * setting, const char * value) { if (setting == nullptr || value == nullptr) @@ -140,6 +165,22 @@ void Settings::SetString(const char * setting, const char * value) NotifyChange(setting); } +void Settings::SetBool(const char * setting, bool value) +{ + if (setting == nullptr) + { + return; + } + + SettingsMapBool::const_iterator it = m_settingsBool.find(setting); + if (it != m_settingsBool.end() && it->second == value) + { + return; + } + m_settingsBool[setting] = value; + NotifyChange(setting); +} + void Settings::Save(void) { std::string jsonStr = JsonStyledWriter().write(m_details); diff --git a/src/nxemu-core/settings/settings.h b/src/nxemu-core/settings/settings.h index 754b5502..86f16f19 100644 --- a/src/nxemu-core/settings/settings.h +++ b/src/nxemu-core/settings/settings.h @@ -22,10 +22,14 @@ public: void SetSettings(const char * section, JsonValue & json); std::string GetDefaultString(const char * setting) const; + bool GetDefaultBool(const char * setting) const; std::string GetString(const char * setting) const; + bool GetBool(const char * setting) const; bool GetChanged(const char * setting) const; void SetDefaultString(const char * setting, const char * value); + void SetDefaultBool(const char * setting, bool value); void SetString(const char * setting, const char * value); + void SetBool(const char * setting, bool value); void SetChanged(const char * setting, bool changed); void Save(void); @@ -39,7 +43,9 @@ private: void NotifyChange(const char * setting); SettingsMapString m_settingsString; + SettingsMapBool m_settingsBool; SettingsMapString m_settingsDefaultString; + SettingsMapBool m_settingsDefaultBool; SettingsMapBool m_settingsChanged; NotificationMap m_notification; diff --git a/src/nxemu-cpu/nxemu-cpu.cpp b/src/nxemu-cpu/nxemu-cpu.cpp index 9f00cc4e..b274d51f 100644 --- a/src/nxemu-cpu/nxemu-cpu.cpp +++ b/src/nxemu-cpu/nxemu-cpu.cpp @@ -1,6 +1,9 @@ #include #include +IModuleNotification * g_notify = nullptr; +IModuleSettings * g_settings = nullptr; + /* Function: GetModuleInfo Purpose: Fills the MODULE_INFO structure with information about the DLL. @@ -18,6 +21,54 @@ void CALL GetModuleInfo(MODULE_INFO * info) #endif } +/* +Function: ModuleInitialize +Purpose: Initializes the module for global use. +Input: None +Output: Returns 0 on success +*/ +int CALL ModuleInitialize(ModuleInterfaces & interfaces) +{ + g_notify = interfaces.notification; + g_settings = interfaces.settings; + + if (g_notify == nullptr || g_settings == nullptr) + { + return -1; + } + return 0; +} + +/* +Function: ModuleCleanup +Purpose: Cleans up global resources used by the module. +Input: None +Output: None +*/ +void CALL ModuleCleanup() +{ +} + +/* +Function: EmulationStarting +Purpose: Called when emulation is starting +Input: None. +Output: None. +*/ +void CALL EmulationStarting() +{ +} + +/* +Function: EmulationStopping +Purpose: Called when emulation is stopping +Input: None +Output: None +*/ +void CALL EmulationStopping() +{ +} + extern "C" int __stdcall DllMain(void * /*hinst*/, unsigned long /*fdwReason*/, void * /*lpReserved*/) { return true; diff --git a/src/nxemu-cpu/nxemu-cpu.vcxproj.filters b/src/nxemu-cpu/nxemu-cpu.vcxproj.filters index a8a65633..528eb19f 100644 --- a/src/nxemu-cpu/nxemu-cpu.vcxproj.filters +++ b/src/nxemu-cpu/nxemu-cpu.vcxproj.filters @@ -14,4 +14,9 @@ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + Source Files + + \ No newline at end of file diff --git a/src/nxemu-module-spec/base.h b/src/nxemu-module-spec/base.h index d345d2b0..c1f9d6a3 100644 --- a/src/nxemu-module-spec/base.h +++ b/src/nxemu-module-spec/base.h @@ -1,5 +1,6 @@ #pragma once #include +#include #if !defined(EXPORT) && defined(__cplusplus) #define EXPORT extern "C" __declspec(dllexport) @@ -27,6 +28,26 @@ enum MODULE_TYPE : uint16_t MODULE_TYPE_OPERATING_SYSTEM = 3, }; +__interface IModuleNotification +{ + void DisplayError(const char * message) = 0; + void BreakPoint(const char * fileName, uint32_t lLineNumber) = 0; +}; + +__interface IModuleSettings +{ + std::string GetString(const char * setting) const = 0; + bool GetBool(const char * setting) const = 0; + void SetString(const char * setting, const char * value) = 0; + void SetBool(const char * setting, bool value) = 0; +}; + +typedef struct +{ + IModuleNotification * notification; + IModuleSettings * settings; +} ModuleInterfaces; + typedef struct { uint16_t version; // Should be set module spec version eg MODULE_VIDEO_SPECS_VERSION @@ -37,7 +58,39 @@ typedef struct /* Function: GetModuleInfo Purpose: Fills the MODULE_INFO structure with information about the DLL. -Input: A pointer to a MODULE_INFO structure to be populated. +Input: A pointer to a MODULE_INFO structure to be populated. Output: none */ EXPORT void CALL GetModuleInfo(MODULE_INFO * info); + +/* +Function: ModuleInitialize +Purpose: Initializes the module for global use. +Input: None +Output: Returns 0 on success +*/ +EXPORT int CALL ModuleInitialize(ModuleInterfaces & interfaces); + +/* +Function: ModuleCleanup +Purpose: Cleans up global resources used by the module. +Input: None +Output: None +*/ +EXPORT void CALL ModuleCleanup(); + +/* +Function: EmulationStarting +Purpose: Called when emulation is starting +Input: None. +Output: None. +*/ +EXPORT void CALL EmulationStarting(); + +/* +Function: EmulationStopping +Purpose: Called when emulation is stopping +Input: None +Output: None +*/ +EXPORT void CALL EmulationStopping(); diff --git a/src/nxemu-os/nxemu-os.cpp b/src/nxemu-os/nxemu-os.cpp index 6e2145f6..53caa431 100644 --- a/src/nxemu-os/nxemu-os.cpp +++ b/src/nxemu-os/nxemu-os.cpp @@ -1,6 +1,10 @@ #include #include +IModuleNotification * g_notify = nullptr; +IModuleSettings * g_settings = nullptr; + + /* Function: GetModuleInfo Purpose: Fills the MODULE_INFO structure with information about the DLL. @@ -18,6 +22,54 @@ void CALL GetModuleInfo(MODULE_INFO * info) #endif } +/* +Function: ModuleInitialize +Purpose: Initializes the module for global use. +Input: None +Output: Returns 0 on success +*/ +int CALL ModuleInitialize(ModuleInterfaces & interfaces) +{ + g_notify = interfaces.notification; + g_settings = interfaces.settings; + + if (g_notify == nullptr || g_settings == nullptr) + { + return -1; + } + return 0; +} + +/* +Function: ModuleCleanup +Purpose: Cleans up global resources used by the module. +Input: None +Output: None +*/ +void CALL ModuleCleanup() +{ +} + +/* +Function: EmulationStarting +Purpose: Called when emulation is starting +Input: None. +Output: None. +*/ +void CALL EmulationStarting() +{ +} + +/* +Function: EmulationStopping +Purpose: Called when emulation is stopping +Input: None +Output: None +*/ +void CALL EmulationStopping() +{ +} + extern "C" int __stdcall DllMain(void * /*hinst*/, unsigned long /*fdwReason*/, void * /*lpReserved*/) { return true; diff --git a/src/nxemu-video/nxemu-video.cpp b/src/nxemu-video/nxemu-video.cpp index 128dc37e..94221f2a 100644 --- a/src/nxemu-video/nxemu-video.cpp +++ b/src/nxemu-video/nxemu-video.cpp @@ -1,6 +1,9 @@ #include #include +IModuleNotification * g_notify = nullptr; +IModuleSettings * g_settings = nullptr; + /* Function: GetModuleInfo Purpose: Fills the MODULE_INFO structure with information about the DLL. @@ -18,6 +21,54 @@ void CALL GetModuleInfo(MODULE_INFO * info) #endif } +/* +Function: ModuleInitialize +Purpose: Initializes the module for global use. +Input: None +Output: Returns 0 on success +*/ +int CALL ModuleInitialize(ModuleInterfaces & interfaces) +{ + g_notify = interfaces.notification; + g_settings = interfaces.settings; + + if (g_notify == nullptr || g_settings == nullptr) + { + return -1; + } + return 0; +} + +/* +Function: ModuleCleanup +Purpose: Cleans up global resources used by the module. +Input: None +Output: None +*/ +void CALL ModuleCleanup() +{ +} + +/* +Function: EmulationStarting +Purpose: Called when emulation is starting +Input: None. +Output: None. +*/ +void CALL EmulationStarting() +{ +} + +/* +Function: EmulationStopping +Purpose: Called when emulation is stopping +Input: None +Output: None +*/ +void CALL EmulationStopping() +{ +} + extern "C" int __stdcall DllMain(void * /*hinst*/, unsigned long /*fdwReason*/, void * /*lpReserved*/) { return true; diff --git a/src/nxemu/user_interface/main_window.cpp b/src/nxemu/user_interface/main_window.cpp index 93f3b013..4e56a1b4 100644 --- a/src/nxemu/user_interface/main_window.cpp +++ b/src/nxemu/user_interface/main_window.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/src/nxemu/user_interface/notification.cpp b/src/nxemu/user_interface/notification.cpp index 6533933e..e4bb8f1c 100644 --- a/src/nxemu/user_interface/notification.cpp +++ b/src/nxemu/user_interface/notification.cpp @@ -1,5 +1,7 @@ #include "notification.h" #include "settings/ui_settings.h" +#include +#include std::unique_ptr Notification::s_instance; @@ -7,6 +9,20 @@ Notification::Notification() { } +void Notification::DisplayError(const char * message) const +{ + MessageBoxW(nullptr, stdstr(message).ToUTF16().c_str(), L"Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); +} + +void Notification::BreakPoint(const char * fileName, uint32_t lineNumber) +{ + DisplayError(stdstr_f("Break point found at\n%s\n%d", fileName, lineNumber).c_str()); + if (IsDebuggerPresent() != 0) + { + DebugBreak(); + } +} + void Notification::AppInitDone(void) { LoadUISetting(); diff --git a/src/nxemu/user_interface/notification.h b/src/nxemu/user_interface/notification.h index c983a72b..db401f5e 100644 --- a/src/nxemu/user_interface/notification.h +++ b/src/nxemu/user_interface/notification.h @@ -2,13 +2,14 @@ #include #include - class Notification : public INotification { public: Notification(); + void DisplayError(const char * message) const; + void BreakPoint(const char * fileName, uint32_t lineNumber); void AppInitDone(void); static Notification & GetInstance(); diff --git a/src/nxemu/user_interface/settings/settings_page_modules.cpp b/src/nxemu/user_interface/settings/settings_page_modules.cpp index a464566d..5280a0ec 100644 --- a/src/nxemu/user_interface/settings/settings_page_modules.cpp +++ b/src/nxemu/user_interface/settings/settings_page_modules.cpp @@ -1,6 +1,7 @@ #include "settings_page_modules.h" #include #include +#include OptionModulesPage::OptionModulesPage(HWND parent, const RECT & dispayRect) {