2021-12-25 22:36:38 +01:00
# include "core/stdafx.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-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
//-----------------------------------------------------------------------------
std : : uint64_t __fastcall RTech : : StringToGuid ( const char * pData )
{
std : : uint32_t * v1 ; // r8
std : : uint64_t v2 ; // r10
2021-12-26 02:30:20 +01:00
std : : int32_t v3 ; // er11
2021-12-25 22:36:38 +01:00
std : : uint32_t v4 ; // er9
std : : uint32_t i ; // edx
std : : uint64_t v6 ; // rcx
2021-12-26 02:30:20 +01:00
std : : int32_t v7 ; // er9
std : : int32_t v8 ; // edx
std : : int32_t v9 ; // eax
2021-12-25 22:36:38 +01:00
std : : uint32_t v10 ; // er8
2021-12-26 02:30:20 +01:00
std : : int32_t v12 ; // ecx
2021-12-25 22:36:38 +01:00
std : : uint32_t * a1 = ( std : : uint32_t * ) pData ;
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 ;
v2 = ( ( ( ( std : : uint64_t ) ( 0xFB8C4D96501 i64 * v6 ) > > 24 ) + 0x633D5F1 * v2 ) > > 61 ) ^ ( ( ( std : : uint64_t ) ( 0xFB8C4D96501 i64 * v6 ) > > 24 )
+ 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 ;
}
return 0x633D5F1 * v2 + ( ( 0xFB8C4D96501 i64 * ( std : : uint64_t ) ( v4 & v10 ) ) > > 24 ) - 0xAE502812AA7333 i64 * ( std : : uint32_t ) ( v3 + v9 / 8 ) ;
}
//-----------------------------------------------------------------------------
// Purpose: calculate 'decompressed' size and commit parameters
//-----------------------------------------------------------------------------
2022-06-17 18:42:13 +02:00
std : : uint64_t __fastcall RTech : : DecompressPakFileInit ( RPakDecompState_t * state , std : : uint8_t * fileBuffer , std : : uint64_t fileSize , std : : uint64_t offNoHeader , std : : uint64_t headerSize )
2021-12-25 22:36:38 +01:00
{
2022-06-17 18:42:13 +02:00
std : : int64_t input_byte_pos_init ; // r9
std : : uint64_t byte_init ; // r11
std : : int32_t decompressed_size_bits ; // ecx
std : : int64_t byte_1_low ; // rdi
std : : uint64_t input_byte_pos_1 ; // r10
std : : uint32_t bit_pos_final ; // ebp
std : : uint64_t byte_1 ; // rdi
std : : uint32_t brih_bits ; // er11
std : : uint64_t inv_mask_in ; // r8
std : : uint64_t byte_final_full ; // rbx
std : : uint64_t bit_pos_final_1 ; // rax
std : : int32_t byte_bit_offset_final ; // ebp
std : : uint64_t input_byte_pos_final ; // r10
std : : uint64_t byte_final ; // rbx
std : : uint32_t brih_bytes ; // er11
std : : uint64_t byte_tmp ; // rdx
std : : uint64_t stream_len_needed ; // r14
std : : uint64_t result ; // rax
std : : uint64_t inv_mask_out ; // r8
std : : uint64_t qw70 ; // rcx
std : : uint64_t stream_compressed_size_new ; // rdx
2021-12-26 02:30:20 +01:00
const std : : uintptr_t mask = UINT64_MAX ;
const std : : uintptr_t file_buf = std : : uintptr_t ( fileBuffer ) ;
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 ;
byte_init = * ( std : : uint64_t * ) ( ( mask & ( offNoHeader + headerSize ) ) + file_buf ) ;
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 ) ;
byte_1_low = * ( std : : uint64_t * ) ( ( mask & input_byte_pos_init ) + file_buf ) < < ( 64
- ( ( std : : uint8_t ) decompressed_size_bits
+ 6 ) ) ;
input_byte_pos_1 = input_byte_pos_init + ( ( std : : uint64_t ) ( std : : uint32_t ) ( decompressed_size_bits + 6 ) > > 3 ) ;
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 ) ;
brih_bits = ( ( ( std : : uint8_t ) byte_1 - 1 ) & 0x3F ) + 1 ;
inv_mask_in = 0xFFFFFFFFFFFFFFFFu i64 > > ( 64 - ( std : : uint8_t ) brih_bits ) ;
state - > m_nInvMaskIn = inv_mask_in ;
state - > m_nInvMaskOut = 0xFFFFFFFFFFFFFFFFu i64 > > ( 63 - ( ( ( byte_1 > > 6 ) - 1 ) & 0x3F ) ) ;
byte_final_full = ( byte_1 > > 13 ) | ( * ( std : : uint64_t * ) ( ( mask & input_byte_pos_1 ) + file_buf ) < < ( 64
- ( std : : uint8_t ) bit_pos_final ) ) ;
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 ;
byte_tmp = * ( std : : uint64_t * ) ( ( mask & input_byte_pos_final ) + file_buf ) ;
state - > input_byte_pos = input_byte_pos_final + brih_bytes + 1 ;
stream_len_needed = byte_tmp & ( ( 1 i64 < < ( 8 * ( ( std : : 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-02-13 17:07:02 +01:00
std : : uint8_t __fastcall RTech : : DecompressPakFile ( RPakDecompState_t * state , std : : uint64_t inLen , std : : uint64_t outLen )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
std : : uint64_t decompressed_position ; // r15
std : : uint32_t byte_bit_offset ; // ebp
std : : uint64_t byte ; // rsi
std : : uint64_t input_byte_pos ; // rdi
std : : uint64_t some_size ; // r12
std : : uint32_t dword6C ; // ecx MAPDST
std : : uint64_t v12 ; // rsi
std : : uint64_t i ; // rax
std : : uint64_t dword6c_shl8 ; // r8
std : : int64_t dword6c_old ; // r9
std : : int32_t LUT_200_val ; // ecx
std : : uint64_t v17 ; // rax
std : : uint64_t byte_new ; // rsi
std : : int64_t LUT_0_VAL ; // r14
std : : int32_t byte_4bits_1 ; // ecx
std : : uint64_t v21 ; // r11
std : : int32_t v22 ; // edx
std : : uint64_t out_mask ; // rax
std : : int32_t v24 ; // er8
std : : uint32_t LUT_400_seek_backwards ; // er13
std : : uint64_t out_seek_back ; // r10
std : : uint64_t out_seekd_1 ; // rax
std : : uint64_t * out_seekd_back ; // r10
std : : uint64_t decompressed_size ; // r9
std : : uint64_t inv_mask_in ; // r10
std : : uint64_t header_skip_bytes_bs ; // r8
std : : uint64_t v32 ; // rax
std : : uint64_t v33 ; // rax
std : : uint64_t v34 ; // rax
std : : uint64_t stream_decompressed_size_new ; // rcx
std : : int64_t v36 ; // rdx
std : : uint64_t len_needed_new ; // r14
std : : uint64_t stream_compressed_size_new ; // r11
char v39 ; // cl MAPDST
std : : uint64_t v40 ; // rsi MAPDST
uint64_t v46 ; // rcx
std : : int64_t v47 ; // r9
std : : int64_t m ; // r8
std : : uint32_t v49 ; // er9
std : : int64_t v50 ; // r8
std : : int64_t v51 ; // rdx
std : : int64_t k ; // r8
char * v53 ; // r10
std : : int64_t v54 ; // rdx
std : : uint32_t lut0_val_abs ; // er14
std : : int64_t * in_seekd ; // rdx
std : : int64_t * out_seekd ; // r8
std : : int64_t byte_3bits ; // rax MAPDST
std : : uint64_t byte_new_tmp ; // r9 MAPDST
std : : int32_t LUT_4D0_480 ; // er10 MAPDST
std : : uint8_t LUT_4D8_4C0_nBits ; // cl MAPDST
std : : uint64_t byte_4bits ; // rax MAPDST
std : : uint32_t copy_bytes_ammount ; // er14
std : : uint32_t j ; // ecx
std : : int64_t v67 ; // rax
std : : uint64_t v68 ; // rcx
std : : uint8_t result ; // al
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 ;
v12 = ( * ( std : : uint64_t * ) ( ( input_byte_pos & state - > m_nMask ) + state - > m_nInputBuf ) < < ( 64 - ( std : : uint8_t ) byte_bit_offset ) ) | byte ;
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 :
dword6c_shl8 = ( std : : uint64_t ) dword6C < < 8 ;
dword6c_old = dword6C ;
LUT_200_val = LUT_200 [ ( std : : uint8_t ) byte + dword6c_shl8 ] ; // LUT_200 - u8 - ammount of bits
v17 = ( std : : uint8_t ) byte + dword6c_shl8 ;
byte_bit_offset + = LUT_200_val ;
byte_new = byte > > LUT_200_val ;
LUT_0_VAL = LUT_0 [ v17 ] ; // LUT_0 - i32 - signed, ammount of bytes
if ( LUT_0_VAL < 0 )
2021-12-25 22:36:38 +01:00
{
2021-12-26 02:30:20 +01:00
lut0_val_abs = - ( std : : int32_t ) LUT_0_VAL ;
in_seekd = ( std : : int64_t * ) ( state - > m_nInputBuf + ( input_byte_pos & state - > m_nMask ) ) ;
dword6C = 1 ;
out_seekd = ( std : : int64_t * ) ( state - > m_nOut + ( decompressed_position & state - > m_nOutMask ) ) ;
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
LUT_4D8_4C0_nBits = LUT_4D8 [ byte_3bits ] ; // LUT_4D8 - u8 - ammount 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
LUT_4D8_4C0_nBits = LUT_4C0 [ byte_4bits ] ; // LUT_4C0 - u8 - ammount 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
{
2021-12-26 02:30:20 +01:00
* ( std : : uint32_t * ) out_seekd = * ( std : : uint32_t * ) in_seekd ;
out_seekd = ( std : : int64_t * ) ( ( char * ) out_seekd + 4 ) ;
in_seekd = ( std : : 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
{
2021-12-26 02:30:20 +01:00
* ( std : : uint16_t * ) out_seekd = * ( std : : uint16_t * ) in_seekd ;
out_seekd = ( std : : int64_t * ) ( ( char * ) out_seekd + 2 ) ;
in_seekd = ( std : : 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
* ( std : : uint8_t * ) out_seekd = * ( std : : uint8_t * ) in_seekd ;
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 ;
v21 = ( ( std : : uint64_t ) ( std : : uint32_t ) byte_new > > ( ( ( std : : uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 6 ) ) & 0x3F ; // 6 bits after shift for who knows how much???
v22 = 1 < < ( byte_4bits_1 + ( ( byte_new > > 4 ) & ( ( 24 * ( ( ( std : : uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 2 ) ) > > 4 ) ) ) ; // ammount of bits to read???
byte_bit_offset + = ( ( ( std : : uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 6 ) // shit shit gets shifted by ammount of bits it read or something
+ LUT_440 [ v21 ]
+ byte_4bits_1
+ ( ( byte_new > > 4 ) & ( ( 24 * ( ( ( std : : uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 2 ) ) > > 4 ) ) ;
out_mask = state - > m_nOutMask ;
v24 = 16
* ( v22
+ ( ( v22 - 1 ) & ( byte_new > > ( ( ( ( std : : uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 6 )
+ LUT_440 [ v21 ] ) ) ) ) ;
byte_new > > = ( ( ( std : : uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 6 )
+ LUT_440 [ v21 ]
+ byte_4bits_1
+ ( ( byte_new > > 4 ) & ( ( 24 * ( ( ( std : : uint32_t ) ( byte_4bits_1 + 0xFFFFFFE1 ) > > 3 ) & 2 ) ) > > 4 ) ) ;
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 ) ;
out_seekd_back = ( std : : uint64_t * ) ( state - > m_nOut + out_seek_back ) ;
if ( ( std : : 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 ;
byte_new_tmp | = ( std : : uint64_t ) * ( std : : uint8_t * ) ( v46 + state - > m_nInputBuf ) < < ( 61
- ( std : : uint8_t ) byte_bit_offset ) ;
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 ;
v47 = ( ( std : : uint32_t ) byte_new_tmp & ( ( 1 < < LUT_4D8_4C0_nBits ) - 1 ) ) + LUT_4D0_480 + 17 ;
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
{
2021-12-26 02:30:20 +01:00
v50 = * ( std : : uint8_t * ) out_seekd_back ;
v51 = 0 i64 ;
for ( k = 0x101010101010101 i64 * v50 ; ( std : : uint32_t ) v51 < v49 ; v51 = ( std : : uint32_t ) ( v51 + 8 ) )
* ( std : : 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
{
2021-12-26 02:30:20 +01:00
* ( std : : uint8_t * ) out_seekd_1 = v53 [ out_seekd_1 ] ; // seekd = seek_back; increment ptrs
+ + out_seekd_1 ;
- - v54 ;
} while ( v54 ) ;
2021-12-25 22:36:38 +01:00
}
}
}
else
{
2021-12-26 02:30:20 +01:00
for ( m = 0 i64 ; ( std : : uint32_t ) m < ( std : : uint32_t ) v47 ; m = ( std : : uint32_t ) ( m + 8 ) )
* ( std : : uint64_t * ) ( m + out_seekd_1 ) = * ( std : : 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 ;
* ( std : : uint64_t * ) out_seekd_1 = * out_seekd_back ;
* ( std : : 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 :
v12 = ( * ( std : : uint64_t * ) ( ( input_byte_pos & state - > m_nMask ) + state - > m_nInputBuf ) < < ( 64 - ( std : : 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 ;
v32 = inv_mask_in & - ( std : : int64_t ) input_byte_pos ;
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 ;
v36 = * ( std : : uint64_t * ) ( v34 + state - > m_nInputBuf ) & ( ( 1LL < < ( 8 * ( std : : 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-06-19 18:07:43 +02:00
# if not defined DEDICATED && defined (GAMEDLL_S3)
2022-07-08 23:18:15 +02:00
# pragma warning( push )
2022-07-09 10:41:02 +02:00
# pragma warning( disable : 6262 ) // Disable stack warning, tells us to move more data to the heap instead. Not really possible with 'initialData' here. Since its parallel processed.
2022-07-08 23:18:15 +02:00
void RTech : : CreateDXTexture ( RTechTextureInfo_t * textureHeader , int64_t imageData )
2022-06-19 18:07:43 +02:00
{
2022-07-09 10:41:02 +02:00
if ( textureHeader - > unk0 & & ! textureHeader - > m_nHeight ) // Return never gets hit. Maybe its some debug check?
2022-07-08 23:18:15 +02:00
return ;
__int64 initialData [ 4096 ] { } ;
textureHeader - > m_nTextureMipLevels = textureHeader - > m_nMipLevels ;
int totalStreamedMips = textureHeader - > m_nMipLevelsStreamedOpt + textureHeader - > m_nMipLevelsStreamed ;
uint32_t mipLevel = textureHeader - > m_nMipLevels + totalStreamedMips ;
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-07-10 13:11:48 +02:00
uint8_t x = s_pRTechBytesPerPixel [ textureHeader - > m_nFormat ] . first ;
uint8_t y = s_pRTechBytesPerPixel [ textureHeader - > m_nFormat ] . 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-07-08 23:18:15 +02:00
subResourceEntry + = textureHeader - > m_nMipLevels ;
2022-06-19 18:07:43 +02:00
}
2022-07-08 23:18:15 +02:00
}
} while ( mipLevel ! = totalStreamedMips ) ;
}
2022-07-08 23:19:53 +02:00
DXGI_FORMAT dxgiFormat = rpakToDxgiFormat [ textureHeader - > m_nFormat ] ; // Get dxgi format
2022-07-08 23:18:15 +02:00
D3D11_TEXTURE2D_DESC textureDesc { } ;
textureDesc . Width = textureHeader - > m_nWidth > > mipLevel ;
textureDesc . Height = textureHeader - > m_nHeight > > mipLevel ;
textureDesc . MipLevels = textureHeader - > m_nMipLevels ;
textureDesc . ArraySize = textureHeader - > m_nArraySize ;
textureDesc . Format = dxgiFormat ;
textureDesc . SampleDesc . Count = 1 ;
textureDesc . SampleDesc . Quality = 0 ;
textureDesc . Usage = ( D3D11_USAGE ) ( textureHeader - > unk2 ! = 2 ) ;
textureDesc . BindFlags = D3D11_BIND_SHADER_RESOURCE ;
textureDesc . MiscFlags = 0 ;
uint32_t offsetStartResourceData = mipLevel < < 4u ;
D3D11_SUBRESOURCE_DATA * subResData = ( D3D11_SUBRESOURCE_DATA * ) ( ( uint8_t * ) initialData + offsetStartResourceData ) ;
2022-07-10 13:24:48 +02:00
HRESULT createTextureRes = ( * g_ppGameDevice ) - > CreateTexture2D ( & textureDesc , subResData , & textureHeader - > m_ppTexture ) ;
if ( createTextureRes < S_OK )
Error ( eDLL_T : : RTECH , " Couldn't create texture \" %s \" : error code %08x \n " , textureHeader - > m_nDebugName , 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-07-10 13:24:48 +02:00
HRESULT createShaderResourceRes = ( * g_ppGameDevice ) - > CreateShaderResourceView ( textureHeader - > m_ppTexture , & shaderResource , & textureHeader - > m_ppShaderResourceView ) ;
if ( createShaderResourceRes < S_OK )
Error ( eDLL_T : : RTECH , " Couldn't create shader resource view for texture \" %s \" : error code %08x \n " , textureHeader - > m_nDebugName , 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
void * * RTech : : LoadShaderSet ( void * * VTablePtr )
{
* VTablePtr = & g_pCShaderGlue_VTable ;
return & g_pCShaderGlue_VTable ;
}
# endif
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-05-19 00:47:16 +02:00
RPakLoadedInfo_t * RTech : : GetPakLoadedInfo ( int nPakId )
2022-03-28 18:47:11 +02:00
{
for ( int i = 0 ; i < * s_pLoadedPakCount ; + + i )
{
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-05-19 00:47:16 +02:00
if ( info - > m_nPakId ! = nPakId )
2022-03-28 18:47:11 +02:00
continue ;
return info ;
}
2022-03-28 19:34:51 +02:00
Warning ( eDLL_T : : RTECH , " %s - Failed getting RPakLoadInfo_t for PakId '%d' \n " , __FUNCTION__ , nPakId ) ;
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 )
{
for ( int i = 0 ; i < * s_pLoadedPakCount ; + + i )
{
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 ;
}
Warning ( eDLL_T : : RTECH , " %s - Failed getting RPakLoadInfo_t for Pak '%s' \n " , __FUNCTION__ , szPakName ) ;
return nullptr ;
2022-03-28 18:47:11 +02:00
}
2022-06-19 18:07:43 +02:00
void RTech_Utils_Attach ( )
{
2022-07-08 23:50:38 +02:00
# if not defined DEDICATED && defined (GAMEDLL_S3)
2022-07-08 22:33:43 +01:00
DetourAttach ( ( LPVOID * ) & RTech_CreateDXTexture , & RTech : : CreateDXTexture ) ;
2022-06-19 18:07:43 +02:00
# endif
}
void RTech_Utils_Detach ( )
{
2022-07-08 23:50:38 +02:00
# if not defined DEDICATED && defined (GAMEDLL_S3)
2022-07-08 22:33:43 +01:00
DetourDetach ( ( LPVOID * ) & RTech_CreateDXTexture , & RTech : : CreateDXTexture ) ;
2022-06-19 18:07:43 +02:00
# endif
}
2021-12-25 22:36:38 +01:00
///////////////////////////////////////////////////////////////////////////////
2022-03-28 18:47:11 +02:00
RTech * g_pRTech = new RTech ( ) ;