From 7b4535698656badcc56f8335a32f39bc59a49aad Mon Sep 17 00:00:00 2001 From: tmp64 Date: Sat, 18 Nov 2023 13:53:19 +0700 Subject: [PATCH] Client: Add interface wrappers for pre-9884 compatibility --- source_sdk | 2 +- src/game/client/CMakeLists.txt | 1 + src/game/client/client_vgui.cpp | 27 +- src/game/client/compat/CMakeLists.txt | 11 + src/game/client/compat/FileSystemCompat.cpp | 291 ++++++++++ src/game/client/compat/FileSystemCompat.h | 437 ++++++++++++++ src/game/client/compat/ISchemeCompat.cpp | 80 +++ src/game/client/compat/ISchemeCompat.h | 55 ++ src/game/client/compat/ISurfaceCompat.cpp | 538 ++++++++++++++++++ src/game/client/compat/ISurfaceCompat.h | 268 +++++++++ src/game/client/compat/anniversary_compat.cpp | 72 +++ src/game/client/compat/anniversary_compat.h | 10 + src/game/client/engine_patches.h | 9 + src/game/client/hud.cpp | 15 + src/game/client/hud.h | 8 +- src/game/client/hud/chat.cpp | 2 +- 16 files changed, 1820 insertions(+), 6 deletions(-) create mode 100644 src/game/client/compat/CMakeLists.txt create mode 100644 src/game/client/compat/FileSystemCompat.cpp create mode 100644 src/game/client/compat/FileSystemCompat.h create mode 100644 src/game/client/compat/ISchemeCompat.cpp create mode 100644 src/game/client/compat/ISchemeCompat.h create mode 100644 src/game/client/compat/ISurfaceCompat.cpp create mode 100644 src/game/client/compat/ISurfaceCompat.h create mode 100644 src/game/client/compat/anniversary_compat.cpp create mode 100644 src/game/client/compat/anniversary_compat.h diff --git a/source_sdk b/source_sdk index b3d55819..25296699 160000 --- a/source_sdk +++ b/source_sdk @@ -1 +1 @@ -Subproject commit b3d558195e8ecd5948c2b5e4d210a199e6881834 +Subproject commit 2529669984193b13ece9e4a9b3209c6c3b879194 diff --git a/src/game/client/CMakeLists.txt b/src/game/client/CMakeLists.txt index 7575c7ba..4a2d8b4e 100644 --- a/src/game/client/CMakeLists.txt +++ b/src/game/client/CMakeLists.txt @@ -108,6 +108,7 @@ else() ) endif() +add_subdirectory( compat ) add_subdirectory( gameui ) add_subdirectory( hl ) add_subdirectory( hud ) diff --git a/src/game/client/client_vgui.cpp b/src/game/client/client_vgui.cpp index b0d75504..85ca08a5 100644 --- a/src/game/client/client_vgui.cpp +++ b/src/game/client/client_vgui.cpp @@ -13,6 +13,9 @@ #include "client_vgui.h" #include "vgui/client_viewport.h" #include "gameui/gameui_viewport.h" +#include "hud.h" +#include "engine_patches.h" +#include "compat/anniversary_compat.h" EXPOSE_SINGLE_INTERFACE(CClientVGUI, IClientVGUI, ICLIENTVGUI_NAME); @@ -28,8 +31,26 @@ HScheme VGui_GetDefaultScheme() void CClientVGUI::Initialize(CreateInterfaceFn *pFactories, int iNumFactories) { - ConnectTier1Libraries(pFactories, iNumFactories); - ConnectTier2Libraries(pFactories, iNumFactories); + std::vector factoryList; + factoryList.insert(factoryList.end(), pFactories, pFactories + iNumFactories); + + if (gHUD.GetEngineBuild() < ENGINE_BUILD_ANNIVERSARY) + { + // Old builds require interface wrappers + CreateInterfaceFn pfnCompatFactory = Compat_CreateFactory(factoryList.data(), factoryList.size()); + + if (pfnCompatFactory) + { + factoryList.insert(factoryList.begin(), pfnCompatFactory); + } + else + { + AssertFatal(!("Failed to intialize compatibility factory")); + } + } + + ConnectTier1Libraries(factoryList.data(), factoryList.size()); + ConnectTier2Libraries(factoryList.data(), factoryList.size()); if (!vgui2::VGui_InitInterfacesList("CLIENT", pFactories, iNumFactories)) { @@ -38,7 +59,7 @@ void CClientVGUI::Initialize(CreateInterfaceFn *pFactories, int iNumFactories) } // Add language files - g_pVGuiLocalize->AddFile(g_pFullFileSystem, VGUI2_ROOT_DIR "resource/language/bugfixedhl_%language%.txt"); + g_pVGuiLocalize->AddFile(g_pEngineFileSystem, VGUI2_ROOT_DIR "resource/language/bugfixedhl_%language%.txt"); new CClientViewport(); new CGameUIViewport(); diff --git a/src/game/client/compat/CMakeLists.txt b/src/game/client/compat/CMakeLists.txt new file mode 100644 index 00000000..d6068ac8 --- /dev/null +++ b/src/game/client/compat/CMakeLists.txt @@ -0,0 +1,11 @@ +add_sources( + CMakeLists.txt + anniversary_compat.cpp + anniversary_compat.h + FileSystemCompat.cpp + FileSystemCompat.h + ISchemeCompat.cpp + ISchemeCompat.h + ISurfaceCompat.cpp + ISurfaceCompat.h +) diff --git a/src/game/client/compat/FileSystemCompat.cpp b/src/game/client/compat/FileSystemCompat.cpp new file mode 100644 index 00000000..236471b9 --- /dev/null +++ b/src/game/client/compat/FileSystemCompat.cpp @@ -0,0 +1,291 @@ +#include +#include "compat/FileSystemCompat.h" + +class CFileSystemCompat final : public IFileSystem +{ +public: + CFileSystemCompat(IFileSystemCompat* pIface) + { + m_pIface = pIface; + } + + virtual void Mount(void) override + { + m_pIface->Mount(); + } + + virtual void Unmount(void) override + { + m_pIface->Unmount(); + } + + virtual void RemoveAllSearchPaths(void) override + { + m_pIface->RemoveAllSearchPaths(); + } + + virtual void AddSearchPath(const char *pPath, const char *pathID) override + { + m_pIface->AddSearchPath(pPath, pathID); + } + + virtual bool RemoveSearchPath(const char *pPath) override + { + return m_pIface->RemoveSearchPath(pPath); + } + + virtual void RemoveFile(const char *pRelativePath, const char *pathID) override + { + m_pIface->RemoveFile(pRelativePath, pathID); + } + + virtual void CreateDirHierarchy(const char *path, const char *pathID) override + { + m_pIface->CreateDirHierarchy(path, pathID); + } + + virtual bool FileExists(const char *pFileName) override + { + return m_pIface->FileExists(pFileName); + } + + virtual bool IsDirectory(const char *pFileName) override + { + return m_pIface->IsDirectory(pFileName); + } + + virtual FileHandle_t Open(const char *pFileName, const char *pOptions, const char *pathID) override + { + return m_pIface->Open(pFileName, pOptions, pathID); + } + + virtual void Close(FileHandle_t file) override + { + m_pIface->Close(file); + } + + virtual void Seek(FileHandle_t file, int pos, FileSystemSeek_t seekType) override + { + m_pIface->Seek(file, pos, seekType); + } + + virtual unsigned int Tell(FileHandle_t file) override + { + return m_pIface->Tell(file); + } + + virtual unsigned int Size(FileHandle_t file) override + { + return m_pIface->Size(file); + } + + virtual unsigned int Size(const char *pFileName) override + { + return m_pIface->Size(pFileName); + } + + virtual long GetFileTime(const char *pFileName) override + { + return m_pIface->GetFileTime(pFileName); + } + + virtual long GetFileModificationTime(const char *pFileName) override + { + return m_pIface->GetFileTime(pFileName); + } + + virtual void FileTimeToString(char *pStrip, int maxCharsIncludingTerminator, long fileTime) override + { + m_pIface->FileTimeToString(pStrip, maxCharsIncludingTerminator, fileTime); + } + + virtual bool IsOk(FileHandle_t file) override + { + return m_pIface->IsOk(file); + } + + virtual void Flush(FileHandle_t file) override + { + m_pIface->Flush(file); + } + + virtual bool EndOfFile(FileHandle_t file) override + { + return m_pIface->EndOfFile(file); + } + + virtual int Read(void *pOutput, int size, FileHandle_t file) override + { + return m_pIface->Read(pOutput, size, file); + } + + virtual int Write(void const *pInput, int size, FileHandle_t file) override + { + return m_pIface->Write(pInput, size, file); + } + + virtual char *ReadLine(char *pOutput, int maxChars, FileHandle_t file) override + { + return m_pIface->ReadLine(pOutput, maxChars, file); + } + + virtual int FPrintf(FileHandle_t file, char *pFormat, ...) override + { + Assert(!("FPrintf is not implemented")); + std::abort(); + return 0; + } + + virtual void *GetReadBuffer(FileHandle_t file, int *outBufferSize, bool failIfNotInCache) override + { + return m_pIface->GetReadBuffer(file, outBufferSize, failIfNotInCache); + } + + virtual void ReleaseReadBuffer(FileHandle_t file, void *readBuffer) override + { + m_pIface->ReleaseReadBuffer(file, readBuffer); + } + + virtual const char *FindFirst(const char *pWildCard, FileFindHandle_t *pHandle, const char *pathID) override + { + return m_pIface->FindFirst(pWildCard, pHandle, pathID); + } + + virtual const char *FindNext(FileFindHandle_t handle) override + { + return m_pIface->FindNext(handle); + } + + virtual bool FindIsDirectory(FileFindHandle_t handle) override + { + return m_pIface->FindIsDirectory(handle); + } + + virtual void FindClose(FileFindHandle_t handle) override + { + m_pIface->FindClose(handle); + } + + virtual void GetLocalCopy(const char *pFileName) override + { + m_pIface->GetLocalCopy(pFileName); + } + + virtual const char *GetLocalPath(const char *pFileName, char *pLocalPath, int localPathBufferSize) override + { + return m_pIface->GetLocalPath(pFileName, pLocalPath, localPathBufferSize); + } + + virtual char *ParseFile(char *pFileBytes, char *pToken, bool *pWasQuoted) override + { + return m_pIface->ParseFile(pFileBytes, pToken, pWasQuoted); + } + + virtual bool FullPathToRelativePath(const char *pFullpath, char *pRelative) override + { + return m_pIface->FullPathToRelativePath(pFullpath, pRelative); + } + + virtual bool GetCurrentDirectory(char *pDirectory, int maxlen) override + { + return m_pIface->GetCurrentDirectory(pDirectory, maxlen); + } + + virtual void PrintOpenedFiles(void) override + { + m_pIface->PrintOpenedFiles(); + } + + virtual void SetWarningFunc(void (*pfnWarning)(const char *fmt, ...)) override + { + m_pIface->SetWarningFunc(pfnWarning); + } + + virtual void SetWarningLevel(FileWarningLevel_t level) override + { + m_pIface->SetWarningLevel(level); + } + + virtual void LogLevelLoadStarted(const char *name) override + { + m_pIface->LogLevelLoadStarted(name); + } + + virtual void LogLevelLoadFinished(const char *name) override + { + m_pIface->LogLevelLoadFinished(name); + } + + virtual int HintResourceNeed(const char *hintlist, int forgetEverything) override + { + return m_pIface->HintResourceNeed(hintlist, forgetEverything); + } + + virtual int PauseResourcePreloading(void) override + { + return m_pIface->PauseResourcePreloading(); + } + + virtual int ResumeResourcePreloading(void) override + { + return m_pIface->ResumeResourcePreloading(); + } + + virtual int SetVBuf(FileHandle_t stream, char *buffer, int mode, long size) override + { + return m_pIface->SetVBuf(stream, buffer, mode, size); + } + + virtual void GetInterfaceVersion(char *p, int maxlen) override + { + m_pIface->GetInterfaceVersion(p, maxlen); + } + + virtual bool IsFileImmediatelyAvailable(const char *pFileName) override + { + return m_pIface->IsFileImmediatelyAvailable(pFileName); + } + + virtual WaitForResourcesHandle_t WaitForResources(const char *resourcelist) override + { + return m_pIface->WaitForResources(resourcelist); + } + + virtual bool GetWaitForResourcesProgress(WaitForResourcesHandle_t handle, float *progress, bool *complete) override + { + return m_pIface->GetWaitForResourcesProgress(handle, progress, complete); + } + + virtual void CancelWaitForResources(WaitForResourcesHandle_t handle) override + { + m_pIface->CancelWaitForResources(handle); + } + + virtual bool IsAppReadyForOfflinePlay(int appID) override + { + return m_pIface->IsAppReadyForOfflinePlay(appID); + } + + virtual bool AddPackFile(const char *fullpath, const char *pathID) override + { + return m_pIface->AddPackFile(fullpath, pathID); + } + + virtual FileHandle_t OpenFromCacheForRead(const char *pFileName, const char *pOptions, const char *pathID) override + { + return m_pIface->OpenFromCacheForRead(pFileName, pOptions, pathID); + } + + virtual void AddSearchPathNoWrite(const char *pPath, const char *pathID) override + { + m_pIface->AddSearchPathNoWrite(pPath, pathID); + } + +private: + IFileSystemCompat *m_pIface = nullptr; +}; + +IFileSystem *Compat_CreateFileSystem(IFileSystemCompat *pIface) +{ + return new CFileSystemCompat(pIface); +} diff --git a/src/game/client/compat/FileSystemCompat.h b/src/game/client/compat/FileSystemCompat.h new file mode 100644 index 00000000..3bf50007 --- /dev/null +++ b/src/game/client/compat/FileSystemCompat.h @@ -0,0 +1,437 @@ +#ifndef FILESYSTEM_COMPAT_H +#define FILESYSTEM_COMPAT_H +#include + +// turn off any windows defines +#undef GetCurrentDirectory + +//! IFileSystem in pre-9884 engines. +class IFileSystemCompat : public IBaseInterface +{ +public: + static constexpr char VERSION[] = "VFileSystem009"; + + // Mount and unmount the filesystem + /** + * Mounts the Steam filesystem. The engine is responsible for calling this. + * Obsolete since the SteamPipe update. + */ + virtual void Mount(void) = 0; + + /** + * Unmounts the Steam filesystem. The engine is responsible for calling this. + * Obsolete since the SteamPipe update. + */ + virtual void Unmount(void) = 0; + + /** + * Remove all search paths (including write path) + */ + virtual void RemoveAllSearchPaths( void ) = 0; + + /** + * Add paths in priority order (mod dir, game dir, ....) + * If one or more .pak files are in the specified directory, then they are + * added after the file system path + * If the path is the relative path to a .bsp file, then any previous .bsp file + * override is cleared and the current .bsp is searched for an embedded PAK file + * and this file becomes the highest priority search path ( i.e., it's looked at first + * even before the mod's file system path ). + * @param pPath Relative path to the directory to search in. Starts in the root game directory (e.g. Half-Life/) + * @param pathID Which path ID this should be assigned to. Can be null, in which case the path will only be used if a null path ID is given to methods taking a path ID. + */ + virtual void AddSearchPath( const char *pPath, const char *pathID ) = 0; + + /** + * Removes a search path. Causes the game to crash due to an illegal access exception. + * See https://github.com/ValveSoftware/halflife/issues/1715 for more information. + * @param pPath Path to remove. + * @return true if the path was removed, false otherwise. + */ + virtual bool RemoveSearchPath( const char *pPath ) = 0; + + /** + * Deletes a file. + * @param pRelativePath The relative path to the file. This path can be relative to any search path that is part of the given path ID. + * @param pathID If not null, only search paths defined for the given path ID will be used to search for the file. + */ + virtual void RemoveFile( const char *pRelativePath, const char *pathID ) = 0; + + /** + * Creates a directory hierarchy. + * This isn't implementable on STEAM as is. (The Steam filesystem is no longer used since the SteamPipe update) + * @param path Path containing one or more directories to create. + * Uses the standard path syntax, e.g. models/player/freeman creates the directory models, creates the directory player in that directory, and creates the directory freeman in that directory. + * @param pathID If not null, uses the first search path defined for the given path ID as the basis for the full path. + * If null, or if no search paths are defined for the given path ID, uses the first write path that was added. + */ + virtual void CreateDirHierarchy( const char *path, const char *pathID ) = 0; + + // File I/O and info + /** + * Checks if the given file exists. Checks all search paths. + * @param pFileName File to check. + * @return Whether the given file exists or not. + */ + virtual bool FileExists( const char *pFileName ) = 0; + + /** + * Checks if the given file is a directory. + * @param pFileName File to check. + * @return Whether the given file is a directory or not. + */ + virtual bool IsDirectory( const char *pFileName ) = 0; + + /** + * Opens a file. + * Note: can open directories as though they were files, but will fail to read anything. + * @param pFileName Name of the file to open. + * @param pOptions File open options. Matches the set of options provided by fopen. See http://www.cplusplus.com/reference/cstdio/fopen/#parameters + * @param pathID Which search paths should be used to find the file. If NULL, all paths will be searched for the file. + * @return Handle to the file, or FILESYSTEM_INVALID_HANDLE if the file could not be opened. + * @see FILESYSTEM_INVALID_HANDLE + */ + virtual FileHandle_t Open( const char *pFileName, const char *pOptions, const char *pathID = 0L ) = 0; + + /** + * Closes a file handle that was previously returned by a call to Open. The handle is no longer valid after this call. + * @param file Handle to the file to close. + */ + virtual void Close( FileHandle_t file ) = 0; + + /** + * @param file Handle to the file. + * @param pos Position to seek to. + * @param seekType Position to use as a reference for pos. + * @see FileSystemSeek_t + */ + virtual void Seek( FileHandle_t file, int pos, FileSystemSeek_t seekType ) = 0; + + /** + * Gets the current read/write offset in the file, measured in bytes. + * @param file Handle to the file. + * @return Offset. + */ + virtual unsigned int Tell( FileHandle_t file ) = 0; + + /** + * Gets the size of the file, in bytes. + * @param file Handle to the file. + * @return Size of the file. + */ + virtual unsigned int Size( FileHandle_t file ) = 0; + + /** + * Gets the size of the file, in bytes. + * @param pFileName Name of the file. + * @return Size of the file. Returns -1 if the file couldn't be found. + */ + virtual unsigned int Size( const char *pFileName ) = 0; + + /** + * Gets the 32 bit UNIX timestamp at which the given file was last modified. + * @param pFileName File to check. + * @return Timestamp, or 0 if the file could not be queried for information. + */ + virtual long GetFileTime( const char *pFileName ) = 0; + + /** + * Converts the given file time to a string. The resulting string produces output as if the CRT function ctime were used. + * @param pStrip Destination buffer. + * @param maxCharsIncludingTerminator Maximum number of characters that can be written to pStrip, including the null terminator. + * @param fileTime File time to convert. + */ + virtual void FileTimeToString( char* pStrip, int maxCharsIncludingTerminator, long fileTime ) = 0; + + /** + * Checks whether the file's I/O status is good for input or output operations to occur on it. + * @param file Handle to the file. + * @return File I/O status. + */ + virtual bool IsOk( FileHandle_t file ) = 0; + + /** + * Flushes pending changes to disk. + * @param file Handle to the file. + */ + virtual void Flush( FileHandle_t file ) = 0; + + /** + * Checks whether the end of the file has been reached by an input operation. + * @param file Handle to the file. + * @return Whether the end of the file has been reached or not. + */ + virtual bool EndOfFile( FileHandle_t file ) = 0; + + /** + * Reads a number of bytes from the file. + * @param pOutput Destination buffer. + * @param size Size of the destination buffer, in bytes. + * @param file Handle to the file. + * @return Number of bytes that were read. + */ + virtual int Read( void* pOutput, int size, FileHandle_t file ) = 0; + + /** + * Writes a number of bytes to the file. + * @param pInput Source buffer. + * @param size Size of the source buffer, in bytes. + * @param file Handle to the file. + * @return Number of bytes that were written. + */ + virtual int Write( void const* pInput, int size, FileHandle_t file ) = 0; + + /** + * Reads a line from the file. + * @param pOutput Destination buffer. + * @param maxChars Maximum number of characters to read, including the null terminator. + * @param file Handle to the file. + * @return If file is FILESYSTEM_INVALID_HANDLE, a pointer to a read-only empty string is returned. + If characters were read from the file, a pointer to the destination buffer. Otherwise, a null pointer. + */ + virtual char *ReadLine( char *pOutput, int maxChars, FileHandle_t file ) = 0; + + /** + * Print formatted data to the file. + * @param file Handle to the file. + * @param pFormat Format string. + * @param ... Arguments. + * @return If the operation succeeded, returns the number of characters that were written. Otherwise, returns a negative number. + */ + virtual int FPrintf( FileHandle_t file, char *pFormat, ... ) = 0; + + // direct filesystem buffer access + + /** + * Returns a handle to a buffer containing the file data. + * This is the optimal way to access the complete data for a file, + * since the file preloader has probably already got it in memory. + * + * Note: always fails. Sets outBufferSize to 0 and returns null in all cases. + * + * @param file Handle to the file. + * @param outBufferSize Pointer to a variable that will contain the size of the buffer. + * @param failIfNotInCache If true, do not load the file into memory if it wasn't already cached. + * @return Pointer to the buffer, or null if the file buffer couldn't be loaded into memory, or if it wasn't loaded and failIfNotInCache was true. + */ + virtual void *GetReadBuffer( FileHandle_t file, int *outBufferSize, bool failIfNotInCache ) = 0; + + /** + * Releases a read buffer previously returned by a call to GetReadBuffer. + * The buffer is no longer valid after this call. + * @param file Handle to the file. + * @param readBuffer Buffer to release. + */ + virtual void ReleaseReadBuffer( FileHandle_t file, void *readBuffer ) = 0; + + // FindFirst/FindNext + /** + * Finds the first file using a given wildcard and set of search paths. + * Note: Check if a file was found using the return value, not the pHandle parameter. + * @param pWildCard WildCard to use when searching. + * @param pHandle If a file was found, this is set to the find handle. If no file was found, this parameter is not modified. + * @param pathID If not null, the search paths assigned to this path ID are searched. Otherwise, all paths are searched. + * @return If a file was found, returns the name of the file. Otherwise, returns null. + */ + virtual const char *FindFirst( const char *pWildCard, FileFindHandle_t *pHandle, const char *pathID = 0L ) = 0; + + /** + * Finds the next file using the wildcard set by a previous call to FindFirst. + * @param handle Handle set by a previous call to FindFirst. + * @return If a file was found, returns the name of the file. Otherwise, returns null. + * @see FindFirst + */ + virtual const char *FindNext( FileFindHandle_t handle ) = 0; + + /** + * Checks whether the last file returned by a call to FindFirst or FindNext is a directory. + * @param handle Handle set by a previous call to FindFirst. + * @return Whether the file is a directory or not. + */ + virtual bool FindIsDirectory( FileFindHandle_t handle ) = 0; + + /** + * Closes a find operation. The handle will be invalid after this call. + * @param handle Handle set by a previous call to FindFirst. + */ + virtual void FindClose( FileFindHandle_t handle ) = 0; + + /** + * Creates a local copy for a file in a GCF file. + * Obsolete since the SteamPipe update, does nothing. + * @param pFileName Name of the file. + */ + virtual void GetLocalCopy( const char *pFileName ) = 0; + + /** + * Gets the local path of a file. This converts a relative path to an absolute path. All search paths are checked. + * @param pFileName Name of the file. + * @param pLocalPath Destination buffer. + * @param localPathBufferSize Size of the buffer, including null terminator. + * @return Pointer to pLocalPath, or null if the file could not be found. + */ + virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) = 0; + + /** + * Parses a string into tokens. + * Note: This function does not take a buffer size parameter. Be careful when using this. + * Note: This is sort of a secondary feature; but it's really useful to have it here. + * + * Uses the characters "{}()':" to split tokens. + * + * @param pFileBytes String to parse. + * @param pToken Destination buffer. + * @param pWasQuoted Optional. Whether the token was quoted or not. + * @return pointer to the next character in the string to parse. + */ + virtual char *ParseFile( char* pFileBytes, char* pToken, bool* pWasQuoted ) = 0; + + /** + * Converts a full (absolute) path to a relative path. + * Note: This function does not take a buffer size parameter. Ensure pRelative is large enough to store at least the entire pFullpath string to prevent buffer overflows. + * @param pFullpath Path to convert. + * @param pRelative Destination buffer. + * @return true on success ( based on current list of search paths, otherwise false if + * it can't be resolved ) + */ + virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative ) = 0; + + /** + * Gets the current working directory. + * @param pDirectory Destination buffer. Must not be null. + * @param maxlen Maximum number of characters, including the null terminator. + */ + virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) = 0; + + /** + * Dump to printf/OutputDebugString the list of files that have not been closed. + */ + virtual void PrintOpenedFiles( void ) = 0; + + /** + * Sets the warning function to invoke when a problem occurs. + * Note: This may be called during shutdown. Do not set a function that is not guaranteed to be in memory for at least as long as the filesystem itself. + * @param pfnWarning Function to set. + */ + virtual void SetWarningFunc( void (*pfnWarning)( const char *fmt, ... ) ) = 0; + + /** + * Sets the warning level. Higher levels output more information. + * @param level Warning level. + */ + virtual void SetWarningLevel( FileWarningLevel_t level ) = 0; + + /** + * Does nothing. + */ + virtual void LogLevelLoadStarted( const char *name ) = 0; + + /** + * Does nothing. + */ + virtual void LogLevelLoadFinished( const char *name ) = 0; + + /** + * Hints that a set of files will be loaded in near future. + * HintResourceNeed() is not to be confused with resource precaching. + * Obsolete since the SteamPipe update. + */ + virtual int HintResourceNeed( const char *hintlist, int forgetEverything ) = 0; + + /** + * Pauses resource preloading. + * Obsolete since the SteamPipe update. + */ + virtual int PauseResourcePreloading( void ) = 0; + + /** + * Resumes resource preloading. + * Obsolete since the SteamPipe update. + */ + virtual int ResumeResourcePreloading( void ) = 0; + + /** + * Sets the buffer for the given file. + * See the CRT function setvbuf (http://www.cplusplus.com/reference/cstdio/setvbuf/) for more information. + * @param stream Handle to the file. + * @param buffer Buffer to use. + * @param mode Buffering mode. + * @param size Size of the buffer, in bytes. + * @return If successful, returns 0. Otherwise, returns a non-zero value. + */ + virtual int SetVBuf( FileHandle_t stream, char *buffer, int mode, long size ) = 0; + + /** + * Gets the name and version of the interface. + * Note: The buffer may not be null terminated if the result has a number of characters equal to or greater than the size of the buffer. + * Note: This is not the same as the CreateInterface name. + * @param p Destination buffer. + * @param maxlen Size of the destination buffer, in characters, including the null terminator. + */ + virtual void GetInterfaceVersion( char *p, int maxlen ) = 0; + + /** + * Checks whether the given file is immediately available for file operations. + * Obsolete since the SteamPipe update. + * @param pFileName Name of the file. + * @return true in all cases. + */ + virtual bool IsFileImmediatelyAvailable(const char *pFileName) = 0; + + /** + * Starts waiting for resources to be available. + * Obsolete since the SteamPipe update. + * @return FILESYSTEM_INVALID_HANDLE if there is nothing to wait on. + */ + virtual WaitForResourcesHandle_t WaitForResources( const char *resourcelist ) = 0; + + /** + * Get progress on waiting for resources; progress is a float [0, 1], complete is true on the waiting being done. + * Any calls after complete is true or on an invalid handle will return false, 0.0f, true. + * Obsolete since the SteamPipe update. + * @return false if no progress is available, true otherwise. + */ + virtual bool GetWaitForResourcesProgress( WaitForResourcesHandle_t handle, float *progress /* out */ , bool *complete /* out */ ) = 0; + + /** + * Cancels a progress call. + * Obsolete since the SteamPipe update. + */ + virtual void CancelWaitForResources( WaitForResourcesHandle_t handle ) = 0; + + /** + * Checks whether the appID has all its caches fully preloaded. + * Obsolete since the SteamPipe update. + * @return true if the appID has all its caches fully preloaded. + */ + virtual bool IsAppReadyForOfflinePlay( int appID ) = 0; + + /** + * Adds pack files to the given path ID for searching. + * Interface for custom pack files > 4Gb. + * @param fullpath Path to the file. The path should be relative to the current working directory. + * @param pathID If not null, the path ID to add the pack file to. Otherwise, only used if null path IDs are used for searching. + * @return true if the pack file was successfully added, false otherwise. + * @see GetCurrentDirectory + */ + virtual bool AddPackFile( const char *fullpath, const char *pathID ) = 0; + + /** + * Open a file but force the data to come from the steam cache, NOT from disk. + * Similar to Open, but will not fall back to the first write path for non-existent or null path IDs. + * Instead, non-existent path IDs result in a failure to open, and null IDs result in all paths being searched. + * @see Open + */ + virtual FileHandle_t OpenFromCacheForRead( const char *pFileName, const char *pOptions, const char *pathID = 0L ) = 0; + + /** + * Adds a read-only search path. + * @see AddSearchPath + */ + virtual void AddSearchPathNoWrite( const char *pPath, const char *pathID ) = 0; +}; + +//! Creates the interface adapter. +IFileSystem *Compat_CreateFileSystem(IFileSystemCompat *pIface); + +#endif // FILESYSTEM_H diff --git a/src/game/client/compat/ISchemeCompat.cpp b/src/game/client/compat/ISchemeCompat.cpp new file mode 100644 index 00000000..2f540a35 --- /dev/null +++ b/src/game/client/compat/ISchemeCompat.cpp @@ -0,0 +1,80 @@ +#include +#include +#include "compat/ISchemeCompat.h" + +using namespace vgui2; + +class CSchemeManagerCompat final : public vgui2::ISchemeManager +{ +public: + CSchemeManagerCompat(vgui2::ISchemeManagerCompat* pIface) + { + m_pIface = pIface; + } + + virtual HScheme LoadSchemeFromFile(const char *fileName, const char *tag) override + { + return m_pIface->LoadSchemeFromFile(fileName, tag); + } + + virtual void ReloadSchemes() override + { + m_pIface->ReloadSchemes(); + } + + virtual HScheme GetDefaultScheme() override + { + return m_pIface->GetDefaultScheme(); + } + + virtual HScheme GetScheme(const char *tag) override + { + return m_pIface->GetScheme(tag); + } + + virtual IImage *GetImage(const char *imageName, bool hardwareFiltered) override + { + return m_pIface->GetImage(imageName, hardwareFiltered); + } + + virtual HTexture GetImageID(const char *imageName, bool hardwareFiltered) override + { + return m_pIface->GetImageID(imageName, hardwareFiltered); + } + + virtual IScheme *GetIScheme(HScheme scheme) override + { + return m_pIface->GetIScheme(scheme); + } + + virtual void Shutdown(bool full) override + { + m_pIface->Shutdown(full); + } + + virtual float GetProportionalScale() override + { + constexpr int BASE_HEIGHT = 480; + int wide, tall; + surface()->GetScreenSize(wide, tall); + return (float)tall / BASE_HEIGHT; + } + + virtual int GetProportionalScaledValue(int normalizedValue) override + { + return m_pIface->GetProportionalScaledValue(normalizedValue); + } + + virtual int GetProportionalNormalizedValue(int scaledValue) override + { + return m_pIface->GetProportionalNormalizedValue(scaledValue); + } + +private: + vgui2::ISchemeManagerCompat *m_pIface = nullptr; +}; + +vgui2::ISchemeManager *Compat_CreateSchemeManager(vgui2::ISchemeManagerCompat *pIface) +{ + return new CSchemeManagerCompat(pIface); +} diff --git a/src/game/client/compat/ISchemeCompat.h b/src/game/client/compat/ISchemeCompat.h new file mode 100644 index 00000000..61a46b87 --- /dev/null +++ b/src/game/client/compat/ISchemeCompat.h @@ -0,0 +1,55 @@ +#ifndef ISCHEMECOMPAT_H +#define ISCHEMECOMPAT_H +#include + +namespace vgui2 +{ + +class ISchemeManagerCompat : public IBaseInterface +{ +public: + static constexpr char VERSION[] = "VGUI_Scheme009"; + + // loads a scheme from a file + // first scheme loaded becomes the default scheme, and all subsequent loaded scheme are derivitives of that + virtual HScheme LoadSchemeFromFile( const char *fileName, const char *tag ) = 0; + + // reloads the scheme from the file - should only be used during development + virtual void ReloadSchemes() = 0; + + // reloads scheme fonts + //virtual void ReloadFonts() = 0; + + // returns a handle to the default (first loaded) scheme + virtual HScheme GetDefaultScheme() = 0; + + // returns a handle to the scheme identified by "tag" + virtual HScheme GetScheme( const char *tag ) = 0; + + // returns a pointer to an image + virtual IImage *GetImage( const char *imageName, bool hardwareFiltered ) = 0; + virtual HTexture GetImageID( const char *imageName, bool hardwareFiltered ) = 0; + + // This can only be called at certain times, like during paint() + // It will assert-fail if you call it at the wrong time... + + // FIXME: This interface should go away!!! It's an icky back-door + // If you're using this interface, try instead to cache off the information + // in ApplySchemeSettings + virtual IScheme *GetIScheme( HScheme scheme ) = 0; + + // unload all schemes + virtual void Shutdown( bool full = true ) = 0; + + // gets the proportional coordinates for doing screen-size independant panel layouts + // use these for font, image and panel size scaling (they all use the pixel height of the display for scaling) + virtual int GetProportionalScaledValue( int normalizedValue ) = 0; + virtual int GetProportionalNormalizedValue( int scaledValue ) = 0; +}; + +} // namespace vgui2 + +//! Creates the interface adapter. +vgui2::ISchemeManager *Compat_CreateSchemeManager(vgui2::ISchemeManagerCompat *pIface); + +#endif // ISCHEME_H diff --git a/src/game/client/compat/ISurfaceCompat.cpp b/src/game/client/compat/ISurfaceCompat.cpp new file mode 100644 index 00000000..a67c09ae --- /dev/null +++ b/src/game/client/compat/ISurfaceCompat.cpp @@ -0,0 +1,538 @@ +#include +#include "compat/ISurfaceCompat.h" + +using namespace vgui2; + +class CSurfaceCompat final : public ISurface +{ +public: + CSurfaceCompat(ISurfaceCompat* pIface) + { + m_pIface = pIface; + } + + virtual void Shutdown() override + { + m_pIface->Shutdown(); + } + + virtual void RunFrame() override + { + m_pIface->RunFrame(); + } + + virtual VPANEL GetEmbeddedPanel() override + { + return m_pIface->GetEmbeddedPanel(); + } + + virtual void SetEmbeddedPanel(VPANEL pPanel) override + { + m_pIface->SetEmbeddedPanel(pPanel); + } + + virtual void PushMakeCurrent(VPANEL panel, bool useInsets) override + { + m_pIface->PushMakeCurrent(panel, useInsets); + } + + virtual void PopMakeCurrent(VPANEL panel) override + { + m_pIface->PopMakeCurrent(panel); + } + + virtual void DrawSetColor(int r, int g, int b, int a) override + { + m_pIface->DrawSetColor(r, g, b, a); + } + + virtual void DrawSetColor(Color col) override + { + m_pIface->DrawSetColor(col); + } + + virtual void DrawFilledRect(int x0, int y0, int x1, int y1) override + { + m_pIface->DrawFilledRect(x0, y0, x1, y1); + } + + virtual void DrawOutlinedRect(int x0, int y0, int x1, int y1) override + { + m_pIface->DrawOutlinedRect(x0, y0, x1, y1); + } + + virtual void DrawLine(int x0, int y0, int x1, int y1) override + { + m_pIface->DrawLine(x0, y0, x1, y1); + } + + virtual void DrawPolyLine(int *px, int *py, int numPoints) override + { + m_pIface->DrawPolyLine(px, py, numPoints); + } + + virtual void DrawSetTextFont(HFont font) override + { + m_pIface->DrawSetTextFont(font); + } + + virtual void DrawSetTextColor(int r, int g, int b, int a) override + { + m_pIface->DrawSetTextColor(r, g, b, a); + } + + virtual void DrawSetTextColor(Color col) override + { + m_pIface->DrawSetTextColor(col); + } + + virtual void DrawSetTextPos(int x, int y) override + { + m_pIface->DrawSetTextPos(x, y); + } + + virtual void DrawGetTextPos(int &x, int &y) override + { + m_pIface->DrawGetTextPos(x, y); + } + + virtual void DrawPrintText(const wchar_t *text, int textLen) override + { + m_pIface->DrawPrintText(text, textLen); + } + + virtual void DrawUnicodeChar(wchar_t wch) override + { + m_pIface->DrawUnicodeChar(wch); + } + + virtual void DrawUnicodeCharAdd(wchar_t wch) override + { + m_pIface->DrawUnicodeCharAdd(wch); + } + + virtual void DrawFlushText() override + { + m_pIface->DrawFlushText(); + } + + virtual IHTML *CreateHTMLWindow(vgui2::IHTMLEvents *events, VPANEL context) override + { + return m_pIface->CreateHTMLWindow(events, context); + } + + virtual void PaintHTMLWindow(vgui2::IHTML *htmlwin) override + { + m_pIface->PaintHTMLWindow(htmlwin); + } + + virtual void DeleteHTMLWindow(IHTML *htmlwin) override + { + m_pIface->DeleteHTMLWindow(htmlwin); + } + + virtual void DrawSetTextureFile(int id, const char *filename, int hardwareFilter, bool forceReload) override + { + m_pIface->DrawSetTextureFile(id, filename, hardwareFilter, forceReload); + } + + virtual void DrawSetTextureRGBA(int id, const unsigned char *rgba, int wide, int tall, int hardwareFilter, bool forceReload) override + { + m_pIface->DrawSetTextureRGBA(id, rgba, wide, tall, hardwareFilter, forceReload); + } + + virtual void DrawSetTexture(int id) override + { + m_pIface->DrawSetTexture(id); + } + + virtual void DrawGetTextureSize(int id, int &wide, int &tall) override + { + m_pIface->DrawGetTextureSize(id, wide, tall); + } + + virtual void DrawTexturedRect(int x0, int y0, int x1, int y1) override + { + m_pIface->DrawTexturedRect(x0, y0, x1, y1); + } + + virtual void DrawTexturedRectAdd(int x0, int y0, int x1, int y1) override + { + m_pIface->DrawTexturedRect(x0, y0, x1, y1); + } + + virtual bool IsTextureIDValid(int id) override + { + return m_pIface->IsTextureIDValid(id); + } + + virtual int CreateNewTextureID(bool procedural) override + { + return m_pIface->CreateNewTextureID(procedural); + } + + virtual void GetScreenSize(int &wide, int &tall) override + { + m_pIface->GetScreenSize(wide, tall); + } + + virtual void SetAsTopMost(VPANEL panel, bool state) override + { + m_pIface->SetAsTopMost(panel, state); + } + + virtual void BringToFront(VPANEL panel) override + { + m_pIface->BringToFront(panel); + } + + virtual void SetForegroundWindow(VPANEL panel) override + { + m_pIface->SetForegroundWindow(panel); + } + + virtual void SetPanelVisible(VPANEL panel, bool state) override + { + m_pIface->SetPanelVisible(panel, state); + } + + virtual void SetMinimized(VPANEL panel, bool state) override + { + m_pIface->SetMinimized(panel, state); + } + + virtual bool IsMinimized(VPANEL panel) override + { + return m_pIface->IsMinimized(panel); + } + + virtual void FlashWindow(VPANEL panel, bool state) override + { + m_pIface->FlashWindow(panel, state); + } + + virtual void SetTitle(VPANEL panel, const wchar_t *title) override + { + m_pIface->SetTitle(panel, title); + } + + virtual void SetAsToolBar(VPANEL panel, bool state) override + { + m_pIface->SetAsToolBar(panel, state); + } + + virtual void SetSupportsEsc(bool bSupportsEsc) override + { + // Not implemented + std::abort(); + } + + virtual void CreatePopup(VPANEL panel, bool minimised, bool showTaskbarIcon, bool disabled, bool mouseInput, bool kbInput) override + { + m_pIface->CreatePopup(panel, minimised, showTaskbarIcon, disabled, mouseInput, kbInput); + } + + virtual void SwapBuffers(VPANEL panel) override + { + m_pIface->SwapBuffers(panel); + } + + virtual void Invalidate(VPANEL panel) override + { + m_pIface->Invalidate(panel); + } + + virtual void SetCursor(HCursor cursor) override + { + m_pIface->SetCursor(cursor); + } + + virtual bool IsCursorVisible() override + { + return m_pIface->IsCursorVisible(); + } + + virtual void ApplyChanges() override + { + m_pIface->ApplyChanges(); + } + + virtual bool IsWithin(int x, int y) override + { + return m_pIface->IsWithin(x, y); + } + + virtual bool HasFocus() override + { + return m_pIface->HasFocus(); + } + + virtual bool SupportsFeature(SurfaceFeature_e feature) override + { + return m_pIface->SupportsFeature(feature); + } + + virtual void RestrictPaintToSinglePanel(VPANEL panel) override + { + m_pIface->RestrictPaintToSinglePanel(panel); + } + + virtual void SetModalPanel(VPANEL _arg0) override + { + m_pIface->SetModalPanel(_arg0); + } + + virtual VPANEL GetModalPanel() override + { + return m_pIface->GetModalPanel(); + } + + virtual void UnlockCursor() override + { + m_pIface->UnlockCursor(); + } + + virtual void LockCursor() override + { + m_pIface->LockCursor(); + } + + virtual void SetTranslateExtendedKeys(bool state) override + { + m_pIface->SetTranslateExtendedKeys(state); + } + + virtual VPANEL GetTopmostPopup() override + { + return m_pIface->GetTopmostPopup(); + } + + virtual void SetTopLevelFocus(VPANEL panel) override + { + m_pIface->SetTopLevelFocus(panel); + } + + virtual HFont CreateFont() override + { + return m_pIface->CreateFont(); + } + + virtual bool AddGlyphSetToFont(HFont font, const char *windowsFontName, int tall, int weight, int blur, int scanlines, int flags, int lowRange, int highRange) override + { + return m_pIface->AddGlyphSetToFont(font, windowsFontName, tall, weight, blur, scanlines, flags, lowRange, highRange); + } + + virtual bool AddCustomFontFile(const char *fontFileName) override + { + return m_pIface->AddCustomFontFile(fontFileName); + } + + virtual int GetFontTall(HFont font) override + { + return m_pIface->GetFontTall(font); + } + + virtual void GetCharABCwide(HFont font, int ch, int &a, int &b, int &c) override + { + m_pIface->GetCharABCwide(font, ch, a, b, c); + } + + virtual int GetCharacterWidth(HFont font, int ch) override + { + return m_pIface->GetCharacterWidth(font, ch); + } + + virtual int GetFontBlur(HFont font) + { + return 0; + } + + virtual bool IsAdditive(HFont font) + { + return false; + } + + virtual void GetTextSize(HFont font, const wchar_t *text, int &wide, int &tall) override + { + return m_pIface->GetTextSize(font, text, wide, tall); + } + + virtual VPANEL GetNotifyPanel() override + { + return m_pIface->GetNotifyPanel(); + } + + virtual void SetNotifyIcon(VPANEL context, HTexture icon, VPANEL panelToReceiveMessages, const char *text) override + { + m_pIface->SetNotifyIcon(context, icon, panelToReceiveMessages, text); + } + + virtual void PlaySound(const char *fileName) override + { + m_pIface->PlaySound(fileName); + } + + virtual int GetPopupCount() override + { + return m_pIface->GetPopupCount(); + } + + virtual VPANEL GetPopup(int index) override + { + return m_pIface->GetPopup(index); + } + + virtual bool ShouldPaintChildPanel(VPANEL childPanel) override + { + return m_pIface->ShouldPaintChildPanel(childPanel); + } + + virtual bool RecreateContext(VPANEL panel) override + { + return m_pIface->RecreateContext(panel); + } + + virtual void AddPanel(VPANEL panel) override + { + m_pIface->AddPanel(panel); + } + + virtual void ReleasePanel(VPANEL panel) override + { + m_pIface->ReleasePanel(panel); + } + + virtual void MovePopupToFront(VPANEL panel) override + { + m_pIface->MovePopupToFront(panel); + } + + virtual void MovePopupToBack(VPANEL panel) override + { + m_pIface->MovePopupToBack(panel); + } + + virtual void SolveTraverse(VPANEL panel, bool forceApplySchemeSettings) override + { + m_pIface->SolveTraverse(panel, forceApplySchemeSettings); + } + + virtual void PaintTraverse(VPANEL panel) override + { + m_pIface->PaintTraverse(panel); + } + + virtual void EnableMouseCapture(VPANEL panel, bool state) override + { + m_pIface->EnableMouseCapture(panel, state); + } + + virtual void GetWorkspaceBounds(int &x, int &y, int &wide, int &tall) override + { + m_pIface->GetWorkspaceBounds(x, y, wide, tall); + } + + virtual void GetAbsoluteWindowBounds(int &x, int &y, int &wide, int &tall) override + { + m_pIface->GetAbsoluteWindowBounds(x, y, wide, tall); + } + + virtual void GetProportionalBase(int &width, int &height) override + { + m_pIface->GetProportionalBase(width, height); + } + + virtual void SetProportionalBase(int width, int height) override + { + // Not implemented + std::abort(); + } + + virtual void CalculateMouseVisible() override + { + m_pIface->CalculateMouseVisible(); + } + + virtual bool NeedKBInput() override + { + return m_pIface->NeedKBInput(); + } + + virtual bool HasCursorPosFunctions() override + { + return m_pIface->HasCursorPosFunctions(); + } + + virtual void SurfaceGetCursorPos(int &x, int &y) override + { + m_pIface->SurfaceGetCursorPos(x, y); + } + + virtual void SurfaceSetCursorPos(int x, int y) override + { + m_pIface->SurfaceSetCursorPos(x, y); + } + + virtual void DrawTexturedPolygon(VGuiVertex *pVertices, int n) override + { + m_pIface->DrawTexturedPolygon(pVertices, n); + } + + virtual int GetFontAscent(HFont font, wchar_t wch) override + { + return m_pIface->GetFontAscent(font, wch); + } + + virtual void SetAllowHTMLJavaScript(bool state) override + { + m_pIface->SetAllowHTMLJavaScript(state); + } + + virtual void SetLanguage(const char *pchLang) override + { + m_pIface->SetLanguage(pchLang); + } + + virtual const char *GetLanguage() override + { + return m_pIface->GetLanguage(); + } + + virtual bool DeleteTextureByID(int id) override + { + return m_pIface->DeleteTextureByID(id); + } + + virtual void DrawUpdateRegionTextureBGRA(int nTextureID, int x, int y, const unsigned char *pchData, int wide, int tall) override + { + m_pIface->DrawUpdateRegionTextureBGRA(nTextureID, x, y, pchData, wide, tall); + } + + virtual void DrawSetTextureBGRA(int id, const unsigned char *pchData, int wide, int tall) override + { + m_pIface->DrawSetTextureBGRA(id, pchData, wide, tall); + } + + virtual void CreateBrowser(vgui2::VPANEL panel, IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier) override + { + m_pIface->CreateBrowser(panel, pBrowser, bPopupWindow, pchUserAgentIdentifier); + } + + virtual void RemoveBrowser(vgui2::VPANEL panel, IHTMLResponses *pBrowser) override + { + m_pIface->RemoveBrowser(panel, pBrowser); + } + + virtual IHTMLChromeController *AccessChromeHTMLController() override + { + return m_pIface->AccessChromeHTMLController(); + } + +private: + ISurfaceCompat *m_pIface = nullptr; +}; + +vgui2::ISurface *Compat_CreateSurface(vgui2::ISurfaceCompat *pIface) +{ + return new CSurfaceCompat(pIface); +} diff --git a/src/game/client/compat/ISurfaceCompat.h b/src/game/client/compat/ISurfaceCompat.h new file mode 100644 index 00000000..dfd384d0 --- /dev/null +++ b/src/game/client/compat/ISurfaceCompat.h @@ -0,0 +1,268 @@ +#ifndef ISURFACECOMPAT_H +#define ISURFACECOMPAT_H +#include + +#ifdef CreateFont +#undef CreateFont +#endif + +#ifdef PlaySound +#undef PlaySound +#endif + + +namespace vgui2 +{ + +class ISurfaceCompat : public IBaseInterface //public IAppSystem +{ +public: + static constexpr char VERSION[] = "VGUI_Surface026"; + + // call to Shutdown surface; surface can no longer be used after this is called + virtual void Shutdown() = 0; + + // frame + virtual void RunFrame() = 0; + + // hierarchy root + virtual VPANEL GetEmbeddedPanel() = 0; + virtual void SetEmbeddedPanel(VPANEL pPanel) = 0; + + // drawing context + virtual void PushMakeCurrent(VPANEL panel, bool useInsets) = 0; + virtual void PopMakeCurrent(VPANEL panel) = 0; + + // rendering functions + virtual void DrawSetColor(int r, int g, int b, int a) = 0; + virtual void DrawSetColor(Color col) = 0; + + virtual void DrawFilledRect(int x0, int y0, int x1, int y1) = 0; + //Not used by GoldSource - Solokiller + //virtual void DrawFilledRectArray( IntRect *pRects, int numRects ) = 0; + virtual void DrawOutlinedRect(int x0, int y0, int x1, int y1) = 0; + + virtual void DrawLine(int x0, int y0, int x1, int y1) = 0; + virtual void DrawPolyLine(int *px, int *py, int numPoints) = 0; + + virtual void DrawSetTextFont(HFont font) = 0; + virtual void DrawSetTextColor(int r, int g, int b, int a) = 0; + virtual void DrawSetTextColor(Color col) = 0; + virtual void DrawSetTextPos(int x, int y) = 0; + virtual void DrawGetTextPos(int &x, int &y) = 0; + //Font draw types aren't used. - Solokiller + virtual void DrawPrintText(const wchar_t *text, int textLen /*, FontDrawType_t drawType = FONT_DRAW_DEFAULT*/) = 0; + virtual void DrawUnicodeChar(wchar_t wch /*, FontDrawType_t drawType = FONT_DRAW_DEFAULT*/) = 0; + virtual void DrawUnicodeCharAdd(wchar_t wch) = 0; + + virtual void DrawFlushText() = 0; // flushes any buffered text (for rendering optimizations) + virtual IHTML *CreateHTMLWindow(vgui2::IHTMLEvents *events, VPANEL context) = 0; + virtual void PaintHTMLWindow(vgui2::IHTML *htmlwin) = 0; + virtual void DeleteHTMLWindow(IHTML *htmlwin) = 0; + + //virtual int DrawGetTextureId( char const *filename ) = 0; + //virtual bool DrawGetTextureFile(int id, char *filename, int maxlen ) = 0; + virtual void DrawSetTextureFile(int id, const char *filename, int hardwareFilter, bool forceReload) = 0; + virtual void DrawSetTextureRGBA(int id, const unsigned char *rgba, int wide, int tall, int hardwareFilter, bool forceReload) = 0; + virtual void DrawSetTexture(int id) = 0; + virtual void DrawGetTextureSize(int id, int &wide, int &tall) = 0; + virtual void DrawTexturedRect(int x0, int y0, int x1, int y1) = 0; + virtual bool IsTextureIDValid(int id) = 0; + + virtual int CreateNewTextureID(bool procedural = false) = 0; +#ifdef _XBOX + virtual void DestroyTextureID(int id) = 0; + virtual bool IsCachedForRendering(int id, bool bSyncWait) = 0; + virtual void CopyFrontBufferToBackBuffer() = 0; + virtual void UncacheUnusedMaterials() = 0; +#endif + + virtual void GetScreenSize(int &wide, int &tall) = 0; + virtual void SetAsTopMost(VPANEL panel, bool state) = 0; + virtual void BringToFront(VPANEL panel) = 0; + virtual void SetForegroundWindow(VPANEL panel) = 0; + virtual void SetPanelVisible(VPANEL panel, bool state) = 0; + virtual void SetMinimized(VPANEL panel, bool state) = 0; + virtual bool IsMinimized(VPANEL panel) = 0; + virtual void FlashWindow(VPANEL panel, bool state) = 0; + virtual void SetTitle(VPANEL panel, const wchar_t *title) = 0; + virtual void SetAsToolBar(VPANEL panel, bool state) = 0; // removes the window's task bar entry (for context menu's, etc.) + + // windows stuff + virtual void CreatePopup(VPANEL panel, bool minimised, bool showTaskbarIcon = true, bool disabled = false, bool mouseInput = true, bool kbInput = true) = 0; + virtual void SwapBuffers(VPANEL panel) = 0; + virtual void Invalidate(VPANEL panel) = 0; + virtual void SetCursor(HCursor cursor) = 0; + virtual bool IsCursorVisible() = 0; + virtual void ApplyChanges() = 0; + virtual bool IsWithin(int x, int y) = 0; + virtual bool HasFocus() = 0; + + // returns true if the surface supports minimize & maximize capabilities + virtual bool SupportsFeature(ISurface::SurfaceFeature_e feature) = 0; + + // restricts what gets drawn to one panel and it's children + // currently only works in the game + virtual void RestrictPaintToSinglePanel(VPANEL panel) = 0; + + // these two functions obselete, use IInput::SetAppModalSurface() instead + virtual void SetModalPanel(VPANEL) = 0; + virtual VPANEL GetModalPanel() = 0; + + virtual void UnlockCursor() = 0; + virtual void LockCursor() = 0; + virtual void SetTranslateExtendedKeys(bool state) = 0; + virtual VPANEL GetTopmostPopup() = 0; + + // engine-only focus handling (replacing WM_FOCUS windows handling) + virtual void SetTopLevelFocus(VPANEL panel) = 0; + + // fonts + // creates an empty handle to a vgui font. windows fonts can be add to this via AddGlyphSetToFont(). + virtual HFont CreateFont() = 0; + + // adds to the font + virtual bool AddGlyphSetToFont(HFont font, const char *windowsFontName, int tall, int weight, int blur, int scanlines, int flags, int lowRange, int highRange) = 0; + + // adds a custom font file (only supports true type font files (.ttf) for now) + virtual bool AddCustomFontFile(const char *fontFileName) = 0; + + // returns the details about the font + virtual int GetFontTall(HFont font) = 0; + //virtual bool IsFontAdditive(HFont font) = 0; + virtual void GetCharABCwide(HFont font, int ch, int &a, int &b, int &c) = 0; + virtual int GetCharacterWidth(HFont font, int ch) = 0; + virtual void GetTextSize(HFont font, const wchar_t *text, int &wide, int &tall) = 0; + + // notify icons?!? + virtual VPANEL GetNotifyPanel() = 0; + virtual void SetNotifyIcon(VPANEL context, HTexture icon, VPANEL panelToReceiveMessages, const char *text) = 0; + + // plays a sound + virtual void PlaySound(const char *fileName) = 0; + + //!! these functions should not be accessed directly, but only through other vgui items + //!! need to move these to seperate interface + virtual int GetPopupCount() = 0; + virtual VPANEL GetPopup(int index) = 0; + virtual bool ShouldPaintChildPanel(VPANEL childPanel) = 0; + virtual bool RecreateContext(VPANEL panel) = 0; + virtual void AddPanel(VPANEL panel) = 0; + virtual void ReleasePanel(VPANEL panel) = 0; + virtual void MovePopupToFront(VPANEL panel) = 0; + virtual void MovePopupToBack(VPANEL panel) = 0; + + virtual void SolveTraverse(VPANEL panel, bool forceApplySchemeSettings = false) = 0; + virtual void PaintTraverse(VPANEL panel) = 0; + + virtual void EnableMouseCapture(VPANEL panel, bool state) = 0; + + // returns the size of the workspace + virtual void GetWorkspaceBounds(int &x, int &y, int &wide, int &tall) = 0; + + // gets the absolute coordinates of the screen (in windows space) + virtual void GetAbsoluteWindowBounds(int &x, int &y, int &wide, int &tall) = 0; + + // gets the base resolution used in proportional mode + virtual void GetProportionalBase(int &width, int &height) = 0; + + virtual void CalculateMouseVisible() = 0; + virtual bool NeedKBInput() = 0; + + virtual bool HasCursorPosFunctions() = 0; + virtual void SurfaceGetCursorPos(int &x, int &y) = 0; + virtual void SurfaceSetCursorPos(int x, int y) = 0; + + // SRC only functions!!! + //virtual void DrawTexturedLine( const Vertex_t &a, const Vertex_t &b ) = 0; + //virtual void DrawOutlinedCircle(int x, int y, int radius, int segments) = 0; + //virtual void DrawTexturedPolyLine( const Vertex_t *p,int n ) = 0; // (Note: this connects the first and last points). + //virtual void DrawTexturedSubRect( int x0, int y0, int x1, int y1, float texs0, float text0, float texs1, float text1 ) = 0; + virtual void DrawTexturedPolygon(VGuiVertex *pVertices, int n) = 0; + virtual int GetFontAscent(HFont font, wchar_t wch) = 0; + //virtual const wchar_t *GetTitle(VPANEL panel) = 0; + //virtual bool IsCursorLocked( void ) const = 0; + //virtual void SetWorkspaceInsets( int left, int top, int right, int bottom ) = 0; + + // Lower level char drawing code, call DrawGet then pass in info to DrawRender + //virtual bool DrawGetUnicodeCharRenderInfo( wchar_t ch, CharRenderInfo& info ) = 0; + //virtual void DrawRenderCharFromInfo( const CharRenderInfo& info ) = 0; + + // global alpha setting functions + // affect all subsequent draw calls - shouldn't normally be used directly, only in Panel::PaintTraverse() + //virtual void DrawSetAlphaMultiplier( float alpha /* [0..1] */ ) = 0; + //virtual float DrawGetAlphaMultiplier() = 0; + + // web browser + virtual void SetAllowHTMLJavaScript(bool state) = 0; + + virtual void SetLanguage(const char *pchLang) = 0; + + virtual const char *GetLanguage() = 0; + + virtual bool DeleteTextureByID(int id) = 0; + + virtual void DrawUpdateRegionTextureBGRA(int nTextureID, int x, int y, const unsigned char *pchData, int wide, int tall) = 0; + + virtual void DrawSetTextureBGRA(int id, const unsigned char *pchData, int wide, int tall) = 0; + + virtual void CreateBrowser(vgui2::VPANEL panel, IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier) = 0; + + virtual void RemoveBrowser(vgui2::VPANEL panel, IHTMLResponses *pBrowser) = 0; + + virtual IHTMLChromeController *AccessChromeHTMLController() = 0; + + //These *might* work, but will likely cause crashes due to interface compatibility issues. - Solokiller + /* + virtual bool setFullscreenMode( int wide, int tall, int bpp ) = 0; + virtual void setWindowedMode() = 0; + + virtual void SetAsTopMost( bool state ) = 0; + virtual void SetAsToolBar( bool state ) = 0; + + virtual void PanelRequestFocus( vgui2::VPANEL panel ) = 0; + virtual void EnableMouseCapture( bool state ) = 0; + + virtual void DrawPrintChar( int x, int y, int wide, int tall, float s0, float t0, float s1, float t1 ) = 0; + + virtual void SetNotifyIcon( vgui2::Image *, vgui2::VPANEL, char const* ) = 0; + + virtual bool SetWatchForComputerUse( bool state ) = 0; + virtual double GetTimeSinceLastUse() = 0; + */ + + // video mode changing + //virtual void OnScreenSizeChanged( int nOldWidth, int nOldHeight ) = 0; +#if !defined(_XBOX) + //virtual vgui2::HCursor CreateCursorFromFile( char const *curOrAniFile, char const *pPathID = 0 ) = 0; +#endif + // create IVguiMatInfo object ( IMaterial wrapper in VguiMatSurface, NULL in CWin32Surface ) + //virtual IVguiMatInfo *DrawGetTextureMatInfoFactory( int id ) = 0; + + //virtual void PaintTraverseEx(VPANEL panel, bool paintPopups = false ) = 0; + + //virtual float GetZPos() const = 0; + + // From the Xbox + //virtual void SetPanelForInput( VPANEL vpanel ) = 0; + //virtual void DrawFilledRectFade( int x0, int y0, int x1, int y1, unsigned int alpha0, unsigned int alpha1, bool bHorizontal ) = 0; + //virtual void DrawSetTextureRGBAEx(int id, const unsigned char *rgba, int wide, int tall, ImageFormat imageFormat ) = 0; + //virtual void DrawSetTextScale(float sx, float sy) = 0; + //virtual bool SetBitmapFontGlyphSet(HFont font, const char *windowsFontName, float scalex, float scaley, int flags) = 0; + //// adds a bitmap font file + //virtual bool AddBitmapFontFile(const char *fontFileName) = 0; + //// sets a symbol for the bitmap font + //virtual void SetBitmapFontName( const char *pName, const char *pFontFilename ) = 0; + //// gets the bitmap font filename + //virtual const char *GetBitmapFontName( const char *pName ) = 0; + + //virtual IImage *GetIconImageForFullPath( char const *pFullPath ) = 0; + //virtual void DrawUnicodeString( const wchar_t *pwString, FontDrawType_t drawType = FONT_DRAW_DEFAULT ) = 0; +}; + +} // namespace vgui2 + +//! Creates the interface adapter. +vgui2::ISurface *Compat_CreateSurface(vgui2::ISurfaceCompat *pIface); + +#endif // ISURFACECOMPAT_H diff --git a/src/game/client/compat/anniversary_compat.cpp b/src/game/client/compat/anniversary_compat.cpp new file mode 100644 index 00000000..d1aa4628 --- /dev/null +++ b/src/game/client/compat/anniversary_compat.cpp @@ -0,0 +1,72 @@ +#include "compat/anniversary_compat.h" +#include "compat/FileSystemCompat.h" +#include "compat/ISchemeCompat.h" +#include "compat/ISurfaceCompat.h" + +static IFileSystem *s_pEngineFileSystem = nullptr; +static IFileSystem *s_pFileSystemCompat = nullptr; +static vgui2::ISchemeManager *s_pSchemeManagerCompat = nullptr; +static vgui2::ISurface *s_pSurfaceCompat = nullptr; + +template +using CompatFactoryFn = TIface*(*)(TCompatIface*); + +template +static void FindAndCreateCompat( + TIface *&compatInstance, + CreateInterfaceFn factory, + CompatFactoryFn compatFactory) +{ + if (compatInstance) + return; + + // Find the interface + const char *version = TCompatIface::VERSION; + void *pRawIface = factory(version, nullptr); + + if (!pRawIface) + return; + + compatInstance = compatFactory(static_cast(pRawIface)); +} + +static void* CompatFactory(const char* pName, int* pReturnCode) +{ + if (!strcmp(pName, FILESYSTEM_INTERFACE_VERSION_ENGINE)) + return s_pEngineFileSystem; + + if (!strcmp(pName, FILESYSTEM_INTERFACE_VERSION)) + return s_pFileSystemCompat; + + if (!strcmp(pName, VGUI_SCHEME_INTERFACE_VERSION_GS)) + return s_pSchemeManagerCompat; + + if (!strcmp(pName, VGUI_SURFACE_INTERFACE_VERSION_GS)) + return s_pSurfaceCompat; + + return nullptr; +} + +CreateInterfaceFn Compat_CreateFactory(CreateInterfaceFn *pFactories, int iNumFactories) +{ + for (int i = 0; i < iNumFactories; i++) + { + FindAndCreateCompat(s_pFileSystemCompat, pFactories[i], Compat_CreateFileSystem); + FindAndCreateCompat(s_pSchemeManagerCompat, pFactories[i], Compat_CreateSchemeManager); + FindAndCreateCompat(s_pSurfaceCompat, pFactories[i], Compat_CreateSurface); + + if (!s_pEngineFileSystem) + s_pEngineFileSystem = static_cast(pFactories[i](FILESYSTEM_INTERFACE_VERSION, nullptr)); + } + + if (!s_pFileSystemCompat) + return nullptr; + + if (!s_pSchemeManagerCompat) + return nullptr; + + if (!s_pSurfaceCompat) + return nullptr; + + return CompatFactory; +} diff --git a/src/game/client/compat/anniversary_compat.h b/src/game/client/compat/anniversary_compat.h new file mode 100644 index 00000000..25256691 --- /dev/null +++ b/src/game/client/compat/anniversary_compat.h @@ -0,0 +1,10 @@ +#ifndef ANNIVERSARY_COMPAT_H +#define ANNIVERSARY_COMPAT_H +#include + +//! Provides compatibility with pre-Anniversary-Update game versions. +//! Works by creating wrappers for new (hl1_source_sdk) interfaces that call old ones. +//! This factory will provide those wrappers. +CreateInterfaceFn Compat_CreateFactory(CreateInterfaceFn *pFactories, int iNumFactories); + +#endif diff --git a/src/game/client/engine_patches.h b/src/game/client/engine_patches.h index d17e1dcd..c9e9467b 100644 --- a/src/game/client/engine_patches.h +++ b/src/game/client/engine_patches.h @@ -7,6 +7,15 @@ struct SvcHandler; struct UserMessage; +//! Probably the last version before SteamPipe. +constexpr int ENGINE_BUILD_PRE_STEAMPIPE = 4554; + +//! First builds of SteamPipe. +constexpr int ENGINE_BUILD_STEAMPIPE = 6000; + +//! First build of the Anniversary Update (2023-11-16). +constexpr int ENGINE_BUILD_ANNIVERSARY = 9884; + /** * Engine patching includes fixing some bugs and */ diff --git a/src/game/client/hud.cpp b/src/game/client/hud.cpp index 76b154a0..2db370bc 100644 --- a/src/game/client/hud.cpp +++ b/src/game/client/hud.cpp @@ -511,9 +511,24 @@ void CHud::SaveEngineVersion() { cvar_t *sv_version = sv_version = gEngfuncs.pfnGetCvarPointer("sv_version"); if (sv_version) + { Q_strncpy(m_szEngineVersion, sv_version->string, sizeof(m_szEngineVersion)); + + // Parse build number + std::string_view version = m_szEngineVersion; + size_t lastComma = version.rfind(','); + + if (lastComma != std::string::npos) + { + const char *buildStr = m_szEngineVersion + lastComma + 1; + m_iEngineBuildNumber = atoi(buildStr); + } + } else + { Q_strncpy(m_szEngineVersion, "< sv_version not found >", sizeof(m_szEngineVersion)); + m_iEngineBuildNumber = -1; + } } bool CHud::IsAG() diff --git a/src/game/client/hud.h b/src/game/client/hud.h index 51c8d492..6f4ac0a1 100644 --- a/src/game/client/hud.h +++ b/src/game/client/hud.h @@ -202,7 +202,6 @@ class CHud ColorCodeAction GetColorCodeAction(); Color GetColorCodeColor(int code); - const char *GetEngineVersion(); /** * Returns a color for client. @@ -221,6 +220,12 @@ class CHud */ inline int GetFrameCount() { return m_iFrameCount; } + //! @returns The engine version string (value of sv_version cvar). + const char *GetEngineVersion(); + + //! @returns The engine build number. + int GetEngineBuild() const { return m_iEngineBuildNumber; } + private: struct SpriteName { @@ -237,6 +242,7 @@ class CHud std::vector m_HudList; std::unordered_map m_CharWidths; char m_szEngineVersion[128]; + int m_iEngineBuildNumber = 0; // the memory for these arrays are allocated in the first call // to CHud::VidInit(), when the hud.txt and associated sprites are loaded. diff --git a/src/game/client/hud/chat.cpp b/src/game/client/hud/chat.cpp index c8fbbdb2..aaeb14aa 100644 --- a/src/game/client/hud/chat.cpp +++ b/src/game/client/hud/chat.cpp @@ -346,7 +346,7 @@ CHudChat::CHudChat() SetScheme(scheme); SetPaintBackgroundEnabled(true); - g_pVGuiLocalize->AddFile(g_pFullFileSystem, VGUI2_ROOT_DIR "resource/language/chat_%language%.txt"); + g_pVGuiLocalize->AddFile(g_pEngineFileSystem, VGUI2_ROOT_DIR "resource/language/chat_%language%.txt"); m_nMessageMode = 0;