Fix line endings. WHAMMY.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,60 +1,60 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// CAPTIONCOMPILER.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,..\common,$SRCDIR\game\shared,.\"
|
||||
$PreprocessorDefinitions "$BASE;captioncompiler"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Captioncompiler"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "captioncompiler.cpp"
|
||||
$File "$SRCDIR\common\compiledcaptionswap.cpp"
|
||||
$File "..\common\filesystem_tools.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "cbase.h"
|
||||
$File "..\common\filesystem_tools.h"
|
||||
}
|
||||
|
||||
$Folder "Shared Code"
|
||||
{
|
||||
$File "..\common\cmdlib.cpp"
|
||||
$File "..\common\cmdlib.h"
|
||||
$File "$SRCDIR\public\filesystem_helpers.cpp"
|
||||
$File "$SRCDIR\public\filesystem_helpers.h"
|
||||
$File "$SRCDIR\public\filesystem_init.cpp"
|
||||
$File "$SRCDIR\public\filesystem_init.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
$File "..\common\pacifier.cpp"
|
||||
$File "..\common\pacifier.h"
|
||||
$File "..\common\scriplib.cpp"
|
||||
$File "..\common\scriplib.h"
|
||||
$File "$SRCDIR\public\stringregistry.cpp"
|
||||
$File "$SRCDIR\public\stringregistry.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib appframework
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
$Lib tier3
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// CAPTIONCOMPILER.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,..\common,$SRCDIR\game\shared,.\"
|
||||
$PreprocessorDefinitions "$BASE;captioncompiler"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Captioncompiler"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "captioncompiler.cpp"
|
||||
$File "$SRCDIR\common\compiledcaptionswap.cpp"
|
||||
$File "..\common\filesystem_tools.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "cbase.h"
|
||||
$File "..\common\filesystem_tools.h"
|
||||
}
|
||||
|
||||
$Folder "Shared Code"
|
||||
{
|
||||
$File "..\common\cmdlib.cpp"
|
||||
$File "..\common\cmdlib.h"
|
||||
$File "$SRCDIR\public\filesystem_helpers.cpp"
|
||||
$File "$SRCDIR\public\filesystem_helpers.h"
|
||||
$File "$SRCDIR\public\filesystem_init.cpp"
|
||||
$File "$SRCDIR\public\filesystem_init.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
$File "..\common\pacifier.cpp"
|
||||
$File "..\common\pacifier.h"
|
||||
$File "..\common\scriplib.cpp"
|
||||
$File "..\common\scriplib.h"
|
||||
$File "$SRCDIR\public\stringregistry.cpp"
|
||||
$File "$SRCDIR\public\stringregistry.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib appframework
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
$Lib tier3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef CBASE_H
|
||||
#define CBASE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basetypes.h"
|
||||
|
||||
// This is just a dummy file to make this tool compile
|
||||
#include "ai_activity.h"
|
||||
#include "utlvector.h"
|
||||
|
||||
#endif // CBASE_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef CBASE_H
|
||||
#define CBASE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basetypes.h"
|
||||
|
||||
// This is just a dummy file to make this tool compile
|
||||
#include "ai_activity.h"
|
||||
#include "utlvector.h"
|
||||
|
||||
#endif // CBASE_H
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef ISQLDLREPLYTARGET_H
|
||||
#define ISQLDLREPLYTARGET_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to handle results of SQL queries
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISQLDBReplyTarget
|
||||
{
|
||||
public:
|
||||
// handles a response from the database
|
||||
virtual void SQLDBResponse(int cmdID, int returnState, int returnVal, void *data) = 0;
|
||||
|
||||
// called from a seperate thread; tells the reply target that a message is waiting for it
|
||||
virtual void WakeUp() = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // ISQLDLREPLYTARGET_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef ISQLDLREPLYTARGET_H
|
||||
#define ISQLDLREPLYTARGET_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to handle results of SQL queries
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISQLDBReplyTarget
|
||||
{
|
||||
public:
|
||||
// handles a response from the database
|
||||
virtual void SQLDBResponse(int cmdID, int returnState, int returnVal, void *data) = 0;
|
||||
|
||||
// called from a seperate thread; tells the reply target that a message is waiting for it
|
||||
virtual void WakeUp() = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // ISQLDLREPLYTARGET_H
|
||||
|
||||
@@ -1,192 +1,192 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "MySqlDatabase.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMySqlDatabase::CMySqlDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
// blocks until db process thread has stopped
|
||||
//-----------------------------------------------------------------------------
|
||||
CMySqlDatabase::~CMySqlDatabase()
|
||||
{
|
||||
// flag the thread to stop
|
||||
m_bRunThread = false;
|
||||
|
||||
// pulse the thread to make it run
|
||||
::SetEvent(m_hEvent);
|
||||
|
||||
// make sure it's done
|
||||
::EnterCriticalSection(&m_csThread);
|
||||
::LeaveCriticalSection(&m_csThread);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Thread access function
|
||||
//-----------------------------------------------------------------------------
|
||||
static DWORD WINAPI staticThreadFunc(void *param)
|
||||
{
|
||||
((CMySqlDatabase *)param)->RunThread();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Establishes connection to the database and sets up this object to handle db command
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMySqlDatabase::Initialize()
|
||||
{
|
||||
// prepare critical sections
|
||||
//!! need to download SDK and replace these with InitializeCriticalSectionAndSpinCount() calls
|
||||
::InitializeCriticalSection(&m_csThread);
|
||||
::InitializeCriticalSection(&m_csInQueue);
|
||||
::InitializeCriticalSection(&m_csOutQueue);
|
||||
::InitializeCriticalSection(&m_csDBAccess);
|
||||
|
||||
// initialize wait calls
|
||||
m_hEvent = ::CreateEvent(NULL, false, true, NULL);
|
||||
|
||||
// start the DB-access thread
|
||||
m_bRunThread = true;
|
||||
|
||||
unsigned long threadID;
|
||||
::CreateThread(NULL, 0, staticThreadFunc, this, 0, &threadID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Main thread loop
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMySqlDatabase::RunThread()
|
||||
{
|
||||
::EnterCriticalSection(&m_csThread);
|
||||
while (m_bRunThread)
|
||||
{
|
||||
if (m_InQueue.Count() > 0)
|
||||
{
|
||||
// get a dispatched DB request
|
||||
::EnterCriticalSection(&m_csInQueue);
|
||||
|
||||
// pop the front of the queue
|
||||
int headIndex = m_InQueue.Head();
|
||||
msg_t msg = m_InQueue[headIndex];
|
||||
m_InQueue.Remove(headIndex);
|
||||
|
||||
::LeaveCriticalSection(&m_csInQueue);
|
||||
|
||||
::EnterCriticalSection(&m_csDBAccess);
|
||||
|
||||
// run sqldb command
|
||||
msg.result = msg.cmd->RunCommand();
|
||||
|
||||
::LeaveCriticalSection(&m_csDBAccess);
|
||||
|
||||
if (msg.replyTarget)
|
||||
{
|
||||
// put the results in the outgoing queue
|
||||
::EnterCriticalSection(&m_csOutQueue);
|
||||
m_OutQueue.AddToTail(msg);
|
||||
::LeaveCriticalSection(&m_csOutQueue);
|
||||
|
||||
// wake up out queue
|
||||
msg.replyTarget->WakeUp();
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is no return data from the call, so kill the object now
|
||||
msg.cmd->deleteThis();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing in incoming queue, so wait until we get the signal
|
||||
::WaitForSingleObject(m_hEvent, INFINITE);
|
||||
}
|
||||
|
||||
// check the size of the outqueue; if it's getting too big, sleep to let the main thread catch up
|
||||
if (m_OutQueue.Count() > 50)
|
||||
{
|
||||
::Sleep(2);
|
||||
}
|
||||
}
|
||||
::LeaveCriticalSection(&m_csThread);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds a database command to the queue, and wakes the db thread
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMySqlDatabase::AddCommandToQueue(ISQLDBCommand *cmd, ISQLDBReplyTarget *replyTarget, int returnState)
|
||||
{
|
||||
::EnterCriticalSection(&m_csInQueue);
|
||||
|
||||
// add to the queue
|
||||
msg_t msg = { cmd, replyTarget, 0, returnState };
|
||||
m_InQueue.AddToTail(msg);
|
||||
|
||||
::LeaveCriticalSection(&m_csInQueue);
|
||||
|
||||
// signal the thread to start running
|
||||
::SetEvent(m_hEvent);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Dispatches responses to SQLDB queries
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMySqlDatabase::RunFrame()
|
||||
{
|
||||
bool doneWork = false;
|
||||
|
||||
while (m_OutQueue.Count() > 0)
|
||||
{
|
||||
::EnterCriticalSection(&m_csOutQueue);
|
||||
|
||||
// pop the first item in the queue
|
||||
int headIndex = m_OutQueue.Head();
|
||||
msg_t msg = m_OutQueue[headIndex];
|
||||
m_OutQueue.Remove(headIndex);
|
||||
|
||||
::LeaveCriticalSection(&m_csOutQueue);
|
||||
|
||||
// run result
|
||||
if (msg.replyTarget)
|
||||
{
|
||||
msg.replyTarget->SQLDBResponse(msg.cmd->GetID(), msg.returnState, msg.result, msg.cmd->GetReturnData());
|
||||
|
||||
// kill command
|
||||
// it would be a good optimization to be able to reuse these
|
||||
msg.cmd->deleteThis();
|
||||
}
|
||||
|
||||
doneWork = true;
|
||||
}
|
||||
|
||||
return doneWork;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: load info - returns the number of sql db queries waiting to be processed
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMySqlDatabase::QueriesInOutQueue()
|
||||
{
|
||||
// the queue names are from the DB point of view, not the server - thus the reversal
|
||||
return m_InQueue.Count();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: number of queries finished processing, waiting to be responded to
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMySqlDatabase::QueriesInFinishedQueue()
|
||||
{
|
||||
return m_OutQueue.Count();
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "MySqlDatabase.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMySqlDatabase::CMySqlDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
// blocks until db process thread has stopped
|
||||
//-----------------------------------------------------------------------------
|
||||
CMySqlDatabase::~CMySqlDatabase()
|
||||
{
|
||||
// flag the thread to stop
|
||||
m_bRunThread = false;
|
||||
|
||||
// pulse the thread to make it run
|
||||
::SetEvent(m_hEvent);
|
||||
|
||||
// make sure it's done
|
||||
::EnterCriticalSection(&m_csThread);
|
||||
::LeaveCriticalSection(&m_csThread);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Thread access function
|
||||
//-----------------------------------------------------------------------------
|
||||
static DWORD WINAPI staticThreadFunc(void *param)
|
||||
{
|
||||
((CMySqlDatabase *)param)->RunThread();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Establishes connection to the database and sets up this object to handle db command
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMySqlDatabase::Initialize()
|
||||
{
|
||||
// prepare critical sections
|
||||
//!! need to download SDK and replace these with InitializeCriticalSectionAndSpinCount() calls
|
||||
::InitializeCriticalSection(&m_csThread);
|
||||
::InitializeCriticalSection(&m_csInQueue);
|
||||
::InitializeCriticalSection(&m_csOutQueue);
|
||||
::InitializeCriticalSection(&m_csDBAccess);
|
||||
|
||||
// initialize wait calls
|
||||
m_hEvent = ::CreateEvent(NULL, false, true, NULL);
|
||||
|
||||
// start the DB-access thread
|
||||
m_bRunThread = true;
|
||||
|
||||
unsigned long threadID;
|
||||
::CreateThread(NULL, 0, staticThreadFunc, this, 0, &threadID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Main thread loop
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMySqlDatabase::RunThread()
|
||||
{
|
||||
::EnterCriticalSection(&m_csThread);
|
||||
while (m_bRunThread)
|
||||
{
|
||||
if (m_InQueue.Count() > 0)
|
||||
{
|
||||
// get a dispatched DB request
|
||||
::EnterCriticalSection(&m_csInQueue);
|
||||
|
||||
// pop the front of the queue
|
||||
int headIndex = m_InQueue.Head();
|
||||
msg_t msg = m_InQueue[headIndex];
|
||||
m_InQueue.Remove(headIndex);
|
||||
|
||||
::LeaveCriticalSection(&m_csInQueue);
|
||||
|
||||
::EnterCriticalSection(&m_csDBAccess);
|
||||
|
||||
// run sqldb command
|
||||
msg.result = msg.cmd->RunCommand();
|
||||
|
||||
::LeaveCriticalSection(&m_csDBAccess);
|
||||
|
||||
if (msg.replyTarget)
|
||||
{
|
||||
// put the results in the outgoing queue
|
||||
::EnterCriticalSection(&m_csOutQueue);
|
||||
m_OutQueue.AddToTail(msg);
|
||||
::LeaveCriticalSection(&m_csOutQueue);
|
||||
|
||||
// wake up out queue
|
||||
msg.replyTarget->WakeUp();
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is no return data from the call, so kill the object now
|
||||
msg.cmd->deleteThis();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing in incoming queue, so wait until we get the signal
|
||||
::WaitForSingleObject(m_hEvent, INFINITE);
|
||||
}
|
||||
|
||||
// check the size of the outqueue; if it's getting too big, sleep to let the main thread catch up
|
||||
if (m_OutQueue.Count() > 50)
|
||||
{
|
||||
::Sleep(2);
|
||||
}
|
||||
}
|
||||
::LeaveCriticalSection(&m_csThread);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds a database command to the queue, and wakes the db thread
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMySqlDatabase::AddCommandToQueue(ISQLDBCommand *cmd, ISQLDBReplyTarget *replyTarget, int returnState)
|
||||
{
|
||||
::EnterCriticalSection(&m_csInQueue);
|
||||
|
||||
// add to the queue
|
||||
msg_t msg = { cmd, replyTarget, 0, returnState };
|
||||
m_InQueue.AddToTail(msg);
|
||||
|
||||
::LeaveCriticalSection(&m_csInQueue);
|
||||
|
||||
// signal the thread to start running
|
||||
::SetEvent(m_hEvent);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Dispatches responses to SQLDB queries
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMySqlDatabase::RunFrame()
|
||||
{
|
||||
bool doneWork = false;
|
||||
|
||||
while (m_OutQueue.Count() > 0)
|
||||
{
|
||||
::EnterCriticalSection(&m_csOutQueue);
|
||||
|
||||
// pop the first item in the queue
|
||||
int headIndex = m_OutQueue.Head();
|
||||
msg_t msg = m_OutQueue[headIndex];
|
||||
m_OutQueue.Remove(headIndex);
|
||||
|
||||
::LeaveCriticalSection(&m_csOutQueue);
|
||||
|
||||
// run result
|
||||
if (msg.replyTarget)
|
||||
{
|
||||
msg.replyTarget->SQLDBResponse(msg.cmd->GetID(), msg.returnState, msg.result, msg.cmd->GetReturnData());
|
||||
|
||||
// kill command
|
||||
// it would be a good optimization to be able to reuse these
|
||||
msg.cmd->deleteThis();
|
||||
}
|
||||
|
||||
doneWork = true;
|
||||
}
|
||||
|
||||
return doneWork;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: load info - returns the number of sql db queries waiting to be processed
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMySqlDatabase::QueriesInOutQueue()
|
||||
{
|
||||
// the queue names are from the DB point of view, not the server - thus the reversal
|
||||
return m_InQueue.Count();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: number of queries finished processing, waiting to be responded to
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMySqlDatabase::QueriesInFinishedQueue()
|
||||
{
|
||||
return m_OutQueue.Count();
|
||||
}
|
||||
|
||||
@@ -1,104 +1,104 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MYSQLDATABASE_H
|
||||
#define MYSQLDATABASE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include "ISQLDBReplyTarget.h"
|
||||
#include "utlvector.h"
|
||||
#include "UtlLinkedList.h"
|
||||
|
||||
class ISQLDBCommand;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Generic MySQL accessing database
|
||||
// Provides threaded I/O queue functionality for accessing a mysql db
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMySqlDatabase
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CMySqlDatabase();
|
||||
~CMySqlDatabase();
|
||||
|
||||
// initialization - must be called before this object can be used
|
||||
bool Initialize();
|
||||
|
||||
// Dispatches responses to SQLDB queries
|
||||
bool RunFrame();
|
||||
|
||||
// load info - returns the number of sql db queries waiting to be processed
|
||||
virtual int QueriesInOutQueue();
|
||||
|
||||
// number of queries finished processing, waiting to be responded to
|
||||
virtual int QueriesInFinishedQueue();
|
||||
|
||||
// activates the thread
|
||||
void RunThread();
|
||||
|
||||
// command queues
|
||||
void AddCommandToQueue(ISQLDBCommand *cmd, ISQLDBReplyTarget *replyTarget, int returnState = 0);
|
||||
|
||||
private:
|
||||
|
||||
// threading data
|
||||
bool m_bRunThread;
|
||||
CRITICAL_SECTION m_csThread;
|
||||
CRITICAL_SECTION m_csInQueue;
|
||||
CRITICAL_SECTION m_csOutQueue;
|
||||
CRITICAL_SECTION m_csDBAccess;
|
||||
|
||||
// wait event
|
||||
HANDLE m_hEvent;
|
||||
|
||||
struct msg_t
|
||||
{
|
||||
ISQLDBCommand *cmd;
|
||||
ISQLDBReplyTarget *replyTarget;
|
||||
int result;
|
||||
int returnState;
|
||||
};
|
||||
|
||||
// command queues
|
||||
CUtlLinkedList<msg_t, int> m_InQueue;
|
||||
CUtlLinkedList<msg_t, int> m_OutQueue;
|
||||
};
|
||||
|
||||
class Connection;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to a command
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISQLDBCommand
|
||||
{
|
||||
public:
|
||||
// makes the command run (blocking), returning the success code
|
||||
virtual int RunCommand() = 0;
|
||||
|
||||
// return data
|
||||
virtual void *GetReturnData() { return NULL; }
|
||||
|
||||
// returns the command ID
|
||||
virtual int GetID() { return 0; }
|
||||
|
||||
// gets information about the command for if it failed
|
||||
virtual void GetDebugInfo(char *buf, int bufSize) { buf[0] = 0; }
|
||||
|
||||
// use to delete
|
||||
virtual void deleteThis() = 0;
|
||||
|
||||
protected:
|
||||
// protected destructor, so that it has to be deleted through deleteThis()
|
||||
virtual ~ISQLDBCommand() {}
|
||||
};
|
||||
|
||||
|
||||
#endif // MYSQLDATABASE_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MYSQLDATABASE_H
|
||||
#define MYSQLDATABASE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include "ISQLDBReplyTarget.h"
|
||||
#include "utlvector.h"
|
||||
#include "UtlLinkedList.h"
|
||||
|
||||
class ISQLDBCommand;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Generic MySQL accessing database
|
||||
// Provides threaded I/O queue functionality for accessing a mysql db
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMySqlDatabase
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CMySqlDatabase();
|
||||
~CMySqlDatabase();
|
||||
|
||||
// initialization - must be called before this object can be used
|
||||
bool Initialize();
|
||||
|
||||
// Dispatches responses to SQLDB queries
|
||||
bool RunFrame();
|
||||
|
||||
// load info - returns the number of sql db queries waiting to be processed
|
||||
virtual int QueriesInOutQueue();
|
||||
|
||||
// number of queries finished processing, waiting to be responded to
|
||||
virtual int QueriesInFinishedQueue();
|
||||
|
||||
// activates the thread
|
||||
void RunThread();
|
||||
|
||||
// command queues
|
||||
void AddCommandToQueue(ISQLDBCommand *cmd, ISQLDBReplyTarget *replyTarget, int returnState = 0);
|
||||
|
||||
private:
|
||||
|
||||
// threading data
|
||||
bool m_bRunThread;
|
||||
CRITICAL_SECTION m_csThread;
|
||||
CRITICAL_SECTION m_csInQueue;
|
||||
CRITICAL_SECTION m_csOutQueue;
|
||||
CRITICAL_SECTION m_csDBAccess;
|
||||
|
||||
// wait event
|
||||
HANDLE m_hEvent;
|
||||
|
||||
struct msg_t
|
||||
{
|
||||
ISQLDBCommand *cmd;
|
||||
ISQLDBReplyTarget *replyTarget;
|
||||
int result;
|
||||
int returnState;
|
||||
};
|
||||
|
||||
// command queues
|
||||
CUtlLinkedList<msg_t, int> m_InQueue;
|
||||
CUtlLinkedList<msg_t, int> m_OutQueue;
|
||||
};
|
||||
|
||||
class Connection;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to a command
|
||||
//-----------------------------------------------------------------------------
|
||||
class ISQLDBCommand
|
||||
{
|
||||
public:
|
||||
// makes the command run (blocking), returning the success code
|
||||
virtual int RunCommand() = 0;
|
||||
|
||||
// return data
|
||||
virtual void *GetReturnData() { return NULL; }
|
||||
|
||||
// returns the command ID
|
||||
virtual int GetID() { return 0; }
|
||||
|
||||
// gets information about the command for if it failed
|
||||
virtual void GetDebugInfo(char *buf, int bufSize) { buf[0] = 0; }
|
||||
|
||||
// use to delete
|
||||
virtual void deleteThis() = 0;
|
||||
|
||||
protected:
|
||||
// protected destructor, so that it has to be deleted through deleteThis()
|
||||
virtual ~ISQLDBCommand() {}
|
||||
};
|
||||
|
||||
|
||||
#endif // MYSQLDATABASE_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,404 +1,404 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BSPLIB_H
|
||||
#define BSPLIB_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "bspfile.h"
|
||||
#include "utlvector.h"
|
||||
#include "utlstring.h"
|
||||
#include "utllinkedlist.h"
|
||||
#include "byteswap.h"
|
||||
#ifdef ENGINE_DLL
|
||||
#include "zone.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENGINE_DLL
|
||||
typedef CUtlVector<unsigned char, CHunkMemory<unsigned char> > CDispLightmapSamplePositions;
|
||||
#else
|
||||
typedef CUtlVector<unsigned char> CDispLightmapSamplePositions;
|
||||
#endif
|
||||
|
||||
class ISpatialQuery;
|
||||
struct Ray_t;
|
||||
class Vector2D;
|
||||
struct portal_t;
|
||||
class CUtlBuffer;
|
||||
class IZip;
|
||||
|
||||
// this is only true in vrad
|
||||
extern bool g_bHDR;
|
||||
|
||||
// default width/height of luxels in world units.
|
||||
#define DEFAULT_LUXEL_SIZE ( 16.0f )
|
||||
|
||||
#define SINGLE_BRUSH_MAP (MAX_BRUSH_LIGHTMAP_DIM_INCLUDING_BORDER*MAX_BRUSH_LIGHTMAP_DIM_INCLUDING_BORDER)
|
||||
#define SINGLEMAP (MAX_LIGHTMAP_DIM_INCLUDING_BORDER*MAX_LIGHTMAP_DIM_INCLUDING_BORDER)
|
||||
|
||||
struct entity_t
|
||||
{
|
||||
Vector origin;
|
||||
int firstbrush;
|
||||
int numbrushes;
|
||||
epair_t *epairs;
|
||||
|
||||
// only valid for func_areaportals
|
||||
int areaportalnum;
|
||||
int portalareas[2];
|
||||
portal_t *m_pPortalsLeadingIntoAreas[2]; // portals leading into portalareas
|
||||
};
|
||||
|
||||
extern int num_entities;
|
||||
extern entity_t entities[MAX_MAP_ENTITIES];
|
||||
|
||||
extern int nummodels;
|
||||
extern dmodel_t dmodels[MAX_MAP_MODELS];
|
||||
|
||||
extern int visdatasize;
|
||||
extern byte dvisdata[MAX_MAP_VISIBILITY];
|
||||
extern dvis_t *dvis;
|
||||
|
||||
extern CUtlVector<byte> dlightdataHDR;
|
||||
extern CUtlVector<byte> dlightdataLDR;
|
||||
extern CUtlVector<byte> *pdlightdata;
|
||||
extern CUtlVector<char> dentdata;
|
||||
|
||||
extern int numleafs;
|
||||
#if !defined( _X360 )
|
||||
extern dleaf_t dleafs[MAX_MAP_LEAFS];
|
||||
#else
|
||||
extern dleaf_t *dleafs;
|
||||
#endif
|
||||
extern CUtlVector<dleafambientlighting_t> *g_pLeafAmbientLighting;
|
||||
extern CUtlVector<dleafambientindex_t> *g_pLeafAmbientIndex;
|
||||
extern unsigned short g_LeafMinDistToWater[MAX_MAP_LEAFS];
|
||||
|
||||
extern int numplanes;
|
||||
extern dplane_t dplanes[MAX_MAP_PLANES];
|
||||
|
||||
extern int numvertexes;
|
||||
extern dvertex_t dvertexes[MAX_MAP_VERTS];
|
||||
|
||||
extern int g_numvertnormalindices; // dfaces reference these. These index g_vertnormals.
|
||||
extern unsigned short g_vertnormalindices[MAX_MAP_VERTNORMALS];
|
||||
|
||||
extern int g_numvertnormals;
|
||||
extern Vector g_vertnormals[MAX_MAP_VERTNORMALS];
|
||||
|
||||
extern int numnodes;
|
||||
extern dnode_t dnodes[MAX_MAP_NODES];
|
||||
|
||||
extern CUtlVector<texinfo_t> texinfo;
|
||||
|
||||
extern int numtexdata;
|
||||
extern dtexdata_t dtexdata[MAX_MAP_TEXDATA];
|
||||
|
||||
// displacement map .bsp file info
|
||||
extern CUtlVector<ddispinfo_t> g_dispinfo;
|
||||
extern CUtlVector<CDispVert> g_DispVerts;
|
||||
extern CUtlVector<CDispTri> g_DispTris;
|
||||
extern CDispLightmapSamplePositions g_DispLightmapSamplePositions; // LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS
|
||||
|
||||
extern int numorigfaces;
|
||||
extern dface_t dorigfaces[MAX_MAP_FACES];
|
||||
|
||||
extern int g_numprimitives;
|
||||
extern dprimitive_t g_primitives[MAX_MAP_PRIMITIVES];
|
||||
|
||||
extern int g_numprimverts;
|
||||
extern dprimvert_t g_primverts[MAX_MAP_PRIMVERTS];
|
||||
|
||||
extern int g_numprimindices;
|
||||
extern unsigned short g_primindices[MAX_MAP_PRIMINDICES];
|
||||
|
||||
extern int numfaces;
|
||||
extern dface_t dfaces[MAX_MAP_FACES];
|
||||
|
||||
extern int numfaceids;
|
||||
extern CUtlVector<dfaceid_t> dfaceids;
|
||||
|
||||
extern int numfaces_hdr;
|
||||
extern dface_t dfaces_hdr[MAX_MAP_FACES];
|
||||
|
||||
extern int numedges;
|
||||
extern dedge_t dedges[MAX_MAP_EDGES];
|
||||
|
||||
extern int numleaffaces;
|
||||
extern unsigned short dleaffaces[MAX_MAP_LEAFFACES];
|
||||
|
||||
extern int numleafbrushes;
|
||||
extern unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES];
|
||||
|
||||
extern int numsurfedges;
|
||||
extern int dsurfedges[MAX_MAP_SURFEDGES];
|
||||
|
||||
extern int numareas;
|
||||
extern darea_t dareas[MAX_MAP_AREAS];
|
||||
|
||||
extern int numareaportals;
|
||||
extern dareaportal_t dareaportals[MAX_MAP_AREAPORTALS];
|
||||
|
||||
extern int numbrushes;
|
||||
extern dbrush_t dbrushes[MAX_MAP_BRUSHES];
|
||||
|
||||
extern int numbrushsides;
|
||||
extern dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES];
|
||||
|
||||
extern int *pNumworldlights;
|
||||
extern dworldlight_t *dworldlights;
|
||||
|
||||
extern Vector g_ClipPortalVerts[MAX_MAP_PORTALVERTS];
|
||||
extern int g_nClipPortalVerts;
|
||||
|
||||
extern dcubemapsample_t g_CubemapSamples[MAX_MAP_CUBEMAPSAMPLES];
|
||||
extern int g_nCubemapSamples;
|
||||
|
||||
extern int g_nOverlayCount;
|
||||
extern doverlay_t g_Overlays[MAX_MAP_OVERLAYS];
|
||||
extern doverlayfade_t g_OverlayFades[MAX_MAP_OVERLAYS]; // Parallel array of fade info in a separate lump to avoid breaking backwards compat
|
||||
|
||||
extern int g_nWaterOverlayCount;
|
||||
extern dwateroverlay_t g_WaterOverlays[MAX_MAP_WATEROVERLAYS];
|
||||
|
||||
extern CUtlVector<char> g_TexDataStringData;
|
||||
extern CUtlVector<int> g_TexDataStringTable;
|
||||
|
||||
extern int numleafwaterdata;
|
||||
extern dleafwaterdata_t dleafwaterdata[MAX_MAP_LEAFWATERDATA];
|
||||
|
||||
extern CUtlVector<CFaceMacroTextureInfo> g_FaceMacroTextureInfos;
|
||||
|
||||
extern CUtlVector<doccluderdata_t> g_OccluderData;
|
||||
extern CUtlVector<doccluderpolydata_t> g_OccluderPolyData;
|
||||
extern CUtlVector<int> g_OccluderVertexIndices;
|
||||
|
||||
// level flags - see LVLFLAGS_xxx in bspfile.h
|
||||
extern uint32 g_LevelFlags;
|
||||
|
||||
// physics collision data
|
||||
extern byte *g_pPhysCollide;
|
||||
extern int g_PhysCollideSize;
|
||||
extern byte *g_pPhysDisp;
|
||||
extern int g_PhysDispSize;
|
||||
|
||||
// Embedded pack/pak file
|
||||
IZip *GetPakFile( void );
|
||||
IZip *GetSwapPakFile( void );
|
||||
void ClearPakFile( IZip *pak );
|
||||
void AddFileToPak( IZip *pak, const char *pRelativeName, const char *fullpath );
|
||||
void AddBufferToPak( IZip *pak, const char *pRelativeName, void *data, int length, bool bTextMode );
|
||||
bool FileExistsInPak( IZip *pak, const char *pRelativeName );
|
||||
bool ReadFileFromPak( IZip *pak, const char *pRelativeName, bool bTextMode, CUtlBuffer &buf );
|
||||
void RemoveFileFromPak( IZip *pak, const char *pRelativeName );
|
||||
int GetNextFilename( IZip *pak, int id, char *pBuffer, int bufferSize, int &fileSize );
|
||||
void ForceAlignment( IZip *pak, bool bAlign, bool bCompatibleFormat, unsigned int alignmentSize );
|
||||
|
||||
typedef bool (*CompressFunc_t)( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer );
|
||||
typedef bool (*VTFConvertFunc_t)( const char *pDebugName, CUtlBuffer &sourceBuf, CUtlBuffer &targetBuf, CompressFunc_t pCompressFunc );
|
||||
typedef bool (*VHVFixupFunc_t)( const char *pVhvFilename, const char *pModelName, CUtlBuffer &sourceBuf, CUtlBuffer &targetBuf );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Game lump memory storage
|
||||
//-----------------------------------------------------------------------------
|
||||
// NOTE: This is not optimal at all; since I expect client lumps to
|
||||
// not be accessed all that often.
|
||||
|
||||
struct GameLump_t
|
||||
{
|
||||
GameLumpId_t m_Id;
|
||||
unsigned short m_Flags;
|
||||
unsigned short m_Version;
|
||||
CUtlMemory< unsigned char > m_Memory;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle to a game lump
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef unsigned short GameLumpHandle_t;
|
||||
|
||||
class CGameLump
|
||||
{
|
||||
public:
|
||||
//-----------------------------------------------------------------------------
|
||||
// Convert four-CC code to a handle + back
|
||||
//-----------------------------------------------------------------------------
|
||||
GameLumpHandle_t GetGameLumpHandle( GameLumpId_t id );
|
||||
GameLumpId_t GetGameLumpId( GameLumpHandle_t handle );
|
||||
int GetGameLumpFlags( GameLumpHandle_t handle );
|
||||
int GetGameLumpVersion( GameLumpHandle_t handle );
|
||||
void ComputeGameLumpSizeAndCount( int& size, int& clumpCount );
|
||||
void ParseGameLump( dheader_t* pHeader );
|
||||
void SwapGameLump( GameLumpId_t id, int version, byte *dest, byte *src, int size );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Game lump accessor methods
|
||||
//-----------------------------------------------------------------------------
|
||||
void* GetGameLump( GameLumpHandle_t handle );
|
||||
int GameLumpSize( GameLumpHandle_t handle );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Game lump iteration methods
|
||||
//-----------------------------------------------------------------------------
|
||||
GameLumpHandle_t FirstGameLump();
|
||||
GameLumpHandle_t NextGameLump( GameLumpHandle_t handle );
|
||||
GameLumpHandle_t InvalidGameLump();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Game lump creation/destruction method
|
||||
//-----------------------------------------------------------------------------
|
||||
GameLumpHandle_t CreateGameLump( GameLumpId_t id, int size, int flags, int version );
|
||||
void DestroyGameLump( GameLumpHandle_t handle );
|
||||
void DestroyAllGameLumps();
|
||||
|
||||
private:
|
||||
CUtlLinkedList< GameLump_t, GameLumpHandle_t > m_GameLumps;
|
||||
};
|
||||
|
||||
extern CGameLump g_GameLumps;
|
||||
extern CByteswap g_Swap;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper for the bspzip tool
|
||||
//-----------------------------------------------------------------------------
|
||||
void ExtractZipFileFromBSP( char *pBSPFileName, char *pZipFileName );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// String table methods
|
||||
//-----------------------------------------------------------------------------
|
||||
const char * TexDataStringTable_GetString( int stringID );
|
||||
int TexDataStringTable_AddOrFindString( const char *pString );
|
||||
|
||||
void DecompressVis (byte *in, byte *decompressed);
|
||||
int CompressVis (byte *vis, byte *dest);
|
||||
|
||||
void OpenBSPFile( const char *filename );
|
||||
void CloseBSPFile(void);
|
||||
void LoadBSPFile( const char *filename );
|
||||
void LoadBSPFile_FileSystemOnly( const char *filename );
|
||||
void LoadBSPFileTexinfo( const char *filename );
|
||||
void WriteBSPFile( const char *filename, char *pUnused = NULL );
|
||||
void PrintBSPFileSizes(void);
|
||||
void PrintBSPPackDirectory(void);
|
||||
void ReleasePakFileLumps(void);
|
||||
bool SwapBSPFile( const char *filename, const char *swapFilename, bool bSwapOnLoad, VTFConvertFunc_t pVTFConvertFunc, VHVFixupFunc_t pVHVFixupFunc, CompressFunc_t pCompressFunc );
|
||||
bool GetPakFileLump( const char *pBSPFilename, void **pPakData, int *pPakSize );
|
||||
bool SetPakFileLump( const char *pBSPFilename, const char *pNewFilename, void *pPakData, int pakSize );
|
||||
void WriteLumpToFile( char *filename, int lump );
|
||||
void WriteLumpToFile( char *filename, int lump, int nLumpVersion, void *pBuffer, size_t nBufLen );
|
||||
bool GetBSPDependants( const char *pBSPFilename, CUtlVector< CUtlString > *pList );
|
||||
void UnloadBSPFile();
|
||||
|
||||
void ParseEntities (void);
|
||||
void UnparseEntities (void);
|
||||
void PrintEntity (entity_t *ent);
|
||||
|
||||
void SetKeyValue (entity_t *ent, const char *key, const char *value);
|
||||
char *ValueForKey (entity_t *ent, char *key);
|
||||
// will return "" if not present
|
||||
int IntForKey (entity_t *ent, char *key);
|
||||
int IntForKeyWithDefault(entity_t *ent, char *key, int nDefault );
|
||||
vec_t FloatForKey (entity_t *ent, char *key);
|
||||
vec_t FloatForKeyWithDefault (entity_t *ent, char *key, float default_value);
|
||||
void GetVectorForKey (entity_t *ent, char *key, Vector& vec);
|
||||
void GetVector2DForKey (entity_t *ent, char *key, Vector2D& vec);
|
||||
void GetAnglesForKey (entity_t *ent, char *key, QAngle& vec);
|
||||
epair_t *ParseEpair (void);
|
||||
void StripTrailing (char *e);
|
||||
|
||||
// Build a list of the face's vertices (index into dvertexes).
|
||||
// points must be able to hold pFace->numedges indices.
|
||||
void BuildFaceCalcWindingData( dface_t *pFace, int *points );
|
||||
|
||||
// Convert a tristrip to a trilist.
|
||||
// Removes degenerates.
|
||||
// Fills in pTriListIndices and pnTriListIndices.
|
||||
// You must free pTriListIndices with delete[].
|
||||
void TriStripToTriList(
|
||||
unsigned short const *pTriStripIndices,
|
||||
int nTriStripIndices,
|
||||
unsigned short **pTriListIndices,
|
||||
int *pnTriListIndices );
|
||||
|
||||
// Calculates the lightmap coordinates at a given set of positions given the
|
||||
// lightmap basis information.
|
||||
void CalcTextureCoordsAtPoints(
|
||||
float const texelsPerWorldUnits[2][4],
|
||||
int const subtractOffset[2],
|
||||
Vector const *pPoints,
|
||||
int const nPoints,
|
||||
Vector2D *pCoords );
|
||||
|
||||
// Figure out lightmap extents on all (lit) faces.
|
||||
void UpdateAllFaceLightmapExtents();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets at an interface for the tree for enumeration of leaves in volumes.
|
||||
//-----------------------------------------------------------------------------
|
||||
ISpatialQuery* ToolBSPTree();
|
||||
|
||||
class IBSPNodeEnumerator
|
||||
{
|
||||
public:
|
||||
// call back with a node and a context
|
||||
virtual bool EnumerateNode( int node, Ray_t const& ray, float f, int context ) = 0;
|
||||
|
||||
// call back with a leaf and a context
|
||||
virtual bool EnumerateLeaf( int leaf, Ray_t const& ray, float start, float end, int context ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enumerates nodes + leafs in front to back order...
|
||||
//-----------------------------------------------------------------------------
|
||||
bool EnumerateNodesAlongRay( Ray_t const& ray, IBSPNodeEnumerator* pEnum, int context );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helps us find all leaves associated with a particular cluster
|
||||
//-----------------------------------------------------------------------------
|
||||
struct clusterlist_t
|
||||
{
|
||||
int leafCount;
|
||||
CUtlVector<int> leafs;
|
||||
};
|
||||
|
||||
extern CUtlVector<clusterlist_t> g_ClusterLeaves;
|
||||
|
||||
// Call this to build the mapping from cluster to leaves
|
||||
void BuildClusterTable( );
|
||||
|
||||
void GetPlatformMapPath( const char *pMapPath, char *pPlatformMapPath, int dxlevel, int maxLength );
|
||||
|
||||
void SetHDRMode( bool bHDR );
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// Helper accessors for the various structures.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
inline ColorRGBExp32* dface_AvgLightColor( dface_t *pFace, int nLightStyleIndex )
|
||||
{
|
||||
return (ColorRGBExp32*)&(*pdlightdata)[pFace->lightofs - (nLightStyleIndex+1) * 4];
|
||||
}
|
||||
|
||||
inline const char* TexInfo_TexName( int iTexInfo )
|
||||
{
|
||||
return TexDataStringTable_GetString( dtexdata[texinfo[iTexInfo].texdata].nameStringTableID );
|
||||
}
|
||||
|
||||
|
||||
#endif // BSPLIB_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BSPLIB_H
|
||||
#define BSPLIB_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "bspfile.h"
|
||||
#include "utlvector.h"
|
||||
#include "utlstring.h"
|
||||
#include "utllinkedlist.h"
|
||||
#include "byteswap.h"
|
||||
#ifdef ENGINE_DLL
|
||||
#include "zone.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENGINE_DLL
|
||||
typedef CUtlVector<unsigned char, CHunkMemory<unsigned char> > CDispLightmapSamplePositions;
|
||||
#else
|
||||
typedef CUtlVector<unsigned char> CDispLightmapSamplePositions;
|
||||
#endif
|
||||
|
||||
class ISpatialQuery;
|
||||
struct Ray_t;
|
||||
class Vector2D;
|
||||
struct portal_t;
|
||||
class CUtlBuffer;
|
||||
class IZip;
|
||||
|
||||
// this is only true in vrad
|
||||
extern bool g_bHDR;
|
||||
|
||||
// default width/height of luxels in world units.
|
||||
#define DEFAULT_LUXEL_SIZE ( 16.0f )
|
||||
|
||||
#define SINGLE_BRUSH_MAP (MAX_BRUSH_LIGHTMAP_DIM_INCLUDING_BORDER*MAX_BRUSH_LIGHTMAP_DIM_INCLUDING_BORDER)
|
||||
#define SINGLEMAP (MAX_LIGHTMAP_DIM_INCLUDING_BORDER*MAX_LIGHTMAP_DIM_INCLUDING_BORDER)
|
||||
|
||||
struct entity_t
|
||||
{
|
||||
Vector origin;
|
||||
int firstbrush;
|
||||
int numbrushes;
|
||||
epair_t *epairs;
|
||||
|
||||
// only valid for func_areaportals
|
||||
int areaportalnum;
|
||||
int portalareas[2];
|
||||
portal_t *m_pPortalsLeadingIntoAreas[2]; // portals leading into portalareas
|
||||
};
|
||||
|
||||
extern int num_entities;
|
||||
extern entity_t entities[MAX_MAP_ENTITIES];
|
||||
|
||||
extern int nummodels;
|
||||
extern dmodel_t dmodels[MAX_MAP_MODELS];
|
||||
|
||||
extern int visdatasize;
|
||||
extern byte dvisdata[MAX_MAP_VISIBILITY];
|
||||
extern dvis_t *dvis;
|
||||
|
||||
extern CUtlVector<byte> dlightdataHDR;
|
||||
extern CUtlVector<byte> dlightdataLDR;
|
||||
extern CUtlVector<byte> *pdlightdata;
|
||||
extern CUtlVector<char> dentdata;
|
||||
|
||||
extern int numleafs;
|
||||
#if !defined( _X360 )
|
||||
extern dleaf_t dleafs[MAX_MAP_LEAFS];
|
||||
#else
|
||||
extern dleaf_t *dleafs;
|
||||
#endif
|
||||
extern CUtlVector<dleafambientlighting_t> *g_pLeafAmbientLighting;
|
||||
extern CUtlVector<dleafambientindex_t> *g_pLeafAmbientIndex;
|
||||
extern unsigned short g_LeafMinDistToWater[MAX_MAP_LEAFS];
|
||||
|
||||
extern int numplanes;
|
||||
extern dplane_t dplanes[MAX_MAP_PLANES];
|
||||
|
||||
extern int numvertexes;
|
||||
extern dvertex_t dvertexes[MAX_MAP_VERTS];
|
||||
|
||||
extern int g_numvertnormalindices; // dfaces reference these. These index g_vertnormals.
|
||||
extern unsigned short g_vertnormalindices[MAX_MAP_VERTNORMALS];
|
||||
|
||||
extern int g_numvertnormals;
|
||||
extern Vector g_vertnormals[MAX_MAP_VERTNORMALS];
|
||||
|
||||
extern int numnodes;
|
||||
extern dnode_t dnodes[MAX_MAP_NODES];
|
||||
|
||||
extern CUtlVector<texinfo_t> texinfo;
|
||||
|
||||
extern int numtexdata;
|
||||
extern dtexdata_t dtexdata[MAX_MAP_TEXDATA];
|
||||
|
||||
// displacement map .bsp file info
|
||||
extern CUtlVector<ddispinfo_t> g_dispinfo;
|
||||
extern CUtlVector<CDispVert> g_DispVerts;
|
||||
extern CUtlVector<CDispTri> g_DispTris;
|
||||
extern CDispLightmapSamplePositions g_DispLightmapSamplePositions; // LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS
|
||||
|
||||
extern int numorigfaces;
|
||||
extern dface_t dorigfaces[MAX_MAP_FACES];
|
||||
|
||||
extern int g_numprimitives;
|
||||
extern dprimitive_t g_primitives[MAX_MAP_PRIMITIVES];
|
||||
|
||||
extern int g_numprimverts;
|
||||
extern dprimvert_t g_primverts[MAX_MAP_PRIMVERTS];
|
||||
|
||||
extern int g_numprimindices;
|
||||
extern unsigned short g_primindices[MAX_MAP_PRIMINDICES];
|
||||
|
||||
extern int numfaces;
|
||||
extern dface_t dfaces[MAX_MAP_FACES];
|
||||
|
||||
extern int numfaceids;
|
||||
extern CUtlVector<dfaceid_t> dfaceids;
|
||||
|
||||
extern int numfaces_hdr;
|
||||
extern dface_t dfaces_hdr[MAX_MAP_FACES];
|
||||
|
||||
extern int numedges;
|
||||
extern dedge_t dedges[MAX_MAP_EDGES];
|
||||
|
||||
extern int numleaffaces;
|
||||
extern unsigned short dleaffaces[MAX_MAP_LEAFFACES];
|
||||
|
||||
extern int numleafbrushes;
|
||||
extern unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES];
|
||||
|
||||
extern int numsurfedges;
|
||||
extern int dsurfedges[MAX_MAP_SURFEDGES];
|
||||
|
||||
extern int numareas;
|
||||
extern darea_t dareas[MAX_MAP_AREAS];
|
||||
|
||||
extern int numareaportals;
|
||||
extern dareaportal_t dareaportals[MAX_MAP_AREAPORTALS];
|
||||
|
||||
extern int numbrushes;
|
||||
extern dbrush_t dbrushes[MAX_MAP_BRUSHES];
|
||||
|
||||
extern int numbrushsides;
|
||||
extern dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES];
|
||||
|
||||
extern int *pNumworldlights;
|
||||
extern dworldlight_t *dworldlights;
|
||||
|
||||
extern Vector g_ClipPortalVerts[MAX_MAP_PORTALVERTS];
|
||||
extern int g_nClipPortalVerts;
|
||||
|
||||
extern dcubemapsample_t g_CubemapSamples[MAX_MAP_CUBEMAPSAMPLES];
|
||||
extern int g_nCubemapSamples;
|
||||
|
||||
extern int g_nOverlayCount;
|
||||
extern doverlay_t g_Overlays[MAX_MAP_OVERLAYS];
|
||||
extern doverlayfade_t g_OverlayFades[MAX_MAP_OVERLAYS]; // Parallel array of fade info in a separate lump to avoid breaking backwards compat
|
||||
|
||||
extern int g_nWaterOverlayCount;
|
||||
extern dwateroverlay_t g_WaterOverlays[MAX_MAP_WATEROVERLAYS];
|
||||
|
||||
extern CUtlVector<char> g_TexDataStringData;
|
||||
extern CUtlVector<int> g_TexDataStringTable;
|
||||
|
||||
extern int numleafwaterdata;
|
||||
extern dleafwaterdata_t dleafwaterdata[MAX_MAP_LEAFWATERDATA];
|
||||
|
||||
extern CUtlVector<CFaceMacroTextureInfo> g_FaceMacroTextureInfos;
|
||||
|
||||
extern CUtlVector<doccluderdata_t> g_OccluderData;
|
||||
extern CUtlVector<doccluderpolydata_t> g_OccluderPolyData;
|
||||
extern CUtlVector<int> g_OccluderVertexIndices;
|
||||
|
||||
// level flags - see LVLFLAGS_xxx in bspfile.h
|
||||
extern uint32 g_LevelFlags;
|
||||
|
||||
// physics collision data
|
||||
extern byte *g_pPhysCollide;
|
||||
extern int g_PhysCollideSize;
|
||||
extern byte *g_pPhysDisp;
|
||||
extern int g_PhysDispSize;
|
||||
|
||||
// Embedded pack/pak file
|
||||
IZip *GetPakFile( void );
|
||||
IZip *GetSwapPakFile( void );
|
||||
void ClearPakFile( IZip *pak );
|
||||
void AddFileToPak( IZip *pak, const char *pRelativeName, const char *fullpath );
|
||||
void AddBufferToPak( IZip *pak, const char *pRelativeName, void *data, int length, bool bTextMode );
|
||||
bool FileExistsInPak( IZip *pak, const char *pRelativeName );
|
||||
bool ReadFileFromPak( IZip *pak, const char *pRelativeName, bool bTextMode, CUtlBuffer &buf );
|
||||
void RemoveFileFromPak( IZip *pak, const char *pRelativeName );
|
||||
int GetNextFilename( IZip *pak, int id, char *pBuffer, int bufferSize, int &fileSize );
|
||||
void ForceAlignment( IZip *pak, bool bAlign, bool bCompatibleFormat, unsigned int alignmentSize );
|
||||
|
||||
typedef bool (*CompressFunc_t)( CUtlBuffer &inputBuffer, CUtlBuffer &outputBuffer );
|
||||
typedef bool (*VTFConvertFunc_t)( const char *pDebugName, CUtlBuffer &sourceBuf, CUtlBuffer &targetBuf, CompressFunc_t pCompressFunc );
|
||||
typedef bool (*VHVFixupFunc_t)( const char *pVhvFilename, const char *pModelName, CUtlBuffer &sourceBuf, CUtlBuffer &targetBuf );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Game lump memory storage
|
||||
//-----------------------------------------------------------------------------
|
||||
// NOTE: This is not optimal at all; since I expect client lumps to
|
||||
// not be accessed all that often.
|
||||
|
||||
struct GameLump_t
|
||||
{
|
||||
GameLumpId_t m_Id;
|
||||
unsigned short m_Flags;
|
||||
unsigned short m_Version;
|
||||
CUtlMemory< unsigned char > m_Memory;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle to a game lump
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef unsigned short GameLumpHandle_t;
|
||||
|
||||
class CGameLump
|
||||
{
|
||||
public:
|
||||
//-----------------------------------------------------------------------------
|
||||
// Convert four-CC code to a handle + back
|
||||
//-----------------------------------------------------------------------------
|
||||
GameLumpHandle_t GetGameLumpHandle( GameLumpId_t id );
|
||||
GameLumpId_t GetGameLumpId( GameLumpHandle_t handle );
|
||||
int GetGameLumpFlags( GameLumpHandle_t handle );
|
||||
int GetGameLumpVersion( GameLumpHandle_t handle );
|
||||
void ComputeGameLumpSizeAndCount( int& size, int& clumpCount );
|
||||
void ParseGameLump( dheader_t* pHeader );
|
||||
void SwapGameLump( GameLumpId_t id, int version, byte *dest, byte *src, int size );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Game lump accessor methods
|
||||
//-----------------------------------------------------------------------------
|
||||
void* GetGameLump( GameLumpHandle_t handle );
|
||||
int GameLumpSize( GameLumpHandle_t handle );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Game lump iteration methods
|
||||
//-----------------------------------------------------------------------------
|
||||
GameLumpHandle_t FirstGameLump();
|
||||
GameLumpHandle_t NextGameLump( GameLumpHandle_t handle );
|
||||
GameLumpHandle_t InvalidGameLump();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Game lump creation/destruction method
|
||||
//-----------------------------------------------------------------------------
|
||||
GameLumpHandle_t CreateGameLump( GameLumpId_t id, int size, int flags, int version );
|
||||
void DestroyGameLump( GameLumpHandle_t handle );
|
||||
void DestroyAllGameLumps();
|
||||
|
||||
private:
|
||||
CUtlLinkedList< GameLump_t, GameLumpHandle_t > m_GameLumps;
|
||||
};
|
||||
|
||||
extern CGameLump g_GameLumps;
|
||||
extern CByteswap g_Swap;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper for the bspzip tool
|
||||
//-----------------------------------------------------------------------------
|
||||
void ExtractZipFileFromBSP( char *pBSPFileName, char *pZipFileName );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// String table methods
|
||||
//-----------------------------------------------------------------------------
|
||||
const char * TexDataStringTable_GetString( int stringID );
|
||||
int TexDataStringTable_AddOrFindString( const char *pString );
|
||||
|
||||
void DecompressVis (byte *in, byte *decompressed);
|
||||
int CompressVis (byte *vis, byte *dest);
|
||||
|
||||
void OpenBSPFile( const char *filename );
|
||||
void CloseBSPFile(void);
|
||||
void LoadBSPFile( const char *filename );
|
||||
void LoadBSPFile_FileSystemOnly( const char *filename );
|
||||
void LoadBSPFileTexinfo( const char *filename );
|
||||
void WriteBSPFile( const char *filename, char *pUnused = NULL );
|
||||
void PrintBSPFileSizes(void);
|
||||
void PrintBSPPackDirectory(void);
|
||||
void ReleasePakFileLumps(void);
|
||||
bool SwapBSPFile( const char *filename, const char *swapFilename, bool bSwapOnLoad, VTFConvertFunc_t pVTFConvertFunc, VHVFixupFunc_t pVHVFixupFunc, CompressFunc_t pCompressFunc );
|
||||
bool GetPakFileLump( const char *pBSPFilename, void **pPakData, int *pPakSize );
|
||||
bool SetPakFileLump( const char *pBSPFilename, const char *pNewFilename, void *pPakData, int pakSize );
|
||||
void WriteLumpToFile( char *filename, int lump );
|
||||
void WriteLumpToFile( char *filename, int lump, int nLumpVersion, void *pBuffer, size_t nBufLen );
|
||||
bool GetBSPDependants( const char *pBSPFilename, CUtlVector< CUtlString > *pList );
|
||||
void UnloadBSPFile();
|
||||
|
||||
void ParseEntities (void);
|
||||
void UnparseEntities (void);
|
||||
void PrintEntity (entity_t *ent);
|
||||
|
||||
void SetKeyValue (entity_t *ent, const char *key, const char *value);
|
||||
char *ValueForKey (entity_t *ent, char *key);
|
||||
// will return "" if not present
|
||||
int IntForKey (entity_t *ent, char *key);
|
||||
int IntForKeyWithDefault(entity_t *ent, char *key, int nDefault );
|
||||
vec_t FloatForKey (entity_t *ent, char *key);
|
||||
vec_t FloatForKeyWithDefault (entity_t *ent, char *key, float default_value);
|
||||
void GetVectorForKey (entity_t *ent, char *key, Vector& vec);
|
||||
void GetVector2DForKey (entity_t *ent, char *key, Vector2D& vec);
|
||||
void GetAnglesForKey (entity_t *ent, char *key, QAngle& vec);
|
||||
epair_t *ParseEpair (void);
|
||||
void StripTrailing (char *e);
|
||||
|
||||
// Build a list of the face's vertices (index into dvertexes).
|
||||
// points must be able to hold pFace->numedges indices.
|
||||
void BuildFaceCalcWindingData( dface_t *pFace, int *points );
|
||||
|
||||
// Convert a tristrip to a trilist.
|
||||
// Removes degenerates.
|
||||
// Fills in pTriListIndices and pnTriListIndices.
|
||||
// You must free pTriListIndices with delete[].
|
||||
void TriStripToTriList(
|
||||
unsigned short const *pTriStripIndices,
|
||||
int nTriStripIndices,
|
||||
unsigned short **pTriListIndices,
|
||||
int *pnTriListIndices );
|
||||
|
||||
// Calculates the lightmap coordinates at a given set of positions given the
|
||||
// lightmap basis information.
|
||||
void CalcTextureCoordsAtPoints(
|
||||
float const texelsPerWorldUnits[2][4],
|
||||
int const subtractOffset[2],
|
||||
Vector const *pPoints,
|
||||
int const nPoints,
|
||||
Vector2D *pCoords );
|
||||
|
||||
// Figure out lightmap extents on all (lit) faces.
|
||||
void UpdateAllFaceLightmapExtents();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets at an interface for the tree for enumeration of leaves in volumes.
|
||||
//-----------------------------------------------------------------------------
|
||||
ISpatialQuery* ToolBSPTree();
|
||||
|
||||
class IBSPNodeEnumerator
|
||||
{
|
||||
public:
|
||||
// call back with a node and a context
|
||||
virtual bool EnumerateNode( int node, Ray_t const& ray, float f, int context ) = 0;
|
||||
|
||||
// call back with a leaf and a context
|
||||
virtual bool EnumerateLeaf( int leaf, Ray_t const& ray, float start, float end, int context ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Enumerates nodes + leafs in front to back order...
|
||||
//-----------------------------------------------------------------------------
|
||||
bool EnumerateNodesAlongRay( Ray_t const& ray, IBSPNodeEnumerator* pEnum, int context );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helps us find all leaves associated with a particular cluster
|
||||
//-----------------------------------------------------------------------------
|
||||
struct clusterlist_t
|
||||
{
|
||||
int leafCount;
|
||||
CUtlVector<int> leafs;
|
||||
};
|
||||
|
||||
extern CUtlVector<clusterlist_t> g_ClusterLeaves;
|
||||
|
||||
// Call this to build the mapping from cluster to leaves
|
||||
void BuildClusterTable( );
|
||||
|
||||
void GetPlatformMapPath( const char *pMapPath, char *pPlatformMapPath, int dxlevel, int maxLength );
|
||||
|
||||
void SetHDRMode( bool bHDR );
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// Helper accessors for the various structures.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
inline ColorRGBExp32* dface_AvgLightColor( dface_t *pFace, int nLightStyleIndex )
|
||||
{
|
||||
return (ColorRGBExp32*)&(*pdlightdata)[pFace->lightofs - (nLightStyleIndex+1) * 4];
|
||||
}
|
||||
|
||||
inline const char* TexInfo_TexName( int iTexInfo )
|
||||
{
|
||||
return TexDataStringTable_GetString( dtexdata[texinfo[iTexInfo].texdata].nameStringTableID );
|
||||
}
|
||||
|
||||
|
||||
#endif // BSPLIB_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,178 +1,178 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CMDLIB_H
|
||||
#define CMDLIB_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// cmdlib.h
|
||||
|
||||
#include "basetypes.h"
|
||||
|
||||
// This can go away when everything is in bin.
|
||||
#if defined( CMDLIB_NODBGLIB )
|
||||
void Error( PRINTF_FORMAT_STRING char const *pMsg, ... );
|
||||
#else
|
||||
#include "tier0/dbg.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
#include "filesystem.h"
|
||||
#include "filesystem_tools.h"
|
||||
#include "tier1/utlstring.h"
|
||||
|
||||
|
||||
// Tools should use this as the read path ID. It'll look into the paths specified by gameinfo.txt
|
||||
#define TOOLS_READ_PATH_ID "GAME"
|
||||
|
||||
|
||||
// Tools should use this to fprintf data to files.
|
||||
void CmdLib_FPrintf( FileHandle_t hFile, PRINTF_FORMAT_STRING const char *pFormat, ... );
|
||||
char* CmdLib_FGets( char *pOut, int outSize, FileHandle_t hFile );
|
||||
|
||||
|
||||
// This can be set so Msg() sends output to hook functions (like the VMPI MySQL database),
|
||||
// but doesn't actually printf the output.
|
||||
extern bool g_bSuppressPrintfOutput;
|
||||
|
||||
extern IBaseFileSystem *g_pFileSystem;
|
||||
|
||||
// These call right into the functions in filesystem_tools.h
|
||||
void CmdLib_InitFileSystem( const char *pFilename, int maxMemoryUsage = 0 );
|
||||
void CmdLib_TermFileSystem(); // GracefulExit calls this.
|
||||
CreateInterfaceFn CmdLib_GetFileSystemFactory();
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
#pragma warning(disable : 4136) // X86
|
||||
#pragma warning(disable : 4051) // ALPHA
|
||||
|
||||
#pragma warning(disable : 4018) // signed/unsigned mismatch
|
||||
#pragma warning(disable : 4305) // truncate from double to float
|
||||
|
||||
#pragma warning(disable : 4389) // singned/unsigned mismatch in ==
|
||||
#pragma warning(disable: 4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
|
||||
// the dec offsetof macro doesnt work very well...
|
||||
#define myoffsetof(type,identifier) offsetof( type, identifier )
|
||||
|
||||
|
||||
// set these before calling CheckParm
|
||||
extern int myargc;
|
||||
extern char **myargv;
|
||||
|
||||
int Q_filelength (FileHandle_t f);
|
||||
int FileTime (char *path);
|
||||
|
||||
void Q_mkdir( char *path );
|
||||
|
||||
char *ExpandArg (char *path); // expand relative to CWD
|
||||
char *ExpandPath (char *path); // expand relative to gamedir
|
||||
|
||||
char *ExpandPathAndArchive (char *path);
|
||||
|
||||
// Fills in pOut with "X hours, Y minutes, Z seconds". Leaves out hours or minutes if they're zero.
|
||||
void GetHourMinuteSecondsString( int nInputSeconds, char *pOut, int outLen );
|
||||
|
||||
|
||||
|
||||
int CheckParm (char *check);
|
||||
|
||||
FileHandle_t SafeOpenWrite ( const char *filename );
|
||||
FileHandle_t SafeOpenRead ( const char *filename );
|
||||
void SafeRead( FileHandle_t f, void *buffer, int count);
|
||||
void SafeWrite( FileHandle_t f, void *buffer, int count);
|
||||
|
||||
int LoadFile ( const char *filename, void **bufferptr );
|
||||
void SaveFile ( const char *filename, void *buffer, int count );
|
||||
qboolean FileExists ( const char *filename );
|
||||
|
||||
int ParseNum (char *str);
|
||||
|
||||
// Do a printf in the specified color.
|
||||
#define CP_ERROR stderr, 1, 0, 0, 1 // default colors..
|
||||
#define CP_WARNING stderr, 1, 1, 0, 1
|
||||
#define CP_STARTUP stdout, 0, 1, 1, 1
|
||||
#define CP_NOTIFY stdout, 1, 1, 1, 1
|
||||
void ColorPrintf( FILE *pFile, bool red, bool green, bool blue, bool intensity, PRINTF_FORMAT_STRING char const *pFormat, ... );
|
||||
|
||||
// Initialize spew output.
|
||||
void InstallSpewFunction();
|
||||
|
||||
// This registers an extra callback for spew output.
|
||||
typedef void (*SpewHookFn)( const char * );
|
||||
void InstallExtraSpewHook( SpewHookFn pFn );
|
||||
|
||||
// Install allocation hooks so we error out if an allocation can't happen.
|
||||
void InstallAllocationFunctions();
|
||||
|
||||
// This shuts down mgrs that use threads gracefully. If you just call exit(), the threads can
|
||||
// get in a state where you can't tell if they are shutdown or not, and it can stall forever.
|
||||
typedef void (*CleanupFn)();
|
||||
void CmdLib_AtCleanup( CleanupFn pFn ); // register a callback when Cleanup() is called.
|
||||
void CmdLib_Cleanup();
|
||||
void CmdLib_Exit( int exitCode ); // Use this to cleanup and call exit().
|
||||
|
||||
// entrypoint if chaining spew functions
|
||||
SpewRetval_t CmdLib_SpewOutputFunc( SpewType_t type, char const *pMsg );
|
||||
unsigned short SetConsoleTextColor( int red, int green, int blue, int intensity );
|
||||
void RestoreConsoleTextColor( unsigned short color );
|
||||
|
||||
// Append all spew output to the specified file.
|
||||
void SetSpewFunctionLogFile( char const *pFilename );
|
||||
|
||||
char *COM_Parse (char *data);
|
||||
|
||||
extern char com_token[1024];
|
||||
|
||||
char *copystring(const char *s);
|
||||
|
||||
void CreatePath( char *path );
|
||||
void QCopyFile( char *from, char *to );
|
||||
void SafeCreatePath( char *path );
|
||||
|
||||
extern qboolean archive;
|
||||
extern char archivedir[1024];
|
||||
|
||||
extern qboolean verbose;
|
||||
|
||||
void qprintf( PRINTF_FORMAT_STRING const char *format, ... );
|
||||
|
||||
void ExpandWildcards (int *argc, char ***argv);
|
||||
|
||||
void CmdLib_AddBasePath( const char *pBasePath );
|
||||
bool CmdLib_HasBasePath( const char *pFileName, int &pathLength );
|
||||
int CmdLib_GetNumBasePaths( void );
|
||||
const char *CmdLib_GetBasePath( int i );
|
||||
// Like ExpandPath but expands the path for each base path like SafeOpenRead
|
||||
int CmdLib_ExpandWithBasePaths( CUtlVector< CUtlString > &expandedPathList, const char *pszPath );
|
||||
|
||||
extern bool g_bStopOnExit;
|
||||
|
||||
// for compression routines
|
||||
typedef struct
|
||||
{
|
||||
byte *data;
|
||||
int count;
|
||||
} cblock_t;
|
||||
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CMDLIB_H
|
||||
#define CMDLIB_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// cmdlib.h
|
||||
|
||||
#include "basetypes.h"
|
||||
|
||||
// This can go away when everything is in bin.
|
||||
#if defined( CMDLIB_NODBGLIB )
|
||||
void Error( PRINTF_FORMAT_STRING char const *pMsg, ... );
|
||||
#else
|
||||
#include "tier0/dbg.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
#include "filesystem.h"
|
||||
#include "filesystem_tools.h"
|
||||
#include "tier1/utlstring.h"
|
||||
|
||||
|
||||
// Tools should use this as the read path ID. It'll look into the paths specified by gameinfo.txt
|
||||
#define TOOLS_READ_PATH_ID "GAME"
|
||||
|
||||
|
||||
// Tools should use this to fprintf data to files.
|
||||
void CmdLib_FPrintf( FileHandle_t hFile, PRINTF_FORMAT_STRING const char *pFormat, ... );
|
||||
char* CmdLib_FGets( char *pOut, int outSize, FileHandle_t hFile );
|
||||
|
||||
|
||||
// This can be set so Msg() sends output to hook functions (like the VMPI MySQL database),
|
||||
// but doesn't actually printf the output.
|
||||
extern bool g_bSuppressPrintfOutput;
|
||||
|
||||
extern IBaseFileSystem *g_pFileSystem;
|
||||
|
||||
// These call right into the functions in filesystem_tools.h
|
||||
void CmdLib_InitFileSystem( const char *pFilename, int maxMemoryUsage = 0 );
|
||||
void CmdLib_TermFileSystem(); // GracefulExit calls this.
|
||||
CreateInterfaceFn CmdLib_GetFileSystemFactory();
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
#pragma warning(disable : 4136) // X86
|
||||
#pragma warning(disable : 4051) // ALPHA
|
||||
|
||||
#pragma warning(disable : 4018) // signed/unsigned mismatch
|
||||
#pragma warning(disable : 4305) // truncate from double to float
|
||||
|
||||
#pragma warning(disable : 4389) // singned/unsigned mismatch in ==
|
||||
#pragma warning(disable: 4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
|
||||
// the dec offsetof macro doesnt work very well...
|
||||
#define myoffsetof(type,identifier) offsetof( type, identifier )
|
||||
|
||||
|
||||
// set these before calling CheckParm
|
||||
extern int myargc;
|
||||
extern char **myargv;
|
||||
|
||||
int Q_filelength (FileHandle_t f);
|
||||
int FileTime (char *path);
|
||||
|
||||
void Q_mkdir( char *path );
|
||||
|
||||
char *ExpandArg (char *path); // expand relative to CWD
|
||||
char *ExpandPath (char *path); // expand relative to gamedir
|
||||
|
||||
char *ExpandPathAndArchive (char *path);
|
||||
|
||||
// Fills in pOut with "X hours, Y minutes, Z seconds". Leaves out hours or minutes if they're zero.
|
||||
void GetHourMinuteSecondsString( int nInputSeconds, char *pOut, int outLen );
|
||||
|
||||
|
||||
|
||||
int CheckParm (char *check);
|
||||
|
||||
FileHandle_t SafeOpenWrite ( const char *filename );
|
||||
FileHandle_t SafeOpenRead ( const char *filename );
|
||||
void SafeRead( FileHandle_t f, void *buffer, int count);
|
||||
void SafeWrite( FileHandle_t f, void *buffer, int count);
|
||||
|
||||
int LoadFile ( const char *filename, void **bufferptr );
|
||||
void SaveFile ( const char *filename, void *buffer, int count );
|
||||
qboolean FileExists ( const char *filename );
|
||||
|
||||
int ParseNum (char *str);
|
||||
|
||||
// Do a printf in the specified color.
|
||||
#define CP_ERROR stderr, 1, 0, 0, 1 // default colors..
|
||||
#define CP_WARNING stderr, 1, 1, 0, 1
|
||||
#define CP_STARTUP stdout, 0, 1, 1, 1
|
||||
#define CP_NOTIFY stdout, 1, 1, 1, 1
|
||||
void ColorPrintf( FILE *pFile, bool red, bool green, bool blue, bool intensity, PRINTF_FORMAT_STRING char const *pFormat, ... );
|
||||
|
||||
// Initialize spew output.
|
||||
void InstallSpewFunction();
|
||||
|
||||
// This registers an extra callback for spew output.
|
||||
typedef void (*SpewHookFn)( const char * );
|
||||
void InstallExtraSpewHook( SpewHookFn pFn );
|
||||
|
||||
// Install allocation hooks so we error out if an allocation can't happen.
|
||||
void InstallAllocationFunctions();
|
||||
|
||||
// This shuts down mgrs that use threads gracefully. If you just call exit(), the threads can
|
||||
// get in a state where you can't tell if they are shutdown or not, and it can stall forever.
|
||||
typedef void (*CleanupFn)();
|
||||
void CmdLib_AtCleanup( CleanupFn pFn ); // register a callback when Cleanup() is called.
|
||||
void CmdLib_Cleanup();
|
||||
void CmdLib_Exit( int exitCode ); // Use this to cleanup and call exit().
|
||||
|
||||
// entrypoint if chaining spew functions
|
||||
SpewRetval_t CmdLib_SpewOutputFunc( SpewType_t type, char const *pMsg );
|
||||
unsigned short SetConsoleTextColor( int red, int green, int blue, int intensity );
|
||||
void RestoreConsoleTextColor( unsigned short color );
|
||||
|
||||
// Append all spew output to the specified file.
|
||||
void SetSpewFunctionLogFile( char const *pFilename );
|
||||
|
||||
char *COM_Parse (char *data);
|
||||
|
||||
extern char com_token[1024];
|
||||
|
||||
char *copystring(const char *s);
|
||||
|
||||
void CreatePath( char *path );
|
||||
void QCopyFile( char *from, char *to );
|
||||
void SafeCreatePath( char *path );
|
||||
|
||||
extern qboolean archive;
|
||||
extern char archivedir[1024];
|
||||
|
||||
extern qboolean verbose;
|
||||
|
||||
void qprintf( PRINTF_FORMAT_STRING const char *format, ... );
|
||||
|
||||
void ExpandWildcards (int *argc, char ***argv);
|
||||
|
||||
void CmdLib_AddBasePath( const char *pBasePath );
|
||||
bool CmdLib_HasBasePath( const char *pFileName, int &pathLength );
|
||||
int CmdLib_GetNumBasePaths( void );
|
||||
const char *CmdLib_GetBasePath( int i );
|
||||
// Like ExpandPath but expands the path for each base path like SafeOpenRead
|
||||
int CmdLib_ExpandWithBasePaths( CUtlVector< CUtlString > &expandedPathList, const char *pszPath );
|
||||
|
||||
extern bool g_bStopOnExit;
|
||||
|
||||
// for compression routines
|
||||
typedef struct
|
||||
{
|
||||
byte *data;
|
||||
int count;
|
||||
} cblock_t;
|
||||
|
||||
|
||||
#endif // CMDLIB_H
|
||||
@@ -1,333 +1,333 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <windows.h>
|
||||
#include "consolewnd.h"
|
||||
|
||||
|
||||
#pragma warning( disable : 4311 ) // warning C4311: 'reinterpret_cast' : pointer truncation from 'CConsoleWnd *const ' to 'LONG'
|
||||
#pragma warning( disable : 4312 ) // warning C4312: 'type cast' : conversion from 'LONG' to 'CConsoleWnd *' of greater size
|
||||
|
||||
#define EDITCONTROL_BORDER_SIZE 5
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
// Functions to manage the console window.
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
|
||||
class CConsoleWnd : public IConsoleWnd
|
||||
{
|
||||
public:
|
||||
CConsoleWnd();
|
||||
~CConsoleWnd();
|
||||
|
||||
bool Init( void *hInstance, int dialogResourceID, int editControlID, bool bVisible );
|
||||
void Term();
|
||||
|
||||
virtual void Release();
|
||||
|
||||
virtual void SetVisible( bool bVisible );
|
||||
virtual bool IsVisible() const;
|
||||
|
||||
virtual void PrintToConsole( const char *pMsg );
|
||||
virtual void SetTitle( const char *pTitle );
|
||||
|
||||
virtual void SetDeleteOnClose( bool bDelete );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
int WindowProc(
|
||||
HWND hwndDlg, // handle to dialog box
|
||||
UINT uMsg, // message
|
||||
WPARAM wParam, // first message parameter
|
||||
LPARAM lParam // second message parameter
|
||||
);
|
||||
|
||||
static int CALLBACK StaticWindowProc(
|
||||
HWND hwndDlg, // handle to dialog box
|
||||
UINT uMsg, // message
|
||||
WPARAM wParam, // first message parameter
|
||||
LPARAM lParam // second message parameter
|
||||
);
|
||||
|
||||
void RepositionEditControl();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
HWND m_hWnd;
|
||||
HWND m_hEditControl;
|
||||
bool m_bVisible;
|
||||
bool m_bDeleteOnClose;
|
||||
int m_nCurrentChars;
|
||||
};
|
||||
|
||||
|
||||
CConsoleWnd::CConsoleWnd()
|
||||
{
|
||||
m_hWnd = m_hEditControl = NULL;
|
||||
m_bVisible = false;
|
||||
m_bDeleteOnClose = false;
|
||||
m_nCurrentChars = 0;
|
||||
}
|
||||
|
||||
|
||||
CConsoleWnd::~CConsoleWnd()
|
||||
{
|
||||
Term();
|
||||
}
|
||||
|
||||
bool CConsoleWnd::Init( void *hInstance, int dialogResourceID, int editControlID, bool bVisible )
|
||||
{
|
||||
// Create the window.
|
||||
m_hWnd = CreateDialog(
|
||||
(HINSTANCE)hInstance,
|
||||
MAKEINTRESOURCE( dialogResourceID ),
|
||||
NULL,
|
||||
&CConsoleWnd::StaticWindowProc );
|
||||
|
||||
if ( !m_hWnd )
|
||||
return false;
|
||||
|
||||
SetWindowLong( m_hWnd, GWL_USERDATA, reinterpret_cast< LONG >( this ) );
|
||||
if ( bVisible )
|
||||
ShowWindow( m_hWnd, SW_SHOW );
|
||||
|
||||
// Get a handle to the edit control.
|
||||
m_hEditControl = GetDlgItem( m_hWnd, editControlID );
|
||||
if ( !m_hEditControl )
|
||||
return false;
|
||||
|
||||
RepositionEditControl();
|
||||
|
||||
m_bVisible = bVisible;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::Term()
|
||||
{
|
||||
if ( m_hWnd )
|
||||
{
|
||||
DestroyWindow( m_hWnd );
|
||||
m_hWnd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::Release()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::SetVisible( bool bVisible )
|
||||
{
|
||||
ShowWindow( m_hWnd, bVisible ? SW_RESTORE : SW_HIDE );
|
||||
|
||||
if ( bVisible )
|
||||
{
|
||||
ShowWindow( m_hWnd, SW_SHOW );
|
||||
SetWindowPos( m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
|
||||
UpdateWindow( m_hWnd );
|
||||
|
||||
int nLen = (int)SendMessage( m_hEditControl, EM_GETLIMITTEXT, 0, 0 );
|
||||
SendMessage( m_hEditControl, EM_SETSEL, nLen, nLen );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWindowPos( m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW | SWP_NOOWNERZORDER );
|
||||
}
|
||||
|
||||
m_bVisible = bVisible;
|
||||
}
|
||||
|
||||
|
||||
bool CConsoleWnd::IsVisible() const
|
||||
{
|
||||
return m_bVisible;
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::PrintToConsole( const char *pMsg )
|
||||
{
|
||||
if ( m_nCurrentChars >= 16*1024 )
|
||||
{
|
||||
// Clear the edit control otherwise it'll stop outputting anything.
|
||||
m_nCurrentChars = 0;
|
||||
|
||||
int nLen = (int)SendMessage( m_hEditControl, EM_GETLIMITTEXT, 0, 0 );
|
||||
SendMessage( m_hEditControl, EM_SETSEL, 0, nLen );
|
||||
SendMessage( m_hEditControl, EM_REPLACESEL, FALSE, (LPARAM)"" );
|
||||
}
|
||||
|
||||
FormatAndSendToEditControl( m_hEditControl, pMsg );
|
||||
m_nCurrentChars += (int)strlen( pMsg );
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::SetTitle( const char *pTitle )
|
||||
{
|
||||
SetWindowText( m_hWnd, pTitle );
|
||||
}
|
||||
|
||||
|
||||
int CConsoleWnd::WindowProc(
|
||||
HWND hwndDlg, // handle to dialog box
|
||||
UINT uMsg, // message
|
||||
WPARAM wParam, // first message parameter
|
||||
LPARAM lParam // second message parameter
|
||||
)
|
||||
{
|
||||
lParam = lParam; // avoid compiler warning
|
||||
|
||||
if ( hwndDlg != m_hWnd )
|
||||
return false;
|
||||
|
||||
switch ( uMsg )
|
||||
{
|
||||
case WM_SYSCOMMAND:
|
||||
{
|
||||
if ( wParam == SC_CLOSE )
|
||||
{
|
||||
if ( m_bDeleteOnClose )
|
||||
{
|
||||
Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetVisible( false );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SHOWWINDOW:
|
||||
{
|
||||
m_bVisible = (wParam != 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
RepositionEditControl();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int CConsoleWnd::StaticWindowProc(
|
||||
HWND hwndDlg, // handle to dialog box
|
||||
UINT uMsg, // message
|
||||
WPARAM wParam, // first message parameter
|
||||
LPARAM lParam // second message parameter
|
||||
)
|
||||
{
|
||||
CConsoleWnd *pDlg = (CConsoleWnd*)GetWindowLong( hwndDlg, GWL_USERDATA );
|
||||
if ( pDlg )
|
||||
return pDlg->WindowProc( hwndDlg, uMsg, wParam, lParam );
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::RepositionEditControl()
|
||||
{
|
||||
RECT rcMain;
|
||||
GetClientRect( m_hWnd, &rcMain );
|
||||
|
||||
RECT rcNew;
|
||||
rcNew.left = rcMain.left + EDITCONTROL_BORDER_SIZE;
|
||||
rcNew.right = rcMain.right - EDITCONTROL_BORDER_SIZE;
|
||||
rcNew.top = rcMain.top + EDITCONTROL_BORDER_SIZE;
|
||||
rcNew.bottom = rcMain.bottom - EDITCONTROL_BORDER_SIZE;
|
||||
|
||||
SetWindowPos(
|
||||
m_hEditControl,
|
||||
NULL,
|
||||
rcNew.left,
|
||||
rcNew.top,
|
||||
rcNew.right - rcNew.left,
|
||||
rcNew.bottom - rcNew.top,
|
||||
SWP_NOZORDER );
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::SetDeleteOnClose( bool bDelete )
|
||||
{
|
||||
m_bDeleteOnClose = bDelete;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
// Module interface.
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
|
||||
void SendToEditControl( HWND hEditControl, const char *pText )
|
||||
{
|
||||
int nLen = (int)SendMessage( hEditControl, EM_GETLIMITTEXT, 0, 0 );
|
||||
SendMessage( hEditControl, EM_SETSEL, nLen, nLen );
|
||||
SendMessage( hEditControl, EM_REPLACESEL, FALSE, (LPARAM)pText );
|
||||
}
|
||||
|
||||
|
||||
void FormatAndSendToEditControl( void *hWnd, const char *pText )
|
||||
{
|
||||
HWND hEditControl = (HWND)hWnd;
|
||||
|
||||
// Translate \n to \r\n.
|
||||
char outMsg[1024];
|
||||
const char *pIn = pText;
|
||||
char *pOut = outMsg;
|
||||
while ( *pIn )
|
||||
{
|
||||
if ( *pIn == '\n' )
|
||||
{
|
||||
*pOut = '\r';
|
||||
pOut++;
|
||||
}
|
||||
*pOut = *pIn;
|
||||
|
||||
++pIn;
|
||||
++pOut;
|
||||
|
||||
if ( pOut - outMsg >= 1020 )
|
||||
{
|
||||
*pOut = 0;
|
||||
SendToEditControl( hEditControl, outMsg );
|
||||
pOut = outMsg;
|
||||
}
|
||||
}
|
||||
*pOut = 0;
|
||||
SendToEditControl( hEditControl, outMsg );
|
||||
}
|
||||
|
||||
|
||||
IConsoleWnd* CreateConsoleWnd( void *hInstance, int dialogResourceID, int editControlID, bool bVisible )
|
||||
{
|
||||
CConsoleWnd *pWnd = new CConsoleWnd;
|
||||
|
||||
if ( pWnd->Init( hInstance, dialogResourceID, editControlID, bVisible ) )
|
||||
{
|
||||
return pWnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
pWnd->Release();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <windows.h>
|
||||
#include "consolewnd.h"
|
||||
|
||||
|
||||
#pragma warning( disable : 4311 ) // warning C4311: 'reinterpret_cast' : pointer truncation from 'CConsoleWnd *const ' to 'LONG'
|
||||
#pragma warning( disable : 4312 ) // warning C4312: 'type cast' : conversion from 'LONG' to 'CConsoleWnd *' of greater size
|
||||
|
||||
#define EDITCONTROL_BORDER_SIZE 5
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
// Functions to manage the console window.
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
|
||||
class CConsoleWnd : public IConsoleWnd
|
||||
{
|
||||
public:
|
||||
CConsoleWnd();
|
||||
~CConsoleWnd();
|
||||
|
||||
bool Init( void *hInstance, int dialogResourceID, int editControlID, bool bVisible );
|
||||
void Term();
|
||||
|
||||
virtual void Release();
|
||||
|
||||
virtual void SetVisible( bool bVisible );
|
||||
virtual bool IsVisible() const;
|
||||
|
||||
virtual void PrintToConsole( const char *pMsg );
|
||||
virtual void SetTitle( const char *pTitle );
|
||||
|
||||
virtual void SetDeleteOnClose( bool bDelete );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
int WindowProc(
|
||||
HWND hwndDlg, // handle to dialog box
|
||||
UINT uMsg, // message
|
||||
WPARAM wParam, // first message parameter
|
||||
LPARAM lParam // second message parameter
|
||||
);
|
||||
|
||||
static int CALLBACK StaticWindowProc(
|
||||
HWND hwndDlg, // handle to dialog box
|
||||
UINT uMsg, // message
|
||||
WPARAM wParam, // first message parameter
|
||||
LPARAM lParam // second message parameter
|
||||
);
|
||||
|
||||
void RepositionEditControl();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
HWND m_hWnd;
|
||||
HWND m_hEditControl;
|
||||
bool m_bVisible;
|
||||
bool m_bDeleteOnClose;
|
||||
int m_nCurrentChars;
|
||||
};
|
||||
|
||||
|
||||
CConsoleWnd::CConsoleWnd()
|
||||
{
|
||||
m_hWnd = m_hEditControl = NULL;
|
||||
m_bVisible = false;
|
||||
m_bDeleteOnClose = false;
|
||||
m_nCurrentChars = 0;
|
||||
}
|
||||
|
||||
|
||||
CConsoleWnd::~CConsoleWnd()
|
||||
{
|
||||
Term();
|
||||
}
|
||||
|
||||
bool CConsoleWnd::Init( void *hInstance, int dialogResourceID, int editControlID, bool bVisible )
|
||||
{
|
||||
// Create the window.
|
||||
m_hWnd = CreateDialog(
|
||||
(HINSTANCE)hInstance,
|
||||
MAKEINTRESOURCE( dialogResourceID ),
|
||||
NULL,
|
||||
&CConsoleWnd::StaticWindowProc );
|
||||
|
||||
if ( !m_hWnd )
|
||||
return false;
|
||||
|
||||
SetWindowLong( m_hWnd, GWL_USERDATA, reinterpret_cast< LONG >( this ) );
|
||||
if ( bVisible )
|
||||
ShowWindow( m_hWnd, SW_SHOW );
|
||||
|
||||
// Get a handle to the edit control.
|
||||
m_hEditControl = GetDlgItem( m_hWnd, editControlID );
|
||||
if ( !m_hEditControl )
|
||||
return false;
|
||||
|
||||
RepositionEditControl();
|
||||
|
||||
m_bVisible = bVisible;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::Term()
|
||||
{
|
||||
if ( m_hWnd )
|
||||
{
|
||||
DestroyWindow( m_hWnd );
|
||||
m_hWnd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::Release()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::SetVisible( bool bVisible )
|
||||
{
|
||||
ShowWindow( m_hWnd, bVisible ? SW_RESTORE : SW_HIDE );
|
||||
|
||||
if ( bVisible )
|
||||
{
|
||||
ShowWindow( m_hWnd, SW_SHOW );
|
||||
SetWindowPos( m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
|
||||
UpdateWindow( m_hWnd );
|
||||
|
||||
int nLen = (int)SendMessage( m_hEditControl, EM_GETLIMITTEXT, 0, 0 );
|
||||
SendMessage( m_hEditControl, EM_SETSEL, nLen, nLen );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWindowPos( m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW | SWP_NOOWNERZORDER );
|
||||
}
|
||||
|
||||
m_bVisible = bVisible;
|
||||
}
|
||||
|
||||
|
||||
bool CConsoleWnd::IsVisible() const
|
||||
{
|
||||
return m_bVisible;
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::PrintToConsole( const char *pMsg )
|
||||
{
|
||||
if ( m_nCurrentChars >= 16*1024 )
|
||||
{
|
||||
// Clear the edit control otherwise it'll stop outputting anything.
|
||||
m_nCurrentChars = 0;
|
||||
|
||||
int nLen = (int)SendMessage( m_hEditControl, EM_GETLIMITTEXT, 0, 0 );
|
||||
SendMessage( m_hEditControl, EM_SETSEL, 0, nLen );
|
||||
SendMessage( m_hEditControl, EM_REPLACESEL, FALSE, (LPARAM)"" );
|
||||
}
|
||||
|
||||
FormatAndSendToEditControl( m_hEditControl, pMsg );
|
||||
m_nCurrentChars += (int)strlen( pMsg );
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::SetTitle( const char *pTitle )
|
||||
{
|
||||
SetWindowText( m_hWnd, pTitle );
|
||||
}
|
||||
|
||||
|
||||
int CConsoleWnd::WindowProc(
|
||||
HWND hwndDlg, // handle to dialog box
|
||||
UINT uMsg, // message
|
||||
WPARAM wParam, // first message parameter
|
||||
LPARAM lParam // second message parameter
|
||||
)
|
||||
{
|
||||
lParam = lParam; // avoid compiler warning
|
||||
|
||||
if ( hwndDlg != m_hWnd )
|
||||
return false;
|
||||
|
||||
switch ( uMsg )
|
||||
{
|
||||
case WM_SYSCOMMAND:
|
||||
{
|
||||
if ( wParam == SC_CLOSE )
|
||||
{
|
||||
if ( m_bDeleteOnClose )
|
||||
{
|
||||
Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetVisible( false );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SHOWWINDOW:
|
||||
{
|
||||
m_bVisible = (wParam != 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
RepositionEditControl();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int CConsoleWnd::StaticWindowProc(
|
||||
HWND hwndDlg, // handle to dialog box
|
||||
UINT uMsg, // message
|
||||
WPARAM wParam, // first message parameter
|
||||
LPARAM lParam // second message parameter
|
||||
)
|
||||
{
|
||||
CConsoleWnd *pDlg = (CConsoleWnd*)GetWindowLong( hwndDlg, GWL_USERDATA );
|
||||
if ( pDlg )
|
||||
return pDlg->WindowProc( hwndDlg, uMsg, wParam, lParam );
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::RepositionEditControl()
|
||||
{
|
||||
RECT rcMain;
|
||||
GetClientRect( m_hWnd, &rcMain );
|
||||
|
||||
RECT rcNew;
|
||||
rcNew.left = rcMain.left + EDITCONTROL_BORDER_SIZE;
|
||||
rcNew.right = rcMain.right - EDITCONTROL_BORDER_SIZE;
|
||||
rcNew.top = rcMain.top + EDITCONTROL_BORDER_SIZE;
|
||||
rcNew.bottom = rcMain.bottom - EDITCONTROL_BORDER_SIZE;
|
||||
|
||||
SetWindowPos(
|
||||
m_hEditControl,
|
||||
NULL,
|
||||
rcNew.left,
|
||||
rcNew.top,
|
||||
rcNew.right - rcNew.left,
|
||||
rcNew.bottom - rcNew.top,
|
||||
SWP_NOZORDER );
|
||||
}
|
||||
|
||||
|
||||
void CConsoleWnd::SetDeleteOnClose( bool bDelete )
|
||||
{
|
||||
m_bDeleteOnClose = bDelete;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
// Module interface.
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
|
||||
void SendToEditControl( HWND hEditControl, const char *pText )
|
||||
{
|
||||
int nLen = (int)SendMessage( hEditControl, EM_GETLIMITTEXT, 0, 0 );
|
||||
SendMessage( hEditControl, EM_SETSEL, nLen, nLen );
|
||||
SendMessage( hEditControl, EM_REPLACESEL, FALSE, (LPARAM)pText );
|
||||
}
|
||||
|
||||
|
||||
void FormatAndSendToEditControl( void *hWnd, const char *pText )
|
||||
{
|
||||
HWND hEditControl = (HWND)hWnd;
|
||||
|
||||
// Translate \n to \r\n.
|
||||
char outMsg[1024];
|
||||
const char *pIn = pText;
|
||||
char *pOut = outMsg;
|
||||
while ( *pIn )
|
||||
{
|
||||
if ( *pIn == '\n' )
|
||||
{
|
||||
*pOut = '\r';
|
||||
pOut++;
|
||||
}
|
||||
*pOut = *pIn;
|
||||
|
||||
++pIn;
|
||||
++pOut;
|
||||
|
||||
if ( pOut - outMsg >= 1020 )
|
||||
{
|
||||
*pOut = 0;
|
||||
SendToEditControl( hEditControl, outMsg );
|
||||
pOut = outMsg;
|
||||
}
|
||||
}
|
||||
*pOut = 0;
|
||||
SendToEditControl( hEditControl, outMsg );
|
||||
}
|
||||
|
||||
|
||||
IConsoleWnd* CreateConsoleWnd( void *hInstance, int dialogResourceID, int editControlID, bool bVisible )
|
||||
{
|
||||
CConsoleWnd *pWnd = new CConsoleWnd;
|
||||
|
||||
if ( pWnd->Init( hInstance, dialogResourceID, editControlID, bVisible ) )
|
||||
{
|
||||
return pWnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
pWnd->Release();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CONSOLEWND_H
|
||||
#define CONSOLEWND_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class IConsoleWnd
|
||||
{
|
||||
public:
|
||||
virtual void Release() = 0;
|
||||
|
||||
// Print a message to the console.
|
||||
virtual void PrintToConsole( const char *pMsg ) = 0;
|
||||
|
||||
// Set the window title.
|
||||
virtual void SetTitle( const char *pTitle ) = 0;
|
||||
|
||||
// Show and hide the console window.
|
||||
virtual void SetVisible( bool bVisible ) = 0;
|
||||
virtual bool IsVisible() const = 0;
|
||||
|
||||
// Normally, the window just hides itself when closed. You can use this to make the window
|
||||
// automatically go away when they close it.
|
||||
virtual void SetDeleteOnClose( bool bDelete ) = 0;
|
||||
};
|
||||
|
||||
|
||||
// Utility functions.
|
||||
|
||||
// This converts adds \r's where necessary and sends the text to the edit control.
|
||||
void FormatAndSendToEditControl( void *hWnd, const char *pText );
|
||||
|
||||
|
||||
IConsoleWnd* CreateConsoleWnd( void *hInstance, int dialogResourceID, int editControlID, bool bVisible );
|
||||
|
||||
|
||||
#endif // CONSOLEWND_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CONSOLEWND_H
|
||||
#define CONSOLEWND_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class IConsoleWnd
|
||||
{
|
||||
public:
|
||||
virtual void Release() = 0;
|
||||
|
||||
// Print a message to the console.
|
||||
virtual void PrintToConsole( const char *pMsg ) = 0;
|
||||
|
||||
// Set the window title.
|
||||
virtual void SetTitle( const char *pTitle ) = 0;
|
||||
|
||||
// Show and hide the console window.
|
||||
virtual void SetVisible( bool bVisible ) = 0;
|
||||
virtual bool IsVisible() const = 0;
|
||||
|
||||
// Normally, the window just hides itself when closed. You can use this to make the window
|
||||
// automatically go away when they close it.
|
||||
virtual void SetDeleteOnClose( bool bDelete ) = 0;
|
||||
};
|
||||
|
||||
|
||||
// Utility functions.
|
||||
|
||||
// This converts adds \r's where necessary and sends the text to the edit control.
|
||||
void FormatAndSendToEditControl( void *hWnd, const char *pText );
|
||||
|
||||
|
||||
IConsoleWnd* CreateConsoleWnd( void *hInstance, int dialogResourceID, int editControlID, bool bVisible );
|
||||
|
||||
|
||||
#endif // CONSOLEWND_H
|
||||
|
||||
@@ -1,209 +1,209 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#if defined( _WIN32 ) && !defined( _X360 )
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#include <io.h> // _chmod
|
||||
#elif _LINUX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include "tier1/strtools.h"
|
||||
#include "filesystem_tools.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "KeyValues.h"
|
||||
#include "tier2/tier2.h"
|
||||
|
||||
#ifdef MPI
|
||||
#include "vmpi.h"
|
||||
#include "vmpi_tools_shared.h"
|
||||
#include "vmpi_filesystem.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------- //
|
||||
// Module interface.
|
||||
// ---------------------------------------------------------------------------------------------------- //
|
||||
|
||||
IBaseFileSystem *g_pFileSystem = NULL;
|
||||
|
||||
// These are only used for tools that need the search paths that the engine's file system provides.
|
||||
CSysModule *g_pFullFileSystemModule = NULL;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// These are the base paths that everything will be referenced relative to (textures especially)
|
||||
// All of these directories include the trailing slash
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// This is the the path of the initial source file (relative to the cwd)
|
||||
char qdir[1024];
|
||||
|
||||
// This is the base engine + mod-specific game dir (e.g. "c:\tf2\mytfmod\")
|
||||
char gamedir[1024];
|
||||
|
||||
void FileSystem_SetupStandardDirectories( const char *pFilename, const char *pGameInfoPath )
|
||||
{
|
||||
// Set qdir.
|
||||
if ( !pFilename )
|
||||
{
|
||||
pFilename = ".";
|
||||
}
|
||||
|
||||
Q_MakeAbsolutePath( qdir, sizeof( qdir ), pFilename, NULL );
|
||||
Q_StripFilename( qdir );
|
||||
Q_strlower( qdir );
|
||||
if ( qdir[0] != 0 )
|
||||
{
|
||||
Q_AppendSlash( qdir, sizeof( qdir ) );
|
||||
}
|
||||
|
||||
// Set gamedir.
|
||||
Q_MakeAbsolutePath( gamedir, sizeof( gamedir ), pGameInfoPath );
|
||||
Q_AppendSlash( gamedir, sizeof( gamedir ) );
|
||||
}
|
||||
|
||||
|
||||
bool FileSystem_Init_Normal( const char *pFilename, FSInitType_t initType, bool bOnlyUseDirectoryName )
|
||||
{
|
||||
if ( initType == FS_INIT_FULL )
|
||||
{
|
||||
// First, get the name of the module
|
||||
char fileSystemDLLName[MAX_PATH];
|
||||
bool bSteam;
|
||||
if ( FileSystem_GetFileSystemDLLName( fileSystemDLLName, MAX_PATH, bSteam ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// If we're under Steam we need extra setup to let us find the proper modules
|
||||
FileSystem_SetupSteamInstallPath();
|
||||
|
||||
// Next, load the module, call Connect/Init.
|
||||
CFSLoadModuleInfo loadModuleInfo;
|
||||
loadModuleInfo.m_pFileSystemDLLName = fileSystemDLLName;
|
||||
loadModuleInfo.m_pDirectoryName = pFilename;
|
||||
loadModuleInfo.m_bOnlyUseDirectoryName = bOnlyUseDirectoryName;
|
||||
loadModuleInfo.m_ConnectFactory = Sys_GetFactoryThis();
|
||||
loadModuleInfo.m_bSteam = bSteam;
|
||||
loadModuleInfo.m_bToolsMode = true;
|
||||
if ( FileSystem_LoadFileSystemModule( loadModuleInfo ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// Next, mount the content
|
||||
CFSMountContentInfo mountContentInfo;
|
||||
mountContentInfo.m_pDirectoryName= loadModuleInfo.m_GameInfoPath;
|
||||
mountContentInfo.m_pFileSystem = loadModuleInfo.m_pFileSystem;
|
||||
mountContentInfo.m_bToolsMode = true;
|
||||
if ( FileSystem_MountContent( mountContentInfo ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// Finally, load the search paths.
|
||||
CFSSearchPathsInit searchPathsInit;
|
||||
searchPathsInit.m_pDirectoryName = loadModuleInfo.m_GameInfoPath;
|
||||
searchPathsInit.m_pFileSystem = loadModuleInfo.m_pFileSystem;
|
||||
if ( FileSystem_LoadSearchPaths( searchPathsInit ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// Store the data we got from filesystem_init.
|
||||
g_pFileSystem = g_pFullFileSystem = loadModuleInfo.m_pFileSystem;
|
||||
g_pFullFileSystemModule = loadModuleInfo.m_pModule;
|
||||
|
||||
FileSystem_AddSearchPath_Platform( g_pFullFileSystem, loadModuleInfo.m_GameInfoPath );
|
||||
|
||||
FileSystem_SetupStandardDirectories( pFilename, loadModuleInfo.m_GameInfoPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !Sys_LoadInterface(
|
||||
"filesystem_stdio",
|
||||
FILESYSTEM_INTERFACE_VERSION,
|
||||
&g_pFullFileSystemModule,
|
||||
(void**)&g_pFullFileSystem ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( g_pFullFileSystem->Init() != INIT_OK )
|
||||
return false;
|
||||
|
||||
g_pFullFileSystem->RemoveAllSearchPaths();
|
||||
g_pFullFileSystem->AddSearchPath( "../platform", "PLATFORM" );
|
||||
g_pFullFileSystem->AddSearchPath( ".", "GAME" );
|
||||
|
||||
g_pFileSystem = g_pFullFileSystem;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FileSystem_Init( const char *pBSPFilename, int maxMemoryUsage, FSInitType_t initType, bool bOnlyUseFilename )
|
||||
{
|
||||
Assert( CommandLine()->GetCmdLine() != NULL ); // Should have called CreateCmdLine by now.
|
||||
|
||||
// If this app uses VMPI, then let VMPI intercept all filesystem calls.
|
||||
#if defined( MPI )
|
||||
if ( g_bUseMPI )
|
||||
{
|
||||
if ( g_bMPIMaster )
|
||||
{
|
||||
if ( !FileSystem_Init_Normal( pBSPFilename, initType, bOnlyUseFilename ) )
|
||||
return false;
|
||||
|
||||
g_pFileSystem = g_pFullFileSystem = VMPI_FileSystem_Init( maxMemoryUsage, g_pFullFileSystem );
|
||||
SendQDirInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pFileSystem = g_pFullFileSystem = VMPI_FileSystem_Init( maxMemoryUsage, NULL );
|
||||
RecvQDirInfo();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return FileSystem_Init_Normal( pBSPFilename, initType, bOnlyUseFilename );
|
||||
}
|
||||
|
||||
|
||||
void FileSystem_Term()
|
||||
{
|
||||
#if defined( MPI )
|
||||
if ( g_bUseMPI )
|
||||
{
|
||||
g_pFileSystem = g_pFullFileSystem = VMPI_FileSystem_Term();
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( g_pFullFileSystem )
|
||||
{
|
||||
g_pFullFileSystem->Shutdown();
|
||||
g_pFullFileSystem = NULL;
|
||||
g_pFileSystem = NULL;
|
||||
}
|
||||
|
||||
if ( g_pFullFileSystemModule )
|
||||
{
|
||||
Sys_UnloadModule( g_pFullFileSystemModule );
|
||||
g_pFullFileSystemModule = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CreateInterfaceFn FileSystem_GetFactory()
|
||||
{
|
||||
#if defined( MPI )
|
||||
if ( g_bUseMPI )
|
||||
return VMPI_FileSystem_GetFactory();
|
||||
#endif
|
||||
return Sys_GetFactory( g_pFullFileSystemModule );
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#if defined( _WIN32 ) && !defined( _X360 )
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#include <io.h> // _chmod
|
||||
#elif _LINUX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include "tier1/strtools.h"
|
||||
#include "filesystem_tools.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "KeyValues.h"
|
||||
#include "tier2/tier2.h"
|
||||
|
||||
#ifdef MPI
|
||||
#include "vmpi.h"
|
||||
#include "vmpi_tools_shared.h"
|
||||
#include "vmpi_filesystem.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------- //
|
||||
// Module interface.
|
||||
// ---------------------------------------------------------------------------------------------------- //
|
||||
|
||||
IBaseFileSystem *g_pFileSystem = NULL;
|
||||
|
||||
// These are only used for tools that need the search paths that the engine's file system provides.
|
||||
CSysModule *g_pFullFileSystemModule = NULL;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// These are the base paths that everything will be referenced relative to (textures especially)
|
||||
// All of these directories include the trailing slash
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// This is the the path of the initial source file (relative to the cwd)
|
||||
char qdir[1024];
|
||||
|
||||
// This is the base engine + mod-specific game dir (e.g. "c:\tf2\mytfmod\")
|
||||
char gamedir[1024];
|
||||
|
||||
void FileSystem_SetupStandardDirectories( const char *pFilename, const char *pGameInfoPath )
|
||||
{
|
||||
// Set qdir.
|
||||
if ( !pFilename )
|
||||
{
|
||||
pFilename = ".";
|
||||
}
|
||||
|
||||
Q_MakeAbsolutePath( qdir, sizeof( qdir ), pFilename, NULL );
|
||||
Q_StripFilename( qdir );
|
||||
Q_strlower( qdir );
|
||||
if ( qdir[0] != 0 )
|
||||
{
|
||||
Q_AppendSlash( qdir, sizeof( qdir ) );
|
||||
}
|
||||
|
||||
// Set gamedir.
|
||||
Q_MakeAbsolutePath( gamedir, sizeof( gamedir ), pGameInfoPath );
|
||||
Q_AppendSlash( gamedir, sizeof( gamedir ) );
|
||||
}
|
||||
|
||||
|
||||
bool FileSystem_Init_Normal( const char *pFilename, FSInitType_t initType, bool bOnlyUseDirectoryName )
|
||||
{
|
||||
if ( initType == FS_INIT_FULL )
|
||||
{
|
||||
// First, get the name of the module
|
||||
char fileSystemDLLName[MAX_PATH];
|
||||
bool bSteam;
|
||||
if ( FileSystem_GetFileSystemDLLName( fileSystemDLLName, MAX_PATH, bSteam ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// If we're under Steam we need extra setup to let us find the proper modules
|
||||
FileSystem_SetupSteamInstallPath();
|
||||
|
||||
// Next, load the module, call Connect/Init.
|
||||
CFSLoadModuleInfo loadModuleInfo;
|
||||
loadModuleInfo.m_pFileSystemDLLName = fileSystemDLLName;
|
||||
loadModuleInfo.m_pDirectoryName = pFilename;
|
||||
loadModuleInfo.m_bOnlyUseDirectoryName = bOnlyUseDirectoryName;
|
||||
loadModuleInfo.m_ConnectFactory = Sys_GetFactoryThis();
|
||||
loadModuleInfo.m_bSteam = bSteam;
|
||||
loadModuleInfo.m_bToolsMode = true;
|
||||
if ( FileSystem_LoadFileSystemModule( loadModuleInfo ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// Next, mount the content
|
||||
CFSMountContentInfo mountContentInfo;
|
||||
mountContentInfo.m_pDirectoryName= loadModuleInfo.m_GameInfoPath;
|
||||
mountContentInfo.m_pFileSystem = loadModuleInfo.m_pFileSystem;
|
||||
mountContentInfo.m_bToolsMode = true;
|
||||
if ( FileSystem_MountContent( mountContentInfo ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// Finally, load the search paths.
|
||||
CFSSearchPathsInit searchPathsInit;
|
||||
searchPathsInit.m_pDirectoryName = loadModuleInfo.m_GameInfoPath;
|
||||
searchPathsInit.m_pFileSystem = loadModuleInfo.m_pFileSystem;
|
||||
if ( FileSystem_LoadSearchPaths( searchPathsInit ) != FS_OK )
|
||||
return false;
|
||||
|
||||
// Store the data we got from filesystem_init.
|
||||
g_pFileSystem = g_pFullFileSystem = loadModuleInfo.m_pFileSystem;
|
||||
g_pFullFileSystemModule = loadModuleInfo.m_pModule;
|
||||
|
||||
FileSystem_AddSearchPath_Platform( g_pFullFileSystem, loadModuleInfo.m_GameInfoPath );
|
||||
|
||||
FileSystem_SetupStandardDirectories( pFilename, loadModuleInfo.m_GameInfoPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !Sys_LoadInterface(
|
||||
"filesystem_stdio",
|
||||
FILESYSTEM_INTERFACE_VERSION,
|
||||
&g_pFullFileSystemModule,
|
||||
(void**)&g_pFullFileSystem ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( g_pFullFileSystem->Init() != INIT_OK )
|
||||
return false;
|
||||
|
||||
g_pFullFileSystem->RemoveAllSearchPaths();
|
||||
g_pFullFileSystem->AddSearchPath( "../platform", "PLATFORM" );
|
||||
g_pFullFileSystem->AddSearchPath( ".", "GAME" );
|
||||
|
||||
g_pFileSystem = g_pFullFileSystem;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FileSystem_Init( const char *pBSPFilename, int maxMemoryUsage, FSInitType_t initType, bool bOnlyUseFilename )
|
||||
{
|
||||
Assert( CommandLine()->GetCmdLine() != NULL ); // Should have called CreateCmdLine by now.
|
||||
|
||||
// If this app uses VMPI, then let VMPI intercept all filesystem calls.
|
||||
#if defined( MPI )
|
||||
if ( g_bUseMPI )
|
||||
{
|
||||
if ( g_bMPIMaster )
|
||||
{
|
||||
if ( !FileSystem_Init_Normal( pBSPFilename, initType, bOnlyUseFilename ) )
|
||||
return false;
|
||||
|
||||
g_pFileSystem = g_pFullFileSystem = VMPI_FileSystem_Init( maxMemoryUsage, g_pFullFileSystem );
|
||||
SendQDirInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pFileSystem = g_pFullFileSystem = VMPI_FileSystem_Init( maxMemoryUsage, NULL );
|
||||
RecvQDirInfo();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return FileSystem_Init_Normal( pBSPFilename, initType, bOnlyUseFilename );
|
||||
}
|
||||
|
||||
|
||||
void FileSystem_Term()
|
||||
{
|
||||
#if defined( MPI )
|
||||
if ( g_bUseMPI )
|
||||
{
|
||||
g_pFileSystem = g_pFullFileSystem = VMPI_FileSystem_Term();
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( g_pFullFileSystem )
|
||||
{
|
||||
g_pFullFileSystem->Shutdown();
|
||||
g_pFullFileSystem = NULL;
|
||||
g_pFileSystem = NULL;
|
||||
}
|
||||
|
||||
if ( g_pFullFileSystemModule )
|
||||
{
|
||||
Sys_UnloadModule( g_pFullFileSystemModule );
|
||||
g_pFullFileSystemModule = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CreateInterfaceFn FileSystem_GetFactory()
|
||||
{
|
||||
#if defined( MPI )
|
||||
if ( g_bUseMPI )
|
||||
return VMPI_FileSystem_GetFactory();
|
||||
#endif
|
||||
return Sys_GetFactory( g_pFullFileSystemModule );
|
||||
}
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef FILESYSTEM_TOOLS_H
|
||||
#define FILESYSTEM_TOOLS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "filesystem_init.h"
|
||||
|
||||
|
||||
// This is the the path of the initial source file
|
||||
extern char qdir[1024];
|
||||
|
||||
// This is the base engine + mod-specific game dir (e.g. "d:\tf2\mytfmod\")
|
||||
extern char gamedir[1024];
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
// Filesystem initialization.
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
|
||||
enum FSInitType_t
|
||||
{
|
||||
FS_INIT_FULL, // Load gameinfo.txt, maybe use filesystem_steam, and setup search paths.
|
||||
FS_INIT_COMPATIBILITY_MODE // Load filesystem_stdio and that's it.
|
||||
};
|
||||
|
||||
//
|
||||
// Initializes qdir, and gamedir. Also initializes the VMPI filesystem if MPI is defined.
|
||||
//
|
||||
// pFilename can be NULL if you want to rely on vproject and qproject. If it's specified, FileSystem_Init
|
||||
// will go up directories from pFilename looking for gameinfo.txt (if vproject isn't specified).
|
||||
//
|
||||
// If bOnlyUseFilename is true, then it won't use any alternative methods of finding the vproject dir
|
||||
// (ie: it won't use -game or -vproject or the vproject env var or qproject).
|
||||
//
|
||||
bool FileSystem_Init( const char *pFilename, int maxMemoryUsage=0, FSInitType_t initType=FS_INIT_FULL, bool bOnlyUseFilename=false );
|
||||
void FileSystem_Term();
|
||||
|
||||
// Used to connect app-framework based console apps to the filesystem tools
|
||||
void FileSystem_SetupStandardDirectories( const char *pFilename, const char *pGameInfoPath );
|
||||
|
||||
CreateInterfaceFn FileSystem_GetFactory( void );
|
||||
|
||||
|
||||
extern IBaseFileSystem *g_pFileSystem;
|
||||
extern IFileSystem *g_pFullFileSystem; // NOTE: this is here when VMPI is being used, but a VMPI app can
|
||||
// ONLY use LoadModule/UnloadModule.
|
||||
|
||||
|
||||
#endif // FILESYSTEM_TOOLS_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef FILESYSTEM_TOOLS_H
|
||||
#define FILESYSTEM_TOOLS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "filesystem_init.h"
|
||||
|
||||
|
||||
// This is the the path of the initial source file
|
||||
extern char qdir[1024];
|
||||
|
||||
// This is the base engine + mod-specific game dir (e.g. "d:\tf2\mytfmod\")
|
||||
extern char gamedir[1024];
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
// Filesystem initialization.
|
||||
// ---------------------------------------------------------------------------------------- //
|
||||
|
||||
enum FSInitType_t
|
||||
{
|
||||
FS_INIT_FULL, // Load gameinfo.txt, maybe use filesystem_steam, and setup search paths.
|
||||
FS_INIT_COMPATIBILITY_MODE // Load filesystem_stdio and that's it.
|
||||
};
|
||||
|
||||
//
|
||||
// Initializes qdir, and gamedir. Also initializes the VMPI filesystem if MPI is defined.
|
||||
//
|
||||
// pFilename can be NULL if you want to rely on vproject and qproject. If it's specified, FileSystem_Init
|
||||
// will go up directories from pFilename looking for gameinfo.txt (if vproject isn't specified).
|
||||
//
|
||||
// If bOnlyUseFilename is true, then it won't use any alternative methods of finding the vproject dir
|
||||
// (ie: it won't use -game or -vproject or the vproject env var or qproject).
|
||||
//
|
||||
bool FileSystem_Init( const char *pFilename, int maxMemoryUsage=0, FSInitType_t initType=FS_INIT_FULL, bool bOnlyUseFilename=false );
|
||||
void FileSystem_Term();
|
||||
|
||||
// Used to connect app-framework based console apps to the filesystem tools
|
||||
void FileSystem_SetupStandardDirectories( const char *pFilename, const char *pGameInfoPath );
|
||||
|
||||
CreateInterfaceFn FileSystem_GetFactory( void );
|
||||
|
||||
|
||||
extern IBaseFileSystem *g_pFileSystem;
|
||||
extern IFileSystem *g_pFullFileSystem; // NOTE: this is here when VMPI is being used, but a VMPI app can
|
||||
// ONLY use LoadModule/UnloadModule.
|
||||
|
||||
|
||||
#endif // FILESYSTEM_TOOLS_H
|
||||
|
||||
@@ -1,136 +1,136 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "map_shared.h"
|
||||
#include "bsplib.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
|
||||
CMapError g_MapError;
|
||||
int g_nMapFileVersion;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *szKey -
|
||||
// *szValue -
|
||||
// *pLoadEntity -
|
||||
// Output : ChunkFileResult_t
|
||||
//-----------------------------------------------------------------------------
|
||||
ChunkFileResult_t LoadEntityKeyCallback(const char *szKey, const char *szValue, LoadEntity_t *pLoadEntity)
|
||||
{
|
||||
if (!stricmp(szKey, "classname"))
|
||||
{
|
||||
if (!stricmp(szValue, "func_detail"))
|
||||
{
|
||||
pLoadEntity->nBaseContents = CONTENTS_DETAIL;
|
||||
}
|
||||
else if (!stricmp(szValue, "func_ladder"))
|
||||
{
|
||||
pLoadEntity->nBaseContents = CONTENTS_LADDER;
|
||||
}
|
||||
else if (!stricmp(szValue, "func_water"))
|
||||
{
|
||||
pLoadEntity->nBaseContents = CONTENTS_WATER;
|
||||
}
|
||||
}
|
||||
else if (!stricmp(szKey, "id"))
|
||||
{
|
||||
// UNDONE: flag entity errors by ID instead of index
|
||||
//g_MapError.EntityState( atoi( szValue ) );
|
||||
// rename this field since DME code uses this name
|
||||
SetKeyValue( pLoadEntity->pEntity, "hammerid", szValue );
|
||||
return(ChunkFile_Ok);
|
||||
}
|
||||
else if( !stricmp( szKey, "mapversion" ) )
|
||||
{
|
||||
// .vmf map revision number
|
||||
g_MapRevision = atoi( szValue );
|
||||
SetKeyValue( pLoadEntity->pEntity, szKey, szValue );
|
||||
return ( ChunkFile_Ok );
|
||||
}
|
||||
|
||||
SetKeyValue( pLoadEntity->pEntity, szKey, szValue );
|
||||
|
||||
return(ChunkFile_Ok);
|
||||
}
|
||||
|
||||
|
||||
static ChunkFileResult_t LoadEntityCallback( CChunkFile *pFile, int nParam )
|
||||
{
|
||||
if (num_entities == MAX_MAP_ENTITIES)
|
||||
{
|
||||
// Exits.
|
||||
g_MapError.ReportError ("num_entities == MAX_MAP_ENTITIES");
|
||||
}
|
||||
|
||||
entity_t *mapent = &entities[num_entities];
|
||||
num_entities++;
|
||||
memset(mapent, 0, sizeof(*mapent));
|
||||
mapent->numbrushes = 0;
|
||||
|
||||
LoadEntity_t LoadEntity;
|
||||
LoadEntity.pEntity = mapent;
|
||||
|
||||
// No default flags/contents
|
||||
LoadEntity.nBaseFlags = 0;
|
||||
LoadEntity.nBaseContents = 0;
|
||||
|
||||
//
|
||||
// Read the entity chunk.
|
||||
//
|
||||
ChunkFileResult_t eResult = pFile->ReadChunk((KeyHandler_t)LoadEntityKeyCallback, &LoadEntity);
|
||||
|
||||
return eResult;
|
||||
}
|
||||
|
||||
|
||||
bool LoadEntsFromMapFile( char const *pFilename )
|
||||
{
|
||||
//
|
||||
// Dummy this up for the texture handling. This can be removed when old .MAP file
|
||||
// support is removed.
|
||||
//
|
||||
g_nMapFileVersion = 400;
|
||||
|
||||
//
|
||||
// Open the file.
|
||||
//
|
||||
CChunkFile File;
|
||||
ChunkFileResult_t eResult = File.Open( pFilename, ChunkFile_Read );
|
||||
|
||||
if(eResult == ChunkFile_Ok)
|
||||
{
|
||||
num_entities = 0;
|
||||
|
||||
//
|
||||
// Set up handlers for the subchunks that we are interested in.
|
||||
//
|
||||
CChunkHandlerMap Handlers;
|
||||
Handlers.AddHandler("entity", (ChunkHandler_t)LoadEntityCallback, 0);
|
||||
|
||||
File.PushHandlers(&Handlers);
|
||||
|
||||
//
|
||||
// Read the sub-chunks. We ignore keys in the root of the file.
|
||||
//
|
||||
while (eResult == ChunkFile_Ok)
|
||||
{
|
||||
eResult = File.ReadChunk();
|
||||
}
|
||||
|
||||
File.PopHandlers();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error("Error in LoadEntsFromMapFile (in-memory file): %s.\n", File.GetErrorText(eResult));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "map_shared.h"
|
||||
#include "bsplib.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
|
||||
CMapError g_MapError;
|
||||
int g_nMapFileVersion;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *szKey -
|
||||
// *szValue -
|
||||
// *pLoadEntity -
|
||||
// Output : ChunkFileResult_t
|
||||
//-----------------------------------------------------------------------------
|
||||
ChunkFileResult_t LoadEntityKeyCallback(const char *szKey, const char *szValue, LoadEntity_t *pLoadEntity)
|
||||
{
|
||||
if (!stricmp(szKey, "classname"))
|
||||
{
|
||||
if (!stricmp(szValue, "func_detail"))
|
||||
{
|
||||
pLoadEntity->nBaseContents = CONTENTS_DETAIL;
|
||||
}
|
||||
else if (!stricmp(szValue, "func_ladder"))
|
||||
{
|
||||
pLoadEntity->nBaseContents = CONTENTS_LADDER;
|
||||
}
|
||||
else if (!stricmp(szValue, "func_water"))
|
||||
{
|
||||
pLoadEntity->nBaseContents = CONTENTS_WATER;
|
||||
}
|
||||
}
|
||||
else if (!stricmp(szKey, "id"))
|
||||
{
|
||||
// UNDONE: flag entity errors by ID instead of index
|
||||
//g_MapError.EntityState( atoi( szValue ) );
|
||||
// rename this field since DME code uses this name
|
||||
SetKeyValue( pLoadEntity->pEntity, "hammerid", szValue );
|
||||
return(ChunkFile_Ok);
|
||||
}
|
||||
else if( !stricmp( szKey, "mapversion" ) )
|
||||
{
|
||||
// .vmf map revision number
|
||||
g_MapRevision = atoi( szValue );
|
||||
SetKeyValue( pLoadEntity->pEntity, szKey, szValue );
|
||||
return ( ChunkFile_Ok );
|
||||
}
|
||||
|
||||
SetKeyValue( pLoadEntity->pEntity, szKey, szValue );
|
||||
|
||||
return(ChunkFile_Ok);
|
||||
}
|
||||
|
||||
|
||||
static ChunkFileResult_t LoadEntityCallback( CChunkFile *pFile, int nParam )
|
||||
{
|
||||
if (num_entities == MAX_MAP_ENTITIES)
|
||||
{
|
||||
// Exits.
|
||||
g_MapError.ReportError ("num_entities == MAX_MAP_ENTITIES");
|
||||
}
|
||||
|
||||
entity_t *mapent = &entities[num_entities];
|
||||
num_entities++;
|
||||
memset(mapent, 0, sizeof(*mapent));
|
||||
mapent->numbrushes = 0;
|
||||
|
||||
LoadEntity_t LoadEntity;
|
||||
LoadEntity.pEntity = mapent;
|
||||
|
||||
// No default flags/contents
|
||||
LoadEntity.nBaseFlags = 0;
|
||||
LoadEntity.nBaseContents = 0;
|
||||
|
||||
//
|
||||
// Read the entity chunk.
|
||||
//
|
||||
ChunkFileResult_t eResult = pFile->ReadChunk((KeyHandler_t)LoadEntityKeyCallback, &LoadEntity);
|
||||
|
||||
return eResult;
|
||||
}
|
||||
|
||||
|
||||
bool LoadEntsFromMapFile( char const *pFilename )
|
||||
{
|
||||
//
|
||||
// Dummy this up for the texture handling. This can be removed when old .MAP file
|
||||
// support is removed.
|
||||
//
|
||||
g_nMapFileVersion = 400;
|
||||
|
||||
//
|
||||
// Open the file.
|
||||
//
|
||||
CChunkFile File;
|
||||
ChunkFileResult_t eResult = File.Open( pFilename, ChunkFile_Read );
|
||||
|
||||
if(eResult == ChunkFile_Ok)
|
||||
{
|
||||
num_entities = 0;
|
||||
|
||||
//
|
||||
// Set up handlers for the subchunks that we are interested in.
|
||||
//
|
||||
CChunkHandlerMap Handlers;
|
||||
Handlers.AddHandler("entity", (ChunkHandler_t)LoadEntityCallback, 0);
|
||||
|
||||
File.PushHandlers(&Handlers);
|
||||
|
||||
//
|
||||
// Read the sub-chunks. We ignore keys in the root of the file.
|
||||
//
|
||||
while (eResult == ChunkFile_Ok)
|
||||
{
|
||||
eResult = File.ReadChunk();
|
||||
}
|
||||
|
||||
File.PopHandlers();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error("Error in LoadEntsFromMapFile (in-memory file): %s.\n", File.GetErrorText(eResult));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,91 +1,91 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MAP_SHARED_H
|
||||
#define MAP_SHARED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "ChunkFile.h"
|
||||
#include "bsplib.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
|
||||
struct LoadEntity_t
|
||||
{
|
||||
entity_t *pEntity;
|
||||
int nID;
|
||||
int nBaseFlags;
|
||||
int nBaseContents;
|
||||
};
|
||||
|
||||
|
||||
class CMapError
|
||||
{
|
||||
public:
|
||||
|
||||
void BrushState( int brushID )
|
||||
{
|
||||
m_brushID = brushID;
|
||||
}
|
||||
|
||||
void BrushSide( int side )
|
||||
{
|
||||
m_sideIndex = side;
|
||||
}
|
||||
|
||||
void TextureState( const char *pTextureName )
|
||||
{
|
||||
Q_strncpy( m_textureName, pTextureName, sizeof( m_textureName ) );
|
||||
}
|
||||
|
||||
void ClearState( void )
|
||||
{
|
||||
BrushState( 0 );
|
||||
BrushSide( 0 );
|
||||
TextureState( "Not a Parse error!" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Hook the map parse errors and report brush/ent/texture state
|
||||
// Input : *pErrorString -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ReportError( const char *pErrorString )
|
||||
{
|
||||
Error( "Brush %i: %s\nSide %i\nTexture: %s\n", m_brushID, pErrorString, m_sideIndex, m_textureName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Hook the map parse errors and report brush/ent/texture state without exiting.
|
||||
// Input : pWarningString -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ReportWarning( const char *pWarningString )
|
||||
{
|
||||
printf( "Brush %i, Side %i: %s\n", m_brushID, m_sideIndex, pWarningString );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int m_brushID;
|
||||
int m_sideIndex;
|
||||
char m_textureName[80];
|
||||
};
|
||||
|
||||
|
||||
extern CMapError g_MapError;
|
||||
extern int g_nMapFileVersion;
|
||||
|
||||
|
||||
// Shared mapload code.
|
||||
ChunkFileResult_t LoadEntityKeyCallback( const char *szKey, const char *szValue, LoadEntity_t *pLoadEntity );
|
||||
|
||||
// Used by VRAD incremental lighting - only load ents from the file and
|
||||
// fill in the global entities/num_entities array.
|
||||
bool LoadEntsFromMapFile( char const *pFilename );
|
||||
|
||||
#endif // MAP_SHARED_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MAP_SHARED_H
|
||||
#define MAP_SHARED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "ChunkFile.h"
|
||||
#include "bsplib.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
|
||||
struct LoadEntity_t
|
||||
{
|
||||
entity_t *pEntity;
|
||||
int nID;
|
||||
int nBaseFlags;
|
||||
int nBaseContents;
|
||||
};
|
||||
|
||||
|
||||
class CMapError
|
||||
{
|
||||
public:
|
||||
|
||||
void BrushState( int brushID )
|
||||
{
|
||||
m_brushID = brushID;
|
||||
}
|
||||
|
||||
void BrushSide( int side )
|
||||
{
|
||||
m_sideIndex = side;
|
||||
}
|
||||
|
||||
void TextureState( const char *pTextureName )
|
||||
{
|
||||
Q_strncpy( m_textureName, pTextureName, sizeof( m_textureName ) );
|
||||
}
|
||||
|
||||
void ClearState( void )
|
||||
{
|
||||
BrushState( 0 );
|
||||
BrushSide( 0 );
|
||||
TextureState( "Not a Parse error!" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Hook the map parse errors and report brush/ent/texture state
|
||||
// Input : *pErrorString -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ReportError( const char *pErrorString )
|
||||
{
|
||||
Error( "Brush %i: %s\nSide %i\nTexture: %s\n", m_brushID, pErrorString, m_sideIndex, m_textureName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Hook the map parse errors and report brush/ent/texture state without exiting.
|
||||
// Input : pWarningString -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ReportWarning( const char *pWarningString )
|
||||
{
|
||||
printf( "Brush %i, Side %i: %s\n", m_brushID, m_sideIndex, pWarningString );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int m_brushID;
|
||||
int m_sideIndex;
|
||||
char m_textureName[80];
|
||||
};
|
||||
|
||||
|
||||
extern CMapError g_MapError;
|
||||
extern int g_nMapFileVersion;
|
||||
|
||||
|
||||
// Shared mapload code.
|
||||
ChunkFileResult_t LoadEntityKeyCallback( const char *szKey, const char *szValue, LoadEntity_t *pLoadEntity );
|
||||
|
||||
// Used by VRAD incremental lighting - only load ents from the file and
|
||||
// fill in the global entities/num_entities array.
|
||||
bool LoadEntsFromMapFile( char const *pFilename );
|
||||
|
||||
#endif // MAP_SHARED_H
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef _MOVIE_H_
|
||||
#define _MOVIE_H_
|
||||
|
||||
/*
|
||||
movie.h
|
||||
|
||||
definitions and such for dumping screen shots to make a movie
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long tag;
|
||||
unsigned long size;
|
||||
} movieblockheader_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short width;
|
||||
short height;
|
||||
short depth;
|
||||
} movieframe_t;
|
||||
|
||||
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef _MOVIE_H_
|
||||
#define _MOVIE_H_
|
||||
|
||||
/*
|
||||
movie.h
|
||||
|
||||
definitions and such for dumping screen shots to make a movie
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long tag;
|
||||
unsigned long size;
|
||||
} movieblockheader_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short width;
|
||||
short height;
|
||||
short depth;
|
||||
} movieframe_t;
|
||||
|
||||
|
||||
|
||||
#endif _MOVIE_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,59 +1,59 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MPI_STATS_H
|
||||
#define MPI_STATS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// The VMPI stats module reports a bunch of statistics to a MySQL server, and the
|
||||
// stats can be used to trace and graph a compile session.
|
||||
//
|
||||
|
||||
// Call this as soon as possible to initialize spew hooks.
|
||||
void VMPI_Stats_InstallSpewHook();
|
||||
|
||||
//
|
||||
// pDBServerName is the hostname (or dotted IP address) of the MySQL server to connect to.
|
||||
// pBSPFilename is the last argument on the command line.
|
||||
// pMachineIP is the dotted IP address of this machine.
|
||||
// jobID is an 8-byte unique identifier for this job.
|
||||
//
|
||||
bool VMPI_Stats_Init_Master( const char *pHostName, const char *pDBName, const char *pUserName, const char *pBSPFilename, unsigned long *pDBJobID );
|
||||
bool VMPI_Stats_Init_Worker( const char *pHostName, const char *pDBName, const char *pUserName, unsigned long DBJobID );
|
||||
void VMPI_Stats_Term();
|
||||
|
||||
// Add a generic text event to the database.
|
||||
void VMPI_Stats_AddEventText( const char *pText );
|
||||
|
||||
class CDBInfo
|
||||
{
|
||||
public:
|
||||
char m_HostName[128];
|
||||
char m_DBName[128];
|
||||
char m_UserName[128];
|
||||
};
|
||||
|
||||
// If you're the master, this loads pDBInfoFilename, sends that info to the workers, and
|
||||
// connects to the database.
|
||||
//
|
||||
// If you're a worker, this waits for the DB info, then connects to the database.
|
||||
void StatsDB_InitStatsDatabase(
|
||||
int argc,
|
||||
char **argv,
|
||||
const char *pDBInfoFilename );
|
||||
|
||||
// The database gives back a unique ID for the job.
|
||||
unsigned long StatsDB_GetUniqueJobID();
|
||||
|
||||
// Get the worker ID (used for the JobWorkerID fields in the database).
|
||||
unsigned long VMPI_Stats_GetJobWorkerID();
|
||||
|
||||
|
||||
#endif // MPI_STATS_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MPI_STATS_H
|
||||
#define MPI_STATS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// The VMPI stats module reports a bunch of statistics to a MySQL server, and the
|
||||
// stats can be used to trace and graph a compile session.
|
||||
//
|
||||
|
||||
// Call this as soon as possible to initialize spew hooks.
|
||||
void VMPI_Stats_InstallSpewHook();
|
||||
|
||||
//
|
||||
// pDBServerName is the hostname (or dotted IP address) of the MySQL server to connect to.
|
||||
// pBSPFilename is the last argument on the command line.
|
||||
// pMachineIP is the dotted IP address of this machine.
|
||||
// jobID is an 8-byte unique identifier for this job.
|
||||
//
|
||||
bool VMPI_Stats_Init_Master( const char *pHostName, const char *pDBName, const char *pUserName, const char *pBSPFilename, unsigned long *pDBJobID );
|
||||
bool VMPI_Stats_Init_Worker( const char *pHostName, const char *pDBName, const char *pUserName, unsigned long DBJobID );
|
||||
void VMPI_Stats_Term();
|
||||
|
||||
// Add a generic text event to the database.
|
||||
void VMPI_Stats_AddEventText( const char *pText );
|
||||
|
||||
class CDBInfo
|
||||
{
|
||||
public:
|
||||
char m_HostName[128];
|
||||
char m_DBName[128];
|
||||
char m_UserName[128];
|
||||
};
|
||||
|
||||
// If you're the master, this loads pDBInfoFilename, sends that info to the workers, and
|
||||
// connects to the database.
|
||||
//
|
||||
// If you're a worker, this waits for the DB info, then connects to the database.
|
||||
void StatsDB_InitStatsDatabase(
|
||||
int argc,
|
||||
char **argv,
|
||||
const char *pDBInfoFilename );
|
||||
|
||||
// The database gives back a unique ID for the job.
|
||||
unsigned long StatsDB_GetUniqueJobID();
|
||||
|
||||
// Get the worker ID (used for the JobWorkerID fields in the database).
|
||||
unsigned long VMPI_Stats_GetJobWorkerID();
|
||||
|
||||
|
||||
#endif // MPI_STATS_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,43 +1,43 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
//-----------------------------------------------------------------------------
|
||||
// FILE: TRISTRIP.H
|
||||
//
|
||||
// Desc: tristrip header file
|
||||
//
|
||||
// Copyright (c) 1999-2000 Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef unsigned short WORD;
|
||||
|
||||
//
|
||||
// Main Stripify routine. Returns number of strip indices contained
|
||||
// in ppstripindices. Caller must delete [] ppstripindices.
|
||||
//
|
||||
int Stripify(
|
||||
int numtris, // Number of triangles
|
||||
WORD *ptriangles, // triangle indices pointer
|
||||
int *pnumindices, // number of indices in ppstripindices (out)
|
||||
WORD **ppstripindices // triangle strip indices
|
||||
);
|
||||
|
||||
//
|
||||
// Re-arrange vertices so that they occur in the order that they are first
|
||||
// used. This function doesn't actually move vertex data around, it returns
|
||||
// an array that specifies where in the new vertex array each old vertex
|
||||
// should go. It also re-maps the strip indices to use the new vertex
|
||||
// locations. Caller must delete [] pVertexPermutation.
|
||||
//
|
||||
void ComputeVertexPermutation
|
||||
(
|
||||
int numstripindices, // Number of strip indices
|
||||
WORD *pstripindices, // Strip indices
|
||||
int *pnumverts, // Number of verts (in and out)
|
||||
WORD **ppvertexpermutation // Map from orignal index to remapped index
|
||||
);
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
//-----------------------------------------------------------------------------
|
||||
// FILE: TRISTRIP.H
|
||||
//
|
||||
// Desc: tristrip header file
|
||||
//
|
||||
// Copyright (c) 1999-2000 Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef unsigned short WORD;
|
||||
|
||||
//
|
||||
// Main Stripify routine. Returns number of strip indices contained
|
||||
// in ppstripindices. Caller must delete [] ppstripindices.
|
||||
//
|
||||
int Stripify(
|
||||
int numtris, // Number of triangles
|
||||
WORD *ptriangles, // triangle indices pointer
|
||||
int *pnumindices, // number of indices in ppstripindices (out)
|
||||
WORD **ppstripindices // triangle strip indices
|
||||
);
|
||||
|
||||
//
|
||||
// Re-arrange vertices so that they occur in the order that they are first
|
||||
// used. This function doesn't actually move vertex data around, it returns
|
||||
// an array that specifies where in the new vertex array each old vertex
|
||||
// should go. It also re-maps the strip indices to use the new vertex
|
||||
// locations. Caller must delete [] pVertexPermutation.
|
||||
//
|
||||
void ComputeVertexPermutation
|
||||
(
|
||||
int numstripindices, // Number of strip indices
|
||||
WORD *pstripindices, // Strip indices
|
||||
int *pnumverts, // Number of verts (in and out)
|
||||
WORD **ppvertexpermutation // Map from orignal index to remapped index
|
||||
);
|
||||
|
||||
|
||||
@@ -1,63 +1,63 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <stdio.h>
|
||||
#include "basetypes.h"
|
||||
#include "pacifier.h"
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
|
||||
static int g_LastPacifierDrawn = -1;
|
||||
static bool g_bPacifierSuppressed = false;
|
||||
|
||||
#define clamp(a,b,c) ( (a) > (c) ? (c) : ( (a) < (b) ? (b) : (a) ) )
|
||||
|
||||
void StartPacifier( char const *pPrefix )
|
||||
{
|
||||
Msg( "%s", pPrefix );
|
||||
g_LastPacifierDrawn = -1;
|
||||
UpdatePacifier( 0.001f );
|
||||
}
|
||||
|
||||
void UpdatePacifier( float flPercent )
|
||||
{
|
||||
int iCur = (int)(flPercent * 40.0f);
|
||||
iCur = clamp( iCur, g_LastPacifierDrawn, 40 );
|
||||
|
||||
if( iCur != g_LastPacifierDrawn && !g_bPacifierSuppressed )
|
||||
{
|
||||
for( int i=g_LastPacifierDrawn+1; i <= iCur; i++ )
|
||||
{
|
||||
if ( !( i % 4 ) )
|
||||
{
|
||||
Msg("%d", i/4);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( i != 40 )
|
||||
{
|
||||
Msg(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_LastPacifierDrawn = iCur;
|
||||
}
|
||||
}
|
||||
|
||||
void EndPacifier( bool bCarriageReturn )
|
||||
{
|
||||
UpdatePacifier(1);
|
||||
|
||||
if( bCarriageReturn && !g_bPacifierSuppressed )
|
||||
Msg("\n");
|
||||
}
|
||||
|
||||
void SuppressPacifier( bool bSuppress )
|
||||
{
|
||||
g_bPacifierSuppressed = bSuppress;
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <stdio.h>
|
||||
#include "basetypes.h"
|
||||
#include "pacifier.h"
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
|
||||
static int g_LastPacifierDrawn = -1;
|
||||
static bool g_bPacifierSuppressed = false;
|
||||
|
||||
#define clamp(a,b,c) ( (a) > (c) ? (c) : ( (a) < (b) ? (b) : (a) ) )
|
||||
|
||||
void StartPacifier( char const *pPrefix )
|
||||
{
|
||||
Msg( "%s", pPrefix );
|
||||
g_LastPacifierDrawn = -1;
|
||||
UpdatePacifier( 0.001f );
|
||||
}
|
||||
|
||||
void UpdatePacifier( float flPercent )
|
||||
{
|
||||
int iCur = (int)(flPercent * 40.0f);
|
||||
iCur = clamp( iCur, g_LastPacifierDrawn, 40 );
|
||||
|
||||
if( iCur != g_LastPacifierDrawn && !g_bPacifierSuppressed )
|
||||
{
|
||||
for( int i=g_LastPacifierDrawn+1; i <= iCur; i++ )
|
||||
{
|
||||
if ( !( i % 4 ) )
|
||||
{
|
||||
Msg("%d", i/4);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( i != 40 )
|
||||
{
|
||||
Msg(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_LastPacifierDrawn = iCur;
|
||||
}
|
||||
}
|
||||
|
||||
void EndPacifier( bool bCarriageReturn )
|
||||
{
|
||||
UpdatePacifier(1);
|
||||
|
||||
if( bCarriageReturn && !g_bPacifierSuppressed )
|
||||
Msg("\n");
|
||||
}
|
||||
|
||||
void SuppressPacifier( bool bSuppress )
|
||||
{
|
||||
g_bPacifierSuppressed = bSuppress;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PACIFIER_H
|
||||
#define PACIFIER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// Use these to display a pacifier like:
|
||||
// ProcessBlock_Thread: 0...1...2...3...4...5...6...7...8...9... (0)
|
||||
void StartPacifier( char const *pPrefix ); // Prints the prefix and resets the pacifier
|
||||
void UpdatePacifier( float flPercent ); // percent value between 0 and 1.
|
||||
void EndPacifier( bool bCarriageReturn = true ); // Completes pacifier as if 100% was done
|
||||
void SuppressPacifier( bool bSuppress = true ); // Suppresses pacifier updates if another thread might still be firing them
|
||||
|
||||
|
||||
#endif // PACIFIER_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PACIFIER_H
|
||||
#define PACIFIER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// Use these to display a pacifier like:
|
||||
// ProcessBlock_Thread: 0...1...2...3...4...5...6...7...8...9... (0)
|
||||
void StartPacifier( char const *pPrefix ); // Prints the prefix and resets the pacifier
|
||||
void UpdatePacifier( float flPercent ); // percent value between 0 and 1.
|
||||
void EndPacifier( bool bCarriageReturn = true ); // Completes pacifier as if 100% was done
|
||||
void SuppressPacifier( bool bSuppress = true ); // Suppresses pacifier updates if another thread might still be firing them
|
||||
|
||||
|
||||
#endif // PACIFIER_H
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include <stdio.h>
|
||||
#include "physdll.h"
|
||||
#include "filesystem_tools.h"
|
||||
|
||||
static CSysModule *pPhysicsModule = NULL;
|
||||
CreateInterfaceFn GetPhysicsFactory( void )
|
||||
{
|
||||
if ( !pPhysicsModule )
|
||||
{
|
||||
pPhysicsModule = g_pFullFileSystem->LoadModule( "VPHYSICS.DLL" );
|
||||
if ( !pPhysicsModule )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Sys_GetFactory( pPhysicsModule );
|
||||
}
|
||||
|
||||
void PhysicsDLLPath( const char *pPathname )
|
||||
{
|
||||
if ( !pPhysicsModule )
|
||||
{
|
||||
pPhysicsModule = g_pFullFileSystem->LoadModule( pPathname );
|
||||
}
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include <stdio.h>
|
||||
#include "physdll.h"
|
||||
#include "filesystem_tools.h"
|
||||
|
||||
static CSysModule *pPhysicsModule = NULL;
|
||||
CreateInterfaceFn GetPhysicsFactory( void )
|
||||
{
|
||||
if ( !pPhysicsModule )
|
||||
{
|
||||
pPhysicsModule = g_pFullFileSystem->LoadModule( "VPHYSICS.DLL" );
|
||||
if ( !pPhysicsModule )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Sys_GetFactory( pPhysicsModule );
|
||||
}
|
||||
|
||||
void PhysicsDLLPath( const char *pPathname )
|
||||
{
|
||||
if ( !pPhysicsModule )
|
||||
{
|
||||
pPhysicsModule = g_pFullFileSystem->LoadModule( pPathname );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSDLL_H
|
||||
#define PHYSDLL_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "vphysics_interface.h"
|
||||
class IPhysics;
|
||||
class IPhysicsCollision;
|
||||
|
||||
extern CreateInterfaceFn GetPhysicsFactory( void );
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// tools need to force the path
|
||||
void PhysicsDLLPath( const char *pPathname );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PHYSDLL_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef PHYSDLL_H
|
||||
#define PHYSDLL_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "vphysics_interface.h"
|
||||
class IPhysics;
|
||||
class IPhysicsCollision;
|
||||
|
||||
extern CreateInterfaceFn GetPhysicsFactory( void );
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// tools need to force the path
|
||||
void PhysicsDLLPath( const char *pPathname );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PHYSDLL_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,78 +1,78 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef POLYLIB_H
|
||||
#define POLYLIB_H
|
||||
#pragma once
|
||||
|
||||
#ifndef MATHLIB_H
|
||||
#include "mathlib/mathlib.h"
|
||||
#endif
|
||||
|
||||
struct winding_t
|
||||
{
|
||||
int numpoints;
|
||||
Vector *p; // variable sized
|
||||
int maxpoints;
|
||||
winding_t *next;
|
||||
};
|
||||
|
||||
#define MAX_POINTS_ON_WINDING 64
|
||||
|
||||
// you can define on_epsilon in the makefile as tighter
|
||||
// point on plane side epsilon
|
||||
// todo: need a world-space epsilon, a lightmap-space epsilon, and a texture space epsilon
|
||||
// or at least convert from a world-space epsilon to lightmap and texture space epsilons
|
||||
#ifndef ON_EPSILON
|
||||
#define ON_EPSILON 0.1
|
||||
#endif
|
||||
|
||||
|
||||
winding_t *AllocWinding (int points);
|
||||
vec_t WindingArea (winding_t *w);
|
||||
void WindingCenter (winding_t *w, Vector ¢er);
|
||||
vec_t WindingAreaAndBalancePoint( winding_t *w, Vector ¢er );
|
||||
void ClipWindingEpsilon (winding_t *in, const Vector &normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back);
|
||||
|
||||
// translates everything by offset, then does the clip, then translates back (to keep precision)
|
||||
void ClipWindingEpsilon_Offset( winding_t *in, const Vector &normal, vec_t dist, vec_t epsilon, winding_t **front, winding_t **back, const Vector &offset );
|
||||
|
||||
void ClassifyWindingEpsilon( winding_t *in, const Vector &normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back, winding_t **on);
|
||||
void ClassifyWindingEpsilon_Offset( winding_t *in, const Vector &normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back, winding_t **on, const Vector &offset);
|
||||
|
||||
winding_t *ChopWinding (winding_t *in, const Vector &normal, vec_t dist);
|
||||
winding_t *CopyWinding (winding_t *w);
|
||||
winding_t *ReverseWinding (winding_t *w);
|
||||
winding_t *BaseWindingForPlane (const Vector &normal, vec_t dist);
|
||||
void CheckWinding (winding_t *w);
|
||||
void WindingPlane (winding_t *w, Vector &normal, vec_t *dist);
|
||||
void RemoveColinearPoints (winding_t *w);
|
||||
int WindingOnPlaneSide (winding_t *w, const Vector &normal, vec_t dist);
|
||||
void FreeWinding (winding_t *w);
|
||||
void WindingBounds (winding_t *w, Vector &mins, Vector &maxs);
|
||||
|
||||
void ChopWindingInPlace (winding_t **w, const Vector &normal, vec_t dist, vec_t epsilon);
|
||||
// frees the original if clipped
|
||||
|
||||
bool PointInWinding( Vector const &pt, winding_t *pWinding );
|
||||
|
||||
// translates a winding by offset
|
||||
void TranslateWinding( winding_t *pWinding, const Vector &offset );
|
||||
|
||||
void pw(winding_t *w);
|
||||
|
||||
|
||||
#endif // POLYLIB_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef POLYLIB_H
|
||||
#define POLYLIB_H
|
||||
#pragma once
|
||||
|
||||
#ifndef MATHLIB_H
|
||||
#include "mathlib/mathlib.h"
|
||||
#endif
|
||||
|
||||
struct winding_t
|
||||
{
|
||||
int numpoints;
|
||||
Vector *p; // variable sized
|
||||
int maxpoints;
|
||||
winding_t *next;
|
||||
};
|
||||
|
||||
#define MAX_POINTS_ON_WINDING 64
|
||||
|
||||
// you can define on_epsilon in the makefile as tighter
|
||||
// point on plane side epsilon
|
||||
// todo: need a world-space epsilon, a lightmap-space epsilon, and a texture space epsilon
|
||||
// or at least convert from a world-space epsilon to lightmap and texture space epsilons
|
||||
#ifndef ON_EPSILON
|
||||
#define ON_EPSILON 0.1
|
||||
#endif
|
||||
|
||||
|
||||
winding_t *AllocWinding (int points);
|
||||
vec_t WindingArea (winding_t *w);
|
||||
void WindingCenter (winding_t *w, Vector ¢er);
|
||||
vec_t WindingAreaAndBalancePoint( winding_t *w, Vector ¢er );
|
||||
void ClipWindingEpsilon (winding_t *in, const Vector &normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back);
|
||||
|
||||
// translates everything by offset, then does the clip, then translates back (to keep precision)
|
||||
void ClipWindingEpsilon_Offset( winding_t *in, const Vector &normal, vec_t dist, vec_t epsilon, winding_t **front, winding_t **back, const Vector &offset );
|
||||
|
||||
void ClassifyWindingEpsilon( winding_t *in, const Vector &normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back, winding_t **on);
|
||||
void ClassifyWindingEpsilon_Offset( winding_t *in, const Vector &normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back, winding_t **on, const Vector &offset);
|
||||
|
||||
winding_t *ChopWinding (winding_t *in, const Vector &normal, vec_t dist);
|
||||
winding_t *CopyWinding (winding_t *w);
|
||||
winding_t *ReverseWinding (winding_t *w);
|
||||
winding_t *BaseWindingForPlane (const Vector &normal, vec_t dist);
|
||||
void CheckWinding (winding_t *w);
|
||||
void WindingPlane (winding_t *w, Vector &normal, vec_t *dist);
|
||||
void RemoveColinearPoints (winding_t *w);
|
||||
int WindingOnPlaneSide (winding_t *w, const Vector &normal, vec_t dist);
|
||||
void FreeWinding (winding_t *w);
|
||||
void WindingBounds (winding_t *w, Vector &mins, Vector &maxs);
|
||||
|
||||
void ChopWindingInPlace (winding_t **w, const Vector &normal, vec_t dist, vec_t epsilon);
|
||||
// frees the original if clipped
|
||||
|
||||
bool PointInWinding( Vector const &pt, winding_t *pWinding );
|
||||
|
||||
// translates a winding by offset
|
||||
void TranslateWinding( winding_t *pWinding, const Vector &offset );
|
||||
|
||||
void pw(winding_t *w);
|
||||
|
||||
|
||||
#endif // POLYLIB_H
|
||||
|
||||
@@ -1,42 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef QFILES_H
|
||||
#define QFILES_H
|
||||
#pragma once
|
||||
|
||||
|
||||
//
|
||||
// qfiles.h: quake file formats
|
||||
// This file must be identical in the quake and utils directories
|
||||
//
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "commonmacros.h"
|
||||
#include "worldsize.h"
|
||||
#include "bspfile.h"
|
||||
|
||||
#define MAX_OSPATH 260
|
||||
#define MAX_QPATH 64
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
The .pak files are just a linear collapse of a directory tree
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
#define IDPAKHEADER (('K'<<24)+('C'<<16)+('A'<<8)+'P')
|
||||
|
||||
#endif // QFILES_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef QFILES_H
|
||||
#define QFILES_H
|
||||
#pragma once
|
||||
|
||||
|
||||
//
|
||||
// qfiles.h: quake file formats
|
||||
// This file must be identical in the quake and utils directories
|
||||
//
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "commonmacros.h"
|
||||
#include "worldsize.h"
|
||||
#include "bspfile.h"
|
||||
|
||||
#define MAX_OSPATH 260
|
||||
#define MAX_QPATH 64
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
The .pak files are just a linear collapse of a directory tree
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
#define IDPAKHEADER (('K'<<24)+('C'<<16)+('A'<<8)+'P')
|
||||
|
||||
#endif // QFILES_H
|
||||
|
||||
@@ -1,103 +1,103 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "scratchpad_helpers.h"
|
||||
#include "bspfile.h"
|
||||
#include "bsplib.h"
|
||||
|
||||
|
||||
void ScratchPad_DrawWinding(
|
||||
IScratchPad3D *pPad,
|
||||
int nPoints,
|
||||
Vector *pPoints,
|
||||
Vector vColor,
|
||||
Vector vOffset )
|
||||
{
|
||||
for ( int i=0; i < nPoints; i++ )
|
||||
{
|
||||
pPad->DrawLine( CSPVert( pPoints[i]+vOffset, vColor ), CSPVert( pPoints[(i+1)%nPoints]+vOffset, vColor ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ScratchPad_DrawFace( IScratchPad3D *pPad, dface_t *f, int iFaceNumber, const CSPColor &faceColor, const Vector &vOffset )
|
||||
{
|
||||
// Draw the face's outline, then put text for its face index on it too.
|
||||
CUtlVector<Vector> points;
|
||||
for ( int iEdge = 0; iEdge < f->numedges; iEdge++ )
|
||||
{
|
||||
int v;
|
||||
int se = dsurfedges[f->firstedge + iEdge];
|
||||
if ( se < 0 )
|
||||
v = dedges[-se].v[1];
|
||||
else
|
||||
v = dedges[se].v[0];
|
||||
|
||||
dvertex_t *dv = &dvertexes[v];
|
||||
points.AddToTail( dv->point );
|
||||
}
|
||||
|
||||
// Draw the outline.
|
||||
Vector vCenter( 0, 0, 0 );
|
||||
for ( int iEdge=0; iEdge < points.Count(); iEdge++ )
|
||||
{
|
||||
pPad->DrawLine( CSPVert( points[iEdge]+vOffset, faceColor ), CSPVert( points[(iEdge+1)%points.Count()]+vOffset, faceColor ) );
|
||||
vCenter += points[iEdge];
|
||||
}
|
||||
vCenter /= points.Count();
|
||||
vCenter += vOffset;
|
||||
|
||||
// Draw the text.
|
||||
if ( iFaceNumber != -1 )
|
||||
{
|
||||
char str[64];
|
||||
Q_snprintf( str, sizeof( str ), "%d", iFaceNumber );
|
||||
|
||||
CTextParams params;
|
||||
|
||||
params.m_bCentered = true;
|
||||
params.m_bOutline = true;
|
||||
params.m_flLetterWidth = 2;
|
||||
params.m_vColor.Init( 1, 0, 0 );
|
||||
|
||||
VectorAngles( dplanes[f->planenum].normal, params.m_vAngles );
|
||||
params.m_bTwoSided = true;
|
||||
|
||||
params.m_vPos = vCenter;
|
||||
|
||||
pPad->DrawText( str, params );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ScratchPad_DrawWorld( IScratchPad3D *pPad, bool bDrawFaceNumbers, const CSPColor &faceColor )
|
||||
{
|
||||
bool bAutoFlush = pPad->GetAutoFlush();
|
||||
pPad->SetAutoFlush( false );
|
||||
|
||||
for ( int i=0; i < numleafs; i++ )
|
||||
{
|
||||
dleaf_t *l = &dleafs[i];
|
||||
if ( l->contents & CONTENTS_DETAIL )
|
||||
continue;
|
||||
|
||||
for ( int z=0; z < l->numleaffaces; z++ )
|
||||
{
|
||||
int iFace = dleaffaces[l->firstleafface+z];
|
||||
dface_t *f = &dfaces[iFace];
|
||||
ScratchPad_DrawFace( pPad, f, bDrawFaceNumbers ? i : -1 );
|
||||
}
|
||||
}
|
||||
|
||||
pPad->SetAutoFlush( bAutoFlush );
|
||||
}
|
||||
|
||||
|
||||
void ScratchPad_DrawWorld( bool bDrawFaceNumbers, const CSPColor &faceColor )
|
||||
{
|
||||
IScratchPad3D *pPad = ScratchPad3D_Create();
|
||||
ScratchPad_DrawWorld( pPad, bDrawFaceNumbers );
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "scratchpad_helpers.h"
|
||||
#include "bspfile.h"
|
||||
#include "bsplib.h"
|
||||
|
||||
|
||||
void ScratchPad_DrawWinding(
|
||||
IScratchPad3D *pPad,
|
||||
int nPoints,
|
||||
Vector *pPoints,
|
||||
Vector vColor,
|
||||
Vector vOffset )
|
||||
{
|
||||
for ( int i=0; i < nPoints; i++ )
|
||||
{
|
||||
pPad->DrawLine( CSPVert( pPoints[i]+vOffset, vColor ), CSPVert( pPoints[(i+1)%nPoints]+vOffset, vColor ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ScratchPad_DrawFace( IScratchPad3D *pPad, dface_t *f, int iFaceNumber, const CSPColor &faceColor, const Vector &vOffset )
|
||||
{
|
||||
// Draw the face's outline, then put text for its face index on it too.
|
||||
CUtlVector<Vector> points;
|
||||
for ( int iEdge = 0; iEdge < f->numedges; iEdge++ )
|
||||
{
|
||||
int v;
|
||||
int se = dsurfedges[f->firstedge + iEdge];
|
||||
if ( se < 0 )
|
||||
v = dedges[-se].v[1];
|
||||
else
|
||||
v = dedges[se].v[0];
|
||||
|
||||
dvertex_t *dv = &dvertexes[v];
|
||||
points.AddToTail( dv->point );
|
||||
}
|
||||
|
||||
// Draw the outline.
|
||||
Vector vCenter( 0, 0, 0 );
|
||||
for ( int iEdge=0; iEdge < points.Count(); iEdge++ )
|
||||
{
|
||||
pPad->DrawLine( CSPVert( points[iEdge]+vOffset, faceColor ), CSPVert( points[(iEdge+1)%points.Count()]+vOffset, faceColor ) );
|
||||
vCenter += points[iEdge];
|
||||
}
|
||||
vCenter /= points.Count();
|
||||
vCenter += vOffset;
|
||||
|
||||
// Draw the text.
|
||||
if ( iFaceNumber != -1 )
|
||||
{
|
||||
char str[64];
|
||||
Q_snprintf( str, sizeof( str ), "%d", iFaceNumber );
|
||||
|
||||
CTextParams params;
|
||||
|
||||
params.m_bCentered = true;
|
||||
params.m_bOutline = true;
|
||||
params.m_flLetterWidth = 2;
|
||||
params.m_vColor.Init( 1, 0, 0 );
|
||||
|
||||
VectorAngles( dplanes[f->planenum].normal, params.m_vAngles );
|
||||
params.m_bTwoSided = true;
|
||||
|
||||
params.m_vPos = vCenter;
|
||||
|
||||
pPad->DrawText( str, params );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ScratchPad_DrawWorld( IScratchPad3D *pPad, bool bDrawFaceNumbers, const CSPColor &faceColor )
|
||||
{
|
||||
bool bAutoFlush = pPad->GetAutoFlush();
|
||||
pPad->SetAutoFlush( false );
|
||||
|
||||
for ( int i=0; i < numleafs; i++ )
|
||||
{
|
||||
dleaf_t *l = &dleafs[i];
|
||||
if ( l->contents & CONTENTS_DETAIL )
|
||||
continue;
|
||||
|
||||
for ( int z=0; z < l->numleaffaces; z++ )
|
||||
{
|
||||
int iFace = dleaffaces[l->firstleafface+z];
|
||||
dface_t *f = &dfaces[iFace];
|
||||
ScratchPad_DrawFace( pPad, f, bDrawFaceNumbers ? i : -1 );
|
||||
}
|
||||
}
|
||||
|
||||
pPad->SetAutoFlush( bAutoFlush );
|
||||
}
|
||||
|
||||
|
||||
void ScratchPad_DrawWorld( bool bDrawFaceNumbers, const CSPColor &faceColor )
|
||||
{
|
||||
IScratchPad3D *pPad = ScratchPad3D_Create();
|
||||
ScratchPad_DrawWorld( pPad, bDrawFaceNumbers );
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SCRATCHPAD_HELPERS_H
|
||||
#define SCRATCHPAD_HELPERS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "iscratchpad3d.h"
|
||||
#include "bspfile.h"
|
||||
|
||||
|
||||
void ScratchPad_DrawWinding( IScratchPad3D *pPad, int nPoints, Vector *pPoints, Vector vColor, Vector vOffset = Vector(0,0,0) );
|
||||
|
||||
void ScratchPad_DrawFace( IScratchPad3D *pPad, dface_t *f, int iFaceNumber = -1, const CSPColor &faceColor=CSPColor(1,1,1,1), const Vector &vOffset=Vector(0,0,0) );
|
||||
void ScratchPad_DrawWorld( IScratchPad3D *pPad, bool bDrawFaceNumbers, const CSPColor &faceColor=CSPColor(1,1,1,1) );
|
||||
void ScratchPad_DrawWorld( bool bDrawFaceNumbers, const CSPColor &faceColor=CSPColor(1,1,1,1) );
|
||||
|
||||
|
||||
#endif // SCRATCHPAD_HELPERS_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SCRATCHPAD_HELPERS_H
|
||||
#define SCRATCHPAD_HELPERS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "iscratchpad3d.h"
|
||||
#include "bspfile.h"
|
||||
|
||||
|
||||
void ScratchPad_DrawWinding( IScratchPad3D *pPad, int nPoints, Vector *pPoints, Vector vColor, Vector vOffset = Vector(0,0,0) );
|
||||
|
||||
void ScratchPad_DrawFace( IScratchPad3D *pPad, dface_t *f, int iFaceNumber = -1, const CSPColor &faceColor=CSPColor(1,1,1,1), const Vector &vOffset=Vector(0,0,0) );
|
||||
void ScratchPad_DrawWorld( IScratchPad3D *pPad, bool bDrawFaceNumbers, const CSPColor &faceColor=CSPColor(1,1,1,1) );
|
||||
void ScratchPad_DrawWorld( bool bDrawFaceNumbers, const CSPColor &faceColor=CSPColor(1,1,1,1) );
|
||||
|
||||
|
||||
#endif // SCRATCHPAD_HELPERS_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,96 +1,96 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SCRIPLIB_H
|
||||
#define SCRIPLIB_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
enum ScriptPathMode_t
|
||||
{
|
||||
SCRIPT_USE_ABSOLUTE_PATH,
|
||||
SCRIPT_USE_RELATIVE_PATH
|
||||
};
|
||||
|
||||
|
||||
// scriplib.h
|
||||
|
||||
#define MAXTOKEN 1024
|
||||
|
||||
extern char token[MAXTOKEN];
|
||||
extern char *scriptbuffer,*script_p,*scriptend_p;
|
||||
extern int grabbed;
|
||||
extern int scriptline;
|
||||
extern qboolean endofscript;
|
||||
|
||||
|
||||
// If pathMode is SCRIPT_USE_ABSOLUTE_PATH, then it uses ExpandPath() on the filename before
|
||||
// trying to open it. Otherwise, it passes the filename straight into the filesystem
|
||||
// (so you can leave it as a relative path).
|
||||
void LoadScriptFile (char *filename, ScriptPathMode_t pathMode=SCRIPT_USE_ABSOLUTE_PATH);
|
||||
void ParseFromMemory (char *buffer, int size);
|
||||
|
||||
qboolean GetToken (qboolean crossline);
|
||||
qboolean GetExprToken (qboolean crossline);
|
||||
void UnGetToken (void);
|
||||
qboolean TokenAvailable (void);
|
||||
qboolean GetTokenizerStatus( char **pFilename, int *pLine );
|
||||
bool SetCheckSingleCharTokens( bool bCheck );
|
||||
|
||||
// SCRIPT_LOADED_CALLBACK:
|
||||
// Is called after the contents of a file is loaded.
|
||||
// pFilenameLoaded is the path of a file that got loaded.
|
||||
// pIncludedFromFileName is the name of the parent file or NULL if loaded because of "LoadScriptFile" toplevel call.
|
||||
// nIncludeLineNumber is the number of the line in the parent file with $include statement or 0 in case of "LoadScriptFile"
|
||||
typedef void ( * SCRIPT_LOADED_CALLBACK )( char const *pFilenameLoaded, char const *pIncludedFromFileName, int nIncludeLineNumber );
|
||||
|
||||
// SetScriptLoadedCallback:
|
||||
// Sets the new callback for script loading.
|
||||
// Returns the previous callback function.
|
||||
SCRIPT_LOADED_CALLBACK SetScriptLoadedCallback( SCRIPT_LOADED_CALLBACK pfnNewScriptLoadedCallback );
|
||||
|
||||
#include "tier1/utlstring.h"
|
||||
#include "tier1/utlvector.h"
|
||||
|
||||
CUtlString SetSingleCharTokenList( const char *pszSingleCharTokenList );
|
||||
|
||||
class CUtlBuffer;
|
||||
|
||||
enum DiskWriteMode_t
|
||||
{
|
||||
WRITE_TO_DISK_NEVER,
|
||||
WRITE_TO_DISK_ALWAYS,
|
||||
WRITE_TO_DISK_UPDATE, // file must exist
|
||||
};
|
||||
|
||||
struct fileList_t
|
||||
{
|
||||
CUtlString fileName;
|
||||
time_t timeWrite;
|
||||
};
|
||||
|
||||
class IScriptLib
|
||||
{
|
||||
public:
|
||||
virtual bool ReadFileToBuffer( const char *pSourceName, CUtlBuffer &buffer, bool bText = false, bool bNoOpenFailureWarning = false ) = 0;
|
||||
virtual bool WriteBufferToFile( const char *pTargetName, CUtlBuffer &buffer, DiskWriteMode_t writeMode ) = 0;
|
||||
virtual int FindFiles( char* pFileMask, bool bRecurse, CUtlVector<fileList_t> &fileList ) = 0;
|
||||
virtual char *MakeTemporaryFilename( char const *pchModPath, char *pPath, int pathSize ) = 0;
|
||||
virtual void DeleteTemporaryFiles( const char *pFileMask ) = 0;
|
||||
virtual int CompareFileTime( const char *pFilenameA, const char *pFilenameB ) = 0;
|
||||
virtual bool DoesFileExist( const char *pFilename ) = 0;
|
||||
};
|
||||
|
||||
extern IScriptLib *scriptlib;
|
||||
|
||||
|
||||
#endif // SCRIPLIB_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SCRIPLIB_H
|
||||
#define SCRIPLIB_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
enum ScriptPathMode_t
|
||||
{
|
||||
SCRIPT_USE_ABSOLUTE_PATH,
|
||||
SCRIPT_USE_RELATIVE_PATH
|
||||
};
|
||||
|
||||
|
||||
// scriplib.h
|
||||
|
||||
#define MAXTOKEN 1024
|
||||
|
||||
extern char token[MAXTOKEN];
|
||||
extern char *scriptbuffer,*script_p,*scriptend_p;
|
||||
extern int grabbed;
|
||||
extern int scriptline;
|
||||
extern qboolean endofscript;
|
||||
|
||||
|
||||
// If pathMode is SCRIPT_USE_ABSOLUTE_PATH, then it uses ExpandPath() on the filename before
|
||||
// trying to open it. Otherwise, it passes the filename straight into the filesystem
|
||||
// (so you can leave it as a relative path).
|
||||
void LoadScriptFile (char *filename, ScriptPathMode_t pathMode=SCRIPT_USE_ABSOLUTE_PATH);
|
||||
void ParseFromMemory (char *buffer, int size);
|
||||
|
||||
qboolean GetToken (qboolean crossline);
|
||||
qboolean GetExprToken (qboolean crossline);
|
||||
void UnGetToken (void);
|
||||
qboolean TokenAvailable (void);
|
||||
qboolean GetTokenizerStatus( char **pFilename, int *pLine );
|
||||
bool SetCheckSingleCharTokens( bool bCheck );
|
||||
|
||||
// SCRIPT_LOADED_CALLBACK:
|
||||
// Is called after the contents of a file is loaded.
|
||||
// pFilenameLoaded is the path of a file that got loaded.
|
||||
// pIncludedFromFileName is the name of the parent file or NULL if loaded because of "LoadScriptFile" toplevel call.
|
||||
// nIncludeLineNumber is the number of the line in the parent file with $include statement or 0 in case of "LoadScriptFile"
|
||||
typedef void ( * SCRIPT_LOADED_CALLBACK )( char const *pFilenameLoaded, char const *pIncludedFromFileName, int nIncludeLineNumber );
|
||||
|
||||
// SetScriptLoadedCallback:
|
||||
// Sets the new callback for script loading.
|
||||
// Returns the previous callback function.
|
||||
SCRIPT_LOADED_CALLBACK SetScriptLoadedCallback( SCRIPT_LOADED_CALLBACK pfnNewScriptLoadedCallback );
|
||||
|
||||
#include "tier1/utlstring.h"
|
||||
#include "tier1/utlvector.h"
|
||||
|
||||
CUtlString SetSingleCharTokenList( const char *pszSingleCharTokenList );
|
||||
|
||||
class CUtlBuffer;
|
||||
|
||||
enum DiskWriteMode_t
|
||||
{
|
||||
WRITE_TO_DISK_NEVER,
|
||||
WRITE_TO_DISK_ALWAYS,
|
||||
WRITE_TO_DISK_UPDATE, // file must exist
|
||||
};
|
||||
|
||||
struct fileList_t
|
||||
{
|
||||
CUtlString fileName;
|
||||
time_t timeWrite;
|
||||
};
|
||||
|
||||
class IScriptLib
|
||||
{
|
||||
public:
|
||||
virtual bool ReadFileToBuffer( const char *pSourceName, CUtlBuffer &buffer, bool bText = false, bool bNoOpenFailureWarning = false ) = 0;
|
||||
virtual bool WriteBufferToFile( const char *pTargetName, CUtlBuffer &buffer, DiskWriteMode_t writeMode ) = 0;
|
||||
virtual int FindFiles( char* pFileMask, bool bRecurse, CUtlVector<fileList_t> &fileList ) = 0;
|
||||
virtual char *MakeTemporaryFilename( char const *pchModPath, char *pPath, int pathSize ) = 0;
|
||||
virtual void DeleteTemporaryFiles( const char *pFileMask ) = 0;
|
||||
virtual int CompareFileTime( const char *pFilenameA, const char *pFilenameB ) = 0;
|
||||
virtual bool DoesFileExist( const char *pFilename ) = 0;
|
||||
};
|
||||
|
||||
extern IScriptLib *scriptlib;
|
||||
|
||||
|
||||
#endif // SCRIPLIB_H
|
||||
|
||||
@@ -1,257 +1,257 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#define USED
|
||||
|
||||
#include <windows.h>
|
||||
#include "cmdlib.h"
|
||||
#define NO_THREAD_NAMES
|
||||
#include "threads.h"
|
||||
#include "pacifier.h"
|
||||
|
||||
#define MAX_THREADS 16
|
||||
|
||||
|
||||
class CRunThreadsData
|
||||
{
|
||||
public:
|
||||
int m_iThread;
|
||||
void *m_pUserData;
|
||||
RunThreadsFn m_Fn;
|
||||
};
|
||||
|
||||
CRunThreadsData g_RunThreadsData[MAX_THREADS];
|
||||
|
||||
|
||||
int dispatch;
|
||||
int workcount;
|
||||
qboolean pacifier;
|
||||
|
||||
qboolean threaded;
|
||||
bool g_bLowPriorityThreads = false;
|
||||
|
||||
HANDLE g_ThreadHandles[MAX_THREADS];
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
GetThreadWork
|
||||
|
||||
=============
|
||||
*/
|
||||
int GetThreadWork (void)
|
||||
{
|
||||
int r;
|
||||
|
||||
ThreadLock ();
|
||||
|
||||
if (dispatch == workcount)
|
||||
{
|
||||
ThreadUnlock ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
UpdatePacifier( (float)dispatch / workcount );
|
||||
|
||||
r = dispatch;
|
||||
dispatch++;
|
||||
ThreadUnlock ();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
ThreadWorkerFn workfunction;
|
||||
|
||||
void ThreadWorkerFunction( int iThread, void *pUserData )
|
||||
{
|
||||
int work;
|
||||
|
||||
while (1)
|
||||
{
|
||||
work = GetThreadWork ();
|
||||
if (work == -1)
|
||||
break;
|
||||
|
||||
workfunction( iThread, work );
|
||||
}
|
||||
}
|
||||
|
||||
void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, ThreadWorkerFn func)
|
||||
{
|
||||
if (numthreads == -1)
|
||||
ThreadSetDefault ();
|
||||
|
||||
workfunction = func;
|
||||
RunThreadsOn (workcnt, showpacifier, ThreadWorkerFunction);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================================================================
|
||||
|
||||
WIN32
|
||||
|
||||
===================================================================
|
||||
*/
|
||||
|
||||
int numthreads = -1;
|
||||
CRITICAL_SECTION crit;
|
||||
static int enter;
|
||||
|
||||
|
||||
class CCritInit
|
||||
{
|
||||
public:
|
||||
CCritInit()
|
||||
{
|
||||
InitializeCriticalSection (&crit);
|
||||
}
|
||||
} g_CritInit;
|
||||
|
||||
|
||||
|
||||
void SetLowPriority()
|
||||
{
|
||||
SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS );
|
||||
}
|
||||
|
||||
|
||||
void ThreadSetDefault (void)
|
||||
{
|
||||
SYSTEM_INFO info;
|
||||
|
||||
if (numthreads == -1) // not set manually
|
||||
{
|
||||
GetSystemInfo (&info);
|
||||
numthreads = info.dwNumberOfProcessors;
|
||||
if (numthreads < 1 || numthreads > 32)
|
||||
numthreads = 1;
|
||||
}
|
||||
|
||||
Msg ("%i threads\n", numthreads);
|
||||
}
|
||||
|
||||
|
||||
void ThreadLock (void)
|
||||
{
|
||||
if (!threaded)
|
||||
return;
|
||||
EnterCriticalSection (&crit);
|
||||
if (enter)
|
||||
Error ("Recursive ThreadLock\n");
|
||||
enter = 1;
|
||||
}
|
||||
|
||||
void ThreadUnlock (void)
|
||||
{
|
||||
if (!threaded)
|
||||
return;
|
||||
if (!enter)
|
||||
Error ("ThreadUnlock without lock\n");
|
||||
enter = 0;
|
||||
LeaveCriticalSection (&crit);
|
||||
}
|
||||
|
||||
|
||||
// This runs in the thread and dispatches a RunThreadsFn call.
|
||||
DWORD WINAPI InternalRunThreadsFn( LPVOID pParameter )
|
||||
{
|
||||
CRunThreadsData *pData = (CRunThreadsData*)pParameter;
|
||||
pData->m_Fn( pData->m_iThread, pData->m_pUserData );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void RunThreads_Start( RunThreadsFn fn, void *pUserData, ERunThreadsPriority ePriority )
|
||||
{
|
||||
Assert( numthreads > 0 );
|
||||
threaded = true;
|
||||
|
||||
if ( numthreads > MAX_TOOL_THREADS )
|
||||
numthreads = MAX_TOOL_THREADS;
|
||||
|
||||
for ( int i=0; i < numthreads ;i++ )
|
||||
{
|
||||
g_RunThreadsData[i].m_iThread = i;
|
||||
g_RunThreadsData[i].m_pUserData = pUserData;
|
||||
g_RunThreadsData[i].m_Fn = fn;
|
||||
|
||||
DWORD dwDummy;
|
||||
g_ThreadHandles[i] = CreateThread(
|
||||
NULL, // LPSECURITY_ATTRIBUTES lpsa,
|
||||
0, // DWORD cbStack,
|
||||
InternalRunThreadsFn, // LPTHREAD_START_ROUTINE lpStartAddr,
|
||||
&g_RunThreadsData[i], // LPVOID lpvThreadParm,
|
||||
0, // DWORD fdwCreate,
|
||||
&dwDummy );
|
||||
|
||||
if ( ePriority == k_eRunThreadsPriority_UseGlobalState )
|
||||
{
|
||||
if( g_bLowPriorityThreads )
|
||||
SetThreadPriority( g_ThreadHandles[i], THREAD_PRIORITY_LOWEST );
|
||||
}
|
||||
else if ( ePriority == k_eRunThreadsPriority_Idle )
|
||||
{
|
||||
SetThreadPriority( g_ThreadHandles[i], THREAD_PRIORITY_IDLE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RunThreads_End()
|
||||
{
|
||||
WaitForMultipleObjects( numthreads, g_ThreadHandles, TRUE, INFINITE );
|
||||
for ( int i=0; i < numthreads; i++ )
|
||||
CloseHandle( g_ThreadHandles[i] );
|
||||
|
||||
threaded = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RunThreadsOn
|
||||
=============
|
||||
*/
|
||||
void RunThreadsOn( int workcnt, qboolean showpacifier, RunThreadsFn fn, void *pUserData )
|
||||
{
|
||||
int start, end;
|
||||
|
||||
start = Plat_FloatTime();
|
||||
dispatch = 0;
|
||||
workcount = workcnt;
|
||||
StartPacifier("");
|
||||
pacifier = showpacifier;
|
||||
|
||||
#ifdef _PROFILE
|
||||
threaded = false;
|
||||
(*func)( 0 );
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
||||
RunThreads_Start( fn, pUserData );
|
||||
RunThreads_End();
|
||||
|
||||
|
||||
end = Plat_FloatTime();
|
||||
if (pacifier)
|
||||
{
|
||||
EndPacifier(false);
|
||||
printf (" (%i)\n", end-start);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#define USED
|
||||
|
||||
#include <windows.h>
|
||||
#include "cmdlib.h"
|
||||
#define NO_THREAD_NAMES
|
||||
#include "threads.h"
|
||||
#include "pacifier.h"
|
||||
|
||||
#define MAX_THREADS 16
|
||||
|
||||
|
||||
class CRunThreadsData
|
||||
{
|
||||
public:
|
||||
int m_iThread;
|
||||
void *m_pUserData;
|
||||
RunThreadsFn m_Fn;
|
||||
};
|
||||
|
||||
CRunThreadsData g_RunThreadsData[MAX_THREADS];
|
||||
|
||||
|
||||
int dispatch;
|
||||
int workcount;
|
||||
qboolean pacifier;
|
||||
|
||||
qboolean threaded;
|
||||
bool g_bLowPriorityThreads = false;
|
||||
|
||||
HANDLE g_ThreadHandles[MAX_THREADS];
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
GetThreadWork
|
||||
|
||||
=============
|
||||
*/
|
||||
int GetThreadWork (void)
|
||||
{
|
||||
int r;
|
||||
|
||||
ThreadLock ();
|
||||
|
||||
if (dispatch == workcount)
|
||||
{
|
||||
ThreadUnlock ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
UpdatePacifier( (float)dispatch / workcount );
|
||||
|
||||
r = dispatch;
|
||||
dispatch++;
|
||||
ThreadUnlock ();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
ThreadWorkerFn workfunction;
|
||||
|
||||
void ThreadWorkerFunction( int iThread, void *pUserData )
|
||||
{
|
||||
int work;
|
||||
|
||||
while (1)
|
||||
{
|
||||
work = GetThreadWork ();
|
||||
if (work == -1)
|
||||
break;
|
||||
|
||||
workfunction( iThread, work );
|
||||
}
|
||||
}
|
||||
|
||||
void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, ThreadWorkerFn func)
|
||||
{
|
||||
if (numthreads == -1)
|
||||
ThreadSetDefault ();
|
||||
|
||||
workfunction = func;
|
||||
RunThreadsOn (workcnt, showpacifier, ThreadWorkerFunction);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================================================================
|
||||
|
||||
WIN32
|
||||
|
||||
===================================================================
|
||||
*/
|
||||
|
||||
int numthreads = -1;
|
||||
CRITICAL_SECTION crit;
|
||||
static int enter;
|
||||
|
||||
|
||||
class CCritInit
|
||||
{
|
||||
public:
|
||||
CCritInit()
|
||||
{
|
||||
InitializeCriticalSection (&crit);
|
||||
}
|
||||
} g_CritInit;
|
||||
|
||||
|
||||
|
||||
void SetLowPriority()
|
||||
{
|
||||
SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS );
|
||||
}
|
||||
|
||||
|
||||
void ThreadSetDefault (void)
|
||||
{
|
||||
SYSTEM_INFO info;
|
||||
|
||||
if (numthreads == -1) // not set manually
|
||||
{
|
||||
GetSystemInfo (&info);
|
||||
numthreads = info.dwNumberOfProcessors;
|
||||
if (numthreads < 1 || numthreads > 32)
|
||||
numthreads = 1;
|
||||
}
|
||||
|
||||
Msg ("%i threads\n", numthreads);
|
||||
}
|
||||
|
||||
|
||||
void ThreadLock (void)
|
||||
{
|
||||
if (!threaded)
|
||||
return;
|
||||
EnterCriticalSection (&crit);
|
||||
if (enter)
|
||||
Error ("Recursive ThreadLock\n");
|
||||
enter = 1;
|
||||
}
|
||||
|
||||
void ThreadUnlock (void)
|
||||
{
|
||||
if (!threaded)
|
||||
return;
|
||||
if (!enter)
|
||||
Error ("ThreadUnlock without lock\n");
|
||||
enter = 0;
|
||||
LeaveCriticalSection (&crit);
|
||||
}
|
||||
|
||||
|
||||
// This runs in the thread and dispatches a RunThreadsFn call.
|
||||
DWORD WINAPI InternalRunThreadsFn( LPVOID pParameter )
|
||||
{
|
||||
CRunThreadsData *pData = (CRunThreadsData*)pParameter;
|
||||
pData->m_Fn( pData->m_iThread, pData->m_pUserData );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void RunThreads_Start( RunThreadsFn fn, void *pUserData, ERunThreadsPriority ePriority )
|
||||
{
|
||||
Assert( numthreads > 0 );
|
||||
threaded = true;
|
||||
|
||||
if ( numthreads > MAX_TOOL_THREADS )
|
||||
numthreads = MAX_TOOL_THREADS;
|
||||
|
||||
for ( int i=0; i < numthreads ;i++ )
|
||||
{
|
||||
g_RunThreadsData[i].m_iThread = i;
|
||||
g_RunThreadsData[i].m_pUserData = pUserData;
|
||||
g_RunThreadsData[i].m_Fn = fn;
|
||||
|
||||
DWORD dwDummy;
|
||||
g_ThreadHandles[i] = CreateThread(
|
||||
NULL, // LPSECURITY_ATTRIBUTES lpsa,
|
||||
0, // DWORD cbStack,
|
||||
InternalRunThreadsFn, // LPTHREAD_START_ROUTINE lpStartAddr,
|
||||
&g_RunThreadsData[i], // LPVOID lpvThreadParm,
|
||||
0, // DWORD fdwCreate,
|
||||
&dwDummy );
|
||||
|
||||
if ( ePriority == k_eRunThreadsPriority_UseGlobalState )
|
||||
{
|
||||
if( g_bLowPriorityThreads )
|
||||
SetThreadPriority( g_ThreadHandles[i], THREAD_PRIORITY_LOWEST );
|
||||
}
|
||||
else if ( ePriority == k_eRunThreadsPriority_Idle )
|
||||
{
|
||||
SetThreadPriority( g_ThreadHandles[i], THREAD_PRIORITY_IDLE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RunThreads_End()
|
||||
{
|
||||
WaitForMultipleObjects( numthreads, g_ThreadHandles, TRUE, INFINITE );
|
||||
for ( int i=0; i < numthreads; i++ )
|
||||
CloseHandle( g_ThreadHandles[i] );
|
||||
|
||||
threaded = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RunThreadsOn
|
||||
=============
|
||||
*/
|
||||
void RunThreadsOn( int workcnt, qboolean showpacifier, RunThreadsFn fn, void *pUserData )
|
||||
{
|
||||
int start, end;
|
||||
|
||||
start = Plat_FloatTime();
|
||||
dispatch = 0;
|
||||
workcount = workcnt;
|
||||
StartPacifier("");
|
||||
pacifier = showpacifier;
|
||||
|
||||
#ifdef _PROFILE
|
||||
threaded = false;
|
||||
(*func)( 0 );
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
||||
RunThreads_Start( fn, pUserData );
|
||||
RunThreads_End();
|
||||
|
||||
|
||||
end = Plat_FloatTime();
|
||||
if (pacifier)
|
||||
{
|
||||
EndPacifier(false);
|
||||
printf (" (%i)\n", end-start);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,65 +1,65 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef THREADS_H
|
||||
#define THREADS_H
|
||||
#pragma once
|
||||
|
||||
|
||||
// Arrays that are indexed by thread should always be MAX_TOOL_THREADS+1
|
||||
// large so THREADINDEX_MAIN can be used from the main thread.
|
||||
#define MAX_TOOL_THREADS 16
|
||||
#define THREADINDEX_MAIN (MAX_TOOL_THREADS)
|
||||
|
||||
|
||||
extern int numthreads;
|
||||
|
||||
// If set to true, then all the threads that are created are low priority.
|
||||
extern bool g_bLowPriorityThreads;
|
||||
|
||||
typedef void (*ThreadWorkerFn)( int iThread, int iWorkItem );
|
||||
typedef void (*RunThreadsFn)( int iThread, void *pUserData );
|
||||
|
||||
|
||||
enum ERunThreadsPriority
|
||||
{
|
||||
k_eRunThreadsPriority_UseGlobalState=0, // Default.. uses g_bLowPriorityThreads to decide what to set the priority to.
|
||||
k_eRunThreadsPriority_Normal, // Doesn't touch thread priorities.
|
||||
k_eRunThreadsPriority_Idle // Sets threads to idle priority.
|
||||
};
|
||||
|
||||
|
||||
// Put the process into an idle priority class so it doesn't hog the UI.
|
||||
void SetLowPriority();
|
||||
|
||||
void ThreadSetDefault (void);
|
||||
int GetThreadWork (void);
|
||||
|
||||
void RunThreadsOnIndividual ( int workcnt, qboolean showpacifier, ThreadWorkerFn fn );
|
||||
|
||||
void RunThreadsOn ( int workcnt, qboolean showpacifier, RunThreadsFn fn, void *pUserData=NULL );
|
||||
|
||||
// This version doesn't track work items - it just runs your function and waits for it to finish.
|
||||
void RunThreads_Start( RunThreadsFn fn, void *pUserData, ERunThreadsPriority ePriority=k_eRunThreadsPriority_UseGlobalState );
|
||||
void RunThreads_End();
|
||||
|
||||
void ThreadLock (void);
|
||||
void ThreadUnlock (void);
|
||||
|
||||
|
||||
#ifndef NO_THREAD_NAMES
|
||||
#define RunThreadsOn(n,p,f) { if (p) printf("%-20s ", #f ":"); RunThreadsOn(n,p,f); }
|
||||
#define RunThreadsOnIndividual(n,p,f) { if (p) printf("%-20s ", #f ":"); RunThreadsOnIndividual(n,p,f); }
|
||||
#endif
|
||||
|
||||
#endif // THREADS_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef THREADS_H
|
||||
#define THREADS_H
|
||||
#pragma once
|
||||
|
||||
|
||||
// Arrays that are indexed by thread should always be MAX_TOOL_THREADS+1
|
||||
// large so THREADINDEX_MAIN can be used from the main thread.
|
||||
#define MAX_TOOL_THREADS 16
|
||||
#define THREADINDEX_MAIN (MAX_TOOL_THREADS)
|
||||
|
||||
|
||||
extern int numthreads;
|
||||
|
||||
// If set to true, then all the threads that are created are low priority.
|
||||
extern bool g_bLowPriorityThreads;
|
||||
|
||||
typedef void (*ThreadWorkerFn)( int iThread, int iWorkItem );
|
||||
typedef void (*RunThreadsFn)( int iThread, void *pUserData );
|
||||
|
||||
|
||||
enum ERunThreadsPriority
|
||||
{
|
||||
k_eRunThreadsPriority_UseGlobalState=0, // Default.. uses g_bLowPriorityThreads to decide what to set the priority to.
|
||||
k_eRunThreadsPriority_Normal, // Doesn't touch thread priorities.
|
||||
k_eRunThreadsPriority_Idle // Sets threads to idle priority.
|
||||
};
|
||||
|
||||
|
||||
// Put the process into an idle priority class so it doesn't hog the UI.
|
||||
void SetLowPriority();
|
||||
|
||||
void ThreadSetDefault (void);
|
||||
int GetThreadWork (void);
|
||||
|
||||
void RunThreadsOnIndividual ( int workcnt, qboolean showpacifier, ThreadWorkerFn fn );
|
||||
|
||||
void RunThreadsOn ( int workcnt, qboolean showpacifier, RunThreadsFn fn, void *pUserData=NULL );
|
||||
|
||||
// This version doesn't track work items - it just runs your function and waits for it to finish.
|
||||
void RunThreads_Start( RunThreadsFn fn, void *pUserData, ERunThreadsPriority ePriority=k_eRunThreadsPriority_UseGlobalState );
|
||||
void RunThreads_End();
|
||||
|
||||
void ThreadLock (void);
|
||||
void ThreadUnlock (void);
|
||||
|
||||
|
||||
#ifndef NO_THREAD_NAMES
|
||||
#define RunThreadsOn(n,p,f) { if (p) printf("%-20s ", #f ":"); RunThreadsOn(n,p,f); }
|
||||
#define RunThreadsOnIndividual(n,p,f) { if (p) printf("%-20s ", #f ":"); RunThreadsOnIndividual(n,p,f); }
|
||||
#endif
|
||||
|
||||
#endif // THREADS_H
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
#include "tier0/minidump.h"
|
||||
#include "tools_minidump.h"
|
||||
|
||||
static bool g_bToolsWriteFullMinidumps = false;
|
||||
static ToolsExceptionHandler g_pCustomExceptionHandler = NULL;
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------- //
|
||||
// Internal helpers.
|
||||
// --------------------------------------------------------------------------------- //
|
||||
|
||||
static LONG __stdcall ToolsExceptionFilter( struct _EXCEPTION_POINTERS *ExceptionInfo )
|
||||
{
|
||||
// Non VMPI workers write a minidump and show a crash dialog like normal.
|
||||
int iType = MiniDumpNormal;
|
||||
if ( g_bToolsWriteFullMinidumps )
|
||||
iType = MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory;
|
||||
|
||||
WriteMiniDumpUsingExceptionInfo( ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo, (MINIDUMP_TYPE)iType );
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
|
||||
static LONG __stdcall ToolsExceptionFilter_Custom( struct _EXCEPTION_POINTERS *ExceptionInfo )
|
||||
{
|
||||
// Run their custom handler.
|
||||
g_pCustomExceptionHandler( ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo );
|
||||
return EXCEPTION_EXECUTE_HANDLER; // (never gets here anyway)
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------- //
|
||||
// Interface functions.
|
||||
// --------------------------------------------------------------------------------- //
|
||||
|
||||
void EnableFullMinidumps( bool bFull )
|
||||
{
|
||||
g_bToolsWriteFullMinidumps = bFull;
|
||||
}
|
||||
|
||||
|
||||
void SetupDefaultToolsMinidumpHandler()
|
||||
{
|
||||
SetUnhandledExceptionFilter( ToolsExceptionFilter );
|
||||
}
|
||||
|
||||
|
||||
void SetupToolsMinidumpHandler( ToolsExceptionHandler fn )
|
||||
{
|
||||
g_pCustomExceptionHandler = fn;
|
||||
SetUnhandledExceptionFilter( ToolsExceptionFilter_Custom );
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
#include "tier0/minidump.h"
|
||||
#include "tools_minidump.h"
|
||||
|
||||
static bool g_bToolsWriteFullMinidumps = false;
|
||||
static ToolsExceptionHandler g_pCustomExceptionHandler = NULL;
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------- //
|
||||
// Internal helpers.
|
||||
// --------------------------------------------------------------------------------- //
|
||||
|
||||
static LONG __stdcall ToolsExceptionFilter( struct _EXCEPTION_POINTERS *ExceptionInfo )
|
||||
{
|
||||
// Non VMPI workers write a minidump and show a crash dialog like normal.
|
||||
int iType = MiniDumpNormal;
|
||||
if ( g_bToolsWriteFullMinidumps )
|
||||
iType = MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory;
|
||||
|
||||
WriteMiniDumpUsingExceptionInfo( ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo, (MINIDUMP_TYPE)iType );
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
|
||||
static LONG __stdcall ToolsExceptionFilter_Custom( struct _EXCEPTION_POINTERS *ExceptionInfo )
|
||||
{
|
||||
// Run their custom handler.
|
||||
g_pCustomExceptionHandler( ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo );
|
||||
return EXCEPTION_EXECUTE_HANDLER; // (never gets here anyway)
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------- //
|
||||
// Interface functions.
|
||||
// --------------------------------------------------------------------------------- //
|
||||
|
||||
void EnableFullMinidumps( bool bFull )
|
||||
{
|
||||
g_bToolsWriteFullMinidumps = bFull;
|
||||
}
|
||||
|
||||
|
||||
void SetupDefaultToolsMinidumpHandler()
|
||||
{
|
||||
SetUnhandledExceptionFilter( ToolsExceptionFilter );
|
||||
}
|
||||
|
||||
|
||||
void SetupToolsMinidumpHandler( ToolsExceptionHandler fn )
|
||||
{
|
||||
g_pCustomExceptionHandler = fn;
|
||||
SetUnhandledExceptionFilter( ToolsExceptionFilter_Custom );
|
||||
}
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TOOLS_MINIDUMP_H
|
||||
#define TOOLS_MINIDUMP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Defaults to false. If true, it'll write larger minidump files with the contents
|
||||
// of global variables and following pointers from where the crash occurred.
|
||||
void EnableFullMinidumps( bool bFull );
|
||||
|
||||
|
||||
// This handler catches any crash, writes a minidump, and runs the default system
|
||||
// crash handler (which usually shows a dialog).
|
||||
void SetupDefaultToolsMinidumpHandler();
|
||||
|
||||
|
||||
// (Used by VMPI) - you specify your own crash handler.
|
||||
// Arguments passed to ToolsExceptionHandler
|
||||
// exceptionCode - exception code
|
||||
// pvExceptionInfo - on Win32 platform points to "struct _EXCEPTION_POINTERS"
|
||||
// otherwise NULL
|
||||
//
|
||||
typedef void (*ToolsExceptionHandler)( unsigned long exceptionCode, void *pvExceptionInfo );
|
||||
void SetupToolsMinidumpHandler( ToolsExceptionHandler fn );
|
||||
|
||||
|
||||
#endif // MINIDUMP_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef TOOLS_MINIDUMP_H
|
||||
#define TOOLS_MINIDUMP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Defaults to false. If true, it'll write larger minidump files with the contents
|
||||
// of global variables and following pointers from where the crash occurred.
|
||||
void EnableFullMinidumps( bool bFull );
|
||||
|
||||
|
||||
// This handler catches any crash, writes a minidump, and runs the default system
|
||||
// crash handler (which usually shows a dialog).
|
||||
void SetupDefaultToolsMinidumpHandler();
|
||||
|
||||
|
||||
// (Used by VMPI) - you specify your own crash handler.
|
||||
// Arguments passed to ToolsExceptionHandler
|
||||
// exceptionCode - exception code
|
||||
// pvExceptionInfo - on Win32 platform points to "struct _EXCEPTION_POINTERS"
|
||||
// otherwise NULL
|
||||
//
|
||||
typedef void (*ToolsExceptionHandler)( unsigned long exceptionCode, void *pvExceptionInfo );
|
||||
void SetupToolsMinidumpHandler( ToolsExceptionHandler fn );
|
||||
|
||||
|
||||
#endif // MINIDUMP_H
|
||||
|
||||
@@ -1,184 +1,184 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
// C callable material system interface for the utils.
|
||||
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include <cmdlib.h>
|
||||
#include "utilmatlib.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include <windows.h>
|
||||
#include "filesystem.h"
|
||||
#include "materialsystem/materialsystem_config.h"
|
||||
#include "mathlib/Mathlib.h"
|
||||
|
||||
void LoadMaterialSystemInterface( CreateInterfaceFn fileSystemFactory )
|
||||
{
|
||||
if( g_pMaterialSystem )
|
||||
return;
|
||||
|
||||
// materialsystem.dll should be in the path, it's in bin along with vbsp.
|
||||
const char *pDllName = "materialsystem.dll";
|
||||
CSysModule *materialSystemDLLHInst;
|
||||
materialSystemDLLHInst = g_pFullFileSystem->LoadModule( pDllName );
|
||||
if( !materialSystemDLLHInst )
|
||||
{
|
||||
Error( "Can't load MaterialSystem.dll\n" );
|
||||
}
|
||||
|
||||
CreateInterfaceFn clientFactory = Sys_GetFactory( materialSystemDLLHInst );
|
||||
if ( clientFactory )
|
||||
{
|
||||
g_pMaterialSystem = (IMaterialSystem *)clientFactory( MATERIAL_SYSTEM_INTERFACE_VERSION, NULL );
|
||||
if ( !g_pMaterialSystem )
|
||||
{
|
||||
Error( "Could not get the material system interface from materialsystem.dll (" __FILE__ ")" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Error( "Could not find factory interface in library MaterialSystem.dll" );
|
||||
}
|
||||
|
||||
if (!g_pMaterialSystem->Init( "shaderapiempty.dll", 0, fileSystemFactory ))
|
||||
{
|
||||
Error( "Could not start the empty shader (shaderapiempty.dll)!" );
|
||||
}
|
||||
}
|
||||
|
||||
void InitMaterialSystem( const char *materialBaseDirPath, CreateInterfaceFn fileSystemFactory )
|
||||
{
|
||||
LoadMaterialSystemInterface( fileSystemFactory );
|
||||
MaterialSystem_Config_t config;
|
||||
g_pMaterialSystem->OverrideConfig( config, false );
|
||||
}
|
||||
|
||||
void ShutdownMaterialSystem( )
|
||||
{
|
||||
if ( g_pMaterialSystem )
|
||||
{
|
||||
g_pMaterialSystem->Shutdown();
|
||||
g_pMaterialSystem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MaterialSystemMaterial_t FindMaterial( const char *materialName, bool *pFound, bool bComplain )
|
||||
{
|
||||
IMaterial *pMat = g_pMaterialSystem->FindMaterial( materialName, TEXTURE_GROUP_OTHER, bComplain );
|
||||
MaterialSystemMaterial_t matHandle = pMat;
|
||||
|
||||
if ( pFound )
|
||||
{
|
||||
*pFound = true;
|
||||
if ( IsErrorMaterial( pMat ) )
|
||||
*pFound = false;
|
||||
}
|
||||
|
||||
return matHandle;
|
||||
}
|
||||
|
||||
void GetMaterialDimensions( MaterialSystemMaterial_t materialHandle, int *width, int *height )
|
||||
{
|
||||
PreviewImageRetVal_t retVal;
|
||||
ImageFormat dummyImageFormat;
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
bool translucent;
|
||||
retVal = material->GetPreviewImageProperties( width, height, &dummyImageFormat, &translucent );
|
||||
if (retVal != MATERIAL_PREVIEW_IMAGE_OK )
|
||||
{
|
||||
#if 0
|
||||
if (retVal == MATERIAL_PREVIEW_IMAGE_BAD )
|
||||
{
|
||||
Error( "problem getting preview image for %s",
|
||||
g_pMaterialSystem->GetMaterialName( materialInfo[matID].materialHandle ) );
|
||||
}
|
||||
#else
|
||||
*width = 128;
|
||||
*height = 128;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void GetMaterialReflectivity( MaterialSystemMaterial_t materialHandle, float *reflectivityVect )
|
||||
{
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
const IMaterialVar *reflectivityVar;
|
||||
|
||||
bool found;
|
||||
reflectivityVar = material->FindVar( "$reflectivity", &found, false );
|
||||
if( !found )
|
||||
{
|
||||
Vector tmp;
|
||||
material->GetReflectivity( tmp );
|
||||
VectorCopy( tmp.Base(), reflectivityVect );
|
||||
}
|
||||
else
|
||||
{
|
||||
reflectivityVar->GetVecValue( reflectivityVect, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
int GetMaterialShaderPropertyBool( MaterialSystemMaterial_t materialHandle, int propID )
|
||||
{
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
switch( propID )
|
||||
{
|
||||
case UTILMATLIB_NEEDS_BUMPED_LIGHTMAPS:
|
||||
return material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
|
||||
|
||||
case UTILMATLIB_NEEDS_LIGHTMAP:
|
||||
return material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
|
||||
|
||||
default:
|
||||
Assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int GetMaterialShaderPropertyInt( MaterialSystemMaterial_t materialHandle, int propID )
|
||||
{
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
switch( propID )
|
||||
{
|
||||
case UTILMATLIB_OPACITY:
|
||||
if (material->IsTranslucent())
|
||||
return UTILMATLIB_TRANSLUCENT;
|
||||
if (material->IsAlphaTested())
|
||||
return UTILMATLIB_ALPHATEST;
|
||||
return UTILMATLIB_OPAQUE;
|
||||
|
||||
default:
|
||||
Assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char *GetMaterialVar( MaterialSystemMaterial_t materialHandle, const char *propertyName )
|
||||
{
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
IMaterialVar *var;
|
||||
bool found;
|
||||
var = material->FindVar( propertyName, &found, false );
|
||||
if( found )
|
||||
{
|
||||
return var->GetStringValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char *GetMaterialShaderName( MaterialSystemMaterial_t materialHandle )
|
||||
{
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
return material->GetShaderName();
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
// C callable material system interface for the utils.
|
||||
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include <cmdlib.h>
|
||||
#include "utilmatlib.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include <windows.h>
|
||||
#include "filesystem.h"
|
||||
#include "materialsystem/materialsystem_config.h"
|
||||
#include "mathlib/Mathlib.h"
|
||||
|
||||
void LoadMaterialSystemInterface( CreateInterfaceFn fileSystemFactory )
|
||||
{
|
||||
if( g_pMaterialSystem )
|
||||
return;
|
||||
|
||||
// materialsystem.dll should be in the path, it's in bin along with vbsp.
|
||||
const char *pDllName = "materialsystem.dll";
|
||||
CSysModule *materialSystemDLLHInst;
|
||||
materialSystemDLLHInst = g_pFullFileSystem->LoadModule( pDllName );
|
||||
if( !materialSystemDLLHInst )
|
||||
{
|
||||
Error( "Can't load MaterialSystem.dll\n" );
|
||||
}
|
||||
|
||||
CreateInterfaceFn clientFactory = Sys_GetFactory( materialSystemDLLHInst );
|
||||
if ( clientFactory )
|
||||
{
|
||||
g_pMaterialSystem = (IMaterialSystem *)clientFactory( MATERIAL_SYSTEM_INTERFACE_VERSION, NULL );
|
||||
if ( !g_pMaterialSystem )
|
||||
{
|
||||
Error( "Could not get the material system interface from materialsystem.dll (" __FILE__ ")" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Error( "Could not find factory interface in library MaterialSystem.dll" );
|
||||
}
|
||||
|
||||
if (!g_pMaterialSystem->Init( "shaderapiempty.dll", 0, fileSystemFactory ))
|
||||
{
|
||||
Error( "Could not start the empty shader (shaderapiempty.dll)!" );
|
||||
}
|
||||
}
|
||||
|
||||
void InitMaterialSystem( const char *materialBaseDirPath, CreateInterfaceFn fileSystemFactory )
|
||||
{
|
||||
LoadMaterialSystemInterface( fileSystemFactory );
|
||||
MaterialSystem_Config_t config;
|
||||
g_pMaterialSystem->OverrideConfig( config, false );
|
||||
}
|
||||
|
||||
void ShutdownMaterialSystem( )
|
||||
{
|
||||
if ( g_pMaterialSystem )
|
||||
{
|
||||
g_pMaterialSystem->Shutdown();
|
||||
g_pMaterialSystem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MaterialSystemMaterial_t FindMaterial( const char *materialName, bool *pFound, bool bComplain )
|
||||
{
|
||||
IMaterial *pMat = g_pMaterialSystem->FindMaterial( materialName, TEXTURE_GROUP_OTHER, bComplain );
|
||||
MaterialSystemMaterial_t matHandle = pMat;
|
||||
|
||||
if ( pFound )
|
||||
{
|
||||
*pFound = true;
|
||||
if ( IsErrorMaterial( pMat ) )
|
||||
*pFound = false;
|
||||
}
|
||||
|
||||
return matHandle;
|
||||
}
|
||||
|
||||
void GetMaterialDimensions( MaterialSystemMaterial_t materialHandle, int *width, int *height )
|
||||
{
|
||||
PreviewImageRetVal_t retVal;
|
||||
ImageFormat dummyImageFormat;
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
bool translucent;
|
||||
retVal = material->GetPreviewImageProperties( width, height, &dummyImageFormat, &translucent );
|
||||
if (retVal != MATERIAL_PREVIEW_IMAGE_OK )
|
||||
{
|
||||
#if 0
|
||||
if (retVal == MATERIAL_PREVIEW_IMAGE_BAD )
|
||||
{
|
||||
Error( "problem getting preview image for %s",
|
||||
g_pMaterialSystem->GetMaterialName( materialInfo[matID].materialHandle ) );
|
||||
}
|
||||
#else
|
||||
*width = 128;
|
||||
*height = 128;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void GetMaterialReflectivity( MaterialSystemMaterial_t materialHandle, float *reflectivityVect )
|
||||
{
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
const IMaterialVar *reflectivityVar;
|
||||
|
||||
bool found;
|
||||
reflectivityVar = material->FindVar( "$reflectivity", &found, false );
|
||||
if( !found )
|
||||
{
|
||||
Vector tmp;
|
||||
material->GetReflectivity( tmp );
|
||||
VectorCopy( tmp.Base(), reflectivityVect );
|
||||
}
|
||||
else
|
||||
{
|
||||
reflectivityVar->GetVecValue( reflectivityVect, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
int GetMaterialShaderPropertyBool( MaterialSystemMaterial_t materialHandle, int propID )
|
||||
{
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
switch( propID )
|
||||
{
|
||||
case UTILMATLIB_NEEDS_BUMPED_LIGHTMAPS:
|
||||
return material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS );
|
||||
|
||||
case UTILMATLIB_NEEDS_LIGHTMAP:
|
||||
return material->GetPropertyFlag( MATERIAL_PROPERTY_NEEDS_LIGHTMAP );
|
||||
|
||||
default:
|
||||
Assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int GetMaterialShaderPropertyInt( MaterialSystemMaterial_t materialHandle, int propID )
|
||||
{
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
switch( propID )
|
||||
{
|
||||
case UTILMATLIB_OPACITY:
|
||||
if (material->IsTranslucent())
|
||||
return UTILMATLIB_TRANSLUCENT;
|
||||
if (material->IsAlphaTested())
|
||||
return UTILMATLIB_ALPHATEST;
|
||||
return UTILMATLIB_OPAQUE;
|
||||
|
||||
default:
|
||||
Assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char *GetMaterialVar( MaterialSystemMaterial_t materialHandle, const char *propertyName )
|
||||
{
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
IMaterialVar *var;
|
||||
bool found;
|
||||
var = material->FindVar( propertyName, &found, false );
|
||||
if( found )
|
||||
{
|
||||
return var->GetStringValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char *GetMaterialShaderName( MaterialSystemMaterial_t materialHandle )
|
||||
{
|
||||
IMaterial *material = ( IMaterial * )materialHandle;
|
||||
return material->GetShaderName();
|
||||
}
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef UTILMATLIB_H
|
||||
#define UTILMATLIB_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define MATERIAL_NOT_FOUND NULL
|
||||
|
||||
class IMaterialSystem;
|
||||
extern IMaterialSystem *g_pMaterialSystem;
|
||||
|
||||
typedef void *MaterialSystemMaterial_t;
|
||||
|
||||
#define UTILMATLIB_NEEDS_BUMPED_LIGHTMAPS 0
|
||||
#define UTILMATLIB_NEEDS_LIGHTMAP 1
|
||||
#define UTILMATLIB_OPACITY 2
|
||||
|
||||
enum { UTILMATLIB_ALPHATEST = 0, UTILMATLIB_OPAQUE, UTILMATLIB_TRANSLUCENT };
|
||||
|
||||
void InitMaterialSystem( const char *materialBaseDirPath, CreateInterfaceFn fileSystemFactory );
|
||||
void ShutdownMaterialSystem( );
|
||||
MaterialSystemMaterial_t FindMaterial( const char *materialName, bool *pFound, bool bComplain = true );
|
||||
void GetMaterialDimensions( MaterialSystemMaterial_t materialHandle, int *width, int *height );
|
||||
int GetMaterialShaderPropertyBool( MaterialSystemMaterial_t materialHandle, int propID );
|
||||
int GetMaterialShaderPropertyInt( MaterialSystemMaterial_t materialHandle, int propID );
|
||||
const char *GetMaterialVar( MaterialSystemMaterial_t materialHandle, const char *propertyName );
|
||||
void GetMaterialReflectivity( MaterialSystemMaterial_t materialHandle, float *reflectivityVect );
|
||||
const char *GetMaterialShaderName( MaterialSystemMaterial_t materialHandle );
|
||||
|
||||
|
||||
#endif // UTILMATLIB_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef UTILMATLIB_H
|
||||
#define UTILMATLIB_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define MATERIAL_NOT_FOUND NULL
|
||||
|
||||
class IMaterialSystem;
|
||||
extern IMaterialSystem *g_pMaterialSystem;
|
||||
|
||||
typedef void *MaterialSystemMaterial_t;
|
||||
|
||||
#define UTILMATLIB_NEEDS_BUMPED_LIGHTMAPS 0
|
||||
#define UTILMATLIB_NEEDS_LIGHTMAP 1
|
||||
#define UTILMATLIB_OPACITY 2
|
||||
|
||||
enum { UTILMATLIB_ALPHATEST = 0, UTILMATLIB_OPAQUE, UTILMATLIB_TRANSLUCENT };
|
||||
|
||||
void InitMaterialSystem( const char *materialBaseDirPath, CreateInterfaceFn fileSystemFactory );
|
||||
void ShutdownMaterialSystem( );
|
||||
MaterialSystemMaterial_t FindMaterial( const char *materialName, bool *pFound, bool bComplain = true );
|
||||
void GetMaterialDimensions( MaterialSystemMaterial_t materialHandle, int *width, int *height );
|
||||
int GetMaterialShaderPropertyBool( MaterialSystemMaterial_t materialHandle, int propID );
|
||||
int GetMaterialShaderPropertyInt( MaterialSystemMaterial_t materialHandle, int propID );
|
||||
const char *GetMaterialVar( MaterialSystemMaterial_t materialHandle, const char *propertyName );
|
||||
void GetMaterialReflectivity( MaterialSystemMaterial_t materialHandle, float *reflectivityVect );
|
||||
const char *GetMaterialShaderName( MaterialSystemMaterial_t materialHandle );
|
||||
|
||||
|
||||
#endif // UTILMATLIB_H
|
||||
|
||||
@@ -1,374 +1,374 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
#include "vmpi.h"
|
||||
#include "cmdlib.h"
|
||||
#include "vmpi_tools_shared.h"
|
||||
#include "tier1/strtools.h"
|
||||
#include "mpi_stats.h"
|
||||
#include "iphelpers.h"
|
||||
#include "tier0/minidump.h"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// Globals.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
static bool g_bReceivedDirectoryInfo = false; // Have we gotten the qdir info yet?
|
||||
|
||||
static bool g_bReceivedDBInfo = false;
|
||||
static CDBInfo g_DBInfo;
|
||||
static unsigned long g_JobPrimaryID;
|
||||
|
||||
static int g_nDisconnects = 0; // Tracks how many remote processes have disconnected ungracefully.
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// Shared dispatch code.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
bool SharedDispatch( MessageBuffer *pBuf, int iSource, int iPacketID )
|
||||
{
|
||||
char *pInPos = &pBuf->data[2];
|
||||
|
||||
switch ( pBuf->data[1] )
|
||||
{
|
||||
case VMPI_SUBPACKETID_DIRECTORIES:
|
||||
{
|
||||
Q_strncpy( gamedir, pInPos, sizeof( gamedir ) );
|
||||
pInPos += strlen( pInPos ) + 1;
|
||||
|
||||
Q_strncpy( qdir, pInPos, sizeof( qdir ) );
|
||||
|
||||
g_bReceivedDirectoryInfo = true;
|
||||
}
|
||||
return true;
|
||||
|
||||
case VMPI_SUBPACKETID_DBINFO:
|
||||
{
|
||||
g_DBInfo = *((CDBInfo*)pInPos);
|
||||
pInPos += sizeof( CDBInfo );
|
||||
g_JobPrimaryID = *((unsigned long*)pInPos);
|
||||
|
||||
g_bReceivedDBInfo = true;
|
||||
}
|
||||
return true;
|
||||
|
||||
case VMPI_SUBPACKETID_CRASH:
|
||||
{
|
||||
char const chCrashInfoType = *pInPos;
|
||||
pInPos += 2;
|
||||
switch ( chCrashInfoType )
|
||||
{
|
||||
case 't':
|
||||
Warning( "\nWorker '%s' dead: %s\n", VMPI_GetMachineName( iSource ), pInPos );
|
||||
break;
|
||||
case 'f':
|
||||
{
|
||||
int iFileSize = * reinterpret_cast< int const * >( pInPos );
|
||||
pInPos += sizeof( iFileSize );
|
||||
|
||||
// Temp folder
|
||||
char const *szFolder = NULL;
|
||||
if ( !szFolder ) szFolder = getenv( "TEMP" );
|
||||
if ( !szFolder ) szFolder = getenv( "TMP" );
|
||||
if ( !szFolder ) szFolder = "c:";
|
||||
|
||||
// Base module name
|
||||
char chModuleName[_MAX_PATH], *pModuleName = chModuleName;
|
||||
::GetModuleFileName( NULL, chModuleName, sizeof( chModuleName ) / sizeof( chModuleName[0] ) );
|
||||
|
||||
if ( char *pch = strrchr( chModuleName, '.' ) )
|
||||
*pch = 0;
|
||||
if ( char *pch = strrchr( chModuleName, '\\' ) )
|
||||
*pch = 0, pModuleName = pch + 1;
|
||||
|
||||
// Current time
|
||||
time_t currTime = ::time( NULL );
|
||||
struct tm * pTime = ::localtime( &currTime );
|
||||
|
||||
// Number of minidumps this run
|
||||
static int s_numMiniDumps = 0;
|
||||
++ s_numMiniDumps;
|
||||
|
||||
// Prepare the filename
|
||||
char chSaveFileName[ 2 * _MAX_PATH ] = { 0 };
|
||||
sprintf( chSaveFileName, "%s\\vmpi_%s_on_%s_%d%.2d%2d%.2d%.2d%.2d_%d.mdmp",
|
||||
szFolder,
|
||||
pModuleName,
|
||||
VMPI_GetMachineName( iSource ),
|
||||
pTime->tm_year + 1900, /* Year less 2000 */
|
||||
pTime->tm_mon + 1, /* month (0 - 11 : 0 = January) */
|
||||
pTime->tm_mday, /* day of month (1 - 31) */
|
||||
pTime->tm_hour, /* hour (0 - 23) */
|
||||
pTime->tm_min, /* minutes (0 - 59) */
|
||||
pTime->tm_sec, /* seconds (0 - 59) */
|
||||
s_numMiniDumps
|
||||
);
|
||||
|
||||
if ( FILE *fDump = fopen( chSaveFileName, "wb" ) )
|
||||
{
|
||||
fwrite( pInPos, 1, iFileSize, fDump );
|
||||
fclose( fDump );
|
||||
|
||||
Warning( "\nSaved worker crash minidump '%s', size %d byte(s).\n",
|
||||
chSaveFileName, iFileSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "\nReceived worker crash minidump size %d byte(s), failed to save.\n", iFileSize );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CDispatchReg g_SharedDispatchReg( VMPI_SHARED_PACKET_ID, SharedDispatch );
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// Module interfaces.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
void SendQDirInfo()
|
||||
{
|
||||
char cPacketID[2] = { VMPI_SHARED_PACKET_ID, VMPI_SUBPACKETID_DIRECTORIES };
|
||||
|
||||
MessageBuffer mb;
|
||||
mb.write( cPacketID, 2 );
|
||||
mb.write( gamedir, strlen( gamedir ) + 1 );
|
||||
mb.write( qdir, strlen( qdir ) + 1 );
|
||||
|
||||
VMPI_SendData( mb.data, mb.getLen(), VMPI_PERSISTENT );
|
||||
}
|
||||
|
||||
|
||||
void RecvQDirInfo()
|
||||
{
|
||||
while ( !g_bReceivedDirectoryInfo )
|
||||
VMPI_DispatchNextMessage();
|
||||
}
|
||||
|
||||
|
||||
void SendDBInfo( const CDBInfo *pInfo, unsigned long jobPrimaryID )
|
||||
{
|
||||
char cPacketInfo[2] = { VMPI_SHARED_PACKET_ID, VMPI_SUBPACKETID_DBINFO };
|
||||
const void *pChunks[] = { cPacketInfo, pInfo, &jobPrimaryID };
|
||||
int chunkLengths[] = { 2, sizeof( CDBInfo ), sizeof( jobPrimaryID ) };
|
||||
|
||||
VMPI_SendChunks( pChunks, chunkLengths, ARRAYSIZE( pChunks ), VMPI_PERSISTENT );
|
||||
}
|
||||
|
||||
|
||||
void RecvDBInfo( CDBInfo *pInfo, unsigned long *pJobPrimaryID )
|
||||
{
|
||||
while ( !g_bReceivedDBInfo )
|
||||
VMPI_DispatchNextMessage();
|
||||
|
||||
*pInfo = g_DBInfo;
|
||||
*pJobPrimaryID = g_JobPrimaryID;
|
||||
}
|
||||
|
||||
// If the file is successfully opened, read and sent returns the size of the file in bytes
|
||||
// otherwise returns 0 and nothing is sent
|
||||
int VMPI_SendFileChunk( const void *pvChunkPrefix, int lenPrefix, tchar const *ptchFileName )
|
||||
{
|
||||
HANDLE hFile = NULL;
|
||||
HANDLE hMapping = NULL;
|
||||
void const *pvMappedData = NULL;
|
||||
int iResult = 0;
|
||||
|
||||
hFile = ::CreateFile( ptchFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
if ( !hFile || ( hFile == INVALID_HANDLE_VALUE ) )
|
||||
goto done;
|
||||
|
||||
hMapping = ::CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
|
||||
if ( !hMapping || ( hMapping == INVALID_HANDLE_VALUE ) )
|
||||
goto done;
|
||||
|
||||
pvMappedData = ::MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
|
||||
if ( !pvMappedData )
|
||||
goto done;
|
||||
|
||||
int iMappedFileSize = ::GetFileSize( hFile, NULL );
|
||||
if ( INVALID_FILE_SIZE == iMappedFileSize )
|
||||
goto done;
|
||||
|
||||
// Send the data over VMPI
|
||||
if ( VMPI_Send3Chunks(
|
||||
pvChunkPrefix, lenPrefix,
|
||||
&iMappedFileSize, sizeof( iMappedFileSize ),
|
||||
pvMappedData, iMappedFileSize,
|
||||
VMPI_MASTER_ID ) )
|
||||
iResult = iMappedFileSize;
|
||||
|
||||
// Fall-through for cleanup code to execute
|
||||
done:
|
||||
if ( pvMappedData )
|
||||
::UnmapViewOfFile( pvMappedData );
|
||||
|
||||
if ( hMapping && ( hMapping != INVALID_HANDLE_VALUE ) )
|
||||
::CloseHandle( hMapping );
|
||||
|
||||
if ( hFile && ( hFile != INVALID_HANDLE_VALUE ) )
|
||||
::CloseHandle( hFile );
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
void VMPI_HandleCrash( const char *pMessage, void *pvExceptionInfo, bool bAssert )
|
||||
{
|
||||
static LONG crashHandlerCount = 0;
|
||||
if ( InterlockedIncrement( &crashHandlerCount ) == 1 )
|
||||
{
|
||||
Msg( "\nFAILURE: '%s' (assert: %d)\n", pMessage, bAssert );
|
||||
|
||||
// Send a message to the master.
|
||||
char crashMsg[4] = { VMPI_SHARED_PACKET_ID, VMPI_SUBPACKETID_CRASH, 't', ':' };
|
||||
|
||||
VMPI_Send2Chunks(
|
||||
crashMsg,
|
||||
sizeof( crashMsg ),
|
||||
pMessage,
|
||||
strlen( pMessage ) + 1,
|
||||
VMPI_MASTER_ID );
|
||||
|
||||
// Now attempt to create a minidump with the given exception information
|
||||
if ( pvExceptionInfo )
|
||||
{
|
||||
struct _EXCEPTION_POINTERS *pvExPointers = ( struct _EXCEPTION_POINTERS * ) pvExceptionInfo;
|
||||
tchar tchMinidumpFileName[_MAX_PATH] = { 0 };
|
||||
bool bSucceededWritingMinidump = WriteMiniDumpUsingExceptionInfo(
|
||||
pvExPointers->ExceptionRecord->ExceptionCode,
|
||||
pvExPointers,
|
||||
( MINIDUMP_TYPE )( MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory | MiniDumpWithProcessThreadData ),
|
||||
// ( MINIDUMP_TYPE )( MiniDumpWithDataSegs | MiniDumpWithFullMemory | MiniDumpWithHandleData | MiniDumpWithUnloadedModules | MiniDumpWithIndirectlyReferencedMemory | MiniDumpWithProcessThreadData | MiniDumpWithPrivateReadWriteMemory ),
|
||||
// ( MINIDUMP_TYPE )( MiniDumpNormal ),
|
||||
tchMinidumpFileName );
|
||||
if ( bSucceededWritingMinidump )
|
||||
{
|
||||
crashMsg[2] = 'f';
|
||||
VMPI_SendFileChunk( crashMsg, sizeof( crashMsg ), tchMinidumpFileName );
|
||||
::DeleteFile( tchMinidumpFileName );
|
||||
}
|
||||
}
|
||||
|
||||
// Let the messages go out.
|
||||
Sleep( 500 );
|
||||
}
|
||||
|
||||
InterlockedDecrement( &crashHandlerCount );
|
||||
}
|
||||
|
||||
|
||||
// This is called if we crash inside our crash handler. It just terminates the process immediately.
|
||||
LONG __stdcall VMPI_SecondExceptionFilter( struct _EXCEPTION_POINTERS *ExceptionInfo )
|
||||
{
|
||||
TerminateProcess( GetCurrentProcess(), 2 );
|
||||
return EXCEPTION_EXECUTE_HANDLER; // (never gets here anyway)
|
||||
}
|
||||
|
||||
|
||||
void VMPI_ExceptionFilter( unsigned long uCode, void *pvExceptionInfo )
|
||||
{
|
||||
// This is called if we crash inside our crash handler. It just terminates the process immediately.
|
||||
SetUnhandledExceptionFilter( VMPI_SecondExceptionFilter );
|
||||
|
||||
//DWORD code = ExceptionInfo->ExceptionRecord->ExceptionCode;
|
||||
|
||||
#define ERR_RECORD( name ) { name, #name }
|
||||
struct
|
||||
{
|
||||
int code;
|
||||
char *pReason;
|
||||
} errors[] =
|
||||
{
|
||||
ERR_RECORD( EXCEPTION_ACCESS_VIOLATION ),
|
||||
ERR_RECORD( EXCEPTION_ARRAY_BOUNDS_EXCEEDED ),
|
||||
ERR_RECORD( EXCEPTION_BREAKPOINT ),
|
||||
ERR_RECORD( EXCEPTION_DATATYPE_MISALIGNMENT ),
|
||||
ERR_RECORD( EXCEPTION_FLT_DENORMAL_OPERAND ),
|
||||
ERR_RECORD( EXCEPTION_FLT_DIVIDE_BY_ZERO ),
|
||||
ERR_RECORD( EXCEPTION_FLT_INEXACT_RESULT ),
|
||||
ERR_RECORD( EXCEPTION_FLT_INVALID_OPERATION ),
|
||||
ERR_RECORD( EXCEPTION_FLT_OVERFLOW ),
|
||||
ERR_RECORD( EXCEPTION_FLT_STACK_CHECK ),
|
||||
ERR_RECORD( EXCEPTION_FLT_UNDERFLOW ),
|
||||
ERR_RECORD( EXCEPTION_ILLEGAL_INSTRUCTION ),
|
||||
ERR_RECORD( EXCEPTION_IN_PAGE_ERROR ),
|
||||
ERR_RECORD( EXCEPTION_INT_DIVIDE_BY_ZERO ),
|
||||
ERR_RECORD( EXCEPTION_INT_OVERFLOW ),
|
||||
ERR_RECORD( EXCEPTION_INVALID_DISPOSITION ),
|
||||
ERR_RECORD( EXCEPTION_NONCONTINUABLE_EXCEPTION ),
|
||||
ERR_RECORD( EXCEPTION_PRIV_INSTRUCTION ),
|
||||
ERR_RECORD( EXCEPTION_SINGLE_STEP ),
|
||||
ERR_RECORD( EXCEPTION_STACK_OVERFLOW ),
|
||||
ERR_RECORD( EXCEPTION_ACCESS_VIOLATION ),
|
||||
};
|
||||
|
||||
int nErrors = sizeof( errors ) / sizeof( errors[0] );
|
||||
int i=0;
|
||||
char *pchReason = NULL;
|
||||
char chUnknownBuffer[32];
|
||||
for ( i; ( i < nErrors ) && !pchReason; i++ )
|
||||
{
|
||||
if ( errors[i].code == uCode )
|
||||
pchReason = errors[i].pReason;
|
||||
}
|
||||
|
||||
if ( i == nErrors )
|
||||
{
|
||||
sprintf( chUnknownBuffer, "Error code 0x%08X", uCode );
|
||||
pchReason = chUnknownBuffer;
|
||||
}
|
||||
|
||||
VMPI_HandleCrash( pchReason, pvExceptionInfo, true );
|
||||
|
||||
TerminateProcess( GetCurrentProcess(), 1 );
|
||||
}
|
||||
|
||||
|
||||
void HandleMPIDisconnect( int procID, const char *pReason )
|
||||
{
|
||||
int nLiveWorkers = VMPI_GetCurrentNumberOfConnections() - g_nDisconnects - 1;
|
||||
|
||||
// We ran into the size limit before and it wasn't readily apparent that the size limit had
|
||||
// been breached, so make sure to show errors about invalid packet sizes..
|
||||
bool bOldSuppress = g_bSuppressPrintfOutput;
|
||||
g_bSuppressPrintfOutput = ( Q_stristr( pReason, "invalid packet size" ) == 0 );
|
||||
|
||||
Warning( "\n\n--- WARNING: lost connection to '%s' (%s).\n", VMPI_GetMachineName( procID ), pReason );
|
||||
|
||||
if ( g_bMPIMaster )
|
||||
{
|
||||
Warning( "%d workers remain.\n\n", nLiveWorkers );
|
||||
|
||||
++g_nDisconnects;
|
||||
/*
|
||||
if ( VMPI_GetCurrentNumberOfConnections() - g_nDisconnects <= 1 )
|
||||
{
|
||||
Error( "All machines disconnected!" );
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
VMPI_HandleAutoRestart();
|
||||
Error( "Worker quitting." );
|
||||
}
|
||||
|
||||
g_bSuppressPrintfOutput = bOldSuppress;
|
||||
}
|
||||
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
#include "vmpi.h"
|
||||
#include "cmdlib.h"
|
||||
#include "vmpi_tools_shared.h"
|
||||
#include "tier1/strtools.h"
|
||||
#include "mpi_stats.h"
|
||||
#include "iphelpers.h"
|
||||
#include "tier0/minidump.h"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// Globals.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
static bool g_bReceivedDirectoryInfo = false; // Have we gotten the qdir info yet?
|
||||
|
||||
static bool g_bReceivedDBInfo = false;
|
||||
static CDBInfo g_DBInfo;
|
||||
static unsigned long g_JobPrimaryID;
|
||||
|
||||
static int g_nDisconnects = 0; // Tracks how many remote processes have disconnected ungracefully.
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// Shared dispatch code.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
bool SharedDispatch( MessageBuffer *pBuf, int iSource, int iPacketID )
|
||||
{
|
||||
char *pInPos = &pBuf->data[2];
|
||||
|
||||
switch ( pBuf->data[1] )
|
||||
{
|
||||
case VMPI_SUBPACKETID_DIRECTORIES:
|
||||
{
|
||||
Q_strncpy( gamedir, pInPos, sizeof( gamedir ) );
|
||||
pInPos += strlen( pInPos ) + 1;
|
||||
|
||||
Q_strncpy( qdir, pInPos, sizeof( qdir ) );
|
||||
|
||||
g_bReceivedDirectoryInfo = true;
|
||||
}
|
||||
return true;
|
||||
|
||||
case VMPI_SUBPACKETID_DBINFO:
|
||||
{
|
||||
g_DBInfo = *((CDBInfo*)pInPos);
|
||||
pInPos += sizeof( CDBInfo );
|
||||
g_JobPrimaryID = *((unsigned long*)pInPos);
|
||||
|
||||
g_bReceivedDBInfo = true;
|
||||
}
|
||||
return true;
|
||||
|
||||
case VMPI_SUBPACKETID_CRASH:
|
||||
{
|
||||
char const chCrashInfoType = *pInPos;
|
||||
pInPos += 2;
|
||||
switch ( chCrashInfoType )
|
||||
{
|
||||
case 't':
|
||||
Warning( "\nWorker '%s' dead: %s\n", VMPI_GetMachineName( iSource ), pInPos );
|
||||
break;
|
||||
case 'f':
|
||||
{
|
||||
int iFileSize = * reinterpret_cast< int const * >( pInPos );
|
||||
pInPos += sizeof( iFileSize );
|
||||
|
||||
// Temp folder
|
||||
char const *szFolder = NULL;
|
||||
if ( !szFolder ) szFolder = getenv( "TEMP" );
|
||||
if ( !szFolder ) szFolder = getenv( "TMP" );
|
||||
if ( !szFolder ) szFolder = "c:";
|
||||
|
||||
// Base module name
|
||||
char chModuleName[_MAX_PATH], *pModuleName = chModuleName;
|
||||
::GetModuleFileName( NULL, chModuleName, sizeof( chModuleName ) / sizeof( chModuleName[0] ) );
|
||||
|
||||
if ( char *pch = strrchr( chModuleName, '.' ) )
|
||||
*pch = 0;
|
||||
if ( char *pch = strrchr( chModuleName, '\\' ) )
|
||||
*pch = 0, pModuleName = pch + 1;
|
||||
|
||||
// Current time
|
||||
time_t currTime = ::time( NULL );
|
||||
struct tm * pTime = ::localtime( &currTime );
|
||||
|
||||
// Number of minidumps this run
|
||||
static int s_numMiniDumps = 0;
|
||||
++ s_numMiniDumps;
|
||||
|
||||
// Prepare the filename
|
||||
char chSaveFileName[ 2 * _MAX_PATH ] = { 0 };
|
||||
sprintf( chSaveFileName, "%s\\vmpi_%s_on_%s_%d%.2d%2d%.2d%.2d%.2d_%d.mdmp",
|
||||
szFolder,
|
||||
pModuleName,
|
||||
VMPI_GetMachineName( iSource ),
|
||||
pTime->tm_year + 1900, /* Year less 2000 */
|
||||
pTime->tm_mon + 1, /* month (0 - 11 : 0 = January) */
|
||||
pTime->tm_mday, /* day of month (1 - 31) */
|
||||
pTime->tm_hour, /* hour (0 - 23) */
|
||||
pTime->tm_min, /* minutes (0 - 59) */
|
||||
pTime->tm_sec, /* seconds (0 - 59) */
|
||||
s_numMiniDumps
|
||||
);
|
||||
|
||||
if ( FILE *fDump = fopen( chSaveFileName, "wb" ) )
|
||||
{
|
||||
fwrite( pInPos, 1, iFileSize, fDump );
|
||||
fclose( fDump );
|
||||
|
||||
Warning( "\nSaved worker crash minidump '%s', size %d byte(s).\n",
|
||||
chSaveFileName, iFileSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "\nReceived worker crash minidump size %d byte(s), failed to save.\n", iFileSize );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CDispatchReg g_SharedDispatchReg( VMPI_SHARED_PACKET_ID, SharedDispatch );
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// Module interfaces.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
void SendQDirInfo()
|
||||
{
|
||||
char cPacketID[2] = { VMPI_SHARED_PACKET_ID, VMPI_SUBPACKETID_DIRECTORIES };
|
||||
|
||||
MessageBuffer mb;
|
||||
mb.write( cPacketID, 2 );
|
||||
mb.write( gamedir, strlen( gamedir ) + 1 );
|
||||
mb.write( qdir, strlen( qdir ) + 1 );
|
||||
|
||||
VMPI_SendData( mb.data, mb.getLen(), VMPI_PERSISTENT );
|
||||
}
|
||||
|
||||
|
||||
void RecvQDirInfo()
|
||||
{
|
||||
while ( !g_bReceivedDirectoryInfo )
|
||||
VMPI_DispatchNextMessage();
|
||||
}
|
||||
|
||||
|
||||
void SendDBInfo( const CDBInfo *pInfo, unsigned long jobPrimaryID )
|
||||
{
|
||||
char cPacketInfo[2] = { VMPI_SHARED_PACKET_ID, VMPI_SUBPACKETID_DBINFO };
|
||||
const void *pChunks[] = { cPacketInfo, pInfo, &jobPrimaryID };
|
||||
int chunkLengths[] = { 2, sizeof( CDBInfo ), sizeof( jobPrimaryID ) };
|
||||
|
||||
VMPI_SendChunks( pChunks, chunkLengths, ARRAYSIZE( pChunks ), VMPI_PERSISTENT );
|
||||
}
|
||||
|
||||
|
||||
void RecvDBInfo( CDBInfo *pInfo, unsigned long *pJobPrimaryID )
|
||||
{
|
||||
while ( !g_bReceivedDBInfo )
|
||||
VMPI_DispatchNextMessage();
|
||||
|
||||
*pInfo = g_DBInfo;
|
||||
*pJobPrimaryID = g_JobPrimaryID;
|
||||
}
|
||||
|
||||
// If the file is successfully opened, read and sent returns the size of the file in bytes
|
||||
// otherwise returns 0 and nothing is sent
|
||||
int VMPI_SendFileChunk( const void *pvChunkPrefix, int lenPrefix, tchar const *ptchFileName )
|
||||
{
|
||||
HANDLE hFile = NULL;
|
||||
HANDLE hMapping = NULL;
|
||||
void const *pvMappedData = NULL;
|
||||
int iResult = 0;
|
||||
|
||||
hFile = ::CreateFile( ptchFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
if ( !hFile || ( hFile == INVALID_HANDLE_VALUE ) )
|
||||
goto done;
|
||||
|
||||
hMapping = ::CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
|
||||
if ( !hMapping || ( hMapping == INVALID_HANDLE_VALUE ) )
|
||||
goto done;
|
||||
|
||||
pvMappedData = ::MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
|
||||
if ( !pvMappedData )
|
||||
goto done;
|
||||
|
||||
int iMappedFileSize = ::GetFileSize( hFile, NULL );
|
||||
if ( INVALID_FILE_SIZE == iMappedFileSize )
|
||||
goto done;
|
||||
|
||||
// Send the data over VMPI
|
||||
if ( VMPI_Send3Chunks(
|
||||
pvChunkPrefix, lenPrefix,
|
||||
&iMappedFileSize, sizeof( iMappedFileSize ),
|
||||
pvMappedData, iMappedFileSize,
|
||||
VMPI_MASTER_ID ) )
|
||||
iResult = iMappedFileSize;
|
||||
|
||||
// Fall-through for cleanup code to execute
|
||||
done:
|
||||
if ( pvMappedData )
|
||||
::UnmapViewOfFile( pvMappedData );
|
||||
|
||||
if ( hMapping && ( hMapping != INVALID_HANDLE_VALUE ) )
|
||||
::CloseHandle( hMapping );
|
||||
|
||||
if ( hFile && ( hFile != INVALID_HANDLE_VALUE ) )
|
||||
::CloseHandle( hFile );
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
void VMPI_HandleCrash( const char *pMessage, void *pvExceptionInfo, bool bAssert )
|
||||
{
|
||||
static LONG crashHandlerCount = 0;
|
||||
if ( InterlockedIncrement( &crashHandlerCount ) == 1 )
|
||||
{
|
||||
Msg( "\nFAILURE: '%s' (assert: %d)\n", pMessage, bAssert );
|
||||
|
||||
// Send a message to the master.
|
||||
char crashMsg[4] = { VMPI_SHARED_PACKET_ID, VMPI_SUBPACKETID_CRASH, 't', ':' };
|
||||
|
||||
VMPI_Send2Chunks(
|
||||
crashMsg,
|
||||
sizeof( crashMsg ),
|
||||
pMessage,
|
||||
strlen( pMessage ) + 1,
|
||||
VMPI_MASTER_ID );
|
||||
|
||||
// Now attempt to create a minidump with the given exception information
|
||||
if ( pvExceptionInfo )
|
||||
{
|
||||
struct _EXCEPTION_POINTERS *pvExPointers = ( struct _EXCEPTION_POINTERS * ) pvExceptionInfo;
|
||||
tchar tchMinidumpFileName[_MAX_PATH] = { 0 };
|
||||
bool bSucceededWritingMinidump = WriteMiniDumpUsingExceptionInfo(
|
||||
pvExPointers->ExceptionRecord->ExceptionCode,
|
||||
pvExPointers,
|
||||
( MINIDUMP_TYPE )( MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory | MiniDumpWithProcessThreadData ),
|
||||
// ( MINIDUMP_TYPE )( MiniDumpWithDataSegs | MiniDumpWithFullMemory | MiniDumpWithHandleData | MiniDumpWithUnloadedModules | MiniDumpWithIndirectlyReferencedMemory | MiniDumpWithProcessThreadData | MiniDumpWithPrivateReadWriteMemory ),
|
||||
// ( MINIDUMP_TYPE )( MiniDumpNormal ),
|
||||
tchMinidumpFileName );
|
||||
if ( bSucceededWritingMinidump )
|
||||
{
|
||||
crashMsg[2] = 'f';
|
||||
VMPI_SendFileChunk( crashMsg, sizeof( crashMsg ), tchMinidumpFileName );
|
||||
::DeleteFile( tchMinidumpFileName );
|
||||
}
|
||||
}
|
||||
|
||||
// Let the messages go out.
|
||||
Sleep( 500 );
|
||||
}
|
||||
|
||||
InterlockedDecrement( &crashHandlerCount );
|
||||
}
|
||||
|
||||
|
||||
// This is called if we crash inside our crash handler. It just terminates the process immediately.
|
||||
LONG __stdcall VMPI_SecondExceptionFilter( struct _EXCEPTION_POINTERS *ExceptionInfo )
|
||||
{
|
||||
TerminateProcess( GetCurrentProcess(), 2 );
|
||||
return EXCEPTION_EXECUTE_HANDLER; // (never gets here anyway)
|
||||
}
|
||||
|
||||
|
||||
void VMPI_ExceptionFilter( unsigned long uCode, void *pvExceptionInfo )
|
||||
{
|
||||
// This is called if we crash inside our crash handler. It just terminates the process immediately.
|
||||
SetUnhandledExceptionFilter( VMPI_SecondExceptionFilter );
|
||||
|
||||
//DWORD code = ExceptionInfo->ExceptionRecord->ExceptionCode;
|
||||
|
||||
#define ERR_RECORD( name ) { name, #name }
|
||||
struct
|
||||
{
|
||||
int code;
|
||||
char *pReason;
|
||||
} errors[] =
|
||||
{
|
||||
ERR_RECORD( EXCEPTION_ACCESS_VIOLATION ),
|
||||
ERR_RECORD( EXCEPTION_ARRAY_BOUNDS_EXCEEDED ),
|
||||
ERR_RECORD( EXCEPTION_BREAKPOINT ),
|
||||
ERR_RECORD( EXCEPTION_DATATYPE_MISALIGNMENT ),
|
||||
ERR_RECORD( EXCEPTION_FLT_DENORMAL_OPERAND ),
|
||||
ERR_RECORD( EXCEPTION_FLT_DIVIDE_BY_ZERO ),
|
||||
ERR_RECORD( EXCEPTION_FLT_INEXACT_RESULT ),
|
||||
ERR_RECORD( EXCEPTION_FLT_INVALID_OPERATION ),
|
||||
ERR_RECORD( EXCEPTION_FLT_OVERFLOW ),
|
||||
ERR_RECORD( EXCEPTION_FLT_STACK_CHECK ),
|
||||
ERR_RECORD( EXCEPTION_FLT_UNDERFLOW ),
|
||||
ERR_RECORD( EXCEPTION_ILLEGAL_INSTRUCTION ),
|
||||
ERR_RECORD( EXCEPTION_IN_PAGE_ERROR ),
|
||||
ERR_RECORD( EXCEPTION_INT_DIVIDE_BY_ZERO ),
|
||||
ERR_RECORD( EXCEPTION_INT_OVERFLOW ),
|
||||
ERR_RECORD( EXCEPTION_INVALID_DISPOSITION ),
|
||||
ERR_RECORD( EXCEPTION_NONCONTINUABLE_EXCEPTION ),
|
||||
ERR_RECORD( EXCEPTION_PRIV_INSTRUCTION ),
|
||||
ERR_RECORD( EXCEPTION_SINGLE_STEP ),
|
||||
ERR_RECORD( EXCEPTION_STACK_OVERFLOW ),
|
||||
ERR_RECORD( EXCEPTION_ACCESS_VIOLATION ),
|
||||
};
|
||||
|
||||
int nErrors = sizeof( errors ) / sizeof( errors[0] );
|
||||
int i=0;
|
||||
char *pchReason = NULL;
|
||||
char chUnknownBuffer[32];
|
||||
for ( i; ( i < nErrors ) && !pchReason; i++ )
|
||||
{
|
||||
if ( errors[i].code == uCode )
|
||||
pchReason = errors[i].pReason;
|
||||
}
|
||||
|
||||
if ( i == nErrors )
|
||||
{
|
||||
sprintf( chUnknownBuffer, "Error code 0x%08X", uCode );
|
||||
pchReason = chUnknownBuffer;
|
||||
}
|
||||
|
||||
VMPI_HandleCrash( pchReason, pvExceptionInfo, true );
|
||||
|
||||
TerminateProcess( GetCurrentProcess(), 1 );
|
||||
}
|
||||
|
||||
|
||||
void HandleMPIDisconnect( int procID, const char *pReason )
|
||||
{
|
||||
int nLiveWorkers = VMPI_GetCurrentNumberOfConnections() - g_nDisconnects - 1;
|
||||
|
||||
// We ran into the size limit before and it wasn't readily apparent that the size limit had
|
||||
// been breached, so make sure to show errors about invalid packet sizes..
|
||||
bool bOldSuppress = g_bSuppressPrintfOutput;
|
||||
g_bSuppressPrintfOutput = ( Q_stristr( pReason, "invalid packet size" ) == 0 );
|
||||
|
||||
Warning( "\n\n--- WARNING: lost connection to '%s' (%s).\n", VMPI_GetMachineName( procID ), pReason );
|
||||
|
||||
if ( g_bMPIMaster )
|
||||
{
|
||||
Warning( "%d workers remain.\n\n", nLiveWorkers );
|
||||
|
||||
++g_nDisconnects;
|
||||
/*
|
||||
if ( VMPI_GetCurrentNumberOfConnections() - g_nDisconnects <= 1 )
|
||||
{
|
||||
Error( "All machines disconnected!" );
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
VMPI_HandleAutoRestart();
|
||||
Error( "Worker quitting." );
|
||||
}
|
||||
|
||||
g_bSuppressPrintfOutput = bOldSuppress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VMPI_TOOLS_SHARED_H
|
||||
#define VMPI_TOOLS_SHARED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// Packet IDs.
|
||||
#define VMPI_SUBPACKETID_DIRECTORIES 0 // qdir directories.
|
||||
#define VMPI_SUBPACKETID_DBINFO 1 // MySQL database info.
|
||||
#define VMPI_SUBPACKETID_CRASH 3 // A worker saying it crashed.
|
||||
#define VMPI_SUBPACKETID_MULTICAST_ADDR 4 // Filesystem multicast address.
|
||||
|
||||
|
||||
class CDBInfo;
|
||||
class CIPAddr;
|
||||
|
||||
|
||||
// Send/receive the qdir info.
|
||||
void SendQDirInfo();
|
||||
void RecvQDirInfo();
|
||||
|
||||
void SendDBInfo( const CDBInfo *pInfo, unsigned long jobPrimaryID );
|
||||
void RecvDBInfo( CDBInfo *pInfo, unsigned long *pJobPrimaryID );
|
||||
|
||||
void SendMulticastIP( const CIPAddr *pAddr );
|
||||
void RecvMulticastIP( CIPAddr *pAddr );
|
||||
|
||||
void VMPI_HandleCrash( const char *pMessage, void *pvExceptionInfo, bool bAssert );
|
||||
|
||||
// Call this from an exception handler (set by SetUnhandledExceptionHandler).
|
||||
// uCode = ExceptionInfo->ExceptionRecord->ExceptionCode.
|
||||
// pvExceptionInfo = ExceptionInfo
|
||||
void VMPI_ExceptionFilter( unsigned long uCode, void *pvExceptionInfo );
|
||||
|
||||
void HandleMPIDisconnect( int procID, const char *pReason );
|
||||
|
||||
|
||||
#endif // VMPI_TOOLS_SHARED_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VMPI_TOOLS_SHARED_H
|
||||
#define VMPI_TOOLS_SHARED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// Packet IDs.
|
||||
#define VMPI_SUBPACKETID_DIRECTORIES 0 // qdir directories.
|
||||
#define VMPI_SUBPACKETID_DBINFO 1 // MySQL database info.
|
||||
#define VMPI_SUBPACKETID_CRASH 3 // A worker saying it crashed.
|
||||
#define VMPI_SUBPACKETID_MULTICAST_ADDR 4 // Filesystem multicast address.
|
||||
|
||||
|
||||
class CDBInfo;
|
||||
class CIPAddr;
|
||||
|
||||
|
||||
// Send/receive the qdir info.
|
||||
void SendQDirInfo();
|
||||
void RecvQDirInfo();
|
||||
|
||||
void SendDBInfo( const CDBInfo *pInfo, unsigned long jobPrimaryID );
|
||||
void RecvDBInfo( CDBInfo *pInfo, unsigned long *pJobPrimaryID );
|
||||
|
||||
void SendMulticastIP( const CIPAddr *pAddr );
|
||||
void RecvMulticastIP( CIPAddr *pAddr );
|
||||
|
||||
void VMPI_HandleCrash( const char *pMessage, void *pvExceptionInfo, bool bAssert );
|
||||
|
||||
// Call this from an exception handler (set by SetUnhandledExceptionHandler).
|
||||
// uCode = ExceptionInfo->ExceptionRecord->ExceptionCode.
|
||||
// pvExceptionInfo = ExceptionInfo
|
||||
void VMPI_ExceptionFilter( unsigned long uCode, void *pvExceptionInfo );
|
||||
|
||||
void HandleMPIDisconnect( int procID, const char *pReason );
|
||||
|
||||
|
||||
#endif // VMPI_TOOLS_SHARED_H
|
||||
|
||||
@@ -1,334 +1,334 @@
|
||||
//========= Copyright © 1996-2005, Valve LLC, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
// wad2lib.c
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
//#include <sys/file.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef NeXT
|
||||
#include <libc.h>
|
||||
#endif
|
||||
#include "cmdlib.h"
|
||||
#include "wadlib.h"
|
||||
#include "commonmacros.h"
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
WAD READING
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
lumpinfo_t *lumpinfo; // location of each lump on disk
|
||||
int numlumps;
|
||||
|
||||
wadinfo_t header;
|
||||
FILE *wadhandle;
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_OpenWad
|
||||
====================
|
||||
*/
|
||||
void W_OpenWad (char *filename)
|
||||
{
|
||||
lumpinfo_t *lump_p;
|
||||
unsigned i;
|
||||
int length;
|
||||
|
||||
//
|
||||
// open the file and add to directory
|
||||
//
|
||||
wadhandle = SafeOpenRead (filename);
|
||||
SafeRead (wadhandle, &header, sizeof(header));
|
||||
|
||||
if (!STRING_MATCHES_ID(header.identification,WAD_ID))
|
||||
Error ("Wad file %s doesn't have %s identifier\n",filename, WAD_IDNAME);
|
||||
|
||||
header.numlumps = LittleLong(header.numlumps);
|
||||
header.infotableofs = LittleLong(header.infotableofs);
|
||||
|
||||
numlumps = header.numlumps;
|
||||
|
||||
length = numlumps*sizeof(lumpinfo_t);
|
||||
lumpinfo = malloc (length);
|
||||
lump_p = lumpinfo;
|
||||
|
||||
fseek (wadhandle, header.infotableofs, SEEK_SET);
|
||||
SafeRead (wadhandle, lumpinfo, length);
|
||||
|
||||
//
|
||||
// Fill in lumpinfo
|
||||
//
|
||||
|
||||
for (i=0 ; i<numlumps ; i++,lump_p++)
|
||||
{
|
||||
lump_p->filepos = LittleLong(lump_p->filepos);
|
||||
lump_p->size = LittleLong(lump_p->size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CleanupName (char *in, char *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<sizeof( ((lumpinfo_t *)0)->name ) ; i++ )
|
||||
{
|
||||
if (!in[i])
|
||||
break;
|
||||
|
||||
out[i] = toupper(in[i]);
|
||||
}
|
||||
|
||||
for ( ; i<sizeof( ((lumpinfo_t *)0)->name ); i++ )
|
||||
out[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_CheckNumForName
|
||||
|
||||
Returns -1 if name not found
|
||||
====================
|
||||
*/
|
||||
int W_CheckNumForName (char *name)
|
||||
{
|
||||
char cleanname[TEXTURE_NAME_LENGTH];
|
||||
int v1,v2, v3, v4;
|
||||
int i;
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
CleanupName (name, cleanname);
|
||||
|
||||
// make the name into four integers for easy compares
|
||||
|
||||
v1 = *(int *)cleanname;
|
||||
v2 = *(int *)&cleanname[4];
|
||||
v3 = *(int *)&cleanname[8];
|
||||
v4 = *(int *)&cleanname[12];
|
||||
|
||||
// find it
|
||||
|
||||
lump_p = lumpinfo;
|
||||
for (i=0 ; i<numlumps ; i++, lump_p++)
|
||||
{
|
||||
if ( *(int *)lump_p->name == v1
|
||||
&& *(int *)&lump_p->name[4] == v2
|
||||
&& *(int *)&lump_p->name[8] == v3
|
||||
&& *(int *)&lump_p->name[12] == v4
|
||||
&& !strcmp( lump_p->name, cleanname ) )
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_GetNumForName
|
||||
|
||||
Calls W_CheckNumForName, but bombs out if not found
|
||||
====================
|
||||
*/
|
||||
int W_GetNumForName (char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = W_CheckNumForName (name);
|
||||
if (i != -1)
|
||||
return i;
|
||||
|
||||
Error ("W_GetNumForName: %s not found!",name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_LumpLength
|
||||
|
||||
Returns the buffer size needed to load the given lump
|
||||
====================
|
||||
*/
|
||||
int W_LumpLength (int lump)
|
||||
{
|
||||
if (lump >= numlumps)
|
||||
Error ("W_LumpLength: %i >= numlumps",lump);
|
||||
return lumpinfo[lump].size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_ReadLumpNum
|
||||
|
||||
Loads the lump into the given buffer, which must be >= W_LumpLength()
|
||||
====================
|
||||
*/
|
||||
void W_ReadLumpNum (int lump, void *dest)
|
||||
{
|
||||
lumpinfo_t *l;
|
||||
|
||||
if (lump >= numlumps)
|
||||
Error ("W_ReadLump: %i >= numlumps",lump);
|
||||
l = lumpinfo+lump;
|
||||
|
||||
fseek (wadhandle, l->filepos, SEEK_SET);
|
||||
SafeRead (wadhandle, dest, l->size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_LoadLumpNum
|
||||
====================
|
||||
*/
|
||||
void *W_LoadLumpNum (int lump)
|
||||
{
|
||||
void *buf;
|
||||
|
||||
if ((unsigned)lump >= numlumps)
|
||||
Error ("W_CacheLumpNum: %i >= numlumps",lump);
|
||||
|
||||
buf = malloc (W_LumpLength (lump));
|
||||
W_ReadLumpNum (lump, buf);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_LoadLumpName
|
||||
====================
|
||||
*/
|
||||
void *W_LoadLumpName (char *name)
|
||||
{
|
||||
return W_LoadLumpNum (W_GetNumForName(name));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
WAD CREATION
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
FILE *outwad;
|
||||
|
||||
lumpinfo_t outinfo[4096];
|
||||
int outlumps;
|
||||
|
||||
short (*wadshort) (short l);
|
||||
int (*wadlong) (int l);
|
||||
|
||||
/*
|
||||
===============
|
||||
NewWad
|
||||
===============
|
||||
*/
|
||||
|
||||
void NewWad (char *pathname, qboolean bigendien)
|
||||
{
|
||||
outwad = SafeOpenWrite (pathname);
|
||||
fseek (outwad, sizeof(wadinfo_t), SEEK_SET);
|
||||
memset (outinfo, 0, sizeof(outinfo));
|
||||
|
||||
if (bigendien)
|
||||
{
|
||||
wadshort = BigShort;
|
||||
wadlong = BigLong;
|
||||
}
|
||||
else
|
||||
{
|
||||
wadshort = LittleShort;
|
||||
wadlong = LittleLong;
|
||||
}
|
||||
|
||||
outlumps = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
AddLump
|
||||
===============
|
||||
*/
|
||||
|
||||
void AddLump (char *name, void *buffer, int length, int type, int compress)
|
||||
{
|
||||
lumpinfo_t *info;
|
||||
int ofs;
|
||||
|
||||
info = &outinfo[outlumps];
|
||||
outlumps++;
|
||||
|
||||
memset (info,0,sizeof(info));
|
||||
|
||||
strcpy (info->name, name);
|
||||
Q_strupr (info->name);
|
||||
|
||||
ofs = ftell(outwad);
|
||||
info->filepos = wadlong(ofs);
|
||||
info->size = info->disksize = wadlong(length);
|
||||
info->type = type;
|
||||
info->compression = compress;
|
||||
|
||||
// FIXME: do compression
|
||||
|
||||
SafeWrite (outwad, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
WriteWad
|
||||
===============
|
||||
*/
|
||||
|
||||
void WriteWad (int wad3)
|
||||
{
|
||||
wadinfo_t header;
|
||||
int ofs;
|
||||
|
||||
// write the lumpingo
|
||||
ofs = ftell(outwad);
|
||||
|
||||
SafeWrite (outwad, outinfo, outlumps*sizeof(lumpinfo_t) );
|
||||
|
||||
// write the header
|
||||
|
||||
// a program will be able to tell the ednieness of a wad by the id
|
||||
ID_TO_STRING( WAD_ID, header.identification );
|
||||
|
||||
header.numlumps = wadlong(outlumps);
|
||||
header.infotableofs = wadlong(ofs);
|
||||
|
||||
fseek (outwad, 0, SEEK_SET);
|
||||
SafeWrite (outwad, &header, sizeof(header));
|
||||
fclose (outwad);
|
||||
}
|
||||
|
||||
|
||||
//========= Copyright © 1996-2005, Valve LLC, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
// wad2lib.c
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
//#include <sys/file.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef NeXT
|
||||
#include <libc.h>
|
||||
#endif
|
||||
#include "cmdlib.h"
|
||||
#include "wadlib.h"
|
||||
#include "commonmacros.h"
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
WAD READING
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
lumpinfo_t *lumpinfo; // location of each lump on disk
|
||||
int numlumps;
|
||||
|
||||
wadinfo_t header;
|
||||
FILE *wadhandle;
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_OpenWad
|
||||
====================
|
||||
*/
|
||||
void W_OpenWad (char *filename)
|
||||
{
|
||||
lumpinfo_t *lump_p;
|
||||
unsigned i;
|
||||
int length;
|
||||
|
||||
//
|
||||
// open the file and add to directory
|
||||
//
|
||||
wadhandle = SafeOpenRead (filename);
|
||||
SafeRead (wadhandle, &header, sizeof(header));
|
||||
|
||||
if (!STRING_MATCHES_ID(header.identification,WAD_ID))
|
||||
Error ("Wad file %s doesn't have %s identifier\n",filename, WAD_IDNAME);
|
||||
|
||||
header.numlumps = LittleLong(header.numlumps);
|
||||
header.infotableofs = LittleLong(header.infotableofs);
|
||||
|
||||
numlumps = header.numlumps;
|
||||
|
||||
length = numlumps*sizeof(lumpinfo_t);
|
||||
lumpinfo = malloc (length);
|
||||
lump_p = lumpinfo;
|
||||
|
||||
fseek (wadhandle, header.infotableofs, SEEK_SET);
|
||||
SafeRead (wadhandle, lumpinfo, length);
|
||||
|
||||
//
|
||||
// Fill in lumpinfo
|
||||
//
|
||||
|
||||
for (i=0 ; i<numlumps ; i++,lump_p++)
|
||||
{
|
||||
lump_p->filepos = LittleLong(lump_p->filepos);
|
||||
lump_p->size = LittleLong(lump_p->size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CleanupName (char *in, char *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<sizeof( ((lumpinfo_t *)0)->name ) ; i++ )
|
||||
{
|
||||
if (!in[i])
|
||||
break;
|
||||
|
||||
out[i] = toupper(in[i]);
|
||||
}
|
||||
|
||||
for ( ; i<sizeof( ((lumpinfo_t *)0)->name ); i++ )
|
||||
out[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_CheckNumForName
|
||||
|
||||
Returns -1 if name not found
|
||||
====================
|
||||
*/
|
||||
int W_CheckNumForName (char *name)
|
||||
{
|
||||
char cleanname[TEXTURE_NAME_LENGTH];
|
||||
int v1,v2, v3, v4;
|
||||
int i;
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
CleanupName (name, cleanname);
|
||||
|
||||
// make the name into four integers for easy compares
|
||||
|
||||
v1 = *(int *)cleanname;
|
||||
v2 = *(int *)&cleanname[4];
|
||||
v3 = *(int *)&cleanname[8];
|
||||
v4 = *(int *)&cleanname[12];
|
||||
|
||||
// find it
|
||||
|
||||
lump_p = lumpinfo;
|
||||
for (i=0 ; i<numlumps ; i++, lump_p++)
|
||||
{
|
||||
if ( *(int *)lump_p->name == v1
|
||||
&& *(int *)&lump_p->name[4] == v2
|
||||
&& *(int *)&lump_p->name[8] == v3
|
||||
&& *(int *)&lump_p->name[12] == v4
|
||||
&& !strcmp( lump_p->name, cleanname ) )
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_GetNumForName
|
||||
|
||||
Calls W_CheckNumForName, but bombs out if not found
|
||||
====================
|
||||
*/
|
||||
int W_GetNumForName (char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = W_CheckNumForName (name);
|
||||
if (i != -1)
|
||||
return i;
|
||||
|
||||
Error ("W_GetNumForName: %s not found!",name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_LumpLength
|
||||
|
||||
Returns the buffer size needed to load the given lump
|
||||
====================
|
||||
*/
|
||||
int W_LumpLength (int lump)
|
||||
{
|
||||
if (lump >= numlumps)
|
||||
Error ("W_LumpLength: %i >= numlumps",lump);
|
||||
return lumpinfo[lump].size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_ReadLumpNum
|
||||
|
||||
Loads the lump into the given buffer, which must be >= W_LumpLength()
|
||||
====================
|
||||
*/
|
||||
void W_ReadLumpNum (int lump, void *dest)
|
||||
{
|
||||
lumpinfo_t *l;
|
||||
|
||||
if (lump >= numlumps)
|
||||
Error ("W_ReadLump: %i >= numlumps",lump);
|
||||
l = lumpinfo+lump;
|
||||
|
||||
fseek (wadhandle, l->filepos, SEEK_SET);
|
||||
SafeRead (wadhandle, dest, l->size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_LoadLumpNum
|
||||
====================
|
||||
*/
|
||||
void *W_LoadLumpNum (int lump)
|
||||
{
|
||||
void *buf;
|
||||
|
||||
if ((unsigned)lump >= numlumps)
|
||||
Error ("W_CacheLumpNum: %i >= numlumps",lump);
|
||||
|
||||
buf = malloc (W_LumpLength (lump));
|
||||
W_ReadLumpNum (lump, buf);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
W_LoadLumpName
|
||||
====================
|
||||
*/
|
||||
void *W_LoadLumpName (char *name)
|
||||
{
|
||||
return W_LoadLumpNum (W_GetNumForName(name));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
WAD CREATION
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
FILE *outwad;
|
||||
|
||||
lumpinfo_t outinfo[4096];
|
||||
int outlumps;
|
||||
|
||||
short (*wadshort) (short l);
|
||||
int (*wadlong) (int l);
|
||||
|
||||
/*
|
||||
===============
|
||||
NewWad
|
||||
===============
|
||||
*/
|
||||
|
||||
void NewWad (char *pathname, qboolean bigendien)
|
||||
{
|
||||
outwad = SafeOpenWrite (pathname);
|
||||
fseek (outwad, sizeof(wadinfo_t), SEEK_SET);
|
||||
memset (outinfo, 0, sizeof(outinfo));
|
||||
|
||||
if (bigendien)
|
||||
{
|
||||
wadshort = BigShort;
|
||||
wadlong = BigLong;
|
||||
}
|
||||
else
|
||||
{
|
||||
wadshort = LittleShort;
|
||||
wadlong = LittleLong;
|
||||
}
|
||||
|
||||
outlumps = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
AddLump
|
||||
===============
|
||||
*/
|
||||
|
||||
void AddLump (char *name, void *buffer, int length, int type, int compress)
|
||||
{
|
||||
lumpinfo_t *info;
|
||||
int ofs;
|
||||
|
||||
info = &outinfo[outlumps];
|
||||
outlumps++;
|
||||
|
||||
memset (info,0,sizeof(info));
|
||||
|
||||
strcpy (info->name, name);
|
||||
Q_strupr (info->name);
|
||||
|
||||
ofs = ftell(outwad);
|
||||
info->filepos = wadlong(ofs);
|
||||
info->size = info->disksize = wadlong(length);
|
||||
info->type = type;
|
||||
info->compression = compress;
|
||||
|
||||
// FIXME: do compression
|
||||
|
||||
SafeWrite (outwad, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
WriteWad
|
||||
===============
|
||||
*/
|
||||
|
||||
void WriteWad (int wad3)
|
||||
{
|
||||
wadinfo_t header;
|
||||
int ofs;
|
||||
|
||||
// write the lumpingo
|
||||
ofs = ftell(outwad);
|
||||
|
||||
SafeWrite (outwad, outinfo, outlumps*sizeof(lumpinfo_t) );
|
||||
|
||||
// write the header
|
||||
|
||||
// a program will be able to tell the ednieness of a wad by the id
|
||||
ID_TO_STRING( WAD_ID, header.identification );
|
||||
|
||||
header.numlumps = wadlong(outlumps);
|
||||
header.infotableofs = wadlong(ofs);
|
||||
|
||||
fseek (outwad, 0, SEEK_SET);
|
||||
SafeWrite (outwad, &header, sizeof(header));
|
||||
fclose (outwad);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
// wadlib.h
|
||||
|
||||
//
|
||||
// wad reading
|
||||
//
|
||||
|
||||
#define CMP_NONE 0
|
||||
#define CMP_LZSS 1
|
||||
|
||||
#define TYP_NONE 0
|
||||
#define TYP_LABEL 1
|
||||
#define TYP_LUMPY 64 // 64 + grab command number
|
||||
|
||||
#ifndef WADTYPES_H
|
||||
#include "wadtypes.h"
|
||||
#endif
|
||||
|
||||
extern lumpinfo_t *lumpinfo; // location of each lump on disk
|
||||
extern int numlumps;
|
||||
extern wadinfo_t header;
|
||||
|
||||
void W_OpenWad (char *filename);
|
||||
int W_CheckNumForName (char *name);
|
||||
int W_GetNumForName (char *name);
|
||||
int W_LumpLength (int lump);
|
||||
void W_ReadLumpNum (int lump, void *dest);
|
||||
void *W_LoadLumpNum (int lump);
|
||||
void *W_LoadLumpName (char *name);
|
||||
|
||||
void CleanupName (char *in, char *out);
|
||||
|
||||
//
|
||||
// wad creation
|
||||
//
|
||||
void NewWad (char *pathname, qboolean bigendien);
|
||||
void AddLump (char *name, void *buffer, int length, int type, int compress);
|
||||
void WriteWad (int wad3);
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
// wadlib.h
|
||||
|
||||
//
|
||||
// wad reading
|
||||
//
|
||||
|
||||
#define CMP_NONE 0
|
||||
#define CMP_LZSS 1
|
||||
|
||||
#define TYP_NONE 0
|
||||
#define TYP_LABEL 1
|
||||
#define TYP_LUMPY 64 // 64 + grab command number
|
||||
|
||||
#ifndef WADTYPES_H
|
||||
#include "wadtypes.h"
|
||||
#endif
|
||||
|
||||
extern lumpinfo_t *lumpinfo; // location of each lump on disk
|
||||
extern int numlumps;
|
||||
extern wadinfo_t header;
|
||||
|
||||
void W_OpenWad (char *filename);
|
||||
int W_CheckNumForName (char *name);
|
||||
int W_GetNumForName (char *name);
|
||||
int W_LumpLength (int lump);
|
||||
void W_ReadLumpNum (int lump, void *dest);
|
||||
void *W_LoadLumpNum (int lump);
|
||||
void *W_LoadLumpName (char *name);
|
||||
|
||||
void CleanupName (char *in, char *out);
|
||||
|
||||
//
|
||||
// wad creation
|
||||
//
|
||||
void NewWad (char *pathname, qboolean bigendien);
|
||||
void AddLump (char *name, void *buffer, int length, int type, int compress);
|
||||
void WriteWad (int wad3);
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
// GLOS.H
|
||||
//
|
||||
// This is an OS specific header file
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// disable data conversion warnings
|
||||
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
#pragma warning(disable : 4136) // X86
|
||||
#pragma warning(disable : 4051) // ALPHA
|
||||
|
||||
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
// GLOS.H
|
||||
//
|
||||
// This is an OS specific header file
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// disable data conversion warnings
|
||||
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
#pragma warning(disable : 4136) // X86
|
||||
#pragma warning(disable : 4051) // ALPHA
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,55 +1,55 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// GLVIEW.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE;..\common"
|
||||
$PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE glu32.lib opengl32.lib odbc32.lib odbccp32.lib winmm.lib"
|
||||
$AdditionalDependencies "$BASE glaux.lib" [!$VS2010]
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Glview"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "glview.cpp"
|
||||
|
||||
$Folder "common files"
|
||||
{
|
||||
$File "..\common\cmdlib.cpp"
|
||||
$File "$SRCDIR\public\filesystem_helpers.cpp"
|
||||
$File "$SRCDIR\public\filesystem_init.cpp"
|
||||
$File "..\common\filesystem_tools.cpp"
|
||||
$File "..\common\physdll.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "..\common\cmdlib.h"
|
||||
$File "glos.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// GLVIEW.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE;..\common"
|
||||
$PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE glu32.lib opengl32.lib odbc32.lib odbccp32.lib winmm.lib"
|
||||
$AdditionalDependencies "$BASE glaux.lib" [!$VS2010]
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Glview"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "glview.cpp"
|
||||
|
||||
$Folder "common files"
|
||||
{
|
||||
$File "..\common\cmdlib.cpp"
|
||||
$File "$SRCDIR\public\filesystem_helpers.cpp"
|
||||
$File "$SRCDIR\public\filesystem_init.cpp"
|
||||
$File "..\common\filesystem_tools.cpp"
|
||||
$File "..\common\physdll.cpp"
|
||||
}
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "..\common\cmdlib.h"
|
||||
$File "glos.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,343 +1,343 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <direct.h>
|
||||
#include "bitmap/imageformat.h"
|
||||
#include "tier1/strtools.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "bitmap/TGAWriter.h"
|
||||
#include "bitmap/TGALoader.h"
|
||||
#include <math.h>
|
||||
#include <conio.h>
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
static bool g_NoPause = false;
|
||||
static bool g_Quiet = false;
|
||||
|
||||
static void Pause( void )
|
||||
{
|
||||
if( !g_NoPause )
|
||||
{
|
||||
printf( "Hit a key to continue\n" );
|
||||
getch();
|
||||
}
|
||||
}
|
||||
|
||||
static bool ImageRGBA8888HasAlpha( unsigned char *pImage, int numTexels )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < numTexels; i++ )
|
||||
{
|
||||
if( pImage[i*4+3] != 255 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GetKeyValueFromBuffer( CUtlBuffer &buf, char **key, char **val )
|
||||
{
|
||||
char stringBuf[2048];
|
||||
while( buf.IsValid() )
|
||||
{
|
||||
buf.GetLine( stringBuf, sizeof(stringBuf) );
|
||||
char *scan = stringBuf;
|
||||
// search for the first quote for the key.
|
||||
while( 1 )
|
||||
{
|
||||
if( *scan == '\"' )
|
||||
{
|
||||
*key = ++scan;
|
||||
break;
|
||||
}
|
||||
if( *scan == '#' )
|
||||
{
|
||||
goto next_line; // comment
|
||||
}
|
||||
if( *scan == '\0' )
|
||||
{
|
||||
goto next_line; // end of line.
|
||||
}
|
||||
scan++;
|
||||
}
|
||||
// read the key until another quote.
|
||||
while( 1 )
|
||||
{
|
||||
if( *scan == '\"' )
|
||||
{
|
||||
*scan = '\0';
|
||||
scan++;
|
||||
break;
|
||||
}
|
||||
if( *scan == '\0' )
|
||||
{
|
||||
goto next_line;
|
||||
}
|
||||
scan++;
|
||||
}
|
||||
// search for the first quote for the value.
|
||||
while( 1 )
|
||||
{
|
||||
if( *scan == '\"' )
|
||||
{
|
||||
*val = ++scan;
|
||||
break;
|
||||
}
|
||||
if( *scan == '#' )
|
||||
{
|
||||
goto next_line; // comment
|
||||
}
|
||||
if( *scan == '\0' )
|
||||
{
|
||||
goto next_line; // end of line.
|
||||
}
|
||||
scan++;
|
||||
}
|
||||
// read the value until another quote.
|
||||
while( 1 )
|
||||
{
|
||||
if( *scan == '\"' )
|
||||
{
|
||||
*scan = '\0';
|
||||
scan++;
|
||||
// got a key and a value, so get the hell out of here.
|
||||
return true;
|
||||
}
|
||||
if( *scan == '\0' )
|
||||
{
|
||||
goto next_line;
|
||||
}
|
||||
scan++;
|
||||
}
|
||||
next_line:
|
||||
;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void LoadConfigFile( const char *pFileName, float *bumpScale, int *startFrame, int *endFrame )
|
||||
{
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
if ( !g_pFullFileSystem->ReadFile( pFileName, NULL, buf ) )
|
||||
{
|
||||
fprintf( stderr, "Can't open: %s\n", pFileName );
|
||||
Pause();
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
char *key = NULL;
|
||||
char *val = NULL;
|
||||
while( GetKeyValueFromBuffer( buf, &key, &val ) )
|
||||
{
|
||||
if( stricmp( key, "bumpscale" ) == 0 )
|
||||
{
|
||||
*bumpScale = atof( val );
|
||||
}
|
||||
if( stricmp( key, "startframe" ) == 0 )
|
||||
{
|
||||
*startFrame = atoi( val );
|
||||
}
|
||||
else if( stricmp( key, "endframe" ) == 0 )
|
||||
{
|
||||
*endFrame = atoi( val );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Usage()
|
||||
{
|
||||
fprintf( stderr, "Usage: height2normal [-nopause] [-quiet] tex1_normal.txt tex2_normal.txt . . .\n" );
|
||||
fprintf( stderr, "-quiet : don't print anything out, don't pause for input\n" );
|
||||
fprintf( stderr, "-nopause : don't pause for input\n" );
|
||||
Pause();
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
void ProcessFiles( const char *pNormalFileNameWithoutExtension,
|
||||
int startFrame, int endFrame,
|
||||
float bumpScale )
|
||||
{
|
||||
static char heightTGAFileName[1024];
|
||||
static char normalTGAFileName[1024];
|
||||
static char buf[1024];
|
||||
bool animated = !( startFrame == -1 || endFrame == -1 );
|
||||
int numFrames = endFrame - startFrame + 1;
|
||||
int frameID;
|
||||
|
||||
for( frameID = 0; frameID < numFrames; frameID++ )
|
||||
{
|
||||
if( animated )
|
||||
{
|
||||
sprintf( normalTGAFileName, "%s%03d.tga", pNormalFileNameWithoutExtension, frameID + startFrame );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( normalTGAFileName, "%s.tga", pNormalFileNameWithoutExtension );
|
||||
}
|
||||
if( !Q_stristr( pNormalFileNameWithoutExtension, "_normal" ) )
|
||||
{
|
||||
fprintf( stderr, "ERROR: config file name must end in _normal.txt\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy( buf, pNormalFileNameWithoutExtension );
|
||||
|
||||
// Strip '_normal' off the end because we're looking for '_height'
|
||||
char *pcUnderscore = Q_stristr( buf, "_normal" );
|
||||
*pcUnderscore = NULL;
|
||||
|
||||
if( animated )
|
||||
{
|
||||
sprintf( heightTGAFileName, "%s_height%03d.tga", buf, frameID + startFrame );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( heightTGAFileName, "%s_height.tga", buf );
|
||||
}
|
||||
|
||||
enum ImageFormat imageFormat;
|
||||
int width, height;
|
||||
float sourceGamma;
|
||||
CUtlBuffer buf;
|
||||
if ( !g_pFullFileSystem->ReadFile( heightTGAFileName, NULL, buf ) )
|
||||
{
|
||||
fprintf( stderr, "%s not found\n", heightTGAFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !TGALoader::GetInfo( buf, &width, &height, &imageFormat, &sourceGamma ) )
|
||||
{
|
||||
fprintf( stderr, "error in %s\n", heightTGAFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
int memRequired = ImageLoader::GetMemRequired( width, height, 1, IMAGE_FORMAT_IA88, false );
|
||||
unsigned char *pImageIA88 = new unsigned char[memRequired];
|
||||
|
||||
buf.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
|
||||
TGALoader::Load( pImageIA88, buf, width, height, IMAGE_FORMAT_IA88, sourceGamma, false );
|
||||
|
||||
memRequired = ImageLoader::GetMemRequired( width, height, 1, IMAGE_FORMAT_RGBA8888, false );
|
||||
unsigned char *pImageRGBA8888 = new unsigned char[memRequired];
|
||||
ImageLoader::ConvertIA88ImageToNormalMapRGBA8888( pImageIA88, width, height, pImageRGBA8888, bumpScale );
|
||||
|
||||
CUtlBuffer normalBuf;
|
||||
ImageLoader::NormalizeNormalMapRGBA8888( pImageRGBA8888, width * height );
|
||||
if( ImageRGBA8888HasAlpha( pImageRGBA8888, width * height ) )
|
||||
{
|
||||
TGAWriter::WriteToBuffer( pImageRGBA8888, normalBuf, width, height, IMAGE_FORMAT_RGBA8888, IMAGE_FORMAT_RGBA8888 );
|
||||
}
|
||||
else
|
||||
{
|
||||
memRequired = ImageLoader::GetMemRequired( width, height, 1, IMAGE_FORMAT_RGB888, false );
|
||||
unsigned char *pImageRGB888 = new unsigned char[memRequired];
|
||||
ImageLoader::ConvertImageFormat( pImageRGBA8888, IMAGE_FORMAT_RGBA8888,
|
||||
pImageRGB888, IMAGE_FORMAT_RGB888, width, height, 0, 0 );
|
||||
TGAWriter::WriteToBuffer( pImageRGB888, normalBuf, width, height, IMAGE_FORMAT_RGB888, IMAGE_FORMAT_RGB888 );
|
||||
delete [] pImageRGB888;
|
||||
}
|
||||
if ( !g_pFullFileSystem->WriteFile( normalTGAFileName, NULL, normalBuf ) )
|
||||
{
|
||||
fprintf( stderr, "unable to write %s\n", normalTGAFileName );
|
||||
return;
|
||||
}
|
||||
delete [] pImageIA88;
|
||||
delete [] pImageRGBA8888;
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
if( argc < 2 )
|
||||
{
|
||||
Usage();
|
||||
}
|
||||
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
|
||||
InitDefaultFileSystem();
|
||||
|
||||
int i = 1;
|
||||
while( i < argc )
|
||||
{
|
||||
if( stricmp( argv[i], "-quiet" ) == 0 )
|
||||
{
|
||||
i++;
|
||||
g_Quiet = true;
|
||||
g_NoPause = true; // no point in pausing if we aren't going to print anything out.
|
||||
}
|
||||
if( stricmp( argv[i], "-nopause" ) == 0 )
|
||||
{
|
||||
i++;
|
||||
g_NoPause = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char pCurrentDirectory[MAX_PATH];
|
||||
if ( _getcwd( pCurrentDirectory, sizeof(pCurrentDirectory) ) == NULL )
|
||||
{
|
||||
fprintf( stderr, "Unable to get the current directory\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
Q_FixSlashes( pCurrentDirectory );
|
||||
Q_StripTrailingSlash( pCurrentDirectory );
|
||||
|
||||
for( ; i < argc; i++ )
|
||||
{
|
||||
static char normalFileNameWithoutExtension[1024];
|
||||
char *pFileName;
|
||||
if ( !Q_IsAbsolutePath( argv[i] ) )
|
||||
{
|
||||
Q_snprintf( normalFileNameWithoutExtension, sizeof(normalFileNameWithoutExtension), "%s\\%s", pCurrentDirectory, argv[i] );
|
||||
pFileName = normalFileNameWithoutExtension;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFileName = argv[i];
|
||||
}
|
||||
|
||||
if( !g_Quiet )
|
||||
{
|
||||
printf( "file: %s\n", pFileName );
|
||||
}
|
||||
float bumpScale = -1.0f;
|
||||
int startFrame = -1;
|
||||
int endFrame = -1;
|
||||
LoadConfigFile( pFileName, &bumpScale, &startFrame, &endFrame );
|
||||
if( bumpScale == -1.0f )
|
||||
{
|
||||
fprintf( stderr, "Must specify \"bumpscale\" in config file\n" );
|
||||
Pause();
|
||||
continue;
|
||||
}
|
||||
if( ( startFrame == -1 && endFrame != -1 ) ||
|
||||
( startFrame != -1 && endFrame == -1 ) )
|
||||
{
|
||||
fprintf( stderr, "ERROR: If you use startframe, you must use endframe, and vice versa.\n" );
|
||||
Pause();
|
||||
continue;
|
||||
}
|
||||
if( !g_Quiet )
|
||||
{
|
||||
printf( "\tbumpscale: %f\n", bumpScale );
|
||||
}
|
||||
|
||||
Q_StripExtension( pFileName, normalFileNameWithoutExtension, sizeof( normalFileNameWithoutExtension ) );
|
||||
ProcessFiles( normalFileNameWithoutExtension,
|
||||
startFrame, endFrame,
|
||||
bumpScale );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <direct.h>
|
||||
#include "bitmap/imageformat.h"
|
||||
#include "tier1/strtools.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "bitmap/TGAWriter.h"
|
||||
#include "bitmap/TGALoader.h"
|
||||
#include <math.h>
|
||||
#include <conio.h>
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
static bool g_NoPause = false;
|
||||
static bool g_Quiet = false;
|
||||
|
||||
static void Pause( void )
|
||||
{
|
||||
if( !g_NoPause )
|
||||
{
|
||||
printf( "Hit a key to continue\n" );
|
||||
getch();
|
||||
}
|
||||
}
|
||||
|
||||
static bool ImageRGBA8888HasAlpha( unsigned char *pImage, int numTexels )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < numTexels; i++ )
|
||||
{
|
||||
if( pImage[i*4+3] != 255 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GetKeyValueFromBuffer( CUtlBuffer &buf, char **key, char **val )
|
||||
{
|
||||
char stringBuf[2048];
|
||||
while( buf.IsValid() )
|
||||
{
|
||||
buf.GetLine( stringBuf, sizeof(stringBuf) );
|
||||
char *scan = stringBuf;
|
||||
// search for the first quote for the key.
|
||||
while( 1 )
|
||||
{
|
||||
if( *scan == '\"' )
|
||||
{
|
||||
*key = ++scan;
|
||||
break;
|
||||
}
|
||||
if( *scan == '#' )
|
||||
{
|
||||
goto next_line; // comment
|
||||
}
|
||||
if( *scan == '\0' )
|
||||
{
|
||||
goto next_line; // end of line.
|
||||
}
|
||||
scan++;
|
||||
}
|
||||
// read the key until another quote.
|
||||
while( 1 )
|
||||
{
|
||||
if( *scan == '\"' )
|
||||
{
|
||||
*scan = '\0';
|
||||
scan++;
|
||||
break;
|
||||
}
|
||||
if( *scan == '\0' )
|
||||
{
|
||||
goto next_line;
|
||||
}
|
||||
scan++;
|
||||
}
|
||||
// search for the first quote for the value.
|
||||
while( 1 )
|
||||
{
|
||||
if( *scan == '\"' )
|
||||
{
|
||||
*val = ++scan;
|
||||
break;
|
||||
}
|
||||
if( *scan == '#' )
|
||||
{
|
||||
goto next_line; // comment
|
||||
}
|
||||
if( *scan == '\0' )
|
||||
{
|
||||
goto next_line; // end of line.
|
||||
}
|
||||
scan++;
|
||||
}
|
||||
// read the value until another quote.
|
||||
while( 1 )
|
||||
{
|
||||
if( *scan == '\"' )
|
||||
{
|
||||
*scan = '\0';
|
||||
scan++;
|
||||
// got a key and a value, so get the hell out of here.
|
||||
return true;
|
||||
}
|
||||
if( *scan == '\0' )
|
||||
{
|
||||
goto next_line;
|
||||
}
|
||||
scan++;
|
||||
}
|
||||
next_line:
|
||||
;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void LoadConfigFile( const char *pFileName, float *bumpScale, int *startFrame, int *endFrame )
|
||||
{
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
if ( !g_pFullFileSystem->ReadFile( pFileName, NULL, buf ) )
|
||||
{
|
||||
fprintf( stderr, "Can't open: %s\n", pFileName );
|
||||
Pause();
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
char *key = NULL;
|
||||
char *val = NULL;
|
||||
while( GetKeyValueFromBuffer( buf, &key, &val ) )
|
||||
{
|
||||
if( stricmp( key, "bumpscale" ) == 0 )
|
||||
{
|
||||
*bumpScale = atof( val );
|
||||
}
|
||||
if( stricmp( key, "startframe" ) == 0 )
|
||||
{
|
||||
*startFrame = atoi( val );
|
||||
}
|
||||
else if( stricmp( key, "endframe" ) == 0 )
|
||||
{
|
||||
*endFrame = atoi( val );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Usage()
|
||||
{
|
||||
fprintf( stderr, "Usage: height2normal [-nopause] [-quiet] tex1_normal.txt tex2_normal.txt . . .\n" );
|
||||
fprintf( stderr, "-quiet : don't print anything out, don't pause for input\n" );
|
||||
fprintf( stderr, "-nopause : don't pause for input\n" );
|
||||
Pause();
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
void ProcessFiles( const char *pNormalFileNameWithoutExtension,
|
||||
int startFrame, int endFrame,
|
||||
float bumpScale )
|
||||
{
|
||||
static char heightTGAFileName[1024];
|
||||
static char normalTGAFileName[1024];
|
||||
static char buf[1024];
|
||||
bool animated = !( startFrame == -1 || endFrame == -1 );
|
||||
int numFrames = endFrame - startFrame + 1;
|
||||
int frameID;
|
||||
|
||||
for( frameID = 0; frameID < numFrames; frameID++ )
|
||||
{
|
||||
if( animated )
|
||||
{
|
||||
sprintf( normalTGAFileName, "%s%03d.tga", pNormalFileNameWithoutExtension, frameID + startFrame );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( normalTGAFileName, "%s.tga", pNormalFileNameWithoutExtension );
|
||||
}
|
||||
if( !Q_stristr( pNormalFileNameWithoutExtension, "_normal" ) )
|
||||
{
|
||||
fprintf( stderr, "ERROR: config file name must end in _normal.txt\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy( buf, pNormalFileNameWithoutExtension );
|
||||
|
||||
// Strip '_normal' off the end because we're looking for '_height'
|
||||
char *pcUnderscore = Q_stristr( buf, "_normal" );
|
||||
*pcUnderscore = NULL;
|
||||
|
||||
if( animated )
|
||||
{
|
||||
sprintf( heightTGAFileName, "%s_height%03d.tga", buf, frameID + startFrame );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( heightTGAFileName, "%s_height.tga", buf );
|
||||
}
|
||||
|
||||
enum ImageFormat imageFormat;
|
||||
int width, height;
|
||||
float sourceGamma;
|
||||
CUtlBuffer buf;
|
||||
if ( !g_pFullFileSystem->ReadFile( heightTGAFileName, NULL, buf ) )
|
||||
{
|
||||
fprintf( stderr, "%s not found\n", heightTGAFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !TGALoader::GetInfo( buf, &width, &height, &imageFormat, &sourceGamma ) )
|
||||
{
|
||||
fprintf( stderr, "error in %s\n", heightTGAFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
int memRequired = ImageLoader::GetMemRequired( width, height, 1, IMAGE_FORMAT_IA88, false );
|
||||
unsigned char *pImageIA88 = new unsigned char[memRequired];
|
||||
|
||||
buf.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
|
||||
TGALoader::Load( pImageIA88, buf, width, height, IMAGE_FORMAT_IA88, sourceGamma, false );
|
||||
|
||||
memRequired = ImageLoader::GetMemRequired( width, height, 1, IMAGE_FORMAT_RGBA8888, false );
|
||||
unsigned char *pImageRGBA8888 = new unsigned char[memRequired];
|
||||
ImageLoader::ConvertIA88ImageToNormalMapRGBA8888( pImageIA88, width, height, pImageRGBA8888, bumpScale );
|
||||
|
||||
CUtlBuffer normalBuf;
|
||||
ImageLoader::NormalizeNormalMapRGBA8888( pImageRGBA8888, width * height );
|
||||
if( ImageRGBA8888HasAlpha( pImageRGBA8888, width * height ) )
|
||||
{
|
||||
TGAWriter::WriteToBuffer( pImageRGBA8888, normalBuf, width, height, IMAGE_FORMAT_RGBA8888, IMAGE_FORMAT_RGBA8888 );
|
||||
}
|
||||
else
|
||||
{
|
||||
memRequired = ImageLoader::GetMemRequired( width, height, 1, IMAGE_FORMAT_RGB888, false );
|
||||
unsigned char *pImageRGB888 = new unsigned char[memRequired];
|
||||
ImageLoader::ConvertImageFormat( pImageRGBA8888, IMAGE_FORMAT_RGBA8888,
|
||||
pImageRGB888, IMAGE_FORMAT_RGB888, width, height, 0, 0 );
|
||||
TGAWriter::WriteToBuffer( pImageRGB888, normalBuf, width, height, IMAGE_FORMAT_RGB888, IMAGE_FORMAT_RGB888 );
|
||||
delete [] pImageRGB888;
|
||||
}
|
||||
if ( !g_pFullFileSystem->WriteFile( normalTGAFileName, NULL, normalBuf ) )
|
||||
{
|
||||
fprintf( stderr, "unable to write %s\n", normalTGAFileName );
|
||||
return;
|
||||
}
|
||||
delete [] pImageIA88;
|
||||
delete [] pImageRGBA8888;
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
if( argc < 2 )
|
||||
{
|
||||
Usage();
|
||||
}
|
||||
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
|
||||
InitDefaultFileSystem();
|
||||
|
||||
int i = 1;
|
||||
while( i < argc )
|
||||
{
|
||||
if( stricmp( argv[i], "-quiet" ) == 0 )
|
||||
{
|
||||
i++;
|
||||
g_Quiet = true;
|
||||
g_NoPause = true; // no point in pausing if we aren't going to print anything out.
|
||||
}
|
||||
if( stricmp( argv[i], "-nopause" ) == 0 )
|
||||
{
|
||||
i++;
|
||||
g_NoPause = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char pCurrentDirectory[MAX_PATH];
|
||||
if ( _getcwd( pCurrentDirectory, sizeof(pCurrentDirectory) ) == NULL )
|
||||
{
|
||||
fprintf( stderr, "Unable to get the current directory\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
Q_FixSlashes( pCurrentDirectory );
|
||||
Q_StripTrailingSlash( pCurrentDirectory );
|
||||
|
||||
for( ; i < argc; i++ )
|
||||
{
|
||||
static char normalFileNameWithoutExtension[1024];
|
||||
char *pFileName;
|
||||
if ( !Q_IsAbsolutePath( argv[i] ) )
|
||||
{
|
||||
Q_snprintf( normalFileNameWithoutExtension, sizeof(normalFileNameWithoutExtension), "%s\\%s", pCurrentDirectory, argv[i] );
|
||||
pFileName = normalFileNameWithoutExtension;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFileName = argv[i];
|
||||
}
|
||||
|
||||
if( !g_Quiet )
|
||||
{
|
||||
printf( "file: %s\n", pFileName );
|
||||
}
|
||||
float bumpScale = -1.0f;
|
||||
int startFrame = -1;
|
||||
int endFrame = -1;
|
||||
LoadConfigFile( pFileName, &bumpScale, &startFrame, &endFrame );
|
||||
if( bumpScale == -1.0f )
|
||||
{
|
||||
fprintf( stderr, "Must specify \"bumpscale\" in config file\n" );
|
||||
Pause();
|
||||
continue;
|
||||
}
|
||||
if( ( startFrame == -1 && endFrame != -1 ) ||
|
||||
( startFrame != -1 && endFrame == -1 ) )
|
||||
{
|
||||
fprintf( stderr, "ERROR: If you use startframe, you must use endframe, and vice versa.\n" );
|
||||
Pause();
|
||||
continue;
|
||||
}
|
||||
if( !g_Quiet )
|
||||
{
|
||||
printf( "\tbumpscale: %f\n", bumpScale );
|
||||
}
|
||||
|
||||
Q_StripExtension( pFileName, normalFileNameWithoutExtension, sizeof( normalFileNameWithoutExtension ) );
|
||||
ProcessFiles( normalFileNameWithoutExtension,
|
||||
startFrame, endFrame,
|
||||
bumpScale );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// HEIGHT2NORMAL.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,..\common"
|
||||
$PreprocessorDefinitions "_HAS_ITERATOR_DEBUGGING=0;_DEBUG;_WIN32;_CONSOLE"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Height2normal"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
-$File "$SRCDIR\public\tier0\memoverride.cpp"
|
||||
$File "height2normal.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\tier1\interface.h"
|
||||
$File "$SRCDIR\public\tier1\utlbuffer.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib bitmap
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// HEIGHT2NORMAL.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,..\common"
|
||||
$PreprocessorDefinitions "_HAS_ITERATOR_DEBUGGING=0;_DEBUG;_WIN32;_CONSOLE"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Height2normal"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
-$File "$SRCDIR\public\tier0\memoverride.cpp"
|
||||
$File "height2normal.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\tier1\interface.h"
|
||||
$File "$SRCDIR\public\tier1\utlbuffer.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib bitmap
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,274 +1,274 @@
|
||||
/***
|
||||
*
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "basetypes.h"
|
||||
#include "utlvector.h"
|
||||
#include "utlsymbol.h"
|
||||
#include "mathlib/vector.h"
|
||||
#include "studio.h"
|
||||
|
||||
struct LodScriptData_t;
|
||||
|
||||
#define IDSTUDIOHEADER (('T'<<24)+('S'<<16)+('D'<<8)+'I')
|
||||
// little-endian "IDST"
|
||||
#define IDSTUDIOANIMGROUPHEADER (('G'<<24)+('A'<<16)+('D'<<8)+'I')
|
||||
// little-endian "IDAG"
|
||||
|
||||
|
||||
#define STUDIO_QUADRATIC_MOTION 0x00002000
|
||||
|
||||
#define MAXSTUDIOANIMFRAMES 2000 // max frames per animation
|
||||
#define MAXSTUDIOSEQUENCES 1524 // total sequences
|
||||
#define MAXSTUDIOSRCBONES 512 // bones allowed at source movement
|
||||
#define MAXSTUDIOBONEWEIGHTS 3
|
||||
#define MAXSTUDIONAME 128
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
EXTERN char outname[1024];
|
||||
EXTERN int numdirs;
|
||||
EXTERN char cddir[32][MAX_PATH];
|
||||
EXTERN char fullpath[1024];
|
||||
|
||||
EXTERN float g_defaultscale;
|
||||
EXTERN float g_currentscale;
|
||||
EXTERN RadianEuler g_defaultrotation;
|
||||
|
||||
|
||||
EXTERN char defaulttexture[16][MAX_PATH];
|
||||
EXTERN char sourcetexture[16][MAX_PATH];
|
||||
|
||||
EXTERN int numrep;
|
||||
|
||||
EXTERN int flip_triangles;
|
||||
EXTERN float normal_blend;
|
||||
|
||||
|
||||
void *kalloc( int num, int size );
|
||||
|
||||
struct s_trianglevert_t
|
||||
{
|
||||
int vertindex;
|
||||
int normindex; // index into normal array
|
||||
int s,t;
|
||||
float u,v;
|
||||
};
|
||||
|
||||
struct s_boneweight_t
|
||||
{
|
||||
int numbones;
|
||||
|
||||
int bone[MAXSTUDIOBONEWEIGHTS];
|
||||
float weight[MAXSTUDIOBONEWEIGHTS];
|
||||
};
|
||||
|
||||
|
||||
struct s_vertexinfo_t
|
||||
{
|
||||
// wtf is this doing here?
|
||||
int material;
|
||||
|
||||
int firstref;
|
||||
int lastref;
|
||||
|
||||
int flexmask;
|
||||
int numflex;
|
||||
int flexoffset;
|
||||
};
|
||||
|
||||
struct s_tmpface_t
|
||||
{
|
||||
int material;
|
||||
unsigned long a, b, c;
|
||||
unsigned long ta, tb, tc;
|
||||
unsigned long na, nb, nc;
|
||||
};
|
||||
|
||||
struct s_face_t
|
||||
{
|
||||
unsigned long a, b, c;
|
||||
};
|
||||
|
||||
struct s_node_t
|
||||
{
|
||||
char name[MAXSTUDIONAME];
|
||||
int parent;
|
||||
};
|
||||
|
||||
|
||||
struct s_bone_t
|
||||
{
|
||||
Vector pos;
|
||||
RadianEuler rot;
|
||||
};
|
||||
|
||||
struct s_texture_t
|
||||
{
|
||||
char name[MAX_PATH];
|
||||
int flags;
|
||||
int parent;
|
||||
int material;
|
||||
float width;
|
||||
float height;
|
||||
float dPdu;
|
||||
float dPdv;
|
||||
};
|
||||
EXTERN s_texture_t g_texture[MAXSTUDIOSKINS];
|
||||
EXTERN int g_numtextures;
|
||||
EXTERN int g_material[MAXSTUDIOSKINS]; // link into texture array
|
||||
EXTERN int g_nummaterials;
|
||||
|
||||
EXTERN float g_gamma;
|
||||
EXTERN int g_numskinref;
|
||||
EXTERN int g_numskinfamilies;
|
||||
EXTERN int g_skinref[256][MAXSTUDIOSKINS]; // [skin][skinref], returns texture index
|
||||
EXTERN int g_numtexturegroups;
|
||||
EXTERN int g_numtexturelayers[32];
|
||||
EXTERN int g_numtexturereps[32];
|
||||
EXTERN int g_texturegroup[32][32][32];
|
||||
|
||||
struct s_mesh_t
|
||||
{
|
||||
int numvertices;
|
||||
int vertexoffset;
|
||||
|
||||
int numfaces;
|
||||
int faceoffset;
|
||||
};
|
||||
|
||||
|
||||
struct s_vertanim_t
|
||||
{
|
||||
int vertex;
|
||||
float speed;
|
||||
float side;
|
||||
Vector pos;
|
||||
Vector normal;
|
||||
};
|
||||
|
||||
// processed aggregate lod pools
|
||||
struct s_loddata_t
|
||||
{
|
||||
int numvertices;
|
||||
s_boneweight_t *globalBoneweight;
|
||||
s_vertexinfo_t *vertexInfo;
|
||||
Vector *vertex;
|
||||
Vector *normal;
|
||||
Vector4D *tangentS;
|
||||
Vector2D *texcoord;
|
||||
|
||||
int numfaces;
|
||||
s_face_t *face;
|
||||
|
||||
s_mesh_t mesh[MAXSTUDIOSKINS];
|
||||
|
||||
// remaps verts from an lod's source mesh to this all-lod processed aggregate pool
|
||||
int *pMeshVertIndexMaps[MAX_NUM_LODS];
|
||||
};
|
||||
|
||||
// raw off-disk source files. Raw data should be not processed.
|
||||
struct s_source_t
|
||||
{
|
||||
char filename[MAX_PATH];
|
||||
int time; // time stamp
|
||||
|
||||
bool isActiveModel;
|
||||
|
||||
// local skeleton hierarchy
|
||||
int numbones;
|
||||
s_node_t localBone[MAXSTUDIOSRCBONES];
|
||||
matrix3x4_t boneToPose[MAXSTUDIOSRCBONES]; // converts bone local data into initial pose data
|
||||
|
||||
// bone remapping
|
||||
int boneflags[MAXSTUDIOSRCBONES]; // attachment, vertex, etc flags for this bone
|
||||
int boneref[MAXSTUDIOSRCBONES]; // flags for this and child bones
|
||||
int boneLocalToGlobal[MAXSTUDIOSRCBONES]; // bonemap : local bone to world bone mapping
|
||||
int boneGlobalToLocal[MAXSTUDIOSRCBONES]; // boneimap : world bone to local bone mapping
|
||||
|
||||
int texmap[MAXSTUDIOSKINS*4]; // map local MAX materials to unique textures
|
||||
|
||||
// per material mesh
|
||||
int nummeshes;
|
||||
int meshindex[MAXSTUDIOSKINS]; // mesh to skin index
|
||||
s_mesh_t mesh[MAXSTUDIOSKINS];
|
||||
|
||||
// model global copy of vertices
|
||||
int numvertices;
|
||||
s_boneweight_t *localBoneweight; // vertex info about local bone weighting
|
||||
s_boneweight_t *globalBoneweight; // vertex info about global bone weighting
|
||||
s_vertexinfo_t *vertexInfo; // generic vertex info
|
||||
Vector *vertex;
|
||||
Vector *normal;
|
||||
Vector4D *tangentS;
|
||||
Vector2D *texcoord;
|
||||
|
||||
int numfaces;
|
||||
s_face_t *face; // vertex indexs per face
|
||||
|
||||
// raw skeletal animation
|
||||
int numframes;
|
||||
int startframe;
|
||||
int endframe;
|
||||
s_bone_t *rawanim[MAXSTUDIOANIMFRAMES]; // [frame][bones];
|
||||
|
||||
// vertex animation
|
||||
int *vanim_mapcount; // local verts map to N target verts
|
||||
int **vanim_map; // local vertices to target vertices mapping list
|
||||
int *vanim_flag; // local vert does animate
|
||||
|
||||
int numvanims[MAXSTUDIOANIMFRAMES];
|
||||
s_vertanim_t *vanim[MAXSTUDIOANIMFRAMES]; // [frame][vertex]
|
||||
|
||||
// processed aggregate lod data
|
||||
s_loddata_t *pLodData;
|
||||
};
|
||||
|
||||
|
||||
EXTERN int g_numsources;
|
||||
EXTERN s_source_t *g_source[MAXSTUDIOSEQUENCES];
|
||||
|
||||
EXTERN int is_v1support;
|
||||
|
||||
EXTERN int g_numverts;
|
||||
EXTERN Vector g_vertex[MAXSTUDIOVERTS];
|
||||
EXTERN s_boneweight_t g_bone[MAXSTUDIOVERTS];
|
||||
|
||||
EXTERN int g_numnormals;
|
||||
EXTERN Vector g_normal[MAXSTUDIOVERTS];
|
||||
|
||||
EXTERN int g_numtexcoords;
|
||||
EXTERN Vector2D g_texcoord[MAXSTUDIOVERTS];
|
||||
|
||||
EXTERN int g_numfaces;
|
||||
EXTERN s_tmpface_t g_face[MAXSTUDIOTRIANGLES];
|
||||
EXTERN s_face_t g_src_uface[MAXSTUDIOTRIANGLES]; // max res unified faces
|
||||
|
||||
struct v_unify_t
|
||||
{
|
||||
int refcount;
|
||||
int lastref;
|
||||
int firstref;
|
||||
int v;
|
||||
int m;
|
||||
int n;
|
||||
int t;
|
||||
v_unify_t *next;
|
||||
};
|
||||
|
||||
EXTERN v_unify_t *v_list[MAXSTUDIOVERTS];
|
||||
EXTERN v_unify_t v_listdata[MAXSTUDIOVERTS];
|
||||
EXTERN int numvlist;
|
||||
|
||||
int SortAndBalanceBones( int iCount, int iMaxCount, int bones[], float weights[] );
|
||||
void Grab_Vertexanimation( s_source_t *psource );
|
||||
extern void BuildIndividualMeshes( s_source_t *psource );
|
||||
/***
|
||||
*
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
****/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "basetypes.h"
|
||||
#include "utlvector.h"
|
||||
#include "utlsymbol.h"
|
||||
#include "mathlib/vector.h"
|
||||
#include "studio.h"
|
||||
|
||||
struct LodScriptData_t;
|
||||
|
||||
#define IDSTUDIOHEADER (('T'<<24)+('S'<<16)+('D'<<8)+'I')
|
||||
// little-endian "IDST"
|
||||
#define IDSTUDIOANIMGROUPHEADER (('G'<<24)+('A'<<16)+('D'<<8)+'I')
|
||||
// little-endian "IDAG"
|
||||
|
||||
|
||||
#define STUDIO_QUADRATIC_MOTION 0x00002000
|
||||
|
||||
#define MAXSTUDIOANIMFRAMES 2000 // max frames per animation
|
||||
#define MAXSTUDIOSEQUENCES 1524 // total sequences
|
||||
#define MAXSTUDIOSRCBONES 512 // bones allowed at source movement
|
||||
#define MAXSTUDIOBONEWEIGHTS 3
|
||||
#define MAXSTUDIONAME 128
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
EXTERN char outname[1024];
|
||||
EXTERN int numdirs;
|
||||
EXTERN char cddir[32][MAX_PATH];
|
||||
EXTERN char fullpath[1024];
|
||||
|
||||
EXTERN float g_defaultscale;
|
||||
EXTERN float g_currentscale;
|
||||
EXTERN RadianEuler g_defaultrotation;
|
||||
|
||||
|
||||
EXTERN char defaulttexture[16][MAX_PATH];
|
||||
EXTERN char sourcetexture[16][MAX_PATH];
|
||||
|
||||
EXTERN int numrep;
|
||||
|
||||
EXTERN int flip_triangles;
|
||||
EXTERN float normal_blend;
|
||||
|
||||
|
||||
void *kalloc( int num, int size );
|
||||
|
||||
struct s_trianglevert_t
|
||||
{
|
||||
int vertindex;
|
||||
int normindex; // index into normal array
|
||||
int s,t;
|
||||
float u,v;
|
||||
};
|
||||
|
||||
struct s_boneweight_t
|
||||
{
|
||||
int numbones;
|
||||
|
||||
int bone[MAXSTUDIOBONEWEIGHTS];
|
||||
float weight[MAXSTUDIOBONEWEIGHTS];
|
||||
};
|
||||
|
||||
|
||||
struct s_vertexinfo_t
|
||||
{
|
||||
// wtf is this doing here?
|
||||
int material;
|
||||
|
||||
int firstref;
|
||||
int lastref;
|
||||
|
||||
int flexmask;
|
||||
int numflex;
|
||||
int flexoffset;
|
||||
};
|
||||
|
||||
struct s_tmpface_t
|
||||
{
|
||||
int material;
|
||||
unsigned long a, b, c;
|
||||
unsigned long ta, tb, tc;
|
||||
unsigned long na, nb, nc;
|
||||
};
|
||||
|
||||
struct s_face_t
|
||||
{
|
||||
unsigned long a, b, c;
|
||||
};
|
||||
|
||||
struct s_node_t
|
||||
{
|
||||
char name[MAXSTUDIONAME];
|
||||
int parent;
|
||||
};
|
||||
|
||||
|
||||
struct s_bone_t
|
||||
{
|
||||
Vector pos;
|
||||
RadianEuler rot;
|
||||
};
|
||||
|
||||
struct s_texture_t
|
||||
{
|
||||
char name[MAX_PATH];
|
||||
int flags;
|
||||
int parent;
|
||||
int material;
|
||||
float width;
|
||||
float height;
|
||||
float dPdu;
|
||||
float dPdv;
|
||||
};
|
||||
EXTERN s_texture_t g_texture[MAXSTUDIOSKINS];
|
||||
EXTERN int g_numtextures;
|
||||
EXTERN int g_material[MAXSTUDIOSKINS]; // link into texture array
|
||||
EXTERN int g_nummaterials;
|
||||
|
||||
EXTERN float g_gamma;
|
||||
EXTERN int g_numskinref;
|
||||
EXTERN int g_numskinfamilies;
|
||||
EXTERN int g_skinref[256][MAXSTUDIOSKINS]; // [skin][skinref], returns texture index
|
||||
EXTERN int g_numtexturegroups;
|
||||
EXTERN int g_numtexturelayers[32];
|
||||
EXTERN int g_numtexturereps[32];
|
||||
EXTERN int g_texturegroup[32][32][32];
|
||||
|
||||
struct s_mesh_t
|
||||
{
|
||||
int numvertices;
|
||||
int vertexoffset;
|
||||
|
||||
int numfaces;
|
||||
int faceoffset;
|
||||
};
|
||||
|
||||
|
||||
struct s_vertanim_t
|
||||
{
|
||||
int vertex;
|
||||
float speed;
|
||||
float side;
|
||||
Vector pos;
|
||||
Vector normal;
|
||||
};
|
||||
|
||||
// processed aggregate lod pools
|
||||
struct s_loddata_t
|
||||
{
|
||||
int numvertices;
|
||||
s_boneweight_t *globalBoneweight;
|
||||
s_vertexinfo_t *vertexInfo;
|
||||
Vector *vertex;
|
||||
Vector *normal;
|
||||
Vector4D *tangentS;
|
||||
Vector2D *texcoord;
|
||||
|
||||
int numfaces;
|
||||
s_face_t *face;
|
||||
|
||||
s_mesh_t mesh[MAXSTUDIOSKINS];
|
||||
|
||||
// remaps verts from an lod's source mesh to this all-lod processed aggregate pool
|
||||
int *pMeshVertIndexMaps[MAX_NUM_LODS];
|
||||
};
|
||||
|
||||
// raw off-disk source files. Raw data should be not processed.
|
||||
struct s_source_t
|
||||
{
|
||||
char filename[MAX_PATH];
|
||||
int time; // time stamp
|
||||
|
||||
bool isActiveModel;
|
||||
|
||||
// local skeleton hierarchy
|
||||
int numbones;
|
||||
s_node_t localBone[MAXSTUDIOSRCBONES];
|
||||
matrix3x4_t boneToPose[MAXSTUDIOSRCBONES]; // converts bone local data into initial pose data
|
||||
|
||||
// bone remapping
|
||||
int boneflags[MAXSTUDIOSRCBONES]; // attachment, vertex, etc flags for this bone
|
||||
int boneref[MAXSTUDIOSRCBONES]; // flags for this and child bones
|
||||
int boneLocalToGlobal[MAXSTUDIOSRCBONES]; // bonemap : local bone to world bone mapping
|
||||
int boneGlobalToLocal[MAXSTUDIOSRCBONES]; // boneimap : world bone to local bone mapping
|
||||
|
||||
int texmap[MAXSTUDIOSKINS*4]; // map local MAX materials to unique textures
|
||||
|
||||
// per material mesh
|
||||
int nummeshes;
|
||||
int meshindex[MAXSTUDIOSKINS]; // mesh to skin index
|
||||
s_mesh_t mesh[MAXSTUDIOSKINS];
|
||||
|
||||
// model global copy of vertices
|
||||
int numvertices;
|
||||
s_boneweight_t *localBoneweight; // vertex info about local bone weighting
|
||||
s_boneweight_t *globalBoneweight; // vertex info about global bone weighting
|
||||
s_vertexinfo_t *vertexInfo; // generic vertex info
|
||||
Vector *vertex;
|
||||
Vector *normal;
|
||||
Vector4D *tangentS;
|
||||
Vector2D *texcoord;
|
||||
|
||||
int numfaces;
|
||||
s_face_t *face; // vertex indexs per face
|
||||
|
||||
// raw skeletal animation
|
||||
int numframes;
|
||||
int startframe;
|
||||
int endframe;
|
||||
s_bone_t *rawanim[MAXSTUDIOANIMFRAMES]; // [frame][bones];
|
||||
|
||||
// vertex animation
|
||||
int *vanim_mapcount; // local verts map to N target verts
|
||||
int **vanim_map; // local vertices to target vertices mapping list
|
||||
int *vanim_flag; // local vert does animate
|
||||
|
||||
int numvanims[MAXSTUDIOANIMFRAMES];
|
||||
s_vertanim_t *vanim[MAXSTUDIOANIMFRAMES]; // [frame][vertex]
|
||||
|
||||
// processed aggregate lod data
|
||||
s_loddata_t *pLodData;
|
||||
};
|
||||
|
||||
|
||||
EXTERN int g_numsources;
|
||||
EXTERN s_source_t *g_source[MAXSTUDIOSEQUENCES];
|
||||
|
||||
EXTERN int is_v1support;
|
||||
|
||||
EXTERN int g_numverts;
|
||||
EXTERN Vector g_vertex[MAXSTUDIOVERTS];
|
||||
EXTERN s_boneweight_t g_bone[MAXSTUDIOVERTS];
|
||||
|
||||
EXTERN int g_numnormals;
|
||||
EXTERN Vector g_normal[MAXSTUDIOVERTS];
|
||||
|
||||
EXTERN int g_numtexcoords;
|
||||
EXTERN Vector2D g_texcoord[MAXSTUDIOVERTS];
|
||||
|
||||
EXTERN int g_numfaces;
|
||||
EXTERN s_tmpface_t g_face[MAXSTUDIOTRIANGLES];
|
||||
EXTERN s_face_t g_src_uface[MAXSTUDIOTRIANGLES]; // max res unified faces
|
||||
|
||||
struct v_unify_t
|
||||
{
|
||||
int refcount;
|
||||
int lastref;
|
||||
int firstref;
|
||||
int v;
|
||||
int m;
|
||||
int n;
|
||||
int t;
|
||||
v_unify_t *next;
|
||||
};
|
||||
|
||||
EXTERN v_unify_t *v_list[MAXSTUDIOVERTS];
|
||||
EXTERN v_unify_t v_listdata[MAXSTUDIOVERTS];
|
||||
EXTERN int numvlist;
|
||||
|
||||
int SortAndBalanceBones( int iCount, int iMaxCount, int bones[], float weights[] );
|
||||
void Grab_Vertexanimation( s_source_t *psource );
|
||||
extern void BuildIndividualMeshes( s_source_t *psource );
|
||||
|
||||
@@ -1,88 +1,88 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// MOTIONMAPPER.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,..\common,..\nvtristriplib,$SRCDIR\Game_Shared"
|
||||
$PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE winmm.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Motionmapper"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "..\common\cmdlib.cpp"
|
||||
$File "$SRCDIR\public\filesystem_helpers.cpp"
|
||||
$File "$SRCDIR\public\filesystem_init.cpp"
|
||||
$File "..\common\filesystem_tools.cpp"
|
||||
$File "motionmapper.cpp"
|
||||
$File "..\common\scriplib.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\mathlib\amd3dx.h"
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\tier1\characterset.h"
|
||||
$File "..\common\cmdlib.h"
|
||||
$File "$SRCDIR\public\Color.h"
|
||||
$File "$SRCDIR\public\tier0\commonmacros.h"
|
||||
$File "$SRCDIR\public\mathlib\compressed_vector.h"
|
||||
$File "$SRCDIR\public\tier0\dbg.h"
|
||||
$File "$SRCDIR\public\tier0\fasttimer.h"
|
||||
$File "$SRCDIR\public\filesystem.h"
|
||||
$File "$SRCDIR\public\filesystem_helpers.h"
|
||||
$File "..\common\filesystem_tools.h"
|
||||
$File "$SRCDIR\public\appframework\IAppSystem.h"
|
||||
$File "$SRCDIR\public\tier0\icommandline.h"
|
||||
$File "$SRCDIR\public\vstdlib\IKeyValuesSystem.h"
|
||||
$File "$SRCDIR\public\tier1\interface.h"
|
||||
$File "$SRCDIR\public\tier1\KeyValues.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
$File "$SRCDIR\public\tier0\mem.h"
|
||||
$File "$SRCDIR\public\tier0\memalloc.h"
|
||||
$File "$SRCDIR\public\tier0\memdbgoff.h"
|
||||
$File "$SRCDIR\public\tier0\memdbgon.h"
|
||||
$File "motionmapper.h"
|
||||
$File "$SRCDIR\public\tier0\platform.h"
|
||||
$File "$SRCDIR\public\tier0\protected_things.h"
|
||||
$File "..\common\scriplib.h"
|
||||
$File "$SRCDIR\public\string_t.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\studio.h"
|
||||
$File "$SRCDIR\public\tier1\utlbuffer.h"
|
||||
$File "$SRCDIR\public\tier1\utldict.h"
|
||||
$File "$SRCDIR\public\tier1\utllinkedlist.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlrbtree.h"
|
||||
$File "$SRCDIR\public\tier1\utlsymbol.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector2d.h"
|
||||
$File "$SRCDIR\public\mathlib\vector4d.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib mathlib
|
||||
$Lib nvtristrip
|
||||
$Lib tier2
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// MOTIONMAPPER.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,..\common,..\nvtristriplib,$SRCDIR\Game_Shared"
|
||||
$PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE winmm.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Motionmapper"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "..\common\cmdlib.cpp"
|
||||
$File "$SRCDIR\public\filesystem_helpers.cpp"
|
||||
$File "$SRCDIR\public\filesystem_init.cpp"
|
||||
$File "..\common\filesystem_tools.cpp"
|
||||
$File "motionmapper.cpp"
|
||||
$File "..\common\scriplib.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\mathlib\amd3dx.h"
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\tier1\characterset.h"
|
||||
$File "..\common\cmdlib.h"
|
||||
$File "$SRCDIR\public\Color.h"
|
||||
$File "$SRCDIR\public\tier0\commonmacros.h"
|
||||
$File "$SRCDIR\public\mathlib\compressed_vector.h"
|
||||
$File "$SRCDIR\public\tier0\dbg.h"
|
||||
$File "$SRCDIR\public\tier0\fasttimer.h"
|
||||
$File "$SRCDIR\public\filesystem.h"
|
||||
$File "$SRCDIR\public\filesystem_helpers.h"
|
||||
$File "..\common\filesystem_tools.h"
|
||||
$File "$SRCDIR\public\appframework\IAppSystem.h"
|
||||
$File "$SRCDIR\public\tier0\icommandline.h"
|
||||
$File "$SRCDIR\public\vstdlib\IKeyValuesSystem.h"
|
||||
$File "$SRCDIR\public\tier1\interface.h"
|
||||
$File "$SRCDIR\public\tier1\KeyValues.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
$File "$SRCDIR\public\tier0\mem.h"
|
||||
$File "$SRCDIR\public\tier0\memalloc.h"
|
||||
$File "$SRCDIR\public\tier0\memdbgoff.h"
|
||||
$File "$SRCDIR\public\tier0\memdbgon.h"
|
||||
$File "motionmapper.h"
|
||||
$File "$SRCDIR\public\tier0\platform.h"
|
||||
$File "$SRCDIR\public\tier0\protected_things.h"
|
||||
$File "..\common\scriplib.h"
|
||||
$File "$SRCDIR\public\string_t.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\studio.h"
|
||||
$File "$SRCDIR\public\tier1\utlbuffer.h"
|
||||
$File "$SRCDIR\public\tier1\utldict.h"
|
||||
$File "$SRCDIR\public\tier1\utllinkedlist.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlrbtree.h"
|
||||
$File "$SRCDIR\public\tier1\utlsymbol.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector2d.h"
|
||||
$File "$SRCDIR\public\mathlib\vector4d.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib mathlib
|
||||
$Lib nvtristrip
|
||||
$Lib tier2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,124 +1,124 @@
|
||||
#ifndef NVTRISTRIP_H
|
||||
#define NVTRISTRIP_H
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#pragma comment(lib, "nvtristrip")
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public interface for stripifier
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//GeForce1 and 2 cache size
|
||||
#define CACHESIZE_GEFORCE1_2 16
|
||||
|
||||
//GeForce3 cache size
|
||||
#define CACHESIZE_GEFORCE3 24
|
||||
|
||||
enum PrimType
|
||||
{
|
||||
PT_LIST,
|
||||
PT_STRIP,
|
||||
PT_FAN
|
||||
};
|
||||
|
||||
struct PrimitiveGroup
|
||||
{
|
||||
PrimType type;
|
||||
unsigned int numIndices;
|
||||
unsigned short* indices;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveGroup() : type(PT_STRIP), numIndices(0), indices(NULL) {}
|
||||
~PrimitiveGroup()
|
||||
{
|
||||
if(indices)
|
||||
delete[] indices;
|
||||
indices = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetCacheSize()
|
||||
//
|
||||
// Sets the cache size which the stripfier uses to optimize the data.
|
||||
// Controls the length of the generated individual strips.
|
||||
// This is the "actual" cache size, so 24 for GeForce3 and 16 for GeForce1/2
|
||||
// You may want to play around with this number to tweak performance.
|
||||
//
|
||||
// Default value: 16
|
||||
//
|
||||
void SetCacheSize(const unsigned int cacheSize);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetStitchStrips()
|
||||
//
|
||||
// bool to indicate whether to stitch together strips into one huge strip or not.
|
||||
// If set to true, you'll get back one huge strip stitched together using degenerate
|
||||
// triangles.
|
||||
// If set to false, you'll get back a large number of separate strips.
|
||||
//
|
||||
// Default value: true
|
||||
//
|
||||
void SetStitchStrips(const bool bStitchStrips);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetMinStripSize()
|
||||
//
|
||||
// Sets the minimum acceptable size for a strip, in triangles.
|
||||
// All strips generated which are shorter than this will be thrown into one big, separate list.
|
||||
//
|
||||
// Default value: 0
|
||||
//
|
||||
void SetMinStripSize(const unsigned int minSize);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetListsOnly()
|
||||
//
|
||||
// If set to true, will return an optimized list, with no strips at all.
|
||||
//
|
||||
// Default value: false
|
||||
//
|
||||
void SetListsOnly(const bool bListsOnly);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GenerateStrips()
|
||||
//
|
||||
// in_indices: input index list, the indices you would use to render
|
||||
// in_numIndices: number of entries in in_indices
|
||||
// primGroups: array of optimized/stripified PrimitiveGroups
|
||||
// numGroups: number of groups returned
|
||||
//
|
||||
// Be sure to call delete[] on the returned primGroups to avoid leaking mem
|
||||
//
|
||||
void GenerateStrips(const unsigned short* in_indices, const unsigned int in_numIndices,
|
||||
PrimitiveGroup** primGroups, unsigned short* numGroups);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RemapIndices()
|
||||
//
|
||||
// Function to remap your indices to improve spatial locality in your vertex buffer.
|
||||
//
|
||||
// in_primGroups: array of PrimitiveGroups you want remapped
|
||||
// numGroups: number of entries in in_primGroups
|
||||
// numVerts: number of vertices in your vertex buffer, also can be thought of as the range
|
||||
// of acceptable values for indices in your primitive groups.
|
||||
// remappedGroups: array of remapped PrimitiveGroups
|
||||
//
|
||||
// Note that, according to the remapping handed back to you, you must reorder your
|
||||
// vertex buffer.
|
||||
//
|
||||
// Credit goes to the MS Xbox crew for the idea for this interface.
|
||||
//
|
||||
void RemapIndices(const PrimitiveGroup* in_primGroups, const unsigned short numGroups,
|
||||
const unsigned short numVerts, PrimitiveGroup** remappedGroups);
|
||||
|
||||
#ifndef NVTRISTRIP_H
|
||||
#define NVTRISTRIP_H
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#pragma comment(lib, "nvtristrip")
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public interface for stripifier
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//GeForce1 and 2 cache size
|
||||
#define CACHESIZE_GEFORCE1_2 16
|
||||
|
||||
//GeForce3 cache size
|
||||
#define CACHESIZE_GEFORCE3 24
|
||||
|
||||
enum PrimType
|
||||
{
|
||||
PT_LIST,
|
||||
PT_STRIP,
|
||||
PT_FAN
|
||||
};
|
||||
|
||||
struct PrimitiveGroup
|
||||
{
|
||||
PrimType type;
|
||||
unsigned int numIndices;
|
||||
unsigned short* indices;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveGroup() : type(PT_STRIP), numIndices(0), indices(NULL) {}
|
||||
~PrimitiveGroup()
|
||||
{
|
||||
if(indices)
|
||||
delete[] indices;
|
||||
indices = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetCacheSize()
|
||||
//
|
||||
// Sets the cache size which the stripfier uses to optimize the data.
|
||||
// Controls the length of the generated individual strips.
|
||||
// This is the "actual" cache size, so 24 for GeForce3 and 16 for GeForce1/2
|
||||
// You may want to play around with this number to tweak performance.
|
||||
//
|
||||
// Default value: 16
|
||||
//
|
||||
void SetCacheSize(const unsigned int cacheSize);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetStitchStrips()
|
||||
//
|
||||
// bool to indicate whether to stitch together strips into one huge strip or not.
|
||||
// If set to true, you'll get back one huge strip stitched together using degenerate
|
||||
// triangles.
|
||||
// If set to false, you'll get back a large number of separate strips.
|
||||
//
|
||||
// Default value: true
|
||||
//
|
||||
void SetStitchStrips(const bool bStitchStrips);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetMinStripSize()
|
||||
//
|
||||
// Sets the minimum acceptable size for a strip, in triangles.
|
||||
// All strips generated which are shorter than this will be thrown into one big, separate list.
|
||||
//
|
||||
// Default value: 0
|
||||
//
|
||||
void SetMinStripSize(const unsigned int minSize);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetListsOnly()
|
||||
//
|
||||
// If set to true, will return an optimized list, with no strips at all.
|
||||
//
|
||||
// Default value: false
|
||||
//
|
||||
void SetListsOnly(const bool bListsOnly);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GenerateStrips()
|
||||
//
|
||||
// in_indices: input index list, the indices you would use to render
|
||||
// in_numIndices: number of entries in in_indices
|
||||
// primGroups: array of optimized/stripified PrimitiveGroups
|
||||
// numGroups: number of groups returned
|
||||
//
|
||||
// Be sure to call delete[] on the returned primGroups to avoid leaking mem
|
||||
//
|
||||
void GenerateStrips(const unsigned short* in_indices, const unsigned int in_numIndices,
|
||||
PrimitiveGroup** primGroups, unsigned short* numGroups);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RemapIndices()
|
||||
//
|
||||
// Function to remap your indices to improve spatial locality in your vertex buffer.
|
||||
//
|
||||
// in_primGroups: array of PrimitiveGroups you want remapped
|
||||
// numGroups: number of entries in in_primGroups
|
||||
// numVerts: number of vertices in your vertex buffer, also can be thought of as the range
|
||||
// of acceptable values for indices in your primitive groups.
|
||||
// remappedGroups: array of remapped PrimitiveGroups
|
||||
//
|
||||
// Note that, according to the remapping handed back to you, you must reorder your
|
||||
// vertex buffer.
|
||||
//
|
||||
// Credit goes to the MS Xbox crew for the idea for this interface.
|
||||
//
|
||||
void RemapIndices(const PrimitiveGroup* in_primGroups, const unsigned short numGroups,
|
||||
const unsigned short numVerts, PrimitiveGroup** remappedGroups);
|
||||
|
||||
#endif
|
||||
@@ -1,28 +1,28 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: converts an english string to unicode
|
||||
//-----------------------------------------------------------------------------
|
||||
int ConvertANSIToUnicode(const char *ansi, wchar_t *unicode, int unicodeBufferSize)
|
||||
{
|
||||
return ::MultiByteToWideChar(CP_ACP, 0, ansi, -1, unicode, unicodeBufferSize);
|
||||
}
|
||||
|
||||
char *va( const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
static char output[4][1024];
|
||||
static int outbuffer = 0;
|
||||
|
||||
outbuffer++;
|
||||
va_start( args, fmt );
|
||||
vprintf( fmt, args );
|
||||
vsprintf( output[ outbuffer & 3 ], fmt, args );
|
||||
return output[ outbuffer & 3 ];
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: converts an english string to unicode
|
||||
//-----------------------------------------------------------------------------
|
||||
int ConvertANSIToUnicode(const char *ansi, wchar_t *unicode, int unicodeBufferSize)
|
||||
{
|
||||
return ::MultiByteToWideChar(CP_ACP, 0, ansi, -1, unicode, unicodeBufferSize);
|
||||
}
|
||||
|
||||
char *va( const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
static char output[4][1024];
|
||||
static int outbuffer = 0;
|
||||
|
||||
outbuffer++;
|
||||
va_start( args, fmt );
|
||||
vprintf( fmt, args );
|
||||
vsprintf( output[ outbuffer & 3 ], fmt, args );
|
||||
return output[ outbuffer & 3 ];
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,83 +1,83 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// PHONEMEEXTRACTOR.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin\phonemeextractors"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE;../common,../hlfaceposer,../sapi51/include"
|
||||
$PreprocessorDefinitions "$BASE;PHONEMEEXTRACTOR_EXPORTS"
|
||||
|
||||
// The project has some trouble with the deprecated string function warnings, so turn those off.
|
||||
$AdditionalOptions "$BASE /wd4995"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE odbc32.lib odbccp32.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Phonemeextractor"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "extractor_utils.cpp"
|
||||
$File "$SRCDIR\public\phonemeconverter.cpp"
|
||||
$File "$SRCDIR\public\sentence.cpp"
|
||||
$File "phonemeextractor.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "talkback.h"
|
||||
}
|
||||
|
||||
$Folder "SAPI Header Files"
|
||||
{ // These are dynamic because sapi might not be present in SDK branches, but we still want VPC to succeed.
|
||||
$DynamicFile "..\sapi51\Include\sapi.h"
|
||||
$DynamicFile "..\sapi51\Include\sapiddk.h"
|
||||
$DynamicFile "..\sapi51\Include\Spddkhlp.h"
|
||||
$DynamicFile "..\sapi51\Include\spdebug.h"
|
||||
$DynamicFile "..\sapi51\Include\sperror.h"
|
||||
$DynamicFile "..\sapi51\Include\sphelper.h"
|
||||
}
|
||||
|
||||
$Folder "Public Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\mathlib\amd3dx.h"
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\tier0\commonmacros.h"
|
||||
$File "$SRCDIR\public\tier0\dbg.h"
|
||||
$File "$SRCDIR\public\tier0\fasttimer.h"
|
||||
$File "$SRCDIR\public\appframework\IAppSystem.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
$File "$SRCDIR\public\phonemeconverter.h"
|
||||
$File "$SRCDIR\public\phonemeextractor\phonemeextractor.h"
|
||||
$File "$SRCDIR\public\tier0\platform.h"
|
||||
$File "$SRCDIR\public\tier0\protected_things.h"
|
||||
$File "$SRCDIR\public\sentence.h"
|
||||
$File "$SRCDIR\public\string_t.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\tier1\utllinkedlist.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector2d.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib mathlib
|
||||
$DynamicFile "..\sapi51\lib\i386\sapi.lib"
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// PHONEMEEXTRACTOR.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin\phonemeextractors"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE;../common,../hlfaceposer,../sapi51/include"
|
||||
$PreprocessorDefinitions "$BASE;PHONEMEEXTRACTOR_EXPORTS"
|
||||
|
||||
// The project has some trouble with the deprecated string function warnings, so turn those off.
|
||||
$AdditionalOptions "$BASE /wd4995"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE odbc32.lib odbccp32.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Phonemeextractor"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "extractor_utils.cpp"
|
||||
$File "$SRCDIR\public\phonemeconverter.cpp"
|
||||
$File "$SRCDIR\public\sentence.cpp"
|
||||
$File "phonemeextractor.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "talkback.h"
|
||||
}
|
||||
|
||||
$Folder "SAPI Header Files"
|
||||
{ // These are dynamic because sapi might not be present in SDK branches, but we still want VPC to succeed.
|
||||
$DynamicFile "..\sapi51\Include\sapi.h"
|
||||
$DynamicFile "..\sapi51\Include\sapiddk.h"
|
||||
$DynamicFile "..\sapi51\Include\Spddkhlp.h"
|
||||
$DynamicFile "..\sapi51\Include\spdebug.h"
|
||||
$DynamicFile "..\sapi51\Include\sperror.h"
|
||||
$DynamicFile "..\sapi51\Include\sphelper.h"
|
||||
}
|
||||
|
||||
$Folder "Public Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\mathlib\amd3dx.h"
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\tier0\commonmacros.h"
|
||||
$File "$SRCDIR\public\tier0\dbg.h"
|
||||
$File "$SRCDIR\public\tier0\fasttimer.h"
|
||||
$File "$SRCDIR\public\appframework\IAppSystem.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
$File "$SRCDIR\public\phonemeconverter.h"
|
||||
$File "$SRCDIR\public\phonemeextractor\phonemeextractor.h"
|
||||
$File "$SRCDIR\public\tier0\platform.h"
|
||||
$File "$SRCDIR\public\tier0\protected_things.h"
|
||||
$File "$SRCDIR\public\sentence.h"
|
||||
$File "$SRCDIR\public\string_t.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\tier1\utllinkedlist.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector2d.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib mathlib
|
||||
$DynamicFile "..\sapi51\lib\i386\sapi.lib"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,98 +1,98 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// PHONEMEEXTRACTOR_IMS.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin\phonemeextractors"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE;../common,../hlfaceposer,../sapi51/include"
|
||||
$PreprocessorDefinitions "$BASE;PHONEMEEXTRACTOR_EXPORTS"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE odbc32.lib odbccp32.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Configuration "Debug"
|
||||
{
|
||||
$General
|
||||
{
|
||||
$OutputDirectory ".\Debug_ims" [$WIN32]
|
||||
$IntermediateDirectory ".\Debug_ims" [$WIN32]
|
||||
}
|
||||
}
|
||||
|
||||
$Configuration "Release"
|
||||
{
|
||||
$General
|
||||
{
|
||||
$OutputDirectory ".\Release_ims" [$WIN32]
|
||||
$IntermediateDirectory ".\Release_ims" [$WIN32]
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Phonemeextractor_ims"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "extractor_utils.cpp"
|
||||
$File "$SRCDIR\public\phonemeconverter.cpp"
|
||||
$File "$SRCDIR\public\sentence.cpp"
|
||||
$File "phonemeextractor_ims.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "talkback.h"
|
||||
}
|
||||
|
||||
$Folder "SAPI Header Files"
|
||||
{
|
||||
$File "..\sapi51\Include\sapi.h"
|
||||
$File "..\sapi51\Include\sapiddk.h"
|
||||
$File "..\sapi51\Include\Spddkhlp.h"
|
||||
$File "..\sapi51\Include\spdebug.h"
|
||||
$File "..\sapi51\Include\sperror.h"
|
||||
$File "..\sapi51\Include\sphelper.h"
|
||||
}
|
||||
|
||||
$Folder "Public Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\mathlib\amd3dx.h"
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\tier0\commonmacros.h"
|
||||
$File "$SRCDIR\public\tier0\dbg.h"
|
||||
$File "$SRCDIR\public\tier0\fasttimer.h"
|
||||
$File "$SRCDIR\public\appframework\IAppSystem.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
$File "$SRCDIR\public\phonemeconverter.h"
|
||||
$File "$SRCDIR\public\phonemeextractor\phonemeextractor.h"
|
||||
$File "$SRCDIR\public\tier0\platform.h"
|
||||
$File "$SRCDIR\public\tier0\protected_things.h"
|
||||
$File "$SRCDIR\public\sentence.h"
|
||||
$File "$SRCDIR\public\string_t.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\tier1\utllinkedlist.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector2d.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib mathlib
|
||||
$File "..\sapi51\lib\i386\sapi.lib"
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// PHONEMEEXTRACTOR_IMS.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin\phonemeextractors"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE;../common,../hlfaceposer,../sapi51/include"
|
||||
$PreprocessorDefinitions "$BASE;PHONEMEEXTRACTOR_EXPORTS"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE odbc32.lib odbccp32.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Configuration "Debug"
|
||||
{
|
||||
$General
|
||||
{
|
||||
$OutputDirectory ".\Debug_ims" [$WIN32]
|
||||
$IntermediateDirectory ".\Debug_ims" [$WIN32]
|
||||
}
|
||||
}
|
||||
|
||||
$Configuration "Release"
|
||||
{
|
||||
$General
|
||||
{
|
||||
$OutputDirectory ".\Release_ims" [$WIN32]
|
||||
$IntermediateDirectory ".\Release_ims" [$WIN32]
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Phonemeextractor_ims"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "extractor_utils.cpp"
|
||||
$File "$SRCDIR\public\phonemeconverter.cpp"
|
||||
$File "$SRCDIR\public\sentence.cpp"
|
||||
$File "phonemeextractor_ims.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "talkback.h"
|
||||
}
|
||||
|
||||
$Folder "SAPI Header Files"
|
||||
{
|
||||
$File "..\sapi51\Include\sapi.h"
|
||||
$File "..\sapi51\Include\sapiddk.h"
|
||||
$File "..\sapi51\Include\Spddkhlp.h"
|
||||
$File "..\sapi51\Include\spdebug.h"
|
||||
$File "..\sapi51\Include\sperror.h"
|
||||
$File "..\sapi51\Include\sphelper.h"
|
||||
}
|
||||
|
||||
$Folder "Public Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\mathlib\amd3dx.h"
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\tier0\commonmacros.h"
|
||||
$File "$SRCDIR\public\tier0\dbg.h"
|
||||
$File "$SRCDIR\public\tier0\fasttimer.h"
|
||||
$File "$SRCDIR\public\appframework\IAppSystem.h"
|
||||
$File "$SRCDIR\public\mathlib\mathlib.h"
|
||||
$File "$SRCDIR\public\phonemeconverter.h"
|
||||
$File "$SRCDIR\public\phonemeextractor\phonemeextractor.h"
|
||||
$File "$SRCDIR\public\tier0\platform.h"
|
||||
$File "$SRCDIR\public\tier0\protected_things.h"
|
||||
$File "$SRCDIR\public\sentence.h"
|
||||
$File "$SRCDIR\public\string_t.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\tier1\utllinkedlist.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector.h"
|
||||
$File "$SRCDIR\public\mathlib\vector2d.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib mathlib
|
||||
$File "..\sapi51\lib\i386\sapi.lib"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,73 +1,73 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// QC_Eyes.cpp : Defines the class behaviors for the application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "QC_Eyes.h"
|
||||
#include "QC_EyesDlg.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CQC_EyesApp
|
||||
|
||||
BEGIN_MESSAGE_MAP(CQC_EyesApp, CWinApp)
|
||||
//{{AFX_MSG_MAP(CQC_EyesApp)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code!
|
||||
//}}AFX_MSG
|
||||
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CQC_EyesApp construction
|
||||
|
||||
CQC_EyesApp::CQC_EyesApp()
|
||||
{
|
||||
// TODO: add construction code here,
|
||||
// Place all significant initialization in InitInstance
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// The one and only CQC_EyesApp object
|
||||
|
||||
CQC_EyesApp theApp;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CQC_EyesApp initialization
|
||||
|
||||
BOOL CQC_EyesApp::InitInstance()
|
||||
{
|
||||
AfxEnableControlContainer();
|
||||
|
||||
// Standard initialization
|
||||
// If you are not using these features and wish to reduce the size
|
||||
// of your final executable, you should remove from the following
|
||||
// the specific initialization routines you do not need.
|
||||
|
||||
#ifdef _AFXDLL
|
||||
Enable3dControls(); // Call this when using MFC in a shared DLL
|
||||
#endif
|
||||
|
||||
CQC_EyesDlg dlg;
|
||||
m_pMainWnd = &dlg;
|
||||
INT_PTR nResponse = dlg.DoModal();
|
||||
if (nResponse == IDOK)
|
||||
{
|
||||
// TODO: Place code here to handle when the dialog is
|
||||
// dismissed with OK
|
||||
}
|
||||
else if (nResponse == IDCANCEL)
|
||||
{
|
||||
// TODO: Place code here to handle when the dialog is
|
||||
// dismissed with Cancel
|
||||
}
|
||||
|
||||
// Since the dialog has been closed, return FALSE so that we exit the
|
||||
// application, rather than start the application's message pump.
|
||||
return FALSE;
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// QC_Eyes.cpp : Defines the class behaviors for the application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "QC_Eyes.h"
|
||||
#include "QC_EyesDlg.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CQC_EyesApp
|
||||
|
||||
BEGIN_MESSAGE_MAP(CQC_EyesApp, CWinApp)
|
||||
//{{AFX_MSG_MAP(CQC_EyesApp)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code!
|
||||
//}}AFX_MSG
|
||||
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CQC_EyesApp construction
|
||||
|
||||
CQC_EyesApp::CQC_EyesApp()
|
||||
{
|
||||
// TODO: add construction code here,
|
||||
// Place all significant initialization in InitInstance
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// The one and only CQC_EyesApp object
|
||||
|
||||
CQC_EyesApp theApp;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CQC_EyesApp initialization
|
||||
|
||||
BOOL CQC_EyesApp::InitInstance()
|
||||
{
|
||||
AfxEnableControlContainer();
|
||||
|
||||
// Standard initialization
|
||||
// If you are not using these features and wish to reduce the size
|
||||
// of your final executable, you should remove from the following
|
||||
// the specific initialization routines you do not need.
|
||||
|
||||
#ifdef _AFXDLL
|
||||
Enable3dControls(); // Call this when using MFC in a shared DLL
|
||||
#endif
|
||||
|
||||
CQC_EyesDlg dlg;
|
||||
m_pMainWnd = &dlg;
|
||||
INT_PTR nResponse = dlg.DoModal();
|
||||
if (nResponse == IDOK)
|
||||
{
|
||||
// TODO: Place code here to handle when the dialog is
|
||||
// dismissed with OK
|
||||
}
|
||||
else if (nResponse == IDCANCEL)
|
||||
{
|
||||
// TODO: Place code here to handle when the dialog is
|
||||
// dismissed with Cancel
|
||||
}
|
||||
|
||||
// Since the dialog has been closed, return FALSE so that we exit the
|
||||
// application, rather than start the application's message pump.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// QC_Eyes.h : main header file for the QC_EYES application
|
||||
//
|
||||
|
||||
#if !defined(AFX_QC_EYES_H__398BAF8D_D3C0_4326_BEF0_5129884EE1A3__INCLUDED_)
|
||||
#define AFX_QC_EYES_H__398BAF8D_D3C0_4326_BEF0_5129884EE1A3__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#ifndef __AFXWIN_H__
|
||||
#error include 'stdafx.h' before including this file for PCH
|
||||
#endif
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CQC_EyesApp:
|
||||
// See QC_Eyes.cpp for the implementation of this class
|
||||
//
|
||||
|
||||
class CQC_EyesApp : public CWinApp
|
||||
{
|
||||
public:
|
||||
CQC_EyesApp();
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CQC_EyesApp)
|
||||
public:
|
||||
virtual BOOL InitInstance();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
|
||||
//{{AFX_MSG(CQC_EyesApp)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_QC_EYES_H__398BAF8D_D3C0_4326_BEF0_5129884EE1A3__INCLUDED_)
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// QC_Eyes.h : main header file for the QC_EYES application
|
||||
//
|
||||
|
||||
#if !defined(AFX_QC_EYES_H__398BAF8D_D3C0_4326_BEF0_5129884EE1A3__INCLUDED_)
|
||||
#define AFX_QC_EYES_H__398BAF8D_D3C0_4326_BEF0_5129884EE1A3__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#ifndef __AFXWIN_H__
|
||||
#error include 'stdafx.h' before including this file for PCH
|
||||
#endif
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CQC_EyesApp:
|
||||
// See QC_Eyes.cpp for the implementation of this class
|
||||
//
|
||||
|
||||
class CQC_EyesApp : public CWinApp
|
||||
{
|
||||
public:
|
||||
CQC_EyesApp();
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CQC_EyesApp)
|
||||
public:
|
||||
virtual BOOL InitInstance();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
|
||||
//{{AFX_MSG(CQC_EyesApp)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_QC_EYES_H__398BAF8D_D3C0_4326_BEF0_5129884EE1A3__INCLUDED_)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,134 +1,134 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// QC_EyesDlg.h : header file
|
||||
//
|
||||
|
||||
#if !defined(AFX_QC_EYESDLG_H__9130E22D_05ED_4851_960C_38D90DA94967__INCLUDED_)
|
||||
#define AFX_QC_EYESDLG_H__9130E22D_05ED_4851_960C_38D90DA94967__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
class CDialogParams
|
||||
{
|
||||
public:
|
||||
float m_flLeftEye[3];
|
||||
float m_flRightEye[3];
|
||||
|
||||
float m_flIrisSize;
|
||||
float m_flEyeballSize;
|
||||
|
||||
float m_flLeftUpperLidRaised;
|
||||
float m_flLeftUpperLidNeutral;
|
||||
float m_flLeftUpperLidLowered;
|
||||
|
||||
float m_flLeftLowerLidRaised;
|
||||
float m_flLeftLowerLidNeutral;
|
||||
float m_flLeftLowerLidLowered;
|
||||
|
||||
float m_flRightUpperLidRaised;
|
||||
float m_flRightUpperLidNeutral;
|
||||
float m_flRightUpperLidLowered;
|
||||
|
||||
float m_flRightLowerLidRaised;
|
||||
float m_flRightLowerLidNeutral;
|
||||
float m_flRightLowerLidLowered;
|
||||
|
||||
char m_ReferenceFilename[1024];
|
||||
char m_ExpressionsFilename[1024];
|
||||
char m_ModelFilename[1024];
|
||||
|
||||
char m_EyeballPrefix[1024]; // eyeball_ or dark_eyeball_
|
||||
char m_PupilPrefix[1024]; // pupil_ or grn_pupil_ or bl_pupil_
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CQC_EyesDlg dialog
|
||||
|
||||
class CQC_EyesDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CQC_EyesDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CQC_EyesDlg)
|
||||
enum { IDD = IDD_QC_EYES_DIALOG };
|
||||
CButton m_IndependentLeftLidControl;
|
||||
CStatic m_PictureControl;
|
||||
//}}AFX_DATA
|
||||
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CQC_EyesDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
HICON m_hIcon;
|
||||
|
||||
void GenerateQCText();
|
||||
void AddText( const char *pFormat, ... );
|
||||
bool IsOptionChecked( UINT option );
|
||||
float GetDlgItemFloat( UINT id );
|
||||
void GetDialogParams( CDialogParams &p );
|
||||
void SetupBitmapLabel( UINT iBitmapResourceID, const char *pString, ... );
|
||||
|
||||
HWND m_hOutputText;
|
||||
|
||||
|
||||
// Cached list of bitmaps.
|
||||
class CBitmapRef
|
||||
{
|
||||
public:
|
||||
UINT m_iResource;
|
||||
HBITMAP m_hBitmap;
|
||||
CBitmapRef *m_pNext;
|
||||
};
|
||||
CBitmapRef *m_pBitmapHead;
|
||||
HBITMAP GetCachedBitmap( UINT id );
|
||||
|
||||
|
||||
size_t m_BufSize;
|
||||
char *m_Buf;
|
||||
bool IsIndependentLeftLidControlEnabled();
|
||||
|
||||
bool CheckNumericInputs();
|
||||
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CQC_EyesDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnPaint();
|
||||
afx_msg HCURSOR OnQueryDragIcon();
|
||||
afx_msg void OnCreateQcText();
|
||||
afx_msg void OnIrisColorBrown();
|
||||
afx_msg void OnIrisColorGreen();
|
||||
afx_msg void OnIrisColorBlue();
|
||||
afx_msg void OnEyeColorDark();
|
||||
afx_msg void OnEyeColorLight();
|
||||
afx_msg void OnSetfocusRightEyeX();
|
||||
afx_msg void OnSetfocusRightEyeY();
|
||||
afx_msg void OnSetfocusRightEyeZ();
|
||||
afx_msg void OnSetfocusLeftEyeX();
|
||||
afx_msg void OnSetfocusLeftEyeY();
|
||||
afx_msg void OnSetfocusLeftEyeZ();
|
||||
afx_msg void OnSetfocusUpperLidLowered();
|
||||
afx_msg void OnSetfocusUpperLidNeutral();
|
||||
afx_msg void OnSetfocusUpperLidRaised();
|
||||
afx_msg void OnSetfocusLowerLidLowered();
|
||||
afx_msg void OnSetfocusLowerLidNeutral();
|
||||
afx_msg void OnSetfocusLowerLidRaised();
|
||||
afx_msg void OnCopyTextToClipboard();
|
||||
afx_msg void OnDefaultControls();
|
||||
afx_msg void OnAdvancedControls();
|
||||
afx_msg void OnLeftLidControl();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_QC_EYESDLG_H__9130E22D_05ED_4851_960C_38D90DA94967__INCLUDED_)
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// QC_EyesDlg.h : header file
|
||||
//
|
||||
|
||||
#if !defined(AFX_QC_EYESDLG_H__9130E22D_05ED_4851_960C_38D90DA94967__INCLUDED_)
|
||||
#define AFX_QC_EYESDLG_H__9130E22D_05ED_4851_960C_38D90DA94967__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
class CDialogParams
|
||||
{
|
||||
public:
|
||||
float m_flLeftEye[3];
|
||||
float m_flRightEye[3];
|
||||
|
||||
float m_flIrisSize;
|
||||
float m_flEyeballSize;
|
||||
|
||||
float m_flLeftUpperLidRaised;
|
||||
float m_flLeftUpperLidNeutral;
|
||||
float m_flLeftUpperLidLowered;
|
||||
|
||||
float m_flLeftLowerLidRaised;
|
||||
float m_flLeftLowerLidNeutral;
|
||||
float m_flLeftLowerLidLowered;
|
||||
|
||||
float m_flRightUpperLidRaised;
|
||||
float m_flRightUpperLidNeutral;
|
||||
float m_flRightUpperLidLowered;
|
||||
|
||||
float m_flRightLowerLidRaised;
|
||||
float m_flRightLowerLidNeutral;
|
||||
float m_flRightLowerLidLowered;
|
||||
|
||||
char m_ReferenceFilename[1024];
|
||||
char m_ExpressionsFilename[1024];
|
||||
char m_ModelFilename[1024];
|
||||
|
||||
char m_EyeballPrefix[1024]; // eyeball_ or dark_eyeball_
|
||||
char m_PupilPrefix[1024]; // pupil_ or grn_pupil_ or bl_pupil_
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CQC_EyesDlg dialog
|
||||
|
||||
class CQC_EyesDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CQC_EyesDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CQC_EyesDlg)
|
||||
enum { IDD = IDD_QC_EYES_DIALOG };
|
||||
CButton m_IndependentLeftLidControl;
|
||||
CStatic m_PictureControl;
|
||||
//}}AFX_DATA
|
||||
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CQC_EyesDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
HICON m_hIcon;
|
||||
|
||||
void GenerateQCText();
|
||||
void AddText( const char *pFormat, ... );
|
||||
bool IsOptionChecked( UINT option );
|
||||
float GetDlgItemFloat( UINT id );
|
||||
void GetDialogParams( CDialogParams &p );
|
||||
void SetupBitmapLabel( UINT iBitmapResourceID, const char *pString, ... );
|
||||
|
||||
HWND m_hOutputText;
|
||||
|
||||
|
||||
// Cached list of bitmaps.
|
||||
class CBitmapRef
|
||||
{
|
||||
public:
|
||||
UINT m_iResource;
|
||||
HBITMAP m_hBitmap;
|
||||
CBitmapRef *m_pNext;
|
||||
};
|
||||
CBitmapRef *m_pBitmapHead;
|
||||
HBITMAP GetCachedBitmap( UINT id );
|
||||
|
||||
|
||||
size_t m_BufSize;
|
||||
char *m_Buf;
|
||||
bool IsIndependentLeftLidControlEnabled();
|
||||
|
||||
bool CheckNumericInputs();
|
||||
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CQC_EyesDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnPaint();
|
||||
afx_msg HCURSOR OnQueryDragIcon();
|
||||
afx_msg void OnCreateQcText();
|
||||
afx_msg void OnIrisColorBrown();
|
||||
afx_msg void OnIrisColorGreen();
|
||||
afx_msg void OnIrisColorBlue();
|
||||
afx_msg void OnEyeColorDark();
|
||||
afx_msg void OnEyeColorLight();
|
||||
afx_msg void OnSetfocusRightEyeX();
|
||||
afx_msg void OnSetfocusRightEyeY();
|
||||
afx_msg void OnSetfocusRightEyeZ();
|
||||
afx_msg void OnSetfocusLeftEyeX();
|
||||
afx_msg void OnSetfocusLeftEyeY();
|
||||
afx_msg void OnSetfocusLeftEyeZ();
|
||||
afx_msg void OnSetfocusUpperLidLowered();
|
||||
afx_msg void OnSetfocusUpperLidNeutral();
|
||||
afx_msg void OnSetfocusUpperLidRaised();
|
||||
afx_msg void OnSetfocusLowerLidLowered();
|
||||
afx_msg void OnSetfocusLowerLidNeutral();
|
||||
afx_msg void OnSetfocusLowerLidRaised();
|
||||
afx_msg void OnCopyTextToClipboard();
|
||||
afx_msg void OnDefaultControls();
|
||||
afx_msg void OnAdvancedControls();
|
||||
afx_msg void OnLeftLidControl();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_QC_EYESDLG_H__9130E22D_05ED_4851_960C_38D90DA94967__INCLUDED_)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// QC_Eyes.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// QC_Eyes.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#if !defined(AFX_STDAFX_H__88FA48B3_A92C_49CA_8A82_50D120A84756__INCLUDED_)
|
||||
#define AFX_STDAFX_H__88FA48B3_A92C_49CA_8A82_50D120A84756__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#include <afxwin.h> // MFC core and standard components
|
||||
#include <afxext.h> // MFC extensions
|
||||
#include <afxdisp.h> // MFC Automation classes
|
||||
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
|
||||
#ifndef _AFX_NO_AFXCMN_SUPPORT
|
||||
#include <afxcmn.h> // MFC support for Windows Common Controls
|
||||
#endif // _AFX_NO_AFXCMN_SUPPORT
|
||||
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__88FA48B3_A92C_49CA_8A82_50D120A84756__INCLUDED_)
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#if !defined(AFX_STDAFX_H__88FA48B3_A92C_49CA_8A82_50D120A84756__INCLUDED_)
|
||||
#define AFX_STDAFX_H__88FA48B3_A92C_49CA_8A82_50D120A84756__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#include <afxwin.h> // MFC core and standard components
|
||||
#include <afxext.h> // MFC extensions
|
||||
#include <afxdisp.h> // MFC Automation classes
|
||||
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
|
||||
#ifndef _AFX_NO_AFXCMN_SUPPORT
|
||||
#include <afxcmn.h> // MFC support for Windows Common Controls
|
||||
#endif // _AFX_NO_AFXCMN_SUPPORT
|
||||
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__88FA48B3_A92C_49CA_8A82_50D120A84756__INCLUDED_)
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// QC_EYES.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)"
|
||||
$PrecompiledHeaderFile "Debug/QC_Eyes.pch"
|
||||
$EnableC++Exceptions "Yes (/EHsc)"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "QC_Eyes"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
-$File "$SRCDIR\public\tier0\memoverride.cpp"
|
||||
|
||||
$File "QC_Eyes.cpp"
|
||||
$File "QC_Eyes.rc"
|
||||
$File "QC_EyesDlg.cpp"
|
||||
$File "StdAfx.cpp"
|
||||
{
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$Create/UsePrecompiledHeader "Create Precompiled Header (/Yc)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "QC_Eyes.h"
|
||||
$File "QC_EyesDlg.h"
|
||||
$File "Resource.h"
|
||||
$File "StdAfx.h"
|
||||
}
|
||||
|
||||
$Folder "Resources"
|
||||
{
|
||||
$File "res\eye_default.bmp"
|
||||
$File "res\eye_lower_hi.bmp"
|
||||
$File "res\eye_lower_lo.bmp"
|
||||
$File "res\eye_lower_mid.bmp"
|
||||
$File "res\eye_upper_hi.bmp"
|
||||
$File "res\eye_upper_lo.bmp"
|
||||
$File "res\eye_upper_mid.bmp"
|
||||
$File "res\eye_XY_L.bmp"
|
||||
$File "res\eye_XY_R.bmp"
|
||||
$File "res\eye_Z_L.bmp"
|
||||
$File "res\eye_Z_R.bmp"
|
||||
$File "res\QC_Eyes.ico"
|
||||
$File "res\QC_Eyes.rc2"
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// QC_EYES.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)"
|
||||
$PrecompiledHeaderFile "Debug/QC_Eyes.pch"
|
||||
$EnableC++Exceptions "Yes (/EHsc)"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "QC_Eyes"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
-$File "$SRCDIR\public\tier0\memoverride.cpp"
|
||||
|
||||
$File "QC_Eyes.cpp"
|
||||
$File "QC_Eyes.rc"
|
||||
$File "QC_EyesDlg.cpp"
|
||||
$File "StdAfx.cpp"
|
||||
{
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$Create/UsePrecompiledHeader "Create Precompiled Header (/Yc)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "QC_Eyes.h"
|
||||
$File "QC_EyesDlg.h"
|
||||
$File "Resource.h"
|
||||
$File "StdAfx.h"
|
||||
}
|
||||
|
||||
$Folder "Resources"
|
||||
{
|
||||
$File "res\eye_default.bmp"
|
||||
$File "res\eye_lower_hi.bmp"
|
||||
$File "res\eye_lower_lo.bmp"
|
||||
$File "res\eye_lower_mid.bmp"
|
||||
$File "res\eye_upper_hi.bmp"
|
||||
$File "res\eye_upper_lo.bmp"
|
||||
$File "res\eye_upper_mid.bmp"
|
||||
$File "res\eye_XY_L.bmp"
|
||||
$File "res\eye_XY_R.bmp"
|
||||
$File "res\eye_Z_L.bmp"
|
||||
$File "res\eye_Z_R.bmp"
|
||||
$File "res\QC_Eyes.ico"
|
||||
$File "res\QC_Eyes.rc2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +1,78 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by QC_Eyes.rc
|
||||
//
|
||||
#define IDD_QC_EYES_DIALOG 102
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDB_EYE_DEFAULT 150
|
||||
#define IDB_EYE_LOWER_HI 151
|
||||
#define IDB_EYE_LOWER_LO 152
|
||||
#define IDB_EYE_LOWER_MID 153
|
||||
#define IDB_EYE_UPPER_HI 154
|
||||
#define IDB_EYE_UPPER_LO 155
|
||||
#define IDB_EYE_UPPER_MID 156
|
||||
#define IDB_EYE_XY_L 157
|
||||
#define IDB_EYE_XY_R 158
|
||||
#define IDB_EYE_Z_L 159
|
||||
#define IDB_EYE_Z_R 160
|
||||
#define IDC_REFERENCE_FILENAME 1000
|
||||
#define IDC_EXPRESSIONS_FILENAME 1001
|
||||
#define IDC_MODEL_FILENAME 1002
|
||||
#define IDC_RIGHT_EYE_X 1003
|
||||
#define IDC_RIGHT_EYE_Y 1004
|
||||
#define IDC_RIGHT_EYE_Z 1005
|
||||
#define IDC_LEFT_EYE_X 1006
|
||||
#define IDC_LEFT_EYE_Y 1007
|
||||
#define IDC_LEFT_EYE_Z 1008
|
||||
#define IDC_Y_AXIS_UP 1009
|
||||
#define IDC_Z_AXIS_UP 1010
|
||||
#define IDC_DEFAULT_CONTROLS 1011
|
||||
#define IDC_ADVANCED_CONTROLS 1012
|
||||
#define IDC_UPPER_LID_RAISED 1013
|
||||
#define IDC_OUTPUT_TEXT 1014
|
||||
#define IDC_UPPER_LEFT_LID_RAISED 1015
|
||||
#define IDC_UPPER_LID_LOWERED 1016
|
||||
#define IDC_UPPER_LID_NEUTRAL 1017
|
||||
#define IDC_LOWER_LID_RAISED 1018
|
||||
#define IDC_LOWER_LID_LOWERED 1019
|
||||
#define IDC_LOWER_LID_NEUTRAL 1020
|
||||
#define IDC_IRIS_COLOR_GREEN 1021
|
||||
#define IDC_IRIS_COLOR_BLUE 1022
|
||||
#define IDC_IRIS_COLOR_BROWN 1023
|
||||
#define IDC_EYE_COLOR_LIGHT 1024
|
||||
#define IDC_EYE_COLOR_DARK 1025
|
||||
#define IDC_IRIS_SIZE 1026
|
||||
#define IDC_CREATE_QC_TEXT 1027
|
||||
#define IDC_EYEBALL_SIZE 1028
|
||||
#define IDC_COPY_TEXT_TO_CLIPBOARD 1029
|
||||
#define IDC_PICTURES 1030
|
||||
#define IDC_PICTURE_LABEL 1031
|
||||
#define IDC_LEFT_LID_CONTROL 1032
|
||||
#define IDC_UPPER_LEFT_LID_NEUTRAL 1033
|
||||
#define IDC_UPPER_LEFT_LID_LOWERED 1034
|
||||
#define IDC_LOWER_LEFT_LID_RAISED 1035
|
||||
#define IDC_LOWER_LEFT_LID_NEUTRAL 1036
|
||||
#define IDC_LOWER_LEFT_LID_LOWERED 1037
|
||||
#define IDC_EYE_DETAIL_CONTROL_FRAME 1038
|
||||
#define IDC_IRIS_SIZE_LABEL 1039
|
||||
#define IDC_EYEBALL_SIZE_LABEL 1040
|
||||
#define IDC_UPPER_LEFT_LID_PANEL 1041
|
||||
#define IDC_UPPER_LEFT_LID_RAISED_LABEL 1042
|
||||
#define IDC_UPPER_LEFT_LID_NEUTRAL_LABEL 1043
|
||||
#define IDC_UPPER_LEFT_LID_LOWERED_LABEL 1044
|
||||
#define IDC_LOWER_LEFT_LID_PANEL 1045
|
||||
#define IDC_LOWER_LEFT_LID_RAISED_LABEL 1046
|
||||
#define IDC_LOWER_LEFT_LID_NEUTRAL_LABEL 1047
|
||||
#define IDC_LOWER_LEFT_LID_LOWERED_LABEL 1048
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 130
|
||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||
#define _APS_NEXT_CONTROL_VALUE 1049
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by QC_Eyes.rc
|
||||
//
|
||||
#define IDD_QC_EYES_DIALOG 102
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDB_EYE_DEFAULT 150
|
||||
#define IDB_EYE_LOWER_HI 151
|
||||
#define IDB_EYE_LOWER_LO 152
|
||||
#define IDB_EYE_LOWER_MID 153
|
||||
#define IDB_EYE_UPPER_HI 154
|
||||
#define IDB_EYE_UPPER_LO 155
|
||||
#define IDB_EYE_UPPER_MID 156
|
||||
#define IDB_EYE_XY_L 157
|
||||
#define IDB_EYE_XY_R 158
|
||||
#define IDB_EYE_Z_L 159
|
||||
#define IDB_EYE_Z_R 160
|
||||
#define IDC_REFERENCE_FILENAME 1000
|
||||
#define IDC_EXPRESSIONS_FILENAME 1001
|
||||
#define IDC_MODEL_FILENAME 1002
|
||||
#define IDC_RIGHT_EYE_X 1003
|
||||
#define IDC_RIGHT_EYE_Y 1004
|
||||
#define IDC_RIGHT_EYE_Z 1005
|
||||
#define IDC_LEFT_EYE_X 1006
|
||||
#define IDC_LEFT_EYE_Y 1007
|
||||
#define IDC_LEFT_EYE_Z 1008
|
||||
#define IDC_Y_AXIS_UP 1009
|
||||
#define IDC_Z_AXIS_UP 1010
|
||||
#define IDC_DEFAULT_CONTROLS 1011
|
||||
#define IDC_ADVANCED_CONTROLS 1012
|
||||
#define IDC_UPPER_LID_RAISED 1013
|
||||
#define IDC_OUTPUT_TEXT 1014
|
||||
#define IDC_UPPER_LEFT_LID_RAISED 1015
|
||||
#define IDC_UPPER_LID_LOWERED 1016
|
||||
#define IDC_UPPER_LID_NEUTRAL 1017
|
||||
#define IDC_LOWER_LID_RAISED 1018
|
||||
#define IDC_LOWER_LID_LOWERED 1019
|
||||
#define IDC_LOWER_LID_NEUTRAL 1020
|
||||
#define IDC_IRIS_COLOR_GREEN 1021
|
||||
#define IDC_IRIS_COLOR_BLUE 1022
|
||||
#define IDC_IRIS_COLOR_BROWN 1023
|
||||
#define IDC_EYE_COLOR_LIGHT 1024
|
||||
#define IDC_EYE_COLOR_DARK 1025
|
||||
#define IDC_IRIS_SIZE 1026
|
||||
#define IDC_CREATE_QC_TEXT 1027
|
||||
#define IDC_EYEBALL_SIZE 1028
|
||||
#define IDC_COPY_TEXT_TO_CLIPBOARD 1029
|
||||
#define IDC_PICTURES 1030
|
||||
#define IDC_PICTURE_LABEL 1031
|
||||
#define IDC_LEFT_LID_CONTROL 1032
|
||||
#define IDC_UPPER_LEFT_LID_NEUTRAL 1033
|
||||
#define IDC_UPPER_LEFT_LID_LOWERED 1034
|
||||
#define IDC_LOWER_LEFT_LID_RAISED 1035
|
||||
#define IDC_LOWER_LEFT_LID_NEUTRAL 1036
|
||||
#define IDC_LOWER_LEFT_LID_LOWERED 1037
|
||||
#define IDC_EYE_DETAIL_CONTROL_FRAME 1038
|
||||
#define IDC_IRIS_SIZE_LABEL 1039
|
||||
#define IDC_EYEBALL_SIZE_LABEL 1040
|
||||
#define IDC_UPPER_LEFT_LID_PANEL 1041
|
||||
#define IDC_UPPER_LEFT_LID_RAISED_LABEL 1042
|
||||
#define IDC_UPPER_LEFT_LID_NEUTRAL_LABEL 1043
|
||||
#define IDC_UPPER_LEFT_LID_LOWERED_LABEL 1044
|
||||
#define IDC_LOWER_LEFT_LID_PANEL 1045
|
||||
#define IDC_LOWER_LEFT_LID_RAISED_LABEL 1046
|
||||
#define IDC_LOWER_LEFT_LID_NEUTRAL_LABEL 1047
|
||||
#define IDC_LOWER_LEFT_LID_LOWERED_LABEL 1048
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 130
|
||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||
#define _APS_NEXT_CONTROL_VALUE 1049
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,383 +1,383 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Basic BOT handling.
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "interface.h"
|
||||
#include "filesystem.h"
|
||||
#undef VECTOR_NO_SLOW_OPERATIONS
|
||||
#include "mathlib/vector.h"
|
||||
|
||||
#include "eiface.h"
|
||||
#include "edict.h"
|
||||
#include "game/server/iplayerinfo.h"
|
||||
#include "igameevents.h"
|
||||
#include "convar.h"
|
||||
#include "vstdlib/random.h"
|
||||
#include "../../game/shared/in_buttons.h"
|
||||
#include "../../game/shared/shareddefs.h"
|
||||
//#include "../../game_shared/util_shared.h"
|
||||
#include "engine/IEngineTrace.h"
|
||||
|
||||
extern IBotManager *botmanager;
|
||||
extern IUniformRandomStream *randomStr;
|
||||
extern IPlayerInfoManager *playerinfomanager;
|
||||
extern IVEngineServer *engine;
|
||||
extern IEngineTrace *enginetrace;
|
||||
extern IPlayerInfoManager *playerinfomanager; // game dll interface to interact with players
|
||||
extern IServerPluginHelpers *helpers; // special 3rd party plugin helpers from the engine
|
||||
|
||||
extern CGlobalVars *gpGlobals;
|
||||
|
||||
ConVar bot_forcefireweapon( "plugin_bot_forcefireweapon", "", 0, "Force bots with the specified weapon to fire." );
|
||||
ConVar bot_forceattack2( "plugin_bot_forceattack2", "0", 0, "When firing, use attack2." );
|
||||
ConVar bot_forceattackon( "plugin_bot_forceattackon", "0", 0, "When firing, don't tap fire, hold it down." );
|
||||
ConVar bot_flipout( "plugin_bot_flipout", "0", 0, "When on, all bots fire their guns." );
|
||||
ConVar bot_changeclass( "plugin_bot_changeclass", "0", 0, "Force all bots to change to the specified class." );
|
||||
static ConVar bot_mimic( "plugin_bot_mimic", "0", 0, "Bot uses usercmd of player by index." );
|
||||
static ConVar bot_mimic_yaw_offset( "plugin_bot_mimic_yaw_offset", "0", 0, "Offsets the bot yaw." );
|
||||
|
||||
ConVar bot_sendcmd( "plugin_bot_sendcmd", "", 0, "Forces bots to send the specified command." );
|
||||
ConVar bot_crouch( "plugin_bot_crouch", "0", 0, "Bot crouches" );
|
||||
|
||||
|
||||
// This is our bot class.
|
||||
class CPluginBot
|
||||
{
|
||||
public:
|
||||
CPluginBot() :
|
||||
m_bBackwards(0),
|
||||
m_flNextTurnTime(0),
|
||||
m_bLastTurnToRight(0),
|
||||
m_flNextStrafeTime(0),
|
||||
m_flSideMove(0),
|
||||
m_ForwardAngle(),
|
||||
m_LastAngles()
|
||||
{
|
||||
}
|
||||
|
||||
bool m_bBackwards;
|
||||
|
||||
float m_flNextTurnTime;
|
||||
bool m_bLastTurnToRight;
|
||||
|
||||
float m_flNextStrafeTime;
|
||||
float m_flSideMove;
|
||||
|
||||
QAngle m_ForwardAngle;
|
||||
QAngle m_LastAngles;
|
||||
|
||||
IBotController *m_BotInterface;
|
||||
IPlayerInfo *m_PlayerInfo;
|
||||
edict_t *m_BotEdict;
|
||||
};
|
||||
|
||||
CUtlVector<CPluginBot> s_Bots;
|
||||
|
||||
void Bot_Think( CPluginBot *pBot );
|
||||
|
||||
// Handler for the "bot" command.
|
||||
void BotAdd_f()
|
||||
{
|
||||
if ( !botmanager )
|
||||
return;
|
||||
|
||||
static int s_BotNum = 0;
|
||||
char botName[64];
|
||||
Q_snprintf( botName, sizeof(botName), "Bot_%i", s_BotNum );
|
||||
s_BotNum++;
|
||||
|
||||
edict_t *botEdict = botmanager->CreateBot( botName );
|
||||
if ( botEdict )
|
||||
{
|
||||
int botIndex = s_Bots.AddToTail();
|
||||
CPluginBot & bot = s_Bots[ botIndex ];
|
||||
bot.m_BotInterface = botmanager->GetBotController( botEdict );
|
||||
bot.m_PlayerInfo = playerinfomanager->GetPlayerInfo( botEdict );
|
||||
bot.m_BotEdict = botEdict;
|
||||
Assert( bot.m_BotInterface );
|
||||
}
|
||||
}
|
||||
|
||||
ConCommand cc_Bot( "plugin_bot_add", BotAdd_f, "Add a bot." );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run through all the Bots in the game and let them think.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bot_RunAll( void )
|
||||
{
|
||||
if ( !botmanager )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i < s_Bots.Count(); i++ )
|
||||
{
|
||||
CPluginBot & bot = s_Bots[i];
|
||||
if ( bot.m_BotEdict->IsFree() || !bot.m_BotEdict->GetUnknown()|| !bot.m_PlayerInfo->IsConnected() )
|
||||
{
|
||||
s_Bots.Remove(i);
|
||||
--i;
|
||||
}
|
||||
else
|
||||
{
|
||||
Bot_Think( &bot );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Bot_RunMimicCommand( CBotCmd& cmd )
|
||||
{
|
||||
if ( bot_mimic.GetInt() <= 0 )
|
||||
return false;
|
||||
|
||||
if ( bot_mimic.GetInt() > gpGlobals->maxClients )
|
||||
return false;
|
||||
|
||||
IPlayerInfo *playerInfo = playerinfomanager->GetPlayerInfo( engine->PEntityOfEntIndex( bot_mimic.GetInt() ) );
|
||||
if ( !playerInfo )
|
||||
return false;
|
||||
|
||||
cmd = playerInfo->GetLastUserCommand();
|
||||
cmd.viewangles[YAW] += bot_mimic_yaw_offset.GetFloat();
|
||||
|
||||
if( bot_crouch.GetInt() )
|
||||
cmd.buttons |= IN_DUCK;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Bot_UpdateStrafing( CPluginBot *pBot, CBotCmd &cmd )
|
||||
{
|
||||
if ( gpGlobals->curtime >= pBot->m_flNextStrafeTime )
|
||||
{
|
||||
pBot->m_flNextStrafeTime = gpGlobals->curtime + 1.0f;
|
||||
|
||||
if ( randomStr->RandomInt( 0, 5 ) == 0 )
|
||||
{
|
||||
pBot->m_flSideMove = -600.0f + 1200.0f * randomStr->RandomFloat( 0, 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->m_flSideMove = 0;
|
||||
}
|
||||
cmd.sidemove = pBot->m_flSideMove;
|
||||
|
||||
if ( randomStr->RandomInt( 0, 20 ) == 0 )
|
||||
{
|
||||
pBot->m_bBackwards = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->m_bBackwards = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Bot_UpdateDirection( CPluginBot *pBot )
|
||||
{
|
||||
float angledelta = 15.0;
|
||||
|
||||
int maxtries = (int)360.0/angledelta;
|
||||
|
||||
if ( pBot->m_bLastTurnToRight )
|
||||
{
|
||||
angledelta = -angledelta;
|
||||
}
|
||||
|
||||
QAngle angle( pBot->m_BotInterface->GetLocalAngles() );
|
||||
|
||||
trace_t trace;
|
||||
Vector vecSrc, vecEnd, forward;
|
||||
while ( --maxtries >= 0 )
|
||||
{
|
||||
AngleVectors( angle, &forward );
|
||||
|
||||
vecSrc = pBot->m_BotInterface->GetLocalOrigin() + Vector( 0, 0, 36 );
|
||||
vecEnd = vecSrc + forward * 10;
|
||||
|
||||
Ray_t ray;
|
||||
ray.Init( vecSrc, vecEnd, Vector(-16, -16, 0 ), Vector( 16, 16, 72 ) );
|
||||
CTraceFilterWorldAndPropsOnly traceFilter;
|
||||
enginetrace->TraceRay( ray, MASK_PLAYERSOLID, &traceFilter, &trace );
|
||||
|
||||
if ( trace.fraction == 1.0 )
|
||||
{
|
||||
if ( gpGlobals->curtime < pBot->m_flNextTurnTime )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
angle.y += angledelta;
|
||||
|
||||
if ( angle.y > 180 )
|
||||
angle.y -= 360;
|
||||
else if ( angle.y < -180 )
|
||||
angle.y += 360;
|
||||
|
||||
pBot->m_flNextTurnTime = gpGlobals->curtime + 2.0;
|
||||
pBot->m_bLastTurnToRight = randomStr->RandomInt( 0, 1 ) == 0 ? true : false;
|
||||
|
||||
pBot->m_ForwardAngle = angle;
|
||||
pBot->m_LastAngles = angle;
|
||||
}
|
||||
|
||||
pBot->m_BotInterface->SetLocalAngles( angle );
|
||||
}
|
||||
|
||||
|
||||
void Bot_FlipOut( CPluginBot *pBot, CBotCmd &cmd )
|
||||
{
|
||||
if ( bot_flipout.GetInt() > 0 && !pBot->m_PlayerInfo->IsDead() )
|
||||
{
|
||||
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
|
||||
{
|
||||
cmd.buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
|
||||
}
|
||||
|
||||
if ( bot_flipout.GetInt() >= 2 )
|
||||
{
|
||||
QAngle angOffset = RandomAngle( -1, 1 );
|
||||
|
||||
pBot->m_LastAngles += angOffset;
|
||||
|
||||
for ( int i = 0 ; i < 2; i++ )
|
||||
{
|
||||
if ( fabs( pBot->m_LastAngles[ i ] - pBot->m_ForwardAngle[ i ] ) > 15.0f )
|
||||
{
|
||||
if ( pBot->m_LastAngles[ i ] > pBot->m_ForwardAngle[ i ] )
|
||||
{
|
||||
pBot->m_LastAngles[ i ] = pBot->m_ForwardAngle[ i ] + 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->m_LastAngles[ i ] = pBot->m_ForwardAngle[ i ] - 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pBot->m_LastAngles[ 2 ] = 0;
|
||||
|
||||
pBot->m_BotInterface->SetLocalAngles( pBot->m_LastAngles );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Bot_HandleSendCmd( CPluginBot *pBot )
|
||||
{
|
||||
if ( strlen( bot_sendcmd.GetString() ) > 0 )
|
||||
{
|
||||
//send the cmd from this bot
|
||||
helpers->ClientCommand( pBot->m_BotEdict, bot_sendcmd.GetString() );
|
||||
|
||||
bot_sendcmd.SetValue("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If bots are being forced to fire a weapon, see if I have it
|
||||
void Bot_ForceFireWeapon( CPluginBot *pBot, CBotCmd &cmd )
|
||||
{
|
||||
if ( Q_strlen( bot_forcefireweapon.GetString() ) > 0 )
|
||||
{
|
||||
pBot->m_BotInterface->SetActiveWeapon( bot_forcefireweapon.GetString() );
|
||||
bot_forcefireweapon.SetValue( "" );
|
||||
// Start firing
|
||||
// Some weapons require releases, so randomise firing
|
||||
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
|
||||
{
|
||||
cmd.buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Bot_SetForwardMovement( CPluginBot *pBot, CBotCmd &cmd )
|
||||
{
|
||||
if ( !pBot->m_BotInterface->IsEFlagSet(EFL_BOT_FROZEN) )
|
||||
{
|
||||
if ( pBot->m_PlayerInfo->GetHealth() == 100 )
|
||||
{
|
||||
cmd.forwardmove = 600 * ( pBot->m_bBackwards ? -1 : 1 );
|
||||
if ( pBot->m_flSideMove != 0.0f )
|
||||
{
|
||||
cmd.forwardmove *= randomStr->RandomFloat( 0.1, 1.0f );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stop when shot
|
||||
cmd.forwardmove = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Bot_HandleRespawn( CPluginBot *pBot, CBotCmd &cmd )
|
||||
{
|
||||
// Wait for Reinforcement wave
|
||||
if ( pBot->m_PlayerInfo->IsDead() )
|
||||
{
|
||||
if ( pBot->m_PlayerInfo->GetTeamIndex() == 0 )
|
||||
{
|
||||
helpers->ClientCommand( pBot->m_BotEdict, "joingame" );
|
||||
helpers->ClientCommand( pBot->m_BotEdict, "jointeam 3" );
|
||||
helpers->ClientCommand( pBot->m_BotEdict, "joinclass 0" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Run this Bot's AI for one frame.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bot_Think( CPluginBot *pBot )
|
||||
{
|
||||
CBotCmd cmd;
|
||||
Q_memset( &cmd, 0, sizeof( cmd ) );
|
||||
|
||||
// Finally, override all this stuff if the bot is being forced to mimic a player.
|
||||
if ( !Bot_RunMimicCommand( cmd ) )
|
||||
{
|
||||
cmd.sidemove = pBot->m_flSideMove;
|
||||
|
||||
if ( !pBot->m_PlayerInfo->IsDead() )
|
||||
{
|
||||
Bot_SetForwardMovement( pBot, cmd );
|
||||
|
||||
// Only turn if I haven't been hurt
|
||||
if ( !pBot->m_BotInterface->IsEFlagSet(EFL_BOT_FROZEN) && pBot->m_PlayerInfo->GetHealth() == 100 )
|
||||
{
|
||||
Bot_UpdateDirection( pBot );
|
||||
Bot_UpdateStrafing( pBot, cmd );
|
||||
}
|
||||
|
||||
// Handle console settings.
|
||||
Bot_ForceFireWeapon( pBot, cmd );
|
||||
Bot_HandleSendCmd( pBot );
|
||||
}
|
||||
else
|
||||
{
|
||||
Bot_HandleRespawn( pBot, cmd );
|
||||
}
|
||||
|
||||
Bot_FlipOut( pBot, cmd );
|
||||
|
||||
cmd.viewangles = pBot->m_BotInterface->GetLocalAngles();
|
||||
cmd.upmove = 0;
|
||||
cmd.impulse = 0;
|
||||
}
|
||||
|
||||
pBot->m_BotInterface->RunPlayerMove( &cmd );
|
||||
}
|
||||
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Basic BOT handling.
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "interface.h"
|
||||
#include "filesystem.h"
|
||||
#undef VECTOR_NO_SLOW_OPERATIONS
|
||||
#include "mathlib/vector.h"
|
||||
|
||||
#include "eiface.h"
|
||||
#include "edict.h"
|
||||
#include "game/server/iplayerinfo.h"
|
||||
#include "igameevents.h"
|
||||
#include "convar.h"
|
||||
#include "vstdlib/random.h"
|
||||
#include "../../game/shared/in_buttons.h"
|
||||
#include "../../game/shared/shareddefs.h"
|
||||
//#include "../../game_shared/util_shared.h"
|
||||
#include "engine/IEngineTrace.h"
|
||||
|
||||
extern IBotManager *botmanager;
|
||||
extern IUniformRandomStream *randomStr;
|
||||
extern IPlayerInfoManager *playerinfomanager;
|
||||
extern IVEngineServer *engine;
|
||||
extern IEngineTrace *enginetrace;
|
||||
extern IPlayerInfoManager *playerinfomanager; // game dll interface to interact with players
|
||||
extern IServerPluginHelpers *helpers; // special 3rd party plugin helpers from the engine
|
||||
|
||||
extern CGlobalVars *gpGlobals;
|
||||
|
||||
ConVar bot_forcefireweapon( "plugin_bot_forcefireweapon", "", 0, "Force bots with the specified weapon to fire." );
|
||||
ConVar bot_forceattack2( "plugin_bot_forceattack2", "0", 0, "When firing, use attack2." );
|
||||
ConVar bot_forceattackon( "plugin_bot_forceattackon", "0", 0, "When firing, don't tap fire, hold it down." );
|
||||
ConVar bot_flipout( "plugin_bot_flipout", "0", 0, "When on, all bots fire their guns." );
|
||||
ConVar bot_changeclass( "plugin_bot_changeclass", "0", 0, "Force all bots to change to the specified class." );
|
||||
static ConVar bot_mimic( "plugin_bot_mimic", "0", 0, "Bot uses usercmd of player by index." );
|
||||
static ConVar bot_mimic_yaw_offset( "plugin_bot_mimic_yaw_offset", "0", 0, "Offsets the bot yaw." );
|
||||
|
||||
ConVar bot_sendcmd( "plugin_bot_sendcmd", "", 0, "Forces bots to send the specified command." );
|
||||
ConVar bot_crouch( "plugin_bot_crouch", "0", 0, "Bot crouches" );
|
||||
|
||||
|
||||
// This is our bot class.
|
||||
class CPluginBot
|
||||
{
|
||||
public:
|
||||
CPluginBot() :
|
||||
m_bBackwards(0),
|
||||
m_flNextTurnTime(0),
|
||||
m_bLastTurnToRight(0),
|
||||
m_flNextStrafeTime(0),
|
||||
m_flSideMove(0),
|
||||
m_ForwardAngle(),
|
||||
m_LastAngles()
|
||||
{
|
||||
}
|
||||
|
||||
bool m_bBackwards;
|
||||
|
||||
float m_flNextTurnTime;
|
||||
bool m_bLastTurnToRight;
|
||||
|
||||
float m_flNextStrafeTime;
|
||||
float m_flSideMove;
|
||||
|
||||
QAngle m_ForwardAngle;
|
||||
QAngle m_LastAngles;
|
||||
|
||||
IBotController *m_BotInterface;
|
||||
IPlayerInfo *m_PlayerInfo;
|
||||
edict_t *m_BotEdict;
|
||||
};
|
||||
|
||||
CUtlVector<CPluginBot> s_Bots;
|
||||
|
||||
void Bot_Think( CPluginBot *pBot );
|
||||
|
||||
// Handler for the "bot" command.
|
||||
void BotAdd_f()
|
||||
{
|
||||
if ( !botmanager )
|
||||
return;
|
||||
|
||||
static int s_BotNum = 0;
|
||||
char botName[64];
|
||||
Q_snprintf( botName, sizeof(botName), "Bot_%i", s_BotNum );
|
||||
s_BotNum++;
|
||||
|
||||
edict_t *botEdict = botmanager->CreateBot( botName );
|
||||
if ( botEdict )
|
||||
{
|
||||
int botIndex = s_Bots.AddToTail();
|
||||
CPluginBot & bot = s_Bots[ botIndex ];
|
||||
bot.m_BotInterface = botmanager->GetBotController( botEdict );
|
||||
bot.m_PlayerInfo = playerinfomanager->GetPlayerInfo( botEdict );
|
||||
bot.m_BotEdict = botEdict;
|
||||
Assert( bot.m_BotInterface );
|
||||
}
|
||||
}
|
||||
|
||||
ConCommand cc_Bot( "plugin_bot_add", BotAdd_f, "Add a bot." );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run through all the Bots in the game and let them think.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bot_RunAll( void )
|
||||
{
|
||||
if ( !botmanager )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i < s_Bots.Count(); i++ )
|
||||
{
|
||||
CPluginBot & bot = s_Bots[i];
|
||||
if ( bot.m_BotEdict->IsFree() || !bot.m_BotEdict->GetUnknown()|| !bot.m_PlayerInfo->IsConnected() )
|
||||
{
|
||||
s_Bots.Remove(i);
|
||||
--i;
|
||||
}
|
||||
else
|
||||
{
|
||||
Bot_Think( &bot );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Bot_RunMimicCommand( CBotCmd& cmd )
|
||||
{
|
||||
if ( bot_mimic.GetInt() <= 0 )
|
||||
return false;
|
||||
|
||||
if ( bot_mimic.GetInt() > gpGlobals->maxClients )
|
||||
return false;
|
||||
|
||||
IPlayerInfo *playerInfo = playerinfomanager->GetPlayerInfo( engine->PEntityOfEntIndex( bot_mimic.GetInt() ) );
|
||||
if ( !playerInfo )
|
||||
return false;
|
||||
|
||||
cmd = playerInfo->GetLastUserCommand();
|
||||
cmd.viewangles[YAW] += bot_mimic_yaw_offset.GetFloat();
|
||||
|
||||
if( bot_crouch.GetInt() )
|
||||
cmd.buttons |= IN_DUCK;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Bot_UpdateStrafing( CPluginBot *pBot, CBotCmd &cmd )
|
||||
{
|
||||
if ( gpGlobals->curtime >= pBot->m_flNextStrafeTime )
|
||||
{
|
||||
pBot->m_flNextStrafeTime = gpGlobals->curtime + 1.0f;
|
||||
|
||||
if ( randomStr->RandomInt( 0, 5 ) == 0 )
|
||||
{
|
||||
pBot->m_flSideMove = -600.0f + 1200.0f * randomStr->RandomFloat( 0, 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->m_flSideMove = 0;
|
||||
}
|
||||
cmd.sidemove = pBot->m_flSideMove;
|
||||
|
||||
if ( randomStr->RandomInt( 0, 20 ) == 0 )
|
||||
{
|
||||
pBot->m_bBackwards = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->m_bBackwards = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Bot_UpdateDirection( CPluginBot *pBot )
|
||||
{
|
||||
float angledelta = 15.0;
|
||||
|
||||
int maxtries = (int)360.0/angledelta;
|
||||
|
||||
if ( pBot->m_bLastTurnToRight )
|
||||
{
|
||||
angledelta = -angledelta;
|
||||
}
|
||||
|
||||
QAngle angle( pBot->m_BotInterface->GetLocalAngles() );
|
||||
|
||||
trace_t trace;
|
||||
Vector vecSrc, vecEnd, forward;
|
||||
while ( --maxtries >= 0 )
|
||||
{
|
||||
AngleVectors( angle, &forward );
|
||||
|
||||
vecSrc = pBot->m_BotInterface->GetLocalOrigin() + Vector( 0, 0, 36 );
|
||||
vecEnd = vecSrc + forward * 10;
|
||||
|
||||
Ray_t ray;
|
||||
ray.Init( vecSrc, vecEnd, Vector(-16, -16, 0 ), Vector( 16, 16, 72 ) );
|
||||
CTraceFilterWorldAndPropsOnly traceFilter;
|
||||
enginetrace->TraceRay( ray, MASK_PLAYERSOLID, &traceFilter, &trace );
|
||||
|
||||
if ( trace.fraction == 1.0 )
|
||||
{
|
||||
if ( gpGlobals->curtime < pBot->m_flNextTurnTime )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
angle.y += angledelta;
|
||||
|
||||
if ( angle.y > 180 )
|
||||
angle.y -= 360;
|
||||
else if ( angle.y < -180 )
|
||||
angle.y += 360;
|
||||
|
||||
pBot->m_flNextTurnTime = gpGlobals->curtime + 2.0;
|
||||
pBot->m_bLastTurnToRight = randomStr->RandomInt( 0, 1 ) == 0 ? true : false;
|
||||
|
||||
pBot->m_ForwardAngle = angle;
|
||||
pBot->m_LastAngles = angle;
|
||||
}
|
||||
|
||||
pBot->m_BotInterface->SetLocalAngles( angle );
|
||||
}
|
||||
|
||||
|
||||
void Bot_FlipOut( CPluginBot *pBot, CBotCmd &cmd )
|
||||
{
|
||||
if ( bot_flipout.GetInt() > 0 && !pBot->m_PlayerInfo->IsDead() )
|
||||
{
|
||||
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
|
||||
{
|
||||
cmd.buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
|
||||
}
|
||||
|
||||
if ( bot_flipout.GetInt() >= 2 )
|
||||
{
|
||||
QAngle angOffset = RandomAngle( -1, 1 );
|
||||
|
||||
pBot->m_LastAngles += angOffset;
|
||||
|
||||
for ( int i = 0 ; i < 2; i++ )
|
||||
{
|
||||
if ( fabs( pBot->m_LastAngles[ i ] - pBot->m_ForwardAngle[ i ] ) > 15.0f )
|
||||
{
|
||||
if ( pBot->m_LastAngles[ i ] > pBot->m_ForwardAngle[ i ] )
|
||||
{
|
||||
pBot->m_LastAngles[ i ] = pBot->m_ForwardAngle[ i ] + 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->m_LastAngles[ i ] = pBot->m_ForwardAngle[ i ] - 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pBot->m_LastAngles[ 2 ] = 0;
|
||||
|
||||
pBot->m_BotInterface->SetLocalAngles( pBot->m_LastAngles );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Bot_HandleSendCmd( CPluginBot *pBot )
|
||||
{
|
||||
if ( strlen( bot_sendcmd.GetString() ) > 0 )
|
||||
{
|
||||
//send the cmd from this bot
|
||||
helpers->ClientCommand( pBot->m_BotEdict, bot_sendcmd.GetString() );
|
||||
|
||||
bot_sendcmd.SetValue("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If bots are being forced to fire a weapon, see if I have it
|
||||
void Bot_ForceFireWeapon( CPluginBot *pBot, CBotCmd &cmd )
|
||||
{
|
||||
if ( Q_strlen( bot_forcefireweapon.GetString() ) > 0 )
|
||||
{
|
||||
pBot->m_BotInterface->SetActiveWeapon( bot_forcefireweapon.GetString() );
|
||||
bot_forcefireweapon.SetValue( "" );
|
||||
// Start firing
|
||||
// Some weapons require releases, so randomise firing
|
||||
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
|
||||
{
|
||||
cmd.buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Bot_SetForwardMovement( CPluginBot *pBot, CBotCmd &cmd )
|
||||
{
|
||||
if ( !pBot->m_BotInterface->IsEFlagSet(EFL_BOT_FROZEN) )
|
||||
{
|
||||
if ( pBot->m_PlayerInfo->GetHealth() == 100 )
|
||||
{
|
||||
cmd.forwardmove = 600 * ( pBot->m_bBackwards ? -1 : 1 );
|
||||
if ( pBot->m_flSideMove != 0.0f )
|
||||
{
|
||||
cmd.forwardmove *= randomStr->RandomFloat( 0.1, 1.0f );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stop when shot
|
||||
cmd.forwardmove = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Bot_HandleRespawn( CPluginBot *pBot, CBotCmd &cmd )
|
||||
{
|
||||
// Wait for Reinforcement wave
|
||||
if ( pBot->m_PlayerInfo->IsDead() )
|
||||
{
|
||||
if ( pBot->m_PlayerInfo->GetTeamIndex() == 0 )
|
||||
{
|
||||
helpers->ClientCommand( pBot->m_BotEdict, "joingame" );
|
||||
helpers->ClientCommand( pBot->m_BotEdict, "jointeam 3" );
|
||||
helpers->ClientCommand( pBot->m_BotEdict, "joinclass 0" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Run this Bot's AI for one frame.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Bot_Think( CPluginBot *pBot )
|
||||
{
|
||||
CBotCmd cmd;
|
||||
Q_memset( &cmd, 0, sizeof( cmd ) );
|
||||
|
||||
// Finally, override all this stuff if the bot is being forced to mimic a player.
|
||||
if ( !Bot_RunMimicCommand( cmd ) )
|
||||
{
|
||||
cmd.sidemove = pBot->m_flSideMove;
|
||||
|
||||
if ( !pBot->m_PlayerInfo->IsDead() )
|
||||
{
|
||||
Bot_SetForwardMovement( pBot, cmd );
|
||||
|
||||
// Only turn if I haven't been hurt
|
||||
if ( !pBot->m_BotInterface->IsEFlagSet(EFL_BOT_FROZEN) && pBot->m_PlayerInfo->GetHealth() == 100 )
|
||||
{
|
||||
Bot_UpdateDirection( pBot );
|
||||
Bot_UpdateStrafing( pBot, cmd );
|
||||
}
|
||||
|
||||
// Handle console settings.
|
||||
Bot_ForceFireWeapon( pBot, cmd );
|
||||
Bot_HandleSendCmd( pBot );
|
||||
}
|
||||
else
|
||||
{
|
||||
Bot_HandleRespawn( pBot, cmd );
|
||||
}
|
||||
|
||||
Bot_FlipOut( pBot, cmd );
|
||||
|
||||
cmd.viewangles = pBot->m_BotInterface->GetLocalAngles();
|
||||
cmd.upmove = 0;
|
||||
cmd.impulse = 0;
|
||||
}
|
||||
|
||||
pBot->m_BotInterface->RunPlayerMove( &cmd );
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,62 +1,62 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// SERVERPLUGIN_EMPTY.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,$SRCDIR\game\server,$SRCDIR\game\shared"
|
||||
$PreprocessorDefinitions "$BASE;serverplugin_emptyONLY;_MBCS"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE odbc32.lib odbccp32.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Serverplugin_empty"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "serverplugin_bot.cpp"
|
||||
$File "serverplugin_empty.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\Color.h"
|
||||
$File "$SRCDIR\public\tier0\dbg.h"
|
||||
$File "$SRCDIR\public\eiface.h"
|
||||
$File "$SRCDIR\public\filesystem.h"
|
||||
$File "$SRCDIR\public\tier0\icommandline.h"
|
||||
$File "$SRCDIR\public\igameevents.h"
|
||||
$File "$SRCDIR\public\tier1\interface.h"
|
||||
$File "$SRCDIR\public\game\server\iplayerinfo.h"
|
||||
$File "$SRCDIR\public\engine\iserverplugin.h"
|
||||
$File "$SRCDIR\public\tier1\KeyValues.h"
|
||||
$File "$SRCDIR\public\tier0\mem.h"
|
||||
$File "$SRCDIR\public\tier0\memalloc.h"
|
||||
$File "$SRCDIR\public\tier0\memdbgon.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\tier1\utlbuffer.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// SERVERPLUGIN_EMPTY.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,$SRCDIR\game\server,$SRCDIR\game\shared"
|
||||
$PreprocessorDefinitions "$BASE;serverplugin_emptyONLY;_MBCS"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE odbc32.lib odbccp32.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Serverplugin_empty"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "serverplugin_bot.cpp"
|
||||
$File "serverplugin_empty.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "$SRCDIR\public\Color.h"
|
||||
$File "$SRCDIR\public\tier0\dbg.h"
|
||||
$File "$SRCDIR\public\eiface.h"
|
||||
$File "$SRCDIR\public\filesystem.h"
|
||||
$File "$SRCDIR\public\tier0\icommandline.h"
|
||||
$File "$SRCDIR\public\igameevents.h"
|
||||
$File "$SRCDIR\public\tier1\interface.h"
|
||||
$File "$SRCDIR\public\game\server\iplayerinfo.h"
|
||||
$File "$SRCDIR\public\engine\iserverplugin.h"
|
||||
$File "$SRCDIR\public\tier1\KeyValues.h"
|
||||
$File "$SRCDIR\public\tier0\mem.h"
|
||||
$File "$SRCDIR\public\tier0\memalloc.h"
|
||||
$File "$SRCDIR\public\tier0\memdbgon.h"
|
||||
$File "$SRCDIR\public\tier1\strtools.h"
|
||||
$File "$SRCDIR\public\tier1\utlbuffer.h"
|
||||
$File "$SRCDIR\public\tier1\utlmemory.h"
|
||||
$File "$SRCDIR\public\tier1\utlvector.h"
|
||||
$File "$SRCDIR\public\vstdlib\vstdlib.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,178 +1,178 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
//===================================================================
|
||||
// Useful macros
|
||||
//
|
||||
#define CONSTRUCTOR
|
||||
#define DESTRUCTOR
|
||||
|
||||
#define EXPORT_THIS __declspec(dllexport)
|
||||
|
||||
#define DEFAULT_EXT _T("smd")
|
||||
|
||||
#define FStrEq(sz1, sz2) (strcmp((sz1), (sz2)) == 0)
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Class that implements the scene-export.
|
||||
//
|
||||
class SmdExportClass : public SceneExport
|
||||
{
|
||||
friend BOOL CALLBACK ExportOptionsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
friend class DumpModelTEP;
|
||||
friend class DumpDeformsTEP;
|
||||
|
||||
public:
|
||||
CONSTRUCTOR SmdExportClass (void);
|
||||
DESTRUCTOR ~SmdExportClass (void);
|
||||
|
||||
// Required by classes derived from SceneExport
|
||||
virtual int ExtCount (void) { return 1; }
|
||||
virtual const TCHAR* Ext (int i) { return DEFAULT_EXT; }
|
||||
virtual const TCHAR* LongDesc (void) { return _T("Valve Skeletal Model Exporter for 3D Studio Max"); }
|
||||
virtual const TCHAR* ShortDesc (void) { return _T("Valve SMD"); }
|
||||
virtual const TCHAR* AuthorName (void) { return _T("Valve, LLC"); }
|
||||
virtual const TCHAR* CopyrightMessage(void) { return _T("Copyright (c) 1998, Valve LLC"); }
|
||||
virtual const TCHAR* OtherMessage1 (void) { return _T(""); }
|
||||
virtual const TCHAR* OtherMessage2 (void) { return _T(""); }
|
||||
virtual unsigned int Version (void) { return 201; }
|
||||
virtual void ShowAbout (HWND hWnd) { return; }
|
||||
// virtual int DoExport (const TCHAR *name, ExpInterface *ei, Interface *i);
|
||||
virtual int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE,DWORD options=0); // Export file
|
||||
|
||||
// Integer constants for this class
|
||||
enum
|
||||
{
|
||||
MAX_NAME_CHARS = 70,
|
||||
UNDESIRABLE_NODE_MARKER = -7777
|
||||
};
|
||||
|
||||
// For keeping info about each (non-ignored) 3dsMax node in the tree
|
||||
typedef struct
|
||||
{
|
||||
char szNodeName[MAX_NAME_CHARS]; // usefull for lookups
|
||||
Matrix3 mat3NodeTM; // node's transformation matrix (at time zero)
|
||||
Matrix3 mat3ObjectTM; // object-offset transformation matrix (at time zero)
|
||||
int imaxnodeParent; // cached index of parent node
|
||||
float xRotFirstFrame; // 1st frame's X rotation
|
||||
float yRotFirstFrame; // 1st frame's Y rotation
|
||||
float zRotFirstFrame; // 1st frame's Z rotation
|
||||
bool isMirrored;
|
||||
} MaxNode;
|
||||
MaxNode *m_rgmaxnode; // array of nodes
|
||||
long m_imaxnodeMac; // # of nodes
|
||||
|
||||
// Animation metrics (gleaned from 3dsMax and cached for convenience)
|
||||
Interval m_intervalOfAnimation;
|
||||
TimeValue m_tvStart;
|
||||
TimeValue m_tvEnd;
|
||||
int m_tpf; // ticks-per-frame
|
||||
|
||||
private:
|
||||
BOOL CollectNodes (ExpInterface *expiface);
|
||||
BOOL DumpBones (FILE *pFile, ExpInterface *pexpiface);
|
||||
BOOL DumpRotations (FILE *pFile, ExpInterface *pexpiface);
|
||||
BOOL DumpModel (FILE *pFile, ExpInterface *pexpiface);
|
||||
BOOL DumpDeforms (FILE *pFile, ExpInterface *pexpiface);
|
||||
|
||||
// Is this MAX file just the reference frame, or an animation?
|
||||
// If TRUE, the "bones" and "mesh" files will be created.
|
||||
// If FALSE, the "rots" file will be created.
|
||||
BOOL m_fReferenceFrame;
|
||||
};
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Basically just a ClassFactory for communicating with 3DSMAX.
|
||||
//
|
||||
class SmdExportClassDesc : public ClassDesc
|
||||
{
|
||||
public:
|
||||
int IsPublic (void) { return TRUE; }
|
||||
void * Create (BOOL loading=FALSE) { return new SmdExportClass; }
|
||||
const TCHAR * ClassName (void) { return _T("SmdExport"); }
|
||||
SClass_ID SuperClassID (void) { return SCENE_EXPORT_CLASS_ID; }
|
||||
Class_ID ClassID (void) { return Class_ID(0x774a43fd, 0x794d2210); }
|
||||
const TCHAR * Category (void) { return _T(""); }
|
||||
};
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Tree Enumeration Callback
|
||||
// Just counts the nodes in the node tree
|
||||
//
|
||||
class CountNodesTEP : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
virtual int callback(INode *node);
|
||||
int m_cNodes; // running count of nodes
|
||||
};
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Tree Enumeration Callback
|
||||
// Collects the nodes in the tree into the global array
|
||||
//
|
||||
class CollectNodesTEP : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
virtual int callback(INode *node);
|
||||
SmdExportClass *m_phec;
|
||||
};
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Tree Enumeration Callback
|
||||
// Dumps the bone offsets to a file.
|
||||
//
|
||||
class DumpNodesTEP : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
virtual int callback(INode *node);
|
||||
FILE *m_pfile; // write to this file
|
||||
SmdExportClass *m_phec;
|
||||
};
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Tree Enumeration Callback
|
||||
// Dumps the per-frame bone rotations to a file.
|
||||
//
|
||||
class DumpFrameRotationsTEP : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
virtual int callback(INode *node);
|
||||
void cleanup(void);
|
||||
FILE *m_pfile; // write to this file
|
||||
TimeValue m_tvToDump; // dump snapshot at this frame time
|
||||
SmdExportClass *m_phec;
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
// Tree Enumeration Callback
|
||||
// Dumps the triangle meshes to a file.
|
||||
//
|
||||
class DumpModelTEP : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
virtual int callback(INode *node);
|
||||
void cleanup(void);
|
||||
FILE *m_pfile; // write to this file
|
||||
TimeValue m_tvToDump; // dump snapshot at this frame time
|
||||
SmdExportClass *m_phec;
|
||||
IPhyContextExport *m_mcExport;
|
||||
IPhysiqueExport *m_phyExport;
|
||||
Modifier *m_phyMod;
|
||||
Modifier *m_bonesProMod;
|
||||
BonesPro_WeightArray *m_wa;
|
||||
private:
|
||||
Point3 Pt3GetRVertexNormal(RVertex *prvertex, DWORD smGroupFace);
|
||||
void DumpWeights( int iVertex );
|
||||
};
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
//===================================================================
|
||||
// Useful macros
|
||||
//
|
||||
#define CONSTRUCTOR
|
||||
#define DESTRUCTOR
|
||||
|
||||
#define EXPORT_THIS __declspec(dllexport)
|
||||
|
||||
#define DEFAULT_EXT _T("smd")
|
||||
|
||||
#define FStrEq(sz1, sz2) (strcmp((sz1), (sz2)) == 0)
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Class that implements the scene-export.
|
||||
//
|
||||
class SmdExportClass : public SceneExport
|
||||
{
|
||||
friend BOOL CALLBACK ExportOptionsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
friend class DumpModelTEP;
|
||||
friend class DumpDeformsTEP;
|
||||
|
||||
public:
|
||||
CONSTRUCTOR SmdExportClass (void);
|
||||
DESTRUCTOR ~SmdExportClass (void);
|
||||
|
||||
// Required by classes derived from SceneExport
|
||||
virtual int ExtCount (void) { return 1; }
|
||||
virtual const TCHAR* Ext (int i) { return DEFAULT_EXT; }
|
||||
virtual const TCHAR* LongDesc (void) { return _T("Valve Skeletal Model Exporter for 3D Studio Max"); }
|
||||
virtual const TCHAR* ShortDesc (void) { return _T("Valve SMD"); }
|
||||
virtual const TCHAR* AuthorName (void) { return _T("Valve, LLC"); }
|
||||
virtual const TCHAR* CopyrightMessage(void) { return _T("Copyright (c) 1998, Valve LLC"); }
|
||||
virtual const TCHAR* OtherMessage1 (void) { return _T(""); }
|
||||
virtual const TCHAR* OtherMessage2 (void) { return _T(""); }
|
||||
virtual unsigned int Version (void) { return 201; }
|
||||
virtual void ShowAbout (HWND hWnd) { return; }
|
||||
// virtual int DoExport (const TCHAR *name, ExpInterface *ei, Interface *i);
|
||||
virtual int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE,DWORD options=0); // Export file
|
||||
|
||||
// Integer constants for this class
|
||||
enum
|
||||
{
|
||||
MAX_NAME_CHARS = 70,
|
||||
UNDESIRABLE_NODE_MARKER = -7777
|
||||
};
|
||||
|
||||
// For keeping info about each (non-ignored) 3dsMax node in the tree
|
||||
typedef struct
|
||||
{
|
||||
char szNodeName[MAX_NAME_CHARS]; // usefull for lookups
|
||||
Matrix3 mat3NodeTM; // node's transformation matrix (at time zero)
|
||||
Matrix3 mat3ObjectTM; // object-offset transformation matrix (at time zero)
|
||||
int imaxnodeParent; // cached index of parent node
|
||||
float xRotFirstFrame; // 1st frame's X rotation
|
||||
float yRotFirstFrame; // 1st frame's Y rotation
|
||||
float zRotFirstFrame; // 1st frame's Z rotation
|
||||
bool isMirrored;
|
||||
} MaxNode;
|
||||
MaxNode *m_rgmaxnode; // array of nodes
|
||||
long m_imaxnodeMac; // # of nodes
|
||||
|
||||
// Animation metrics (gleaned from 3dsMax and cached for convenience)
|
||||
Interval m_intervalOfAnimation;
|
||||
TimeValue m_tvStart;
|
||||
TimeValue m_tvEnd;
|
||||
int m_tpf; // ticks-per-frame
|
||||
|
||||
private:
|
||||
BOOL CollectNodes (ExpInterface *expiface);
|
||||
BOOL DumpBones (FILE *pFile, ExpInterface *pexpiface);
|
||||
BOOL DumpRotations (FILE *pFile, ExpInterface *pexpiface);
|
||||
BOOL DumpModel (FILE *pFile, ExpInterface *pexpiface);
|
||||
BOOL DumpDeforms (FILE *pFile, ExpInterface *pexpiface);
|
||||
|
||||
// Is this MAX file just the reference frame, or an animation?
|
||||
// If TRUE, the "bones" and "mesh" files will be created.
|
||||
// If FALSE, the "rots" file will be created.
|
||||
BOOL m_fReferenceFrame;
|
||||
};
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Basically just a ClassFactory for communicating with 3DSMAX.
|
||||
//
|
||||
class SmdExportClassDesc : public ClassDesc
|
||||
{
|
||||
public:
|
||||
int IsPublic (void) { return TRUE; }
|
||||
void * Create (BOOL loading=FALSE) { return new SmdExportClass; }
|
||||
const TCHAR * ClassName (void) { return _T("SmdExport"); }
|
||||
SClass_ID SuperClassID (void) { return SCENE_EXPORT_CLASS_ID; }
|
||||
Class_ID ClassID (void) { return Class_ID(0x774a43fd, 0x794d2210); }
|
||||
const TCHAR * Category (void) { return _T(""); }
|
||||
};
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Tree Enumeration Callback
|
||||
// Just counts the nodes in the node tree
|
||||
//
|
||||
class CountNodesTEP : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
virtual int callback(INode *node);
|
||||
int m_cNodes; // running count of nodes
|
||||
};
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Tree Enumeration Callback
|
||||
// Collects the nodes in the tree into the global array
|
||||
//
|
||||
class CollectNodesTEP : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
virtual int callback(INode *node);
|
||||
SmdExportClass *m_phec;
|
||||
};
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Tree Enumeration Callback
|
||||
// Dumps the bone offsets to a file.
|
||||
//
|
||||
class DumpNodesTEP : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
virtual int callback(INode *node);
|
||||
FILE *m_pfile; // write to this file
|
||||
SmdExportClass *m_phec;
|
||||
};
|
||||
|
||||
|
||||
//===================================================================
|
||||
// Tree Enumeration Callback
|
||||
// Dumps the per-frame bone rotations to a file.
|
||||
//
|
||||
class DumpFrameRotationsTEP : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
virtual int callback(INode *node);
|
||||
void cleanup(void);
|
||||
FILE *m_pfile; // write to this file
|
||||
TimeValue m_tvToDump; // dump snapshot at this frame time
|
||||
SmdExportClass *m_phec;
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
// Tree Enumeration Callback
|
||||
// Dumps the triangle meshes to a file.
|
||||
//
|
||||
class DumpModelTEP : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
virtual int callback(INode *node);
|
||||
void cleanup(void);
|
||||
FILE *m_pfile; // write to this file
|
||||
TimeValue m_tvToDump; // dump snapshot at this frame time
|
||||
SmdExportClass *m_phec;
|
||||
IPhyContextExport *m_mcExport;
|
||||
IPhysiqueExport *m_phyExport;
|
||||
Modifier *m_phyMod;
|
||||
Modifier *m_bonesProMod;
|
||||
BonesPro_WeightArray *m_wa;
|
||||
private:
|
||||
Point3 Pt3GetRVertexNormal(RVertex *prvertex, DWORD smGroupFace);
|
||||
void DumpWeights( int iVertex );
|
||||
};
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by smdlexp.rc
|
||||
//
|
||||
#define IDD_SMDLEXP_UI 101
|
||||
#define IDD_EXPORTOPTIONS 101
|
||||
#define IDC_CHECK_SKELETAL 1000
|
||||
#define IDC_CHECK_DEFORM 1001
|
||||
#define IDC_CHECK_REFFRAME 1002
|
||||
#define IDC_CHECK_PHYSIQUE 1003
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1006
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by smdlexp.rc
|
||||
//
|
||||
#define IDD_SMDLEXP_UI 101
|
||||
#define IDD_EXPORTOPTIONS 101
|
||||
#define IDC_CHECK_SKELETAL 1000
|
||||
#define IDC_CHECK_DEFORM 1001
|
||||
#define IDC_CHECK_REFFRAME 1002
|
||||
#define IDC_CHECK_PHYSIQUE 1003
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1006
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,184 +1,184 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <direct.h>
|
||||
#include "bitmap/tgaloader.h"
|
||||
#include "bitmap/tgawriter.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
void Usage( void )
|
||||
{
|
||||
printf( "Usage: tgadiff src1.tga src2.tga diff.tga\n" );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
if( argc != 4 )
|
||||
{
|
||||
Usage();
|
||||
}
|
||||
|
||||
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
|
||||
InitDefaultFileSystem();
|
||||
|
||||
char pCurrentDirectory[MAX_PATH];
|
||||
if ( _getcwd( pCurrentDirectory, sizeof(pCurrentDirectory) ) == NULL )
|
||||
{
|
||||
fprintf( stderr, "Unable to get the current directory\n" );
|
||||
return -1;
|
||||
}
|
||||
Q_FixSlashes( pCurrentDirectory );
|
||||
Q_StripTrailingSlash( pCurrentDirectory );
|
||||
|
||||
char pBuf[3][MAX_PATH];
|
||||
const char *pFileName[3];
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
if ( !Q_IsAbsolutePath( argv[i+1] ) )
|
||||
{
|
||||
Q_snprintf( pBuf[i], sizeof(pBuf[i]), "%s\\%s", pCurrentDirectory, argv[i+1] );
|
||||
pFileName[i] = pBuf[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
pFileName[i] = argv[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
int width1, height1;
|
||||
ImageFormat imageFormat1;
|
||||
float gamma1;
|
||||
|
||||
CUtlBuffer buf1;
|
||||
if ( !g_pFullFileSystem->ReadFile( pFileName[0], NULL, buf1 ) )
|
||||
{
|
||||
fprintf( stderr, "%s not found\n", pFileName[0] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !TGALoader::GetInfo( buf1, &width1, &height1, &imageFormat1, &gamma1 ) )
|
||||
{
|
||||
printf( "error loading %s\n", pFileName[0] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
int width2, height2;
|
||||
ImageFormat imageFormat2;
|
||||
float gamma2;
|
||||
|
||||
CUtlBuffer buf2;
|
||||
if ( !g_pFullFileSystem->ReadFile( pFileName[1], NULL, buf2 ) )
|
||||
{
|
||||
fprintf( stderr, "%s not found\n", pFileName[1] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !TGALoader::GetInfo( buf2, &width2, &height2, &imageFormat2, &gamma2 ) )
|
||||
{
|
||||
printf( "error loading %s\n", pFileName[1] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
if( width1 != width2 || height1 != height2 )
|
||||
{
|
||||
printf( "image dimensions different (%dx%d!=%dx%d): can't do diff for %s\n",
|
||||
width1, height1, width2, height2, pFileName[2] );
|
||||
exit( -1 );
|
||||
}
|
||||
#if 0
|
||||
// have to allow for different formats for now due to *.txt file screwup.
|
||||
if( imageFormat1 != imageFormat2 )
|
||||
{
|
||||
printf( "image format different (%s!=%s). . can't do diff for %s\n",
|
||||
ImageLoader::GetName( imageFormat1 ), ImageLoader::GetName( imageFormat2 ), pFileName[2] );
|
||||
exit( -1 );
|
||||
}
|
||||
#endif
|
||||
if( gamma1 != gamma2 )
|
||||
{
|
||||
printf( "image gamma different (%f!=%f). . can't do diff for %s\n", gamma1, gamma2, pFileName[2] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
unsigned char *pImage1Tmp = new unsigned char[ImageLoader::GetMemRequired( width1, height1, 1, imageFormat1, false )];
|
||||
unsigned char *pImage2Tmp = new unsigned char[ImageLoader::GetMemRequired( width2, height2, 1, imageFormat2, false )];
|
||||
|
||||
buf1.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
|
||||
if( !TGALoader::Load( pImage1Tmp, buf1, width1, height1, imageFormat1, 2.2f, false ) )
|
||||
{
|
||||
printf( "error loading %s\n", pFileName[0] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
buf2.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
|
||||
if( !TGALoader::Load( pImage2Tmp, buf2, width2, height2, imageFormat2, 2.2f, false ) )
|
||||
{
|
||||
printf( "error loading %s\n", pFileName[1] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
unsigned char *pImage1 = new unsigned char[ImageLoader::GetMemRequired( width1, height1, 1, IMAGE_FORMAT_ABGR8888, false )];
|
||||
unsigned char *pImage2 = new unsigned char[ImageLoader::GetMemRequired( width2, height2, 1, IMAGE_FORMAT_ABGR8888, false )];
|
||||
unsigned char *pDiff = new unsigned char[ImageLoader::GetMemRequired( width2, height2, 1, IMAGE_FORMAT_ABGR8888, false )];
|
||||
ImageLoader::ConvertImageFormat( pImage1Tmp, imageFormat1, pImage1, IMAGE_FORMAT_ABGR8888, width1, height1, 0, 0 );
|
||||
ImageLoader::ConvertImageFormat( pImage2Tmp, imageFormat2, pImage2, IMAGE_FORMAT_ABGR8888, width2, height2, 0, 0 );
|
||||
|
||||
int sizeInBytes = ImageLoader::SizeInBytes( IMAGE_FORMAT_ABGR8888 );
|
||||
bool isDifferent = false;
|
||||
for( int i = 0; i < width1 * height1 * sizeInBytes; i++ )
|
||||
{
|
||||
int d;
|
||||
d = pImage2[i] - pImage1[i];
|
||||
pDiff[i] = d > 0 ? d : -d;
|
||||
if( d != 0 )
|
||||
{
|
||||
isDifferent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !isDifferent )
|
||||
{
|
||||
printf( "Files are the same %s %s : not generating %s\n", pFileName[0], pFileName[1], pFileName[2] );
|
||||
exit( -1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Generating diff: %s!\n", pFileName[2] );
|
||||
}
|
||||
|
||||
ImageFormat dstImageFormat;
|
||||
// get rid of this until we get the formats matching
|
||||
// if( sizeInBytes == 3 )
|
||||
// {
|
||||
// dstImageFormat = IMAGE_FORMAT_RGB888;
|
||||
// }
|
||||
// else
|
||||
{
|
||||
dstImageFormat = IMAGE_FORMAT_RGBA8888;
|
||||
}
|
||||
|
||||
CUtlBuffer outBuffer;
|
||||
if ( !TGAWriter::WriteToBuffer( pDiff, outBuffer, width1, height1, dstImageFormat, dstImageFormat ) )
|
||||
{
|
||||
printf( "error writing %s to buffer\n", pFileName[2] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
if ( !g_pFullFileSystem->WriteFile( pFileName[2], NULL, outBuffer ) )
|
||||
{
|
||||
fprintf( stderr, "unable to write %s\n", pFileName[2] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <direct.h>
|
||||
#include "bitmap/tgaloader.h"
|
||||
#include "bitmap/tgawriter.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
void Usage( void )
|
||||
{
|
||||
printf( "Usage: tgadiff src1.tga src2.tga diff.tga\n" );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
if( argc != 4 )
|
||||
{
|
||||
Usage();
|
||||
}
|
||||
|
||||
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
|
||||
InitDefaultFileSystem();
|
||||
|
||||
char pCurrentDirectory[MAX_PATH];
|
||||
if ( _getcwd( pCurrentDirectory, sizeof(pCurrentDirectory) ) == NULL )
|
||||
{
|
||||
fprintf( stderr, "Unable to get the current directory\n" );
|
||||
return -1;
|
||||
}
|
||||
Q_FixSlashes( pCurrentDirectory );
|
||||
Q_StripTrailingSlash( pCurrentDirectory );
|
||||
|
||||
char pBuf[3][MAX_PATH];
|
||||
const char *pFileName[3];
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
if ( !Q_IsAbsolutePath( argv[i+1] ) )
|
||||
{
|
||||
Q_snprintf( pBuf[i], sizeof(pBuf[i]), "%s\\%s", pCurrentDirectory, argv[i+1] );
|
||||
pFileName[i] = pBuf[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
pFileName[i] = argv[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
int width1, height1;
|
||||
ImageFormat imageFormat1;
|
||||
float gamma1;
|
||||
|
||||
CUtlBuffer buf1;
|
||||
if ( !g_pFullFileSystem->ReadFile( pFileName[0], NULL, buf1 ) )
|
||||
{
|
||||
fprintf( stderr, "%s not found\n", pFileName[0] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !TGALoader::GetInfo( buf1, &width1, &height1, &imageFormat1, &gamma1 ) )
|
||||
{
|
||||
printf( "error loading %s\n", pFileName[0] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
int width2, height2;
|
||||
ImageFormat imageFormat2;
|
||||
float gamma2;
|
||||
|
||||
CUtlBuffer buf2;
|
||||
if ( !g_pFullFileSystem->ReadFile( pFileName[1], NULL, buf2 ) )
|
||||
{
|
||||
fprintf( stderr, "%s not found\n", pFileName[1] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !TGALoader::GetInfo( buf2, &width2, &height2, &imageFormat2, &gamma2 ) )
|
||||
{
|
||||
printf( "error loading %s\n", pFileName[1] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
if( width1 != width2 || height1 != height2 )
|
||||
{
|
||||
printf( "image dimensions different (%dx%d!=%dx%d): can't do diff for %s\n",
|
||||
width1, height1, width2, height2, pFileName[2] );
|
||||
exit( -1 );
|
||||
}
|
||||
#if 0
|
||||
// have to allow for different formats for now due to *.txt file screwup.
|
||||
if( imageFormat1 != imageFormat2 )
|
||||
{
|
||||
printf( "image format different (%s!=%s). . can't do diff for %s\n",
|
||||
ImageLoader::GetName( imageFormat1 ), ImageLoader::GetName( imageFormat2 ), pFileName[2] );
|
||||
exit( -1 );
|
||||
}
|
||||
#endif
|
||||
if( gamma1 != gamma2 )
|
||||
{
|
||||
printf( "image gamma different (%f!=%f). . can't do diff for %s\n", gamma1, gamma2, pFileName[2] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
unsigned char *pImage1Tmp = new unsigned char[ImageLoader::GetMemRequired( width1, height1, 1, imageFormat1, false )];
|
||||
unsigned char *pImage2Tmp = new unsigned char[ImageLoader::GetMemRequired( width2, height2, 1, imageFormat2, false )];
|
||||
|
||||
buf1.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
|
||||
if( !TGALoader::Load( pImage1Tmp, buf1, width1, height1, imageFormat1, 2.2f, false ) )
|
||||
{
|
||||
printf( "error loading %s\n", pFileName[0] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
buf2.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
|
||||
if( !TGALoader::Load( pImage2Tmp, buf2, width2, height2, imageFormat2, 2.2f, false ) )
|
||||
{
|
||||
printf( "error loading %s\n", pFileName[1] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
unsigned char *pImage1 = new unsigned char[ImageLoader::GetMemRequired( width1, height1, 1, IMAGE_FORMAT_ABGR8888, false )];
|
||||
unsigned char *pImage2 = new unsigned char[ImageLoader::GetMemRequired( width2, height2, 1, IMAGE_FORMAT_ABGR8888, false )];
|
||||
unsigned char *pDiff = new unsigned char[ImageLoader::GetMemRequired( width2, height2, 1, IMAGE_FORMAT_ABGR8888, false )];
|
||||
ImageLoader::ConvertImageFormat( pImage1Tmp, imageFormat1, pImage1, IMAGE_FORMAT_ABGR8888, width1, height1, 0, 0 );
|
||||
ImageLoader::ConvertImageFormat( pImage2Tmp, imageFormat2, pImage2, IMAGE_FORMAT_ABGR8888, width2, height2, 0, 0 );
|
||||
|
||||
int sizeInBytes = ImageLoader::SizeInBytes( IMAGE_FORMAT_ABGR8888 );
|
||||
bool isDifferent = false;
|
||||
for( int i = 0; i < width1 * height1 * sizeInBytes; i++ )
|
||||
{
|
||||
int d;
|
||||
d = pImage2[i] - pImage1[i];
|
||||
pDiff[i] = d > 0 ? d : -d;
|
||||
if( d != 0 )
|
||||
{
|
||||
isDifferent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !isDifferent )
|
||||
{
|
||||
printf( "Files are the same %s %s : not generating %s\n", pFileName[0], pFileName[1], pFileName[2] );
|
||||
exit( -1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Generating diff: %s!\n", pFileName[2] );
|
||||
}
|
||||
|
||||
ImageFormat dstImageFormat;
|
||||
// get rid of this until we get the formats matching
|
||||
// if( sizeInBytes == 3 )
|
||||
// {
|
||||
// dstImageFormat = IMAGE_FORMAT_RGB888;
|
||||
// }
|
||||
// else
|
||||
{
|
||||
dstImageFormat = IMAGE_FORMAT_RGBA8888;
|
||||
}
|
||||
|
||||
CUtlBuffer outBuffer;
|
||||
if ( !TGAWriter::WriteToBuffer( pDiff, outBuffer, width1, height1, dstImageFormat, dstImageFormat ) )
|
||||
{
|
||||
printf( "error writing %s to buffer\n", pFileName[2] );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
if ( !g_pFullFileSystem->WriteFile( pFileName[2], NULL, outBuffer ) )
|
||||
{
|
||||
fprintf( stderr, "unable to write %s\n", pFileName[2] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// TGADIFF.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
$Project "Tgadiff"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "tgadiff.cpp"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib bitmap
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// TGADIFF.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
$Project "Tgadiff"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "tgadiff.cpp"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib bitmap
|
||||
$Lib mathlib
|
||||
$Lib tier2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,285 +1,285 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "vbsp.h"
|
||||
#include "BoundBox.h"
|
||||
//#include "hammer_mathlib.h"
|
||||
//#include "MapDefs.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
float rint(float f)
|
||||
{
|
||||
if (f > 0.0f) {
|
||||
return (float) floor(f + 0.5f);
|
||||
} else if (f < 0.0f) {
|
||||
return (float) ceil(f - 0.5f);
|
||||
} else
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
BoundBox::BoundBox(void)
|
||||
{
|
||||
ResetBounds();
|
||||
}
|
||||
|
||||
BoundBox::BoundBox(const Vector &mins, const Vector &maxs)
|
||||
{
|
||||
bmins = mins;
|
||||
bmaxs = maxs;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the box to an uninitialized state, so that calls to UpdateBounds
|
||||
// will properly set the mins and maxs.
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::ResetBounds(void)
|
||||
{
|
||||
bmins[0] = bmins[1] = bmins[2] = COORD_NOTINIT;
|
||||
bmaxs[0] = bmaxs[1] = bmaxs[2] = -COORD_NOTINIT;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pt -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::UpdateBounds(const Vector& pt)
|
||||
{
|
||||
if(pt[0] < bmins[0])
|
||||
bmins[0] = pt[0];
|
||||
if(pt[1] < bmins[1])
|
||||
bmins[1] = pt[1];
|
||||
if(pt[2] < bmins[2])
|
||||
bmins[2] = pt[2];
|
||||
|
||||
if(pt[0] > bmaxs[0])
|
||||
bmaxs[0] = pt[0];
|
||||
if(pt[1] > bmaxs[1])
|
||||
bmaxs[1] = pt[1];
|
||||
if(pt[2] > bmaxs[2])
|
||||
bmaxs[2] = pt[2];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bmins -
|
||||
// bmaxs -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::UpdateBounds(const Vector& mins, const Vector& maxs)
|
||||
{
|
||||
if(mins[0] < bmins[0])
|
||||
bmins[0] = mins[0];
|
||||
if(mins[1] < bmins[1])
|
||||
bmins[1] = mins[1];
|
||||
if(mins[2] < bmins[2])
|
||||
bmins[2] = mins[2];
|
||||
|
||||
if(maxs[0] > bmaxs[0])
|
||||
bmaxs[0] = maxs[0];
|
||||
if(maxs[1] > bmaxs[1])
|
||||
bmaxs[1] = maxs[1];
|
||||
if(maxs[2] > bmaxs[2])
|
||||
bmaxs[2] = maxs[2];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pBox -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::UpdateBounds(const BoundBox *pBox)
|
||||
{
|
||||
UpdateBounds(pBox->bmins, pBox->bmaxs);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : ptdest -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::GetBoundsCenter(Vector& ptdest)
|
||||
{
|
||||
ptdest = (bmins + bmaxs)/2.0f;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pt -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BoundBox::ContainsPoint(const Vector& pt) const
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (pt[i] < bmins[i] || pt[i] > bmaxs[i])
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pfMins -
|
||||
// pfMaxs -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BoundBox::IsIntersectingBox(const Vector& pfMins, const Vector& pfMaxs) const
|
||||
{
|
||||
if ((bmins[0] >= pfMaxs[0]) || (bmaxs[0] <= pfMins[0]))
|
||||
{
|
||||
return(false);
|
||||
|
||||
}
|
||||
if ((bmins[1] >= pfMaxs[1]) || (bmaxs[1] <= pfMins[1]))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
if ((bmins[2] >= pfMaxs[2]) || (bmaxs[2] <= pfMins[2]))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pfMins -
|
||||
// pfMaxs -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BoundBox::IsInsideBox(const Vector& pfMins, const Vector& pfMaxs) const
|
||||
{
|
||||
if ((bmins[0] < pfMins[0]) || (bmaxs[0] > pfMaxs[0]))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
if ((bmins[1] < pfMins[1]) || (bmaxs[1] > pfMaxs[1]))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
if ((bmins[2] < pfMins[2]) || (bmaxs[2] > pfMaxs[2]))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns whether this bounding box is valid, ie maxs >= mins.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BoundBox::IsValidBox(void) const
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (bmins[i] > bmaxs[i])
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : size -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::GetBoundsSize(Vector& size)
|
||||
{
|
||||
size[0] = bmaxs[0] - bmins[0];
|
||||
size[1] = bmaxs[1] - bmins[1];
|
||||
size[2] = bmaxs[2] - bmins[2];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : iValue -
|
||||
// iGridSize -
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
static int Snap(/*int*/ float iValue, int iGridSize)
|
||||
{
|
||||
return (int)(rint(iValue/iGridSize) * iGridSize);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : iGridSize -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::SnapToGrid(int iGridSize)
|
||||
{
|
||||
// does not alter the size of the box .. snaps its minimal coordinates
|
||||
// to the grid size specified in iGridSize
|
||||
Vector size;
|
||||
GetBoundsSize(size);
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
bmins[i] = (float)Snap(/* YWB (int)*/bmins[i], iGridSize);
|
||||
bmaxs[i] = bmins[i] + size[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : axis -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::Rotate90(int axis)
|
||||
{
|
||||
int e1 = AXIS_X, e2 = AXIS_Y;
|
||||
|
||||
// get bounds center first
|
||||
Vector center;
|
||||
GetBoundsCenter(center);
|
||||
|
||||
switch(axis)
|
||||
{
|
||||
case AXIS_Z:
|
||||
e1 = AXIS_X;
|
||||
e2 = AXIS_Y;
|
||||
break;
|
||||
case AXIS_X:
|
||||
e1 = AXIS_Y;
|
||||
e2 = AXIS_Z;
|
||||
break;
|
||||
case AXIS_Y:
|
||||
e1 = AXIS_X;
|
||||
e2 = AXIS_Z;
|
||||
break;
|
||||
}
|
||||
|
||||
float tmp1, tmp2;
|
||||
tmp1 = bmins[e1] - center[e1] + center[e2];
|
||||
tmp2 = bmaxs[e1] - center[e1] + center[e2];
|
||||
bmins[e1] = bmins[e2] - center[e2] + center[e1];
|
||||
bmaxs[e1] = bmaxs[e2] - center[e2] + center[e1];
|
||||
bmins[e2] = tmp1;
|
||||
bmaxs[e2] = tmp2;
|
||||
}
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "vbsp.h"
|
||||
#include "BoundBox.h"
|
||||
//#include "hammer_mathlib.h"
|
||||
//#include "MapDefs.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
float rint(float f)
|
||||
{
|
||||
if (f > 0.0f) {
|
||||
return (float) floor(f + 0.5f);
|
||||
} else if (f < 0.0f) {
|
||||
return (float) ceil(f - 0.5f);
|
||||
} else
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
BoundBox::BoundBox(void)
|
||||
{
|
||||
ResetBounds();
|
||||
}
|
||||
|
||||
BoundBox::BoundBox(const Vector &mins, const Vector &maxs)
|
||||
{
|
||||
bmins = mins;
|
||||
bmaxs = maxs;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the box to an uninitialized state, so that calls to UpdateBounds
|
||||
// will properly set the mins and maxs.
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::ResetBounds(void)
|
||||
{
|
||||
bmins[0] = bmins[1] = bmins[2] = COORD_NOTINIT;
|
||||
bmaxs[0] = bmaxs[1] = bmaxs[2] = -COORD_NOTINIT;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pt -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::UpdateBounds(const Vector& pt)
|
||||
{
|
||||
if(pt[0] < bmins[0])
|
||||
bmins[0] = pt[0];
|
||||
if(pt[1] < bmins[1])
|
||||
bmins[1] = pt[1];
|
||||
if(pt[2] < bmins[2])
|
||||
bmins[2] = pt[2];
|
||||
|
||||
if(pt[0] > bmaxs[0])
|
||||
bmaxs[0] = pt[0];
|
||||
if(pt[1] > bmaxs[1])
|
||||
bmaxs[1] = pt[1];
|
||||
if(pt[2] > bmaxs[2])
|
||||
bmaxs[2] = pt[2];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bmins -
|
||||
// bmaxs -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::UpdateBounds(const Vector& mins, const Vector& maxs)
|
||||
{
|
||||
if(mins[0] < bmins[0])
|
||||
bmins[0] = mins[0];
|
||||
if(mins[1] < bmins[1])
|
||||
bmins[1] = mins[1];
|
||||
if(mins[2] < bmins[2])
|
||||
bmins[2] = mins[2];
|
||||
|
||||
if(maxs[0] > bmaxs[0])
|
||||
bmaxs[0] = maxs[0];
|
||||
if(maxs[1] > bmaxs[1])
|
||||
bmaxs[1] = maxs[1];
|
||||
if(maxs[2] > bmaxs[2])
|
||||
bmaxs[2] = maxs[2];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pBox -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::UpdateBounds(const BoundBox *pBox)
|
||||
{
|
||||
UpdateBounds(pBox->bmins, pBox->bmaxs);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : ptdest -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::GetBoundsCenter(Vector& ptdest)
|
||||
{
|
||||
ptdest = (bmins + bmaxs)/2.0f;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pt -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BoundBox::ContainsPoint(const Vector& pt) const
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (pt[i] < bmins[i] || pt[i] > bmaxs[i])
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pfMins -
|
||||
// pfMaxs -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BoundBox::IsIntersectingBox(const Vector& pfMins, const Vector& pfMaxs) const
|
||||
{
|
||||
if ((bmins[0] >= pfMaxs[0]) || (bmaxs[0] <= pfMins[0]))
|
||||
{
|
||||
return(false);
|
||||
|
||||
}
|
||||
if ((bmins[1] >= pfMaxs[1]) || (bmaxs[1] <= pfMins[1]))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
if ((bmins[2] >= pfMaxs[2]) || (bmaxs[2] <= pfMins[2]))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pfMins -
|
||||
// pfMaxs -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BoundBox::IsInsideBox(const Vector& pfMins, const Vector& pfMaxs) const
|
||||
{
|
||||
if ((bmins[0] < pfMins[0]) || (bmaxs[0] > pfMaxs[0]))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
if ((bmins[1] < pfMins[1]) || (bmaxs[1] > pfMaxs[1]))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
if ((bmins[2] < pfMins[2]) || (bmaxs[2] > pfMaxs[2]))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns whether this bounding box is valid, ie maxs >= mins.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool BoundBox::IsValidBox(void) const
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (bmins[i] > bmaxs[i])
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : size -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::GetBoundsSize(Vector& size)
|
||||
{
|
||||
size[0] = bmaxs[0] - bmins[0];
|
||||
size[1] = bmaxs[1] - bmins[1];
|
||||
size[2] = bmaxs[2] - bmins[2];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : iValue -
|
||||
// iGridSize -
|
||||
// Output :
|
||||
//-----------------------------------------------------------------------------
|
||||
static int Snap(/*int*/ float iValue, int iGridSize)
|
||||
{
|
||||
return (int)(rint(iValue/iGridSize) * iGridSize);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : iGridSize -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::SnapToGrid(int iGridSize)
|
||||
{
|
||||
// does not alter the size of the box .. snaps its minimal coordinates
|
||||
// to the grid size specified in iGridSize
|
||||
Vector size;
|
||||
GetBoundsSize(size);
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
bmins[i] = (float)Snap(/* YWB (int)*/bmins[i], iGridSize);
|
||||
bmaxs[i] = bmins[i] + size[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : axis -
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::Rotate90(int axis)
|
||||
{
|
||||
int e1 = AXIS_X, e2 = AXIS_Y;
|
||||
|
||||
// get bounds center first
|
||||
Vector center;
|
||||
GetBoundsCenter(center);
|
||||
|
||||
switch(axis)
|
||||
{
|
||||
case AXIS_Z:
|
||||
e1 = AXIS_X;
|
||||
e2 = AXIS_Y;
|
||||
break;
|
||||
case AXIS_X:
|
||||
e1 = AXIS_Y;
|
||||
e2 = AXIS_Z;
|
||||
break;
|
||||
case AXIS_Y:
|
||||
e1 = AXIS_X;
|
||||
e2 = AXIS_Z;
|
||||
break;
|
||||
}
|
||||
|
||||
float tmp1, tmp2;
|
||||
tmp1 = bmins[e1] - center[e1] + center[e2];
|
||||
tmp2 = bmaxs[e1] - center[e1] + center[e2];
|
||||
bmins[e1] = bmins[e2] - center[e2] + center[e1];
|
||||
bmaxs[e1] = bmaxs[e2] - center[e2] + center[e1];
|
||||
bmins[e2] = tmp1;
|
||||
bmaxs[e2] = tmp2;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,79 +1,79 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: An axis aligned bounding box class.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BOUNDBOX_H
|
||||
#define BOUNDBOX_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "mathlib/vector.h"
|
||||
|
||||
#define COORD_NOTINIT ((float)(99999.0))
|
||||
|
||||
enum
|
||||
{
|
||||
AXIS_X = 0,
|
||||
AXIS_Y,
|
||||
AXIS_Z
|
||||
};
|
||||
|
||||
class BoundBox
|
||||
{
|
||||
public:
|
||||
|
||||
BoundBox(void);
|
||||
BoundBox(const Vector &mins, const Vector &maxs);
|
||||
|
||||
void ResetBounds(void);
|
||||
inline void SetBounds(const Vector &mins, const Vector &maxs);
|
||||
|
||||
void UpdateBounds(const Vector& bmins, const Vector& bmaxs);
|
||||
void UpdateBounds(const Vector& pt);
|
||||
void UpdateBounds(const BoundBox *pBox);
|
||||
void GetBoundsCenter(Vector& ptdest);
|
||||
inline void GetBounds(Vector& Mins, Vector& Maxs);
|
||||
|
||||
virtual bool IsIntersectingBox(const Vector& pfMins, const Vector& pfMaxs) const;
|
||||
bool IsInsideBox(const Vector& pfMins, const Vector& pfMaxs) const;
|
||||
bool ContainsPoint(const Vector& pt) const;
|
||||
bool IsValidBox(void) const;
|
||||
void GetBoundsSize(Vector& size);
|
||||
void SnapToGrid(int iGridSize);
|
||||
void Rotate90(int axis);
|
||||
|
||||
Vector bmins;
|
||||
Vector bmaxs;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gets the bounding box as two vectors, a min and a max.
|
||||
// Input : Mins - Receives the box's minima.
|
||||
// Maxs - Receives the box's maxima.
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::GetBounds(Vector &Mins, Vector &Maxs)
|
||||
{
|
||||
Mins = bmins;
|
||||
Maxs = bmaxs;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the box outright, equivalent to ResetBounds + UpdateBounds.
|
||||
// Input : mins - Minima to set.
|
||||
// maxs - Maxima to set.
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::SetBounds(const Vector &mins, const Vector &maxs)
|
||||
{
|
||||
bmins = mins;
|
||||
bmaxs = maxs;
|
||||
}
|
||||
|
||||
|
||||
#endif // BOUNDBOX_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: An axis aligned bounding box class.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BOUNDBOX_H
|
||||
#define BOUNDBOX_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "mathlib/vector.h"
|
||||
|
||||
#define COORD_NOTINIT ((float)(99999.0))
|
||||
|
||||
enum
|
||||
{
|
||||
AXIS_X = 0,
|
||||
AXIS_Y,
|
||||
AXIS_Z
|
||||
};
|
||||
|
||||
class BoundBox
|
||||
{
|
||||
public:
|
||||
|
||||
BoundBox(void);
|
||||
BoundBox(const Vector &mins, const Vector &maxs);
|
||||
|
||||
void ResetBounds(void);
|
||||
inline void SetBounds(const Vector &mins, const Vector &maxs);
|
||||
|
||||
void UpdateBounds(const Vector& bmins, const Vector& bmaxs);
|
||||
void UpdateBounds(const Vector& pt);
|
||||
void UpdateBounds(const BoundBox *pBox);
|
||||
void GetBoundsCenter(Vector& ptdest);
|
||||
inline void GetBounds(Vector& Mins, Vector& Maxs);
|
||||
|
||||
virtual bool IsIntersectingBox(const Vector& pfMins, const Vector& pfMaxs) const;
|
||||
bool IsInsideBox(const Vector& pfMins, const Vector& pfMaxs) const;
|
||||
bool ContainsPoint(const Vector& pt) const;
|
||||
bool IsValidBox(void) const;
|
||||
void GetBoundsSize(Vector& size);
|
||||
void SnapToGrid(int iGridSize);
|
||||
void Rotate90(int axis);
|
||||
|
||||
Vector bmins;
|
||||
Vector bmaxs;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gets the bounding box as two vectors, a min and a max.
|
||||
// Input : Mins - Receives the box's minima.
|
||||
// Maxs - Receives the box's maxima.
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::GetBounds(Vector &Mins, Vector &Maxs)
|
||||
{
|
||||
Mins = bmins;
|
||||
Maxs = bmaxs;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the box outright, equivalent to ResetBounds + UpdateBounds.
|
||||
// Input : mins - Minima to set.
|
||||
// maxs - Maxima to set.
|
||||
//-----------------------------------------------------------------------------
|
||||
void BoundBox::SetBounds(const Vector &mins, const Vector &maxs)
|
||||
{
|
||||
bmins = mins;
|
||||
bmaxs = maxs;
|
||||
}
|
||||
|
||||
|
||||
#endif // BOUNDBOX_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,32 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CSG_H
|
||||
#define CSG_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// Print a CONTENTS_ mask to a string.
|
||||
void PrintBrushContentsToString( int contents, char *pOut, int nMaxChars );
|
||||
|
||||
// Print a CONTENTS_ mask with Msg().
|
||||
void PrintBrushContents( int contents );
|
||||
|
||||
void FixupAreaportalWaterBrushes( bspbrush_t *pList );
|
||||
|
||||
bspbrush_t *MakeBspBrushList (int startbrush, int endbrush,
|
||||
const Vector& clipmins, const Vector& clipmaxs, int detailScreen);
|
||||
bspbrush_t *MakeBspBrushList (mapbrush_t **pBrushes, int nBrushCount, const Vector& clipmins, const Vector& clipmaxs);
|
||||
|
||||
void WriteBrushMap (char *name, bspbrush_t *list);
|
||||
|
||||
bspbrush_t *ChopBrushes (bspbrush_t *head);
|
||||
bspbrush_t *IntersectBrush (bspbrush_t *a, bspbrush_t *b);
|
||||
qboolean BrushesDisjoint (bspbrush_t *a, bspbrush_t *b);
|
||||
|
||||
#endif // CSG_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CSG_H
|
||||
#define CSG_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// Print a CONTENTS_ mask to a string.
|
||||
void PrintBrushContentsToString( int contents, char *pOut, int nMaxChars );
|
||||
|
||||
// Print a CONTENTS_ mask with Msg().
|
||||
void PrintBrushContents( int contents );
|
||||
|
||||
void FixupAreaportalWaterBrushes( bspbrush_t *pList );
|
||||
|
||||
bspbrush_t *MakeBspBrushList (int startbrush, int endbrush,
|
||||
const Vector& clipmins, const Vector& clipmaxs, int detailScreen);
|
||||
bspbrush_t *MakeBspBrushList (mapbrush_t **pBrushes, int nBrushCount, const Vector& clipmins, const Vector& clipmaxs);
|
||||
|
||||
void WriteBrushMap (char *name, bspbrush_t *list);
|
||||
|
||||
bspbrush_t *ChopBrushes (bspbrush_t *head);
|
||||
bspbrush_t *IntersectBrush (bspbrush_t *a, bspbrush_t *b);
|
||||
qboolean BrushesDisjoint (bspbrush_t *a, bspbrush_t *b);
|
||||
|
||||
#endif // CSG_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,18 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DETAIL_H
|
||||
#define DETAIL_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
face_t *MergeDetailTree( tree_t *worldtree, int brush_start, int brush_end );
|
||||
|
||||
|
||||
#endif // DETAIL_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DETAIL_H
|
||||
#define DETAIL_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
face_t *MergeDetailTree( tree_t *worldtree, int brush_start, int brush_end );
|
||||
|
||||
|
||||
#endif // DETAIL_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,359 +1,359 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "vbsp.h"
|
||||
#include "disp_vbsp.h"
|
||||
#include "builddisp.h"
|
||||
#include "disp_common.h"
|
||||
#include "ivp.h"
|
||||
#include "disp_ivp.h"
|
||||
#include "vphysics_interface.h"
|
||||
#include "vphysics/virtualmesh.h"
|
||||
#include "utlrbtree.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "materialpatch.h"
|
||||
|
||||
struct disp_grid_t
|
||||
{
|
||||
int gridIndex;
|
||||
CUtlVector<int> dispList;
|
||||
};
|
||||
|
||||
static CUtlVector<disp_grid_t> gDispGridList;
|
||||
|
||||
|
||||
|
||||
disp_grid_t &FindOrInsertGrid( int gridIndex )
|
||||
{
|
||||
// linear search is slow, but only a few grids will be present
|
||||
for ( int i = gDispGridList.Count()-1; i >= 0; i-- )
|
||||
{
|
||||
if ( gDispGridList[i].gridIndex == gridIndex )
|
||||
{
|
||||
return gDispGridList[i];
|
||||
}
|
||||
}
|
||||
int index = gDispGridList.AddToTail();
|
||||
gDispGridList[index].gridIndex = gridIndex;
|
||||
|
||||
// must be empty
|
||||
Assert( gDispGridList[index].dispList.Count() == 0 );
|
||||
|
||||
return gDispGridList[index];
|
||||
}
|
||||
|
||||
// UNDONE: Tune these or adapt them to map size or triangle count?
|
||||
#define DISP_GRID_SIZEX 4096
|
||||
#define DISP_GRID_SIZEY 4096
|
||||
#define DISP_GRID_SIZEZ 8192
|
||||
|
||||
int Disp_GridIndex( CCoreDispInfo *pDispInfo )
|
||||
{
|
||||
// quick hash the center into the grid and put the whole terrain in that grid
|
||||
Vector mins, maxs;
|
||||
pDispInfo->GetNode(0)->GetBoundingBox( mins, maxs );
|
||||
Vector center;
|
||||
center = 0.5 * (mins + maxs);
|
||||
// make sure it's positive
|
||||
center += Vector(MAX_COORD_INTEGER,MAX_COORD_INTEGER,MAX_COORD_INTEGER);
|
||||
int gridX = center.x / DISP_GRID_SIZEX;
|
||||
int gridY = center.y / DISP_GRID_SIZEY;
|
||||
int gridZ = center.z / DISP_GRID_SIZEZ;
|
||||
|
||||
gridX &= 0xFF;
|
||||
gridY &= 0xFF;
|
||||
gridZ &= 0xFF;
|
||||
return MAKEID( gridX, gridY, gridZ, 0 );
|
||||
}
|
||||
|
||||
void AddToGrid( int gridIndex, int dispIndex )
|
||||
{
|
||||
disp_grid_t &grid = FindOrInsertGrid( gridIndex );
|
||||
grid.dispList.AddToTail( dispIndex );
|
||||
}
|
||||
|
||||
MaterialSystemMaterial_t GetMatIDFromDisp( mapdispinfo_t *pMapDisp )
|
||||
{
|
||||
texinfo_t *pTexInfo = &texinfo[pMapDisp->face.texinfo];
|
||||
dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
|
||||
MaterialSystemMaterial_t matID = FindOriginalMaterial( TexDataStringTable_GetString( pTexData->nameStringTableID ), NULL, true );
|
||||
return matID;
|
||||
}
|
||||
|
||||
// check this and disable virtual mesh if in use
|
||||
bool Disp_HasPower4Displacements()
|
||||
{
|
||||
for ( int i = 0; i < g_CoreDispInfos.Count(); i++ )
|
||||
{
|
||||
if ( g_CoreDispInfos[i]->GetPower() > 3 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// adds all displacement faces as a series of convex objects
|
||||
// UNDONE: Only add the displacements for this model?
|
||||
void Disp_AddCollisionModels( CUtlVector<CPhysCollisionEntry *> &collisionList, dmodel_t *pModel, int contentsMask)
|
||||
{
|
||||
int dispIndex;
|
||||
|
||||
// Add each displacement to the grid hash
|
||||
for ( dispIndex = 0; dispIndex < g_CoreDispInfos.Count(); dispIndex++ )
|
||||
{
|
||||
CCoreDispInfo *pDispInfo = g_CoreDispInfos[ dispIndex ];
|
||||
mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ];
|
||||
|
||||
// not solid for this pass
|
||||
if ( !(pMapDisp->contents & contentsMask) )
|
||||
continue;
|
||||
|
||||
int gridIndex = Disp_GridIndex( pDispInfo );
|
||||
AddToGrid( gridIndex, dispIndex );
|
||||
}
|
||||
|
||||
// now make a polysoup for the terrain in each grid
|
||||
for ( int grid = 0; grid < gDispGridList.Count(); grid++ )
|
||||
{
|
||||
int triCount = 0;
|
||||
CPhysPolysoup *pTerrainPhysics = physcollision->PolysoupCreate();
|
||||
|
||||
// iterate the displacements in this grid
|
||||
for ( int listIndex = 0; listIndex < gDispGridList[grid].dispList.Count(); listIndex++ )
|
||||
{
|
||||
dispIndex = gDispGridList[grid].dispList[listIndex];
|
||||
CCoreDispInfo *pDispInfo = g_CoreDispInfos[ dispIndex ];
|
||||
mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ];
|
||||
|
||||
// Get the material id.
|
||||
MaterialSystemMaterial_t matID = GetMatIDFromDisp( pMapDisp );
|
||||
|
||||
// Build a triangle list. This shares the tesselation code with the engine.
|
||||
CUtlVector<unsigned short> indices;
|
||||
CVBSPTesselateHelper helper;
|
||||
helper.m_pIndices = &indices;
|
||||
helper.m_pActiveVerts = pDispInfo->GetAllowedVerts().Base();
|
||||
helper.m_pPowerInfo = pDispInfo->GetPowerInfo();
|
||||
|
||||
::TesselateDisplacement( &helper );
|
||||
|
||||
Assert( indices.Count() > 0 );
|
||||
Assert( indices.Count() % 3 == 0 ); // Make sure indices are a multiple of 3.
|
||||
int nTriCount = indices.Count() / 3;
|
||||
triCount += nTriCount;
|
||||
if ( triCount >= 65536 )
|
||||
{
|
||||
// don't put more than 64K tris in any single collision model
|
||||
CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics, false );
|
||||
if ( pCollide )
|
||||
{
|
||||
collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) );
|
||||
}
|
||||
// Throw this polysoup away and start over for the remaining triangles
|
||||
physcollision->PolysoupDestroy( pTerrainPhysics );
|
||||
pTerrainPhysics = physcollision->PolysoupCreate();
|
||||
triCount = nTriCount;
|
||||
}
|
||||
Vector tmpVerts[3];
|
||||
for ( int iTri = 0; iTri < nTriCount; ++iTri )
|
||||
{
|
||||
float flAlphaTotal = 0.0f;
|
||||
for ( int iTriVert = 0; iTriVert < 3; ++iTriVert )
|
||||
{
|
||||
pDispInfo->GetVert( indices[iTri*3+iTriVert], tmpVerts[iTriVert] );
|
||||
flAlphaTotal += pDispInfo->GetAlpha( indices[iTri*3+iTriVert] );
|
||||
}
|
||||
|
||||
int nProp = g_SurfaceProperties[texinfo[pMapDisp->face.texinfo].texdata];
|
||||
if ( flAlphaTotal > DISP_ALPHA_PROP_DELTA )
|
||||
{
|
||||
int nProp2 = GetSurfaceProperties2( matID, "surfaceprop2" );
|
||||
if ( nProp2 != -1 )
|
||||
{
|
||||
nProp = nProp2;
|
||||
}
|
||||
}
|
||||
int nMaterialIndex = RemapWorldMaterial( nProp );
|
||||
physcollision->PolysoupAddTriangle( pTerrainPhysics, tmpVerts[0], tmpVerts[1], tmpVerts[2], nMaterialIndex );
|
||||
}
|
||||
}
|
||||
|
||||
// convert the whole grid's polysoup to a collide and store in the collision list
|
||||
CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics, false );
|
||||
if ( pCollide )
|
||||
{
|
||||
collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) );
|
||||
}
|
||||
// now that we have the collide, we're done with the soup
|
||||
physcollision->PolysoupDestroy( pTerrainPhysics );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CDispMeshEvent : public IVirtualMeshEvent
|
||||
{
|
||||
public:
|
||||
CDispMeshEvent( unsigned short *pIndices, int indexCount, CCoreDispInfo *pDispInfo );
|
||||
virtual void GetVirtualMesh( void *userData, virtualmeshlist_t *pList );
|
||||
virtual void GetWorldspaceBounds( void *userData, Vector *pMins, Vector *pMaxs );
|
||||
virtual void GetTrianglesInSphere( void *userData, const Vector ¢er, float radius, virtualmeshtrianglelist_t *pList );
|
||||
|
||||
CUtlVector<Vector> m_verts;
|
||||
unsigned short *m_pIndices;
|
||||
int m_indexCount;
|
||||
};
|
||||
|
||||
CDispMeshEvent::CDispMeshEvent( unsigned short *pIndices, int indexCount, CCoreDispInfo *pDispInfo )
|
||||
{
|
||||
m_pIndices = pIndices;
|
||||
m_indexCount = indexCount;
|
||||
int maxIndex = 0;
|
||||
for ( int i = 0; i < indexCount; i++ )
|
||||
{
|
||||
if ( pIndices[i] > maxIndex )
|
||||
{
|
||||
maxIndex = pIndices[i];
|
||||
}
|
||||
}
|
||||
for ( int i = 0; i < indexCount/2; i++ )
|
||||
{
|
||||
V_swap( pIndices[i], pIndices[(indexCount-i)-1] );
|
||||
}
|
||||
int count = maxIndex + 1;
|
||||
m_verts.SetCount( count );
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
m_verts[i] = pDispInfo->GetVert(i);
|
||||
}
|
||||
}
|
||||
|
||||
void CDispMeshEvent::GetVirtualMesh( void *userData, virtualmeshlist_t *pList )
|
||||
{
|
||||
Assert(userData==((void *)this));
|
||||
pList->pVerts = m_verts.Base();
|
||||
pList->indexCount = m_indexCount;
|
||||
pList->triangleCount = m_indexCount/3;
|
||||
pList->vertexCount = m_verts.Count();
|
||||
pList->surfacePropsIndex = 0; // doesn't matter here, reset at runtime
|
||||
pList->pHull = NULL;
|
||||
int indexMax = ARRAYSIZE(pList->indices);
|
||||
int indexCount = min(m_indexCount, indexMax);
|
||||
Assert(m_indexCount < indexMax);
|
||||
Q_memcpy( pList->indices, m_pIndices, sizeof(*m_pIndices) * indexCount );
|
||||
}
|
||||
|
||||
void CDispMeshEvent::GetWorldspaceBounds( void *userData, Vector *pMins, Vector *pMaxs )
|
||||
{
|
||||
Assert(userData==((void *)this));
|
||||
ClearBounds( *pMins, *pMaxs );
|
||||
for ( int i = 0; i < m_verts.Count(); i++ )
|
||||
{
|
||||
AddPointToBounds( m_verts[i], *pMins, *pMaxs );
|
||||
}
|
||||
}
|
||||
|
||||
void CDispMeshEvent::GetTrianglesInSphere( void *userData, const Vector ¢er, float radius, virtualmeshtrianglelist_t *pList )
|
||||
{
|
||||
Assert(userData==((void *)this));
|
||||
pList->triangleCount = m_indexCount/3;
|
||||
int indexMax = ARRAYSIZE(pList->triangleIndices);
|
||||
int indexCount = min(m_indexCount, indexMax);
|
||||
Assert(m_indexCount < MAX_VIRTUAL_TRIANGLES*3);
|
||||
Q_memcpy( pList->triangleIndices, m_pIndices, sizeof(*m_pIndices) * indexCount );
|
||||
}
|
||||
|
||||
void Disp_BuildVirtualMesh( int contentsMask )
|
||||
{
|
||||
CUtlVector<CPhysCollide *> virtualMeshes;
|
||||
virtualMeshes.EnsureCount( g_CoreDispInfos.Count() );
|
||||
for ( int i = 0; i < g_CoreDispInfos.Count(); i++ )
|
||||
{
|
||||
CCoreDispInfo *pDispInfo = g_CoreDispInfos[ i ];
|
||||
mapdispinfo_t *pMapDisp = &mapdispinfo[ i ];
|
||||
|
||||
virtualMeshes[i] = NULL;
|
||||
// not solid for this pass
|
||||
if ( !(pMapDisp->contents & contentsMask) )
|
||||
continue;
|
||||
|
||||
// Build a triangle list. This shares the tesselation code with the engine.
|
||||
CUtlVector<unsigned short> indices;
|
||||
CVBSPTesselateHelper helper;
|
||||
helper.m_pIndices = &indices;
|
||||
helper.m_pActiveVerts = pDispInfo->GetAllowedVerts().Base();
|
||||
helper.m_pPowerInfo = pDispInfo->GetPowerInfo();
|
||||
|
||||
::TesselateDisplacement( &helper );
|
||||
|
||||
// validate the collision data
|
||||
if ( 1 )
|
||||
{
|
||||
int triCount = indices.Count() / 3;
|
||||
for ( int j = 0; j < triCount; j++ )
|
||||
{
|
||||
int index = j * 3;
|
||||
Vector v0 = pDispInfo->GetVert( indices[index+0] );
|
||||
Vector v1 = pDispInfo->GetVert( indices[index+1] );
|
||||
Vector v2 = pDispInfo->GetVert( indices[index+2] );
|
||||
if ( v0 == v1 || v1 == v2 || v2 == v0 )
|
||||
{
|
||||
Warning( "Displacement %d has bad geometry near %.2f %.2f %.2f\n", i, v0.x, v0.y, v0.z );
|
||||
texinfo_t *pTexInfo = &texinfo[pMapDisp->face.texinfo];
|
||||
dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
|
||||
const char *pMatName = TexDataStringTable_GetString( pTexData->nameStringTableID );
|
||||
|
||||
Error( "Can't compile displacement physics, exiting. Texture is %s\n", pMatName );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
CDispMeshEvent meshHandler( indices.Base(), indices.Count(), pDispInfo );
|
||||
virtualmeshparams_t params;
|
||||
params.buildOuterHull = true;
|
||||
params.pMeshEventHandler = &meshHandler;
|
||||
params.userData = &meshHandler;
|
||||
virtualMeshes[i] = physcollision->CreateVirtualMesh( params );
|
||||
}
|
||||
unsigned int totalSize = 0;
|
||||
CUtlBuffer buf;
|
||||
dphysdisp_t header;
|
||||
header.numDisplacements = g_CoreDispInfos.Count();
|
||||
buf.PutObjects( &header );
|
||||
|
||||
CUtlVector<char> dispBuf;
|
||||
for ( int i = 0; i < header.numDisplacements; i++ )
|
||||
{
|
||||
if ( virtualMeshes[i] )
|
||||
{
|
||||
unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] );
|
||||
totalSize += testSize;
|
||||
buf.PutShort( testSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.PutShort( -1 );
|
||||
}
|
||||
}
|
||||
for ( int i = 0; i < header.numDisplacements; i++ )
|
||||
{
|
||||
if ( virtualMeshes[i] )
|
||||
{
|
||||
unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] );
|
||||
dispBuf.RemoveAll();
|
||||
dispBuf.EnsureCount(testSize);
|
||||
|
||||
unsigned int outSize = physcollision->CollideWrite( dispBuf.Base(), virtualMeshes[i], false );
|
||||
Assert( outSize == testSize );
|
||||
buf.Put( dispBuf.Base(), outSize );
|
||||
}
|
||||
}
|
||||
g_PhysDispSize = totalSize + sizeof(dphysdisp_t) + (sizeof(unsigned short) * header.numDisplacements);
|
||||
Assert( buf.TellMaxPut() == g_PhysDispSize );
|
||||
g_PhysDispSize = buf.TellMaxPut();
|
||||
g_pPhysDisp = new byte[g_PhysDispSize];
|
||||
Q_memcpy( g_pPhysDisp, buf.Base(), g_PhysDispSize );
|
||||
}
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "vbsp.h"
|
||||
#include "disp_vbsp.h"
|
||||
#include "builddisp.h"
|
||||
#include "disp_common.h"
|
||||
#include "ivp.h"
|
||||
#include "disp_ivp.h"
|
||||
#include "vphysics_interface.h"
|
||||
#include "vphysics/virtualmesh.h"
|
||||
#include "utlrbtree.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "materialpatch.h"
|
||||
|
||||
struct disp_grid_t
|
||||
{
|
||||
int gridIndex;
|
||||
CUtlVector<int> dispList;
|
||||
};
|
||||
|
||||
static CUtlVector<disp_grid_t> gDispGridList;
|
||||
|
||||
|
||||
|
||||
disp_grid_t &FindOrInsertGrid( int gridIndex )
|
||||
{
|
||||
// linear search is slow, but only a few grids will be present
|
||||
for ( int i = gDispGridList.Count()-1; i >= 0; i-- )
|
||||
{
|
||||
if ( gDispGridList[i].gridIndex == gridIndex )
|
||||
{
|
||||
return gDispGridList[i];
|
||||
}
|
||||
}
|
||||
int index = gDispGridList.AddToTail();
|
||||
gDispGridList[index].gridIndex = gridIndex;
|
||||
|
||||
// must be empty
|
||||
Assert( gDispGridList[index].dispList.Count() == 0 );
|
||||
|
||||
return gDispGridList[index];
|
||||
}
|
||||
|
||||
// UNDONE: Tune these or adapt them to map size or triangle count?
|
||||
#define DISP_GRID_SIZEX 4096
|
||||
#define DISP_GRID_SIZEY 4096
|
||||
#define DISP_GRID_SIZEZ 8192
|
||||
|
||||
int Disp_GridIndex( CCoreDispInfo *pDispInfo )
|
||||
{
|
||||
// quick hash the center into the grid and put the whole terrain in that grid
|
||||
Vector mins, maxs;
|
||||
pDispInfo->GetNode(0)->GetBoundingBox( mins, maxs );
|
||||
Vector center;
|
||||
center = 0.5 * (mins + maxs);
|
||||
// make sure it's positive
|
||||
center += Vector(MAX_COORD_INTEGER,MAX_COORD_INTEGER,MAX_COORD_INTEGER);
|
||||
int gridX = center.x / DISP_GRID_SIZEX;
|
||||
int gridY = center.y / DISP_GRID_SIZEY;
|
||||
int gridZ = center.z / DISP_GRID_SIZEZ;
|
||||
|
||||
gridX &= 0xFF;
|
||||
gridY &= 0xFF;
|
||||
gridZ &= 0xFF;
|
||||
return MAKEID( gridX, gridY, gridZ, 0 );
|
||||
}
|
||||
|
||||
void AddToGrid( int gridIndex, int dispIndex )
|
||||
{
|
||||
disp_grid_t &grid = FindOrInsertGrid( gridIndex );
|
||||
grid.dispList.AddToTail( dispIndex );
|
||||
}
|
||||
|
||||
MaterialSystemMaterial_t GetMatIDFromDisp( mapdispinfo_t *pMapDisp )
|
||||
{
|
||||
texinfo_t *pTexInfo = &texinfo[pMapDisp->face.texinfo];
|
||||
dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
|
||||
MaterialSystemMaterial_t matID = FindOriginalMaterial( TexDataStringTable_GetString( pTexData->nameStringTableID ), NULL, true );
|
||||
return matID;
|
||||
}
|
||||
|
||||
// check this and disable virtual mesh if in use
|
||||
bool Disp_HasPower4Displacements()
|
||||
{
|
||||
for ( int i = 0; i < g_CoreDispInfos.Count(); i++ )
|
||||
{
|
||||
if ( g_CoreDispInfos[i]->GetPower() > 3 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// adds all displacement faces as a series of convex objects
|
||||
// UNDONE: Only add the displacements for this model?
|
||||
void Disp_AddCollisionModels( CUtlVector<CPhysCollisionEntry *> &collisionList, dmodel_t *pModel, int contentsMask)
|
||||
{
|
||||
int dispIndex;
|
||||
|
||||
// Add each displacement to the grid hash
|
||||
for ( dispIndex = 0; dispIndex < g_CoreDispInfos.Count(); dispIndex++ )
|
||||
{
|
||||
CCoreDispInfo *pDispInfo = g_CoreDispInfos[ dispIndex ];
|
||||
mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ];
|
||||
|
||||
// not solid for this pass
|
||||
if ( !(pMapDisp->contents & contentsMask) )
|
||||
continue;
|
||||
|
||||
int gridIndex = Disp_GridIndex( pDispInfo );
|
||||
AddToGrid( gridIndex, dispIndex );
|
||||
}
|
||||
|
||||
// now make a polysoup for the terrain in each grid
|
||||
for ( int grid = 0; grid < gDispGridList.Count(); grid++ )
|
||||
{
|
||||
int triCount = 0;
|
||||
CPhysPolysoup *pTerrainPhysics = physcollision->PolysoupCreate();
|
||||
|
||||
// iterate the displacements in this grid
|
||||
for ( int listIndex = 0; listIndex < gDispGridList[grid].dispList.Count(); listIndex++ )
|
||||
{
|
||||
dispIndex = gDispGridList[grid].dispList[listIndex];
|
||||
CCoreDispInfo *pDispInfo = g_CoreDispInfos[ dispIndex ];
|
||||
mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ];
|
||||
|
||||
// Get the material id.
|
||||
MaterialSystemMaterial_t matID = GetMatIDFromDisp( pMapDisp );
|
||||
|
||||
// Build a triangle list. This shares the tesselation code with the engine.
|
||||
CUtlVector<unsigned short> indices;
|
||||
CVBSPTesselateHelper helper;
|
||||
helper.m_pIndices = &indices;
|
||||
helper.m_pActiveVerts = pDispInfo->GetAllowedVerts().Base();
|
||||
helper.m_pPowerInfo = pDispInfo->GetPowerInfo();
|
||||
|
||||
::TesselateDisplacement( &helper );
|
||||
|
||||
Assert( indices.Count() > 0 );
|
||||
Assert( indices.Count() % 3 == 0 ); // Make sure indices are a multiple of 3.
|
||||
int nTriCount = indices.Count() / 3;
|
||||
triCount += nTriCount;
|
||||
if ( triCount >= 65536 )
|
||||
{
|
||||
// don't put more than 64K tris in any single collision model
|
||||
CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics, false );
|
||||
if ( pCollide )
|
||||
{
|
||||
collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) );
|
||||
}
|
||||
// Throw this polysoup away and start over for the remaining triangles
|
||||
physcollision->PolysoupDestroy( pTerrainPhysics );
|
||||
pTerrainPhysics = physcollision->PolysoupCreate();
|
||||
triCount = nTriCount;
|
||||
}
|
||||
Vector tmpVerts[3];
|
||||
for ( int iTri = 0; iTri < nTriCount; ++iTri )
|
||||
{
|
||||
float flAlphaTotal = 0.0f;
|
||||
for ( int iTriVert = 0; iTriVert < 3; ++iTriVert )
|
||||
{
|
||||
pDispInfo->GetVert( indices[iTri*3+iTriVert], tmpVerts[iTriVert] );
|
||||
flAlphaTotal += pDispInfo->GetAlpha( indices[iTri*3+iTriVert] );
|
||||
}
|
||||
|
||||
int nProp = g_SurfaceProperties[texinfo[pMapDisp->face.texinfo].texdata];
|
||||
if ( flAlphaTotal > DISP_ALPHA_PROP_DELTA )
|
||||
{
|
||||
int nProp2 = GetSurfaceProperties2( matID, "surfaceprop2" );
|
||||
if ( nProp2 != -1 )
|
||||
{
|
||||
nProp = nProp2;
|
||||
}
|
||||
}
|
||||
int nMaterialIndex = RemapWorldMaterial( nProp );
|
||||
physcollision->PolysoupAddTriangle( pTerrainPhysics, tmpVerts[0], tmpVerts[1], tmpVerts[2], nMaterialIndex );
|
||||
}
|
||||
}
|
||||
|
||||
// convert the whole grid's polysoup to a collide and store in the collision list
|
||||
CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics, false );
|
||||
if ( pCollide )
|
||||
{
|
||||
collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) );
|
||||
}
|
||||
// now that we have the collide, we're done with the soup
|
||||
physcollision->PolysoupDestroy( pTerrainPhysics );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CDispMeshEvent : public IVirtualMeshEvent
|
||||
{
|
||||
public:
|
||||
CDispMeshEvent( unsigned short *pIndices, int indexCount, CCoreDispInfo *pDispInfo );
|
||||
virtual void GetVirtualMesh( void *userData, virtualmeshlist_t *pList );
|
||||
virtual void GetWorldspaceBounds( void *userData, Vector *pMins, Vector *pMaxs );
|
||||
virtual void GetTrianglesInSphere( void *userData, const Vector ¢er, float radius, virtualmeshtrianglelist_t *pList );
|
||||
|
||||
CUtlVector<Vector> m_verts;
|
||||
unsigned short *m_pIndices;
|
||||
int m_indexCount;
|
||||
};
|
||||
|
||||
CDispMeshEvent::CDispMeshEvent( unsigned short *pIndices, int indexCount, CCoreDispInfo *pDispInfo )
|
||||
{
|
||||
m_pIndices = pIndices;
|
||||
m_indexCount = indexCount;
|
||||
int maxIndex = 0;
|
||||
for ( int i = 0; i < indexCount; i++ )
|
||||
{
|
||||
if ( pIndices[i] > maxIndex )
|
||||
{
|
||||
maxIndex = pIndices[i];
|
||||
}
|
||||
}
|
||||
for ( int i = 0; i < indexCount/2; i++ )
|
||||
{
|
||||
V_swap( pIndices[i], pIndices[(indexCount-i)-1] );
|
||||
}
|
||||
int count = maxIndex + 1;
|
||||
m_verts.SetCount( count );
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
m_verts[i] = pDispInfo->GetVert(i);
|
||||
}
|
||||
}
|
||||
|
||||
void CDispMeshEvent::GetVirtualMesh( void *userData, virtualmeshlist_t *pList )
|
||||
{
|
||||
Assert(userData==((void *)this));
|
||||
pList->pVerts = m_verts.Base();
|
||||
pList->indexCount = m_indexCount;
|
||||
pList->triangleCount = m_indexCount/3;
|
||||
pList->vertexCount = m_verts.Count();
|
||||
pList->surfacePropsIndex = 0; // doesn't matter here, reset at runtime
|
||||
pList->pHull = NULL;
|
||||
int indexMax = ARRAYSIZE(pList->indices);
|
||||
int indexCount = min(m_indexCount, indexMax);
|
||||
Assert(m_indexCount < indexMax);
|
||||
Q_memcpy( pList->indices, m_pIndices, sizeof(*m_pIndices) * indexCount );
|
||||
}
|
||||
|
||||
void CDispMeshEvent::GetWorldspaceBounds( void *userData, Vector *pMins, Vector *pMaxs )
|
||||
{
|
||||
Assert(userData==((void *)this));
|
||||
ClearBounds( *pMins, *pMaxs );
|
||||
for ( int i = 0; i < m_verts.Count(); i++ )
|
||||
{
|
||||
AddPointToBounds( m_verts[i], *pMins, *pMaxs );
|
||||
}
|
||||
}
|
||||
|
||||
void CDispMeshEvent::GetTrianglesInSphere( void *userData, const Vector ¢er, float radius, virtualmeshtrianglelist_t *pList )
|
||||
{
|
||||
Assert(userData==((void *)this));
|
||||
pList->triangleCount = m_indexCount/3;
|
||||
int indexMax = ARRAYSIZE(pList->triangleIndices);
|
||||
int indexCount = min(m_indexCount, indexMax);
|
||||
Assert(m_indexCount < MAX_VIRTUAL_TRIANGLES*3);
|
||||
Q_memcpy( pList->triangleIndices, m_pIndices, sizeof(*m_pIndices) * indexCount );
|
||||
}
|
||||
|
||||
void Disp_BuildVirtualMesh( int contentsMask )
|
||||
{
|
||||
CUtlVector<CPhysCollide *> virtualMeshes;
|
||||
virtualMeshes.EnsureCount( g_CoreDispInfos.Count() );
|
||||
for ( int i = 0; i < g_CoreDispInfos.Count(); i++ )
|
||||
{
|
||||
CCoreDispInfo *pDispInfo = g_CoreDispInfos[ i ];
|
||||
mapdispinfo_t *pMapDisp = &mapdispinfo[ i ];
|
||||
|
||||
virtualMeshes[i] = NULL;
|
||||
// not solid for this pass
|
||||
if ( !(pMapDisp->contents & contentsMask) )
|
||||
continue;
|
||||
|
||||
// Build a triangle list. This shares the tesselation code with the engine.
|
||||
CUtlVector<unsigned short> indices;
|
||||
CVBSPTesselateHelper helper;
|
||||
helper.m_pIndices = &indices;
|
||||
helper.m_pActiveVerts = pDispInfo->GetAllowedVerts().Base();
|
||||
helper.m_pPowerInfo = pDispInfo->GetPowerInfo();
|
||||
|
||||
::TesselateDisplacement( &helper );
|
||||
|
||||
// validate the collision data
|
||||
if ( 1 )
|
||||
{
|
||||
int triCount = indices.Count() / 3;
|
||||
for ( int j = 0; j < triCount; j++ )
|
||||
{
|
||||
int index = j * 3;
|
||||
Vector v0 = pDispInfo->GetVert( indices[index+0] );
|
||||
Vector v1 = pDispInfo->GetVert( indices[index+1] );
|
||||
Vector v2 = pDispInfo->GetVert( indices[index+2] );
|
||||
if ( v0 == v1 || v1 == v2 || v2 == v0 )
|
||||
{
|
||||
Warning( "Displacement %d has bad geometry near %.2f %.2f %.2f\n", i, v0.x, v0.y, v0.z );
|
||||
texinfo_t *pTexInfo = &texinfo[pMapDisp->face.texinfo];
|
||||
dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
|
||||
const char *pMatName = TexDataStringTable_GetString( pTexData->nameStringTableID );
|
||||
|
||||
Error( "Can't compile displacement physics, exiting. Texture is %s\n", pMatName );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
CDispMeshEvent meshHandler( indices.Base(), indices.Count(), pDispInfo );
|
||||
virtualmeshparams_t params;
|
||||
params.buildOuterHull = true;
|
||||
params.pMeshEventHandler = &meshHandler;
|
||||
params.userData = &meshHandler;
|
||||
virtualMeshes[i] = physcollision->CreateVirtualMesh( params );
|
||||
}
|
||||
unsigned int totalSize = 0;
|
||||
CUtlBuffer buf;
|
||||
dphysdisp_t header;
|
||||
header.numDisplacements = g_CoreDispInfos.Count();
|
||||
buf.PutObjects( &header );
|
||||
|
||||
CUtlVector<char> dispBuf;
|
||||
for ( int i = 0; i < header.numDisplacements; i++ )
|
||||
{
|
||||
if ( virtualMeshes[i] )
|
||||
{
|
||||
unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] );
|
||||
totalSize += testSize;
|
||||
buf.PutShort( testSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.PutShort( -1 );
|
||||
}
|
||||
}
|
||||
for ( int i = 0; i < header.numDisplacements; i++ )
|
||||
{
|
||||
if ( virtualMeshes[i] )
|
||||
{
|
||||
unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] );
|
||||
dispBuf.RemoveAll();
|
||||
dispBuf.EnsureCount(testSize);
|
||||
|
||||
unsigned int outSize = physcollision->CollideWrite( dispBuf.Base(), virtualMeshes[i], false );
|
||||
Assert( outSize == testSize );
|
||||
buf.Put( dispBuf.Base(), outSize );
|
||||
}
|
||||
}
|
||||
g_PhysDispSize = totalSize + sizeof(dphysdisp_t) + (sizeof(unsigned short) * header.numDisplacements);
|
||||
Assert( buf.TellMaxPut() == g_PhysDispSize );
|
||||
g_PhysDispSize = buf.TellMaxPut();
|
||||
g_pPhysDisp = new byte[g_PhysDispSize];
|
||||
Q_memcpy( g_pPhysDisp, buf.Base(), g_PhysDispSize );
|
||||
}
|
||||
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DISP_IVP_H
|
||||
#define DISP_IVP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utlvector.h"
|
||||
#include "../../public/disp_tesselate.h"
|
||||
|
||||
|
||||
class CPhysCollisionEntry;
|
||||
struct dmodel_t;
|
||||
|
||||
|
||||
// This provides the template functions that the engine's tesselation code needs
|
||||
// so we can share the code in VBSP.
|
||||
class CVBSPTesselateHelper : public CBaseTesselateHelper
|
||||
{
|
||||
public:
|
||||
void EndTriangle()
|
||||
{
|
||||
m_pIndices->AddToTail( m_TempIndices[0] );
|
||||
m_pIndices->AddToTail( m_TempIndices[1] );
|
||||
m_pIndices->AddToTail( m_TempIndices[2] );
|
||||
}
|
||||
|
||||
DispNodeInfo_t& GetNodeInfo( int iNodeBit )
|
||||
{
|
||||
// VBSP doesn't care about these. Give it back something to play with.
|
||||
static DispNodeInfo_t dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
public:
|
||||
CUtlVector<unsigned short> *m_pIndices;
|
||||
};
|
||||
|
||||
|
||||
extern void Disp_AddCollisionModels( CUtlVector<CPhysCollisionEntry *> &collisionList, dmodel_t *pModel, int contentsMask );
|
||||
extern void Disp_BuildVirtualMesh( int contentsMask );
|
||||
extern bool Disp_HasPower4Displacements();
|
||||
|
||||
#endif // DISP_IVP_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef DISP_IVP_H
|
||||
#define DISP_IVP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utlvector.h"
|
||||
#include "../../public/disp_tesselate.h"
|
||||
|
||||
|
||||
class CPhysCollisionEntry;
|
||||
struct dmodel_t;
|
||||
|
||||
|
||||
// This provides the template functions that the engine's tesselation code needs
|
||||
// so we can share the code in VBSP.
|
||||
class CVBSPTesselateHelper : public CBaseTesselateHelper
|
||||
{
|
||||
public:
|
||||
void EndTriangle()
|
||||
{
|
||||
m_pIndices->AddToTail( m_TempIndices[0] );
|
||||
m_pIndices->AddToTail( m_TempIndices[1] );
|
||||
m_pIndices->AddToTail( m_TempIndices[2] );
|
||||
}
|
||||
|
||||
DispNodeInfo_t& GetNodeInfo( int iNodeBit )
|
||||
{
|
||||
// VBSP doesn't care about these. Give it back something to play with.
|
||||
static DispNodeInfo_t dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
public:
|
||||
CUtlVector<unsigned short> *m_pIndices;
|
||||
};
|
||||
|
||||
|
||||
extern void Disp_AddCollisionModels( CUtlVector<CPhysCollisionEntry *> &collisionList, dmodel_t *pModel, int contentsMask );
|
||||
extern void Disp_BuildVirtualMesh( int contentsMask );
|
||||
extern bool Disp_HasPower4Displacements();
|
||||
|
||||
#endif // DISP_IVP_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,46 +1,46 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VBSP_DISPINFO_H
|
||||
#define VBSP_DISPINFO_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "vbsp.h"
|
||||
|
||||
|
||||
|
||||
class CCoreDispInfo;
|
||||
|
||||
|
||||
extern CUtlVector<CCoreDispInfo*> g_CoreDispInfos;
|
||||
|
||||
|
||||
// Setup initial entries in g_dispinfo with some of the vertex data from the mapdisps.
|
||||
void EmitInitialDispInfos();
|
||||
|
||||
// Resample vertex alpha into lightmap alpha for displacement surfaces so LOD popping artifacts are
|
||||
// less noticeable on the mid-to-high end.
|
||||
//
|
||||
// Also builds neighbor data.
|
||||
void EmitDispLMAlphaAndNeighbors();
|
||||
|
||||
// Setup a CCoreDispInfo given a mapdispinfo_t.
|
||||
// If pFace is non-NULL, then lightmap texture coordinates will be generated.
|
||||
void DispMapToCoreDispInfo( mapdispinfo_t *pMapDisp,
|
||||
CCoreDispInfo *pCoreDispInfo, dface_t *pFace, int *pSwappedTexInfos );
|
||||
|
||||
|
||||
void DispGetFaceInfo( mapbrush_t *pBrush );
|
||||
bool HasDispInfo( mapbrush_t *pBrush );
|
||||
|
||||
// Computes the bounds for a disp info
|
||||
void ComputeDispInfoBounds( int dispinfo, Vector& mins, Vector& maxs );
|
||||
|
||||
#endif // VBSP_DISPINFO_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef VBSP_DISPINFO_H
|
||||
#define VBSP_DISPINFO_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "vbsp.h"
|
||||
|
||||
|
||||
|
||||
class CCoreDispInfo;
|
||||
|
||||
|
||||
extern CUtlVector<CCoreDispInfo*> g_CoreDispInfos;
|
||||
|
||||
|
||||
// Setup initial entries in g_dispinfo with some of the vertex data from the mapdisps.
|
||||
void EmitInitialDispInfos();
|
||||
|
||||
// Resample vertex alpha into lightmap alpha for displacement surfaces so LOD popping artifacts are
|
||||
// less noticeable on the mid-to-high end.
|
||||
//
|
||||
// Also builds neighbor data.
|
||||
void EmitDispLMAlphaAndNeighbors();
|
||||
|
||||
// Setup a CCoreDispInfo given a mapdispinfo_t.
|
||||
// If pFace is non-NULL, then lightmap texture coordinates will be generated.
|
||||
void DispMapToCoreDispInfo( mapdispinfo_t *pMapDisp,
|
||||
CCoreDispInfo *pCoreDispInfo, dface_t *pFace, int *pSwappedTexInfos );
|
||||
|
||||
|
||||
void DispGetFaceInfo( mapbrush_t *pBrush );
|
||||
bool HasDispInfo( mapbrush_t *pBrush );
|
||||
|
||||
// Computes the bounds for a disp info
|
||||
void ComputeDispInfoBounds( int dispinfo, Vector& mins, Vector& maxs );
|
||||
|
||||
#endif // VBSP_DISPINFO_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,20 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef FACES_H
|
||||
#define FACES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
void GetEdge2_InitOptimizedList(); // Call this before calling GetEdge2() on a bunch of edges.
|
||||
int AddEdge( int v1, int v2, face_t *f );
|
||||
int GetEdge2(int v1, int v2, face_t *f);
|
||||
|
||||
|
||||
#endif // FACES_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef FACES_H
|
||||
#define FACES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
void GetEdge2_InitOptimizedList(); // Call this before calling GetEdge2() on a bunch of edges.
|
||||
int AddEdge( int v1, int v2, face_t *f );
|
||||
int GetEdge2(int v1, int v2, face_t *f);
|
||||
|
||||
|
||||
#endif // FACES_H
|
||||
|
||||
@@ -1,219 +1,219 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "vbsp.h"
|
||||
|
||||
int c_glfaces;
|
||||
|
||||
int PortalVisibleSides (portal_t *p)
|
||||
{
|
||||
int fcon, bcon;
|
||||
|
||||
if (!p->onnode)
|
||||
return 0; // outside
|
||||
|
||||
fcon = p->nodes[0]->contents;
|
||||
bcon = p->nodes[1]->contents;
|
||||
|
||||
// same contents never create a face
|
||||
if (fcon == bcon)
|
||||
return 0;
|
||||
|
||||
// FIXME: is this correct now?
|
||||
if (!fcon)
|
||||
return 1;
|
||||
if (!bcon)
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OutputWinding (winding_t *w, FileHandle_t glview)
|
||||
{
|
||||
static int level = 128;
|
||||
vec_t light;
|
||||
int i;
|
||||
|
||||
CmdLib_FPrintf( glview, "%i\n", w->numpoints);
|
||||
level+=28;
|
||||
light = (level&255)/255.0;
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
{
|
||||
CmdLib_FPrintf(glview, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n",
|
||||
w->p[i][0],
|
||||
w->p[i][1],
|
||||
w->p[i][2],
|
||||
light,
|
||||
light,
|
||||
light);
|
||||
}
|
||||
//CmdLib_FPrintf(glview, "\n");
|
||||
}
|
||||
|
||||
void OutputWindingColor (winding_t *w, FileHandle_t glview, int r, int g, int b)
|
||||
{
|
||||
int i;
|
||||
|
||||
CmdLib_FPrintf( glview, "%i\n", w->numpoints);
|
||||
float lr = r * (1.0f/255.0f);
|
||||
float lg = g * (1.0f/255.0f);
|
||||
float lb = b * (1.0f/255.0f);
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
{
|
||||
CmdLib_FPrintf(glview, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n",
|
||||
w->p[i][0],
|
||||
w->p[i][1],
|
||||
w->p[i][2],
|
||||
lr,
|
||||
lg,
|
||||
lb);
|
||||
}
|
||||
//CmdLib_FPrintf(glview, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
OutputPortal
|
||||
=============
|
||||
*/
|
||||
void OutputPortal (portal_t *p, FileHandle_t glview)
|
||||
{
|
||||
winding_t *w;
|
||||
int sides;
|
||||
|
||||
sides = PortalVisibleSides (p);
|
||||
if (!sides)
|
||||
return;
|
||||
|
||||
c_glfaces++;
|
||||
|
||||
w = p->winding;
|
||||
|
||||
if (sides == 2) // back side
|
||||
w = ReverseWinding (w);
|
||||
|
||||
OutputWinding (w, glview);
|
||||
|
||||
if (sides == 2)
|
||||
FreeWinding(w);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
WriteGLView_r
|
||||
=============
|
||||
*/
|
||||
void WriteGLView_r (node_t *node, FileHandle_t glview)
|
||||
{
|
||||
portal_t *p, *nextp;
|
||||
|
||||
if (node->planenum != PLANENUM_LEAF)
|
||||
{
|
||||
WriteGLView_r (node->children[0], glview);
|
||||
WriteGLView_r (node->children[1], glview);
|
||||
return;
|
||||
}
|
||||
|
||||
// write all the portals
|
||||
for (p=node->portals ; p ; p=nextp)
|
||||
{
|
||||
if (p->nodes[0] == node)
|
||||
{
|
||||
OutputPortal (p, glview);
|
||||
nextp = p->next[0];
|
||||
}
|
||||
else
|
||||
nextp = p->next[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WriteGLViewFaces_r( node_t *node, FileHandle_t glview )
|
||||
{
|
||||
portal_t *p, *nextp;
|
||||
|
||||
if (node->planenum != PLANENUM_LEAF)
|
||||
{
|
||||
WriteGLViewFaces_r (node->children[0], glview);
|
||||
WriteGLViewFaces_r (node->children[1], glview);
|
||||
return;
|
||||
}
|
||||
|
||||
// write all the portals
|
||||
for (p=node->portals ; p ; p=nextp)
|
||||
{
|
||||
int s = (p->nodes[1] == node);
|
||||
|
||||
if ( p->face[s] )
|
||||
{
|
||||
OutputWinding( p->face[s]->w, glview );
|
||||
}
|
||||
nextp = p->next[s];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
WriteGLView
|
||||
=============
|
||||
*/
|
||||
void WriteGLView (tree_t *tree, char *source)
|
||||
{
|
||||
char name[1024];
|
||||
FileHandle_t glview;
|
||||
|
||||
c_glfaces = 0;
|
||||
sprintf (name, "%s%s.gl",outbase, source);
|
||||
Msg("Writing %s\n", name);
|
||||
|
||||
glview = g_pFileSystem->Open( name, "w" );
|
||||
if (!glview)
|
||||
Error ("Couldn't open %s", name);
|
||||
WriteGLView_r (tree->headnode, glview);
|
||||
g_pFileSystem->Close( glview );
|
||||
|
||||
Msg("%5i c_glfaces\n", c_glfaces);
|
||||
}
|
||||
|
||||
|
||||
void WriteGLViewFaces( tree_t *tree, const char *pName )
|
||||
{
|
||||
char name[1024];
|
||||
FileHandle_t glview;
|
||||
|
||||
c_glfaces = 0;
|
||||
sprintf (name, "%s%s.gl", outbase, pName);
|
||||
Msg("Writing %s\n", name);
|
||||
|
||||
glview = g_pFileSystem->Open( name, "w" );
|
||||
if (!glview)
|
||||
Error ("Couldn't open %s", name);
|
||||
WriteGLViewFaces_r (tree->headnode, glview);
|
||||
g_pFileSystem->Close( glview );
|
||||
|
||||
Msg("%5i c_glfaces\n", c_glfaces);
|
||||
}
|
||||
|
||||
|
||||
void WriteGLViewBrushList( bspbrush_t *pList, const char *pName )
|
||||
{
|
||||
char name[1024];
|
||||
FileHandle_t glview;
|
||||
|
||||
sprintf (name, "%s%s.gl", outbase, pName );
|
||||
Msg("Writing %s\n", name);
|
||||
|
||||
glview = g_pFileSystem->Open( name, "w" );
|
||||
if (!glview)
|
||||
Error ("Couldn't open %s", name);
|
||||
for ( bspbrush_t *pBrush = pList; pBrush; pBrush = pBrush->next )
|
||||
{
|
||||
for (int i = 0; i < pBrush->numsides; i++ )
|
||||
OutputWinding( pBrush->sides[i].winding, glview );
|
||||
}
|
||||
g_pFileSystem->Close( glview );
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "vbsp.h"
|
||||
|
||||
int c_glfaces;
|
||||
|
||||
int PortalVisibleSides (portal_t *p)
|
||||
{
|
||||
int fcon, bcon;
|
||||
|
||||
if (!p->onnode)
|
||||
return 0; // outside
|
||||
|
||||
fcon = p->nodes[0]->contents;
|
||||
bcon = p->nodes[1]->contents;
|
||||
|
||||
// same contents never create a face
|
||||
if (fcon == bcon)
|
||||
return 0;
|
||||
|
||||
// FIXME: is this correct now?
|
||||
if (!fcon)
|
||||
return 1;
|
||||
if (!bcon)
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OutputWinding (winding_t *w, FileHandle_t glview)
|
||||
{
|
||||
static int level = 128;
|
||||
vec_t light;
|
||||
int i;
|
||||
|
||||
CmdLib_FPrintf( glview, "%i\n", w->numpoints);
|
||||
level+=28;
|
||||
light = (level&255)/255.0;
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
{
|
||||
CmdLib_FPrintf(glview, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n",
|
||||
w->p[i][0],
|
||||
w->p[i][1],
|
||||
w->p[i][2],
|
||||
light,
|
||||
light,
|
||||
light);
|
||||
}
|
||||
//CmdLib_FPrintf(glview, "\n");
|
||||
}
|
||||
|
||||
void OutputWindingColor (winding_t *w, FileHandle_t glview, int r, int g, int b)
|
||||
{
|
||||
int i;
|
||||
|
||||
CmdLib_FPrintf( glview, "%i\n", w->numpoints);
|
||||
float lr = r * (1.0f/255.0f);
|
||||
float lg = g * (1.0f/255.0f);
|
||||
float lb = b * (1.0f/255.0f);
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
{
|
||||
CmdLib_FPrintf(glview, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n",
|
||||
w->p[i][0],
|
||||
w->p[i][1],
|
||||
w->p[i][2],
|
||||
lr,
|
||||
lg,
|
||||
lb);
|
||||
}
|
||||
//CmdLib_FPrintf(glview, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
OutputPortal
|
||||
=============
|
||||
*/
|
||||
void OutputPortal (portal_t *p, FileHandle_t glview)
|
||||
{
|
||||
winding_t *w;
|
||||
int sides;
|
||||
|
||||
sides = PortalVisibleSides (p);
|
||||
if (!sides)
|
||||
return;
|
||||
|
||||
c_glfaces++;
|
||||
|
||||
w = p->winding;
|
||||
|
||||
if (sides == 2) // back side
|
||||
w = ReverseWinding (w);
|
||||
|
||||
OutputWinding (w, glview);
|
||||
|
||||
if (sides == 2)
|
||||
FreeWinding(w);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
WriteGLView_r
|
||||
=============
|
||||
*/
|
||||
void WriteGLView_r (node_t *node, FileHandle_t glview)
|
||||
{
|
||||
portal_t *p, *nextp;
|
||||
|
||||
if (node->planenum != PLANENUM_LEAF)
|
||||
{
|
||||
WriteGLView_r (node->children[0], glview);
|
||||
WriteGLView_r (node->children[1], glview);
|
||||
return;
|
||||
}
|
||||
|
||||
// write all the portals
|
||||
for (p=node->portals ; p ; p=nextp)
|
||||
{
|
||||
if (p->nodes[0] == node)
|
||||
{
|
||||
OutputPortal (p, glview);
|
||||
nextp = p->next[0];
|
||||
}
|
||||
else
|
||||
nextp = p->next[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WriteGLViewFaces_r( node_t *node, FileHandle_t glview )
|
||||
{
|
||||
portal_t *p, *nextp;
|
||||
|
||||
if (node->planenum != PLANENUM_LEAF)
|
||||
{
|
||||
WriteGLViewFaces_r (node->children[0], glview);
|
||||
WriteGLViewFaces_r (node->children[1], glview);
|
||||
return;
|
||||
}
|
||||
|
||||
// write all the portals
|
||||
for (p=node->portals ; p ; p=nextp)
|
||||
{
|
||||
int s = (p->nodes[1] == node);
|
||||
|
||||
if ( p->face[s] )
|
||||
{
|
||||
OutputWinding( p->face[s]->w, glview );
|
||||
}
|
||||
nextp = p->next[s];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
WriteGLView
|
||||
=============
|
||||
*/
|
||||
void WriteGLView (tree_t *tree, char *source)
|
||||
{
|
||||
char name[1024];
|
||||
FileHandle_t glview;
|
||||
|
||||
c_glfaces = 0;
|
||||
sprintf (name, "%s%s.gl",outbase, source);
|
||||
Msg("Writing %s\n", name);
|
||||
|
||||
glview = g_pFileSystem->Open( name, "w" );
|
||||
if (!glview)
|
||||
Error ("Couldn't open %s", name);
|
||||
WriteGLView_r (tree->headnode, glview);
|
||||
g_pFileSystem->Close( glview );
|
||||
|
||||
Msg("%5i c_glfaces\n", c_glfaces);
|
||||
}
|
||||
|
||||
|
||||
void WriteGLViewFaces( tree_t *tree, const char *pName )
|
||||
{
|
||||
char name[1024];
|
||||
FileHandle_t glview;
|
||||
|
||||
c_glfaces = 0;
|
||||
sprintf (name, "%s%s.gl", outbase, pName);
|
||||
Msg("Writing %s\n", name);
|
||||
|
||||
glview = g_pFileSystem->Open( name, "w" );
|
||||
if (!glview)
|
||||
Error ("Couldn't open %s", name);
|
||||
WriteGLViewFaces_r (tree->headnode, glview);
|
||||
g_pFileSystem->Close( glview );
|
||||
|
||||
Msg("%5i c_glfaces\n", c_glfaces);
|
||||
}
|
||||
|
||||
|
||||
void WriteGLViewBrushList( bspbrush_t *pList, const char *pName )
|
||||
{
|
||||
char name[1024];
|
||||
FileHandle_t glview;
|
||||
|
||||
sprintf (name, "%s%s.gl", outbase, pName );
|
||||
Msg("Writing %s\n", name);
|
||||
|
||||
glview = g_pFileSystem->Open( name, "w" );
|
||||
if (!glview)
|
||||
Error ("Couldn't open %s", name);
|
||||
for ( bspbrush_t *pBrush = pList; pBrush; pBrush = pBrush->next )
|
||||
{
|
||||
for (int i = 0; i < pBrush->numsides; i++ )
|
||||
OutputWinding( pBrush->sides[i].winding, glview );
|
||||
}
|
||||
g_pFileSystem->Close( glview );
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,75 +1,75 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef IVP_H
|
||||
#define IVP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utlvector.h"
|
||||
|
||||
class CPhysCollide;
|
||||
class CTextBuffer;
|
||||
class IPhysicsCollision;
|
||||
extern IPhysicsCollision *physcollision;
|
||||
|
||||
// a list of all of the materials in the world model
|
||||
extern int RemapWorldMaterial( int materialIndexIn );
|
||||
|
||||
class CPhysCollisionEntry
|
||||
{
|
||||
public:
|
||||
CPhysCollisionEntry( CPhysCollide *pCollide );
|
||||
|
||||
virtual void WriteToTextBuffer( CTextBuffer *pTextBuffer, int modelIndex, int collideIndex ) = 0;
|
||||
virtual void DumpCollide( CTextBuffer *pTextBuffer, int modelIndex, int collideIndex ) = 0;
|
||||
|
||||
unsigned int GetCollisionBinarySize();
|
||||
unsigned int WriteCollisionBinary( char *pDest );
|
||||
|
||||
protected:
|
||||
void DumpCollideFileName( const char *pName, int modelIndex, CTextBuffer *pTextBuffer );
|
||||
|
||||
protected:
|
||||
CPhysCollide *m_pCollide;
|
||||
};
|
||||
|
||||
class CPhysCollisionEntryStaticMesh : public CPhysCollisionEntry
|
||||
{
|
||||
public:
|
||||
CPhysCollisionEntryStaticMesh( CPhysCollide *pCollide, const char *pMaterialName );
|
||||
|
||||
virtual void WriteToTextBuffer( CTextBuffer *pTextBuffer, int modelIndex, int collideIndex );
|
||||
virtual void DumpCollide( CTextBuffer *pTextBuffer, int modelIndex, int collideIndex );
|
||||
|
||||
private:
|
||||
const char *m_pMaterial;
|
||||
};
|
||||
|
||||
|
||||
class CTextBuffer
|
||||
{
|
||||
public:
|
||||
CTextBuffer( void );
|
||||
~CTextBuffer( void );
|
||||
inline int GetSize( void ) { return m_buffer.Count(); }
|
||||
inline char *GetData( void ) { return m_buffer.Base(); }
|
||||
|
||||
void WriteText( const char *pText );
|
||||
void WriteIntKey( const char *pKeyName, int outputData );
|
||||
void WriteStringKey( const char *pKeyName, const char *outputData );
|
||||
void WriteFloatKey( const char *pKeyName, float outputData );
|
||||
void WriteFloatArrayKey( const char *pKeyName, const float *outputData, int count );
|
||||
|
||||
void CopyStringQuotes( const char *pString );
|
||||
void Terminate( void );
|
||||
private:
|
||||
void CopyData( const char *pData, int len );
|
||||
CUtlVector<char> m_buffer;
|
||||
};
|
||||
|
||||
#endif // IVP_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef IVP_H
|
||||
#define IVP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utlvector.h"
|
||||
|
||||
class CPhysCollide;
|
||||
class CTextBuffer;
|
||||
class IPhysicsCollision;
|
||||
extern IPhysicsCollision *physcollision;
|
||||
|
||||
// a list of all of the materials in the world model
|
||||
extern int RemapWorldMaterial( int materialIndexIn );
|
||||
|
||||
class CPhysCollisionEntry
|
||||
{
|
||||
public:
|
||||
CPhysCollisionEntry( CPhysCollide *pCollide );
|
||||
|
||||
virtual void WriteToTextBuffer( CTextBuffer *pTextBuffer, int modelIndex, int collideIndex ) = 0;
|
||||
virtual void DumpCollide( CTextBuffer *pTextBuffer, int modelIndex, int collideIndex ) = 0;
|
||||
|
||||
unsigned int GetCollisionBinarySize();
|
||||
unsigned int WriteCollisionBinary( char *pDest );
|
||||
|
||||
protected:
|
||||
void DumpCollideFileName( const char *pName, int modelIndex, CTextBuffer *pTextBuffer );
|
||||
|
||||
protected:
|
||||
CPhysCollide *m_pCollide;
|
||||
};
|
||||
|
||||
class CPhysCollisionEntryStaticMesh : public CPhysCollisionEntry
|
||||
{
|
||||
public:
|
||||
CPhysCollisionEntryStaticMesh( CPhysCollide *pCollide, const char *pMaterialName );
|
||||
|
||||
virtual void WriteToTextBuffer( CTextBuffer *pTextBuffer, int modelIndex, int collideIndex );
|
||||
virtual void DumpCollide( CTextBuffer *pTextBuffer, int modelIndex, int collideIndex );
|
||||
|
||||
private:
|
||||
const char *m_pMaterial;
|
||||
};
|
||||
|
||||
|
||||
class CTextBuffer
|
||||
{
|
||||
public:
|
||||
CTextBuffer( void );
|
||||
~CTextBuffer( void );
|
||||
inline int GetSize( void ) { return m_buffer.Count(); }
|
||||
inline char *GetData( void ) { return m_buffer.Base(); }
|
||||
|
||||
void WriteText( const char *pText );
|
||||
void WriteIntKey( const char *pKeyName, int outputData );
|
||||
void WriteStringKey( const char *pKeyName, const char *outputData );
|
||||
void WriteFloatKey( const char *pKeyName, float outputData );
|
||||
void WriteFloatArrayKey( const char *pKeyName, const float *outputData, int count );
|
||||
|
||||
void CopyStringQuotes( const char *pString );
|
||||
void Terminate( void );
|
||||
private:
|
||||
void CopyData( const char *pData, int len );
|
||||
CUtlVector<char> m_buffer;
|
||||
};
|
||||
|
||||
#endif // IVP_H
|
||||
|
||||
@@ -1,168 +1,168 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "vbsp.h"
|
||||
#include "color.h"
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
LEAF FILE GENERATION
|
||||
|
||||
Save out name.line for qe3 to read
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
LeakFile
|
||||
|
||||
Finds the shortest possible chain of portals
|
||||
that leads from the outside leaf to a specifically
|
||||
occupied leaf
|
||||
=============
|
||||
*/
|
||||
void LeakFile (tree_t *tree)
|
||||
{
|
||||
Vector mid;
|
||||
FILE *linefile;
|
||||
char filename[1024];
|
||||
node_t *node;
|
||||
int count;
|
||||
|
||||
if (!tree->outside_node.occupied)
|
||||
return;
|
||||
|
||||
tree->leaked = true;
|
||||
qprintf ("--- LeakFile ---\n");
|
||||
|
||||
//
|
||||
// write the points to the file
|
||||
//
|
||||
sprintf (filename, "%s.lin", source);
|
||||
linefile = fopen (filename, "w");
|
||||
if (!linefile)
|
||||
Error ("Couldn't open %s\n", filename);
|
||||
|
||||
count = 0;
|
||||
node = &tree->outside_node;
|
||||
while (node->occupied > 1)
|
||||
{
|
||||
portal_t *nextportal = NULL;
|
||||
node_t *nextnode = NULL;
|
||||
int s = 0;
|
||||
|
||||
// find the best portal exit
|
||||
int next = node->occupied;
|
||||
for (portal_t *p=node->portals ; p ; p = p->next[!s])
|
||||
{
|
||||
s = (p->nodes[0] == node);
|
||||
if (p->nodes[s]->occupied
|
||||
&& p->nodes[s]->occupied < next)
|
||||
{
|
||||
nextportal = p;
|
||||
nextnode = p->nodes[s];
|
||||
next = nextnode->occupied;
|
||||
}
|
||||
}
|
||||
node = nextnode;
|
||||
WindingCenter (nextportal->winding, mid);
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
count++;
|
||||
}
|
||||
|
||||
// Add the occupant's origin to the leakfile.
|
||||
Vector origin;
|
||||
GetVectorForKey (node->occupant, "origin", origin);
|
||||
|
||||
fprintf (linefile, "%f %f %f\n", origin[0], origin[1], origin[2]);
|
||||
qprintf ("%5i point linefile\n", count+1);
|
||||
|
||||
fclose (linefile);
|
||||
|
||||
// Emit a leak warning.
|
||||
const char *cl = ValueForKey (node->occupant, "classname");
|
||||
Color red(255,0,0,255);
|
||||
ColorSpewMessage( SPEW_MESSAGE, &red, "Entity %s (%.2f %.2f %.2f) leaked!\n", cl, origin[0], origin[1], origin[2] );
|
||||
}
|
||||
|
||||
void AreaportalLeakFile( tree_t *tree, portal_t *pStartPortal, portal_t *pEndPortal, node_t *pStart )
|
||||
{
|
||||
Vector mid;
|
||||
FILE *linefile;
|
||||
char filename[1024];
|
||||
node_t *node;
|
||||
int count;
|
||||
|
||||
// wrote a leak line file already, don't overwrite it with the areaportal leak file
|
||||
if ( tree->leaked )
|
||||
return;
|
||||
|
||||
tree->leaked = true;
|
||||
qprintf ("--- LeakFile ---\n");
|
||||
|
||||
//
|
||||
// write the points to the file
|
||||
//
|
||||
sprintf (filename, "%s.lin", source);
|
||||
linefile = fopen (filename, "w");
|
||||
if (!linefile)
|
||||
Error ("Couldn't open %s\n", filename);
|
||||
|
||||
count = 2;
|
||||
WindingCenter (pEndPortal->winding, mid);
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
mid = 0.5 * (pStart->mins + pStart->maxs);
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
|
||||
node = pStart;
|
||||
while (node->occupied >= 1)
|
||||
{
|
||||
portal_t *nextportal = NULL;
|
||||
node_t *nextnode = NULL;
|
||||
int s = 0;
|
||||
|
||||
// find the best portal exit
|
||||
int next = node->occupied;
|
||||
for (portal_t *p=node->portals ; p ; p = p->next[!s])
|
||||
{
|
||||
s = (p->nodes[0] == node);
|
||||
if (p->nodes[s]->occupied
|
||||
&& p->nodes[s]->occupied < next)
|
||||
{
|
||||
nextportal = p;
|
||||
nextnode = p->nodes[s];
|
||||
next = nextnode->occupied;
|
||||
}
|
||||
}
|
||||
if ( !nextnode )
|
||||
break;
|
||||
node = nextnode;
|
||||
WindingCenter (nextportal->winding, mid);
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
count++;
|
||||
}
|
||||
// add the occupant center
|
||||
if ( node )
|
||||
{
|
||||
mid = 0.5 * (node->mins + node->maxs);
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
count++;
|
||||
}
|
||||
WindingCenter (pStartPortal->winding, mid);
|
||||
count++;
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
|
||||
qprintf ("%5i point linefile\n", count);
|
||||
|
||||
fclose (linefile);
|
||||
Warning( "Wrote %s\n", filename );
|
||||
Color red(255,0,0,255);
|
||||
ColorSpewMessage( SPEW_MESSAGE, &red, "Areaportal leak ! File: %s ", filename );
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "vbsp.h"
|
||||
#include "color.h"
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
LEAF FILE GENERATION
|
||||
|
||||
Save out name.line for qe3 to read
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
LeakFile
|
||||
|
||||
Finds the shortest possible chain of portals
|
||||
that leads from the outside leaf to a specifically
|
||||
occupied leaf
|
||||
=============
|
||||
*/
|
||||
void LeakFile (tree_t *tree)
|
||||
{
|
||||
Vector mid;
|
||||
FILE *linefile;
|
||||
char filename[1024];
|
||||
node_t *node;
|
||||
int count;
|
||||
|
||||
if (!tree->outside_node.occupied)
|
||||
return;
|
||||
|
||||
tree->leaked = true;
|
||||
qprintf ("--- LeakFile ---\n");
|
||||
|
||||
//
|
||||
// write the points to the file
|
||||
//
|
||||
sprintf (filename, "%s.lin", source);
|
||||
linefile = fopen (filename, "w");
|
||||
if (!linefile)
|
||||
Error ("Couldn't open %s\n", filename);
|
||||
|
||||
count = 0;
|
||||
node = &tree->outside_node;
|
||||
while (node->occupied > 1)
|
||||
{
|
||||
portal_t *nextportal = NULL;
|
||||
node_t *nextnode = NULL;
|
||||
int s = 0;
|
||||
|
||||
// find the best portal exit
|
||||
int next = node->occupied;
|
||||
for (portal_t *p=node->portals ; p ; p = p->next[!s])
|
||||
{
|
||||
s = (p->nodes[0] == node);
|
||||
if (p->nodes[s]->occupied
|
||||
&& p->nodes[s]->occupied < next)
|
||||
{
|
||||
nextportal = p;
|
||||
nextnode = p->nodes[s];
|
||||
next = nextnode->occupied;
|
||||
}
|
||||
}
|
||||
node = nextnode;
|
||||
WindingCenter (nextportal->winding, mid);
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
count++;
|
||||
}
|
||||
|
||||
// Add the occupant's origin to the leakfile.
|
||||
Vector origin;
|
||||
GetVectorForKey (node->occupant, "origin", origin);
|
||||
|
||||
fprintf (linefile, "%f %f %f\n", origin[0], origin[1], origin[2]);
|
||||
qprintf ("%5i point linefile\n", count+1);
|
||||
|
||||
fclose (linefile);
|
||||
|
||||
// Emit a leak warning.
|
||||
const char *cl = ValueForKey (node->occupant, "classname");
|
||||
Color red(255,0,0,255);
|
||||
ColorSpewMessage( SPEW_MESSAGE, &red, "Entity %s (%.2f %.2f %.2f) leaked!\n", cl, origin[0], origin[1], origin[2] );
|
||||
}
|
||||
|
||||
void AreaportalLeakFile( tree_t *tree, portal_t *pStartPortal, portal_t *pEndPortal, node_t *pStart )
|
||||
{
|
||||
Vector mid;
|
||||
FILE *linefile;
|
||||
char filename[1024];
|
||||
node_t *node;
|
||||
int count;
|
||||
|
||||
// wrote a leak line file already, don't overwrite it with the areaportal leak file
|
||||
if ( tree->leaked )
|
||||
return;
|
||||
|
||||
tree->leaked = true;
|
||||
qprintf ("--- LeakFile ---\n");
|
||||
|
||||
//
|
||||
// write the points to the file
|
||||
//
|
||||
sprintf (filename, "%s.lin", source);
|
||||
linefile = fopen (filename, "w");
|
||||
if (!linefile)
|
||||
Error ("Couldn't open %s\n", filename);
|
||||
|
||||
count = 2;
|
||||
WindingCenter (pEndPortal->winding, mid);
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
mid = 0.5 * (pStart->mins + pStart->maxs);
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
|
||||
node = pStart;
|
||||
while (node->occupied >= 1)
|
||||
{
|
||||
portal_t *nextportal = NULL;
|
||||
node_t *nextnode = NULL;
|
||||
int s = 0;
|
||||
|
||||
// find the best portal exit
|
||||
int next = node->occupied;
|
||||
for (portal_t *p=node->portals ; p ; p = p->next[!s])
|
||||
{
|
||||
s = (p->nodes[0] == node);
|
||||
if (p->nodes[s]->occupied
|
||||
&& p->nodes[s]->occupied < next)
|
||||
{
|
||||
nextportal = p;
|
||||
nextnode = p->nodes[s];
|
||||
next = nextnode->occupied;
|
||||
}
|
||||
}
|
||||
if ( !nextnode )
|
||||
break;
|
||||
node = nextnode;
|
||||
WindingCenter (nextportal->winding, mid);
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
count++;
|
||||
}
|
||||
// add the occupant center
|
||||
if ( node )
|
||||
{
|
||||
mid = 0.5 * (node->mins + node->maxs);
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
count++;
|
||||
}
|
||||
WindingCenter (pStartPortal->winding, mid);
|
||||
count++;
|
||||
fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
|
||||
|
||||
qprintf ("%5i point linefile\n", count);
|
||||
|
||||
fclose (linefile);
|
||||
Warning( "Wrote %s\n", filename );
|
||||
Color red(255,0,0,255);
|
||||
ColorSpewMessage( SPEW_MESSAGE, &red, "Areaportal leak ! File: %s ", filename );
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,73 +1,73 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=====================================================================================//
|
||||
|
||||
#ifndef __MANIFEST_H
|
||||
#define __MANIFEST_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "boundbox.h"
|
||||
|
||||
//
|
||||
// Each cordon is a named collection of bounding boxes.
|
||||
//
|
||||
struct Cordon_t
|
||||
{
|
||||
inline Cordon_t()
|
||||
{
|
||||
m_bActive = false;
|
||||
}
|
||||
|
||||
CUtlString m_szName;
|
||||
bool m_bActive; // True means cull using this cordon when cordoning is enabled.
|
||||
CUtlVector<BoundBox> m_Boxes;
|
||||
};
|
||||
|
||||
class CManifestMap
|
||||
{
|
||||
public:
|
||||
CManifestMap( void );
|
||||
char m_RelativeMapFileName[ MAX_PATH ];
|
||||
bool m_bTopLevelMap;
|
||||
};
|
||||
|
||||
class CManifest
|
||||
{
|
||||
public:
|
||||
CManifest( void );
|
||||
|
||||
static ChunkFileResult_t LoadManifestMapKeyCallback( const char *szKey, const char *szValue, CManifestMap *pManifestMap );
|
||||
static ChunkFileResult_t LoadManifestVMFCallback( CChunkFile *pFile, CManifest *pManifest );
|
||||
static ChunkFileResult_t LoadManifestMapsCallback( CChunkFile *pFile, CManifest *pManifest );
|
||||
static ChunkFileResult_t LoadCordonBoxCallback( CChunkFile *pFile, Cordon_t *pCordon );
|
||||
static ChunkFileResult_t LoadCordonBoxKeyCallback( const char *szKey, const char *szValue, BoundBox *pBox );
|
||||
static ChunkFileResult_t LoadCordonKeyCallback( const char *szKey, const char *szValue, Cordon_t *pCordon );
|
||||
static ChunkFileResult_t LoadCordonCallback( CChunkFile *pFile, CManifest *pManifest );
|
||||
static ChunkFileResult_t LoadCordonsKeyCallback( const char *pszKey, const char *pszValue, CManifest *pManifest );
|
||||
static ChunkFileResult_t LoadCordonsCallback( CChunkFile *pFile, CManifest *pManifest );
|
||||
static ChunkFileResult_t LoadManifestCordoningPrefsCallback( CChunkFile *pFile, CManifest *pManifest );
|
||||
|
||||
bool LoadSubMaps( CMapFile *pMapFile, const char *pszFileName );
|
||||
epair_t *CreateEPair( char *pKey, char *pValue );
|
||||
bool LoadVMFManifest( const char *pszFileName );
|
||||
const char *GetInstancePath( ) { return m_InstancePath; }
|
||||
|
||||
void CordonWorld( );
|
||||
|
||||
private:
|
||||
bool LoadVMFManifestUserPrefs( const char *pszFileName );
|
||||
|
||||
|
||||
CUtlVector< CManifestMap * > m_Maps;
|
||||
char m_InstancePath[ MAX_PATH ];
|
||||
bool m_bIsCordoning;
|
||||
CUtlVector< Cordon_t > m_Cordons;
|
||||
entity_t *m_CordoningMapEnt;
|
||||
};
|
||||
|
||||
#endif // #ifndef __MANIFEST_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=====================================================================================//
|
||||
|
||||
#ifndef __MANIFEST_H
|
||||
#define __MANIFEST_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "boundbox.h"
|
||||
|
||||
//
|
||||
// Each cordon is a named collection of bounding boxes.
|
||||
//
|
||||
struct Cordon_t
|
||||
{
|
||||
inline Cordon_t()
|
||||
{
|
||||
m_bActive = false;
|
||||
}
|
||||
|
||||
CUtlString m_szName;
|
||||
bool m_bActive; // True means cull using this cordon when cordoning is enabled.
|
||||
CUtlVector<BoundBox> m_Boxes;
|
||||
};
|
||||
|
||||
class CManifestMap
|
||||
{
|
||||
public:
|
||||
CManifestMap( void );
|
||||
char m_RelativeMapFileName[ MAX_PATH ];
|
||||
bool m_bTopLevelMap;
|
||||
};
|
||||
|
||||
class CManifest
|
||||
{
|
||||
public:
|
||||
CManifest( void );
|
||||
|
||||
static ChunkFileResult_t LoadManifestMapKeyCallback( const char *szKey, const char *szValue, CManifestMap *pManifestMap );
|
||||
static ChunkFileResult_t LoadManifestVMFCallback( CChunkFile *pFile, CManifest *pManifest );
|
||||
static ChunkFileResult_t LoadManifestMapsCallback( CChunkFile *pFile, CManifest *pManifest );
|
||||
static ChunkFileResult_t LoadCordonBoxCallback( CChunkFile *pFile, Cordon_t *pCordon );
|
||||
static ChunkFileResult_t LoadCordonBoxKeyCallback( const char *szKey, const char *szValue, BoundBox *pBox );
|
||||
static ChunkFileResult_t LoadCordonKeyCallback( const char *szKey, const char *szValue, Cordon_t *pCordon );
|
||||
static ChunkFileResult_t LoadCordonCallback( CChunkFile *pFile, CManifest *pManifest );
|
||||
static ChunkFileResult_t LoadCordonsKeyCallback( const char *pszKey, const char *pszValue, CManifest *pManifest );
|
||||
static ChunkFileResult_t LoadCordonsCallback( CChunkFile *pFile, CManifest *pManifest );
|
||||
static ChunkFileResult_t LoadManifestCordoningPrefsCallback( CChunkFile *pFile, CManifest *pManifest );
|
||||
|
||||
bool LoadSubMaps( CMapFile *pMapFile, const char *pszFileName );
|
||||
epair_t *CreateEPair( char *pKey, char *pValue );
|
||||
bool LoadVMFManifest( const char *pszFileName );
|
||||
const char *GetInstancePath( ) { return m_InstancePath; }
|
||||
|
||||
void CordonWorld( );
|
||||
|
||||
private:
|
||||
bool LoadVMFManifestUserPrefs( const char *pszFileName );
|
||||
|
||||
|
||||
CUtlVector< CManifestMap * > m_Maps;
|
||||
char m_InstancePath[ MAX_PATH ];
|
||||
bool m_bIsCordoning;
|
||||
CUtlVector< Cordon_t > m_Cordons;
|
||||
entity_t *m_CordoningMapEnt;
|
||||
};
|
||||
|
||||
#endif // #ifndef __MANIFEST_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,18 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MAP_H
|
||||
#define MAP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// All the brush sides referenced by info_no_dynamic_shadow entities.
|
||||
extern CUtlVector<int> g_NoDynamicShadowSides;
|
||||
|
||||
|
||||
#endif // MAP_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MAP_H
|
||||
#define MAP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// All the brush sides referenced by info_no_dynamic_shadow entities.
|
||||
extern CUtlVector<int> g_NoDynamicShadowSides;
|
||||
|
||||
|
||||
#endif // MAP_H
|
||||
|
||||
@@ -1,440 +1,440 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "vbsp.h"
|
||||
#include "UtlBuffer.h"
|
||||
#include "utlsymbol.h"
|
||||
#include "utlrbtree.h"
|
||||
#include "KeyValues.h"
|
||||
#include "bsplib.h"
|
||||
#include "materialpatch.h"
|
||||
#include "tier1/strtools.h"
|
||||
|
||||
// case insensitive
|
||||
static CUtlSymbolTable s_SymbolTable( 0, 32, true );
|
||||
|
||||
struct NameTranslationLookup_t
|
||||
{
|
||||
CUtlSymbol m_OriginalFileName;
|
||||
CUtlSymbol m_PatchFileName;
|
||||
};
|
||||
|
||||
static bool NameTranslationLessFunc( NameTranslationLookup_t const& src1,
|
||||
NameTranslationLookup_t const& src2 )
|
||||
{
|
||||
return src1.m_PatchFileName < src2.m_PatchFileName;
|
||||
}
|
||||
|
||||
CUtlRBTree<NameTranslationLookup_t, int> s_MapPatchedMatToOriginalMat( 0, 256, NameTranslationLessFunc );
|
||||
|
||||
void AddNewTranslation( const char *pOriginalMaterialName, const char *pNewMaterialName )
|
||||
{
|
||||
NameTranslationLookup_t newEntry;
|
||||
|
||||
newEntry.m_OriginalFileName = s_SymbolTable.AddString( pOriginalMaterialName );
|
||||
newEntry.m_PatchFileName = s_SymbolTable.AddString( pNewMaterialName );
|
||||
|
||||
s_MapPatchedMatToOriginalMat.Insert( newEntry );
|
||||
}
|
||||
|
||||
const char *GetOriginalMaterialNameForPatchedMaterial( const char *pPatchMaterialName )
|
||||
{
|
||||
const char *pRetName = NULL;
|
||||
int id;
|
||||
NameTranslationLookup_t lookup;
|
||||
lookup.m_PatchFileName = s_SymbolTable.AddString( pPatchMaterialName );
|
||||
do
|
||||
{
|
||||
id = s_MapPatchedMatToOriginalMat.Find( lookup );
|
||||
if( id >= 0 )
|
||||
{
|
||||
NameTranslationLookup_t &found = s_MapPatchedMatToOriginalMat[id];
|
||||
lookup.m_PatchFileName = found.m_OriginalFileName;
|
||||
pRetName = s_SymbolTable.String( found.m_OriginalFileName );
|
||||
}
|
||||
} while( id >= 0 );
|
||||
if( !pRetName )
|
||||
{
|
||||
// This isn't a patched material, so just return the original name.
|
||||
return pPatchMaterialName;
|
||||
}
|
||||
return pRetName;
|
||||
}
|
||||
|
||||
|
||||
void CreateMaterialPatchRecursive( KeyValues *pOriginalKeyValues, KeyValues *pPatchKeyValues, int nKeys, const MaterialPatchInfo_t *pInfo )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < nKeys; i++ )
|
||||
{
|
||||
const char *pVal = pOriginalKeyValues->GetString( pInfo[i].m_pKey, NULL );
|
||||
if( !pVal )
|
||||
continue;
|
||||
if( pInfo[i].m_pRequiredOriginalValue && Q_stricmp( pVal, pInfo[i].m_pRequiredOriginalValue ) != 0 )
|
||||
continue;
|
||||
pPatchKeyValues->SetString( pInfo[i].m_pKey, pInfo[i].m_pValue );
|
||||
}
|
||||
KeyValues *pScan;
|
||||
for( pScan = pOriginalKeyValues->GetFirstTrueSubKey(); pScan; pScan = pScan->GetNextTrueSubKey() )
|
||||
{
|
||||
CreateMaterialPatchRecursive( pScan, pPatchKeyValues->FindKey( pScan->GetName(), true ), nKeys, pInfo );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A version which allows you to patch multiple key values
|
||||
//-----------------------------------------------------------------------------
|
||||
void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName,
|
||||
int nKeys, const MaterialPatchInfo_t *pInfo, MaterialPatchType_t nPatchType )
|
||||
{
|
||||
char pOldVMTFile[ 512 ];
|
||||
char pNewVMTFile[ 512 ];
|
||||
|
||||
AddNewTranslation( pOriginalMaterialName, pNewMaterialName );
|
||||
|
||||
Q_snprintf( pOldVMTFile, 512, "materials/%s.vmt", pOriginalMaterialName );
|
||||
Q_snprintf( pNewVMTFile, 512, "materials/%s.vmt", pNewMaterialName );
|
||||
|
||||
// printf( "Creating material patch file %s which points at %s\n", newVMTFile, oldVMTFile );
|
||||
|
||||
KeyValues *kv = new KeyValues( "patch" );
|
||||
if ( !kv )
|
||||
{
|
||||
Error( "Couldn't allocate KeyValues for %s!!!", pNewMaterialName );
|
||||
}
|
||||
|
||||
kv->SetString( "include", pOldVMTFile );
|
||||
|
||||
const char *pSectionName = (nPatchType == PATCH_INSERT) ? "insert" : "replace";
|
||||
KeyValues *section = kv->FindKey( pSectionName, true );
|
||||
|
||||
if( nPatchType == PATCH_REPLACE )
|
||||
{
|
||||
char name[512];
|
||||
Q_snprintf( name, 512, "materials/%s.vmt", GetOriginalMaterialNameForPatchedMaterial( pOriginalMaterialName ) );
|
||||
KeyValues *origkv = new KeyValues( "blah" );
|
||||
|
||||
if ( !origkv->LoadFromFile( g_pFileSystem, name ) )
|
||||
{
|
||||
origkv->deleteThis();
|
||||
Assert( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
CreateMaterialPatchRecursive( origkv, section, nKeys, pInfo );
|
||||
origkv->deleteThis();
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int i = 0; i < nKeys; ++i )
|
||||
{
|
||||
section->SetString( pInfo[i].m_pKey, pInfo[i].m_pValue );
|
||||
}
|
||||
}
|
||||
|
||||
// Write patched .vmt into a memory buffer
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
kv->RecursiveSaveToFile( buf, 0 );
|
||||
|
||||
// Add to pak file for this .bsp
|
||||
AddBufferToPak( GetPakFile(), pNewVMTFile, (void*)buf.Base(), buf.TellPut(), true );
|
||||
|
||||
// Cleanup
|
||||
kv->deleteThis();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Patches a single keyvalue in a material
|
||||
//-----------------------------------------------------------------------------
|
||||
void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName,
|
||||
const char *pNewKey, const char *pNewValue, MaterialPatchType_t nPatchType )
|
||||
{
|
||||
MaterialPatchInfo_t info;
|
||||
info.m_pKey = pNewKey;
|
||||
info.m_pValue = pNewValue;
|
||||
CreateMaterialPatch( pOriginalMaterialName, pNewMaterialName, 1, &info, nPatchType );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scan material + all subsections for key
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool DoesMaterialHaveKey( KeyValues *pKeyValues, const char *pKeyName )
|
||||
{
|
||||
const char *pVal;
|
||||
pVal = pKeyValues->GetString( pKeyName, NULL );
|
||||
if ( pVal != NULL )
|
||||
return true;
|
||||
|
||||
for( KeyValues *pSubKey = pKeyValues->GetFirstTrueSubKey(); pSubKey; pSubKey = pSubKey->GetNextTrueSubKey() )
|
||||
{
|
||||
if ( DoesMaterialHaveKey( pSubKey, pKeyName) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scan material + all subsections for key/value pair
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool DoesMaterialHaveKeyValuePair( KeyValues *pKeyValues, const char *pKeyName, const char *pSearchValue )
|
||||
{
|
||||
const char *pVal;
|
||||
pVal = pKeyValues->GetString( pKeyName, NULL );
|
||||
if ( pVal != NULL && ( Q_stricmp( pSearchValue, pVal ) == 0 ) )
|
||||
return true;
|
||||
|
||||
for( KeyValues *pSubKey = pKeyValues->GetFirstTrueSubKey(); pSubKey; pSubKey = pSubKey->GetNextTrueSubKey() )
|
||||
{
|
||||
if ( DoesMaterialHaveKeyValuePair( pSubKey, pKeyName, pSearchValue ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scan material + all subsections for key
|
||||
//-----------------------------------------------------------------------------
|
||||
bool DoesMaterialHaveKey( const char *pMaterialName, const char *pKeyName )
|
||||
{
|
||||
char name[512];
|
||||
Q_snprintf( name, 512, "materials/%s.vmt", GetOriginalMaterialNameForPatchedMaterial( pMaterialName ) );
|
||||
KeyValues *kv = new KeyValues( "blah" );
|
||||
|
||||
if ( !kv->LoadFromFile( g_pFileSystem, name ) )
|
||||
{
|
||||
kv->deleteThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool retVal = DoesMaterialHaveKey( kv, pKeyName );
|
||||
|
||||
kv->deleteThis();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scan material + all subsections for key/value pair
|
||||
//-----------------------------------------------------------------------------
|
||||
bool DoesMaterialHaveKeyValuePair( const char *pMaterialName, const char *pKeyName, const char *pSearchValue )
|
||||
{
|
||||
char name[512];
|
||||
Q_snprintf( name, 512, "materials/%s.vmt", GetOriginalMaterialNameForPatchedMaterial( pMaterialName ) );
|
||||
KeyValues *kv = new KeyValues( "blah" );
|
||||
|
||||
if ( !kv->LoadFromFile( g_pFileSystem, name ) )
|
||||
{
|
||||
kv->deleteThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool retVal = DoesMaterialHaveKeyValuePair( kv, pKeyName, pSearchValue );
|
||||
|
||||
kv->deleteThis();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets a material value from a material. Ignores all patches
|
||||
//-----------------------------------------------------------------------------
|
||||
bool GetValueFromMaterial( const char *pMaterialName, const char *pKey, char *pValue, int len )
|
||||
{
|
||||
char name[512];
|
||||
Q_snprintf( name, 512, "materials/%s.vmt", GetOriginalMaterialNameForPatchedMaterial( pMaterialName ) );
|
||||
KeyValues *kv = new KeyValues( "blah" );
|
||||
|
||||
if ( !kv->LoadFromFile( g_pFileSystem, name ) )
|
||||
{
|
||||
// Assert( 0 );
|
||||
kv->deleteThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *pTmpValue = kv->GetString( pKey, NULL );
|
||||
if( pTmpValue )
|
||||
{
|
||||
Q_strncpy( pValue, pTmpValue, len );
|
||||
}
|
||||
|
||||
kv->deleteThis();
|
||||
return ( pTmpValue != NULL );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds the original material associated with a patched material
|
||||
//-----------------------------------------------------------------------------
|
||||
MaterialSystemMaterial_t FindOriginalMaterial( const char *materialName, bool *pFound, bool bComplain )
|
||||
{
|
||||
MaterialSystemMaterial_t matID;
|
||||
matID = FindMaterial( GetOriginalMaterialNameForPatchedMaterial( materialName ), pFound, bComplain );
|
||||
return matID;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Load keyvalues from the local pack file, or from a file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool LoadKeyValuesFromPackOrFile( const char *pFileName, KeyValues *pKeyValues )
|
||||
{
|
||||
CUtlBuffer buf;
|
||||
if ( ReadFileFromPak( GetPakFile(), pFileName, true, buf ) )
|
||||
{
|
||||
return pKeyValues->LoadFromBuffer( pFileName, buf );
|
||||
}
|
||||
|
||||
return pKeyValues->LoadFromFile( g_pFileSystem, pFileName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// VMT parser
|
||||
//-----------------------------------------------------------------------------
|
||||
static void InsertKeyValues( KeyValues &dst, KeyValues& src, bool bCheckForExistence )
|
||||
{
|
||||
KeyValues *pSrcVar = src.GetFirstSubKey();
|
||||
while( pSrcVar )
|
||||
{
|
||||
if ( !bCheckForExistence || dst.FindKey( pSrcVar->GetName() ) )
|
||||
{
|
||||
switch( pSrcVar->GetDataType() )
|
||||
{
|
||||
case KeyValues::TYPE_STRING:
|
||||
dst.SetString( pSrcVar->GetName(), pSrcVar->GetString() );
|
||||
break;
|
||||
case KeyValues::TYPE_INT:
|
||||
dst.SetInt( pSrcVar->GetName(), pSrcVar->GetInt() );
|
||||
break;
|
||||
case KeyValues::TYPE_FLOAT:
|
||||
dst.SetFloat( pSrcVar->GetName(), pSrcVar->GetFloat() );
|
||||
break;
|
||||
case KeyValues::TYPE_PTR:
|
||||
dst.SetPtr( pSrcVar->GetName(), pSrcVar->GetPtr() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
pSrcVar = pSrcVar->GetNextKey();
|
||||
}
|
||||
}
|
||||
|
||||
static void ExpandPatchFile( KeyValues &keyValues )
|
||||
{
|
||||
int nCount = 0;
|
||||
while( nCount < 10 && stricmp( keyValues.GetName(), "patch" ) == 0 )
|
||||
{
|
||||
// WriteKeyValuesToFile( "patch.txt", keyValues );
|
||||
const char *pIncludeFileName = keyValues.GetString( "include" );
|
||||
if( !pIncludeFileName )
|
||||
return;
|
||||
|
||||
KeyValues * includeKeyValues = new KeyValues( "vmt" );
|
||||
int nBufLen = Q_strlen( pIncludeFileName ) + Q_strlen( "materials/.vmt" ) + 1;
|
||||
char *pFileName = ( char * )stackalloc( nBufLen );
|
||||
Q_strncpy( pFileName, pIncludeFileName, nBufLen );
|
||||
bool bSuccess = LoadKeyValuesFromPackOrFile( pFileName, includeKeyValues );
|
||||
if ( !bSuccess )
|
||||
{
|
||||
includeKeyValues->deleteThis();
|
||||
return;
|
||||
}
|
||||
|
||||
KeyValues *pInsertSection = keyValues.FindKey( "insert" );
|
||||
if( pInsertSection )
|
||||
{
|
||||
InsertKeyValues( *includeKeyValues, *pInsertSection, false );
|
||||
keyValues = *includeKeyValues;
|
||||
}
|
||||
|
||||
KeyValues *pReplaceSection = keyValues.FindKey( "replace" );
|
||||
if( pReplaceSection )
|
||||
{
|
||||
InsertKeyValues( *includeKeyValues, *pReplaceSection, true );
|
||||
keyValues = *includeKeyValues;
|
||||
}
|
||||
|
||||
// Could add other commands here, like "delete", "rename", etc.
|
||||
|
||||
includeKeyValues->deleteThis();
|
||||
nCount++;
|
||||
}
|
||||
|
||||
if( nCount >= 10 )
|
||||
{
|
||||
Warning( "Infinite recursion in patch file?\n" );
|
||||
}
|
||||
}
|
||||
|
||||
KeyValues *LoadMaterialKeyValues( const char *pMaterialName, unsigned int nFlags )
|
||||
{
|
||||
// Load the underlying file
|
||||
KeyValues *kv = new KeyValues( "blah" );
|
||||
|
||||
char pFullMaterialName[512];
|
||||
Q_snprintf( pFullMaterialName, 512, "materials/%s.vmt", pMaterialName );
|
||||
if ( !LoadKeyValuesFromPackOrFile( pFullMaterialName, kv ) )
|
||||
{
|
||||
// Assert( 0 );
|
||||
kv->deleteThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( nFlags & LOAD_MATERIAL_KEY_VALUES_FLAGS_EXPAND_PATCH )
|
||||
{
|
||||
ExpandPatchFile( *kv );
|
||||
}
|
||||
|
||||
return kv;
|
||||
}
|
||||
|
||||
void WriteMaterialKeyValuesToPak( const char *pMaterialName, KeyValues *kv )
|
||||
{
|
||||
char pFullMaterialName[512];
|
||||
Q_snprintf( pFullMaterialName, 512, "materials/%s.vmt", pMaterialName );
|
||||
|
||||
// Write patched .vmt into a memory buffer
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
kv->RecursiveSaveToFile( buf, 0 );
|
||||
|
||||
// Add to pak file for this .bsp
|
||||
AddBufferToPak( GetPakFile(), pFullMaterialName, (void*)buf.Base(), buf.TellPut(), true );
|
||||
|
||||
// Cleanup
|
||||
kv->deleteThis();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets a keyvalue from a *patched* material
|
||||
//-----------------------------------------------------------------------------
|
||||
bool GetValueFromPatchedMaterial( const char *pMaterialName, const char *pKey, char *pValue, int len )
|
||||
{
|
||||
// Load the underlying file so that we can check if env_cubemap is in there.
|
||||
KeyValues *kv = new KeyValues( "blah" );
|
||||
|
||||
char pFullMaterialName[512];
|
||||
Q_snprintf( pFullMaterialName, 512, "materials/%s.vmt", pMaterialName );
|
||||
if ( !LoadKeyValuesFromPackOrFile( pFullMaterialName, kv ) )
|
||||
{
|
||||
// Assert( 0 );
|
||||
kv->deleteThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ExpandPatchFile( *kv );
|
||||
|
||||
const char *pTmpValue = kv->GetString( pKey, NULL );
|
||||
if( pTmpValue )
|
||||
{
|
||||
Q_strncpy( pValue, pTmpValue, len );
|
||||
}
|
||||
|
||||
kv->deleteThis();
|
||||
return ( pTmpValue != NULL );
|
||||
}
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "vbsp.h"
|
||||
#include "UtlBuffer.h"
|
||||
#include "utlsymbol.h"
|
||||
#include "utlrbtree.h"
|
||||
#include "KeyValues.h"
|
||||
#include "bsplib.h"
|
||||
#include "materialpatch.h"
|
||||
#include "tier1/strtools.h"
|
||||
|
||||
// case insensitive
|
||||
static CUtlSymbolTable s_SymbolTable( 0, 32, true );
|
||||
|
||||
struct NameTranslationLookup_t
|
||||
{
|
||||
CUtlSymbol m_OriginalFileName;
|
||||
CUtlSymbol m_PatchFileName;
|
||||
};
|
||||
|
||||
static bool NameTranslationLessFunc( NameTranslationLookup_t const& src1,
|
||||
NameTranslationLookup_t const& src2 )
|
||||
{
|
||||
return src1.m_PatchFileName < src2.m_PatchFileName;
|
||||
}
|
||||
|
||||
CUtlRBTree<NameTranslationLookup_t, int> s_MapPatchedMatToOriginalMat( 0, 256, NameTranslationLessFunc );
|
||||
|
||||
void AddNewTranslation( const char *pOriginalMaterialName, const char *pNewMaterialName )
|
||||
{
|
||||
NameTranslationLookup_t newEntry;
|
||||
|
||||
newEntry.m_OriginalFileName = s_SymbolTable.AddString( pOriginalMaterialName );
|
||||
newEntry.m_PatchFileName = s_SymbolTable.AddString( pNewMaterialName );
|
||||
|
||||
s_MapPatchedMatToOriginalMat.Insert( newEntry );
|
||||
}
|
||||
|
||||
const char *GetOriginalMaterialNameForPatchedMaterial( const char *pPatchMaterialName )
|
||||
{
|
||||
const char *pRetName = NULL;
|
||||
int id;
|
||||
NameTranslationLookup_t lookup;
|
||||
lookup.m_PatchFileName = s_SymbolTable.AddString( pPatchMaterialName );
|
||||
do
|
||||
{
|
||||
id = s_MapPatchedMatToOriginalMat.Find( lookup );
|
||||
if( id >= 0 )
|
||||
{
|
||||
NameTranslationLookup_t &found = s_MapPatchedMatToOriginalMat[id];
|
||||
lookup.m_PatchFileName = found.m_OriginalFileName;
|
||||
pRetName = s_SymbolTable.String( found.m_OriginalFileName );
|
||||
}
|
||||
} while( id >= 0 );
|
||||
if( !pRetName )
|
||||
{
|
||||
// This isn't a patched material, so just return the original name.
|
||||
return pPatchMaterialName;
|
||||
}
|
||||
return pRetName;
|
||||
}
|
||||
|
||||
|
||||
void CreateMaterialPatchRecursive( KeyValues *pOriginalKeyValues, KeyValues *pPatchKeyValues, int nKeys, const MaterialPatchInfo_t *pInfo )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < nKeys; i++ )
|
||||
{
|
||||
const char *pVal = pOriginalKeyValues->GetString( pInfo[i].m_pKey, NULL );
|
||||
if( !pVal )
|
||||
continue;
|
||||
if( pInfo[i].m_pRequiredOriginalValue && Q_stricmp( pVal, pInfo[i].m_pRequiredOriginalValue ) != 0 )
|
||||
continue;
|
||||
pPatchKeyValues->SetString( pInfo[i].m_pKey, pInfo[i].m_pValue );
|
||||
}
|
||||
KeyValues *pScan;
|
||||
for( pScan = pOriginalKeyValues->GetFirstTrueSubKey(); pScan; pScan = pScan->GetNextTrueSubKey() )
|
||||
{
|
||||
CreateMaterialPatchRecursive( pScan, pPatchKeyValues->FindKey( pScan->GetName(), true ), nKeys, pInfo );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A version which allows you to patch multiple key values
|
||||
//-----------------------------------------------------------------------------
|
||||
void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName,
|
||||
int nKeys, const MaterialPatchInfo_t *pInfo, MaterialPatchType_t nPatchType )
|
||||
{
|
||||
char pOldVMTFile[ 512 ];
|
||||
char pNewVMTFile[ 512 ];
|
||||
|
||||
AddNewTranslation( pOriginalMaterialName, pNewMaterialName );
|
||||
|
||||
Q_snprintf( pOldVMTFile, 512, "materials/%s.vmt", pOriginalMaterialName );
|
||||
Q_snprintf( pNewVMTFile, 512, "materials/%s.vmt", pNewMaterialName );
|
||||
|
||||
// printf( "Creating material patch file %s which points at %s\n", newVMTFile, oldVMTFile );
|
||||
|
||||
KeyValues *kv = new KeyValues( "patch" );
|
||||
if ( !kv )
|
||||
{
|
||||
Error( "Couldn't allocate KeyValues for %s!!!", pNewMaterialName );
|
||||
}
|
||||
|
||||
kv->SetString( "include", pOldVMTFile );
|
||||
|
||||
const char *pSectionName = (nPatchType == PATCH_INSERT) ? "insert" : "replace";
|
||||
KeyValues *section = kv->FindKey( pSectionName, true );
|
||||
|
||||
if( nPatchType == PATCH_REPLACE )
|
||||
{
|
||||
char name[512];
|
||||
Q_snprintf( name, 512, "materials/%s.vmt", GetOriginalMaterialNameForPatchedMaterial( pOriginalMaterialName ) );
|
||||
KeyValues *origkv = new KeyValues( "blah" );
|
||||
|
||||
if ( !origkv->LoadFromFile( g_pFileSystem, name ) )
|
||||
{
|
||||
origkv->deleteThis();
|
||||
Assert( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
CreateMaterialPatchRecursive( origkv, section, nKeys, pInfo );
|
||||
origkv->deleteThis();
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int i = 0; i < nKeys; ++i )
|
||||
{
|
||||
section->SetString( pInfo[i].m_pKey, pInfo[i].m_pValue );
|
||||
}
|
||||
}
|
||||
|
||||
// Write patched .vmt into a memory buffer
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
kv->RecursiveSaveToFile( buf, 0 );
|
||||
|
||||
// Add to pak file for this .bsp
|
||||
AddBufferToPak( GetPakFile(), pNewVMTFile, (void*)buf.Base(), buf.TellPut(), true );
|
||||
|
||||
// Cleanup
|
||||
kv->deleteThis();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Patches a single keyvalue in a material
|
||||
//-----------------------------------------------------------------------------
|
||||
void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName,
|
||||
const char *pNewKey, const char *pNewValue, MaterialPatchType_t nPatchType )
|
||||
{
|
||||
MaterialPatchInfo_t info;
|
||||
info.m_pKey = pNewKey;
|
||||
info.m_pValue = pNewValue;
|
||||
CreateMaterialPatch( pOriginalMaterialName, pNewMaterialName, 1, &info, nPatchType );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scan material + all subsections for key
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool DoesMaterialHaveKey( KeyValues *pKeyValues, const char *pKeyName )
|
||||
{
|
||||
const char *pVal;
|
||||
pVal = pKeyValues->GetString( pKeyName, NULL );
|
||||
if ( pVal != NULL )
|
||||
return true;
|
||||
|
||||
for( KeyValues *pSubKey = pKeyValues->GetFirstTrueSubKey(); pSubKey; pSubKey = pSubKey->GetNextTrueSubKey() )
|
||||
{
|
||||
if ( DoesMaterialHaveKey( pSubKey, pKeyName) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scan material + all subsections for key/value pair
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool DoesMaterialHaveKeyValuePair( KeyValues *pKeyValues, const char *pKeyName, const char *pSearchValue )
|
||||
{
|
||||
const char *pVal;
|
||||
pVal = pKeyValues->GetString( pKeyName, NULL );
|
||||
if ( pVal != NULL && ( Q_stricmp( pSearchValue, pVal ) == 0 ) )
|
||||
return true;
|
||||
|
||||
for( KeyValues *pSubKey = pKeyValues->GetFirstTrueSubKey(); pSubKey; pSubKey = pSubKey->GetNextTrueSubKey() )
|
||||
{
|
||||
if ( DoesMaterialHaveKeyValuePair( pSubKey, pKeyName, pSearchValue ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scan material + all subsections for key
|
||||
//-----------------------------------------------------------------------------
|
||||
bool DoesMaterialHaveKey( const char *pMaterialName, const char *pKeyName )
|
||||
{
|
||||
char name[512];
|
||||
Q_snprintf( name, 512, "materials/%s.vmt", GetOriginalMaterialNameForPatchedMaterial( pMaterialName ) );
|
||||
KeyValues *kv = new KeyValues( "blah" );
|
||||
|
||||
if ( !kv->LoadFromFile( g_pFileSystem, name ) )
|
||||
{
|
||||
kv->deleteThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool retVal = DoesMaterialHaveKey( kv, pKeyName );
|
||||
|
||||
kv->deleteThis();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Scan material + all subsections for key/value pair
|
||||
//-----------------------------------------------------------------------------
|
||||
bool DoesMaterialHaveKeyValuePair( const char *pMaterialName, const char *pKeyName, const char *pSearchValue )
|
||||
{
|
||||
char name[512];
|
||||
Q_snprintf( name, 512, "materials/%s.vmt", GetOriginalMaterialNameForPatchedMaterial( pMaterialName ) );
|
||||
KeyValues *kv = new KeyValues( "blah" );
|
||||
|
||||
if ( !kv->LoadFromFile( g_pFileSystem, name ) )
|
||||
{
|
||||
kv->deleteThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool retVal = DoesMaterialHaveKeyValuePair( kv, pKeyName, pSearchValue );
|
||||
|
||||
kv->deleteThis();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets a material value from a material. Ignores all patches
|
||||
//-----------------------------------------------------------------------------
|
||||
bool GetValueFromMaterial( const char *pMaterialName, const char *pKey, char *pValue, int len )
|
||||
{
|
||||
char name[512];
|
||||
Q_snprintf( name, 512, "materials/%s.vmt", GetOriginalMaterialNameForPatchedMaterial( pMaterialName ) );
|
||||
KeyValues *kv = new KeyValues( "blah" );
|
||||
|
||||
if ( !kv->LoadFromFile( g_pFileSystem, name ) )
|
||||
{
|
||||
// Assert( 0 );
|
||||
kv->deleteThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *pTmpValue = kv->GetString( pKey, NULL );
|
||||
if( pTmpValue )
|
||||
{
|
||||
Q_strncpy( pValue, pTmpValue, len );
|
||||
}
|
||||
|
||||
kv->deleteThis();
|
||||
return ( pTmpValue != NULL );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds the original material associated with a patched material
|
||||
//-----------------------------------------------------------------------------
|
||||
MaterialSystemMaterial_t FindOriginalMaterial( const char *materialName, bool *pFound, bool bComplain )
|
||||
{
|
||||
MaterialSystemMaterial_t matID;
|
||||
matID = FindMaterial( GetOriginalMaterialNameForPatchedMaterial( materialName ), pFound, bComplain );
|
||||
return matID;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Load keyvalues from the local pack file, or from a file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool LoadKeyValuesFromPackOrFile( const char *pFileName, KeyValues *pKeyValues )
|
||||
{
|
||||
CUtlBuffer buf;
|
||||
if ( ReadFileFromPak( GetPakFile(), pFileName, true, buf ) )
|
||||
{
|
||||
return pKeyValues->LoadFromBuffer( pFileName, buf );
|
||||
}
|
||||
|
||||
return pKeyValues->LoadFromFile( g_pFileSystem, pFileName );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// VMT parser
|
||||
//-----------------------------------------------------------------------------
|
||||
static void InsertKeyValues( KeyValues &dst, KeyValues& src, bool bCheckForExistence )
|
||||
{
|
||||
KeyValues *pSrcVar = src.GetFirstSubKey();
|
||||
while( pSrcVar )
|
||||
{
|
||||
if ( !bCheckForExistence || dst.FindKey( pSrcVar->GetName() ) )
|
||||
{
|
||||
switch( pSrcVar->GetDataType() )
|
||||
{
|
||||
case KeyValues::TYPE_STRING:
|
||||
dst.SetString( pSrcVar->GetName(), pSrcVar->GetString() );
|
||||
break;
|
||||
case KeyValues::TYPE_INT:
|
||||
dst.SetInt( pSrcVar->GetName(), pSrcVar->GetInt() );
|
||||
break;
|
||||
case KeyValues::TYPE_FLOAT:
|
||||
dst.SetFloat( pSrcVar->GetName(), pSrcVar->GetFloat() );
|
||||
break;
|
||||
case KeyValues::TYPE_PTR:
|
||||
dst.SetPtr( pSrcVar->GetName(), pSrcVar->GetPtr() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
pSrcVar = pSrcVar->GetNextKey();
|
||||
}
|
||||
}
|
||||
|
||||
static void ExpandPatchFile( KeyValues &keyValues )
|
||||
{
|
||||
int nCount = 0;
|
||||
while( nCount < 10 && stricmp( keyValues.GetName(), "patch" ) == 0 )
|
||||
{
|
||||
// WriteKeyValuesToFile( "patch.txt", keyValues );
|
||||
const char *pIncludeFileName = keyValues.GetString( "include" );
|
||||
if( !pIncludeFileName )
|
||||
return;
|
||||
|
||||
KeyValues * includeKeyValues = new KeyValues( "vmt" );
|
||||
int nBufLen = Q_strlen( pIncludeFileName ) + Q_strlen( "materials/.vmt" ) + 1;
|
||||
char *pFileName = ( char * )stackalloc( nBufLen );
|
||||
Q_strncpy( pFileName, pIncludeFileName, nBufLen );
|
||||
bool bSuccess = LoadKeyValuesFromPackOrFile( pFileName, includeKeyValues );
|
||||
if ( !bSuccess )
|
||||
{
|
||||
includeKeyValues->deleteThis();
|
||||
return;
|
||||
}
|
||||
|
||||
KeyValues *pInsertSection = keyValues.FindKey( "insert" );
|
||||
if( pInsertSection )
|
||||
{
|
||||
InsertKeyValues( *includeKeyValues, *pInsertSection, false );
|
||||
keyValues = *includeKeyValues;
|
||||
}
|
||||
|
||||
KeyValues *pReplaceSection = keyValues.FindKey( "replace" );
|
||||
if( pReplaceSection )
|
||||
{
|
||||
InsertKeyValues( *includeKeyValues, *pReplaceSection, true );
|
||||
keyValues = *includeKeyValues;
|
||||
}
|
||||
|
||||
// Could add other commands here, like "delete", "rename", etc.
|
||||
|
||||
includeKeyValues->deleteThis();
|
||||
nCount++;
|
||||
}
|
||||
|
||||
if( nCount >= 10 )
|
||||
{
|
||||
Warning( "Infinite recursion in patch file?\n" );
|
||||
}
|
||||
}
|
||||
|
||||
KeyValues *LoadMaterialKeyValues( const char *pMaterialName, unsigned int nFlags )
|
||||
{
|
||||
// Load the underlying file
|
||||
KeyValues *kv = new KeyValues( "blah" );
|
||||
|
||||
char pFullMaterialName[512];
|
||||
Q_snprintf( pFullMaterialName, 512, "materials/%s.vmt", pMaterialName );
|
||||
if ( !LoadKeyValuesFromPackOrFile( pFullMaterialName, kv ) )
|
||||
{
|
||||
// Assert( 0 );
|
||||
kv->deleteThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( nFlags & LOAD_MATERIAL_KEY_VALUES_FLAGS_EXPAND_PATCH )
|
||||
{
|
||||
ExpandPatchFile( *kv );
|
||||
}
|
||||
|
||||
return kv;
|
||||
}
|
||||
|
||||
void WriteMaterialKeyValuesToPak( const char *pMaterialName, KeyValues *kv )
|
||||
{
|
||||
char pFullMaterialName[512];
|
||||
Q_snprintf( pFullMaterialName, 512, "materials/%s.vmt", pMaterialName );
|
||||
|
||||
// Write patched .vmt into a memory buffer
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
kv->RecursiveSaveToFile( buf, 0 );
|
||||
|
||||
// Add to pak file for this .bsp
|
||||
AddBufferToPak( GetPakFile(), pFullMaterialName, (void*)buf.Base(), buf.TellPut(), true );
|
||||
|
||||
// Cleanup
|
||||
kv->deleteThis();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets a keyvalue from a *patched* material
|
||||
//-----------------------------------------------------------------------------
|
||||
bool GetValueFromPatchedMaterial( const char *pMaterialName, const char *pKey, char *pValue, int len )
|
||||
{
|
||||
// Load the underlying file so that we can check if env_cubemap is in there.
|
||||
KeyValues *kv = new KeyValues( "blah" );
|
||||
|
||||
char pFullMaterialName[512];
|
||||
Q_snprintf( pFullMaterialName, 512, "materials/%s.vmt", pMaterialName );
|
||||
if ( !LoadKeyValuesFromPackOrFile( pFullMaterialName, kv ) )
|
||||
{
|
||||
// Assert( 0 );
|
||||
kv->deleteThis();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ExpandPatchFile( *kv );
|
||||
|
||||
const char *pTmpValue = kv->GetString( pKey, NULL );
|
||||
if( pTmpValue )
|
||||
{
|
||||
Q_strncpy( pValue, pTmpValue, len );
|
||||
}
|
||||
|
||||
kv->deleteThis();
|
||||
return ( pTmpValue != NULL );
|
||||
}
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MATERIALPATCH_H
|
||||
#define MATERIALPATCH_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utilmatlib.h"
|
||||
|
||||
struct MaterialPatchInfo_t
|
||||
{
|
||||
const char *m_pKey;
|
||||
const char *m_pRequiredOriginalValue; // NULL if you don't require one.
|
||||
const char *m_pValue;
|
||||
MaterialPatchInfo_t()
|
||||
{
|
||||
memset( this, 0, sizeof( *this ) );
|
||||
}
|
||||
};
|
||||
|
||||
enum MaterialPatchType_t
|
||||
{
|
||||
PATCH_INSERT = 0, // Add the key no matter what
|
||||
PATCH_REPLACE, // Add the key only if it exists
|
||||
};
|
||||
|
||||
void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName,
|
||||
const char *pNewKey, const char *pNewValue, MaterialPatchType_t nPatchType );
|
||||
|
||||
// A version which allows you to use multiple key values
|
||||
void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName,
|
||||
int nKeys, const MaterialPatchInfo_t *pInfo, MaterialPatchType_t nPatchType );
|
||||
|
||||
// This gets a keyvalue from the *unpatched* version of the passed-in material
|
||||
bool GetValueFromMaterial( const char *pMaterialName, const char *pKey, char *pValue, int len );
|
||||
|
||||
// Gets a keyvalue from a *patched* material
|
||||
bool GetValueFromPatchedMaterial( const char *pMaterialName, const char *pKey, char *pValue, int len );
|
||||
|
||||
const char *GetOriginalMaterialNameForPatchedMaterial( const char *pPatchMaterialName );
|
||||
|
||||
MaterialSystemMaterial_t FindOriginalMaterial( const char *materialName, bool *pFound, bool bComplain = true );
|
||||
|
||||
bool DoesMaterialHaveKeyValuePair( const char *pMaterialName, const char *pKeyName, const char *pSearchValue );
|
||||
bool DoesMaterialHaveKey( const char *pMaterialName, const char *pKeyName );
|
||||
|
||||
enum LoadMaterialKeyValuesFlags_t
|
||||
{
|
||||
LOAD_MATERIAL_KEY_VALUES_FLAGS_EXPAND_PATCH = 1,
|
||||
};
|
||||
|
||||
KeyValues *LoadMaterialKeyValues( const char *pMaterialName, unsigned int nFlags );
|
||||
void WriteMaterialKeyValuesToPak( const char *pMaterialName, KeyValues *kv );
|
||||
|
||||
#endif // MATERIALPATCH_H
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef MATERIALPATCH_H
|
||||
#define MATERIALPATCH_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "utilmatlib.h"
|
||||
|
||||
struct MaterialPatchInfo_t
|
||||
{
|
||||
const char *m_pKey;
|
||||
const char *m_pRequiredOriginalValue; // NULL if you don't require one.
|
||||
const char *m_pValue;
|
||||
MaterialPatchInfo_t()
|
||||
{
|
||||
memset( this, 0, sizeof( *this ) );
|
||||
}
|
||||
};
|
||||
|
||||
enum MaterialPatchType_t
|
||||
{
|
||||
PATCH_INSERT = 0, // Add the key no matter what
|
||||
PATCH_REPLACE, // Add the key only if it exists
|
||||
};
|
||||
|
||||
void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName,
|
||||
const char *pNewKey, const char *pNewValue, MaterialPatchType_t nPatchType );
|
||||
|
||||
// A version which allows you to use multiple key values
|
||||
void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName,
|
||||
int nKeys, const MaterialPatchInfo_t *pInfo, MaterialPatchType_t nPatchType );
|
||||
|
||||
// This gets a keyvalue from the *unpatched* version of the passed-in material
|
||||
bool GetValueFromMaterial( const char *pMaterialName, const char *pKey, char *pValue, int len );
|
||||
|
||||
// Gets a keyvalue from a *patched* material
|
||||
bool GetValueFromPatchedMaterial( const char *pMaterialName, const char *pKey, char *pValue, int len );
|
||||
|
||||
const char *GetOriginalMaterialNameForPatchedMaterial( const char *pPatchMaterialName );
|
||||
|
||||
MaterialSystemMaterial_t FindOriginalMaterial( const char *materialName, bool *pFound, bool bComplain = true );
|
||||
|
||||
bool DoesMaterialHaveKeyValuePair( const char *pMaterialName, const char *pKeyName, const char *pSearchValue );
|
||||
bool DoesMaterialHaveKey( const char *pMaterialName, const char *pKeyName );
|
||||
|
||||
enum LoadMaterialKeyValuesFlags_t
|
||||
{
|
||||
LOAD_MATERIAL_KEY_VALUES_FLAGS_EXPAND_PATCH = 1,
|
||||
};
|
||||
|
||||
KeyValues *LoadMaterialKeyValues( const char *pMaterialName, unsigned int nFlags );
|
||||
void WriteMaterialKeyValuesToPak( const char *pMaterialName, KeyValues *kv );
|
||||
|
||||
#endif // MATERIALPATCH_H
|
||||
|
||||
@@ -1,90 +1,90 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This file loads a KeyValues file containing material name mappings.
|
||||
// When the bsp is compiled, all materials listed in the file will
|
||||
// be replaced by the second material in the pair.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "vbsp.h"
|
||||
#include "materialsub.h"
|
||||
#include "KeyValues.h"
|
||||
#include "tier1/strtools.h"
|
||||
|
||||
bool g_ReplaceMaterials = false;
|
||||
|
||||
static KeyValues *kv = 0;
|
||||
static KeyValues *allMapKeys = 0;
|
||||
static KeyValues *curMapKeys = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Loads the KeyValues file for materials replacements
|
||||
//-----------------------------------------------------------------------------
|
||||
void LoadMaterialReplacementKeys( const char *gamedir, const char *mapname )
|
||||
{
|
||||
// Careful with static variables
|
||||
if( kv )
|
||||
{
|
||||
kv->deleteThis();
|
||||
kv = 0;
|
||||
}
|
||||
if( allMapKeys )
|
||||
allMapKeys = 0;
|
||||
if( curMapKeys )
|
||||
curMapKeys = 0;
|
||||
|
||||
Msg( "Loading Replacement Keys\n" );
|
||||
|
||||
// Attach the path to the keyValues file
|
||||
char path[1024];
|
||||
Q_snprintf( path, sizeof( path ), "%scfg\\materialsub.cfg", gamedir );
|
||||
|
||||
// Load the keyvalues file
|
||||
kv = new KeyValues( "MaterialReplacements" );
|
||||
|
||||
Msg( "File path: %s", path );
|
||||
if( !kv->LoadFromFile( g_pFileSystem, path ) )
|
||||
{
|
||||
Msg( "Failed to load KeyValues file!\n" );
|
||||
g_ReplaceMaterials = false;
|
||||
kv->deleteThis();
|
||||
kv = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Load global replace keys
|
||||
allMapKeys = kv->FindKey( "AllMaps", true );
|
||||
|
||||
// Load keys for the current map
|
||||
curMapKeys = kv->FindKey( mapname );
|
||||
|
||||
allMapKeys->ChainKeyValue( curMapKeys );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Deletes all keys
|
||||
//-----------------------------------------------------------------------------
|
||||
void DeleteMaterialReplacementKeys( void )
|
||||
{
|
||||
if( kv )
|
||||
{
|
||||
kv->deleteThis();
|
||||
kv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Replace the passed-in material name with a replacement name, if one exists
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* ReplaceMaterialName( const char *name )
|
||||
{
|
||||
// Look for the material name in the global and map KeyValues
|
||||
// If it's not there, just return the original name
|
||||
|
||||
// HACK: This stinks - KeyValues won't take a string with '/' in it.
|
||||
// If they did, this could be a simple pointer swap.
|
||||
char newName[1024];
|
||||
Q_strncpy( newName, name, sizeof( newName ) );
|
||||
Q_FixSlashes( newName );
|
||||
return allMapKeys->GetString( newName, name );
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This file loads a KeyValues file containing material name mappings.
|
||||
// When the bsp is compiled, all materials listed in the file will
|
||||
// be replaced by the second material in the pair.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "vbsp.h"
|
||||
#include "materialsub.h"
|
||||
#include "KeyValues.h"
|
||||
#include "tier1/strtools.h"
|
||||
|
||||
bool g_ReplaceMaterials = false;
|
||||
|
||||
static KeyValues *kv = 0;
|
||||
static KeyValues *allMapKeys = 0;
|
||||
static KeyValues *curMapKeys = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Loads the KeyValues file for materials replacements
|
||||
//-----------------------------------------------------------------------------
|
||||
void LoadMaterialReplacementKeys( const char *gamedir, const char *mapname )
|
||||
{
|
||||
// Careful with static variables
|
||||
if( kv )
|
||||
{
|
||||
kv->deleteThis();
|
||||
kv = 0;
|
||||
}
|
||||
if( allMapKeys )
|
||||
allMapKeys = 0;
|
||||
if( curMapKeys )
|
||||
curMapKeys = 0;
|
||||
|
||||
Msg( "Loading Replacement Keys\n" );
|
||||
|
||||
// Attach the path to the keyValues file
|
||||
char path[1024];
|
||||
Q_snprintf( path, sizeof( path ), "%scfg\\materialsub.cfg", gamedir );
|
||||
|
||||
// Load the keyvalues file
|
||||
kv = new KeyValues( "MaterialReplacements" );
|
||||
|
||||
Msg( "File path: %s", path );
|
||||
if( !kv->LoadFromFile( g_pFileSystem, path ) )
|
||||
{
|
||||
Msg( "Failed to load KeyValues file!\n" );
|
||||
g_ReplaceMaterials = false;
|
||||
kv->deleteThis();
|
||||
kv = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Load global replace keys
|
||||
allMapKeys = kv->FindKey( "AllMaps", true );
|
||||
|
||||
// Load keys for the current map
|
||||
curMapKeys = kv->FindKey( mapname );
|
||||
|
||||
allMapKeys->ChainKeyValue( curMapKeys );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Deletes all keys
|
||||
//-----------------------------------------------------------------------------
|
||||
void DeleteMaterialReplacementKeys( void )
|
||||
{
|
||||
if( kv )
|
||||
{
|
||||
kv->deleteThis();
|
||||
kv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Replace the passed-in material name with a replacement name, if one exists
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* ReplaceMaterialName( const char *name )
|
||||
{
|
||||
// Look for the material name in the global and map KeyValues
|
||||
// If it's not there, just return the original name
|
||||
|
||||
// HACK: This stinks - KeyValues won't take a string with '/' in it.
|
||||
// If they did, this could be a simple pointer swap.
|
||||
char newName[1024];
|
||||
Q_strncpy( newName, name, sizeof( newName ) );
|
||||
Q_FixSlashes( newName );
|
||||
return allMapKeys->GetString( newName, name );
|
||||
}
|
||||
@@ -1,25 +1,25 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This file loads a KeyValues file containing material name mappings.
|
||||
// When the bsp is compiled, all materials listed in the file will
|
||||
// be replaced by the second material in the pair.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef MATERIALSUB_H
|
||||
#define MATERIALSUB_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
extern bool g_ReplaceMaterials;
|
||||
|
||||
// Setup / Cleanup
|
||||
void LoadMaterialReplacementKeys( const char *gamedir, const char *mapname );
|
||||
void DeleteMaterialReplacementKeys( void );
|
||||
|
||||
// Takes a material name and returns it's replacement, if there is one.
|
||||
// If there isn't a replacement, it returns the original.
|
||||
const char* ReplaceMaterialName( const char *name );
|
||||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: This file loads a KeyValues file containing material name mappings.
|
||||
// When the bsp is compiled, all materials listed in the file will
|
||||
// be replaced by the second material in the pair.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef MATERIALSUB_H
|
||||
#define MATERIALSUB_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
extern bool g_ReplaceMaterials;
|
||||
|
||||
// Setup / Cleanup
|
||||
void LoadMaterialReplacementKeys( const char *gamedir, const char *mapname );
|
||||
void DeleteMaterialReplacementKeys( void );
|
||||
|
||||
// Takes a material name and returns it's replacement, if there is one.
|
||||
// If there isn't a replacement, it returns the original.
|
||||
const char* ReplaceMaterialName( const char *name );
|
||||
|
||||
#endif // MATERIALSUB_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user