Merge remote-tracking branch 'origin/develop' into jenkins
This commit is contained in:
commit
0aa337f219
2
deps/fmt
vendored
2
deps/fmt
vendored
@ -1 +1 @@
|
||||
Subproject commit 0d25f6fcbbf0a867b939a5501965ee4462b21ee6
|
||||
Subproject commit 1fb0586b065c4202e976528a6bdc6384dc56dc04
|
2
deps/mongoose
vendored
2
deps/mongoose
vendored
@ -1 +1 @@
|
||||
Subproject commit 2a541175b56a1aeecd2dc8474f981923ef580af6
|
||||
Subproject commit d6dda04f4f00016e12618d0b55c972498e6249b5
|
2
deps/protobuf
vendored
2
deps/protobuf
vendored
@ -1 +1 @@
|
||||
Subproject commit 14e74f6a21f2726d25e0e679c59d569f6bc8fe8e
|
||||
Subproject commit 86fcd879b38505446799b2f2a2929415ddad620a
|
@ -56,6 +56,7 @@ namespace Components
|
||||
Loader::Register(new BitMessage());
|
||||
#endif
|
||||
Loader::Register(new FileSystem());
|
||||
Loader::Register(new ModelSurfs());
|
||||
Loader::Register(new PlayerName());
|
||||
Loader::Register(new QuickPatch());
|
||||
Loader::Register(new ServerInfo());
|
||||
|
@ -69,6 +69,7 @@ namespace Components
|
||||
#include "Modules\Singleton.hpp"
|
||||
#include "Modules\BitMessage.hpp"
|
||||
#include "Modules\FileSystem.hpp"
|
||||
#include "Modules\ModelSurfs.hpp"
|
||||
#include "Modules\PlayerName.hpp"
|
||||
#include "Modules\QuickPatch.hpp"
|
||||
#include "Modules\ServerInfo.hpp"
|
||||
|
@ -522,7 +522,7 @@ namespace Components
|
||||
|
||||
if (file.Exists())
|
||||
{
|
||||
std::string& buffer = file.GetBuffer();
|
||||
std::string buffer = file.GetBuffer();
|
||||
|
||||
mg_printf(nc,
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
|
@ -2,24 +2,64 @@
|
||||
|
||||
namespace Components
|
||||
{
|
||||
void FileSystem::File::Read()
|
||||
FileSystem::File::File(std::string file) : Name(file), Handle(0)
|
||||
{
|
||||
this->Size = Game::FS_FOpenFileRead(this->Name.data(), &this->Handle, 0);
|
||||
}
|
||||
|
||||
FileSystem::File::~File()
|
||||
{
|
||||
char* buffer = nullptr;
|
||||
int size = Game::FS_ReadFile(this->FilePath.data(), &buffer);
|
||||
|
||||
this->Buffer.clear();
|
||||
|
||||
if (size < 0)
|
||||
if (this->Exists())
|
||||
{
|
||||
if (buffer)
|
||||
{
|
||||
Game::FS_FreeFile(buffer);
|
||||
}
|
||||
Game::FS_FCloseFile(this->Handle);
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
bool FileSystem::File::Exists()
|
||||
{
|
||||
return (this->Size > 0);
|
||||
}
|
||||
|
||||
std::string FileSystem::File::GetName()
|
||||
{
|
||||
return this->Name;
|
||||
}
|
||||
|
||||
std::string FileSystem::File::GetBuffer()
|
||||
{
|
||||
Utils::Memory::Allocator allocator;
|
||||
if (!this->Exists()) return std::string();
|
||||
|
||||
int position = Game::FS_FTell(this->Handle);
|
||||
this->Seek(0, FS_SEEK_SET);
|
||||
|
||||
char* buffer = allocator.AllocateArray<char>(this->Size);
|
||||
if (!FileSystem::File::Read(buffer, this->Size))
|
||||
{
|
||||
this->Buffer.append(buffer, size);
|
||||
Game::FS_FreeFile(buffer);
|
||||
this->Seek(position, FS_SEEK_SET);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
this->Seek(position, FS_SEEK_SET);
|
||||
|
||||
return std::string(buffer, this->Size);
|
||||
}
|
||||
|
||||
bool FileSystem::File::Read(void* buffer, size_t size)
|
||||
{
|
||||
if (!this->Exists() || static_cast<size_t>(this->Size) < size || Game::FS_Read(buffer, size, this->Handle) != static_cast<int>(size))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSystem::File::Seek(int offset, int origin)
|
||||
{
|
||||
if (this->Exists())
|
||||
{
|
||||
Game::FS_Seek(this->Handle, offset, origin);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,18 +7,20 @@ namespace Components
|
||||
class File
|
||||
{
|
||||
public:
|
||||
File() {};
|
||||
File(std::string file) : FilePath(file) { this->Read(); };
|
||||
File() : Size(-1), Name(), Handle(0) {};
|
||||
File(std::string file);
|
||||
~File();
|
||||
|
||||
bool Exists() { return !this->Buffer.empty(); };
|
||||
std::string GetName() { return this->FilePath; };
|
||||
std::string& GetBuffer() { return this->Buffer; };
|
||||
bool Exists();
|
||||
std::string GetName();
|
||||
std::string GetBuffer();
|
||||
bool Read(void* buffer, size_t size);
|
||||
void Seek(int offset, int origin);
|
||||
|
||||
private:
|
||||
std::string FilePath;
|
||||
std::string Buffer;
|
||||
|
||||
void Read();
|
||||
int Handle;
|
||||
int Size;
|
||||
std::string Name;
|
||||
};
|
||||
|
||||
class FileWriter
|
||||
|
@ -25,7 +25,7 @@ namespace Components
|
||||
return i;
|
||||
}
|
||||
|
||||
Game::script_t* Menus::LoadMenuScript(std::string name, std::string& buffer)
|
||||
Game::script_t* Menus::LoadMenuScript(std::string name, std::string buffer)
|
||||
{
|
||||
Game::script_t* script = Game::Script_Alloc(sizeof(Game::script_t) + 1 + buffer.length());
|
||||
|
||||
@ -52,7 +52,7 @@ namespace Components
|
||||
return script;
|
||||
}
|
||||
|
||||
int Menus::LoadMenuSource(std::string name, std::string& buffer)
|
||||
int Menus::LoadMenuSource(std::string name, std::string buffer)
|
||||
{
|
||||
int handle = Menus::ReserveSourceHandle();
|
||||
if (!Menus::IsValidSourceHandle(handle)) return 0; // No free source slot!
|
||||
|
@ -30,8 +30,8 @@ namespace Components
|
||||
static std::vector<Game::menuDef_t*> LoadMenu(Game::menuDef_t* menudef);
|
||||
static std::vector<Game::menuDef_t*> LoadMenu(std::string file);
|
||||
|
||||
static Game::script_t* LoadMenuScript(std::string name, std::string& buffer);
|
||||
static int LoadMenuSource(std::string name, std::string& buffer);
|
||||
static Game::script_t* LoadMenuScript(std::string name, std::string buffer);
|
||||
static int LoadMenuSource(std::string name, std::string buffer);
|
||||
|
||||
static int ReserveSourceHandle();
|
||||
static bool IsValidSourceHandle(int handle);
|
||||
|
308
src/Components/Modules/ModelSurfs.cpp
Normal file
308
src/Components/Modules/ModelSurfs.cpp
Normal file
@ -0,0 +1,308 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
std::map<void*, IUnknown*> ModelSurfs::BufferMap;
|
||||
std::map<void*, Game::CModelAllocData*> ModelSurfs::AllocMap;
|
||||
|
||||
IUnknown* ModelSurfs::GetBuffer(void* buffer)
|
||||
{
|
||||
return ModelSurfs::BufferMap[buffer];
|
||||
}
|
||||
|
||||
void ModelSurfs::SetBuffer(char /*streamHandle*/, void* buffer, IUnknown** bufferOut, int* offsetOut)
|
||||
{
|
||||
*offsetOut = 0;
|
||||
*bufferOut = ModelSurfs::BufferMap[buffer];
|
||||
}
|
||||
|
||||
void ModelSurfs::CreateBuffers(Game::XModelSurfs* surfs)
|
||||
{
|
||||
for (int i = 0; i < surfs->numSurfaces; ++i)
|
||||
{
|
||||
Game::XSurface* surface = &surfs->surfaces[i];
|
||||
if (surface->streamHandle == 0xFF)
|
||||
{
|
||||
IDirect3DVertexBuffer9* vertexBuffer;
|
||||
IDirect3DIndexBuffer9* indexBuffer;
|
||||
|
||||
Game::Load_VertexBuffer(surface->vertexBuffer, &vertexBuffer, surface->numVertices * 32);
|
||||
Game::Load_IndexBuffer(surface->indexBuffer, &indexBuffer, surface->numPrimitives * 3);
|
||||
|
||||
ModelSurfs::BufferMap[surface->vertexBuffer] = vertexBuffer;
|
||||
ModelSurfs::BufferMap[surface->indexBuffer] = indexBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Game::XModelSurfs* ModelSurfs::LoadXModelSurfaces(std::string name)
|
||||
{
|
||||
Utils::Memory::Allocator allocator;
|
||||
FileSystem::File model(fmt::sprintf("models/%s", name.data()));
|
||||
|
||||
if (!model.Exists())
|
||||
{
|
||||
Logger::Error("Loading model %s failed!", name.data());
|
||||
}
|
||||
|
||||
Game::CModelHeader header;
|
||||
if (!model.Read(&header, sizeof header))
|
||||
{
|
||||
Logger::Error("Reading header for model %s failed!", name.data());
|
||||
}
|
||||
|
||||
if (header.version != 1)
|
||||
{
|
||||
Logger::Error("Model %s has an invalid version %d (should be 1)!", name.data(), header.version);
|
||||
}
|
||||
|
||||
// Allocate section buffers
|
||||
header.sectionHeader[Game::SECTION_MAIN].buffer = Utils::Memory::Allocate(header.sectionHeader[Game::SECTION_MAIN].size);
|
||||
header.sectionHeader[Game::SECTION_INDEX].buffer = Utils::Memory::AllocateAlign(header.sectionHeader[Game::SECTION_INDEX].size, 16);
|
||||
header.sectionHeader[Game::SECTION_VERTEX].buffer = Utils::Memory::AllocateAlign(header.sectionHeader[Game::SECTION_VERTEX].size, 16);
|
||||
header.sectionHeader[Game::SECTION_FIXUP].buffer = allocator.AllocateArray<char>(header.sectionHeader[Game::SECTION_FIXUP].size);
|
||||
|
||||
// Load section data
|
||||
for (int i = 0; i < ARRAY_SIZE(header.sectionHeader); ++i)
|
||||
{
|
||||
model.Seek(header.sectionHeader[i].offset, FS_SEEK_SET);
|
||||
if (!model.Read(header.sectionHeader[i].buffer, header.sectionHeader[i].size))
|
||||
{
|
||||
Logger::Error("Reading section %d for model %s failed!", i, name.data());
|
||||
}
|
||||
}
|
||||
|
||||
// Fixup sections
|
||||
unsigned int* fixups = reinterpret_cast<unsigned int*>(header.sectionHeader[Game::SECTION_FIXUP].buffer);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
Game::CModelSectionHeader* section = &header.sectionHeader[i];
|
||||
for (int j = section->fixupStart; j < section->fixupStart + section->fixupCount; ++j)
|
||||
{
|
||||
unsigned int fixup = fixups[i];
|
||||
*reinterpret_cast<DWORD*>(reinterpret_cast<char*>(section->buffer) + (fixup >> 3)) += reinterpret_cast<DWORD>(header.sectionHeader[fixup & 3].buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Store allocation data (not sure if this is correct)
|
||||
Game::CModelAllocData* allocationData = Utils::Memory::AllocateArray<Game::CModelAllocData>();
|
||||
allocationData->mainArray = header.sectionHeader[Game::SECTION_MAIN].buffer;
|
||||
allocationData->indexBuffer = header.sectionHeader[Game::SECTION_INDEX].buffer;
|
||||
allocationData->vertexBuffer = header.sectionHeader[Game::SECTION_VERTEX].buffer;
|
||||
|
||||
ModelSurfs::AllocMap[allocationData->vertexBuffer] = allocationData;
|
||||
*reinterpret_cast<void**>(reinterpret_cast<char*>(allocationData->mainArray) + 44) = allocationData;
|
||||
|
||||
Assert_Size(Game::XSurface, 64);
|
||||
Game::XModelSurfs* modelSurfs = reinterpret_cast<Game::XModelSurfs*>(allocationData->mainArray);
|
||||
Game::XSurface* tempSurfaces = allocator.AllocateArray<Game::XSurface>(modelSurfs->numSurfaces);
|
||||
char* surfaceData = reinterpret_cast<char*>(modelSurfs->surfaces);
|
||||
|
||||
for (int i = 0; i < modelSurfs->numSurfaces; ++i)
|
||||
{
|
||||
memcpy(&tempSurfaces[i], surfaceData + (i * 84), 12);
|
||||
memcpy(&tempSurfaces[i].indexBuffer, surfaceData + (i * 84) + 16, 20);
|
||||
memcpy(&tempSurfaces[i].numCT, surfaceData + (i * 84) + 40, 8);
|
||||
memcpy(&tempSurfaces[i].pad5, surfaceData + (i * 84) + 52, 24);
|
||||
tempSurfaces[i].streamHandle = 0xFF; // Fake handle for buffer interception
|
||||
}
|
||||
|
||||
memcpy(surfaceData, tempSurfaces, 64 * modelSurfs->numSurfaces);
|
||||
|
||||
ModelSurfs::CreateBuffers(modelSurfs);
|
||||
|
||||
return modelSurfs;
|
||||
}
|
||||
|
||||
bool ModelSurfs::LoadSurfaces(Game::XModel* model)
|
||||
{
|
||||
if (!model) return false;
|
||||
bool changed = false;
|
||||
|
||||
short surfCount = 0;
|
||||
|
||||
for (char i = 0; i < model->numLods; ++i)
|
||||
{
|
||||
Game::XModelSurfs* surfs = model->lods[i].surfaces;
|
||||
|
||||
if (!surfs->surfaces)
|
||||
{
|
||||
Game::XModelSurfs* newSurfs = ModelSurfs::LoadXModelSurfaces(surfs->name);
|
||||
|
||||
surfs->surfaces = newSurfs->surfaces;
|
||||
surfs->numSurfaces = newSurfs->numSurfaces;
|
||||
|
||||
model->lods[i].surfaces = newSurfs;
|
||||
memcpy(model->lods[i].pad3, newSurfs->pad, 24);
|
||||
|
||||
short numSurfs = static_cast<short>(newSurfs->numSurfaces);
|
||||
model->lods[i].someCount = numSurfs;
|
||||
model->lods[i].someTotalCount = surfCount;
|
||||
surfCount += numSurfs;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void ModelSurfs::ReleaseModelSurf(Game::XAssetHeader header)
|
||||
{
|
||||
for (int i = 0; i < header.surfaces->numSurfaces && header.surfaces->surfaces; ++i)
|
||||
{
|
||||
Game::XSurface* surface = &header.surfaces->surfaces[i];
|
||||
if (surface->streamHandle == 0xFF)
|
||||
{
|
||||
auto buffer = ModelSurfs::BufferMap.find(surface->indexBuffer);
|
||||
if (buffer != ModelSurfs::BufferMap.end())
|
||||
{
|
||||
buffer->second->Release();
|
||||
ModelSurfs::BufferMap.erase(buffer);
|
||||
}
|
||||
|
||||
buffer = ModelSurfs::BufferMap.find(surface->vertexBuffer);
|
||||
if (buffer != ModelSurfs::BufferMap.end())
|
||||
{
|
||||
buffer->second->Release();
|
||||
ModelSurfs::BufferMap.erase(buffer);
|
||||
}
|
||||
|
||||
auto allocData = ModelSurfs::AllocMap.find(surface->vertexBuffer);
|
||||
if (allocData != ModelSurfs::AllocMap.end())
|
||||
{
|
||||
Utils::Memory::Free(allocData->second->indexBuffer);
|
||||
Utils::Memory::Free(allocData->second->vertexBuffer);
|
||||
Utils::Memory::Free(allocData->second->mainArray);
|
||||
Utils::Memory::Free(allocData->second);
|
||||
|
||||
ModelSurfs::AllocMap.erase(allocData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelSurfs::BeginRecover()
|
||||
{
|
||||
for (auto& buffer : ModelSurfs::BufferMap)
|
||||
{
|
||||
buffer.second->Release();
|
||||
}
|
||||
|
||||
ModelSurfs::BufferMap.clear();
|
||||
}
|
||||
|
||||
void ModelSurfs::EndRecover()
|
||||
{
|
||||
Game::DB_EnumXAssets_Internal(Game::XAssetType::ASSET_TYPE_XMODELSURFS, [] (Game::XAssetHeader header, void* /*userdata*/)
|
||||
{
|
||||
ModelSurfs::CreateBuffers(header.surfaces);
|
||||
}, nullptr, false);
|
||||
}
|
||||
|
||||
void ModelSurfs::XModelSurfsFixup(Game::XModel* model)
|
||||
{
|
||||
if (!ModelSurfs::LoadSurfaces(model))
|
||||
{
|
||||
Game::DB_XModelSurfsFixup(model);
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) void ModelSurfs::GetIndexBufferStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp + 4h]
|
||||
cmp al, 0FFh
|
||||
|
||||
jne returnSafe
|
||||
|
||||
jmp ModelSurfs::SetBuffer
|
||||
|
||||
returnSafe:
|
||||
movzx eax, [esp + 4h]
|
||||
mov edx, 4B4DE5h
|
||||
jmp edx
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) void ModelSurfs::GetIndexBufferStub2()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp + 4h]
|
||||
cmp al, 0FFh
|
||||
|
||||
jne returnSafe
|
||||
|
||||
mov eax, [edi + 0Ch]
|
||||
push eax
|
||||
call ModelSurfs::GetBuffer
|
||||
add esp, 4h
|
||||
retn
|
||||
|
||||
returnSafe:
|
||||
mov eax, 4FDC20h
|
||||
jmp eax
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) void ModelSurfs::GetIndexBaseStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp + 4h]
|
||||
cmp al, 0FFh
|
||||
|
||||
jne returnSafe
|
||||
|
||||
xor eax, eax
|
||||
retn
|
||||
|
||||
returnSafe:
|
||||
mov eax, 48C5F0h
|
||||
jmp eax
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) void ModelSurfs::GetVertexBufferStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp + 4h]
|
||||
cmp al, 0FFh
|
||||
|
||||
jne returnSafe
|
||||
|
||||
jmp ModelSurfs::SetBuffer
|
||||
|
||||
returnSafe:
|
||||
movzx eax, [esp + 4h]
|
||||
mov edx, 5BC055h
|
||||
jmp edx
|
||||
}
|
||||
}
|
||||
|
||||
ModelSurfs::ModelSurfs()
|
||||
{
|
||||
ModelSurfs::BufferMap.clear();
|
||||
|
||||
// Install release handler
|
||||
Game::DB_ReleaseXAssetHandlers[Game::XAssetType::ASSET_TYPE_XMODELSURFS] = ModelSurfs::ReleaseModelSurf;
|
||||
|
||||
// Install device recovery handlers
|
||||
Renderer::OnDeviceRecoveryBegin(ModelSurfs::BeginRecover);
|
||||
Renderer::OnDeviceRecoveryEnd(ModelSurfs::EndRecover);
|
||||
|
||||
// Install hooks
|
||||
Utils::Hook(0x47A6BD, ModelSurfs::XModelSurfsFixup, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x558F12, ModelSurfs::GetIndexBaseStub, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x5BC050, ModelSurfs::GetIndexBufferStub, HOOK_JUMP).Install()->Quick();
|
||||
Utils::Hook(0x558E70, ModelSurfs::GetIndexBufferStub2, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x5BC050, ModelSurfs::GetVertexBufferStub, HOOK_JUMP).Install()->Quick();
|
||||
}
|
||||
|
||||
ModelSurfs::~ModelSurfs()
|
||||
{
|
||||
assert(ModelSurfs::BufferMap.empty());
|
||||
assert(ModelSurfs::AllocMap.empty());
|
||||
}
|
||||
}
|
31
src/Components/Modules/ModelSurfs.hpp
Normal file
31
src/Components/Modules/ModelSurfs.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
namespace Components
|
||||
{
|
||||
class ModelSurfs : public Component
|
||||
{
|
||||
public:
|
||||
ModelSurfs();
|
||||
~ModelSurfs();
|
||||
|
||||
private:
|
||||
static std::map<void*, IUnknown*> BufferMap;
|
||||
static std::map<void*, Game::CModelAllocData*> AllocMap;
|
||||
|
||||
static void ReleaseModelSurf(Game::XAssetHeader header);
|
||||
|
||||
static void BeginRecover();
|
||||
static void EndRecover();
|
||||
|
||||
static IUnknown* GetBuffer(void* buffer);
|
||||
static void SetBuffer(char streamHandle, void* buffer, IUnknown** bufferOut, int* offsetOut);
|
||||
|
||||
static void CreateBuffers(Game::XModelSurfs* surfs);
|
||||
static Game::XModelSurfs* LoadXModelSurfaces(std::string name);
|
||||
static bool LoadSurfaces(Game::XModel* model);
|
||||
static void XModelSurfsFixup(Game::XModel* model);
|
||||
|
||||
static void GetIndexBaseStub();
|
||||
static void GetIndexBufferStub();
|
||||
static void GetIndexBufferStub2();
|
||||
static void GetVertexBufferStub();
|
||||
};
|
||||
}
|
@ -7,6 +7,9 @@ namespace Components
|
||||
wink::signal<wink::slot<Renderer::Callback>> Renderer::FrameOnceSignal;
|
||||
wink::signal<wink::slot<Renderer::BackendCallback>> Renderer::BackendFrameSignal;
|
||||
|
||||
wink::signal<wink::slot<Renderer::Callback>> Renderer::EndRecoverDeviceSignal;
|
||||
wink::signal<wink::slot<Renderer::Callback>> Renderer::BeginRecoverDeviceSignal;
|
||||
|
||||
__declspec(naked) void Renderer::FrameStub()
|
||||
{
|
||||
__asm
|
||||
@ -62,6 +65,16 @@ namespace Components
|
||||
Renderer::BackendFrameSignal.connect(callback);
|
||||
}
|
||||
|
||||
void Renderer::OnDeviceRecoveryEnd(Renderer::Callback* callback)
|
||||
{
|
||||
Renderer::EndRecoverDeviceSignal.connect(callback);
|
||||
}
|
||||
|
||||
void Renderer::OnDeviceRecoveryBegin(Renderer::Callback* callback)
|
||||
{
|
||||
Renderer::BeginRecoverDeviceSignal.connect(callback);
|
||||
}
|
||||
|
||||
int Renderer::Width()
|
||||
{
|
||||
return Utils::Hook::Get<int>(0x66E1C68);
|
||||
@ -106,6 +119,18 @@ namespace Components
|
||||
Renderer::DrawFrameHook.Initialize(0x5ACB99, Renderer::FrameStub, HOOK_CALL)->Install();
|
||||
|
||||
Utils::Hook(0x536A80, Renderer::BackendFrameStub, HOOK_JUMP).Install()->Quick();
|
||||
|
||||
Utils::Hook(0x508298, [] ()
|
||||
{
|
||||
Game::DB_BeginRecoverLostDevice();
|
||||
Renderer::BeginRecoverDeviceSignal();
|
||||
}, HOOK_CALL).Install()->Quick();
|
||||
|
||||
Utils::Hook(0x508355, [] ()
|
||||
{
|
||||
Renderer::EndRecoverDeviceSignal();
|
||||
Game::DB_EndRecoverLostDevice();
|
||||
}, HOOK_CALL).Install()->Quick();
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
@ -114,5 +139,8 @@ namespace Components
|
||||
Renderer::BackendFrameSignal.clear();
|
||||
Renderer::FrameOnceSignal.clear();
|
||||
Renderer::FrameSignal.clear();
|
||||
|
||||
Renderer::EndRecoverDeviceSignal.clear();
|
||||
Renderer::BeginRecoverDeviceSignal.clear();
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,9 @@ namespace Components
|
||||
static void OnFrame(Callback* callback);
|
||||
static void OnBackendFrame(BackendCallback* callback);
|
||||
|
||||
static void OnDeviceRecoveryEnd(Callback* callback);
|
||||
static void OnDeviceRecoveryBegin(Callback* callback);
|
||||
|
||||
private:
|
||||
static void FrameStub();
|
||||
static void FrameHandler();
|
||||
@ -29,6 +32,10 @@ namespace Components
|
||||
|
||||
static wink::signal<wink::slot<Callback>> FrameSignal;
|
||||
static wink::signal<wink::slot<Callback>> FrameOnceSignal;
|
||||
|
||||
static wink::signal<wink::slot<Callback>> EndRecoverDeviceSignal;
|
||||
static wink::signal<wink::slot<Callback>> BeginRecoverDeviceSignal;
|
||||
|
||||
static wink::signal<wink::slot<BackendCallback>> BackendFrameSignal;
|
||||
static Utils::Hook DrawFrameHook;
|
||||
};
|
||||
|
@ -31,6 +31,8 @@ namespace Game
|
||||
Con_DrawMiniConsole_t Con_DrawMiniConsole = (Con_DrawMiniConsole_t)0x464F30;
|
||||
Con_DrawSolidConsole_t Con_DrawSolidConsole = (Con_DrawSolidConsole_t)0x5A5040;
|
||||
|
||||
DB_BeginRecoverLostDevice_t DB_BeginRecoverLostDevice = (DB_BeginRecoverLostDevice_t)0x4BFF90;
|
||||
DB_EndRecoverLostDevice_t DB_EndRecoverLostDevice = (DB_EndRecoverLostDevice_t)0x46B660;
|
||||
DB_EnumXAssets_t DB_EnumXAssets = (DB_EnumXAssets_t)0x4B76D0;
|
||||
DB_EnumXAssets_Internal_t DB_EnumXAssets_Internal = (DB_EnumXAssets_Internal_t)0x5BB0A0;
|
||||
DB_FindXAssetHeader_t DB_FindXAssetHeader = (DB_FindXAssetHeader_t)0x407930;
|
||||
@ -40,6 +42,8 @@ namespace Game
|
||||
DB_IsXAssetDefault_t DB_IsXAssetDefault = (DB_IsXAssetDefault_t)0x48E6A0;
|
||||
DB_LoadXAssets_t DB_LoadXAssets = (DB_LoadXAssets_t)0x4E5930;
|
||||
DB_ReadXFileUncompressed_t DB_ReadXFileUncompressed = (DB_ReadXFileUncompressed_t)0x4705E0;
|
||||
DB_ReleaseXAssetHandler_t* DB_ReleaseXAssetHandlers = (DB_ReleaseXAssetHandler_t*)0x799AB8;
|
||||
DB_XModelSurfsFixup_t DB_XModelSurfsFixup = (DB_XModelSurfsFixup_t)0x5BAC50;
|
||||
|
||||
Dvar_RegisterBool_t Dvar_RegisterBool = (Dvar_RegisterBool_t)0x4CE1A0;
|
||||
Dvar_RegisterFloat_t Dvar_RegisterFloat = (Dvar_RegisterFloat_t)0x648440;
|
||||
@ -131,6 +135,7 @@ namespace Game
|
||||
PartyHost_GetMemberName_t PartyHost_GetMemberName = (PartyHost_GetMemberName_t)0x44BE90;
|
||||
|
||||
R_AddCmdDrawStretchPic_t R_AddCmdDrawStretchPic = (R_AddCmdDrawStretchPic_t)0x509770;
|
||||
R_AllocStaticIndexBuffer_t R_AllocStaticIndexBuffer = (R_AllocStaticIndexBuffer_t)0x51E7A0;
|
||||
R_Cinematic_StartPlayback_Now_t R_Cinematic_StartPlayback_Now = (R_Cinematic_StartPlayback_Now_t)0x51C5B0;
|
||||
R_RegisterFont_t R_RegisterFont = (R_RegisterFont_t)0x505670;
|
||||
R_AddCmdDrawText_t R_AddCmdDrawText = (R_AddCmdDrawText_t)0x509D80;
|
||||
@ -461,4 +466,38 @@ namespace Game
|
||||
pop esi
|
||||
}
|
||||
}
|
||||
|
||||
void Load_IndexBuffer(void* data, IDirect3DIndexBuffer9** storeHere, int count)
|
||||
{
|
||||
if (Components::Dvar::Var("r_loadForRenderer").Get<bool>())
|
||||
{
|
||||
void* buffer = R_AllocStaticIndexBuffer(storeHere, 2 * count);
|
||||
memcpy(buffer, data, 2 * count);
|
||||
|
||||
if (storeHere && *storeHere)
|
||||
{
|
||||
(*storeHere)->Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Load_VertexBuffer(void* data, IDirect3DVertexBuffer9** where, int len)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push edi
|
||||
push ebx
|
||||
|
||||
mov eax, len
|
||||
mov edi, where
|
||||
push data
|
||||
|
||||
mov ebx, 5112C0h
|
||||
call ebx
|
||||
add esp, 4
|
||||
|
||||
pop ebx
|
||||
pop edi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,12 @@ namespace Game
|
||||
typedef void (__cdecl * Con_DrawSolidConsole_t)();
|
||||
extern Con_DrawSolidConsole_t Con_DrawSolidConsole;
|
||||
|
||||
typedef void(__cdecl * DB_BeginRecoverLostDevice_t)();
|
||||
extern DB_BeginRecoverLostDevice_t DB_BeginRecoverLostDevice;
|
||||
|
||||
typedef void(__cdecl * DB_EndRecoverLostDevice_t)();
|
||||
extern DB_EndRecoverLostDevice_t DB_EndRecoverLostDevice;
|
||||
|
||||
typedef void(__cdecl * DB_EnumXAssets_t)(XAssetType type, void(*)(XAssetHeader, void *), void* userdata, bool overrides);
|
||||
extern DB_EnumXAssets_t DB_EnumXAssets;
|
||||
|
||||
@ -90,6 +96,12 @@ namespace Game
|
||||
typedef void(__cdecl * DB_ReadXFileUncompressed_t)(void* buffer, int size);
|
||||
extern DB_ReadXFileUncompressed_t DB_ReadXFileUncompressed;
|
||||
|
||||
typedef void(__cdecl * DB_ReleaseXAssetHandler_t)(XAssetHeader header);
|
||||
extern DB_ReleaseXAssetHandler_t* DB_ReleaseXAssetHandlers;
|
||||
|
||||
typedef void(__cdecl * DB_XModelSurfsFixup_t)(XModel* model);
|
||||
extern DB_XModelSurfsFixup_t DB_XModelSurfsFixup;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterBool_t)(const char* name, bool default, int flags, const char* description);
|
||||
extern Dvar_RegisterBool_t Dvar_RegisterBool;
|
||||
|
||||
@ -317,6 +329,9 @@ namespace Game
|
||||
typedef void(_cdecl * R_AddCmdDrawStretchPic_t)(float x, float y, float w, float h, float xScale, float yScale, float xay, float yay, const float *color, Game::Material* material);
|
||||
extern R_AddCmdDrawStretchPic_t R_AddCmdDrawStretchPic;
|
||||
|
||||
typedef void* (__cdecl * R_AllocStaticIndexBuffer_t)(IDirect3DIndexBuffer9** store, int length);
|
||||
extern R_AllocStaticIndexBuffer_t R_AllocStaticIndexBuffer;
|
||||
|
||||
typedef bool(__cdecl * R_Cinematic_StartPlayback_Now_t)();
|
||||
extern R_Cinematic_StartPlayback_Now_t R_Cinematic_StartPlayback_Now;
|
||||
|
||||
@ -518,4 +533,7 @@ namespace Game
|
||||
|
||||
void IN_KeyUp(kbutton_t* button);
|
||||
void IN_KeyDown(kbutton_t* button);
|
||||
|
||||
void Load_IndexBuffer(void* data, IDirect3DIndexBuffer9** storeHere, int count);
|
||||
void Load_VertexBuffer(void* data, IDirect3DVertexBuffer9** where, int len);
|
||||
}
|
||||
|
@ -818,6 +818,10 @@ namespace Game
|
||||
menuDef_t **menus;
|
||||
};
|
||||
|
||||
#define FS_SEEK_CUR 0
|
||||
#define FS_SEEK_END 1
|
||||
#define FS_SEEK_SET 2
|
||||
|
||||
enum FsListBehavior_e
|
||||
{
|
||||
FS_LIST_PURE_ONLY = 0x0,
|
||||
@ -1394,7 +1398,10 @@ namespace Game
|
||||
|
||||
struct XModelLodInfo
|
||||
{
|
||||
char pad[4]; // +0
|
||||
// I'm not sure if this is correct
|
||||
short someCount;
|
||||
short someTotalCount;
|
||||
|
||||
short numSurfs; // +4
|
||||
short pad2;// +6
|
||||
XModelSurfs* surfaces; // +8
|
||||
@ -1525,6 +1532,39 @@ namespace Game
|
||||
PhysCollmap* physCollmap;
|
||||
}; // total size 304
|
||||
|
||||
//static_assert(offsetof(XModel, lods) <= 70, "");
|
||||
|
||||
struct CModelAllocData
|
||||
{
|
||||
void* mainArray;
|
||||
void* vertexBuffer;
|
||||
void* indexBuffer;
|
||||
};
|
||||
|
||||
struct CModelSectionHeader
|
||||
{
|
||||
int size;
|
||||
int offset;
|
||||
int fixupStart;
|
||||
int fixupCount;
|
||||
void* buffer;
|
||||
};
|
||||
|
||||
enum CModelSection
|
||||
{
|
||||
SECTION_MAIN = 0,
|
||||
SECTION_INDEX = 1,
|
||||
SECTION_VERTEX = 2,
|
||||
SECTION_FIXUP = 3,
|
||||
};
|
||||
|
||||
struct CModelHeader
|
||||
{
|
||||
int version;
|
||||
unsigned int signature;
|
||||
CModelSectionHeader sectionHeader[4];
|
||||
};
|
||||
|
||||
struct DSkelPartBits
|
||||
{
|
||||
int anim[4];
|
||||
|
@ -2,17 +2,17 @@
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
void* Memory::AllocateAlign(size_t length, size_t alignment)
|
||||
{
|
||||
void* data = _aligned_malloc(length, alignment);
|
||||
assert(data != nullptr);
|
||||
return data;
|
||||
}
|
||||
|
||||
void* Memory::Allocate(size_t length)
|
||||
{
|
||||
void* data = new char[length];
|
||||
|
||||
void* data = calloc(length, 1);
|
||||
assert(data != nullptr);
|
||||
|
||||
if (data)
|
||||
{
|
||||
ZeroMemory(data, length);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ namespace Utils
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
delete[] data;
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,7 @@ namespace Utils
|
||||
std::map<void*, FreeCallback> RefMemory;
|
||||
};
|
||||
|
||||
static void* AllocateAlign(size_t length, size_t alignment);
|
||||
static void* Allocate(size_t length);
|
||||
template <typename T> static T* Allocate()
|
||||
{
|
||||
|
@ -12,7 +12,7 @@ namespace Utils
|
||||
class Reader
|
||||
{
|
||||
public:
|
||||
Reader(Utils::Memory::Allocator* allocator, std::string& buffer) : Buffer(buffer), Allocator(allocator), Position(0) {}
|
||||
Reader(Utils::Memory::Allocator* allocator, std::string buffer) : Buffer(buffer), Allocator(allocator), Position(0) {}
|
||||
|
||||
std::string ReadString();
|
||||
const char* ReadCString();
|
||||
|
Loading…
Reference in New Issue
Block a user