aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2009-11-24 22:11:07 +0000
committerMax Horn2009-11-24 22:11:07 +0000
commit1a313a7eca87e9c135171d404ff10a90718f8c4c (patch)
tree418528e4834f748973f5c38ee48aaed583933f19
parent5e0f79a2edd388dd727ecf6377bc6b8f37c577ed (diff)
downloadscummvm-rg350-1a313a7eca87e9c135171d404ff10a90718f8c4c.tar.gz
scummvm-rg350-1a313a7eca87e9c135171d404ff10a90718f8c4c.tar.bz2
scummvm-rg350-1a313a7eca87e9c135171d404ff10a90718f8c4c.zip
COMMON: Remove dependency on engines code (by using the inversion principle).
svn-id: r46130
-rw-r--r--common/console.cpp144
-rw-r--r--common/console.h89
-rw-r--r--common/debug.cpp22
-rw-r--r--common/debug.h7
-rw-r--r--common/module.mk1
-rw-r--r--common/util.cpp112
-rw-r--r--common/util.h25
-rw-r--r--engines/engine.cpp31
8 files changed, 289 insertions, 142 deletions
diff --git a/common/console.cpp b/common/console.cpp
new file mode 100644
index 0000000000..cce478b58a
--- /dev/null
+++ b/common/console.cpp
@@ -0,0 +1,144 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program 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.
+ *
+ * This program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#include "common/console.h"
+#include "common/system.h"
+
+namespace Common {
+
+static OutputFormatter s_errorOutputFormatter = 0;
+
+void setErrorOutputFormatter(OutputFormatter f) {
+ s_errorOutputFormatter = f;
+}
+
+static ErrorHandler s_errorHandler = 0;
+
+void setErrorHandler(ErrorHandler handler) {
+ s_errorHandler = handler;
+}
+
+
+} // End of namespace Common
+
+
+#ifndef DISABLE_TEXT_CONSOLE
+
+void warning(const char *s, ...) {
+ char buf[STRINGBUFLEN];
+ va_list va;
+
+ va_start(va, s);
+ vsnprintf(buf, STRINGBUFLEN, s, va);
+ va_end(va);
+
+#if !defined (__SYMBIAN32__)
+ fputs("WARNING: ", stderr);
+ fputs(buf, stderr);
+ fputs("!\n", stderr);
+#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
+}
+
+#endif
+
+void NORETURN 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);
+
+
+ // Next, give the active engine (if any) a chance to augment the message
+ if (Common::s_errorOutputFormatter) {
+ (*Common::s_errorOutputFormatter)(buf_output, buf_input, STRINGBUFLEN);
+ } else {
+ strncpy(buf_output, buf_input, STRINGBUFLEN);
+ }
+
+ buf_output[STRINGBUFLEN-3] = '\0';
+ buf_output[STRINGBUFLEN-2] = '\0';
+ buf_output[STRINGBUFLEN-1] = '\0';
+ strcat(buf_output, "!\n");
+
+
+ // Print the error message to stderr
+ fputs(buf_output, stderr);
+
+ // If there is an error handler, invoke it now
+ if (Common::s_errorHandler)
+ (*Common::s_errorHandler)(buf_output);
+
+ // TODO: Add a OSystem::fatalError() method and invoke it here.
+ // The default implementation would just call OSystem::quit().
+
+#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
+ // Finally exit. quit() will terminate the program if g_system is present
+ if (g_system)
+ g_system->quit();
+
+#if defined(SAMSUNGTV)
+ // FIXME
+ for (;;) {}
+#else
+ exit(1);
+#endif
+}
diff --git a/common/console.h b/common/console.h
new file mode 100644
index 0000000000..cff0dad55b
--- /dev/null
+++ b/common/console.h
@@ -0,0 +1,89 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program 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.
+ *
+ * This program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef COMMON_CONSOLE_H
+#define COMMON_CONSOLE_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+/**
+ * An output formatter takes a source string and 'decorates' it with
+ * extra information, storing the result in a destination buffer.
+ * A typical use is to (optionally) enhance the output given by
+ * the error() and debug() functions with extra information on
+ * the state of the active engine.
+ */
+typedef void (*OutputFormatter)(char *dst, const char *src, size_t dstSize);
+
+/**
+ * Set the output formatter used by error().
+ */
+void setErrorOutputFormatter(OutputFormatter f);
+
+
+/**
+ * A callback which is invoked by error() just before aborting.
+ * A typical example would be a function which shows a debug
+ * console and displays the given message in it.
+ */
+typedef void (*ErrorHandler)(const char *msg);
+
+/**
+ * Set a callback that is invoked by error() after the error
+ * message has been printed, but before the application is
+ * terminated.
+ * This can be used to e.g. show a debugger console.
+ */
+void setErrorHandler(ErrorHandler handler);
+
+} // End of namespace Common
+
+
+#if defined(__GNUC__)
+void error(const char *s, ...) GCC_PRINTF(1, 2) NORETURN;
+#else
+void NORETURN error(const char *s, ...);
+#endif
+
+#ifdef DISABLE_TEXT_CONSOLE
+
+inline int printf(const char *s, ...) { return 0; }
+
+inline void warning(const char *s, ...) {}
+
+#else
+
+/**
+ * Print a warning message to the text console (stderr).
+ * Automatically prepends the text "WARNING: " and appends
+ * an exclamation mark and a newline.
+ */
+void warning(const char *s, ...) GCC_PRINTF(1, 2);
+
+#endif
+
+
+#endif
diff --git a/common/debug.cpp b/common/debug.cpp
index cbd1db5f45..11b36e7d12 100644
--- a/common/debug.cpp
+++ b/common/debug.cpp
@@ -25,8 +25,7 @@
#include "common/debug.h"
#include "common/util.h"
#include "common/hashmap.h"
-
-#include "engines/engine.h"
+#include "common/hash-str.h"
#include <stdarg.h> // For va_list etc.
@@ -47,6 +46,12 @@
#endif
+
+// TODO: Move gDebugLevel into namespace Common.
+int gDebugLevel = -1;
+
+
+
namespace Common {
namespace {
@@ -135,10 +140,15 @@ bool isDebugChannelEnabled(const String &name) {
}
-} // End of namespace Common
+static OutputFormatter s_debugOutputFormatter = 0;
+
+void setDebugOutputFormatter(OutputFormatter f) {
+ s_debugOutputFormatter = f;
+}
+
+} // End of namespace Common
-int gDebugLevel = -1;
#ifndef DISABLE_TEXT_CONSOLE
@@ -149,8 +159,8 @@ static void debugHelper(const char *s, va_list va, bool caret = true) {
// Next, give the active engine (if any) a chance to augment the message,
// but only if not used from debugN.
- if (g_engine && caret) {
- g_engine->errorString(in_buf, buf, STRINGBUFLEN);
+ if (Common::s_debugOutputFormatter) {
+ (*Common::s_debugOutputFormatter)(buf, in_buf, STRINGBUFLEN);
} else {
strncpy(buf, in_buf, STRINGBUFLEN);
}
diff --git a/common/debug.h b/common/debug.h
index 95779af617..c84bc7d8af 100644
--- a/common/debug.h
+++ b/common/debug.h
@@ -26,6 +26,7 @@
#define COMMON_DEBUG_H
#include "common/scummsys.h"
+#include "common/console.h"
#include "common/list.h"
#include "common/str.h"
@@ -96,6 +97,12 @@ bool isDebugChannelEnabled(uint32 level);
bool isDebugChannelEnabled(const String &name);
+/**
+ * Set the output formatter used by debug() and related functions.
+ */
+void setDebugOutputFormatter(OutputFormatter f);
+
+
} // End of namespace Common
diff --git a/common/module.mk b/common/module.mk
index d4f92f0791..bc8e2b5b86 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
archive.o \
config-file.o \
config-manager.o \
+ console.o \
debug.o \
EventDispatcher.o \
EventRecorder.o \
diff --git a/common/util.cpp b/common/util.cpp
index 5e4ee2b2c7..94f5906b80 100644
--- a/common/util.cpp
+++ b/common/util.cpp
@@ -25,8 +25,6 @@
#include "common/util.h"
#include "common/system.h"
#include "common/config-manager.h"
-#include "gui/debugger.h"
-#include "engines/engine.h"
#include <stdarg.h> // For va_list etc.
@@ -421,113 +419,3 @@ void updateGameGUIOptions(const uint32 options) {
}
} // End of namespace Common
-
-
-
-#ifndef DISABLE_TEXT_CONSOLE
-
-void warning(const char *s, ...) {
- char buf[STRINGBUFLEN];
- va_list va;
-
- va_start(va, s);
- vsnprintf(buf, STRINGBUFLEN, s, va);
- va_end(va);
-
-#if !defined (__SYMBIAN32__)
- fputs("WARNING: ", stderr);
- fputs(buf, stderr);
- fputs("!\n", stderr);
-#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
-}
-
-#endif
-
-void NORETURN 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);
-
-
- // Next, give the active engine (if any) a chance to augment the message
- if (g_engine) {
- g_engine->errorString(buf_input, buf_output, STRINGBUFLEN);
- } else {
- strncpy(buf_output, buf_input, STRINGBUFLEN);
- }
-
- buf_output[STRINGBUFLEN-3] = '\0';
- buf_output[STRINGBUFLEN-2] = '\0';
- buf_output[STRINGBUFLEN-1] = '\0';
- strcat(buf_output, "!\n");
-
-
- // Print the error message to stderr
- fputs(buf_output, stderr);
-
- // Unless this error -originated- within the debugger itself, we
- // now invoke the debugger, if available / supported.
- if (g_engine) {
- GUI::Debugger *debugger = g_engine->getDebugger();
-#ifdef _WIN32_WCE
- if (isSmartphone())
- debugger = 0;
-#endif
- if (debugger && !debugger->isAttached()) {
- debugger->attach(buf_output);
- debugger->onFrame();
- }
- }
-
-
-#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
- // Finally exit. quit() will terminate the program if g_system is present
- if (g_system)
- g_system->quit();
-
-#if defined(SAMSUNGTV)
- // FIXME
- for (;;) {}
-#else
- exit(1);
-#endif
-}
diff --git a/common/util.h b/common/util.h
index c17557a077..986fb1cc4e 100644
--- a/common/util.h
+++ b/common/util.h
@@ -26,6 +26,7 @@
#define COMMON_UTIL_H
#include "common/scummsys.h"
+#include "common/console.h"
#include "common/str.h"
@@ -293,28 +294,4 @@ void updateGameGUIOptions(const uint32 options);
} // End of namespace Common
-
-#if defined(__GNUC__)
-void error(const char *s, ...) GCC_PRINTF(1, 2) NORETURN;
-#else
-void NORETURN error(const char *s, ...);
-#endif
-
-#ifdef DISABLE_TEXT_CONSOLE
-
-inline int printf(const char *s, ...) { return 0; }
-
-inline void warning(const char *s, ...) {}
-
-#else
-
-/**
- * Print a warning message to the text console (stderr).
- * Automatically prepends the text "WARNING: " and appends
- * an exclamation mark and a newline.
- */
-void warning(const char *s, ...) GCC_PRINTF(1, 2);
-
-#endif
-
#endif
diff --git a/engines/engine.cpp b/engines/engine.cpp
index 3c659a5d9e..d8aeb88278 100644
--- a/engines/engine.cpp
+++ b/engines/engine.cpp
@@ -31,11 +31,13 @@
#include "engines/engine.h"
#include "common/config-manager.h"
+#include "common/debug.h"
#include "common/events.h"
#include "common/file.h"
#include "common/timer.h"
#include "common/savefile.h"
#include "common/system.h"
+#include "gui/debugger.h"
#include "gui/message.h"
#include "gui/GuiManager.h"
#include "sound/mixer.h"
@@ -49,6 +51,32 @@ extern bool isSmartphone();
// FIXME: HACK for MidiEmu & error()
Engine *g_engine = 0;
+// Output formatter for debug() and error() which invokes
+// the errorString method of the active engine, if any.
+static void defaultOutputFormatter(char *dst, const char *src, size_t dstSize) {
+ if (g_engine) {
+ g_engine->errorString(src, dst, dstSize);
+ } else {
+ strncpy(dst, src, dstSize);
+ }
+}
+
+static void defaultErrorHandler(const char *msg) {
+ // Unless this error -originated- within the debugger itself, we
+ // now invoke the debugger, if available / supported.
+ if (g_engine) {
+ GUI::Debugger *debugger = g_engine->getDebugger();
+#ifdef _WIN32_WCE
+ if (isSmartphone())
+ debugger = 0;
+#endif
+ if (debugger && !debugger->isAttached()) {
+ debugger->attach(msg);
+ debugger->onFrame();
+ }
+ }
+}
+
Engine::Engine(OSystem *syst)
: _system(syst),
@@ -62,6 +90,9 @@ Engine::Engine(OSystem *syst)
_mainMenuDialog(NULL) {
g_engine = this;
+ Common::setDebugOutputFormatter(defaultOutputFormatter);
+ Common::setErrorOutputFormatter(defaultOutputFormatter);
+ Common::setErrorHandler(defaultErrorHandler);
// FIXME: Get rid of the following again. It is only here temporarily.
// We really should never run with a non-working Mixer, so ought to handle