forked from sears2424/Source-PlusPlus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbsp_utils.cpp
170 lines (146 loc) · 4.66 KB
/
bsp_utils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Exposes bsp tools to game for e.g. workshop use
//
// $NoKeywords: $
//===========================================================================//
#include "cbase.h"
#include <tier2/tier2.h>
#include "filesystem.h"
#include "bsp_utils.h"
#include "utlbuffer.h"
#include "igamesystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
bool BSP_SyncRepack( const char *pszInputMapFile,
const char *pszOutputMapFile,
IBSPPack::eRepackBSPFlags eRepackFlags )
{
// load the bsppack dll
IBSPPack *libBSPPack = NULL;
CSysModule *pModule = g_pFullFileSystem->LoadModule( "bsppack" );
if ( pModule )
{
CreateInterfaceFn BSPPackFactory = Sys_GetFactory( pModule );
if ( BSPPackFactory )
{
libBSPPack = ( IBSPPack * )BSPPackFactory( IBSPPACK_VERSION_STRING, NULL );
}
}
if( !libBSPPack )
{
Warning( "Can't load bsppack library - unable to compress bsp\n" );
return false;
}
Msg( "Repacking %s -> %s\n", pszInputMapFile, pszOutputMapFile );
if ( !g_pFullFileSystem->FileExists( pszInputMapFile ) )
{
Warning( "Couldn't open input file %s - BSP recompress failed\n", pszInputMapFile );
return false;
}
CUtlBuffer inputBuffer;
if ( !g_pFullFileSystem->ReadFile( pszInputMapFile, NULL, inputBuffer ) )
{
Warning( "Couldn't read file %s - BSP compression failed\n", pszInputMapFile );
return false;
}
CUtlBuffer outputBuffer;
if ( !libBSPPack->RepackBSP( inputBuffer, outputBuffer, eRepackFlags ) )
{
Warning( "Internal error compressing BSP\n" );
return false;
}
g_pFullFileSystem->WriteFile( pszOutputMapFile, NULL, outputBuffer );
Msg( "Successfully repacked %s as %s -- %u -> %u bytes\n",
pszInputMapFile, pszOutputMapFile, inputBuffer.TellPut(), outputBuffer.TellPut() );
return true;
}
// Helper to create a thread that calls SyncCompressMap, and clean it up when it exists
void BSP_BackgroundRepack( const char *pszInputMapFile,
const char *pszOutputMapFile,
IBSPPack::eRepackBSPFlags eRepackFlags )
{
// Make this a gamesystem and thread, so it can check for completion each frame and clean itself up. Run() is the
// background thread, Update() is the main thread tick.
class BackgroundBSPRepackThread : public CThread, public CAutoGameSystemPerFrame
{
public:
BackgroundBSPRepackThread( const char *pszInputFile, const char *pszOutputFile, IBSPPack::eRepackBSPFlags eRepackFlags )
: m_strInput( pszInputFile )
, m_strOutput( pszOutputFile )
, m_eRepackFlags( eRepackFlags )
{
Start();
}
// CThread job - returns 0 for success
virtual int Run() OVERRIDE
{
return BSP_SyncRepack( m_strInput.Get(), m_strOutput.Get(), m_eRepackFlags ) ? 0 : 1;
}
// GameSystem
virtual const char* Name( void ) OVERRIDE { return "BackgroundBSPRepackThread"; }
// Runs on main thread
void CheckFinished()
{
if ( !IsAlive() )
{
// Thread finished
if ( GetResult() != 0 )
{
Warning( "Map compression thread failed :(\n" );
}
// AutoGameSystem deregisters itself on destruction, we're done
delete this;
}
}
#ifdef CLIENT_DLL
virtual void Update( float frametime ) OVERRIDE { CheckFinished(); }
#else // GAME DLL
virtual void FrameUpdatePostEntityThink() OVERRIDE { CheckFinished(); }
#endif
private:
CUtlString m_strInput;
CUtlString m_strOutput;
IBSPPack::eRepackBSPFlags m_eRepackFlags;
};
Msg( "Starting BSP repack job %s -> %s\n", pszInputMapFile, pszOutputMapFile );
// Deletes itself up when done
new BackgroundBSPRepackThread( pszInputMapFile, pszOutputMapFile, eRepackFlags );
}
CON_COMMAND( bsp_repack, "Repack and output a (re)compressed version of a bsp file" )
{
#ifdef GAME_DLL
if ( !UTIL_IsCommandIssuedByServerAdmin() )
return;
#endif
// Handle -nocompress
bool bCompress = true;
const char *szInFilename = NULL;
const char *szOutFilename = NULL;
if ( args.ArgC() == 4 && V_strcasecmp( args.Arg( 1 ), "-nocompress" ) == 0 )
{
bCompress = false;
szInFilename = args.Arg( 2 );
szOutFilename = args.Arg( 3 );
}
else if ( args.ArgC() == 3 )
{
szInFilename = args.Arg( 1 );
szOutFilename = args.Arg( 2 );
}
if ( !szInFilename || !szOutFilename || !strlen( szInFilename ) || !strlen( szOutFilename ) )
{
Msg( "Usage: bsp_repack [-nocompress] map.bsp output_map.bsp\n" );
return;
}
if ( bCompress )
{
// Use default compress flags
BSP_BackgroundRepack( szInFilename, szOutFilename );
}
else
{
// No compression
BSP_BackgroundRepack( szInFilename, szOutFilename, (IBSPPack::eRepackBSPFlags)0 );
}
}