You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

307 lines
6.3 KiB

#include "diablo.h"
#include "../3rdParty/Storm/Source/storm.h"
DEVILUTION_BEGIN_NAMESPACE
char sz_error_buf[256];
BOOL terminating;
int cleanup_thread_id;
// delete overloads the delete operator.
//void operator delete(void *ptr)
//{
// if (ptr != NULL) {
// SMemFree(ptr, "delete", -1, 0);
// }
//}
#ifdef _DEBUG
LONG __stdcall BreakFilter(PEXCEPTION_POINTERS pExc)
{
if (pExc->ExceptionRecord == NULL) {
return 0;
}
if (pExc->ExceptionRecord->ExceptionCode != EXCEPTION_BREAKPOINT) {
return 0;
}
if (((BYTE *)pExc->ContextRecord->Eip)[0] == 0xCC) { // int 3
pExc->ContextRecord->Eip++;
}
return -1;
}
#endif
char *GetErrorStr(DWORD error_code)
{
DWORD upper_code;
int size;
char *chr;
upper_code = (error_code >> 16) & 0x1FFF;
if (upper_code == 0x0878) {
TraceErrorDS(error_code, sz_error_buf, 256);
} else if (upper_code == 0x0876) {
TraceErrorDD(error_code, sz_error_buf, 256);
} else if (!SErrGetErrorStr(error_code, sz_error_buf, 256)
&& !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, 0x400, sz_error_buf, 0x100, NULL)) {
wsprintf(sz_error_buf, "unknown error 0x%08x", error_code);
}
size = strlen(sz_error_buf);
chr = &sz_error_buf[size - 1];
while (size > 0) {
size--;
chr--;
if (*chr != '\r' && *chr != '\n')
break;
*chr = 0x00;
}
return sz_error_buf;
}
void TraceErrorDD(HRESULT hError, char *pszBuffer, DWORD dwMaxChars)
{
const char *szError;
switch (hError) {
case DD_OK:
szError = "DD_OK";
break;
case DDERR_INVALIDOBJECT:
szError = "DDERR_INVALIDOBJECT";
break;
case DDERR_OUTOFMEMORY:
szError = "DDERR_OUTOFMEMORY";
break;
default: {
const char szUnknown[] = "DDERR unknown 0x%x";
/// ASSERT: assert(dwMaxChars >= sizeof(szUnknown) + 10);
sprintf(pszBuffer, szUnknown, hError);
return;
}
}
strncpy(pszBuffer, szError, dwMaxChars);
}
void TraceErrorDS(HRESULT hError, char *pszBuffer, DWORD dwMaxChars)
{
const char *szError;
switch (hError) {
case DS_OK:
szError = "DS_OK";
break;
default: {
const char szUnknown[] = "DSERR unknown 0x%x";
/// ASSERT: assert(dwMaxChars >= sizeof(szUnknown) + 10);
sprintf(pszBuffer, szUnknown, hError);
return;
}
}
strncpy(pszBuffer, szError, dwMaxChars);
}
char *TraceLastError()
{
return GetErrorStr(GetLastError());
}
void __cdecl app_fatal(const char *pszFmt, ...)
{
va_list va;
va_start(va, pszFmt);
FreeDlg();
if (pszFmt)
MsgBox(pszFmt, va);
va_end(va);
init_cleanup(FALSE);
exit(1);
}
void MsgBox(const char *pszFmt, va_list va)
{
char Text[256];
wvsprintf(Text, pszFmt, va);
if (ghMainWnd)
SetWindowPos(ghMainWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
MessageBox(ghMainWnd, Text, "ERROR", MB_TASKMODAL | MB_ICONHAND);
}
void FreeDlg()
{
// Diablo calls this method before calling the dialog, which wouldn't work
// for DevilutionX.
puts("FreeDlg(): skipping");
return;
if (terminating && cleanup_thread_id != GetCurrentThreadId())
Sleep(20000);
terminating = TRUE;
cleanup_thread_id = GetCurrentThreadId();
dx_cleanup();
if (gbMaxPlayers > 1) {
if (SNetLeaveGame(3))
Sleep(2000);
}
SNetDestroy();
ShowCursor(TRUE);
}
void __cdecl DrawDlg(char *pszFmt, ...)
{
char text[256];
va_list arglist;
va_start(arglist, pszFmt);
wvsprintf(text, pszFmt, arglist);
va_end(arglist);
SDrawMessageBox(text, "Diablo", MB_TASKMODAL | MB_ICONEXCLAMATION);
}
#ifdef _DEBUG
void assert_fail(int nLineNo, const char *pszFile, const char *pszFail)
{
app_fatal("assertion failed (%d:%s)\n%s", nLineNo, pszFile, pszFail);
}
#endif
void DDErrMsg(DWORD error_code, int log_line_nr, char *log_file_path)
{
char *msg;
if (error_code) {
msg = GetErrorStr(error_code);
app_fatal("Direct draw error (%s:%d)\n%s", log_file_path, log_line_nr, msg);
}
}
void DSErrMsg(DWORD error_code, int log_line_nr, char *log_file_path)
{
char *msg;
if (error_code) {
msg = GetErrorStr(error_code);
app_fatal("Direct sound error (%s:%d)\n%s", log_file_path, log_line_nr, msg);
}
}
void center_window(HWND hDlg)
{
LONG w, h;
int screenW, screenH;
struct tagRECT Rect;
HDC hdc;
GetWindowRect(hDlg, &Rect);
w = Rect.right - Rect.left;
h = Rect.bottom - Rect.top;
screenW = GetDeviceCaps(hdc, HORZRES);
screenH = GetDeviceCaps(hdc, VERTRES);
if (!SetWindowPos(hDlg, HWND_TOP, (screenW - w) / 2, (screenH - h) / 2, 0, 0, SWP_NOZORDER | SWP_NOSIZE)) {
app_fatal("center_window: %s", TraceLastError());
}
}
void ErrDlg(int template_id, DWORD error_code, char *log_file_path, int log_line_nr)
{
char *size;
LPARAM dwInitParam[128];
FreeDlg();
size = strrchr(log_file_path, '\\');
if (size)
log_file_path = size + 1;
wsprintf((LPSTR)dwInitParam, "%s\nat: %s line %d", GetErrorStr(error_code), log_file_path, log_line_nr);
if (DialogBoxParam(ghInst, MAKEINTRESOURCE(template_id), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)dwInitParam) == -1)
app_fatal("ErrDlg: %d", template_id);
app_fatal(NULL);
}
BOOL __stdcall FuncDlg(HWND hDlg, UINT uMsg, WPARAM wParam, char *text)
{
switch (uMsg) {
case WM_INITDIALOG:
TextDlg(hDlg, text);
break;
case WM_COMMAND:
if ((WORD)wParam == 1) {
EndDialog(hDlg, 1);
} else if ((WORD)wParam == 2) {
EndDialog(hDlg, 0);
}
break;
default:
return FALSE;
}
return TRUE;
}
void TextDlg(HWND hDlg, char *text)
{
center_window(hDlg);
if (text)
SetDlgItemText(hDlg, 1000, text);
}
void FileErrDlg(const char *error)
{
FreeDlg();
if (!error)
error = "";
if (DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG3), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)error) == -1)
app_fatal("FileErrDlg");
app_fatal(NULL);
}
BOOL InsertCDDlg()
{
int nResult;
ShowCursor(TRUE);
nResult = DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG9), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM) "");
if (nResult == -1)
app_fatal("InsertCDDlg");
ShowCursor(FALSE);
return nResult == 1;
}
void DirErrorDlg(char *error)
{
FreeDlg();
if (DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG11), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)error) == -1)
app_fatal("DirErrorDlg");
app_fatal(NULL);
}
DEVILUTION_END_NAMESPACE