scummvm/common/debug.cpp
2008-07-30 10:40:44 +00:00

242 lines
5.3 KiB
C++

/* Residual - Virtual machine to run LucasArts' 3D adventure games
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
* $URL$
* $Id$
*
*/
#include "common/sys.h"
#include "common/debug.h"
#include "common/str.h"
#include "engine/backend/platform/driver.h"
Common::String tag2string(uint32 tag) {
char str[5];
str[0] = (char)(tag >> 24);
str[1] = (char)(tag >> 16);
str[2] = (char)(tag >> 8);
str[3] = (char)tag;
str[4] = '\0';
return Common::String(str);
}
void hexdump(const byte *data, int len, int bytesPerLine) {
assert(1 <= bytesPerLine && bytesPerLine <= 32);
int i;
byte c;
int offset = 0;
while (len >= bytesPerLine) {
printf("%06x: ", offset);
for (i = 0; i < bytesPerLine; i++) {
printf("%02x ", data[i]);
if (i % 4 == 3)
printf(" ");
}
printf(" |");
for (i = 0; i < bytesPerLine; i++) {
c = data[i];
if (c < 32 || c >= 127)
c = '.';
printf("%c", c);
}
printf("|\n");
data += bytesPerLine;
len -= bytesPerLine;
offset += bytesPerLine;
}
if (len <= 0)
return;
printf("%06x: ", offset);
for (i = 0; i < bytesPerLine; i++) {
if (i < len)
printf("%02x ", data[i]);
else
printf(" ");
if (i % 4 == 3)
printf(" ");
}
printf(" |");
for (i = 0; i < len; i++) {
c = data[i];
if (c < 32 || c >= 127)
c = '.';
printf("%c", c);
}
for (; i < bytesPerLine; i++)
printf(" ");
printf("|\n");
}
static void debugHelper(const char *in_buf, bool caret = true) {
char buf[STRINGBUFLEN];
strcpy(buf, in_buf);
if (caret)
printf("%s\n", buf);
else
printf("%s", buf);
#if defined(USE_WINDBG)
if (caret)
strcat(buf, "\n");
#if defined(_WIN32_WCE)
TCHAR buf_unicode[1024];
MultiByteToWideChar(CP_ACP, 0, buf, strlen(buf) + 1, buf_unicode, sizeof(buf_unicode));
OutputDebugString(buf_unicode);
#else
OutputDebugString(buf);
#endif
#endif
fflush(stdout);
}
void CDECL debug(const char *s, ...) {
char buf[STRINGBUFLEN];
va_list va;
va_start(va, s);
vsnprintf(buf, STRINGBUFLEN, s, va);
va_end(va);
debugHelper(buf);
}
void CDECL debug(int level, const char *s, ...) {
char buf[STRINGBUFLEN];
va_list va;
if (level > debugLevel)
return;
va_start(va, s);
vsnprintf(buf, STRINGBUFLEN, s, va);
va_end(va);
debugHelper(buf);
}
void NORETURN CDECL error(const char *s, ...) {
char buf_input[STRINGBUFLEN];
char buf_output[STRINGBUFLEN];
va_list va;
// Generate the full error message
va_start(va, s);
vsnprintf(buf_input, STRINGBUFLEN, s, va);
va_end(va);
strcpy(buf_output, buf_input);
// Print the error message to stderr
fprintf(stderr, "%s!\n", buf_output);
#if defined(USE_WINDBG)
#if defined(_WIN32_WCE)
TCHAR buf_output_unicode[1024];
MultiByteToWideChar(CP_ACP, 0, buf_output, strlen(buf_output) + 1, buf_output_unicode, sizeof(buf_output_unicode));
OutputDebugString(buf_output_unicode);
#ifndef DEBUG
drawError(buf_output);
#else
int cmon_break_into_the_debugger_if_you_please = *(int *)(buf_output + 1); // bus error
printf("%d", cmon_break_into_the_debugger_if_you_please); // don't optimize the int out
#endif
#else
OutputDebugString(buf_output);
#endif
#endif
#ifdef PALMOS_MODE
extern void PalmFatalError(const char *err);
PalmFatalError(buf_output);
#endif
#ifdef __SYMBIAN32__
Symbian::FatalError(buf_output);
#endif
if (g_driver)
g_driver->quit();
exit(1);
}
void CDECL warning(const char *fmt, ...) {
char buf[STRINGBUFLEN];
va_list va;
va_start(va, fmt);
vsnprintf(buf, STRINGBUFLEN, fmt, va);
va_end(va);
#if !defined (__SYMBIAN32__)
fprintf(stderr, "WARNING: %s!\n", buf);
#endif
#if defined(USE_WINDBG)
strcat(buf, "\n");
#if defined(_WIN32_WCE)
TCHAR buf_unicode[1024];
MultiByteToWideChar(CP_ACP, 0, buf, strlen(buf) + 1, buf_unicode, sizeof(buf_unicode));
OutputDebugString(buf_unicode);
#else
OutputDebugString(buf);
#endif
#endif
}
const char *debug_levels[] = {
"NONE",
"NORMAL",
"WARN",
"ERROR",
"FUNC",
"BITMAP",
"MODEL",
"STUB",
"SMUSH",
"IMUSE",
"CHORE",
"ALL"
};
const char *debug_descriptions[] = {
"No debug messages will be printed (default)",
"\"Normal\" debug messages will be printed",
"Warning debug messages will be printed",
"Error debug messages will be printed",
"Function (normal and stub) debug messages will be printed",
"Bitmap debug messages will be printed",
"Model debug messages will be printed",
"Stub (missing function) debug messages will be printed",
"SMUSH (video) debug messages will be printed",
"IMUSE (audio) debug messages will be printed",
"Chore debug messages will be printed",
"All debug messages will be printed",
};