From 6c5580a5ce9ec169edcc1fc09852277f18096ee4 Mon Sep 17 00:00:00 2001 From: ScriptedSnark <51358194+ScriptedSnark@users.noreply.github.com> Date: Thu, 1 Aug 2024 23:12:49 +0500 Subject: [PATCH] Host-side RTA timer, IL mode, Nihilanth/changelevel autostop, etc. --- licenses/BXT_LICENSE | 22 ++ src/CMakeLists.txt | 15 + src/CTimer.h | 139 +++++++++ src/SvenBXT.cpp | 146 +++++++++- src/SvenBXT.h | 52 ++++ src/Utils.cpp | 13 + src/Utils.h | 2 + src/cl_dll/cdll_int.cpp | 1 + src/cl_dll/hud.cpp | 199 ++++++++++++- src/cl_dll/hud.h | 13 +- src/cl_dll/hud_timer.cpp | 164 +++++++++++ src/cl_dll/hud_timer.h | 47 +++ src/cl_dll/parsemsg.cpp | 258 +++++++++++++++++ src/cl_dll/parsemsg.h | 63 ++++ src/dlls/enginecallback.h | 152 ++++++++++ src/dlls/server.cpp | 76 +++++ src/dlls/server.h | 31 ++ src/engine/server.h | 591 ++++++++++++++++++++++++++++++++++++++ src/engine/sound.h | 191 ++++++++++++ src/engine_patterns.hpp | 31 ++ 20 files changed, 2201 insertions(+), 5 deletions(-) create mode 100644 licenses/BXT_LICENSE create mode 100644 src/CTimer.h create mode 100644 src/cl_dll/hud_timer.cpp create mode 100644 src/cl_dll/hud_timer.h create mode 100644 src/cl_dll/parsemsg.cpp create mode 100644 src/cl_dll/parsemsg.h create mode 100644 src/dlls/enginecallback.h create mode 100644 src/dlls/server.cpp create mode 100644 src/dlls/server.h create mode 100644 src/engine/server.h create mode 100644 src/engine/sound.h diff --git a/licenses/BXT_LICENSE b/licenses/BXT_LICENSE new file mode 100644 index 0000000..c60f327 --- /dev/null +++ b/licenses/BXT_LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014-2020 Ivan Molodetskikh +Copyright (c) 2015-2018 Chong Jiang Wei + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cd3a0fe..670ca9a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,10 +29,16 @@ add_library(SvenBXT SHARED cl_dll/hud_origin.h cl_dll/hud_speedometer.cpp cl_dll/hud_speedometer.h + cl_dll/hud_timer.cpp + cl_dll/hud_timer.h cl_dll/hud_viewangles.cpp cl_dll/hud_viewangles.h + cl_dll/parsemsg.cpp + cl_dll/parsemsg.h cl_dll/view.cpp cl_dll/view.h + dlls/server.cpp + dlls/server.h SvenBXT.cpp SvenBXT.h Utils.cpp @@ -69,6 +75,15 @@ elseif( COMPILER_MSVC ) ) endif() +if (COMPILER_GNU) +set_target_properties(SvenBXT PROPERTIES + C_VISIBILITY_PRESET hidden + CXX_VISIBILITY_PRESET hidden + COMPILE_FLAGS "${COMPILE_FLAGS} -fvisibility=hidden" + LINKER_FLAGS "${LINKER_FLAGS} -fvisibility=hidden" +) +endif() + target_compile_definitions( SvenBXT PUBLIC ${COMMON_DEFINES} ) diff --git a/src/CTimer.h b/src/CTimer.h new file mode 100644 index 0000000..7fa813e --- /dev/null +++ b/src/CTimer.h @@ -0,0 +1,139 @@ +#ifdef CTIMER_H_RECURSE_GUARD +#error Recursive header files inclusion detected in CTimer.h +#else //CTIMER_H_RECURSE_GUARD + +#define CTIMER_H_RECURSE_GUARD + +#ifndef CTIMER_H_GUARD +#define CTIMER_H_GUARD +#pragma once + +#ifdef __cplusplus + +class CTimer +{ +public: + CTimer() + { + Init(); + } + + void Init() + { + ResetTimer(); + } + + void StartTimer() + { + m_bStarted = true; + if (!m_bRunning) + { + m_startTime = std::chrono::steady_clock::now(); + m_bRunning = true; + } + } + + void StopTimer() + { + if (m_bRunning) + { + auto now = std::chrono::steady_clock::now(); + m_elapsedTime += std::chrono::duration_cast(now - m_startTime).count(); + m_bRunning = false; + } + } + + void ResetTimer() + { + m_bRunning = false; + m_elapsedTime = 0; + } + + void SetTime(long long time) + { + m_elapsedTime = time; + } + + + void SyncTimer(long long serverTime, bool stop) + { + if (stop) + { + StopTimer(); + SetTime(serverTime); + } + else + { + if (m_bRunning) + { + auto now = std::chrono::steady_clock::now(); + long long currentElapsedTime = std::chrono::duration_cast(now - m_startTime).count() + m_elapsedTime; + long long adjustment = serverTime - currentElapsedTime; + m_startTime += std::chrono::milliseconds(adjustment); + } + else + { + SetTime(serverTime); + StartTimer(); + } + } + } + + long long GetTime() const + { + if (m_bRunning) + { + auto now = std::chrono::steady_clock::now(); + return m_elapsedTime + std::chrono::duration_cast(now - m_startTime).count(); + } + return m_elapsedTime; + } + + int GetMilliseconds() const + { + return static_cast(fmod(GetTime(), 1000.0)); + } + + int GetSeconds() const + { + double seconds = GetTime() / 1000.0; + return static_cast(fmod(seconds, 60.0)); + } + + int GetMinutes() const + { + double minutes = GetTime() / 60000.0; + return static_cast(fmod(minutes, 60.0)); + } + + int GetHours() const + { + double hours = GetTime() / 3600000.0; + return static_cast(fmod(hours, 24.0)); + } + + int GetDays() const + { + double days = GetTime() / 86400000.0; + return static_cast(days); + } + + bool IsStopped() const + { + return m_bRunning ? false : true; + } + +private: + std::chrono::time_point m_startTime; + long long m_elapsedTime; // elapsed time in milliseconds + bool m_bRunning, m_bStarted; +}; + +#else //!__cplusplus +#error C++ compiler required to compile CTimer.h +#endif //__cplusplus + +#endif //CTIMER_H_GUARD + +#undef CTIMER_H_RECURSE_GUARD +#endif //CTIMER_H_RECURSE_GUARD \ No newline at end of file diff --git a/src/SvenBXT.cpp b/src/SvenBXT.cpp index 51e9dea..8b098c8 100644 --- a/src/SvenBXT.cpp +++ b/src/SvenBXT.cpp @@ -6,36 +6,93 @@ #ifdef PLATFORM_WINDOWS Utils utils = Utils::Utils(NULL, NULL, NULL); +Utils sv_utils = Utils::Utils(NULL, NULL, NULL); #endif +funchook_t* g_lpFuncHook_Server; +funchook_t* g_lpFuncHook_Engine; funchook_t* g_lpFuncHook_Client; dllhandle_t g_lpEngine; +dllhandle_t g_lpServer; dllhandle_t g_lpClient; cl_enginefunc_t* g_lpEngfuncs; +enginefuncs_t* g_engfuncs; +globalvars_t* gpGlobals; +server_t* sv; bool g_bHasLoaded = false; void SvenBXT_HookClient(); +// TODO: move to separate file +typedef void (*_SCR_BeginLoadingPlaque)(qboolean reconnect); +typedef void (*_SCR_EndLoadingPlaque)(); +_SCR_BeginLoadingPlaque ORIG_SCR_BeginLoadingPlaque = NULL; +_SCR_EndLoadingPlaque ORIG_SCR_EndLoadingPlaque = NULL; + +void HOOKED_SCR_BeginLoadingPlaque(qboolean reconnect) +{ + ORIG_SCR_BeginLoadingPlaque(reconnect); + + if (g_lpHUDTimer->IsInILMode()) + g_lpHUDTimer->TimerStop(); +} + +void HOOKED_SCR_EndLoadingPlaque() +{ + ORIG_SCR_EndLoadingPlaque(); + + if (g_lpHUDTimer->IsInILMode() && g_RTATimer.GetMilliseconds() <= 0) + g_lpHUDTimer->TimerStart(); +} + void SvenBXT_FindEngineStuff() { TRACE("Finding engine stuff...\n"); + g_lpFuncHook_Engine = funchook_create(); + + int status; #ifdef PLATFORM_LINUX g_lpEngfuncs = (cl_enginefunc_t*)Sys_GetProcAddress(g_lpEngine, "cl_enginefuncs"); if (!g_lpEngfuncs) { - Sys_Printf("[hw dll] Failed to get \"cl_enginefuncs\".\n"); + Sys_Printf("[hw so] Failed to get \"cl_enginefuncs\".\n"); return; } else { - Sys_Printf("[hw dll] Found cl_enginefuncs at %p.\n", g_lpEngfuncs); + Sys_Printf("[hw so] Found cl_enginefuncs at %p.\n", g_lpEngfuncs); SvenBXT_HookClient(); } + + // TODO: use GET_VARIABLE define + enginefuncs_t** p_engfuncs = (enginefuncs_t**)Sys_GetProcAddress(g_lpEngine, "g_pengfuncsExportedToDlls"); + g_engfuncs = (*p_engfuncs); + gpGlobals = (globalvars_t*)Sys_GetProcAddress(g_lpEngine, "gGlobalVariables"); + sv = (server_t*)Sys_GetProcAddress(g_lpEngine, "sv"); + + if (!gpGlobals) + { + Sys_Printf("[hw so] Failed to get \"gGlobalVariables\".\n"); + } + + if (!g_engfuncs) + { + Sys_Printf("[hw so] Failed to get \"g_engfuncsExportedToDlls\".\n[hw dll] Sharing time to clients is not available.\n"); + } + + if (!sv) + { + Sys_Printf("[hw so] Failed to get \"sv\".\n"); + } + + GET_VARIABLE(Engine, ORIG_LoadThisDll, _Z11LoadThisDllPc); + GET_VARIABLE(Engine, ORIG_SCR_BeginLoadingPlaque, _Z22SCR_BeginLoadingPlaquei); + GET_VARIABLE(Engine, ORIG_SCR_EndLoadingPlaque, _Z20SCR_EndLoadingPlaquev); #else void* handle; static void* base; @@ -70,7 +127,86 @@ void SvenBXT_FindEngineStuff() break; } }); + + void* LoadThisDll; + auto fLoadThisDll = utils.FindAsync( + LoadThisDll, + patterns::engine::LoadThisDll, + [&](auto pattern) + { + switch (pattern - patterns::engine::LoadThisDll.cbegin()) + { + default: + case 0: // Sven-5.25 + Sys_Printf("Searching g_engfuncs in Sven-5.25 pattern...\n"); + enginefuncs_t** p_engfuncs = *reinterpret_cast(reinterpret_cast(LoadThisDll) + 109); + g_engfuncs = (*p_engfuncs); + gpGlobals = *reinterpret_cast(reinterpret_cast(LoadThisDll) + 67); + + if (g_engfuncs) + Sys_Printf("[hw dll] Found g_engfuncs at 0x%p.\n", g_engfuncs); + + if (gpGlobals) + Sys_Printf("[hw dll] Found gpGlobals at 0x%p.\n", gpGlobals); + break; + } + }); + + void* Host_ClearMemory; + auto fHost_ClearMemory = utils.FindAsync( + Host_ClearMemory, + patterns::engine::Host_ClearMemory, + [&](auto pattern) + { + switch (pattern - patterns::engine::Host_ClearMemory.cbegin()) + { + default: + case 0: // HL-9920 + Sys_Printf("Searching sv in HL-9920 pattern...\n"); + sv = *reinterpret_cast(reinterpret_cast(Host_ClearMemory) + 0xA4); + + if (sv) + { + Sys_Printf("[hw dll] Found sv at 0x%p.\n", sv); + } + break; + case 1: // HL-8684 + Sys_Printf("Searching sv in HL-8684 pattern...\n"); + sv = *reinterpret_cast(reinterpret_cast(Host_ClearMemory) + 0x5E); + if (sv) + { + Sys_Printf("[hw dll] Found sv at 0x%p.\n", sv); + } + break; + case 2: // HL-4554 + Sys_Printf("Searching sv in HL-4554 pattern...\n"); + sv = *reinterpret_cast(reinterpret_cast(Host_ClearMemory) + 0x5C); + if (sv) + { + Sys_Printf("[hw dll] Found sv at 0x%p.\n", sv); + } + break; + case 3: // Sven-5.25 + Sys_Printf("Searching sv in Sven-5.25 pattern...\n"); + sv = *reinterpret_cast(reinterpret_cast(Host_ClearMemory) + 0x98); + if (sv) + { + Sys_Printf("[hw dll] Found sv at 0x%p.\n", sv); + } + break; + } + }); + + SPTEngineFind(LoadThisDll); + SPTEngineFind(SCR_BeginLoadingPlaque); + SPTEngineFind(SCR_EndLoadingPlaque); #endif + + CreateHook(Engine, LoadThisDll); + CreateHook(Engine, SCR_BeginLoadingPlaque); + CreateHook(Engine, SCR_EndLoadingPlaque); + + funchook_install(g_lpFuncHook_Engine, 0); } void SvenBXT_HookClient() @@ -119,6 +255,11 @@ void SvenBXT_UnhookClient() void SvenBXT_UnhookEngine() { + if (g_lpFuncHook_Engine) + { + funchook_uninstall(g_lpFuncHook_Engine, 0); + funchook_destroy(g_lpFuncHook_Engine); + } } //----------------------------------------------------------------------------- @@ -137,7 +278,6 @@ void WaitUntilClientLoads() { SvenBXT_HookEngine(); g_bHasLoaded = true; - // SvenBXT_HookClient(); } else goto lbl_waitFor; diff --git a/src/SvenBXT.h b/src/SvenBXT.h index 6b5d9dc..4d26d51 100644 --- a/src/SvenBXT.h +++ b/src/SvenBXT.h @@ -43,27 +43,56 @@ #include "external/SPTLib/Utils.hpp" #include "engine_patterns.hpp" extern Utils utils; +extern Utils sv_utils; #endif #include #include "hlsdk_mini.hpp" +#include "engine/sound.h" +#include "engine/server.h" // OWN STUFF #include "Utils.h" +#include "CTimer.h" +extern funchook_t* g_lpFuncHook_Server; extern funchook_t* g_lpFuncHook_Client; extern dllhandle_t g_lpEngine; +extern dllhandle_t g_lpServer; extern dllhandle_t g_lpClient; extern cl_enginefunc_t* g_lpEngfuncs; +extern enginefuncs_t* g_engfuncs; +extern globalvars_t* gpGlobals; +extern server_t* sv; #include "cl_dll/cdll_int.h" #include "cl_dll/hud.h" +#include "cl_dll/parsemsg.h" #include "cl_dll/view.h" +#include "dlls/enginecallback.h" +#include "dlls/server.h" + // HUD #include "cl_dll/hud_speedometer.h" #include "cl_dll/hud_viewangles.h" #include "cl_dll/hud_origin.h" +#include "cl_dll/hud_timer.h" + +#ifdef PLATFORM_WINDOWS +#define FASTCALL __fastcall +#elif defined(PLATFORM_LINUX) +#define FASTCALL +#else +#error Unsupported platform +#endif + +#define GET_VARIABLE(tag, resultVar, procName) \ + resultVar = (decltype(resultVar))Sys_GetProcAddress(g_lp##tag, #procName); \ + if (!resultVar) \ + Sys_Printf("[" #tag "] Failed to get \"" #procName "\".\n"); \ + else \ + Sys_Printf("[" #tag "] Found " #procName " at %p.\n", resultVar) \ #define Find(lib, func_name) \ if ((ORIG_##func_name = reinterpret_cast<_##func_name>(Sys_GetProcAddress(g_lp##lib, "" #func_name "")))) \ @@ -71,6 +100,29 @@ extern cl_enginefunc_t* g_lpEngfuncs; else \ Sys_Printf("[" #lib "] Could not find " #func_name ".\n") + +#ifdef PLATFORM_WINDOWS +#define SPTEngineFind(future_name) \ + { \ + auto f##future_name = utils.FindAsync(ORIG_##future_name, patterns::engine::future_name); \ + auto pattern = f##future_name.get(); \ + if (ORIG_##future_name) \ + { \ + Sys_Printf("[hw dll] Found " #future_name " at %p (using the %s pattern).\n", ORIG_##future_name, pattern->name()); \ + } \ + } + +#define SPTServerFind(future_name) \ + { \ + auto f##future_name = sv_utils.FindAsync(ORIG_##future_name, patterns::server::future_name); \ + auto pattern = f##future_name.get(); \ + if (ORIG_##future_name) \ + { \ + Sys_Printf("[Server] Found " #future_name " at %p (using the %s pattern).\n", ORIG_##future_name, pattern->name()); \ + } \ + } +#endif + #define CreateHook(lib, func_name) \ do \ { \ diff --git a/src/Utils.cpp b/src/Utils.cpp index 66373ad..c6912cd 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -4,6 +4,19 @@ #include "SvenBXT.h" +/* +================ +UTIL_IsHost +================ +*/ +bool UTIL_IsHost() +{ + if (!sv) + return false; + + return sv->active; +} + /* ================ Sys_Printf diff --git a/src/Utils.h b/src/Utils.h index 448f481..df903d5 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -22,6 +22,8 @@ using farproc_t = void*; #define TRACE(format, ...) Sys_Printf("%s::%s(%d): " format, __FILE__, __FUNCTION__, __LINE__) +bool UTIL_IsHost(); + void Sys_Printf(const char* fmt, ...); dllhandle_t Sys_GetModuleHandle(const char* pszModuleName); farproc_t Sys_GetProcAddress(dllhandle_t handle, const char* name); diff --git a/src/cl_dll/cdll_int.cpp b/src/cl_dll/cdll_int.cpp index 485198c..b58fd72 100644 --- a/src/cl_dll/cdll_int.cpp +++ b/src/cl_dll/cdll_int.cpp @@ -67,6 +67,7 @@ int HOOKED_HUD_VidInit(void) { TRACE("Initializing visuals...\n"); gBXTHud.VidInit(); + return ORIG_HUD_VidInit(); } diff --git a/src/cl_dll/hud.cpp b/src/cl_dll/hud.cpp index ed87ddf..dfdd67b 100644 --- a/src/cl_dll/hud.cpp +++ b/src/cl_dll/hud.cpp @@ -7,7 +7,7 @@ CBXTHud gBXTHud; // some code is from HL SDK, OpenAG, BunnymodXT -static constexpr int ten_powers[] = { +constexpr int ten_powers[] = { 1, 10, 100, @@ -65,6 +65,7 @@ void CBXTHud::Init(void) RegisterHUDElement(); RegisterHUDElement(); RegisterHUDElement(); + RegisterHUDElement(); for (CBXTHudBase* i : m_vecHudList) { @@ -289,4 +290,200 @@ int CBXTHud::DrawMultilineString(int x, int y, std::string s) }; return max_new_x; +} + +int CBXTHud::DrawBitmap(int x, int y, const int bitmap[], int width, int height, int r, int g, int b) +{ + for (int i = 0; i < height; i++) + for (int j = 0; j < width; j++) + FillRGBA(x + j, y + i, 1, 1, r, g, b, bitmap[i * width + j]); + + return width; +} + +void CBXTHud::DrawDot(int x, int y, int r, int g, int b) +{ + const int Dot320[] = { + 143, 199, 122, + 255, 255, 218, + 120, 169, 95}; + + const int Dot640[] = { + 21, 114, 128, 128, 83, 21, + 150, 255, 255, 255, 255, 104, + 239, 255, 255, 255, 255, 192, + 226, 255, 255, 255, 255, 165, + 114, 255, 255, 255, 255, 65, + 29, 43, 89, 89, 29, 29}; + + if (ScreenWidth < 640) + DrawBitmap(x, y, Dot320, 3, 3, r, g, b); + else + DrawBitmap(x, y, Dot640, 6, 6, r, g, b); +} + +void CBXTHud::DrawLine(int x, int y, int length, int r, int g, int b) +{ + if ((ScreenWidth < 640 && length < 3) || length < 5) + { + // might as well draw a dot + DrawDot(x, y, r, g, b); + return; + } + + + const int Line640_left[] = { + 21, 114, + 150, 255, + 239, 255, + 226, 255, + 114, 255, + 29, 43}; + + const int Line640_repeat[] = { + 128, + 255, + 255, + 255, + 255, + 89}; + + const int Line640_Right[] = { + 83, 21, + 255, 104, + 255, 192, + 255, 165, + 255, 65, + 29, 29}; + + const int Line320_left[] = { + 143, + 255, + 120, + }; + + const int Line320_repeat[] = { + 199, + 255, + 169, + }; + + const int Line320_Right[] = { + 122, + 218, + 95}; + + const int* line_left; + const int* line_repeat; + const int* line_right; + int linesprite_height; + int linesprite_width; + + if (ScreenWidth <= 640) + { + line_left = Line320_left; + line_repeat = Line320_repeat; + line_right = Line320_Right; + linesprite_height = 3; + linesprite_width = 1; + } + else + { + line_left = Line640_left; + line_repeat = Line640_repeat; + line_right = Line640_Right; + linesprite_height = 6; + linesprite_width = 2; + } + + y -= linesprite_height / 2; + + x += DrawBitmap(x, y, line_left, linesprite_width, linesprite_height, r, g, b); + + for (int xOffset = 0; xOffset < length - linesprite_width * 2; xOffset++) + { + x += DrawBitmap(x, y, line_repeat, 1, linesprite_height, r, g, b); + } + + DrawBitmap(x, y, line_right, linesprite_width, linesprite_height, r, g, b); +} + +int CBXTHud::DrawNumberXT(int number, int x, int y, int r, int g, int b, int fieldMinWidth) +{ + if (number < 0) + { + if (number == std::numeric_limits::min()) + { + number = 0; + } + else + { + number = abs(number); + DrawLine(x - NumberWidth, y + NumberHeight / 2, NumberWidth, r, g, b); + } + } + + static_assert(sizeof(int) >= 4, "Int less than 4 bytes in size is not supported."); + + int digits[10] = {0}; + int i; + for (i = 0; i < 10; ++i) + { + if (number == 0) + break; + + digits[i] = number % 10; + number /= 10; + } + + for (; fieldMinWidth > 10; --fieldMinWidth) + { + DrawHudNumber(x, y, 0, r, g, b); + x += NumberWidth; + } + if (fieldMinWidth > i) + i = fieldMinWidth; + + for (int j = i; j > 0; --j) + { + DrawHudNumber(x, y, digits[j - 1], r, g, b); + x += NumberWidth; + } + + return x; +} + +int CBXTHud::DrawNumberTimer(int number, int x, int y, int fieldMinWidth) +{ + return DrawNumberXT(number, x, y, SVEN_HUD_COLOR, fieldMinWidth); +} + +int CBXTHud::DrawNumberTimer(int number, int x, int y, int r, int g, int b, int fieldMinWidth) +{ + return DrawNumberXT(number, x, y, r, g, b, fieldMinWidth); +} + +void CBXTHud::DrawDecimalSeparator(int x, int y, int r, int g, int b) +{ + x += (NumberWidth - 6) / 2; + y += NumberHeight - 5; + DrawDot(x + 1, y, r, g, b); +} + +void CBXTHud::DrawDecimalSeparator(int x, int y) +{ + return DrawDecimalSeparator(x, y, SVEN_HUD_COLOR); +} + +void CBXTHud::DrawColon(int x, int y, int r, int g, int b) +{ + x += (NumberWidth - 6) / 2; + DrawDot(x + 1, y + 2, r, g, b); + y += NumberHeight - 5; + DrawDot(x + 1, y - 2, r, g, b); +} + +void CBXTHud::DrawColon(int x, int y) +{ + return DrawColon(x, y, SVEN_HUD_COLOR); } \ No newline at end of file diff --git a/src/cl_dll/hud.h b/src/cl_dll/hud.h index 5508ee7..a23e68f 100644 --- a/src/cl_dll/hud.h +++ b/src/cl_dll/hud.h @@ -28,6 +28,8 @@ // CharHeight returns the height of the char, in pixels #define CharHeight (gBXTHud.m_scrinfo.iCharHeight) +#define NumberWidth (gBXTHud.GetSpriteRect(gBXTHud.m_HUD_number_0).right - gBXTHud.GetSpriteRect(gBXTHud.m_HUD_number_0).left) +#define NumberHeight (gBXTHud.GetSpriteRect(gBXTHud.m_HUD_number_0).bottom - gBXTHud.GetSpriteRect(gBXTHud.m_HUD_number_0).top) // //----------------------------------------------------- @@ -74,7 +76,16 @@ class CBXTHud int DrawHudNumberString(int xpos, int ypos, int iMinX, int iNumber, int r, int g, int b); int DrawHudNumberStringFixed(int xpos, int ypos, int iNumber, int r, int g, int b); int DrawMultilineString(int x, int y, std::string s); - + int DrawNumberTimer(int number, int x, int y, int fieldMinWidth); + int DrawBitmap(int x, int y, const int bitmap[], int width, int height, int r, int g, int b); + void DrawDot(int x, int y, int r, int g, int b); + void DrawLine(int x, int y, int length, int r, int g, int b); + int DrawNumberXT(int number, int x, int y, int r, int g, int b, int fieldMinWidth); + int DrawNumberTimer(int number, int x, int y, int r, int g, int b, int fieldMinWidth); + void DrawDecimalSeparator(int x, int y, int r, int g, int b); + void DrawDecimalSeparator(int x, int y); + void DrawColon(int x, int y, int r, int g, int b); + void DrawColon(int x, int y); HSPRITE_HL GetSprite(int index) { return (index < 0) ? 0 : m_rghSprites[index]; diff --git a/src/cl_dll/hud_timer.cpp b/src/cl_dll/hud_timer.cpp new file mode 100644 index 0000000..a177d9e --- /dev/null +++ b/src/cl_dll/hud_timer.cpp @@ -0,0 +1,164 @@ +#include "SvenBXT.h" + +CTimer g_RTATimer; +CTimer g_IGTTimer; + +CHudTimer* g_lpHUDTimer; + +void __CmdFunc_TimerStart() +{ + if (!g_lpHUDTimer) + return; + + if (g_lpHUDTimer->ShouldSync()) + return; + + g_lpHUDTimer->TimerStart(); +} + +void __CmdFunc_TimerStop() +{ + if (!g_lpHUDTimer) + return; + + if (g_lpHUDTimer->ShouldSync()) + return; + + g_lpHUDTimer->TimerStop(); +} + +void __CmdFunc_TimerReset() +{ + if (!g_lpHUDTimer) + return; + + if (g_lpHUDTimer->ShouldSync()) + return; + + g_lpHUDTimer->TimerStop(); + g_lpHUDTimer->TimerReset(); +} + +int __MsgFunc_BXTTimer(const char* pszName, int iSize, void* pbuf) +{ + BEGIN_READ(pbuf, iSize); + + if (!g_lpHUDTimer->ShouldSync()) + return 0; + + long time = READ_LONG(); + bool stop = READ_BYTE(); + + g_RTATimer.SyncTimer(time, stop); + + return 0; +} + +int CHudTimer::Init() +{ + g_lpHUDTimer = this; + m_iFlags = HUD_ACTIVE; + + hud_timer_serversync = CVAR_CREATE("sbxt_timer_serversync", "1", 0); + hud_timer_il_mode = CVAR_CREATE("sbxt_timer_il_mode", "0", 0); + hud_timer = CVAR_CREATE("sbxt_hud_timer", "0", 0); + hud_timer_anchor = CVAR_CREATE("sbxt_hud_timer_anchor", "0.0 0.5", 0); + hud_timer_offset = CVAR_CREATE("sbxt_hud_timer_offset", "", 0); + + HOOK_COMMAND("sbxt_timer_start", TimerStart); + HOOK_COMMAND("sbxt_timer_stop", TimerStop); + HOOK_COMMAND("sbxt_timer_reset", TimerReset); + + HOOK_MESSAGE(BXTTimer); + + return 0; +} + +int CHudTimer::VidInit() +{ + return 1; +} + +int CHudTimer::Draw(float time) +{ + if (!hud_timer->value) + return 0; + + int x, y; + gBXTHud.GetPosition(hud_timer_offset, hud_timer_anchor, &x, &y, 0, 0); + + int hours = g_RTATimer.GetHours(); + int minutes = g_RTATimer.GetMinutes(); + int seconds = g_RTATimer.GetSeconds(); + int milliseconds = g_RTATimer.GetMilliseconds(); + + if (hud_timer->value == 1) + { + char rta_timer[64]; + sprintf(rta_timer, "RTA | %d:%02d:%02d.%03d", hours, minutes, seconds, milliseconds); + g_lpEngfuncs->VGUI2_DrawLocalizedHudString(x, y, rta_timer, SVEN_HUD_COLOR); + } + else if (hud_timer->value >= 2) + { + if (hours) + { + x = gBXTHud.DrawNumberTimer(hours, x, y, 1); + gBXTHud.DrawColon(x, y); + x += NumberWidth; + } + + if (hours || minutes) + { + int fieldMinWidth = (hours && minutes < 10) ? 2 : 1; + x = gBXTHud.DrawNumberTimer(minutes, x, y, fieldMinWidth); + gBXTHud.DrawColon(x, y); + x += NumberWidth; + } + + int fieldMinWidth = ((hours || minutes) && seconds < 10) ? 2 : 1; + x = gBXTHud.DrawNumberTimer(seconds, x, y, fieldMinWidth); + + gBXTHud.DrawDecimalSeparator(x, y); + x += NumberWidth; + + gBXTHud.DrawNumberTimer(milliseconds, x, y, 3); + } + + //sprintf_s(igt_timer, "IGT | %d:%02d:%02d.%03d", g_IGTTimer.GetHours(), g_IGTTimer.GetMinutes(), g_IGTTimer.GetSeconds(), g_IGTTimer.GetMilliseconds()); + //g_lpEngfuncs->VGUI2_DrawLocalizedHudString(x, y + CharHeight, rta_timer, SVEN_HUD_COLOR); + + return 0; +} + +void CHudTimer::TimerStart() +{ + g_RTATimer.StartTimer(); + //g_IGTTimer.StartTimer(); + + if (UTIL_IsHost()) + { + SV_SyncTimer(); + } +} + +void CHudTimer::TimerStop() +{ + g_RTATimer.StopTimer(); + //g_IGTTimer.StopTimer(); + + if (UTIL_IsHost()) + { + SV_SyncTimer(); + } +} + +void CHudTimer::TimerReset() +{ + g_RTATimer.ResetTimer(); + //g_IGTTimer.ResetTimer(); + + if (UTIL_IsHost()) + { + SV_SyncTimer(); + } +} \ No newline at end of file diff --git a/src/cl_dll/hud_timer.h b/src/cl_dll/hud_timer.h new file mode 100644 index 0000000..88f1ffd --- /dev/null +++ b/src/cl_dll/hud_timer.h @@ -0,0 +1,47 @@ +#ifdef HUD_TIMER_H_RECURSE_GUARD +#error Recursive header files inclusion detected in hud_timer.h +#else //HUD_TIMER_H_RECURSE_GUARD + +#define HUD_TIMER_H_RECURSE_GUARD + +#ifndef HUD_TIMER_H_GUARD +#define HUD_TIMER_H_GUARD +#pragma once + +#ifdef __cplusplus + +extern CTimer g_RTATimer; +extern CTimer g_IGTTimer; + +class CHudTimer: public CBXTHudBase +{ +public: + virtual int Init(); + virtual int VidInit(); + virtual int Draw(float time); + + void TimerStart(); + void TimerStop(); + void TimerReset(); + + bool ShouldSync() { return (hud_timer_serversync->value && !UTIL_IsHost()); } + bool IsInILMode() { return hud_timer_il_mode->value; }; + +private: + cvar_t* hud_timer_serversync; + cvar_t* hud_timer_il_mode; + cvar_t* hud_timer; + cvar_t* hud_timer_anchor; + cvar_t* hud_timer_offset; +}; + +extern CHudTimer* g_lpHUDTimer; + +#else //!__cplusplus +#error C++ compiler required to compile hud_timer.h +#endif //__cplusplus + +#endif //HUD_TIMER_H_GUARD + +#undef HUD_TIMER_H_RECURSE_GUARD +#endif //HUD_TIMER_H_RECURSE_GUARD \ No newline at end of file diff --git a/src/cl_dll/parsemsg.cpp b/src/cl_dll/parsemsg.cpp new file mode 100644 index 0000000..1f3ed74 --- /dev/null +++ b/src/cl_dll/parsemsg.cpp @@ -0,0 +1,258 @@ +/*** +* +* Copyright (c) 1999, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// +// parsemsg.cpp +// +//-------------------------------------------------------------------------------------------------------------- +#include "SvenBXT.h" + +typedef unsigned char byte; +#define true 1 + +static byte* gpBuf; +static int giSize; +static int giRead; +static int giBadRead; + +int READ_OK(void) +{ + return !giBadRead; +} + +void BEGIN_READ(void* buf, int size) +{ + giRead = 0; + giBadRead = 0; + giSize = size; + gpBuf = (byte*)buf; +} + + +int READ_CHAR(void) +{ + int c; + + if (giRead + 1 > giSize) + { + giBadRead = true; + return -1; + } + + c = (signed char)gpBuf[giRead]; + giRead++; + + return c; +} + +int READ_BYTE(void) +{ + int c; + + if (giRead + 1 > giSize) + { + giBadRead = true; + return -1; + } + + c = (unsigned char)gpBuf[giRead]; + giRead++; + + return c; +} + +int READ_SHORT(void) +{ + int c; + + if (giRead + 2 > giSize) + { + giBadRead = true; + return -1; + } + + c = (short)(gpBuf[giRead] + (gpBuf[giRead + 1] << 8)); + + giRead += 2; + + return c; +} + +int READ_WORD(void) +{ + return READ_SHORT(); +} + + +int READ_LONG(void) +{ + int c; + + if (giRead + 4 > giSize) + { + giBadRead = true; + return -1; + } + + c = gpBuf[giRead] + (gpBuf[giRead + 1] << 8) + (gpBuf[giRead + 2] << 16) + (gpBuf[giRead + 3] << 24); + + giRead += 4; + + return c; +} + +float READ_FLOAT(void) +{ + union + { + byte b[4]; + float f; + int l; + } dat; + + dat.b[0] = gpBuf[giRead]; + dat.b[1] = gpBuf[giRead + 1]; + dat.b[2] = gpBuf[giRead + 2]; + dat.b[3] = gpBuf[giRead + 3]; + giRead += 4; + + // dat.l = LittleLong (dat.l); + + return dat.f; +} + +char* READ_STRING(void) +{ + static char string[2048]; + int l, c; + + string[0] = 0; + + l = 0; + do + { + if (giRead + 1 > giSize) + break; // no more characters + + c = READ_CHAR(); + if (c == -1 || c == 0) + break; + string[l] = c; + l++; + } while (l < sizeof(string) - 1); + + string[l] = 0; + + return string; +} + +float READ_COORD(void) +{ + return (float)(READ_SHORT() * (1.0 / 8)); +} + +float READ_ANGLE(void) +{ + return (float)(READ_CHAR() * (360.0 / 256)); +} + +float READ_HIRESANGLE(void) +{ + return (float)(READ_SHORT() * (360.0 / 65536)); +} + +//-------------------------------------------------------------------------------------------------------------- +BufferWriter::BufferWriter() +{ + Init(NULL, 0); +} + +//-------------------------------------------------------------------------------------------------------------- +BufferWriter::BufferWriter(unsigned char* buffer, int bufferLen) +{ + Init(buffer, bufferLen); +} + +//-------------------------------------------------------------------------------------------------------------- +void BufferWriter::Init(unsigned char* buffer, int bufferLen) +{ + m_overflow = false; + m_buffer = buffer; + m_remaining = bufferLen; + m_overallLength = bufferLen; +} + +//-------------------------------------------------------------------------------------------------------------- +void BufferWriter::WriteByte(unsigned char data) +{ + if (!m_buffer || !m_remaining) + { + m_overflow = true; + return; + } + + *m_buffer = data; + ++m_buffer; + --m_remaining; +} + +//-------------------------------------------------------------------------------------------------------------- +void BufferWriter::WriteLong(int data) +{ + if (!m_buffer || m_remaining < 4) + { + m_overflow = true; + return; + } + + m_buffer[0] = data & 0xff; + m_buffer[1] = (data >> 8) & 0xff; + m_buffer[2] = (data >> 16) & 0xff; + m_buffer[3] = data >> 24; + m_buffer += 4; + m_remaining -= 4; +} + +//-------------------------------------------------------------------------------------------------------------- +void BufferWriter::WriteString(const char* str) +{ + if (!m_buffer || !m_remaining) + { + m_overflow = true; + return; + } + + if (!str) + str = ""; + + int len = strlen(str) + 1; + if (len > m_remaining) + { + m_overflow = true; + str = ""; + len = 1; + } + + strcpy((char*)m_buffer, str); + m_remaining -= len; + m_buffer += len; +} + +//-------------------------------------------------------------------------------------------------------------- +int BufferWriter::GetSpaceUsed() +{ + return m_overallLength - m_remaining; +} + +//-------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/cl_dll/parsemsg.h b/src/cl_dll/parsemsg.h new file mode 100644 index 0000000..fcff839 --- /dev/null +++ b/src/cl_dll/parsemsg.h @@ -0,0 +1,63 @@ +/*** +* +* Copyright (c) 1999, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// +// parsemsg.h +// MDC - copying from cstrike\cl_dll so career-mode stuff can catch messages +// in this dll. (and C++ifying it) +// + +#ifndef PARSEMSG_H +#define PARSEMSG_H + +#define ASSERT( x ) +//-------------------------------------------------------------------------------------------------------------- +void BEGIN_READ(void* buf, int size); +int READ_CHAR(void); +int READ_BYTE(void); +int READ_SHORT(void); +int READ_WORD(void); +int READ_LONG(void); +float READ_FLOAT(void); +char* READ_STRING(void); +float READ_COORD(void); +float READ_ANGLE(void); +float READ_HIRESANGLE(void); +int READ_OK(void); + +//-------------------------------------------------------------------------------------------------------------- +class BufferWriter +{ +public: + BufferWriter(); + BufferWriter(unsigned char* buffer, int bufferLen); + void Init(unsigned char* buffer, int bufferLen); + + void WriteByte(unsigned char data); + void WriteLong(int data); + void WriteString(const char* str); + + bool HasOverflowed(); + int GetSpaceUsed(); + +protected: + unsigned char* m_buffer; + int m_remaining; + bool m_overflow; + int m_overallLength; +}; + +//-------------------------------------------------------------------------------------------------------------- + +#endif // PARSEMSG_H \ No newline at end of file diff --git a/src/dlls/enginecallback.h b/src/dlls/enginecallback.h new file mode 100644 index 0000000..84833b4 --- /dev/null +++ b/src/dlls/enginecallback.h @@ -0,0 +1,152 @@ +/*** +* +* Copyright (c) 1996-2001, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef ENGINECALLBACK_H +#define ENGINECALLBACK_H +#pragma once + +// The actual engine callbacks +#define GETPLAYERUSERID (*g_engfuncs->pfnGetPlayerUserId) +#define PRECACHE_MODEL (*g_engfuncs->pfnPrecacheModel) +#define PRECACHE_SOUND (*g_engfuncs->pfnPrecacheSound) +#define PRECACHE_GENERIC (*g_engfuncs->pfnPrecacheGeneric) +#define SET_MODEL (*g_engfuncs->pfnSetModel) +#define MODEL_INDEX (*g_engfuncs->pfnModelIndex) +#define MODEL_FRAMES (*g_engfuncs->pfnModelFrames) +#define SET_SIZE (*g_engfuncs->pfnSetSize) +#define CHANGE_LEVEL (*g_engfuncs->pfnChangeLevel) +#define GET_SPAWN_PARMS (*g_engfuncs->pfnGetSpawnParms) +#define SAVE_SPAWN_PARMS (*g_engfuncs->pfnSaveSpawnParms) +#define VEC_TO_YAW (*g_engfuncs->pfnVecToYaw) +#define VEC_TO_ANGLES (*g_engfuncs->pfnVecToAngles) +#define MOVE_TO_ORIGIN (*g_engfuncs->pfnMoveToOrigin) +#define oldCHANGE_YAW (*g_engfuncs->pfnChangeYaw) +#define CHANGE_PITCH (*g_engfuncs->pfnChangePitch) +#define MAKE_VECTORS (*g_engfuncs->pfnMakeVectors) +#define CREATE_ENTITY (*g_engfuncs->pfnCreateEntity) +#define REMOVE_ENTITY (*g_engfuncs->pfnRemoveEntity) +#define CREATE_NAMED_ENTITY (*g_engfuncs->pfnCreateNamedEntity) +#define MAKE_STATIC (*g_engfuncs->pfnMakeStatic) +#define ENT_IS_ON_FLOOR (*g_engfuncs->pfnEntIsOnFloor) +#define DROP_TO_FLOOR (*g_engfuncs->pfnDropToFloor) +#define WALK_MOVE (*g_engfuncs->pfnWalkMove) +#define SET_ORIGIN (*g_engfuncs->pfnSetOrigin) +#define EMIT_SOUND_DYN2 (*g_engfuncs->pfnEmitSound) +#define BUILD_SOUND_MSG (*g_engfuncs->pfnBuildSoundMsg) +#define TRACE_LINE (*g_engfuncs->pfnTraceLine) +#define TRACE_TOSS (*g_engfuncs->pfnTraceToss) +#define TRACE_MONSTER_HULL (*g_engfuncs->pfnTraceMonsterHull) +#define TRACE_HULL (*g_engfuncs->pfnTraceHull) +#define GET_AIM_VECTOR (*g_engfuncs->pfnGetAimVector) +#define SERVER_COMMAND (*g_engfuncs->pfnServerCommand) +#define CLIENT_COMMAND (*g_engfuncs->pfnClientCommand) +#define PARTICLE_EFFECT (*g_engfuncs->pfnParticleEffect) +#define LIGHT_STYLE (*g_engfuncs->pfnLightStyle) +#define DECAL_INDEX (*g_engfuncs->pfnDecalIndex) +#define POINT_CONTENTS (*g_engfuncs->pfnPointContents) +#define CRC32_INIT (*g_engfuncs->pfnCRC32_Init) +#define CRC32_PROCESS_BUFFER (*g_engfuncs->pfnCRC32_ProcessBuffer) +#define CRC32_PROCESS_BYTE (*g_engfuncs->pfnCRC32_ProcessByte) +#define CRC32_FINAL (*g_engfuncs->pfnCRC32_Final) +#define RANDOM_LONG (*g_engfuncs->pfnRandomLong) +#define RANDOM_FLOAT (*g_engfuncs->pfnRandomFloat) +#define GETPLAYERAUTHID (*g_engfuncs->pfnGetPlayerAuthId) + +inline void MESSAGE_BEGIN(int msg_dest, int msg_type, const float* pOrigin = NULL, edict_t* ed = NULL) { + (*g_engfuncs->pfnMessageBegin)(msg_dest, msg_type, pOrigin, ed); +} +#define MESSAGE_END (*g_engfuncs->pfnMessageEnd) +#define WRITE_BYTE (*g_engfuncs->pfnWriteByte) +#define WRITE_CHAR (*g_engfuncs->pfnWriteChar) +#define WRITE_SHORT (*g_engfuncs->pfnWriteShort) +#define WRITE_LONG (*g_engfuncs->pfnWriteLong) +#define WRITE_ANGLE (*g_engfuncs->pfnWriteAngle) +#define WRITE_COORD (*g_engfuncs->pfnWriteCoord) +#define WRITE_STRING (*g_engfuncs->pfnWriteString) +#define WRITE_ENTITY (*g_engfuncs->pfnWriteEntity) +#define CVAR_REGISTER (*g_engfuncs->pfnCVarRegister) +#define CVAR_GET_FLOAT (*g_engfuncs->pfnCVarGetFloat) +#define CVAR_GET_STRING (*g_engfuncs->pfnCVarGetString) +#define CVAR_SET_FLOAT (*g_engfuncs->pfnCVarSetFloat) +#define CVAR_SET_STRING (*g_engfuncs->pfnCVarSetString) +#define CVAR_GET_POINTER (*g_engfuncs->pfnCVarGetPointer) +#define ALERT (*g_engfuncs->pfnAlertMessage) +#define ENGINE_FPRINTF (*g_engfuncs->pfnEngineFprintf) +#define ALLOC_PRIVATE (*g_engfuncs->pfnPvAllocEntPrivateData) +inline void* GET_PRIVATE(edict_t* pent) +{ + if (pent) + return pent->pvPrivateData; + return NULL; +} + +#define FREE_PRIVATE (*g_engfuncs->pfnFreeEntPrivateData) +//#define STRING (*g_engfuncs->pfnSzFromIndex) +#define ALLOC_STRING (*g_engfuncs->pfnAllocString) +#define FIND_ENTITY_BY_STRING (*g_engfuncs->pfnFindEntityByString) +#define GETENTITYILLUM (*g_engfuncs->pfnGetEntityIllum) +#define FIND_ENTITY_IN_SPHERE (*g_engfuncs->pfnFindEntityInSphere) +#define FIND_CLIENT_IN_PVS (*g_engfuncs->pfnFindClientInPVS) +#define EMIT_AMBIENT_SOUND (*g_engfuncs->pfnEmitAmbientSound) +#define GET_MODEL_PTR (*g_engfuncs->pfnGetModelPtr) +#define REG_USER_MSG (*g_engfuncs->pfnRegUserMsg) +#define GET_BONE_POSITION (*g_engfuncs->pfnGetBonePosition) +#define FUNCTION_FROM_NAME (*g_engfuncs->pfnFunctionFromName) +#define NAME_FOR_FUNCTION (*g_engfuncs->pfnNameForFunction) +#define TRACE_TEXTURE (*g_engfuncs->pfnTraceTexture) +#define CLIENT_PRINTF (*g_engfuncs->pfnClientPrintf) +#define CMD_ARGS (*g_engfuncs->pfnCmd_Args) +#define CMD_ARGC (*g_engfuncs->pfnCmd_Argc) +#define CMD_ARGV (*g_engfuncs->pfnCmd_Argv) +#define GET_ATTACHMENT (*g_engfuncs->pfnGetAttachment) +#define SET_VIEW (*g_engfuncs->pfnSetView) +#define SET_CROSSHAIRANGLE (*g_engfuncs->pfnCrosshairAngle) +#define LOAD_FILE_FOR_ME (*g_engfuncs->pfnLoadFileForMe) +#define FREE_FILE (*g_engfuncs->pfnFreeFile) +#define COMPARE_FILE_TIME (*g_engfuncs->pfnCompareFileTime) +#define GET_GAME_DIR (*g_engfuncs->pfnGetGameDir) +#define IS_MAP_VALID (*g_engfuncs->pfnIsMapValid) +#define NUMBER_OF_ENTITIES (*g_engfuncs->pfnNumberOfEntities) +#define IS_DEDICATED_SERVER (*g_engfuncs->pfnIsDedicatedServer) + +#define PRECACHE_EVENT (*g_engfuncs->pfnPrecacheEvent) +#define PLAYBACK_EVENT_FULL (*g_engfuncs->pfnPlaybackEvent) + +#define ENGINE_SET_PVS (*g_engfuncs->pfnSetFatPVS) +#define ENGINE_SET_PAS (*g_engfuncs->pfnSetFatPAS) + +#define ENGINE_CHECK_VISIBILITY (*g_engfuncs->pfnCheckVisibility) + +#define DELTA_SET ( *g_engfuncs->pfnDeltaSetField ) +#define DELTA_UNSET ( *g_engfuncs->pfnDeltaUnsetField ) +#define DELTA_ADDENCODER ( *g_engfuncs->pfnDeltaAddEncoder ) +#define ENGINE_CURRENT_PLAYER ( *g_engfuncs->pfnGetCurrentPlayer ) + +#define ENGINE_CANSKIP ( *g_engfuncs->pfnCanSkipPlayer ) + +#define DELTA_FINDFIELD ( *g_engfuncs->pfnDeltaFindField ) +#define DELTA_SETBYINDEX ( *g_engfuncs->pfnDeltaSetFieldByIndex ) +#define DELTA_UNSETBYINDEX ( *g_engfuncs->pfnDeltaUnsetFieldByIndex ) + +#define ENGINE_GETPHYSINFO ( *g_engfuncs->pfnGetPhysicsInfoString ) + +#define ENGINE_SETGROUPMASK ( *g_engfuncs->pfnSetGroupMask ) + +#define ENGINE_INSTANCE_BASELINE ( *g_engfuncs->pfnCreateInstancedBaseline ) + +#define ENGINE_FORCE_UNMODIFIED ( *g_engfuncs->pfnForceUnmodified ) + +#define PLAYER_CNX_STATS ( *g_engfuncs->pfnGetPlayerStats ) + +#endif //ENGINECALLBACK_H \ No newline at end of file diff --git a/src/dlls/server.cpp b/src/dlls/server.cpp new file mode 100644 index 0000000..0ac69bf --- /dev/null +++ b/src/dlls/server.cpp @@ -0,0 +1,76 @@ +#include "SvenBXT.h" + +typedef void (FASTCALL* _CNihilanth_DyingThink)(void* thisptr); + +_CNihilanth_DyingThink ORIG_CNihilanth_DyingThink = NULL; +_LoadThisDll ORIG_LoadThisDll = NULL; + +int gmsgBXTTimer = 0; + +void FASTCALL HOOKED_CNihilanth_DyingThink(void* thisptr) +{ + g_lpHUDTimer->TimerStop(); + + ORIG_CNihilanth_DyingThink(thisptr); +} + +void HOOKED_LoadThisDll(char* szDllFilename) +{ + ORIG_LoadThisDll(szDllFilename); + + g_lpServer = Sys_GetModuleHandle(szDllFilename); + + if (!g_lpServer) + { + Sys_Printf("[Server] Failed to get module handle. Path: \"%s\"\n", szDllFilename); + return; + } + + SV_HookStuff(); + SV_Initialize(); // may break some things but seems ok +} + +void SV_SyncTimer() +{ + MESSAGE_BEGIN(MSG_ALL, gmsgBXTTimer); + WRITE_LONG(g_RTATimer.GetTime()); + WRITE_BYTE(g_RTATimer.IsStopped()); + MESSAGE_END(); +} + +void SV_Initialize() +{ + if (!g_engfuncs) + return; + + gmsgBXTTimer = REG_USER_MSG("BXTTimer", -1); + g_engfuncs->pfnAddServerCommand("sbxt_sv_synctimer", SV_SyncTimer); +} + +void SV_HookStuff() +{ + g_lpFuncHook_Server = funchook_create(); + + int status; + +#ifdef PLATFORM_LINUX + GET_VARIABLE(Server, ORIG_CNihilanth_DyingThink, _ZN10CNihilanth10DyingThinkEv); +#else // PLATFORM_WINDOWS + static void* handle; + static void* base; + static size_t size; + + if (!MemUtils::GetModuleInfo(L"svencoop\\dlls\\server.dll", &handle, &base, &size)) // TODO: use szDllFilename + { + Sys_Printf("[Server] Failed to get module info from server.\n"); + return; + } + + sv_utils = Utils::Utils(handle, base, size); + + SPTServerFind(CNihilanth_DyingThink); +#endif + + CreateHook(Server, CNihilanth_DyingThink); + funchook_install(g_lpFuncHook_Server, 0); +} \ No newline at end of file diff --git a/src/dlls/server.h b/src/dlls/server.h new file mode 100644 index 0000000..63804c8 --- /dev/null +++ b/src/dlls/server.h @@ -0,0 +1,31 @@ +#ifdef SERVER_H_RECURSE_GUARD +#error Recursive header files inclusion detected in server.h +#else //SERVER_H_RECURSE_GUARD + +#define SERVER_H_RECURSE_GUARD + +#ifndef SERVER_H_GUARD +#define SERVER_H_GUARD +#pragma once + +#ifdef __cplusplus + +typedef void (*_LoadThisDll)(char* szDllFilename); +extern _LoadThisDll ORIG_LoadThisDll; + +extern int gmsgBXTTimer; + +void HOOKED_LoadThisDll(char* szDllFilename); + +void SV_SyncTimer(); +void SV_Initialize(); +void SV_HookStuff(); + +#else //!__cplusplus +#error C++ compiler required to compile server.h +#endif //__cplusplus + +#endif //SERVER_H_GUARD + +#undef SERVER_H_RECURSE_GUARD +#endif //SERVER_H_RECURSE_GUARD \ No newline at end of file diff --git a/src/engine/server.h b/src/engine/server.h new file mode 100644 index 0000000..cdb16d0 --- /dev/null +++ b/src/engine/server.h @@ -0,0 +1,591 @@ +#ifdef SVC_MESSAGES_H_RECURSE_GUARD +#error Recursive header files inclusion detected in svc_messages.h +#else //SVC_MESSAGES_H_RECURSE_GUARD + +#define SVC_MESSAGES_H_RECURSE_GUARD + +#ifndef SVC_MESSAGES_H_GUARD +#define SVC_MESSAGES_H_GUARD +#pragma once + +#ifdef __cplusplus + +#define SVC_BAD 0 +#define SVC_NOP 1 +#define SVC_DISCONNECT 2 +#define SVC_EVENT 3 +#define SVC_VERSION 4 +#define SVC_SETVIEW 5 +#define SVC_SOUND 6 +#define SVC_TIME 7 +#define SVC_PRINT 8 +#define SVC_STUFFTEXT 9 +#define SVC_SETANGLE 10 +#define SVC_SERVERINFO 11 +#define SVC_LIGHTSTYLE 12 +#define SVC_UPDATEUSERINFO 13 +#define SVC_DELTADESCRIPTION 14 +#define SVC_CLIENTDATA 15 +#define SVC_STOPSOUND 16 +#define SVC_PINGS 17 +#define SVC_PARTICLE 18 +#define SVC_DAMAGE 19 +#define SVC_SPAWNSTATIC 20 +#define SVC_EVENT_RELIABLE 21 +#define SVC_SPAWNBASELINE 22 +#define SVC_TEMPENTITY 23 +#define SVC_SETPAUSE 24 +#define SVC_SIGNONNUM 25 +#define SVC_CENTERPRINT 26 +#define SVC_KILLEDMONSTER 27 +#define SVC_FOUNDSECRET 28 +#define SVC_SPAWNSTATICSOUND 29 +#define SVC_INTERMISSION 30 +#define SVC_FINALE 31 +#define SVC_CDTRACK 32 +#define SVC_RESTORE 33 +#define SVC_CUTSCENE 34 +#define SVC_WEAPONANIM 35 +#define SVC_DECALNAME 36 +#define SVC_ROOMTYPE 37 +#define SVC_ADDANGLE 38 +#define SVC_NEWUSERMSG 39 +#define SVC_PACKETENTITIES 40 +#define SVC_DELTAPACKETENTITIES 41 +#define SVC_CHOKE 42 +#define SVC_RESOURCELIST 43 +#define SVC_NEWMOVEVARS 44 +#define SVC_RESOURCEREQUEST 45 +#define SVC_CUSTOMIZATION 46 +#define SVC_CROSSHAIRANGLE 47 +#define SVC_SOUNDFADE 48 +#define SVC_FILETXFERFAILED 49 +#define SVC_HLTV 50 +#define SVC_DIRECTOR 51 +#define SVC_VOICEINIT 52 +#define SVC_VOICEDATA 53 +#define SVC_SENDEXTRAINFO 54 +#define SVC_TIMESCALE 55 +#define SVC_RESOURCELOCATION 56 +#define SVC_SENDCVARVALUE 57 +#define SVC_SENDCVARVALUE2 58 + +typedef struct _UserMsg +{ + int iMsg; + int iSize; + char szName[16]; + _UserMsg* next; + pfnUserMsgHook pfn; +} UserMsg; + +const int MAX_CONSISTENCY_LIST = 512; + +typedef struct consistency_s +{ + char* filename; + int issound; + int orig_index; + int value; + int check_type; + float mins[3]; + float maxs[3]; +} consistency_t; + +typedef struct event_s +{ + unsigned short index; + const char* filename; + int filesize; + const char* pszScript; +} event_t; + +typedef enum server_state_e +{ + ss_dead = 0, + ss_loading = 1, + ss_active = 2, +} server_state_t; + +typedef struct sizebuf_s +{ + const char* buffername; + uint16_t flags; + byte* data; + int maxsize; + int cursize; +} sizebuf_t; + +const int NUM_BASELINES = 64; +#define MAX_RESOURCE_LIST 1280 + +#define MAX_MODEL_INDEX_BITS 9 // sent as a short +#define MAX_MODELS (1 << MAX_MODEL_INDEX_BITS) + +#define MAX_EVENTS 256 + +#define MAX_SOUND_INDEX_BITS 9 +#define MAX_SOUNDS (1 << MAX_SOUND_INDEX_BITS) +#define MAX_SOUNDS_HASHLOOKUP_SIZE (MAX_SOUNDS * 2 - 1) + +#define MAX_GENERIC_INDEX_BITS 9 +#define MAX_GENERIC (1 << MAX_GENERIC_INDEX_BITS) + +#define MAX_LIGHTSTYLE_INDEX_BITS 6 +#define MAX_LIGHTSTYLES (1 << MAX_LIGHTSTYLE_INDEX_BITS) + +const int MAX_DATAGRAM = 4000; + +typedef struct extra_baselines_s +{ + int number; + int classname[NUM_BASELINES]; + entity_state_t baseline[NUM_BASELINES]; +} extra_baselines_t; + +typedef struct server_s +{ + qboolean active; + qboolean paused; + qboolean loadgame; + double time; + double oldtime; + int lastcheck; + double lastchecktime; + char name[64]; + char oldname[64]; + char startspot[64]; + char modelname[64]; + struct model_s* worldmodel; + CRC32_t worldmapCRC; + unsigned char clientdllmd5[16]; + resource_t resourcelist[MAX_RESOURCE_LIST]; + int num_resources; + consistency_t consistency_list[MAX_CONSISTENCY_LIST]; + int num_consistency; + const char* model_precache[MAX_MODELS]; + struct model_s* models[MAX_MODELS]; + unsigned char model_precache_flags[MAX_MODELS]; + struct event_s event_precache[MAX_EVENTS]; + const char* sound_precache[MAX_SOUNDS]; + short int sound_precache_hashedlookup[MAX_SOUNDS_HASHLOOKUP_SIZE]; + qboolean sound_precache_hashedlookup_built; + const char* generic_precache[MAX_GENERIC]; + char generic_precache_names[MAX_GENERIC][64]; + int num_generic_names; + const char* lightstyles[MAX_LIGHTSTYLES]; + int num_edicts; + int max_edicts; + edict_t* edicts; + entity_state_s* baselines; + extra_baselines_t* instance_baselines; + server_state_t state; + sizebuf_t datagram; + unsigned char datagram_buf[MAX_DATAGRAM]; + sizebuf_t reliable_datagram; + unsigned char reliable_datagram_buf[MAX_DATAGRAM]; + sizebuf_t multicast; + unsigned char multicast_buf[1024]; + sizebuf_t spectator; + unsigned char spectator_buf[1024]; + sizebuf_t signon; + unsigned char signon_data[32768]; +} server_t; + +#define MAX_PACKET_ENTITIES 256 +#define MAX_PACKET_ENTITIES_HL25 1024 + +struct packet_entities_t +{ + int num_entities; + byte flags[MAX_PACKET_ENTITIES / 8]; + entity_state_s* entities; +}; + +struct packet_entities_HL25_t +{ + int num_entities; + byte flags[MAX_PACKET_ENTITIES_HL25 / 8]; + entity_state_s* entities; +}; + +typedef struct cmd_s +{ + usercmd_t cmd; + float senttime; + float receivedtime; + float frame_lerp; + qboolean processedfuncs; + qboolean heldback; + int sendsize; +} cmd_t; + +typedef struct event_args_s +{ + int flags; + int entindex; + float origin[3]; + float angles[3]; + float velocity[3]; + int ducking; + float fparam1; + float fparam2; + int iparam1; + int iparam2; + int bparam1; + int bparam2; +} event_args_t; + + +struct event_info_s +{ + unsigned short index; // 0 implies not in use + + short packet_index; // Use data from state info for entity in delta_packet . -1 implies separate info based on event + // parameter signature + short entity_index; // The edict this event is associated with + + float fire_time; // if non-zero, the time when the event should be fired ( fixed up on the client ) + + event_args_t args; + + // CLIENT ONLY + int flags; // Reliable or not, etc. +}; + +typedef struct event_state_s event_state_t; + +struct event_state_s +{ + struct event_info_s ei[64]; +}; + +typedef struct screenfade_s +{ + float fadeSpeed; + float fadeEnd; + float fadeTotalEnd; + float fadeReset; + byte fader; + byte fadeg; + byte fadeb; + byte fadealpha; + int fadeFlags; +} screenfade_t; + +typedef struct clientdata_s +{ + vec3_t origin; + vec3_t velocity; + int viewmodel; + vec3_t punchangle; + int flags; + int waterlevel; + int watertype; + vec3_t view_ofs; + float health; + int bInDuck; + int weapons; + int flTimeStepSound; + int flDuckTime; + int flSwimTime; + int waterjumptime; + float maxspeed; + float fov; + int weaponanim; + int m_iId; + int ammo_shells; + int ammo_nails; + int ammo_cells; + int ammo_rockets; + float m_flNextAttack; + int tfstate; + int pushmsec; + int deadflag; + char physinfo[256]; + int iuser1; + int iuser2; + int iuser3; + int iuser4; + float fuser1; + float fuser2; + float fuser3; + float fuser4; + vec3_t vuser1; + vec3_t vuser2; + vec3_t vuser3; + vec3_t vuser4; +} clientdata_t; + +typedef struct weapon_data_s +{ + int m_iId; + int m_iClip; + float m_flNextPrimaryAttack; + float m_flNextSecondaryAttack; + float m_flTimeWeaponIdle; + int m_fInReload; + int m_fInSpecialReload; + float m_flNextReload; + float m_flPumpTime; + float m_fReloadTime; + float m_fAimedDamage; + float m_fNextAimBonus; + int m_fInZoom; + int m_iWeaponState; + int iuser1; + int iuser2; + int iuser3; + int iuser4; + float fuser1; + float fuser2; + float fuser3; + float fuser4; +} weapon_data_t; + +typedef struct local_state_s +{ + entity_state_t playerstate; + clientdata_t client; + weapon_data_t weapondata[64]; +} local_state_t; + +typedef struct dlight_s +{ + vec3_t origin; + float radius; + color24 color; + float die; + float decay; + float minlight; + int key; + qboolean dark; +} dlight_t; + +typedef struct player_info_s +{ + int userid; + char userinfo[256]; + char name[32]; + int spectator; + int ping; + int packet_loss; + char model[64]; + int topcolor; + int bottomcolor; + int renderframe; + int gaitsequence; + float gaitframe; + float gaityaw; + vec3_t prevgaitorigin; + customization_t customdata; + char hashedcdkey[16]; + uint64_t m_nSteamID; +} player_info_t; + +typedef struct frame_s +{ + double receivedtime; + double latency; + qboolean invalid; + qboolean choked; + entity_state_t playerstate[32]; + double time; + clientdata_t clientdata; + weapon_data_t weapondata[64]; + packet_entities_t packet_entities; + unsigned short clientbytes; + unsigned short playerinfobytes; + unsigned short packetentitybytes; + unsigned short tentitybytes; + unsigned short soundbytes; + unsigned short eventbytes; + unsigned short usrbytes; + unsigned short voicebytes; + unsigned short msgbytes; + +} frame_t; + +typedef struct frame_HL25_s +{ + double receivedtime; + double latency; + qboolean invalid; + qboolean choked; + entity_state_t playerstate[32]; + double time; + clientdata_t clientdata; + weapon_data_t weapondata[64]; + packet_entities_HL25_t packet_entities; + unsigned short clientbytes; + unsigned short playerinfobytes; + unsigned short packetentitybytes; + unsigned short tentitybytes; + unsigned short soundbytes; + unsigned short eventbytes; + unsigned short usrbytes; + unsigned short voicebytes; + unsigned short msgbytes; +} frame_HL25_t; + +typedef struct client_state_s +{ + int max_edicts; + resource_t resourcesonhand; + resource_t resourcesneeded; + resource_t resourcelist[MAX_RESOURCE_LIST]; + int num_resources; + qboolean need_force_consistency_response; + char serverinfo[512]; + int servercount; + int validsequence; + int parsecount; + int parsecountmod; + int stats[32]; + int weapons; + usercmd_t cmd; + Vector viewangles; + Vector punchangle; + Vector crosshairangle; + Vector simorg; + Vector simvel; + Vector simangles; + Vector predicted_origins[64]; + Vector prediction_error; + float idealpitch; + Vector viewheight; + screenfade_t sf; + qboolean paused; + int onground; + int moving; + int waterlevel; + int usehull; + float maxspeed; + int pushmsec; + int light_level; + int intermission; + double mtime[2]; + double time; + double oldtime; + frame_t frames[64]; + cmd_t commands[64]; + local_state_t predicted_frames[64]; + int delta_sequence; + int playernum; + event_t event_precache[MAX_EVENTS]; + model_t* model_precache[MAX_MODELS]; + int model_precache_count; + sfx_t* sound_precache[MAX_SOUNDS]; + consistency_t consistency_list[MAX_CONSISTENCY_LIST]; + int num_consistency; + int highentity; + char levelname[40]; + int maxclients; + int gametype; + int viewentity; + model_t* worldmodel; + efrag_t* free_efrags; + int num_entities; + int num_statics; + cl_entity_t viewent; + int cdtrack; + int looptrack; + CRC32_t serverCRC; + unsigned char clientdllmd5[16]; + float weaponstarttime; + int weaponsequence; + int fPrecaching; + dlight_t* pLight; + player_info_t players[32]; + entity_state_t instanced_baseline[64]; + int instanced_baseline_number; + CRC32_t mapCRC; + event_state_t events; + char downloadUrl[128]; +} client_state_t; + +typedef struct client_state_HL25_s +{ + int max_edicts; + resource_t resourcesonhand; + resource_t resourcesneeded; + resource_t resourcelist[MAX_RESOURCE_LIST]; + int num_resources; + qboolean need_force_consistency_response; + char serverinfo[512]; + int servercount; + int validsequence; + int parsecount; + int parsecountmod; + int stats[32]; + int weapons; + usercmd_t cmd; + Vector viewangles; + Vector punchangle; + Vector crosshairangle; + Vector simorg; + Vector simvel; + Vector simangles; + Vector predicted_origins[64]; + Vector prediction_error; + float idealpitch; + Vector viewheight; + screenfade_t sf; + qboolean paused; + int onground; + int moving; + int waterlevel; + int usehull; + float maxspeed; + int pushmsec; + int light_level; + int intermission; + double mtime[2]; + double time; + double oldtime; + frame_HL25_t frames[64]; + cmd_t commands[64]; + local_state_t predicted_frames[64]; + int delta_sequence; + int playernum; + event_t event_precache[MAX_EVENTS]; + model_t* model_precache[MAX_MODELS]; + int model_precache_count; + sfx_t* sound_precache[MAX_SOUNDS]; + consistency_t consistency_list[MAX_CONSISTENCY_LIST]; + int num_consistency; + int highentity; + char levelname[40]; + int maxclients; + int gametype; + int viewentity; + model_t* worldmodel; + efrag_t* free_efrags; + int num_entities; + int num_statics; + cl_entity_t viewent; + int cdtrack; + int looptrack; + CRC32_t serverCRC; + unsigned char clientdllmd5[16]; + float weaponstarttime; + int weaponsequence; + int fPrecaching; + dlight_t* pLight; + player_info_t players[32]; + entity_state_t instanced_baseline[64]; + int instanced_baseline_number; + CRC32_t mapCRC; + event_state_t events; + char downloadUrl[128]; +} client_state_HL25_t; + + +#else //!__cplusplus +#error C++ compiler required to compile svc_messages.h +#endif //__cplusplus + +#endif //SVC_MESSAGES_H_GUARD + +#undef SVC_MESSAGES_H_RECURSE_GUARD +#endif //SVC_MESSAGES_H_RECURSE_GUARD \ No newline at end of file diff --git a/src/engine/sound.h b/src/engine/sound.h new file mode 100644 index 0000000..92fd331 --- /dev/null +++ b/src/engine/sound.h @@ -0,0 +1,191 @@ +/*** + * + * Copyright (c) 1996-2002, Valve LLC. All rights reserved. + * + * This product contains software technology licensed from Id + * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. + * All Rights Reserved. + * + * Use, distribution, and modification of this source code and/or resulting + * object code is restricted to non-commercial enhancements to products from + * Valve LLC. All other use, distribution, or modification is prohibited + * without written permission from Valve LLC. + * + ****/ + + // sound.h -- client sound i/o functions + +#ifndef SOUND_H +#define SOUND_H +#ifdef _WIN32 +#pragma once +#endif + +#define MAX_QPATH 64 // Must match value in quakedefs.h + +#define PAINTBUFFER_SIZE 512 + +// sound engine rate defines +#define SOUND_DMA_SPEED 22050 // hardware playback rate + +#define SOUND_11k 11025 // 11khz sample rate + +// sentence groups +#define CBSENTENCENAME_MAX 16 +#define CVOXFILESENTENCEMAX 1536 // max number of sentences in game. NOTE: this must match + // CVOXFILESENTENCEMAX in dlls\util.h!!! + +//===================================================================== +// FX presets +//===================================================================== + +#define SXROOM_OFF 0 + +#define SXROOM_GENERIC 1 // general, low reflective, diffuse room + +#define SXROOM_METALIC_S 2 // highly reflective, parallel surfaces +#define SXROOM_METALIC_M 3 +#define SXROOM_METALIC_L 4 + +#define SXROOM_TUNNEL_S 5 // resonant reflective, long surfaces +#define SXROOM_TUNNEL_M 6 +#define SXROOM_TUNNEL_L 7 + +#define SXROOM_CHAMBER_S 8 // diffuse, moderately reflective surfaces +#define SXROOM_CHAMBER_M 9 +#define SXROOM_CHAMBER_L 10 + +#define SXROOM_BRITE_S 11 // diffuse, highly reflective +#define SXROOM_BRITE_M 12 +#define SXROOM_BRITE_L 13 + +#define SXROOM_WATER1 14 // underwater fx +#define SXROOM_WATER2 15 +#define SXROOM_WATER3 16 + +#define SXROOM_CONCRETE_S 17 // bare, reflective, parallel surfaces +#define SXROOM_CONCRETE_M 18 +#define SXROOM_CONCRETE_L 19 + +#define SXROOM_OUTSIDE1 20 // echoing, moderately reflective +#define SXROOM_OUTSIDE2 21 // echoing, dull +#define SXROOM_OUTSIDE3 22 // echoing, very dull + +#define SXROOM_CAVERN_S 23 // large, echoing area +#define SXROOM_CAVERN_M 24 +#define SXROOM_CAVERN_L 25 + +#define SXROOM_WEIRDO1 26 +#define SXROOM_WEIRDO2 27 +#define SXROOM_WEIRDO3 28 + +#define CSXROOM 29 + +// !!! if this is changed, it much be changed in asm_i386.h too !!! +struct portable_samplepair_t +{ + int left; + int right; +}; + +struct sfx_t +{ + char name[MAX_QPATH]; + cache_user_t cache; + int servercount; +}; + +// !!! if this is changed, it much be changed in asm_i386.h too !!! +struct sfxcache_t +{ + int length; + int loopstart; + int speed; + int width; + int stereo; + byte data[1]; // variable sized +}; + +struct dma_t +{ + qboolean gamealive; + qboolean soundalive; + qboolean splitbuffer; + int channels; + int samples; // mono samples in buffer + int submission_chunk; // don't mix less than this # + int samplepos; // in mono samples + int samplebits; + int speed; + int dmaspeed; + unsigned char* buffer; +}; + +// !!! if this is changed, it much be changed in asm_i386.h too !!! +struct channel_t +{ + sfx_t* sfx; // sfx number + int leftvol; // 0-255 volume + int rightvol; // 0-255 volume + + int end; // end time in global paintsamples + int pos; // sample position in sfx + + int looping; // where to loop, -1 = no looping + + int entnum; // to allow overriding a specific sound + int entchannel; // TODO: Define as enum, modify const.h then -Enko + + vec3_t origin; // origin of sound effect + vec_t dist_mult; // distance multiplier (attenuation/clipK) + + int master_vol; // 0-255 master volume + + int isentence; // true if playing linked sentence + int iword; + + int pitch; +}; + +struct wavinfo_t +{ + int rate; + int width; + int channels; + int loopstart; + int samples; + int dataofs; // chunk starts this many bytes from file start +}; + +struct wavstream_t +{ + int csamplesplayed; + int csamplesinmem; + void* hFile; + wavinfo_t info; + int lastposloaded; +}; + +struct voxword_t +{ + int volume; // increase percent, ie: 125 = 125% increase + int pitch; // pitch shift up percent + int start; // offset start of wave percent + int end; // offset end of wave percent + int cbtrim; // end of wave after being trimmed to 'end' + int fKeepCached; // 1 if this word was already in cache before sentence referenced it + int samplefrac; // if pitch shifting, this is position into wav * 256 + int timecompress; // % of wave to skip during playback (causes no pitch shift) + sfx_t* sfx; // name and cache pointer +}; + +#define CVOXWORDMAX 32 + +// ==================================================================== +// User-setable variables +// ==================================================================== + +#define MAX_CHANNELS 128 +#define MAX_DYNAMIC_CHANNELS 8 + +#endif // SOUND_H \ No newline at end of file diff --git a/src/engine_patterns.hpp b/src/engine_patterns.hpp index ca30578..4d25cdc 100644 --- a/src/engine_patterns.hpp +++ b/src/engine_patterns.hpp @@ -13,6 +13,15 @@ namespace patterns { + namespace server + { + PATTERNS(CNihilanth_DyingThink, + "Sven-5.25", + "A1 ?? ?? ?? ?? 83 EC 74 F3 0F 10 00"); + + + } + namespace engine { PATTERNS(ClientDLL_HudInit, @@ -39,6 +48,20 @@ namespace patterns "81 EC 04 02 00 00 A1 ?? ?? ?? ?? 33 C4 89 84 24 ?? ?? ?? ?? 68 ?? ?? ?? ?? 8D 44 24 ?? 68 00 02 00 00" ); + PATTERNS(Host_ClearMemory, + "HL-9920", + "55 8B EC E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 7D ?? 00 75 ?? 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 C4 04 E8 ?? ?? ?? ??", + "HL-8684", + "55 8B EC E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 8B 45 ?? 85 C0 75 ?? 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 C4 04 E8 ?? ?? ?? ?? E8 ?? ?? ?? ??", + "HL-4554", + "E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 8B 44 24 ?? 85 C0", + "Sven-5.25", + "E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 7C 24 ?? 00 75 ??"); + + PATTERNS(LoadThisDll, + "Sven-5.25", + "53 57 8B 7C 24 ?? 57 E8 ?? ?? ?? ?? 8B D8 83 C4 04 85 DB 75 ?? E8 ?? ?? ?? ??"); + PATTERNS(Netchan_CreateFragments, "HL-8684", "55 8B EC B8 14 00 01 00 E8 ?? ?? ?? ?? 53", "Sven-5.25", "B8 1C 00 04 00"); @@ -55,6 +78,14 @@ namespace patterns "HL-8684", "55 8B EC B8 C0 53 05 00", "Sven-5.25", "83 EC 74 A1 ?? ?? ?? ?? 33 C4 89 44 24 ?? 53 8B 5C 24 ??"); + PATTERNS(SCR_BeginLoadingPlaque, + "Sven-5.25", + "6A 01 E8 ?? ?? ?? ?? A1 ?? ?? ?? ?? 83 C4 04 83 F8 03"); + + PATTERNS(SCR_EndLoadingPlaque, + "Sven-5.25", + "C7 05 ?? ?? ?? ?? 00 00 00 00 E8 ?? ?? ?? ?? 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 C4 08"); + PATTERNS(S_StartDynamicSound, "HL-9920", "55 8B EC 83 EC 5C A1 ?? ?? ?? ?? 33 C5 89 45 ?? 83 3D ?? ?? ?? ?? 00 8B 45 ?? 8B 4D ??",