diff --git a/CMakeLists.txt b/CMakeLists.txt index 035692a4..bdcaaa86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,3 +49,5 @@ add_subdirectory(sqrat) add_subdirectory(sdk) # Include Module library add_subdirectory(module) +# Include Sample module +#add_subdirectory(hello) diff --git a/hello/Common.cpp b/hello/Common.cpp new file mode 100644 index 00000000..31a5c54b --- /dev/null +++ b/hello/Common.cpp @@ -0,0 +1,273 @@ +// ------------------------------------------------------------------------------------------------ +#include "Common.hpp" +// ------------------------------------------------------------------------------------------------ +#ifdef SQMOD_OS_WINDOWS + #include +#endif // SQMOD_OS_WINDOWS +// ------------------------------------------------------------------------------------------------ +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +PluginFuncs* _Func = nullptr; +PluginCallbacks* _Clbk = nullptr; +PluginInfo* _Info = nullptr; + +/* ------------------------------------------------------------------------------------------------ + * Common buffers to reduce memory allocations. To be immediately copied upon return! +*/ +static SQChar g_Buffer[4096]; + +// ------------------------------------------------------------------------------------------------ +void SqThrowF(const SQChar * str, ...) +{ + // Initialize the argument list + va_list args; + va_start (args, str); + // Write the requested contents + if (std::vsnprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0) + { + // Write a generic message at least + std::strcpy(g_Buffer, "Unknown error has occurred"); + } + // Finalize the argument list + va_end(args); + // Throw the exception with the resulted message + throw Sqrat::Exception(g_Buffer); // NOLINT(hicpp-exception-baseclass,cert-err60-cpp) +} + +/* ------------------------------------------------------------------------------------------------ + * Raw console message output. +*/ +static inline void OutputMessageImpl(const SQChar * msg, va_list args) +{ +#ifdef SQMOD_OS_WINDOWS + HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO csb_before; + GetConsoleScreenBufferInfo( hstdout, &csb_before); + SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN); + std::printf("[SQMOD] "); + + SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); // NOLINT(hicpp-signed-bitwise) + std::vprintf(msg, args); + std::puts(""); + + SetConsoleTextAttribute(hstdout, csb_before.wAttributes); +#else + std::printf("\033[21;32m[SQMOD]\033[0m"); + std::vprintf(msg, args); + std::puts(""); +#endif // SQMOD_OS_WINDOWS +} + +/* ------------------------------------------------------------------------------------------------ + * Raw console error output. +*/ +static inline void OutputErrorImpl(const SQChar * msg, va_list args) +{ +#ifdef SQMOD_OS_WINDOWS + HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO csb_before; + GetConsoleScreenBufferInfo( hstdout, &csb_before); + SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY); // NOLINT(hicpp-signed-bitwise) + std::printf("[SQMOD] "); + + SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); // NOLINT(hicpp-signed-bitwise) + std::vprintf(msg, args); + std::puts(""); + + SetConsoleTextAttribute(hstdout, csb_before.wAttributes); +#else + std::printf("\033[21;91m[SQMOD]\033[0m"); + std::vprintf(msg, args); + std::puts(""); +#endif // SQMOD_OS_WINDOWS +} + +// ------------------------------------------------------------------------------------------------ +void OutputDebug(const SQChar * msg, ...) +{ +#ifdef _DEBUG + // Initialize the arguments list + va_list args; + va_start(args, msg); + // Call the output function + OutputMessageImpl(msg, args); + // Finalize the arguments list + va_end(args); +#else + SQMOD_UNUSED_VAR(msg); +#endif +} + +// ------------------------------------------------------------------------------------------------ +void OutputMessage(const SQChar * msg, ...) +{ + // Initialize the arguments list + va_list args; + va_start(args, msg); + // Call the output function + OutputMessageImpl(msg, args); + // Finalize the arguments list + va_end(args); +} + +// ------------------------------------------------------------------------------------------------ +void OutputError(const SQChar * msg, ...) +{ + // Initialize the arguments list + va_list args; + va_start(args, msg); + // Call the output function + OutputErrorImpl(msg, args); + // Finalize the arguments list + va_end(args); +} + +// ------------------------------------------------------------------------------------------------ +bool CheckModuleAPIVer(const SQChar * ver, const SQChar * mod) +{ + // Obtain the numeric representation of the API version + const long int vernum = std::strtol(ver, nullptr, 10); + // Check against version mismatch + if (vernum == SQMOD_API_VER) + { + return true; + } + // Log the incident + OutputError("API version mismatch on %s", mod); + OutputMessage("=> Requested: %ld Have: %ld", vernum, SQMOD_API_VER); + // Invoker should not attempt to communicate through the module API + return false; +} + +// ------------------------------------------------------------------------------------------------ +bool CheckModuleOrder(PluginFuncs * vcapi, uint32_t mod_id, const SQChar * mod) +{ + // Make sure a valid server API was provided + if (!vcapi) + { + OutputError("Invalid pointer to server API structure"); + // Validation failed! + return false; + } + // Attempt to find the host plug-in identifier + const int plugin_id = vcapi->FindPlugin(SQMOD_HOST_NAME); + // See if our module was loaded after the host plug-in + if (plugin_id < 0) + { + OutputError("%s: could find the host plug-in", mod); + // Validation failed! + return false; + } + // Should never reach this point but just in case + else if (static_cast< uint32_t >(plugin_id) > mod_id) + { + OutputError("%s: loaded after the host plug-in", mod); + // Validation failed! + return false; + } + // Loaded in the correct order + return true; +} + +// ------------------------------------------------------------------------------------------------ +void ImportModuleAPI(PluginFuncs * vcapi, const SQChar * mod) +{ + // Make sure a valid server API was provided + if (!vcapi) + { + STHROWF("%s: Invalid pointer to server API structure", mod); + } + + size_t exports_struct_size; + + // Attempt to find the host plug-in identifier + int plugin_id = vcapi->FindPlugin(SQMOD_HOST_NAME); + // Validate the obtained plug-in identifier + if (plugin_id < 0) + { + STHROWF("%s: Unable to obtain the host plug-in identifier", mod); + } + + // Attempt to retrieve the host plug-in exports + const void ** raw_plugin_exports = vcapi->GetPluginExports(plugin_id, &exports_struct_size); + // See if the size of the exports structure matches + if (exports_struct_size <= 0) + { + STHROWF("%s: Incompatible host plug-in exports structure", mod); + } + // See if we have any exports from the host plug-in + else if (raw_plugin_exports == nullptr) + { + STHROWF("%s: Unable to obtain pointer host plug-in exports", mod); + } + + // Obtain pointer to the exports structure + const SQMODEXPORTS * plugin_exports = *reinterpret_cast< const SQMODEXPORTS ** >(raw_plugin_exports); + // See if we have a valid pointer to the exports structure + if (plugin_exports == nullptr) + { + STHROWF("%s: Invalid pointer to host plug-in exports structure", mod); + } + else if (plugin_exports->PopulateModuleAPI == nullptr || plugin_exports->PopulateSquirrelAPI == nullptr) + { + STHROWF("%s: Invalid pointer to host plug-in import functions", mod); + } + + // Prepare a structure to obtain the module API + SQMODAPI sqmodapi; + // Attempt to populate the structure + switch (plugin_exports->PopulateModuleAPI(&sqmodapi, sizeof(SQMODAPI))) + { + case -1: STHROWF("%s: Incompatible module API structure", mod); + // fall through + case 0: STHROWF("%s: Invalid pointer to module API structure", mod); + } + + // Prepare a structure to obtain the squirrel API + SQLIBAPI sqlibapi; + // Attempt to populate the structure + switch (plugin_exports->PopulateSquirrelAPI(&sqlibapi, sizeof(SQLIBAPI))) + { + case -1: STHROWF("%s: Incompatible squirrel API structure", mod); + // fall through + case 0: STHROWF("%s: Invalid pointer to squirrel API structure", mod); + } + + // Attempt to expand the obtained API + if (!sqmod_api_expand(&sqmodapi)) + { + // Collapse the API first + sqmod_api_collapse(); + // Now it's safe to throw the exception + STHROWF("%s: Unable to expand module API structure", mod); + } + else if (!sqlib_api_expand(&sqlibapi)) + { + // Collapse the API first + sqmod_api_collapse(); + sqlib_api_collapse(); + // Now it's safe to throw the exception + STHROWF("%s: Unable to expand module API structure", mod); + } +} + +// ------------------------------------------------------------------------------------------------ +int SampleFunction() +{ + OutputMessage("Hello from the sample plug-in function!"); + return rand(); +} + +// ------------------------------------------------------------------------------------------------ +void SampleType::SampleMethod() const +{ + OutputMessage("I have the values %d and %d", m_MyVal, mMyNum); +} + +} // Namespace:: SqMod diff --git a/hello/Common.hpp b/hello/Common.hpp new file mode 100644 index 00000000..58118427 --- /dev/null +++ b/hello/Common.hpp @@ -0,0 +1,153 @@ +#ifndef _SQSAMPLE_COMMON_HPP_ +#define _SQSAMPLE_COMMON_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include +#include +#include + +// ------------------------------------------------------------------------------------------------ +#include +#include +#include +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +using namespace Sqrat; + +/* ------------------------------------------------------------------------------------------------ + * SOFTWARE INFORMATION +*/ +#define SQSAMPLE_NAME "Squirrel Sample Module" +#define SQSAMPLE_AUTHOR "Sandu Liviu Catalin (S.L.C)" +#define SQSAMPLE_COPYRIGHT "Copyright (C) 2018 Sandu Liviu Catalin" +#define SQSAMPLE_HOST_NAME "SqModSampleHost" +#define SQSAMPLE_VERSION 001 +#define SQSAMPLE_VERSION_STR "0.0.1" +#define SQSAMPLE_VERSION_MAJOR 0 +#define SQSAMPLE_VERSION_MINOR 0 +#define SQSAMPLE_VERSION_PATCH 1 + +/* ------------------------------------------------------------------------------------------------ + * LOGGING LOCATION +*/ + +#define SQMOD_TRUESTRINGIZE(x) #x +#define SQMOD_STRINGIZEWRAP(x) SQMOD_TRUESTRINGIZE(x) + +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) + #define SQMOD_MSGLOC(m) (m " =>[" __FILE__ ":" SQMOD_STRINGIZEWRAP(__LINE__) "] ") +#else + #define SQMOD_MSGLOC(m) (m) +#endif // _DEBUG + +/* ------------------------------------------------------------------------------------------------ + * EXCEPTION THROWING +*/ + +#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC) + #define STHROW(e, m, ...) throw e(m " =>[" __FILE__ ":" SQMOD_STRINGIZEWRAP(__LINE__) "] ", ##__VA_ARGS__) + #define STHROWF(m, ...) SqThrowF(m " =>[" __FILE__ ":" SQMOD_STRINGIZEWRAP(__LINE__) "] ", ##__VA_ARGS__) + #define STHROWLASTF(m, ...) SqThrowLastF(m " =>[" __FILE__ ":" SQMOD_STRINGIZEWRAP(__LINE__) "] ", ##__VA_ARGS__) +#else + #define STHROW(e, m, ...) throw e(m, ##__VA_ARGS__) + #define STHROWF(m, ...) SqThrowF(m, ##__VA_ARGS__) + #define STHROWLASTF(m, ...) SqThrowLastF(m, ##__VA_ARGS__) +#endif // _DEBUG + +/* ------------------------------------------------------------------------------------------------ + * GENERAL RESPONSES +*/ +#define SQMOD_SUCCESS 1 +#define SQMOD_FAILURE 0 +#define SQMOD_UNKNOWN (-1) + +/* ------------------------------------------------------------------------------------------------ + * Proxies to communicate with the server. +*/ +extern PluginFuncs* _Func; +extern PluginCallbacks* _Clbk; +extern PluginInfo* _Info; + +/* ------------------------------------------------------------------------------------------------ + * Generate a formatted string and throw it as a sqrat exception. +*/ +void SqThrowF(const char * str, ...); + +/* ------------------------------------------------------------------------------------------------ + * Output a message only if the _DEBUG was defined. +*/ +void OutputDebug(const SQChar * msg, ...); + +/* ------------------------------------------------------------------------------------------------ + * Output a formatted user message to the console. +*/ +void OutputMessage(const SQChar * msg, ...); + +/* ------------------------------------------------------------------------------------------------ + * Output a formatted error message to the console. +*/ +void OutputError(const SQChar * msg, ...); + +/* ------------------------------------------------------------------------------------------------ + * Validate the module API to make sure we don't run into issues. +*/ +bool CheckModuleAPIVer(const SQChar * ver, const SQChar * mod); + +/* ------------------------------------------------------------------------------------------------ + * Make sure that the module was loaded after the host plug-in. +*/ +bool CheckModuleOrder(PluginFuncs * vcapi, uint32_t mod_id, const SQChar * mod); + +/* ------------------------------------------------------------------------------------------------ + * Used by the modules to import the API from the host plug-in. +*/ +void ImportModuleAPI(PluginFuncs * vcapi, const SQChar * mod); + +/* -------------------------------------------------------------------------------------------- + * Sample Plug-in API +*/ + +int SampleFunction(); + +class SampleType +{ +private: + + int m_MyVal; + +public: + + int mMyNum; + + SampleType() + : m_MyVal(0), mMyNum(0) + { + + } + + SampleType(int num) + : m_MyVal(num * 2), mMyNum(num) + { + + } + + int GetMyVal() const + { + return m_MyVal; + } + + void SetMyVal(int val) + { + m_MyVal = val; + } + + void SampleMethod() const; +}; + +} // Namespace:: SqMod + +#endif // _SQSAMPLE_COMMON_HPP_ diff --git a/hello/Module.cpp b/hello/Module.cpp new file mode 100644 index 00000000..8ae7d9e0 --- /dev/null +++ b/hello/Module.cpp @@ -0,0 +1,201 @@ +// ------------------------------------------------------------------------------------------------ +#include "Common.hpp" + +// ------------------------------------------------------------------------------------------------ +#include +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +/* ------------------------------------------------------------------------------------------------ + * Register the module API under the obtained virtual machine. +*/ +static bool RegisterAPI(HSQUIRRELVM vm) +{ + // Make sure there's a valid virtual machine before proceeding + if (!vm) + { + OutputError("%s: Cannot register API without a valid virtual machine", SQSAMPLE_NAME); + // Registration failed + return false; + } + + RootTable(vm).Bind(_SC("SampleType"), + Class< SampleType >(vm, _SC("SampleType")) + .Ctor() + .Ctor< int >() + .Var(_SC("MyNum"), &SampleType::mMyNum) + .Prop(_SC("MyVal"), &SampleType::GetMyVal, &SampleType::SetMyVal) + .Func(_SC("SampleMethod"), &SampleType::SampleMethod) + ); + + RootTable(vm).Func(_SC("SampleFunction"), &SampleFunction); + + // Registration was successful + return true; +} + +/* ------------------------------------------------------------------------------------------------ + * Load the module on the virtual machine provided by the host module. +*/ +static bool OnSquirrelLoad() +{ + // Make sure that we have a valid module API + if (!SqMod_GetSquirrelVM) + { + OutputError("%s: Cannot obtain the Squirrel virtual machine without the module API", SQSAMPLE_NAME); + // Unable to proceed! + return false; + } + // Obtain the Squirrel virtual machine from the host plug-in + DefaultVM::Set(SqMod_GetSquirrelVM()); + // Make sure that a valid virtual machine exists + if (!DefaultVM::Get()) + { + OutputError("%s: Squirrel virtual machine obtained from the host plug-in is invalid", SQSAMPLE_NAME); + // Unable to proceed! + return false; + } + // Register the module API + if (RegisterAPI(DefaultVM::Get())) + { + OutputMessage("Registered: %s", SQSAMPLE_NAME); + } + else + { + return false; + } + // At this point, the module was successfully loaded + return true; +} + +/* ------------------------------------------------------------------------------------------------ + * The virtual machine is about to be terminated and script resources should be released. +*/ +static void OnSquirrelTerminate() +{ + OutputMessage("Terminating: %s", SQSAMPLE_NAME); + // Release script resources... +} + +/* ------------------------------------------------------------------------------------------------ + * The virtual machined is about to be closed. Last chance to release anything manually. +*/ +static void OnSquirrelClosing() +{ + // Nothing to release manually... +} + +/* ------------------------------------------------------------------------------------------------ + * The virtual machined was closed and all memory associated with it was released. +*/ +static void OnSquirrelReleased() +{ + // Release the current virtual machine, if any + DefaultVM::Set(nullptr); +} + +/* ------------------------------------------------------------------------------------------------ + * React to command sent by other plug-ins. +*/ +static uint8_t OnPluginCommand(uint32_t command_identifier, const char * message) +{ + switch(command_identifier) + { + case SQMOD_INITIALIZE_CMD: + { + if (CheckModuleAPIVer(message, SQSAMPLE_NAME)) + { + try + { + ImportModuleAPI(_Func, SQSAMPLE_NAME); + } + catch (const Sqrat::Exception & e) + { + OutputError("%s", e.what()); + // Failed to initialize + return 0; + } + } + } break; + case SQMOD_LOAD_CMD: + { + return OnSquirrelLoad(); + } break; + case SQMOD_TERMINATE_CMD: + { + OnSquirrelTerminate(); + } break; + case SQMOD_CLOSING_CMD: + { + OnSquirrelClosing(); + } break; + case SQMOD_RELEASED_CMD: + { + OnSquirrelReleased(); + } break; + default: break; + } + return 1; +} + +/* ------------------------------------------------------------------------------------------------ + * The server was initialized and this plug-in was loaded successfully. +*/ +static uint8_t OnServerInitialise() +{ + return 1; // Initialization was successful +} + +/* ------------------------------------------------------------------------------------------------ + * The server is about to shutdown gracefully. +*/ +static void OnServerShutdown(void) +{ + // The server may still send callbacks + _Clbk->OnServerInitialise = nullptr; + _Clbk->OnServerShutdown = nullptr; + _Clbk->OnPluginCommand = nullptr; +} + +} // Namespace:: SqMod + +// ------------------------------------------------------------------------------------------------ +SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * functions, PluginCallbacks * callbacks, PluginInfo * info) +{ + using namespace SqMod; + // Output plug-in header + puts(""); + OutputMessage("--------------------------------------------------------------------"); + OutputMessage("Plug-in: %s", SQSAMPLE_NAME); + OutputMessage("Author: %s", SQSAMPLE_AUTHOR); + OutputMessage("Legal: %s", SQSAMPLE_COPYRIGHT); + OutputMessage("--------------------------------------------------------------------"); + puts(""); + // Make sure that the module was loaded after the host plug-in + if (!CheckModuleOrder(functions, info->pluginId, SQSAMPLE_NAME)) + { + return SQMOD_FAILURE; + } + // Store server proxies + _Func = functions; + _Clbk = callbacks; + _Info = info; + // Assign plug-in version + _Info->pluginVersion = SQSAMPLE_VERSION; + _Info->apiMajorVersion = PLUGIN_API_MAJOR; + _Info->apiMinorVersion = PLUGIN_API_MINOR; + // Assign the plug-in name + std::snprintf(_Info->name, sizeof(_Info->name), "%s", SQSAMPLE_HOST_NAME); + // Bind to the server callbacks + _Clbk->OnServerInitialise = OnServerInitialise; + _Clbk->OnServerShutdown = OnServerShutdown; + _Clbk->OnPluginCommand = OnPluginCommand; + // Notify that the plug-in was successfully loaded + OutputMessage("Successfully loaded %s", SQSAMPLE_NAME); + // Dummy spacing + puts(""); + // Done! + return SQMOD_SUCCESS; +} diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt index e243f929..8cd26af5 100644 --- a/module/CMakeLists.txt +++ b/module/CMakeLists.txt @@ -73,7 +73,7 @@ add_library(SqModule MODULE Misc/Weapon.cpp Misc/Weapon.hpp ) # Link to base libraries -target_link_libraries(SqModule VCMP Squirrel Sqrat SqSDK) +target_link_libraries(SqModule VCMP Squirrel Sqrat SqSDKAPI) # Link to third-party libraries target_link_libraries(SqModule SimpleINI HashLib B64Lib AES256Lib WhirlpoolLib TinyDir PUGIXML SQLite MaxmindDB SimpleSocket) # Link to mysql client library @@ -100,10 +100,6 @@ endif() if(FORCE_32BIT_BIN) set_target_properties(SqModule PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") endif() -# Size of a pointer in bytes. To identify CPU architecture. -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - target_compile_definitions(SqModule PRIVATE _SQ64) -endif() # Don't prefix the module binary. set_target_properties(SqModule PROPERTIES PREFIX "") # Custmize module binary name/ diff --git a/module/SqBase.hpp b/module/SqBase.hpp index 9f3ce5e7..5523a495 100644 --- a/module/SqBase.hpp +++ b/module/SqBase.hpp @@ -98,14 +98,6 @@ #error This operating system is not supported by the Squirrel Module #endif -#ifndef SQMOD_ARCHITECTURE - #define SQMOD_ARCHITECTURE 0 -#endif - -#ifndef SQMOD_PLATFORM - #define SQMOD_PLATFORM 0 -#endif - /* ------------------------------------------------------------------------------------------------ * SOFTWARE INFORMATION */ diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt index ee622331..461bce36 100644 --- a/sdk/CMakeLists.txt +++ b/sdk/CMakeLists.txt @@ -1,4 +1,10 @@ # Create the SqSDK library +add_library(SqSDKAPI INTERFACE) +# Library includes +target_include_directories(SqSDKAPI INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) +# Link to required libraries +target_link_libraries(SqSDKAPI INTERFACE VCMP SquirrelAPI) +# Create the SqSDK library add_library(SqSDK STATIC include/SqConfSDK.h include/SqAPI.h @@ -9,4 +15,6 @@ add_library(SqSDK STATIC target_include_directories(SqSDK PRIVATE ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(SqSDK PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) # Link to required libraries -target_link_libraries(SqSDK PRIVATE VCMP Squirrel) +target_link_libraries(SqSDK PRIVATE VCMP SquirrelAPI) +# Compile definitions +target_compile_definitions(SqSDK PUBLIC SQMOD_PLUGIN_API=1) \ No newline at end of file diff --git a/sdk/include/SqMod.h b/sdk/include/SqMod.h index ce88662c..8e5701f9 100644 --- a/sdk/include/SqMod.h +++ b/sdk/include/SqMod.h @@ -37,6 +37,105 @@ extern "C" { #endif + /* ------------------------------------------------------------------------------------------------ + * ARCHITECTURE IDENTIFIERS + */ + + #define SQMOD_ARCH_ID_UNKNOWN 0 + #define SQMOD_ARCH_ID_32_BIT 1 + #define SQMOD_ARCH_ID_64_BIT 2 + + /* ------------------------------------------------------------------------------------------------ + * PLATFORM IDENTIFIERS + */ + + #define SQMOD_PLAT_ID_UNKNOWN 0 + #define SQMOD_PLAT_ID_WINDOWS 1 + #define SQMOD_PLAT_ID_LINUX 2 + #define SQMOD_PLAT_ID_MACOS 3 + #define SQMOD_PLAT_ID_UNIX 4 + + /* ------------------------------------------------------------------------------------------------ + * OS IDENTIFICATION + */ + + #if defined(_WIN32) || defined(__WIN32__) || defined(_WIN) || defined(__WIN__) + // Windows x32 + #define SQMOD_OS_WINDOWS + #define SQMOD_OS_32 + #define SQMOD_OS_WINDOWS32 + #define SQMOD_ARCHITECTURE 1 + #define SQMOD_PLATFORM 1 + #elif defined(_WIN64) || defined(__WIN64__) + // Windows x64 + #define SQMOD_OS_WINDOWS + #define SQMOD_OS_64 + #define SQMOD_OS_WINDOWS64 + #define SQMOD_ARCHITECTURE 2 + #define SQMOD_PLATFORM 1 + #elif defined(linux) || defined(__linux) || defined(__linux__) + // Linux + #define SQMOD_OS_LINUX + #if __GNUC__ + #if __x86_64__ || __ppc64__ + #define SQMOD_OS_64 + #define SQMOD_OS_LINUX64 + #define SQMOD_ARCHITECTURE 2 + #define SQMOD_PLATFORM 2 + #else + #define SQMOD_OS_32 + #define SQMOD_OS_LINUX32 + #define SQMOD_ARCHITECTURE 1 + #define SQMOD_PLATFORM 2 + #endif + #endif + #elif defined(__APPLE__) || defined(__MACH__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh) + // MacOS + #define SQMOD_OS_MACOS + #if __GNUC__ + #if __x86_64__ || __ppc64__ + #define SQMOD_OS_64 + #define SQMOD_OS_MACOS64 + #define SQMOD_ARCHITECTURE 2 + #define SQMOD_PLATFORM 3 + #else + #define SQMOD_OS_32 + #define SQMOD_OS_MACOS32 + #define SQMOD_ARCHITECTURE 1 + #define SQMOD_PLATFORM 3 + #endif + #endif + #elif defined(__unix) || defined(__unix__) + // Unix + #define SQMOD_OS_UNIX + #if __GNUC__ + #if __x86_64__ || __ppc64__ + #define SQMOD_OS_64 + #define SQMOD_OS_UNIX64 + #define SQMOD_ARCHITECTURE 2 + #define SQMOD_PLATFORM 4 + #else + #define SQMOD_OS_32 + #define SQMOD_OS_UNIX32 + #define SQMOD_ARCHITECTURE 1 + #define SQMOD_PLATFORM 4 + #endif + #endif + #else + // Unsupported system + #error This operating system is not supported by the Squirrel Module + #endif + + /* ------------------------------------------------------------------------------------------------ + * VCMP SDK VERSION CHECK. + */ + #define SQMOD_SDK_MATCH(MJR, MNR) ((PLUGIN_API_MAJOR == (MJR)) && (PLUGIN_API_MINOR == (MNR))) + #define SQMOD_SDK_LEAST(MJR, MNR) ((PLUGIN_API_MAJOR >= (MJR)) && (PLUGIN_API_MINOR >= (MNR))) + #define SQMOD_SDK_PRIOR(MJR, MNR) ((PLUGIN_API_MAJOR < (MJR)) && (PLUGIN_API_MINOR < (MNR))) + + #define SQMOD_DECL_UNUSED_VAR(t, n, v) t n = v; (void)(n) + #define SQMOD_UNUSED_VAR(n) (void)(n) + /**< 64 bits integer types */ #if defined(_MSC_VER) typedef __int64 SqInt64; diff --git a/squirrel/CMakeLists.txt b/squirrel/CMakeLists.txt index 8dfcaccd..38c52b92 100644 --- a/squirrel/CMakeLists.txt +++ b/squirrel/CMakeLists.txt @@ -67,3 +67,7 @@ target_compile_definitions(Squirrel PRIVATE GARBAGE_COLLECTOR=1) target_include_directories(Squirrel PRIVATE ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(Squirrel PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) target_include_directories(Squirrel PRIVATE ${CMAKE_CURRENT_LIST_DIR}/stdlib) +# Create the Squirrel library +add_library(SquirrelAPI INTERFACE) +# Library includes +target_include_directories(SquirrelAPI INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) \ No newline at end of file