Path: blob/master/RSDKv5/RSDK/Core/Link.hpp
1163 views
#ifndef LINK_H1#define LINK_H23namespace RSDK4{56#if RETRO_REV027enum APITableIDs {8APITable_GetUserLanguage,9APITable_GetConfirmButtonFlip,10APITable_ExitGame,11APITable_LaunchManual,12#if RETRO_REV0U13APITable_GetDefaultGamepadType,14#endif15APITable_IsOverlayEnabled,16APITable_CheckDLC,17#if RETRO_VER_EGS18APITable_SetupExtensionOverlay,19APITable_CanShowExtensionOverlay,20APITable_ShowExtensionOverlay,21APITable_CanShowAltExtensionOverlay,22APITable_ShowAltExtensionOverlay,23APITable_GetConnectingStringID,24APITable_ShowLimitedVideoOptions,25#else26APITable_ShowExtensionOverlay,27#endif28APITable_UnlockAchievement,29APITable_GetAchievementsEnabled,30APITable_SetAchievementsEnabled,31#if RETRO_VER_EGS32APITable_CheckAchievementsEnabled,33APITable_SetAchievementNames,34#endif35APITable_InitLeaderboards,36#if RETRO_VER_EGS37APITable_CheckLeaderboardsEnabled,38#endif39APITable_FetchLeaderboard,40APITable_TrackScore,41APITable_GetLeaderboardsStatus,42APITable_LeaderboardEntryViewSize,43APITable_LeaderboardEntryLoadSize,44APITable_LoadLeaderboardEntries,45APITable_ResetLeaderboardInfo,46APITable_ReadLeaderboardEntry,47APITable_SetPresence,48APITable_TryTrackStat,49APITable_GetStatsEnabled,50APITable_SetStatsEnabled,51APITable_ClearPrerollErrors,52APITable_TryAuth,53APITable_GetUserAuthStatus,54APITable_GetUsername,55APITable_TryInitStorage,56APITable_GetUserStorageStatus,57APITable_GetSaveStatus,58APITable_ClearSaveStatus,59APITable_SetSaveStatusContinue,60APITable_SetSaveStatusOK,61APITable_SetSaveStatusForbidden,62APITable_SetSaveStatusError,63APITable_SetUserStorageNoSave,64APITable_GetUserStorageNoSave,65APITable_LoadUserFile,66APITable_SaveUserFile,67APITable_DeleteUserFile,68APITable_InitUserDB,69APITable_OpenUserDB,70APITable_SaveUserDB,71APITable_ClearUserDB,72APITable_ClearAllUserDBs,73APITable_SetupUserDBRowSorting,74APITable_GetUserDBRowsChanged,75APITable_AddUserDBRowSortFilter,76APITable_SortUserDBRows,77APITable_GetSortedUserDBRowCount,78APITable_GetSortedUserDBRowID,79APITable_AddUserDBRow,80APITable_SetUserDBValue,81APITable_GetUserDBValue,82APITable_GetRowUUID,83APITable_GetUserDBRowByID,84APITable_GetUserDBRowCreationTime,85APITable_RemoveDBRow,86APITable_RemoveAllDBRows,87APITable_Count,88};89#else90#define APITABLE_COUNT (32)91#endif9293enum FunctionTableIDs {94FunctionTable_RegisterGlobalVariables,95FunctionTable_RegisterObject,96#if RETRO_REV0297FunctionTable_RegisterStaticVariables,98#endif99FunctionTable_GetActiveEntities,100FunctionTable_GetAllEntities,101FunctionTable_BreakForeachLoop,102FunctionTable_SetEditableVar,103FunctionTable_GetEntity,104FunctionTable_GetEntitySlot,105FunctionTable_GetEntityCount,106FunctionTable_GetDrawListRefSlot,107FunctionTable_GetDrawListRef,108FunctionTable_ResetEntity,109FunctionTable_ResetEntitySlot,110FunctionTable_CreateEntity,111FunctionTable_CopyEntity,112FunctionTable_CheckOnScreen,113FunctionTable_CheckPosOnScreen,114FunctionTable_AddDrawListRef,115FunctionTable_SwapDrawListEntries,116FunctionTable_SetDrawGroupProperties,117FunctionTable_SetScene,118FunctionTable_SetEngineState,119#if RETRO_REV02120FunctionTable_ForceHardReset,121#endif122FunctionTable_CheckValidScene,123FunctionTable_CheckSceneFolder,124FunctionTable_LoadScene,125FunctionTable_FindObject,126FunctionTable_ClearCameras,127FunctionTable_AddCamera,128#if !RETRO_REV02129FunctionTable_GetAPIFunction,130#endif131FunctionTable_GetVideoSetting,132FunctionTable_SetVideoSetting,133FunctionTable_UpdateWindow,134FunctionTable_Sin1024,135FunctionTable_Cos1024,136FunctionTable_ATan1024,137FunctionTable_ASin1024,138FunctionTable_ACos1024,139FunctionTable_Sin512,140FunctionTable_Cos512,141FunctionTable_ATan512,142FunctionTable_ASin512,143FunctionTable_ACos512,144FunctionTable_Sin256,145FunctionTable_Cos256,146FunctionTable_ATan256,147FunctionTable_ASin256,148FunctionTable_ACos256,149FunctionTable_Rand,150FunctionTable_RandSeeded,151FunctionTable_SetRandSeed,152FunctionTable_ATan2,153FunctionTable_SetIdentityMatrix,154FunctionTable_MatrixMultiply,155FunctionTable_MatrixTranslateXYZ,156FunctionTable_MatrixScaleXYZ,157FunctionTable_MatrixRotateX,158FunctionTable_MatrixRotateY,159FunctionTable_MatrixRotateZ,160FunctionTable_MatrixRotateXYZ,161FunctionTable_MatrixInverse,162FunctionTable_MatrixCopy,163FunctionTable_InitString,164FunctionTable_CopyString,165FunctionTable_SetString,166FunctionTable_AppendString,167FunctionTable_AppendText,168FunctionTable_LoadStringList,169FunctionTable_SplitStringList,170FunctionTable_GetCString,171FunctionTable_CompareStrings,172FunctionTable_GetDisplayInfo,173FunctionTable_GetWindowSize,174FunctionTable_SetScreenSize,175FunctionTable_SetClipBounds,176#if RETRO_REV02177FunctionTable_SetScreenVertices,178#endif179FunctionTable_LoadSpriteSheet,180FunctionTable_SetTintLookupTable,181FunctionTable_SetPaletteMask,182FunctionTable_SetPaletteEntry,183FunctionTable_GetPaletteEntry,184FunctionTable_SetActivePalette,185FunctionTable_CopyPalette,186#if RETRO_REV02187FunctionTable_LoadPalette,188#endif189FunctionTable_RotatePalette,190FunctionTable_SetLimitedFade,191#if RETRO_REV02192FunctionTable_BlendColors,193#endif194FunctionTable_DrawRect,195FunctionTable_DrawLine,196FunctionTable_DrawCircle,197FunctionTable_DrawCircleOutline,198FunctionTable_DrawFace,199FunctionTable_DrawBlendedFace,200FunctionTable_DrawSprite,201FunctionTable_DrawDeformedSprite,202FunctionTable_DrawString,203FunctionTable_DrawTile,204FunctionTable_CopyTile,205FunctionTable_DrawAniTile,206#if RETRO_REV0U207FunctionTable_DrawDynamicAniTile,208#endif209FunctionTable_FillScreen,210FunctionTable_LoadMesh,211FunctionTable_Create3DScene,212FunctionTable_Prepare3DScene,213FunctionTable_SetDiffuseColor,214FunctionTable_SetDiffuseIntensity,215FunctionTable_SetSpecularIntensity,216FunctionTable_AddModelToScene,217FunctionTable_SetModelAnimation,218FunctionTable_AddMeshFrameToScene,219FunctionTable_Draw3DScene,220FunctionTable_LoadSpriteAnimation,221FunctionTable_CreateSpriteAnimation,222FunctionTable_SetSpriteAnimation,223FunctionTable_EditSpriteAnimation,224FunctionTable_SetSpriteString,225FunctionTable_FindSpriteAnimation,226FunctionTable_GetFrame,227FunctionTable_GetHitbox,228FunctionTable_GetFrameID,229FunctionTable_GetStringWidth,230FunctionTable_ProcessAnimation,231FunctionTable_GetTileLayerID,232FunctionTable_GetTileLayer,233FunctionTable_GetLayerSize,234FunctionTable_GetTile,235FunctionTable_SetTile,236FunctionTable_CopyTileLayer,237FunctionTable_ProcessParallax,238FunctionTable_GetScanlines,239FunctionTable_CheckObjectCollisionTouch,240FunctionTable_CheckObjectCollisionCircle,241FunctionTable_CheckObjectCollisionBox,242FunctionTable_CheckObjectCollisionPlatform,243FunctionTable_ObjectTileCollision,244FunctionTable_ObjectTileGrip,245FunctionTable_ProcessObjectMovement,246#if RETRO_REV0U247FunctionTable_SetupCollisionConfig,248FunctionTable_SetPathGripSensors,249FunctionTable_FloorCollision,250FunctionTable_LWallCollision,251FunctionTable_RoofCollision,252FunctionTable_RWallCollision,253FunctionTable_FindFloorPosition,254FunctionTable_FindLWallPosition,255FunctionTable_FindRoofPosition,256FunctionTable_FindRWallPosition,257#endif258FunctionTable_GetTileAngle,259FunctionTable_SetTileAngle,260FunctionTable_GetTileFlags,261FunctionTable_SetTileFlags,262#if RETRO_REV0U263FunctionTable_CopyCollisionMask,264FunctionTable_GetCollisionInfo,265#endif266FunctionTable_GetSfx,267FunctionTable_PlaySfx,268FunctionTable_StopSfx,269FunctionTable_PlayMusic,270FunctionTable_SetChannelAttributes,271FunctionTable_StopChannel,272FunctionTable_PauseChannel,273FunctionTable_ResumeChannel,274FunctionTable_SfxPlaying,275FunctionTable_ChannelActive,276FunctionTable_GetChannelPos,277FunctionTable_LoadVideo,278FunctionTable_LoadImage,279#if RETRO_REV02280FunctionTable_GetInputDeviceID,281FunctionTable_GetFilteredInputDeviceID,282FunctionTable_GetInputDeviceType,283FunctionTable_IsInputDeviceAssigned,284FunctionTable_GetInputDeviceUnknown,285FunctionTable_InputDeviceUnknown1,286FunctionTable_InputDeviceUnknown2,287FunctionTable_GetInputSlotUnknown,288FunctionTable_InputSlotUnknown1,289FunctionTable_InputSlotUnknown2,290FunctionTable_AssignInputSlotToDevice,291FunctionTable_IsInputSlotAssigned,292FunctionTable_ResetInputSlotAssignments,293#endif294#if !RETRO_REV02295FunctionTable_GetUnknownInputValue,296#endif297FunctionTable_LoadUserFile,298FunctionTable_SaveUserFile,299#if RETRO_REV02300FunctionTable_PrintLog,301FunctionTable_PrintText,302FunctionTable_PrintString,303FunctionTable_PrintUInt32,304FunctionTable_PrintInt32,305FunctionTable_PrintFloat,306FunctionTable_PrintVector2,307FunctionTable_PrintHitbox,308#endif309FunctionTable_SetActiveVariable,310FunctionTable_AddEnumVariable,311#if !RETRO_REV02312FunctionTable_PrintMessage,313#endif314#if RETRO_REV02315FunctionTable_ClearDebugValues,316FunctionTable_SetDebugValue,317#endif318#if RETRO_REV0U319FunctionTable_NotifyCallback,320FunctionTable_SetGameFinished,321FunctionTable_StopAllSfx,322#endif323FunctionTable_Count,324};325326extern void *RSDKFunctionTable[FunctionTable_Count];327#if RETRO_REV02328extern void *APIFunctionTable[APITable_Count];329#else330struct APITableEntry {331void *ptr;332RETRO_HASH_MD5(hash);333};334335extern APITableEntry APIFunctionTable[APITABLE_COUNT];336extern int32 APIFunctionTableCount;337#endif338339#if RETRO_REV02340struct EngineInfo {341void *functionTable;342void *APITable;343344GameVersionInfo *gameInfo;345SKU::SKUInfo *currentSKU;346SceneInfo *sceneInfo;347348ControllerState *controller;349AnalogState *stickL;350AnalogState *stickR;351TriggerState *triggerL;352TriggerState *triggerR;353TouchInfo *touchMouse;354355SKU::UnknownInfo *unknown;356357ScreenInfo *screenInfo;358359#if RETRO_REV0U360// only for origins, not technically needed for v5U if standalone I think361void *hedgehogLink;362#endif363364#if RETRO_USE_MOD_LOADER365void *modTable;366#endif367};368#else369struct EngineInfo {370void *functionTable;371372GameVersionInfo *gameInfo;373SceneInfo *sceneInfo;374375ControllerState *controllerInfo;376AnalogState *stickInfo;377378TouchInfo *touchInfo;379380ScreenInfo *screenInfo;381382#if RETRO_USE_MOD_LOADER383void *modTable;384#endif385};386#endif387388void SetupFunctionTables();389390#if RETRO_REV02391void LinkGameLogic(void *info);392#else393void LinkGameLogic(EngineInfo info);394#endif395396// ORIGINAL CLASS397398// Windows.h already included by master header399#if !(RETRO_PLATFORM == RETRO_WIN || RETRO_PLATFORM == RETRO_SWITCH)400#include <dlfcn.h>401#endif402403// Only define this if you want to prioritize checking libraries first (Game_x64.dll then Game.dll)404// e.x. -DRETRO_ARCHIITECTURE="x64"405#ifndef RETRO_ARCHITECTURE406#define RETRO_ARCHITECTURE NULL407#endif408409class Link410{411public:412#if RETRO_PLATFORM == RETRO_WIN413typedef HMODULE Handle;414// constexpr was added in C++11 this is safe don't kill me415static constexpr const char *extention = ".dll";416static constexpr const char *prefix = NULL;417#elif RETRO_PLATFORM == RETRO_SWITCH418typedef DynModule *Handle;419static constexpr const char *extention = ".elf";420static constexpr const char *prefix = NULL;421422static Handle dlopen(const char *, int);423static void *dlsym(Handle, const char *);424static int dlclose(Handle);425static char *dlerror();426427static constexpr const int RTLD_LOCAL = 0;428static constexpr const int RTLD_LAZY = 0;429430private:431static Result err;432433public:434#else435typedef void *Handle;436static constexpr const char *prefix = "lib";437#if RETRO_PLATFORM == RETRO_OSX438static constexpr const char *extention = ".dylib";439#else440static constexpr const char *extention = ".so";441#endif442#endif443444static inline Handle PlatformLoadLibrary(std::string path)445{446Handle ret;447#if RETRO_PLATFORM == RETRO_WIN448ret = (Handle)LoadLibraryA(path.c_str());449#else450#if RETRO_PLATFORM == RETRO_ANDROID451// path should only load local libs452if (path.find_last_of('/') != std::string::npos)453path = path.substr(path.find_last_of('/') + 1);454path = "lib" + path;455#endif // ! RETRO_PLATFORM == ANDROID456ret = (Handle)dlopen(path.c_str(), RTLD_LOCAL | RTLD_LAZY);457#if RETRO_PLATFORM != RETRO_SWITCH458// try loading the library globally on linux459if (!ret) {460if (path.find_last_of('/') != std::string::npos)461path = path.substr(path.find_last_of('/') + 1);462ret = (Handle)dlopen(path.c_str(), RTLD_LOCAL | RTLD_LAZY);463}464#endif // ! RETRO_PLATFORM != SWITCH465#endif // ! RETRO_PLATFORM == WIN466return ret;467}468469static inline Handle Open(std::string path)470{471std::string original_path = path;472473// if it ends with extension474if (path.length() >= strlen(extention) && 0 == path.compare(path.length() - strlen(extention), strlen(extention), extention)) {475// remove it!476path = path.substr(0, path.size() - strlen(extention));477}478479#if RETRO_ARCHITECTURE480path += "_" RETRO_ARCHITECTURE;481#endif // ! RETRO_ARCHITECTURE482483// put it again!484path += extention;485486Handle ret = NULL;487if (prefix) {488int32 last = (int32)path.find_last_of('/') + 1;489if (last == std::string::npos + 1)490ret = PlatformLoadLibrary(prefix + path);491else492ret = PlatformLoadLibrary(path.substr(0, last) + prefix + path.substr(last));493}494if (!ret)495ret = PlatformLoadLibrary(path);496497#if RETRO_ARCHITECTURE498if (!ret) {499if (prefix) {500int32 last = original_path.find_last_of('/') + 1;501if (last == std::string::npos + 1)502ret = PlatformLoadLibrary(prefix + original_path);503else504ret = PlatformLoadLibrary(original_path.substr(0, last) + prefix + original_path.substr(last));505}506if (!ret)507ret = PlatformLoadLibrary(original_path);508}509#endif // ! RETRO_ARCHITECTURE510return ret;511}512513static inline void Close(Handle handle)514{515if (handle)516#if RETRO_PLATFORM == RETRO_WIN517FreeLibrary(handle);518#else519dlclose(handle);520#endif521}522523static inline void *GetSymbol(Handle handle, const char *symbol)524{525if (!handle)526return NULL;527#if RETRO_PLATFORM == RETRO_WIN528return (void *)GetProcAddress(handle, symbol);529#else530return (void *)dlsym(handle, symbol);531#endif532}533534static inline char *GetError()535{536#if RETRO_PLATFORM == RETRO_WIN537return (char *)GetLastErrorAsString();538#else539return dlerror();540#endif541}542543private:544#if RETRO_PLATFORM == RETRO_WIN545#if _MSC_VER546// from here: https://stackoverflow.com/a/17387176547// WINAPI sucks lol548// Returns the last Win32 error, in string format. Returns an empty string if there is no error.549static inline char *GetLastErrorAsString()550{551// Get the error message ID, if any.552DWORD errorMessageID = ::GetLastError();553if (errorMessageID == 0) {554return (char *)""; // No error message has been recorded555}556557LPSTR messageBuffer = nullptr;558559// Ask Win32 to give us the string version of that message ID.560// The parameters we pass in, tell Win32 to create the buffer that holds the message for us (because we don't yet know how long the message561// string will be).562size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,563errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);564565// Copy the error message into a std::string.566std::string message(messageBuffer, size);567568// Free the Win32's string's buffer.569LocalFree(messageBuffer);570571strcpy(textBuffer, message.c_str());572return textBuffer;573}574#else575static inline char *GetLastErrorAsString() { return (char *)""; }576#endif577#endif578};579580} // namespace RSDK581582#endif583584585