2007-11-04 03:51:54 +00:00
/*
2012-03-17 20:01:54 +00:00
Copyright ( C ) 1999 - 2007 id Software , Inc . and contributors .
For a list of contributors , see the accompanying CONTRIBUTORS file .
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
This file is part of GtkRadiant .
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
GtkRadiant 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 .
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
GtkRadiant 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 .
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
You should have received a copy of the GNU General Public License
along with GtkRadiant ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
# if defined ( __linux__ ) || defined ( __APPLE__ )
2007-11-04 03:51:54 +00:00
# include <gdk/gdkx.h>
# include <pwd.h>
2008-06-26 07:52:02 +00:00
# include <unistd.h>
2007-11-04 03:51:54 +00:00
# ifdef __linux__
2012-03-17 20:01:54 +00:00
# include <mntent.h>
2007-11-04 03:51:54 +00:00
# endif
# include <dirent.h>
# include <pthread.h>
# include <sys/wait.h>
# include <signal.h>
# include <sys/stat.h>
# endif
# include <gtk/gtk.h>
2010-11-26 19:50:08 +00:00
# include <gtk/gtkgl.h>
2008-06-26 07:52:02 +00:00
# include <glib/gi18n.h>
2007-11-04 03:51:54 +00:00
# include "stdafx.h"
# include <assert.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <stdlib.h>
# include "watchbsp.h"
# include "filters.h"
2010-11-26 19:50:08 +00:00
# include "glwidget.h"
2007-11-04 03:51:54 +00:00
bool g_bBuildList = false ;
int g_argc ;
char * * g_argv ;
2012-05-17 12:11:03 +00:00
// =============================================================================
// Windows WinMain() wrapper for main()
// used in Release Builds to suppress the Console
# if defined(_WIN32)
# include <winbase.h>
int main ( int argc , char * argv [ ] ) ;
int CALLBACK WinMain (
__in HINSTANCE hInstance ,
__in HINSTANCE hPrevInstance ,
__in LPSTR lpCmdLine ,
__in int nCmdShow
) {
2012-05-17 12:14:34 +00:00
return main ( __argc , __argv ) ;
2012-05-17 12:11:03 +00:00
}
# endif
2007-11-04 03:51:54 +00:00
// =============================================================================
// Splash screen
// get rid of it when debugging
2012-03-17 20:01:54 +00:00
# if defined ( _DEBUG )
2007-11-04 03:51:54 +00:00
# define SKIP_SPLASH
# endif
static GtkWidget * splash_screen ;
// called based on a timer, or in particular cases when we don't want to keep it around
2012-03-17 20:01:54 +00:00
gint try_destroy_splash ( gpointer data ) {
if ( splash_screen ) {
gtk_widget_destroy ( splash_screen ) ;
splash_screen = NULL ;
}
return FALSE ;
2007-11-04 03:51:54 +00:00
}
2012-03-17 20:01:54 +00:00
static void create_splash ( ) {
GtkWidget * alert_frame , * alert_frame1 , * pixmap ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
splash_screen = gtk_window_new ( GTK_WINDOW_POPUP ) ;
gtk_window_position ( GTK_WINDOW ( splash_screen ) , GTK_WIN_POS_CENTER ) ;
gtk_widget_realize ( splash_screen ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
alert_frame1 = gtk_frame_new ( NULL ) ;
gtk_widget_show ( alert_frame1 ) ;
gtk_container_add ( GTK_CONTAINER ( splash_screen ) , alert_frame1 ) ;
gtk_frame_set_shadow_type ( GTK_FRAME ( alert_frame1 ) , GTK_SHADOW_OUT ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
alert_frame = gtk_frame_new ( NULL ) ;
gtk_widget_show ( alert_frame ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
gtk_container_add ( GTK_CONTAINER ( alert_frame1 ) , alert_frame ) ;
gtk_frame_set_shadow_type ( GTK_FRAME ( alert_frame ) , GTK_SHADOW_IN ) ;
gtk_container_border_width ( GTK_CONTAINER ( alert_frame ) , 3 ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
pixmap = gtk_preview_new ( GTK_PREVIEW_COLOR ) ;
gtk_widget_show ( pixmap ) ;
gtk_container_add ( GTK_CONTAINER ( alert_frame ) , pixmap ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
CString str ;
guint16 width , height ;
unsigned char * buf ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
str = g_strGameToolsPath ;
str + = " bitmaps/splash.bmp " ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
unsigned char * load_bitmap_file ( const char * filename , guint16 * width , guint16 * height ) ;
buf = load_bitmap_file ( str . GetBuffer ( ) , & width , & height ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
if ( ! buf ) {
str = g_strBitmapsPath ;
str + = " splash.bmp " ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
buf = load_bitmap_file ( str . GetBuffer ( ) , & width , & height ) ;
}
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
if ( buf ) {
GtkPreview * preview = GTK_PREVIEW ( pixmap ) ;
gtk_preview_size ( preview , width , height ) ;
for ( int y = 0 ; y < height ; y + + )
gtk_preview_draw_row ( preview , buf + y * width * 3 , 0 , y , width ) ;
}
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
gtk_widget_show_all ( splash_screen ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
while ( gtk_events_pending ( ) )
gtk_main_iteration ( ) ;
2007-11-04 03:51:54 +00:00
}
// =============================================================================
// Loki stuff
2012-03-17 20:01:54 +00:00
# if defined ( __linux__ ) || defined ( __APPLE__ )
2007-11-04 03:51:54 +00:00
/* A short game name, could be used as argv[0] */
static char game_name [ 100 ] = " " ;
/* The directory where the data files can be found (run directory) */
static char datapath [ PATH_MAX ] ;
2012-03-17 20:01:54 +00:00
char * loki_gethomedir ( void ) {
char * home = NULL ;
home = getenv ( " HOME " ) ;
if ( home = = NULL ) {
uid_t id = getuid ( ) ;
struct passwd * pwd ;
setpwent ( ) ;
while ( ( pwd = getpwent ( ) ) ! = NULL )
{
if ( pwd - > pw_uid = = id ) {
home = pwd - > pw_dir ;
break ;
}
}
endpwent ( ) ;
}
return home ;
2007-11-04 03:51:54 +00:00
}
/* Must be called BEFORE loki_initialize */
2012-03-17 20:01:54 +00:00
void loki_setgamename ( const char * n ) {
strncpy ( game_name , n , sizeof ( game_name ) ) ;
2007-11-04 03:51:54 +00:00
}
# ifdef __linux__
/* Code to determine the mount point of a CD-ROM */
2012-03-17 20:01:54 +00:00
int loki_getmountpoint ( const char * device , char * mntpt , int max_size ) {
char devpath [ PATH_MAX ] , mntdevpath [ PATH_MAX ] ;
FILE * mountfp ;
struct mntent * mntent ;
int mounted ;
/* Nothing to do with no device file */
if ( device = = NULL ) {
* mntpt = ' \0 ' ;
return - 1 ;
}
/* Get the fully qualified path of the CD-ROM device */
if ( realpath ( device , devpath ) = = NULL ) {
perror ( " realpath() on your CD-ROM failed " ) ;
return ( - 1 ) ;
}
/* Get the mount point */
mounted = - 1 ;
memset ( mntpt , 0 , max_size ) ;
mountfp = setmntent ( _PATH_MNTTAB , " r " ) ;
if ( mountfp ! = NULL ) {
mounted = 0 ;
while ( ( mntent = getmntent ( mountfp ) ) ! = NULL )
{
char * tmp , mntdev [ 1024 ] ;
strcpy ( mntdev , mntent - > mnt_fsname ) ;
if ( strcmp ( mntent - > mnt_type , " supermount " ) = = 0 ) {
tmp = strstr ( mntent - > mnt_opts , " dev= " ) ;
if ( tmp ) {
strcpy ( mntdev , tmp + strlen ( " dev= " ) ) ;
tmp = strchr ( mntdev , ' , ' ) ;
if ( tmp ) {
* tmp = ' \0 ' ;
}
}
}
if ( strncmp ( mntdev , " /dev " , 4 ) | |
realpath ( mntdev , mntdevpath ) = = NULL ) {
continue ;
}
if ( strcmp ( mntdevpath , devpath ) = = 0 ) {
mounted = 1 ;
assert ( ( int ) strlen ( mntent - > mnt_dir ) < max_size ) ;
strncpy ( mntpt , mntent - > mnt_dir , max_size - 1 ) ;
mntpt [ max_size - 1 ] = ' \0 ' ;
break ;
}
}
endmntent ( mountfp ) ;
}
return ( mounted ) ;
2008-06-26 07:52:02 +00:00
}
2007-11-04 03:51:54 +00:00
# endif
2008-06-26 07:52:02 +00:00
/*
2007-11-04 03:51:54 +00:00
This function gets the directory containing the running program .
argv0 - the 0 ' th argument to the program
2012-03-17 20:01:54 +00:00
*/
2007-11-04 03:51:54 +00:00
// FIXME TTimo
// I don't understand this function. It looks like something cut from another piece of software
// we somehow get the g_strAppPath from it, but it's done through a weird scan across $PATH env. var.
// even worse, it doesn't behave the same in all cases .. works well when ran through gdb and borks when ran from a shell
2012-03-17 20:01:54 +00:00
void loki_initpaths ( char * argv0 ) {
char temppath [ PATH_MAX ] ; //, env[100];
char * home ; //, *ptr, *data_env;
home = loki_gethomedir ( ) ;
if ( home = = NULL ) {
home = " . " ;
}
if ( * game_name = = 0 ) { /* Game name defaults to argv[0] */
loki_setgamename ( argv0 ) ;
}
strcpy ( temppath , argv0 ) ; /* If this overflows, it's your own fault :) */
if ( ! strrchr ( temppath , ' / ' ) ) {
char * path ;
char * last ;
int found ;
found = 0 ;
path = getenv ( " PATH " ) ;
do
{
/* Initialize our filename variable */
temppath [ 0 ] = ' \0 ' ;
/* Get next entry from path variable */
last = strchr ( path , ' : ' ) ;
if ( ! last ) {
last = path + strlen ( path ) ;
}
/* Perform tilde expansion */
if ( * path = = ' ~ ' ) {
strcpy ( temppath , home ) ;
+ + path ;
}
/* Fill in the rest of the filename */
if ( last > ( path + 1 ) ) {
strncat ( temppath , path , ( last - path ) ) ;
strcat ( temppath , " / " ) ;
}
strcat ( temppath , " ./ " ) ;
strcat ( temppath , argv0 ) ;
/* See if it exists, and update path */
if ( access ( temppath , X_OK ) = = 0 ) {
+ + found ;
}
path = last + 1 ;
} while ( * last & & ! found ) ;
}
else
{
/* Increment argv0 to the basename */
argv0 = strrchr ( argv0 , ' / ' ) + 1 ;
}
/* Now canonicalize it to a full pathname for the data path */
if ( realpath ( temppath , datapath ) ) {
/* There should always be '/' in the path */
* ( strrchr ( datapath , ' / ' ) ) = ' \0 ' ;
}
2007-11-04 03:51:54 +00:00
}
2012-03-17 20:01:54 +00:00
char * loki_getdatapath ( void ) {
return ( datapath ) ;
2007-11-04 03:51:54 +00:00
}
# endif
// end of Loki stuff
// =============================================================================
2012-03-17 20:01:54 +00:00
void error_redirect ( const gchar * domain , GLogLevelFlags log_level , const gchar * message , gpointer user_data ) {
gboolean in_recursion ;
gboolean is_fatal ;
char buf [ 256 ] ;
in_recursion = ( log_level & G_LOG_FLAG_RECURSION ) ! = 0 ;
is_fatal = ( log_level & G_LOG_FLAG_FATAL ) ! = 0 ;
log_level = ( GLogLevelFlags ) ( log_level & G_LOG_LEVEL_MASK ) ;
if ( ! message ) {
message = " (NULL) message " ;
}
if ( domain ) {
strcpy ( buf , domain ) ;
}
else {
strcpy ( buf , " ** " ) ;
}
strcat ( buf , " - " ) ;
switch ( log_level )
{
case G_LOG_LEVEL_ERROR :
if ( in_recursion ) {
strcat ( buf , " ERROR (recursed) **: " ) ;
}
else {
strcat ( buf , " ERROR **: " ) ;
}
break ;
case G_LOG_LEVEL_CRITICAL :
if ( in_recursion ) {
strcat ( buf , " CRITICAL (recursed) **: " ) ;
}
else {
strcat ( buf , " CRITICAL **: " ) ;
}
break ;
case G_LOG_LEVEL_WARNING :
if ( in_recursion ) {
strcat ( buf , " WARNING (recursed) **: " ) ;
}
else {
strcat ( buf , " WARNING **: " ) ;
}
break ;
case G_LOG_LEVEL_MESSAGE :
if ( in_recursion ) {
strcat ( buf , " Message (recursed): " ) ;
}
else {
strcat ( buf , " Message: " ) ;
}
break ;
case G_LOG_LEVEL_INFO :
if ( in_recursion ) {
strcat ( buf , " INFO (recursed): " ) ;
}
else {
strcat ( buf , " INFO: " ) ;
}
break ;
case G_LOG_LEVEL_DEBUG :
if ( in_recursion ) {
strcat ( buf , " DEBUG (recursed): " ) ;
}
else {
strcat ( buf , " DEBUG: " ) ;
}
break ;
default :
/* we are used for a log level that is not defined by GLib itself,
* try to make the best out of it .
*/
if ( in_recursion ) {
strcat ( buf , " LOG (recursed: " ) ;
}
else {
strcat ( buf , " LOG ( " ) ;
}
if ( log_level ) {
gchar string [ ] = " 0x00): " ;
gchar * p = string + 2 ;
guint i ;
i = g_bit_nth_msf ( log_level , - 1 ) ;
* p = i > > 4 ;
p + + ;
* p = ' 0 ' + ( i & 0xf ) ;
if ( * p > ' 9 ' ) {
* p + = ' A ' - ' 9 ' - 1 ;
}
strcat ( buf , string ) ;
}
else {
strcat ( buf , " ): " ) ;
}
}
strcat ( buf , message ) ;
if ( is_fatal ) {
strcat ( buf , " \n aborting... \n " ) ;
}
else {
strcat ( buf , " \n " ) ;
}
printf ( " %s \n " , buf ) ;
Sys_FPrintf ( SYS_WRN , buf ) ;
// TTimo NOTE: in some cases it may be handy to log only to the file
2007-11-04 03:51:54 +00:00
// Sys_FPrintf (SYS_NOCON, buf);
}
2008-06-26 08:31:13 +00:00
# define GETTEXT_PACKAGE "radiant"
# define LOCALEDIR "lang"
2007-12-25 00:10:45 +00:00
int main ( int argc , char * argv [ ] ) {
char * libgl , * ptr ;
int i , j , k ;
2007-11-04 03:51:54 +00:00
2011-01-22 03:22:21 +00:00
2012-03-17 20:01:54 +00:00
/*
Rambetter on Sat Nov 13 , 2010 :
The following line fixes parsing and writing of floating point numbers in locales such as
Italy , Germany , and others outside of en_US . In particular , in such problem locales , users
are not able to use certain map entities such as " light " because the definitions of these entities
in the entity definition files contain floating point values written in the standard " C " format
( containing a dot instead of , for example , a comma ) . The call sscanf ( ) is all over the code ,
including parsing entity definition files and reading Radiant preferences . sscanf ( ) is sensitive
to locale ( in particular when reading floating point numbers ) .
The line below is the minimalistic way to address only this particular problem - the parsing
and writing of floating point values . There may be other yet - undiscovered bugs related to
locale still lingering in the code . When such bugs are discovered , they should be addressed by
setting more than just " LC_NUMERIC=C " ( for example LC_CTYPE for regular expression matching )
or by fixing the problem in the actual code instead of fiddling with LC_ * variables .
Another way to fix the floating point format problem is to locate all calls such as * scanf ( )
and * printf ( ) in the code and replace them with other functions . However , we ' re also using
external libraries such as libxml and [ maybe ? ] they use locale to parse their numeric values .
I ' m just saying , it may get ugly if we try to fix the problem without setting LC_NUMERIC .
Usage of sscanf ( ) throughout the code looks like so :
sscanf ( str , " %f %f %f " , & val1 , & val2 , & val3 ) ;
Code like this exists in many files , here are 4 examples :
tools / quake3 / q3map2 / light . c
tools / quake3 / q3map2 / model . c
radiant / preferences . cpp
plugins / entity / miscmodel . cpp
Also affected are printf ( ) calls when using formats that contain " %f " .
I did some research and putenv ( ) seems to be the best choice for being cross - platform . It
used to be a function in Windows ( now deprecated ) :
http : //msdn.microsoft.com/en-us/library/ms235321(VS.80).aspx
And of course it ' s defined in UNIX .
One more thing . the gtk_init ( ) call below modifies all of the locale settings . In fact if it
weren ' t for gtk_init ( ) , we wouldn ' t have to set LC_NUMERIC ( parsing of floating points with
a dot works just fine before the gtk_init ( ) call on a sample Linux system ) . If we were to
just setlocale ( ) here , it would get clobbered by gtk_init ( ) . So instead of using setlocale ( )
_after_ gtk_init ( ) , I chose to fix this problem via environment variable . I think it ' s cleaner
that way .
*/
putenv ( " LC_NUMERIC=C " ) ;
2010-11-14 01:40:25 +00:00
2007-11-04 03:51:54 +00:00
# ifdef _WIN32
2012-03-17 20:01:54 +00:00
libgl = " opengl32.dll " ;
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
# if defined ( __linux__ )
libgl = " libGL.so.1 " ;
2007-11-04 03:51:54 +00:00
# endif
# ifdef __APPLE__
2013-03-29 21:00:54 +00:00
// libgl = "/usr/X11R6/lib/libGL.dylib";
// libgl = "/usr/X11/lib/libGL.dylib";
libgl = " /opt/local/lib/libGL.dylib " ;
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
# if defined ( __linux__ ) || defined ( __APPLE__ )
// Give away unnecessary root privileges.
// Important: must be done before calling gtk_init().
char * loginname ;
struct passwd * pw ;
seteuid ( getuid ( ) ) ;
if ( geteuid ( ) = = 0 & & ( loginname = getlogin ( ) ) ! = NULL & & ( pw = getpwnam ( loginname ) ) ! = NULL ) {
setuid ( pw - > pw_uid ) ;
}
2007-11-04 03:51:54 +00:00
# endif
2008-06-26 08:31:13 +00:00
2012-03-17 20:01:54 +00:00
bindtextdomain ( GETTEXT_PACKAGE , LOCALEDIR ) ;
bind_textdomain_codeset ( GETTEXT_PACKAGE , " UTF-8 " ) ;
textdomain ( GETTEXT_PACKAGE ) ;
2008-06-26 08:31:13 +00:00
// gtk_disable_setlocale();
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
gtk_init ( & argc , & argv ) ;
gtk_gl_init ( & argc , & argv ) ;
gdk_gl_init ( & argc , & argv ) ;
// TODO: Find a better place to call this.
gtk_glwidget_create_font ( ) ;
if ( ( ptr = getenv ( " Q3R_LIBGL " ) ) ! = NULL ) {
libgl = ptr ;
}
for ( i = 1 ; i < argc ; i + + )
{
char * param = argv [ i ] ;
if ( param [ 0 ] = = ' - ' & & param [ 1 ] = = ' - ' ) {
param + = 2 ;
if ( ( strcmp ( param , " libgl " ) = = 0 ) & & ( i ! = argc ) ) {
libgl = argv [ i + 1 ] ;
argv [ i ] = argv [ i + 1 ] = NULL ;
i + + ;
}
else if ( strcmp ( param , " builddefs " ) = = 0 ) {
g_bBuildList = true ;
argv [ i ] = NULL ;
}
}
}
for ( i = 1 ; i < argc ; i + + )
{
for ( k = i ; k < argc ; k + + )
if ( argv [ k ] ! = NULL ) {
break ;
}
if ( k > i ) {
k - = i ;
for ( j = i + k ; j < argc ; j + + )
argv [ j - k ] = argv [ j ] ;
argc - = k ;
}
}
g_argc = argc ;
g_argv = argv ;
g_strPluginsDir = " plugins/ " ;
g_strModulesDir = " modules/ " ;
2007-11-04 03:51:54 +00:00
# ifdef _WIN32
2012-03-17 20:01:54 +00:00
// get path to the editor
char * pBuffer = g_strAppPath . GetBufferSetLength ( _MAX_PATH + 1 ) ;
GetModuleFileName ( NULL , pBuffer , _MAX_PATH ) ;
pBuffer [ g_strAppPath . ReverseFind ( ' \\ ' ) + 1 ] = ' \0 ' ;
QE_ConvertDOSToUnixName ( pBuffer , pBuffer ) ;
g_strAppPath . ReleaseBuffer ( ) ;
g_strBitmapsPath = g_strAppPath ;
g_strBitmapsPath + = " bitmaps/ " ;
CGameDialog : : UpdateNetrun ( false ) ; // read the netrun configuration
if ( CGameDialog : : GetNetrun ( ) ) {
// we have to find a per-user g_strTempPath
// this behaves the same as on Linux
g_strTempPath = getenv ( " USERPROFILE " ) ;
if ( ! g_strTempPath . GetLength ( ) ) {
CString msg ;
msg = " Radiant is configured to run from a network installation. \n " ;
msg + = " I couldn't find the environement variable USERPROFILE \n " ;
msg + = " I'm going to use C: \\ RadiantSettings. Please set USERPROFILE \n " ;
gtk_MessageBox ( NULL , msg , " Radiant - Network mode " , MB_OK ) ;
g_strTempPath = " C: \\ " ;
}
g_strTempPath + = " \\ RadiantSettings \\ " ;
Q_mkdir ( g_strTempPath . GetBuffer ( ) , 0755 ) ;
g_strTempPath + = RADIANT_VERSION ;
g_strTempPath + = " \\ " ;
Q_mkdir ( g_strTempPath . GetBuffer ( ) , 0755 ) ;
}
else
{
// use the core path as temp (to save commandlist.txt, and do the .pid files)
g_strTempPath = g_strAppPath ;
}
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
# if defined ( __linux__ ) || defined ( __APPLE__ )
Str home ;
home = g_get_home_dir ( ) ;
AddSlash ( home ) ;
home + = " .radiant/ " ;
Q_mkdir ( home . GetBuffer ( ) , 0775 ) ;
home + = RADIANT_VERSION ;
Q_mkdir ( home . GetBuffer ( ) , 0775 ) ;
g_strTempPath = home . GetBuffer ( ) ;
AddSlash ( g_strTempPath ) ;
loki_initpaths ( argv [ 0 ] ) ;
// NOTE: we build g_strAppPath with a '/' (or '\' on WIN32)
// it's a general convention in Radiant to have the slash at the end of directories
char real [ PATH_MAX ] ;
realpath ( loki_getdatapath ( ) , real ) ;
if ( real [ strlen ( real ) - 1 ] ! = ' / ' ) {
strcat ( real , " / " ) ;
}
g_strAppPath = real ;
// radiant is installed in the parent dir of "tools/"
// NOTE: this is not very easy for debugging
// maybe add options to lookup in several places?
// (for now I had to create symlinks)
g_strBitmapsPath = g_strAppPath ;
g_strBitmapsPath + = " bitmaps/ " ;
// we will set this right after the game selection is done
g_strGameToolsPath = g_strAppPath ;
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
// init the DTD path
g_strDTDPath = g_strAppPath ;
g_strDTDPath + = " dtds/ " ;
/*!
the global prefs loading / game selection dialog might fail for any reason we don ' t know about
we need to catch when it happens , to cleanup the stateful prefs which might be killing it
and to turn on console logging for lookup of the problem
this is the first part of the two step . pid system
*/
g_pidFile = g_strTempPath . GetBuffer ( ) ;
g_pidFile + = " radiant.pid " ;
FILE * pid ;
pid = fopen ( g_pidFile . GetBuffer ( ) , " r " ) ;
if ( pid ! = NULL ) {
fclose ( pid ) ;
CString msg ;
if ( remove ( g_pidFile . GetBuffer ( ) ) = = - 1 ) {
msg = " WARNING: Could not delete " ; msg + = g_pidFile ;
gtk_MessageBox ( NULL , msg , " Radiant " , MB_OK | MB_ICONERROR ) ;
}
// in debug, never prompt to clean registry, turn console logging auto after a failed start
# if !defined( _DEBUG )
msg = " Found the file " ;
msg + = g_pidFile ;
msg + = " . \n This indicates that Radiant failed during the game selection startup last time it was run. \n "
" Choose YES to clean Radiant's registry settings and shut down Radiant. \n "
" WARNING: the global prefs will be lost if you choose YES. " ;
if ( gtk_MessageBox ( NULL , msg , " Radiant - Reset global startup? " , MB_YESNO | MB_ICONQUESTION ) = = IDYES ) {
// remove global prefs and shutdown
g_PrefsDlg . mGamesDialog . Reset ( ) ;
// remove the prefs file (like a full reset of the registry)
//remove (g_PrefsDlg.m_inipath->str);
gtk_MessageBox ( NULL , " Removed global settings, choose OK to close Radiant. " , " Radiant " , MB_OK ) ;
_exit ( - 1 ) ;
}
msg = " Logging console output to " ;
msg + = g_strTempPath ;
msg + = " radiant.log \n Refer to the log if Radiant fails to start again. " ;
gtk_MessageBox ( NULL , msg , " Radiant - Console Log " , MB_OK ) ;
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
// set without saving, the class is not in a coherent state yet
// just do the value change and call to start logging, CGamesDialog will pickup when relevant
g_PrefsDlg . mGamesDialog . m_bLogConsole = true ;
g_PrefsDlg . mGamesDialog . m_bForceLogConsole = true ;
Sys_LogFile ( ) ;
}
// create a primary .pid for global init run
pid = fopen ( g_pidFile . GetBuffer ( ) , " w " ) ;
if ( pid ) {
fclose ( pid ) ;
}
// a safe check to avoid people running broken installations
// (otherwise, they run it, crash it, and blame us for not forcing them hard enough to pay attention while installing)
// make something idiot proof and someone will make better idiots, this may be overkill
// let's leave it disabled in debug mode in any case
2007-11-04 03:51:54 +00:00
# ifndef _DEBUG
2012-03-17 20:01:54 +00:00
//#define CHECK_VERSION
2007-11-04 03:51:54 +00:00
# endif
2008-06-26 07:52:02 +00:00
# ifdef CHECK_VERSION
2012-03-17 20:01:54 +00:00
// locate and open RADIANT_MAJOR and RADIANT_MINOR
qboolean bVerIsGood = true ;
Str ver_file_name ;
ver_file_name = g_strAppPath ;
ver_file_name + = " RADIANT_MAJOR " ;
FILE * ver_file = fopen ( ver_file_name . GetBuffer ( ) , " r " ) ;
if ( ver_file ) {
char buf [ 10 ] ;
int chomp ;
fread ( buf , 1 , 10 , ver_file ) ;
// chomp it (the hard way)
chomp = 0 ;
while ( buf [ chomp ] > = ' 0 ' & & buf [ chomp ] < = ' 9 ' )
chomp + + ;
buf [ chomp ] = ' \0 ' ;
if ( strcmp ( buf , RADIANT_MAJOR_VERSION ) ) {
Sys_Printf ( " ERROR: file RADIANT_MAJOR doesn't match ('%s') \n " , buf ) ;
bVerIsGood = false ;
}
}
else
{
Sys_Printf ( " ERROR: can't find RADIANT_MAJOR in '%s' \n " , ver_file_name . GetBuffer ( ) ) ;
bVerIsGood = false ;
}
ver_file_name = g_strAppPath ;
ver_file_name + = " RADIANT_MINOR " ;
ver_file = fopen ( ver_file_name . GetBuffer ( ) , " r " ) ;
if ( ver_file ) {
char buf [ 10 ] ;
int chomp ;
fread ( buf , 1 , 10 , ver_file ) ;
// chomp it (the hard way)
chomp = 0 ;
while ( buf [ chomp ] > = ' 0 ' & & buf [ chomp ] < = ' 9 ' )
chomp + + ;
buf [ chomp ] = ' \0 ' ;
if ( strcmp ( buf , RADIANT_MINOR_VERSION ) ) {
Sys_Printf ( " ERROR: file RADIANT_MINOR doesn't match ('%s') \n " , buf ) ;
bVerIsGood = false ;
}
}
else
{
Sys_Printf ( " ERROR: can't find RADIANT_MINOR in '%s' \n " , ver_file_name . GetBuffer ( ) ) ;
bVerIsGood = false ;
}
if ( ! bVerIsGood ) {
CString msg ;
msg = " This editor binary ( " RADIANT_VERSION " ) doesn't match what the latest setup has configured in this directory \n " ;
msg + = " Make sure you run the right/latest editor binary you installed \n " ;
msg + = g_strAppPath ; msg + = " \n " ;
msg + = " Check http://www.qeradiant.com/faq/index.cgi?file=219 for more information " ;
gtk_MessageBox ( NULL , msg . GetBuffer ( ) , " Radiant " , MB_OK , " http://www.qeradiant.com/faq/index.cgi?file=219 " ) ;
_exit ( - 1 ) ;
}
2007-11-04 03:51:54 +00:00
# endif
2008-06-26 07:52:02 +00:00
2012-03-17 20:01:54 +00:00
g_qeglobals . disable_ini = false ;
g_PrefsDlg . Init ( ) ;
// close the primary
if ( remove ( g_pidFile . GetBuffer ( ) ) = = - 1 ) {
CString msg ;
msg = " WARNING: Could not delete " ; msg + = g_pidGameFile ;
gtk_MessageBox ( NULL , msg , " Radiant " , MB_OK | MB_ICONERROR ) ;
}
/*!
now the secondary game dependant . pid file
*/
g_pidGameFile = g_PrefsDlg . m_rc_path - > str ;
g_pidGameFile + = " radiant-game.pid " ;
pid = fopen ( g_pidGameFile . GetBuffer ( ) , " r " ) ;
if ( pid ! = NULL ) {
fclose ( pid ) ;
CString msg ;
if ( remove ( g_pidGameFile . GetBuffer ( ) ) = = - 1 ) {
msg = " WARNING: Could not delete " ; msg + = g_pidGameFile ;
gtk_MessageBox ( NULL , msg , " Radiant " , MB_OK | MB_ICONERROR ) ;
}
msg = " Found the file " ;
msg + = g_pidGameFile ;
msg + = " . \n This indicates that Radiant failed to load the last time it was run. \n "
" Choose YES to clean Radiant's registry settings and shut down Radiant. \n "
" WARNING: preferences will be lost if you choose YES. " ;
// in debug, never prompt to clean registry, turn console logging auto after a failed start
# if !defined( _DEBUG )
//bleh
if ( gtk_MessageBox ( NULL , msg , " Radiant - Clean Registry? " , MB_YESNO | MB_ICONQUESTION ) = = IDYES ) {
// remove the game prefs files
remove ( g_PrefsDlg . m_inipath - > str ) ;
char buf [ PATH_MAX ] ;
sprintf ( buf , " %sSavedInfo.bin " , g_PrefsDlg . m_rc_path - > str ) ;
remove ( buf ) ;
// remove the global pref too
g_PrefsDlg . mGamesDialog . Reset ( ) ;
gtk_MessageBox ( NULL , " Cleaned registry settings, choose OK to close Radiant. \n The next time Radiant runs it will use default settings. " , " Radiant " , MB_OK ) ;
_exit ( - 1 ) ;
}
msg = " Logging console output to " ;
msg + = g_strTempPath ;
msg + = " radiant.log \n Refer to the log if Radiant fails to start again. " ;
gtk_MessageBox ( NULL , msg , " Radiant - Console Log " , MB_OK ) ;
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
// force console logging on! (will go in prefs too)
g_PrefsDlg . mGamesDialog . m_bLogConsole = true ;
g_PrefsDlg . mGamesDialog . SavePrefs ( ) ;
Sys_LogFile ( ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
g_PrefsDlg . LoadPrefs ( ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
}
else
{
// create one, will remove right after entering message loop
pid = fopen ( g_pidGameFile . GetBuffer ( ) , " w " ) ;
if ( pid ) {
fclose ( pid ) ;
}
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
g_PrefsDlg . LoadPrefs ( ) ;
2007-11-04 03:51:54 +00:00
# ifndef _DEBUG // I can't be arsed about that prompt in debug mode
2012-03-17 20:01:54 +00:00
// if console logging is on in the prefs, warn about performance hit
if ( g_PrefsDlg . mGamesDialog . m_bLogConsole ) {
if ( gtk_MessageBox ( NULL , " Preferences indicate that console logging is on. This affects performance. \n "
" Turn it off? " , " Radiant " , MB_YESNO | MB_ICONQUESTION ) = = IDYES ) {
g_PrefsDlg . mGamesDialog . m_bLogConsole = false ;
g_PrefsDlg . mGamesDialog . SavePrefs ( ) ;
}
}
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
// toggle console logging if necessary
Sys_LogFile ( ) ;
}
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
// we should search in g_strTempPath, then move over to look at g_strAppPath?
2007-11-04 03:51:54 +00:00
# ifdef _WIN32
2012-03-17 20:01:54 +00:00
// fine tune the look of the app using a gtk rc file
// we try to load an RC file placed in the application directory
// build the full path
Str sRCFile ;
sRCFile = g_strAppPath ;
sRCFile + = " radiantgtkrc " ;
// we load that file with g_new in gtk_rc_parse_file (gtkrc.c), change the '/' into '\\'
pBuffer = ( char * ) sRCFile . GetBuffer ( ) ;
for ( i = 0 ; i < sRCFile . GetLength ( ) ; i + + )
{
if ( pBuffer [ i ] = = ' / ' ) {
pBuffer [ i ] = ' \\ ' ;
}
}
// check the file exists
if ( access ( sRCFile . GetBuffer ( ) , R_OK ) ! = 0 ) {
Sys_Printf ( " RC file %s not found \n " , sRCFile . GetBuffer ( ) ) ;
}
else
{
Sys_Printf ( " Attemping to load RC file %s \n " , sRCFile . GetBuffer ( ) ) ;
gtk_rc_parse ( sRCFile . GetBuffer ( ) ) ;
}
2007-11-04 03:51:54 +00:00
# endif
# ifndef SKIP_SPLASH
2012-03-17 20:01:54 +00:00
create_splash ( ) ;
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
if ( ! QGL_Init ( libgl , " " ) ) {
Sys_FPrintf ( SYS_ERR , " Failed to load OpenGL libraries \n " ) ;
_exit ( 1 ) ;
return 1 ;
}
# if defined ( __linux__ ) || defined ( __APPLE__ )
if ( ( qglXQueryExtension = = NULL ) | | ( qglXQueryExtension ( GDK_DISPLAY ( ) , NULL , NULL ) ! = True ) ) {
Sys_FPrintf ( SYS_ERR , " glXQueryExtension failed \n " ) ;
_exit ( 1 ) ;
return 1 ;
}
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
// redirect Gtk warnings to the console
g_log_set_handler ( " Gdk " , ( GLogLevelFlags ) ( G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG ) , error_redirect , NULL ) ;
g_log_set_handler ( " Gtk " , ( GLogLevelFlags ) ( G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG ) , error_redirect , NULL ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
// spog - creates new filters list for the first time
g_qeglobals . d_savedinfo . filters = NULL ;
g_qeglobals . d_savedinfo . filters = FilterAddBase ( g_qeglobals . d_savedinfo . filters ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
g_pParentWnd = new MainFrame ( ) ;
2007-11-04 03:51:54 +00:00
2012-05-04 08:02:31 +00:00
// If the first parameter is a .map, load that.
if ( g_argc > 1 & & IsMap ( g_argv [ 1 ] ) ) {
Map_LoadFile ( g_argv [ 1 ] ) ;
}
else if ( g_PrefsDlg . m_bLoadLastMap & & g_PrefsDlg . m_strLastMap . GetLength ( ) > 0 ) {
2012-03-17 20:01:54 +00:00
Map_LoadFile ( g_PrefsDlg . m_strLastMap . GetBuffer ( ) ) ;
}
else {
Map_New ( ) ;
}
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
// load up shaders now that we have the map loaded
// eviltypeguy
Texture_ShowStartupShaders ( ) ;
2007-11-04 03:51:54 +00:00
# ifndef SKIP_SPLASH
2012-03-17 20:01:54 +00:00
gdk_window_raise ( splash_screen - > window ) ;
gtk_window_set_transient_for ( GTK_WINDOW ( splash_screen ) , GTK_WINDOW ( g_pParentWnd - > m_pWidget ) ) ;
gtk_timeout_add ( 1000 , try_destroy_splash , NULL ) ;
2007-11-04 03:51:54 +00:00
# endif
2008-06-26 07:52:02 +00:00
2012-03-17 20:01:54 +00:00
g_pParentWnd - > GetSynapseServer ( ) . DumpActiveClients ( ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
//++timo: temporary debug
g_pParentWnd - > DoWatchBSP ( ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
gtk_main ( ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
// close the log file if any
// NOTE: don't save prefs past this point!
g_PrefsDlg . mGamesDialog . m_bLogConsole = false ;
// set the console window to NULL to avoid Sys_Printf crashing
g_qeglobals_gui . d_edit = NULL ;
Sys_LogFile ( ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
// NOTE TTimo not sure what this _exit(0) call is worth
// restricting it to linux build
2007-11-04 03:51:54 +00:00
# ifdef __linux__
2012-03-17 20:01:54 +00:00
_exit ( 0 ) ;
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
return 0 ;
2007-11-04 03:51:54 +00:00
}
// ydnar: quick and dirty fix, just make the buffer bigger
2012-03-17 20:01:54 +00:00
# define BIG_PATH_MAX 4096
2007-11-04 03:51:54 +00:00
// TTimo: decompose the BSP command into several steps so we can monitor them eventually
2012-03-17 20:01:54 +00:00
void QE_ExpandBspString ( char * bspaction , GPtrArray * out_array , char * mapname ) {
const char * in ;
char * out ;
char src [ BIG_PATH_MAX ] ;
char rsh [ BIG_PATH_MAX ] ;
char base [ BIG_PATH_MAX ] ;
strcpy ( src , mapname ) ;
strlwr ( src ) ;
in = strstr ( src , " maps/ " ) ;
if ( ! in ) {
in = strstr ( src , " maps/ " ) ;
}
if ( in ) {
in + = 5 ;
strcpy ( base , in ) ;
out = base ;
while ( * out )
{
if ( * out = = ' \\ ' ) {
* out = ' / ' ;
}
out + + ;
}
}
else
{
ExtractFileName ( mapname , base ) ;
}
// this important step alters the map name to add fs_game
// NOTE: it used to add fs_basepath too
// the fs_basepath addition moved to being in the project file during the bug fixing rush
// but it may not have been the right thing to do
// HACK: halflife compiler tools don't support -fs_game
// HACK: neither does JKII/SoF2/ etc..
// do we use & have fs_game?
if ( g_pGameDescription - > mGameFile ! = " hl.game " & &
* ValueForKey ( g_qeglobals . d_project_entity , " gamename " ) ! = ' \0 ' ) {
// set with fs_game
sprintf ( src , " -fs_game %s \" %s \" " , ValueForKey ( g_qeglobals . d_project_entity , " gamename " ) , mapname ) ;
}
else
{
sprintf ( src , " \" %s \" " , mapname ) ;
}
rsh [ 0 ] = 0 ;
QE_ConvertDOSToUnixName ( src , src ) ;
// initialise the first step
out = new char [ BIG_PATH_MAX ] ; //% PATH_MAX
g_ptr_array_add ( out_array , out ) ;
in = ValueForKey ( g_qeglobals . d_project_entity , bspaction ) ;
while ( * in )
{
if ( in [ 0 ] = = ' ! ' ) {
strcpy ( out , rsh ) ;
out + = strlen ( rsh ) ;
in + + ;
continue ;
}
if ( in [ 0 ] = = ' # ' ) {
char tmp [ 2048 ] ;
// we process these only if monitoring
if ( g_PrefsDlg . m_bWatchBSP ) {
// -connect global option (the only global option so far anyway)
strcpy ( tmp , " -connect 127.0.0.1:39000 " ) ;
strcpy ( out , tmp ) ;
out + = strlen ( tmp ) ;
}
in + + ;
continue ;
}
if ( in [ 0 ] = = ' $ ' ) {
// $ expansion
strcpy ( out , src ) ;
out + = strlen ( src ) ;
in + + ;
continue ;
}
if ( in [ 0 ] = = ' @ ' ) {
* out + + = ' " ' ;
in + + ;
continue ;
}
if ( in [ 0 ] = = ' & ' ) {
if ( in [ 1 ] = = ' & ' ) {
// start a new step
* out = 0 ;
in = in + 2 ;
out = new char [ BIG_PATH_MAX ] ; //% PATH_MAX
g_ptr_array_add ( out_array , out ) ;
}
}
* out + + = * in + + ;
}
* out = 0 ;
2007-11-04 03:51:54 +00:00
}
2012-03-17 20:01:54 +00:00
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 ;
}
2007-11-04 03:51:54 +00:00
}
// save the map, deals with regioning
2012-03-17 20:01:54 +00:00
void SaveWithRegion ( char * name ) {
strcpy ( name , currentmap ) ;
if ( region_active ) {
// temporary cut the region to save regular map
region_active = false ;
Map_SaveFile ( name , false ) ;
region_active = true ;
StripExtension ( name ) ;
strcat ( name , " .reg " ) ;
}
Map_SaveFile ( name , region_active ) ;
2007-11-04 03:51:54 +00:00
}
2012-03-17 20:01:54 +00:00
void RunBsp ( char * command ) {
GPtrArray * sys ;
char batpath [ BIG_PATH_MAX ] ; //% PATH_MAX
char temppath [ BIG_PATH_MAX ] ; //% PATH_MAX
char name [ BIG_PATH_MAX ] ; //% PATH_MAX
char cWork [ BIG_PATH_MAX ] ; //% PATH_MAX
FILE * hFile ;
unsigned int i ;
SetInspectorMode ( W_CONSOLE ) ;
strcpy ( temppath , g_strTempPath . GetBuffer ( ) ) ;
SaveWithRegion ( name ) ;
const char * rsh = ValueForKey ( g_qeglobals . d_project_entity , " rshcmd " ) ;
if ( rsh = = NULL ) {
CString strPath , strFile ;
ExtractPath_and_Filename ( name , strPath , strFile ) ;
AddSlash ( strPath ) ;
strncpy ( cWork , strPath , 1024 ) ;
strcat ( cWork , strFile ) ;
}
else
{
strcpy ( cWork , name ) ;
}
// get the array ready
//++timo TODO: free the array, free the strings ourselves with delete[]
sys = g_ptr_array_new ( ) ;
QE_ExpandBspString ( command , sys , cWork ) ;
if ( g_PrefsDlg . m_bWatchBSP ) {
// grab the file name for engine running
char * bspname = new char [ 1024 ] ;
ExtractFileName ( currentmap , bspname ) ;
StripExtension ( bspname ) ;
g_pParentWnd - > GetWatchBSP ( ) - > DoMonitoringLoop ( sys , bspname ) ;
}
else
{
// write all the steps in a single BAT / .sh file and run it, don't bother monitoring it
CString strSys ;
for ( i = 0 ; i < sys - > len ; i + + )
{
strSys + = ( char * ) g_ptr_array_index ( sys , i ) ;
2007-11-04 03:51:54 +00:00
# ifdef _WIN32 // write temp\junk.txt in win32... NOTE: stops output to shell prompt window
2012-03-17 20:01:54 +00:00
if ( i = = 0 ) {
strSys + = " > " ;
}
else {
strSys + = " >> " ;
}
strSys + = " \" " ;
strSys + = temppath ;
strSys + = " junk.txt \" " ;
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
strSys + = " \n " ;
} ;
# if defined ( __linux__ ) || defined ( __APPLE__ )
// write qe3bsp.sh
sprintf ( batpath , " %sqe3bsp.sh " , temppath ) ;
Sys_Printf ( " Writing the compile script to '%s' \n " , batpath ) ;
Sys_Printf ( " The build output will be saved in '%sjunk.txt' \n " , temppath ) ;
hFile = fopen ( batpath , " w " ) ;
if ( ! hFile ) {
Error ( " Can't write to %s " , batpath ) ;
}
fprintf ( hFile , " #!/bin/sh \n \n " ) ;
2012-03-17 21:32:01 +00:00
fprintf ( hFile , " %s " , strSys . GetBuffer ( ) ) ;
2012-03-17 20:01:54 +00:00
fclose ( hFile ) ;
chmod ( batpath , 0744 ) ;
2007-11-04 03:51:54 +00:00
# endif
# ifdef _WIN32
2012-03-17 20:01:54 +00:00
sprintf ( batpath , " %sqe3bsp.bat " , temppath ) ;
Sys_Printf ( " Writing the compile script to '%s' \n " , batpath ) ;
Sys_Printf ( " The build output will be saved in '%sjunk.txt' \n " , temppath ) ;
hFile = fopen ( batpath , " w " ) ;
if ( ! hFile ) {
Error ( " Can't write to %s " , batpath ) ;
}
2012-03-17 21:32:01 +00:00
fprintf ( hFile , " %s " , strSys . GetBuffer ( ) ) ;
2012-03-17 20:01:54 +00:00
fclose ( hFile ) ;
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
Pointfile_Delete ( ) ;
# if defined ( __linux__ ) || defined ( __APPLE__ )
pid_t pid ;
pid = fork ( ) ;
switch ( pid )
{
case - 1 :
Error ( " CreateProcess failed " ) ;
break ;
case 0 :
execlp ( batpath , batpath , NULL ) ;
printf ( " execlp error ! " ) ;
_exit ( 0 ) ;
break ;
default :
break ;
}
2007-11-04 03:51:54 +00:00
# endif
# ifdef _WIN32
2012-03-17 20:01:54 +00:00
Sys_Printf ( " Running bsp command... \n " ) ;
Sys_Printf ( " \n %s \n " , strSys . GetBuffer ( ) ) ;
2007-11-04 03:51:54 +00:00
2012-03-17 20:01:54 +00:00
WinExec ( batpath , SW_SHOWNORMAL ) ;
2007-11-04 03:51:54 +00:00
# endif
2012-03-17 20:01:54 +00:00
}
2007-11-04 03:51:54 +00:00
# ifdef _DEBUG
2012-03-17 20:01:54 +00:00
// yeah, do it .. but not now right before 1.1-TA-beta release
Sys_Printf ( " TODO: erase GPtrArray \n " ) ;
2007-11-04 03:51:54 +00:00
# endif
}
#if 0
# ifdef _WIN32
2012-03-17 20:01:54 +00:00
int WINAPI 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 ) {
LPVOID lpMsgBuf ;
FormatMessage (
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS ,
NULL ,
GetLastError ( ) ,
MAKELANGID ( LANG_NEUTRAL , SUBLANG_DEFAULT ) , // Default language
( LPTSTR ) & lpMsgBuf ,
0 ,
NULL
) ;
Sys_FPrintf ( SYS_WRN , " GetLastError: %s " , lpMsgBuf ) ;
Error ( " ChoosePixelFormat failed " ) ;
}
if ( ! SetPixelFormat ( hDC , pixelformat , & pfd ) ) {
Error ( " SetPixelFormat failed " ) ;
}
return pixelformat ;
2007-11-04 03:51:54 +00:00
}
# endif
# endif