617 lines
13 KiB
C
617 lines
13 KiB
C
#include "qe3.h"
|
|
#include "win_bsp.h"
|
|
#include "mru.h"
|
|
|
|
int screen_width;
|
|
int screen_height;
|
|
qboolean have_quit;
|
|
char UserName[256];
|
|
int update_bits;
|
|
|
|
HANDLE bsp_process;
|
|
|
|
//===========================================
|
|
|
|
#define ShortTime "%a %b %d %Y %I:%M:%S %p"
|
|
|
|
void WriteUserLog(char *fmt, ...)
|
|
{
|
|
char Buffer[1024], FileName[1024], TimeBuff[1024];
|
|
int Length;
|
|
va_list argptr;
|
|
FILE *FH;
|
|
struct tm *tblock;
|
|
time_t TempTime;
|
|
|
|
va_start(argptr, fmt);
|
|
Length = vsprintf(Buffer, fmt, argptr);
|
|
va_end(argptr);
|
|
|
|
TempTime = time(NULL);
|
|
tblock = localtime(&TempTime);
|
|
strftime(TimeBuff,80,ShortTime,tblock);
|
|
|
|
sprintf(FileName, "h:\\rjohnson\\ul\\%s.txt", UserName);
|
|
FH = fopen(FileName, "r+");
|
|
if (!FH)
|
|
{
|
|
FH = fopen(FileName, "w");
|
|
if (!FH)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fseek(FH, 0, SEEK_END);
|
|
}
|
|
fprintf(FH, "%s %s\n", TimeBuff, Buffer);
|
|
fclose(FH);
|
|
}
|
|
|
|
void Sys_SetTitle (char *text)
|
|
{
|
|
SetWindowText (g_qeglobals.d_hwndMain, text);
|
|
}
|
|
|
|
HCURSOR waitcursor;
|
|
|
|
void Sys_BeginWait (void)
|
|
{
|
|
waitcursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
|
|
}
|
|
|
|
void Sys_EndWait (void)
|
|
{
|
|
if (waitcursor)
|
|
{
|
|
SetCursor (waitcursor);
|
|
waitcursor = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void Sys_GetCursorPos (int *x, int *y)
|
|
{
|
|
POINT lpPoint;
|
|
|
|
GetCursorPos (&lpPoint);
|
|
*x = lpPoint.x;
|
|
*y = lpPoint.y;
|
|
}
|
|
|
|
void Sys_SetCursorPos (int x, int y)
|
|
{
|
|
SetCursorPos (x, y);
|
|
}
|
|
|
|
void Sys_UpdateWindows (int bits)
|
|
{
|
|
// Sys_Printf("updating 0x%X\n", bits);
|
|
update_bits |= bits;
|
|
//update_bits = -1;
|
|
}
|
|
|
|
|
|
void Sys_Beep (void)
|
|
{
|
|
MessageBeep (MB_ICONASTERISK);
|
|
}
|
|
|
|
char *TranslateString (char *buf)
|
|
{
|
|
static char buf2[32768];
|
|
int i, l;
|
|
char *out;
|
|
|
|
l = strlen(buf);
|
|
out = buf2;
|
|
for (i=0 ; i<l ; i++)
|
|
{
|
|
if (buf[i] == '\n')
|
|
{
|
|
*out++ = '\r';
|
|
*out++ = '\n';
|
|
}
|
|
else
|
|
*out++ = buf[i];
|
|
}
|
|
*out++ = 0;
|
|
|
|
return buf2;
|
|
}
|
|
|
|
void Sys_ClearPrintf (void)
|
|
{
|
|
char text[4];
|
|
|
|
text[0] = 0;
|
|
|
|
SendMessage (g_qeglobals.d_hwndEdit,
|
|
WM_SETTEXT,
|
|
0,
|
|
(LPARAM)text);
|
|
}
|
|
|
|
void Sys_Printf (char *text, ...)
|
|
{
|
|
va_list argptr;
|
|
char buf[32768];
|
|
char *out;
|
|
|
|
va_start (argptr,text);
|
|
vsprintf (buf, text,argptr);
|
|
va_end (argptr);
|
|
|
|
out = TranslateString (buf);
|
|
|
|
#ifdef LATER
|
|
Sys_Status(out);
|
|
#else
|
|
SendMessage (g_qeglobals.d_hwndEdit,
|
|
EM_REPLACESEL,
|
|
0,
|
|
(LPARAM)out);
|
|
#endif
|
|
|
|
}
|
|
|
|
double Sys_DoubleTime (void)
|
|
{
|
|
return clock()/ 1000.0;
|
|
}
|
|
|
|
void PrintPixels (HDC hDC)
|
|
{
|
|
int i;
|
|
PIXELFORMATDESCRIPTOR p[64];
|
|
|
|
printf ("### flags color layer\n");
|
|
for (i=1 ; i<64 ; i++)
|
|
{
|
|
if (!DescribePixelFormat ( hDC, i, sizeof(p[0]), &p[i]))
|
|
break;
|
|
printf ("%3i %5i %5i %5i\n", i,
|
|
p[i].dwFlags,
|
|
p[i].cColorBits,
|
|
p[i].bReserved);
|
|
}
|
|
printf ("%i modes\n", i-1);
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
void QEW_StopGL( HWND hWnd, HGLRC hGLRC, HDC hDC )
|
|
{
|
|
wglMakeCurrent( NULL, NULL );
|
|
wglDeleteContext( hGLRC );
|
|
ReleaseDC( hWnd, hDC );
|
|
}
|
|
|
|
int QEW_SetupPixelFormat(HDC hDC, qboolean zbuffer )
|
|
{
|
|
static PIXELFORMATDESCRIPTOR pfd = {
|
|
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
|
|
1, // version number
|
|
PFD_DRAW_TO_WINDOW | // support window
|
|
PFD_SUPPORT_OPENGL | // support OpenGL
|
|
PFD_DOUBLEBUFFER, // double buffered
|
|
PFD_TYPE_RGBA, // RGBA type
|
|
24, // 24-bit color depth
|
|
0, 0, 0, 0, 0, 0, // color bits ignored
|
|
0, // no alpha buffer
|
|
0, // shift bit ignored
|
|
0, // no accumulation buffer
|
|
0, 0, 0, 0, // accum bits ignored
|
|
32, // depth bits
|
|
0, // no stencil buffer
|
|
0, // no auxiliary buffer
|
|
PFD_MAIN_PLANE, // main layer
|
|
0, // reserved
|
|
0, 0, 0 // layer masks ignored
|
|
};
|
|
int pixelformat = 0;
|
|
|
|
zbuffer = true;
|
|
if ( !zbuffer )
|
|
pfd.cDepthBits = 0;
|
|
|
|
if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 )
|
|
{
|
|
printf("%d",GetLastError());
|
|
Error ("ChoosePixelFormat failed");
|
|
}
|
|
|
|
if (!SetPixelFormat(hDC, pixelformat, &pfd))
|
|
Error ("SetPixelFormat failed");
|
|
|
|
return pixelformat;
|
|
}
|
|
|
|
/*
|
|
======================================================================
|
|
|
|
FILE DIALOGS
|
|
|
|
======================================================================
|
|
*/
|
|
|
|
qboolean ConfirmModified (void)
|
|
{
|
|
if (!modified)
|
|
return true;
|
|
|
|
if (MessageBox (g_qeglobals.d_hwndMain, "This will lose changes to the map"
|
|
, "warning", MB_OKCANCEL) == IDCANCEL)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
static OPENFILENAME ofn; /* common dialog box structure */
|
|
static char szDirName[MAX_PATH]; /* directory string */
|
|
static char szFile[260]; /* filename string */
|
|
static char szFileTitle[260]; /* file title string */
|
|
static char szFilter[260] = /* filter string */
|
|
"QuakeEd file (*.map)\0*.map\0\0";
|
|
static char szProjectFilter[260] = /* filter string */
|
|
"QuakeEd project (*.qe4)\0*.qe4\0\0";
|
|
static char chReplace; /* string separator for szFilter */
|
|
static int i, cbString; /* integer count variables */
|
|
static HANDLE hf; /* file handle */
|
|
|
|
void OpenDialog (void)
|
|
{
|
|
/*
|
|
* Obtain the system directory name and
|
|
* store it in szDirName.
|
|
*/
|
|
|
|
strcpy (szDirName, ValueForKey (g_qeglobals.d_project_entity, "basepath") );
|
|
strcat (szDirName, "\\maps");
|
|
|
|
/* Place the terminating null character in the szFile. */
|
|
|
|
szFile[0] = '\0';
|
|
|
|
/* Set the members of the OPENFILENAME structure. */
|
|
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = g_qeglobals.d_hwndCamera;
|
|
ofn.lpstrFilter = szFilter;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = szFile;
|
|
ofn.nMaxFile = sizeof(szFile);
|
|
ofn.lpstrFileTitle = szFileTitle;
|
|
ofn.nMaxFileTitle = sizeof(szFileTitle);
|
|
ofn.lpstrInitialDir = szDirName;
|
|
ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
|
|
OFN_FILEMUSTEXIST;
|
|
|
|
/* Display the Open dialog box. */
|
|
|
|
if (!GetOpenFileName(&ofn))
|
|
return; // canceled
|
|
|
|
// Add the file in MRU.
|
|
AddNewItem( g_qeglobals.d_lpMruMenu, ofn.lpstrFile);
|
|
|
|
// Refresh the File menu.
|
|
PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(g_qeglobals.d_hwndMain),0),
|
|
ID_FILE_EXIT);
|
|
|
|
/* Open the file. */
|
|
|
|
Map_LoadFile (ofn.lpstrFile);
|
|
}
|
|
|
|
void ProjectDialog (void)
|
|
{
|
|
/*
|
|
* Obtain the system directory name and
|
|
* store it in szDirName.
|
|
*/
|
|
|
|
strcpy (szDirName, ValueForKey(g_qeglobals.d_project_entity, "basepath") );
|
|
strcat (szDirName, "\\scripts");
|
|
|
|
/* Place the terminating null character in the szFile. */
|
|
|
|
szFile[0] = '\0';
|
|
|
|
/* Set the members of the OPENFILENAME structure. */
|
|
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = g_qeglobals.d_hwndCamera;
|
|
ofn.lpstrFilter = szProjectFilter;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = szFile;
|
|
ofn.nMaxFile = sizeof(szFile);
|
|
ofn.lpstrFileTitle = szFileTitle;
|
|
ofn.nMaxFileTitle = sizeof(szFileTitle);
|
|
ofn.lpstrInitialDir = szDirName;
|
|
ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
|
|
OFN_FILEMUSTEXIST;
|
|
|
|
/* Display the Open dialog box. */
|
|
|
|
if (!GetOpenFileName(&ofn))
|
|
return; // canceled
|
|
|
|
// Refresh the File menu.
|
|
PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(g_qeglobals.d_hwndMain),0),
|
|
ID_FILE_EXIT);
|
|
|
|
/* Open the file. */
|
|
if (!QE_LoadProject(ofn.lpstrFile))
|
|
Error ("Couldn't load project file");
|
|
}
|
|
|
|
|
|
void SaveAsDialog (void)
|
|
{
|
|
strcpy (szDirName, ValueForKey (g_qeglobals.d_project_entity, "basepath") );
|
|
strcat (szDirName, "\\maps");
|
|
|
|
/* Place the terminating null character in the szFile. */
|
|
|
|
szFile[0] = '\0';
|
|
|
|
/* Set the members of the OPENFILENAME structure. */
|
|
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = g_qeglobals.d_hwndCamera;
|
|
ofn.lpstrFilter = szFilter;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = szFile;
|
|
ofn.nMaxFile = sizeof(szFile);
|
|
ofn.lpstrFileTitle = szFileTitle;
|
|
ofn.nMaxFileTitle = sizeof(szFileTitle);
|
|
ofn.lpstrInitialDir = szDirName;
|
|
ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
|
|
OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT;
|
|
|
|
/* Display the Open dialog box. */
|
|
|
|
if (!GetSaveFileName(&ofn))
|
|
return; // canceled
|
|
|
|
DefaultExtension (ofn.lpstrFile, ".map");
|
|
strcpy (currentmap, ofn.lpstrFile);
|
|
|
|
// Add the file in MRU.
|
|
AddNewItem(g_qeglobals.d_lpMruMenu, ofn.lpstrFile);
|
|
|
|
// Refresh the File menu.
|
|
PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(g_qeglobals.d_hwndMain),0),
|
|
ID_FILE_EXIT);
|
|
|
|
Map_SaveFile (ofn.lpstrFile, false); // ignore region
|
|
}
|
|
|
|
/*
|
|
=======================================================
|
|
|
|
Menu modifications
|
|
|
|
=======================================================
|
|
*/
|
|
|
|
/*
|
|
==================
|
|
FillBSPMenu
|
|
|
|
==================
|
|
*/
|
|
char *bsp_commands[256];
|
|
|
|
void FillBSPMenu (void)
|
|
{
|
|
HMENU hmenu;
|
|
epair_t *ep;
|
|
int i;
|
|
static int count;
|
|
|
|
hmenu = GetSubMenu (GetMenu(g_qeglobals.d_hwndMain), MENU_BSP);
|
|
|
|
for (i=0 ; i<count ; i++)
|
|
DeleteMenu (hmenu, CMD_BSPCOMMAND+i, MF_BYCOMMAND);
|
|
count = 0;
|
|
|
|
i = 0;
|
|
for (ep = g_qeglobals.d_project_entity->epairs ; ep ; ep=ep->next)
|
|
{
|
|
if (ep->key[0] == 'b' && ep->key[1] == 's' && ep->key[2] == 'p')
|
|
{
|
|
bsp_commands[i] = ep->key;
|
|
AppendMenu (hmenu, MF_ENABLED|MF_STRING,
|
|
CMD_BSPCOMMAND+i, (LPCTSTR)ep->key);
|
|
i++;
|
|
}
|
|
}
|
|
count = i;
|
|
}
|
|
|
|
//==============================================
|
|
|
|
/*
|
|
===============
|
|
CheckBspProcess
|
|
|
|
See if the BSP is done yet
|
|
===============
|
|
*/
|
|
void CheckBspProcess (void)
|
|
{
|
|
char outputpath[1024];
|
|
char temppath[512];
|
|
DWORD exitcode;
|
|
char *out;
|
|
BOOL ret;
|
|
|
|
if (!bsp_process)
|
|
return;
|
|
|
|
ret = GetExitCodeProcess (bsp_process, &exitcode);
|
|
if (!ret)
|
|
Error ("GetExitCodeProcess failed");
|
|
if (exitcode == STILL_ACTIVE)
|
|
return;
|
|
|
|
bsp_process = 0;
|
|
|
|
GetTempPath(512, temppath);
|
|
sprintf (outputpath, "%sjunk.txt", temppath);
|
|
|
|
LoadFile (outputpath, (void *)&out);
|
|
Sys_Printf ("%s", out);
|
|
Sys_Printf ("\ncompleted.\n");
|
|
free (out);
|
|
Sys_Beep ();
|
|
|
|
Pointfile_Check ();
|
|
}
|
|
|
|
extern int cambuttonstate;
|
|
|
|
/*
|
|
==================
|
|
WinMain
|
|
|
|
==================
|
|
*/
|
|
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance
|
|
,LPSTR lpCmdLine, int nCmdShow)
|
|
{
|
|
MSG msg;
|
|
double time, oldtime, delta;
|
|
HACCEL accelerators;
|
|
DWORD Size;
|
|
|
|
Size = sizeof(UserName);
|
|
GetUserName(UserName, &Size);
|
|
|
|
WriteUserLog("Opened QE4");
|
|
|
|
g_qeglobals.d_hInstance = hInstance;
|
|
|
|
InitCommonControls ();
|
|
|
|
screen_width = GetSystemMetrics (SM_CXFULLSCREEN);
|
|
screen_height = GetSystemMetrics (SM_CYFULLSCREEN);
|
|
|
|
// hack for broken NT 4.0 dual screen
|
|
if (screen_width > 2*screen_height)
|
|
screen_width /= 2;
|
|
|
|
accelerators = LoadAccelerators (hInstance
|
|
, MAKEINTRESOURCE(IDR_ACCELERATOR1));
|
|
if (!accelerators)
|
|
Error ("LoadAccelerators failed");
|
|
|
|
Main_Create (hInstance);
|
|
|
|
WCam_Create (hInstance);
|
|
WXY_Create (hInstance);
|
|
WZ_Create (hInstance);
|
|
CreateEntityWindow(hInstance);
|
|
|
|
// the project file can be specified on the command line,
|
|
// or implicitly found in the scripts directory
|
|
if (lpCmdLine && strlen(lpCmdLine))
|
|
{
|
|
ParseCommandLine (lpCmdLine);
|
|
if (!QE_LoadProject(argv[1]))
|
|
Error ("Couldn't load %s project file", argv[1]);
|
|
}
|
|
else if (!QE_LoadProject("scripts/quake.qe4"))
|
|
Error ("Couldn't load scripts/quake.qe4 project file");
|
|
|
|
QE_Init ();
|
|
|
|
|
|
// The unintellimouse uses a Registered
|
|
// message to transmit
|
|
// wheel rotation info. So get ready for it!
|
|
// dis glob inited to 0 in QE_Init
|
|
|
|
g_qeglobals.uMSH_MOUSEWHEEL =
|
|
RegisterWindowMessage(MSH_MOUSEWHEEL);
|
|
if ( !g_qeglobals.uMSH_MOUSEWHEEL )
|
|
{
|
|
Error ("RegisterWindowMessag Failed!");
|
|
}
|
|
|
|
Sys_Printf ("Entering message loop\n");
|
|
|
|
oldtime = Sys_DoubleTime ();
|
|
|
|
while (!have_quit)
|
|
{
|
|
Sys_EndWait (); // remove wait cursor if active
|
|
|
|
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
|
|
{
|
|
if (!TranslateAccelerator(g_qeglobals.d_hwndMain, accelerators, &msg) )
|
|
{
|
|
if(!IsDialogMessage(g_qeglobals.d_hwndTexModDlg, &msg))
|
|
{
|
|
TranslateMessage (&msg);
|
|
DispatchMessage (&msg);
|
|
}
|
|
}
|
|
if (msg.message == WM_QUIT)
|
|
have_quit = true;
|
|
}
|
|
|
|
|
|
bsp_CheckTask ();
|
|
|
|
time = Sys_DoubleTime ();
|
|
delta = time - oldtime;
|
|
oldtime = time;
|
|
if (delta > 0.2)
|
|
delta = 0.2;
|
|
|
|
// run time dependant behavior
|
|
Cam_MouseControl (delta);
|
|
|
|
// update any windows now
|
|
if (update_bits & W_CAMERA)
|
|
{
|
|
InvalidateRect(g_qeglobals.d_hwndCamera, NULL, false);
|
|
UpdateWindow (g_qeglobals.d_hwndCamera);
|
|
}
|
|
if (update_bits & (W_Z | W_Z_OVERLAY) )
|
|
{
|
|
InvalidateRect(g_qeglobals.d_hwndZ, NULL, false);
|
|
UpdateWindow (g_qeglobals.d_hwndZ);
|
|
}
|
|
|
|
if ( update_bits & W_TEXTURE )
|
|
{
|
|
InvalidateRect(g_qeglobals.d_hwndTexture, NULL, false);
|
|
UpdateWindow (g_qeglobals.d_hwndEntity);
|
|
}
|
|
|
|
if (update_bits & (W_XY | W_XY_OVERLAY))
|
|
{
|
|
InvalidateRect(g_qeglobals.d_hwndXY, NULL, false);
|
|
UpdateWindow (g_qeglobals.d_hwndXY);
|
|
}
|
|
|
|
update_bits = 0;
|
|
|
|
if (!cambuttonstate && !have_quit)
|
|
{ // if not driving in the camera view, block
|
|
WaitMessage ();
|
|
}
|
|
|
|
}
|
|
|
|
/* return success of application */
|
|
return TRUE;
|
|
|
|
}
|
|
|