From bc63eaea48ca5e1f8ba3d01106018a0288da77b2 Mon Sep 17 00:00:00 2001 From: DHrpcs3 Date: Sun, 8 May 2016 16:19:24 +0300 Subject: [PATCH] Added rpcs3 api (dynamic library) --- ps3emu_api/ps3emu_api.cpp | 65 ++++++++++ ps3emu_api/ps3emu_api.h | 35 ++++++ rpcs3/emucore.vcxproj | 31 +++++ rpcs3/emucore.vcxproj.filters | 15 +++ rpcs3/ps3emu_api_enums.h | 51 ++++++++ rpcs3/ps3emu_api_structs.h | 23 ++++ rpcs3/rpcs3.vcxproj | 6 +- rpcs3/rpcs3_api.cpp | 219 ++++++++++++++++++++++++++++++++++ 8 files changed, 443 insertions(+), 2 deletions(-) create mode 100644 ps3emu_api/ps3emu_api.cpp create mode 100644 ps3emu_api/ps3emu_api.h create mode 100644 rpcs3/ps3emu_api_enums.h create mode 100644 rpcs3/ps3emu_api_structs.h create mode 100644 rpcs3/rpcs3_api.cpp 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/emucore.vcxproj b/rpcs3/emucore.vcxproj index 7ebe0f69b7..5486f84215 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -63,8 +63,35 @@ 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 + @@ -350,6 +377,7 @@ + @@ -358,6 +386,7 @@ + @@ -613,6 +642,8 @@ + + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 5b334d4510..6b845772c8 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -857,6 +857,12 @@ Utilities + + Source Files + + + Source Files + @@ -1630,5 +1636,14 @@ 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; +}