gtkradiant/tools/quake2/extra/qe4/win_qe3.c
2012-04-07 18:53:01 -05:00

605 lines
13 KiB
C

/*
===========================================================================
Copyright (C) 1997-2006 Id Software, Inc.
This file is part of Quake 2 Tools source code.
Quake 2 Tools source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake 2 Tools source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake 2 Tools source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qe3.h"
#include "mru.h"
int screen_width;
int screen_height;
qboolean have_quit;
int update_bits;
HANDLE bsp_process;
//===========================================
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;
}
/*
=================
Error
For abnormal program terminations
=================
*/
void Error (char *error, ...)
{
va_list argptr;
char text[1024];
char text2[1024];
int err;
err = GetLastError ();
va_start (argptr,error);
vsprintf (text, error,argptr);
va_end (argptr);
sprintf (text2, "%s\nGetLastError() = %i", text, err);
MessageBox(g_qeglobals.d_hwndMain, text2, "Error", 0 /* MB_OK */ );
exit (1);
}
/*
======================================================================
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;
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 ();
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) )
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
if (msg.message == WM_QUIT)
have_quit = true;
}
CheckBspProcess ();
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;
}