]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/error.cpp
reorganized about dialog code, added updated 1.5.0 .ico
[xonotic/netradiant.git] / radiant / error.cpp
1 /*
2    Copyright (C) 1999-2007 id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #define UNICODE
23 #include "stdafx.h"
24
25 #if defined ( __linux__ ) || defined ( __APPLE__ )
26 #include <unistd.h>
27 #endif
28
29 /*
30    =================
31    Error
32
33    For abnormal program terminations
34    =================
35  */
36
37 /*!
38    \todo
39    FIXME the prompt wether to do prefs dialog, may not even be possible
40    if the crash happens before the game is loaded
41  */
42
43 void Error( const char *error, ... ){
44         va_list argptr;
45         char text[4096];
46
47         va_start( argptr,error );
48         vsprintf( text, error,argptr );
49         va_end( argptr );
50
51         strcat( text, "\n" );
52
53 #if defined ( __linux__ ) || defined ( __APPLE__ )
54         if ( errno != 0 ) {
55                 strcat( text, "errno: " );
56                 strcat( text, strerror( errno ) );
57                 strcat( text, "\n" );
58         }
59 #endif
60
61 #ifdef _WIN32
62         if ( GetLastError() != 0 ) {
63                 LPVOID lpMsgBuf;
64                 FormatMessage(
65                         FORMAT_MESSAGE_ALLOCATE_BUFFER |
66                         FORMAT_MESSAGE_FROM_SYSTEM |
67                         FORMAT_MESSAGE_IGNORE_INSERTS,
68                         NULL,
69                         GetLastError(),
70                         MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
71                         (LPTSTR) &lpMsgBuf,
72                         0,
73                         NULL
74                         );
75                 strcat( text, "GetLastError: " );
76                 /*
77                    Gtk will only crunch 0<=char<=127
78                    this is a bit hackish, but I didn't find useful functions in win32 API for this
79                  */
80                 TCHAR *scan, *next = (TCHAR*)lpMsgBuf;
81                 do
82                 {
83                         scan = next;
84                         text[strlen( text ) + 1] = '\0';
85                         if ( ( scan[0] >= 0 ) && ( scan[0] <= 127 ) ) {
86                                 text[strlen( text )] = scan[0];
87                         }
88                         else{
89                                 text[strlen( text )] = '?';
90                         }
91                         next = CharNext( scan );
92                 } while ( next != scan );
93                 strcat( text, "\n" );
94                 LocalFree( lpMsgBuf );
95         }
96 #endif
97
98         // we need to have a current context to call glError()
99         if ( g_qeglobals_gui.d_glBase != NULL ) {
100                 // qglGetError .. can record several errors, clears after calling
101                 //++timo TODO: be able to deal with several errors if necessary, for now I'm just warning about pending error messages
102                 // NOTE: forget that, most boards don't seem to follow the OpenGL standard
103                 GLenum iGLError = qglGetError();
104                 if ( iGLError != GL_NO_ERROR ) {
105                         // use our own gluErrorString
106                         strcat( text, "qgluErrorString: " );
107                         strcat( text, (char*)qgluErrorString( iGLError ) );
108                         strcat( text, "\n" );
109                 }
110         }
111
112         strcat( text, "An unrecoverable error has occured.\n"
113                                   "Would you like to edit Preferences before exiting Radiant?" );
114
115         Sys_Printf( text );
116
117         if ( gtk_MessageBox( NULL, text, "Error", MB_YESNO ) == IDYES ) {
118                 Sys_Printf( "Doing prefs..\n" );
119                 g_PrefsDlg.LoadPrefs();
120                 g_PrefsDlg.DoModal();
121         }
122
123         QGL_Shutdown();
124
125         g_PrefsDlg.Destroy();
126         g_dlgSurface.Destroy();
127         g_dlgFind.Destroy();
128
129         // force close logging if necessary
130         g_PrefsDlg.mGamesDialog.m_bLogConsole = false;
131         Sys_LogFile();
132
133         _exit( 1 );
134 }
135
136 void WINAPI Error( char *error, ... ){
137         va_list argptr;
138         char text[1024];
139
140         va_start( argptr,error );
141         vsprintf( text, error,argptr );
142         va_end( argptr );
143
144         Error( (const char *)text );
145 }