IW4Of Fixes (#775)
Co-authored-by: Louvenarde <louve@louve.systems> Co-authored-by: FutureRave <edoardo.sanguineti222@gmail.com>
This commit is contained in:
parent
d1f6f1db8b
commit
4103e4d174
2
deps/iw4-open-formats
vendored
2
deps/iw4-open-formats
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 2dde0c2103aab094f27b3c1daa790995df54faef
|
Subproject commit 6ef68c8535b60c681b179608f0c95fe0893e8937
|
3
deps/premake/iw4-open-formats.lua
vendored
3
deps/premake/iw4-open-formats.lua
vendored
@ -17,7 +17,8 @@ end
|
|||||||
function iw4_open_formats.project()
|
function iw4_open_formats.project()
|
||||||
project "iw4-open-formats"
|
project "iw4-open-formats"
|
||||||
language "C++"
|
language "C++"
|
||||||
|
cppdialect "C++latest"
|
||||||
|
|
||||||
iw4_open_formats.includes()
|
iw4_open_formats.includes()
|
||||||
|
|
||||||
pchheader "std_include.hpp"
|
pchheader "std_include.hpp"
|
||||||
|
@ -22,7 +22,34 @@ namespace Assets
|
|||||||
|
|
||||||
void IMaterialTechniqueSet::loadFromDisk(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder)
|
void IMaterialTechniqueSet::loadFromDisk(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder)
|
||||||
{
|
{
|
||||||
header->techniqueSet = builder->getIW4OfApi()->read<Game::MaterialTechniqueSet>(Game::XAssetType::ASSET_TYPE_TECHNIQUE_SET, name);
|
header->techniqueSet = builder->getIW4OfApi()->read<Game::MaterialTechniqueSet>(Game::ASSET_TYPE_TECHNIQUE_SET, name);
|
||||||
|
|
||||||
|
auto ptr = header->techniqueSet;
|
||||||
|
if (!ptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ptr->remappedTechniqueSet && ptr->remappedTechniqueSet != ptr)
|
||||||
|
{
|
||||||
|
ptr = ptr->remappedTechniqueSet;
|
||||||
|
builder->loadAsset(Game::ASSET_TYPE_TECHNIQUE_SET, ptr, false);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < Game::TECHNIQUE_COUNT; i++)
|
||||||
|
{
|
||||||
|
const auto technique = ptr->techniques[i];
|
||||||
|
if (technique)
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < technique->passCount; j++)
|
||||||
|
{
|
||||||
|
const auto pass = &technique->passArray[j];
|
||||||
|
builder->loadAsset(Game::ASSET_TYPE_VERTEXDECL, pass->vertexDecl, true);
|
||||||
|
builder->loadAsset(Game::ASSET_TYPE_PIXELSHADER, pass->pixelShader, true);
|
||||||
|
builder->loadAsset(Game::ASSET_TYPE_VERTEXSHADER, pass->vertexShader, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IMaterialTechniqueSet::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
|
void IMaterialTechniqueSet::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
|
||||||
|
@ -572,7 +572,7 @@ namespace Assets
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MAP_ENTS, asset);
|
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MAP_ENTS, asset->mapEnts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IclipMap_t::load(Game::XAssetHeader* header, const std::string& _name, Components::ZoneBuilder::Zone* builder)
|
void IclipMap_t::load(Game::XAssetHeader* header, const std::string& _name, Components::ZoneBuilder::Zone* builder)
|
||||||
|
@ -666,12 +666,25 @@ namespace Components
|
|||||||
return Utils::Hook::Call<bool(Game::gentity_s*)>(0x5050C0)(ent);
|
return Utils::Hook::Call<bool(Game::gentity_s*)>(0x5050C0)(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 Maps::CM_TriggerModelBounds(int modelPointer, Game::Bounds* bounds) {
|
unsigned short Maps::CM_TriggerModelBounds_Hk(unsigned int triggerIndex, Game::Bounds* bounds)
|
||||||
#ifdef DEBUG
|
{
|
||||||
Game::MapEnts* ents = *reinterpret_cast<Game::MapEnts**>(0x1AA651C); // Use me for debugging
|
|
||||||
(void)ents;
|
auto* ents = *reinterpret_cast<Game::MapEnts**>(0x1AA651C); // Use me for debugging
|
||||||
#endif
|
|
||||||
return Utils::Hook::Call<int16(int, Game::Bounds*)>(0x4416C0)(modelPointer, bounds);
|
if (ents)
|
||||||
|
{
|
||||||
|
if (triggerIndex >= ents->trigger.count)
|
||||||
|
{
|
||||||
|
Logger::Error(Game::errorParm_t::ERR_DROP, "Invalid trigger index ({}) in entities exceeds the maximum trigger count ({}) defined in the clipmap. Check your map ents, or your clipmap!", triggerIndex, ents->trigger.count);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Utils::Hook::Call<unsigned short(int, Game::Bounds*)>(0x4416C0)(triggerIndex, bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maps::Maps()
|
Maps::Maps()
|
||||||
@ -714,11 +727,13 @@ namespace Components
|
|||||||
Utils::Hook(0x5EE577, Maps::G_SpawnTurretHook, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5EE577, Maps::G_SpawnTurretHook, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x44A4D5, Maps::G_SpawnTurretHook, HOOK_CALL).install()->quick();
|
Utils::Hook(0x44A4D5, Maps::G_SpawnTurretHook, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
// Catch trigger errors before they're critical
|
||||||
|
Utils::Hook(0x5050D4, Maps::CM_TriggerModelBounds_Hk, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Check trigger models
|
// Check trigger models
|
||||||
Utils::Hook(0x5FC0F1, Maps::SV_SetTriggerModelHook, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5FC0F1, Maps::SV_SetTriggerModelHook, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x5FC2671, Maps::SV_SetTriggerModelHook, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5FC2671, Maps::SV_SetTriggerModelHook, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x5050D4, Maps::CM_TriggerModelBounds, HOOK_CALL).install()->quick();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -121,6 +121,6 @@ namespace Components
|
|||||||
|
|
||||||
static void G_SpawnTurretHook(Game::gentity_s* ent, int unk, int unk2);
|
static void G_SpawnTurretHook(Game::gentity_s* ent, int unk, int unk2);
|
||||||
static bool SV_SetTriggerModelHook(Game::gentity_s* ent);
|
static bool SV_SetTriggerModelHook(Game::gentity_s* ent);
|
||||||
static int16 CM_TriggerModelBounds(int brushModelPointer, Game::Bounds* bounds);
|
static unsigned short CM_TriggerModelBounds_Hk(unsigned int brushModelPointer, Game::Bounds* bounds);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,9 @@ namespace Components
|
|||||||
zoneName(name),
|
zoneName(name),
|
||||||
dataMap("zone_source/" + name + ".csv"),
|
dataMap("zone_source/" + name + ".csv"),
|
||||||
branding{nullptr},
|
branding{nullptr},
|
||||||
assetDepth(0)
|
assetDepth(0),
|
||||||
|
iw4ofApi(getIW4OfApiParams())
|
||||||
{
|
{
|
||||||
this->initializeIW4OfApi();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneBuilder::Zone::~Zone()
|
ZoneBuilder::Zone::~Zone()
|
||||||
@ -535,18 +535,21 @@ namespace Components
|
|||||||
// Add branding asset
|
// Add branding asset
|
||||||
void ZoneBuilder::Zone::addBranding()
|
void ZoneBuilder::Zone::addBranding()
|
||||||
{
|
{
|
||||||
constexpr auto* data = "Built using the IW4x Zone:B:uilder Version 4";
|
static std::string zoneBranding;
|
||||||
auto dataLen = std::strlen(data); // + 1 is added by the save code
|
|
||||||
|
|
||||||
this->branding = {this->zoneName.data(), 0, static_cast<int>(dataLen), data};
|
const auto now = std::chrono::system_clock::now();
|
||||||
|
zoneBranding = std::format("Built using the IW4x ZoneBuilder! {:%d-%m-%Y %H:%M:%OS}", now);
|
||||||
|
auto brandingLen = zoneBranding.size(); // + 1 is added by the save code
|
||||||
|
|
||||||
if (this->findAsset(Game::XAssetType::ASSET_TYPE_RAWFILE, this->branding.name) != -1)
|
this->branding = {this->zoneName.data(), 0, static_cast<int>(brandingLen), zoneBranding.data()};
|
||||||
|
|
||||||
|
if (this->findAsset(Game::ASSET_TYPE_RAWFILE, this->branding.name) != -1)
|
||||||
{
|
{
|
||||||
Logger::Error(Game::ERR_FATAL, "Unable to add branding. Asset '{}' already exists!", this->branding.name);
|
Logger::Error(Game::ERR_FATAL, "Unable to add branding. Asset '{}' already exists!", this->branding.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::XAssetHeader header = { &this->branding };
|
Game::XAssetHeader header = { &this->branding };
|
||||||
Game::XAsset brandingAsset = { Game::XAssetType::ASSET_TYPE_RAWFILE, header };
|
Game::XAsset brandingAsset = { Game::ASSET_TYPE_RAWFILE, header };
|
||||||
this->loadedAssets.push_back(brandingAsset);
|
this->loadedAssets.push_back(brandingAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,7 +760,7 @@ namespace Components
|
|||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneBuilder::Zone::initializeIW4OfApi()
|
iw4of::params_t ZoneBuilder::Zone::getIW4OfApiParams()
|
||||||
{
|
{
|
||||||
iw4of::params_t params;
|
iw4of::params_t params;
|
||||||
|
|
||||||
@ -787,7 +790,7 @@ namespace Components
|
|||||||
switch (t)
|
switch (t)
|
||||||
{
|
{
|
||||||
case iw4of::params_t::P_ERR:
|
case iw4of::params_t::P_ERR:
|
||||||
Logger::PrintError(Game::CON_CHANNEL_ERROR, "{}", message);
|
Logger::Error(Game::ERR_FATAL, "{}", message);
|
||||||
break;
|
break;
|
||||||
case iw4of::params_t::P_WARN:
|
case iw4of::params_t::P_WARN:
|
||||||
Logger::Print("{}", message);
|
Logger::Print("{}", message);
|
||||||
@ -795,9 +798,16 @@ namespace Components
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
params.work_directory = (*Game::fs_basepath)->current.string;
|
if (*Game::fs_basepath && *Game::fs_gameDirVar)
|
||||||
|
{
|
||||||
|
params.work_directory = std::format("{}/{}", (*Game::fs_basepath)->current.string, (*Game::fs_gameDirVar)->current.string);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::Error(Game::ERR_FATAL, "Missing FS Game directory or basepath directory!");
|
||||||
|
}
|
||||||
|
|
||||||
this->iw4ofApi = iw4of::api{ params };
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZoneBuilder::StoreTexture(Game::GfxImageLoadDef **loadDef, Game::GfxImage *image)
|
int ZoneBuilder::StoreTexture(Game::GfxImageLoadDef **loadDef, Game::GfxImage *image)
|
||||||
|
@ -90,7 +90,7 @@ namespace Components
|
|||||||
|
|
||||||
void addBranding();
|
void addBranding();
|
||||||
|
|
||||||
void initializeIW4OfApi();
|
iw4of::params_t getIW4OfApiParams();
|
||||||
|
|
||||||
uint32_t safeGetPointer(const void* pointer);
|
uint32_t safeGetPointer(const void* pointer);
|
||||||
|
|
||||||
|
@ -48,6 +48,9 @@ namespace Game
|
|||||||
const char* DB_GetXAssetName(XAsset* asset)
|
const char* DB_GetXAssetName(XAsset* asset)
|
||||||
{
|
{
|
||||||
if (!asset) return "";
|
if (!asset) return "";
|
||||||
|
|
||||||
|
assert(asset->header.data);
|
||||||
|
|
||||||
return DB_GetXAssetNameHandlers[asset->type](&asset->header);
|
return DB_GetXAssetNameHandlers[asset->type](&asset->header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7801,6 +7801,13 @@ namespace Game
|
|||||||
R_RENDERTARGET_NONE = 0xD,
|
R_RENDERTARGET_NONE = 0xD,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GfxDrawPrimArgs
|
||||||
|
{
|
||||||
|
int vertexCount;
|
||||||
|
int triCount;
|
||||||
|
int baseIndex;
|
||||||
|
};
|
||||||
|
|
||||||
struct GfxCmdBufState
|
struct GfxCmdBufState
|
||||||
{
|
{
|
||||||
char refSamplerState[16];
|
char refSamplerState[16];
|
||||||
|
Loading…
Reference in New Issue
Block a user