win_main.cpp
来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 1,065 行 · 第 1/2 页
CPP
1,065 行
#include "stdafx.h"
#include "qe3.h"
#include <process.h>
#include "mru.h"
#include "entityw.h"
#include "PrefsDlg.h"
static HWND s_hwndToolbar;
BOOL SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize);
BOOL LoadRegistryInfo(const char *pszName, void *pvBuf, long *plSize);
static HWND CreateMyStatusWindow(HINSTANCE hInst);
static HWND CreateToolBar(HINSTANCE hinst);
extern void WXY_Print( void );
/*
==============================================================================
MENU
==============================================================================
*/
void OpenDialog (void);
void SaveAsDialog (bool bRegion);
qboolean ConfirmModified (void);
void Select_Ungroup (void);
void QE_ExpandBspString (char *bspaction, char *out, char *mapname, bool useTemps)
{
char *in;
char src[2048];
char rsh[2048];
char base[2048];
strcpy(src, mapname);
strlwr(src);
in = strstr(src, "maps/");
if (!in)
{
in = strstr(src, "maps\\");
}
if (in)
{
in += 5;
strcpy(base, in);
in = base;
while (*in)
{
if (*in == '\\')
{
*in = '/';
}
in++;
}
}
else
{
ExtractFileName (mapname, base);
}
if (useTemps) {
CString str;
CString strExt = "map";
if ( strstr(mapname, ".reg") ) {
strExt = "reg";
}
str.Format("%s/maps/%i.%s", ValueForKey(g_qeglobals.d_project_entity, "remotebasepath"), ::GetTickCount(), strExt);
CopyFile(mapname, str, FALSE);
sprintf (src, "-tempname %s %s/maps/%s", str, ValueForKey(g_qeglobals.d_project_entity, "remotebasepath"), base);
} else {
sprintf (src, "%s/maps/%s", ValueForKey(g_qeglobals.d_project_entity, "remotebasepath"), base);
}
strcpy (rsh, ValueForKey(g_qeglobals.d_project_entity, "rshcmd"));
QE_ConvertDOSToUnixName(src, src);
in = ValueForKey( g_qeglobals.d_project_entity, bspaction );
while (*in)
{
if (in[0] == '!')
{
strcpy (out, rsh);
out += strlen(rsh);
in++;
continue;
}
if (in[0] == '$')
{
strcpy (out, src);
out += strlen(src);
in++;
continue;
}
if (in[0] == '@')
{
*out++ = '"';
in++;
continue;
}
*out++ = *in++;
}
*out = 0;
}
void FindReplace(CString& strContents, const char* pTag, const char* pValue)
{
if (strcmp(pTag, pValue) == 0)
return;
for (int nPos = strContents.Find(pTag); nPos >= 0; nPos = strContents.Find(pTag))
{
int nRightLen = strContents.GetLength() - strlen(pTag) - nPos;
CString strLeft = strContents.Left(nPos);
CString strRight = strContents.Right(nRightLen);
strLeft += pValue;
strLeft += strRight;
strContents = strLeft;
}
}
HWND g_hWnd = NULL;
HANDLE g_hToolThread = NULL;
CString g_strParams;
UINT ToolThread(LPVOID pParam)
{
char* p = reinterpret_cast<char*>(pParam);
if (g_PrefsDlg.m_bPAK)
RunTools(p, g_hWnd, g_PrefsDlg.m_strPAKFile);
else
RunTools(p, g_hWnd, "");
g_hToolThread = NULL;
delete []p;
return 0;
}
void ThreadTools(char* p)
{
CWinThread* pThread = AfxBeginThread(ToolThread, reinterpret_cast<LPVOID>(p));
g_hToolThread = pThread->m_hThread;
}
HWND g_hwndFoundIt = NULL;
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) {
char buff[1024];
const char* p = reinterpret_cast<const char*>(lParam);
GetWindowText(hwnd, buff, 1024);
if (!strcmpi(p, buff)) {
g_hwndFoundIt = hwnd;
return 1;
}
return 1;
}
HWND FindAnyWindow(const char *pTitle) {
HWND hwndDesktop = GetDesktopWindow();
g_hwndFoundIt = NULL;
if ( hwndDesktop ) {
EnumChildWindows(hwndDesktop, (WNDENUMPROC)EnumChildProc, reinterpret_cast<LPARAM>(pTitle));
}
return g_hwndFoundIt;
}
const UINT wm_AddCommand = RegisterWindowMessage( "Q3MPC_AddCommand" );
CTime g_tBegin;
void RunBsp (char *command)
{
char sys[2048];
char batpath[2048];
char outputpath[2048];
char temppath[1024];
char name[2048];
char cWork[2048];
FILE *hFile;
BOOL ret;
PROCESS_INFORMATION ProcessInformation;
STARTUPINFO startupinfo;
HWND hwndPClient = NULL;
g_hWnd = g_pParentWnd->GetSafeHwnd();
SetInspectorMode(W_CONSOLE);
g_tBegin = CTime::GetCurrentTime();
DWORD dwExitcode;
ret = GetExitCodeProcess (g_hToolThread, &dwExitcode);
if (dwExitcode != STILL_ACTIVE)
g_hToolThread = NULL;
if (bsp_process || g_hToolThread)
{
Sys_Printf ("BSP is still going...\n");
return;
}
outputpath[0] = '\0';
GetTempPath(512, temppath);
CString strOutFile = temppath;
AddSlash(strOutFile);
strOutFile += "junk.txt";
sprintf (outputpath, " >>%s\r\n", strOutFile);
strcpy (name, currentmap);
if (region_active)
{
Map_SaveFile (name, false);
StripExtension (name);
strcat (name, ".reg");
}
Map_SaveFile (name, region_active);
// FIXME: this code just gets worse and worse
CString strPath, strFile;
char *rsh = ValueForKey(g_qeglobals.d_project_entity, "rshcmd");
if (rsh == NULL)
{
ExtractPath_and_Filename(name, strPath, strFile);
AddSlash(strPath);
BuildShortPathName(strPath, cWork, 1024);
strcat(cWork, strFile);
}
else
{
strcpy(cWork, name);
}
hwndPClient = FindWindow(NULL, "Q3Map Process Client");
if ( hwndPClient == NULL ) {
hwndPClient = FindAnyWindow("Q3Map Process Client");
}
Sys_Printf("Window info for Process Client %i\n", reinterpret_cast<int>(hwndPClient));
bool processServer = (rsh && strlen(rsh) > 0 && hwndPClient);
QE_ExpandBspString (command, sys, cWork, processServer);
// if we can find the q3map process server running
// we will submit maps to it instead of via createprocess
//
if (processServer)
{
CString str;
char cBuff[2048];
char *pStart = sys;
char *pEnd = strstr(pStart, "&&");
while (pEnd)
{
int nLen = pEnd-pStart-1;
strncpy(cBuff, pStart, nLen);
cBuff[nLen] = 0;
str = cBuff;
FindReplace(str, rsh, "");
str.TrimLeft(' ');
str.TrimRight(' ');
ATOM a = GlobalAddAtom(str);
PostMessage(hwndPClient, wm_AddCommand, 0, (LPARAM)a);
pStart = pEnd+2;
pEnd = strstr(pStart, "&&");
}
str = pStart;
FindReplace(str, rsh, "");
str.TrimLeft(' ');
str.TrimRight(' ');
ATOM a = GlobalAddAtom(str);
PostMessage(hwndPClient, wm_AddCommand, 0, (LPARAM)a);
Sys_Printf("Commands sent to Q3Map Process Client\n");
return;
}
CString strSys = sys;
FindReplace(strSys, "&&", outputpath);
strcpy(sys, strSys);
strcat(sys, outputpath);
if (g_PrefsDlg.m_bInternalBSP)
{
g_tBegin = CTime::GetCurrentTime();
strSys.MakeLower();
char* p = new char[strSys.GetLength()+1];
strcpy(p, strSys.GetBuffer(0));
ThreadTools(p);
}
else
{
Sys_ClearPrintf ();
Sys_Printf ("==================\nRunning bsp command...\n");
Sys_Printf ("\n%s\n", sys);
//++timo removed the old way BSP commands .. dumping to junk.txt doesn't work on my win98 box
// FIXME : will most likely break Quake2 BSP commands, is fitted to a one-lined sys command
//
// write qe3bsp.bat
//
sprintf (batpath, "%sqe3bsp.bat", temppath);
hFile = fopen(batpath, "w");
if (!hFile)
Error ("Can't write to %s", batpath);
fprintf (hFile, sys);
fclose (hFile);
Pointfile_Delete ();
// delete junk.txt file
remove(strOutFile);
GetStartupInfo (&startupinfo);
ret = CreateProcess(
batpath,
NULL,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&startupinfo,
&ProcessInformation
);
if (!ret)
Error ("CreateProcess failed");
bsp_process = ProcessInformation.hProcess;
Sleep (100); // give the new process a chance to open it's window
BringWindowToTop( g_qeglobals.d_hwndMain ); // pop us back on top
#if 0
//
// write qe3bsp.bat
//
sprintf (batpath, "%sqe3bsp.bat", temppath);
hFile = fopen(batpath, "w");
if (!hFile)
Error ("Can't write to %s", batpath);
fprintf (hFile, sys);
fclose (hFile);
//
// write qe3bsp2.bat
//
sprintf (batpath, "%sqe3bsp2.bat", temppath);
hFile = fopen(batpath, "w");
if (!hFile)
Error ("Can't write to %s", batpath);
fprintf (hFile, "%sqe3bsp.bat > %s", temppath, outputpath);
fclose (hFile);
Pointfile_Delete ();
GetStartupInfo (&startupinfo);
ret = CreateProcess(
batpath, // pointer to name of executable module
NULL, // pointer to command line string
NULL, // pointer to process security attributes
NULL, // pointer to thread security attributes
FALSE, // handle inheritance flag
0 /*DETACHED_PROCESS*/, // creation flags
NULL, // pointer to new environment block
NULL, // pointer to current directory name
&startupinfo, // pointer to STARTUPINFO
&ProcessInformation // pointer to PROCESS_INFORMATION
);
if (!ret)
Error ("CreateProcess failed");
bsp_process = ProcessInformation.hProcess;
Sleep (100); // give the new process a chance to open it's window
//BringWindowToTop( g_qeglobals.d_hwndMain ); // pop us back on top
//SetFocus (g_qeglobals.d_hwndCamera);
#endif
}
}
void DLLBuildDone()
{
g_hToolThread = NULL;
CTime tEnd = CTime::GetCurrentTime();
CTimeSpan tElapsed = tEnd - g_tBegin;
CString strElapsed;
strElapsed.Format("Run time was %i hours, %i minutes and %i seconds", tElapsed.GetHours(), tElapsed.GetMinutes(), tElapsed.GetSeconds());
Sys_Printf(strElapsed.GetBuffer(0));
Pointfile_Check();
if (g_PrefsDlg.m_bRunQuake == TRUE)
{
char cCurDir[1024];
GetCurrentDirectory(1024, cCurDir);
CString strExePath = g_PrefsDlg.m_strQuake2;
CString strOrgPath;
CString strOrgFile;
ExtractPath_and_Filename(currentmap, strOrgPath, strOrgFile);
if (g_PrefsDlg.m_bSetGame == TRUE) // run in place with set game.. don't copy map
{
CString strBasePath = ValueForKey(g_qeglobals.d_project_entity, "basepath");
strExePath += " +set game ";
strExePath += strBasePath;
WinExec(strExePath, SW_SHOW);
}
else
{
CString strCopyPath = strExePath;
char* pBuffer = strCopyPath.GetBufferSetLength(_MAX_PATH + 1);
pBuffer[strCopyPath.ReverseFind('\\') + 1] = '\0';
strCopyPath.ReleaseBuffer();
SetCurrentDirectory(strCopyPath);
CString strOrgPath;
CString strOrgFile;
ExtractPath_and_Filename(currentmap, strOrgPath, strOrgFile);
AddSlash(strCopyPath);
FindReplace(strOrgFile, ".map", ".bsp");
strCopyPath += "\\baseq2\\maps\\";
strCopyPath += strOrgFile;
AddSlash(strOrgPath);
strOrgPath += strOrgFile;
bool bRun = (strOrgPath.CompareNoCase(strCopyPath) == 0);
if (!bRun)
bRun = (CopyFile(strOrgPath, strCopyPath, FALSE) == TRUE);
if (bRun)
{
FindReplace(strOrgFile, ".bsp", "");
strExePath += " +map ";
strExePath += strOrgFile;
WinExec(strExePath, SW_SHOW);
}
}
SetCurrentDirectory(cCurDir);
}
}
/*
=============
DoColor
=============
*/
class CMyColorDialog : public CColorDialog
{
DECLARE_DYNCREATE(CMyColorDialog);
// Construction
public:
CMyColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd*
pParentWnd = NULL );
// Statics
protected:
enum { NCUSTCOLORS = 16 };
static COLORREF c_CustColors[NCUSTCOLORS];
static COLORREF c_LastCustColors[NCUSTCOLORS];
static bool c_NeedToInitCustColors;
protected:
static void InitCustColors();
static void SaveCustColors();
// Dialog Data
protected:
//{{AFX_DATA(CMyColorDialog)
//}}AFX_DATA
// Overrides
protected:
// ClassWizard generate virtual function overrides
//{{AFX_VIRTUAL(CMyColorDialog)
public:
virtual int DoModal();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CMyColorDialog)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
IMPLEMENT_DYNCREATE(CMyColorDialog, CColorDialog)
bool CMyColorDialog::c_NeedToInitCustColors = true;
COLORREF CMyColorDialog::c_CustColors[];
COLORREF CMyColorDialog::c_LastCustColors[];
#define SECTION _T("Custom Colors")
void CMyColorDialog::InitCustColors() {
for (int i = 0; i < NCUSTCOLORS; i++) {
CString entry; entry.Format("%d",i);
c_LastCustColors[i] = c_CustColors[i] =
::AfxGetApp()->GetProfileInt(SECTION,entry,RGB(255,255,255));
}
c_NeedToInitCustColors= false;
}
void CMyColorDialog::SaveCustColors() {
for (int i = 0; i < NCUSTCOLORS; i++) {
if (c_LastCustColors[i] != c_CustColors[i]) {
CString entry; entry.Format("%d",i);
if (c_CustColors[i] == RGB(255,255,255)) {
::AfxGetApp()->WriteProfileString(SECTION,entry,NULL);
} else {
::AfxGetApp()->WriteProfileInt(SECTION, entry,c_CustColors[i]);
}
c_LastCustColors[i] = c_CustColors[i];
}
}
}
CMyColorDialog::CMyColorDialog( COLORREF clrInit, DWORD dwFlags,
CWnd* pParentWnd) : CColorDialog(clrInit,dwFlags,pParentWnd)
{
//{{AFX_DATA_INIT(CMyColorDialog)
//}}AFX_DATA_INIT
if (c_NeedToInitCustColors) {
InitCustColors();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?