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-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 = 0i64;
|
|
|
|
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)(0xFB8C4D96501i64 * v6) >> 24) + 0x633D5F1 * v2) >> 61) ^ (((uint64_t)(0xFB8C4D96501i64 * 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 + ((0xFB8C4D96501i64 * (uint64_t)(v4 & v10)) >> 24) - 0xAE502812AA7333i64 * (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 = 0i64;
|
|
|
|
state->m_nOutMask = 0i64;
|
|
|
|
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 & ((1i64 << decompressed_size_bits) - 1) | (1i64 << 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 = (0xFFFFFFFFFFFFFFFFui64 >> ((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 = 0xFFFFFFFFFFFFFFFFui64 >> (64 - (uint8_t)brih_bits);
|
2021-12-26 02:30:20 +01:00
|
|
|
state->m_nInvMaskIn = inv_mask_in;
|
|
|
|
state->m_nInvMaskOut = 0xFFFFFFFFFFFFFFFFui64 >> (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 = (0xFFFFFFFFFFFFFFFFui64 >> byte_bit_offset_final) & byte_final_full;
|
|
|
|
state->input_byte_pos = input_byte_pos_final;
|
|
|
|
if (inv_mask_in == -1i64)
|
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 & ((1i64 << (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 - 6i64;
|
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 = (0xFFFFFFFFFFFFFFFFui64 >> 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-08-06 00:16:11 +02:00
|
|
|
LUT_200_val = LUT_200[(uint8_t)byte + dword6c_shl8];// LUT_200 - u8 - ammount of bits
|
|
|
|
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;
|
|
|
|
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
|
|
|
{
|
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
|
|
|
|
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
|
|
|
{
|
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???
|
|
|
|
v22 = 1 << (byte_4bits_1 + ((byte_new >> 4) & ((24 * (((uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 2)) >> 4)));// ammount of bits to read???
|
|
|
|
byte_bit_offset += (((uint32_t)(byte_4bits_1 + 0xFFFFFFE1) >> 3) & 6)// shit shit gets shifted by ammount 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 -= 13i64;
|
|
|
|
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 = 0i64;
|
2022-08-06 00:16:11 +02:00
|
|
|
for (k = 0x101010101010101i64 * 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-08-06 00:16:11 +02:00
|
|
|
*(uint8_t*)out_seekd_1 = v53[out_seekd_1];// seekd = 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 = 0i64; (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-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;
|
|
|
|
|
2022-08-06 00:16:11 +02:00
|
|
|
const int totalStreamedMips = textureHeader->m_nMipLevelsStreamedOpt + textureHeader->m_nMipLevelsStreamed;
|
2022-07-08 23:18:15 +02:00
|
|
|
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-08-06 00:16:11 +02:00
|
|
|
const DXGI_FORMAT dxgiFormat = rpakToDxgiFormat[textureHeader->m_nFormat]; // 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;
|
|
|
|
textureDesc.MipLevels = textureHeader->m_nMipLevels;
|
|
|
|
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-08-22 12:42:41 +02:00
|
|
|
Error(eDLL_T::RTECH, true, "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-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-08-22 12:42:41 +02:00
|
|
|
Error(eDLL_T::RTECH, true, "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
|
2022-08-06 00:16:11 +02:00
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Purpose: start loading shader sets, assign vtable pointer
|
|
|
|
//----------------------------------------------------------------------------------
|
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
|
|
|
|
|
|
|
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-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-06 00:16:11 +02:00
|
|
|
// [ PIXIE ]: Everything related to RTech::OpenFile should be compatible across seasons.
|
2022-08-18 12:34:33 +02:00
|
|
|
DetourDetach((LPVOID*)&RTech_OpenFile, &RTech::OpenFile);
|
2022-08-06 00:16:11 +02:00
|
|
|
|
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();
|