bool Alert(const char* fmt, VARG_PARAM dummy, ...) { GtkWidget *dialog; string msg; va_list list; va_start(list, dummy); vssprintf(msg, fmt, list); va_end(list); // fixme: using NULL terminators on std::string might work, but are technically "incorrect." // This should use one of the std::string trimming functions instead. if (msg[msg.length()-1] == '\n') msg[msg.length()-1] = 0; if (!UseGui) { Console::Error(msg.c_str()); return false; } dialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, msg.c_str()); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return false; }
int ssprintf(char *buf, int bufsz, const char *fmt, ...) { va_list ap; va_start(ap, fmt); bufsz = vssprintf(buf, bufsz, fmt, ap); va_end(ap); return bufsz; }
void RageLog::ProfileStop( const CString &name, const char *fmt, ...) { CString s; va_list va; va_start(va, fmt); s += vssprintf( fmt, va ); va_end(va); map<CString, ProfilingTimer*>::iterator i = TimeMap.find(name); if ( i == TimeMap.end() ) { // category not found, error LOG->Warn( "Called ProfileStop() with unknown category %s", name.c_str() ); return; } ProfilingTimer *t = i->second; t->Stop(); double TimeSinceInNS = t->GetElapsedSoFarInS(); if( LOG != NULL ) LOG->Debug( "[%6.4f] %s", TimeSinceInNS, s.c_str() ); else fprintf( stderr, "[%6.4f] %s", TimeSinceInNS, s.c_str() ); SAFE_DELETE(t); }
static RString ov_ssprintf( int err, const char *fmt, ...) { va_list va; va_start( va, fmt ); RString s = vssprintf( fmt, va ); va_end( va ); RString errstr; switch( err ) { /* XXX: In the case of OV_EREAD, can we snoop at errno? */ case OV_EREAD: errstr = "Read error"; break; case OV_EFAULT: errstr = "Internal error"; break; case OV_EIMPL: errstr = "Feature not implemented"; break; case OV_EINVAL: errstr = "Invalid argument"; break; case OV_ENOTVORBIS: errstr = "Not Vorbis data"; break; case OV_EBADHEADER: errstr = "Invalid Vorbis bitstream header"; break; case OV_EVERSION: errstr = "Vorbis version mismatch"; break; case OV_ENOTAUDIO: errstr = "OV_ENOTAUDIO"; break; case OV_EBADPACKET: errstr = "OV_EBADPACKET"; break; case OV_EBADLINK: errstr = "Link corrupted"; break; case OV_ENOSEEK: errstr = "Stream is not seekable"; break; default: errstr = ssprintf( "unknown error %i", err ); break; } return s + ssprintf( " (%s)", errstr.c_str() ); }
/*! Formated output to error console */ void warn ( char *format, ... ) { char text[CONSOLE_MAXLEN]; vssprintf ( text, CONSOLE_MAXLEN, &format ); u_stderr->print ( CONSOLE_USER, text ); }
/*! Formated output to console (lightweight version of 'printf') */ int printf ( char *format, ... ) { char text[CONSOLE_MAXLEN]; vssprintf ( text, CONSOLE_MAXLEN, &format ); return u_stdout->print ( CONSOLE_USER, text ); }
/* Use this for more important information; it'll always be included * in crash dumps. */ void RageLog::Info( const char *fmt, ...) { va_list va; va_start(va, fmt); CString sBuff = vssprintf( fmt, va ); va_end(va); Write(WRITE_TO_INFO, sBuff); }
void RageLog::Trace( const char *fmt, ... ) { va_list va; va_start( va, fmt ); RString sBuff = vssprintf( fmt, va ); va_end( va ); Write( 0, sBuff ); }
void RageLog::Warn( const char *fmt, ... ) { va_list va; va_start( va, fmt ); RString sBuff = vssprintf( fmt, va ); va_end( va ); Write( WRITE_TO_INFO | WRITE_LOUD, sBuff ); }
/* Acts like Trace(), but displays even with ShowLogOutput off. */ void RageLog::Debug( const char *fmt, ...) { va_list va; va_start(va, fmt); CString sBuff = vssprintf( fmt, va ); va_end(va); Write( WRITE_TO_STDOUT, sBuff ); }
void RageLog::Time(const char *fmt, ...) { va_list va; va_start(va, fmt); RString sBuff = vssprintf(fmt, va); va_end(va); Write(WRITE_TO_TIME, sBuff); }
void zlog(int level, const struct zone *zone, const char *fmt, ...) { va_list ap; char buf[128]; char name[DNS_MAXDOMAIN+1]; va_start(ap, fmt); vssprintf(buf, sizeof(buf), fmt, ap); va_end(ap); dns_dntop(zone->z_dn, name, sizeof(name)); dslog(level, 0, "zone %.70s: %s", name, buf); }
void RageLog::MapLog( const RString &key, const char *fmt, ... ) { RString s; va_list va; va_start( va, fmt ); s += vssprintf( fmt, va ); va_end( va ); LogMaps[key] = s; UpdateMappedLog(); }
static RString wo_ssprintf( MMRESULT err, const char *fmt, ...) { char buf[MAXERRORLENGTH]; waveOutGetErrorText(err, buf, MAXERRORLENGTH); va_list va; va_start(va, fmt); RString s = vssprintf( fmt, va ); va_end(va); return s += ssprintf( "(%s)", buf ); }
void RageLog::UserLog( const RString &sType, const RString &sElement, const char *fmt, ... ) { va_list va; va_start( va, fmt ); RString sBuf = vssprintf( fmt, va ); va_end( va ); if( !sType.empty() ) sBuf = ssprintf( "%s \"%s\" %s", sType.c_str(), sElement.c_str(), sBuf.c_str() ); Write( WRITE_TO_USER_LOG, sBuf ); }
void _realObjTrace(int id, const char *function, const char *str, ...) { char vaBuffer[MAX_LEN_LOG_LINE]; char outputBuffer[MAX_LEN_LOG_LINE]; va_list ap; va_start(ap, str); vssprintf(vaBuffer, str, ap); va_end(ap); ssprintf(outputBuffer, "[%6d]: [%s] %s", id, function, vaBuffer); printToDebugCallbacks(outputBuffer); }
void Alsa9Buf::ErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...) { va_list va; va_start( va, fmt ); RString str = vssprintf(fmt, va); va_end( va ); if( err ) str += ssprintf( " (%s)", dsnd_strerror(err) ); /* Annoying: these happen both normally (eg. "out of memory" when allocating too many PCM * slots) and abnormally, and there's no way to tell which is which. I don't want to * pollute the warning output. */ LOG->Trace( "ALSA error: %s:%i %s: %s", file, line, function, str.c_str() ); }
CString hr_ssprintf( int hr, const char *fmt, ...) { va_list va; va_start(va, fmt); CString s = vssprintf( fmt, va ); va_end(va); #ifdef _XBOX char szError[1024] = ""; D3DXGetErrorString( hr, szError, sizeof(szError) ); #else const char *szError = DXGetErrorString8( hr ); #endif return s + ssprintf( " (%s)", szError ); }
void RageLog::ProfileStart(const CString &name, const char *fmt, ...) { CString s; va_list va; va_start(va, fmt); s += vssprintf( fmt, va ); va_end(va); TimeMap[name] = new ProfilingTimer(); TimeMap[name]->Start(); if ( LOG != NULL ) LOG->Debug(s); else fprintf( stderr, s ); }
void error(int errnum, const char *fmt, ...) { char buf[256]; int l, pl; va_list ap; l = pl = ssprintf(buf, sizeof(buf), "%.30s: ", progname); va_start(ap, fmt); l += vssprintf(buf + l, sizeof(buf) - l, fmt, ap); if (errnum) l += ssprintf(buf + l, sizeof(buf) - l, ": %.50s", strerror(errnum)); if (logto & LOGTO_SYSLOG) { fmt = buf + pl; syslog(LOG_ERR, strchr(fmt, '%') ? "%s" : fmt, fmt); } buf[l++] = '\n'; write(2, buf, l); _exit(1); }
static RString averr_ssprintf( int err, const char *fmt, ... ) { ASSERT( err < 0 ); va_list va; va_start(va, fmt); RString s = vssprintf( fmt, va ); va_end(va); size_t errbuf_size = 512; char* errbuf = new char[errbuf_size]; avcodec::av_strerror(err, errbuf, errbuf_size); RString Error = ssprintf("%i: %s", err, errbuf); delete[] errbuf; return s + " (" + Error + ")"; }
void dsloaded(struct dsctx *dsc, const char *fmt, ...) { va_list ap; if (dsc->dsc_warns > MAXWARN) dslog(LOG_WARNING, dsc, "%d more warnings suppressed", dsc->dsc_warns - MAXWARN); va_start(ap, fmt); if (dsc->dsc_subset) vdslog(LOG_INFO, dsc, fmt, ap); else { struct tm *tm = gmtime(&dsc->dsc_ds->ds_stamp); char buf[128]; vssprintf(buf, sizeof(buf), fmt, ap); dslog(LOG_INFO, dsc, "%04d%02d%02d %02d%02d%02d: %s", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, buf); } va_end(ap); }
static void vdslog(int level, struct dsctx *dsc, const char *fmt, va_list ap) { char buf[1024]; int pl, l; if ((logto & LOGTO_STDOUT) || (level <= LOG_WARNING && (logto & LOGTO_STDERR))) l = pl = ssprintf(buf, sizeof(buf), "%.30s: ", progname); else if (logto & LOGTO_SYSLOG) l = pl = 0; else return; if (dsc) { if (dsc->dsc_fname) { l += ssprintf(buf + l, sizeof(buf) - l, "file %.60s", dsc->dsc_fname); l += ssprintf(buf + l, sizeof(buf) - l, dsc->dsc_lineno ? "(%d): " : ": ", dsc->dsc_lineno); } else { l += ssprintf(buf + l, sizeof(buf) - l, "%s:%.60s:", dsc->dsc_ds->ds_type->dst_name, dsc->dsc_ds->ds_spec); if (dsc->dsc_subset) { l += ssprintf(buf + l, sizeof(buf) - l, "%s:", dsc->dsc_subset->ds_type->dst_name); if (dsc->dsc_subset->ds_spec) l += ssprintf(buf + l, sizeof(buf) - l, "%s:", dsc->dsc_subset->ds_spec); } l += ssprintf(buf + l, sizeof(buf) - l, " "); } } l += vssprintf(buf + l, sizeof(buf) - l, fmt, ap); if (logto & LOGTO_SYSLOG) { fmt = buf + pl; syslog(level, strchr(fmt, '%') ? "%s" : fmt, fmt); } buf[l++] = '\n'; if (level <= LOG_WARNING) { if (logto & (LOGTO_STDERR|LOGTO_STDOUT)) write(2, buf, l); } else if (logto & LOGTO_STDOUT) write(1, buf, l); }
RString werr_ssprintf( int err, const char *fmt, ... ) { char buf[1024] = ""; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, err, 0, buf, sizeof(buf), NULL); // Why is FormatMessage returning text ending with \r\n? (who? -aj) // Perhaps it's because you're on Windows, where newlines are \r\n. -aj RString text = buf; text.Replace( "\n", "" ); text.Replace( "\r", " " ); // foo\r\nbar -> foo bar TrimRight( text ); // "foo\r\n" -> "foo" va_list va; va_start(va, fmt); RString s = vssprintf( fmt, va ); va_end(va); return s += ssprintf( " (%s)", text.c_str() ); }
CString werr_ssprintf( int err, const char *fmt, ...) { char buf[1024] = ""; #ifndef _XBOX FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, err, 0, buf, sizeof(buf), NULL); #endif /* Why is FormatMessage returning text ending with \r\n? */ CString text = buf; text.Replace( "\n", "" ); text.Replace( "\r", " " ); /* foo\r\nbar -> foo bar */ TrimRight( text ); /* "foo\r\n" -> "foo" */ va_list va; va_start(va, fmt); CString s = vssprintf( fmt, va ); va_end(va); return s += ssprintf( " (%s)", text.c_str() ); }
static CString averr_ssprintf( int err, const char *fmt, ... ) { ASSERT( err < 0 ); va_list va; va_start(va, fmt); CString s = vssprintf( fmt, va ); va_end(va); CString Error; switch( err ) { case AVERROR_IO: Error = "I/O error"; break; case AVERROR_NUMEXPECTED: Error = "number syntax expected in filename"; break; case AVERROR_INVALIDDATA: Error = "invalid data found"; break; case AVERROR_NOMEM: Error = "not enough memory"; break; case AVERROR_NOFMT: Error = "unknown format"; break; default: Error = ssprintf( "unknown error %i", err ); break; } return s + " (" + Error + ")"; }
string StringUtil::ssprintf(const char *fmt, ...) { va_list va; va_start(va, fmt); return vssprintf(fmt, va); }
void _debug(int line, code_part part, const char *function, const char *str, ...) { va_list ap; static char outputBuffer[MAX_LEN_LOG_LINE]; static unsigned int repeated = 0; /* times current message repeated */ static unsigned int next = 2; /* next total to print update */ static unsigned int prev = 0; /* total on last update */ va_start(ap, str); vssprintf(outputBuffer, str, ap); va_end(ap); if (part == LOG_WARNING) { std::pair<std::map<std::string, int>::iterator, bool> ret; ret = warning_list.insert(std::pair<std::string, int>(std::string(function) + "-" + std::string(outputBuffer), line)); if (ret.second) { ssprintf(inputBuffer[useInputBuffer1 ? 1 : 0], "[%s:%d] %s (**Further warnings of this type are suppressed.)", function, line, outputBuffer); } else { return; // don't bother adding any more } } else { ssprintf(inputBuffer[useInputBuffer1 ? 1 : 0], "[%s:%d] %s", function, line, outputBuffer); } if (sstrcmp(inputBuffer[0], inputBuffer[1]) == 0) { // Received again the same line repeated++; if (repeated == next) { if (repeated > 2) { ssprintf(outputBuffer, "last message repeated %u times (total %u repeats)", repeated - prev, repeated); } else { ssprintf(outputBuffer, "last message repeated %u times", repeated - prev); } printToDebugCallbacks(outputBuffer); prev = repeated; next *= 2; } } else { // Received another line, cleanup the old if (repeated > 0 && repeated != prev && repeated != 1) { /* just repeat the previous message when only one repeat occurred */ if (repeated > 2) { ssprintf(outputBuffer, "last message repeated %u times (total %u repeats)", repeated - prev, repeated); } else { ssprintf(outputBuffer, "last message repeated %u times", repeated - prev); } printToDebugCallbacks(outputBuffer); } repeated = 0; next = 2; prev = 0; } if (!repeated) { time_t rawtime; struct tm *timeinfo; char ourtime[15]; //HH:MM:SS time(&rawtime); timeinfo = localtime(&rawtime); strftime(ourtime, 15, "%I:%M:%S", timeinfo); // Assemble the outputBuffer: ssprintf(outputBuffer, "%-8s|%s: %s", code_part_names[part], ourtime, useInputBuffer1 ? inputBuffer[1] : inputBuffer[0]); printToDebugCallbacks(outputBuffer); if (part == LOG_ERROR) { // used to signal user that there was a error condition, and to check the logs. sstrcpy(errorStore, useInputBuffer1 ? inputBuffer[1] : inputBuffer[0]); errorWaiting = true; } // Throw up a dialog box for users since most don't have a clue to check the dump file for information. Use for (duh) Fatal errors, that force us to terminate the game. if (part == LOG_FATAL) { if (wzIsFullscreen()) { wzToggleFullscreen(); } #if defined(WZ_OS_WIN) char wbuf[512]; ssprintf(wbuf, "%s\n\nPlease check the file (%s) in your configuration directory for more details. \ \nDo not forget to upload the %s file, WZdebuginfo.txt and the warzone2100.rpt files in your bug reports at http://developer.wz2100.net/newticket!", useInputBuffer1 ? inputBuffer[1] : inputBuffer[0], WZ_DBGFile, WZ_DBGFile); MessageBoxA(NULL, wbuf, "Warzone has terminated unexpectedly", MB_OK | MB_ICONERROR); #elif defined(WZ_OS_MAC) int clickedIndex = \ cocoaShowAlert("Warzone has quit unexpectedly.", "Please check your logs and attach them along with a bug report. Thanks!", 2, "Show Log Files & Open Bug Reporter", "Ignore", NULL); if (clickedIndex == 0) { cocoaOpenURL("http://developer.wz2100.net/newticket"); if (WZDebugfilename == NULL) { cocoaShowAlert("Unable to open debug log.", "The debug log subsystem has not yet been initialised.", 2, "Continue", NULL); } else { cocoaSelectFileInFinder(WZDebugfilename); } cocoaOpenUserCrashReportFolder(); } #else const char *popupBuf = useInputBuffer1 ? inputBuffer[1] : inputBuffer[0]; wzFatalDialog(popupBuf); #endif } // Throw up a dialog box for windows users since most don't have a clue to check the stderr.txt file for information // This is a popup dialog used for times when the error isn't fatal, but we still need to notify user what is going on. if (part == LOG_POPUP) { #if defined(WZ_OS_WIN) char wbuf[512]; ssprintf(wbuf, "A non fatal error has occurred.\n\n%s\n\n", useInputBuffer1 ? inputBuffer[1] : inputBuffer[0]); MessageBoxA(NULL, wbuf, "Warzone has detected a problem.", MB_OK | MB_ICONINFORMATION); #elif defined(WZ_OS_MAC) cocoaShowAlert("Warzone has detected a problem.", inputBuffer[useInputBuffer1 ? 1 : 0], 0, "OK", NULL); #endif } }
void _debug( code_part part, const char *function, const char *str, ... ) { va_list ap; static char outputBuffer[MAX_LEN_LOG_LINE]; static unsigned int repeated = 0; /* times current message repeated */ static unsigned int next = 2; /* next total to print update */ static unsigned int prev = 0; /* total on last update */ va_start(ap, str); vssprintf(outputBuffer, str, ap); va_end(ap); ssprintf(inputBuffer[useInputBuffer1 ? 1 : 0], "[%s] %s", function, outputBuffer); if (sstrcmp(inputBuffer[0], inputBuffer[1]) == 0) { // Received again the same line repeated++; if (repeated == next) { if (repeated > 2) { ssprintf(outputBuffer, "last message repeated %u times (total %u repeats)", repeated - prev, repeated); } else { ssprintf(outputBuffer, "last message repeated %u times", repeated - prev); } printToDebugCallbacks(outputBuffer); prev = repeated; next *= 2; } } else { // Received another line, cleanup the old if (repeated > 0 && repeated != prev && repeated != 1) { /* just repeat the previous message when only one repeat occurred */ if (repeated > 2) { ssprintf(outputBuffer, "last message repeated %u times (total %u repeats)", repeated - prev, repeated); } else { ssprintf(outputBuffer, "last message repeated %u times", repeated - prev); } printToDebugCallbacks(outputBuffer); } repeated = 0; next = 2; prev = 0; } if (!repeated) { time_t rawtime; struct tm * timeinfo; char ourtime[15]; //HH:MM:SS time ( &rawtime ); timeinfo = localtime ( &rawtime ); strftime (ourtime,15,"%I:%M:%S",timeinfo); // Assemble the outputBuffer: ssprintf(outputBuffer, "%-8s|%s: %s", code_part_names[part], ourtime, useInputBuffer1 ? inputBuffer[1] : inputBuffer[0]); printToDebugCallbacks(outputBuffer); if (part == LOG_ERROR) { // used to signal user that there was a error condition, and to check the logs. NotifyUserOfError(useInputBuffer1 ? inputBuffer[1] : inputBuffer[0]); } // Throw up a dialog box for users since most don't have a clue to check the dump file for information. Use for (duh) Fatal errors, that force us to terminate the game. if (part == LOG_FATAL) { #if defined(WZ_OS_WIN) char wbuf[512]; ssprintf(wbuf, "%s\n\nPlease check your stderr.txt file in the same directory as the program file for more details. \ \nDo not forget to upload both the stderr.txt file and the warzone2100.rpt file in your bug reports!", useInputBuffer1 ? inputBuffer[1] : inputBuffer[0]); MessageBoxA( NULL, wbuf, "Warzone has terminated unexpectedly", MB_OK|MB_ICONERROR); #elif defined(WZ_OS_MAC) cocoaShowAlert("Warzone has terminated unexpectedly.", "Please check your logs for more details." "\n\nRun Console.app, search for \"wz2100\", and copy that to a file." "\n\nIf you are on 10.4 (Tiger) or 10.5 (Leopard) the crash report" " is in ~/Library/Logs/CrashReporter." " If you are on 10.6 (Snow Leopard), it is in" "\n~/Library/Logs/DiagnosticReports." "\n\nDo not forget to upload and attach those to a bug report at http://developer.wz2100.net/newticket" "\nThanks!", 2); #else const char* popupBuf = useInputBuffer1 ? inputBuffer[1] : inputBuffer[0]; wzFatalDialog(popupBuf); #endif }
void _debug( code_part part, const char *function, const char *str, ... ) { va_list ap; static char outputBuffer[MAX_LEN_LOG_LINE]; static unsigned int repeated = 0; /* times current message repeated */ static unsigned int next = 2; /* next total to print update */ static unsigned int prev = 0; /* total on last update */ va_start(ap, str); vssprintf(outputBuffer, str, ap); va_end(ap); ssprintf(inputBuffer[useInputBuffer1 ? 1 : 0], "[%s] %s", function, outputBuffer); if (sstrcmp(inputBuffer[0], inputBuffer[1]) == 0) { // Received again the same line repeated++; if (repeated == next) { if (repeated > 2) { ssprintf(outputBuffer, "last message repeated %u times (total %u repeats)", repeated - prev, repeated); } else { ssprintf(outputBuffer, "last message repeated %u times", repeated - prev); } printToDebugCallbacks(outputBuffer); prev = repeated; next *= 2; } } else { // Received another line, cleanup the old if (repeated > 0 && repeated != prev && repeated != 1) { /* just repeat the previous message when only one repeat occurred */ if (repeated > 2) { ssprintf(outputBuffer, "last message repeated %u times (total %u repeats)", repeated - prev, repeated); } else { ssprintf(outputBuffer, "last message repeated %u times", repeated - prev); } printToDebugCallbacks(outputBuffer); } repeated = 0; next = 2; prev = 0; } if (!repeated) { time_t rawtime; struct tm * timeinfo; char ourtime[15]; //HH:MM:SS time ( &rawtime ); timeinfo = localtime ( &rawtime ); strftime (ourtime,15,"%I:%M:%S",timeinfo); // Assemble the outputBuffer: ssprintf(outputBuffer, "%-8s|%s: %s", code_part_names[part], ourtime, useInputBuffer1 ? inputBuffer[1] : inputBuffer[0]); printToDebugCallbacks(outputBuffer); // Throw up a dialog box for windows users since most don't have a clue to check the stderr.txt file for information // Use for (duh) Fatal errors, that force us to terminate the game. if (part == LOG_FATAL) { #if defined(WZ_OS_WIN) char wbuf[512]; ssprintf(wbuf, "%s\n\nPlease check your stderr.txt file in the same directory as the program file for more details. \ \nDo not forget to upload both the stderr.txt file and the warzone2100.rpt file in your bug reports!", useInputBuffer1 ? inputBuffer[1] : inputBuffer[0]); MessageBoxA( NULL, wbuf, "Warzone has terminated unexpectedly", MB_OK|MB_ICONERROR); #elif defined(WZ_OS_MAC32) // FIXME: Needs to be made compatible with 64bit AlertStdCFStringAlertParamRec param; DialogRef dialog; OSStatus err; DialogItemIndex itemHit; char aBuffer[512]; GetStandardAlertDefaultParams( ¶m, kStdCFStringAlertVersionOne ); param.movable = true; ssprintf(aBuffer, "%s\n\nPlease check your logs for more details.\n", useInputBuffer1 ? inputBuffer[1] : inputBuffer[0] ); err = CreateStandardAlert( kAlertStopAlert, CFStringCreateWithCString( nil, aBuffer, kCFStringEncodingMacRoman), CFSTR( "Run Console.app and search for wz2100 and copy that to a file.\ \n\nFor the Crash report on 10.4/10.5 check\ \n~/Library/Logs/CrashReporter,\ \non 10.6 check ~/Library/Logs/DiagnosticReports\ \nDo not forget to upload and attach those to a bug report at http://developer.wz2100.net/newticket\ \nThanks!" ), ¶m, &dialog ); SetWindowTitleWithCFString( GetDialogWindow( dialog ), CFSTR( "Warzone has terminated unexpectedly" ) ); RunStandardAlert( dialog, NULL, &itemHit ); #endif }