mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Merge branch 'Mauler125:pylon' into pylon
This commit is contained in:
commit
194908caca
@ -3,11 +3,12 @@
|
||||
#include "tier0/basetypes.h"
|
||||
#include "tier0/IConVar.h"
|
||||
#include "tier0/cvar.h"
|
||||
#include "tier0/commandline.h"
|
||||
#include "client/IVEngineClient.h"
|
||||
#include "client/client.h"
|
||||
#include "client/cdll_engine_int.h"
|
||||
#include "public/include/bansystem.h"
|
||||
#include "engine/net_chan.h"
|
||||
#include "public/include/bansystem.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -23,23 +24,35 @@ void __fastcall HFrameStageNotify(CHLClient* rcx, ClientFrameStage_t frameStage)
|
||||
static bool bInitialized = false;
|
||||
if (!bInitialized)
|
||||
{
|
||||
IConVar_ClearHostNames();
|
||||
ConCommand_InitConCommand();
|
||||
#ifdef GAMEDLL_S3
|
||||
g_pConVar->ClearHostNames();
|
||||
#endif // GAMEDLL_S3
|
||||
|
||||
g_pConCommand->Init();
|
||||
CKeyValueSystem_Init();
|
||||
|
||||
if (!g_pCmdLine->CheckParm("-devsdk"))
|
||||
{
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_server.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_client.cfg");
|
||||
}
|
||||
else // Development configs.
|
||||
{
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_server_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_client_dev.cfg");
|
||||
}
|
||||
|
||||
*(bool*)m_bRestrictServerCommands = true; // Restrict commands.
|
||||
ConCommandBase* disconnect = (ConCommandBase*)g_pCvar->FindCommand("disconnect");
|
||||
ConCommandBase* disconnect = (ConCommandBase*)g_pCVar->FindCommand("disconnect");
|
||||
disconnect->AddFlags(FCVAR_SERVER_CAN_EXECUTE); // Make sure server is not restricted to this.
|
||||
|
||||
if (net_userandomkey->m_pParent->m_iValue == 1)
|
||||
if (net_userandomkey->GetBool())
|
||||
{
|
||||
HNET_GenerateKey();
|
||||
}
|
||||
g_pCvar->FindVar("net_usesocketsforloopback")->m_pParent->m_iValue = 1;
|
||||
g_pCVar->FindVar("net_usesocketsforloopback")->SetValue(1);
|
||||
|
||||
bInitialized = true;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "tier0/basetypes.h"
|
||||
|
||||
|
||||
enum class ClientFrameStage_t : int
|
||||
{
|
||||
FRAME_UNDEFINED = -1, // (haven't run any frames yet)
|
||||
@ -50,6 +49,8 @@ namespace
|
||||
ADDRESS p_CHLClient_PostInit = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x48\x83\x3D\x00\x00\x00\x00\x00\x48\x8D\x05\x00\x00\x00\x00", "xxxxxxx?????xxx????");
|
||||
void* (*CHLClient_PostInit)() = (void* (*)())p_CHLClient_PostInit.GetPtr(); /*48 83 EC 28 48 83 3D ? ? ? ? ? 48 8D 05 ? ? ? ?*/
|
||||
#endif
|
||||
|
||||
bool* scr_drawloading = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x80\x3D\x00\x00\x00\x00\x00\x74\x14\x66\x0F\x6E\x05\x00\x00\x00\x00", "xx?????xxxxxx????").ResolveRelativeAddress(0x2, 0x7).RCast<bool*>();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -66,6 +67,7 @@ class HDll_Engine_Int : public IDetour
|
||||
{
|
||||
std::cout << "| FUN: CHLClient::FrameStageNotify : 0x" << std::hex << std::uppercase << p_CHLClient_FrameStageNotify.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: CHLClient::PostInit : 0x" << std::hex << std::uppercase << p_CHLClient_PostInit.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| VAR: scr_drawloading : 0x" << std::hex << std::uppercase << scr_drawloading << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
}
|
||||
};
|
||||
|
@ -6,8 +6,12 @@
|
||||
#include "tier0/basetypes.h"
|
||||
#include "common/opcodes.h"
|
||||
#include "engine/host_cmd.h"
|
||||
#include "materialsystem/materialsystem.h"
|
||||
#include "bsplib/bsplib.h"
|
||||
#include "ebisusdk/EbisuSDK.h"
|
||||
#ifndef DEDICATED
|
||||
#include "milessdk/win64_rrthreads.h"
|
||||
#endif // !DEDICATED
|
||||
|
||||
|
||||
#ifdef DEDICATED
|
||||
@ -126,13 +130,12 @@ void Dedicated_Init()
|
||||
//-------------------------------------------------------------------------
|
||||
// RUNTIME: EBISUSDK
|
||||
//-------------------------------------------------------------------------
|
||||
p_EbisuSDK_Init_Tier0.Offset(0x0B).Patch({ 0xE9, 0x63, 0x02, 0x00, 0x00, 0x00 }); // JNZ --> JMP | Prevent EbisuSDK from initializing on the engine and server.
|
||||
p_EbisuSDK_SetState.Offset(0x0E).Patch({ 0xE9, 0xCB, 0x03, 0x00, 0x00 }); // JNZ --> JMP | Prevent EbisuSDK from initializing on the engine and server.
|
||||
p_EbisuSDK_SetState.Offset(0x0).FindPatternSelf("0F 84", ADDRESS::Direction::DOWN).Patch({ 0x0F, 0x85 }); // JE --> JNZ | Prevent EbisuSDK from initializing on the engine and server.
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// RUNTIME: FAIRFIGHT
|
||||
//-------------------------------------------------------------------------
|
||||
FairFight_Init.Offset(0x61).Patch({ 0xE9, 0xED, 0x00, 0x00, 0x00, 0x00 });
|
||||
FairFight_Init.Offset(0x0).FindPatternSelf("0F 87", ADDRESS::Direction::DOWN, 200).Patch({ 0x0F, 0x85 }); // JA --> JNZ | Prevent 'FairFight' anti-cheat from initializing on the server by comparing RAX against 0x0 instead. Init will crash since the plugins aren't shipped.
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// RUNTIME: BSP_LUMP
|
||||
@ -170,18 +173,16 @@ void Dedicated_Init()
|
||||
|
||||
void RuntimePtc_Init() /* .TEXT */
|
||||
{
|
||||
SCR_BeginLoadingPlaque.Offset(0x1D6).Patch({ 0xEB, 0x27 }); // JNE --> JMP | Prevent connect command from crashing by invalid call to UI function.
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JMP | Allow games to be loaded without the optional texture streaming file
|
||||
//WriteProcessMemory(GameProcess, LPVOID(dst002 + 0x8E5), "\xEB\x19", 2, NULL);
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
// JA --> JMP | Prevent FairFight anti-cheat from initializing on the server.
|
||||
FairFight_Init.Offset(0x61).Patch({ 0xE9, 0xED, 0x00, 0x00, 0x00, 0x00 });
|
||||
#ifndef DEDICATED
|
||||
p_WASAPI_GetAudioDevice.Offset(0x410).FindPattern("FF 15 ?? ?? 01 00", ADDRESS::Direction::DOWN, 100).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xEB }); // CAL --> NOP | Disable debugger check when miles searches for audio device to allow attaching the debugger to the game upon launch.
|
||||
FairFight_Init.Offset(0x0).FindPatternSelf("0F 87", ADDRESS::Direction::DOWN, 200).Patch({ 0x0F, 0x85 }); // JA --> JNZ | Prevent 'FairFight' anti-cheat from initializing on the server by comparing RAX against 0x0 instead. Init will crash since the plugins aren't shipped.
|
||||
SCR_BeginLoadingPlaque.Offset(0x1AD).FindPatternSelf("75 27", ADDRESS::Direction::DOWN).Patch({ 0xEB, 0x27 }); // JNE --> JMP | Prevent connect command from crashing by invalid call to UI function.
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
void RuntimePtc_Toggle() /* .TEXT */
|
||||
{
|
||||
#ifdef GAMEDLL_S3
|
||||
static bool g_nop = true;
|
||||
|
||||
if (g_nop)
|
||||
@ -191,7 +192,7 @@ void RuntimePtc_Toggle() /* .TEXT */
|
||||
dst007.Offset(0x5E8).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 });
|
||||
//-------------------------------------------------------------------------
|
||||
// CALL --> NOP | Disable the viewmodel rendered to avoid a crash from a certain entity in desertlands_mu1
|
||||
dst008.Offset(0x67).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90 });
|
||||
//dst008.Offset(0x67).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90 });
|
||||
|
||||
|
||||
printf("\n");
|
||||
@ -207,7 +208,7 @@ void RuntimePtc_Toggle() /* .TEXT */
|
||||
dst007.Offset(0x5E8).Patch({ 0x48, 0x8B, 0x03, 0xFF, 0x90, 0xB0, 0x02, 0x00, 0x00, 0x84, 0xC0 });
|
||||
//-------------------------------------------------------------------------
|
||||
// NOP --> CALL | Recover function DST008
|
||||
dst008.Offset(0x67).Patch({ 0xE8, 0x54, 0xD8, 0xFF, 0xFF });
|
||||
//dst008.Offset(0x67).Patch({ 0xE8, 0x54, 0xD8, 0xFF, 0xFF });
|
||||
|
||||
printf("\n");
|
||||
printf("+--------------------------------------------------------+\n");
|
||||
@ -216,4 +217,13 @@ void RuntimePtc_Toggle() /* .TEXT */
|
||||
printf("\n");
|
||||
}
|
||||
g_nop = !g_nop;
|
||||
|
||||
|
||||
/*
|
||||
rtech_asyncload "common.rpak"
|
||||
rtech_asyncload "common_mp.rpak"
|
||||
rtech_asyncload "mp_rr_canyonlands_mu1.rpak"
|
||||
rtech_asyncload "mp_rr_desertlands_64k_x_64k.rpak"
|
||||
*/
|
||||
#endif // GAMEDLL_S3
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
#include "tier0/basetypes.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
#ifdef DEDICATED
|
||||
@ -14,11 +16,12 @@ void RuntimePtc_Toggle();
|
||||
|
||||
namespace
|
||||
{
|
||||
#ifdef GAMEDLL_S3
|
||||
/* -------------- OTHER ------------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
ADDRESS dst007 = /*0x14028F3B0*/ FindPatternSIMD(g_szGameDll, (const unsigned char*)"\x48\x8B\xC4\x44\x89\x40\x18\x48\x89\x50\x10\x55\x53\x56\x57\x41", "xxxxxxxxxxxxxxxx");
|
||||
ADDRESS dst008 = /*0x140E3E110*/ FindPatternSIMD(g_szGameDll, (const unsigned char*)"\x48\x83\xEC\x78\x48\x8B\x84\x24\x00\x00\x00\x00\x4D\x8B\xD8\x00", "xxxxxxxx????xxx?");
|
||||
/* -------------- ------- ----------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
#endif // GAMEDLL_S3
|
||||
namespace
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
@ -57,15 +60,6 @@ namespace
|
||||
ADDRESS CShaderSystem__Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\xC6\x41\x10\x00", "xxxx?xxxx?xxxxxxxxx");
|
||||
// 0x1403DF870 // 48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 C6 41 10 00 //
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CMATERIALSYSTEM
|
||||
//-------------------------------------------------------------------------
|
||||
ADDRESS CMaterialSystem__Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x70\x48\x83\x3D\x00\x00\x00\x00\x00", "xxxx?xxxxxxxxxxxxxxxxxx?????");
|
||||
// 0x1403BBFD0 // 48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 70 48 83 3D ? ? ? ? ? //
|
||||
|
||||
ADDRESS InitMaterialSystem = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x48\x8B\x0D\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\x48\x8B\x01\xFF\x90\x00\x00\x00\x00\x48\x8B\x0D\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\x48\x8B\x01\xFF\x90\x00\x00\x00\x00", "xxxxxxx????xxx????xxxxx????xxx????xxx????xxxxx????"); //
|
||||
// 0x14024B390 // 48 83 EC 28 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? 48 8B 01 FF 90 ? ? ? ? 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? 48 8B 01 FF 90 ? ? ? ? //
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// RUNTIME: BSP_LUMP
|
||||
//-------------------------------------------------------------------------
|
||||
@ -75,19 +69,37 @@ namespace
|
||||
ADDRESS CollisionBSPData_LinkPhysics = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x57\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\xF9\x33\xED", "xxxx?xxxx?xxxx????xxxxx"); // case 1: only gets called on changelevel, needs more research, function gets called by CModelLoader virtual function.
|
||||
// 0x140256480 // 48 89 5C 24 ? 48 89 6C 24 ? 57 48 81 EC ? ? ? ? 48 8B F9 33 ED //
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CSTUDIORENDERCONTEXT
|
||||
//-------------------------------------------------------------------------
|
||||
#if defined (GAMEDLL_S1)
|
||||
ADDRESS CStudioRenderContext__LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x89\x44\x24\x00\x53\x55\x56\x41\x54\x41\x57", "xxxx?xxxxxxx");
|
||||
#elif defined (GAMEDLL_S2)
|
||||
ADDRESS CStudioRenderContext__LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x89\x44\x24\x00\x48\x89\x54\x24\x00\x53\x57\x41\x55\x48\x81\xEC\x00\x00\x00\x00", "xxxx?xxxx?xxxxxxx????");
|
||||
#elif defined (GAMEDLL_S3)
|
||||
ADDRESS CStudioRenderContext__LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x89\x44\x24\x00\x48\x89\x54\x24\x00\x48\x89\x4C\x24\x00\x53\x55\x56\x57\x48\x83\xEC\x78", "xxxx?xxxx?xxxx?xxxxxxxx");
|
||||
// 0x1404554C0 // 4C 89 44 24 ? 48 89 54 24 ? 48 89 4C 24 ? 53 55 56 57 48 83 EC 78 //
|
||||
#endif// 0x1404554C0 // 4C 89 44 24 ? 48 89 54 24 ? 48 89 4C 24 ? 53 55 56 57 48 83 EC 78 //
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
ADDRESS CStudioRenderContext__LoadMaterials = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x89\x44\x24\x00\x55\x56\x41\x57", "xxxx?xxxx");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
ADDRESS CStudioRenderContext__LoadMaterials = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xC4\x4C\x89\x40\x18\x55\x56\x41\x55", "xxxxxxxxxxx");
|
||||
// 0x140456B50 // 48 8B C4 4C 89 40 18 55 56 41 55 //
|
||||
#endif// 0x140456B50 // 48 8B C4 4C 89 40 18 55 56 41 55 //
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CMODELLOADER
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
ADDRESS CModelLoader__FindModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x55\x41\x55\x41\x56\x48\x8D\xAC\x24\x00\x00\x00\x00", "xxxxxxxxxx????");
|
||||
// 0x1402A1F10 // 40 55 41 55 41 56 48 8D AC 24 ? ? ? ? //
|
||||
|
||||
ADDRESS CModelLoader__LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x57\x41\x56\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\xFA", "xxxxxxxx????xxx");
|
||||
// 0x1402A23B0 // 40 53 57 41 56 48 81 EC ? ? ? ? 48 8B FA //
|
||||
|
||||
ADDRESS CModelLoader__Studio_LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x56\x48\x8D\xAC\x24\x00\x00\x00\x00", "xxxx?xxxxxxxxxxx????");
|
||||
// 0x140252F10 // 48 89 5C 24 ? 55 56 57 41 54 41 57 48 81 EC ? ? ? ? //
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
ADDRESS CModelLoader__FindModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x55\x41\x57\x48\x83\xEC\x48\x80\x3A\x2A", "xxxxxxxxxxx");
|
||||
// 0x140253530 // 40 55 41 57 48 83 EC 48 80 3A 2A //
|
||||
|
||||
@ -96,18 +108,26 @@ namespace
|
||||
|
||||
ADDRESS CModelLoader__Studio_LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x57\x48\x81\xEC\x00\x00\x00\x00", "xxxx?xxxxxxxxxx????");
|
||||
// 0x140252F10 // 48 89 5C 24 ? 55 56 57 41 54 41 57 48 81 EC ? ? ? ? //
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CGAMESERVER
|
||||
//-------------------------------------------------------------------------
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
ADDRESS CGameServer__SpawnServer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x55\x56\x57\x41\x55\x41\x56\x41\x57\x48\x81\xEC\x00\x00\x00\x00", "xxxxxxxxxxxxxx????");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
ADDRESS CGameServer__SpawnServer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xC4\x53\x55\x56\x57\x41\x54\x41\x55\x41\x57", "xxxxxxxxxxxxx");
|
||||
// 0x140312D80 // 48 8B C4 53 55 56 57 41 54 41 55 41 57 //
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// RUNTIME: FAIRFIGHT
|
||||
//-------------------------------------------------------------------------
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
ADDRESS FairFight_Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x57\x41\x57\x48\x83\xEC\x30\x8B\x81\x00\x00\x00\x00", "xxxxxxxxxxx????");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
ADDRESS FairFight_Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x8B\x81\xB0\x03\x00\x00\x48\x8B\xD9\xC6", "xxxxxxxxxxxxxxxx");
|
||||
// 0x140303AE0 // 40 53 48 83 EC 20 8B 81 ? ? ? ? 48 8B D9 C6 81 ? ? ? ? ? //
|
||||
#endif // 0x140303AE0 // 40 53 48 83 EC 20 8B 81 ? ? ? ? 48 8B D9 C6 81 ? ? ? ? ? //
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// RUNTIME: HOST_INIT
|
||||
@ -136,8 +156,14 @@ namespace
|
||||
//-------------------------------------------------------------------------
|
||||
// RUNTIME: GL_SCREEN
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
ADDRESS SCR_BeginLoadingPlaque = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x30\x0F\x29\x74\x24\x00\x48\x8B\xF9", "xxxx?xxxx?xxxxxxxxx?xxx");
|
||||
// 0x14022A4A0 // 48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 30 0F 29 74 24 ? 48 8B F9 //
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
ADDRESS SCR_BeginLoadingPlaque = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x38\x0F\x29\x74\x24\x00\x48\x89\x5C\x24\x00", "xxxxxxxx?xxxx?");
|
||||
// 0x14022A4A0 // 48 83 EC 38 0F 29 74 24 ? 48 89 5C 24 ? //
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,9 +179,6 @@ class HOpcodes : public IDetour
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| FUN: CShaderSystem::Init : 0x" << std::hex << std::uppercase << CShaderSystem__Init.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| FUN: CMaterialSystem::Init : 0x" << std::hex << std::uppercase << CMaterialSystem__Init.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: InitMaterialSystem : 0x" << std::hex << std::uppercase << InitMaterialSystem.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| FUN: CollisionBSPData_LoadAllLumps : 0x" << std::hex << std::uppercase << CollisionBSPData_LoadAllLumps.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: CollisionBSPData_LinkPhysics : 0x" << std::hex << std::uppercase << CollisionBSPData_LinkPhysics.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
|
13
r5dev/core/assert.h
Normal file
13
r5dev/core/assert.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#ifndef NDEBUG
|
||||
# define Assert(condition, message) \
|
||||
do { \
|
||||
if (! (condition)) { \
|
||||
std::cerr << "Assertion `" #condition "` failed in " << __FILE__ \
|
||||
<< " line " << __LINE__ << ": " << message << std::endl; \
|
||||
std::terminate(); \
|
||||
} \
|
||||
} while (false)
|
||||
#else
|
||||
# define Assert(condition, message) do { } while (false)
|
||||
#endif
|
@ -1,6 +1,7 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "core/r5dev.h"
|
||||
#include "core/init.h"
|
||||
#include "core/logdef.h"
|
||||
/*****************************************************************************/
|
||||
#ifndef DEDICATED
|
||||
#include "windows/id3dx.h"
|
||||
@ -15,7 +16,13 @@
|
||||
|
||||
void R5Dev_Init()
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
if (strstr(GetCommandLineA(), "-wconsole")) { Console_Init(); }
|
||||
#else
|
||||
Console_Init();
|
||||
#endif // !DEDICATED
|
||||
|
||||
SpdLog_Init();
|
||||
Systems_Init();
|
||||
WinSys_Attach();
|
||||
|
||||
@ -24,13 +31,17 @@ void R5Dev_Init()
|
||||
DirectX_Init();
|
||||
#endif // !DEDICATED
|
||||
|
||||
spdlog::get("console")->set_pattern("%v");
|
||||
spdlog::info("\n");
|
||||
spdlog::info("+-----------------------------------------------------------------------------+\n");
|
||||
spdlog::info("| R5 DEVELOPER CONSOLE -- INITIALIZED ----------------------------------- |\n");
|
||||
spdlog::info("+-----------------------------------------------------------------------------+\n");
|
||||
spdlog::get("console")->set_pattern("[%S.%e] %v");
|
||||
spdlog::info("\n");
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
// SHUTDOWN
|
||||
//#############################################################################
|
||||
|
||||
void R5Dev_Shutdown()
|
||||
{
|
||||
Systems_Shutdown();
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "core/init.h"
|
||||
#include "common/opcodes.h"
|
||||
#include "tier0/commandline.h"
|
||||
#include "tier0/ConCommand.h"
|
||||
#include "tier0/completion.h"
|
||||
#include "tier0/cvar.h"
|
||||
@ -15,11 +15,16 @@
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "vpc/basefilesystem.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "common/opcodes.h"
|
||||
#include "launcher/IApplication.h"
|
||||
#include "ebisusdk/EbisuSDK.h"
|
||||
#ifndef DEDICATED
|
||||
#include "milessdk/win64_rrthreads.h"
|
||||
#endif // !DEDICATED
|
||||
#include "vphysics/QHull.h"
|
||||
#include "bsplib/bsplib.h"
|
||||
#ifndef DEDICATED
|
||||
#include "materialsystem/materialsystem.h"
|
||||
#include "vgui/CEngineVGui.h"
|
||||
#include "vgui/vgui_fpspanel.h"
|
||||
#include "vguimatsurface/MatSystemSurface.h"
|
||||
@ -42,6 +47,7 @@
|
||||
#include "engine/sys_dll2.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#ifndef DEDICATED
|
||||
#include "engine/debugoverlay.h"
|
||||
#include "inputsystem/inputsystem.h"
|
||||
#include "windows/id3dx.h"
|
||||
#endif // !DEDICATED
|
||||
@ -78,7 +84,9 @@ void Systems_Init()
|
||||
CHLClient_Attach();
|
||||
#endif // !DEDICATED
|
||||
|
||||
CServer_Attach();
|
||||
#ifdef GAMEDLL_S3
|
||||
CServer_Attach(); // S1 and S2 CServer functions require work.
|
||||
#endif // GAMEDLL_S3
|
||||
|
||||
#ifdef DEDICATED
|
||||
CHostState_Attach(); // Dedicated only for now until backwards compatible with S1.
|
||||
@ -107,12 +115,11 @@ void Systems_Init()
|
||||
TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE);
|
||||
}
|
||||
|
||||
IConVar_InitConVar();
|
||||
g_pConVar->Init();
|
||||
|
||||
#ifdef DEDICATED
|
||||
Dedicated_Init();
|
||||
#endif // DEDICATED
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -145,7 +152,10 @@ void Systems_Shutdown()
|
||||
CFPSPanel_Detach();
|
||||
CHLClient_Detach();
|
||||
#endif // !DEDICATED
|
||||
CServer_Detach();
|
||||
|
||||
#ifdef GAMEDLL_S3
|
||||
CServer_Detach(); // S1 and S2 CServer functions require work.
|
||||
#endif // GAMEDLL_S3
|
||||
|
||||
#ifdef DEDICATED
|
||||
CHostState_Detach(); // Dedicated only for now until backwards compatible with S1.
|
||||
|
60
r5dev/core/logdef.cpp
Normal file
60
r5dev/core/logdef.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "core/logdef.h"
|
||||
|
||||
//#############################################################################
|
||||
// SPDLOG SETUP
|
||||
//#############################################################################
|
||||
void SpdLog_Init(void)
|
||||
{
|
||||
static bool bInitialized = false;
|
||||
|
||||
if (bInitialized)
|
||||
{
|
||||
Assert(bInitialized, "'SpdLog_Init()' has already been called.");
|
||||
return;
|
||||
}
|
||||
|
||||
/************************
|
||||
* IMGUI LOGGER SETUP *
|
||||
************************/
|
||||
{
|
||||
auto iconsole = std::make_shared<spdlog::logger>("game_console", g_spd_sys_p_ostream_sink);
|
||||
spdlog::register_logger(iconsole); // in-game console logger.
|
||||
iconsole->set_pattern("[%S.%e] %v");
|
||||
iconsole->set_level(spdlog::level::trace);
|
||||
}
|
||||
|
||||
/************************
|
||||
* WINDOWS LOGGER SETUP *
|
||||
************************/
|
||||
{
|
||||
auto wconsole = spdlog::stdout_logger_mt("win_console");
|
||||
|
||||
// Determine if user wants ansi-color logging in the terminal.
|
||||
if (strstr(GetCommandLineA(), "-ansiclr"))
|
||||
{
|
||||
wconsole->set_pattern("[%S.%e] %v\u001b[0m");
|
||||
g_bSpdLog_UseAnsiClr = true;
|
||||
}
|
||||
else { wconsole->set_pattern("[%S.%e] %v"); }
|
||||
wconsole->set_level(spdlog::level::trace);
|
||||
spdlog::set_default_logger(wconsole); // Set as default.
|
||||
}
|
||||
|
||||
/************************
|
||||
* ROTATE LOGGER SETUP *
|
||||
************************/
|
||||
{
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sqvm_warn_logger", "platform\\logs\\sqvm_warn.log", SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sqvm_print_logger", "platform\\logs\\sqvm_print.log", SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("dev_message_logger", "platform\\logs\\dev_message.log", SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("netchan_pack_logger", "platform\\logs\\net_trace.log", SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("qhull_debug_logger", "platform\\logs\\qhull_print.log", SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("filesystem_warn_logger", "platform\\logs\\fs_warn.log", SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
|
||||
}
|
||||
|
||||
spdlog::set_level(spdlog::level::trace);
|
||||
spdlog::flush_every(std::chrono::seconds(5)); // Flush buffers every 5 seconds for every logger.
|
||||
|
||||
bInitialized = true;
|
||||
}
|
@ -1,27 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
constexpr int SPDLOG_MAX_SIZE = 10 * 1024; // Sets number of bytes before rotating logger.
|
||||
constexpr int SPDLOG_NUM_FILE = 0; // Sets number of files to rotate to.
|
||||
|
||||
inline bool g_bSpdLog_UseAnsiClr = false;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// NETCHAN |
|
||||
inline auto g_spd_netchan_logger = spdlog::basic_logger_mt("netchan_logger", "platform\\logs\\net_trace.log");
|
||||
inline std::ostringstream g_spd_net_p_oss;
|
||||
inline auto g_spd_net_p_ostream_sink = std::make_shared<spdlog::sinks::ostream_sink_st>(g_spd_net_p_oss);
|
||||
//-------------------------------------------------------------------------
|
||||
// FILESYSTEM |
|
||||
inline std::ostringstream fs_oss;
|
||||
inline auto fs_ostream_sink = std::make_shared<spdlog::sinks::ostream_sink_st>(fs_oss);
|
||||
//-------------------------------------------------------------------------
|
||||
// SQUIRREL PRINTF |
|
||||
inline std::ostringstream g_spd_sqvm_p_oss;
|
||||
inline auto g_spd_sqvm_p_ostream_sink = std::make_shared<spdlog::sinks::ostream_sink_st>(g_spd_sqvm_p_oss);
|
||||
//-------------------------------------------------------------------------
|
||||
// SQUIRREL WARNF |
|
||||
inline std::ostringstream g_spd_sqvm_w_oss;
|
||||
inline auto g_spd_sqvm_w_ostream_sink = std::make_shared<spdlog::sinks::ostream_sink_st>(g_spd_sqvm_w_oss);
|
||||
//-------------------------------------------------------------------------
|
||||
// SYSTEM PRINTF |
|
||||
// IMGUI CONSOLE SINK |
|
||||
inline std::ostringstream g_spd_sys_w_oss;
|
||||
inline auto g_spd_sys_p_ostream_sink = std::make_shared<spdlog::sinks::ostream_sink_st>(g_spd_sys_w_oss);
|
||||
//-------------------------------------------------------------------------
|
||||
// QHULL PRINTF |
|
||||
inline std::ostringstream g_spd_qhull_p_w_oss;
|
||||
inline auto g_spd_qhull_p_ostream_sink = std::make_shared<spdlog::sinks::ostream_sink_st>(g_spd_qhull_p_w_oss);
|
||||
|
||||
void SpdLog_Init(void);
|
||||
|
@ -36,27 +36,38 @@
|
||||
#include "thirdparty/imgui/include/imgui_impl_win32.h"
|
||||
#endif // !DEDICATED
|
||||
|
||||
#if !defined(SDKLAUNCHER)
|
||||
#include "thirdparty/lzham/include/lzham_types.h"
|
||||
#include "thirdparty/lzham/include/lzham.h"
|
||||
#endif // !SDKLAUNCHER
|
||||
|
||||
#include "thirdparty/spdlog/include/spdlog.h"
|
||||
#include "thirdparty/spdlog/include/async.h"
|
||||
#include "thirdparty/spdlog/include/sinks/ostream_sink.h"
|
||||
#include "thirdparty/spdlog/include/sinks/basic_file_sink.h"
|
||||
#include "thirdparty/spdlog/include/sinks/stdout_sinks.h"
|
||||
#include "thirdparty/spdlog/include/sinks/ostream_sink.h"
|
||||
#include "thirdparty/spdlog/include/sinks/stdout_color_sinks.h"
|
||||
#include "thirdparty/spdlog/include/sinks/ansicolor_sink.h"
|
||||
#include "thirdparty/spdlog/include/sinks/rotating_file_sink.h"
|
||||
|
||||
#include "public/include/utility.h"
|
||||
#include "public/include/memaddr.h"
|
||||
#include "public/include/httplib.h"
|
||||
#include "public/include/json.hpp"
|
||||
|
||||
#include "networksystem/net_structs.h"
|
||||
#include "tier0/basetypes.h"
|
||||
#include "core/assert.h"
|
||||
|
||||
#ifndef SDKLAUNCHER
|
||||
#if !defined (SDKLAUNCHER)
|
||||
namespace
|
||||
{
|
||||
#ifdef DEDICATED
|
||||
MODULE g_mGameDll = MODULE("r5apex_ds.exe");
|
||||
#else
|
||||
#if !defined (DEDICATED)
|
||||
MODULE g_mGameDll = MODULE("r5apex.exe");
|
||||
#endif // DEDICATED
|
||||
#else
|
||||
MODULE g_mGameDll = MODULE("r5apex_ds.exe");
|
||||
#endif // !DEDICATED
|
||||
MODULE g_mRadVideoToolsDll = MODULE("bink2w64.dll");
|
||||
MODULE g_mRadAudioDecoderDll = MODULE("binkawin64.dll");
|
||||
MODULE g_mRadAudioSystemDll = MODULE("mileswin64.dll");
|
||||
}
|
||||
#endif // SDKLAUNCHER
|
||||
#endif // !SDKLAUNCHER
|
||||
|
@ -135,7 +135,7 @@
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>detours.lib;lzhamlib_x64D.lib;lzhamcomp_x64D.lib;lzhamdecomp_x64D.lib;d3d11.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>User32.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>del "..\..\..\$(ProjectName)" && copy /Y "$(TargetPath)" "..\..\..\</Command>
|
||||
@ -162,7 +162,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>detours.lib;lzhamlib_x64.lib;lzhamcomp_x64.lib;lzhamdecomp_x64.lib;d3d11.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>User32.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>del "..\..\..\$(ProjectName)" && copy /Y "$(TargetPath)" "..\..\..\</Command>
|
||||
@ -175,13 +175,13 @@
|
||||
<ClInclude Include="common\opcodes.h" />
|
||||
<ClInclude Include="common\protocol.h" />
|
||||
<ClInclude Include="common\psuedodefs.h" />
|
||||
<ClInclude Include="core\assert.h" />
|
||||
<ClInclude Include="core\init.h" />
|
||||
<ClInclude Include="core\logdef.h" />
|
||||
<ClInclude Include="core\r5dev.h" />
|
||||
<ClInclude Include="core\stdafx.h" />
|
||||
<ClInclude Include="ebisusdk\EbisuSDK.h" />
|
||||
<ClInclude Include="engine\baseclient.h" />
|
||||
<ClInclude Include="engine\baseclientstate.h" />
|
||||
<ClInclude Include="engine\host_cmd.h" />
|
||||
<ClInclude Include="engine\host_state.h" />
|
||||
<ClInclude Include="engine\net_chan.h" />
|
||||
@ -190,6 +190,7 @@
|
||||
<ClInclude Include="engine\sys_utils.h" />
|
||||
<ClInclude Include="launcher\IApplication.h" />
|
||||
<ClInclude Include="mathlib\adler32.h" />
|
||||
<ClInclude Include="mathlib\bits.h" />
|
||||
<ClInclude Include="mathlib\crc32.h" />
|
||||
<ClInclude Include="mathlib\IceKey.H" />
|
||||
<ClInclude Include="mathlib\parallel_for.h" />
|
||||
@ -216,7 +217,34 @@
|
||||
<ClInclude Include="thirdparty\detours\include\idetour.h" />
|
||||
<ClInclude Include="thirdparty\detours\include\syelog.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_assert.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_checksum.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_config.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_core.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_helpers.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_huffman_codes.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_lzbase.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_match_accel.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_math.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_mem.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_null_threading.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_platform.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_polar_codes.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_prefix_coding.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_pthreads_threading.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_static_lib.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_symbol_codec.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_threading.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_timer.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_traits.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_types.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_utils.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_vector.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_win32_threading.h" />
|
||||
<ClInclude Include="thirdparty\lzham\lzhamcomp\lzham_comp.h" />
|
||||
<ClInclude Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_internal.h" />
|
||||
<ClInclude Include="thirdparty\lzham\lzhamdecomp\lzham_decomp.h" />
|
||||
<ClInclude Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecompbase.h" />
|
||||
<ClInclude Include="thirdparty\spdlog\include\async.h" />
|
||||
<ClInclude Include="thirdparty\spdlog\include\async_logger-inl.h" />
|
||||
<ClInclude Include="thirdparty\spdlog\include\async_logger.h" />
|
||||
@ -312,6 +340,7 @@
|
||||
<ClInclude Include="thirdparty\spdlog\include\tweakme.h" />
|
||||
<ClInclude Include="thirdparty\spdlog\include\version.h" />
|
||||
<ClInclude Include="tier0\basetypes.h" />
|
||||
<ClInclude Include="tier0\commandline.h" />
|
||||
<ClInclude Include="tier0\ConCommand.h" />
|
||||
<ClInclude Include="tier0\completion.h" />
|
||||
<ClInclude Include="tier0\cvar.h" />
|
||||
@ -333,13 +362,13 @@
|
||||
<ClCompile Include="common\opcodes.cpp" />
|
||||
<ClCompile Include="core\dllmain.cpp" />
|
||||
<ClCompile Include="core\init.cpp" />
|
||||
<ClCompile Include="core\logdef.cpp" />
|
||||
<ClCompile Include="core\stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ebisusdk\EbisuSDK.cpp" />
|
||||
<ClCompile Include="engine\baseclient.cpp" />
|
||||
<ClCompile Include="engine\baseclientstate.cpp" />
|
||||
<ClCompile Include="engine\host_cmd.cpp" />
|
||||
<ClCompile Include="engine\host_state.cpp" />
|
||||
<ClCompile Include="engine\net_chan.cpp" />
|
||||
@ -348,6 +377,7 @@
|
||||
<ClCompile Include="engine\sys_utils.cpp" />
|
||||
<ClCompile Include="launcher\IApplication.cpp" />
|
||||
<ClCompile Include="mathlib\adler32.cpp" />
|
||||
<ClCompile Include="mathlib\bits.cpp" />
|
||||
<ClCompile Include="mathlib\crc32.cpp" />
|
||||
<ClCompile Include="mathlib\IceKey.cpp" />
|
||||
<ClCompile Include="networksystem\r5net.cpp" />
|
||||
@ -362,6 +392,103 @@
|
||||
<ClCompile Include="squirrel\sqapi.cpp" />
|
||||
<ClCompile Include="squirrel\sqinit.cpp" />
|
||||
<ClCompile Include="squirrel\sqvm.cpp" />
|
||||
<ClCompile Include="thirdparty\detours\src\creatwth.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\detours.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\disasm.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\modules.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_internal.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_state.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecomp.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecompbase.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_api.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_assert.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_checksum.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_huffman_codes.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_lzbase.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_match_accel.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_mem.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_platform.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_polar_codes.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_prefix_coding.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_pthreads_threading.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_symbol_codec.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_timer.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_vector.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_win32_threading.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tier0\commandline.cpp" />
|
||||
<ClCompile Include="tier0\ConCommand.cpp" />
|
||||
<ClCompile Include="tier0\completion.cpp" />
|
||||
<ClCompile Include="tier0\cvar.cpp" />
|
||||
|
@ -97,6 +97,18 @@
|
||||
<Filter Include="sdk\bsplib">
|
||||
<UniqueIdentifier>{8288ba1a-7609-42ef-af3b-850727635a99}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="thirdparty\lzham\lzhamcomp">
|
||||
<UniqueIdentifier>{8736d047-b4af-4c17-99ee-454cc96ec1ba}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="thirdparty\lzham\lzhamcomp\include">
|
||||
<UniqueIdentifier>{e84ad150-2358-4146-971a-02c5f045437c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="thirdparty\lzham\lzhamdecomp">
|
||||
<UniqueIdentifier>{eb98cd2b-4508-43a0-95e1-feacc7c83a8d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="thirdparty\lzham\lzhamdecomp\include">
|
||||
<UniqueIdentifier>{463e0739-1e5f-47a0-94d1-6cf5b6bf3ea6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="client\client.h">
|
||||
@ -126,9 +138,6 @@
|
||||
<ClInclude Include="ebisusdk\EbisuSDK.h">
|
||||
<Filter>sdk\ebisusdk</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="engine\baseclientstate.h">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="engine\host_state.h">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClInclude>
|
||||
@ -543,12 +552,6 @@
|
||||
<ClInclude Include="public\include\binstream.h">
|
||||
<Filter>sdk\public\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_static_lib.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mathlib\adler32.h">
|
||||
<Filter>sdk\mathlib</Filter>
|
||||
</ClInclude>
|
||||
@ -567,6 +570,102 @@
|
||||
<ClInclude Include="windows\system.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_config.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_core.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_helpers.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_huffman_codes.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_lzbase.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_match_accel.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_math.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_mem.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_null_threading.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_platform.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_polar_codes.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_prefix_coding.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_pthreads_threading.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_static_lib.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_symbol_codec.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_threading.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_timer.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_traits.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_types.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_utils.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_vector.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_win32_threading.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_assert.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_checksum.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\lzhamcomp\lzham_comp.h">
|
||||
<Filter>thirdparty\lzham\lzhamcomp\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_internal.h">
|
||||
<Filter>thirdparty\lzham\lzhamcomp\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\lzhamdecomp\lzham_decomp.h">
|
||||
<Filter>thirdparty\lzham\lzhamdecomp\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecompbase.h">
|
||||
<Filter>thirdparty\lzham\lzhamdecomp\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mathlib\bits.h">
|
||||
<Filter>sdk\mathlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="tier0\commandline.h">
|
||||
<Filter>sdk\tier0</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="core\assert.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="client\IVEngineClient.cpp">
|
||||
@ -608,9 +707,6 @@
|
||||
<ClCompile Include="engine\baseclient.cpp">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="engine\baseclientstate.cpp">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="launcher\IApplication.cpp">
|
||||
<Filter>sdk\launcher</Filter>
|
||||
</ClCompile>
|
||||
@ -698,6 +794,87 @@
|
||||
<ClCompile Include="windows\system.cpp">
|
||||
<Filter>windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\detours.cpp">
|
||||
<Filter>thirdparty\detours</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\disasm.cpp">
|
||||
<Filter>thirdparty\detours</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\modules.cpp">
|
||||
<Filter>thirdparty\detours</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\creatwth.cpp">
|
||||
<Filter>thirdparty\detours</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_assert.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_checksum.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_huffman_codes.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_lzbase.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_match_accel.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_mem.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_platform.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_polar_codes.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_prefix_coding.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_pthreads_threading.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_symbol_codec.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_timer.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_vector.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_win32_threading.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_api.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp.cpp">
|
||||
<Filter>thirdparty\lzham\lzhamcomp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_internal.cpp">
|
||||
<Filter>thirdparty\lzham\lzhamcomp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_state.cpp">
|
||||
<Filter>thirdparty\lzham\lzhamcomp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecomp.cpp">
|
||||
<Filter>thirdparty\lzham\lzhamdecomp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecompbase.cpp">
|
||||
<Filter>thirdparty\lzham\lzhamdecomp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mathlib\bits.cpp">
|
||||
<Filter>sdk\mathlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tier0\commandline.cpp">
|
||||
<Filter>sdk\tier0</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="core\logdef.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="r5dev.def" />
|
||||
|
@ -9,9 +9,9 @@
|
||||
void HEbisuSDK_Init()
|
||||
{
|
||||
#ifdef DEDICATED
|
||||
*(char*)g_bEbisuSDKInitialized.GetPtr() = (char)0x1; // <- 1st EbisuSDK
|
||||
*(char*)g_bEbisuSDKCvarInitialized.GetPtr() = (char)0x1; // <- 2nd EbisuSDK
|
||||
*(char*)g_qEbisuSDKCvarInitialized.GetPtr() = (char)0x1; // <- 3rd EbisuSDK
|
||||
*(char*)g_bEbisuSDKInitialized = (char)0x1; // <- 1st EbisuSDK
|
||||
*(char*)g_bEbisuSDKCvarInitialized = (char)0x1; // <- 2nd EbisuSDK
|
||||
*(char*)g_qEbisuSDKCvarInitialized = (char)0x1; // <- 3rd EbisuSDK
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
namespace
|
||||
{
|
||||
#ifdef DEDICATED
|
||||
ADDRESS p_EbisuSDK_Init_Tier0 = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x80\x3D\x00\x00\x00\x00\x00\x0F\x85\x00\x02\x00\x00\x48\x89\x5C\x24\x20", "xxxxxx????xxx?xxxxxxxx").GetPtr();
|
||||
ADDRESS p_EbisuSDK_Init_Tier0 = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x80\x3D\x00\x00\x00\x00\x00\x0F\x85\x00\x02\x00\x00\x48\x89\x5C\x24\x20", "xxxxxx????xxx?xxxxxxxx");
|
||||
void(*EbisuSDK_Init_Tier0) = (void(*))p_EbisuSDK_Init_Tier0.GetPtr(); /*48 83 EC 28 80 3D ?? ?? ?? ?? 00 0F 85 ?? 02 00 00 48 89 5C 24 20*/
|
||||
|
||||
ADDRESS p_EbisuSDK_CVar_Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x57\x48\x83\xEC\x40\x83\x3D", "xxxxxxxx");
|
||||
@ -14,27 +14,13 @@ namespace
|
||||
|
||||
ADDRESS p_EbisuSDK_SetState = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x81\xEC\x00\x00\x00\x00\x80\x3D\x00\x00\x00\x00\x00\x0F\x84\x00\x00\x00\x00\x80\x3D\x00\x00\x00\x00\x00\x74\x5B", "xxx????xx?????xx????xx?????xx");
|
||||
void(*EbisuSDK_SetState) = (void(*))p_EbisuSDK_SetState.GetPtr(); /*48 81 EC ? ? ? ? 80 3D ? ? ? ? ? 0F 84 ? ? ? ? 80 3D ? ? ? ? ? 74 5B*/
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
#ifdef DEDICATED
|
||||
#if defined (GAMEDLL_S1)
|
||||
ADDRESS g_bEbisuSDKInitialized = p_EbisuSDK_Init_Tier0.FindPatternSelf("80 3D ?? ?? ?? ?? 00", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).GetPtr();
|
||||
ADDRESS g_bEbisuSDKCvarInitialized = p_Host_Map_f_CompletionFunc.FindPatternSelf("80 3D 8F 7C 1E 22 00", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).GetPtr();
|
||||
ADDRESS g_qEbisuSDKCvarInitialized = p_EbisuSDK_CVar_Init.FindPatternSelf("4C 89 05 C4 2B 0E 22", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr();
|
||||
#elif defined (GAMEDLL_S2)
|
||||
ADDRESS g_bEbisuSDKInitialized = p_EbisuSDK_Init_Tier0.FindPatternSelf("80 3D ?? ?? ?? ?? 00", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).GetPtr();
|
||||
ADDRESS g_bEbisuSDKCvarInitialized = p_Host_Map_f_CompletionFunc.FindPatternSelf("80 3D 43 2D 41 22 00", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).GetPtr();
|
||||
ADDRESS g_qEbisuSDKCvarInitialized = p_EbisuSDK_CVar_Init.FindPatternSelf("4C 89 05 74 2D 32 22", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr();
|
||||
#elif defined (GAMEDLL_S3)
|
||||
ADDRESS g_bEbisuSDKInitialized = p_EbisuSDK_Init_Tier0.FindPatternSelf("80 3D ?? ?? ?? ?? 00", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).GetPtr();
|
||||
ADDRESS g_bEbisuSDKCvarInitialized = p_Host_Map_f_CompletionFunc.FindPatternSelf("80 3D 23 54 2B 23 00", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).GetPtr();
|
||||
ADDRESS g_qEbisuSDKCvarInitialized = p_EbisuSDK_CVar_Init.FindPatternSelf("4C 89 05 B4 2C 1C 23", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr();
|
||||
#endif // GAMEDLL_*
|
||||
bool* g_bEbisuSDKInitialized = p_EbisuSDK_Init_Tier0.Offset(0x0).FindPatternSelf("80 3D", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>();
|
||||
bool* g_bEbisuSDKCvarInitialized = p_EbisuSDK_CVar_Init.Offset(0x12A).FindPatternSelf("C6 05", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>();
|
||||
bool* g_qEbisuSDKCvarInitialized = p_EbisuSDK_CVar_Init.Offset(0x20).FindPatternSelf("4C 89 05", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<bool*>();
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void HEbisuSDK_Init();
|
||||
|
||||
@ -51,9 +37,9 @@ class HEbisuSDK : public IDetour
|
||||
std::cout << "| FUN: EbisuSDK_Init_Tier0 : 0x" << std::hex << std::uppercase << p_EbisuSDK_Init_Tier0.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: EbisuSDK_CVar_Init : 0x" << std::hex << std::uppercase << p_EbisuSDK_CVar_Init.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: EbisuSDK_SetState : 0x" << std::hex << std::uppercase << p_EbisuSDK_SetState.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| VAR: g_bEbisuSDKInitialized : 0x" << std::hex << std::uppercase << g_bEbisuSDKInitialized.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| VAR: g_bEbisuSDKCvarInitialized : 0x" << std::hex << std::uppercase << g_bEbisuSDKCvarInitialized.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| VAR: g_qEbisuSDKCvarInitialized : 0x" << std::hex << std::uppercase << g_qEbisuSDKCvarInitialized.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| VAR: g_bEbisuSDKInitialized : 0x" << std::hex << std::uppercase << g_bEbisuSDKInitialized << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "| VAR: g_bEbisuSDKCvarInitialized : 0x" << std::hex << std::uppercase << g_bEbisuSDKCvarInitialized << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "| VAR: g_qEbisuSDKCvarInitialized : 0x" << std::hex << std::uppercase << g_qEbisuSDKCvarInitialized << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
#endif // DEDICATED
|
||||
}
|
||||
|
@ -5,5 +5,49 @@
|
||||
//===========================================================================//
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "client/cdll_engine_int.h"
|
||||
#include "engine/debugoverlay.h"
|
||||
#include "engine/baseclientstate.h"
|
||||
//TODO
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: returns true if client simulation is paused
|
||||
//------------------------------------------------------------------------------
|
||||
bool CBaseClientState::IsPaused()
|
||||
{
|
||||
return *m_bPaused;
|
||||
}
|
||||
|
||||
// Technically doesn't belong here.
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: gets the client time
|
||||
//------------------------------------------------------------------------------
|
||||
float CBaseClientState::GetClientTime()
|
||||
{
|
||||
if (*scr_drawloading)
|
||||
{
|
||||
return (float)(int)*host_tickcount * (float)*client_debugdraw_int_unk;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *(float*)client_debugdraw_float_unk;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: gets the client simulation tick count
|
||||
//------------------------------------------------------------------------------
|
||||
int CBaseClientState::GetClientTickCount() const
|
||||
{
|
||||
return *host_tickcount;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: sets the client simulation tick count
|
||||
//------------------------------------------------------------------------------
|
||||
void CBaseClientState::SetClientTickCount(int tick)
|
||||
{
|
||||
*host_tickcount = tick;
|
||||
}
|
||||
|
||||
CBaseClientState* g_pBaseClientState = new CBaseClientState();
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "tier0/basetypes.h"
|
||||
#include "engine/debugoverlay.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -16,6 +17,30 @@ namespace
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
bool* cl_m_bPaused = p_DrawAllOverlays.Offset(0x90).FindPatternSelf("80 3D ? ? ? 0B ?", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x2).RCast<bool*>();
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
bool* cl_m_bPaused = p_DrawAllOverlays.Offset(0x70).FindPatternSelf("80 3D ? ? ? 01 ?", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x7).RCast<bool*>();
|
||||
#endif
|
||||
int* cl_host_tickcount = p_DrawAllOverlays.Offset(0xC0).FindPatternSelf("66 0F 6E", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x4, 0x8).RCast<int*>();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class CBaseClientState
|
||||
{
|
||||
public:
|
||||
bool* m_bPaused = cl_m_bPaused; // pauzes the client side simulation in apex.
|
||||
int* host_tickcount = cl_host_tickcount; // client simulation tick count.
|
||||
|
||||
bool IsPaused();
|
||||
float GetClientTime();
|
||||
int GetClientTickCount() const; // Get the client tick count.
|
||||
void SetClientTickCount(int tick); // Set the client tick count.
|
||||
};
|
||||
|
||||
extern CBaseClientState* g_pBaseClientState;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class HClientState : public IDetour
|
||||
@ -23,7 +48,9 @@ class HClientState : public IDetour
|
||||
virtual void debugp()
|
||||
{
|
||||
//std::cout << "| FUN: CClientState::CheckForResend : 0x" << std::hex << std::uppercase << p_CClientState__CheckForResend.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
//std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| VAR: cl_m_bPaused : 0x" << std::hex << std::uppercase << cl_m_bPaused << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "| FUN: cl_host_tickcount : 0x" << std::hex << std::uppercase << cl_host_tickcount << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
}
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
144
r5dev/engine/debugoverlay.h
Normal file
144
r5dev/engine/debugoverlay.h
Normal file
@ -0,0 +1,144 @@
|
||||
#pragma once
|
||||
#include "mathlib/vector.h"
|
||||
#include "mathlib/color.h"
|
||||
|
||||
// Something has to be hardcoded..
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
|
||||
constexpr auto MATERIALSYSTEM_VCALL_OFF_0 = 0x3F8;
|
||||
constexpr auto CMATQUEUEDRENDERCONTEXT_VCALL_OFS_0 = 0x278;
|
||||
constexpr auto CMATQUEUEDRENDERCONTEXT_VCALL_OFS_1 = 0x280;
|
||||
|
||||
#elif defined (GAMEDLL_S3)
|
||||
|
||||
constexpr auto MATERIALSYSTEM_VCALL_OFF_0 = 0x3F0;
|
||||
constexpr auto CMATQUEUEDRENDERCONTEXT_VCALL_OFS_0 = 0x288;
|
||||
constexpr auto CMATQUEUEDRENDERCONTEXT_VCALL_OFS_1 = 0x290;
|
||||
|
||||
#endif
|
||||
constexpr auto CMATQUEUEDRENDERCONTEXT_VCALL_OFS_2 = 0x8;
|
||||
constexpr auto NDEBUG_PERSIST_TILL_NEXT_SERVER = (0.01023f);
|
||||
|
||||
enum class OverlayType_t
|
||||
{
|
||||
OVERLAY_BOX = 0,
|
||||
OVERLAY_SPHERE,
|
||||
OVERLAY_LINE,
|
||||
OVERLAY_TRIANGLE,
|
||||
OVERLAY_SWEPT_BOX,
|
||||
OVERLAY_BOX2,
|
||||
OVERLAY_CAPSULE,
|
||||
OVERLAY_UNK0,
|
||||
OVERLAY_UNK1
|
||||
};
|
||||
|
||||
struct OverlayBase_t
|
||||
{
|
||||
OverlayBase_t()
|
||||
{
|
||||
m_Type = OverlayType_t::OVERLAY_BOX;
|
||||
m_nServerCount = -1;
|
||||
m_nCreationTick = -1;
|
||||
m_flEndTime = 0.0f;
|
||||
m_pNextOverlay = NULL;
|
||||
unk0 = NULL;
|
||||
}
|
||||
bool IsDead();
|
||||
|
||||
OverlayType_t m_Type {}; // What type of overlay is it?
|
||||
int m_nCreationTick{}; // Duration -1 means go away after this frame #
|
||||
float m_nServerCount {}; // Latch server count, too
|
||||
float m_flEndTime {}; // When does this box go away
|
||||
OverlayBase_t* m_pNextOverlay {}; // 16
|
||||
int64_t unk0 {}; // 24
|
||||
};
|
||||
|
||||
struct OverlayLine_t : public OverlayBase_t
|
||||
{
|
||||
OverlayLine_t() { m_Type = OverlayType_t::OVERLAY_LINE; }
|
||||
|
||||
Vector3 origin{};
|
||||
Vector3 dest{};
|
||||
int r{};
|
||||
int g{};
|
||||
int b{};
|
||||
int a{};
|
||||
bool noDepthTest{};
|
||||
};
|
||||
|
||||
struct OverlayBox_t : public OverlayBase_t
|
||||
{
|
||||
OverlayBox_t() { m_Type = OverlayType_t::OVERLAY_BOX; }
|
||||
|
||||
Vector3 origin{};
|
||||
Vector3 mins{};
|
||||
Vector3 maxs{};
|
||||
QAngle angles{};
|
||||
int r{};
|
||||
int g{};
|
||||
int b{};
|
||||
int a{};
|
||||
};
|
||||
|
||||
void HDestroyOverlay(OverlayBase_t* pOverlay);
|
||||
void DrawOverlay(OverlayBase_t* pOverlay);
|
||||
void DebugOverlays_Attach();
|
||||
void DebugOverlays_Detach();
|
||||
|
||||
namespace
|
||||
{
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
ADDRESS p_DrawAllOverlays = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x55\x48\x83\xEC\x50\x48\x8B\x05\x00\x00\x00\x00", "xxxxxxxxx????");
|
||||
void (*DrawAllOverlays)(char a1) = (void (*)(char))p_DrawAllOverlays.GetPtr(); /*40 55 48 83 EC 50 48 8B 05 ? ? ? ?*/
|
||||
|
||||
ADDRESS p_RenderBox = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x44\x89\x4C\x24\x00", "xxxx?xxxx?xxxx?"); /*48 89 5C 24 ? 48 89 6C 24 ? 44 89 4C 24 ?*/
|
||||
void* (*RenderBox)(Vector3 origin, QAngle angles, Vector3 vMins, Vector3 vMaxs, Color color, bool bZBuffer) = (void* (*)(Vector3, QAngle, Vector3, Vector3, Color, bool))p_RenderBox.GetPtr();
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
ADDRESS p_DrawAllOverlays = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x55\x48\x83\xEC\x30\x48\x8B\x05\x00\x00\x00\x00\x0F\xB6\xE9", "xxxxxxxxx????xxx");
|
||||
void (*DrawAllOverlays)(char a1) = (void (*)(char))p_DrawAllOverlays.GetPtr(); /*40 55 48 83 EC 30 48 8B 05 ? ? ? ? 0F B6 E9*/
|
||||
|
||||
ADDRESS p_RenderBox = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x44\x89\x4C\x24\x00", "xxxx?xxxx?xxxx?"); /*48 89 5C 24 ? 48 89 6C 24 ? 44 89 4C 24 ?*/
|
||||
void* (*RenderBox)(Vector3 origin, QAngle angles, Vector3 vMins, Vector3 vMaxs, Color color, bool bZBuffer) = (void* (*)(Vector3, QAngle, Vector3, Vector3, Color, bool))p_RenderBox.GetPtr();
|
||||
#endif
|
||||
ADDRESS p_RenderLine = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x74\x24\x00\x44\x89\x44\x24\x00\x57\x41\x56", "xxxx?xxxx?xxx"); /*48 89 74 24 ? 44 89 44 24 ? 57 41 56*/
|
||||
void* (*RenderLine)(Vector3 origin, Vector3 dest, Color color, bool bZBuffer) = (void* (*)(Vector3, Vector3, Color, bool))p_RenderLine.GetPtr();
|
||||
|
||||
ADDRESS p_DestroyOverlay = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x48\x8B\xD9\x48\x8D\x0D\x00\x00\x00\x00\xFF\x15\x00\x00\x00\x00\x48\x63\x03", "xxxxxxxxxxxx????xx????xxx");
|
||||
void (*DestroyOverlay)(void* pOverlay) = (void (*)(void*))p_DestroyOverlay.GetPtr(); /*40 53 48 83 EC 20 48 8B D9 48 8D 0D ? ? ? ? FF 15 ? ? ? ? 48 63 03 */
|
||||
|
||||
int* client_debugdraw_int_unk = p_DrawAllOverlays.Offset(0xC0).FindPatternSelf("F3 0F 59", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x4, 0x8).RCast<int*>();
|
||||
float* client_debugdraw_float_unk = p_DrawAllOverlays.Offset(0xD0).FindPatternSelf("F3 0F 10", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x4, 0x8).RCast<float*>();
|
||||
|
||||
OverlayBase_t** s_pOverlays = p_DrawAllOverlays.Offset(0x10).FindPatternSelf("48 8B 3D", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<OverlayBase_t**>();
|
||||
LPCRITICAL_SECTION s_OverlayMutex = p_DrawAllOverlays.Offset(0x10).FindPatternSelf("48 8D 0D", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast<LPCRITICAL_SECTION>();
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
int* render_tickcount = p_DrawAllOverlays.Offset(0x80).FindPatternSelf("3B 0D", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
int* overlay_tickcount = p_DrawAllOverlays.Offset(0x70).FindPatternSelf("3B 0D", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
int* render_tickcount = p_DrawAllOverlays.Offset(0x50).FindPatternSelf("3B 05", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
int* overlay_tickcount = p_DrawAllOverlays.Offset(0x70).FindPatternSelf("3B 05", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class HDebugOverlay : public IDetour
|
||||
{
|
||||
virtual void debugp()
|
||||
{
|
||||
std::cout << "| FUN: DrawAllOverlays : 0x" << std::hex << std::uppercase << p_DrawAllOverlays.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: RenderBox : 0x" << std::hex << std::uppercase << p_RenderBox.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: RenderLine : 0x" << std::hex << std::uppercase << p_RenderLine.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: DestroyOverlay : 0x" << std::hex << std::uppercase << p_DestroyOverlay.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| VAR: s_pOverlays : 0x" << std::hex << std::uppercase << s_pOverlays << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "| VAR: s_OverlayMutex : 0x" << std::hex << std::uppercase << s_OverlayMutex << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "| VAR: client_debugdraw_int_unk : 0x" << std::hex << std::uppercase << client_debugdraw_int_unk << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "| VAR: client_debugdraw_float_unk : 0x" << std::hex << std::uppercase << client_debugdraw_float_unk << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "| VAR: overlay_tickcount : 0x" << std::hex << std::uppercase << overlay_tickcount << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "| VAR: render_tickcount : 0x" << std::hex << std::uppercase << render_tickcount << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
}
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
REGISTER(HDebugOverlay);
|
@ -10,6 +10,8 @@ namespace
|
||||
ADDRESS p_Host_Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x48\x89\x7C\x24\x00\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x00\x00\x00\x00\xB8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x2B\xE0\x48\x8B\xD9", "xxxx?xxxx?xxxx?xxxxxxxxxxxxx????x????x????xxxxxx");
|
||||
void* (*Host_Init)(bool* bDedicated) = (void* (*)(bool*))p_Host_Init.GetPtr(); /*48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? B8 ? ? ? ? E8 ? ? ? ? 48 2B E0 48 8B D9*/
|
||||
#endif
|
||||
ADDRESS p_malloc_internal = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xE9\x00\x00\x00\x00\xCC\xCC\xCC\x40\x53\x48\x83\xEC\x20\x48\x8D\x05\x00\x00\x00\x00", "x????xxxxxxxxxxxx????");
|
||||
void* (*malloc_internal)(void* pPool, int64_t size) = (void* (*)(void*, int64_t))p_malloc_internal.GetPtr(); /*E9 ? ? ? ? CC CC CC 40 53 48 83 EC 20 48 8D 05 ? ? ? ?*/
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -27,6 +29,7 @@ class HHostCmd : public IDetour
|
||||
virtual void debugp()
|
||||
{
|
||||
std::cout << "| FUN: Host_Init : 0x" << std::hex << std::uppercase << p_Host_Init.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: malloc_internal : 0x" << std::hex << std::uppercase << p_malloc_internal.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| VAR: g_pMallocPool : 0x" << std::hex << std::uppercase << g_pMallocPool.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "tier0/cvar.h"
|
||||
#include "tier0/commandline.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "engine/host_state.h"
|
||||
#include "engine/net_chan.h"
|
||||
#include "tier0/cvar.h"
|
||||
#include "client/IVEngineClient.h"
|
||||
#include "networksystem/r5net.h"
|
||||
#include "squirrel/sqinit.h"
|
||||
#include "public/include/bansystem.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Send keep alive request to Pylon Master Server.
|
||||
@ -13,20 +15,24 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
void KeepAliveToPylon()
|
||||
{
|
||||
if (g_pHostState->m_bActiveGame && sv_pylonvisibility->m_iValue == 1) // Check for active game.
|
||||
if (g_pHostState->m_bActiveGame && sv_pylonvisibility->GetBool()) // Check for active game.
|
||||
{
|
||||
std::string m_szHostToken = std::string();
|
||||
std::string m_szHostRequestMessage = std::string();
|
||||
DevMsg(eDLL_T::CLIENT, "Sending PostServerHost request\n");
|
||||
bool result = g_pR5net->PostServerHost(m_szHostRequestMessage, m_szHostToken,
|
||||
ServerListing{
|
||||
g_pCvar->FindVar("hostname")->m_pzsCurrentValue,
|
||||
g_pCVar->FindVar("hostname")->GetString(),
|
||||
std::string(g_pHostState->m_levelName),
|
||||
"",
|
||||
g_pCvar->FindVar("hostport")->m_pzsCurrentValue,
|
||||
g_pCvar->FindVar("mp_gamemode")->m_pzsCurrentValue,
|
||||
g_pCVar->FindVar("hostport")->GetString(),
|
||||
g_pCVar->FindVar("mp_gamemode")->GetString(),
|
||||
false,
|
||||
std::to_string(*g_nRemoteFunctionCallsChecksum), // BUG BUG: Checksum is null on dedi
|
||||
|
||||
// BUG BUG: Checksum is null on dedi
|
||||
// ADDITIONAL NOTES: seems to be related to scripts, this also happens when the listen server is started but the client from the same process never connects.
|
||||
// Checksum only gets set on the server if the client from its own process connects to it.
|
||||
std::to_string(*g_nRemoteFunctionCallsChecksum),
|
||||
std::string(),
|
||||
g_szNetKey.c_str()
|
||||
}
|
||||
@ -34,6 +40,66 @@ void KeepAliveToPylon()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check refuse list and kill netchan connection.
|
||||
//-----------------------------------------------------------------------------
|
||||
void BanListCheck()
|
||||
{
|
||||
if (g_pBanSystem->IsRefuseListValid())
|
||||
{
|
||||
for (int i = 0; i < g_pBanSystem->vsvrefuseList.size(); i++) // Loop through vector.
|
||||
{
|
||||
for (int c = 0; c < MAX_PLAYERS; c++) // Loop through all possible client instances.
|
||||
{
|
||||
CClient* client = g_pClient->GetClientInstance(c); // Get client instance.
|
||||
if (!client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!client->GetNetChan()) // Netchan valid?
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_pClient->m_iOriginID != g_pBanSystem->vsvrefuseList[i].second) // See if nucleus id matches entry.
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string finalIpAddress = std::string();
|
||||
ADDRESS ipAddressField = ADDRESS(((std::uintptr_t)client->GetNetChan()) + 0x1AC0); // Get client ip from netchan.
|
||||
if (ipAddressField && ipAddressField.GetValue<int>() != 0x0)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::to_string(ipAddressField.GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x1).GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x2).GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x3).GetValue<std::uint8_t>());
|
||||
|
||||
finalIpAddress = ss.str();
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::SERVER, "\n");
|
||||
DevMsg(eDLL_T::SERVER, "______________________________________________________________\n");
|
||||
DevMsg(eDLL_T::SERVER, "] PYLON NOTICE -----------------------------------------------\n");
|
||||
DevMsg(eDLL_T::SERVER, "] OriginID : | '%lld' IS GETTING DISCONNECTED.\n", g_pClient->m_iOriginID);
|
||||
if (finalIpAddress.empty())
|
||||
DevMsg(eDLL_T::SERVER, "] IP-ADDR : | CLIENT MODIFIED PACKET.\n");
|
||||
else
|
||||
DevMsg(eDLL_T::SERVER, "] IP-ADDR : | '%s'\n", finalIpAddress.c_str());
|
||||
DevMsg(eDLL_T::SERVER, "--------------------------------------------------------------\n");
|
||||
DevMsg(eDLL_T::SERVER, "\n");
|
||||
|
||||
g_pBanSystem->AddEntry(finalIpAddress, g_pClient->m_iOriginID); // Add local entry to reserve a non needed request.
|
||||
g_pBanSystem->Save(); // Save list.
|
||||
NET_DisconnectClient(g_pClient, c, g_pBanSystem->vsvrefuseList[i].first.c_str(), 0, 1); // Disconnect client.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: state machine's main processing loop
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -64,17 +130,29 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
|
||||
static bool bInitialized = false;
|
||||
if (!bInitialized)
|
||||
{
|
||||
IConVar_ClearHostNames();
|
||||
ConCommand_InitConCommand();
|
||||
g_pConCommand->Init();
|
||||
g_pConVar->ClearHostNames();
|
||||
|
||||
|
||||
if (!g_pCmdLine->CheckParm("-devsdk"))
|
||||
{
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_server.cfg");
|
||||
#ifndef DEDICATED
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_client.cfg");
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
else // Development configs.
|
||||
{
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_dev.cfg");
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_server_dev.cfg");
|
||||
#ifndef DEDICATED
|
||||
IVEngineClient_CommandExecute(NULL, "exec autoexec_client_dev.cfg");
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
*(bool*)m_bRestrictServerCommands = true; // Restrict commands.
|
||||
ConCommandBase* disconnect = (ConCommandBase*)g_pCvar->FindCommand("disconnect");
|
||||
ConCommandBase* disconnect = (ConCommandBase*)g_pCVar->FindCommand("disconnect");
|
||||
disconnect->AddFlags(FCVAR_SERVER_CAN_EXECUTE); // Make sure server is not restricted to this.
|
||||
|
||||
static std::thread PylonThread([]() // Pylon request thread.
|
||||
@ -86,12 +164,21 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
|
||||
}
|
||||
});
|
||||
|
||||
if (net_userandomkey->m_pParent->m_iValue == 1)
|
||||
static std::thread BanlistThread([]()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
BanListCheck();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
}
|
||||
});
|
||||
|
||||
if (net_userandomkey->GetBool())
|
||||
{
|
||||
HNET_GenerateKey();
|
||||
}
|
||||
|
||||
g_pCvar->FindVar("net_usesocketsforloopback")->m_pParent->m_iValue = 1;
|
||||
g_pCVar->FindVar("net_usesocketsforloopback")->SetValue(1);
|
||||
|
||||
bInitialized = true;
|
||||
}
|
||||
@ -111,6 +198,7 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
|
||||
{
|
||||
Cbuf_ExecuteFn();
|
||||
oldState = g_pHostState->m_iCurrentState;
|
||||
|
||||
switch (g_pHostState->m_iCurrentState)
|
||||
{
|
||||
case HostStates_t::HS_NEW_GAME:
|
||||
@ -159,7 +247,7 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
|
||||
g_pHostState->m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run.
|
||||
|
||||
// If our next state isn't a shutdown or its a forced shutdown then set next state to run.
|
||||
if (g_pHostState->m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCvar->FindVar("host_hasIrreversibleShutdown")->m_pParent->m_iValue)
|
||||
if (g_pHostState->m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCVar->FindVar("host_hasIrreversibleShutdown")->GetBool())
|
||||
{
|
||||
g_pHostState->m_iNextState = HostStates_t::HS_RUN;
|
||||
}
|
||||
@ -189,7 +277,7 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
|
||||
g_pHostState->m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run.
|
||||
|
||||
// If our next state isn't a shutdown or its a forced shutdown then set next state to run.
|
||||
if (g_pHostState->m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCvar->FindVar("host_hasIrreversibleShutdown")->m_pParent->m_iValue)
|
||||
if (g_pHostState->m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCVar->FindVar("host_hasIrreversibleShutdown")->GetBool())
|
||||
{
|
||||
g_pHostState->m_iNextState = HostStates_t::HS_RUN;
|
||||
}
|
||||
@ -222,7 +310,7 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
|
||||
g_pHostState->m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run.
|
||||
|
||||
// If our next state isn't a shutdown or its a forced shutdown then set next state to run.
|
||||
if (g_pHostState->m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCvar->FindVar("host_hasIrreversibleShutdown")->m_pParent->m_iValue)
|
||||
if (g_pHostState->m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCVar->FindVar("host_hasIrreversibleShutdown")->GetBool())
|
||||
{
|
||||
g_pHostState->m_iNextState = HostStates_t::HS_RUN;
|
||||
}
|
||||
@ -262,7 +350,7 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time)
|
||||
}
|
||||
}
|
||||
|
||||
} while ((oldState != HostStates_t::HS_RUN || g_pHostState->m_iNextState == HostStates_t::HS_LOAD_GAME && g_pCvar->FindVar("g_single_frame_shutdown_for_reload_cvar")->m_pParent->m_iValue)
|
||||
} while ((oldState != HostStates_t::HS_RUN || g_pHostState->m_iNextState == HostStates_t::HS_LOAD_GAME && g_pCVar->FindVar("g_single_frame_shutdown_for_reload_cvar")->GetBool())
|
||||
&& oldState != HostStates_t::HS_SHUTDOWN
|
||||
&& oldState != HostStates_t::HS_RESTART);
|
||||
|
||||
|
@ -22,7 +22,9 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
void HNET_ShutDown(void* thisptr, const char* szReason, std::uint8_t a1, char a2)
|
||||
{
|
||||
#ifndef GAMEDLL_S1 // TODO
|
||||
DownloadPlaylists_f_CompletionFunc(); // Re-load playlist from disk after getting disconnected from the server.
|
||||
#endif
|
||||
NET_Shutdown(thisptr, szReason, a1, a2);
|
||||
}
|
||||
|
||||
@ -76,7 +78,7 @@ void HNET_SetKey(std::string svNetKey)
|
||||
void HNET_GenerateKey()
|
||||
{
|
||||
g_szNetKey.clear();
|
||||
net_userandomkey->m_pParent->m_iValue = 1;
|
||||
net_userandomkey->SetValue(1);
|
||||
|
||||
BCRYPT_ALG_HANDLE hAlgorithm;
|
||||
if (BCryptOpenAlgorithmProvider(&hAlgorithm, L"RNG", 0, 0) < 0)
|
||||
@ -181,4 +183,4 @@ void CNetChan_Trace_Detach()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
std::string g_szNetKey = "WDNWLmJYQ2ZlM0VoTid3Yg==";
|
||||
std::uintptr_t g_pNetKey = g_mGameDll.StringSearch("client:NetEncryption_NewKey").FindPatternSelf("48 8D ? ? ? ? ? 48 3B", ADDRESS::Direction::UP, 150).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr();
|
||||
std::uintptr_t g_pNetKey = g_mGameDll.StringSearch("client:NetEncryption_NewKey").FindPatternSelf("48 8D ? ? ? ? ? 48 3B", ADDRESS::Direction::UP, 300).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr();
|
||||
|
@ -7,7 +7,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
int HSys_Error_Internal(char* fmt, va_list args)
|
||||
{
|
||||
printf("\n_____________________________________________________________\n");
|
||||
printf("\n______________________________________________________________\n");
|
||||
printf("] ENGINE ERROR ################################################\n");
|
||||
vprintf(fmt, args);
|
||||
|
||||
|
@ -29,7 +29,7 @@ class HSys_Dll2 : public IDetour
|
||||
{
|
||||
virtual void debugp()
|
||||
{
|
||||
std::cout << "| FUN: CEngineAPI_Connect : 0x" << std::hex << std::uppercase << p_CEngineAPI_Connect.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: CEngineAPI::Connect : 0x" << std::hex << std::uppercase << p_CEngineAPI_Connect.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: PakFile_Init : 0x" << std::hex << std::uppercase << p_PakFile_Init.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| VAR: g_pMapVPKCache : 0x" << std::hex << std::uppercase << g_pMapVPKCache.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
|
@ -1,18 +1,23 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "core/logdef.h"
|
||||
#include "tier0/commandline.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#ifndef DEDICATED
|
||||
#include "vgui/CEngineVGui.h"
|
||||
#include "gameui/IConsole.h"
|
||||
#endif // !DEDICATED
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sys_Error
|
||||
//
|
||||
// Purpose: Exit engine with error
|
||||
// Input : *error -
|
||||
// ... -
|
||||
// Output : void Sys_Error
|
||||
//-----------------------------------------------------------------------------
|
||||
void HSys_Error(char* fmt, ...)
|
||||
{
|
||||
static char buf[1024];
|
||||
static char buf[1024] = {};
|
||||
|
||||
va_list args;
|
||||
va_list args{};
|
||||
va_start(args, fmt);
|
||||
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
@ -25,39 +30,16 @@ void HSys_Error(char* fmt, ...)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sys_Print
|
||||
//
|
||||
// Purpose: Show warning in the console, exit engine with error when level 5
|
||||
// Input : level -
|
||||
// *error - ... -
|
||||
// Output : void* Sys_Warning
|
||||
//-----------------------------------------------------------------------------
|
||||
void DevMsg(eDLL_T idx, const char* fmt, ...)
|
||||
void* HSys_Warning(int level, char* fmt, ...)
|
||||
{
|
||||
int vmIdx = (int)idx;
|
||||
static bool initialized = false;
|
||||
static char buf[1024];
|
||||
static char buf[1024] = {};
|
||||
|
||||
static std::string vmType[7] = { "Native(S):", "Native(C):", "Native(U):", "Native(E):", "Native(F):", "Native(R):", "Native(M):" };
|
||||
|
||||
static auto iconsole = spdlog::stdout_logger_mt("sys_print_iconsole"); // in-game console.
|
||||
static auto wconsole = spdlog::stdout_logger_mt("sys_print_wconsole"); // windows console.
|
||||
static auto sqlogger = spdlog::basic_logger_mt("sys_print_logger", "platform\\logs\\sys_print.log"); // file logger.
|
||||
|
||||
std::string vmStr = vmType[vmIdx].c_str();
|
||||
|
||||
g_spd_sys_w_oss.str("");
|
||||
g_spd_sys_w_oss.clear();
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
iconsole = std::make_shared<spdlog::logger>("sys_print_ostream", g_spd_sys_p_ostream_sink);
|
||||
iconsole->set_pattern("[%S.%e] %v");
|
||||
iconsole->set_level(spdlog::level::debug);
|
||||
wconsole->set_pattern("[%S.%e] %v");
|
||||
wconsole->set_level(spdlog::level::debug);
|
||||
sqlogger->set_pattern("[%S.%e] %v");
|
||||
sqlogger->set_level(spdlog::level::debug);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_list args{};
|
||||
va_start(args, fmt);
|
||||
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
@ -65,24 +47,65 @@ void DevMsg(eDLL_T idx, const char* fmt, ...)
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
|
||||
DevMsg(eDLL_T::NONE, "Warning(%d)%s\n", level, buf); // TODO: Color
|
||||
return Sys_Warning(level, buf);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Show logs to all console interfaces
|
||||
// Input : idx -
|
||||
// *fmt - ... -
|
||||
// Output : void DevMsg
|
||||
//-----------------------------------------------------------------------------
|
||||
void DevMsg(eDLL_T idx, const char* fmt, ...)
|
||||
{
|
||||
static char buf[1024] = {};
|
||||
|
||||
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
|
||||
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
|
||||
static std::shared_ptr<spdlog::logger> sqlogger = spdlog::get("dev_message_logger");
|
||||
|
||||
{/////////////////////////////
|
||||
va_list args{};
|
||||
va_start(args, fmt);
|
||||
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
}/////////////////////////////
|
||||
|
||||
std::string vmStr = sDLL_T[(int)idx].c_str();
|
||||
vmStr.append(buf);
|
||||
|
||||
iconsole->debug(vmStr);
|
||||
wconsole->debug(vmStr);
|
||||
sqlogger->debug(vmStr);
|
||||
|
||||
if (!g_bSpdLog_UseAnsiClr) { wconsole->debug(vmStr); }
|
||||
else
|
||||
{
|
||||
std::string vmStrAnsi = sANSI_DLL_T[(int)idx].c_str();
|
||||
vmStrAnsi.append(buf);
|
||||
wconsole->debug(vmStrAnsi);
|
||||
}
|
||||
|
||||
#ifndef DEDICATED
|
||||
g_spd_sys_w_oss.str("");
|
||||
g_spd_sys_w_oss.clear();
|
||||
|
||||
iconsole->info(vmStr);
|
||||
|
||||
std::string s = g_spd_sys_w_oss.str();
|
||||
const char* c = s.c_str();
|
||||
|
||||
g_pLogSystem.AddLog((LogType_t)eDLL_T::ENGINE, s);
|
||||
Items.push_back(Strdup((const char*)c));
|
||||
g_pIConsole->m_ivConLog.push_back(Strdup(s.c_str()));
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sys_LoadAssetHelper
|
||||
//
|
||||
// Purpose: Load assets from a custom directory if file exists
|
||||
// Input : *lpFileName -
|
||||
// a2 - *a3 -
|
||||
// Output : void* Sys_LoadAssetHelper
|
||||
//-----------------------------------------------------------------------------
|
||||
void* HSys_LoadAssetHelper(const CHAR* lpFileName, std::int64_t a2, LARGE_INTEGER* a3)
|
||||
{
|
||||
@ -113,11 +136,13 @@ void* HSys_LoadAssetHelper(const CHAR* lpFileName, std::int64_t a2, LARGE_INTEGE
|
||||
void SysUtils_Attach()
|
||||
{
|
||||
DetourAttach((LPVOID*)&Sys_Error, &HSys_Error);
|
||||
DetourAttach((LPVOID*)&Sys_Warning, &HSys_Warning);
|
||||
DetourAttach((LPVOID*)&Sys_LoadAssetHelper, &HSys_LoadAssetHelper);
|
||||
}
|
||||
|
||||
void SysUtils_Detach()
|
||||
{
|
||||
DetourDetach((LPVOID*)&Sys_Error, &HSys_Error);
|
||||
DetourDetach((LPVOID*)&Sys_Warning, &HSys_Warning);
|
||||
DetourDetach((LPVOID*)&Sys_LoadAssetHelper, &HSys_LoadAssetHelper);
|
||||
}
|
||||
|
@ -7,11 +7,17 @@ namespace
|
||||
ADDRESS p_Sys_Error = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x4C\x24\x08\x48\x89\x54\x24\x10\x4C\x89\x44\x24\x18\x4C\x89\x4C\x24\x20\x53\x55\x41\x54\x41\x56\xB8\x58\x10\x00\x00\xE8", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
|
||||
void (*Sys_Error)(char* fmt, ...) = (void (*)(char* fmt, ...))p_Sys_Error.GetPtr(); /*48 89 4C 24 08 48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 53 55 41 54 41 56 B8 58 10 00 00 E8*/
|
||||
|
||||
ADDRESS p_Warning = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x54\x24\x00\x4C\x89\x44\x24\x00\x4C\x89\x4C\x24\x00\x48\x83\xEC\x28\x4C\x8D\x44\x24\x00\xE8\x00\x00\x00\x00\x48\x83\xC4\x28\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x48\x89\x7C\x24\x00\x8B\x05\x00\x00\x00\x00", "xxxx?xxxx?xxxx?xxxxxxxx?x????xxxxxxxxxxxxxxxxxxxxxxx?xxxx?xxxx?xx????");
|
||||
void* (*Sys_Warning)(int level, char* fmt, ...) = (void* (*)(int, char* fmt, ...))p_Warning.GetPtr(); /*48 89 54 24 ? 4C 89 44 24 ? 4C 89 4C 24 ? 48 83 EC 28 4C 8D 44 24 ? E8 ? ? ? ? 48 83 C4 28 C3 CC CC CC CC CC CC CC CC CC CC CC CC CC CC 48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 8B 05 ? ? ? ?*/
|
||||
|
||||
ADDRESS p_Sys_LoadAssetHelper = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x74\x24\x10\x48\x89\x7C\x24\x18\x41\x56\x48\x83\xEC\x40\x33", "xxxxxxxxxxxxxxxxx");
|
||||
void*(*Sys_LoadAssetHelper)(const CHAR* lpFileName, std::int64_t a2, LARGE_INTEGER* a3) = (void*(*)(const CHAR*, std::int64_t, LARGE_INTEGER*))p_Sys_LoadAssetHelper.GetPtr();/*48 89 74 24 10 48 89 7C 24 18 41 56 48 83 EC 40 33*/
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
ADDRESS p_MemAlloc_Wrapper = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\xD9\x48\x85\xC0\x75\x0C\xE8\x16", "xxxxxxxxx????xxxxxxxxxx");
|
||||
void* (*MemAlloc_Wrapper)(std::int64_t size) = (void* (*)(std::int64_t))p_MemAlloc_Wrapper.GetPtr(); /*40 53 48 83 EC 20 48 8B 05 ?? ?? ?? ?? 48 8B D9 48 85 C0 75 0C E8 16*/
|
||||
#elif defined (GAMEDLL_S2)
|
||||
ADDRESS p_MemAlloc_Wrapper = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\xD9\x48\x85\xC0\x75\x0C\xE8\x00\x00\x00\x00\x48\x89\x05\x00\x00\x00\x00\x4C\x8B\x00\x48\x8B\xD3\x48\x8B\xC8\x48\x83\xC4\x20\x5B\x49\xFF\x60\x08", "xxxxxxxxx????xxxxxxxxx????xxx????xxxxxxxxxxxxxxxxxx");
|
||||
void* (*MemAlloc_Wrapper)(std::int64_t size) = (void* (*)(std::int64_t))p_MemAlloc_Wrapper.GetPtr(); /*40 53 48 83 EC 20 48 8B 05 ? ? ? ? 48 8B D9 48 85 C0 75 0C E8 ? ? ? ? 48 89 05 ? ? ? ? 4C 8B 00 48 8B D3 48 8B C8 48 83 C4 20 5B 49 FF 60 08 */
|
||||
#elif defined (GAMEDLL_S3)
|
||||
ADDRESS p_MemAlloc_Wrapper = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x48\x8B\x05\x6B\x83\x25\x0D\x48\x8B\xD9", "xxxxxxxxxxxxxxxx");
|
||||
void* (*MemAlloc_Wrapper)(std::int64_t size) = (void* (*)(std::int64_t))p_MemAlloc_Wrapper.GetPtr(); /*40 53 48 83 EC 20 48 8B 05 6B 83 25 0D 48 8B D9*/
|
||||
@ -27,7 +33,32 @@ enum class eDLL_T : int
|
||||
ENGINE = 3, // Wrapper
|
||||
FS = 4, // File System
|
||||
RTECH = 5, // RTech API
|
||||
MS = 6 // Material System
|
||||
MS = 6, // Material System
|
||||
NONE = 7
|
||||
};
|
||||
|
||||
const std::string sDLL_T[8] =
|
||||
{
|
||||
"Native(S):",
|
||||
"Native(C):",
|
||||
"Native(U):",
|
||||
"Native(E):",
|
||||
"Native(F):",
|
||||
"Native(R):",
|
||||
"Native(M):",
|
||||
""
|
||||
};
|
||||
|
||||
const static std::string sANSI_DLL_T[8] =
|
||||
{
|
||||
"\u001b[94mNative(S):",
|
||||
"\u001b[90mNative(C):",
|
||||
"\u001b[33mNative(U):",
|
||||
"\u001b[37mNative(E):",
|
||||
"\u001b[96mNative(F):",
|
||||
"\u001b[92mNative(R):",
|
||||
"\u001b[91mNative(M):",
|
||||
""
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -43,6 +74,7 @@ class HSys_Utils : public IDetour
|
||||
virtual void debugp()
|
||||
{
|
||||
std::cout << "| FUN: Sys_Error : 0x" << std::hex << std::uppercase << p_Sys_Error.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: Sys_Warning : 0x" << std::hex << std::uppercase << p_Warning.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: Sys_LoadAssetHelper : 0x" << std::hex << std::uppercase << p_Sys_LoadAssetHelper.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: MemAlloc_Wrapper : 0x" << std::hex << std::uppercase << p_MemAlloc_Wrapper.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
|
@ -1,17 +1,9 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "core/init.h"
|
||||
#include "tier0/cvar.h"
|
||||
#include "windows/id3dx.h"
|
||||
#include "windows/console.h"
|
||||
#include "gameui/IConsole.h"
|
||||
#include "client/IVEngineClient.h"
|
||||
|
||||
/******************************************************************************
|
||||
-------------------------------------------------------------------------------
|
||||
File : IConsole.cpp
|
||||
Date : 18:07:2021
|
||||
Author : Kawe Mazidjatari
|
||||
Purpose: Implements the in-game console frontend
|
||||
Purpose: Implements the in-game console front-end
|
||||
-------------------------------------------------------------------------------
|
||||
History:
|
||||
- 15:06:2021 | 14:56 : Created by Kawe Mazidjatari
|
||||
@ -20,6 +12,14 @@ History:
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "core/init.h"
|
||||
#include "tier0/cvar.h"
|
||||
#include "windows/id3dx.h"
|
||||
#include "windows/console.h"
|
||||
#include "gameui/IConsole.h"
|
||||
#include "client/IVEngineClient.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -31,12 +31,11 @@ CConsole::CConsole()
|
||||
m_nHistoryPos = -1;
|
||||
m_bAutoScroll = true;
|
||||
m_bScrollToBottom = false;
|
||||
m_bThemeSet = false;
|
||||
m_bInitialized = false;
|
||||
|
||||
m_ivCommands.push_back("CLEAR");
|
||||
m_ivCommands.push_back("HELP");
|
||||
m_ivCommands.push_back("HISTORY");
|
||||
AddLog("[DEBUG] THREAD ID: %ld\n", g_dThreadId);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -54,21 +53,24 @@ CConsole::~CConsole()
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: draws the console frontend
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConsole::Draw(const char* title, bool* bDraw)
|
||||
void CConsole::Draw(const char* pszTitle, bool* bDraw)
|
||||
{
|
||||
bool copy_to_clipboard = false;
|
||||
static auto iConsoleConfig = &g_pImGuiConfig->IConsole_Config;
|
||||
static auto iBrowserConfig = &g_pImGuiConfig->IBrowser_Config;
|
||||
|
||||
if (!m_bThemeSet)
|
||||
if (!m_bInitialized)
|
||||
{
|
||||
SetStyleVar();
|
||||
m_bThemeSet = true;
|
||||
m_bInitialized = true;
|
||||
}
|
||||
if (iConsoleConfig->m_bAutoClear && Items.Size > iConsoleConfig->m_nAutoClearLimit) // Check if Auto-Clear is enabled and if its above our limit.
|
||||
if (g_pImGuiConfig->IConsole_Config.m_bAutoClear) // Check if Auto-Clear is enabled.
|
||||
{
|
||||
ClearLog();
|
||||
m_ivHistory.clear();
|
||||
// Loop and clear the beginning of the vector until we are below our limit.
|
||||
while (m_ivConLog.Size > g_pImGuiConfig->IConsole_Config.m_nAutoClearLimit)
|
||||
{
|
||||
m_ivConLog.erase(m_ivConLog.begin());
|
||||
}
|
||||
while (m_ivHistory.Size > 512)
|
||||
{
|
||||
m_ivHistory.erase(m_ivHistory.begin());
|
||||
}
|
||||
}
|
||||
|
||||
//ImGui::ShowStyleEditor();
|
||||
@ -76,14 +78,14 @@ void CConsole::Draw(const char* title, bool* bDraw)
|
||||
ImGui::SetNextWindowSize(ImVec2(1000, 600), ImGuiCond_FirstUseEver);
|
||||
ImGui::SetWindowPos(ImVec2(-1000, 50), ImGuiCond_FirstUseEver);
|
||||
|
||||
if (!ImGui::Begin(title, bDraw))
|
||||
if (!ImGui::Begin(pszTitle, bDraw))
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
if (*bDraw == NULL)
|
||||
if (!*bDraw)
|
||||
{
|
||||
g_bShowConsole = false;
|
||||
m_bActivate = false;
|
||||
}
|
||||
|
||||
// Reserve enough left-over height and width for 1 separator + 1 input text
|
||||
@ -93,10 +95,84 @@ void CConsole::Draw(const char* title, bool* bDraw)
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginPopup("Options"))
|
||||
{
|
||||
Options();
|
||||
}
|
||||
if (ImGui::Button("Options"))
|
||||
{
|
||||
ImGui::OpenPopup("Options");
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
m_itFilter.Draw("Filter [\"-incl,-excl\"] [\"error\"]", footer_width_to_reserve - 500);
|
||||
ImGui::Separator();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 4.f, 6.f });
|
||||
|
||||
if (m_bCopyToClipBoard) { ImGui::LogToClipboard(); }
|
||||
ColorLog();
|
||||
if (m_bCopyToClipBoard)
|
||||
{
|
||||
ImGui::LogToClipboard();
|
||||
ImGui::LogFinish();
|
||||
|
||||
m_bCopyToClipBoard = false;
|
||||
}
|
||||
|
||||
if (m_bScrollToBottom || (m_bAutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
|
||||
{
|
||||
ImGui::SetScrollHereY(1.0f);
|
||||
m_bScrollToBottom = false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::EndChild();
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushItemWidth(footer_width_to_reserve - 80);
|
||||
if (ImGui::IsWindowAppearing()) { ImGui::SetKeyboardFocusHere(); }
|
||||
|
||||
ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
|
||||
|
||||
if (ImGui::InputText("##input", m_szInputBuf, IM_ARRAYSIZE(m_szInputBuf), input_text_flags, &TextEditCallbackStub, (void*)this))
|
||||
{
|
||||
if (m_szInputBuf[0]) { ProcessCommand(m_szInputBuf); }
|
||||
strcpy_s(m_szInputBuf, 1, "");
|
||||
m_bReclaimFocus = true;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Submit"))
|
||||
{
|
||||
if (m_szInputBuf[0]) { ProcessCommand(m_szInputBuf); }
|
||||
strcpy_s(m_szInputBuf, 1, "");
|
||||
m_bReclaimFocus = true;
|
||||
}
|
||||
|
||||
// Auto-focus on window apparition.
|
||||
ImGui::SetItemDefaultFocus();
|
||||
|
||||
// Auto focus previous widget.
|
||||
if (m_bReclaimFocus)
|
||||
{
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
m_bReclaimFocus = false;
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: draws the options panel
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConsole::Options()
|
||||
{
|
||||
ImGui::Checkbox("Auto-Scroll", &m_bAutoScroll);
|
||||
|
||||
if (ImGui::Checkbox("Auto-Clear", &iConsoleConfig->m_bAutoClear))
|
||||
if (ImGui::Checkbox("Auto-Clear", &g_pImGuiConfig->IConsole_Config.m_bAutoClear))
|
||||
{
|
||||
g_pImGuiConfig->Save();
|
||||
}
|
||||
@ -104,7 +180,7 @@ void CConsole::Draw(const char* title, bool* bDraw)
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(100);
|
||||
|
||||
if (ImGui::InputInt("Limit##AutoClearAfterCertainIndexCGameConsole", &iConsoleConfig->m_nAutoClearLimit))
|
||||
if (ImGui::InputInt("Limit##AutoClearFirstIConsole", &g_pImGuiConfig->IConsole_Config.m_nAutoClearLimit))
|
||||
{
|
||||
g_pImGuiConfig->Save();
|
||||
}
|
||||
@ -117,12 +193,12 @@ void CConsole::Draw(const char* title, bool* bDraw)
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
copy_to_clipboard = ImGui::SmallButton("Copy");
|
||||
m_bCopyToClipBoard = ImGui::SmallButton("Copy");
|
||||
|
||||
ImGui::Text("Console Hotkey:");
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Hotkey("##OpenIConsoleBind0", &iConsoleConfig->m_nBind0, ImVec2(80, 80)))
|
||||
if (ImGui::Hotkey("##OpenIConsoleBind0", &g_pImGuiConfig->IConsole_Config.m_nBind0, ImVec2(80, 80)))
|
||||
{
|
||||
g_pImGuiConfig->Save();
|
||||
}
|
||||
@ -130,158 +206,22 @@ void CConsole::Draw(const char* title, bool* bDraw)
|
||||
ImGui::Text("Browser Hotkey:");
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Hotkey("##OpenIBrowserBind0", &iBrowserConfig->m_nBind0, ImVec2(80, 80)))
|
||||
if (ImGui::Hotkey("##OpenIBrowserBind0", &g_pImGuiConfig->IBrowser_Config.m_nBind0, ImVec2(80, 80)))
|
||||
{
|
||||
g_pImGuiConfig->Save();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (ImGui::Button("Options"))
|
||||
{
|
||||
ImGui::OpenPopup("Options");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
m_itFilter.Draw("Filter [\"-incl,-excl\"] [\"error\"]", footer_width_to_reserve - 500);
|
||||
ImGui::Separator();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 4.f, 6.f });
|
||||
if (copy_to_clipboard)
|
||||
{
|
||||
ImGui::LogToClipboard();
|
||||
}
|
||||
for (int i = 0; i < Items.Size; i++)
|
||||
{
|
||||
const char* item = Items[i];
|
||||
if (!m_itFilter.PassFilter(item))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////
|
||||
ImVec4 color;
|
||||
bool has_color = false;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// General
|
||||
if (strstr(item, "[INFO]")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
|
||||
if (strstr(item, "[ERROR]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "[DEBUG]")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "[WARNING]")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
|
||||
if (strncmp(item, "# ", 2) == 0) { color = ImVec4(1.00f, 0.80f, 0.60f, 1.00f); has_color = true; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Script virtual machines per game dll
|
||||
if (strstr(item, "Script(S):")) { color = ImVec4(0.59f, 0.58f, 0.73f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "Script(C):")) { color = ImVec4(0.59f, 0.58f, 0.63f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "Script(U):")) { color = ImVec4(0.59f, 0.48f, 0.53f, 1.00f); has_color = true; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Native per game dll
|
||||
if (strstr(item, "Native(S):")) { color = ImVec4(0.59f, 0.58f, 0.73f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "Native(C):")) { color = ImVec4(0.59f, 0.58f, 0.63f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "Native(U):")) { color = ImVec4(0.59f, 0.48f, 0.53f, 1.00f); has_color = true; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Native per sys dll
|
||||
if (strstr(item, "Native(E):")) { color = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "Native(F):")) { color = ImVec4(0.32f, 0.64f, 0.72f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "Native(R):")) { color = ImVec4(0.36f, 0.70f, 0.35f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "Native(M):")) { color = ImVec4(0.75f, 0.41f, 0.67f, 1.00f); has_color = true; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Callbacks
|
||||
//if (strstr(item, "CodeCallback_")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Squirrel VM script errors
|
||||
if (strstr(item, ".gnut")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); has_color = true; }
|
||||
if (strstr(item, ".nut")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); has_color = true; }
|
||||
if (strstr(item, "[CLIENT]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "[SERVER]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "[UI]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "SCRIPT ERROR")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "SCRIPT COMPILE")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
|
||||
if (strstr(item, ".gnut #")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
|
||||
if (strstr(item, ".nut #")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "): -> ")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Squirrel VM script debug
|
||||
if (strstr(item, "CALLSTACK")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
|
||||
if (strstr(item, "LOCALS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
|
||||
if (strstr(item, "*FUNCTION")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
|
||||
if (strstr(item, "DIAGPRINTS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
|
||||
if (strstr(item, " File : ")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
|
||||
if (strstr(item, "<><>GRX<><>")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Filters
|
||||
//if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
|
||||
|
||||
if (has_color) { ImGui::PushStyleColor(ImGuiCol_Text, color); }
|
||||
ImGui::TextWrapped(item);
|
||||
if (has_color) { ImGui::PopStyleColor(); }
|
||||
}
|
||||
if (copy_to_clipboard) { ImGui::LogFinish(); }
|
||||
|
||||
if (m_bScrollToBottom || (m_bAutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) { ImGui::SetScrollHereY(1.0f); }
|
||||
m_bScrollToBottom = false;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::EndChild();
|
||||
ImGui::Separator();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Console
|
||||
bool reclaim_focus = false;
|
||||
ImGui::PushItemWidth(footer_width_to_reserve - 80);
|
||||
if (ImGui::IsWindowAppearing()) { ImGui::SetKeyboardFocusHere(); }
|
||||
ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
|
||||
|
||||
if (ImGui::InputText("##input", m_szInputBuf, IM_ARRAYSIZE(m_szInputBuf), input_text_flags, &TextEditCallbackStub, (void*)this))
|
||||
{
|
||||
char* s = m_szInputBuf;
|
||||
const char* replace = "";
|
||||
if (strstr(m_szInputBuf, "`")) { strcpy_s(s, sizeof(replace), replace); }
|
||||
Strtrim(s);
|
||||
if (s[0]) { ProcessCommand(s); }
|
||||
strcpy_s(s, sizeof(replace), replace);
|
||||
reclaim_focus = true;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Submit"))
|
||||
{
|
||||
char* s = m_szInputBuf;
|
||||
const char* replace = "";
|
||||
if (s[0]) { ProcessCommand(s); }
|
||||
strcpy_s(s, sizeof(replace), replace);
|
||||
reclaim_focus = true;
|
||||
}
|
||||
|
||||
// Auto-focus on window apparition.
|
||||
ImGui::SetItemDefaultFocus();
|
||||
|
||||
// Auto focus previous widget.
|
||||
if (reclaim_focus)
|
||||
{
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: executes submitted commands in a separate thread
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConsole::ProcessCommand(const char* command_line)
|
||||
void CConsole::ProcessCommand(const char* pszCommand)
|
||||
{
|
||||
AddLog("# %s\n", command_line);
|
||||
AddLog("# %s\n", pszCommand);
|
||||
|
||||
std::thread t(IVEngineClient_CommandExecute, this, command_line);
|
||||
std::thread t(IVEngineClient_CommandExecute, this, pszCommand);
|
||||
t.detach(); // Detach from render thread.
|
||||
|
||||
// This is to avoid a race condition.
|
||||
@ -290,7 +230,7 @@ void CConsole::ProcessCommand(const char* command_line)
|
||||
m_nHistoryPos = -1;
|
||||
for (int i = m_ivHistory.Size - 1; i >= 0; i--)
|
||||
{
|
||||
if (Stricmp(m_ivHistory[i], command_line) == 0)
|
||||
if (Stricmp(m_ivHistory[i], pszCommand) == 0)
|
||||
{
|
||||
delete m_ivHistory[i];
|
||||
m_ivHistory.erase(m_ivHistory.begin() + i);
|
||||
@ -298,34 +238,34 @@ void CConsole::ProcessCommand(const char* command_line)
|
||||
}
|
||||
}
|
||||
|
||||
m_ivHistory.push_back(Strdup(command_line));
|
||||
if (Stricmp(command_line, "CLEAR") == 0)
|
||||
m_ivHistory.push_back(Strdup(pszCommand));
|
||||
if (Stricmp(pszCommand, "CLEAR") == 0)
|
||||
{
|
||||
ClearLog();
|
||||
}
|
||||
else if (Stricmp(command_line, "HELP") == 0)
|
||||
else if (Stricmp(pszCommand, "HELP") == 0)
|
||||
{
|
||||
AddLog("Frontend commands:");
|
||||
AddLog("Commands:");
|
||||
for (int i = 0; i < m_ivCommands.Size; i++)
|
||||
{
|
||||
AddLog("- %s", m_ivCommands[i]);
|
||||
}
|
||||
|
||||
AddLog("Log types:");
|
||||
AddLog("Script(S): = Server (Script VM)");
|
||||
AddLog("Script(C): = Client (Script VM)");
|
||||
AddLog("Script(U): = UI (Script VM)");
|
||||
AddLog("Script(S): = Server DLL (Script VM)");
|
||||
AddLog("Script(C): = Client DLL (Script VM)");
|
||||
AddLog("Script(U): = UI DLL (Script VM)");
|
||||
|
||||
AddLog("Native(S): = Server dll (Code)");
|
||||
AddLog("Native(C): = Client dll (code)");
|
||||
AddLog("Native(U): = UI dll (code)");
|
||||
AddLog("Native(S): = Server DLL (Code)");
|
||||
AddLog("Native(C): = Client DLL (Code)");
|
||||
AddLog("Native(U): = UI DLL (Code)");
|
||||
|
||||
AddLog("Native(E): = Engine dll (code)");
|
||||
AddLog("Native(F): = FileSystem dll (code)");
|
||||
AddLog("Native(R): = RTech dll (code)");
|
||||
AddLog("Native(M): = MaterialSystem dll (code)");
|
||||
AddLog("Native(E): = Engine DLL (Code)");
|
||||
AddLog("Native(F): = FileSys DLL (Code)");
|
||||
AddLog("Native(R): = RTech DLL (Code)");
|
||||
AddLog("Native(M): = MatSys DLL (Code)");
|
||||
}
|
||||
else if (Stricmp(command_line, "HISTORY") == 0)
|
||||
else if (Stricmp(pszCommand, "HISTORY") == 0)
|
||||
{
|
||||
int first = m_ivHistory.Size - 10;
|
||||
for (int i = first > 0 ? first : 0; i < m_ivHistory.Size; i++)
|
||||
@ -347,22 +287,22 @@ int CConsole::TextEditCallback(ImGuiInputTextCallbackData* data)
|
||||
case ImGuiInputTextFlags_CallbackCompletion:
|
||||
{
|
||||
// Locate beginning of current word.
|
||||
const char* word_end = data->Buf + data->CursorPos;
|
||||
const char* word_start = word_end;
|
||||
while (word_start > data->Buf)
|
||||
const char* pszWordEnd = data->Buf + data->CursorPos;
|
||||
const char* pszWordStart = pszWordEnd;
|
||||
while (pszWordStart > data->Buf)
|
||||
{
|
||||
const char c = word_start[-1];
|
||||
const char c = pszWordStart[-1];
|
||||
if (c == ' ' || c == '\t' || c == ',' || c == ';')
|
||||
{
|
||||
break;
|
||||
}
|
||||
word_start--;
|
||||
pszWordStart--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ImGuiInputTextFlags_CallbackHistory:
|
||||
{
|
||||
const int prev_history_pos = m_nHistoryPos;
|
||||
const int nPrevHistoryPos = m_nHistoryPos;
|
||||
if (data->EventKey == ImGuiKey_UpArrow)
|
||||
{
|
||||
if (m_nHistoryPos == -1) { m_nHistoryPos = m_ivHistory.Size - 1; }
|
||||
@ -378,31 +318,180 @@ int CConsole::TextEditCallback(ImGuiInputTextCallbackData* data)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prev_history_pos != m_nHistoryPos)
|
||||
if (nPrevHistoryPos != m_nHistoryPos)
|
||||
{
|
||||
const char* history_str = (m_nHistoryPos >= 0) ? m_ivHistory[m_nHistoryPos] : "";
|
||||
const char* pszHistory = (m_nHistoryPos >= 0) ? m_ivHistory[m_nHistoryPos] : "";
|
||||
data->DeleteChars(0, data->BufTextLen);
|
||||
data->InsertChars(0, history_str);
|
||||
data->InsertChars(0, pszHistory);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
// ENTRYPOINT
|
||||
//#############################################################################
|
||||
|
||||
CConsole* g_GameConsole = nullptr;
|
||||
void DrawConsole(bool* bDraw)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: text edit callback stub
|
||||
//-----------------------------------------------------------------------------
|
||||
int CConsole::TextEditCallbackStub(ImGuiInputTextCallbackData* data)
|
||||
{
|
||||
static CConsole console;
|
||||
static bool AssignPtr = []()
|
||||
{
|
||||
g_GameConsole = &console;
|
||||
return true;
|
||||
} ();
|
||||
console.Draw("Console", bDraw);
|
||||
CConsole* pConsole = (CConsole*)data->UserData;
|
||||
return pConsole->TextEditCallback(data);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: adds logs to the vector
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConsole::AddLog(const char* fmt, ...) IM_FMTARGS(2)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
m_ivConLog.push_back(Strdup(buf));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: clears the entire vector
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConsole::ClearLog()
|
||||
{
|
||||
for (int i = 0; i < m_ivConLog.Size; i++) { free(m_ivConLog[i]); }
|
||||
m_ivConLog.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: colors important logs
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConsole::ColorLog()
|
||||
{
|
||||
for (int i = 0; i < m_ivConLog.Size; i++)
|
||||
{
|
||||
const char* pszConLog = m_ivConLog[i];
|
||||
if (!m_itFilter.PassFilter(pszConLog))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
ImVec4 imColor;
|
||||
|
||||
// General
|
||||
if (strstr(pszConLog, "[INFO]")) { imColor = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); true; }
|
||||
if (strstr(pszConLog, "[ERROR]")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "[DEBUG]")) { imColor = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "[WARNING]")) { imColor = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); true; }
|
||||
if (strncmp(pszConLog, "# ", 2) == 0) { imColor = ImVec4(1.00f, 0.80f, 0.60f, 1.00f); true; }
|
||||
|
||||
// Script virtual machines per game dll
|
||||
if (strstr(pszConLog, "Script(S):")) { imColor = ImVec4(0.59f, 0.58f, 0.73f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "Script(C):")) { imColor = ImVec4(0.59f, 0.58f, 0.63f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "Script(U):")) { imColor = ImVec4(0.59f, 0.48f, 0.53f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "Script(X):")) { imColor = ImVec4(0.59f, 0.58f, 0.63f, 1.00f); true; }
|
||||
|
||||
// Native per game dll
|
||||
if (strstr(pszConLog, "Native(S):")) { imColor = ImVec4(0.59f, 0.58f, 0.73f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "Native(C):")) { imColor = ImVec4(0.59f, 0.58f, 0.63f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "Native(U):")) { imColor = ImVec4(0.59f, 0.48f, 0.53f, 1.00f); true; }
|
||||
|
||||
// Native per sys dll
|
||||
if (strstr(pszConLog, "Native(E):")) { imColor = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "Native(F):")) { imColor = ImVec4(0.32f, 0.64f, 0.72f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "Native(R):")) { imColor = ImVec4(0.36f, 0.70f, 0.35f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "Native(M):")) { imColor = ImVec4(0.75f, 0.41f, 0.67f, 1.00f); true; }
|
||||
|
||||
// Callbacks
|
||||
//if (strstr(item, "CodeCallback_")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
|
||||
|
||||
// Squirrel VM script errors
|
||||
if (strstr(pszConLog, ".gnut")) { imColor = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); true; }
|
||||
if (strstr(pszConLog, ".nut")) { imColor = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); true; }
|
||||
if (strstr(pszConLog, "[CLIENT]")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "[SERVER]")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "[UI]")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "SCRIPT ERROR")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "SCRIPT COMPILE")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; }
|
||||
if (strstr(pszConLog, ".gnut #")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; }
|
||||
if (strstr(pszConLog, ".nut #")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "): -> ")) { imColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); true; }
|
||||
|
||||
// Squirrel VM script debug
|
||||
if (strstr(pszConLog, "CALLSTACK")) { imColor = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); true; }
|
||||
if (strstr(pszConLog, "LOCALS")) { imColor = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); true; }
|
||||
if (strstr(pszConLog, "*FUNCTION")) { imColor = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); true; }
|
||||
if (strstr(pszConLog, "DIAGPRINTS")) { imColor = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); true; }
|
||||
if (strstr(pszConLog, " File : ")) { imColor = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); true; }
|
||||
if (strstr(pszConLog, "<><>GRX<><>")) { imColor = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); true; }
|
||||
|
||||
// Filters
|
||||
//if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, imColor);
|
||||
ImGui::TextWrapped(pszConLog);
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the console front-end style
|
||||
//-----------------------------------------------------------------------------
|
||||
void CConsole::SetStyleVar()
|
||||
{
|
||||
ImGuiStyle& imStyle = ImGui::GetStyle();
|
||||
ImVec4* imColor = imStyle.Colors;
|
||||
|
||||
imColor[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
|
||||
imColor[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f);
|
||||
imColor[ImGuiCol_WindowBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
|
||||
imColor[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
||||
imColor[ImGuiCol_PopupBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
|
||||
imColor[ImGuiCol_Border] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||
imColor[ImGuiCol_BorderShadow] = ImVec4(0.04f, 0.04f, 0.04f, 0.64f);
|
||||
imColor[ImGuiCol_FrameBg] = ImVec4(0.13f, 0.13f, 0.13f, 1.00f);
|
||||
imColor[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 1.00f);
|
||||
imColor[ImGuiCol_FrameBgActive] = ImVec4(0.24f, 0.24f, 0.24f, 1.00f);
|
||||
imColor[ImGuiCol_TitleBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f);
|
||||
imColor[ImGuiCol_TitleBgActive] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
|
||||
imColor[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
||||
imColor[ImGuiCol_MenuBarBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f);
|
||||
imColor[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f);
|
||||
imColor[ImGuiCol_ScrollbarGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||
imColor[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
||||
imColor[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
|
||||
imColor[ImGuiCol_CheckMark] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
|
||||
imColor[ImGuiCol_SliderGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||
imColor[ImGuiCol_SliderGrabActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
||||
imColor[ImGuiCol_Button] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
|
||||
imColor[ImGuiCol_ButtonHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
|
||||
imColor[ImGuiCol_ButtonActive] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f);
|
||||
imColor[ImGuiCol_Header] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
|
||||
imColor[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
|
||||
imColor[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
||||
imColor[ImGuiCol_Separator] = ImVec4(0.53f, 0.53f, 0.57f, 1.00f);
|
||||
imColor[ImGuiCol_SeparatorHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
||||
imColor[ImGuiCol_SeparatorActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
|
||||
imColor[ImGuiCol_ResizeGrip] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||
imColor[ImGuiCol_ResizeGripHovered] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f);
|
||||
imColor[ImGuiCol_ResizeGripActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
|
||||
imColor[ImGuiCol_Tab] = ImVec4(0.18f, 0.18f, 0.18f, 1.00f);
|
||||
imColor[ImGuiCol_TabHovered] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
|
||||
imColor[ImGuiCol_TabActive] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
|
||||
|
||||
imStyle.WindowBorderSize = 0.0f;
|
||||
imStyle.FrameBorderSize = 1.0f;
|
||||
imStyle.ChildBorderSize = 1.0f;
|
||||
imStyle.PopupBorderSize = 1.0f;
|
||||
imStyle.TabBorderSize = 1.0f;
|
||||
|
||||
imStyle.WindowRounding = 2.5f;
|
||||
imStyle.FrameRounding = 0.0f;
|
||||
imStyle.ChildRounding = 0.0f;
|
||||
imStyle.PopupRounding = 0.0f;
|
||||
imStyle.TabRounding = 1.0f;
|
||||
imStyle.ScrollbarRounding = 1.0f;
|
||||
|
||||
imStyle.ItemSpacing = ImVec2(4, 4);
|
||||
imStyle.WindowPadding = ImVec2(5, 5);
|
||||
}
|
||||
|
||||
CConsole* g_pIConsole = new CConsole();
|
||||
|
@ -1,124 +1,44 @@
|
||||
#pragma once
|
||||
#ifndef DEDICATED
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Initialization
|
||||
void DrawConsole(bool* bDraw);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Globals
|
||||
inline ImVector<char*> Items;
|
||||
|
||||
class CConsole
|
||||
{
|
||||
private:
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
char m_szInputBuf[256] = { 0 };
|
||||
char m_szInputBuf[512] = { 0 };
|
||||
ImVector<const char*> m_ivCommands;
|
||||
ImVector<char*> m_ivHistory;
|
||||
int m_nHistoryPos = -1;
|
||||
ImGuiTextFilter m_itFilter;
|
||||
bool m_bAutoScroll = true;
|
||||
bool m_bScrollToBottom = false;
|
||||
bool m_bThemeSet = false;
|
||||
bool m_bCopyToClipBoard = false;
|
||||
bool m_bReclaimFocus = false;
|
||||
bool m_bInitialized = false;
|
||||
|
||||
public:
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
bool m_bActivate = false;
|
||||
ImVector<char*> m_ivConLog;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
CConsole();
|
||||
~CConsole();
|
||||
|
||||
void Draw(const char* title, bool* bDraw);
|
||||
void Options();
|
||||
|
||||
void ProcessCommand(const char* command_line);
|
||||
int TextEditCallback(ImGuiInputTextCallbackData* data);
|
||||
static int TextEditCallbackStub(ImGuiInputTextCallbackData* data);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// History
|
||||
static int TextEditCallbackStub(ImGuiInputTextCallbackData* data)
|
||||
{
|
||||
CConsole* console = (CConsole*)data->UserData;
|
||||
return console->TextEditCallback(data);
|
||||
}
|
||||
void AddLog(const char* fmt, ...) IM_FMTARGS(2);
|
||||
void ClearLog();
|
||||
void ColorLog();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Utility
|
||||
void ClearLog()
|
||||
{
|
||||
for (int i = 0; i < Items.Size; i++) { free(Items[i]); }
|
||||
Items.clear();
|
||||
}
|
||||
void AddLog(const char* fmt, ...) IM_FMTARGS(2)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
Items.push_back(Strdup(buf));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Style
|
||||
void SetStyleVar()
|
||||
{
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
ImVec4* colors = style.Colors;
|
||||
|
||||
colors[ImGuiCol_Text] = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
|
||||
colors[ImGuiCol_TextDisabled] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f);
|
||||
colors[ImGuiCol_WindowBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
|
||||
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PopupBg] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
|
||||
colors[ImGuiCol_Border] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||
colors[ImGuiCol_BorderShadow] = ImVec4(0.04f, 0.04f, 0.04f, 0.64f);
|
||||
colors[ImGuiCol_FrameBg] = ImVec4(0.13f, 0.13f, 0.13f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4(0.24f, 0.24f, 0.24f, 1.00f);
|
||||
colors[ImGuiCol_TitleBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f);
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4(0.27f, 0.27f, 0.27f, 1.00f);
|
||||
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_MenuBarBg] = ImVec4(0.22f, 0.22f, 0.22f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
|
||||
colors[ImGuiCol_CheckMark] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
||||
colors[ImGuiCol_Button] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_ButtonHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
|
||||
colors[ImGuiCol_ButtonActive] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f);
|
||||
colors[ImGuiCol_Header] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
|
||||
colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
||||
colors[ImGuiCol_Separator] = ImVec4(0.53f, 0.53f, 0.57f, 1.00f);
|
||||
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.53f, 0.53f, 0.53f, 1.00f);
|
||||
colors[ImGuiCol_SeparatorActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.63f, 0.63f, 0.63f, 1.00f);
|
||||
colors[ImGuiCol_Tab] = ImVec4(0.18f, 0.18f, 0.18f, 1.00f);
|
||||
colors[ImGuiCol_TabHovered] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
|
||||
colors[ImGuiCol_TabActive] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
|
||||
|
||||
style.WindowBorderSize = 0.0f;
|
||||
style.FrameBorderSize = 1.0f;
|
||||
style.ChildBorderSize = 1.0f;
|
||||
style.PopupBorderSize = 1.0f;
|
||||
style.TabBorderSize = 1.0f;
|
||||
|
||||
style.WindowRounding = 2.5f;
|
||||
style.FrameRounding = 0.0f;
|
||||
style.ChildRounding = 0.0f;
|
||||
style.PopupRounding = 0.0f;
|
||||
style.TabRounding = 1.0f;
|
||||
style.ScrollbarRounding = 1.0f;
|
||||
|
||||
style.ItemSpacing = ImVec2(4, 4);
|
||||
style.WindowPadding = ImVec2(5, 5);
|
||||
}
|
||||
void SetStyleVar();
|
||||
};
|
||||
|
||||
extern CConsole* g_GameConsole;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
extern CConsole* g_pIConsole;
|
||||
#endif // !DEDICATED
|
||||
|
@ -3,10 +3,14 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
#if defined (GAMEDLL_S1) || defined (GAMEDLL_S1)
|
||||
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
/* ==== CAPPSYSTEMGROUP ================================================================================================================================================= */
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
ADDRESS p_IAppSystem_Main = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x80\xB9\x00\x00\x00\x00\x00\x48\x8B\x15\x00\x00\x00\x00", "xxxxxx?????xxx????");
|
||||
void* (*IAppSystem_Main)(void* a1, void* a2) = (void* (*)(void*, void*))p_IAppSystem_Main.GetPtr(); /*48 83 EC 28 80 B9 ?? ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? */
|
||||
|
||||
ADDRESS p_IAppSystem_Create = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xC4\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x60\x48\xC7\x40\x00\x00\x00\x00\x00\x48\x89\x58\x08", "xxxxxxxxxxxxxxxxxxx?????xxxx");
|
||||
bool (*IAppSystem_Create)(void* a1) = (bool(*)(void*))p_IAppSystem_Create.GetPtr(); /*48 8B C4 57 41 54 41 55 41 56 41 57 48 83 EC 60 48 C7 40 ?? ?? ?? ?? ?? 48 89 58 08*/
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
ADDRESS p_IAppSystem_Main = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x80\xB9\x00\x00\x00\x00\x00\xBB\x00\x00\x00\x00", "xxxxxxxx?????x????");
|
||||
void* (*IAppSystem_Main)(void* a1, void* a2) = (void* (*)(void*, void*))p_IAppSystem_Main.GetPtr(); /*40 53 48 83 EC 20 80 B9 ?? ?? ?? ?? ?? BB ?? ?? ?? ??*/
|
||||
|
||||
|
39
r5dev/materialsystem/materialsystem.h
Normal file
39
r5dev/materialsystem/materialsystem.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include "engine/debugoverlay.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
/* ==== MATERIALSYSTEM ================================================================================================================================================== */
|
||||
ADDRESS CMaterialSystem__Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x70\x48\x83\x3D\x00\x00\x00\x00\x00", "xxxx?xxxxxxxxxxxxxxxxxx?????");
|
||||
// 0x1403BBFD0 // 48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 70 48 83 3D ? ? ? ? ? //
|
||||
|
||||
ADDRESS InitMaterialSystem = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x48\x8B\x0D\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\x48\x8B\x01\xFF\x90\x00\x00\x00\x00\x48\x8B\x0D\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\x48\x8B\x01\xFF\x90\x00\x00\x00\x00", "xxxxxxx????xxx????xxxxx????xxx????xxx????xxxxx????"); //
|
||||
// 0x14024B390 // 48 83 EC 28 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? 48 8B 01 FF 90 ? ? ? ? 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? 48 8B 01 FF 90 ? ? ? ? //
|
||||
|
||||
ADDRESS p_DrawStreamOverlay = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x41\x56\xB8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x2B\xE0\xC6\x02\x00", "xxx????x????xxxxxx"); // 41 56 B8 ? ? ? ? E8 ? ? ? ? 48 2B E0 C6 02 00 //
|
||||
const char* (*DrawStreamOverlay)(void* thisptr, std::uint8_t* a2, void* unused, void* a4) = (const char* (*)(void*, std::uint8_t*, void*, void*))p_DrawStreamOverlay.GetPtr();
|
||||
|
||||
void* g_pMaterialSystem = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\x0D\x00\x00\x00\x00\x48\x85\xC9\x74\x11\x48\x8B\x01\x48\x8D\x15\x00\x00\x00\x00", "xxx????xxxxxxxxxxx????").ResolveRelativeAddressSelf(0x3, 0x7).RCast<void*>();
|
||||
|
||||
int* total_streaming_tex_memory = p_DrawStreamOverlay.Offset(0x0).FindPatternSelf("48 8B 05", ADDRESS::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<int*>();
|
||||
int* unfree_streaming_tex_memory = p_DrawStreamOverlay.Offset(0x20).FindPatternSelf("48 8B 05", ADDRESS::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<int*>();
|
||||
int* unusable_streaming_tex_memory = p_DrawStreamOverlay.Offset(0x50).FindPatternSelf("48 8B 05", ADDRESS::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<int*>();
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class HMaterialSystem : public IDetour
|
||||
{
|
||||
virtual void debugp()
|
||||
{
|
||||
std::cout << "| FUN: CMaterialSystem::Init : 0x" << std::hex << std::uppercase << CMaterialSystem__Init.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: InitMaterialSystem : 0x" << std::hex << std::uppercase << InitMaterialSystem.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: DrawStreamOverlay : 0x" << std::hex << std::uppercase << p_DrawStreamOverlay.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| VAR: g_pMaterialSystem : 0x" << std::hex << std::uppercase << g_pMaterialSystem << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
}
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DebugOverlays_Attach();
|
||||
REGISTER(HMaterialSystem);
|
46
r5dev/mathlib/bits.cpp
Normal file
46
r5dev/mathlib/bits.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
//=============================================================================//
|
||||
//
|
||||
// Purpose: look for NANs, infinities, and underflows.
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "core/stdafx.h"
|
||||
#include "mathlib/bits.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This follows the ANSI/IEEE 754-1985 standard
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned long& FloatBits(float& f)
|
||||
{
|
||||
return *reinterpret_cast<unsigned long*>(&f);
|
||||
}
|
||||
|
||||
unsigned long const& FloatBits(float const& f)
|
||||
{
|
||||
return *reinterpret_cast<unsigned long const*>(&f);
|
||||
}
|
||||
|
||||
float BitsToFloat(unsigned long i)
|
||||
{
|
||||
return *reinterpret_cast<float*>(&i);
|
||||
}
|
||||
|
||||
bool IsFinite(float f)
|
||||
{
|
||||
return ((FloatBits(f) & 0x7F800000) != 0x7F800000);
|
||||
}
|
||||
|
||||
unsigned long FloatAbsBits(float f)
|
||||
{
|
||||
return FloatBits(f) & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
float FloatMakePositive(float f)
|
||||
{
|
||||
return fabsf(f);
|
||||
}
|
||||
|
||||
float FloatNegate(float f)
|
||||
{
|
||||
return -f; //BitsToFloat( FloatBits(f) ^ 0x80000000 );
|
||||
}
|
10
r5dev/mathlib/bits.h
Normal file
10
r5dev/mathlib/bits.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
unsigned long& FloatBits(float& f);
|
||||
unsigned long const& FloatBits(float const& f);
|
||||
float BitsToFloat(unsigned long i);
|
||||
bool IsFinite(float f);
|
||||
unsigned long FloatAbsBits(float f);
|
||||
|
||||
#define FLOAT32_NAN_BITS (std::uint32_t)0x7FC00000 // NaN!
|
||||
#define FLOAT32_NAN BitsToFloat( FLOAT32_NAN_BITS )
|
14
r5dev/mathlib/color.h
Normal file
14
r5dev/mathlib/color.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
class Color
|
||||
{
|
||||
public:
|
||||
Color(int r, int g, int b, int a)
|
||||
{
|
||||
_color[0] = (unsigned char)r;
|
||||
_color[1] = (unsigned char)g;
|
||||
_color[2] = (unsigned char)b;
|
||||
_color[3] = (unsigned char)a;
|
||||
}
|
||||
unsigned char _color[4];
|
||||
};
|
21
r5dev/milessdk/win64_rrthreads.h
Normal file
21
r5dev/milessdk/win64_rrthreads.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
namespace
|
||||
{
|
||||
/* ==== WASAPI THREAD SERVICE =========================================================================================================================================== */
|
||||
ADDRESS p_WASAPI_GetAudioDevice = g_mRadAudioSystemDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xC4\x48\x89\x58\x20\x55\x56\x41\x54", "xxxxxxxxxxx");
|
||||
// 0x18005AD10 // 48 8B C4 48 89 58 20 55 56 41 54 //
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class HWASAPIServiceThread : public IDetour
|
||||
{
|
||||
virtual void debugp()
|
||||
{
|
||||
std::cout << "| FUN: WASAPI_GetAudioDevice : 0x" << std::hex << std::uppercase << p_WASAPI_GetAudioDevice.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
}
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
REGISTER(HWASAPIServiceThread);
|
@ -81,7 +81,11 @@ void CBanSystem::AddEntry(std::string svIpAddress, std::int64_t nOriginID)
|
||||
{
|
||||
if (!svIpAddress.empty() && nOriginID > 0) // Check if args are valid.
|
||||
{
|
||||
vsvBanList.push_back(std::make_pair(svIpAddress, nOriginID)); // Push it back into the vector.
|
||||
auto it = std::find(vsvBanList.begin(), vsvBanList.end(), std::make_pair(svIpAddress, nOriginID)); // Check if we have this entry already.
|
||||
if (it == vsvBanList.end()) // We don't have that entry?
|
||||
{
|
||||
vsvBanList.push_back(std::make_pair(svIpAddress, nOriginID)); // Add it.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,19 +106,19 @@ void CBanSystem::DeleteEntry(std::string svIpAddress, std::int64_t nOriginID)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: adds a connect refuse entry to the refuselist
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBanSystem::AddConnectionRefuse(std::string svError, int nUserID)
|
||||
void CBanSystem::AddConnectionRefuse(std::string svError, std::int64_t nOriginID)
|
||||
{
|
||||
if (vsvrefuseList.empty())
|
||||
{
|
||||
vsvrefuseList.push_back(std::make_pair(svError, nUserID));
|
||||
vsvrefuseList.push_back(std::make_pair(svError, nOriginID));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < vsvrefuseList.size(); i++) // Loop through vector.
|
||||
{
|
||||
if (vsvrefuseList[i].second != nUserID) // Do any entries match our vector?
|
||||
if (vsvrefuseList[i].second != nOriginID) // Do any entries match our vector?
|
||||
{
|
||||
vsvrefuseList.push_back(std::make_pair(svError, nUserID)); // Push it back into the vector.
|
||||
vsvrefuseList.push_back(std::make_pair(svError, nOriginID)); // Push it back into the vector.
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,11 +127,11 @@ void CBanSystem::AddConnectionRefuse(std::string svError, int nUserID)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: deletes an entry in the refuselist
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBanSystem::DeleteConnectionRefuse(int nUserID)
|
||||
void CBanSystem::DeleteConnectionRefuse(std::int64_t nOriginID)
|
||||
{
|
||||
for (int i = 0; i < vsvrefuseList.size(); i++) // Loop through vector.
|
||||
{
|
||||
if (vsvrefuseList[i].second == nUserID) // Do any entries match our vector?
|
||||
if (vsvrefuseList[i].second == nOriginID) // Do any entries match our vector?
|
||||
{
|
||||
vsvrefuseList.erase(vsvrefuseList.begin() + i); // If so erase that vector element.
|
||||
}
|
||||
|
@ -10,13 +10,13 @@ public:
|
||||
void Save();
|
||||
void AddEntry(std::string svIpAddress, std::int64_t nOriginID);
|
||||
void DeleteEntry(std::string svIpAddress, std::int64_t nOriginID);
|
||||
void AddConnectionRefuse(std::string svError, int nUserID);
|
||||
void DeleteConnectionRefuse(int nUserID);
|
||||
void AddConnectionRefuse(std::string svError, std::int64_t nOriginID);
|
||||
void DeleteConnectionRefuse(std::int64_t nUserID);
|
||||
bool IsBanned(std::string svIpAddress, std::int64_t nOriginID);
|
||||
bool IsRefuseListValid();
|
||||
bool IsBanListValid();
|
||||
|
||||
std::vector<std::pair<std::string, int>> vsvrefuseList = {};;
|
||||
std::vector<std::pair<std::string, std::int64_t>> vsvrefuseList = {};;
|
||||
private:
|
||||
std::vector<std::pair<std::string, std::int64_t>> vsvBanList = {};
|
||||
};
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Internals
|
||||
BOOL IsBadReadPtrV2(void* ptr);
|
||||
BOOL FileExists(const char* szPath);
|
||||
MODULEINFO GetModuleInfo(const char* szModule);
|
||||
DWORD64 FindPatternSIMD(const char* szModule, const unsigned char* szPattern, const char* szMask);
|
||||
|
@ -13,6 +13,22 @@ BOOL FileExists(const char* szPath)
|
||||
return std::filesystem::exists(szPath);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// For checking if pointer is valid or bad.
|
||||
BOOL IsBadReadPtrV2(void* ptr)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi = { 0 };
|
||||
if (::VirtualQuery(ptr, &mbi, sizeof(mbi)))
|
||||
{
|
||||
DWORD mask = (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY);
|
||||
bool b = !(mbi.Protect & mask);
|
||||
// check the page is not a guard page
|
||||
if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) b = true;
|
||||
return b;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// For getting information about the executing module.
|
||||
MODULEINFO GetModuleInfo(const char* szModule)
|
||||
@ -132,7 +148,7 @@ void HexDump(const char* szHeader, int nFunc, const void* pData, int nSize)
|
||||
szAscii[16] = '\0';
|
||||
|
||||
// Add new loggers here to replace the placeholder.
|
||||
if (nFunc == 0) { logger = g_spd_netchan_logger; }
|
||||
if (nFunc == 0) { logger = spdlog::get("netchan_pack_logger"); }
|
||||
|
||||
// Add timestamp.
|
||||
logger->set_level(spdlog::level::trace);
|
||||
|
@ -26,6 +26,7 @@
|
||||
<ClCompile Include="common\opcodes.cpp" />
|
||||
<ClCompile Include="core\dllmain.cpp" />
|
||||
<ClCompile Include="core\init.cpp" />
|
||||
<ClCompile Include="core\logdef.cpp" />
|
||||
<ClCompile Include="core\stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
@ -44,6 +45,7 @@
|
||||
<ClCompile Include="inputsystem\inputsystem.cpp" />
|
||||
<ClCompile Include="launcher\IApplication.cpp" />
|
||||
<ClCompile Include="mathlib\adler32.cpp" />
|
||||
<ClCompile Include="mathlib\bits.cpp" />
|
||||
<ClCompile Include="mathlib\crc32.cpp" />
|
||||
<ClCompile Include="mathlib\IceKey.cpp" />
|
||||
<ClCompile Include="networksystem\r5net.cpp" />
|
||||
@ -57,7 +59,24 @@
|
||||
<ClCompile Include="server\server.cpp" />
|
||||
<ClCompile Include="squirrel\sqapi.cpp" />
|
||||
<ClCompile Include="squirrel\sqinit.cpp" />
|
||||
<ClCompile Include="squirrel\sqnativefunctions.cpp" />
|
||||
<ClCompile Include="squirrel\sqvm.cpp" />
|
||||
<ClCompile Include="thirdparty\detours\src\creatwth.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\detours.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\disasm.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\modules.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\imgui\src\imgui.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
@ -87,13 +106,94 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\imgui\src\imgui_utility.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\imgui\src\imgui_widgets.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_internal.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_state.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecomp.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecompbase.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_api.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_assert.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_checksum.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_huffman_codes.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_lzbase.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_match_accel.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_mem.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_platform.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_polar_codes.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_prefix_coding.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_pthreads_threading.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_symbol_codec.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_timer.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_vector.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_win32_threading.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tier0\commandline.cpp" />
|
||||
<ClCompile Include="tier0\ConCommand.cpp" />
|
||||
<ClCompile Include="tier0\completion.cpp" />
|
||||
<ClCompile Include="tier0\cvar.cpp" />
|
||||
@ -119,6 +219,7 @@
|
||||
<ClInclude Include="common\opcodes.h" />
|
||||
<ClInclude Include="common\protocol.h" />
|
||||
<ClInclude Include="common\pseudodefs.h" />
|
||||
<ClInclude Include="core\assert.h" />
|
||||
<ClInclude Include="core\init.h" />
|
||||
<ClInclude Include="core\logdef.h" />
|
||||
<ClInclude Include="core\r5dev.h" />
|
||||
@ -126,6 +227,7 @@
|
||||
<ClInclude Include="ebisusdk\EbisuSDK.h" />
|
||||
<ClInclude Include="engine\baseclient.h" />
|
||||
<ClInclude Include="engine\baseclientstate.h" />
|
||||
<ClInclude Include="engine\debugoverlay.h" />
|
||||
<ClInclude Include="engine\host_cmd.h" />
|
||||
<ClInclude Include="engine\host_state.h" />
|
||||
<ClInclude Include="engine\net_chan.h" />
|
||||
@ -137,12 +239,15 @@
|
||||
<ClInclude Include="inputsystem\ButtonCode.h" />
|
||||
<ClInclude Include="inputsystem\inputsystem.h" />
|
||||
<ClInclude Include="launcher\IApplication.h" />
|
||||
<ClInclude Include="materialsystem\materialsystem.h" />
|
||||
<ClInclude Include="mathlib\adler32.h" />
|
||||
<ClInclude Include="mathlib\bits.h" />
|
||||
<ClInclude Include="mathlib\color.h" />
|
||||
<ClInclude Include="mathlib\crc32.h" />
|
||||
<ClInclude Include="mathlib\IceKey.H" />
|
||||
<ClInclude Include="mathlib\parallel_for.h" />
|
||||
<ClInclude Include="mathlib\vector.h" />
|
||||
<ClInclude Include="networksystem\net_structs.h" />
|
||||
<ClInclude Include="milessdk\win64_rrthreads.h" />
|
||||
<ClInclude Include="networksystem\r5net.h" />
|
||||
<ClInclude Include="networksystem\sm_protocol.h" />
|
||||
<ClInclude Include="public\include\memaddr.h" />
|
||||
@ -160,6 +265,7 @@
|
||||
<ClInclude Include="server\server.h" />
|
||||
<ClInclude Include="squirrel\sqapi.h" />
|
||||
<ClInclude Include="squirrel\sqinit.h" />
|
||||
<ClInclude Include="squirrel\sqnativefunctions.h" />
|
||||
<ClInclude Include="squirrel\sqvm.h" />
|
||||
<ClInclude Include="thirdparty\detours\include\detours.h" />
|
||||
<ClInclude Include="thirdparty\detours\include\detver.h" />
|
||||
@ -176,7 +282,34 @@
|
||||
<ClInclude Include="thirdparty\imgui\include\imstb_textedit.h" />
|
||||
<ClInclude Include="thirdparty\imgui\include\imstb_truetype.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_assert.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_checksum.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_config.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_core.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_helpers.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_huffman_codes.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_lzbase.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_match_accel.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_math.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_mem.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_null_threading.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_platform.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_polar_codes.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_prefix_coding.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_pthreads_threading.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_static_lib.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_symbol_codec.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_threading.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_timer.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_traits.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_types.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_utils.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_vector.h" />
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_win32_threading.h" />
|
||||
<ClInclude Include="thirdparty\lzham\lzhamcomp\lzham_comp.h" />
|
||||
<ClInclude Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_internal.h" />
|
||||
<ClInclude Include="thirdparty\lzham\lzhamdecomp\lzham_decomp.h" />
|
||||
<ClInclude Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecompbase.h" />
|
||||
<ClInclude Include="thirdparty\spdlog\include\async.h" />
|
||||
<ClInclude Include="thirdparty\spdlog\include\async_logger-inl.h" />
|
||||
<ClInclude Include="thirdparty\spdlog\include\async_logger.h" />
|
||||
@ -272,6 +405,7 @@
|
||||
<ClInclude Include="thirdparty\spdlog\include\tweakme.h" />
|
||||
<ClInclude Include="thirdparty\spdlog\include\version.h" />
|
||||
<ClInclude Include="tier0\basetypes.h" />
|
||||
<ClInclude Include="tier0\commandline.h" />
|
||||
<ClInclude Include="tier0\ConCommand.h" />
|
||||
<ClInclude Include="tier0\completion.h" />
|
||||
<ClInclude Include="tier0\cvar.h" />
|
||||
@ -368,7 +502,7 @@
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)r5dev\;$(IncludePath);$(DXSDK_DIR)Include</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)r5dev\thirdparty\detours\libs;$(SolutionDir)r5dev\thirdparty\lzham\libs;$(LibraryPath);$(DXSDK_DIR)Lib\x64</LibraryPath>
|
||||
<TargetName>r5apexvtxd</TargetName>
|
||||
<TargetName>r5apexsdkd</TargetName>
|
||||
<OutDir>$(SolutionDir)bin\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
<ReferencePath>$(VC_ReferencesPath_x64);</ReferencePath>
|
||||
@ -436,10 +570,10 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>r5dev.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>detours.lib;lzhamlib_x64D.lib;lzhamcomp_x64D.lib;lzhamdecomp_x64D.lib;d3d11.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>d3d11.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(TargetPath)" "..\..\..\bin\$(TargetFileName)"</Command>
|
||||
<Command>copy /Y "$(TargetPath)" "..\..\..\$(TargetFileName)" && del "..\..\..\r5apexsdkd64.dll" && rename "..\..\..\$(TargetFileName)" "r5apexsdkd64.dll"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@ -472,7 +606,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>r5dev.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>detours.lib;lzhamlib_x64.lib;lzhamcomp_x64.lib;lzhamdecomp_x64.lib;d3d11.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>d3d11.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(TargetPath)" "..\..\..\$(TargetFileName)" && del "..\..\..\r5apexsdkd64.dll" && rename "..\..\..\$(TargetFileName)" "r5apexsdkd64.dll"</Command>
|
||||
|
@ -121,6 +121,24 @@
|
||||
<Filter Include="sdk\bsplib">
|
||||
<UniqueIdentifier>{336e3141-0276-4cd5-a836-585eef681b7b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sdk\materialsystem">
|
||||
<UniqueIdentifier>{55bb4f60-5f5a-4780-a7a2-b3db51c53680}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sdk\milessdk">
|
||||
<UniqueIdentifier>{f52dfb17-f5bd-4258-91a2-500587bee708}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="thirdparty\lzham\lzhamcomp">
|
||||
<UniqueIdentifier>{f450ee50-7010-49e2-9f91-05a74fcb6a8b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="thirdparty\lzham\lzhamcomp\include">
|
||||
<UniqueIdentifier>{11645361-fd70-462f-ab8b-8a78283a5fc7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="thirdparty\lzham\lzhamdecomp">
|
||||
<UniqueIdentifier>{785353c2-6417-4213-b55f-3007a0b79801}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="thirdparty\lzham\lzhamdecomp\include">
|
||||
<UniqueIdentifier>{5beb12b5-0422-4337-9be6-2e6c0a05a69b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="client\client.cpp">
|
||||
@ -303,8 +321,89 @@
|
||||
<ClCompile Include="windows\system.cpp">
|
||||
<Filter>windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IDevPallete.cpp">
|
||||
<Filter>sdk\gameui</Filter>
|
||||
<ClCompile Include="thirdparty\detours\src\disasm.cpp">
|
||||
<Filter>thirdparty\detours</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\modules.cpp">
|
||||
<Filter>thirdparty\detours</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\detours.cpp">
|
||||
<Filter>thirdparty\detours</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\creatwth.cpp">
|
||||
<Filter>thirdparty\detours</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_assert.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_checksum.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_huffman_codes.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_lzbase.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_match_accel.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_mem.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_platform.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_polar_codes.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_prefix_coding.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_pthreads_threading.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_symbol_codec.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_timer.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_vector.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_win32_threading.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzham_api.cpp">
|
||||
<Filter>thirdparty\lzham</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_internal.cpp">
|
||||
<Filter>thirdparty\lzham\lzhamcomp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_state.cpp">
|
||||
<Filter>thirdparty\lzham\lzhamcomp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp.cpp">
|
||||
<Filter>thirdparty\lzham\lzhamcomp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecomp.cpp">
|
||||
<Filter>thirdparty\lzham\lzhamdecomp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecompbase.cpp">
|
||||
<Filter>thirdparty\lzham\lzhamdecomp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mathlib\bits.cpp">
|
||||
<Filter>sdk\mathlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tier0\commandline.cpp">
|
||||
<Filter>sdk\tier0</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="core\logdef.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="squirrel\sqnativefunctions.cpp">
|
||||
<Filter>sdk\squirrel</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -815,12 +914,6 @@
|
||||
<ClInclude Include="public\include\binstream.h">
|
||||
<Filter>sdk\public\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_static_lib.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mathlib\adler32.h">
|
||||
<Filter>sdk\mathlib</Filter>
|
||||
</ClInclude>
|
||||
@ -839,11 +932,116 @@
|
||||
<ClInclude Include="windows\system.h">
|
||||
<Filter>windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="networksystem\net_structs.h">
|
||||
<Filter>sdk\networksystem</Filter>
|
||||
<ClInclude Include="mathlib\color.h">
|
||||
<Filter>sdk\mathlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IDevPalette.h">
|
||||
<Filter>sdk\gameui</Filter>
|
||||
<ClInclude Include="materialsystem\materialsystem.h">
|
||||
<Filter>sdk\materialsystem</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="engine\debugoverlay.h">
|
||||
<Filter>sdk\engine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="milessdk\win64_rrthreads.h">
|
||||
<Filter>sdk\milessdk</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_config.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_core.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_helpers.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_huffman_codes.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_lzbase.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_match_accel.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_math.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_mem.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_null_threading.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_platform.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_polar_codes.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_prefix_coding.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_pthreads_threading.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_static_lib.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_symbol_codec.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_threading.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_timer.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_traits.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_types.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_utils.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_vector.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_win32_threading.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_assert.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\include\lzham_checksum.h">
|
||||
<Filter>thirdparty\lzham\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\lzhamcomp\lzham_comp.h">
|
||||
<Filter>thirdparty\lzham\lzhamcomp\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\lzhamcomp\lzham_lzcomp_internal.h">
|
||||
<Filter>thirdparty\lzham\lzhamcomp\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\lzhamdecomp\lzham_decomp.h">
|
||||
<Filter>thirdparty\lzham\lzhamdecomp\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\lzham\lzhamdecomp\lzham_lzdecompbase.h">
|
||||
<Filter>thirdparty\lzham\lzhamdecomp\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mathlib\bits.h">
|
||||
<Filter>sdk\mathlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="tier0\commandline.h">
|
||||
<Filter>sdk\tier0</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="core\assert.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="squirrel\sqnativefunctions.h">
|
||||
<Filter>sdk\squirrel</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -51,10 +51,10 @@ void HRtech_AsyncLoad(std::string svPakFileName)
|
||||
|
||||
void RTech_Game_Attach()
|
||||
{
|
||||
DetourAttach((LPVOID*)&RTech_UnloadAsset, &HRTech_UnloadAsset);
|
||||
//DetourAttach((LPVOID*)&RTech_UnloadAsset, &HRTech_UnloadAsset);
|
||||
}
|
||||
|
||||
void RTech_Game_Detach()
|
||||
{
|
||||
DetourAttach((LPVOID*)&RTech_UnloadAsset, &HRTech_UnloadAsset);
|
||||
//DetourAttach((LPVOID*)&RTech_UnloadAsset, &HRTech_UnloadAsset);
|
||||
}
|
||||
|
@ -7,12 +7,15 @@ namespace
|
||||
ADDRESS p_RTech_UnloadAsset = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x48\x85\xC9\x0F\x84\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00", "xxxxxxxxx????xxx????");
|
||||
void (*RTech_UnloadAsset)(std::int64_t a1) = (void (*)(std::int64_t))p_RTech_UnloadAsset.GetPtr(); /*48 83 EC 28 48 85 C9 0F 84 ? ? ? ? 48 8B 05 ? ? ? ? */
|
||||
|
||||
ADDRESS p_RTech_AsyncLoad = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x40\x48\x89\x6C\x24\x00\x41\x8B\xE8", "xxxxxxxxxx?xxx");
|
||||
unsigned int (*RTech_AsyncLoad)(void* Src, __int64 a2, int a3, char pakfile) = (unsigned int (*)(void*, __int64, int, char))p_RTech_AsyncLoad.GetPtr(); /*40 53 48 83 EC 40 48 89 6C 24 ? 41 8B E8*/
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
ADDRESS p_RTech_UnloadAsset = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x48\x85\xD2\x74\x40\x48\x8B\x05\x00\x00\x00\x00", "xxxxxxxxxxxx????");
|
||||
void (*RTech_UnloadAsset)(std::int64_t a1, std::int64_t a2) = (void (*)(std::int64_t, std::int64_t))p_RTech_UnloadAsset.GetPtr(); /*48 83 EC 28 48 85 D2 74 40 48 8B 05 ? ? ? ?*/
|
||||
#endif
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2)
|
||||
ADDRESS p_RTech_AsyncLoad = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x40\x48\x89\x6C\x24\x00\x41\x8B\xE8", "xxxxxxxxxx?xxx");
|
||||
unsigned int (*RTech_AsyncLoad)(void* Src, __int64 a2, int a3, char pakfile) = (unsigned int (*)(void*, __int64, int, char))p_RTech_AsyncLoad.GetPtr(); /*40 53 48 83 EC 40 48 89 6C 24 ? 41 8B E8*/
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
ADDRESS p_RTech_AsyncLoad = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x40\x48\x89\x6C\x24\x00\x41\x0F\xB6\xE9", "xxxxxxxxxx?xxxx");
|
||||
unsigned int (*RTech_AsyncLoad)(void* Src, __int64 a2, int a3, char pakfile) = (unsigned int (*)(void*, __int64, int, char))p_RTech_AsyncLoad.GetPtr(); /*40 53 48 83 EC 40 48 89 6C 24 ? 41 0F B6 E9*/
|
||||
#endif
|
||||
|
@ -140,7 +140,7 @@
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>del "..\..\..\r5reloaded.exe" && copy /Y "$(TargetPath)" "..\..\..\$(TargetFileName)"</Command>
|
||||
@ -174,7 +174,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>del "..\..\..\r5reloaded.exe" && copy /Y "$(TargetPath)" "..\..\..\$(TargetFileName)"</Command>
|
||||
@ -186,6 +186,22 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sdklauncher\sdklauncher.cpp" />
|
||||
<ClCompile Include="thirdparty\detours\src\creatwth.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\detours.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\disasm.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\modules.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="resource\sdklauncher.rc" />
|
||||
@ -198,6 +214,9 @@
|
||||
<ClInclude Include="core\stdafx.h" />
|
||||
<ClInclude Include="sdklauncher\sdklauncher.h" />
|
||||
<ClInclude Include="sdklauncher\sdklauncher_res.h" />
|
||||
<ClInclude Include="thirdparty\detours\include\detours.h" />
|
||||
<ClInclude Include="thirdparty\detours\include\detver.h" />
|
||||
<ClInclude Include="thirdparty\detours\include\syelog.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
@ -13,6 +13,12 @@
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Detours Files">
|
||||
<UniqueIdentifier>{82b18787-373d-42ce-8d8d-1e3adba8d3a0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Detours Files\include">
|
||||
<UniqueIdentifier>{dc968871-7ca2-452b-a5b1-350a12dd54aa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="sdklauncher\sdklauncher.cpp">
|
||||
@ -21,6 +27,18 @@
|
||||
<ClCompile Include="core\stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\detours.cpp">
|
||||
<Filter>Detours Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\disasm.cpp">
|
||||
<Filter>Detours Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\modules.cpp">
|
||||
<Filter>Detours Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thirdparty\detours\src\creatwth.cpp">
|
||||
<Filter>Detours Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="resource\sdklauncher.rc">
|
||||
@ -37,6 +55,15 @@
|
||||
<ClInclude Include="sdklauncher\sdklauncher_res.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\detours\include\detver.h">
|
||||
<Filter>Detours Files\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\detours\include\syelog.h">
|
||||
<Filter>Detours Files\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\detours\include\detours.h">
|
||||
<Filter>Detours Files\include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="resource\ico\sdklauncher_rel.ico">
|
||||
|
@ -56,7 +56,7 @@ bool LaunchR5Apex(LAUNCHMODE lMode, LAUNCHSTATE lState)
|
||||
}
|
||||
cfgFile.close(); // Close cfg file.
|
||||
|
||||
WorkerDll = currentDirectory + "\\bin\\r5apexvtxd.dll"; // Get path to worker dll.
|
||||
WorkerDll = currentDirectory + "\\r5apexsdkd64.dll"; // Get path to worker dll.
|
||||
GameDirectory = currentDirectory + "\\r5apex.exe"; // Get path to game executeable.
|
||||
StartupCommandLine = currentDirectory + "\\r5apex.exe " + CommandLineArguments; // Setup startup command line string.
|
||||
|
||||
|
@ -18,7 +18,7 @@ bool HIVEngineServer_PersistenceAvailable(void* entidx, int clientidx)
|
||||
CClient* pClient = g_pClient->GetClientInstance(clientidx); // Get client instance.
|
||||
*(char*)((std::uintptr_t)pClient + g_dwPersistenceVar) = (char)0x5; // Set the client instance to 'ready'.
|
||||
|
||||
if (!g_bIsPersistenceVarSet[clientidx] && sv_showconnecting->m_pParent->m_iValue > 0)
|
||||
if (!g_bIsPersistenceVarSet[clientidx] && sv_showconnecting->GetBool())
|
||||
{
|
||||
void* clientNamePtr = (void**)(((std::uintptr_t)pClient->GetNetChan()) + 0x1A8D); // Get client name from netchan.
|
||||
std::string clientName((char*)clientNamePtr, 32); // Get full name.
|
||||
@ -66,4 +66,4 @@ void IVEngineServer_Detach()
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool g_bIsPersistenceVarSet[128];
|
||||
bool g_bIsPersistenceVarSet[MAX_PLAYERS];
|
||||
|
@ -14,7 +14,7 @@ void IVEngineServer_Attach();
|
||||
void IVEngineServer_Detach();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
extern bool g_bIsPersistenceVarSet[128];
|
||||
extern bool g_bIsPersistenceVarSet[MAX_PLAYERS];
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class HVEngineServer : public IDetour
|
||||
|
@ -24,33 +24,13 @@ void IsClientBanned(R5Net::Client* pR5net, const std::string svIPAddr, std::int6
|
||||
bool bCompBanned = res.isBanned;
|
||||
if (bCompBanned)
|
||||
{
|
||||
while (bCompBanned)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) // Loop through all possible client instances.
|
||||
{
|
||||
CClient* pClient = g_pClient->GetClientInstance(i); // Get client instance.
|
||||
if (!pClient) // Client instance valid?
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!pClient->GetNetChan()) // Netchan valid?
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::int64_t nOriginID = pClient->m_iOriginID; // Get originID.
|
||||
if (nOriginID != nNucleusID) // See if they match.
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
g_pBanSystem->AddConnectionRefuse(svError, pClient->m_iUserID + 1); // Add to the vector.
|
||||
bCompBanned = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DevMsg(eDLL_T::SERVER, "\n");
|
||||
DevMsg(eDLL_T::SERVER, "______________________________________________________________\n");
|
||||
DevMsg(eDLL_T::SERVER, "] PYLON NOTICE -----------------------------------------------\n");
|
||||
DevMsg(eDLL_T::SERVER, "] OriginID : | '%lld' IS PYLON BANNED.\n", nNucleusID);
|
||||
DevMsg(eDLL_T::SERVER, "--------------------------------------------------------------\n");
|
||||
DevMsg(eDLL_T::SERVER, "\n");
|
||||
g_pBanSystem->AddConnectionRefuse(svError, nNucleusID); // Add to the vector.
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +53,7 @@ void* HCServer_Authenticate(void* pServer, user_creds* pInpacket)
|
||||
svIpAddress = ss.str();
|
||||
}
|
||||
|
||||
if (sv_showconnecting->m_pParent->m_iValue > 0)
|
||||
if (sv_showconnecting->GetBool())
|
||||
{
|
||||
DevMsg(eDLL_T::SERVER, "\n");
|
||||
DevMsg(eDLL_T::SERVER, "______________________________________________________________\n");
|
||||
@ -90,7 +70,7 @@ void* HCServer_Authenticate(void* pServer, user_creds* pInpacket)
|
||||
{
|
||||
CServer_RejectConnection(pServer, *(unsigned int*)((std::uintptr_t)pServer + 0xC), pInpacket, "You have been banned from this Server."); // RejectConnection for the client.
|
||||
|
||||
if (sv_showconnecting->m_pParent->m_iValue > 0)
|
||||
if (sv_showconnecting->GetBool())
|
||||
{
|
||||
DevMsg(eDLL_T::SERVER, "] NOTICE : | THIS CLIENT IS BANNED!\n");
|
||||
DevMsg(eDLL_T::SERVER, "--------------------------------------------------------------\n\n");
|
||||
@ -98,7 +78,7 @@ void* HCServer_Authenticate(void* pServer, user_creds* pInpacket)
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (sv_showconnecting->m_pParent->m_iValue > 0)
|
||||
if (sv_showconnecting->GetBool())
|
||||
{
|
||||
DevMsg(eDLL_T::SERVER, "\n");
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ struct user_creds
|
||||
namespace
|
||||
{
|
||||
/* ==== CSERVER ========================================================================================================================================================= */
|
||||
ADDRESS p_CServer_Think = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x81\xEC\x00\x00\x00\x00\x80\x3D\x00\x00\x00\x00\x00", "xxxx?xxxx?xxxx????xx?????");
|
||||
void (*CServer_Think)(bool check_clock_drift, bool bIsSimulating) = (void (*)(bool, bool))p_CServer_Think.GetPtr(); /*48 89 5C 24 ? 48 89 74 24 ? 57 48 81 EC ? ? ? ? 80 3D ? ? ? ? ?*/
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
ADDRESS p_CServer_Authenticate = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x44\x89\x44\x24\x00\x55\x56\x57\x48\x8D\xAC\x24\x00\x00\x00\x00", "xxxx?xxxxxxx????");
|
||||
void* (*CServer_Authenticate)(void* cserver, user_creds* creds) = (void* (*)(void* cserver, user_creds * creds))p_CServer_Authenticate.GetPtr(); /*44 89 44 24 ?? 55 56 57 48 8D AC 24 ?? ?? ?? ??*/
|
||||
@ -28,6 +30,8 @@ namespace
|
||||
#endif
|
||||
ADDRESS p_CServer_RejectConnection = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x89\x4C\x24\x00\x53\x55\x56\x57\x48\x81\xEC\x00\x00\x00\x00\x49\x8B\xD9", "xxxx?xxxxxxx????xxx");
|
||||
void* (*CServer_RejectConnection)(void* pServer, unsigned int a2, user_creds* pCreds, const char* szMessage) = (void* (*)(void*, unsigned int, user_creds*, const char*))p_CServer_RejectConnection.GetPtr(); /*4C 89 4C 24 ?? 53 55 56 57 48 81 EC ?? ?? ?? ?? 49 8B D9*/
|
||||
|
||||
int* sv_m_nTickCount = p_CServer_Think.Offset(0xB0).FindPatternSelf("8B 15", ADDRESS::Direction::DOWN).ResolveRelativeAddressSelf(0x2, 0x6).RCast<int*>();
|
||||
}
|
||||
|
||||
void CServer_Attach();
|
||||
@ -42,8 +46,10 @@ class HServer : public IDetour
|
||||
{
|
||||
virtual void debugp()
|
||||
{
|
||||
std::cout << "| FUN: CServer::Think : 0x" << std::hex << std::uppercase << p_CServer_Think.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: CServer::Authenticate : 0x" << std::hex << std::uppercase << p_CServer_Authenticate.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| FUN: CServer::RejectConnection : 0x" << std::hex << std::uppercase << p_CServer_RejectConnection.GetPtr() << std::setw(npad) << " |" << std::endl;
|
||||
std::cout << "| VAR: sv_m_nTickCount : 0x" << std::hex << std::uppercase << sv_m_nTickCount << std::setw(0) << " |" << std::endl;
|
||||
std::cout << "+----------------------------------------------------------------+" << std::endl;
|
||||
}
|
||||
};
|
||||
|
@ -48,6 +48,12 @@ void hsq_newslot(void* sqvm, int idx);
|
||||
void SQAPI_Attach();
|
||||
void SQAPI_Detach();
|
||||
|
||||
typedef int SQRESULT;
|
||||
#define SQ_OK (1)
|
||||
#define SQ_ERROR (-1)
|
||||
#define SQ_FAILED(res) (res<0)
|
||||
#define SQ_SUCCEEDED(res) (res>=0)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class HSqapi : public IDetour
|
||||
{
|
||||
|
265
r5dev/squirrel/sqnativefunctions.cpp
Normal file
265
r5dev/squirrel/sqnativefunctions.cpp
Normal file
@ -0,0 +1,265 @@
|
||||
#include "core/stdafx.h"
|
||||
#include "squirrel/sqnativefunctions.h"
|
||||
|
||||
#include "engine/sys_utils.h"
|
||||
#include "gameui/IBrowser.h"
|
||||
|
||||
namespace SQNativeFunctions
|
||||
{
|
||||
namespace IBrowser
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose: get servers current server name from serverlist index
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT GetServerName(void* sqvm)
|
||||
{
|
||||
int svIndex = hsq_getinteger(sqvm, 1);
|
||||
std::string szSvName = g_pIBrowser->m_vServerList[svIndex].svServerName;
|
||||
|
||||
hsq_pushstring(sqvm, szSvName.c_str(), -1);
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose: get servers current playlist via serverlist index
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT GetServerPlaylist(void* sqvm)
|
||||
{
|
||||
int svIndex = hsq_getinteger(sqvm, 1);
|
||||
std::string szSvPlaylist = g_pIBrowser->m_vServerList[svIndex].svPlaylist;
|
||||
|
||||
hsq_pushstring(sqvm, szSvPlaylist.c_str(), -1);
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose: get servers current map via serverlist index
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT GetServerMap(void* sqvm)
|
||||
{
|
||||
int svIndex = hsq_getinteger(sqvm, 1);
|
||||
std::string szSvMapName = g_pIBrowser->m_vServerList[svIndex].svMapName;
|
||||
|
||||
hsq_pushstring(sqvm, szSvMapName.c_str(), -1);
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose: get current server count from pylon
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT GetServerCount(void* sqvm)
|
||||
{
|
||||
g_pIBrowser->GetServerList(); // Refresh svListing list.
|
||||
|
||||
hsq_pushinteger(sqvm, g_pIBrowser->m_vServerList.size());
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose: expose SDK version to SQ
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT GetSDKVersion(void* sqvm)
|
||||
{
|
||||
hsq_pushstring(sqvm, g_pR5net->GetSDKVersion().c_str(), -1);
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose: get promo data for serverbrowser panels
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT GetPromoData(void* sqvm)
|
||||
{
|
||||
enum class R5RPromoData : int
|
||||
{
|
||||
PromoLargeTitle,
|
||||
PromoLargeDesc,
|
||||
PromoLeftTitle,
|
||||
PromoLeftDesc,
|
||||
PromoRightTitle,
|
||||
PromoRightDesc
|
||||
};
|
||||
|
||||
R5RPromoData ePromoIndex = (R5RPromoData)hsq_getinteger(sqvm, 1);
|
||||
|
||||
std::string szPromo = std::string();
|
||||
|
||||
switch (ePromoIndex)
|
||||
{
|
||||
case R5RPromoData::PromoLargeTitle:
|
||||
{
|
||||
szPromo = "Welcome To R5Reloaded!";
|
||||
break;
|
||||
}
|
||||
case R5RPromoData::PromoLargeDesc:
|
||||
{
|
||||
szPromo = "Make sure to join the discord! discord.gg/r5reloaded";
|
||||
break;
|
||||
}
|
||||
case R5RPromoData::PromoLeftTitle:
|
||||
{
|
||||
szPromo = "Yes";
|
||||
break;
|
||||
}
|
||||
case R5RPromoData::PromoLeftDesc:
|
||||
{
|
||||
szPromo = "Your ad could be here";
|
||||
break;
|
||||
}
|
||||
case R5RPromoData::PromoRightTitle:
|
||||
{
|
||||
szPromo = "Yes2";
|
||||
break;
|
||||
}
|
||||
case R5RPromoData::PromoRightDesc:
|
||||
{
|
||||
szPromo = "Yes3";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
szPromo = "You should not see this.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hsq_pushstring(sqvm, szPromo.c_str(), -1);
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: set netchannel encryption key and connect to server
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT SetEncKeyAndConnect(void* sqvm)
|
||||
{
|
||||
int svIndex = hsq_getinteger(sqvm, 1);
|
||||
|
||||
g_pIBrowser->ConnectToServer(g_pIBrowser->m_vServerList[svIndex].svIpAddress, g_pIBrowser->m_vServerList[svIndex].svPort, g_pIBrowser->m_vServerList[svIndex].svEncryptionKey);
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: create server via native serverbrowser entries
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT CreateServerFromMenu(void* sqvm)
|
||||
{
|
||||
std::string szSvName = hsq_getstring(sqvm, 1);
|
||||
std::string szSvMapName = hsq_getstring(sqvm, 2);
|
||||
std::string szSvPlaylist = hsq_getstring(sqvm, 3);
|
||||
EServerVisibility eSvVisibility = (EServerVisibility)hsq_getinteger(sqvm, 4);
|
||||
|
||||
if (szSvName.empty() || szSvMapName.empty() || szSvPlaylist.empty())
|
||||
return SQ_OK;
|
||||
|
||||
// Adjust browser settings.
|
||||
g_pIBrowser->m_Server.svPlaylist = szSvPlaylist;
|
||||
g_pIBrowser->m_Server.svMapName = szSvMapName;
|
||||
g_pIBrowser->m_Server.svServerName = szSvName;
|
||||
g_pIBrowser->eServerVisibility = eSvVisibility;
|
||||
|
||||
// Launch server.
|
||||
g_pIBrowser->LaunchServer();
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// // Purpose: request token from pylon and join server with result.
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT JoinPrivateServerFromMenu(void* sqvm)
|
||||
{
|
||||
std::string szHiddenServerRequestMessage = std::string();
|
||||
|
||||
std::string szToken = hsq_getstring(sqvm, 1);
|
||||
|
||||
ServerListing svListing;
|
||||
bool result = g_pR5net->GetServerByToken(svListing, szHiddenServerRequestMessage, szToken); // Send szToken connect request.
|
||||
if (result)
|
||||
{
|
||||
g_pIBrowser->ConnectToServer(svListing.svIpAddress, svListing.svPort, svListing.svEncryptionKey);
|
||||
}
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: get response from private server request
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT GetPrivateServerMessage(void* sqvm)
|
||||
{
|
||||
std::string szHiddenServerRequestMessage = std::string();
|
||||
|
||||
std::string szToken = hsq_getstring(sqvm, 1);
|
||||
|
||||
ServerListing slServer;
|
||||
bool result = g_pR5net->GetServerByToken(slServer, szHiddenServerRequestMessage, szToken); // Send szToken connect request.
|
||||
if (!slServer.svServerName.empty())
|
||||
{
|
||||
szHiddenServerRequestMessage = "Found Server: " + slServer.svServerName;
|
||||
|
||||
hsq_pushstring(sqvm, szHiddenServerRequestMessage.c_str(), -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
szHiddenServerRequestMessage = "Error: Server Not Found";
|
||||
|
||||
hsq_pushstring(sqvm, szHiddenServerRequestMessage.c_str(), -1);
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::UI, "GetPrivateServeMessage response: %s\n", szHiddenServerRequestMessage.c_str());
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: connect to server from native server browser entries
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT ConnectToIPFromMenu(void* sqvm)
|
||||
{
|
||||
std::string szIP = hsq_getstring(sqvm, 1);
|
||||
std::string szEncKey = hsq_getstring(sqvm, 2);
|
||||
|
||||
if (szIP.empty() || szEncKey.empty())
|
||||
return SQ_OK;
|
||||
|
||||
DevMsg(eDLL_T::UI, "Connecting to server with connection string %s and encryptionkey %s\n", szIP, szEncKey);
|
||||
|
||||
g_pIBrowser->ConnectToServer(szIP, szEncKey);
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: return all available map
|
||||
//-----------------------------------------------------------------------------
|
||||
SQRESULT GetAvailableMaps(void* sqvm)
|
||||
{
|
||||
std::vector<std::string> mapList = g_pIBrowser->m_vszMapFileNameList;
|
||||
|
||||
if (mapList.empty())
|
||||
{
|
||||
DevMsg(eDLL_T::UI, "Available maps is empty!!!\n");
|
||||
return SQ_OK;
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::UI, "Requesting an array of %i available maps from script\n", mapList.size());
|
||||
|
||||
hsq_newarray(sqvm, 0);
|
||||
|
||||
for (auto& it : mapList)
|
||||
{
|
||||
hsq_pushstring(sqvm, it.c_str(), -1);
|
||||
hsq_arrayappend(sqvm, -2);
|
||||
}
|
||||
|
||||
return SQ_OK;
|
||||
}
|
||||
}
|
||||
}
|
21
r5dev/squirrel/sqnativefunctions.h
Normal file
21
r5dev/squirrel/sqnativefunctions.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "squirrel/sqapi.h"
|
||||
|
||||
namespace SQNativeFunctions
|
||||
{
|
||||
namespace IBrowser
|
||||
{
|
||||
SQRESULT GetServerName(void* sqvm);
|
||||
SQRESULT GetServerPlaylist(void* sqvm);
|
||||
SQRESULT GetServerMap(void* sqvm);
|
||||
SQRESULT GetServerCount(void* sqvm);
|
||||
SQRESULT GetSDKVersion(void* sqvm);
|
||||
SQRESULT GetPromoData(void* sqvm);
|
||||
SQRESULT SetEncKeyAndConnect(void* sqvm);
|
||||
SQRESULT CreateServerFromMenu(void* sqvm);
|
||||
SQRESULT JoinPrivateServerFromMenu(void* sqvm);
|
||||
SQRESULT GetPrivateServerMessage(void* sqvm);
|
||||
SQRESULT ConnectToIPFromMenu(void* sqvm);
|
||||
SQRESULT GetAvailableMaps(void* sqvm);
|
||||
}
|
||||
}
|
@ -9,11 +9,12 @@
|
||||
#include "tier0/basetypes.h"
|
||||
#include "tier0/cvar.h"
|
||||
#include "tier0/IConVar.h"
|
||||
#include "tier0/commandline.h"
|
||||
#include "engine/sys_utils.h"
|
||||
#include "squirrel/sqvm.h"
|
||||
#include "vgui/CEngineVGui.h"
|
||||
#include "gameui/IConsole.h"
|
||||
#include "serverbrowser/serverbrowser.h"
|
||||
#include "squirrel/sqvm.h"
|
||||
#include "squirrel/sqnativefunctions.h"
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose: prints the output of each VM to the console
|
||||
@ -22,66 +23,60 @@ void* HSQVM_PrintFunc(void* sqvm, char* fmt, ...)
|
||||
{
|
||||
#ifdef GAMEDLL_S3
|
||||
int vmIdx = *(int*)((std::uintptr_t)sqvm + 0x18);
|
||||
#else // TODO [ AMOS ]: nothing equal to 'rdx + 18h' exist in the vm pointers for anything below S3.
|
||||
int vmIdx = 3;
|
||||
#else // TODO [ AMOS ]: nothing equal to 'rdx + 18h' exist in the vm structs for anything below S3.
|
||||
static int vmIdx = 3;
|
||||
#endif
|
||||
static bool initialized = false;
|
||||
static char buf[1024] = {};
|
||||
|
||||
static char buf[1024];
|
||||
static std::string vmType[4] = { "Script(S):", "Script(C):", "Script(U):", "Script(X):" };
|
||||
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
|
||||
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
|
||||
static std::shared_ptr<spdlog::logger> sqlogger = spdlog::get("sqvm_print_logger");
|
||||
|
||||
static auto iconsole = spdlog::stdout_logger_mt("sqvm_print_iconsole"); // in-game console.
|
||||
static auto wconsole = spdlog::stdout_logger_mt("sqvm_print_wconsole"); // windows console.
|
||||
static auto sqlogger = spdlog::basic_logger_mt("sqvm_print_logger", "platform\\logs\\sqvm_print.log"); // file logger.
|
||||
|
||||
std::string vmStr = vmType[vmIdx].c_str();
|
||||
|
||||
g_spd_sqvm_p_oss.str("");
|
||||
g_spd_sqvm_p_oss.clear();
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
iconsole = std::make_shared<spdlog::logger>("sqvm_print_ostream", g_spd_sqvm_p_ostream_sink);
|
||||
iconsole->set_pattern("[%S.%e] %v");
|
||||
iconsole->set_level(spdlog::level::debug);
|
||||
wconsole->set_pattern("[%S.%e] %v");
|
||||
wconsole->set_level(spdlog::level::debug);
|
||||
sqlogger->set_pattern("[%S.%e] %v");
|
||||
sqlogger->set_level(spdlog::level::debug);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
va_list args;
|
||||
{/////////////////////////////
|
||||
va_list args{};
|
||||
va_start(args, fmt);
|
||||
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
}/////////////////////////////
|
||||
|
||||
std::string vmStr = SQVM_LOG_T[vmIdx].c_str();
|
||||
vmStr.append(buf);
|
||||
|
||||
if (sq_showvmoutput->m_pParent->m_iValue > 0)
|
||||
if (sq_showvmoutput->GetInt() > 0)
|
||||
{
|
||||
sqlogger->debug(vmStr);
|
||||
}
|
||||
if (sq_showvmoutput->m_pParent->m_iValue > 1)
|
||||
if (sq_showvmoutput->GetInt() > 1)
|
||||
{
|
||||
if (!g_bSpdLog_UseAnsiClr)
|
||||
{
|
||||
iconsole->debug(vmStr);
|
||||
wconsole->debug(vmStr);
|
||||
#ifndef DEDICATED
|
||||
std::string s = g_spd_sqvm_p_oss.str();
|
||||
const char* c = s.c_str();
|
||||
Items.push_back(Strdup((const char*)c));
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
#ifndef DEDICATED
|
||||
if (sq_showvmoutput->m_pParent->m_iValue > 2)
|
||||
else
|
||||
{
|
||||
std::string vmStrAnsi = SQVM_ANSI_LOG_T[vmIdx].c_str();
|
||||
vmStrAnsi.append(buf);
|
||||
wconsole->debug(vmStrAnsi);
|
||||
}
|
||||
|
||||
#ifndef DEDICATED
|
||||
g_spd_sys_w_oss.str("");
|
||||
g_spd_sys_w_oss.clear();
|
||||
|
||||
iconsole->debug(vmStr);
|
||||
|
||||
std::string s = g_spd_sys_w_oss.str();
|
||||
g_pIConsole->m_ivConLog.push_back(Strdup(s.c_str()));
|
||||
|
||||
if (sq_showvmoutput->GetInt() > 2)
|
||||
{
|
||||
std::string s = g_spd_sqvm_p_oss.str();
|
||||
g_pLogSystem.AddLog((LogType_t)vmIdx, s);
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -91,80 +86,61 @@ void* HSQVM_PrintFunc(void* sqvm, char* fmt, ...)
|
||||
void* HSQVM_WarningFunc(void* sqvm, int a2, int a3, int* nStringSize, void** ppString)
|
||||
{
|
||||
void* result = SQVM_WarningFunc(sqvm, a2, a3, nStringSize, ppString);
|
||||
if (g_bSQVM_WarnFuncCalled) // Check if its SQVM_Warning calling.
|
||||
void* retaddr = _ReturnAddress();
|
||||
|
||||
if (retaddr != SQVM_WarningFunc) // Check if its SQVM_Warning calling.
|
||||
{
|
||||
return result; // If not return.
|
||||
}
|
||||
|
||||
static bool initialized = false;
|
||||
static std::string vmType[4] = { "Script(S): WARNING: ", "Script(C): WARNING: ", "Script(U): WARNING: ", "Script(X): WARNING: " };
|
||||
|
||||
static auto iconsole = spdlog::stdout_logger_mt("sqvm_warn_iconsole"); // in-game console.
|
||||
static auto wconsole = spdlog::stdout_logger_mt("sqvm_warn_wconsole"); // windows console.
|
||||
static auto sqlogger = spdlog::basic_logger_mt("sqvm_warn_logger", "platform\\logs\\sqvm_warn.log"); // file logger.
|
||||
|
||||
#ifdef GAMEDLL_S3
|
||||
int vmIdx = *(int*)((std::uintptr_t)sqvm + 0x18);
|
||||
#else // TODO [ AMOS ]: nothing equal to 'rdx + 18h' exist in the vm pointers for anything below S3.
|
||||
#else // TODO [ AMOS ]: nothing equal to 'rdx + 18h' exist in the vm structs for anything below S3.
|
||||
int vmIdx = 3;
|
||||
#endif
|
||||
std::string vmStr = vmType[vmIdx].c_str();
|
||||
|
||||
g_spd_sqvm_w_oss.str("");
|
||||
g_spd_sqvm_w_oss.clear();
|
||||
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
|
||||
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
|
||||
static std::shared_ptr<spdlog::logger> sqlogger = spdlog::get("sqvm_warn_logger");
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
iconsole = std::make_shared<spdlog::logger>("sqvm_warn_ostream", g_spd_sqvm_p_ostream_sink);
|
||||
iconsole->set_pattern("[%S.%e] %v\n");
|
||||
iconsole->set_level(spdlog::level::debug);
|
||||
wconsole->set_pattern("[%S.%e] %v\n");
|
||||
wconsole->set_level(spdlog::level::debug);
|
||||
sqlogger->set_pattern("[%S.%e] %v\n");
|
||||
sqlogger->set_level(spdlog::level::debug);
|
||||
initialized = true;
|
||||
}
|
||||
std::string vmStr = SQVM_LOG_T[vmIdx].c_str();
|
||||
std::string svConstructor((char*)*ppString, *nStringSize); // Get string from memory via std::string constructor.
|
||||
vmStr.append(svConstructor);
|
||||
|
||||
std::string stringConstructor((char*)*ppString, *nStringSize); // Get string from memory via std::string constructor.
|
||||
vmStr.append(stringConstructor);
|
||||
|
||||
std::string s = g_spd_sqvm_w_oss.str();
|
||||
const char* c = s.c_str();
|
||||
|
||||
if (sq_showvmwarning->m_pParent->m_iValue > 0)
|
||||
if (sq_showvmwarning->GetInt() > 0)
|
||||
{
|
||||
sqlogger->debug(vmStr); // Emit to file.
|
||||
}
|
||||
if (sq_showvmwarning->m_pParent->m_iValue > 1)
|
||||
if (sq_showvmwarning->GetInt() > 1)
|
||||
{
|
||||
iconsole->debug(vmStr); // Emit to in-game console.
|
||||
wconsole->debug(vmStr); // Emit to windows console.
|
||||
#ifndef DEDICATED
|
||||
std::string s = g_spd_sqvm_w_oss.str();
|
||||
const char* c = s.c_str();
|
||||
Items.push_back(Strdup(c));
|
||||
#endif // !DEDICATED
|
||||
if (!g_bSpdLog_UseAnsiClr)
|
||||
{
|
||||
wconsole->debug(vmStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string vmStrAnsi = SQVM_ANSI_LOG_T[vmIdx].c_str();
|
||||
vmStrAnsi.append(svConstructor);
|
||||
wconsole->debug(vmStrAnsi);
|
||||
}
|
||||
|
||||
#ifndef DEDICATED
|
||||
if (sq_showvmwarning->m_pParent->m_iValue > 2)
|
||||
g_spd_sys_w_oss.str("");
|
||||
g_spd_sys_w_oss.clear();
|
||||
|
||||
iconsole->debug(vmStr); // Emit to in-game console.
|
||||
|
||||
std::string s = g_spd_sys_w_oss.str();
|
||||
g_pIConsole->m_ivConLog.push_back(Strdup(s.c_str()));
|
||||
|
||||
if (sq_showvmwarning->GetInt() > 2)
|
||||
{
|
||||
g_pLogSystem.AddLog((LogType_t)vmIdx, s);
|
||||
const char* c = s.c_str();
|
||||
Items.push_back(Strdup(c));
|
||||
g_pIConsole->m_ivConLog.push_back(Strdup(s.c_str()));
|
||||
}
|
||||
#endif // !DEDICATED
|
||||
g_bSQVM_WarnFuncCalled = false;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//---------------------------------------------------------------------------------
|
||||
void* HSQVM_WarningCmd(int a1, int a2)
|
||||
{
|
||||
g_bSQVM_WarnFuncCalled = true;
|
||||
return SQVM_WarningCmd(a1, a2);
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
@ -187,7 +163,7 @@ void* HSQVM_LoadRson(const char* szRsonName)
|
||||
// Returns the new path if the rson exists on the disk
|
||||
if (FileExists(szFilePath) && SQVM_LoadRson(szRsonName))
|
||||
{
|
||||
if (sq_showrsonloading->m_pParent->m_iValue > 0)
|
||||
if (sq_showrsonloading->GetBool())
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "\n");
|
||||
DevMsg(eDLL_T::ENGINE, "______________________________________________________________\n");
|
||||
@ -200,7 +176,7 @@ void* HSQVM_LoadRson(const char* szRsonName)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sq_showrsonloading->m_pParent->m_iValue > 0)
|
||||
if (sq_showrsonloading->GetBool())
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "\n");
|
||||
DevMsg(eDLL_T::ENGINE, "______________________________________________________________\n");
|
||||
@ -230,7 +206,7 @@ bool HSQVM_LoadScript(void* sqvm, const char* szScriptPath, const char* szScript
|
||||
}
|
||||
}
|
||||
|
||||
if (sq_showscriptloading->m_pParent->m_iValue > 0)
|
||||
if (sq_showscriptloading->GetBool())
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "Loading SQVM Script '%s'\n", filepath);
|
||||
}
|
||||
@ -241,7 +217,7 @@ bool HSQVM_LoadScript(void* sqvm, const char* szScriptPath, const char* szScript
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sq_showscriptloading->m_pParent->m_iValue > 0)
|
||||
if (sq_showscriptloading->GetBool())
|
||||
{
|
||||
DevMsg(eDLL_T::ENGINE, "FAILED. Try SP / VPK for '%s'\n", filepath);
|
||||
}
|
||||
@ -272,7 +248,28 @@ int HSQVM_NativeTest(void* sqvm)
|
||||
|
||||
void RegisterUIScriptFunctions(void* sqvm)
|
||||
{
|
||||
HSQVM_RegisterFunction(sqvm, "UINativeTest", "native ui function", "void", "", &HSQVM_NativeTest);
|
||||
#ifndef DEDICATED
|
||||
HSQVM_RegisterFunction(sqvm, "UINativeTest", "native ui test function", "void", "", &HSQVM_NativeTest);
|
||||
|
||||
// functions for retrieving server browser data
|
||||
HSQVM_RegisterFunction(sqvm, "GetServerName", "get name of the server at the specified index of the server list", "string", "int", &SQNativeFunctions::IBrowser::GetServerName);
|
||||
HSQVM_RegisterFunction(sqvm, "GetServerPlaylist", "get playlist of the server at the specified index of the server list", "string", "int", &SQNativeFunctions::IBrowser::GetServerPlaylist);
|
||||
HSQVM_RegisterFunction(sqvm, "GetServerMap", "get map of the server at the specified index of the server list", "string", "int", &SQNativeFunctions::IBrowser::GetServerMap);
|
||||
HSQVM_RegisterFunction(sqvm, "GetServerCount", "get number of public servers", "int", "", &SQNativeFunctions::IBrowser::GetServerCount);
|
||||
|
||||
// misc main menu functions
|
||||
HSQVM_RegisterFunction(sqvm, "GetSDKVersion", "get sdk version as a string", "string", "", &SQNativeFunctions::IBrowser::GetSDKVersion);
|
||||
HSQVM_RegisterFunction(sqvm, "GetPromoData", "get promo data for specified slot type", "string", "int", &SQNativeFunctions::IBrowser::GetPromoData);
|
||||
|
||||
// functions for connecting to servers
|
||||
HSQVM_RegisterFunction(sqvm, "CreateServer", "start server with the specified settings", "void", "string,string,string,int", &SQNativeFunctions::IBrowser::CreateServerFromMenu);
|
||||
HSQVM_RegisterFunction(sqvm, "SetEncKeyAndConnect", "set the encryption key to that of the specified server and connects to it", "void", "int", &SQNativeFunctions::IBrowser::SetEncKeyAndConnect);
|
||||
HSQVM_RegisterFunction(sqvm, "JoinPrivateServerFromMenu", "join private server by token", "void", "string", &SQNativeFunctions::IBrowser::JoinPrivateServerFromMenu);
|
||||
HSQVM_RegisterFunction(sqvm, "GetPrivateServerMessage", "get private server join status message", "string", "string", &SQNativeFunctions::IBrowser::GetPrivateServerMessage);
|
||||
HSQVM_RegisterFunction(sqvm, "ConnectToIPFromMenu", "join server by ip and encryption key", "void", "string,string", &SQNativeFunctions::IBrowser::ConnectToIPFromMenu);
|
||||
|
||||
HSQVM_RegisterFunction(sqvm, "GetAvailableMaps", "gets an array of all the available maps that can be used to host a server", "array<string>", "", &SQNativeFunctions::IBrowser::GetAvailableMaps);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RegisterClientScriptFunctions(void* sqvm)
|
||||
@ -285,14 +282,13 @@ void RegisterServerScriptFunctions(void* sqvm)
|
||||
HSQVM_RegisterFunction(sqvm, "ServerNativeTest", "native server function", "void", "", &HSQVM_NativeTest);
|
||||
}
|
||||
|
||||
ADDRESS UIVM = (void*)p_SQVM_CreateUIVM.FollowNearCall().FindPatternSelf("48 8B 1D", ADDRESS::Direction::DOWN, 50).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr();
|
||||
|
||||
void HSQVM_RegisterOriginFuncs(void* sqvm)
|
||||
{
|
||||
if (sqvm == *UIVM.RCast<void**>())
|
||||
if (sqvm == *p_SQVM_UIVM.RCast<void**>())
|
||||
RegisterUIScriptFunctions(sqvm);
|
||||
else
|
||||
RegisterClientScriptFunctions(sqvm);
|
||||
|
||||
return SQVM_RegisterOriginFuncs(sqvm);
|
||||
}
|
||||
|
||||
@ -300,7 +296,6 @@ void SQVM_Attach()
|
||||
{
|
||||
DetourAttach((LPVOID*)&SQVM_PrintFunc, &HSQVM_PrintFunc);
|
||||
DetourAttach((LPVOID*)&SQVM_WarningFunc, &HSQVM_WarningFunc);
|
||||
DetourAttach((LPVOID*)&SQVM_WarningCmd, &HSQVM_WarningCmd);
|
||||
DetourAttach((LPVOID*)&SQVM_LoadRson, &HSQVM_LoadRson);
|
||||
DetourAttach((LPVOID*)&SQVM_LoadScript, &HSQVM_LoadScript);
|
||||
DetourAttach((LPVOID*)&SQVM_RegisterOriginFuncs, &HSQVM_RegisterOriginFuncs);
|
||||
@ -310,7 +305,6 @@ void SQVM_Detach()
|
||||
{
|
||||
DetourDetach((LPVOID*)&SQVM_PrintFunc, &HSQVM_PrintFunc);
|
||||
DetourDetach((LPVOID*)&SQVM_WarningFunc, &HSQVM_WarningFunc);
|
||||
DetourDetach((LPVOID*)&SQVM_WarningCmd, &HSQVM_WarningCmd);
|
||||
DetourDetach((LPVOID*)&SQVM_LoadRson, &HSQVM_LoadRson);
|
||||
DetourDetach((LPVOID*)&SQVM_LoadScript, &HSQVM_LoadScript);
|
||||
DetourDetach((LPVOID*)&SQVM_RegisterOriginFuncs, &HSQVM_RegisterOriginFuncs);
|
||||
|
@ -27,6 +27,28 @@ struct SQFuncRegistration
|
||||
}
|
||||
};
|
||||
|
||||
const static std::string SQVM_LOG_T[4] =
|
||||
{
|
||||
"Script(S):",
|
||||
"Script(C):",
|
||||
"Script(U):",
|
||||
"Script(X):"
|
||||
};
|
||||
|
||||
const static std::string SQVM_ANSI_LOG_T[4] =
|
||||
{
|
||||
"\u001b[94mScript(S):",
|
||||
"\u001b[90mScript(C):",
|
||||
"\u001b[33mScript(U):",
|
||||
"\u001b[90mScript(X):"
|
||||
};
|
||||
|
||||
typedef int SQRESULT;
|
||||
#define SQ_OK (1)
|
||||
#define SQ_ERROR (-1)
|
||||
#define SQ_FAILED(res) (res<0)
|
||||
#define SQ_SUCCEEDED(res) (res>=0)
|
||||
|
||||
namespace
|
||||
{
|
||||
/* ==== SQUIRREL ======================================================================================================================================================== */
|
||||
@ -51,15 +73,11 @@ namespace
|
||||
ADDRESS p_SQVM_RegisterFunc = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x38\x45\x0F\xB6\xC8", "xxxxxxxx"); /*48 83 EC 38 45 0F B6 C8*/
|
||||
void* (*SQVM_RegisterFunc)(void* sqvm, SQFuncRegistration* sqFunc, int a1) = (void* (*)(void*, SQFuncRegistration*, int))p_SQVM_RegisterFunc.GetPtr();
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
ADDRESS p_SQVM_CreateUIVM = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xE8\x00\x00\x00\x00\x84\xC0\x74\x18\xE8\x00\x00\x00\x00", "x????xxxxx????")
|
||||
bool (*SQVM_CreateUIVM)() = (bool(*)())p_SQVM_CreateUIVM.FollowNearCall().GetPtr();
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
ADDRESS p_SQVM_CreateUIVM = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xE8\x00\x00\x00\x00\x84\xC0\x74\xE0\x44\x38\x25\x00\x00\x00\x00", "x????xxxxxxx????");
|
||||
bool (*SQVM_CreateUIVM)() = (bool(*)())p_SQVM_CreateUIVM.FollowNearCall().GetPtr();
|
||||
#endif
|
||||
ADDRESS p_SQVM_CreateUIVM = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x48\x8B\x1D\x00\x00\x00\x00\xC6\x05\x00\x00\x00\x00\x00", "xxxxxxxxx????xx?????"); /*40 53 48 83 EC 20 48 8B 1D ? ? ? ? C6 05 ? ? ? ? ?*/
|
||||
bool (*SQVM_CreateUIVM)() = (bool(*)())p_SQVM_CreateUIVM.GetPtr();
|
||||
ADDRESS p_SQVM_UIVM = (void*)p_SQVM_CreateUIVM.FindPatternSelf("48 8B 1D", ADDRESS::Direction::DOWN, 50).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr();
|
||||
|
||||
ADDRESS p_SQVM_RegisterOriginFuncs = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xE8\x00\x00\x00\x00\x48\x8B\x0D\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\xC7\x05\x00\x00\x00\x00\x00\x00\x00\x00", "x????xxx????xxx????x????xxx????xx????????");
|
||||
ADDRESS p_SQVM_RegisterOriginFuncs = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xE8\x00\x00\x00\x00\x48\x8B\x0D\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\xC7\x05\x00\x00\x00\x00\x00\x00\x00\x00", "x????xxx????xxx????x????xxx????xx????????"); /*E8 ? ? ? ? 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? E8 ? ? ? ? 48 8B 05 ? ? ? ? C7 05 ? ? ? ? ? ? ? ?*/
|
||||
void (*SQVM_RegisterOriginFuncs)(void* sqvm) = (void(*)(void*))p_SQVM_RegisterOriginFuncs.FollowNearCall().GetPtr();
|
||||
}
|
||||
|
||||
@ -69,15 +87,11 @@ bool HSQVM_LoadScript(void* sqvm, const char* szScriptPath, const char* szScript
|
||||
|
||||
void HSQVM_RegisterFunction(void* sqvm, const char* szName, const char* szHelpString, const char* szRetValType, const char* szArgTypes, void* pFunction);
|
||||
int HSQVM_NativeTest(void* sqvm);
|
||||
|
||||
void HSQVM_RegisterOriginFuncs(void* sqvm);
|
||||
|
||||
void SQVM_Attach();
|
||||
void SQVM_Detach();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
extern bool g_bSQVM_WarnFuncCalled;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class HSQVM : public IDetour
|
||||
{
|
||||
|
BIN
r5dev/thirdparty/detours/libs/detours.lib
vendored
BIN
r5dev/thirdparty/detours/libs/detours.lib
vendored
Binary file not shown.
BIN
r5dev/thirdparty/detours/libs/syelog.lib
vendored
BIN
r5dev/thirdparty/detours/libs/syelog.lib
vendored
Binary file not shown.
1783
r5dev/thirdparty/detours/src/creatwth.cpp
vendored
Normal file
1783
r5dev/thirdparty/detours/src/creatwth.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2597
r5dev/thirdparty/detours/src/detours.cpp
vendored
Normal file
2597
r5dev/thirdparty/detours/src/detours.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4306
r5dev/thirdparty/detours/src/disasm.cpp
vendored
Normal file
4306
r5dev/thirdparty/detours/src/disasm.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
932
r5dev/thirdparty/detours/src/modules.cpp
vendored
Normal file
932
r5dev/thirdparty/detours/src/modules.cpp
vendored
Normal file
@ -0,0 +1,932 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Module Enumeration Functions (modules.cpp of detours.lib)
|
||||
//
|
||||
// Microsoft Research Detours Package, Version 4.0.1
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// Module enumeration functions.
|
||||
//
|
||||
|
||||
// #define DETOUR_DEBUG 1
|
||||
#define DETOURS_INTERNAL
|
||||
#include "../include/detours.h"
|
||||
|
||||
#if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH
|
||||
#error detours.h version mismatch
|
||||
#endif
|
||||
|
||||
#define CLR_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]
|
||||
#define IAT_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT]
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
const GUID DETOUR_EXE_RESTORE_GUID = {
|
||||
0xbda26f34, 0xbc82, 0x4829,
|
||||
{ 0x9e, 0x64, 0x74, 0x2c, 0x4, 0xc8, 0x4f, 0xa0 } };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
PDETOUR_SYM_INFO DetourLoadImageHlp(VOID)
|
||||
{
|
||||
static DETOUR_SYM_INFO symInfo;
|
||||
static PDETOUR_SYM_INFO pSymInfo = NULL;
|
||||
static BOOL failed = false;
|
||||
|
||||
if (failed) {
|
||||
return NULL;
|
||||
}
|
||||
if (pSymInfo != NULL) {
|
||||
return pSymInfo;
|
||||
}
|
||||
|
||||
ZeroMemory(&symInfo, sizeof(symInfo));
|
||||
// Create a real handle to the process.
|
||||
#if 0
|
||||
DuplicateHandle(GetCurrentProcess(),
|
||||
GetCurrentProcess(),
|
||||
GetCurrentProcess(),
|
||||
&symInfo.hProcess,
|
||||
0,
|
||||
FALSE,
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
#else
|
||||
symInfo.hProcess = GetCurrentProcess();
|
||||
#endif
|
||||
|
||||
symInfo.hDbgHelp = LoadLibraryExW(L"dbghelp.dll", NULL, 0);
|
||||
if (symInfo.hDbgHelp == NULL) {
|
||||
abort:
|
||||
failed = true;
|
||||
if (symInfo.hDbgHelp != NULL) {
|
||||
FreeLibrary(symInfo.hDbgHelp);
|
||||
}
|
||||
symInfo.pfImagehlpApiVersionEx = NULL;
|
||||
symInfo.pfSymInitialize = NULL;
|
||||
symInfo.pfSymSetOptions = NULL;
|
||||
symInfo.pfSymGetOptions = NULL;
|
||||
symInfo.pfSymLoadModule64 = NULL;
|
||||
symInfo.pfSymGetModuleInfo64 = NULL;
|
||||
symInfo.pfSymFromName = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
symInfo.pfImagehlpApiVersionEx
|
||||
= (PF_ImagehlpApiVersionEx)GetProcAddress(symInfo.hDbgHelp,
|
||||
"ImagehlpApiVersionEx");
|
||||
symInfo.pfSymInitialize
|
||||
= (PF_SymInitialize)GetProcAddress(symInfo.hDbgHelp, "SymInitialize");
|
||||
symInfo.pfSymSetOptions
|
||||
= (PF_SymSetOptions)GetProcAddress(symInfo.hDbgHelp, "SymSetOptions");
|
||||
symInfo.pfSymGetOptions
|
||||
= (PF_SymGetOptions)GetProcAddress(symInfo.hDbgHelp, "SymGetOptions");
|
||||
symInfo.pfSymLoadModule64
|
||||
= (PF_SymLoadModule64)GetProcAddress(symInfo.hDbgHelp, "SymLoadModule64");
|
||||
symInfo.pfSymGetModuleInfo64
|
||||
= (PF_SymGetModuleInfo64)GetProcAddress(symInfo.hDbgHelp, "SymGetModuleInfo64");
|
||||
symInfo.pfSymFromName
|
||||
= (PF_SymFromName)GetProcAddress(symInfo.hDbgHelp, "SymFromName");
|
||||
|
||||
API_VERSION av;
|
||||
ZeroMemory(&av, sizeof(av));
|
||||
av.MajorVersion = API_VERSION_NUMBER;
|
||||
|
||||
if (symInfo.pfImagehlpApiVersionEx == NULL ||
|
||||
symInfo.pfSymInitialize == NULL ||
|
||||
symInfo.pfSymLoadModule64 == NULL ||
|
||||
symInfo.pfSymGetModuleInfo64 == NULL ||
|
||||
symInfo.pfSymFromName == NULL) {
|
||||
goto abort;
|
||||
}
|
||||
|
||||
symInfo.pfImagehlpApiVersionEx(&av);
|
||||
if (av.MajorVersion < API_VERSION_NUMBER) {
|
||||
goto abort;
|
||||
}
|
||||
|
||||
if (!symInfo.pfSymInitialize(symInfo.hProcess, NULL, FALSE)) {
|
||||
// We won't retry the initialize if it fails.
|
||||
goto abort;
|
||||
}
|
||||
|
||||
if (symInfo.pfSymGetOptions != NULL && symInfo.pfSymSetOptions != NULL) {
|
||||
DWORD dw = symInfo.pfSymGetOptions();
|
||||
|
||||
dw &= ~(SYMOPT_CASE_INSENSITIVE |
|
||||
SYMOPT_UNDNAME |
|
||||
SYMOPT_DEFERRED_LOADS |
|
||||
0);
|
||||
dw |= (
|
||||
#if defined(SYMOPT_EXACT_SYMBOLS)
|
||||
SYMOPT_EXACT_SYMBOLS |
|
||||
#endif
|
||||
#if defined(SYMOPT_NO_UNQUALIFIED_LOADS)
|
||||
SYMOPT_NO_UNQUALIFIED_LOADS |
|
||||
#endif
|
||||
SYMOPT_DEFERRED_LOADS |
|
||||
#if defined(SYMOPT_FAIL_CRITICAL_ERRORS)
|
||||
SYMOPT_FAIL_CRITICAL_ERRORS |
|
||||
#endif
|
||||
#if defined(SYMOPT_INCLUDE_32BIT_MODULES)
|
||||
SYMOPT_INCLUDE_32BIT_MODULES |
|
||||
#endif
|
||||
0);
|
||||
symInfo.pfSymSetOptions(dw);
|
||||
}
|
||||
|
||||
pSymInfo = &symInfo;
|
||||
return pSymInfo;
|
||||
}
|
||||
|
||||
PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule,
|
||||
_In_ LPCSTR pszFunction)
|
||||
{
|
||||
if (pszFunction == NULL) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////// First, try GetProcAddress.
|
||||
//
|
||||
#pragma prefast(suppress:28752, "We don't do the unicode conversion for LoadLibraryExA.")
|
||||
HMODULE hModule = LoadLibraryExA(pszModule, NULL, 0);
|
||||
if (hModule == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PBYTE pbCode = (PBYTE)GetProcAddress(hModule, pszFunction);
|
||||
if (pbCode) {
|
||||
return pbCode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////// Then try ImageHelp.
|
||||
//
|
||||
DETOUR_TRACE(("DetourFindFunction(%hs, %hs)\n", pszModule, pszFunction));
|
||||
PDETOUR_SYM_INFO pSymInfo = DetourLoadImageHlp();
|
||||
if (pSymInfo == NULL) {
|
||||
DETOUR_TRACE(("DetourLoadImageHlp failed: %lu\n",
|
||||
GetLastError()));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pSymInfo->pfSymLoadModule64(pSymInfo->hProcess, NULL,
|
||||
(PCHAR)pszModule, NULL,
|
||||
(DWORD64)hModule, 0) == 0) {
|
||||
if (ERROR_SUCCESS != GetLastError()) {
|
||||
DETOUR_TRACE(("SymLoadModule64(%p) failed: %lu\n",
|
||||
pSymInfo->hProcess, GetLastError()));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hrRet;
|
||||
CHAR szFullName[512];
|
||||
IMAGEHLP_MODULE64 modinfo;
|
||||
ZeroMemory(&modinfo, sizeof(modinfo));
|
||||
modinfo.SizeOfStruct = sizeof(modinfo);
|
||||
if (!pSymInfo->pfSymGetModuleInfo64(pSymInfo->hProcess, (DWORD64)hModule, &modinfo)) {
|
||||
DETOUR_TRACE(("SymGetModuleInfo64(%p, %p) failed: %lu\n",
|
||||
pSymInfo->hProcess, hModule, GetLastError()));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hrRet = StringCchCopyA(szFullName, sizeof(szFullName)/sizeof(CHAR), modinfo.ModuleName);
|
||||
if (FAILED(hrRet)) {
|
||||
DETOUR_TRACE(("StringCchCopyA failed: %08lx\n", hrRet));
|
||||
return NULL;
|
||||
}
|
||||
hrRet = StringCchCatA(szFullName, sizeof(szFullName)/sizeof(CHAR), "!");
|
||||
if (FAILED(hrRet)) {
|
||||
DETOUR_TRACE(("StringCchCatA failed: %08lx\n", hrRet));
|
||||
return NULL;
|
||||
}
|
||||
hrRet = StringCchCatA(szFullName, sizeof(szFullName)/sizeof(CHAR), pszFunction);
|
||||
if (FAILED(hrRet)) {
|
||||
DETOUR_TRACE(("StringCchCatA failed: %08lx\n", hrRet));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct CFullSymbol : SYMBOL_INFO {
|
||||
CHAR szRestOfName[512];
|
||||
} symbol;
|
||||
ZeroMemory(&symbol, sizeof(symbol));
|
||||
//symbol.ModBase = (ULONG64)hModule;
|
||||
symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
#ifdef DBHLPAPI
|
||||
symbol.MaxNameLen = sizeof(symbol.szRestOfName)/sizeof(symbol.szRestOfName[0]);
|
||||
#else
|
||||
symbol.MaxNameLength = sizeof(symbol.szRestOfName)/sizeof(symbol.szRestOfName[0]);
|
||||
#endif
|
||||
|
||||
if (!pSymInfo->pfSymFromName(pSymInfo->hProcess, szFullName, &symbol)) {
|
||||
DETOUR_TRACE(("SymFromName(%hs) failed: %lu\n", szFullName, GetLastError()));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(DETOURS_IA64)
|
||||
// On the IA64, we get a raw code pointer from the symbol engine
|
||||
// and have to convert it to a wrapped [code pointer, global pointer].
|
||||
//
|
||||
PPLABEL_DESCRIPTOR pldEntry = (PPLABEL_DESCRIPTOR)DetourGetEntryPoint(hModule);
|
||||
PPLABEL_DESCRIPTOR pldSymbol = new PLABEL_DESCRIPTOR;
|
||||
|
||||
pldSymbol->EntryPoint = symbol.Address;
|
||||
pldSymbol->GlobalPointer = pldEntry->GlobalPointer;
|
||||
return (PBYTE)pldSymbol;
|
||||
#elif defined(DETOURS_ARM)
|
||||
// On the ARM, we get a raw code pointer, which we must convert into a
|
||||
// valied Thumb2 function pointer.
|
||||
return DETOURS_PBYTE_TO_PFUNC(symbol.Address);
|
||||
#else
|
||||
return (PBYTE)symbol.Address;
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////// Module Image Functions.
|
||||
//
|
||||
|
||||
HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast)
|
||||
{
|
||||
PBYTE pbLast = (PBYTE)hModuleLast + MM_ALLOCATION_GRANULARITY;
|
||||
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
ZeroMemory(&mbi, sizeof(mbi));
|
||||
|
||||
// Find the next memory region that contains a mapped PE image.
|
||||
//
|
||||
for (;; pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) {
|
||||
if (VirtualQuery(pbLast, &mbi, sizeof(mbi)) <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Skip uncommitted regions and guard pages.
|
||||
//
|
||||
if ((mbi.State != MEM_COMMIT) ||
|
||||
((mbi.Protect & 0xff) == PAGE_NOACCESS) ||
|
||||
(mbi.Protect & PAGE_GUARD)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
__try {
|
||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pbLast;
|
||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
|
||||
(DWORD)pDosHeader->e_lfanew > mbi.RegionSize ||
|
||||
(DWORD)pDosHeader->e_lfanew < sizeof(*pDosHeader)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
||||
pDosHeader->e_lfanew);
|
||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
return (HMODULE)pDosHeader;
|
||||
}
|
||||
#pragma prefast(suppress:28940, "A bad pointer means this probably isn't a PE header.")
|
||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule)
|
||||
{
|
||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
|
||||
if (hModule == NULL) {
|
||||
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
|
||||
}
|
||||
|
||||
__try {
|
||||
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
|
||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
||||
pDosHeader->e_lfanew);
|
||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
||||
return NULL;
|
||||
}
|
||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PDETOUR_CLR_HEADER pClrHeader = NULL;
|
||||
if (pNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
if (((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.VirtualAddress != 0 &&
|
||||
((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.Size != 0) {
|
||||
pClrHeader = (PDETOUR_CLR_HEADER)
|
||||
(((PBYTE)pDosHeader)
|
||||
+ ((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.VirtualAddress);
|
||||
}
|
||||
}
|
||||
else if (pNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
||||
if (((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.VirtualAddress != 0 &&
|
||||
((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.Size != 0) {
|
||||
pClrHeader = (PDETOUR_CLR_HEADER)
|
||||
(((PBYTE)pDosHeader)
|
||||
+ ((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.VirtualAddress);
|
||||
}
|
||||
}
|
||||
|
||||
if (pClrHeader != NULL) {
|
||||
// For MSIL assemblies, we want to use the _Cor entry points.
|
||||
|
||||
HMODULE hClr = GetModuleHandleW(L"MSCOREE.DLL");
|
||||
if (hClr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
return (PVOID)GetProcAddress(hClr, "_CorExeMain");
|
||||
}
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
|
||||
// Pure resource DLLs have neither an entry point nor CLR information
|
||||
// so handle them by returning NULL (LastError is NO_ERROR)
|
||||
if (pNtHeader->OptionalHeader.AddressOfEntryPoint == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ((PBYTE)pDosHeader) +
|
||||
pNtHeader->OptionalHeader.AddressOfEntryPoint;
|
||||
}
|
||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule)
|
||||
{
|
||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
|
||||
if (hModule == NULL) {
|
||||
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
|
||||
}
|
||||
|
||||
__try {
|
||||
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
|
||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
||||
pDosHeader->e_lfanew);
|
||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
||||
return NULL;
|
||||
}
|
||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return NULL;
|
||||
}
|
||||
SetLastError(NO_ERROR);
|
||||
|
||||
return (pNtHeader->OptionalHeader.SizeOfImage);
|
||||
}
|
||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
ZeroMemory(&mbi, sizeof(mbi));
|
||||
|
||||
__try {
|
||||
if (VirtualQuery(pvAddr, &mbi, sizeof(mbi)) <= 0) {
|
||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Skip uncommitted regions and guard pages.
|
||||
//
|
||||
if ((mbi.State != MEM_COMMIT) ||
|
||||
((mbi.Protect & 0xff) == PAGE_NOACCESS) ||
|
||||
(mbi.Protect & PAGE_GUARD)) {
|
||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mbi.AllocationBase;
|
||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
||||
pDosHeader->e_lfanew);
|
||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
||||
return NULL;
|
||||
}
|
||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return NULL;
|
||||
}
|
||||
SetLastError(NO_ERROR);
|
||||
|
||||
return (HMODULE)pDosHeader;
|
||||
}
|
||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline PBYTE RvaAdjust(_Pre_notnull_ PIMAGE_DOS_HEADER pDosHeader, _In_ DWORD raddr)
|
||||
{
|
||||
if (raddr != NULL) {
|
||||
return ((PBYTE)pDosHeader) + raddr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule,
|
||||
_In_opt_ PVOID pContext,
|
||||
_In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport)
|
||||
{
|
||||
if (pfExport == NULL) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
|
||||
if (hModule == NULL) {
|
||||
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
|
||||
}
|
||||
|
||||
__try {
|
||||
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
|
||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
||||
pDosHeader->e_lfanew);
|
||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
||||
return FALSE;
|
||||
}
|
||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PIMAGE_EXPORT_DIRECTORY pExportDir
|
||||
= (PIMAGE_EXPORT_DIRECTORY)
|
||||
RvaAdjust(pDosHeader,
|
||||
pNtHeader->OptionalHeader
|
||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
||||
|
||||
if (pExportDir == NULL) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PBYTE pExportDirEnd = (PBYTE)pExportDir + pNtHeader->OptionalHeader
|
||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
|
||||
PDWORD pdwFunctions = (PDWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfFunctions);
|
||||
PDWORD pdwNames = (PDWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfNames);
|
||||
PWORD pwOrdinals = (PWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfNameOrdinals);
|
||||
|
||||
for (DWORD nFunc = 0; nFunc < pExportDir->NumberOfFunctions; nFunc++) {
|
||||
PBYTE pbCode = (pdwFunctions != NULL)
|
||||
? (PBYTE)RvaAdjust(pDosHeader, pdwFunctions[nFunc]) : NULL;
|
||||
PCHAR pszName = NULL;
|
||||
|
||||
// if the pointer is in the export region, then it is a forwarder.
|
||||
if (pbCode > (PBYTE)pExportDir && pbCode < pExportDirEnd) {
|
||||
pbCode = NULL;
|
||||
}
|
||||
|
||||
for (DWORD n = 0; n < pExportDir->NumberOfNames; n++) {
|
||||
if (pwOrdinals[n] == nFunc) {
|
||||
pszName = (pdwNames != NULL)
|
||||
? (PCHAR)RvaAdjust(pDosHeader, pdwNames[n]) : NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ULONG nOrdinal = pExportDir->Base + nFunc;
|
||||
|
||||
if (!pfExport(pContext, nOrdinal, pszName, pbCode)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetLastError(NO_ERROR);
|
||||
return TRUE;
|
||||
}
|
||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule,
|
||||
_In_opt_ PVOID pContext,
|
||||
_In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
|
||||
_In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFunc)
|
||||
{
|
||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
|
||||
if (hModule == NULL) {
|
||||
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
|
||||
}
|
||||
|
||||
__try {
|
||||
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
|
||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
||||
pDosHeader->e_lfanew);
|
||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
||||
return FALSE;
|
||||
}
|
||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PIMAGE_IMPORT_DESCRIPTOR iidp
|
||||
= (PIMAGE_IMPORT_DESCRIPTOR)
|
||||
RvaAdjust(pDosHeader,
|
||||
pNtHeader->OptionalHeader
|
||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||
|
||||
if (iidp == NULL) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (; iidp->OriginalFirstThunk != 0; iidp++) {
|
||||
|
||||
PCSTR pszName = (PCHAR)RvaAdjust(pDosHeader, iidp->Name);
|
||||
if (pszName == NULL) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PIMAGE_THUNK_DATA pThunks = (PIMAGE_THUNK_DATA)
|
||||
RvaAdjust(pDosHeader, iidp->OriginalFirstThunk);
|
||||
PVOID * pAddrs = (PVOID *)
|
||||
RvaAdjust(pDosHeader, iidp->FirstThunk);
|
||||
|
||||
HMODULE hFile = DetourGetContainingModule(pAddrs[0]);
|
||||
|
||||
if (pfImportFile != NULL) {
|
||||
if (!pfImportFile(pContext, hFile, pszName)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD nNames = 0;
|
||||
if (pThunks) {
|
||||
for (; pThunks[nNames].u1.Ordinal; nNames++) {
|
||||
DWORD nOrdinal = 0;
|
||||
PCSTR pszFunc = NULL;
|
||||
|
||||
if (IMAGE_SNAP_BY_ORDINAL(pThunks[nNames].u1.Ordinal)) {
|
||||
nOrdinal = (DWORD)IMAGE_ORDINAL(pThunks[nNames].u1.Ordinal);
|
||||
}
|
||||
else {
|
||||
pszFunc = (PCSTR)RvaAdjust(pDosHeader,
|
||||
(DWORD)pThunks[nNames].u1.AddressOfData + 2);
|
||||
}
|
||||
|
||||
if (pfImportFunc != NULL) {
|
||||
if (!pfImportFunc(pContext,
|
||||
nOrdinal,
|
||||
pszFunc,
|
||||
&pAddrs[nNames])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pfImportFunc != NULL) {
|
||||
pfImportFunc(pContext, 0, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pfImportFile != NULL) {
|
||||
pfImportFile(pContext, NULL, NULL);
|
||||
}
|
||||
SetLastError(NO_ERROR);
|
||||
return TRUE;
|
||||
}
|
||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Context for DetourEnumerateImportsThunk, which adapts "regular" callbacks for use with "Ex".
|
||||
struct _DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT
|
||||
{
|
||||
PVOID pContext;
|
||||
PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc;
|
||||
};
|
||||
|
||||
// Callback for DetourEnumerateImportsEx that adapts DetourEnumerateImportsEx
|
||||
// for use with a DetourEnumerateImports callback -- derefence the IAT and pass the value on.
|
||||
|
||||
static
|
||||
BOOL
|
||||
CALLBACK
|
||||
DetourEnumerateImportsThunk(_In_ PVOID VoidContext,
|
||||
_In_ DWORD nOrdinal,
|
||||
_In_opt_ PCSTR pszFunc,
|
||||
_In_opt_ PVOID* ppvFunc)
|
||||
{
|
||||
_DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT const * const
|
||||
pContext = (_DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT*)VoidContext;
|
||||
return pContext->pfImportFunc(pContext->pContext, nOrdinal, pszFunc, ppvFunc ? *ppvFunc : NULL);
|
||||
}
|
||||
|
||||
BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule,
|
||||
_In_opt_ PVOID pContext,
|
||||
_In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
|
||||
_In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc)
|
||||
{
|
||||
if (pfImportFile == NULL || pfImportFunc == NULL) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT const context = { pContext, pfImportFunc };
|
||||
|
||||
return DetourEnumerateImportsEx(hModule,
|
||||
(PVOID)&context,
|
||||
pfImportFile,
|
||||
&DetourEnumerateImportsThunk);
|
||||
}
|
||||
|
||||
static PDETOUR_LOADED_BINARY WINAPI GetPayloadSectionFromModule(HMODULE hModule)
|
||||
{
|
||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
|
||||
if (hModule == NULL) {
|
||||
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
|
||||
}
|
||||
|
||||
__try {
|
||||
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
|
||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
||||
pDosHeader->e_lfanew);
|
||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
||||
return NULL;
|
||||
}
|
||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PIMAGE_SECTION_HEADER pSectionHeaders
|
||||
= (PIMAGE_SECTION_HEADER)((PBYTE)pNtHeader
|
||||
+ sizeof(pNtHeader->Signature)
|
||||
+ sizeof(pNtHeader->FileHeader)
|
||||
+ pNtHeader->FileHeader.SizeOfOptionalHeader);
|
||||
|
||||
for (DWORD n = 0; n < pNtHeader->FileHeader.NumberOfSections; n++) {
|
||||
if (strcmp((PCHAR)pSectionHeaders[n].Name, ".detour") == 0) {
|
||||
if (pSectionHeaders[n].VirtualAddress == 0 ||
|
||||
pSectionHeaders[n].SizeOfRawData == 0) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
PBYTE pbData = (PBYTE)pDosHeader + pSectionHeaders[n].VirtualAddress;
|
||||
DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pbData;
|
||||
if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
|
||||
pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (pHeader->nDataOffset == 0) {
|
||||
pHeader->nDataOffset = pHeader->cbHeaderSize;
|
||||
}
|
||||
SetLastError(NO_ERROR);
|
||||
return (PBYTE)pHeader;
|
||||
}
|
||||
}
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return NULL;
|
||||
}
|
||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule)
|
||||
{
|
||||
PDETOUR_LOADED_BINARY pBinary = GetPayloadSectionFromModule(hModule);
|
||||
if (pBinary == NULL) {
|
||||
// Error set by GetPayloadSectionFromModule.
|
||||
return 0;
|
||||
}
|
||||
|
||||
__try {
|
||||
DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pBinary;
|
||||
if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
|
||||
pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
|
||||
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return 0;
|
||||
}
|
||||
SetLastError(NO_ERROR);
|
||||
return pHeader->cbDataSize;
|
||||
}
|
||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
_Writable_bytes_(*pcbData)
|
||||
_Readable_bytes_(*pcbData)
|
||||
_Success_(return != NULL)
|
||||
PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule,
|
||||
_In_ REFGUID rguid,
|
||||
_Out_opt_ DWORD *pcbData)
|
||||
{
|
||||
PBYTE pbData = NULL;
|
||||
if (pcbData) {
|
||||
*pcbData = 0;
|
||||
}
|
||||
|
||||
PDETOUR_LOADED_BINARY pBinary = GetPayloadSectionFromModule(hModule);
|
||||
if (pBinary == NULL) {
|
||||
// Error set by GetPayloadSectionFromModule.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__try {
|
||||
DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pBinary;
|
||||
if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
|
||||
pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
|
||||
|
||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PBYTE pbBeg = ((PBYTE)pHeader) + pHeader->nDataOffset;
|
||||
PBYTE pbEnd = ((PBYTE)pHeader) + pHeader->cbDataSize;
|
||||
|
||||
for (pbData = pbBeg; pbData < pbEnd;) {
|
||||
DETOUR_SECTION_RECORD *pSection = (DETOUR_SECTION_RECORD *)pbData;
|
||||
|
||||
if (DetourAreSameGuid(pSection->guid, rguid)) {
|
||||
if (pcbData) {
|
||||
*pcbData = pSection->cbBytes - sizeof(*pSection);
|
||||
}
|
||||
SetLastError(NO_ERROR);
|
||||
return (PBYTE)(pSection + 1);
|
||||
}
|
||||
|
||||
pbData = (PBYTE)pSection + pSection->cbBytes;
|
||||
}
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_Writable_bytes_(*pcbData)
|
||||
_Readable_bytes_(*pcbData)
|
||||
_Success_(return != NULL)
|
||||
PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid,
|
||||
_Out_opt_ DWORD *pcbData)
|
||||
{
|
||||
for (HMODULE hMod = NULL; (hMod = DetourEnumerateModules(hMod)) != NULL;) {
|
||||
PVOID pvData;
|
||||
|
||||
pvData = DetourFindPayload(hMod, rguid, pcbData);
|
||||
if (pvData != NULL) {
|
||||
return pvData;
|
||||
}
|
||||
}
|
||||
SetLastError(ERROR_MOD_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI DetourFreePayload(_In_ PVOID pvData)
|
||||
{
|
||||
BOOL fSucceeded = FALSE;
|
||||
|
||||
// If you have any doubts about the following code, please refer to the comments in DetourCopyPayloadToProcess.
|
||||
HMODULE hModule = DetourGetContainingModule(pvData);
|
||||
DETOUR_ASSERT(hModule != NULL);
|
||||
if (hModule != NULL) {
|
||||
fSucceeded = VirtualFree(hModule, 0, MEM_RELEASE);
|
||||
DETOUR_ASSERT(fSucceeded);
|
||||
if (fSucceeded) {
|
||||
hModule = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return fSucceeded;
|
||||
}
|
||||
|
||||
BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData,
|
||||
_In_ DWORD cbData)
|
||||
{
|
||||
PDETOUR_EXE_RESTORE pder = (PDETOUR_EXE_RESTORE)pvData;
|
||||
|
||||
if (pder->cb != sizeof(*pder) || pder->cb > cbData) {
|
||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD dwPermIdh = ~0u;
|
||||
DWORD dwPermInh = ~0u;
|
||||
DWORD dwPermClr = ~0u;
|
||||
DWORD dwIgnore;
|
||||
BOOL fSucceeded = FALSE;
|
||||
BOOL fUpdated32To64 = FALSE;
|
||||
|
||||
if (pder->pclr != NULL && pder->clr.Flags != ((PDETOUR_CLR_HEADER)pder->pclr)->Flags) {
|
||||
// If we had to promote the 32/64-bit agnostic IL to 64-bit, we can't restore
|
||||
// that.
|
||||
fUpdated32To64 = TRUE;
|
||||
}
|
||||
|
||||
if (DetourVirtualProtectSameExecute(pder->pidh, pder->cbidh,
|
||||
PAGE_EXECUTE_READWRITE, &dwPermIdh)) {
|
||||
if (DetourVirtualProtectSameExecute(pder->pinh, pder->cbinh,
|
||||
PAGE_EXECUTE_READWRITE, &dwPermInh)) {
|
||||
|
||||
CopyMemory(pder->pidh, &pder->idh, pder->cbidh);
|
||||
CopyMemory(pder->pinh, &pder->inh, pder->cbinh);
|
||||
|
||||
if (pder->pclr != NULL && !fUpdated32To64) {
|
||||
if (DetourVirtualProtectSameExecute(pder->pclr, pder->cbclr,
|
||||
PAGE_EXECUTE_READWRITE, &dwPermClr)) {
|
||||
CopyMemory(pder->pclr, &pder->clr, pder->cbclr);
|
||||
VirtualProtect(pder->pclr, pder->cbclr, dwPermClr, &dwIgnore);
|
||||
fSucceeded = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fSucceeded = TRUE;
|
||||
}
|
||||
VirtualProtect(pder->pinh, pder->cbinh, dwPermInh, &dwIgnore);
|
||||
}
|
||||
VirtualProtect(pder->pidh, pder->cbidh, dwPermIdh, &dwIgnore);
|
||||
}
|
||||
// Delete the payload after successful recovery to prevent repeated restore
|
||||
if (fSucceeded) {
|
||||
DetourFreePayload(pder);
|
||||
pder = NULL;
|
||||
}
|
||||
return fSucceeded;
|
||||
}
|
||||
|
||||
BOOL WINAPI DetourRestoreAfterWith()
|
||||
{
|
||||
PVOID pvData;
|
||||
DWORD cbData;
|
||||
|
||||
pvData = DetourFindPayloadEx(DETOUR_EXE_RESTORE_GUID, &cbData);
|
||||
|
||||
if (pvData != NULL && cbData != 0) {
|
||||
return DetourRestoreAfterWithEx(pvData, cbData);
|
||||
}
|
||||
SetLastError(ERROR_MOD_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// End of File
|
335
r5dev/thirdparty/detours/src/uimports.cpp
vendored
Normal file
335
r5dev/thirdparty/detours/src/uimports.cpp
vendored
Normal file
@ -0,0 +1,335 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Add DLLs to a module import table (uimports.cpp of detours.lib)
|
||||
//
|
||||
// Microsoft Research Detours Package, Version 4.0.1
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// Note that this file is included into creatwth.cpp one or more times
|
||||
// (once for each supported module format).
|
||||
//
|
||||
|
||||
#include "../include/detours.h"
|
||||
|
||||
#if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH
|
||||
#error detours.h version mismatch
|
||||
#endif
|
||||
|
||||
// UpdateImports32 aka UpdateImports64
|
||||
static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess,
|
||||
HMODULE hModule,
|
||||
__in_ecount(nDlls) LPCSTR *plpDlls,
|
||||
DWORD nDlls)
|
||||
{
|
||||
BOOL fSucceeded = FALSE;
|
||||
DWORD cbNew = 0;
|
||||
|
||||
BYTE * pbNew = NULL;
|
||||
DWORD i;
|
||||
SIZE_T cbRead;
|
||||
DWORD n;
|
||||
|
||||
PBYTE pbModule = (PBYTE)hModule;
|
||||
|
||||
IMAGE_DOS_HEADER idh;
|
||||
ZeroMemory(&idh, sizeof(idh));
|
||||
if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), &cbRead)
|
||||
|| cbRead < sizeof(idh)) {
|
||||
|
||||
DETOUR_TRACE(("ReadProcessMemory(idh@%p..%p) failed: %lu\n",
|
||||
pbModule, pbModule + sizeof(idh), GetLastError()));
|
||||
|
||||
finish:
|
||||
if (pbNew != NULL) {
|
||||
delete[] pbNew;
|
||||
pbNew = NULL;
|
||||
}
|
||||
return fSucceeded;
|
||||
}
|
||||
|
||||
IMAGE_NT_HEADERS_XX inh;
|
||||
ZeroMemory(&inh, sizeof(inh));
|
||||
|
||||
if (!ReadProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), &cbRead)
|
||||
|| cbRead < sizeof(inh)) {
|
||||
DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p) failed: %lu\n",
|
||||
pbModule + idh.e_lfanew,
|
||||
pbModule + idh.e_lfanew + sizeof(inh),
|
||||
GetLastError()));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (inh.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC_XX) {
|
||||
DETOUR_TRACE(("Wrong size image (%04x != %04x).\n",
|
||||
inh.OptionalHeader.Magic, IMAGE_NT_OPTIONAL_HDR_MAGIC_XX));
|
||||
SetLastError(ERROR_INVALID_BLOCK);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
// Zero out the bound table so loader doesn't use it instead of our new table.
|
||||
inh.BOUND_DIRECTORY.VirtualAddress = 0;
|
||||
inh.BOUND_DIRECTORY.Size = 0;
|
||||
|
||||
// Find the size of the mapped file.
|
||||
DWORD dwSec = idh.e_lfanew +
|
||||
FIELD_OFFSET(IMAGE_NT_HEADERS_XX, OptionalHeader) +
|
||||
inh.FileHeader.SizeOfOptionalHeader;
|
||||
|
||||
for (i = 0; i < inh.FileHeader.NumberOfSections; i++) {
|
||||
IMAGE_SECTION_HEADER ish;
|
||||
ZeroMemory(&ish, sizeof(ish));
|
||||
|
||||
if (!ReadProcessMemory(hProcess, pbModule + dwSec + sizeof(ish) * i, &ish,
|
||||
sizeof(ish), &cbRead)
|
||||
|| cbRead < sizeof(ish)) {
|
||||
|
||||
DETOUR_TRACE(("ReadProcessMemory(ish@%p..%p) failed: %lu\n",
|
||||
pbModule + dwSec + sizeof(ish) * i,
|
||||
pbModule + dwSec + sizeof(ish) * (i + 1),
|
||||
GetLastError()));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
DETOUR_TRACE(("ish[%lu] : va=%08lx sr=%lu\n", i, ish.VirtualAddress, ish.SizeOfRawData));
|
||||
|
||||
// If the linker didn't suggest an IAT in the data directories, the
|
||||
// loader will look for the section of the import directory to be used
|
||||
// for this instead. Since we put out new IMPORT_DIRECTORY outside any
|
||||
// section boundary, the loader will not find it. So we provide one
|
||||
// explicitly to avoid the search.
|
||||
//
|
||||
if (inh.IAT_DIRECTORY.VirtualAddress == 0 &&
|
||||
inh.IMPORT_DIRECTORY.VirtualAddress >= ish.VirtualAddress &&
|
||||
inh.IMPORT_DIRECTORY.VirtualAddress < ish.VirtualAddress + ish.SizeOfRawData) {
|
||||
|
||||
inh.IAT_DIRECTORY.VirtualAddress = ish.VirtualAddress;
|
||||
inh.IAT_DIRECTORY.Size = ish.SizeOfRawData;
|
||||
}
|
||||
}
|
||||
|
||||
if (inh.IMPORT_DIRECTORY.VirtualAddress != 0 && inh.IMPORT_DIRECTORY.Size == 0) {
|
||||
|
||||
// Don't worry about changing the PE file,
|
||||
// because the load information of the original PE header has been saved and will be restored.
|
||||
// The change here is just for the following code to work normally
|
||||
|
||||
PIMAGE_IMPORT_DESCRIPTOR pImageImport = (PIMAGE_IMPORT_DESCRIPTOR)(pbModule + inh.IMPORT_DIRECTORY.VirtualAddress);
|
||||
|
||||
do {
|
||||
IMAGE_IMPORT_DESCRIPTOR ImageImport;
|
||||
if (!ReadProcessMemory(hProcess, pImageImport, &ImageImport, sizeof(ImageImport), NULL)) {
|
||||
DETOUR_TRACE(("ReadProcessMemory failed: %lu\n", GetLastError()));
|
||||
goto finish;
|
||||
}
|
||||
inh.IMPORT_DIRECTORY.Size += sizeof(IMAGE_IMPORT_DESCRIPTOR);
|
||||
if (!ImageImport.Name) {
|
||||
break;
|
||||
}
|
||||
++pImageImport;
|
||||
} while (TRUE);
|
||||
|
||||
DWORD dwLastError = GetLastError();
|
||||
OutputDebugString(TEXT("[This PE file has an import table, but the import table size is marked as 0. This is an error.")
|
||||
TEXT("If it is not repaired, the launched program will not work properly, Detours has automatically repaired its import table size for you! ! !]\r\n"));
|
||||
if (GetLastError() != dwLastError) {
|
||||
SetLastError(dwLastError);
|
||||
}
|
||||
}
|
||||
|
||||
DETOUR_TRACE((" Imports: %p..%p\n",
|
||||
pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,
|
||||
pbModule + inh.IMPORT_DIRECTORY.VirtualAddress +
|
||||
inh.IMPORT_DIRECTORY.Size));
|
||||
|
||||
// Calculate new import directory size. Note that since inh is from another
|
||||
// process, inh could have been corrupted. We need to protect against
|
||||
// integer overflow in allocation calculations.
|
||||
DWORD nOldDlls = inh.IMPORT_DIRECTORY.Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
|
||||
DWORD obRem;
|
||||
if (DWordMult(sizeof(IMAGE_IMPORT_DESCRIPTOR), nDlls, &obRem) != S_OK) {
|
||||
DETOUR_TRACE(("too many new DLLs.\n"));
|
||||
goto finish;
|
||||
}
|
||||
DWORD obOld;
|
||||
if (DWordAdd(obRem, sizeof(IMAGE_IMPORT_DESCRIPTOR) * nOldDlls, &obOld) != S_OK) {
|
||||
DETOUR_TRACE(("DLL entries overflow.\n"));
|
||||
goto finish;
|
||||
}
|
||||
DWORD obTab = PadToDwordPtr(obOld);
|
||||
// Check for integer overflow.
|
||||
if (obTab < obOld) {
|
||||
DETOUR_TRACE(("DLL entries padding overflow.\n"));
|
||||
goto finish;
|
||||
}
|
||||
DWORD stSize;
|
||||
if (DWordMult(sizeof(DWORD_XX) * 4, nDlls, &stSize) != S_OK) {
|
||||
DETOUR_TRACE(("String table overflow.\n"));
|
||||
goto finish;
|
||||
}
|
||||
DWORD obDll;
|
||||
if (DWordAdd(obTab, stSize, &obDll) != S_OK) {
|
||||
DETOUR_TRACE(("Import table size overflow\n"));
|
||||
goto finish;
|
||||
}
|
||||
DWORD obStr = obDll;
|
||||
cbNew = obStr;
|
||||
for (n = 0; n < nDlls; n++) {
|
||||
if (DWordAdd(cbNew, PadToDword((DWORD)strlen(plpDlls[n]) + 1), &cbNew) != S_OK) {
|
||||
DETOUR_TRACE(("Overflow adding string table entry\n"));
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
pbNew = new BYTE [cbNew];
|
||||
if (pbNew == NULL) {
|
||||
DETOUR_TRACE(("new BYTE [cbNew] failed.\n"));
|
||||
goto finish;
|
||||
}
|
||||
ZeroMemory(pbNew, cbNew);
|
||||
|
||||
PBYTE pbBase = pbModule;
|
||||
PBYTE pbNext = pbBase
|
||||
+ inh.OptionalHeader.BaseOfCode
|
||||
+ inh.OptionalHeader.SizeOfCode
|
||||
+ inh.OptionalHeader.SizeOfInitializedData
|
||||
+ inh.OptionalHeader.SizeOfUninitializedData;
|
||||
if (pbBase < pbNext) {
|
||||
pbBase = pbNext;
|
||||
}
|
||||
DETOUR_TRACE(("pbBase = %p\n", pbBase));
|
||||
|
||||
PBYTE pbNewIid = FindAndAllocateNearBase(hProcess, pbModule, pbBase, cbNew);
|
||||
if (pbNewIid == NULL) {
|
||||
DETOUR_TRACE(("FindAndAllocateNearBase failed.\n"));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
PIMAGE_IMPORT_DESCRIPTOR piid = (PIMAGE_IMPORT_DESCRIPTOR)pbNew;
|
||||
IMAGE_THUNK_DATAXX *pt = NULL;
|
||||
|
||||
DWORD obBase = (DWORD)(pbNewIid - pbModule);
|
||||
DWORD dwProtect = 0;
|
||||
|
||||
if (inh.IMPORT_DIRECTORY.VirtualAddress != 0) {
|
||||
// Read the old import directory if it exists.
|
||||
DETOUR_TRACE(("IMPORT_DIRECTORY perms=%lx\n", dwProtect));
|
||||
|
||||
if (!ReadProcessMemory(hProcess,
|
||||
pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,
|
||||
&piid[nDlls],
|
||||
nOldDlls * sizeof(IMAGE_IMPORT_DESCRIPTOR), &cbRead)
|
||||
|| cbRead < nOldDlls * sizeof(IMAGE_IMPORT_DESCRIPTOR)) {
|
||||
|
||||
DETOUR_TRACE(("ReadProcessMemory(imports) failed: %lu\n", GetLastError()));
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
for (n = 0; n < nDlls; n++) {
|
||||
HRESULT hrRet = StringCchCopyA((char*)pbNew + obStr, cbNew - obStr, plpDlls[n]);
|
||||
if (FAILED(hrRet)) {
|
||||
DETOUR_TRACE(("StringCchCopyA failed: %08lx\n", hrRet));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
// After copying the string, we patch up the size "??" bits if any.
|
||||
hrRet = ReplaceOptionalSizeA((char*)pbNew + obStr,
|
||||
cbNew - obStr,
|
||||
DETOURS_STRINGIFY(DETOURS_BITS_XX));
|
||||
if (FAILED(hrRet)) {
|
||||
DETOUR_TRACE(("ReplaceOptionalSizeA failed: %08lx\n", hrRet));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
DWORD nOffset = obTab + (sizeof(IMAGE_THUNK_DATAXX) * (4 * n));
|
||||
piid[n].OriginalFirstThunk = obBase + nOffset;
|
||||
|
||||
// We need 2 thunks for the import table and 2 thunks for the IAT.
|
||||
// One for an ordinal import and one to mark the end of the list.
|
||||
pt = ((IMAGE_THUNK_DATAXX*)(pbNew + nOffset));
|
||||
pt[0].u1.Ordinal = IMAGE_ORDINAL_FLAG_XX + 1;
|
||||
pt[1].u1.Ordinal = 0;
|
||||
|
||||
nOffset = obTab + (sizeof(IMAGE_THUNK_DATAXX) * ((4 * n) + 2));
|
||||
piid[n].FirstThunk = obBase + nOffset;
|
||||
pt = ((IMAGE_THUNK_DATAXX*)(pbNew + nOffset));
|
||||
pt[0].u1.Ordinal = IMAGE_ORDINAL_FLAG_XX + 1;
|
||||
pt[1].u1.Ordinal = 0;
|
||||
piid[n].TimeDateStamp = 0;
|
||||
piid[n].ForwarderChain = 0;
|
||||
piid[n].Name = obBase + obStr;
|
||||
|
||||
obStr += PadToDword((DWORD)strlen(plpDlls[n]) + 1);
|
||||
}
|
||||
_Analysis_assume_(obStr <= cbNew);
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < nDlls + nOldDlls; i++) {
|
||||
DETOUR_TRACE(("%8d. Look=%08x Time=%08x Fore=%08x Name=%08x Addr=%08x\n",
|
||||
i,
|
||||
piid[i].OriginalFirstThunk,
|
||||
piid[i].TimeDateStamp,
|
||||
piid[i].ForwarderChain,
|
||||
piid[i].Name,
|
||||
piid[i].FirstThunk));
|
||||
if (piid[i].OriginalFirstThunk == 0 && piid[i].FirstThunk == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!WriteProcessMemory(hProcess, pbNewIid, pbNew, obStr, NULL)) {
|
||||
DETOUR_TRACE(("WriteProcessMemory(iid) failed: %lu\n", GetLastError()));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
DETOUR_TRACE(("obBaseBef = %08lx..%08lx\n",
|
||||
inh.IMPORT_DIRECTORY.VirtualAddress,
|
||||
inh.IMPORT_DIRECTORY.VirtualAddress + inh.IMPORT_DIRECTORY.Size));
|
||||
DETOUR_TRACE(("obBaseAft = %08lx..%08lx\n", obBase, obBase + obStr));
|
||||
|
||||
// In this case the file didn't have an import directory in first place,
|
||||
// so we couldn't fix the missing IAT above. We still need to explicitly
|
||||
// provide an IAT to prevent to loader from looking for one.
|
||||
//
|
||||
if (inh.IAT_DIRECTORY.VirtualAddress == 0) {
|
||||
inh.IAT_DIRECTORY.VirtualAddress = obBase;
|
||||
inh.IAT_DIRECTORY.Size = cbNew;
|
||||
}
|
||||
|
||||
inh.IMPORT_DIRECTORY.VirtualAddress = obBase;
|
||||
inh.IMPORT_DIRECTORY.Size = cbNew;
|
||||
|
||||
/////////////////////// Update the NT header for the new import directory.
|
||||
//
|
||||
if (!DetourVirtualProtectSameExecuteEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders,
|
||||
PAGE_EXECUTE_READWRITE, &dwProtect)) {
|
||||
DETOUR_TRACE(("VirtualProtectEx(inh) write failed: %lu\n", GetLastError()));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
inh.OptionalHeader.CheckSum = 0;
|
||||
|
||||
if (!WriteProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {
|
||||
DETOUR_TRACE(("WriteProcessMemory(idh) failed: %lu\n", GetLastError()));
|
||||
goto finish;
|
||||
}
|
||||
DETOUR_TRACE(("WriteProcessMemory(idh:%p..%p)\n", pbModule, pbModule + sizeof(idh)));
|
||||
|
||||
if (!WriteProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), NULL)) {
|
||||
DETOUR_TRACE(("WriteProcessMemory(inh) failed: %lu\n", GetLastError()));
|
||||
goto finish;
|
||||
}
|
||||
DETOUR_TRACE(("WriteProcessMemory(inh:%p..%p)\n",
|
||||
pbModule + idh.e_lfanew,
|
||||
pbModule + idh.e_lfanew + sizeof(inh)));
|
||||
|
||||
if (!VirtualProtectEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders,
|
||||
dwProtect, &dwProtect)) {
|
||||
DETOUR_TRACE(("VirtualProtectEx(idh) restore failed: %lu\n", GetLastError()));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
fSucceeded = TRUE;
|
||||
goto finish;
|
||||
}
|
14
r5dev/thirdparty/imgui/src/imgui_impl_win32.cpp
vendored
14
r5dev/thirdparty/imgui/src/imgui_impl_win32.cpp
vendored
@ -21,6 +21,15 @@
|
||||
#include <tchar.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
// Includes of the game have to be here since this header is precompiled.
|
||||
#include "string"
|
||||
#include "d3d11.h"
|
||||
#include "public/include/httplib.h"
|
||||
|
||||
// Game ImGui headers are here for mouse tracking.
|
||||
#include "gameui/IBrowser.h"
|
||||
#include "gameui/IConsole.h"
|
||||
|
||||
// Configuration flags to add in your imconfig.h file:
|
||||
//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant.
|
||||
|
||||
@ -189,6 +198,9 @@ void ImGui_ImplWin32_Shutdown()
|
||||
}
|
||||
|
||||
static bool ImGui_ImplWin32_UpdateMouseCursor()
|
||||
{
|
||||
// These have to be here to prevent the mouse in-game from flickering when '::SetCursor(...)' is called.
|
||||
if (g_pIBrowser->m_bActivate || g_pIConsole->m_bActivate)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
||||
@ -220,6 +232,8 @@ static bool ImGui_ImplWin32_UpdateMouseCursor()
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateMousePos()
|
||||
{
|
||||
|
40
r5dev/thirdparty/lzham/include/lzham_assert.h
vendored
Normal file
40
r5dev/thirdparty/lzham/include/lzham_assert.h
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
// File: lzham_assert.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
const unsigned int LZHAM_FAIL_EXCEPTION_CODE = 256U;
|
||||
void lzham_enable_fail_exceptions(bool enabled);
|
||||
|
||||
void lzham_assert(const char* pExp, const char* pFile, unsigned line);
|
||||
void lzham_fail(const char* pExp, const char* pFile, unsigned line);
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define LZHAM_ASSERT(x) ((void)0)
|
||||
#else
|
||||
#define LZHAM_ASSERT(_exp) (void)( (!!(_exp)) || (lzham_assert(#_exp, __FILE__, __LINE__), 0) )
|
||||
#define LZHAM_ASSERTS_ENABLED 1
|
||||
#endif
|
||||
|
||||
#define LZHAM_VERIFY(_exp) (void)( (!!(_exp)) || (lzham_assert(#_exp, __FILE__, __LINE__), 0) )
|
||||
|
||||
#define LZHAM_FAIL(msg) do { lzham_fail(#msg, __FILE__, __LINE__); } while(0)
|
||||
|
||||
#define LZHAM_ASSERT_OPEN_RANGE(x, l, h) LZHAM_ASSERT((x >= l) && (x < h))
|
||||
#define LZHAM_ASSERT_CLOSED_RANGE(x, l, h) LZHAM_ASSERT((x >= l) && (x <= h))
|
||||
|
||||
void lzham_trace(const char* pFmt, va_list args);
|
||||
void lzham_trace(const char* pFmt, ...);
|
||||
|
||||
// Borrowed from boost libraries.
|
||||
template <bool x> struct assume_failure;
|
||||
template <> struct assume_failure<true> { enum { blah = 1 }; };
|
||||
template<int x> struct assume_try { };
|
||||
|
||||
#define LZHAM_JOINER_FINAL(a, b) a##b
|
||||
#define LZHAM_JOINER(a, b) LZHAM_JOINER_FINAL(a, b)
|
||||
#define LZHAM_JOIN(a, b) LZHAM_JOINER(a, b)
|
||||
#if defined(__GNUC__)
|
||||
#define LZHAM_ASSUME(p) typedef assume_try < sizeof(assume_failure< (bool)(p) > ) > LZHAM_JOIN(assume_typedef, __COUNTER__) __attribute__((unused))
|
||||
#else
|
||||
#define LZHAM_ASSUME(p) typedef assume_try < sizeof(assume_failure< (bool)(p) > ) > LZHAM_JOIN(assume_typedef, __COUNTER__)
|
||||
#endif
|
13
r5dev/thirdparty/lzham/include/lzham_checksum.h
vendored
Normal file
13
r5dev/thirdparty/lzham/include/lzham_checksum.h
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// File: lzham_checksum.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
const uint cInitAdler32 = 1U;
|
||||
uint adler32(const void* pBuf, size_t buflen, uint adler32 = cInitAdler32);
|
||||
|
||||
const uint cInitCRC32 = 0U;
|
||||
uint crc32(uint crc, const lzham_uint8 *ptr, size_t buf_len);
|
||||
|
||||
} // namespace lzham
|
23
r5dev/thirdparty/lzham/include/lzham_config.h
vendored
Normal file
23
r5dev/thirdparty/lzham/include/lzham_config.h
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// File: lzham_config.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define LZHAM_BUILD_DEBUG
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG
|
||||
#endif
|
||||
#else
|
||||
#define LZHAM_BUILD_RELEASE
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#error DEBUG cannot be defined in LZHAM_BUILD_RELEASE
|
||||
#endif
|
||||
#endif
|
||||
#define LZHAM_BUFFERED_PRINTF 0
|
||||
#define LZHAM_PERF_SECTIONS 0
|
171
r5dev/thirdparty/lzham/include/lzham_core.h
vendored
Normal file
171
r5dev/thirdparty/lzham/include/lzham_core.h
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
// File: lzham_core.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning (disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
#if defined(_XBOX) && !defined(LZHAM_ANSI_CPLUSPLUS)
|
||||
// X360
|
||||
#include <xtl.h>
|
||||
#define _HAS_EXCEPTIONS 0
|
||||
#define NOMINMAX
|
||||
|
||||
#define LZHAM_PLATFORM_X360 1
|
||||
#define LZHAM_USE_WIN32_API 1
|
||||
#define LZHAM_USE_WIN32_ATOMIC_FUNCTIONS 1
|
||||
#define LZHAM_64BIT_POINTERS 0
|
||||
#define LZHAM_CPU_HAS_64BIT_REGISTERS 1
|
||||
#define LZHAM_BIG_ENDIAN_CPU 1
|
||||
#define LZHAM_USE_UNALIGNED_INT_LOADS 1
|
||||
#define LZHAM_RESTRICT __restrict
|
||||
#define LZHAM_FORCE_INLINE __forceinline
|
||||
#define LZHAM_NOTE_UNUSED(x) (void)x
|
||||
|
||||
#elif defined(WIN32) && !defined(LZHAM_ANSI_CPLUSPLUS)
|
||||
// MSVC or MinGW, x86 or x64, Win32 API's for threading and Win32 Interlocked API's or GCC built-ins for atomic ops.
|
||||
#ifdef NDEBUG
|
||||
// Ensure checked iterators are disabled.
|
||||
#define _SECURE_SCL 0
|
||||
#define _HAS_ITERATOR_DEBUGGING 0
|
||||
#endif
|
||||
#ifndef _DLL
|
||||
// If we're using the DLL form of the run-time libs, we're also going to be enabling exceptions because we'll be building CLR apps.
|
||||
// Otherwise, we disable exceptions for a small speed boost.
|
||||
//#define _HAS_EXCEPTIONS 0
|
||||
#endif
|
||||
#define NOMINMAX
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x500
|
||||
#endif
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define LZHAM_USE_WIN32_API 1
|
||||
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#define LZHAM_USE_GCC_ATOMIC_BUILTINS 1
|
||||
#else
|
||||
#define LZHAM_USE_WIN32_ATOMIC_FUNCTIONS 1
|
||||
#endif
|
||||
|
||||
#define LZHAM_PLATFORM_PC 1
|
||||
|
||||
#ifdef _WIN64
|
||||
#define LZHAM_PLATFORM_PC_X64 1
|
||||
#define LZHAM_64BIT_POINTERS 1
|
||||
#define LZHAM_CPU_HAS_64BIT_REGISTERS 1
|
||||
#define LZHAM_LITTLE_ENDIAN_CPU 1
|
||||
#else
|
||||
#define LZHAM_PLATFORM_PC_X86 1
|
||||
#define LZHAM_64BIT_POINTERS 0
|
||||
#define LZHAM_CPU_HAS_64BIT_REGISTERS 0
|
||||
#define LZHAM_LITTLE_ENDIAN_CPU 1
|
||||
#endif
|
||||
|
||||
#define LZHAM_USE_UNALIGNED_INT_LOADS 1
|
||||
#define LZHAM_RESTRICT __restrict
|
||||
#define LZHAM_FORCE_INLINE __forceinline
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#define LZHAM_USE_MSVC_INTRINSICS 1
|
||||
#endif
|
||||
|
||||
#define LZHAM_NOTE_UNUSED(x) (void)x
|
||||
|
||||
#elif defined(__GNUC__) && !defined(LZHAM_ANSI_CPLUSPLUS)
|
||||
// GCC x86 or x64, pthreads for threading and GCC built-ins for atomic ops.
|
||||
#define LZHAM_PLATFORM_PC 1
|
||||
|
||||
#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
|
||||
#define LZHAM_PLATFORM_PC_X64 1
|
||||
#define LZHAM_64BIT_POINTERS 1
|
||||
#define LZHAM_CPU_HAS_64BIT_REGISTERS 1
|
||||
#else
|
||||
#define LZHAM_PLATFORM_PC_X86 1
|
||||
#define LZHAM_64BIT_POINTERS 0
|
||||
#define LZHAM_CPU_HAS_64BIT_REGISTERS 0
|
||||
#endif
|
||||
|
||||
#define LZHAM_USE_UNALIGNED_INT_LOADS 1
|
||||
|
||||
#define LZHAM_LITTLE_ENDIAN_CPU 1
|
||||
|
||||
#define LZHAM_USE_PTHREADS_API 1
|
||||
#define LZHAM_USE_GCC_ATOMIC_BUILTINS 1
|
||||
|
||||
#define LZHAM_RESTRICT
|
||||
|
||||
#if defined(__clang__)
|
||||
#define LZHAM_FORCE_INLINE inline
|
||||
#else
|
||||
#define LZHAM_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__))
|
||||
#endif
|
||||
|
||||
#define LZHAM_NOTE_UNUSED(x) (void)x
|
||||
#else
|
||||
// Vanilla ANSI-C/C++
|
||||
// No threading support, unaligned loads are NOT okay.
|
||||
#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
|
||||
#define LZHAM_64BIT_POINTERS 1
|
||||
#define LZHAM_CPU_HAS_64BIT_REGISTERS 1
|
||||
#else
|
||||
#define LZHAM_64BIT_POINTERS 0
|
||||
#define LZHAM_CPU_HAS_64BIT_REGISTERS 0
|
||||
#endif
|
||||
|
||||
#define LZHAM_USE_UNALIGNED_INT_LOADS 0
|
||||
|
||||
#if __BIG_ENDIAN__
|
||||
#define LZHAM_BIG_ENDIAN_CPU 1
|
||||
#else
|
||||
#define LZHAM_LITTLE_ENDIAN_CPU 1
|
||||
#endif
|
||||
|
||||
#define LZHAM_USE_GCC_ATOMIC_BUILTINS 0
|
||||
#define LZHAM_USE_WIN32_ATOMIC_FUNCTIONS 0
|
||||
|
||||
#define LZHAM_RESTRICT
|
||||
#define LZHAM_FORCE_INLINE inline
|
||||
|
||||
#define LZHAM_NOTE_UNUSED(x) (void)x
|
||||
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if LZHAM_LITTLE_ENDIAN_CPU
|
||||
const bool c_lzham_little_endian_platform = true;
|
||||
#else
|
||||
const bool c_lzham_little_endian_platform = false;
|
||||
#endif
|
||||
|
||||
const bool c_lzham_big_endian_platform = !c_lzham_little_endian_platform;
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <malloc.h>
|
||||
#include <stdarg.h>
|
||||
#include <memory.h>
|
||||
#include <limits.h>
|
||||
#include <algorithm>
|
||||
#include <errno.h>
|
||||
|
||||
#include "lzham.h"
|
||||
#include "lzham_config.h"
|
||||
#include "lzham_types.h"
|
||||
#include "lzham_assert.h"
|
||||
#include "lzham_platform.h"
|
||||
|
||||
#include "lzham_helpers.h"
|
||||
#include "lzham_traits.h"
|
||||
#include "lzham_mem.h"
|
||||
#include "lzham_math.h"
|
||||
#include "lzham_utils.h"
|
||||
#include "lzham_vector.h"
|
54
r5dev/thirdparty/lzham/include/lzham_helpers.h
vendored
Normal file
54
r5dev/thirdparty/lzham/include/lzham_helpers.h
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// File: lzham_helpers.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
#define LZHAM_NO_COPY_OR_ASSIGNMENT_OP(c) c(const c&); c& operator= (const c&);
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
namespace helpers
|
||||
{
|
||||
template<typename T> struct rel_ops
|
||||
{
|
||||
friend inline bool operator!=(const T& x, const T& y) { return (!(x == y)); }
|
||||
friend inline bool operator> (const T& x, const T& y) { return (y < x); }
|
||||
friend inline bool operator<=(const T& x, const T& y) { return (!(y < x)); }
|
||||
friend inline bool operator>=(const T& x, const T& y) { return (!(x < y)); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline T* construct(T* p)
|
||||
{
|
||||
return new (static_cast<void*>(p)) T;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline T* construct(T* p, const U& init)
|
||||
{
|
||||
return new (static_cast<void*>(p)) T(init);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void construct_array(T* p, uint n);
|
||||
|
||||
template <typename T, typename U>
|
||||
inline void construct_array(T* p, uint n, const U& init)
|
||||
{
|
||||
T* q = p + n;
|
||||
for ( ; p != q; ++p)
|
||||
new (static_cast<void*>(p)) T(init);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void destruct(T* p)
|
||||
{
|
||||
LZHAM_NOTE_UNUSED(p);
|
||||
p->~T();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void destruct_array(T* p, uint n);
|
||||
|
||||
} // namespace helpers
|
||||
|
||||
} // namespace lzham
|
14
r5dev/thirdparty/lzham/include/lzham_huffman_codes.h
vendored
Normal file
14
r5dev/thirdparty/lzham/include/lzham_huffman_codes.h
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// File: lzham_huffman_codes.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
//const uint cHuffmanMaxSupportedSyms = 600;
|
||||
const uint cHuffmanMaxSupportedSyms = 1024;
|
||||
|
||||
uint get_generate_huffman_codes_table_size();
|
||||
|
||||
bool generate_huffman_codes(void* pContext, uint num_syms, const uint16* pFreq, uint8* pCodesizes, uint& max_code_size, uint& total_freq_ret);
|
||||
|
||||
} // namespace lzham
|
45
r5dev/thirdparty/lzham/include/lzham_lzbase.h
vendored
Normal file
45
r5dev/thirdparty/lzham/include/lzham_lzbase.h
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
// File: lzham_lzbase.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
#include "../lzhamdecomp/lzham_lzdecompbase.h"
|
||||
|
||||
//#define LZHAM_LZVERIFY
|
||||
//#define LZHAM_DISABLE_RAW_BLOCKS
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
struct CLZBase : CLZDecompBase
|
||||
{
|
||||
uint8 m_slot_tab0[4096];
|
||||
uint8 m_slot_tab1[512];
|
||||
uint8 m_slot_tab2[256];
|
||||
|
||||
void init_slot_tabs();
|
||||
|
||||
inline void compute_lzx_position_slot(uint dist, uint& slot, uint& ofs)
|
||||
{
|
||||
uint s;
|
||||
if (dist < 0x1000)
|
||||
s = m_slot_tab0[dist];
|
||||
else if (dist < 0x100000)
|
||||
s = m_slot_tab1[dist >> 11];
|
||||
else if (dist < 0x1000000)
|
||||
s = m_slot_tab2[dist >> 16];
|
||||
else if (dist < 0x2000000)
|
||||
s = 48 + ((dist - 0x1000000) >> 23);
|
||||
else if (dist < 0x4000000)
|
||||
s = 50 + ((dist - 0x2000000) >> 24);
|
||||
else
|
||||
s = 52 + ((dist - 0x4000000) >> 25);
|
||||
|
||||
ofs = (dist - m_lzx_position_base[s]) & m_lzx_position_extra_mask[s];
|
||||
slot = s;
|
||||
|
||||
LZHAM_ASSERT(s < m_num_lzx_slots);
|
||||
LZHAM_ASSERT((m_lzx_position_base[slot] + ofs) == dist);
|
||||
LZHAM_ASSERT(ofs < (1U << m_lzx_position_extra_bits[slot]));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace lzham
|
146
r5dev/thirdparty/lzham/include/lzham_match_accel.h
vendored
Normal file
146
r5dev/thirdparty/lzham/include/lzham_match_accel.h
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
// File: lzham_match_accel.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
#include "lzham_lzbase.h"
|
||||
#include "lzham_threading.h"
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
const uint cMatchAccelMaxSupportedProbes = 128;
|
||||
|
||||
struct node
|
||||
{
|
||||
uint m_left;
|
||||
uint m_right;
|
||||
};
|
||||
|
||||
LZHAM_DEFINE_BITWISE_MOVABLE(node);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct dict_match
|
||||
{
|
||||
uint m_dist;
|
||||
uint16 m_len;
|
||||
|
||||
inline uint get_dist() const { return m_dist & 0x7FFFFFFF; }
|
||||
inline uint get_len() const { return m_len + 2; }
|
||||
inline bool is_last() const { return (int)m_dist < 0; }
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
LZHAM_DEFINE_BITWISE_MOVABLE(dict_match);
|
||||
|
||||
class search_accelerator
|
||||
{
|
||||
public:
|
||||
search_accelerator();
|
||||
|
||||
// If all_matches is true, the match finder returns all found matches with no filtering.
|
||||
// Otherwise, the finder will tend to return lists of matches with mostly unique lengths.
|
||||
// For each length, it will discard matches with worse distances (in the coding sense).
|
||||
bool init(CLZBase* pLZBase, task_pool* pPool, uint max_helper_threads, uint max_dict_size, uint max_matches, bool all_matches, uint max_probes);
|
||||
|
||||
void reset();
|
||||
void flush();
|
||||
|
||||
inline uint get_max_dict_size() const { return m_max_dict_size; }
|
||||
inline uint get_max_dict_size_mask() const { return m_max_dict_size_mask; }
|
||||
inline uint get_cur_dict_size() const { return m_cur_dict_size; }
|
||||
|
||||
inline uint get_lookahead_pos() const { return m_lookahead_pos; }
|
||||
inline uint get_lookahead_size() const { return m_lookahead_size; }
|
||||
|
||||
inline uint get_char(int delta_pos) const { return m_dict[(m_lookahead_pos + delta_pos) & m_max_dict_size_mask]; }
|
||||
inline uint get_char(uint cur_dict_pos, int delta_pos) const { return m_dict[(cur_dict_pos + delta_pos) & m_max_dict_size_mask]; }
|
||||
inline const uint8* get_ptr(uint pos) const { return &m_dict[pos]; }
|
||||
|
||||
uint get_max_helper_threads() const { return m_max_helper_threads; }
|
||||
|
||||
inline uint operator[](uint pos) const { return m_dict[pos]; }
|
||||
|
||||
uint get_max_add_bytes() const;
|
||||
bool add_bytes_begin(uint num_bytes, const uint8* pBytes);
|
||||
inline atomic32_t get_num_completed_helper_threads() const { return m_num_completed_helper_threads; }
|
||||
void add_bytes_end();
|
||||
|
||||
// Returns the lookahead's raw position/size/dict_size at the time add_bytes_begin() is called.
|
||||
inline uint get_fill_lookahead_pos() const { return m_fill_lookahead_pos; }
|
||||
inline uint get_fill_lookahead_size() const { return m_fill_lookahead_size; }
|
||||
inline uint get_fill_dict_size() const { return m_fill_dict_size; }
|
||||
|
||||
uint get_len2_match(uint lookahead_ofs);
|
||||
dict_match* find_matches(uint lookahead_ofs, bool spin = true);
|
||||
|
||||
void advance_bytes(uint num_bytes);
|
||||
|
||||
LZHAM_FORCE_INLINE uint get_match_len(uint lookahead_ofs, int dist, uint max_match_len, uint start_match_len = 0) const
|
||||
{
|
||||
LZHAM_ASSERT(lookahead_ofs < m_lookahead_size);
|
||||
LZHAM_ASSERT(start_match_len <= max_match_len);
|
||||
LZHAM_ASSERT(max_match_len <= (get_lookahead_size() - lookahead_ofs));
|
||||
|
||||
const int find_dict_size = m_cur_dict_size + lookahead_ofs;
|
||||
if (dist > find_dict_size)
|
||||
return 0;
|
||||
|
||||
const uint comp_pos = static_cast<uint>((m_lookahead_pos + lookahead_ofs - dist) & m_max_dict_size_mask);
|
||||
const uint lookahead_pos = (m_lookahead_pos + lookahead_ofs) & m_max_dict_size_mask;
|
||||
|
||||
const uint8* pComp = &m_dict[comp_pos];
|
||||
const uint8* pLookahead = &m_dict[lookahead_pos];
|
||||
|
||||
uint match_len;
|
||||
for (match_len = start_match_len; match_len < max_match_len; match_len++)
|
||||
if (pComp[match_len] != pLookahead[match_len])
|
||||
break;
|
||||
|
||||
return match_len;
|
||||
}
|
||||
|
||||
public:
|
||||
CLZBase* m_pLZBase;
|
||||
task_pool* m_pTask_pool;
|
||||
uint m_max_helper_threads;
|
||||
|
||||
uint m_max_dict_size;
|
||||
uint m_max_dict_size_mask;
|
||||
|
||||
uint m_lookahead_pos;
|
||||
uint m_lookahead_size;
|
||||
|
||||
uint m_cur_dict_size;
|
||||
|
||||
lzham::vector<uint8> m_dict;
|
||||
|
||||
enum { cHashSize = 65536 };
|
||||
lzham::vector<uint> m_hash;
|
||||
lzham::vector<node> m_nodes;
|
||||
|
||||
lzham::vector<dict_match> m_matches;
|
||||
lzham::vector<atomic32_t> m_match_refs;
|
||||
|
||||
lzham::vector<uint8> m_hash_thread_index;
|
||||
|
||||
enum { cDigramHashSize = 4096 };
|
||||
lzham::vector<uint> m_digram_hash;
|
||||
lzham::vector<uint> m_digram_next;
|
||||
|
||||
uint m_fill_lookahead_pos;
|
||||
uint m_fill_lookahead_size;
|
||||
uint m_fill_dict_size;
|
||||
|
||||
uint m_max_probes;
|
||||
uint m_max_matches;
|
||||
|
||||
bool m_all_matches;
|
||||
|
||||
volatile atomic32_t m_next_match_ref;
|
||||
|
||||
volatile atomic32_t m_num_completed_helper_threads;
|
||||
|
||||
void find_all_matches_callback(uint64 data, void* pData_ptr);
|
||||
bool find_all_matches(uint num_bytes);
|
||||
bool find_len2_matches();
|
||||
};
|
||||
|
||||
} // namespace lzham
|
113
r5dev/thirdparty/lzham/include/lzham_math.h
vendored
Normal file
113
r5dev/thirdparty/lzham/include/lzham_math.h
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
// File: lzham_math.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
#if defined(LZHAM_USE_MSVC_INTRINSICS) && !defined(__MINGW32__)
|
||||
#include <intrin.h>
|
||||
#if defined(_MSC_VER)
|
||||
#pragma intrinsic(_BitScanReverse)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
// Yes I know these should probably be pass by ref, not val:
|
||||
// http://www.stepanovpapers.com/notes.pdf
|
||||
// Just don't use them on non-simple (non built-in) types!
|
||||
template<typename T> inline T minimum(T a, T b) { return (a < b) ? a : b; }
|
||||
|
||||
template<typename T> inline T minimum(T a, T b, T c) { return minimum(minimum(a, b), c); }
|
||||
|
||||
template<typename T> inline T maximum(T a, T b) { return (a > b) ? a : b; }
|
||||
|
||||
template<typename T> inline T maximum(T a, T b, T c) { return maximum(maximum(a, b), c); }
|
||||
|
||||
template<typename T> inline T clamp(T value, T low, T high) { return (value < low) ? low : ((value > high) ? high : value); }
|
||||
|
||||
inline bool is_power_of_2(uint32 x) { return x && ((x & (x - 1U)) == 0U); }
|
||||
inline bool is_power_of_2(uint64 x) { return x && ((x & (x - 1U)) == 0U); }
|
||||
|
||||
template<typename T> inline T align_up_pointer(T p, uint alignment)
|
||||
{
|
||||
LZHAM_ASSERT(is_power_of_2(alignment));
|
||||
ptr_bits_t q = reinterpret_cast<ptr_bits_t>(p);
|
||||
q = (q + alignment - 1) & (~((uint_ptr)alignment - 1));
|
||||
return reinterpret_cast<T>(q);
|
||||
}
|
||||
|
||||
// From "Hackers Delight"
|
||||
// val remains unchanged if it is already a power of 2.
|
||||
inline uint32 next_pow2(uint32 val)
|
||||
{
|
||||
val--;
|
||||
val |= val >> 16;
|
||||
val |= val >> 8;
|
||||
val |= val >> 4;
|
||||
val |= val >> 2;
|
||||
val |= val >> 1;
|
||||
return val + 1;
|
||||
}
|
||||
|
||||
// val remains unchanged if it is already a power of 2.
|
||||
inline uint64 next_pow2(uint64 val)
|
||||
{
|
||||
val--;
|
||||
val |= val >> 32;
|
||||
val |= val >> 16;
|
||||
val |= val >> 8;
|
||||
val |= val >> 4;
|
||||
val |= val >> 2;
|
||||
val |= val >> 1;
|
||||
return val + 1;
|
||||
}
|
||||
|
||||
inline uint floor_log2i(uint v)
|
||||
{
|
||||
uint l = 0;
|
||||
while (v > 1U)
|
||||
{
|
||||
v >>= 1;
|
||||
l++;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
inline uint ceil_log2i(uint v)
|
||||
{
|
||||
uint l = floor_log2i(v);
|
||||
if ((l != cIntBits) && (v > (1U << l)))
|
||||
l++;
|
||||
return l;
|
||||
}
|
||||
|
||||
// Returns the total number of bits needed to encode v.
|
||||
// This needs to be fast - it's used heavily when determining Polar codelengths.
|
||||
inline uint total_bits(uint v)
|
||||
{
|
||||
unsigned long l = 0;
|
||||
#if defined(__MINGW32__)
|
||||
if (v)
|
||||
{
|
||||
l = 32 -__builtin_clz(v);
|
||||
}
|
||||
#elif defined(LZHAM_USE_MSVC_INTRINSICS)
|
||||
if (_BitScanReverse(&l, v))
|
||||
{
|
||||
l++;
|
||||
}
|
||||
#else
|
||||
while (v > 0U)
|
||||
{
|
||||
v >>= 1;
|
||||
l++;
|
||||
}
|
||||
#endif
|
||||
return l;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace lzham
|
||||
|
112
r5dev/thirdparty/lzham/include/lzham_mem.h
vendored
Normal file
112
r5dev/thirdparty/lzham/include/lzham_mem.h
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
// File: lzham_mem.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
void lzham_mem_init();
|
||||
|
||||
void* lzham_malloc(size_t size, size_t* pActual_size = NULL);
|
||||
void* lzham_realloc(void* p, size_t size, size_t* pActual_size = NULL, bool movable = true);
|
||||
void lzham_free(void* p);
|
||||
size_t lzham_msize(void* p);
|
||||
|
||||
template<typename T>
|
||||
inline T* lzham_new()
|
||||
{
|
||||
T* p = static_cast<T*>(lzham_malloc(sizeof(T)));
|
||||
if (!p) return NULL;
|
||||
if (LZHAM_IS_SCALAR_TYPE(T))
|
||||
return p;
|
||||
return helpers::construct(p);
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline T* lzham_new(const A& init0)
|
||||
{
|
||||
T* p = static_cast<T*>(lzham_malloc(sizeof(T)));
|
||||
if (!p) return NULL;
|
||||
return new (static_cast<void*>(p)) T(init0);
|
||||
}
|
||||
|
||||
template<typename T, typename A, typename B>
|
||||
inline T* lzham_new(const A& init0, const B& init1)
|
||||
{
|
||||
T* p = static_cast<T*>(lzham_malloc(sizeof(T)));
|
||||
if (!p) return NULL;
|
||||
return new (static_cast<void*>(p)) T(init0, init1);
|
||||
}
|
||||
|
||||
template<typename T, typename A, typename B, typename C>
|
||||
inline T* lzham_new(const A& init0, const B& init1, const C& init2)
|
||||
{
|
||||
T* p = static_cast<T*>(lzham_malloc(sizeof(T)));
|
||||
if (!p) return NULL;
|
||||
return new (static_cast<void*>(p)) T(init0, init1, init2);
|
||||
}
|
||||
|
||||
template<typename T, typename A, typename B, typename C, typename D>
|
||||
inline T* lzham_new(const A& init0, const B& init1, const C& init2, const D& init3)
|
||||
{
|
||||
T* p = static_cast<T*>(lzham_malloc(sizeof(T)));
|
||||
if (!p) return NULL;
|
||||
return new (static_cast<void*>(p)) T(init0, init1, init2, init3);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T* lzham_new_array(uint32 num)
|
||||
{
|
||||
if (!num) num = 1;
|
||||
|
||||
uint8* q = static_cast<uint8*>(lzham_malloc(LZHAM_MIN_ALLOC_ALIGNMENT + sizeof(T) * num));
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
T* p = reinterpret_cast<T*>(q + LZHAM_MIN_ALLOC_ALIGNMENT);
|
||||
|
||||
reinterpret_cast<uint32*>(p)[-1] = num;
|
||||
reinterpret_cast<uint32*>(p)[-2] = ~num;
|
||||
|
||||
if (!LZHAM_IS_SCALAR_TYPE(T))
|
||||
{
|
||||
helpers::construct_array(p, num);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void lzham_delete(T* p)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
if (!LZHAM_IS_SCALAR_TYPE(T))
|
||||
{
|
||||
helpers::destruct(p);
|
||||
}
|
||||
lzham_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void lzham_delete_array(T* p)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
const uint32 num = reinterpret_cast<uint32*>(p)[-1];
|
||||
const uint32 num_check = reinterpret_cast<uint32*>(p)[-2];
|
||||
LZHAM_ASSERT(num && (num == ~num_check));
|
||||
if (num == ~num_check)
|
||||
{
|
||||
if (!LZHAM_IS_SCALAR_TYPE(T))
|
||||
{
|
||||
helpers::destruct_array(p, num);
|
||||
}
|
||||
|
||||
lzham_free(reinterpret_cast<uint8*>(p) - LZHAM_MIN_ALLOC_ALIGNMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lzham_print_mem_stats();
|
||||
|
||||
} // namespace lzham
|
97
r5dev/thirdparty/lzham/include/lzham_null_threading.h
vendored
Normal file
97
r5dev/thirdparty/lzham/include/lzham_null_threading.h
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
// File: lzham_task_pool_null.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
class semaphore
|
||||
{
|
||||
LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore);
|
||||
|
||||
public:
|
||||
inline semaphore(long initialCount = 0, long maximumCount = 1, const char* pName = NULL)
|
||||
{
|
||||
initialCount, maximumCount, pName;
|
||||
}
|
||||
|
||||
inline ~semaphore()
|
||||
{
|
||||
}
|
||||
|
||||
inline void release(long releaseCount = 1, long *pPreviousCount = NULL)
|
||||
{
|
||||
releaseCount, pPreviousCount;
|
||||
}
|
||||
|
||||
inline bool wait(uint32 milliseconds = UINT32_MAX)
|
||||
{
|
||||
milliseconds;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class task_pool
|
||||
{
|
||||
public:
|
||||
inline task_pool() { }
|
||||
inline task_pool(uint num_threads) { num_threads; }
|
||||
inline ~task_pool() { }
|
||||
|
||||
inline bool init(uint num_threads) { num_threads; return true; }
|
||||
inline void deinit();
|
||||
|
||||
inline uint get_num_threads() const { return 0; }
|
||||
inline uint get_num_outstanding_tasks() const { return 0; }
|
||||
|
||||
// C-style task callback
|
||||
typedef void (*task_callback_func)(uint64 data, void* pData_ptr);
|
||||
inline bool queue_task(task_callback_func pFunc, uint64 data = 0, void* pData_ptr = NULL)
|
||||
{
|
||||
pFunc(data, pData_ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
class executable_task
|
||||
{
|
||||
public:
|
||||
virtual void execute_task(uint64 data, void* pData_ptr) = 0;
|
||||
};
|
||||
|
||||
// It's the caller's responsibility to delete pObj within the execute_task() method, if needed!
|
||||
inline bool queue_task(executable_task* pObj, uint64 data = 0, void* pData_ptr = NULL)
|
||||
{
|
||||
pObj->execute_task(data, pData_ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename S, typename T>
|
||||
inline bool queue_object_task(S* pObject, T pObject_method, uint64 data = 0, void* pData_ptr = NULL)
|
||||
{
|
||||
(pObject->*pObject_method)(data, pData_ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename S, typename T>
|
||||
inline bool queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr = NULL)
|
||||
{
|
||||
for (uint i = 0; i < num_tasks; i++)
|
||||
{
|
||||
(pObject->*pObject_method)(first_data + i, pData_ptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void join() { }
|
||||
};
|
||||
|
||||
inline void lzham_sleep(unsigned int milliseconds)
|
||||
{
|
||||
milliseconds;
|
||||
}
|
||||
|
||||
inline uint lzham_get_max_helper_threads()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace lzham
|
284
r5dev/thirdparty/lzham/include/lzham_platform.h
vendored
Normal file
284
r5dev/thirdparty/lzham/include/lzham_platform.h
vendored
Normal file
@ -0,0 +1,284 @@
|
||||
// File: lzham_platform.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
bool lzham_is_debugger_present(void);
|
||||
void lzham_debug_break(void);
|
||||
void lzham_output_debug_string(const char* p);
|
||||
|
||||
// actually in lzham_assert.cpp
|
||||
void lzham_assert(const char* pExp, const char* pFile, unsigned line);
|
||||
void lzham_fail(const char* pExp, const char* pFile, unsigned line);
|
||||
|
||||
#ifdef WIN32
|
||||
#define LZHAM_BREAKPOINT DebuggerBreak();
|
||||
#define LZHAM_BUILTIN_EXPECT(c, v) c
|
||||
#elif defined(__GNUC__)
|
||||
#define LZHAM_BREAKPOINT asm("int $3");
|
||||
#define LZHAM_BUILTIN_EXPECT(c, v) __builtin_expect(c, v)
|
||||
#else
|
||||
#define LZHAM_BREAKPOINT
|
||||
#define LZHAM_BUILTIN_EXPECT(c, v) c
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && LZHAM_PLATFORM_PC
|
||||
extern __inline__ __attribute__((__always_inline__,__gnu_inline__)) void lzham_yield_processor()
|
||||
{
|
||||
__asm__ __volatile__("pause");
|
||||
}
|
||||
#elif LZHAM_PLATFORM_X360
|
||||
#define lzham_yield_processor() \
|
||||
YieldProcessor(); \
|
||||
__asm { or r0, r0, r0 } \
|
||||
YieldProcessor(); \
|
||||
__asm { or r1, r1, r1 } \
|
||||
YieldProcessor(); \
|
||||
__asm { or r0, r0, r0 } \
|
||||
YieldProcessor(); \
|
||||
__asm { or r1, r1, r1 } \
|
||||
YieldProcessor(); \
|
||||
__asm { or r0, r0, r0 } \
|
||||
YieldProcessor(); \
|
||||
__asm { or r1, r1, r1 } \
|
||||
YieldProcessor(); \
|
||||
__asm { or r0, r0, r0 } \
|
||||
YieldProcessor(); \
|
||||
__asm { or r1, r1, r1 }
|
||||
#else
|
||||
LZHAM_FORCE_INLINE void lzham_yield_processor()
|
||||
{
|
||||
#if LZHAM_USE_MSVC_INTRINSICS
|
||||
#if LZHAM_PLATFORM_PC_X64
|
||||
_mm_pause();
|
||||
#else
|
||||
YieldProcessor();
|
||||
#endif
|
||||
#else
|
||||
// No implementation
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...);
|
||||
int vsprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, va_list args);
|
||||
#endif
|
||||
|
||||
#if LZHAM_PLATFORM_X360
|
||||
#define LZHAM_MEMORY_EXPORT_BARRIER MemoryBarrier();
|
||||
#else
|
||||
// Barriers shouldn't be necessary on x86/x64.
|
||||
// TODO: Should use __sync_synchronize() on other platforms that support GCC.
|
||||
#define LZHAM_MEMORY_EXPORT_BARRIER
|
||||
#endif
|
||||
|
||||
#if LZHAM_PLATFORM_X360
|
||||
#define LZHAM_MEMORY_IMPORT_BARRIER MemoryBarrier();
|
||||
#else
|
||||
// Barriers shouldn't be necessary on x86/x64.
|
||||
// TODO: Should use __sync_synchronize() on other platforms that support GCC.
|
||||
#define LZHAM_MEMORY_IMPORT_BARRIER
|
||||
#endif
|
||||
|
||||
// Note: It's very important that LZHAM_READ_BIG_ENDIAN_UINT32() is fast on the target platform.
|
||||
// This is used to read every DWORD from the input stream.
|
||||
|
||||
#if LZHAM_USE_UNALIGNED_INT_LOADS
|
||||
#if LZHAM_BIG_ENDIAN_CPU
|
||||
#define LZHAM_READ_BIG_ENDIAN_UINT32(p) *reinterpret_cast<const uint32*>(p)
|
||||
#else
|
||||
#if defined(LZHAM_USE_MSVC_INTRINSICS)
|
||||
#define LZHAM_READ_BIG_ENDIAN_UINT32(p) _byteswap_ulong(*reinterpret_cast<const uint32*>(p))
|
||||
#elif defined(__GNUC__)
|
||||
#define LZHAM_READ_BIG_ENDIAN_UINT32(p) __builtin_bswap32(*reinterpret_cast<const uint32*>(p))
|
||||
#else
|
||||
#define LZHAM_READ_BIG_ENDIAN_UINT32(p) utils::swap32(*reinterpret_cast<const uint32*>(p))
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define LZHAM_READ_BIG_ENDIAN_UINT32(p) ((reinterpret_cast<const uint8*>(p)[0] << 24) | (reinterpret_cast<const uint8*>(p)[1] << 16) | (reinterpret_cast<const uint8*>(p)[2] << 8) | (reinterpret_cast<const uint8*>(p)[3]))
|
||||
#endif
|
||||
|
||||
#if LZHAM_USE_WIN32_ATOMIC_FUNCTIONS
|
||||
extern "C" __int64 _InterlockedCompareExchange64(__int64 volatile * Destination, __int64 Exchange, __int64 Comperand);
|
||||
#if defined(_MSC_VER)
|
||||
#pragma intrinsic(_InterlockedCompareExchange64)
|
||||
#endif
|
||||
#endif // LZHAM_USE_WIN32_ATOMIC_FUNCTIONS
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
#if LZHAM_USE_WIN32_ATOMIC_FUNCTIONS
|
||||
typedef LONG atomic32_t;
|
||||
typedef LONGLONG atomic64_t;
|
||||
|
||||
// Returns the original value.
|
||||
inline atomic32_t atomic_compare_exchange32(atomic32_t volatile *pDest, atomic32_t exchange, atomic32_t comparand)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return InterlockedCompareExchange(pDest, exchange, comparand);
|
||||
}
|
||||
|
||||
// Returns the original value.
|
||||
inline atomic64_t atomic_compare_exchange64(atomic64_t volatile *pDest, atomic64_t exchange, atomic64_t comparand)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 7) == 0);
|
||||
return _InterlockedCompareExchange64(pDest, exchange, comparand);
|
||||
}
|
||||
|
||||
// Returns the resulting incremented value.
|
||||
inline atomic32_t atomic_increment32(atomic32_t volatile *pDest)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return InterlockedIncrement(pDest);
|
||||
}
|
||||
|
||||
// Returns the resulting decremented value.
|
||||
inline atomic32_t atomic_decrement32(atomic32_t volatile *pDest)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return InterlockedDecrement(pDest);
|
||||
}
|
||||
|
||||
// Returns the original value.
|
||||
inline atomic32_t atomic_exchange32(atomic32_t volatile *pDest, atomic32_t val)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return InterlockedExchange(pDest, val);
|
||||
}
|
||||
|
||||
// Returns the resulting value.
|
||||
inline atomic32_t atomic_add32(atomic32_t volatile *pDest, atomic32_t val)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return InterlockedExchangeAdd(pDest, val) + val;
|
||||
}
|
||||
|
||||
// Returns the original value.
|
||||
inline atomic32_t atomic_exchange_add(atomic32_t volatile *pDest, atomic32_t val)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return InterlockedExchangeAdd(pDest, val);
|
||||
}
|
||||
#elif LZHAM_USE_GCC_ATOMIC_BUILTINS
|
||||
typedef long atomic32_t;
|
||||
typedef long long atomic64_t;
|
||||
|
||||
// Returns the original value.
|
||||
inline atomic32_t atomic_compare_exchange32(atomic32_t volatile *pDest, atomic32_t exchange, atomic32_t comparand)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return __sync_val_compare_and_swap(pDest, comparand, exchange);
|
||||
}
|
||||
|
||||
// Returns the original value.
|
||||
inline atomic64_t atomic_compare_exchange64(atomic64_t volatile *pDest, atomic64_t exchange, atomic64_t comparand)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 7) == 0);
|
||||
return __sync_val_compare_and_swap(pDest, comparand, exchange);
|
||||
}
|
||||
|
||||
// Returns the resulting incremented value.
|
||||
inline atomic32_t atomic_increment32(atomic32_t volatile *pDest)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return __sync_add_and_fetch(pDest, 1);
|
||||
}
|
||||
|
||||
// Returns the resulting decremented value.
|
||||
inline atomic32_t atomic_decrement32(atomic32_t volatile *pDest)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return __sync_sub_and_fetch(pDest, 1);
|
||||
}
|
||||
|
||||
// Returns the original value.
|
||||
inline atomic32_t atomic_exchange32(atomic32_t volatile *pDest, atomic32_t val)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return __sync_lock_test_and_set(pDest, val);
|
||||
}
|
||||
|
||||
// Returns the resulting value.
|
||||
inline atomic32_t atomic_add32(atomic32_t volatile *pDest, atomic32_t val)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return __sync_add_and_fetch(pDest, val);
|
||||
}
|
||||
|
||||
// Returns the original value.
|
||||
inline atomic32_t atomic_exchange_add(atomic32_t volatile *pDest, atomic32_t val)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return __sync_fetch_and_add(pDest, val);
|
||||
}
|
||||
#else
|
||||
#define LZHAM_NO_ATOMICS 1
|
||||
|
||||
// Atomic ops not supported - but try to do something reasonable. Assumes no threading at all.
|
||||
typedef long atomic32_t;
|
||||
typedef long long atomic64_t;
|
||||
|
||||
inline atomic32_t atomic_compare_exchange32(atomic32_t volatile *pDest, atomic32_t exchange, atomic32_t comparand)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
atomic32_t cur = *pDest;
|
||||
if (cur == comparand)
|
||||
*pDest = exchange;
|
||||
return cur;
|
||||
}
|
||||
|
||||
inline atomic64_t atomic_compare_exchange64(atomic64_t volatile *pDest, atomic64_t exchange, atomic64_t comparand)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 7) == 0);
|
||||
atomic64_t cur = *pDest;
|
||||
if (cur == comparand)
|
||||
*pDest = exchange;
|
||||
return cur;
|
||||
}
|
||||
|
||||
inline atomic32_t atomic_increment32(atomic32_t volatile *pDest)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return (*pDest += 1);
|
||||
}
|
||||
|
||||
inline atomic32_t atomic_decrement32(atomic32_t volatile *pDest)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return (*pDest -= 1);
|
||||
}
|
||||
|
||||
inline atomic32_t atomic_exchange32(atomic32_t volatile *pDest, atomic32_t val)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
atomic32_t cur = *pDest;
|
||||
*pDest = val;
|
||||
return cur;
|
||||
}
|
||||
|
||||
inline atomic32_t atomic_add32(atomic32_t volatile *pDest, atomic32_t val)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
return (*pDest += val);
|
||||
}
|
||||
|
||||
inline atomic32_t atomic_exchange_add(atomic32_t volatile *pDest, atomic32_t val)
|
||||
{
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(pDest) & 3) == 0);
|
||||
atomic32_t cur = *pDest;
|
||||
*pDest += val;
|
||||
return cur;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if LZHAM_BUFFERED_PRINTF
|
||||
void lzham_buffered_printf(const char *format, ...);
|
||||
void lzham_flush_buffered_printf();
|
||||
#else
|
||||
inline void lzham_buffered_printf(const char *format, ...) { (void)format; }
|
||||
inline void lzham_flush_buffered_printf() { }
|
||||
#endif
|
||||
|
||||
} // namespace lzham
|
14
r5dev/thirdparty/lzham/include/lzham_polar_codes.h
vendored
Normal file
14
r5dev/thirdparty/lzham/include/lzham_polar_codes.h
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// File: lzham_polar_codes.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
//const uint cPolarMaxSupportedSyms = 600;
|
||||
const uint cPolarMaxSupportedSyms = 1024;
|
||||
|
||||
uint get_generate_polar_codes_table_size();
|
||||
|
||||
bool generate_polar_codes(void* pContext, uint num_syms, const uint16* pFreq, uint8* pCodesizes, uint& max_code_size, uint& total_freq_ret);
|
||||
|
||||
} // namespace lzham
|
144
r5dev/thirdparty/lzham/include/lzham_prefix_coding.h
vendored
Normal file
144
r5dev/thirdparty/lzham/include/lzham_prefix_coding.h
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
// File: lzham_prefix_coding.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
namespace prefix_coding
|
||||
{
|
||||
const uint cMaxExpectedCodeSize = 16;
|
||||
const uint cMaxSupportedSyms = 1024;
|
||||
const uint cMaxTableBits = 11;
|
||||
|
||||
bool limit_max_code_size(uint num_syms, uint8* pCodesizes, uint max_code_size);
|
||||
|
||||
bool generate_codes(uint num_syms, const uint8* pCodesizes, uint16* pCodes);
|
||||
|
||||
class decoder_tables
|
||||
{
|
||||
public:
|
||||
inline decoder_tables() :
|
||||
m_table_shift(0), m_table_max_code(0), m_decode_start_code_size(0), m_cur_lookup_size(0), m_lookup(NULL), m_cur_sorted_symbol_order_size(0), m_sorted_symbol_order(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
inline decoder_tables(const decoder_tables& other) :
|
||||
m_table_shift(0), m_table_max_code(0), m_decode_start_code_size(0), m_cur_lookup_size(0), m_lookup(NULL), m_cur_sorted_symbol_order_size(0), m_sorted_symbol_order(NULL)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
inline decoder_tables& operator= (const decoder_tables& rhs)
|
||||
{
|
||||
assign(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool assign(const decoder_tables& rhs)
|
||||
{
|
||||
if (this == &rhs)
|
||||
return true;
|
||||
|
||||
uint32* pCur_lookup = m_lookup;
|
||||
uint16* pCur_sorted_symbol_order = m_sorted_symbol_order;
|
||||
|
||||
memcpy(this, &rhs, sizeof(*this));
|
||||
|
||||
if ((pCur_lookup) && (pCur_sorted_symbol_order) && (rhs.m_cur_lookup_size == m_cur_lookup_size) && (rhs.m_cur_sorted_symbol_order_size == m_cur_sorted_symbol_order_size))
|
||||
{
|
||||
m_lookup = pCur_lookup;
|
||||
m_sorted_symbol_order = pCur_sorted_symbol_order;
|
||||
|
||||
memcpy(m_lookup, rhs.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size);
|
||||
memcpy(m_sorted_symbol_order, rhs.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
lzham_delete_array(pCur_lookup);
|
||||
m_lookup = NULL;
|
||||
|
||||
if (rhs.m_lookup)
|
||||
{
|
||||
m_lookup = lzham_new_array<uint32>(m_cur_lookup_size);
|
||||
if (!m_lookup)
|
||||
return false;
|
||||
memcpy(m_lookup, rhs.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size);
|
||||
}
|
||||
|
||||
lzham_delete_array(pCur_sorted_symbol_order);
|
||||
m_sorted_symbol_order = NULL;
|
||||
|
||||
if (rhs.m_sorted_symbol_order)
|
||||
{
|
||||
m_sorted_symbol_order = lzham_new_array<uint16>(m_cur_sorted_symbol_order_size);
|
||||
if (!m_sorted_symbol_order)
|
||||
return false;
|
||||
memcpy(m_sorted_symbol_order, rhs.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
if (m_lookup)
|
||||
{
|
||||
lzham_delete_array(m_lookup);
|
||||
m_lookup = 0;
|
||||
m_cur_lookup_size = 0;
|
||||
}
|
||||
|
||||
if (m_sorted_symbol_order)
|
||||
{
|
||||
lzham_delete_array(m_sorted_symbol_order);
|
||||
m_sorted_symbol_order = NULL;
|
||||
m_cur_sorted_symbol_order_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline ~decoder_tables()
|
||||
{
|
||||
if (m_lookup)
|
||||
lzham_delete_array(m_lookup);
|
||||
|
||||
if (m_sorted_symbol_order)
|
||||
lzham_delete_array(m_sorted_symbol_order);
|
||||
}
|
||||
|
||||
// DO NOT use any complex classes here - it is bitwise copied.
|
||||
|
||||
uint m_num_syms;
|
||||
uint m_total_used_syms;
|
||||
uint m_table_bits;
|
||||
uint m_table_shift;
|
||||
uint m_table_max_code;
|
||||
uint m_decode_start_code_size;
|
||||
|
||||
uint8 m_min_code_size;
|
||||
uint8 m_max_code_size;
|
||||
|
||||
uint m_max_codes[cMaxExpectedCodeSize + 1];
|
||||
int m_val_ptrs[cMaxExpectedCodeSize + 1];
|
||||
|
||||
uint m_cur_lookup_size;
|
||||
uint32* m_lookup;
|
||||
|
||||
uint m_cur_sorted_symbol_order_size;
|
||||
uint16* m_sorted_symbol_order;
|
||||
|
||||
inline uint get_unshifted_max_code(uint len) const
|
||||
{
|
||||
LZHAM_ASSERT( (len >= 1) && (len <= cMaxExpectedCodeSize) );
|
||||
uint k = m_max_codes[len - 1];
|
||||
if (!k)
|
||||
return UINT_MAX;
|
||||
return (k - 1) >> (16 - len);
|
||||
}
|
||||
};
|
||||
|
||||
bool generate_decoder_tables(uint num_syms, const uint8* pCodesizes, decoder_tables* pTables, uint table_bits);
|
||||
|
||||
} // namespace prefix_coding
|
||||
|
||||
} // namespace lzham
|
383
r5dev/thirdparty/lzham/include/lzham_pthreads_threading.h
vendored
Normal file
383
r5dev/thirdparty/lzham/include/lzham_pthreads_threading.h
vendored
Normal file
@ -0,0 +1,383 @@
|
||||
// File: lzham_task_pool_pthreads.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
#if LZHAM_USE_PTHREADS_API
|
||||
|
||||
#if LZHAM_NO_ATOMICS
|
||||
#error No atomic operations defined in lzham_platform.h!
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
class semaphore
|
||||
{
|
||||
LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore);
|
||||
|
||||
public:
|
||||
inline semaphore(long initialCount = 0, long maximumCount = 1, const char* pName = NULL)
|
||||
{
|
||||
LZHAM_NOTE_UNUSED(maximumCount), LZHAM_NOTE_UNUSED(pName);
|
||||
LZHAM_ASSERT(maximumCount >= initialCount);
|
||||
if (sem_init(&m_sem, 0, initialCount))
|
||||
{
|
||||
LZHAM_FAIL("semaphore: sem_init() failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline ~semaphore()
|
||||
{
|
||||
sem_destroy(&m_sem);
|
||||
}
|
||||
|
||||
inline void release(long releaseCount = 1)
|
||||
{
|
||||
LZHAM_ASSERT(releaseCount >= 1);
|
||||
|
||||
int status = 0;
|
||||
#ifdef WIN32
|
||||
if (1 == releaseCount)
|
||||
status = sem_post(&m_sem);
|
||||
else
|
||||
status = sem_post_multiple(&m_sem, releaseCount);
|
||||
#else
|
||||
while (releaseCount > 0)
|
||||
{
|
||||
status = sem_post(&m_sem);
|
||||
if (status)
|
||||
break;
|
||||
releaseCount--;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (status)
|
||||
{
|
||||
LZHAM_FAIL("semaphore: sem_post() or sem_post_multiple() failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline bool wait(uint32 milliseconds = UINT32_MAX)
|
||||
{
|
||||
int status;
|
||||
if (milliseconds == UINT32_MAX)
|
||||
{
|
||||
status = sem_wait(&m_sem);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct timespec interval;
|
||||
interval.tv_sec = milliseconds / 1000;
|
||||
interval.tv_nsec = (milliseconds % 1000) * 1000000L;
|
||||
status = sem_timedwait(&m_sem, &interval);
|
||||
}
|
||||
|
||||
if (status)
|
||||
{
|
||||
if (errno != ETIMEDOUT)
|
||||
{
|
||||
LZHAM_FAIL("semaphore: sem_wait() or sem_timedwait() failed");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
sem_t m_sem;
|
||||
};
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
inline spinlock()
|
||||
{
|
||||
if (pthread_spin_init(&m_spinlock, 0))
|
||||
{
|
||||
LZHAM_FAIL("spinlock: pthread_spin_init() failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline ~spinlock()
|
||||
{
|
||||
pthread_spin_destroy(&m_spinlock);
|
||||
}
|
||||
|
||||
inline void lock()
|
||||
{
|
||||
if (pthread_spin_lock(&m_spinlock))
|
||||
{
|
||||
LZHAM_FAIL("spinlock: pthread_spin_lock() failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void unlock()
|
||||
{
|
||||
if (pthread_spin_unlock(&m_spinlock))
|
||||
{
|
||||
LZHAM_FAIL("spinlock: pthread_spin_unlock() failed");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
pthread_spinlock_t m_spinlock;
|
||||
};
|
||||
|
||||
template<typename T, uint cMaxSize>
|
||||
class tsstack
|
||||
{
|
||||
public:
|
||||
inline tsstack() : m_top(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline ~tsstack()
|
||||
{
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
m_spinlock.lock();
|
||||
m_top = 0;
|
||||
m_spinlock.unlock();
|
||||
}
|
||||
|
||||
inline bool try_push(const T& obj)
|
||||
{
|
||||
bool result = false;
|
||||
m_spinlock.lock();
|
||||
if (m_top < (int)cMaxSize)
|
||||
{
|
||||
m_stack[m_top++] = obj;
|
||||
result = true;
|
||||
}
|
||||
m_spinlock.unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool pop(T& obj)
|
||||
{
|
||||
bool result = false;
|
||||
m_spinlock.lock();
|
||||
if (m_top > 0)
|
||||
{
|
||||
obj = m_stack[--m_top];
|
||||
result = true;
|
||||
}
|
||||
m_spinlock.unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
spinlock m_spinlock;
|
||||
T m_stack[cMaxSize];
|
||||
int m_top;
|
||||
};
|
||||
|
||||
class task_pool
|
||||
{
|
||||
public:
|
||||
task_pool();
|
||||
task_pool(uint num_threads);
|
||||
~task_pool();
|
||||
|
||||
enum { cMaxThreads = LZHAM_MAX_HELPER_THREADS };
|
||||
bool init(uint num_threads);
|
||||
void deinit();
|
||||
|
||||
inline uint get_num_threads() const { return m_num_threads; }
|
||||
inline uint get_num_outstanding_tasks() const { return m_num_outstanding_tasks; }
|
||||
|
||||
// C-style task callback
|
||||
typedef void (*task_callback_func)(uint64 data, void* pData_ptr);
|
||||
bool queue_task(task_callback_func pFunc, uint64 data = 0, void* pData_ptr = NULL);
|
||||
|
||||
class executable_task
|
||||
{
|
||||
public:
|
||||
virtual void execute_task(uint64 data, void* pData_ptr) = 0;
|
||||
};
|
||||
|
||||
// It's the caller's responsibility to delete pObj within the execute_task() method, if needed!
|
||||
bool queue_task(executable_task* pObj, uint64 data = 0, void* pData_ptr = NULL);
|
||||
|
||||
template<typename S, typename T>
|
||||
inline bool queue_object_task(S* pObject, T pObject_method, uint64 data = 0, void* pData_ptr = NULL);
|
||||
|
||||
template<typename S, typename T>
|
||||
inline bool queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr = NULL);
|
||||
|
||||
void join();
|
||||
|
||||
private:
|
||||
struct task
|
||||
{
|
||||
inline task() : m_data(0), m_pData_ptr(NULL), m_pObj(NULL), m_flags(0) { }
|
||||
|
||||
uint64 m_data;
|
||||
void* m_pData_ptr;
|
||||
|
||||
union
|
||||
{
|
||||
task_callback_func m_callback;
|
||||
executable_task* m_pObj;
|
||||
};
|
||||
|
||||
uint m_flags;
|
||||
};
|
||||
|
||||
tsstack<task, cMaxThreads> m_task_stack;
|
||||
|
||||
uint m_num_threads;
|
||||
pthread_t m_threads[cMaxThreads];
|
||||
|
||||
semaphore m_tasks_available;
|
||||
|
||||
enum task_flags
|
||||
{
|
||||
cTaskFlagObject = 1
|
||||
};
|
||||
|
||||
volatile atomic32_t m_num_outstanding_tasks;
|
||||
volatile atomic32_t m_exit_flag;
|
||||
|
||||
void process_task(task& tsk);
|
||||
|
||||
static void* thread_func(void *pContext);
|
||||
};
|
||||
|
||||
enum object_task_flags
|
||||
{
|
||||
cObjectTaskFlagDefault = 0,
|
||||
cObjectTaskFlagDeleteAfterExecution = 1
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class object_task : public task_pool::executable_task
|
||||
{
|
||||
public:
|
||||
object_task(uint flags = cObjectTaskFlagDefault) :
|
||||
m_pObject(NULL),
|
||||
m_pMethod(NULL),
|
||||
m_flags(flags)
|
||||
{
|
||||
}
|
||||
|
||||
typedef void (T::*object_method_ptr)(uint64 data, void* pData_ptr);
|
||||
|
||||
object_task(T* pObject, object_method_ptr pMethod, uint flags = cObjectTaskFlagDefault) :
|
||||
m_pObject(pObject),
|
||||
m_pMethod(pMethod),
|
||||
m_flags(flags)
|
||||
{
|
||||
LZHAM_ASSERT(pObject && pMethod);
|
||||
}
|
||||
|
||||
void init(T* pObject, object_method_ptr pMethod, uint flags = cObjectTaskFlagDefault)
|
||||
{
|
||||
LZHAM_ASSERT(pObject && pMethod);
|
||||
|
||||
m_pObject = pObject;
|
||||
m_pMethod = pMethod;
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
T* get_object() const { return m_pObject; }
|
||||
object_method_ptr get_method() const { return m_pMethod; }
|
||||
|
||||
virtual void execute_task(uint64 data, void* pData_ptr)
|
||||
{
|
||||
(m_pObject->*m_pMethod)(data, pData_ptr);
|
||||
|
||||
if (m_flags & cObjectTaskFlagDeleteAfterExecution)
|
||||
lzham_delete(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
T* m_pObject;
|
||||
|
||||
object_method_ptr m_pMethod;
|
||||
|
||||
uint m_flags;
|
||||
};
|
||||
|
||||
template<typename S, typename T>
|
||||
inline bool task_pool::queue_object_task(S* pObject, T pObject_method, uint64 data, void* pData_ptr)
|
||||
{
|
||||
object_task<S> *pTask = lzham_new< object_task<S> >(pObject, pObject_method, cObjectTaskFlagDeleteAfterExecution);
|
||||
if (!pTask)
|
||||
return false;
|
||||
return queue_task(pTask, data, pData_ptr);
|
||||
}
|
||||
|
||||
template<typename S, typename T>
|
||||
inline bool task_pool::queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr)
|
||||
{
|
||||
LZHAM_ASSERT(m_num_threads);
|
||||
LZHAM_ASSERT(pObject);
|
||||
LZHAM_ASSERT(num_tasks);
|
||||
if (!num_tasks)
|
||||
return true;
|
||||
|
||||
bool status = true;
|
||||
|
||||
uint i;
|
||||
for (i = 0; i < num_tasks; i++)
|
||||
{
|
||||
task tsk;
|
||||
|
||||
tsk.m_pObj = lzham_new< object_task<S> >(pObject, pObject_method, cObjectTaskFlagDeleteAfterExecution);
|
||||
if (!tsk.m_pObj)
|
||||
{
|
||||
status = false;
|
||||
break;
|
||||
}
|
||||
|
||||
tsk.m_data = first_data + i;
|
||||
tsk.m_pData_ptr = pData_ptr;
|
||||
tsk.m_flags = cTaskFlagObject;
|
||||
|
||||
if (!m_task_stack.try_push(tsk))
|
||||
{
|
||||
status = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
atomic_add32(&m_num_outstanding_tasks, i);
|
||||
|
||||
m_tasks_available.release(i);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
inline void lzham_sleep(unsigned int milliseconds)
|
||||
{
|
||||
#ifdef WIN32
|
||||
struct timespec interval;
|
||||
interval.tv_sec = milliseconds / 1000;
|
||||
interval.tv_nsec = (milliseconds % 1000) * 1000000L;
|
||||
pthread_delay_np(&interval);
|
||||
#else
|
||||
while (milliseconds)
|
||||
{
|
||||
int msecs_to_sleep = LZHAM_MIN(milliseconds, 1000);
|
||||
usleep(msecs_to_sleep * 1000);
|
||||
milliseconds -= msecs_to_sleep;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: Implement
|
||||
uint lzham_get_max_helper_threads();
|
||||
|
||||
} // namespace lzham
|
||||
|
||||
#endif // LZHAM_USE_PTHREADS_API
|
556
r5dev/thirdparty/lzham/include/lzham_symbol_codec.h
vendored
Normal file
556
r5dev/thirdparty/lzham/include/lzham_symbol_codec.h
vendored
Normal file
@ -0,0 +1,556 @@
|
||||
// File: lzham_symbol_codec.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
#include "lzham_prefix_coding.h"
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
class symbol_codec;
|
||||
class adaptive_arith_data_model;
|
||||
|
||||
const uint cSymbolCodecArithMinLen = 0x01000000U;
|
||||
const uint cSymbolCodecArithMaxLen = 0xFFFFFFFFU;
|
||||
|
||||
const uint cSymbolCodecArithProbBits = 11;
|
||||
const uint cSymbolCodecArithProbScale = 1 << cSymbolCodecArithProbBits;
|
||||
const uint cSymbolCodecArithProbHalfScale = 1 << (cSymbolCodecArithProbBits - 1);
|
||||
const uint cSymbolCodecArithProbMoveBits = 5;
|
||||
|
||||
typedef uint64 bit_cost_t;
|
||||
const uint32 cBitCostScaleShift = 24;
|
||||
const uint32 cBitCostScale = (1U << cBitCostScaleShift);
|
||||
const bit_cost_t cBitCostMax = UINT64_MAX;
|
||||
|
||||
inline bit_cost_t convert_to_scaled_bitcost(uint bits) { LZHAM_ASSERT(bits <= 255); uint32 scaled_bits = bits << cBitCostScaleShift; return static_cast<bit_cost_t>(scaled_bits); }
|
||||
|
||||
extern uint32 g_prob_cost[cSymbolCodecArithProbScale];
|
||||
|
||||
class raw_quasi_adaptive_huffman_data_model
|
||||
{
|
||||
public:
|
||||
raw_quasi_adaptive_huffman_data_model(bool encoding = true, uint total_syms = 0, bool fast_encoding = false, bool use_polar_codes = false);
|
||||
raw_quasi_adaptive_huffman_data_model(const raw_quasi_adaptive_huffman_data_model& other);
|
||||
~raw_quasi_adaptive_huffman_data_model();
|
||||
|
||||
bool assign(const raw_quasi_adaptive_huffman_data_model& rhs);
|
||||
raw_quasi_adaptive_huffman_data_model& operator= (const raw_quasi_adaptive_huffman_data_model& rhs);
|
||||
|
||||
void clear();
|
||||
|
||||
bool init(bool encoding, uint total_syms, bool fast_encoding, bool use_polar_codes, const uint16 *pInitial_sym_freq = NULL);
|
||||
bool reset();
|
||||
|
||||
inline uint get_total_syms() const { return m_total_syms; }
|
||||
|
||||
void rescale();
|
||||
void reset_update_rate();
|
||||
|
||||
bool update(uint sym);
|
||||
|
||||
inline bit_cost_t get_cost(uint sym) const { return convert_to_scaled_bitcost(m_code_sizes[sym]); }
|
||||
|
||||
public:
|
||||
lzham::vector<uint16> m_initial_sym_freq;
|
||||
|
||||
lzham::vector<uint16> m_sym_freq;
|
||||
|
||||
lzham::vector<uint16> m_codes;
|
||||
lzham::vector<uint8> m_code_sizes;
|
||||
|
||||
prefix_coding::decoder_tables* m_pDecode_tables;
|
||||
|
||||
uint m_total_syms;
|
||||
|
||||
uint m_max_cycle;
|
||||
uint m_update_cycle;
|
||||
uint m_symbols_until_update;
|
||||
|
||||
uint m_total_count;
|
||||
|
||||
uint8 m_decoder_table_bits;
|
||||
bool m_encoding;
|
||||
bool m_fast_updating;
|
||||
bool m_use_polar_codes;
|
||||
|
||||
bool update();
|
||||
|
||||
friend class symbol_codec;
|
||||
};
|
||||
|
||||
struct quasi_adaptive_huffman_data_model : public raw_quasi_adaptive_huffman_data_model
|
||||
{
|
||||
#if LZHAM_64BIT_POINTERS
|
||||
// Ensures sizeof(quasi_adaptive_huffman_data_model) is 128 bytes on x64 (it's 64 on x86).
|
||||
char m_unused_alignment[128 - sizeof(raw_quasi_adaptive_huffman_data_model)];
|
||||
#endif
|
||||
};
|
||||
|
||||
class adaptive_bit_model
|
||||
{
|
||||
public:
|
||||
adaptive_bit_model();
|
||||
adaptive_bit_model(float prob0);
|
||||
adaptive_bit_model(const adaptive_bit_model& other);
|
||||
|
||||
inline adaptive_bit_model& operator= (const adaptive_bit_model& rhs) { m_bit_0_prob = rhs.m_bit_0_prob; return *this; }
|
||||
|
||||
inline void clear() { m_bit_0_prob = 1U << (cSymbolCodecArithProbBits - 1); }
|
||||
|
||||
void set_probability_0(float prob0);
|
||||
|
||||
inline void update(uint bit)
|
||||
{
|
||||
if (!bit)
|
||||
m_bit_0_prob += ((cSymbolCodecArithProbScale - m_bit_0_prob) >> cSymbolCodecArithProbMoveBits);
|
||||
else
|
||||
m_bit_0_prob -= (m_bit_0_prob >> cSymbolCodecArithProbMoveBits);
|
||||
LZHAM_ASSERT(m_bit_0_prob >= 1);
|
||||
LZHAM_ASSERT(m_bit_0_prob < cSymbolCodecArithProbScale);
|
||||
}
|
||||
|
||||
inline bit_cost_t get_cost(uint bit) const { return g_prob_cost[bit ? (cSymbolCodecArithProbScale - m_bit_0_prob) : m_bit_0_prob]; }
|
||||
|
||||
public:
|
||||
uint16 m_bit_0_prob;
|
||||
|
||||
friend class symbol_codec;
|
||||
friend class adaptive_arith_data_model;
|
||||
};
|
||||
|
||||
// This class is not actually used by LZHAM - it's only here for comparison/experimental purposes.
|
||||
class adaptive_arith_data_model
|
||||
{
|
||||
public:
|
||||
adaptive_arith_data_model(bool encoding = true, uint total_syms = 0);
|
||||
adaptive_arith_data_model(const adaptive_arith_data_model& other);
|
||||
~adaptive_arith_data_model();
|
||||
|
||||
adaptive_arith_data_model& operator= (const adaptive_arith_data_model& rhs);
|
||||
|
||||
void clear();
|
||||
|
||||
bool init(bool encoding, uint total_syms);
|
||||
bool init(bool encoding, uint total_syms, bool fast_encoding, bool use_polar_codes = false) { LZHAM_NOTE_UNUSED(fast_encoding), LZHAM_NOTE_UNUSED(use_polar_codes); return init(encoding, total_syms); }
|
||||
void reset();
|
||||
|
||||
void reset_update_rate();
|
||||
|
||||
bool update(uint sym);
|
||||
|
||||
uint get_total_syms() const { return m_total_syms; }
|
||||
bit_cost_t get_cost(uint sym) const;
|
||||
|
||||
public:
|
||||
uint m_total_syms;
|
||||
typedef lzham::vector<adaptive_bit_model> adaptive_bit_model_vector;
|
||||
adaptive_bit_model_vector m_probs;
|
||||
|
||||
friend class symbol_codec;
|
||||
};
|
||||
|
||||
#if LZHAM_CPU_HAS_64BIT_REGISTERS
|
||||
#define LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER 1
|
||||
#else
|
||||
#define LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER 0
|
||||
#endif
|
||||
|
||||
class symbol_codec
|
||||
{
|
||||
public:
|
||||
symbol_codec();
|
||||
|
||||
void reset();
|
||||
|
||||
// clear() is like reset(), except it also frees all memory.
|
||||
void clear();
|
||||
|
||||
// Encoding
|
||||
bool start_encoding(uint expected_file_size);
|
||||
bool encode_bits(uint bits, uint num_bits);
|
||||
bool encode_arith_init();
|
||||
bool encode_align_to_byte();
|
||||
bool encode(uint sym, quasi_adaptive_huffman_data_model& model);
|
||||
bool encode(uint bit, adaptive_bit_model& model, bool update_model = true);
|
||||
bool encode(uint sym, adaptive_arith_data_model& model);
|
||||
|
||||
inline uint encode_get_total_bits_written() const { return m_total_bits_written; }
|
||||
|
||||
bool stop_encoding(bool support_arith);
|
||||
|
||||
const lzham::vector<uint8>& get_encoding_buf() const { return m_output_buf; }
|
||||
lzham::vector<uint8>& get_encoding_buf() { return m_output_buf; }
|
||||
|
||||
// Decoding
|
||||
|
||||
typedef void (*need_bytes_func_ptr)(size_t num_bytes_consumed, void *pPrivate_data, const uint8* &pBuf, size_t &buf_size, bool &eof_flag);
|
||||
|
||||
bool start_decoding(const uint8* pBuf, size_t buf_size, bool eof_flag = true, need_bytes_func_ptr pNeed_bytes_func = NULL, void *pPrivate_data = NULL);
|
||||
|
||||
inline void decode_set_input_buffer(const uint8* pBuf, size_t buf_size, const uint8* pBuf_next, bool eof_flag)
|
||||
{
|
||||
m_pDecode_buf = pBuf;
|
||||
m_pDecode_buf_next = pBuf_next;
|
||||
m_decode_buf_size = buf_size;
|
||||
m_pDecode_buf_end = pBuf + buf_size;
|
||||
m_decode_buf_eof = eof_flag;
|
||||
}
|
||||
inline uint64 decode_get_bytes_consumed() const { return m_pDecode_buf_next - m_pDecode_buf; }
|
||||
inline uint64 decode_get_bits_remaining() const { return ((m_pDecode_buf_end - m_pDecode_buf_next) << 3) + m_bit_count; }
|
||||
|
||||
void start_arith_decoding();
|
||||
uint decode_bits(uint num_bits);
|
||||
uint decode_peek_bits(uint num_bits);
|
||||
void decode_remove_bits(uint num_bits);
|
||||
void decode_align_to_byte();
|
||||
int decode_remove_byte_from_bit_buf();
|
||||
uint decode(quasi_adaptive_huffman_data_model& model);
|
||||
uint decode(adaptive_bit_model& model, bool update_model = true);
|
||||
uint decode(adaptive_arith_data_model& model);
|
||||
uint64 stop_decoding();
|
||||
|
||||
uint get_total_model_updates() const { return m_total_model_updates; }
|
||||
|
||||
public:
|
||||
const uint8* m_pDecode_buf;
|
||||
const uint8* m_pDecode_buf_next;
|
||||
const uint8* m_pDecode_buf_end;
|
||||
size_t m_decode_buf_size;
|
||||
bool m_decode_buf_eof;
|
||||
|
||||
need_bytes_func_ptr m_pDecode_need_bytes_func;
|
||||
void* m_pDecode_private_data;
|
||||
|
||||
#if LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER
|
||||
typedef uint64 bit_buf_t;
|
||||
enum { cBitBufSize = 64 };
|
||||
#else
|
||||
typedef uint32 bit_buf_t;
|
||||
enum { cBitBufSize = 32 };
|
||||
#endif
|
||||
|
||||
bit_buf_t m_bit_buf;
|
||||
int m_bit_count;
|
||||
|
||||
uint m_total_model_updates;
|
||||
|
||||
lzham::vector<uint8> m_output_buf;
|
||||
lzham::vector<uint8> m_arith_output_buf;
|
||||
|
||||
struct output_symbol
|
||||
{
|
||||
uint m_bits;
|
||||
|
||||
enum
|
||||
{
|
||||
cArithSym = -1,
|
||||
cAlignToByteSym = -2,
|
||||
cArithInit = -3
|
||||
};
|
||||
int16 m_num_bits;
|
||||
|
||||
uint16 m_arith_prob0;
|
||||
};
|
||||
lzham::vector<output_symbol> m_output_syms;
|
||||
|
||||
uint m_total_bits_written;
|
||||
|
||||
uint m_arith_base;
|
||||
uint m_arith_value;
|
||||
uint m_arith_length;
|
||||
uint m_arith_total_bits;
|
||||
|
||||
quasi_adaptive_huffman_data_model* m_pSaved_huff_model;
|
||||
void* m_pSaved_model;
|
||||
uint m_saved_node_index;
|
||||
|
||||
bool put_bits_init(uint expected_size);
|
||||
bool record_put_bits(uint bits, uint num_bits);
|
||||
|
||||
void arith_propagate_carry();
|
||||
bool arith_renorm_enc_interval();
|
||||
void arith_start_encoding();
|
||||
bool arith_stop_encoding();
|
||||
|
||||
bool put_bits(uint bits, uint num_bits);
|
||||
bool put_bits_align_to_byte();
|
||||
bool flush_bits();
|
||||
bool assemble_output_buf();
|
||||
|
||||
uint get_bits(uint num_bits);
|
||||
void remove_bits(uint num_bits);
|
||||
|
||||
void decode_need_bytes();
|
||||
|
||||
enum
|
||||
{
|
||||
cNull,
|
||||
cEncoding,
|
||||
cDecoding
|
||||
} m_mode;
|
||||
};
|
||||
|
||||
// Optional macros for faster decompression. These macros implement the symbol_codec class's decode functionality.
|
||||
// This is hard to debug (and just plain ugly), but using these macros eliminate function calls, and they place the most important
|
||||
// member variables on the stack so they're hopefully put in registers (avoiding horrible load hit stores on some CPU's).
|
||||
// The user must define the LZHAM_DECODE_NEEDS_BYTES macro, which is invoked when the decode buffer is exhausted.
|
||||
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_DECLARE(codec) \
|
||||
uint arith_value = 0; \
|
||||
uint arith_length = 0; \
|
||||
symbol_codec::bit_buf_t bit_buf = 0; \
|
||||
int bit_count = 0; \
|
||||
const uint8* pDecode_buf_next = NULL;
|
||||
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
|
||||
arith_value = codec.m_arith_value; \
|
||||
arith_length = codec.m_arith_length; \
|
||||
bit_buf = codec.m_bit_buf; \
|
||||
bit_count = codec.m_bit_count; \
|
||||
pDecode_buf_next = codec.m_pDecode_buf_next;
|
||||
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
|
||||
codec.m_arith_value = arith_value; \
|
||||
codec.m_arith_length = arith_length; \
|
||||
codec.m_bit_buf = bit_buf; \
|
||||
codec.m_bit_count = bit_count; \
|
||||
codec.m_pDecode_buf_next = pDecode_buf_next;
|
||||
|
||||
// The user must declare the LZHAM_DECODE_NEEDS_BYTES macro.
|
||||
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, result, num_bits) \
|
||||
{ \
|
||||
while (LZHAM_BUILTIN_EXPECT(bit_count < (int)(num_bits), 0)) \
|
||||
{ \
|
||||
uint r; \
|
||||
if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next == codec.m_pDecode_buf_end, 0)) \
|
||||
{ \
|
||||
if (LZHAM_BUILTIN_EXPECT(!codec.m_decode_buf_eof, 1)) \
|
||||
{ \
|
||||
LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
|
||||
LZHAM_DECODE_NEEDS_BYTES \
|
||||
LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
|
||||
} \
|
||||
r = 0; \
|
||||
if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next < codec.m_pDecode_buf_end, 1)) r = *pDecode_buf_next++; \
|
||||
} \
|
||||
else \
|
||||
r = *pDecode_buf_next++; \
|
||||
bit_count += 8; \
|
||||
bit_buf |= (static_cast<symbol_codec::bit_buf_t>(r) << (symbol_codec::cBitBufSize - bit_count)); \
|
||||
} \
|
||||
result = (num_bits) ? static_cast<uint>(bit_buf >> (symbol_codec::cBitBufSize - (num_bits))) : 0; \
|
||||
bit_buf <<= (num_bits); \
|
||||
bit_count -= (num_bits); \
|
||||
}
|
||||
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_ARITH_BIT(codec, result, model) \
|
||||
{ \
|
||||
adaptive_bit_model *pModel; \
|
||||
pModel = &model; \
|
||||
while (LZHAM_BUILTIN_EXPECT(arith_length < cSymbolCodecArithMinLen, 0)) \
|
||||
{ \
|
||||
uint c; codec.m_pSaved_model = pModel; \
|
||||
LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, c, 8); \
|
||||
pModel = static_cast<adaptive_bit_model*>(codec.m_pSaved_model); \
|
||||
arith_value = (arith_value << 8) | c; \
|
||||
arith_length <<= 8; \
|
||||
} \
|
||||
uint x = pModel->m_bit_0_prob * (arith_length >> cSymbolCodecArithProbBits); \
|
||||
result = (arith_value >= x); \
|
||||
if (!result) \
|
||||
{ \
|
||||
pModel->m_bit_0_prob += ((cSymbolCodecArithProbScale - pModel->m_bit_0_prob) >> cSymbolCodecArithProbMoveBits); \
|
||||
arith_length = x; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
pModel->m_bit_0_prob -= (pModel->m_bit_0_prob >> cSymbolCodecArithProbMoveBits); \
|
||||
arith_value -= x; \
|
||||
arith_length -= x; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_ARITHMETIC(codec, result, model) \
|
||||
{ \
|
||||
adaptive_arith_data_model *pArith_data_model; \
|
||||
pArith_data_model = &model; \
|
||||
uint node_index; \
|
||||
node_index = 1; \
|
||||
do \
|
||||
{ \
|
||||
while (LZHAM_BUILTIN_EXPECT(arith_length < cSymbolCodecArithMinLen, 0)) \
|
||||
{ \
|
||||
uint c; codec.m_saved_node_index = node_index; codec.m_pSaved_model = pArith_data_model; \
|
||||
LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, c, 8); \
|
||||
node_index = codec.m_saved_node_index; pArith_data_model = static_cast<adaptive_arith_data_model *>(codec.m_pSaved_model); \
|
||||
arith_value = (arith_value << 8) | c; \
|
||||
arith_length <<= 8; \
|
||||
} \
|
||||
adaptive_bit_model *pBit_model; pBit_model = &pArith_data_model->m_probs[node_index]; \
|
||||
uint x = pBit_model->m_bit_0_prob * (arith_length >> cSymbolCodecArithProbBits); \
|
||||
uint bit; bit = (arith_value >= x); \
|
||||
if (!bit) \
|
||||
{ \
|
||||
pBit_model->m_bit_0_prob += ((cSymbolCodecArithProbScale - pBit_model->m_bit_0_prob) >> cSymbolCodecArithProbMoveBits); \
|
||||
arith_length = x; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
pBit_model->m_bit_0_prob -= (pBit_model->m_bit_0_prob >> cSymbolCodecArithProbMoveBits); \
|
||||
arith_value -= x; \
|
||||
arith_length -= x; \
|
||||
} \
|
||||
node_index = (node_index << 1) + bit; \
|
||||
} while (node_index < pArith_data_model->m_total_syms); \
|
||||
result = node_index - pArith_data_model->m_total_syms; \
|
||||
}
|
||||
|
||||
#if LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_HUFFMAN(codec, result, model) \
|
||||
{ \
|
||||
quasi_adaptive_huffman_data_model* pModel; const prefix_coding::decoder_tables* pTables; \
|
||||
pModel = &model; pTables = model.m_pDecode_tables; \
|
||||
if (LZHAM_BUILTIN_EXPECT(bit_count < 24, 0)) \
|
||||
{ \
|
||||
uint c; \
|
||||
pDecode_buf_next += sizeof(uint32); \
|
||||
if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next >= codec.m_pDecode_buf_end, 0)) \
|
||||
{ \
|
||||
pDecode_buf_next -= sizeof(uint32); \
|
||||
while (bit_count < 24) \
|
||||
{ \
|
||||
if (!codec.m_decode_buf_eof) \
|
||||
{ \
|
||||
codec.m_pSaved_huff_model = pModel; \
|
||||
LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
|
||||
LZHAM_DECODE_NEEDS_BYTES \
|
||||
LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
|
||||
pModel = codec.m_pSaved_huff_model; pTables = pModel->m_pDecode_tables; \
|
||||
} \
|
||||
c = 0; if (pDecode_buf_next < codec.m_pDecode_buf_end) c = *pDecode_buf_next++; \
|
||||
bit_count += 8; \
|
||||
bit_buf |= (static_cast<symbol_codec::bit_buf_t>(c) << (symbol_codec::cBitBufSize - bit_count)); \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
c = LZHAM_READ_BIG_ENDIAN_UINT32(pDecode_buf_next - sizeof(uint32)); \
|
||||
bit_count += 32; \
|
||||
bit_buf |= (static_cast<symbol_codec::bit_buf_t>(c) << (symbol_codec::cBitBufSize - bit_count)); \
|
||||
} \
|
||||
} \
|
||||
uint k = static_cast<uint>((bit_buf >> (symbol_codec::cBitBufSize - 16)) + 1); \
|
||||
uint len; \
|
||||
if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_table_max_code, 1)) \
|
||||
{ \
|
||||
uint32 t = pTables->m_lookup[bit_buf >> (symbol_codec::cBitBufSize - pTables->m_table_bits)]; \
|
||||
result = t & UINT16_MAX; \
|
||||
len = t >> 16; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
len = pTables->m_decode_start_code_size; \
|
||||
for ( ; ; ) \
|
||||
{ \
|
||||
if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_max_codes[len - 1], 0)) \
|
||||
break; \
|
||||
len++; \
|
||||
} \
|
||||
int val_ptr = pTables->m_val_ptrs[len - 1] + static_cast<int>(bit_buf >> (symbol_codec::cBitBufSize - len)); \
|
||||
if (((uint)val_ptr >= pModel->m_total_syms)) val_ptr = 0; \
|
||||
result = pTables->m_sorted_symbol_order[val_ptr]; \
|
||||
} \
|
||||
bit_buf <<= len; \
|
||||
bit_count -= len; \
|
||||
uint freq = pModel->m_sym_freq[result]; \
|
||||
freq++; \
|
||||
pModel->m_sym_freq[result] = static_cast<uint16>(freq); \
|
||||
LZHAM_ASSERT(freq <= UINT16_MAX); \
|
||||
if (LZHAM_BUILTIN_EXPECT(--pModel->m_symbols_until_update == 0, 0)) \
|
||||
{ \
|
||||
pModel->update(); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_HUFFMAN(codec, result, model) \
|
||||
{ \
|
||||
quasi_adaptive_huffman_data_model* pModel; const prefix_coding::decoder_tables* pTables; \
|
||||
pModel = &model; pTables = model.m_pDecode_tables; \
|
||||
while (LZHAM_BUILTIN_EXPECT(bit_count < (symbol_codec::cBitBufSize - 8), 1)) \
|
||||
{ \
|
||||
uint c; \
|
||||
if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next == codec.m_pDecode_buf_end, 0)) \
|
||||
{ \
|
||||
if (LZHAM_BUILTIN_EXPECT(!codec.m_decode_buf_eof, 1)) \
|
||||
{ \
|
||||
codec.m_pSaved_huff_model = pModel; \
|
||||
LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
|
||||
LZHAM_DECODE_NEEDS_BYTES \
|
||||
LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
|
||||
pModel = codec.m_pSaved_huff_model; pTables = pModel->m_pDecode_tables; \
|
||||
} \
|
||||
c = 0; if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next < codec.m_pDecode_buf_end, 1)) c = *pDecode_buf_next++; \
|
||||
} \
|
||||
else \
|
||||
c = *pDecode_buf_next++; \
|
||||
bit_count += 8; \
|
||||
bit_buf |= (static_cast<symbol_codec::bit_buf_t>(c) << (symbol_codec::cBitBufSize - bit_count)); \
|
||||
} \
|
||||
uint k = static_cast<uint>((bit_buf >> (symbol_codec::cBitBufSize - 16)) + 1); \
|
||||
uint len; \
|
||||
if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_table_max_code, 1)) \
|
||||
{ \
|
||||
uint32 t = pTables->m_lookup[bit_buf >> (symbol_codec::cBitBufSize - pTables->m_table_bits)]; \
|
||||
result = t & UINT16_MAX; \
|
||||
len = t >> 16; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
len = pTables->m_decode_start_code_size; \
|
||||
for ( ; ; ) \
|
||||
{ \
|
||||
if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_max_codes[len - 1], 0)) \
|
||||
break; \
|
||||
len++; \
|
||||
} \
|
||||
int val_ptr = pTables->m_val_ptrs[len - 1] + static_cast<int>(bit_buf >> (symbol_codec::cBitBufSize - len)); \
|
||||
if (LZHAM_BUILTIN_EXPECT(((uint)val_ptr >= pModel->m_total_syms), 0)) val_ptr = 0; \
|
||||
result = pTables->m_sorted_symbol_order[val_ptr]; \
|
||||
} \
|
||||
bit_buf <<= len; \
|
||||
bit_count -= len; \
|
||||
uint freq = pModel->m_sym_freq[result]; \
|
||||
freq++; \
|
||||
pModel->m_sym_freq[result] = static_cast<uint16>(freq); \
|
||||
LZHAM_ASSERT(freq <= UINT16_MAX); \
|
||||
if (LZHAM_BUILTIN_EXPECT(--pModel->m_symbols_until_update == 0, 0)) \
|
||||
{ \
|
||||
pModel->update(); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_ALIGN_TO_BYTE(codec) if (bit_count & 7) { int dummy_result; LZHAM_NOTE_UNUSED(dummy_result); LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, dummy_result, bit_count & 7); }
|
||||
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_REMOVE_BYTE_FROM_BIT_BUF(codec, result) \
|
||||
{ \
|
||||
result = -1; \
|
||||
if (bit_count >= 8) \
|
||||
{ \
|
||||
result = static_cast<int>(bit_buf >> (symbol_codec::cBitBufSize - 8)); \
|
||||
bit_buf <<= 8; \
|
||||
bit_count -= 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LZHAM_SYMBOL_CODEC_DECODE_ARITH_START(codec) \
|
||||
{ \
|
||||
for ( arith_value = 0, arith_length = 0; arith_length < 4; ++arith_length ) \
|
||||
{ \
|
||||
uint val; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, val, 8); \
|
||||
arith_value = (arith_value << 8) | val; \
|
||||
} \
|
||||
arith_length = cSymbolCodecArithMaxLen; \
|
||||
}
|
||||
|
||||
} // namespace lzham
|
12
r5dev/thirdparty/lzham/include/lzham_threading.h
vendored
Normal file
12
r5dev/thirdparty/lzham/include/lzham_threading.h
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// File: lzham_threading.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
|
||||
#if LZHAM_USE_WIN32_API
|
||||
#include "lzham_win32_threading.h"
|
||||
#elif LZHAM_USE_PTHREADS_API
|
||||
#include "lzham_pthreads_threading.h"
|
||||
#else
|
||||
#include "lzham_null_threading.h"
|
||||
#endif
|
||||
|
||||
|
99
r5dev/thirdparty/lzham/include/lzham_timer.h
vendored
Normal file
99
r5dev/thirdparty/lzham/include/lzham_timer.h
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
// File: lzham_timer.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
typedef unsigned long long timer_ticks;
|
||||
|
||||
class lzham_timer
|
||||
{
|
||||
public:
|
||||
lzham_timer();
|
||||
lzham_timer(timer_ticks start_ticks);
|
||||
|
||||
void start();
|
||||
void start(timer_ticks start_ticks);
|
||||
|
||||
void stop();
|
||||
|
||||
double get_elapsed_secs() const;
|
||||
inline double get_elapsed_ms() const { return get_elapsed_secs() * 1000.0f; }
|
||||
timer_ticks get_elapsed_us() const;
|
||||
|
||||
static void init();
|
||||
static inline timer_ticks get_ticks_per_sec() { return g_freq; }
|
||||
static timer_ticks get_init_ticks();
|
||||
static timer_ticks get_ticks();
|
||||
static double ticks_to_secs(timer_ticks ticks);
|
||||
static inline double ticks_to_ms(timer_ticks ticks) { return ticks_to_secs(ticks) * 1000.0f; }
|
||||
static inline double get_secs() { return ticks_to_secs(get_ticks()); }
|
||||
static inline double get_ms() { return ticks_to_ms(get_ticks()); }
|
||||
|
||||
private:
|
||||
static timer_ticks g_init_ticks;
|
||||
static timer_ticks g_freq;
|
||||
static double g_inv_freq;
|
||||
|
||||
timer_ticks m_start_time;
|
||||
timer_ticks m_stop_time;
|
||||
|
||||
bool m_started : 1;
|
||||
bool m_stopped : 1;
|
||||
};
|
||||
|
||||
enum var_args_t { cVarArgs };
|
||||
|
||||
#if LZHAM_PERF_SECTIONS
|
||||
class scoped_perf_section
|
||||
{
|
||||
public:
|
||||
inline scoped_perf_section() :
|
||||
m_start_ticks(lzham_timer::get_ticks())
|
||||
{
|
||||
m_name[0] = '?';
|
||||
m_name[1] = '\0';
|
||||
}
|
||||
|
||||
inline scoped_perf_section(const char *pName) :
|
||||
m_start_ticks(lzham_timer::get_ticks())
|
||||
{
|
||||
strcpy_s(m_name, pName);
|
||||
|
||||
lzham_buffered_printf("Thread: 0x%08X, BEGIN Time: %3.3fms, Section: %s\n", GetCurrentThreadId(), lzham_timer::ticks_to_ms(m_start_ticks), m_name);
|
||||
}
|
||||
|
||||
inline scoped_perf_section(var_args_t, const char *pName, ...) :
|
||||
m_start_ticks(lzham_timer::get_ticks())
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, pName);
|
||||
vsprintf_s(m_name, sizeof(m_name), pName, args);
|
||||
va_end(args);
|
||||
|
||||
lzham_buffered_printf("Thread: 0x%08X, BEGIN Time: %3.3fms, Section: %s\n", GetCurrentThreadId(), lzham_timer::ticks_to_ms(m_start_ticks), m_name);
|
||||
}
|
||||
|
||||
inline ~scoped_perf_section()
|
||||
{
|
||||
double end_ms = lzham_timer::get_ms();
|
||||
double start_ms = lzham_timer::ticks_to_ms(m_start_ticks);
|
||||
|
||||
lzham_buffered_printf("Thread: 0x%08X, END Time: %3.3fms, Total: %3.3fms, Section: %s\n", GetCurrentThreadId(), end_ms, end_ms - start_ms, m_name);
|
||||
}
|
||||
|
||||
private:
|
||||
char m_name[64];
|
||||
timer_ticks m_start_ticks;
|
||||
};
|
||||
#else
|
||||
class scoped_perf_section
|
||||
{
|
||||
public:
|
||||
inline scoped_perf_section() { }
|
||||
inline scoped_perf_section(const char *pName) { (void)pName; }
|
||||
inline scoped_perf_section(var_args_t, const char *pName, ...) { (void)pName; }
|
||||
};
|
||||
#endif // LZHAM_PERF_SECTIONS
|
||||
|
||||
} // namespace lzham
|
137
r5dev/thirdparty/lzham/include/lzham_traits.h
vendored
Normal file
137
r5dev/thirdparty/lzham/include/lzham_traits.h
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
// File: lzham_traits.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
template<typename T>
|
||||
struct scalar_type
|
||||
{
|
||||
enum { cFlag = false };
|
||||
static inline void construct(T* p) { helpers::construct(p); }
|
||||
static inline void construct(T* p, const T& init) { helpers::construct(p, init); }
|
||||
static inline void construct_array(T* p, uint n) { helpers::construct_array(p, n); }
|
||||
static inline void destruct(T* p) { helpers::destruct(p); }
|
||||
static inline void destruct_array(T* p, uint n) { helpers::destruct_array(p, n); }
|
||||
};
|
||||
|
||||
template<typename T> struct scalar_type<T*>
|
||||
{
|
||||
enum { cFlag = true };
|
||||
static inline void construct(T** p) { memset(p, 0, sizeof(T*)); }
|
||||
static inline void construct(T** p, T* init) { *p = init; }
|
||||
static inline void construct_array(T** p, uint n) { memset(p, 0, sizeof(T*) * n); }
|
||||
static inline void destruct(T** p) { LZHAM_NOTE_UNUSED(p); }
|
||||
static inline void destruct_array(T** p, uint n) { LZHAM_NOTE_UNUSED(p); LZHAM_NOTE_UNUSED(n); }
|
||||
};
|
||||
|
||||
#define LZHAM_DEFINE_BUILT_IN_TYPE(X) \
|
||||
template<> struct scalar_type<X> { \
|
||||
enum { cFlag = true }; \
|
||||
static inline void construct(X* p) { memset(p, 0, sizeof(X)); } \
|
||||
static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); } \
|
||||
static inline void construct_array(X* p, uint n) { memset(p, 0, sizeof(X) * n); } \
|
||||
static inline void destruct(X* p) { LZHAM_NOTE_UNUSED(p); } \
|
||||
static inline void destruct_array(X* p, uint n) { LZHAM_NOTE_UNUSED(p); LZHAM_NOTE_UNUSED(n); } };
|
||||
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(bool)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(char)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(unsigned char)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(short)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(unsigned short)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(int)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(unsigned int)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(long)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(unsigned long)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(float)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(double)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(long double)
|
||||
#if defined(WIN32)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(__int64)
|
||||
LZHAM_DEFINE_BUILT_IN_TYPE(unsigned __int64)
|
||||
#endif
|
||||
|
||||
#undef LZHAM_DEFINE_BUILT_IN_TYPE
|
||||
|
||||
// See: http://erdani.org/publications/cuj-2004-06.pdf
|
||||
|
||||
template<typename T>
|
||||
struct bitwise_movable { enum { cFlag = false }; };
|
||||
|
||||
// Defines type Q as bitwise movable.
|
||||
#define LZHAM_DEFINE_BITWISE_MOVABLE(Q) template<> struct bitwise_movable<Q> { enum { cFlag = true }; };
|
||||
|
||||
template<typename T>
|
||||
struct bitwise_copyable { enum { cFlag = false }; };
|
||||
|
||||
// Defines type Q as bitwise copyable.
|
||||
#define LZHAM_DEFINE_BITWISE_COPYABLE(Q) template<> struct bitwise_copyable<Q> { enum { cFlag = true }; };
|
||||
|
||||
#define LZHAM_IS_POD(T) __is_pod(T)
|
||||
|
||||
#define LZHAM_IS_SCALAR_TYPE(T) (scalar_type<T>::cFlag)
|
||||
|
||||
#define LZHAM_IS_BITWISE_COPYABLE(T) ((scalar_type<T>::cFlag) || (bitwise_copyable<T>::cFlag) || LZHAM_IS_POD(T))
|
||||
|
||||
#define LZHAM_IS_BITWISE_MOVABLE(T) (LZHAM_IS_BITWISE_COPYABLE(T) || (bitwise_movable<T>::cFlag))
|
||||
|
||||
#define LZHAM_HAS_DESTRUCTOR(T) ((!scalar_type<T>::cFlag) && (!__is_pod(T)))
|
||||
|
||||
// From yasli_traits.h:
|
||||
// Credit goes to Boost;
|
||||
// also found in the C++ Templates book by Vandevoorde and Josuttis
|
||||
|
||||
typedef char (&yes_t)[1];
|
||||
typedef char (&no_t)[2];
|
||||
|
||||
template <class U> yes_t class_test(int U::*);
|
||||
template <class U> no_t class_test(...);
|
||||
|
||||
template <class T> struct is_class
|
||||
{
|
||||
enum { value = (sizeof(class_test<T>(0)) == sizeof(yes_t)) };
|
||||
};
|
||||
|
||||
template <typename T> struct is_pointer
|
||||
{
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
template <typename T> struct is_pointer<T*>
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
LZHAM_DEFINE_BITWISE_COPYABLE(empty_type);
|
||||
LZHAM_DEFINE_BITWISE_MOVABLE(empty_type);
|
||||
|
||||
namespace helpers
|
||||
{
|
||||
template <typename T>
|
||||
inline void construct_array(T* p, uint n)
|
||||
{
|
||||
if (LZHAM_IS_SCALAR_TYPE(T))
|
||||
{
|
||||
memset(p, 0, sizeof(T) * n);
|
||||
}
|
||||
else
|
||||
{
|
||||
T* q = p + n;
|
||||
for ( ; p != q; ++p)
|
||||
new (static_cast<void*>(p)) T;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void destruct_array(T* p, uint n)
|
||||
{
|
||||
if ( LZHAM_HAS_DESTRUCTOR(T) )
|
||||
{
|
||||
T* q = p + n;
|
||||
for ( ; p != q; ++p)
|
||||
p->~T();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace lzham
|
74
r5dev/thirdparty/lzham/include/lzham_types.h
vendored
Normal file
74
r5dev/thirdparty/lzham/include/lzham_types.h
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
// File: types.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef signed short int16;
|
||||
typedef unsigned int uint32;
|
||||
typedef uint32 uint;
|
||||
typedef signed int int32;
|
||||
|
||||
#ifdef __GNUC__
|
||||
typedef unsigned long long uint64;
|
||||
typedef long long int64;
|
||||
#else
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef signed __int64 int64;
|
||||
#endif
|
||||
|
||||
const uint8 UINT8_MIN = 0;
|
||||
//const uint8 UINT8_MAX = 0xFFU;
|
||||
const uint16 UINT16_MIN = 0;
|
||||
//const uint16 UINT16_MAX = 0xFFFFU;
|
||||
const uint32 UINT32_MIN = 0;
|
||||
//const uint32 UINT32_MAX = 0xFFFFFFFFU;
|
||||
const uint64 UINT64_MIN = 0;
|
||||
//const uint64 UINT64_MAX = 0xFFFFFFFFFFFFFFFFULL; //0xFFFFFFFFFFFFFFFFui64;
|
||||
|
||||
//const int8 INT8_MIN = -128;
|
||||
//const int8 INT8_MAX = 127;
|
||||
//const int16 INT16_MIN = -32768;
|
||||
//const int16 INT16_MAX = 32767;
|
||||
//const int32 INT32_MIN = (-2147483647 - 1);
|
||||
//const int32 INT32_MAX = 2147483647;
|
||||
//const int64 INT64_MIN = (int64)0x8000000000000000ULL; //(-9223372036854775807i64 - 1);
|
||||
//const int64 INT64_MAX = (int64)0x7FFFFFFFFFFFFFFFULL; //9223372036854775807i64;
|
||||
|
||||
#if LZHAM_64BIT_POINTERS
|
||||
typedef uint64 uint_ptr;
|
||||
typedef uint64 uint32_ptr;
|
||||
typedef int64 signed_size_t;
|
||||
typedef uint64 ptr_bits_t;
|
||||
const ptr_bits_t PTR_BITS_XOR = 0xDB0DD4415C87DCF7ULL;
|
||||
#else
|
||||
typedef unsigned int uint_ptr;
|
||||
typedef unsigned int uint32_ptr;
|
||||
typedef signed int signed_size_t;
|
||||
typedef uint32 ptr_bits_t;
|
||||
const ptr_bits_t PTR_BITS_XOR = 0x5C87DCF7UL;
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
cInvalidIndex = -1
|
||||
};
|
||||
|
||||
const uint cIntBits = sizeof(uint) * CHAR_BIT;
|
||||
|
||||
template<typename T> struct int_traits { enum { cMin = INT_MIN, cMax = INT_MAX, cSigned = true }; };
|
||||
template<> struct int_traits<int8> { enum { cMin = INT8_MIN, cMax = INT8_MAX, cSigned = true }; };
|
||||
template<> struct int_traits<int16> { enum { cMin = INT16_MIN, cMax = INT16_MAX, cSigned = true }; };
|
||||
template<> struct int_traits<int32> { enum { cMin = INT32_MIN, cMax = INT32_MAX, cSigned = true }; };
|
||||
|
||||
template<> struct int_traits<uint> { enum { cMin = 0, cMax = UINT_MAX, cSigned = false }; };
|
||||
template<> struct int_traits<uint8> { enum { cMin = 0, cMax = UINT8_MAX, cSigned = false }; };
|
||||
template<> struct int_traits<uint16> { enum { cMin = 0, cMax = UINT16_MAX, cSigned = false }; };
|
||||
|
||||
struct empty_type { };
|
||||
|
||||
} // namespace lzham
|
58
r5dev/thirdparty/lzham/include/lzham_utils.h
vendored
Normal file
58
r5dev/thirdparty/lzham/include/lzham_utils.h
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
// File: lzham_utils.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
#define LZHAM_GET_ALIGNMENT(v) ((!sizeof(v)) ? 1 : (__alignof(v) ? __alignof(v) : sizeof(uint32)))
|
||||
|
||||
#define LZHAM_MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define LZHAM_MAX(a, b) (((a) < (b)) ? (b) : (a))
|
||||
|
||||
template<class T, size_t N> T decay_array_to_subtype(T (&a)[N]);
|
||||
#define LZHAM_ARRAY_SIZE(X) (sizeof(X) / sizeof(decay_array_to_subtype(X)))
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
namespace utils
|
||||
{
|
||||
template<typename T> inline void swap(T& l, T& r)
|
||||
{
|
||||
T temp(l);
|
||||
l = r;
|
||||
r = temp;
|
||||
}
|
||||
|
||||
template<typename T> inline void zero_object(T& obj)
|
||||
{
|
||||
memset(&obj, 0, sizeof(obj));
|
||||
}
|
||||
|
||||
static inline uint32 swap32(uint32 x) { return ((x << 24U) | ((x << 8U) & 0x00FF0000U) | ((x >> 8U) & 0x0000FF00U) | (x >> 24U)); }
|
||||
|
||||
inline uint count_leading_zeros16(uint v)
|
||||
{
|
||||
LZHAM_ASSERT(v < 0x10000);
|
||||
|
||||
uint temp;
|
||||
uint n = 16;
|
||||
|
||||
temp = v >> 8;
|
||||
if (temp) { n -= 8; v = temp; }
|
||||
|
||||
temp = v >> 4;
|
||||
if (temp) { n -= 4; v = temp; }
|
||||
|
||||
temp = v >> 2;
|
||||
if (temp) { n -= 2; v = temp; }
|
||||
|
||||
temp = v >> 1;
|
||||
if (temp) { n -= 1; v = temp; }
|
||||
|
||||
if (v & 1) n--;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
|
||||
} // namespace lzham
|
||||
|
588
r5dev/thirdparty/lzham/include/lzham_vector.h
vendored
Normal file
588
r5dev/thirdparty/lzham/include/lzham_vector.h
vendored
Normal file
@ -0,0 +1,588 @@
|
||||
// File: lzham_vector.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
struct elemental_vector
|
||||
{
|
||||
void* m_p;
|
||||
uint m_size;
|
||||
uint m_capacity;
|
||||
|
||||
typedef void (*object_mover)(void* pDst, void* pSrc, uint num);
|
||||
|
||||
bool increase_capacity(uint min_new_capacity, bool grow_hint, uint element_size, object_mover pRelocate, bool nofail);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class vector : public helpers::rel_ops< vector<T> >
|
||||
{
|
||||
public:
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
|
||||
inline vector() :
|
||||
m_p(NULL),
|
||||
m_size(0),
|
||||
m_capacity(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline vector(uint n, const T& init) :
|
||||
m_p(NULL),
|
||||
m_size(0),
|
||||
m_capacity(0)
|
||||
{
|
||||
increase_capacity(n, false);
|
||||
helpers::construct_array(m_p, n, init);
|
||||
m_size = n;
|
||||
}
|
||||
|
||||
inline vector(const vector& other) :
|
||||
m_p(NULL),
|
||||
m_size(0),
|
||||
m_capacity(0)
|
||||
{
|
||||
increase_capacity(other.m_size, false);
|
||||
|
||||
m_size = other.m_size;
|
||||
|
||||
if (LZHAM_IS_BITWISE_COPYABLE(T))
|
||||
memcpy(m_p, other.m_p, m_size * sizeof(T));
|
||||
else
|
||||
{
|
||||
T* pDst = m_p;
|
||||
const T* pSrc = other.m_p;
|
||||
for (uint i = m_size; i > 0; i--)
|
||||
helpers::construct(pDst++, *pSrc++);
|
||||
}
|
||||
}
|
||||
|
||||
inline explicit vector(uint size) :
|
||||
m_p(NULL),
|
||||
m_size(0),
|
||||
m_capacity(0)
|
||||
{
|
||||
try_resize(size);
|
||||
}
|
||||
|
||||
inline ~vector()
|
||||
{
|
||||
if (m_p)
|
||||
{
|
||||
scalar_type<T>::destruct_array(m_p, m_size);
|
||||
lzham_free(m_p);
|
||||
}
|
||||
}
|
||||
|
||||
inline vector& operator= (const vector& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
if (m_capacity >= other.m_size)
|
||||
try_resize(0);
|
||||
else
|
||||
{
|
||||
clear();
|
||||
if (!increase_capacity(other.m_size, false))
|
||||
{
|
||||
LZHAM_FAIL("lzham::vector operator=: Out of memory!");
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
if (LZHAM_IS_BITWISE_COPYABLE(T))
|
||||
memcpy(m_p, other.m_p, other.m_size * sizeof(T));
|
||||
else
|
||||
{
|
||||
T* pDst = m_p;
|
||||
const T* pSrc = other.m_p;
|
||||
for (uint i = other.m_size; i > 0; i--)
|
||||
helpers::construct(pDst++, *pSrc++);
|
||||
}
|
||||
|
||||
m_size = other.m_size;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const T* begin() const { return m_p; }
|
||||
T* begin() { return m_p; }
|
||||
|
||||
inline const T* end() const { return m_p + m_size; }
|
||||
T* end() { return m_p + m_size; }
|
||||
|
||||
inline bool empty() const { return !m_size; }
|
||||
inline uint size() const { return m_size; }
|
||||
inline uint size_in_bytes() const { return m_size * sizeof(T); }
|
||||
inline uint capacity() const { return m_capacity; }
|
||||
|
||||
// operator[] will assert on out of range indices, but in final builds there is (and will never be) any range checking on this method.
|
||||
inline const T& operator[] (uint i) const { LZHAM_ASSERT(i < m_size); return m_p[i]; }
|
||||
inline T& operator[] (uint i) { LZHAM_ASSERT(i < m_size); return m_p[i]; }
|
||||
|
||||
// at() always includes range checking, even in final builds, unlike operator [].
|
||||
// The first element is returned if the index is out of range.
|
||||
inline const T& at(uint i) const { LZHAM_ASSERT(i < m_size); return (i >= m_size) ? m_p[0] : m_p[i]; }
|
||||
inline T& at(uint i) { LZHAM_ASSERT(i < m_size); return (i >= m_size) ? m_p[0] : m_p[i]; }
|
||||
|
||||
inline const T& front() const { LZHAM_ASSERT(m_size); return m_p[0]; }
|
||||
inline T& front() { LZHAM_ASSERT(m_size); return m_p[0]; }
|
||||
|
||||
inline const T& back() const { LZHAM_ASSERT(m_size); return m_p[m_size - 1]; }
|
||||
inline T& back() { LZHAM_ASSERT(m_size); return m_p[m_size - 1]; }
|
||||
|
||||
inline const T* get_ptr() const { return m_p; }
|
||||
inline T* get_ptr() { return m_p; }
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
if (m_p)
|
||||
{
|
||||
scalar_type<T>::destruct_array(m_p, m_size);
|
||||
lzham_free(m_p);
|
||||
m_p = NULL;
|
||||
m_size = 0;
|
||||
m_capacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void clear_no_destruction()
|
||||
{
|
||||
if (m_p)
|
||||
{
|
||||
lzham_free(m_p);
|
||||
m_p = NULL;
|
||||
m_size = 0;
|
||||
m_capacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool try_reserve(uint new_capacity)
|
||||
{
|
||||
return increase_capacity(new_capacity, true, true);
|
||||
}
|
||||
|
||||
inline bool try_resize(uint new_size, bool grow_hint = false)
|
||||
{
|
||||
if (m_size != new_size)
|
||||
{
|
||||
if (new_size < m_size)
|
||||
scalar_type<T>::destruct_array(m_p + new_size, m_size - new_size);
|
||||
else
|
||||
{
|
||||
if (new_size > m_capacity)
|
||||
{
|
||||
if (!increase_capacity(new_size, (new_size == (m_size + 1)) || grow_hint, true))
|
||||
return false;
|
||||
}
|
||||
|
||||
scalar_type<T>::construct_array(m_p + m_size, new_size - m_size);
|
||||
}
|
||||
|
||||
m_size = new_size;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool try_resize_no_construct(uint new_size, bool grow_hint = false)
|
||||
{
|
||||
if (new_size > m_capacity)
|
||||
{
|
||||
if (!increase_capacity(new_size, (new_size == (m_size + 1)) || grow_hint, true))
|
||||
return false;
|
||||
}
|
||||
|
||||
m_size = new_size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline T* try_enlarge(uint i)
|
||||
{
|
||||
uint cur_size = m_size;
|
||||
if (!try_resize(cur_size + i, true))
|
||||
return NULL;
|
||||
return get_ptr() + cur_size;
|
||||
}
|
||||
|
||||
inline bool try_push_back(const T& obj)
|
||||
{
|
||||
LZHAM_ASSERT(!m_p || (&obj < m_p) || (&obj >= (m_p + m_size)));
|
||||
|
||||
if (m_size >= m_capacity)
|
||||
{
|
||||
if (!increase_capacity(m_size + 1, true, true))
|
||||
return false;
|
||||
}
|
||||
|
||||
scalar_type<T>::construct(m_p + m_size, obj);
|
||||
m_size++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void pop_back()
|
||||
{
|
||||
LZHAM_ASSERT(m_size);
|
||||
|
||||
if (m_size)
|
||||
{
|
||||
m_size--;
|
||||
scalar_type<T>::destruct(&m_p[m_size]);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool insert(uint index, const T* p, uint n)
|
||||
{
|
||||
LZHAM_ASSERT(index <= m_size);
|
||||
if (!n)
|
||||
return true;
|
||||
|
||||
const uint orig_size = m_size;
|
||||
if (!try_resize(m_size + n, true))
|
||||
return false;
|
||||
|
||||
const uint num_to_move = orig_size - index;
|
||||
if (num_to_move)
|
||||
{
|
||||
if (LZHAM_IS_BITWISE_COPYABLE(T))
|
||||
memmove(m_p + index + n, m_p + index, sizeof(T) * num_to_move);
|
||||
else
|
||||
{
|
||||
const T* pSrc = m_p + orig_size - 1;
|
||||
T* pDst = const_cast<T*>(pSrc) + n;
|
||||
|
||||
for (uint i = 0; i < num_to_move; i++)
|
||||
{
|
||||
LZHAM_ASSERT((pDst - m_p) < (int)m_size);
|
||||
*pDst-- = *pSrc--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
T* pDst = m_p + index;
|
||||
|
||||
if (LZHAM_IS_BITWISE_COPYABLE(T))
|
||||
memcpy(pDst, p, sizeof(T) * n);
|
||||
else
|
||||
{
|
||||
for (uint i = 0; i < n; i++)
|
||||
{
|
||||
LZHAM_ASSERT((pDst - m_p) < (int)m_size);
|
||||
*pDst++ = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// push_front() isn't going to be very fast - it's only here for usability.
|
||||
inline bool try_push_front(const T& obj)
|
||||
{
|
||||
return insert(0, &obj, 1);
|
||||
}
|
||||
|
||||
bool append(const vector& other)
|
||||
{
|
||||
if (other.m_size)
|
||||
return insert(m_size, &other[0], other.m_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool append(const T* p, uint n)
|
||||
{
|
||||
if (n)
|
||||
return insert(m_size, p, n);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void erase(uint start, uint n)
|
||||
{
|
||||
LZHAM_ASSERT((start + n) <= m_size);
|
||||
if ((start + n) > m_size)
|
||||
return;
|
||||
|
||||
if (!n)
|
||||
return;
|
||||
|
||||
const uint num_to_move = m_size - (start + n);
|
||||
|
||||
T* pDst = m_p + start;
|
||||
|
||||
const T* pSrc = m_p + start + n;
|
||||
|
||||
if (LZHAM_IS_BITWISE_COPYABLE(T))
|
||||
memmove(pDst, pSrc, num_to_move * sizeof(T));
|
||||
else
|
||||
{
|
||||
T* pDst_end = pDst + num_to_move;
|
||||
|
||||
while (pDst != pDst_end)
|
||||
*pDst++ = *pSrc++;
|
||||
|
||||
scalar_type<T>::destruct_array(pDst_end, n);
|
||||
}
|
||||
|
||||
m_size -= n;
|
||||
}
|
||||
|
||||
inline void erase(uint index)
|
||||
{
|
||||
erase(index, 1);
|
||||
}
|
||||
|
||||
inline void erase(T* p)
|
||||
{
|
||||
LZHAM_ASSERT((p >= m_p) && (p < (m_p + m_size)));
|
||||
erase(static_cast<uint>(p - m_p));
|
||||
}
|
||||
|
||||
void erase_unordered(uint index)
|
||||
{
|
||||
LZHAM_ASSERT(index < m_size);
|
||||
|
||||
if ((index + 1) < m_size)
|
||||
(*this)[index] = back();
|
||||
|
||||
pop_back();
|
||||
}
|
||||
|
||||
inline bool operator== (const vector& rhs) const
|
||||
{
|
||||
if (m_size != rhs.m_size)
|
||||
return false;
|
||||
else if (m_size)
|
||||
{
|
||||
if (scalar_type<T>::cFlag)
|
||||
return memcmp(m_p, rhs.m_p, sizeof(T) * m_size) == 0;
|
||||
else
|
||||
{
|
||||
const T* pSrc = m_p;
|
||||
const T* pDst = rhs.m_p;
|
||||
for (uint i = m_size; i; i--)
|
||||
if (!(*pSrc++ == *pDst++))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator< (const vector& rhs) const
|
||||
{
|
||||
const uint min_size = math::minimum(m_size, rhs.m_size);
|
||||
|
||||
const T* pSrc = m_p;
|
||||
const T* pSrc_end = m_p + min_size;
|
||||
const T* pDst = rhs.m_p;
|
||||
|
||||
while ((pSrc < pSrc_end) && (*pSrc == *pDst))
|
||||
{
|
||||
pSrc++;
|
||||
pDst++;
|
||||
}
|
||||
|
||||
if (pSrc < pSrc_end)
|
||||
return *pSrc < *pDst;
|
||||
|
||||
return m_size < rhs.m_size;
|
||||
}
|
||||
|
||||
inline void swap(vector& other)
|
||||
{
|
||||
utils::swap(m_p, other.m_p);
|
||||
utils::swap(m_size, other.m_size);
|
||||
utils::swap(m_capacity, other.m_capacity);
|
||||
}
|
||||
|
||||
inline void sort()
|
||||
{
|
||||
std::sort(begin(), end());
|
||||
}
|
||||
|
||||
inline void unique()
|
||||
{
|
||||
if (!empty())
|
||||
{
|
||||
sort();
|
||||
|
||||
resize(std::unique(begin(), end()) - begin());
|
||||
}
|
||||
}
|
||||
|
||||
inline void reverse()
|
||||
{
|
||||
uint j = m_size >> 1;
|
||||
for (uint i = 0; i < j; i++)
|
||||
utils::swap(m_p[i], m_p[m_size - 1 - i]);
|
||||
}
|
||||
|
||||
inline int find(const T& key) const
|
||||
{
|
||||
const T* p = m_p;
|
||||
const T* p_end = m_p + m_size;
|
||||
|
||||
uint index = 0;
|
||||
|
||||
while (p != p_end)
|
||||
{
|
||||
if (key == *p)
|
||||
return index;
|
||||
|
||||
p++;
|
||||
index++;
|
||||
}
|
||||
|
||||
return cInvalidIndex;
|
||||
}
|
||||
|
||||
inline int find_sorted(const T& key) const
|
||||
{
|
||||
if (m_size)
|
||||
{
|
||||
// Uniform binary search - Knuth Algorithm 6.2.1 U, unrolled twice.
|
||||
int i = ((m_size + 1) >> 1) - 1;
|
||||
int m = m_size;
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
LZHAM_ASSERT_OPEN_RANGE(i, 0, (int)m_size);
|
||||
const T* pKey_i = m_p + i;
|
||||
int cmp = key < *pKey_i;
|
||||
if ((!cmp) && (key == *pKey_i)) return i;
|
||||
m >>= 1;
|
||||
if (!m) break;
|
||||
cmp = -cmp;
|
||||
i += (((m + 1) >> 1) ^ cmp) - cmp;
|
||||
|
||||
LZHAM_ASSERT_OPEN_RANGE(i, 0, (int)m_size);
|
||||
pKey_i = m_p + i;
|
||||
cmp = key < *pKey_i;
|
||||
if ((!cmp) && (key == *pKey_i)) return i;
|
||||
m >>= 1;
|
||||
if (!m) break;
|
||||
cmp = -cmp;
|
||||
i += (((m + 1) >> 1) ^ cmp) - cmp;
|
||||
}
|
||||
}
|
||||
|
||||
return cInvalidIndex;
|
||||
}
|
||||
|
||||
template<typename Q>
|
||||
inline int find_sorted(const T& key, Q less_than) const
|
||||
{
|
||||
if (m_size)
|
||||
{
|
||||
// Uniform binary search - Knuth Algorithm 6.2.1 U, unrolled twice.
|
||||
int i = ((m_size + 1) >> 1) - 1;
|
||||
int m = m_size;
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
LZHAM_ASSERT_OPEN_RANGE(i, 0, (int)m_size);
|
||||
const T* pKey_i = m_p + i;
|
||||
int cmp = less_than(key, *pKey_i);
|
||||
if ((!cmp) && (!less_than(*pKey_i, key))) return i;
|
||||
m >>= 1;
|
||||
if (!m) break;
|
||||
cmp = -cmp;
|
||||
i += (((m + 1) >> 1) ^ cmp) - cmp;
|
||||
|
||||
LZHAM_ASSERT_OPEN_RANGE(i, 0, (int)m_size);
|
||||
pKey_i = m_p + i;
|
||||
cmp = less_than(key, *pKey_i);
|
||||
if ((!cmp) && (!less_than(*pKey_i, key))) return i;
|
||||
m >>= 1;
|
||||
if (!m) break;
|
||||
cmp = -cmp;
|
||||
i += (((m + 1) >> 1) ^ cmp) - cmp;
|
||||
}
|
||||
}
|
||||
|
||||
return cInvalidIndex;
|
||||
}
|
||||
|
||||
inline uint count_occurences(const T& key) const
|
||||
{
|
||||
uint c = 0;
|
||||
|
||||
const T* p = m_p;
|
||||
const T* p_end = m_p + m_size;
|
||||
|
||||
while (p != p_end)
|
||||
{
|
||||
if (key == *p)
|
||||
c++;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
inline void set_all(const T& o)
|
||||
{
|
||||
if ((sizeof(T) == 1) && (scalar_type<T>::cFlag))
|
||||
memset(m_p, *reinterpret_cast<const uint8*>(&o), m_size);
|
||||
else
|
||||
{
|
||||
T* pDst = m_p;
|
||||
T* pDst_end = pDst + m_size;
|
||||
while (pDst != pDst_end)
|
||||
*pDst++ = o;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
T* m_p;
|
||||
uint m_size;
|
||||
uint m_capacity;
|
||||
|
||||
template<typename Q> struct is_vector { enum { cFlag = false }; };
|
||||
template<typename Q> struct is_vector< vector<Q> > { enum { cFlag = true }; };
|
||||
|
||||
static void object_mover(void* pDst_void, void* pSrc_void, uint num)
|
||||
{
|
||||
T* pSrc = static_cast<T*>(pSrc_void);
|
||||
T* const pSrc_end = pSrc + num;
|
||||
T* pDst = static_cast<T*>(pDst_void);
|
||||
|
||||
while (pSrc != pSrc_end)
|
||||
{
|
||||
new (static_cast<void*>(pDst)) T(*pSrc);
|
||||
pSrc->~T();
|
||||
pSrc++;
|
||||
pDst++;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool increase_capacity(uint min_new_capacity, bool grow_hint, bool nofail = false)
|
||||
{
|
||||
return reinterpret_cast<elemental_vector*>(this)->increase_capacity(
|
||||
min_new_capacity, grow_hint, sizeof(T),
|
||||
(LZHAM_IS_BITWISE_MOVABLE(T) || (is_vector<T>::cFlag)) ? NULL : object_mover, nofail);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct bitwise_movable< vector<T> > { enum { cFlag = true }; };
|
||||
|
||||
extern void vector_test();
|
||||
|
||||
template<typename T>
|
||||
inline void swap(vector<T>& a, vector<T>& b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
} // namespace lzham
|
||||
|
368
r5dev/thirdparty/lzham/include/lzham_win32_threading.h
vendored
Normal file
368
r5dev/thirdparty/lzham/include/lzham_win32_threading.h
vendored
Normal file
@ -0,0 +1,368 @@
|
||||
// File: lzham_task_pool_win32.h
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#pragma once
|
||||
|
||||
#if LZHAM_USE_WIN32_API
|
||||
|
||||
#if LZHAM_NO_ATOMICS
|
||||
#error No atomic operations defined in lzham_platform.h!
|
||||
#endif
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
class semaphore
|
||||
{
|
||||
LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore);
|
||||
|
||||
public:
|
||||
semaphore(long initialCount = 0, long maximumCount = 1, const char* pName = NULL)
|
||||
{
|
||||
m_handle = CreateSemaphoreA(NULL, initialCount, maximumCount, pName);
|
||||
if (NULL == m_handle)
|
||||
{
|
||||
LZHAM_FAIL("semaphore: CreateSemaphore() failed");
|
||||
}
|
||||
}
|
||||
|
||||
~semaphore()
|
||||
{
|
||||
if (m_handle)
|
||||
{
|
||||
CloseHandle(m_handle);
|
||||
m_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inline HANDLE get_handle(void) const { return m_handle; }
|
||||
|
||||
void release(long releaseCount = 1)
|
||||
{
|
||||
if (0 == ReleaseSemaphore(m_handle, releaseCount, NULL))
|
||||
{
|
||||
LZHAM_FAIL("semaphore: ReleaseSemaphore() failed");
|
||||
}
|
||||
}
|
||||
|
||||
bool wait(uint32 milliseconds = UINT32_MAX)
|
||||
{
|
||||
LZHAM_ASSUME(INFINITE == UINT32_MAX);
|
||||
|
||||
DWORD result = WaitForSingleObject(m_handle, milliseconds);
|
||||
|
||||
if (WAIT_FAILED == result)
|
||||
{
|
||||
LZHAM_FAIL("semaphore: WaitForSingleObject() failed");
|
||||
}
|
||||
|
||||
return WAIT_OBJECT_0 == result;
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE m_handle;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class tsstack
|
||||
{
|
||||
public:
|
||||
inline tsstack(bool use_freelist = true) :
|
||||
m_use_freelist(use_freelist)
|
||||
{
|
||||
LZHAM_VERIFY(((ptr_bits_t)this & (LZHAM_GET_ALIGNMENT(tsstack) - 1)) == 0);
|
||||
InitializeSListHead(&m_stack_head);
|
||||
InitializeSListHead(&m_freelist_head);
|
||||
}
|
||||
|
||||
inline ~tsstack()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
for ( ; ; )
|
||||
{
|
||||
node* pNode = (node*)InterlockedPopEntrySList(&m_stack_head);
|
||||
if (!pNode)
|
||||
break;
|
||||
|
||||
LZHAM_MEMORY_IMPORT_BARRIER
|
||||
|
||||
helpers::destruct(&pNode->m_obj);
|
||||
|
||||
lzham_free(pNode);
|
||||
}
|
||||
|
||||
flush_freelist();
|
||||
}
|
||||
|
||||
inline void flush_freelist()
|
||||
{
|
||||
if (!m_use_freelist)
|
||||
return;
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
node* pNode = (node*)InterlockedPopEntrySList(&m_freelist_head);
|
||||
if (!pNode)
|
||||
break;
|
||||
|
||||
LZHAM_MEMORY_IMPORT_BARRIER
|
||||
|
||||
lzham_free(pNode);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool try_push(const T& obj)
|
||||
{
|
||||
node* pNode = alloc_node();
|
||||
if (!pNode)
|
||||
return false;
|
||||
|
||||
helpers::construct(&pNode->m_obj, obj);
|
||||
|
||||
LZHAM_MEMORY_EXPORT_BARRIER
|
||||
|
||||
InterlockedPushEntrySList(&m_stack_head, &pNode->m_slist_entry);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool pop(T& obj)
|
||||
{
|
||||
node* pNode = (node*)InterlockedPopEntrySList(&m_stack_head);
|
||||
if (!pNode)
|
||||
return false;
|
||||
|
||||
LZHAM_MEMORY_IMPORT_BARRIER
|
||||
|
||||
obj = pNode->m_obj;
|
||||
|
||||
helpers::destruct(&pNode->m_obj);
|
||||
|
||||
free_node(pNode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
SLIST_HEADER m_stack_head;
|
||||
SLIST_HEADER m_freelist_head;
|
||||
|
||||
struct node
|
||||
{
|
||||
SLIST_ENTRY m_slist_entry;
|
||||
T m_obj;
|
||||
};
|
||||
|
||||
bool m_use_freelist;
|
||||
|
||||
inline node* alloc_node()
|
||||
{
|
||||
node* pNode = m_use_freelist ? (node*)InterlockedPopEntrySList(&m_freelist_head) : NULL;
|
||||
|
||||
if (!pNode)
|
||||
pNode = (node*)lzham_malloc(sizeof(node));
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
inline void free_node(node* pNode)
|
||||
{
|
||||
if (m_use_freelist)
|
||||
InterlockedPushEntrySList(&m_freelist_head, &pNode->m_slist_entry);
|
||||
else
|
||||
lzham_free(pNode);
|
||||
}
|
||||
};
|
||||
|
||||
class task_pool
|
||||
{
|
||||
public:
|
||||
task_pool();
|
||||
task_pool(uint num_threads);
|
||||
~task_pool();
|
||||
|
||||
enum { cMaxThreads = LZHAM_MAX_HELPER_THREADS };
|
||||
bool init(uint num_threads);
|
||||
void deinit();
|
||||
|
||||
inline uint get_num_threads() const { return m_num_threads; }
|
||||
inline uint get_num_outstanding_tasks() const { return m_num_outstanding_tasks; }
|
||||
|
||||
// C-style task callback
|
||||
typedef void (*task_callback_func)(uint64 data, void* pData_ptr);
|
||||
bool queue_task(task_callback_func pFunc, uint64 data = 0, void* pData_ptr = NULL);
|
||||
|
||||
class executable_task
|
||||
{
|
||||
public:
|
||||
virtual void execute_task(uint64 data, void* pData_ptr) = 0;
|
||||
};
|
||||
|
||||
// It's the caller's responsibility to delete pObj within the execute_task() method, if needed!
|
||||
bool queue_task(executable_task* pObj, uint64 data = 0, void* pData_ptr = NULL);
|
||||
|
||||
template<typename S, typename T>
|
||||
inline bool queue_object_task(S* pObject, T pObject_method, uint64 data = 0, void* pData_ptr = NULL);
|
||||
|
||||
template<typename S, typename T>
|
||||
inline bool queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr = NULL);
|
||||
|
||||
void join();
|
||||
|
||||
private:
|
||||
struct task
|
||||
{
|
||||
//inline task() : m_data(0), m_pData_ptr(NULL), m_pObj(NULL), m_flags(0) { }
|
||||
|
||||
uint64 m_data;
|
||||
void* m_pData_ptr;
|
||||
|
||||
union
|
||||
{
|
||||
task_callback_func m_callback;
|
||||
executable_task* m_pObj;
|
||||
};
|
||||
|
||||
uint m_flags;
|
||||
};
|
||||
|
||||
tsstack<task> m_task_stack;
|
||||
|
||||
uint m_num_threads;
|
||||
HANDLE m_threads[cMaxThreads];
|
||||
|
||||
semaphore m_tasks_available;
|
||||
|
||||
enum task_flags
|
||||
{
|
||||
cTaskFlagObject = 1
|
||||
};
|
||||
|
||||
volatile atomic32_t m_num_outstanding_tasks;
|
||||
volatile atomic32_t m_exit_flag;
|
||||
|
||||
void process_task(task& tsk);
|
||||
|
||||
static unsigned __stdcall thread_func(void* pContext);
|
||||
};
|
||||
|
||||
enum object_task_flags
|
||||
{
|
||||
cObjectTaskFlagDefault = 0,
|
||||
cObjectTaskFlagDeleteAfterExecution = 1
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class object_task : public task_pool::executable_task
|
||||
{
|
||||
public:
|
||||
object_task(uint flags = cObjectTaskFlagDefault) :
|
||||
m_pObject(NULL),
|
||||
m_pMethod(NULL),
|
||||
m_flags(flags)
|
||||
{
|
||||
}
|
||||
|
||||
typedef void (T::*object_method_ptr)(uint64 data, void* pData_ptr);
|
||||
|
||||
object_task(T* pObject, object_method_ptr pMethod, uint flags = cObjectTaskFlagDefault) :
|
||||
m_pObject(pObject),
|
||||
m_pMethod(pMethod),
|
||||
m_flags(flags)
|
||||
{
|
||||
LZHAM_ASSERT(pObject && pMethod);
|
||||
}
|
||||
|
||||
void init(T* pObject, object_method_ptr pMethod, uint flags = cObjectTaskFlagDefault)
|
||||
{
|
||||
LZHAM_ASSERT(pObject && pMethod);
|
||||
|
||||
m_pObject = pObject;
|
||||
m_pMethod = pMethod;
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
T* get_object() const { return m_pObject; }
|
||||
object_method_ptr get_method() const { return m_pMethod; }
|
||||
|
||||
virtual void execute_task(uint64 data, void* pData_ptr)
|
||||
{
|
||||
(m_pObject->*m_pMethod)(data, pData_ptr);
|
||||
|
||||
if (m_flags & cObjectTaskFlagDeleteAfterExecution)
|
||||
lzham_delete(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
T* m_pObject;
|
||||
|
||||
object_method_ptr m_pMethod;
|
||||
|
||||
uint m_flags;
|
||||
};
|
||||
|
||||
template<typename S, typename T>
|
||||
inline bool task_pool::queue_object_task(S* pObject, T pObject_method, uint64 data, void* pData_ptr)
|
||||
{
|
||||
object_task<S> *pTask = lzham_new< object_task<S> >(pObject, pObject_method, cObjectTaskFlagDeleteAfterExecution);
|
||||
if (!pTask)
|
||||
return false;
|
||||
return queue_task(pTask, data, pData_ptr);
|
||||
}
|
||||
|
||||
template<typename S, typename T>
|
||||
inline bool task_pool::queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr)
|
||||
{
|
||||
LZHAM_ASSERT(m_num_threads);
|
||||
LZHAM_ASSERT(pObject);
|
||||
LZHAM_ASSERT(num_tasks);
|
||||
if (!num_tasks)
|
||||
return true;
|
||||
|
||||
bool status = true;
|
||||
|
||||
uint i;
|
||||
for (i = 0; i < num_tasks; i++)
|
||||
{
|
||||
task tsk;
|
||||
|
||||
tsk.m_pObj = lzham_new< object_task<S> >(pObject, pObject_method, cObjectTaskFlagDeleteAfterExecution);
|
||||
if (!tsk.m_pObj)
|
||||
{
|
||||
status = false;
|
||||
break;
|
||||
}
|
||||
|
||||
tsk.m_data = first_data + i;
|
||||
tsk.m_pData_ptr = pData_ptr;
|
||||
tsk.m_flags = cTaskFlagObject;
|
||||
|
||||
if (!m_task_stack.try_push(tsk))
|
||||
{
|
||||
status = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
atomic_add32(&m_num_outstanding_tasks, i);
|
||||
|
||||
m_tasks_available.release(i);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
inline void lzham_sleep(unsigned int milliseconds)
|
||||
{
|
||||
Sleep(milliseconds);
|
||||
}
|
||||
|
||||
uint lzham_get_max_helper_threads();
|
||||
|
||||
} // namespace lzham
|
||||
|
||||
#endif // LZHAM_USE_WIN32_API
|
BIN
r5dev/thirdparty/lzham/libs/lzhamcomp_x64.lib
vendored
BIN
r5dev/thirdparty/lzham/libs/lzhamcomp_x64.lib
vendored
Binary file not shown.
BIN
r5dev/thirdparty/lzham/libs/lzhamcomp_x64D.lib
vendored
BIN
r5dev/thirdparty/lzham/libs/lzhamcomp_x64D.lib
vendored
Binary file not shown.
BIN
r5dev/thirdparty/lzham/libs/lzhamdecomp_x64.lib
vendored
BIN
r5dev/thirdparty/lzham/libs/lzhamdecomp_x64.lib
vendored
Binary file not shown.
BIN
r5dev/thirdparty/lzham/libs/lzhamdecomp_x64D.lib
vendored
BIN
r5dev/thirdparty/lzham/libs/lzhamdecomp_x64D.lib
vendored
Binary file not shown.
BIN
r5dev/thirdparty/lzham/libs/lzhamlib_x64.lib
vendored
BIN
r5dev/thirdparty/lzham/libs/lzhamlib_x64.lib
vendored
Binary file not shown.
BIN
r5dev/thirdparty/lzham/libs/lzhamlib_x64D.lib
vendored
BIN
r5dev/thirdparty/lzham/libs/lzhamlib_x64D.lib
vendored
Binary file not shown.
179
r5dev/thirdparty/lzham/lzham_api.cpp
vendored
Normal file
179
r5dev/thirdparty/lzham/lzham_api.cpp
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
// File: lzham_api.cpp - Dynamic DLL entrypoints.
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#include "include/lzham_core.h"
|
||||
#include "lzhamdecomp/lzham_decomp.h"
|
||||
#include "lzhamcomp/lzham_comp.h"
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_uint32 lzham_get_version(void)
|
||||
{
|
||||
return LZHAM_DLL_VERSION;
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT void lzham_set_memory_callbacks(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data)
|
||||
{
|
||||
lzham::lzham_lib_set_memory_callbacks(pRealloc, pMSize, pUser_data);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_decompress_state_ptr lzham_decompress_init(const lzham_decompress_params *pParams)
|
||||
{
|
||||
return lzham::lzham_lib_decompress_init(pParams);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_decompress_state_ptr lzham_decompress_reinit(lzham_decompress_state_ptr p, const lzham_decompress_params *pParams)
|
||||
{
|
||||
return lzham::lzham_lib_decompress_reinit(p, pParams);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_decompress_checksums* lzham_decompress_deinit(lzham_decompress_state_ptr p)
|
||||
{
|
||||
return lzham::lzham_lib_decompress_deinit(p);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_decompress_status_t lzham_decompress(
|
||||
lzham_decompress_state_ptr p,
|
||||
const lzham_uint8 *pIn_buf, size_t *pIn_buf_size,
|
||||
lzham_uint8 *pOut_buf, size_t *pOut_buf_size,
|
||||
lzham_bool no_more_input_bytes_flag)
|
||||
{
|
||||
return lzham::lzham_lib_decompress(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, no_more_input_bytes_flag);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_decompress_status_t lzham_decompress_memory(const lzham_decompress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32, lzham_uint32 *pCrc32)
|
||||
{
|
||||
return lzham::lzham_lib_decompress_memory(pParams, pDst_buf, pDst_len, pSrc_buf, src_len, pAdler32, pCrc32);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_compress_state_ptr lzham_compress_init(const lzham_compress_params *pParams)
|
||||
{
|
||||
return lzham::lzham_lib_compress_init(pParams);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_compress_state_ptr lzham_compress_reinit(lzham_compress_state_ptr p)
|
||||
{
|
||||
return lzham::lzham_lib_compress_reinit(p);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_compress_checksums* lzham_compress_deinit(lzham_compress_state_ptr p)
|
||||
{
|
||||
return lzham::lzham_lib_compress_deinit(p);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_compress_status_t lzham_compress(
|
||||
lzham_compress_state_ptr p,
|
||||
const lzham_uint8 *pIn_buf, size_t *pIn_buf_size,
|
||||
lzham_uint8 *pOut_buf, size_t *pOut_buf_size,
|
||||
lzham_bool no_more_input_bytes_flag)
|
||||
{
|
||||
return lzham::lzham_lib_compress(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, no_more_input_bytes_flag);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_compress_status_t lzham_compress2(
|
||||
lzham_compress_state_ptr p,
|
||||
const lzham_uint8 *pIn_buf, size_t *pIn_buf_size,
|
||||
lzham_uint8 *pOut_buf, size_t *pOut_buf_size,
|
||||
lzham_flush_t flush_type)
|
||||
{
|
||||
return lzham::lzham_lib_compress2(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, flush_type);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_compress_status_t lzham_compress_memory(const lzham_compress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32, lzham_uint32 * pCrc32)
|
||||
{
|
||||
return lzham::lzham_lib_compress_memory(pParams, pDst_buf, pDst_len, pSrc_buf, src_len, pAdler32, pCrc32);
|
||||
}
|
||||
|
||||
// ----------------- zlib-style API's
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT const char *lzham_z_version(void)
|
||||
{
|
||||
return LZHAM_Z_VERSION;
|
||||
}
|
||||
|
||||
extern "C" lzham_z_ulong LZHAM_DLL_EXPORT lzham_z_adler32(lzham_z_ulong adler, const unsigned char *ptr, size_t buf_len)
|
||||
{
|
||||
return lzham::lzham_lib_z_adler32(adler, ptr, buf_len);
|
||||
}
|
||||
|
||||
extern "C" lzham_z_ulong LZHAM_DLL_EXPORT lzham_z_crc32(lzham_z_ulong crc, const lzham_uint8 *ptr, size_t buf_len)
|
||||
{
|
||||
return lzham::lzham_lib_z_crc32(crc, ptr, buf_len);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_deflateInit(lzham_z_streamp pStream, int level)
|
||||
{
|
||||
return lzham::lzham_lib_z_deflateInit(pStream, level);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_deflateInit2(lzham_z_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
|
||||
{
|
||||
return lzham::lzham_lib_z_deflateInit2(pStream, level, method, window_bits, mem_level, strategy);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_deflateReset(lzham_z_streamp pStream)
|
||||
{
|
||||
return lzham::lzham_lib_z_deflateReset(pStream);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_deflate(lzham_z_streamp pStream, int flush)
|
||||
{
|
||||
return lzham::lzham_lib_z_deflate(pStream, flush);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_deflateEnd(lzham_z_streamp pStream)
|
||||
{
|
||||
return lzham::lzham_lib_z_deflateEnd(pStream);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_z_ulong lzham_z_deflateBound(lzham_z_streamp pStream, lzham_z_ulong source_len)
|
||||
{
|
||||
return lzham::lzham_lib_z_deflateBound(pStream, source_len);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_compress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len)
|
||||
{
|
||||
return lzham::lzham_lib_z_compress(pDest, pDest_len, pSource, source_len);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_compress2(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len, int level)
|
||||
{
|
||||
return lzham::lzham_lib_z_compress2(pDest, pDest_len, pSource, source_len, level);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT lzham_z_ulong lzham_z_compressBound(lzham_z_ulong source_len)
|
||||
{
|
||||
return lzham::lzham_lib_z_compressBound(source_len);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_inflateInit(lzham_z_streamp pStream)
|
||||
{
|
||||
return lzham::lzham_lib_z_inflateInit(pStream);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_inflateInit2(lzham_z_streamp pStream, int window_bits)
|
||||
{
|
||||
return lzham::lzham_lib_z_inflateInit2(pStream, window_bits);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_inflateReset(lzham_z_streamp pStream)
|
||||
{
|
||||
return lzham::lzham_lib_z_inflateReset(pStream);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_inflate(lzham_z_streamp pStream, int flush)
|
||||
{
|
||||
return lzham::lzham_lib_z_inflate(pStream, flush);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_inflateEnd(lzham_z_streamp pStream)
|
||||
{
|
||||
return lzham::lzham_lib_z_inflateEnd(pStream);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT int lzham_z_uncompress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len)
|
||||
{
|
||||
return lzham::lzham_lib_z_uncompress(pDest, pDest_len, pSource, source_len);
|
||||
}
|
||||
|
||||
extern "C" LZHAM_DLL_EXPORT const char *lzham_z_error(int err)
|
||||
{
|
||||
return lzham::lzham_lib_z_error(err);
|
||||
}
|
66
r5dev/thirdparty/lzham/lzham_assert.cpp
vendored
Normal file
66
r5dev/thirdparty/lzham/lzham_assert.cpp
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
// File: lzham_assert.cpp
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#include "include/lzham_core.h"
|
||||
|
||||
static bool g_fail_exceptions;
|
||||
static bool g_exit_on_failure = true;
|
||||
|
||||
void lzham_enable_fail_exceptions(bool enabled)
|
||||
{
|
||||
g_fail_exceptions = enabled;
|
||||
}
|
||||
|
||||
void lzham_assert(const char* pExp, const char* pFile, unsigned line)
|
||||
{
|
||||
char buf[512];
|
||||
|
||||
sprintf_s(buf, sizeof(buf), "%s(%u): Assertion failed: \"%s\"\n", pFile, line, pExp);
|
||||
|
||||
lzham_output_debug_string(buf);
|
||||
|
||||
printf("%s", buf);
|
||||
|
||||
if (lzham_is_debugger_present())
|
||||
lzham_debug_break();
|
||||
}
|
||||
|
||||
void lzham_fail(const char* pExp, const char* pFile, unsigned line)
|
||||
{
|
||||
char buf[512];
|
||||
|
||||
sprintf_s(buf, sizeof(buf), "%s(%u): Failure: \"%s\"\n", pFile, line, pExp);
|
||||
|
||||
lzham_output_debug_string(buf);
|
||||
|
||||
printf("%s", buf);
|
||||
|
||||
if (lzham_is_debugger_present())
|
||||
lzham_debug_break();
|
||||
|
||||
#if LZHAM_USE_WIN32_API
|
||||
if (g_fail_exceptions)
|
||||
RaiseException(LZHAM_FAIL_EXCEPTION_CODE, 0, 0, NULL);
|
||||
else
|
||||
#endif
|
||||
if (g_exit_on_failure)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void lzham_trace(const char* pFmt, va_list args)
|
||||
{
|
||||
if (lzham_is_debugger_present())
|
||||
{
|
||||
char buf[512];
|
||||
vsprintf_s(buf, sizeof(buf), pFmt, args);
|
||||
|
||||
lzham_output_debug_string(buf);
|
||||
}
|
||||
};
|
||||
|
||||
void lzham_trace(const char* pFmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, pFmt);
|
||||
lzham_trace(pFmt, args);
|
||||
va_end(args);
|
||||
};
|
73
r5dev/thirdparty/lzham/lzham_checksum.cpp
vendored
Normal file
73
r5dev/thirdparty/lzham/lzham_checksum.cpp
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
// File: lzham_checksum.cpp
|
||||
#include "include/lzham_core.h"
|
||||
#include "include/lzham_checksum.h"
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
// Originally from the public domain stb.h header.
|
||||
uint adler32(const void* pBuf, size_t buflen, uint adler32)
|
||||
{
|
||||
if (!pBuf)
|
||||
return cInitAdler32;
|
||||
|
||||
const uint8* buffer = static_cast<const uint8*>(pBuf);
|
||||
|
||||
const unsigned long ADLER_MOD = 65521;
|
||||
unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
|
||||
size_t blocklen;
|
||||
unsigned long i;
|
||||
|
||||
blocklen = buflen % 5552;
|
||||
while (buflen)
|
||||
{
|
||||
for (i=0; i + 7 < blocklen; i += 8)
|
||||
{
|
||||
s1 += buffer[0], s2 += s1;
|
||||
s1 += buffer[1], s2 += s1;
|
||||
s1 += buffer[2], s2 += s1;
|
||||
s1 += buffer[3], s2 += s1;
|
||||
s1 += buffer[4], s2 += s1;
|
||||
s1 += buffer[5], s2 += s1;
|
||||
s1 += buffer[6], s2 += s1;
|
||||
s1 += buffer[7], s2 += s1;
|
||||
|
||||
buffer += 8;
|
||||
}
|
||||
|
||||
for (; i < blocklen; ++i)
|
||||
s1 += *buffer++, s2 += s1;
|
||||
|
||||
s1 %= ADLER_MOD, s2 %= ADLER_MOD;
|
||||
buflen -= blocklen;
|
||||
blocklen = 5552;
|
||||
}
|
||||
return (s2 << 16) + s1;
|
||||
}
|
||||
|
||||
// Karl Malbrain's compact CRC-32, with pre and post conditioning.
|
||||
// See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed":
|
||||
// http://www.geocities.com/malbrain/
|
||||
static const lzham_uint32 s_crc32[16] =
|
||||
{
|
||||
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
||||
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
|
||||
};
|
||||
|
||||
uint crc32(uint crc, const lzham_uint8 *ptr, size_t buf_len)
|
||||
{
|
||||
if (!ptr)
|
||||
return cInitCRC32;
|
||||
|
||||
crc = ~crc;
|
||||
while (buf_len--)
|
||||
{
|
||||
lzham_uint8 b = *ptr++;
|
||||
crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b & 0xF)];
|
||||
crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b >> 4)];
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
|
||||
} // namespace lzham
|
||||
|
390
r5dev/thirdparty/lzham/lzham_huffman_codes.cpp
vendored
Normal file
390
r5dev/thirdparty/lzham/lzham_huffman_codes.cpp
vendored
Normal file
@ -0,0 +1,390 @@
|
||||
// File: huffman_codes.cpp
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#include "include/lzham_core.h"
|
||||
#include "include/lzham_huffman_codes.h"
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
struct sym_freq
|
||||
{
|
||||
uint m_freq;
|
||||
uint16 m_left;
|
||||
uint16 m_right;
|
||||
|
||||
inline bool operator< (const sym_freq& other) const
|
||||
{
|
||||
return m_freq > other.m_freq;
|
||||
}
|
||||
};
|
||||
|
||||
static inline sym_freq* radix_sort_syms(uint num_syms, sym_freq* syms0, sym_freq* syms1)
|
||||
{
|
||||
const uint cMaxPasses = 2;
|
||||
uint hist[256 * cMaxPasses];
|
||||
|
||||
memset(hist, 0, sizeof(hist[0]) * 256 * cMaxPasses);
|
||||
|
||||
{
|
||||
sym_freq* p = syms0;
|
||||
sym_freq* q = syms0 + (num_syms >> 1) * 2;
|
||||
|
||||
for ( ; p != q; p += 2)
|
||||
{
|
||||
const uint freq0 = p[0].m_freq;
|
||||
const uint freq1 = p[1].m_freq;
|
||||
|
||||
hist[ freq0 & 0xFF]++;
|
||||
hist[256 + ((freq0 >> 8) & 0xFF)]++;
|
||||
|
||||
hist[ freq1 & 0xFF]++;
|
||||
hist[256 + ((freq1 >> 8) & 0xFF)]++;
|
||||
}
|
||||
|
||||
if (num_syms & 1)
|
||||
{
|
||||
const uint freq = p->m_freq;
|
||||
|
||||
hist[ freq & 0xFF]++;
|
||||
hist[256 + ((freq >> 8) & 0xFF)]++;
|
||||
}
|
||||
}
|
||||
|
||||
sym_freq* pCur_syms = syms0;
|
||||
sym_freq* pNew_syms = syms1;
|
||||
|
||||
const uint total_passes = (hist[256] == num_syms) ? 1 : cMaxPasses;
|
||||
|
||||
for (uint pass = 0; pass < total_passes; pass++)
|
||||
{
|
||||
const uint* pHist = &hist[pass << 8];
|
||||
|
||||
uint offsets[256];
|
||||
|
||||
uint cur_ofs = 0;
|
||||
for (uint i = 0; i < 256; i += 2)
|
||||
{
|
||||
offsets[i] = cur_ofs;
|
||||
cur_ofs += pHist[i];
|
||||
|
||||
offsets[i+1] = cur_ofs;
|
||||
cur_ofs += pHist[i+1];
|
||||
}
|
||||
|
||||
const uint pass_shift = pass << 3;
|
||||
|
||||
sym_freq* p = pCur_syms;
|
||||
sym_freq* q = pCur_syms + (num_syms >> 1) * 2;
|
||||
|
||||
for ( ; p != q; p += 2)
|
||||
{
|
||||
uint c0 = p[0].m_freq;
|
||||
uint c1 = p[1].m_freq;
|
||||
|
||||
if (pass)
|
||||
{
|
||||
c0 >>= 8;
|
||||
c1 >>= 8;
|
||||
}
|
||||
|
||||
c0 &= 0xFF;
|
||||
c1 &= 0xFF;
|
||||
|
||||
if (c0 == c1)
|
||||
{
|
||||
uint dst_offset0 = offsets[c0];
|
||||
|
||||
offsets[c0] = dst_offset0 + 2;
|
||||
|
||||
pNew_syms[dst_offset0] = p[0];
|
||||
pNew_syms[dst_offset0 + 1] = p[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint dst_offset0 = offsets[c0]++;
|
||||
uint dst_offset1 = offsets[c1]++;
|
||||
|
||||
pNew_syms[dst_offset0] = p[0];
|
||||
pNew_syms[dst_offset1] = p[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (num_syms & 1)
|
||||
{
|
||||
uint c = ((p->m_freq) >> pass_shift) & 0xFF;
|
||||
|
||||
uint dst_offset = offsets[c];
|
||||
offsets[c] = dst_offset + 1;
|
||||
|
||||
pNew_syms[dst_offset] = *p;
|
||||
}
|
||||
|
||||
sym_freq* t = pCur_syms;
|
||||
pCur_syms = pNew_syms;
|
||||
pNew_syms = t;
|
||||
}
|
||||
|
||||
#if LZHAM_ASSERTS_ENABLED
|
||||
uint prev_freq = 0;
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
LZHAM_ASSERT(!(pCur_syms[i].m_freq < prev_freq));
|
||||
prev_freq = pCur_syms[i].m_freq;
|
||||
}
|
||||
#endif
|
||||
|
||||
return pCur_syms;
|
||||
}
|
||||
|
||||
struct huffman_work_tables
|
||||
{
|
||||
enum { cMaxInternalNodes = cHuffmanMaxSupportedSyms };
|
||||
|
||||
sym_freq syms0[cHuffmanMaxSupportedSyms + 1 + cMaxInternalNodes];
|
||||
sym_freq syms1[cHuffmanMaxSupportedSyms + 1 + cMaxInternalNodes];
|
||||
|
||||
#if !USE_CALCULATE_MINIMUM_REDUNDANCY
|
||||
uint16 queue[cMaxInternalNodes];
|
||||
#endif
|
||||
};
|
||||
|
||||
uint get_generate_huffman_codes_table_size()
|
||||
{
|
||||
return sizeof(huffman_work_tables);
|
||||
}
|
||||
|
||||
#define USE_CALCULATE_MINIMUM_REDUNDANCY 1
|
||||
#if USE_CALCULATE_MINIMUM_REDUNDANCY
|
||||
/* calculate_minimum_redundancy() written by
|
||||
Alistair Moffat, alistair@cs.mu.oz.au,
|
||||
Jyrki Katajainen, jyrki@diku.dk
|
||||
November 1996.
|
||||
*/
|
||||
static void calculate_minimum_redundancy(int A[], int n) {
|
||||
int root; /* next root node to be used */
|
||||
int leaf; /* next leaf to be used */
|
||||
int next; /* next value to be assigned */
|
||||
int avbl; /* number of available nodes */
|
||||
int used; /* number of internal nodes */
|
||||
int dpth; /* current depth of leaves */
|
||||
|
||||
/* check for pathological cases */
|
||||
if (n==0) { return; }
|
||||
if (n==1) { A[0] = 0; return; }
|
||||
|
||||
/* first pass, left to right, setting parent pointers */
|
||||
A[0] += A[1]; root = 0; leaf = 2;
|
||||
for (next=1; next < n-1; next++) {
|
||||
/* select first item for a pairing */
|
||||
if (leaf>=n || A[root]<A[leaf]) {
|
||||
A[next] = A[root]; A[root++] = next;
|
||||
} else
|
||||
A[next] = A[leaf++];
|
||||
|
||||
/* add on the second item */
|
||||
if (leaf>=n || (root<next && A[root]<A[leaf])) {
|
||||
A[next] += A[root]; A[root++] = next;
|
||||
} else
|
||||
A[next] += A[leaf++];
|
||||
}
|
||||
|
||||
/* second pass, right to left, setting internal depths */
|
||||
A[n-2] = 0;
|
||||
for (next=n-3; next>=0; next--)
|
||||
A[next] = A[A[next]]+1;
|
||||
|
||||
/* third pass, right to left, setting leaf depths */
|
||||
avbl = 1; used = dpth = 0; root = n-2; next = n-1;
|
||||
while (avbl>0) {
|
||||
while (root>=0 && A[root]==dpth) {
|
||||
used++; root--;
|
||||
}
|
||||
while (avbl>used) {
|
||||
A[next--] = dpth; avbl--;
|
||||
}
|
||||
avbl = 2*used; dpth++; used = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool generate_huffman_codes(void* pContext, uint num_syms, const uint16* pFreq, uint8* pCodesizes, uint& max_code_size, uint& total_freq_ret)
|
||||
{
|
||||
if ((!num_syms) || (num_syms > cHuffmanMaxSupportedSyms))
|
||||
return false;
|
||||
|
||||
huffman_work_tables& state = *static_cast<huffman_work_tables*>(pContext);;
|
||||
|
||||
uint max_freq = 0;
|
||||
uint total_freq = 0;
|
||||
|
||||
uint num_used_syms = 0;
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint freq = pFreq[i];
|
||||
|
||||
if (!freq)
|
||||
pCodesizes[i] = 0;
|
||||
else
|
||||
{
|
||||
total_freq += freq;
|
||||
max_freq = math::maximum(max_freq, freq);
|
||||
|
||||
sym_freq& sf = state.syms0[num_used_syms];
|
||||
sf.m_left = (uint16)i;
|
||||
sf.m_right = UINT16_MAX;
|
||||
sf.m_freq = freq;
|
||||
num_used_syms++;
|
||||
}
|
||||
}
|
||||
|
||||
total_freq_ret = total_freq;
|
||||
|
||||
if (num_used_syms == 1)
|
||||
{
|
||||
pCodesizes[state.syms0[0].m_left] = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
sym_freq* syms = radix_sort_syms(num_used_syms, state.syms0, state.syms1);
|
||||
|
||||
#if USE_CALCULATE_MINIMUM_REDUNDANCY
|
||||
int x[cHuffmanMaxSupportedSyms];
|
||||
for (uint i = 0; i < num_used_syms; i++)
|
||||
x[i] = syms[i].m_freq;
|
||||
|
||||
calculate_minimum_redundancy(x, num_used_syms);
|
||||
|
||||
uint max_len = 0;
|
||||
for (uint i = 0; i < num_used_syms; i++)
|
||||
{
|
||||
uint len = x[i];
|
||||
max_len = math::maximum(len, max_len);
|
||||
pCodesizes[syms[i].m_left] = static_cast<uint8>(len);
|
||||
}
|
||||
max_code_size = max_len;
|
||||
#else
|
||||
// Computes Huffman codelengths in linear time. More readable than calculate_minimum_redundancy(), and approximately the same speed, but not in-place.
|
||||
|
||||
// Dummy node
|
||||
sym_freq& sf = state.syms0[num_used_syms];
|
||||
sf.m_left = UINT16_MAX;
|
||||
sf.m_right = UINT16_MAX;
|
||||
sf.m_freq = UINT_MAX;
|
||||
|
||||
uint next_internal_node = num_used_syms + 1;
|
||||
|
||||
uint queue_front = 0;
|
||||
uint queue_end = 0;
|
||||
|
||||
uint next_lowest_sym = 0;
|
||||
|
||||
uint num_nodes_remaining = num_used_syms;
|
||||
do
|
||||
{
|
||||
uint left_freq = syms[next_lowest_sym].m_freq;
|
||||
uint left_child = next_lowest_sym;
|
||||
|
||||
if ((queue_end > queue_front) && (syms[state.queue[queue_front]].m_freq < left_freq))
|
||||
{
|
||||
left_child = state.queue[queue_front];
|
||||
left_freq = syms[left_child].m_freq;
|
||||
|
||||
queue_front++;
|
||||
}
|
||||
else
|
||||
next_lowest_sym++;
|
||||
|
||||
uint right_freq = syms[next_lowest_sym].m_freq;
|
||||
uint right_child = next_lowest_sym;
|
||||
|
||||
if ((queue_end > queue_front) && (syms[state.queue[queue_front]].m_freq < right_freq))
|
||||
{
|
||||
right_child = state.queue[queue_front];
|
||||
right_freq = syms[right_child].m_freq;
|
||||
|
||||
queue_front++;
|
||||
}
|
||||
else
|
||||
next_lowest_sym++;
|
||||
|
||||
LZHAM_ASSERT(next_internal_node < huffman_work_tables::cMaxInternalNodes);
|
||||
|
||||
const uint internal_node_index = next_internal_node;
|
||||
next_internal_node++;
|
||||
|
||||
syms[internal_node_index].m_freq = left_freq + right_freq;
|
||||
syms[internal_node_index].m_left = static_cast<uint16>(left_child);
|
||||
syms[internal_node_index].m_right = static_cast<uint16>(right_child);
|
||||
|
||||
LZHAM_ASSERT(queue_end < huffman_work_tables::cMaxInternalNodes);
|
||||
state.queue[queue_end] = static_cast<uint16>(internal_node_index);
|
||||
queue_end++;
|
||||
|
||||
num_nodes_remaining--;
|
||||
|
||||
} while (num_nodes_remaining > 1);
|
||||
|
||||
LZHAM_ASSERT(next_lowest_sym == num_used_syms);
|
||||
LZHAM_ASSERT((queue_end - queue_front) == 1);
|
||||
|
||||
uint cur_node_index = state.queue[queue_front];
|
||||
|
||||
uint32* pStack = (syms == state.syms0) ? (uint32*)state.syms1 : (uint32*)state.syms0;
|
||||
uint32* pStack_top = pStack;
|
||||
|
||||
uint max_level = 0;
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
uint level = cur_node_index >> 16;
|
||||
uint node_index = cur_node_index & 0xFFFF;
|
||||
|
||||
uint left_child = syms[node_index].m_left;
|
||||
uint right_child = syms[node_index].m_right;
|
||||
|
||||
uint next_level = (cur_node_index + 0x10000) & 0xFFFF0000;
|
||||
|
||||
if (left_child < num_used_syms)
|
||||
{
|
||||
max_level = math::maximum(max_level, level);
|
||||
|
||||
pCodesizes[syms[left_child].m_left] = static_cast<uint8>(level + 1);
|
||||
|
||||
if (right_child < num_used_syms)
|
||||
{
|
||||
pCodesizes[syms[right_child].m_left] = static_cast<uint8>(level + 1);
|
||||
|
||||
if (pStack == pStack_top) break;
|
||||
cur_node_index = *--pStack;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_node_index = next_level | right_child;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (right_child < num_used_syms)
|
||||
{
|
||||
max_level = math::maximum(max_level, level);
|
||||
|
||||
pCodesizes[syms[right_child].m_left] = static_cast<uint8>(level + 1);
|
||||
|
||||
cur_node_index = next_level | left_child;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pStack++ = next_level | left_child;
|
||||
|
||||
cur_node_index = next_level | right_child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
max_code_size = max_level + 1;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace lzham
|
||||
|
71
r5dev/thirdparty/lzham/lzham_lzbase.cpp
vendored
Normal file
71
r5dev/thirdparty/lzham/lzham_lzbase.cpp
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
// File: lzham_lzbase.cpp
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#include "include/lzham_core.h"
|
||||
#include "include/lzham_lzbase.h"
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
void CLZBase::init_slot_tabs()
|
||||
{
|
||||
for (uint i = 0; i < m_num_lzx_slots; i++)
|
||||
{
|
||||
//printf("%u: 0x%08X - 0x%08X, %u\n", i, m_lzx_position_base[i], m_lzx_position_base[i] + (1 << m_lzx_position_extra_bits[i]) - 1, m_lzx_position_extra_bits[i]);
|
||||
|
||||
uint lo = m_lzx_position_base[i];
|
||||
uint hi = lo + m_lzx_position_extra_mask[i];
|
||||
|
||||
uint8* pTab;
|
||||
uint shift;
|
||||
uint n; LZHAM_NOTE_UNUSED(n);
|
||||
|
||||
if (hi < 0x1000)
|
||||
{
|
||||
pTab = m_slot_tab0;
|
||||
shift = 0;
|
||||
n = sizeof(m_slot_tab0);
|
||||
}
|
||||
else if (hi < 0x100000)
|
||||
{
|
||||
pTab = m_slot_tab1;
|
||||
shift = 11;
|
||||
n = sizeof(m_slot_tab1);
|
||||
}
|
||||
else if (hi < 0x1000000)
|
||||
{
|
||||
pTab = m_slot_tab2;
|
||||
shift = 16;
|
||||
n = sizeof(m_slot_tab2);
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
lo >>= shift;
|
||||
hi >>= shift;
|
||||
|
||||
LZHAM_ASSERT(hi < n);
|
||||
memset(pTab + lo, (uint8)i, hi - lo + 1);
|
||||
}
|
||||
|
||||
#ifdef LZHAM_BUILD_DEBUG
|
||||
uint slot, ofs;
|
||||
for (uint i = 1; i < m_num_lzx_slots; i++)
|
||||
{
|
||||
compute_lzx_position_slot(m_lzx_position_base[i], slot, ofs);
|
||||
LZHAM_ASSERT(slot == i);
|
||||
|
||||
compute_lzx_position_slot(m_lzx_position_base[i] + m_lzx_position_extra_mask[i], slot, ofs);
|
||||
LZHAM_ASSERT(slot == i);
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= (m_dict_size-1); i += 512U*1024U)
|
||||
{
|
||||
compute_lzx_position_slot(i, slot, ofs);
|
||||
LZHAM_ASSERT(i == m_lzx_position_base[slot] + ofs);
|
||||
}
|
||||
|
||||
compute_lzx_position_slot(m_dict_size - 1, slot, ofs);
|
||||
LZHAM_ASSERT((m_dict_size - 1) == m_lzx_position_base[slot] + ofs);
|
||||
#endif
|
||||
}
|
||||
} //namespace lzham
|
||||
|
562
r5dev/thirdparty/lzham/lzham_match_accel.cpp
vendored
Normal file
562
r5dev/thirdparty/lzham/lzham_match_accel.cpp
vendored
Normal file
@ -0,0 +1,562 @@
|
||||
// File: lzham_match_accel.cpp
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#include "include/lzham_core.h"
|
||||
#include "include/lzham_match_accel.h"
|
||||
#include "include/lzham_timer.h"
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
static inline uint32 hash2_to_12(uint c0, uint c1)
|
||||
{
|
||||
return c0 ^ (c1 << 4);
|
||||
}
|
||||
|
||||
static inline uint32 hash3_to_16(uint c0, uint c1, uint c2)
|
||||
{
|
||||
return (c0 | (c1 << 8)) ^ (c2 << 4);
|
||||
}
|
||||
|
||||
search_accelerator::search_accelerator() :
|
||||
m_pLZBase(NULL),
|
||||
m_pTask_pool(NULL),
|
||||
m_max_helper_threads(0),
|
||||
m_max_dict_size(0),
|
||||
m_max_dict_size_mask(0),
|
||||
m_lookahead_pos(0),
|
||||
m_lookahead_size(0),
|
||||
m_cur_dict_size(0),
|
||||
m_fill_lookahead_pos(0),
|
||||
m_fill_lookahead_size(0),
|
||||
m_fill_dict_size(0),
|
||||
m_max_probes(0),
|
||||
m_max_matches(0),
|
||||
m_all_matches(false),
|
||||
m_next_match_ref(0),
|
||||
m_num_completed_helper_threads(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool search_accelerator::init(CLZBase* pLZBase, task_pool* pPool, uint max_helper_threads, uint max_dict_size, uint max_matches, bool all_matches, uint max_probes)
|
||||
{
|
||||
LZHAM_ASSERT(pLZBase);
|
||||
LZHAM_ASSERT(max_dict_size && math::is_power_of_2(max_dict_size));
|
||||
LZHAM_ASSERT(max_probes);
|
||||
|
||||
m_max_probes = LZHAM_MIN(cMatchAccelMaxSupportedProbes, max_probes);
|
||||
|
||||
m_pLZBase = pLZBase;
|
||||
m_pTask_pool = max_helper_threads ? pPool : NULL;
|
||||
m_max_helper_threads = m_pTask_pool ? max_helper_threads : 0;
|
||||
m_max_matches = LZHAM_MIN(m_max_probes, max_matches);
|
||||
m_all_matches = all_matches;
|
||||
|
||||
m_max_dict_size = max_dict_size;
|
||||
m_max_dict_size_mask = m_max_dict_size - 1;
|
||||
m_cur_dict_size = 0;
|
||||
m_lookahead_size = 0;
|
||||
m_lookahead_pos = 0;
|
||||
m_fill_lookahead_pos = 0;
|
||||
m_fill_lookahead_size = 0;
|
||||
m_fill_dict_size = 0;
|
||||
m_num_completed_helper_threads = 0;
|
||||
|
||||
if (!m_dict.try_resize_no_construct(max_dict_size + LZHAM_MIN(m_max_dict_size, static_cast<uint>(CLZBase::cMaxHugeMatchLen))))
|
||||
return false;
|
||||
|
||||
if (!m_hash.try_resize_no_construct(cHashSize))
|
||||
return false;
|
||||
|
||||
if (!m_nodes.try_resize_no_construct(max_dict_size))
|
||||
return false;
|
||||
|
||||
memset(m_hash.get_ptr(), 0, m_hash.size_in_bytes());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void search_accelerator::reset()
|
||||
{
|
||||
m_cur_dict_size = 0;
|
||||
m_lookahead_size = 0;
|
||||
m_lookahead_pos = 0;
|
||||
m_fill_lookahead_pos = 0;
|
||||
m_fill_lookahead_size = 0;
|
||||
m_fill_dict_size = 0;
|
||||
m_num_completed_helper_threads = 0;
|
||||
|
||||
// Clearing the hash tables is only necessary for determinism (otherwise, it's possible the matches returned after a reset will depend on the data processes before the reset).
|
||||
if (m_hash.size())
|
||||
memset(m_hash.get_ptr(), 0, m_hash.size_in_bytes());
|
||||
if (m_digram_hash.size())
|
||||
memset(m_digram_hash.get_ptr(), 0, m_digram_hash.size_in_bytes());
|
||||
}
|
||||
|
||||
void search_accelerator::flush()
|
||||
{
|
||||
m_cur_dict_size = 0;
|
||||
}
|
||||
|
||||
uint search_accelerator::get_max_add_bytes() const
|
||||
{
|
||||
uint add_pos = static_cast<uint>(m_lookahead_pos & (m_max_dict_size - 1));
|
||||
return m_max_dict_size - add_pos;
|
||||
}
|
||||
|
||||
static uint8 g_hamming_dist[256] =
|
||||
{
|
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
|
||||
};
|
||||
|
||||
void search_accelerator::find_all_matches_callback(uint64 data, void* pData_ptr)
|
||||
{
|
||||
scoped_perf_section find_all_matches_timer("find_all_matches_callback");
|
||||
|
||||
LZHAM_NOTE_UNUSED(pData_ptr);
|
||||
const uint thread_index = (uint)data;
|
||||
|
||||
dict_match temp_matches[cMatchAccelMaxSupportedProbes * 2];
|
||||
|
||||
uint fill_lookahead_pos = m_fill_lookahead_pos;
|
||||
uint fill_dict_size = m_fill_dict_size;
|
||||
uint fill_lookahead_size = m_fill_lookahead_size;
|
||||
|
||||
uint c0 = 0, c1 = 0;
|
||||
if (fill_lookahead_size >= 2)
|
||||
{
|
||||
c0 = m_dict[fill_lookahead_pos & m_max_dict_size_mask];
|
||||
c1 = m_dict[(fill_lookahead_pos & m_max_dict_size_mask) + 1];
|
||||
}
|
||||
|
||||
const uint8* pDict = m_dict.get_ptr();
|
||||
|
||||
while (fill_lookahead_size >= 3)
|
||||
{
|
||||
uint insert_pos = fill_lookahead_pos & m_max_dict_size_mask;
|
||||
|
||||
uint c2 = pDict[insert_pos + 2];
|
||||
uint h = hash3_to_16(c0, c1, c2);
|
||||
c0 = c1;
|
||||
c1 = c2;
|
||||
|
||||
LZHAM_ASSERT(!m_hash_thread_index.size() || (m_hash_thread_index[h] != UINT8_MAX));
|
||||
|
||||
// Only process those strings that this worker thread was assigned to - this allows us to manipulate multiple trees in parallel with no worries about synchronization.
|
||||
if (m_hash_thread_index.size() && (m_hash_thread_index[h] != thread_index))
|
||||
{
|
||||
fill_lookahead_pos++;
|
||||
fill_lookahead_size--;
|
||||
fill_dict_size++;
|
||||
continue;
|
||||
}
|
||||
|
||||
dict_match* pDstMatch = temp_matches;
|
||||
|
||||
uint cur_pos = m_hash[h];
|
||||
m_hash[h] = static_cast<uint>(fill_lookahead_pos);
|
||||
|
||||
uint *pLeft = &m_nodes[insert_pos].m_left;
|
||||
uint *pRight = &m_nodes[insert_pos].m_right;
|
||||
|
||||
const uint max_match_len = LZHAM_MIN(static_cast<uint>(CLZBase::cMaxMatchLen), fill_lookahead_size);
|
||||
uint best_match_len = 2;
|
||||
|
||||
const uint8* pIns = &pDict[insert_pos];
|
||||
|
||||
uint n = m_max_probes;
|
||||
for ( ; ; )
|
||||
{
|
||||
uint delta_pos = fill_lookahead_pos - cur_pos;
|
||||
if ((n-- == 0) || (!delta_pos) || (delta_pos >= fill_dict_size))
|
||||
{
|
||||
*pLeft = 0;
|
||||
*pRight = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
uint pos = cur_pos & m_max_dict_size_mask;
|
||||
node *pNode = &m_nodes[pos];
|
||||
|
||||
// Unfortunately, the initial compare match_len must be 0 because of the way we hash and truncate matches at the end of each block.
|
||||
uint match_len = 0;
|
||||
const uint8* pComp = &pDict[pos];
|
||||
|
||||
#if LZHAM_PLATFORM_X360
|
||||
for ( ; match_len < max_match_len; match_len++)
|
||||
if (pComp[match_len] != pIns[match_len])
|
||||
break;
|
||||
#else
|
||||
// Compare a qword at a time for a bit more efficiency.
|
||||
const uint64* pComp_end = reinterpret_cast<const uint64*>(pComp + max_match_len - 7);
|
||||
const uint64* pComp_cur = reinterpret_cast<const uint64*>(pComp);
|
||||
const uint64* pIns_cur = reinterpret_cast<const uint64*>(pIns);
|
||||
while (pComp_cur < pComp_end)
|
||||
{
|
||||
if (*pComp_cur != *pIns_cur)
|
||||
break;
|
||||
pComp_cur++;
|
||||
pIns_cur++;
|
||||
}
|
||||
uint alt_match_len = static_cast<uint>(reinterpret_cast<const uint8*>(pComp_cur) - reinterpret_cast<const uint8*>(pComp));
|
||||
for ( ; alt_match_len < max_match_len; alt_match_len++)
|
||||
if (pComp[alt_match_len] != pIns[alt_match_len])
|
||||
break;
|
||||
#ifdef LZVERIFY
|
||||
for ( ; match_len < max_match_len; match_len++)
|
||||
if (pComp[match_len] != pIns[match_len])
|
||||
break;
|
||||
LZHAM_VERIFY(alt_match_len == match_len);
|
||||
#endif
|
||||
match_len = alt_match_len;
|
||||
#endif
|
||||
|
||||
if (match_len > best_match_len)
|
||||
{
|
||||
pDstMatch->m_len = static_cast<uint16>(match_len - CLZBase::cMinMatchLen);
|
||||
pDstMatch->m_dist = delta_pos;
|
||||
pDstMatch++;
|
||||
|
||||
best_match_len = match_len;
|
||||
|
||||
if (match_len == max_match_len)
|
||||
{
|
||||
*pLeft = pNode->m_left;
|
||||
*pRight = pNode->m_right;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (m_all_matches)
|
||||
{
|
||||
pDstMatch->m_len = static_cast<uint16>(match_len - CLZBase::cMinMatchLen);
|
||||
pDstMatch->m_dist = delta_pos;
|
||||
pDstMatch++;
|
||||
}
|
||||
else if ((best_match_len > 2) && (best_match_len == match_len))
|
||||
{
|
||||
uint bestMatchDist = pDstMatch[-1].m_dist;
|
||||
uint compMatchDist = delta_pos;
|
||||
|
||||
uint bestMatchSlot, bestMatchSlotOfs;
|
||||
m_pLZBase->compute_lzx_position_slot(bestMatchDist, bestMatchSlot, bestMatchSlotOfs);
|
||||
|
||||
uint compMatchSlot, compMatchOfs;
|
||||
m_pLZBase->compute_lzx_position_slot(compMatchDist, compMatchSlot, compMatchOfs);
|
||||
|
||||
// If both matches uses the same match slot, choose the one with the offset containing the lowest nibble as these bits separately entropy coded.
|
||||
// This could choose a match which is further away in the absolute sense, but closer in a coding sense.
|
||||
if ( (compMatchSlot < bestMatchSlot) ||
|
||||
((compMatchSlot >= 8) && (compMatchSlot == bestMatchSlot) && ((compMatchOfs & 15) < (bestMatchSlotOfs & 15))) )
|
||||
{
|
||||
LZHAM_ASSERT((pDstMatch[-1].m_len + (uint)CLZBase::cMinMatchLen) == best_match_len);
|
||||
pDstMatch[-1].m_dist = delta_pos;
|
||||
}
|
||||
else if ((match_len < max_match_len) && (compMatchSlot <= bestMatchSlot))
|
||||
{
|
||||
// Choose the match which has lowest hamming distance in the mismatch byte for a tiny win on binary files.
|
||||
// TODO: This competes against the prev. optimization.
|
||||
uint desired_mismatch_byte = pIns[match_len];
|
||||
|
||||
uint cur_mismatch_byte = pDict[(insert_pos - bestMatchDist + match_len) & m_max_dict_size_mask];
|
||||
uint cur_mismatch_dist = g_hamming_dist[cur_mismatch_byte ^ desired_mismatch_byte];
|
||||
|
||||
uint new_mismatch_byte = pComp[match_len];
|
||||
uint new_mismatch_dist = g_hamming_dist[new_mismatch_byte ^ desired_mismatch_byte];
|
||||
if (new_mismatch_dist < cur_mismatch_dist)
|
||||
{
|
||||
LZHAM_ASSERT((pDstMatch[-1].m_len + (uint)CLZBase::cMinMatchLen) == best_match_len);
|
||||
pDstMatch[-1].m_dist = delta_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint new_pos;
|
||||
if (pComp[match_len] < pIns[match_len])
|
||||
{
|
||||
*pLeft = cur_pos;
|
||||
pLeft = &pNode->m_right;
|
||||
new_pos = pNode->m_right;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pRight = cur_pos;
|
||||
pRight = &pNode->m_left;
|
||||
new_pos = pNode->m_left;
|
||||
}
|
||||
if (new_pos == cur_pos)
|
||||
break;
|
||||
cur_pos = new_pos;
|
||||
}
|
||||
|
||||
const uint num_matches = (uint)(pDstMatch - temp_matches);
|
||||
|
||||
if (num_matches)
|
||||
{
|
||||
pDstMatch[-1].m_dist |= 0x80000000;
|
||||
|
||||
const uint num_matches_to_write = LZHAM_MIN(num_matches, m_max_matches);
|
||||
|
||||
const uint match_ref_ofs = atomic_exchange_add(&m_next_match_ref, num_matches_to_write);
|
||||
|
||||
memcpy(&m_matches[match_ref_ofs],
|
||||
temp_matches + (num_matches - num_matches_to_write),
|
||||
sizeof(temp_matches[0]) * num_matches_to_write);
|
||||
|
||||
// FIXME: This is going to really hurt on platforms requiring export barriers.
|
||||
LZHAM_MEMORY_EXPORT_BARRIER
|
||||
|
||||
atomic_exchange32((atomic32_t*)&m_match_refs[static_cast<uint>(fill_lookahead_pos - m_fill_lookahead_pos)], match_ref_ofs);
|
||||
}
|
||||
else
|
||||
{
|
||||
atomic_exchange32((atomic32_t*)&m_match_refs[static_cast<uint>(fill_lookahead_pos - m_fill_lookahead_pos)], -2);
|
||||
}
|
||||
|
||||
fill_lookahead_pos++;
|
||||
fill_lookahead_size--;
|
||||
fill_dict_size++;
|
||||
}
|
||||
|
||||
while (fill_lookahead_size)
|
||||
{
|
||||
uint insert_pos = fill_lookahead_pos & m_max_dict_size_mask;
|
||||
m_nodes[insert_pos].m_left = 0;
|
||||
m_nodes[insert_pos].m_right = 0;
|
||||
|
||||
atomic_exchange32((atomic32_t*)&m_match_refs[static_cast<uint>(fill_lookahead_pos - m_fill_lookahead_pos)], -2);
|
||||
|
||||
fill_lookahead_pos++;
|
||||
fill_lookahead_size--;
|
||||
fill_dict_size++;
|
||||
}
|
||||
|
||||
atomic_increment32(&m_num_completed_helper_threads);
|
||||
}
|
||||
|
||||
bool search_accelerator::find_len2_matches()
|
||||
{
|
||||
if (!m_digram_hash.size())
|
||||
{
|
||||
if (!m_digram_hash.try_resize(cDigramHashSize))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_digram_next.size() < m_lookahead_size)
|
||||
{
|
||||
if (!m_digram_next.try_resize(m_lookahead_size))
|
||||
return false;
|
||||
}
|
||||
|
||||
uint lookahead_dict_pos = m_lookahead_pos & m_max_dict_size_mask;
|
||||
|
||||
for (int lookahead_ofs = 0; lookahead_ofs < ((int)m_lookahead_size - 1); ++lookahead_ofs, ++lookahead_dict_pos)
|
||||
{
|
||||
uint c0 = m_dict[lookahead_dict_pos];
|
||||
uint c1 = m_dict[lookahead_dict_pos + 1];
|
||||
|
||||
uint h = hash2_to_12(c0, c1) & (cDigramHashSize - 1);
|
||||
|
||||
m_digram_next[lookahead_ofs] = m_digram_hash[h];
|
||||
m_digram_hash[h] = m_lookahead_pos + lookahead_ofs;
|
||||
}
|
||||
|
||||
m_digram_next[m_lookahead_size - 1] = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint search_accelerator::get_len2_match(uint lookahead_ofs)
|
||||
{
|
||||
if ((m_fill_lookahead_size - lookahead_ofs) < 2)
|
||||
return 0;
|
||||
|
||||
uint cur_pos = m_lookahead_pos + lookahead_ofs;
|
||||
|
||||
uint next_match_pos = m_digram_next[cur_pos - m_fill_lookahead_pos];
|
||||
|
||||
uint match_dist = cur_pos - next_match_pos;
|
||||
|
||||
if ((!match_dist) || (match_dist > CLZBase::cMaxLen2MatchDist) || (match_dist > (m_cur_dict_size + lookahead_ofs)))
|
||||
return 0;
|
||||
|
||||
const uint8* pCur = &m_dict[cur_pos & m_max_dict_size_mask];
|
||||
const uint8* pMatch = &m_dict[next_match_pos & m_max_dict_size_mask];
|
||||
|
||||
if ((pCur[0] == pMatch[0]) && (pCur[1] == pMatch[1]))
|
||||
return match_dist;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool search_accelerator::find_all_matches(uint num_bytes)
|
||||
{
|
||||
if (!m_matches.try_resize_no_construct(m_max_probes * num_bytes))
|
||||
return false;
|
||||
|
||||
if (!m_match_refs.try_resize_no_construct(num_bytes))
|
||||
return false;
|
||||
|
||||
memset(m_match_refs.get_ptr(), 0xFF, m_match_refs.size_in_bytes());
|
||||
|
||||
m_fill_lookahead_pos = m_lookahead_pos;
|
||||
m_fill_lookahead_size = num_bytes;
|
||||
m_fill_dict_size = m_cur_dict_size;
|
||||
|
||||
m_next_match_ref = 0;
|
||||
|
||||
if (!m_pTask_pool)
|
||||
{
|
||||
find_all_matches_callback(0, NULL);
|
||||
|
||||
m_num_completed_helper_threads = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_hash_thread_index.try_resize_no_construct(0x10000))
|
||||
return false;
|
||||
|
||||
memset(m_hash_thread_index.get_ptr(), 0xFF, m_hash_thread_index.size_in_bytes());
|
||||
|
||||
uint next_thread_index = 0;
|
||||
const uint8* pDict = &m_dict[m_lookahead_pos & m_max_dict_size_mask];
|
||||
uint num_unique_trigrams = 0;
|
||||
|
||||
if (num_bytes >= 3)
|
||||
{
|
||||
uint c0 = pDict[0];
|
||||
uint c1 = pDict[1];
|
||||
|
||||
const int limit = ((int)num_bytes - 2);
|
||||
for (int i = 0; i < limit; i++)
|
||||
{
|
||||
uint c2 = pDict[2];
|
||||
uint t = hash3_to_16(c0, c1, c2);
|
||||
c0 = c1;
|
||||
c1 = c2;
|
||||
|
||||
pDict++;
|
||||
|
||||
if (m_hash_thread_index[t] == UINT8_MAX)
|
||||
{
|
||||
num_unique_trigrams++;
|
||||
|
||||
m_hash_thread_index[t] = static_cast<uint8>(next_thread_index);
|
||||
if (++next_thread_index == m_max_helper_threads)
|
||||
next_thread_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_num_completed_helper_threads = 0;
|
||||
|
||||
if (!m_pTask_pool->queue_multiple_object_tasks(this, &search_accelerator::find_all_matches_callback, 0, m_max_helper_threads))
|
||||
return false;
|
||||
}
|
||||
|
||||
return find_len2_matches();
|
||||
}
|
||||
|
||||
bool search_accelerator::add_bytes_begin(uint num_bytes, const uint8* pBytes)
|
||||
{
|
||||
LZHAM_ASSERT(num_bytes <= m_max_dict_size);
|
||||
LZHAM_ASSERT(!m_lookahead_size);
|
||||
|
||||
uint add_pos = m_lookahead_pos & m_max_dict_size_mask;
|
||||
LZHAM_ASSERT((add_pos + num_bytes) <= m_max_dict_size);
|
||||
|
||||
memcpy(&m_dict[add_pos], pBytes, num_bytes);
|
||||
|
||||
uint dict_bytes_to_mirror = LZHAM_MIN(static_cast<uint>(CLZBase::cMaxHugeMatchLen), m_max_dict_size);
|
||||
if (add_pos < dict_bytes_to_mirror)
|
||||
memcpy(&m_dict[m_max_dict_size], &m_dict[0], dict_bytes_to_mirror);
|
||||
|
||||
m_lookahead_size = num_bytes;
|
||||
|
||||
uint max_possible_dict_size = m_max_dict_size - num_bytes;
|
||||
m_cur_dict_size = LZHAM_MIN(m_cur_dict_size, max_possible_dict_size);
|
||||
|
||||
m_next_match_ref = 0;
|
||||
|
||||
return find_all_matches(num_bytes);
|
||||
}
|
||||
|
||||
void search_accelerator::add_bytes_end()
|
||||
{
|
||||
if (m_pTask_pool)
|
||||
{
|
||||
m_pTask_pool->join();
|
||||
}
|
||||
|
||||
LZHAM_ASSERT((uint)m_next_match_ref <= m_matches.size());
|
||||
}
|
||||
|
||||
dict_match* search_accelerator::find_matches(uint lookahead_ofs, bool spin)
|
||||
{
|
||||
LZHAM_ASSERT(lookahead_ofs < m_lookahead_size);
|
||||
|
||||
const uint match_ref_ofs = static_cast<uint>(m_lookahead_pos - m_fill_lookahead_pos + lookahead_ofs);
|
||||
|
||||
int match_ref;
|
||||
uint spin_count = 0;
|
||||
|
||||
// This may spin until the match finder job(s) catch up to the caller's lookahead position.
|
||||
for ( ; ; )
|
||||
{
|
||||
match_ref = m_match_refs[match_ref_ofs];
|
||||
if (match_ref == -2)
|
||||
return NULL;
|
||||
else if (match_ref != -1)
|
||||
break;
|
||||
|
||||
spin_count++;
|
||||
const uint cMaxSpinCount = 1000;
|
||||
if ((spin) && (spin_count < cMaxSpinCount))
|
||||
{
|
||||
lzham_yield_processor();
|
||||
lzham_yield_processor();
|
||||
lzham_yield_processor();
|
||||
lzham_yield_processor();
|
||||
lzham_yield_processor();
|
||||
lzham_yield_processor();
|
||||
lzham_yield_processor();
|
||||
lzham_yield_processor();
|
||||
|
||||
LZHAM_MEMORY_IMPORT_BARRIER
|
||||
}
|
||||
else
|
||||
{
|
||||
spin_count = cMaxSpinCount;
|
||||
|
||||
lzham_sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
LZHAM_MEMORY_IMPORT_BARRIER
|
||||
|
||||
return &m_matches[match_ref];
|
||||
}
|
||||
|
||||
void search_accelerator::advance_bytes(uint num_bytes)
|
||||
{
|
||||
LZHAM_ASSERT(num_bytes <= m_lookahead_size);
|
||||
|
||||
m_lookahead_pos += num_bytes;
|
||||
m_lookahead_size -= num_bytes;
|
||||
|
||||
m_cur_dict_size += num_bytes;
|
||||
LZHAM_ASSERT(m_cur_dict_size <= m_max_dict_size);
|
||||
}
|
||||
}
|
272
r5dev/thirdparty/lzham/lzham_mem.cpp
vendored
Normal file
272
r5dev/thirdparty/lzham/lzham_mem.cpp
vendored
Normal file
@ -0,0 +1,272 @@
|
||||
// File: lzham_mem.cpp
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#include "include/lzham_core.h"
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
|
||||
using namespace lzham;
|
||||
|
||||
#define LZHAM_MEM_STATS 0
|
||||
|
||||
#ifndef LZHAM_USE_WIN32_API
|
||||
//#define _msize malloc_usable_size
|
||||
#endif
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
#if LZHAM_64BIT_POINTERS
|
||||
const uint64 MAX_POSSIBLE_BLOCK_SIZE = 0x400000000ULL;
|
||||
#else
|
||||
const uint32 MAX_POSSIBLE_BLOCK_SIZE = 0x7FFF0000U;
|
||||
#endif
|
||||
|
||||
#if LZHAM_MEM_STATS
|
||||
#if LZHAM_64BIT_POINTERS
|
||||
typedef atomic64_t mem_stat_t;
|
||||
#define LZHAM_MEM_COMPARE_EXCHANGE atomic_compare_exchange64
|
||||
#else
|
||||
typedef atomic32_t mem_stat_t;
|
||||
#define LZHAM_MEM_COMPARE_EXCHANGE atomic_compare_exchange32
|
||||
#endif
|
||||
|
||||
static volatile atomic32_t g_total_blocks;
|
||||
static volatile mem_stat_t g_total_allocated;
|
||||
static volatile mem_stat_t g_max_allocated;
|
||||
|
||||
static mem_stat_t update_total_allocated(int block_delta, mem_stat_t byte_delta)
|
||||
{
|
||||
atomic32_t cur_total_blocks;
|
||||
for ( ; ; )
|
||||
{
|
||||
cur_total_blocks = g_total_blocks;
|
||||
atomic32_t new_total_blocks = static_cast<atomic32_t>(cur_total_blocks + block_delta);
|
||||
LZHAM_ASSERT(new_total_blocks >= 0);
|
||||
if (atomic_compare_exchange32(&g_total_blocks, new_total_blocks, cur_total_blocks) == cur_total_blocks)
|
||||
break;
|
||||
}
|
||||
|
||||
mem_stat_t cur_total_allocated, new_total_allocated;
|
||||
for ( ; ; )
|
||||
{
|
||||
cur_total_allocated = g_total_allocated;
|
||||
new_total_allocated = static_cast<mem_stat_t>(cur_total_allocated + byte_delta);
|
||||
LZHAM_ASSERT(new_total_allocated >= 0);
|
||||
if (LZHAM_MEM_COMPARE_EXCHANGE(&g_total_allocated, new_total_allocated, cur_total_allocated) == cur_total_allocated)
|
||||
break;
|
||||
}
|
||||
for ( ; ; )
|
||||
{
|
||||
mem_stat_t cur_max_allocated = g_max_allocated;
|
||||
mem_stat_t new_max_allocated = LZHAM_MAX(new_total_allocated, cur_max_allocated);
|
||||
if (LZHAM_MEM_COMPARE_EXCHANGE(&g_max_allocated, new_max_allocated, cur_max_allocated) == cur_max_allocated)
|
||||
break;
|
||||
}
|
||||
return new_total_allocated;
|
||||
}
|
||||
#endif // LZHAM_MEM_STATS
|
||||
|
||||
static void* lzham_default_realloc(void* p, size_t size, size_t* pActual_size, lzham_bool movable, void* pUser_data)
|
||||
{
|
||||
LZHAM_NOTE_UNUSED(pUser_data);
|
||||
|
||||
void* p_new;
|
||||
|
||||
if (!p)
|
||||
{
|
||||
p_new = malloc(size);
|
||||
LZHAM_ASSERT( (reinterpret_cast<ptr_bits_t>(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0 );
|
||||
|
||||
if (pActual_size)
|
||||
*pActual_size = p_new ? _msize(p_new) : 0;
|
||||
}
|
||||
else if (!size)
|
||||
{
|
||||
free(p);
|
||||
p_new = NULL;
|
||||
|
||||
if (pActual_size)
|
||||
*pActual_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
void* p_final_block = p;
|
||||
#ifdef WIN32
|
||||
p_new = _expand(p, size);
|
||||
#else
|
||||
|
||||
p_new = NULL;
|
||||
#endif
|
||||
|
||||
if (p_new)
|
||||
{
|
||||
LZHAM_ASSERT( (reinterpret_cast<ptr_bits_t>(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0 );
|
||||
p_final_block = p_new;
|
||||
}
|
||||
else if (movable)
|
||||
{
|
||||
p_new = realloc(p, size);
|
||||
|
||||
if (p_new)
|
||||
{
|
||||
LZHAM_ASSERT( (reinterpret_cast<ptr_bits_t>(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0 );
|
||||
p_final_block = p_new;
|
||||
}
|
||||
}
|
||||
|
||||
if (pActual_size)
|
||||
*pActual_size = _msize(p_final_block);
|
||||
}
|
||||
|
||||
return p_new;
|
||||
}
|
||||
|
||||
static size_t lzham_default_msize(void* p, void* pUser_data)
|
||||
{
|
||||
LZHAM_NOTE_UNUSED(pUser_data);
|
||||
return p ? _msize(p) : 0;
|
||||
}
|
||||
|
||||
static lzham_realloc_func g_pRealloc = lzham_default_realloc;
|
||||
static lzham_msize_func g_pMSize = lzham_default_msize;
|
||||
static void* g_pUser_data;
|
||||
|
||||
static inline void lzham_mem_error(const char* p_msg)
|
||||
{
|
||||
lzham_assert(p_msg, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void* lzham_malloc(size_t size, size_t* pActual_size)
|
||||
{
|
||||
size = (size + sizeof(uint32) - 1U) & ~(sizeof(uint32) - 1U);
|
||||
if (!size)
|
||||
size = sizeof(uint32);
|
||||
|
||||
if (size > MAX_POSSIBLE_BLOCK_SIZE)
|
||||
{
|
||||
lzham_mem_error("lzham_malloc: size too big");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t actual_size = size;
|
||||
uint8* p_new = static_cast<uint8*>((*g_pRealloc)(NULL, size, &actual_size, true, g_pUser_data));
|
||||
|
||||
if (pActual_size)
|
||||
*pActual_size = actual_size;
|
||||
|
||||
if ((!p_new) || (actual_size < size))
|
||||
{
|
||||
lzham_mem_error("lzham_malloc: out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0);
|
||||
|
||||
#if LZHAM_MEM_STATS
|
||||
update_total_allocated(1, static_cast<mem_stat_t>(actual_size));
|
||||
#endif
|
||||
|
||||
return p_new;
|
||||
}
|
||||
|
||||
void* lzham_realloc(void* p, size_t size, size_t* pActual_size, bool movable)
|
||||
{
|
||||
if ((ptr_bits_t)p & (LZHAM_MIN_ALLOC_ALIGNMENT - 1))
|
||||
{
|
||||
lzham_mem_error("lzham_realloc: bad ptr");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size > MAX_POSSIBLE_BLOCK_SIZE)
|
||||
{
|
||||
lzham_mem_error("lzham_malloc: size too big");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if LZHAM_MEM_STATS
|
||||
size_t cur_size = p ? (*g_pMSize)(p, g_pUser_data) : 0;
|
||||
#endif
|
||||
|
||||
size_t actual_size = size;
|
||||
void* p_new = (*g_pRealloc)(p, size, &actual_size, movable, g_pUser_data);
|
||||
|
||||
if (pActual_size)
|
||||
*pActual_size = actual_size;
|
||||
|
||||
LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0);
|
||||
|
||||
#if LZHAM_MEM_STATS
|
||||
int num_new_blocks = 0;
|
||||
if (p)
|
||||
{
|
||||
if (!p_new)
|
||||
num_new_blocks = -1;
|
||||
}
|
||||
else if (p_new)
|
||||
{
|
||||
num_new_blocks = 1;
|
||||
}
|
||||
update_total_allocated(num_new_blocks, static_cast<mem_stat_t>(actual_size) - static_cast<mem_stat_t>(cur_size));
|
||||
#endif
|
||||
|
||||
return p_new;
|
||||
}
|
||||
|
||||
void lzham_free(void* p)
|
||||
{
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
if (reinterpret_cast<ptr_bits_t>(p) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1))
|
||||
{
|
||||
lzham_mem_error("lzham_free: bad ptr");
|
||||
return;
|
||||
}
|
||||
|
||||
#if LZHAM_MEM_STATS
|
||||
size_t cur_size = (*g_pMSize)(p, g_pUser_data);
|
||||
update_total_allocated(-1, -static_cast<mem_stat_t>(cur_size));
|
||||
#endif
|
||||
|
||||
(*g_pRealloc)(p, 0, NULL, true, g_pUser_data);
|
||||
}
|
||||
|
||||
size_t lzham_msize(void* p)
|
||||
{
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
if (reinterpret_cast<ptr_bits_t>(p) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1))
|
||||
{
|
||||
lzham_mem_error("lzham_msize: bad ptr");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (*g_pMSize)(p, g_pUser_data);
|
||||
}
|
||||
|
||||
void LZHAM_CDECL lzham_lib_set_memory_callbacks(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data)
|
||||
{
|
||||
if ((!pRealloc) || (!pMSize))
|
||||
{
|
||||
g_pRealloc = lzham_default_realloc;
|
||||
g_pMSize = lzham_default_msize;
|
||||
g_pUser_data = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRealloc = pRealloc;
|
||||
g_pMSize = pMSize;
|
||||
g_pUser_data = pUser_data;
|
||||
}
|
||||
}
|
||||
|
||||
void lzham_print_mem_stats()
|
||||
{
|
||||
#if LZHAM_MEM_STATS
|
||||
printf("Current blocks: %u, allocated: %I64u, max ever allocated: %I64i\n", g_total_blocks, (int64)g_total_allocated, (int64)g_max_allocated);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace lzham
|
||||
|
146
r5dev/thirdparty/lzham/lzham_platform.cpp
vendored
Normal file
146
r5dev/thirdparty/lzham/lzham_platform.cpp
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
// File: platform.cpp
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#include "include/lzham_core.h"
|
||||
#include "include/lzham_timer.h"
|
||||
|
||||
#if LZHAM_PLATFORM_X360
|
||||
#include <xbdm.h>
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...)
|
||||
{
|
||||
if (!sizeOfBuffer)
|
||||
return 0;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int c = vsnprintf(buffer, sizeOfBuffer, format, args);
|
||||
va_end(args);
|
||||
|
||||
buffer[sizeOfBuffer - 1] = '\0';
|
||||
|
||||
if (c < 0)
|
||||
return sizeOfBuffer - 1;
|
||||
|
||||
return LZHAM_MIN(c, (int)sizeOfBuffer - 1);
|
||||
}
|
||||
int vsprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, va_list args)
|
||||
{
|
||||
if (!sizeOfBuffer)
|
||||
return 0;
|
||||
|
||||
int c = vsnprintf(buffer, sizeOfBuffer, format, args);
|
||||
|
||||
buffer[sizeOfBuffer - 1] = '\0';
|
||||
|
||||
if (c < 0)
|
||||
return sizeOfBuffer - 1;
|
||||
|
||||
return LZHAM_MIN(c, (int)sizeOfBuffer - 1);
|
||||
}
|
||||
#endif // __GNUC__
|
||||
|
||||
bool lzham_is_debugger_present(void)
|
||||
{
|
||||
#if LZHAM_PLATFORM_X360
|
||||
return DmIsDebuggerPresent() != 0;
|
||||
#elif LZHAM_USE_WIN32_API
|
||||
return IsDebuggerPresent() != 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void lzham_debug_break(void)
|
||||
{
|
||||
#if LZHAM_USE_WIN32_API
|
||||
DebugBreak();
|
||||
#endif
|
||||
}
|
||||
|
||||
void lzham_output_debug_string(const char* p)
|
||||
{
|
||||
LZHAM_NOTE_UNUSED(p);
|
||||
#if LZHAM_USE_WIN32_API
|
||||
OutputDebugStringA(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LZHAM_BUFFERED_PRINTF
|
||||
// This stuff was a quick hack only intended for debugging/development.
|
||||
namespace lzham
|
||||
{
|
||||
struct buffered_str
|
||||
{
|
||||
enum { cBufSize = 256 };
|
||||
char m_buf[cBufSize];
|
||||
};
|
||||
|
||||
static lzham::vector<buffered_str> g_buffered_strings;
|
||||
static volatile long g_buffered_string_locked;
|
||||
|
||||
static void lock_buffered_strings()
|
||||
{
|
||||
while (atomic_exchange32(&g_buffered_string_locked, 1) == 1)
|
||||
{
|
||||
lzham_yield_processor();
|
||||
lzham_yield_processor();
|
||||
lzham_yield_processor();
|
||||
lzham_yield_processor();
|
||||
}
|
||||
|
||||
LZHAM_MEMORY_IMPORT_BARRIER
|
||||
}
|
||||
|
||||
static void unlock_buffered_strings()
|
||||
{
|
||||
LZHAM_MEMORY_EXPORT_BARRIER
|
||||
|
||||
atomic_exchange32(&g_buffered_string_locked, 0);
|
||||
}
|
||||
|
||||
} // namespace lzham
|
||||
|
||||
void lzham_buffered_printf(const char *format, ...)
|
||||
{
|
||||
format;
|
||||
|
||||
char buf[lzham::buffered_str::cBufSize];
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf_s(buf, sizeof(buf), sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
|
||||
lzham::lock_buffered_strings();
|
||||
|
||||
if (!lzham::g_buffered_strings.capacity())
|
||||
{
|
||||
lzham::g_buffered_strings.try_reserve(2048);
|
||||
}
|
||||
|
||||
if (lzham::g_buffered_strings.try_resize(lzham::g_buffered_strings.size() + 1))
|
||||
{
|
||||
memcpy(lzham::g_buffered_strings.back().m_buf, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
lzham::unlock_buffered_strings();
|
||||
}
|
||||
|
||||
void lzham_flush_buffered_printf()
|
||||
{
|
||||
lzham::lock_buffered_strings();
|
||||
|
||||
for (lzham::uint i = 0; i < lzham::g_buffered_strings.size(); i++)
|
||||
{
|
||||
printf("%s", lzham::g_buffered_strings[i].m_buf);
|
||||
}
|
||||
|
||||
lzham::g_buffered_strings.try_resize(0);
|
||||
|
||||
lzham::unlock_buffered_strings();
|
||||
}
|
||||
#endif
|
414
r5dev/thirdparty/lzham/lzham_polar_codes.cpp
vendored
Normal file
414
r5dev/thirdparty/lzham/lzham_polar_codes.cpp
vendored
Normal file
@ -0,0 +1,414 @@
|
||||
// File: polar_codes.cpp
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
//
|
||||
// Andrew Polar's prefix code algorithm:
|
||||
// http://ezcodesample.com/prefixer/prefixer_article.html
|
||||
//
|
||||
// Also implements Fyffe's approximate codelength generation method, which is
|
||||
// very similar but operates directly on codelengths vs. symbol frequencies:
|
||||
// Fyffe Codes for Fast Codelength Approximation, Graham Fyffe, 1999
|
||||
// http://code.google.com/p/lzham/wiki/FyffeCodes
|
||||
#include "include/lzham_core.h"
|
||||
#include "include/lzham_polar_codes.h"
|
||||
|
||||
#define LZHAM_USE_SHANNON_FANO_CODES 0
|
||||
#define LZHAM_USE_FYFFE_CODES 0
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
struct sym_freq
|
||||
{
|
||||
uint16 m_freq;
|
||||
uint16 m_sym;
|
||||
};
|
||||
|
||||
static inline sym_freq* radix_sort_syms(uint num_syms, sym_freq* syms0, sym_freq* syms1)
|
||||
{
|
||||
const uint cMaxPasses = 2;
|
||||
uint hist[256 * cMaxPasses];
|
||||
|
||||
memset(hist, 0, sizeof(hist[0]) * 256 * cMaxPasses);
|
||||
|
||||
{
|
||||
sym_freq* p = syms0;
|
||||
sym_freq* q = syms0 + (num_syms >> 1) * 2;
|
||||
|
||||
for ( ; p != q; p += 2)
|
||||
{
|
||||
const uint freq0 = p[0].m_freq;
|
||||
const uint freq1 = p[1].m_freq;
|
||||
|
||||
hist[ freq0 & 0xFF]++;
|
||||
hist[256 + ((freq0 >> 8) & 0xFF)]++;
|
||||
|
||||
hist[ freq1 & 0xFF]++;
|
||||
hist[256 + ((freq1 >> 8) & 0xFF)]++;
|
||||
}
|
||||
|
||||
if (num_syms & 1)
|
||||
{
|
||||
const uint freq = p->m_freq;
|
||||
|
||||
hist[ freq & 0xFF]++;
|
||||
hist[256 + ((freq >> 8) & 0xFF)]++;
|
||||
}
|
||||
}
|
||||
|
||||
sym_freq* pCur_syms = syms0;
|
||||
sym_freq* pNew_syms = syms1;
|
||||
|
||||
const uint total_passes = (hist[256] == num_syms) ? 1 : cMaxPasses;
|
||||
|
||||
for (uint pass = 0; pass < total_passes; pass++)
|
||||
{
|
||||
const uint* pHist = &hist[pass << 8];
|
||||
|
||||
uint offsets[256];
|
||||
|
||||
uint cur_ofs = 0;
|
||||
for (uint i = 0; i < 256; i += 2)
|
||||
{
|
||||
offsets[i] = cur_ofs;
|
||||
cur_ofs += pHist[i];
|
||||
|
||||
offsets[i+1] = cur_ofs;
|
||||
cur_ofs += pHist[i+1];
|
||||
}
|
||||
|
||||
const uint pass_shift = pass << 3;
|
||||
|
||||
sym_freq* p = pCur_syms;
|
||||
sym_freq* q = pCur_syms + (num_syms >> 1) * 2;
|
||||
|
||||
for ( ; p != q; p += 2)
|
||||
{
|
||||
uint c0 = p[0].m_freq;
|
||||
uint c1 = p[1].m_freq;
|
||||
|
||||
if (pass)
|
||||
{
|
||||
c0 >>= 8;
|
||||
c1 >>= 8;
|
||||
}
|
||||
|
||||
c0 &= 0xFF;
|
||||
c1 &= 0xFF;
|
||||
|
||||
// Cut down on LHS's on console platforms by processing two at a time.
|
||||
if (c0 == c1)
|
||||
{
|
||||
uint dst_offset0 = offsets[c0];
|
||||
|
||||
offsets[c0] = dst_offset0 + 2;
|
||||
|
||||
pNew_syms[dst_offset0] = p[0];
|
||||
pNew_syms[dst_offset0 + 1] = p[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint dst_offset0 = offsets[c0]++;
|
||||
uint dst_offset1 = offsets[c1]++;
|
||||
|
||||
pNew_syms[dst_offset0] = p[0];
|
||||
pNew_syms[dst_offset1] = p[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (num_syms & 1)
|
||||
{
|
||||
uint c = ((p->m_freq) >> pass_shift) & 0xFF;
|
||||
|
||||
uint dst_offset = offsets[c];
|
||||
offsets[c] = dst_offset + 1;
|
||||
|
||||
pNew_syms[dst_offset] = *p;
|
||||
}
|
||||
|
||||
sym_freq* t = pCur_syms;
|
||||
pCur_syms = pNew_syms;
|
||||
pNew_syms = t;
|
||||
}
|
||||
|
||||
#if LZHAM_ASSERTS_ENABLED
|
||||
uint prev_freq = 0;
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
LZHAM_ASSERT(!(pCur_syms[i].m_freq < prev_freq));
|
||||
prev_freq = pCur_syms[i].m_freq;
|
||||
}
|
||||
#endif
|
||||
|
||||
return pCur_syms;
|
||||
}
|
||||
|
||||
struct polar_work_tables
|
||||
{
|
||||
sym_freq syms0[cPolarMaxSupportedSyms];
|
||||
sym_freq syms1[cPolarMaxSupportedSyms];
|
||||
};
|
||||
|
||||
uint get_generate_polar_codes_table_size()
|
||||
{
|
||||
return sizeof(polar_work_tables);
|
||||
}
|
||||
|
||||
void generate_polar_codes(uint num_syms, sym_freq* pSF, uint8* pCodesizes, uint& max_code_size_ret)
|
||||
{
|
||||
int tmp_freq[cPolarMaxSupportedSyms];
|
||||
|
||||
uint orig_total_freq = 0;
|
||||
uint cur_total = 0;
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint sym_freq = pSF[num_syms - 1 - i].m_freq;
|
||||
orig_total_freq += sym_freq;
|
||||
|
||||
uint sym_len = math::total_bits(sym_freq);
|
||||
uint adjusted_sym_freq = 1 << (sym_len - 1);
|
||||
tmp_freq[i] = adjusted_sym_freq;
|
||||
cur_total += adjusted_sym_freq;
|
||||
}
|
||||
|
||||
uint tree_total = 1 << (math::total_bits(orig_total_freq) - 1);
|
||||
if (tree_total < orig_total_freq)
|
||||
tree_total <<= 1;
|
||||
|
||||
uint start_index = 0;
|
||||
while ((cur_total < tree_total) && (start_index < num_syms))
|
||||
{
|
||||
for (uint i = start_index; i < num_syms; i++)
|
||||
{
|
||||
uint freq = tmp_freq[i];
|
||||
if ((cur_total + freq) <= tree_total)
|
||||
{
|
||||
tmp_freq[i] += freq;
|
||||
if ((cur_total += freq) == tree_total)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
start_index = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LZHAM_ASSERT(cur_total == tree_total);
|
||||
|
||||
uint max_code_size = 0;
|
||||
const uint tree_total_bits = math::total_bits(tree_total);
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint codesize = (tree_total_bits - math::total_bits(tmp_freq[i]));
|
||||
max_code_size = LZHAM_MAX(codesize, max_code_size);
|
||||
pCodesizes[pSF[num_syms-1-i].m_sym] = static_cast<uint8>(codesize);
|
||||
}
|
||||
max_code_size_ret = max_code_size;
|
||||
}
|
||||
|
||||
#if LZHAM_USE_FYFFE_CODES
|
||||
void generate_fyffe_codes(uint num_syms, sym_freq* pSF, uint8* pCodesizes, uint& max_code_size_ret)
|
||||
{
|
||||
int tmp_codesizes[cPolarMaxSupportedSyms];
|
||||
|
||||
uint cur_total = 0;
|
||||
uint orig_total = 0;
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint sym_freq = pSF[i].m_freq;
|
||||
orig_total += sym_freq;
|
||||
|
||||
// Compute the nearest power of 2 lower or equal to the symbol's frequency.
|
||||
// This is equivalent to codesize=ceil(-log2(sym_prob)).
|
||||
uint floor_sym_freq = sym_freq;
|
||||
if (!math::is_power_of_2(floor_sym_freq))
|
||||
{
|
||||
uint sym_freq_bits = math::total_bits(sym_freq);
|
||||
floor_sym_freq = 1 << (sym_freq_bits - 1);
|
||||
}
|
||||
|
||||
// Compute preliminary codesizes. tmp_freq's will always be <= the input frequencies.
|
||||
tmp_codesizes[i] = math::total_bits(floor_sym_freq);
|
||||
cur_total += floor_sym_freq;
|
||||
}
|
||||
|
||||
// Desired_total is a power of 2, and will always be >= the adjusted frequency total.
|
||||
uint desired_total = cur_total;
|
||||
if (!math::is_power_of_2(desired_total))
|
||||
desired_total = math::next_pow2(desired_total);
|
||||
|
||||
LZHAM_ASSERT(cur_total <= desired_total);
|
||||
|
||||
// Compute residual and initial symbol codesizes.
|
||||
uint desired_total_bits = math::total_bits(desired_total);
|
||||
int r = desired_total;
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint codesize = desired_total_bits - tmp_codesizes[i];
|
||||
tmp_codesizes[i] = static_cast<uint8>(codesize);
|
||||
r -= (desired_total >> codesize);
|
||||
}
|
||||
|
||||
LZHAM_ASSERT(r >= 0);
|
||||
|
||||
int sym_freq_scale = (desired_total << 7) / orig_total;
|
||||
|
||||
// Promote codesizes from most probable to lowest, as needed.
|
||||
bool force_unhappiness = false;
|
||||
while (r > 0)
|
||||
{
|
||||
for (int i = num_syms - 1; i >= 0; i--)
|
||||
{
|
||||
uint codesize = tmp_codesizes[i];
|
||||
if (codesize == 1)
|
||||
continue;
|
||||
|
||||
int sym_freq = pSF[i].m_freq;
|
||||
int f = desired_total >> codesize;
|
||||
if (f > r)
|
||||
continue;
|
||||
|
||||
// A code is "unhappy" when it is assigned more bits than -log2(sym_prob).
|
||||
// It's too expensive to compute -log2(sym_freq/total_freq), so instead this directly compares the symbol's original
|
||||
// frequency vs. the effective/adjusted frequency. sym_freq >= f is an approximation.
|
||||
//bool unhappy = force_unhappiness || (sym_freq >= f);
|
||||
|
||||
// Compare the symbol's original probability vs. its effective probability at its current codelength.
|
||||
//bool unhappy = force_unhappiness || ((sym_freq * ((float)desired_total / orig_total)) > f);
|
||||
bool unhappy = force_unhappiness || ((sym_freq * sym_freq_scale) > (f << 7));
|
||||
|
||||
if (unhappy)
|
||||
{
|
||||
tmp_codesizes[i]--;
|
||||
|
||||
r -= f;
|
||||
if (r <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Occasionally, a second pass is required to reduce the residual to 0.
|
||||
// Subsequent passes ignore unhappiness. This is not discussed in Fyffe's original article.
|
||||
force_unhappiness = true;
|
||||
}
|
||||
|
||||
LZHAM_ASSERT(!r);
|
||||
|
||||
uint max_code_size = 0;
|
||||
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint codesize = tmp_codesizes[i];
|
||||
max_code_size = LZHAM_MAX(codesize, max_code_size);
|
||||
pCodesizes[pSF[i].m_sym] = static_cast<uint8>(codesize);
|
||||
}
|
||||
max_code_size_ret = max_code_size;
|
||||
}
|
||||
#endif //LZHAM_USE_FYFFE_CODES
|
||||
|
||||
#if LZHAM_USE_SHANNON_FANO_CODES
|
||||
// Straightforward recursive Shannon-Fano implementation, for comparison purposes.
|
||||
static void generate_shannon_fano_codes_internal(uint num_syms, sym_freq* pSF, uint8* pCodesizes, int l, int h, uint total_freq)
|
||||
{
|
||||
LZHAM_ASSERT((h - l) >= 2);
|
||||
|
||||
uint left_total = total_freq;
|
||||
uint right_total = 0;
|
||||
int best_diff = INT_MAX;
|
||||
int best_split_index = 0;
|
||||
for (int i = h - 1; i > l; i--)
|
||||
{
|
||||
uint freq = pSF[i].m_freq;
|
||||
uint next_left_total = left_total - freq;
|
||||
uint next_right_total = right_total + freq;
|
||||
LZHAM_ASSERT((next_left_total + next_right_total) == total_freq);
|
||||
|
||||
int diff = labs(next_left_total - next_right_total);
|
||||
if (diff >= best_diff)
|
||||
break;
|
||||
|
||||
left_total = next_left_total;
|
||||
right_total = next_right_total;
|
||||
best_split_index = i;
|
||||
best_diff = diff;
|
||||
if (!best_diff)
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = l; i < h; i++)
|
||||
pCodesizes[i]++;
|
||||
|
||||
if ((best_split_index - l) > 1) generate_shannon_fano_codes_internal(num_syms, pSF, pCodesizes, l, best_split_index, left_total);
|
||||
if ((h - best_split_index) > 1) generate_shannon_fano_codes_internal(num_syms, pSF, pCodesizes, best_split_index, h, right_total);
|
||||
}
|
||||
|
||||
void generate_shannon_fano_codes(uint num_syms, sym_freq* pSF, uint total_freq, uint8* pCodesizes, uint& max_code_size_ret)
|
||||
{
|
||||
LZHAM_ASSERT(num_syms >= 2);
|
||||
uint8 tmp_codesizes[cPolarMaxSupportedSyms];
|
||||
memset(tmp_codesizes, 0, num_syms);
|
||||
|
||||
generate_shannon_fano_codes_internal(num_syms, pSF, tmp_codesizes, 0, num_syms, total_freq);
|
||||
|
||||
uint max_code_size = 0;
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint codesize = tmp_codesizes[i];
|
||||
max_code_size = LZHAM_MAX(codesize, max_code_size);
|
||||
pCodesizes[pSF[i].m_sym] = static_cast<uint8>(codesize);
|
||||
}
|
||||
max_code_size_ret = max_code_size;
|
||||
}
|
||||
#endif // LZHAM_USE_SHANNON_FANO_CODES
|
||||
|
||||
bool generate_polar_codes(void* pContext, uint num_syms, const uint16* pFreq, uint8* pCodesizes, uint& max_code_size, uint& total_freq_ret)
|
||||
{
|
||||
if ((!num_syms) || (num_syms > cPolarMaxSupportedSyms))
|
||||
return false;
|
||||
|
||||
polar_work_tables& state = *static_cast<polar_work_tables*>(pContext);;
|
||||
|
||||
uint max_freq = 0;
|
||||
uint total_freq = 0;
|
||||
|
||||
uint num_used_syms = 0;
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint freq = pFreq[i];
|
||||
|
||||
if (!freq)
|
||||
pCodesizes[i] = 0;
|
||||
else
|
||||
{
|
||||
total_freq += freq;
|
||||
max_freq = math::maximum(max_freq, freq);
|
||||
|
||||
sym_freq& sf = state.syms0[num_used_syms];
|
||||
sf.m_sym = static_cast<uint16>(i);
|
||||
sf.m_freq = static_cast<uint16>(freq);
|
||||
num_used_syms++;
|
||||
}
|
||||
}
|
||||
|
||||
total_freq_ret = total_freq;
|
||||
|
||||
if (num_used_syms == 1)
|
||||
{
|
||||
pCodesizes[state.syms0[0].m_sym] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sym_freq* syms = radix_sort_syms(num_used_syms, state.syms0, state.syms1);
|
||||
|
||||
#if LZHAM_USE_SHANNON_FANO_CODES
|
||||
generate_shannon_fano_codes(num_syms, syms, total_freq, pCodesizes, max_code_size);
|
||||
#elif LZHAM_USE_FYFFE_CODES
|
||||
generate_fyffe_codes(num_syms, syms, pCodesizes, max_code_size);
|
||||
#else
|
||||
generate_polar_codes(num_syms, syms, pCodesizes, max_code_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace lzham
|
||||
|
350
r5dev/thirdparty/lzham/lzham_prefix_coding.cpp
vendored
Normal file
350
r5dev/thirdparty/lzham/lzham_prefix_coding.cpp
vendored
Normal file
@ -0,0 +1,350 @@
|
||||
// File: lzham_prefix_coding.cpp
|
||||
// See Copyright Notice and license at the end of include/lzham.h
|
||||
#include "include/lzham_core.h"
|
||||
#include "include/lzham_prefix_coding.h"
|
||||
|
||||
#ifdef LZHAM_BUILD_DEBUG
|
||||
//#define TEST_DECODER_TABLES
|
||||
#endif
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
namespace prefix_coding
|
||||
{
|
||||
bool limit_max_code_size(uint num_syms, uint8* pCodesizes, uint max_code_size)
|
||||
{
|
||||
const uint cMaxEverCodeSize = 34;
|
||||
|
||||
if ((!num_syms) || (num_syms > cMaxSupportedSyms) || (max_code_size < 1) || (max_code_size > cMaxEverCodeSize))
|
||||
return false;
|
||||
|
||||
uint num_codes[cMaxEverCodeSize + 1];
|
||||
utils::zero_object(num_codes);
|
||||
|
||||
bool should_limit = false;
|
||||
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint c = pCodesizes[i];
|
||||
|
||||
LZHAM_ASSERT(c <= cMaxEverCodeSize);
|
||||
|
||||
num_codes[c]++;
|
||||
if (c > max_code_size)
|
||||
should_limit = true;
|
||||
}
|
||||
|
||||
if (!should_limit)
|
||||
return true;
|
||||
|
||||
uint ofs = 0;
|
||||
uint next_sorted_ofs[cMaxEverCodeSize + 1];
|
||||
for (uint i = 1; i <= cMaxEverCodeSize; i++)
|
||||
{
|
||||
next_sorted_ofs[i] = ofs;
|
||||
ofs += num_codes[i];
|
||||
}
|
||||
|
||||
if ((ofs < 2) || (ofs > cMaxSupportedSyms))
|
||||
return true;
|
||||
|
||||
if (ofs > (1U << max_code_size))
|
||||
return false;
|
||||
|
||||
for (uint i = max_code_size + 1; i <= cMaxEverCodeSize; i++)
|
||||
num_codes[max_code_size] += num_codes[i];
|
||||
|
||||
// Technique of adjusting tree to enforce maximum code size from LHArc.
|
||||
|
||||
uint total = 0;
|
||||
for (uint i = max_code_size; i; --i)
|
||||
total += (num_codes[i] << (max_code_size - i));
|
||||
|
||||
if (total == (1U << max_code_size))
|
||||
return true;
|
||||
|
||||
do
|
||||
{
|
||||
num_codes[max_code_size]--;
|
||||
|
||||
uint i;
|
||||
for (i = max_code_size - 1; i; --i)
|
||||
{
|
||||
if (!num_codes[i])
|
||||
continue;
|
||||
num_codes[i]--;
|
||||
num_codes[i + 1] += 2;
|
||||
break;
|
||||
}
|
||||
if (!i)
|
||||
return false;
|
||||
|
||||
total--;
|
||||
} while (total != (1U << max_code_size));
|
||||
|
||||
uint8 new_codesizes[cMaxSupportedSyms];
|
||||
uint8* p = new_codesizes;
|
||||
for (uint i = 1; i <= max_code_size; i++)
|
||||
{
|
||||
uint n = num_codes[i];
|
||||
if (n)
|
||||
{
|
||||
memset(p, i, n);
|
||||
p += n;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
const uint c = pCodesizes[i];
|
||||
if (c)
|
||||
{
|
||||
uint next_ofs = next_sorted_ofs[c];
|
||||
next_sorted_ofs[c] = next_ofs + 1;
|
||||
|
||||
pCodesizes[i] = static_cast<uint8>(new_codesizes[next_ofs]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool generate_codes(uint num_syms, const uint8* pCodesizes, uint16* pCodes)
|
||||
{
|
||||
uint num_codes[cMaxExpectedCodeSize + 1];
|
||||
utils::zero_object(num_codes);
|
||||
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint c = pCodesizes[i];
|
||||
LZHAM_ASSERT(c <= cMaxExpectedCodeSize);
|
||||
num_codes[c]++;
|
||||
}
|
||||
|
||||
uint code = 0;
|
||||
|
||||
uint next_code[cMaxExpectedCodeSize + 1];
|
||||
next_code[0] = 0;
|
||||
|
||||
for (uint i = 1; i <= cMaxExpectedCodeSize; i++)
|
||||
{
|
||||
next_code[i] = code;
|
||||
|
||||
code = (code + num_codes[i]) << 1;
|
||||
}
|
||||
|
||||
if (code != (1 << (cMaxExpectedCodeSize + 1)))
|
||||
{
|
||||
uint t = 0;
|
||||
for (uint i = 1; i <= cMaxExpectedCodeSize; i++)
|
||||
{
|
||||
t += num_codes[i];
|
||||
if (t > 1)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint c = pCodesizes[i];
|
||||
|
||||
LZHAM_ASSERT(!c || (next_code[c] <= UINT16_MAX));
|
||||
|
||||
pCodes[i] = static_cast<uint16>(next_code[c]++);
|
||||
|
||||
LZHAM_ASSERT(!c || (math::total_bits(pCodes[i]) <= pCodesizes[i]));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool generate_decoder_tables(uint num_syms, const uint8* pCodesizes, decoder_tables* pTables, uint table_bits)
|
||||
{
|
||||
uint min_codes[cMaxExpectedCodeSize];
|
||||
|
||||
if ((!num_syms) || (table_bits > cMaxTableBits))
|
||||
return false;
|
||||
|
||||
pTables->m_num_syms = num_syms;
|
||||
|
||||
uint num_codes[cMaxExpectedCodeSize + 1];
|
||||
utils::zero_object(num_codes);
|
||||
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint c = pCodesizes[i];
|
||||
num_codes[c]++;
|
||||
}
|
||||
|
||||
uint sorted_positions[cMaxExpectedCodeSize + 1];
|
||||
|
||||
uint next_code = 0;
|
||||
|
||||
uint total_used_syms = 0;
|
||||
uint max_code_size = 0;
|
||||
uint min_code_size = UINT_MAX;
|
||||
for (uint i = 1; i <= cMaxExpectedCodeSize; i++)
|
||||
{
|
||||
const uint n = num_codes[i];
|
||||
|
||||
if (!n)
|
||||
pTables->m_max_codes[i - 1] = 0;//UINT_MAX;
|
||||
else
|
||||
{
|
||||
min_code_size = math::minimum(min_code_size, i);
|
||||
max_code_size = math::maximum(max_code_size, i);
|
||||
|
||||
min_codes[i - 1] = next_code;
|
||||
|
||||
pTables->m_max_codes[i - 1] = next_code + n - 1;
|
||||
pTables->m_max_codes[i - 1] = 1 + ((pTables->m_max_codes[i - 1] << (16 - i)) | ((1 << (16 - i)) - 1));
|
||||
|
||||
pTables->m_val_ptrs[i - 1] = total_used_syms;
|
||||
|
||||
sorted_positions[i] = total_used_syms;
|
||||
|
||||
next_code += n;
|
||||
total_used_syms += n;
|
||||
}
|
||||
|
||||
next_code <<= 1;
|
||||
}
|
||||
|
||||
pTables->m_total_used_syms = total_used_syms;
|
||||
|
||||
if (total_used_syms > pTables->m_cur_sorted_symbol_order_size)
|
||||
{
|
||||
pTables->m_cur_sorted_symbol_order_size = total_used_syms;
|
||||
|
||||
if (!math::is_power_of_2(total_used_syms))
|
||||
pTables->m_cur_sorted_symbol_order_size = math::minimum<uint>(num_syms, math::next_pow2(total_used_syms));
|
||||
|
||||
if (pTables->m_sorted_symbol_order)
|
||||
{
|
||||
lzham_delete_array(pTables->m_sorted_symbol_order);
|
||||
pTables->m_sorted_symbol_order = NULL;
|
||||
}
|
||||
|
||||
pTables->m_sorted_symbol_order = lzham_new_array<uint16>(pTables->m_cur_sorted_symbol_order_size);
|
||||
if (!pTables->m_sorted_symbol_order)
|
||||
return false;
|
||||
}
|
||||
|
||||
pTables->m_min_code_size = static_cast<uint8>(min_code_size);
|
||||
pTables->m_max_code_size = static_cast<uint8>(max_code_size);
|
||||
|
||||
for (uint i = 0; i < num_syms; i++)
|
||||
{
|
||||
uint c = pCodesizes[i];
|
||||
if (c)
|
||||
{
|
||||
LZHAM_ASSERT(num_codes[c]);
|
||||
|
||||
uint sorted_pos = sorted_positions[c]++;
|
||||
|
||||
LZHAM_ASSERT(sorted_pos < total_used_syms);
|
||||
|
||||
pTables->m_sorted_symbol_order[sorted_pos] = static_cast<uint16>(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (table_bits <= pTables->m_min_code_size)
|
||||
table_bits = 0;
|
||||
pTables->m_table_bits = table_bits;
|
||||
|
||||
if (table_bits)
|
||||
{
|
||||
uint table_size = 1 << table_bits;
|
||||
if (table_size > pTables->m_cur_lookup_size)
|
||||
{
|
||||
pTables->m_cur_lookup_size = table_size;
|
||||
|
||||
if (pTables->m_lookup)
|
||||
{
|
||||
lzham_delete_array(pTables->m_lookup);
|
||||
pTables->m_lookup = NULL;
|
||||
}
|
||||
|
||||
pTables->m_lookup = lzham_new_array<uint32>(table_size);
|
||||
if (!pTables->m_lookup)
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(pTables->m_lookup, 0xFF, static_cast<uint>(sizeof(pTables->m_lookup[0])) * (1UL << table_bits));
|
||||
|
||||
for (uint codesize = 1; codesize <= table_bits; codesize++)
|
||||
{
|
||||
if (!num_codes[codesize])
|
||||
continue;
|
||||
|
||||
const uint fillsize = table_bits - codesize;
|
||||
const uint fillnum = 1 << fillsize;
|
||||
|
||||
const uint min_code = min_codes[codesize - 1];
|
||||
const uint max_code = pTables->get_unshifted_max_code(codesize);
|
||||
const uint val_ptr = pTables->m_val_ptrs[codesize - 1];
|
||||
|
||||
for (uint code = min_code; code <= max_code; code++)
|
||||
{
|
||||
const uint sym_index = pTables->m_sorted_symbol_order[ val_ptr + code - min_code ];
|
||||
LZHAM_ASSERT( pCodesizes[sym_index] == codesize );
|
||||
|
||||
for (uint j = 0; j < fillnum; j++)
|
||||
{
|
||||
const uint t = j + (code << fillsize);
|
||||
|
||||
LZHAM_ASSERT(t < (1U << table_bits));
|
||||
|
||||
LZHAM_ASSERT(pTables->m_lookup[t] == UINT32_MAX);
|
||||
|
||||
pTables->m_lookup[t] = sym_index | (codesize << 16U);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint i = 0; i < cMaxExpectedCodeSize; i++)
|
||||
pTables->m_val_ptrs[i] -= min_codes[i];
|
||||
|
||||
pTables->m_table_max_code = 0;
|
||||
pTables->m_decode_start_code_size = pTables->m_min_code_size;
|
||||
|
||||
if (table_bits)
|
||||
{
|
||||
uint i;
|
||||
for (i = table_bits; i >= 1; i--)
|
||||
{
|
||||
if (num_codes[i])
|
||||
{
|
||||
pTables->m_table_max_code = pTables->m_max_codes[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= 1)
|
||||
{
|
||||
pTables->m_decode_start_code_size = table_bits + 1;
|
||||
for (i = table_bits + 1; i <= max_code_size; i++)
|
||||
{
|
||||
if (num_codes[i])
|
||||
{
|
||||
pTables->m_decode_start_code_size = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sentinels
|
||||
pTables->m_max_codes[cMaxExpectedCodeSize] = UINT_MAX;
|
||||
pTables->m_val_ptrs[cMaxExpectedCodeSize] = 0xFFFFF;
|
||||
|
||||
pTables->m_table_shift = 32 - pTables->m_table_bits;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace prefix_codig
|
||||
|
||||
} // namespace lzham
|
||||
|
||||
|
227
r5dev/thirdparty/lzham/lzham_pthreads_threading.cpp
vendored
Normal file
227
r5dev/thirdparty/lzham/lzham_pthreads_threading.cpp
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
// File: lzham_task_pool_pthreads.cpp
|
||||
//
|
||||
// Copyright (c) 2009-2010 Richard Geldreich, Jr. <richgel99@gmail.com>
|
||||
//
|
||||
// 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.
|
||||
#include "include/lzham_core.h"
|
||||
#include "include/lzham_pthreads_threading.h"
|
||||
#include "include/lzham_timer.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <sys/sysinfo.h>
|
||||
#endif
|
||||
|
||||
#if LZHAM_USE_PTHREADS_API
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma comment(lib, "../ext/libpthread/lib/pthreadVC2.lib")
|
||||
#endif
|
||||
|
||||
namespace lzham
|
||||
{
|
||||
task_pool::task_pool() :
|
||||
m_num_threads(0),
|
||||
m_tasks_available(0, 32767),
|
||||
m_num_outstanding_tasks(0),
|
||||
m_exit_flag(false)
|
||||
{
|
||||
utils::zero_object(m_threads);
|
||||
}
|
||||
|
||||
task_pool::task_pool(uint num_threads) :
|
||||
m_num_threads(0),
|
||||
m_tasks_available(0, 32767),
|
||||
m_num_outstanding_tasks(0),
|
||||
m_exit_flag(false)
|
||||
{
|
||||
utils::zero_object(m_threads);
|
||||
|
||||
bool status = init(num_threads);
|
||||
LZHAM_VERIFY(status);
|
||||
}
|
||||
|
||||
task_pool::~task_pool()
|
||||
{
|
||||
deinit();
|
||||
}
|
||||
|
||||
bool task_pool::init(uint num_threads)
|
||||
{
|
||||
LZHAM_ASSERT(num_threads <= cMaxThreads);
|
||||
num_threads = math::minimum<uint>(num_threads, cMaxThreads);
|
||||
|
||||
deinit();
|
||||
|
||||
bool succeeded = true;
|
||||
|
||||
m_num_threads = 0;
|
||||
while (m_num_threads < num_threads)
|
||||
{
|
||||
int status = pthread_create(&m_threads[m_num_threads], NULL, thread_func, this);
|
||||
if (status)
|
||||
{
|
||||
succeeded = false;
|
||||
break;
|
||||
}
|
||||
|
||||
m_num_threads++;
|
||||
}
|
||||
|
||||
if (!succeeded)
|
||||
{
|
||||
deinit();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void task_pool::deinit()
|
||||
{
|
||||
if (m_num_threads)
|
||||
{
|
||||
join();
|
||||
|
||||
atomic_exchange32(&m_exit_flag, true);
|
||||
|
||||
m_tasks_available.release(m_num_threads);
|
||||
|
||||
for (uint i = 0; i < m_num_threads; i++)
|
||||
pthread_join(m_threads[i], NULL);
|
||||
|
||||
m_num_threads = 0;
|
||||
|
||||
atomic_exchange32(&m_exit_flag, false);
|
||||
}
|
||||
|
||||
m_task_stack.clear();
|
||||
m_num_outstanding_tasks = 0;
|
||||
}
|
||||
|
||||
bool task_pool::queue_task(task_callback_func pFunc, uint64 data, void* pData_ptr)
|
||||
{
|
||||
LZHAM_ASSERT(m_num_threads);
|
||||
LZHAM_ASSERT(pFunc);
|
||||
|
||||
task tsk;
|
||||
tsk.m_callback = pFunc;
|
||||
tsk.m_data = data;
|
||||
tsk.m_pData_ptr = pData_ptr;
|
||||
tsk.m_flags = 0;
|
||||
|
||||
if (!m_task_stack.try_push(tsk))
|
||||
return false;
|
||||
|
||||
atomic_increment32(&m_num_outstanding_tasks);
|
||||
|
||||
m_tasks_available.release(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// It's the object's responsibility to delete pObj within the execute_task() method, if needed!
|
||||
bool task_pool::queue_task(executable_task* pObj, uint64 data, void* pData_ptr)
|
||||
{
|
||||
LZHAM_ASSERT(m_num_threads);
|
||||
LZHAM_ASSERT(pObj);
|
||||
|
||||
task tsk;
|
||||
tsk.m_pObj = pObj;
|
||||
tsk.m_data = data;
|
||||
tsk.m_pData_ptr = pData_ptr;
|
||||
tsk.m_flags = cTaskFlagObject;
|
||||
|
||||
if (!m_task_stack.try_push(tsk))
|
||||
return false;
|
||||
|
||||
atomic_increment32(&m_num_outstanding_tasks);
|
||||
|
||||
m_tasks_available.release(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void task_pool::process_task(task& tsk)
|
||||
{
|
||||
if (tsk.m_flags & cTaskFlagObject)
|
||||
tsk.m_pObj->execute_task(tsk.m_data, tsk.m_pData_ptr);
|
||||
else
|
||||
tsk.m_callback(tsk.m_data, tsk.m_pData_ptr);
|
||||
|
||||
atomic_decrement32(&m_num_outstanding_tasks);
|
||||
}
|
||||
|
||||
void task_pool::join()
|
||||
{
|
||||
task tsk;
|
||||
while (atomic_add32(&m_num_outstanding_tasks, 0) > 0)
|
||||
{
|
||||
if (m_task_stack.pop(tsk))
|
||||
{
|
||||
process_task(tsk);
|
||||
}
|
||||
else
|
||||
{
|
||||
lzham_sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void * task_pool::thread_func(void *pContext)
|
||||
{
|
||||
task_pool* pPool = static_cast<task_pool*>(pContext);
|
||||
task tsk;
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
if (!pPool->m_tasks_available.wait())
|
||||
break;
|
||||
|
||||
if (pPool->m_exit_flag)
|
||||
break;
|
||||
|
||||
if (pPool->m_task_stack.pop(tsk))
|
||||
{
|
||||
pPool->process_task(tsk);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint lzham_get_max_helper_threads()
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
uint num_procs = get_nprocs();
|
||||
return num_procs ? (num_procs - 1) : 0;
|
||||
#else
|
||||
printf("TODO: lzham_get_max_helper_threads(): Implement system specific func to determine the max # of helper threads\n");
|
||||
|
||||
// Just assume a dual-core machine.
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace lzham
|
||||
|
||||
#endif // LZHAM_USE_PTHREADS_API
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user