2016-01-04 14:58:00 -05:00
# include "STDInclude.hpp"
2015-12-25 20:51:58 -05:00
namespace Components
{
void * Maps : : WorldMP = 0 ;
void * Maps : : WorldSP = 0 ;
2015-12-26 08:27:34 -05:00
std : : map < std : : string , std : : string > Maps : : DependencyList ;
std : : vector < std : : string > Maps : : CurrentDependencies ;
std : : vector < Game : : XAssetEntry > Maps : : EntryPool ;
void Maps : : LoadMapZones ( Game : : XZoneInfo * zoneInfo , unsigned int zoneCount , int sync )
{
2015-12-30 16:22:24 -05:00
if ( ! zoneInfo ) return ;
2015-12-26 08:27:34 -05:00
Maps : : CurrentDependencies . clear ( ) ;
2016-01-24 13:58:13 -05:00
for ( auto i = Maps : : DependencyList . begin ( ) ; i ! = Maps : : DependencyList . end ( ) ; + + i )
2015-12-26 08:27:34 -05:00
{
if ( std : : regex_match ( zoneInfo - > name , std : : regex ( i - > first ) ) )
{
if ( std : : find ( Maps : : CurrentDependencies . begin ( ) , Maps : : CurrentDependencies . end ( ) , i - > second ) = = Maps : : CurrentDependencies . end ( ) )
{
Maps : : CurrentDependencies . push_back ( i - > second ) ;
}
}
}
2015-12-30 16:22:24 -05:00
std : : vector < Game : : XZoneInfo > data ;
2016-01-24 06:19:34 -05:00
Utils : : Merge ( & data , zoneInfo , zoneCount ) ;
2015-12-26 08:27:34 -05:00
2016-01-24 13:58:13 -05:00
for ( unsigned int i = 0 ; i < Maps : : CurrentDependencies . size ( ) ; + + i )
2015-12-30 16:22:24 -05:00
{
Game : : XZoneInfo info ;
info . name = ( & Maps : : CurrentDependencies [ i ] ) - > data ( ) ;
info . allocFlags = zoneInfo - > allocFlags ;
info . freeFlags = zoneInfo - > freeFlags ;
data . push_back ( info ) ;
}
2015-12-26 08:27:34 -05:00
2016-01-27 04:54:29 -05:00
// Load patch files
std : : string patchZone = Utils : : VA ( " patch_%s " , zoneInfo - > name ) ;
if ( FastFiles : : Exists ( patchZone ) )
{
data . push_back ( { patchZone . data ( ) , zoneInfo - > allocFlags , zoneInfo - > freeFlags } ) ;
}
2016-01-27 18:32:46 -05:00
return FastFiles : : LoadLocalizeZones ( data . data ( ) , data . size ( ) , sync ) ;
2015-12-26 08:27:34 -05:00
}
bool Maps : : LoadAssetRestrict ( Game : : XAssetType type , Game : : XAssetHeader asset , const char * name )
{
if ( std : : find ( Maps : : CurrentDependencies . begin ( ) , Maps : : CurrentDependencies . end ( ) , FastFiles : : Current ( ) ) ! = Maps : : CurrentDependencies . end ( ) )
{
if ( type = = Game : : XAssetType : : ASSET_TYPE_GAME_MAP_MP | | type = = Game : : XAssetType : : ASSET_TYPE_COL_MAP_MP | | type = = Game : : XAssetType : : ASSET_TYPE_GFX_MAP | | type = = Game : : XAssetType : : ASSET_TYPE_MAP_ENTS | | type = = Game : : XAssetType : : ASSET_TYPE_COM_MAP | | type = = Game : : XAssetType : : ASSET_TYPE_FX_MAP )
{
return false ;
}
}
if ( type = = Game : : XAssetType : : ASSET_TYPE_MAP_ENTS )
{
static std : : string mapEntities ;
FileSystem : : File ents ( Utils : : VA ( " %s.ents " , name ) ) ;
if ( ents . Exists ( ) )
{
mapEntities = ents . GetBuffer ( ) ;
asset . mapEnts - > entitystring = mapEntities . data ( ) ;
}
}
return true ;
}
2015-12-25 20:51:58 -05:00
void Maps : : GetBSPName ( char * buffer , size_t size , const char * format , const char * mapname )
{
if ( _strnicmp ( " mp_ " , mapname , 3 ) )
{
format = " maps/%s.d3dbsp " ;
2015-12-26 08:27:34 -05:00
// Adjust pointer to GameMap_Data
Utils : : Hook : : Set < void * > ( 0x4D90B7 , Maps : : WorldSP ) ;
2015-12-25 20:51:58 -05:00
}
else
{
2015-12-26 08:27:34 -05:00
// Adjust pointer to GameMap_Data
Utils : : Hook : : Set < void * > ( 0x4D90B7 , Maps : : WorldMP ) ;
2015-12-25 20:51:58 -05:00
}
_snprintf ( buffer , size , format , mapname ) ;
}
2015-12-26 08:27:34 -05:00
void Maps : : AddDependency ( std : : string expression , std : : string zone )
2015-12-25 20:51:58 -05:00
{
2015-12-26 08:27:34 -05:00
// Test expression before adding it
try
{
std : : regex _ ( expression ) ;
}
2016-01-24 15:08:14 -05:00
catch ( const std : : exception e )
2015-12-26 08:27:34 -05:00
{
MessageBoxA ( 0 , Utils : : VA ( " Invalid regular expression: %s " , expression . data ( ) ) , " Warning " , MB_ICONEXCLAMATION ) ;
return ;
}
2015-12-25 20:51:58 -05:00
2015-12-26 08:27:34 -05:00
Maps : : DependencyList [ expression ] = zone ;
}
2015-12-25 20:51:58 -05:00
2015-12-26 08:27:34 -05:00
void Maps : : ReallocateEntryPool ( )
2015-12-25 20:51:58 -05:00
{
2015-12-26 08:27:34 -05:00
static_assert ( sizeof ( Game : : XAssetEntry ) = = 16 , " XAssetEntry size mismatch " ) ;
Maps : : EntryPool . clear ( ) ;
Maps : : EntryPool . resize ( 789312 ) ;
// Apply new size
Utils : : Hook : : Set < DWORD > ( 0x5BAEB0 , Maps : : EntryPool . size ( ) ) ;
// Apply new pool
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x48E6F4 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x4C67E4 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x4C8584 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BAEA8 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB0C4 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB0F5 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB1D4 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB235 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB278 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB34C , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB484 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB570 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB6B7 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB844 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB98D , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBA66 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBB8D , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBCB1 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBD9B , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBE4C , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBF14 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBF54 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBFB8 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BAE91 , Maps : : EntryPool . data ( ) + 1 ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BAEA2 , Maps : : EntryPool . data ( ) + 1 ) ;
2015-12-25 20:51:58 -05:00
}
Maps : : Maps ( )
{
2015-12-26 08:27:34 -05:00
// Restrict asset loading
AssetHandler : : OnLoad ( Maps : : LoadAssetRestrict ) ;
2015-12-25 20:51:58 -05:00
// hunk size (was 300 MiB)
Utils : : Hook : : Set < DWORD > ( 0x64A029 , 0x1C200000 ) ; // 450 MiB
Utils : : Hook : : Set < DWORD > ( 0x64A057 , 0x1C200000 ) ;
// Intercept BSP name resolving
Utils : : Hook ( 0x4C5979 , Maps : : GetBSPName , HOOK_CALL ) . Install ( ) - > Quick ( ) ;
2015-12-26 08:27:34 -05:00
// Intercept map zone loading
Utils : : Hook ( 0x42C2AF , Maps : : LoadMapZones , HOOK_CALL ) . Install ( ) - > Quick ( ) ;
2016-01-24 06:19:34 -05:00
Maps : : WorldSP = static_cast < char * > ( Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_GAME_MAP_SP , 1 ) ) + 52 ; // Skip name and other padding to reach world data
2015-12-26 08:27:34 -05:00
Maps : : WorldMP = Utils : : Hook : : Get < char * > ( 0x4D90B7 ) ;
2015-12-25 20:51:58 -05:00
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_IMAGE , 7168 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_LOADED_SOUND , 2700 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_FX , 1200 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_LOCALIZE , 14000 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_XANIM , 8192 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_XMODEL , 5125 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_PHYSPRESET , 128 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_PIXELSHADER , 10000 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_VERTEXSHADER , 3072 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_MATERIAL , 8192 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_VERTEXDECL , 196 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_WEAPON , 2400 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_STRINGTABLE , 800 ) ;
2015-12-26 08:27:34 -05:00
Maps : : ReallocateEntryPool ( ) ;
2015-12-25 20:51:58 -05:00
2015-12-26 08:27:34 -05:00
// Dependencies
2016-02-03 06:20:21 -05:00
//Maps::AddDependency("oilrig", "mp_subbase");
//Maps::AddDependency("gulag", "mp_subbase");
//Maps::AddDependency("invasion", "mp_rust");
Maps : : AddDependency ( " ^(?!mp_).* " , " dependencies_mp " ) ; // All maps not starting with "mp_"
2015-12-26 08:27:34 -05:00
}
2015-12-25 20:51:58 -05:00
2015-12-26 08:27:34 -05:00
Maps : : ~ Maps ( )
{
Maps : : EntryPool . clear ( ) ;
2015-12-25 20:51:58 -05:00
}
}