Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

845 lines
19 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #include "cbase.h"
  9. #include "StatusWindow.h"
  10. #include "cmdlib.h"
  11. #include <sys/stat.h>
  12. #include "workspace.h"
  13. #include "workspacemanager.h"
  14. #include "workspacebrowser.h"
  15. #include "tier2/riff.h"
  16. #include "sentence.h"
  17. #include "utlbuffer.h"
  18. #include "SoundEmitterSystem/isoundemittersystembase.h"
  19. #include <KeyValues.h>
  20. #include "MultipleRequest.h"
  21. bool SceneManager_HasWindowStyle( mxWindow *w, int bits )
  22. {
  23. HWND wnd = (HWND)w->getHandle();
  24. DWORD style = GetWindowLong( wnd, GWL_STYLE );
  25. return ( style & bits ) ? true : false;
  26. }
  27. bool SceneManager_HasWindowExStyle( mxWindow *w, int bits )
  28. {
  29. HWND wnd = (HWND)w->getHandle();
  30. DWORD style = GetWindowLong( wnd, GWL_EXSTYLE );
  31. return ( style & bits ) ? true : false;
  32. }
  33. void SceneManager_AddWindowStyle( mxWindow *w, int addbits )
  34. {
  35. HWND wnd = (HWND)w->getHandle();
  36. DWORD style = GetWindowLong( wnd, GWL_STYLE );
  37. style |= addbits;
  38. SetWindowLong( wnd, GWL_STYLE, style );
  39. }
  40. void SceneManager_AddWindowExStyle( mxWindow *w, int addbits )
  41. {
  42. HWND wnd = (HWND)w->getHandle();
  43. DWORD style = GetWindowLong( wnd, GWL_EXSTYLE );
  44. style |= addbits;
  45. SetWindowLong( wnd, GWL_EXSTYLE, style );
  46. }
  47. void SceneManager_RemoveWindowStyle( mxWindow *w, int removebits )
  48. {
  49. HWND wnd = (HWND)w->getHandle();
  50. DWORD style = GetWindowLong( wnd, GWL_STYLE );
  51. style &= ~removebits;
  52. SetWindowLong( wnd, GWL_STYLE, style );
  53. }
  54. void SceneManager_RemoveWindowExStyle( mxWindow *w, int removebits )
  55. {
  56. HWND wnd = (HWND)w->getHandle();
  57. DWORD style = GetWindowLong( wnd, GWL_EXSTYLE );
  58. style &= ~removebits;
  59. SetWindowLong( wnd, GWL_EXSTYLE, style );
  60. }
  61. //-----------------------------------------------------------------------------
  62. // Purpose:
  63. // Input : *w -
  64. //-----------------------------------------------------------------------------
  65. void SceneManager_MakeToolWindow( mxWindow *w, bool smallcaption )
  66. {
  67. SceneManager_AddWindowStyle( w, WS_VISIBLE | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS );
  68. if ( smallcaption )
  69. {
  70. SceneManager_AddWindowExStyle( w, WS_EX_OVERLAPPEDWINDOW );
  71. SceneManager_AddWindowExStyle( w, WS_EX_TOOLWINDOW );
  72. }
  73. else
  74. {
  75. SceneManager_RemoveWindowStyle( w, WS_SYSMENU );
  76. }
  77. }
  78. char *va( const char *fmt, ... )
  79. {
  80. va_list args;
  81. static char output[4][1024];
  82. static int outbuffer = 0;
  83. outbuffer++;
  84. va_start( args, fmt );
  85. vprintf( fmt, args );
  86. vsprintf( output[ outbuffer & 3 ], fmt, args );
  87. return output[ outbuffer & 3 ];
  88. }
  89. void Con_Overprintf( const char *fmt, ... )
  90. {
  91. va_list args;
  92. static char output[1024];
  93. va_start( args, fmt );
  94. vprintf( fmt, args );
  95. vsprintf( output, fmt, args );
  96. if ( !g_pStatusWindow )
  97. {
  98. return;
  99. }
  100. g_pStatusWindow->StatusPrint( CONSOLE_R, CONSOLE_G, CONSOLE_B, true, output );
  101. }
  102. void Con_Printf( const char *fmt, ... )
  103. {
  104. va_list args;
  105. static char output[1024];
  106. va_start( args, fmt );
  107. // vprintf( fmt, args );
  108. vsprintf( output, fmt, args );
  109. va_end( args );
  110. if ( !g_pStatusWindow )
  111. {
  112. return;
  113. }
  114. g_pStatusWindow->StatusPrint( CONSOLE_R, CONSOLE_G, CONSOLE_B, false, output );
  115. }
  116. void Con_ColorPrintf( int r, int g, int b, const char *fmt, ... )
  117. {
  118. va_list args;
  119. static char output[1024];
  120. va_start( args, fmt );
  121. vprintf( fmt, args );
  122. vsprintf( output, fmt, args );
  123. if ( !g_pStatusWindow )
  124. {
  125. return;
  126. }
  127. g_pStatusWindow->StatusPrint( r, g, b, false, output );
  128. }
  129. //-----------------------------------------------------------------------------
  130. // Purpose:
  131. // Input : *pname -
  132. // Output : char
  133. //-----------------------------------------------------------------------------
  134. char *SceneManager_MakeWindowsSlashes( char *pname )
  135. {
  136. static char returnString[ 4096 ];
  137. strcpy( returnString, pname );
  138. pname = returnString;
  139. while ( *pname ) {
  140. if ( *pname == '/' )
  141. *pname = '\\';
  142. pname++;
  143. }
  144. return returnString;
  145. }
  146. //-----------------------------------------------------------------------------
  147. // Purpose:
  148. // Output : const char
  149. //-----------------------------------------------------------------------------
  150. const char *SceneManager_GetGameDirectory( void )
  151. {
  152. // Todo: Make SceneManager only use the filesystem read/write paths.
  153. return gamedir;
  154. }
  155. //-----------------------------------------------------------------------------
  156. // Purpose: Takes a full path and determines if the file exists on the disk
  157. // Input : *filename -
  158. // Output : Returns true on success, false on failure.
  159. //-----------------------------------------------------------------------------
  160. bool SceneManager_FullpathFileExists( const char *filename )
  161. {
  162. // Should be a full path
  163. Assert( strchr( filename, ':' ) );
  164. struct _stat buf;
  165. int result = _stat( filename, &buf );
  166. if ( result != -1 )
  167. return true;
  168. return false;
  169. }
  170. //-----------------------------------------------------------------------------
  171. // Purpose: converts an english string to unicode
  172. //-----------------------------------------------------------------------------
  173. int ConvertANSIToUnicode(const char *ansi, wchar_t *unicode, int unicodeBufferSize)
  174. {
  175. return ::MultiByteToWideChar(CP_ACP, 0, ansi, -1, unicode, unicodeBufferSize);
  176. }
  177. //-----------------------------------------------------------------------------
  178. // Purpose: converts an unicode string to an english string
  179. //-----------------------------------------------------------------------------
  180. int ConvertUnicodeToANSI(const wchar_t *unicode, char *ansi, int ansiBufferSize)
  181. {
  182. return ::WideCharToMultiByte(CP_ACP, 0, unicode, -1, ansi, ansiBufferSize, NULL, NULL);
  183. }
  184. int Sys_Exec( const char *pProgName, const char *pCmdLine, bool verbose )
  185. {
  186. #if 0
  187. int count = 0;
  188. char cmdLine[1024];
  189. STARTUPINFO si;
  190. memset( &si, 0, sizeof(si) );
  191. si.cb = sizeof(si);
  192. //GetStartupInfo( &si );
  193. sprintf( cmdLine, "%s %s", pProgName, pCmdLine );
  194. PROCESS_INFORMATION pi;
  195. memset( &pi, 0, sizeof( pi ) );
  196. si.cb = sizeof(si);
  197. si.dwFlags = STARTF_USESTDHANDLES;
  198. if ( CreateProcess( NULL, cmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi ) )
  199. {
  200. WaitForSingleObject( pi.hProcess, INFINITE );
  201. /*
  202. do
  203. {
  204. WaitForInputIdle( pi.hProcess, 100 );
  205. count++;
  206. } while ( count < 100 );
  207. */
  208. /*
  209. DWORD exitCode = STILL_ACTIVE;
  210. do
  211. {
  212. BOOL ok = GetExitCodeProcess( pi.hProcess, &exitCode );
  213. if ( !ok )
  214. break;
  215. Sleep( 100 );
  216. } while ( exitCode == STILL_ACTIVE );
  217. */
  218. DWORD exitCode;
  219. GetExitCodeProcess( pi.hProcess, &exitCode );
  220. Con_Printf( "Finished\n" );
  221. CloseHandle( pi.hProcess );
  222. return (int)exitCode;
  223. }
  224. else
  225. {
  226. char *lpMsgBuf;
  227. FormatMessage(
  228. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  229. FORMAT_MESSAGE_FROM_SYSTEM |
  230. FORMAT_MESSAGE_IGNORE_INSERTS,
  231. NULL,
  232. GetLastError(),
  233. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  234. (LPTSTR) &lpMsgBuf,
  235. 0,
  236. NULL
  237. );
  238. Con_Printf( "error %s\n", lpMsgBuf );
  239. LocalFree( (HLOCAL)lpMsgBuf );
  240. }
  241. return false;
  242. #else
  243. char tmp[1024];
  244. sprintf( tmp, "%s %s\n", pProgName, pCmdLine );
  245. _strlwr( tmp );
  246. int iret = system( tmp );
  247. if ( iret != 0 && verbose )
  248. {
  249. Con_Printf( "Execution failed: %s\n", tmp );
  250. }
  251. return iret;
  252. #endif
  253. }
  254. //-----------------------------------------------------------------------------
  255. // Checks it out/ checks it in baby
  256. //-----------------------------------------------------------------------------
  257. static void SceneManager_VSSCheckout( char const *pUserName, char const *pProjectDir,
  258. char const* pRelativeDir, char const* pDestPath, char const* pFileNameWithExtension )
  259. {
  260. char buf[1024];
  261. // Check for the existence of the file in source safe...
  262. sprintf( buf, "filetype %s/%s%s -O- -y%s\n",
  263. pProjectDir, pRelativeDir, pFileNameWithExtension,
  264. pUserName );
  265. int retVal = Sys_Exec( "ss.exe", buf, false );
  266. if (retVal != 0 )
  267. {
  268. Con_Printf( "File %s missing from VSS\n", pFileNameWithExtension );
  269. return;
  270. }
  271. // It's there, try to check it out
  272. sprintf( buf, "checkout %s/%s%s -GL%s -GWA -O- -y%s\n",
  273. pProjectDir, pRelativeDir, pFileNameWithExtension,
  274. pDestPath, pUserName );
  275. Sys_Exec( "ss.exe", buf, true );
  276. }
  277. //-----------------------------------------------------------------------------
  278. // Checks it out/ checks it in baby
  279. //-----------------------------------------------------------------------------
  280. static void SceneManager_VSSCheckin( char const *pUserName, char const *pProjectDir,
  281. char const* pRelativeDir, char const* pDestPath, char const* pFileNameWithExtension )
  282. {
  283. char buf[1024];
  284. // Check for the existence of the file on disk. If it's not there, don't bother
  285. sprintf( buf, "%s%s", pDestPath, pFileNameWithExtension );
  286. struct _stat statbuf;
  287. int result = _stat( buf, &statbuf );
  288. if (result != 0)
  289. return;
  290. // Check for the existence of the file in source safe...
  291. sprintf( buf, "filetype %s/%s%s -O- -y%s\n",
  292. pProjectDir, pRelativeDir, pFileNameWithExtension,
  293. pUserName );
  294. int retVal = Sys_Exec( "ss.exe", buf, false );
  295. if (retVal != 0)
  296. {
  297. sprintf( buf, "Cp %s -O- -y%s\n",
  298. pProjectDir ,
  299. pUserName );
  300. Sys_Exec( "ss.exe", buf, true );
  301. // Try to add the file to source safe...
  302. sprintf( buf, "add %s%s -GL%s -O- -I- -y%s\n",
  303. pRelativeDir, pFileNameWithExtension,
  304. pDestPath, pUserName );
  305. Sys_Exec( "ss.exe", buf, true );
  306. }
  307. else
  308. {
  309. // It's there, just check it in
  310. sprintf( buf, "checkin %s/%s%s -GL%s -O- -I- -y%s\n",
  311. pProjectDir, pRelativeDir, pFileNameWithExtension,
  312. pDestPath, pUserName );
  313. Sys_Exec( "ss.exe", buf, true );
  314. }
  315. }
  316. void SplitFileName( char const *in, char *path, int maxpath, char *filename, int maxfilename )
  317. {
  318. char drive[_MAX_DRIVE];
  319. char dir[_MAX_DIR];
  320. char fname[_MAX_FNAME];
  321. char ext[_MAX_EXT];
  322. _splitpath( in, drive, dir, fname, ext );
  323. if ( dir[0] )
  324. {
  325. Q_snprintf( path, maxpath, "\\%s", dir );
  326. }
  327. else
  328. {
  329. path[0] = 0;
  330. }
  331. Q_snprintf( filename, maxfilename, "%s%s", fname, ext );
  332. }
  333. void VSS_Checkout( char const *name, bool updatestaticons /*= true*/ )
  334. {
  335. CWorkspace *ws = GetWorkspaceManager()->GetBrowser()->GetWorkspace();
  336. if ( !ws )
  337. {
  338. return;
  339. }
  340. if ( filesystem->IsFileWritable( name ) )
  341. {
  342. return;
  343. }
  344. char path[ 256 ];
  345. char filename[ 256 ];
  346. SplitFileName( name, path, sizeof( path ), filename, sizeof( filename ) );
  347. Con_ColorPrintf( 200, 200, 100, "VSS Checkout: '%s'\n", name );
  348. SceneManager_VSSCheckout(
  349. ws->GetVSSUserName(),
  350. ws->GetVSSProject(),
  351. path,
  352. va( "%s%s", gamedir, path ),
  353. filename );
  354. if ( updatestaticons )
  355. {
  356. GetWorkspaceManager()->RefreshBrowsers();
  357. }
  358. }
  359. void VSS_Checkin( char const *name, bool updatestaticons /*= true*/ )
  360. {
  361. CWorkspace *ws = GetWorkspaceManager()->GetBrowser()->GetWorkspace();
  362. if ( !ws )
  363. {
  364. return;
  365. }
  366. if ( !filesystem->IsFileWritable( name ) )
  367. {
  368. return;
  369. }
  370. char path[ 256 ];
  371. char filename[ 256 ];
  372. SplitFileName( name, path, sizeof( path ), filename, sizeof( filename ) );
  373. Con_ColorPrintf( 200, 200, 100, "VSS Checkin: '%s'\n", name );
  374. SceneManager_VSSCheckin(
  375. ws->GetVSSUserName(),
  376. ws->GetVSSProject(),
  377. path,
  378. va( "%s%s", gamedir, path ),
  379. filename );
  380. if ( updatestaticons )
  381. {
  382. GetWorkspaceManager()->RefreshBrowsers();
  383. }
  384. }
  385. //-----------------------------------------------------------------------------
  386. // Purpose: Implements the RIFF i/o interface on stdio
  387. //-----------------------------------------------------------------------------
  388. class StdIOReadBinary : public IFileReadBinary
  389. {
  390. public:
  391. int open( const char *pFileName )
  392. {
  393. return (int)filesystem->Open( pFileName, "rb" );
  394. }
  395. int read( void *pOutput, int size, int file )
  396. {
  397. if ( !file )
  398. return 0;
  399. return filesystem->Read( pOutput, size, (FileHandle_t)file );
  400. }
  401. void seek( int file, int pos )
  402. {
  403. if ( !file )
  404. return;
  405. filesystem->Seek( (FileHandle_t)file, pos, FILESYSTEM_SEEK_HEAD );
  406. }
  407. unsigned int tell( int file )
  408. {
  409. if ( !file )
  410. return 0;
  411. return filesystem->Tell( (FileHandle_t)file );
  412. }
  413. unsigned int size( int file )
  414. {
  415. if ( !file )
  416. return 0;
  417. return filesystem->Size( (FileHandle_t)file );
  418. }
  419. void close( int file )
  420. {
  421. if ( !file )
  422. return;
  423. filesystem->Close( (FileHandle_t)file );
  424. }
  425. };
  426. class StdIOWriteBinary : public IFileWriteBinary
  427. {
  428. public:
  429. int create( const char *pFileName )
  430. {
  431. return (int)filesystem->Open( pFileName, "wb" );
  432. }
  433. int write( void *pData, int size, int file )
  434. {
  435. return filesystem->Write( pData, size, (FileHandle_t)file );
  436. }
  437. void close( int file )
  438. {
  439. filesystem->Close( (FileHandle_t)file );
  440. }
  441. void seek( int file, int pos )
  442. {
  443. filesystem->Seek( (FileHandle_t)file, pos, FILESYSTEM_SEEK_HEAD );
  444. }
  445. unsigned int tell( int file )
  446. {
  447. return filesystem->Tell( (FileHandle_t)file );
  448. }
  449. };
  450. static StdIOReadBinary io_in;
  451. static StdIOWriteBinary io_out;
  452. #define RIFF_WAVE MAKEID('W','A','V','E')
  453. #define WAVE_FMT MAKEID('f','m','t',' ')
  454. #define WAVE_DATA MAKEID('d','a','t','a')
  455. #define WAVE_FACT MAKEID('f','a','c','t')
  456. #define WAVE_CUE MAKEID('c','u','e',' ')
  457. //-----------------------------------------------------------------------------
  458. // Purpose:
  459. // Input : &walk -
  460. //-----------------------------------------------------------------------------
  461. static void SceneManager_ParseSentence( CSentence& sentence, IterateRIFF &walk )
  462. {
  463. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  464. buf.EnsureCapacity( walk.ChunkSize() );
  465. walk.ChunkRead( buf.Base() );
  466. buf.SeekPut( CUtlBuffer::SEEK_HEAD, walk.ChunkSize() );
  467. sentence.InitFromDataChunk( buf.Base(), buf.TellPut() );
  468. }
  469. bool SceneManager_LoadSentenceFromWavFileUsingIO( char const *wavfile, CSentence& sentence, IFileReadBinary& io )
  470. {
  471. sentence.Reset();
  472. InFileRIFF riff( wavfile, io );
  473. // UNDONE: Don't use printf to handle errors
  474. if ( riff.RIFFName() != RIFF_WAVE )
  475. {
  476. return false;
  477. }
  478. // set up the iterator for the whole file (root RIFF is a chunk)
  479. IterateRIFF walk( riff, riff.RIFFSize() );
  480. // This chunk must be first as it contains the wave's format
  481. // break out when we've parsed it
  482. bool found = false;
  483. while ( walk.ChunkAvailable() && !found )
  484. {
  485. switch( walk.ChunkName() )
  486. {
  487. case WAVE_VALVEDATA:
  488. {
  489. found = true;
  490. SceneManager_ParseSentence( sentence, walk );
  491. }
  492. break;
  493. }
  494. walk.ChunkNext();
  495. }
  496. return true;
  497. }
  498. bool SceneManager_LoadSentenceFromWavFile( char const *wavfile, CSentence& sentence )
  499. {
  500. return SceneManager_LoadSentenceFromWavFileUsingIO( wavfile, sentence, io_in );
  501. }
  502. //-----------------------------------------------------------------------------
  503. // Purpose:
  504. // Input : store -
  505. //-----------------------------------------------------------------------------
  506. static void SceneManager_StoreValveDataChunk( CSentence& sentence, IterateOutputRIFF& store )
  507. {
  508. // Buffer and dump data
  509. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  510. sentence.SaveToBuffer( buf );
  511. // Copy into store
  512. store.ChunkWriteData( buf.Base(), buf.TellPut() );
  513. }
  514. bool SceneManager_SaveSentenceToWavFile( char const *wavfile, CSentence& sentence )
  515. {
  516. char tempfile[ 512 ];
  517. Q_StripExtension( wavfile, tempfile, sizeof( tempfile ) );
  518. Q_DefaultExtension( tempfile, ".tmp", sizeof( tempfile ) );
  519. if ( filesystem->FileExists( tempfile, "GAME" ) )
  520. {
  521. filesystem->RemoveFile( tempfile, "GAME" );
  522. }
  523. if ( !filesystem->IsFileWritable( wavfile ) )
  524. {
  525. int retval = MultipleRequest( va( "Check out '%s'?", wavfile ) );
  526. if ( retval != 0 )
  527. return false;
  528. VSS_Checkout( wavfile );
  529. }
  530. if ( !filesystem->IsFileWritable( wavfile ) )
  531. {
  532. Con_Printf( "%s is not writable, can't save sentence data to file\n", wavfile );
  533. return false;
  534. }
  535. // Rename original wavfile to temp
  536. filesystem->RenameFile( wavfile, tempfile, "GAME" );
  537. // NOTE: Put this in it's own scope so that the destructor for outfileRFF actually closes the file!!!!
  538. {
  539. // Read from Temp
  540. InFileRIFF riff( tempfile, io_in );
  541. Assert( riff.RIFFName() == RIFF_WAVE );
  542. // set up the iterator for the whole file (root RIFF is a chunk)
  543. IterateRIFF walk( riff, riff.RIFFSize() );
  544. // And put data back into original wavfile by name
  545. OutFileRIFF riffout( wavfile, io_out );
  546. IterateOutputRIFF store( riffout );
  547. bool wordtrackwritten = false;
  548. // Walk input chunks and copy to output
  549. while ( walk.ChunkAvailable() )
  550. {
  551. store.ChunkStart( walk.ChunkName() );
  552. switch ( walk.ChunkName() )
  553. {
  554. case WAVE_VALVEDATA:
  555. {
  556. // Overwrite data
  557. SceneManager_StoreValveDataChunk( sentence, store );
  558. wordtrackwritten = true;
  559. }
  560. break;
  561. default:
  562. store.CopyChunkData( walk );
  563. break;
  564. }
  565. store.ChunkFinish();
  566. walk.ChunkNext();
  567. }
  568. // If we didn't write it above, write it now
  569. if ( !wordtrackwritten )
  570. {
  571. store.ChunkStart( WAVE_VALVEDATA );
  572. SceneManager_StoreValveDataChunk( sentence, store );
  573. store.ChunkFinish();
  574. }
  575. }
  576. // Remove temp file
  577. filesystem->RemoveFile( tempfile, NULL );
  578. return true;
  579. }
  580. void SceneManager_LoadWindowPositions( KeyValues *kv, mxWindow *wnd )
  581. {
  582. bool zoomed = kv->GetInt( "zoomed", 0 ) ? true : false;
  583. int x = kv->GetInt( "x", 0 );
  584. int y = kv->GetInt( "y", 0 );
  585. int w = kv->GetInt( "w", 400 );
  586. int h = kv->GetInt( "h", 300 );
  587. wnd->setBounds( x, y, w, h );
  588. if ( zoomed )
  589. {
  590. ShowWindow( (HWND)wnd->getHandle(), SW_SHOWMAXIMIZED );
  591. }
  592. }
  593. static void Indent( CUtlBuffer& buf, int numtabs )
  594. {
  595. for ( int i = 0 ; i < numtabs; i++ )
  596. {
  597. buf.Printf( "\t" );
  598. }
  599. }
  600. void SceneManager_SaveWindowPositions( CUtlBuffer& buf, int indent, mxWindow *wnd )
  601. {
  602. int x, y, w, h;
  603. x = wnd->x();
  604. y = wnd->y();
  605. w = wnd->w();
  606. h = wnd->h();
  607. // xpos and ypos are screen space
  608. POINT pt;
  609. pt.x = x;
  610. pt.y = y;
  611. // Convert from screen space to relative to client area of parent window so
  612. // the setBounds == MoveWindow call will offset to the same location
  613. if ( wnd->getParent() )
  614. {
  615. ScreenToClient( (HWND)wnd->getParent()->getHandle(), &pt );
  616. x = (short)pt.x;
  617. y = (short)pt.y;
  618. }
  619. Indent( buf, indent );
  620. buf.Printf( "\"x\"\t\"%i\"\n", x );
  621. Indent( buf, indent );
  622. buf.Printf( "\"y\"\t\"%i\"\n", y );
  623. Indent( buf, indent );
  624. buf.Printf( "\"w\"\t\"%i\"\n", w );
  625. Indent( buf, indent );
  626. buf.Printf( "\"h\"\t\"%i\"\n", h );
  627. bool zoomed = IsZoomed( (HWND)wnd->getHandle() ) ? true : false;
  628. Indent( buf, indent );
  629. buf.Printf( "\"zoomed\"\t\"%i\"\n", zoomed ? 1 : 0 );
  630. }
  631. #if defined( _WIN32 ) || defined( WIN32 )
  632. #define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/')
  633. #else //_WIN32
  634. #define PATHSEPARATOR(c) ((c) == '/')
  635. #endif //_WIN32
  636. static bool charsmatch( char c1, char c2 )
  637. {
  638. if ( tolower( c1 ) == tolower( c2 ) )
  639. return true;
  640. if ( PATHSEPARATOR( c1 ) && PATHSEPARATOR( c2 ) )
  641. return true;
  642. return false;
  643. }
  644. char *Q_stristr_slash( char const *pStr, char const *pSearch )
  645. {
  646. AssertValidStringPtr(pStr);
  647. AssertValidStringPtr(pSearch);
  648. if (!pStr || !pSearch)
  649. return 0;
  650. char const* pLetter = pStr;
  651. // Check the entire string
  652. while (*pLetter != 0)
  653. {
  654. // Skip over non-matches
  655. if ( charsmatch( *pLetter, *pSearch ) )
  656. {
  657. // Check for match
  658. char const* pMatch = pLetter + 1;
  659. char const* pTest = pSearch + 1;
  660. while (*pTest != 0)
  661. {
  662. // We've run off the end; don't bother.
  663. if (*pMatch == 0)
  664. return 0;
  665. if ( !charsmatch( *pMatch, *pTest ) )
  666. break;
  667. ++pMatch;
  668. ++pTest;
  669. }
  670. // Found a match!
  671. if (*pTest == 0)
  672. return (char *)pLetter;
  673. }
  674. ++pLetter;
  675. }
  676. return 0;
  677. }
  678. //-----------------------------------------------------------------------------
  679. // Purpose:
  680. // Input : *filename -
  681. //-----------------------------------------------------------------------------
  682. void MakeFileWriteable( const char *filename )
  683. {
  684. Assert( filesystem );
  685. char fullpath[ 512 ];
  686. if (filesystem->GetLocalPath( filename, fullpath, sizeof(fullpath) ))
  687. {
  688. Q_FixSlashes( fullpath );
  689. SetFileAttributes( fullpath, FILE_ATTRIBUTE_NORMAL );
  690. }
  691. }