From 578a7d1a448ccb419950727524e4600b7e03f3ec Mon Sep 17 00:00:00 2001 From: craftablescience Date: Wed, 23 Oct 2024 04:56:40 -0400 Subject: [PATCH] feat(gamepp): create C wrapper --- CMakeLists.txt | 2 +- README.md | 2 +- docs/index.md | 2 +- lang/c/include/gameppc/Convert.hpp | 23 +++++++ lang/c/include/gameppc/gamepp.h | 45 ++++++++++++++ lang/c/src/gameppc/Convert.cpp | 9 +++ lang/c/src/gameppc/_gameppc.cmake | 6 ++ lang/c/src/gameppc/gamepp.cpp | 98 ++++++++++++++++++++++++++++++ 8 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 lang/c/include/gameppc/Convert.hpp create mode 100644 lang/c/include/gameppc/gamepp.h create mode 100644 lang/c/src/gameppc/Convert.cpp create mode 100644 lang/c/src/gameppc/_gameppc.cmake create mode 100644 lang/c/src/gameppc/gamepp.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dac69a2c8..0106c49b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,7 +160,7 @@ endif() # Add libraries add_sourcepp_library(bsppp NO_TEST ) # sourcepp::bsppp add_sourcepp_library(dmxpp ) # sourcepp::dmxpp -add_sourcepp_library(gamepp PYTHON ) # sourcepp::gamepp +add_sourcepp_library(gamepp C PYTHON ) # sourcepp::gamepp add_sourcepp_library(kvpp BENCH) # sourcepp::kvpp add_sourcepp_library(mdlpp ) # sourcepp::mdlpp add_sourcepp_library(steampp C PYTHON ) # sourcepp::steampp diff --git a/README.md b/README.md index 40722cef3..d917ff4f0 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one Get Source engine instance window title/position/size ✅ ❌ - Python + C
Python diff --git a/docs/index.md b/docs/index.md index ef612a425..303ed1ba6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -40,7 +40,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one Get Source engine instance window title/position/size ✅ ❌ - Python + C
Python Run commands in a Source engine instance remotely diff --git a/lang/c/include/gameppc/Convert.hpp b/lang/c/include/gameppc/Convert.hpp new file mode 100644 index 000000000..ce6eb85f8 --- /dev/null +++ b/lang/c/include/gameppc/Convert.hpp @@ -0,0 +1,23 @@ +#pragma once + +/* + * This is a header designed to be included in C++ source code. + * It should not be included in applications using any C wrapper libraries! + */ +#ifndef __cplusplus +#error "This header can only be used in C++!" +#endif + +#include "gamepp.h" + +namespace gamepp { + +class GameInstance; + +} // namespace gamepp + +namespace Convert { + +gamepp::GameInstance* gameInstance(gamepp_game_instance_handle_t handle); + +} // namespace Convert diff --git a/lang/c/include/gameppc/gamepp.h b/lang/c/include/gameppc/gamepp.h new file mode 100644 index 000000000..7205fc261 --- /dev/null +++ b/lang/c/include/gameppc/gamepp.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* gamepp_game_instance_handle_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +// REQUIRES MANUAL FREE: gamepp_game_instance_free +SOURCEPP_API gamepp_game_instance_handle_t gamepp_find_game_instance(); + +// REQUIRES MANUAL FREE: gamepp_game_instance_free +SOURCEPP_API gamepp_game_instance_handle_t gamepp_find_game_instance_with_name(const char* windowNameOverride); + +SOURCEPP_API void gamepp_game_instance_free(gamepp_game_instance_handle_t* handle); + +// REQUIRES MANUAL FREE: sourcepp_string_free +SOURCEPP_API sourcepp_string_t gamepp_get_window_title(gamepp_game_instance_handle_t handle); + +SOURCEPP_API int gamepp_get_window_pos_x(gamepp_game_instance_handle_t handle); + +SOURCEPP_API int gamepp_get_window_pos_y(gamepp_game_instance_handle_t handle); + +SOURCEPP_API int gamepp_get_window_width(gamepp_game_instance_handle_t handle); + +SOURCEPP_API int gamepp_get_window_height(gamepp_game_instance_handle_t handle); + +SOURCEPP_API void gamepp_command(gamepp_game_instance_handle_t handle, const char* command); + +SOURCEPP_API void gamepp_input_begin(gamepp_game_instance_handle_t handle, const char* input); + +SOURCEPP_API void gamepp_input_end(gamepp_game_instance_handle_t handle, const char* input); + +SOURCEPP_API void gamepp_input_once(gamepp_game_instance_handle_t handle, const char* input); + +SOURCEPP_API void gamepp_input_hold(gamepp_game_instance_handle_t handle, const char* input, double sec); + +SOURCEPP_API void gamepp_wait(gamepp_game_instance_handle_t handle, double sec); diff --git a/lang/c/src/gameppc/Convert.cpp b/lang/c/src/gameppc/Convert.cpp new file mode 100644 index 000000000..f0a22c653 --- /dev/null +++ b/lang/c/src/gameppc/Convert.cpp @@ -0,0 +1,9 @@ +#include + +#include + +using namespace gamepp; + +GameInstance* Convert::gameInstance(gamepp_game_instance_handle_t handle) { + return static_cast(handle); +} diff --git a/lang/c/src/gameppc/_gameppc.cmake b/lang/c/src/gameppc/_gameppc.cmake new file mode 100644 index 000000000..8516bd855 --- /dev/null +++ b/lang/c/src/gameppc/_gameppc.cmake @@ -0,0 +1,6 @@ +add_pretty_parser(gamepp C + SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/gameppc/Convert.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/gameppc/gamepp.h" + "${CMAKE_CURRENT_LIST_DIR}/Convert.cpp" + "${CMAKE_CURRENT_LIST_DIR}/gamepp.cpp") diff --git a/lang/c/src/gameppc/gamepp.cpp b/lang/c/src/gameppc/gamepp.cpp new file mode 100644 index 000000000..12c660899 --- /dev/null +++ b/lang/c/src/gameppc/gamepp.cpp @@ -0,0 +1,98 @@ +#include + +#include + +#include +#include +#include + +using namespace gamepp; + +SOURCEPP_API gamepp_game_instance_handle_t gamepp_find_game_instance() { + auto instance = GameInstance::find(); + if (!instance) { + return nullptr; + } + return new GameInstance{*instance}; +} + +SOURCEPP_API gamepp_game_instance_handle_t gamepp_find_game_instance_with_name(const char* windowNameOverride) { + auto instance = GameInstance::find(windowNameOverride); + if (!instance) { + return nullptr; + } + return new GameInstance{*instance}; +} + +SOURCEPP_API void gamepp_game_instance_free(gamepp_game_instance_handle_t* handle) { + SOURCEPP_EARLY_RETURN(handle); + + delete Convert::gameInstance(*handle); + *handle = nullptr; +} + +SOURCEPP_API sourcepp_string_t gamepp_get_window_title(gamepp_game_instance_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID); + + return Convert::toString(Convert::gameInstance(handle)->getWindowTitle()); +} + +SOURCEPP_API int gamepp_get_window_pos_x(gamepp_game_instance_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::gameInstance(handle)->getWindowPos()[0]; +} + +SOURCEPP_API int gamepp_get_window_pos_y(gamepp_game_instance_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::gameInstance(handle)->getWindowPos()[1]; +} + +SOURCEPP_API int gamepp_get_window_width(gamepp_game_instance_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::gameInstance(handle)->getWindowSize()[0]; +} + +SOURCEPP_API int gamepp_get_window_height(gamepp_game_instance_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::gameInstance(handle)->getWindowSize()[1]; +} + +SOURCEPP_API void gamepp_command(gamepp_game_instance_handle_t handle, const char* command) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::gameInstance(handle)->command(command); +} + +SOURCEPP_API void gamepp_input_begin(gamepp_game_instance_handle_t handle, const char* input) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::gameInstance(handle)->inputBegin(input); +} + +SOURCEPP_API void gamepp_input_end(gamepp_game_instance_handle_t handle, const char* input) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::gameInstance(handle)->inputEnd(input); +} + +SOURCEPP_API void gamepp_input_once(gamepp_game_instance_handle_t handle, const char* input) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::gameInstance(handle)->inputOnce(input); +} + +SOURCEPP_API void gamepp_input_hold(gamepp_game_instance_handle_t handle, const char* input, double sec) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::gameInstance(handle)->inputHold(input, sec); +} + +SOURCEPP_API void gamepp_wait(gamepp_game_instance_handle_t handle, double sec) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::gameInstance(handle)->wait(sec); +}