diff --git a/Utilities/dynamic_library.cpp b/Utilities/dynamic_library.cpp new file mode 100644 index 0000000000..572edc42ea --- /dev/null +++ b/Utilities/dynamic_library.cpp @@ -0,0 +1,60 @@ +#include "stdafx.h" +#include "dynamic_library.h" + +#ifdef _WIN32 + #include +#else + #include +#endif + +namespace utils +{ + dynamic_library::dynamic_library(const std::string &path) + { + load(path); + } + + dynamic_library::~dynamic_library() + { + close(); + } + + bool dynamic_library::load(const std::string &path) + { +#ifdef _WIN32 + m_handle = LoadLibraryA(path.c_str()); +#else + m_handle = dlopen(path.c_str(), RTLD_LAZY); +#endif + return loaded(); + } + + void dynamic_library::close() + { +#ifdef _WIN32 + FreeLibrary((HMODULE)m_handle); +#else + dlclose(m_handle); +#endif + m_handle = nullptr; + } + + void *dynamic_library::get_impl(const std::string &name) const + { +#ifdef _WIN32 + return GetProcAddress((HMODULE)m_handle, name.c_str()); +#else + return dlsym(m_handle, (char *)name.c_str()); +#endif + } + + bool dynamic_library::loaded() const + { + return !m_handle; + } + + dynamic_library::operator bool() const + { + return loaded(); + } +} diff --git a/Utilities/dynamic_library.h b/Utilities/dynamic_library.h new file mode 100644 index 0000000000..d5578d08e0 --- /dev/null +++ b/Utilities/dynamic_library.h @@ -0,0 +1,41 @@ +#include + +namespace utils +{ + class dynamic_library + { + void *m_handle = nullptr; + + public: + dynamic_library() = default; + dynamic_library(const std::string &path); + + ~dynamic_library(); + + bool load(const std::string &path); + void close(); + + private: + void *get_impl(const std::string &name) const; + + public: + template + Type *get(const std::string &name) const + { + Type *result; + *(void **)(&result) = get_impl(name); + return result; + } + + template + bool get(Type *&function, const std::string &name) const + { + *(void **)(&function) = get_impl(name); + + return !!function; + } + + bool loaded() const; + explicit operator bool() const; + }; +} diff --git a/Utilities/version.cpp b/Utilities/version.cpp new file mode 100644 index 0000000000..dcbd910b4b --- /dev/null +++ b/Utilities/version.cpp @@ -0,0 +1,65 @@ +#include "stdafx.h" +#include "version.h" + +namespace utils +{ + std::string to_string(version_type type) + { + switch (type) + { + case version_type::pre_alpha: return "Pre-Alpha"; + case version_type::alpha: return "Alpha"; + case version_type::beta: return "Beta"; + case version_type::release_candidate: return "RC"; + case version_type::release: return "Release"; + } + + throw; + } + + version::version(std::uint8_t hi, std::uint8_t mid, std::uint8_t lo) + : m_hi(hi) + , m_mid(mid) + , m_lo(lo) + { + } + + version& version::type(version_type type, std::uint8_t type_index) + { + m_type = type; + m_type_index = type_index; + return *this; + } + + std::uint16_t version::to_hex() const + { + return (m_hi << 24) | (m_mid << 16) | (m_lo << 8) | ((std::uint8_t(m_type) & 0xf) << 4) | (m_type_index & 0xf); + } + + std::string version::to_string() const + { + std::string version = std::to_string(hi()) + "." + std::to_string(mid()); + + if (lo()) + { + version += "." + std::to_string(lo()); + } + + if (type() != version_type::release) + { + if (!postfix().empty()) + { + version += "-" + postfix(); + } + + version += " " + utils::to_string(type()); + + if (type_index() > 1) + { + version += " " + std::to_string(type_index()); + } + } + + return version; + } +} diff --git a/Utilities/version.h b/Utilities/version.h new file mode 100644 index 0000000000..af75c1f764 --- /dev/null +++ b/Utilities/version.h @@ -0,0 +1,71 @@ +#pragma once +#include +#include + +namespace utils +{ + enum class version_type : std::uint8_t + { + pre_alpha, + alpha, + beta, + release_candidate, + release + }; + + std::string to_string(version_type type); + + class version + { + std::uint8_t m_hi; + std::uint8_t m_mid; + std::uint8_t m_lo; + version_type m_type = version_type::release; + std::uint8_t m_type_index = 1; + std::string m_postfix; + + public: + version(std::uint8_t hi, std::uint8_t mid, std::uint8_t lo = 0); + + version& type(version_type type, std::uint8_t type_index = 1); + + std::uint8_t hi() const + { + return m_hi; + } + + std::uint8_t mid() const + { + return m_mid; + } + + std::uint8_t lo() const + { + return m_lo; + } + + version_type type() const + { + return m_type; + } + + std::string postfix() const + { + return m_postfix; + } + + version& postfix(const std::string& value) + { + m_postfix = value; + return *this; + } + + std::uint8_t type_index() const + { + return m_type_index; + } + + std::uint16_t to_hex() const; + std::string to_string() const; + }; +} diff --git a/ps3emu_api/ps3emu_api.cpp b/ps3emu_api/ps3emu_api.cpp new file mode 100644 index 0000000000..62cb1a510d --- /dev/null +++ b/ps3emu_api/ps3emu_api.cpp @@ -0,0 +1,65 @@ +#include "ps3emu_api.h" + +ps3emu_api::ps3emu_api(const std::string &path) +{ + load(path); +} + +bool ps3emu_api::load(const std::string &path) +{ + if (!m_library.load(path)) + { + return false; + } + + bool is_no_errors = true; + + if (!m_library.get(get_api_version, "ps3emu_api_get_api_version") || get_api_version() != ps3emu_api_version) + { + is_no_errors = false; + } + + is_no_errors = is_no_errors && m_library.get(initialize, "ps3emu_api_initialize"); + is_no_errors = is_no_errors && m_library.get(destroy, "ps3emu_api_destroy"); + + is_no_errors = is_no_errors && m_library.get(get_version_string, "ps3emu_api_get_version_string"); + is_no_errors = is_no_errors && m_library.get(get_version_number, "ps3emu_api_get_version_number"); + is_no_errors = is_no_errors && m_library.get(get_name_string, "ps3emu_api_get_name_string"); + + is_no_errors = is_no_errors && m_library.get(load_elf, "ps3emu_api_load_elf"); + + is_no_errors = is_no_errors && m_library.get(set_state, "ps3emu_api_set_state"); + is_no_errors = is_no_errors && m_library.get(get_state, "ps3emu_api_get_state"); + + if (!is_no_errors) + { + close(); + return false; + } + + return true; +} + +bool ps3emu_api::loaded() const +{ + return m_library.loaded(); +} + +void ps3emu_api::close() +{ + initialize = nullptr; + destroy = nullptr; + get_version_string = nullptr; + get_version_number = nullptr; + get_name_string = nullptr; + load_elf = nullptr; + set_state = nullptr; + get_state = nullptr; + + m_library.close(); +} + +ps3emu_api::operator bool() const +{ + return loaded(); +} diff --git a/ps3emu_api/ps3emu_api.h b/ps3emu_api/ps3emu_api.h new file mode 100644 index 0000000000..6469086d28 --- /dev/null +++ b/ps3emu_api/ps3emu_api.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include "ps3emu_api_enums.h" +#include "ps3emu_api_structs.h" + +class ps3emu_api +{ + utils::dynamic_library m_library; + +public: + ps3emu_api() = default; + ps3emu_api(const std::string &path); + + unsigned int(*get_api_version)() = nullptr; + ps3emu_api_error_code(*initialize)(const ps3emu_api_initialize_callbacks *callbacks) = nullptr; + ps3emu_api_error_code(*destroy)() = nullptr; + + ps3emu_api_error_code(*get_version_string)(char *dest_buffer, int dest_buffer_size) = nullptr; + ps3emu_api_error_code(*get_version_number)(int *version_number) = nullptr; + ps3emu_api_error_code(*get_name_string)(char *dest_buffer, int dest_buffer_size) = nullptr; + + ps3emu_api_error_code(*load_elf)(const char *path) = nullptr; + + ps3emu_api_error_code(*set_state)(ps3emu_api_state state) = nullptr; + ps3emu_api_error_code(*get_state)(ps3emu_api_state *state) = nullptr; + + bool load(const std::string &path); + bool loaded() const; + void close(); + + explicit operator bool() const; +}; + diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index d4416d6c75..4b4cd91f49 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -198,7 +198,7 @@ if(WIN32) target_link_libraries(rpcs3 avformat.lib avcodec.lib avutil.lib swresample.lib swscale.lib png16_static ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS}) else() target_link_libraries(rpcs3 ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES}) - target_link_libraries(rpcs3 libavformat.a libavcodec.a libavutil.a libswresample.a libswscale.a png16_static ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS}) + target_link_libraries(rpcs3 libavformat.a libavcodec.a libavutil.a libswresample.a libswscale.a -ldl png16_static ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS}) if (NOT APPLE) target_link_libraries(rpcs3 vulkan glslang OSDependent OGLCompiler SPIRV) endif() diff --git a/rpcs3/Gui/AboutDialog.h b/rpcs3/Gui/AboutDialog.h index b8471ed69a..1fdae020ad 100644 --- a/rpcs3/Gui/AboutDialog.h +++ b/rpcs3/Gui/AboutDialog.h @@ -1,4 +1,5 @@ #pragma once +#include "rpcs3_version.h" class AboutDialog : public wxDialog { @@ -30,7 +31,7 @@ public: t_descr->SetForegroundColour(wxColor(255, 255, 255)); t_descr->SetPosition(wxPoint(12, 50)); - wxStaticText* t_version = new wxStaticText(this, wxID_ANY, wxString::Format(_PRGNAME_ " Version: " _PRGVER_ "-" RPCS3_GIT_VERSION)); + wxStaticText* t_version = new wxStaticText(this, wxID_ANY, std::string(_PRGNAME_ " Version: ") + rpcs3::version.to_string()); t_version->SetBackgroundColour(wxColor(100, 100, 100)); t_version->SetForegroundColour(wxColor(200, 200, 200)); t_version->SetPosition(wxPoint(12, 66)); diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 8233aaf435..b7b4f403f8 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -2,7 +2,7 @@ #include "stdafx_gui.h" #include "rpcs3.h" #include "MainFrame.h" -#include "git-version.h" +#include "rpcs3_version.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" @@ -69,7 +69,7 @@ MainFrame::MainFrame() , m_sys_menu_opened(false) { - SetLabel(_PRGNAME_ " v" _PRGVER_ "-" RPCS3_GIT_VERSION); + SetLabel(std::string(_PRGNAME_ " v") + rpcs3::version.to_string()); wxMenuBar* menubar = new wxMenuBar(); @@ -158,7 +158,7 @@ MainFrame::MainFrame() wxGetApp().Bind(wxEVT_KEY_DOWN, &MainFrame::OnKeyDown, this); wxGetApp().Bind(wxEVT_DBG_COMMAND, &MainFrame::UpdateUI, this); - LOG_NOTICE(GENERAL, "%s", _PRGNAME_ " v" _PRGVER_ "-" RPCS3_GIT_VERSION); + LOG_NOTICE(GENERAL, "%s", (std::string(_PRGNAME_ " v") + rpcs3::version.to_string()).c_str()); LOG_NOTICE(GENERAL, ""); } diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index f2ee70cae5..5486f84215 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -63,9 +63,37 @@ Use ..\llvm\include;..\llvm_build\include; + + %windir%\sysnative\cmd.exe /c "$(SolutionDir)\Utilities\git-version-gen.cmd" + Updating git-version.h + + + %windir%\sysnative\cmd.exe /c "$(SolutionDir)\Utilities\git-version-gen.cmd" + Updating git-version.h + + + %windir%\sysnative\cmd.exe /c "$(SolutionDir)\Utilities\git-version-gen.cmd" + Updating git-version.h + + + %windir%\sysnative\cmd.exe /c "$(SolutionDir)\Utilities\git-version-gen.cmd" + Updating git-version.h + + + %windir%\sysnative\cmd.exe /c "$(SolutionDir)\Utilities\git-version-gen.cmd" + Updating git-version.h + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + NotUsing @@ -84,6 +112,7 @@ NotUsing + @@ -348,6 +377,8 @@ + + Create @@ -355,12 +386,14 @@ + + @@ -379,6 +412,7 @@ + @@ -608,7 +642,10 @@ + + + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index ca8e48a36b..6b845772c8 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -854,6 +854,15 @@ Emu\PSP2\Modules + + Utilities + + + Source Files + + + Source Files + @@ -1624,5 +1633,17 @@ Utilities + + Utilities + + + Header Files + + + Header Files + + + Header Files + \ No newline at end of file diff --git a/rpcs3/ps3emu_api_enums.h b/rpcs3/ps3emu_api_enums.h new file mode 100644 index 0000000000..92a6371873 --- /dev/null +++ b/rpcs3/ps3emu_api_enums.h @@ -0,0 +1,51 @@ +#pragma once + +#ifndef _PS3EMU_API_ENUMS +#define _PS3EMU_API_ENUMS + +#ifdef __cplusplus +extern"C" +{ +#endif /* __cplusplus */ + + typedef enum + { + ps3emu_api_ok, + ps3emu_api_bad_argument, + ps3emu_api_not_found, + ps3emu_api_internal_error, + ps3emu_api_not_initialized, + ps3emu_api_already_initialized + } ps3emu_api_error_code; + + enum + { + ps3emu_api_version = 1, + ps3emu_api_max_name_length = 16, + ps3emu_api_max_version_length = 64 + }; + + typedef enum + { + ps3emu_api_state_idle, + ps3emu_api_state_stoping, + ps3emu_api_state_stopped, + ps3emu_api_state_pausing, + ps3emu_api_state_paused, + ps3emu_api_state_starting, + ps3emu_api_state_started + } ps3emu_api_state; + + typedef enum + { + ps3emu_api_window_null, + ps3emu_api_window_opengl, + ps3emu_api_window_vulkan + /* ps3emu_api_window_direct3d */ + } ps3emu_api_window_type; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _PS3EMU_API_ENUMS */ diff --git a/rpcs3/ps3emu_api_structs.h b/rpcs3/ps3emu_api_structs.h new file mode 100644 index 0000000000..cc8337f21e --- /dev/null +++ b/rpcs3/ps3emu_api_structs.h @@ -0,0 +1,23 @@ +#ifndef _PS3EMU_API_STRUCTS +#define _PS3EMU_API_STRUCTS + +#include "ps3emu_api_enums.h" + +#ifdef __cplusplus +extern"C" +{ +#endif /* __cplusplus */ + typedef struct ps3emu_api_window_handle_s * ps3emu_api_window; + + typedef struct + { + ps3emu_api_error_code(*create_window)(ps3emu_api_window *window, ps3emu_api_window_type type, unsigned int version); + ps3emu_api_error_code(*destroy_window)(ps3emu_api_window window); + ps3emu_api_error_code(*flip)(ps3emu_api_window window); + } ps3emu_api_initialize_callbacks; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _PS3EMU_API_STRUCTS */ diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 9e81a8b0a0..82b7632775 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -84,8 +84,10 @@ - %windir%\sysnative\cmd.exe /c "$(SolutionDir)\Utilities\git-version-gen.cmd" - Updating git-version.h + + + + ..\wxWidgets\include\msvc;..\wxWidgets\include;..\3rdparty\XAudio2_7;..\Vulkan\Vulkan-LoaderAndValidationLayers\include;..\Vulkan\glslang\glslang\Public;%(AdditionalIncludeDirectories) diff --git a/rpcs3/rpcs3_api.cpp b/rpcs3/rpcs3_api.cpp new file mode 100644 index 0000000000..499431b83b --- /dev/null +++ b/rpcs3/rpcs3_api.cpp @@ -0,0 +1,219 @@ +#include "stdafx.h" +#include "ps3emu_api_enums.h" +#include "ps3emu_api_structs.h" +#include "rpcs3_version.h" +#include "Emu/System.h" + +#ifdef _MSC_VER + #define UTILS_DLL_C_EXPORT extern "C" __declspec(dllexport) +#else + #define UTILS_DLL_C_EXPORT extern "C" __attribute__((visibility("default"))) +#endif + +static bool g_is_initialized = false; + +UTILS_DLL_C_EXPORT unsigned int ps3emu_api_get_api_version() +{ + return ps3emu_api_version; +} + +UTILS_DLL_C_EXPORT ps3emu_api_error_code ps3emu_api_initialize(const ps3emu_api_initialize_callbacks *callbacks) +{ + if (g_is_initialized) + { + return ps3emu_api_already_initialized; + } + + if (!callbacks) + { + return ps3emu_api_bad_argument; + } + + g_is_initialized = true; + + //TODO + return ps3emu_api_ok; +} + +UTILS_DLL_C_EXPORT ps3emu_api_error_code ps3emu_api_destroy() +{ + if (!g_is_initialized) + { + return ps3emu_api_not_initialized; + } + + g_is_initialized = false; + + //TODO + return ps3emu_api_ok; +} + +UTILS_DLL_C_EXPORT ps3emu_api_error_code ps3emu_api_get_version_string(char *dest_buffer, int dest_buffer_size) +{ + if (!g_is_initialized) + { + return ps3emu_api_not_initialized; + } + + if (!dest_buffer || dest_buffer_size <= 0) + { + return ps3emu_api_bad_argument; + } + + if (dest_buffer_size > ps3emu_api_max_version_length) + { + dest_buffer_size = ps3emu_api_max_version_length; + } + + const std::string version_string = rpcs3::version.to_string(); + + if (dest_buffer_size > version_string.length()) + { + dest_buffer_size = version_string.length(); + } + + std::memcpy(dest_buffer, version_string.c_str(), dest_buffer_size - 1); + dest_buffer[dest_buffer_size - 1] = '\0'; + return ps3emu_api_ok; +} + +UTILS_DLL_C_EXPORT ps3emu_api_error_code ps3emu_api_get_version_number(int *version_number) +{ + if (!g_is_initialized) + { + return ps3emu_api_not_initialized; + } + + if (!version_number) + { + return ps3emu_api_bad_argument; + } + + *version_number = rpcs3::version.to_hex(); + return ps3emu_api_ok; +} + +UTILS_DLL_C_EXPORT ps3emu_api_error_code ps3emu_api_get_name_string(char *dest_buffer, int dest_buffer_size) +{ + if (!g_is_initialized) + { + return ps3emu_api_not_initialized; + } + + if (!dest_buffer || dest_buffer_size <= 0) + { + return ps3emu_api_bad_argument; + } + + if (dest_buffer_size > ps3emu_api_max_name_length) + { + dest_buffer_size = ps3emu_api_max_name_length; + } + + const std::string name_string = "RPCS3"; + + if (dest_buffer_size > name_string.length()) + { + dest_buffer_size = name_string.length(); + } + + std::memcpy(dest_buffer, name_string.c_str(), dest_buffer_size - 1); + dest_buffer[dest_buffer_size - 1] = '\0'; + + return ps3emu_api_ok; +} + +UTILS_DLL_C_EXPORT ps3emu_api_error_code ps3emu_api_load_elf(const char *path) +{ + if (!g_is_initialized) + { + return ps3emu_api_not_initialized; + } + + if (!path) + { + return ps3emu_api_bad_argument; + } + + if (!fs::is_file(path)) + { + return ps3emu_api_not_found; + } + + Emu.SetPath(path); + Emu.Load(); + + return ps3emu_api_ok; +} + +UTILS_DLL_C_EXPORT ps3emu_api_error_code ps3emu_api_set_state(ps3emu_api_state state) +{ + if (!g_is_initialized) + { + return ps3emu_api_not_initialized; + } + + //TODO state machine + switch (state) + { + case ps3emu_api_state_stoping: + Emu.Stop(); + break; + + case ps3emu_api_state_pausing: + Emu.Pause(); + break; + + case ps3emu_api_state_starting: + if (Emu.IsPaused()) + { + Emu.Resume(); + } + else + { + Emu.Run(); + } + break; + + default: + return ps3emu_api_bad_argument; + } + + return ps3emu_api_ok; +} + +UTILS_DLL_C_EXPORT ps3emu_api_error_code ps3emu_api_get_state(ps3emu_api_state *state) +{ + if (!g_is_initialized) + { + return ps3emu_api_not_initialized; + } + + if (!state) + { + return ps3emu_api_bad_argument; + } + + if (Emu.IsRunning()) + { + *state = ps3emu_api_state_started; + } + else if (Emu.IsPaused()) + { + *state = ps3emu_api_state_paused; + } + else if (Emu.IsStopped()) + { + *state = ps3emu_api_state_stopped; + } + else if (Emu.IsReady()) + { + *state = ps3emu_api_state_idle; + } + else + { + return ps3emu_api_internal_error; + } + + return ps3emu_api_ok; +} diff --git a/rpcs3/rpcs3_version.cpp b/rpcs3/rpcs3_version.cpp new file mode 100644 index 0000000000..2874f882ad --- /dev/null +++ b/rpcs3/rpcs3_version.cpp @@ -0,0 +1,10 @@ +#include "stdafx.h" +#include "rpcs3_version.h" +#include "git-version.h" + +namespace rpcs3 +{ + const utils::version version = utils::version{ 0, 0, 1 } + .type(utils::version_type::pre_alpha) + .postfix(RPCS3_GIT_VERSION); +} diff --git a/rpcs3/rpcs3_version.h b/rpcs3/rpcs3_version.h new file mode 100644 index 0000000000..671fed850e --- /dev/null +++ b/rpcs3/rpcs3_version.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include +#include + +namespace rpcs3 +{ + extern const utils::version version; +} diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index d29af71143..95857b0a30 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -42,7 +42,6 @@ using namespace std::literals; #define EXCEPTION(format_str, ...) fmt::exception("%s(): " format_str HERE, __FUNCTION__, ##__VA_ARGS__) #define _PRGNAME_ "RPCS3" -#define _PRGVER_ "0.0.0.9" #include "Utilities/types.h" #include "Utilities/Macro.h" diff --git a/rsx_program_decompiler b/rsx_program_decompiler index 139d8092b9..b4d0986764 160000 --- a/rsx_program_decompiler +++ b/rsx_program_decompiler @@ -1 +1 @@ -Subproject commit 139d8092b9daaa823f6398d4a273fdc0a1d20c09 +Subproject commit b4d09867643df26e503ec09119c8048832676780