2021-12-25 22:36:38 +01:00
# include "core/stdafx.h"
2022-08-22 21:15:46 +02:00
# include "tier1/cvar.h"
2021-12-27 16:53:35 +01:00
# include "rtech/rtech_utils.h"
2022-06-19 18:07:43 +02:00
# ifndef DEDICATED
# include "windows/id3dx.h"
2022-07-04 22:52:10 +02:00
# include "materialsystem/cshaderglue.h"
2022-10-13 21:59:06 +02:00
# include "public/rendersystem/schema/texture.g.h"
2022-06-19 18:07:43 +02:00
# endif // !DEDICATED
2021-12-25 22:36:38 +01:00
/******************************************************************************
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
File : rtech . cpp
Date : 18 : 07 : 2021
Author : Kawe Mazidjatari
Purpose : Implements the ' rtech_game ' core utilities
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
History :
- 18 : 07 : 2021 | 13 : 02 : Created by Kawe Mazidjatari
- 10 : 09 : 2021 | 18 : 22 : Implement ' StringToGuid ' method
- 12 : 11 : 2021 | 14 : 41 : Add decompression method to ConCommand callback
2021-12-26 02:30:20 +01:00
- 25 : 12 : 2021 | 23 : 20 : Made everything more readable thanks to bezdna5 - rs
2022-03-28 19:34:51 +02:00
- 28 : 03 : 2022 | 18 : 00 : Added getting pak info by PakID .
2021-12-25 22:36:38 +01:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//-----------------------------------------------------------------------------
// Purpose: calculate 'GUID' from input data
//-----------------------------------------------------------------------------
2022-08-06 00:16:11 +02:00
uint64_t __fastcall RTech : : StringToGuid ( const char * pData )
2021-12-25 22:36:38 +01:00
{
2022-08-06 00:16:11 +02:00
uint32_t * v1 ; // r8
uint64_t v2 ; // r10
int32_t v3 ; // er11
uint32_t v4 ; // er9
uint32_t i ; // edx
uint64_t v6 ; // rcx
int32_t v7 ; // er9
int32_t v8 ; // edx
int32_t v9 ; // eax
uint32_t v10 ; // er8
int32_t v12 ; // ecx
uint32_t * a1 = ( uint32_t * ) pData ;
2021-12-25 22:36:38 +01:00
v1 = a1 ;
v2 = 0 i64 ;
v3 = 0 ;
v4 = ( * a1 - 45 * ( ( ~ ( * a1 ^ 0x5C5C5C5Cu ) > > 7 ) & ( ( ( * a1 ^ 0x5C5C5C5Cu ) - 0x1010101 ) > > 7 ) & 0x1010101 ) ) & 0xDFDFDFDF ;
for ( i = ~ * a1 & ( * a1 - 0x1010101 ) & 0x80808080 ; ! i ; i = v8 & 0x80808080 )
{
v6 = v4 ;
v7 = v1 [ 1 ] ;
+ + v1 ;
v3 + = 4 ;
2022-08-06 00:16:11 +02:00
v2 = ( ( ( ( uint64_t ) ( 0xFB8C4D96501 i64 * v6 ) > > 24 ) + 0x633D5F1 * v2 ) > > 61 ) ^ ( ( ( uint64_t ) ( 0xFB8C4D96501 i64 * v6 ) > > 24 )
2021-12-25 22:36:38 +01:00
+ 0x633D5F1 * v2 ) ;
v8 = ~ v7 & ( v7 - 0x1010101 ) ;
v4 = ( v7 - 45 * ( ( ~ ( v7 ^ 0x5C5C5C5Cu ) > > 7 ) & ( ( ( v7 ^ 0x5C5C5C5Cu ) - 0x1010101 ) > > 7 ) & 0x1010101 ) ) & 0xDFDFDFDF ;
}
v9 = - 1 ;
v10 = ( i & - ( signed ) i ) - 1 ;
if ( _BitScanReverse ( ( unsigned long * ) & v12 , v10 ) )
{
v9 = v12 ;
}
2022-08-06 00:16:11 +02:00
return 0x633D5F1 * v2 + ( ( 0xFB8C4D96501 i64 * ( uint64_t ) ( v4 & v10 ) ) > > 24 ) - 0xAE502812AA7333 i64 * ( uint32_t ) ( v3 + v9 / 8 ) ;
2021-12-25 22:36:38 +01:00
}
//-----------------------------------------------------------------------------
// Purpose: calculate 'decompressed' size and commit parameters
//-----------------------------------------------------------------------------
2022-08-06 00:16:11 +02:00
uint64_t __fastcall RTech : : DecompressPakFileInit ( RPakDecompState_t * state , uint8_t * fileBuffer , uint64_t fileSize , uint64_t offNoHeader , uint64_t headerSize )
2021-12-25 22:36:38 +01:00
{
2022-08-06 00:16:11 +02:00
int64_t input_byte_pos_init ; // r9
uint64_t byte_init ; // r11
int32_t decompressed_size_bits ; // ecx
int64_t byte_1_low ; // rdi
uint64_t input_byte_pos_1 ; // r10
uint32_t bit_pos_final ; // ebp
uint64_t byte_1 ; // rdi
uint32_t brih_bits ; // er11
uint64_t inv_mask_in ; // r8
uint64_t byte_final_full ; // rbx
uint64_t bit_pos_final_1 ; // rax
int32_t byte_bit_offset_final ; // ebp
uint64_t input_byte_pos_final ; // r10
uint64_t byte_final ; // rbx
uint32_t brih_bytes ; // er11
uint64_t byte_tmp ; // rdx
uint64_t stream_len_needed ; // r14
uint64_t result ; // rax
uint64_t inv_mask_out ; // r8
uint64_t qw70 ; // rcx
uint64_t stream_compressed_size_new ; // rdx
const uintptr_t mask = UINT64_MAX ;
const uintptr_t file_buf = uintptr_t ( fileBuffer ) ;
2021-12-26 02:30:20 +01:00
state - > m_nInputBuf = file_buf ;
state - > m_nOut = 0 i64 ;
state - > m_nOutMask = 0 i64 ;
state - > dword44 = 0 ;
state - > m_nTotalFileLen = fileSize + offNoHeader ;
state - > m_nMask = mask ;
input_byte_pos_init = offNoHeader + headerSize + 8 ;
2022-08-06 00:16:11 +02:00
byte_init = * ( uint64_t * ) ( ( mask & ( offNoHeader + headerSize ) ) + file_buf ) ;
2021-12-26 02:30:20 +01:00
state - > m_nDecompPosition = headerSize ;
decompressed_size_bits = byte_init & 0x3F ;
byte_init > > = 6 ;
state - > input_byte_pos = input_byte_pos_init ;
state - > m_nDecompSize = byte_init & ( ( 1 i64 < < decompressed_size_bits ) - 1 ) | ( 1 i64 < < decompressed_size_bits ) ;
2022-08-06 00:16:11 +02:00
byte_1_low = * ( uint64_t * ) ( ( mask & input_byte_pos_init ) + file_buf ) < < ( 64
- ( ( uint8_t ) decompressed_size_bits
2021-12-26 02:30:20 +01:00
+ 6 ) ) ;
2022-08-06 00:16:11 +02:00
input_byte_pos_1 = input_byte_pos_init + ( ( uint64_t ) ( uint32_t ) ( decompressed_size_bits + 6 ) > > 3 ) ;
2021-12-26 02:30:20 +01:00
state - > input_byte_pos = input_byte_pos_1 ;
bit_pos_final = ( ( decompressed_size_bits + 6 ) & 7 ) + 13 ;
byte_1 = ( 0xFFFFFFFFFFFFFFFFu i64 > > ( ( decompressed_size_bits + 6 ) & 7 ) ) & ( ( byte_init > > decompressed_size_bits ) | byte_1_low ) ;
2022-08-06 00:16:11 +02:00
brih_bits = ( ( ( uint8_t ) byte_1 - 1 ) & 0x3F ) + 1 ;
inv_mask_in = 0xFFFFFFFFFFFFFFFFu i64 > > ( 64 - ( uint8_t ) brih_bits ) ;
2021-12-26 02:30:20 +01:00
state - > m_nInvMaskIn = inv_mask_in ;
state - > m_nInvMaskOut = 0xFFFFFFFFFFFFFFFFu i64 > > ( 63 - ( ( ( byte_1 > > 6 ) - 1 ) & 0x3F ) ) ;
2022-08-06 00:16:11 +02:00
byte_final_full = ( byte_1 > > 13 ) | ( * ( uint64_t * ) ( ( mask & input_byte_pos_1 ) + file_buf ) < < ( 64
- ( uint8_t ) bit_pos_final ) ) ;
2021-12-26 02:30:20 +01:00
bit_pos_final_1 = bit_pos_final ;
byte_bit_offset_final = bit_pos_final & 7 ;
input_byte_pos_final = ( bit_pos_final_1 > > 3 ) + input_byte_pos_1 ;
byte_final = ( 0xFFFFFFFFFFFFFFFFu i64 > > byte_bit_offset_final ) & byte_final_full ;
state - > input_byte_pos = input_byte_pos_final ;
if ( inv_mask_in = = - 1 i64 )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
state - > header_skip_bytes_bs = 0 ;
stream_len_needed = fileSize ;
2021-12-25 22:36:38 +01:00
}
else
{
2021-12-26 02:30:20 +01:00
brih_bytes = brih_bits > > 3 ;
state - > header_skip_bytes_bs = brih_bytes + 1 ;
2022-08-06 00:16:11 +02:00
byte_tmp = * ( uint64_t * ) ( ( mask & input_byte_pos_final ) + file_buf ) ;
2021-12-26 02:30:20 +01:00
state - > input_byte_pos = input_byte_pos_final + brih_bytes + 1 ;
2022-08-06 00:16:11 +02:00
stream_len_needed = byte_tmp & ( ( 1 i64 < < ( 8 * ( ( uint8_t ) brih_bytes + 1 ) ) ) - 1 ) ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
result = state - > m_nDecompSize ;
inv_mask_out = state - > m_nInvMaskOut ;
qw70 = offNoHeader + state - > m_nInvMaskIn - 6 i64 ;
2022-02-13 17:07:02 +01:00
state - > m_nLengthNeeded = stream_len_needed + offNoHeader ;
2021-12-26 02:30:20 +01:00
state - > qword70 = qw70 ;
state - > byte = byte_final ;
state - > byte_bit_offset = byte_bit_offset_final ;
state - > dword6C = 0 ;
state - > m_nCompressedStreamSize = stream_len_needed + offNoHeader ;
state - > m_nDecompStreamSize = result ;
if ( result - 1 > inv_mask_out )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
stream_compressed_size_new = stream_len_needed + offNoHeader - state - > header_skip_bytes_bs ;
state - > m_nDecompStreamSize = inv_mask_out + 1 ;
state - > m_nCompressedStreamSize = stream_compressed_size_new ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
2021-12-25 22:36:38 +01:00
return result ;
}
//-----------------------------------------------------------------------------
// Purpose: decompress input data
//-----------------------------------------------------------------------------
2022-08-06 00:16:11 +02:00
uint8_t __fastcall RTech : : DecompressPakFile ( RPakDecompState_t * state , uint64_t inLen , uint64_t outLen )
2021-12-25 22:36:38 +01:00
{
2022-08-06 00:16:11 +02:00
uint64_t decompressed_position ; // r15
uint32_t byte_bit_offset ; // ebp
uint64_t byte ; // rsi
uint64_t input_byte_pos ; // rdi
uint64_t some_size ; // r12
uint32_t dword6C ; // ecx MAPDST
uint64_t v12 ; // rsi
uint64_t i ; // rax
uint64_t dword6c_shl8 ; // r8
int64_t dword6c_old ; // r9
int32_t LUT_200_val ; // ecx
uint64_t v17 ; // rax
uint64_t byte_new ; // rsi
int64_t LUT_0_VAL ; // r14
int32_t byte_4bits_1 ; // ecx
uint64_t v21 ; // r11
int32_t v22 ; // edx
uint64_t out_mask ; // rax
int32_t v24 ; // er8
uint32_t LUT_400_seek_backwards ; // er13
uint64_t out_seek_back ; // r10
uint64_t out_seekd_1 ; // rax
uint64_t * out_seekd_back ; // r10
uint64_t decompressed_size ; // r9
uint64_t inv_mask_in ; // r10
uint64_t header_skip_bytes_bs ; // r8
uint64_t v32 ; // rax
uint64_t v33 ; // rax
uint64_t v34 ; // rax
uint64_t stream_decompressed_size_new ; // rcx
int64_t v36 ; // rdx
uint64_t len_needed_new ; // r14
uint64_t stream_compressed_size_new ; // r11
2021-12-26 02:30:20 +01:00
char v39 ; // cl MAPDST
2022-08-06 00:16:11 +02:00
uint64_t v40 ; // rsi MAPDST
2021-12-26 02:30:20 +01:00
uint64_t v46 ; // rcx
2022-08-06 00:16:11 +02:00
int64_t v47 ; // r9
int64_t m ; // r8
uint32_t v49 ; // er9
int64_t v50 ; // r8
int64_t v51 ; // rdx
int64_t k ; // r8
2021-12-26 02:30:20 +01:00
char * v53 ; // r10
2022-08-06 00:16:11 +02:00
int64_t v54 ; // rdx
uint32_t lut0_val_abs ; // er14
int64_t * in_seekd ; // rdx
int64_t * out_seekd ; // r8
int64_t byte_3bits ; // rax MAPDST
uint64_t byte_new_tmp ; // r9 MAPDST
int32_t LUT_4D0_480 ; // er10 MAPDST
uint8_t LUT_4D8_4C0_nBits ; // cl MAPDST
uint64_t byte_4bits ; // rax MAPDST
uint32_t copy_bytes_ammount ; // er14
uint32_t j ; // ecx
int64_t v67 ; // rax
uint64_t v68 ; // rcx
uint8_t result ; // al
2021-12-26 02:30:20 +01:00
2022-02-13 17:07:02 +01:00
if ( inLen < state - > m_nLengthNeeded )
2021-12-25 22:36:38 +01:00
return 0 ;
2021-12-26 02:30:20 +01:00
decompressed_position = state - > m_nDecompPosition ;
if ( outLen < state - > m_nInvMaskOut + ( decompressed_position & ~ state - > m_nInvMaskOut ) + 1 & & outLen < state - > m_nDecompSize )
2021-12-25 22:36:38 +01:00
return 0 ;
2021-12-26 02:30:20 +01:00
byte_bit_offset = state - > byte_bit_offset ; // Keeping copy since we increment it down below.
byte = state - > byte ; // Keeping copy since its getting overwritten down below.
input_byte_pos = state - > input_byte_pos ; // Keeping copy since we increment it down below.
some_size = state - > qword70 ;
if ( state - > m_nCompressedStreamSize < some_size )
some_size = state - > m_nCompressedStreamSize ;
dword6C = state - > dword6C ;
if ( ! byte_bit_offset )
goto LABEL_9 ;
2022-08-06 00:16:11 +02:00
v12 = ( * ( uint64_t * ) ( ( input_byte_pos & state - > m_nMask ) + state - > m_nInputBuf ) < < ( 64 - ( uint8_t ) byte_bit_offset ) ) | byte ;
2021-12-26 02:30:20 +01:00
for ( i = byte_bit_offset ; ; i = byte_bit_offset )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
byte_bit_offset & = 7u ;
input_byte_pos + = i > > 3 ;
byte = ( 0xFFFFFFFFFFFFFFFFu i64 > > byte_bit_offset ) & v12 ;
LABEL_9 :
2022-08-06 00:16:11 +02:00
dword6c_shl8 = ( uint64_t ) dword6C < < 8 ;
2021-12-26 02:30:20 +01:00
dword6c_old = dword6C ;
2022-09-09 19:47:31 +02:00
LUT_200_val = LUT_200 [ ( uint8_t ) byte + dword6c_shl8 ] ; // LUT_200 - u8 - amount of bits
2022-08-06 00:16:11 +02:00
v17 = ( uint8_t ) byte + dword6c_shl8 ;
2021-12-26 02:30:20 +01:00
byte_bit_offset + = LUT_200_val ;
byte_new = byte > > LUT_200_val ;
2022-09-09 19:47:31 +02:00
LUT_0_VAL = LUT_0 [ v17 ] ; // LUT_0 - i32 - signed, amount of bytes
2021-12-26 02:30:20 +01:00
if ( LUT_0_VAL < 0 )
2021-12-25 22:36:38 +01:00
{
2022-08-06 00:16:11 +02:00
lut0_val_abs = - ( int32_t ) LUT_0_VAL ;
in_seekd = ( int64_t * ) ( state - > m_nInputBuf + ( input_byte_pos & state - > m_nMask ) ) ;
2021-12-26 02:30:20 +01:00
dword6C = 1 ;
2022-08-06 00:16:11 +02:00
out_seekd = ( int64_t * ) ( state - > m_nOut + ( decompressed_position & state - > m_nOutMask ) ) ;
2021-12-26 02:30:20 +01:00
if ( lut0_val_abs = = LUT_4E0 [ dword6c_old ] )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
if ( ( ~ input_byte_pos & state - > m_nInvMaskIn ) < 0xF
| | ( state - > m_nInvMaskOut & ~ decompressed_position ) < 0xF
| | state - > m_nDecompSize - decompressed_position < 0x10 )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
lut0_val_abs = 1 ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
v39 = byte_new ;
v40 = byte_new > > 3 ;
byte_3bits = v39 & 7 ;
byte_new_tmp = v40 ;
if ( byte_3bits )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
LUT_4D0_480 = LUT_4D0 [ byte_3bits ] ; // LUT_4D0 - u8
2022-09-09 19:47:31 +02:00
LUT_4D8_4C0_nBits = LUT_4D8 [ byte_3bits ] ; // LUT_4D8 - u8 - amount of bits
2021-12-25 22:36:38 +01:00
}
else
{
2021-12-26 02:30:20 +01:00
byte_new_tmp = v40 > > 4 ;
byte_4bits = v40 & 15 ;
byte_bit_offset + = 4 ;
LUT_4D0_480 = LUT_480 [ byte_4bits ] ; // LUT_480 - u32
2022-09-09 19:47:31 +02:00
LUT_4D8_4C0_nBits = LUT_4C0 [ byte_4bits ] ; // LUT_4C0 - u8 - amount of bits???
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
byte_bit_offset + = LUT_4D8_4C0_nBits + 3 ;
byte_new = byte_new_tmp > > LUT_4D8_4C0_nBits ;
copy_bytes_ammount = LUT_4D0_480 + ( byte_new_tmp & ( ( 1 < < LUT_4D8_4C0_nBits ) - 1 ) ) + lut0_val_abs ;
for ( j = copy_bytes_ammount > > 3 ; j ; - - j ) // copy by 8 bytes
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
v67 = * in_seekd + + ;
* out_seekd + + = v67 ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
if ( ( copy_bytes_ammount & 4 ) ! = 0 ) // copy by 4
2021-12-25 22:36:38 +01:00
{
2022-08-06 00:16:11 +02:00
* ( uint32_t * ) out_seekd = * ( uint32_t * ) in_seekd ;
out_seekd = ( int64_t * ) ( ( char * ) out_seekd + 4 ) ;
in_seekd = ( int64_t * ) ( ( char * ) in_seekd + 4 ) ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
if ( ( copy_bytes_ammount & 2 ) ! = 0 ) // copy by 2
2021-12-25 22:36:38 +01:00
{
2022-08-06 00:16:11 +02:00
* ( uint16_t * ) out_seekd = * ( uint16_t * ) in_seekd ;
out_seekd = ( int64_t * ) ( ( char * ) out_seekd + 2 ) ;
in_seekd = ( int64_t * ) ( ( char * ) in_seekd + 2 ) ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
if ( ( copy_bytes_ammount & 1 ) ! = 0 ) // copy by 1
2022-08-06 00:16:11 +02:00
* ( uint8_t * ) out_seekd = * ( uint8_t * ) in_seekd ;
2021-12-26 02:30:20 +01:00
input_byte_pos + = copy_bytes_ammount ;
decompressed_position + = copy_bytes_ammount ;
2021-12-25 22:36:38 +01:00
}
else
{
2021-12-26 02:30:20 +01:00
* out_seekd = * in_seekd ;
out_seekd [ 1 ] = in_seekd [ 1 ] ;
input_byte_pos + = lut0_val_abs ;
decompressed_position + = lut0_val_abs ;
2021-12-25 22:36:38 +01:00
}
}
else
{
2021-12-26 02:30:20 +01:00
byte_4bits_1 = byte_new & 0xF ;
dword6C = 0 ;
2022-08-06 00:16:11 +02:00
v21 = ( ( uint64_t ) ( uint32_t ) byte_new > > ( ( ( uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 6 ) ) & 0x3F ; // 6 bits after shift for who knows how much???
2022-09-09 19:47:31 +02:00
v22 = 1 < < ( byte_4bits_1 + ( ( byte_new > > 4 ) & ( ( 24 * ( ( ( uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 2 ) ) > > 4 ) ) ) ; // amount of bits to read???
byte_bit_offset + = ( ( ( uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 6 ) // shit shit gets shifted by amount of bits it read or something
2021-12-26 02:30:20 +01:00
+ LUT_440 [ v21 ]
+ byte_4bits_1
2022-08-06 00:16:11 +02:00
+ ( ( byte_new > > 4 ) & ( ( 24 * ( ( ( uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 2 ) ) > > 4 ) ) ;
2021-12-26 02:30:20 +01:00
out_mask = state - > m_nOutMask ;
v24 = 16
* ( v22
2022-08-06 00:16:11 +02:00
+ ( ( v22 - 1 ) & ( byte_new > > ( ( ( ( uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 6 )
2021-12-26 02:30:20 +01:00
+ LUT_440 [ v21 ] ) ) ) ) ;
2022-08-06 00:16:11 +02:00
byte_new > > = ( ( ( uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 6 )
2021-12-26 02:30:20 +01:00
+ LUT_440 [ v21 ]
+ byte_4bits_1
2022-08-06 00:16:11 +02:00
+ ( ( byte_new > > 4 ) & ( ( 24 * ( ( ( uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 2 ) ) > > 4 ) ) ;
2021-12-26 02:30:20 +01:00
LUT_400_seek_backwards = v24 + LUT_400 [ v21 ] - 16 ; // LUT_400 - u8 - seek backwards
out_seek_back = out_mask & ( decompressed_position - LUT_400_seek_backwards ) ;
out_seekd_1 = state - > m_nOut + ( decompressed_position & out_mask ) ;
2022-08-06 00:16:11 +02:00
out_seekd_back = ( uint64_t * ) ( state - > m_nOut + out_seek_back ) ;
if ( ( int32_t ) LUT_0_VAL = = 17 )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
v39 = byte_new ;
v40 = byte_new > > 3 ;
byte_3bits = v39 & 7 ;
byte_new_tmp = v40 ;
if ( byte_3bits )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
LUT_4D0_480 = LUT_4D0 [ byte_3bits ] ;
LUT_4D8_4C0_nBits = LUT_4D8 [ byte_3bits ] ;
2021-12-25 22:36:38 +01:00
}
else
{
2021-12-26 02:30:20 +01:00
byte_bit_offset + = 4 ;
byte_4bits = v40 & 0xF ;
byte_new_tmp = v40 > > 4 ;
LUT_4D0_480 = LUT_480 [ byte_4bits ] ;
LUT_4D8_4C0_nBits = LUT_4C0 [ byte_4bits ] ;
if ( state - > m_nInputBuf & & byte_bit_offset + LUT_4D8_4C0_nBits > = 0x3D )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
v46 = input_byte_pos + + & state - > m_nMask ;
2022-08-06 00:16:11 +02:00
byte_new_tmp | = ( uint64_t ) * ( uint8_t * ) ( v46 + state - > m_nInputBuf ) < < ( 61
- ( uint8_t ) byte_bit_offset ) ;
2021-12-26 02:30:20 +01:00
byte_bit_offset - = 8 ;
2021-12-25 22:36:38 +01:00
}
}
2021-12-26 02:30:20 +01:00
byte_bit_offset + = LUT_4D8_4C0_nBits + 3 ;
byte_new = byte_new_tmp > > LUT_4D8_4C0_nBits ;
2022-08-06 00:16:11 +02:00
v47 = ( ( uint32_t ) byte_new_tmp & ( ( 1 < < LUT_4D8_4C0_nBits ) - 1 ) ) + LUT_4D0_480 + 17 ;
2021-12-26 02:30:20 +01:00
decompressed_position + = v47 ;
if ( LUT_400_seek_backwards < 8 )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
v49 = v47 - 13 ;
decompressed_position - = 13 i64 ;
if ( LUT_400_seek_backwards = = 1 ) // 1 means copy v49 qwords?
2021-12-25 22:36:38 +01:00
{
2022-08-06 00:16:11 +02:00
v50 = * ( uint8_t * ) out_seekd_back ;
2021-12-26 02:30:20 +01:00
v51 = 0 i64 ;
2022-08-06 00:16:11 +02:00
for ( k = 0x101010101010101 i64 * v50 ; ( uint32_t ) v51 < v49 ; v51 = ( uint32_t ) ( v51 + 8 ) )
* ( uint64_t * ) ( v51 + out_seekd_1 ) = k ;
2021-12-25 22:36:38 +01:00
}
else
{
2021-12-26 02:30:20 +01:00
if ( v49 )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
v53 = ( char * ) out_seekd_back - out_seekd_1 ;
v54 = v49 ;
2021-12-25 22:36:38 +01:00
do
{
2022-09-09 19:47:31 +02:00
* ( uint8_t * ) out_seekd_1 = v53 [ out_seekd_1 ] ; // seeked = seek_back; increment ptrs
2021-12-26 02:30:20 +01:00
+ + out_seekd_1 ;
- - v54 ;
} while ( v54 ) ;
2021-12-25 22:36:38 +01:00
}
}
}
else
{
2022-08-06 00:16:11 +02:00
for ( m = 0 i64 ; ( uint32_t ) m < ( uint32_t ) v47 ; m = ( uint32_t ) ( m + 8 ) )
* ( uint64_t * ) ( m + out_seekd_1 ) = * ( uint64_t * ) ( ( char * ) out_seekd_back + m ) ;
2021-12-25 22:36:38 +01:00
}
}
else
{
2021-12-26 02:30:20 +01:00
decompressed_position + = LUT_0_VAL ;
2022-08-06 00:16:11 +02:00
* ( uint64_t * ) out_seekd_1 = * out_seekd_back ;
* ( uint64_t * ) ( out_seekd_1 + 8 ) = out_seekd_back [ 1 ] ;
2021-12-25 22:36:38 +01:00
}
}
2021-12-26 02:30:20 +01:00
if ( input_byte_pos > = some_size )
2021-12-25 22:36:38 +01:00
break ;
2021-12-26 02:30:20 +01:00
LABEL_26 :
2022-08-06 00:16:11 +02:00
v12 = ( * ( uint64_t * ) ( ( input_byte_pos & state - > m_nMask ) + state - > m_nInputBuf ) < < ( 64 - ( uint8_t ) byte_bit_offset ) ) | byte_new ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
if ( decompressed_position ! = state - > m_nDecompStreamSize )
goto LABEL_22 ;
decompressed_size = state - > m_nDecompSize ;
if ( decompressed_position = = decompressed_size )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
state - > input_byte_pos = input_byte_pos ;
2021-12-25 22:36:38 +01:00
result = 1 ;
2021-12-26 02:30:20 +01:00
state - > m_nDecompPosition = decompressed_position ;
return result ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
inv_mask_in = state - > m_nInvMaskIn ;
header_skip_bytes_bs = state - > header_skip_bytes_bs ;
2022-08-06 00:16:11 +02:00
v32 = inv_mask_in & - ( int64_t ) input_byte_pos ;
2021-12-26 02:30:20 +01:00
byte_new > > = 1 ;
+ + byte_bit_offset ;
if ( header_skip_bytes_bs > v32 )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
input_byte_pos + = v32 ;
v33 = state - > qword70 ;
if ( input_byte_pos > v33 )
state - > qword70 = inv_mask_in + v33 + 1 ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
v34 = input_byte_pos & state - > m_nMask ;
input_byte_pos + = header_skip_bytes_bs ;
stream_decompressed_size_new = decompressed_position + state - > m_nInvMaskOut + 1 ;
2022-08-06 00:16:11 +02:00
v36 = * ( uint64_t * ) ( v34 + state - > m_nInputBuf ) & ( ( 1LL < < ( 8 * ( uint8_t ) header_skip_bytes_bs ) ) - 1 ) ;
2022-02-13 17:07:02 +01:00
len_needed_new = v36 + state - > m_nLengthNeeded ;
2021-12-26 02:30:20 +01:00
stream_compressed_size_new = v36 + state - > m_nCompressedStreamSize ;
2022-02-13 17:07:02 +01:00
state - > m_nLengthNeeded = len_needed_new ;
2021-12-26 02:30:20 +01:00
state - > m_nCompressedStreamSize = stream_compressed_size_new ;
if ( stream_decompressed_size_new > = decompressed_size )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
stream_decompressed_size_new = decompressed_size ;
state - > m_nCompressedStreamSize = header_skip_bytes_bs + stream_compressed_size_new ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
state - > m_nDecompStreamSize = stream_decompressed_size_new ;
if ( inLen > = len_needed_new & & outLen > = stream_decompressed_size_new )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
LABEL_22 :
some_size = state - > qword70 ;
if ( input_byte_pos > = some_size )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
input_byte_pos = ~ state - > m_nInvMaskIn & ( input_byte_pos + 7 ) ;
some_size + = state - > m_nInvMaskIn + 1 ;
state - > qword70 = some_size ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
if ( state - > m_nCompressedStreamSize < some_size )
some_size = state - > m_nCompressedStreamSize ;
goto LABEL_26 ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
v68 = state - > qword70 ;
if ( input_byte_pos > = v68 )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
input_byte_pos = ~ inv_mask_in & ( input_byte_pos + 7 ) ;
state - > qword70 = v68 + inv_mask_in + 1 ;
2021-12-25 22:36:38 +01:00
}
2021-12-26 02:30:20 +01:00
state - > dword6C = dword6C ;
2021-12-25 22:36:38 +01:00
result = 0 ;
2021-12-26 02:30:20 +01:00
state - > input_byte_pos = input_byte_pos ;
state - > m_nDecompPosition = decompressed_position ;
state - > byte = byte_new ;
state - > byte_bit_offset = byte_bit_offset ;
2021-12-25 22:36:38 +01:00
return result ;
}
2022-03-28 18:47:11 +02:00
2022-08-18 02:15:23 +02:00
# if not defined DEDICATED
2022-06-19 18:07:43 +02:00
2022-07-08 23:18:15 +02:00
# pragma warning( push )
2022-07-20 14:54:59 +02:00
// Disable stack warning, tells us to move more data to the heap instead. Not really possible with 'initialData' here. Since its parallel processed.
// Also disable 6378, complains that there is no control path where it would use 'nullptr', if that happens 'Error' will be called though.
# pragma warning( disable : 6262 6387)
2022-07-20 11:27:42 +02:00
//----------------------------------------------------------------------------------
// Purpose: creates 2D texture and shader resource from textureHeader and imageData.
//----------------------------------------------------------------------------------
2022-10-13 21:59:06 +02:00
void RTech : : CreateDXTexture ( TextureHeader_t * textureHeader , int64_t imageData )
2022-06-19 18:07:43 +02:00
{
2022-10-13 21:59:06 +02:00
if ( textureHeader - > m_nDepth & & ! textureHeader - > m_nHeight ) // Return never gets hit. Maybe its some debug check?
2022-07-08 23:18:15 +02:00
return ;
__int64 initialData [ 4096 ] { } ;
2022-10-13 21:59:06 +02:00
textureHeader - > m_nTextureMipLevels = textureHeader - > m_nPermanentMipCount ;
2022-07-08 23:18:15 +02:00
2022-10-13 21:59:06 +02:00
const int totalStreamedMips = textureHeader - > m_nOptStreamedMipCount + textureHeader - > m_nStreamedMipCount ;
uint32_t mipLevel = textureHeader - > m_nPermanentMipCount + totalStreamedMips ;
2022-07-08 23:18:15 +02:00
if ( mipLevel ! = totalStreamedMips )
2022-06-19 18:07:43 +02:00
{
2022-07-08 23:18:15 +02:00
do
2022-06-19 18:07:43 +02:00
{
2022-07-08 23:18:15 +02:00
- - mipLevel ;
if ( textureHeader - > m_nArraySize )
2022-06-19 18:07:43 +02:00
{
2022-07-08 23:18:15 +02:00
int mipWidth = 0 ;
if ( textureHeader - > m_nWidth > > mipLevel > 1 )
mipWidth = ( textureHeader - > m_nWidth > > mipLevel ) - 1 ;
int mipHeight = 0 ;
if ( textureHeader - > m_nHeight > > mipLevel > 1 )
mipHeight = ( textureHeader - > m_nHeight > > mipLevel ) - 1 ;
2022-07-09 10:41:02 +02:00
2022-10-13 21:59:06 +02:00
uint8_t x = s_pBytesPerPixel [ textureHeader - > m_nImageFormat ] . first ;
uint8_t y = s_pBytesPerPixel [ textureHeader - > m_nImageFormat ] . second ;
2022-07-08 23:18:15 +02:00
2022-07-09 10:41:02 +02:00
uint32_t bytesPerPixelWidth = ( y + mipWidth ) > > ( y > > 1 ) ;
uint32_t bytesPerPixelHeight = ( y + mipHeight ) > > ( y > > 1 ) ;
uint32_t sliceWidth = x * ( y > > ( y > > 1 ) ) ;
2022-07-08 23:18:15 +02:00
2022-07-09 10:41:02 +02:00
uint32_t rowPitch = sliceWidth * bytesPerPixelWidth ;
uint32_t slicePitch = x * bytesPerPixelWidth * bytesPerPixelHeight ;
2022-07-08 23:18:15 +02:00
uint32_t subResourceEntry = mipLevel ;
for ( int i = 0 ; i < textureHeader - > m_nArraySize ; i + + )
2022-06-19 18:07:43 +02:00
{
2022-07-08 23:18:15 +02:00
uint32_t offsetCurrentResourceData = subResourceEntry < < 4u ;
* ( int64_t * ) ( ( uint8_t * ) initialData + offsetCurrentResourceData ) = imageData ;
2022-07-09 10:41:02 +02:00
* ( uint32_t * ) ( ( uint8_t * ) & initialData [ 1 ] + offsetCurrentResourceData ) = rowPitch ;
* ( uint32_t * ) ( ( uint8_t * ) & initialData [ 1 ] + offsetCurrentResourceData + 4 ) = slicePitch ;
2022-07-08 23:18:15 +02:00
2022-07-09 10:41:02 +02:00
imageData + = ( slicePitch + 15 ) & 0xFFFFFFF0 ;
2022-10-13 21:59:06 +02:00
subResourceEntry + = textureHeader - > m_nPermanentMipCount ;
2022-06-19 18:07:43 +02:00
}
2022-07-08 23:18:15 +02:00
}
} while ( mipLevel ! = totalStreamedMips ) ;
}
2022-10-13 21:59:06 +02:00
const DXGI_FORMAT dxgiFormat = s_TxtrToDxgiTable . at ( textureHeader - > m_nImageFormat ) ; // Get dxgi format
2022-07-08 23:19:53 +02:00
2022-07-08 23:18:15 +02:00
D3D11_TEXTURE2D_DESC textureDesc { } ;
textureDesc . Width = textureHeader - > m_nWidth > > mipLevel ;
textureDesc . Height = textureHeader - > m_nHeight > > mipLevel ;
2022-10-13 21:59:06 +02:00
textureDesc . MipLevels = textureHeader - > m_nPermanentMipCount ;
2022-07-08 23:18:15 +02:00
textureDesc . ArraySize = textureHeader - > m_nArraySize ;
textureDesc . Format = dxgiFormat ;
textureDesc . SampleDesc . Count = 1 ;
textureDesc . SampleDesc . Quality = 0 ;
2022-07-20 14:54:59 +02:00
textureDesc . Usage = textureHeader - > m_nCPUAccessFlag ! = 2 ? D3D11_USAGE_IMMUTABLE : D3D11_USAGE_DEFAULT ;
2022-07-08 23:18:15 +02:00
textureDesc . BindFlags = D3D11_BIND_SHADER_RESOURCE ;
textureDesc . MiscFlags = 0 ;
2022-08-06 00:16:11 +02:00
const uint32_t offsetStartResourceData = mipLevel < < 4u ;
const D3D11_SUBRESOURCE_DATA * subResData = ( D3D11_SUBRESOURCE_DATA * ) ( ( uint8_t * ) initialData + offsetStartResourceData ) ;
const HRESULT createTextureRes = ( * g_ppGameDevice ) - > CreateTexture2D ( & textureDesc , subResData , & textureHeader - > m_ppTexture ) ;
2022-07-10 13:24:48 +02:00
if ( createTextureRes < S_OK )
2022-10-13 21:59:06 +02:00
Error ( eDLL_T : : RTECH , EXIT_FAILURE , " Couldn't create texture \" %s \" : error code %08x \n " , textureHeader - > m_pDebugName , createTextureRes ) ;
2022-07-08 23:18:15 +02:00
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResource { } ;
shaderResource . Format = dxgiFormat ;
shaderResource . Texture2D . MipLevels = textureHeader - > m_nTextureMipLevels ;
if ( textureHeader - > m_nArraySize > 1 ) // Do we have a texture array?
{
shaderResource . Texture2DArray . FirstArraySlice = 0 ;
shaderResource . Texture2DArray . ArraySize = textureHeader - > m_nArraySize ;
shaderResource . ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY ;
}
else
{
shaderResource . ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D ;
2022-06-19 18:07:43 +02:00
}
2022-08-06 00:16:11 +02:00
const HRESULT createShaderResourceRes = ( * g_ppGameDevice ) - > CreateShaderResourceView ( textureHeader - > m_ppTexture , & shaderResource , & textureHeader - > m_ppShaderResourceView ) ;
2022-07-10 13:24:48 +02:00
if ( createShaderResourceRes < S_OK )
2022-10-13 21:59:06 +02:00
Error ( eDLL_T : : RTECH , EXIT_FAILURE , " Couldn't create shader resource view for texture \" %s \" : error code %08x \n " , textureHeader - > m_pDebugName , createShaderResourceRes ) ;
2022-07-08 23:18:15 +02:00
}
# pragma warning( pop )
2022-06-19 18:07:43 +02:00
# endif
2022-07-04 22:52:10 +02:00
# ifndef DEDICATED
2022-08-06 00:16:11 +02:00
//----------------------------------------------------------------------------------
2022-09-09 19:47:31 +02:00
// Purpose: start loading shader sets, assign vftable pointer
2022-08-06 00:16:11 +02:00
//----------------------------------------------------------------------------------
2022-07-04 22:52:10 +02:00
void * * RTech : : LoadShaderSet ( void * * VTablePtr )
{
2022-08-15 22:29:16 +02:00
* VTablePtr = & g_pShaderGlueVFTable ;
return & g_pShaderGlueVFTable ;
2022-07-04 22:52:10 +02:00
}
# endif
2022-08-06 00:16:11 +02:00
//----------------------------------------------------------------------------------
// Purpose: open a file and add it to m_FileHandles.
//----------------------------------------------------------------------------------
2022-08-18 12:34:33 +02:00
int32_t RTech : : OpenFile ( const CHAR * szFilePath , void * unused , LONGLONG * fileSizeOut )
2022-08-06 00:16:11 +02:00
{
2022-08-18 12:34:33 +02:00
string svModFile = szFilePath ;
string svBaseFile = szFilePath ;
const string svModDir = " paks \\ Win32 \\ " ;
const string svBaseDir = " paks \\ Win64 \\ " ;
2022-08-22 14:43:06 +02:00
if ( strstr ( ConvertToWinPath ( szFilePath ) . c_str ( ) , svBaseDir . c_str ( ) ) )
2022-08-18 12:34:33 +02:00
{
svBaseFile . erase ( 0 , 11 ) ; // Erase 'base_dir'.
svModFile = svModDir + svBaseFile ; // Prepend 'mod_dir'.
if ( ! FileExists ( svModFile ) )
{
svModFile = szFilePath ;
}
}
const HANDLE hFile = CreateFileA ( svModFile . c_str ( ) , GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_DELETE , 0 , OPEN_EXISTING , FILE_SUPPORTS_GHOSTING , 0 ) ;
2022-08-06 00:16:11 +02:00
if ( hFile = = INVALID_HANDLE_VALUE )
return - 1 ;
2022-08-22 21:15:46 +02:00
if ( rtech_debug - > GetBool ( ) )
DevMsg ( eDLL_T : : RTECH , " Opened file: '%s' \n " , svModFile . c_str ( ) ) ;
2022-08-22 14:43:06 +02:00
2022-08-06 00:16:11 +02:00
if ( fileSizeOut )
{
LARGE_INTEGER fileSize { } ;
if ( GetFileSizeEx ( hFile , & fileSize ) )
* fileSizeOut = fileSize . QuadPart ;
}
AcquireSRWLockExclusive ( reinterpret_cast < PSRWLOCK > ( & * g_pPakFileSlotLock ) ) ;
2022-08-06 00:20:49 +02:00
const int32_t fileIdx = RTech_FindFreeSlotInFiles ( s_pFileArray ) ;
2022-08-06 00:16:11 +02:00
ReleaseSRWLockExclusive ( reinterpret_cast < PSRWLOCK > ( & * g_pPakFileSlotLock ) ) ;
2022-08-06 22:17:47 +02:00
const int32_t fileHandleIdx = ( fileIdx & 0x3FF ) ; // Something with ArraySize.
2022-08-06 00:16:11 +02:00
2022-08-06 00:20:49 +02:00
m_FileHandles - > self [ fileHandleIdx ] . m_nFileNumber = fileIdx ;
m_FileHandles - > self [ fileHandleIdx ] . m_hFileHandle = hFile ;
m_FileHandles - > self [ fileHandleIdx ] . m_nCurOfs = 1 ;
2022-08-06 00:16:11 +02:00
2022-08-06 00:20:49 +02:00
return fileIdx ;
2022-08-06 00:16:11 +02:00
}
2022-04-18 03:35:08 +02:00
//-----------------------------------------------------------------------------
2022-05-19 00:53:58 +02:00
// Purpose: gets information about loaded pak file via pak ID
2022-04-18 03:35:08 +02:00
//-----------------------------------------------------------------------------
2022-08-29 17:00:50 +02:00
RPakLoadedInfo_t * RTech : : GetPakLoadedInfo ( RPakHandle_t nHandle )
2022-03-28 18:47:11 +02:00
{
2022-08-11 11:07:45 +02:00
for ( int16_t i = 0 ; i < * s_pLoadedPakCount ; + + i )
2022-03-28 18:47:11 +02:00
{
2022-05-19 00:47:16 +02:00
RPakLoadedInfo_t * info = & g_pLoadedPakInfo [ i ] ;
if ( ! info )
continue ;
2022-03-28 18:47:11 +02:00
2022-08-29 17:00:50 +02:00
if ( info - > m_nHandle ! = nHandle )
2022-03-28 18:47:11 +02:00
continue ;
return info ;
}
2022-08-29 17:00:50 +02:00
Warning ( eDLL_T : : RTECH , " %s - Failed to retrieve pak info for handle '%d' \n " , __FUNCTION__ , nHandle ) ;
2022-05-19 00:47:16 +02:00
return nullptr ;
}
//-----------------------------------------------------------------------------
2022-05-19 00:53:58 +02:00
// Purpose: gets information about loaded pak file via pak name
2022-05-19 00:47:16 +02:00
//-----------------------------------------------------------------------------
RPakLoadedInfo_t * RTech : : GetPakLoadedInfo ( const char * szPakName )
{
2022-08-11 11:07:45 +02:00
for ( int16_t i = 0 ; i < * s_pLoadedPakCount ; + + i )
2022-05-19 00:47:16 +02:00
{
RPakLoadedInfo_t * info = & g_pLoadedPakInfo [ i ] ;
if ( ! info )
continue ;
if ( ! info - > m_pszFileName | | ! * info - > m_pszFileName )
continue ;
if ( strcmp ( szPakName , info - > m_pszFileName ) ! = 0 )
continue ;
return info ;
}
2022-08-29 17:00:50 +02:00
Warning ( eDLL_T : : RTECH , " %s - Failed to retrieve pak info for name '%s' \n " , __FUNCTION__ , szPakName ) ;
2022-05-19 00:47:16 +02:00
return nullptr ;
2022-03-28 18:47:11 +02:00
}
2022-06-19 18:07:43 +02:00
2022-10-30 20:17:50 +01:00
//-----------------------------------------------------------------------------
// Purpose: process guid relations for asset
//-----------------------------------------------------------------------------
void RTech : : PakProcessGuidRelationsForAsset ( PakFile_t * pPak , RPakAssetEntry * pAsset )
{
RPakDescriptor * pGuidDescriptors = & pPak - > m_pGuidDescriptors [ pAsset - > m_nUsesStartIdx ] ;
volatile uint32_t * v5 = reinterpret_cast < volatile uint32_t * > ( * ( reinterpret_cast < uint64_t * > ( g_pUnknownPakStruct ) + 0x17 * ( pPak - > qword578 & 0x1FF ) + 0x160212 ) ) ;
if ( rtech_debug - > GetBool ( ) )
DevMsg ( eDLL_T : : RTECH , " Processing GUID relations for asset '0x%-16llX' in pak '%-32s'. Uses: %-4i \n " , pAsset - > m_Guid , pPak - > m_pszFileName , pAsset - > m_nUsesCount ) ;
for ( uint64_t i = 0 ; i < pAsset - > m_nUsesCount ; i + + )
{
void * * pCurrentGuid = reinterpret_cast < void * * > ( pPak - > m_ppPagePointers [ pGuidDescriptors [ i ] . m_Index ] + pGuidDescriptors [ i ] . m_Offset ) ;
// Get current guid.
uint64_t currentGuid = reinterpret_cast < uint64_t > ( * pCurrentGuid ) ;
// Get asset index.
int assetIdx = currentGuid & 0x3FFFF ;
uint64_t assetIdxEntryGuid = g_pUnknownPakStruct - > m_Assets [ assetIdx ] . m_Guid ;
int64_t v9 = 2 i64 * InterlockedExchangeAdd ( v5 , 1u ) ;
* ( uint64_t * ) & v5 [ 2 * v9 + 2 ] = currentGuid ;
* ( uint64_t * ) & v5 [ 2 * v9 + 4 ] = pAsset - > m_Guid ;
std : : function < bool ( bool ) > fnCheckAsset = [ & ] ( bool shouldCheckTwo )
{
while ( true )
{
if ( shouldCheckTwo & & assetIdxEntryGuid = = 2 )
{
if ( pPak - > m_PakHdr . m_nAssetEntryCount )
return false ;
}
assetIdx + + ;
assetIdx & = 0x3FFFF ;
assetIdxEntryGuid = g_pUnknownPakStruct - > m_Assets [ assetIdx ] . m_Guid ;
// Check if we have a deadlock and report it if we have rtech_debug enabled.
if ( rtech_debug - > GetBool ( ) & & assetIdx > 0x40000 )
{
DevMsg ( eDLL_T : : RTECH , " Possible deadlock detected in fnCheckAsset for asset '0x%-16llX' in pak '%-32s'. Uses: %-4i | assetIdxEntryGuid: '0x%-16llX' | currentGuid: '0x%-16llX' \n " , pAsset - > m_Guid , pPak - > m_pszFileName , pAsset - > m_nUsesCount , assetIdxEntryGuid , currentGuid ) ;
if ( IsDebuggerPresent ( ) )
DebugBreak ( ) ;
}
if ( assetIdxEntryGuid = = currentGuid )
return true ;
}
} ;
if ( assetIdxEntryGuid ! = currentGuid )
{
// Are we some special asset with the guid 2?
if ( ! fnCheckAsset ( true ) )
{
RPakAssetEntry * assetEntries = pPak - > m_pAssetEntries ;
uint64_t a ; for ( a = 0 ; assetEntries - > m_Guid ! = currentGuid ; a + + , assetEntries + + )
{
if ( a > = pPak - > m_PakHdr . m_nAssetEntryCount )
{
fnCheckAsset ( false ) ;
break ;
}
}
assetIdx = pPak - > qword580 [ a ] ;
}
}
// Finally write the pointer to the guid entry.
* pCurrentGuid = g_pUnknownPakStruct - > m_Assets [ assetIdx ] . m_pHead ;
}
}
2022-06-19 18:07:43 +02:00
void RTech_Utils_Attach ( )
{
2022-08-18 12:34:33 +02:00
DetourAttach ( ( LPVOID * ) & RTech_OpenFile , & RTech : : OpenFile ) ;
2022-08-06 00:16:11 +02:00
2022-10-30 20:17:50 +01:00
# ifdef GAMEDLL_S3
DetourAttach ( ( LPVOID * ) & RTech_Pak_ProcessGuidRelationsForAsset , & RTech : : PakProcessGuidRelationsForAsset ) ;
# endif
2022-08-18 02:15:23 +02:00
# if not defined DEDICATED && defined GAMEDLL_S3
2022-07-08 22:33:43 +01:00
DetourAttach ( ( LPVOID * ) & RTech_CreateDXTexture , & RTech : : CreateDXTexture ) ;
2022-08-18 02:15:23 +02:00
# endif // !DEDICATED
2022-06-19 18:07:43 +02:00
}
void RTech_Utils_Detach ( )
{
2022-08-18 12:34:33 +02:00
DetourDetach ( ( LPVOID * ) & RTech_OpenFile , & RTech : : OpenFile ) ;
2022-08-06 00:16:11 +02:00
2022-10-30 20:17:50 +01:00
# ifdef GAMEDLL_S3
DetourDetach ( ( LPVOID * ) & RTech_Pak_ProcessGuidRelationsForAsset , & RTech : : PakProcessGuidRelationsForAsset ) ;
# endif
2022-08-18 02:15:23 +02:00
# if not defined DEDICATED && defined GAMEDLL_S3
2022-07-08 22:33:43 +01:00
DetourDetach ( ( LPVOID * ) & RTech_CreateDXTexture , & RTech : : CreateDXTexture ) ;
2022-08-18 02:15:23 +02:00
# endif // !DEDICATED
2022-06-19 18:07:43 +02:00
}
2021-12-25 22:36:38 +01:00
///////////////////////////////////////////////////////////////////////////////
2022-03-28 18:47:11 +02:00
RTech * g_pRTech = new RTech ( ) ;